From 1bdfc28a8390c1f9bf4bc573b5f16dfc8c2c5b68 Mon Sep 17 00:00:00 2001 From: harlequin Date: Tue, 28 Jun 2016 14:14:02 +0200 Subject: [PATCH] add h series and modify makefile for supporting more models --- Makefile | 50 +++++-- models/serie_d_mst.c | 6 +- models/serie_h_mst.c | 328 ++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 365 insertions(+), 19 deletions(-) diff --git a/Makefile b/Makefile index 3612d3c..28f3819 100644 --- a/Makefile +++ b/Makefile @@ -1,26 +1,46 @@ -TARGETS=libdvbapi.so - -CFLAGS += -fPIC -O2 -std=gnu99 -I../include -mglibc -march=34kc +APP_OBJ = dvbapi.o hook.o C_support.o log.o +LIB_TV_MODEL= +CFLAGS += -fPIC -O2 -std=gnu99 CFLAGS += -ldl -DBUILD_GIT_SHA=\"$(GIT_VERSION)\" GIT_VERSION := $(shell git describe --dirty --always --abbrev=4) +BRANCH := $(shell git symbolic-ref --short -q HEAD) -# DEFAULT VERSION INFORMATION -CFLAGS += -DLIB_NAME=\""dvbapi"\" -DLIB_VERSION=\""v0.1"\" -DLIB_TV_MODELS=\""D T-MST"\" +ifeq ($(PLATFORM), D-MST) + LIB_TV_MODEL=${PLATFORM} + APP_OBJ += models/serie_d_mst.o + CFLAGS += -mel -mglibc -march=34kc +endif + +ifeq ($(PLATFORM), H-MST) + LIB_TV_MODEL=${PLATFORM} + APP_OBJ += models/serie_h_mst.o + CFLAGS += +endif -all: ${TARGETS} - -libdvbapi.so: dvbapi.c hook.c C_support.c log.c models/serie_d_mst.c $(wildcard *.h) $(wildcard ../include/*.h) - $(CROSS)gcc $(filter %.c %.cpp,$^) ${CFLAGS} -mel -shared -Wl,-soname,$@ -o $@ -clean: - rm -f ${TARGETS} -ifeq (${TARGET_IP}, ) +OBJS = $(APP_OBJ) +LIB:=libdvbapi-${PLATFORM}-${BRANCH}-${GIT_VERSION}.so + +# DEFAULT VERSION INFORMATION +CFLAGS += -DLIB_NAME=\""dvbapi"\" -DLIB_VERSION=\""${BRANCH}"\" -DLIB_TV_MODELS=\""${LIB_TV_MODEL}"\" + +all: libdvbapi.so +ifeq ($(LIB_TV_MODEL), ) + $(error No platform selected!) endif -install: ${TARGETS} - ping -c1 -W1 -w1 ${TARGET_IP} >/dev/null && \ - lftp -v -c "open ${TARGET_IP};cd ${TARGET_DEST_DIR};mput $^;" +libdvbapi.so: $(OBJS) + $(CROSS)gcc $(CFLAGS) $(OBJS) -shared -Wl,-soname,$(LIB) -o $(LIB) + + +#$(CROSS)gcc $(CFLAGS) $(OBJS) -shared -Wl,-soname,$@ -o $@ + +.c.o: + $(CROSS)gcc $(CFLAGS) -c -o $@ $< + +clean: + rm -f $(OBJS) ${TARGETS} ./models/*.o .PHONY: clean .PHONY: install diff --git a/models/serie_d_mst.c b/models/serie_d_mst.c index 8375f85..5f38c44 100644 --- a/models/serie_d_mst.c +++ b/models/serie_d_mst.c @@ -55,7 +55,7 @@ static demux_filter_t *g_demux_filter = NULL; static SdTSData_Settings_t g_emmParams; typedef union { - const void *procs[19]; + const void *procs[18]; struct { const int (*SdTSData_StartMonitor)(u32 dmx_handle, SdTSData_Settings_t *a1); const int (*SdTSData_StopMonitor)(u32 dmx_handle, u32 mon_handle); @@ -75,7 +75,6 @@ typedef union { const int (*MDrv_DSCMB_FltTypeSet)(unsigned int u32DscmbId, unsigned int eType); const int (*MDrv_DSCMB_FltAlloc)(void); const int (*MDrv_DSCMB_FltKeySet)(u32 u32DscmbId, DSCMB_Key_Type eKeyType, u8 *pu8Key); - const int (*SdAVDec_DemuxStart) (unsigned int dmxHandle, int eDemuxOut); }; } api_callbacks_t; @@ -99,7 +98,6 @@ api_callbacks_t api_callbacks = { (const void*)"MDrv_DSCMB_FltTypeSet", (const void*)"MDrv_DSCMB_FltAlloc", (const void*)"MDrv_DSCMB_FltKeySet", - (const void*)"_Z18SdAVDec_DemuxStartj18SdAVDec_DemuxOut_k", }; static void stopMonitors() { @@ -271,6 +269,8 @@ STATIC hook_entry_t TCCIMManagerBase_hooks[] = }; +////////////////////////////////////////////////////////////////////////////// + int dvbapi_install(void *h) { int res = 0; diff --git a/models/serie_h_mst.c b/models/serie_h_mst.c index c00cfb7..c2ba168 100644 --- a/models/serie_h_mst.c +++ b/models/serie_h_mst.c @@ -17,5 +17,331 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - +#include +#include +#include +#include /*ntohs*/ +#include "../dvbapi.h" +#include "../utlist.h" +#include "../hook.h" #include "../models.h" +#include "../log.h" +#include "../version.h" + +#define FILTER_MASK_SIZE 16 + +#define DMX_HANDLE_19800000 0x19800000 +#define DMX_HANDLE_LIVE 0x19800620 +#define DMX_HANDLE_PVR 0x19800621 +#define DMX_HANDLE_UNKNOWN 0x19800622 +#define DMX_HANDLE_PIP 0x19800623 + +typedef struct DEMUX_FILTER { + u16 tableId; + s32 monHandle; + u8 demuxId; + u8 filterId; + struct DEMUX_FILTER *next; +} demux_filter_t; + +static int g_send_PMT_required = 0; +static int g_SID = 0; +static int g_fltDscmb = 0; +static unsigned int g_dmxHandle = DMX_HANDLE_LIVE; +static SdTSData_Settings_t g_dmxParams; +static s32 g_dmxMonHandle = -1; +static s32 g_dmxTableId = -1; +static demux_filter_t *g_demux_filter = NULL; +static SdTSData_Settings_t g_emmParams; + +typedef union { + const void *procs[18]; + struct { + const int (*SdTSData_StartMonitor)(u32 dmx_handle, SdTSData_Settings_t *a1); + const int (*SdTSData_StopMonitor)(u32 dmx_handle, u32 mon_handle); + const int (*MDrv_DSCMB_Init)(void); + void* (*TCAPI_GetWindow) (void /*void *this, void *window*/); + const int (*GetSource) (void *window, int *source, int arg3); + const int (*GetTvChannel)(void *window, void *channel, int arg3); + const int (*SetChannelQuiet)(void *window, void *channel, int arg3); + const void* (*TCChannel_Create)(void *channel); + const void* (*TCChannel_Destroy)(void *channel); + const int (*ProgramNumber)(void *this); + const int (*FlagScrambled)(void *this); + const int (*MDrv_DSCMB_FltDisconnectPid)(u32 a1,unsigned int u32DscmbId, unsigned int u32Pid); + const int (*MDrv_DSCMB_FltFree)(u32 a1,unsigned int u32DscmbId); + const int (*MDrv_DSCMB_FltConnectPid)(u32 a1,unsigned int u32DscmbId, unsigned int u32Pid); + const int (*MDrv_DSCMB_FltTypeSet)(u32 a1,unsigned int u32DscmbId, unsigned int eType); + const int (*MDrv_DSCMB_FltAlloc)(void); + const int (*MDrv_DSCMB_FltKeySet)(u32 a1,u32 u32DscmbId, DSCMB_Key_Type eKeyType, u8 *pu8Key); + const int (*msAPI_DMX_Init)(void); + }; + +} api_callbacks_t; + +api_callbacks_t api_callbacks = { + (const void*)"_Z21SdTSData_StartMonitorjP19SdTSData_Settings_tj12SdMainChip_k", + (const void*)"_Z20SdTSData_StopMonitorjj12SdMainChip_k", + (const void*)"MDrv_DSCMB_Init", + (const void*)"_ZN5TCAPI9GetWindowEN8TCWindow7EWindowE", + (const void*)"_ZN8TCWindow9GetSourceEPii", + (const void*)"_ZN8TCWindow12GetTVChannelEP9TCChanneli", + (const void*)"_ZN8TCWindow15SetChannelQuietEPK9TCChannelb", + (const void*)"_ZN9TCChannelC2Ev", + (const void*)"_ZN9TCChannelD2Ev", + (const void*)"_ZNK9TCChannel13ProgramNumberEv", + (const void*)"_ZNK9TCChannel13FlagScrambledEv", + (const void*)"MDrv_DSCMB2_FltDisconnectPid", + (const void*)"MDrv_DSCMB2_FltFree", + (const void*)"MDrv_DSCMB_FltConnectPid", + (const void*)"MDrv_DSCMB2_FltTypeSet", + (const void*)"MDrv_DSCMB2_FltAlloc", + (const void*)"MDrv_DSCMB2_FltKeySet", + (const void*)"msAPI_DMX_Init", +}; + +static void stopMonitors() { + u32 ret; + + if (g_dmxMonHandle >= 0) { + ret = api_callbacks.SdTSData_StopMonitor(g_dmxHandle, g_dmxMonHandle); + log("ECM%02X monitor stopped, dmxHandle=0x%08x, monHandle=0x%08x, ret=0x%08x\n",g_dmxTableId, g_dmxHandle, g_dmxMonHandle, ret); + g_dmxMonHandle = -1; + g_dmxTableId = -1; + } +} + + +static void changeMonitor(unsigned int dmxHandle) { + if ( g_dmxTableId == -1) { + return; + } + + stopMonitors(); + + g_dmxHandle = dmxHandle; + log("using dmxHandle=0x%08X\n", dmxHandle); + + g_dmxMonHandle = api_callbacks.SdTSData_StartMonitor(DMX_HANDLE_LIVE, &g_dmxParams); + log("ECM%02x monitor restarted, dmxHandle=0x%08x, monHandle=0x%08x\n",g_dmxTableId, g_dmxHandle, g_dmxMonHandle); +} + + + + +_HOOK_IMPL(int,SdAVDec_DemuxStop, unsigned int dmxHandle, int eDemuxOut) { + log("SdAVDec_DemuxStop, dmxHandle=0x%08X, eDemuxOut=0x%08X\n", dmxHandle, eDemuxOut); + log("g_dmxHandle=0x%08X\n", g_dmxHandle); + + switch (g_dmxHandle) { + case DMX_HANDLE_LIVE: + api_callbacks.SdTSData_StopMonitor(DMX_HANDLE_LIVE, 0x00); + break; + case DMX_HANDLE_PIP: + case DMX_HANDLE_PVR: + log("CHANGE MONITOR NORMALY ...\n"); + changeMonitor(DMX_HANDLE_LIVE); + break; + default: + log("Unknown dmx handle value: 0x%08X\n", dmxHandle); + break; + } + + _HOOK_DISPATCH(SdAVDec_DemuxStop, dmxHandle, eDemuxOut); + return (int)h_ret; +} + +_HOOK_IMPL(int,SdAVDec_DemuxStart, unsigned int dmxHandle, int eDemuxOut) { + log("SdDemux_Start, dmxHandle=0x%08X, eDemuxOut=0x%08X\n", dmxHandle, eDemuxOut); + log("g_dmxHandle=0x%08X\n", g_dmxHandle); + _HOOK_DISPATCH(SdAVDec_DemuxStart, dmxHandle, eDemuxOut); + + if ( g_dmxHandle != DMX_HANDLE_PVR) { + changeMonitor(dmxHandle); + } + + return (int)h_ret; +} + +_HOOK_IMPL(int,DemuxBase_m_Demux_SICallback, u32* data) { + //log("DemuxBase_m_Demux_SICallback, ra: %p, hmon=0x%08X, pid=0x%08X, buf=0x%08X, len=0x%08X\n", ra, SICallBackSettings_t[0], SICallBackSettings_t[1],SICallBackSettings_t[2],SICallBackSettings_t[3]); + //void *ra; + //asm("move %0, $ra\n" : "=r" (ra)); + + _HOOK_DISPATCH(DemuxBase_m_Demux_SICallback, data); + + pmt_t *buf; + + u16 sid = 0x00; + + if ( data[3] > 0 ) { + + if ( be8((u8 *)data[2]) == 0x02 ) { + + sid = be16( ((u8*)data[2]) + 0x03 ); + + if ( sid == 0x00 ) { + return (int)h_ret; + } + + if ( sid == g_SID && g_send_PMT_required == 1 ) { + buf = malloc(sizeof(pmt_t)); + buf->sid = sid; + buf->lm = PMT_LIST_FIRST | PMT_LIST_LAST; + buf->len = be8(((u8*)data[2]) + 0x02) + 0x03 - 0x0A; + buf->ptr = malloc(buf->len); + memcpy(buf->ptr, ((u8*)data[2]) + 0x0A , buf->len); + socket_send_pm_table(buf); + g_send_PMT_required = 0; + } + + } else { + demux_filter_t *filter; + LL_SEARCH_SCALAR(g_demux_filter, filter, monHandle, data[0]); + if ( filter ) { + log(">> EMM%02x ... hmon:0x%08x send data\n", be8((u8 *)data[2]), data[0]); + socket_send_filter_data( filter->demuxId, filter->filterId, ((u8*)data[2]) , data[3] ); + } + } + } + + return (int)h_ret; +} + +_HOOK_IMPL(int, TCCIMManagerBase_HostChannelChangeCompleted, u32 this, u32 TCChannel, u32 a3, u32 ESource, u32 a5) { + //void *ra; + //asm("move %0, $ra\n" : "=r" (ra)); + log("TCCIMManagerBase_HostChannelChangeCompleted, this: 0x%08x tcchannel: 0x%08x a3: 0x%08x esource: 0x%08x a5: 0x%08x\n",this,TCChannel,a3,ESource,a5); + _HOOK_DISPATCH(TCCIMManagerBase_HostChannelChangeCompleted, this, TCChannel, a3, ESource, a5); + + if ( TCChannel != 0x00 ) { + int sid = api_callbacks.ProgramNumber( (void *) TCChannel); + if ( g_SID != sid ) { + g_SID = sid; + g_send_PMT_required = 1; + log("Service id changes, new SID: 0x%04x\n", g_SID); + } + } + + return (int)h_ret; +} + +_HOOK_IMPL(int,TCCIMManagerBase_SetAVPID,u32 a1, u32 pid_video, u32 pid_audio, u32 eWindow, u32 a4, u32 a5) { + log("TCCIMManagerBase_SetAVPID, video: 0x%08x, audio: 0x%08x, window: 0x%08x, a4: 0x%08x, a5: 0x%08x\n",pid_video, pid_audio, eWindow, a4, a5); + _HOOK_DISPATCH(TCCIMManagerBase_SetAVPID,a1, pid_video, pid_audio, eWindow, a4, a5); + + u32 res; + if (g_fltDscmb == 1) { + api_callbacks.MDrv_DSCMB_FltDisconnectPid(0, 0, pid_video); + api_callbacks.MDrv_DSCMB_FltDisconnectPid(0, 0, pid_audio); + api_callbacks.MDrv_DSCMB_FltFree(0, 0); + g_fltDscmb = 0; + } + api_callbacks.MDrv_DSCMB_FltAlloc(); + res = api_callbacks.MDrv_DSCMB_FltConnectPid(0, 0, pid_video); + log("MDrv_DSCMB_FltConnectPid=%d\n", res); + res = api_callbacks.MDrv_DSCMB_FltConnectPid(0, 0, pid_audio); + log("MDrv_DSCMB_FltConnectPid=%d\n", res); + res = api_callbacks.MDrv_DSCMB_FltTypeSet(0, 0, 0); + log("MDrv_DSCMB_FltTypeSet=%d\n", res); + + return (int)h_ret; +} + +STATIC dyn_fn_t TCCIMManagerBase_func_table[] = { + { 0, "_ZN13TDsPrimeDemux15t_DemuxCallbackEPN8CDiDemux20SICallBackSettings_tE" }, + { 0, "_ZN16TCCIMManagerPlus13ChannelChangeEPK9TCChannelP12TCSourceConf" }, + { 0, "_Z13SdDemux_Startj13SdDemux_Out_k12SdMainChip_k" }, + { 0, "_Z12SdDemux_Stopj13SdDemux_Out_k12SdMainChip_k" }, + { 0, "_ZN5TCCBM8SetAVPIDEii"}, +}; + +STATIC hook_entry_t TCCIMManagerBase_hooks[] = +{ +#define _HOOK_ENTRY(F, I) \ + &hook_##F, &TCCIMManagerBase_func_table[I], &x_##F + { _HOOK_ENTRY(DemuxBase_m_Demux_SICallback, __COUNTER__) }, + { _HOOK_ENTRY(TCCIMManagerBase_HostChannelChangeCompleted, __COUNTER__) }, + { _HOOK_ENTRY(SdAVDec_DemuxStart, __COUNTER__) }, + { _HOOK_ENTRY(SdAVDec_DemuxStop, __COUNTER__) }, + { _HOOK_ENTRY(TCCIMManagerBase_SetAVPID, __COUNTER__) }, +#undef _HOOK_ENTRY +}; + + +////////////////////////////////////////////////////////////////////////////// + +int dvbapi_install(void *h) { + int res = 0; + + log("Install "LIB_TV_MODELS" lib"LIB_NAME" "LIB_VERSION" - "BUILD_GIT_TIME" (c) harlequin 2016\n"); + + samyGO_whacky_t_init(h, &api_callbacks, ARRAYSIZE(api_callbacks.procs)); + + if ( dyn_sym_tab_init(h, TCCIMManagerBase_func_table, ARRAYSIZE(TCCIMManagerBase_func_table)) >= 0 ) { + set_hooks(TCCIMManagerBase_hooks, ARRAYSIZE(TCCIMManagerBase_hooks)); + res = 1; + } + + u32 init = api_callbacks.MDrv_DSCMB_Init(); + log("MDrc_DSCMB_Init=0x%04x\n", init); + + return res; +} + +int dvbapi_server_info(void) { + //g_SID = -1; + + u8 channel[0x20]; + u32 source = 0; /*TODO Check if source is live tv 0x00 */ + api_callbacks.GetSource(api_callbacks.TCAPI_GetWindow(), &source, 0x01); + api_callbacks.TCChannel_Create(channel); + api_callbacks.GetTvChannel(api_callbacks.TCAPI_GetWindow(), channel, 0x01); + int scrambled = api_callbacks.FlagScrambled(channel); + if ( scrambled != 0) { + api_callbacks.SetChannelQuiet(api_callbacks.TCAPI_GetWindow(), channel, 0x01); + } + + return 0; +} + +int dvbapi_set_descriptor(ca_descr_t ca_descr) { + g_fltDscmb = api_callbacks.MDrv_DSCMB_FltKeySet(0, 0 /*ca_descr.index*/ , ca_descr.parity + 1 , ca_descr.cw); + log("MDrv_DSCMB_FltKeySet=%d g_fltDscmb=%d\n", g_fltDscmb, g_fltDscmb); + return g_fltDscmb; +} + +int dvbapi_start_filter(u8 demux_index, u8 filter_num, struct dmx_sct_filter_params params){ + /* This pid zero still occurs because the pmt is not send correctly */ + if ( ntohs(params.pid) != 0x00 ) { + demux_filter_t *filter; + + LL_SEARCH_SCALAR(g_demux_filter, filter, filterId, filter_num ); + if(!filter) { + filter = malloc(sizeof(demux_filter_t)); + filter->tableId = -1; + filter->filterId = filter_num; + filter->demuxId = demux_index; + filter->monHandle = -1; + LL_APPEND(g_demux_filter, filter); + } + + if (filter->monHandle != -1) { + u32 ret = api_callbacks.SdTSData_StopMonitor(g_dmxHandle, filter->monHandle); + log("EMM%02X monitor stopped, dmxHandle=0x%08x, monHandle=0x%08x, ret=0x%08x\n",filter->tableId, g_dmxHandle, filter->monHandle, ret); + filter->monHandle = -1; + filter->tableId = -1; + } + + g_emmParams.pid = ntohs(params.pid); + memcpy(g_emmParams.filter, params.filter.filter, FILTER_MASK_SIZE); + memcpy(g_emmParams.mask, params.filter.mask, FILTER_MASK_SIZE); + + filter->tableId = params.filter.filter[0]; + filter->demuxId = demux_index; + filter->filterId = filter_num; + filter->monHandle = api_callbacks.SdTSData_StartMonitor(DMX_HANDLE_LIVE, &g_emmParams); + log("EMM%02x monitor started, dmxHandle=0x%08x, monHandle=0x%08x\n",filter->tableId, g_dmxHandle, filter->monHandle); + } + return 0; +}