From 2af3bb129b7a8496b1cebf86c56f85c7c53374e3 Mon Sep 17 00:00:00 2001 From: harlequin Date: Fri, 3 Jun 2016 18:11:42 +0200 Subject: [PATCH] Remove pull request #1 due to many many errors and no testing of changes Fix issue #2 --- README.md | 2 +- dvbapi.c | 708 +++++++++++++++++++++++++----------------------------- tv_info.c | 120 --------- tv_info.h | 103 +++++++- 4 files changed, 419 insertions(+), 514 deletions(-) delete mode 100644 tv_info.c diff --git a/README.md b/README.md index 5977d37..345524d 100644 --- a/README.md +++ b/README.md @@ -13,4 +13,4 @@ Based on: - EMM - Enables emm messages ### Example call format -samyGOso -D -r -l /mtd_rwdata/oscam/libdvbapi.so OSCAM_SERVER_IP:192.168.1.49 OSCAM_SERVER_PORT:20000 EMM \ No newline at end of file +samyGOso -D -r -l /mtd_rwdata/oscam/libdvbapi.so OSCAM_SERVER_IP:192.168.1.48 OSCAM_SERVER_PORT:20000 EMM \ No newline at end of file diff --git a/dvbapi.c b/dvbapi.c index e813378..c7039f2 100644 --- a/dvbapi.c +++ b/dvbapi.c @@ -3,9 +3,6 @@ * https://github.com/harlequin/samygo-plugin-dvbapi * * This file is part of samygo-plugin-dvbapi. - * The project is based on following open-source projects: - * vdr-plugin-dvbapi (manio): https://github.com/manio/vdr-plugin-dvbapi - * libOSCAM v0.4.0 (bugficks): (sorry, cannot find URL with original code) * * samygo-plugin-dvbapi is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -25,7 +22,7 @@ #include #include #include -#include +#include #include #include #include @@ -61,20 +58,17 @@ static u8* oscam_server_ip = NULL; static u16 oscam_server_port = 0; static u8 oscam_emm_enabled; -#define SOCKET_PATH "/tmp/.listen.camd.socket" -#define SOCKET_BACKLOG 3 -#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 -static int tv_model = -1; -static int tv_type = -1; +#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 +static u32 tv_model = 0x00; static pthread_t x_thread_socket_handler; -static int g_send_PMT_required = 1; +static int g_send_PMT_required = 0; static int g_SID = 0; static int _hooked = 0; static int g_fltDscmb = 0; @@ -83,31 +77,33 @@ static unsigned int g_dmxHandle = DMX_HANDLE_LIVE; static int g_pidVideo = 0x0; static int g_pidAudio = 0x0; -typedef struct { - /* 0 */ u32 pid; - /* 1 */ u32 res; - /* 2 */ u32 res2; - /* 3 */ u32 filter; - /* 4 */ u32 res3; - /* 5 */ u32 res4; - /* 6 */ u32 res5; - /* 7 */ u8 mask[0x10]; +typedef struct { + /* 0 */ u32 pid; + /* 1 */ u32 res; + /* 2 */ u32 res2; + /* 3 */ u32 filter; + /* 4 */ u32 res3; + /* 5 */ u32 res4; + /* 6 */ u32 res5; + /* 7 */ u8 mask[0x10]; } SdTSData_Settings_t; static SdTSData_Settings_t g_dmxParams80; static SdTSData_Settings_t g_dmxParams81; + static s32 g_monHandle81 = -1; static s32 g_monHandle80 = -1; + static u8 g_80_demux_id; static u8 g_80_filter_id; static u8 g_81_demux_id; static u8 g_81_filter_id; -static u8 socket_connected = 0; /* will be set to 1 if handshake was done */ +static u8 socket_connected = 0x00; /* will be set to 1 if handshake was done */ static struct PMT *_pmt = NULL; static int protocol_version = 0; static u8 adapter_index; -static int sock; +static int sockfd; @@ -168,20 +164,18 @@ static void print_hash(u8 *ptr, u32 len){ while(len--) { sprintf(buffer,"%s %02x",buffer, *ptr++); if((++i % 16) == 0) { - log(" %s\n", buffer); + log(" %s\n", buffer); buffer[0] = '\0'; } } - log(" %s\n", buffer); + log(" %s\n", buffer); } static void socket_send_filter_data(u8 demux_id, u8 filter_num, u8 *data, u32 len) { - if(!socket_connected) { - return; - } + if(!socket_connected) {return;} log("send filter data demux_id: 0x%02x filter_num: 0x%02x\n", demux_id, filter_num); //log(">>>\n"); print_hash(data, len); log("<<<\n"); unsigned char buff[6 + len]; @@ -190,30 +184,26 @@ static void socket_send_filter_data(u8 demux_id, u8 filter_num, u8 *data, u32 le buff[4] = demux_id; buff[5] = filter_num; memcpy(buff + 6, data, len); - write(sock, buff, sizeof(buff)); + write(sockfd, buff, sizeof(buff)); } static void socket_send_client_info() { - int len = sizeof(INFO_VERSION) - 1; //ignoring null termination + int len = sizeof(INFO_VERSION) - 1; //ignoring null termination unsigned char buff[7 + len]; - u32 req = htonl(DVBAPI_CLIENT_INFO); //type of request + u32 req = htonl(DVBAPI_CLIENT_INFO); //type of request memcpy(&buff[0], &req, 4); - u16 proto_version = htons(DVBAPI_PROTOCOL_VERSION); //supported protocol version + u16 proto_version = htons(DVBAPI_PROTOCOL_VERSION); //supported protocol version memcpy(&buff[4], &proto_version, 2); buff[6] = len; - memcpy(&buff[7], &INFO_VERSION, len); //copy info string - write(sock, buff, sizeof(buff)); + memcpy(&buff[7], &INFO_VERSION, len); //copy info string + write(sockfd, buff, sizeof(buff)); } static void socket_send_pm_table(pmt_t *pmt) { - if(!socket_connected) { - return; - } + if(!socket_connected) {return;} - if ( pmt->len == 0) { - return; - } + if ( pmt->len == 0){return;} u8 offset = 0x0A; u8 caPMT[pmt->len + offset]; @@ -232,7 +222,7 @@ static void socket_send_pm_table(pmt_t *pmt) { memcpy(caPMT + offset, pmt->ptr, pmt->len); //print_hash((u8*)caPMT, pmt->len + offset); - write(sock, caPMT, pmt->len + offset); + write(sockfd, caPMT, pmt->len + offset); } static void stopMonitors() { @@ -308,8 +298,8 @@ _HOOK_IMPL(int,SdAVDec_DemuxStart, unsigned int dmxHandle, int eDemuxOut) { _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)); + //void *ra; + //asm("move %0, $ra\n" : "=r" (ra)); _HOOK_DISPATCH(DemuxBase_m_Demux_SICallback, data); @@ -322,35 +312,49 @@ _HOOK_IMPL(int,DemuxBase_m_Demux_SICallback, u32* data) { switch (be8((u8 *)data[2])) { case 0x02: sid = be16( ((u8*)data[2]) + 0x03 ); - LL_SEARCH_SCALAR(_pmt, buf, sid, sid); - if ( !buf ) { - //log("GOT PMT SID: 0x%04x\n", sid); - buf = malloc(sizeof(pmt_t)); - //print_hash((u8*)data[2], data[3]); - 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); - LL_APPEND(_pmt, buf); - g_send_PMT_required = 1; + + /* skip empty sid */ + if ( sid == 0x00 ) { + break; + } + + /* skip empty sid */ + if ( sid == g_SID && g_send_PMT_required == 1 ) { + //LL_SEARCH_SCALAR(_pmt, buf, sid, sid); + //if ( !buf ) { + //log("GOT PMT SID: 0x%04x\n", sid); + buf = malloc(sizeof(pmt_t)); + //print_hash((u8*)data[2], data[3]); + 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; + //LL_APPEND(_pmt, buf); + //g_send_PMT_required = 1; + //} } break; + case 0x82: + log("GOT ECM82 !!!\n"); + break; case 0x80: if ( data[3] < 0x400 ) { - log("GOT ECM80\n"); + log("GOT ECM%02x\n", be8((u8 *)data[2])); if (g_monHandle80 != -1){ - socket_send_filter_data( g_80_demux_id, g_80_filter_id, ((u8*)data[2]), data[3] ); + socket_send_filter_data( g_80_demux_id, g_80_filter_id, ((u8*)data[2]) , data[3] ); } } break; case 0x81: if ( data[3] < 0x400 ) { - log("GOT ECM81\n"); + log("GOT ECM%02x\n", be8((u8 *)data[2])); if (g_monHandle81 != -1){ - socket_send_filter_data( g_81_demux_id, g_81_filter_id, ((u8*)data[2]), data[3] ); + socket_send_filter_data( g_81_demux_id, g_81_filter_id, ((u8*)data[2]) , data[3] ); } } break; @@ -362,20 +366,20 @@ _HOOK_IMPL(int,DemuxBase_m_Demux_SICallback, u32* data) { } - if(g_send_PMT_required == 1 && g_SID != 0x00) { - LL_SEARCH_SCALAR(_pmt, buf, sid, g_SID); - if ( buf ) { - socket_send_pm_table(_pmt); - g_send_PMT_required = 0; - } - } +// if(g_send_PMT_required == 1) { +// LL_SEARCH_SCALAR(_pmt, buf, sid, g_SID); +// if ( buf ) { +// socket_send_pm_table(buf); +// g_send_PMT_required = 0; +// } +// } 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)); + //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); @@ -391,11 +395,9 @@ _HOOK_IMPL(int, TCCIMManagerBase_HostChannelChangeCompleted, u32 this, u32 TCCha return (int)h_ret; } -_HOOK_IMPL(int,TCCIMManagerBase_SetAVPID, u32 a1, u32 pid_video, u32 pid_audio, u32 a4, u32 a5 /*u32 pidVideo, u32 pidAudio, unsigned int eWindow*/) { - void *ra; - asm("move %0, $ra\n" : "=r" (ra)); - log("TCCIMManagerBase_SetAVPID, ra:%p, a1: 0x%08x, a2: 0x%08x, a3: 0x%08x, a4: 0x%08x, a5: 0x%08x\n",ra, a1, pid_video, pid_audio, a4, a5); - _HOOK_DISPATCH(TCCIMManagerBase_SetAVPID, a1, pid_video, pid_audio, a4, a5); +_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) { @@ -435,338 +437,278 @@ STATIC hook_entry_t TCCIMManagerBase_hooks[] = #undef _HOOK_ENTRY }; -void handle_dvbapi_ca_set_descr(unsigned char *buf) -{ - ca_descr_t ca_descr; - memcpy(&ca_descr, &buf[4], sizeof(ca_descr_t)); - ca_descr.index = ntohl(ca_descr.index); - ca_descr.parity = ntohl(ca_descr.parity); - log("Got CA_SET_DESCR request, index=0x%04x parity=0x%04x\n", ca_descr.index, ca_descr.parity); - - g_fltDscmb = TCCIMManagerBase.MDrv_DSCMB_FltKeySet(0 /*ca_descr.index*/ , ca_descr.parity + 1 , ca_descr.cw); - log("MDrv_DSCMB_FltKeySet=%d g_fltDscmb=%d\n", g_fltDscmb, g_fltDscmb); -} - -void handle_dmx_set_filter(unsigned char *buf) -{ - struct dmx_sct_filter_params params; - unsigned char demux_index = buf[4]; - unsigned char filter_num = buf[5]; - memcpy(¶ms, &buf[6], sizeof(struct dmx_sct_filter_params)); - log("Got DMX_SET_FILTER request, pid=0x%02x, byte1=0x%02x, mask1=0x%02x\n", ntohs(params.pid), params.filter.filter[0], params.filter.mask[0] ); - - stopMonitors(); - - switch (params.filter.filter[0]) { - case 0x80: - g_dmxParams81.pid = 0; - g_80_demux_id = demux_index; - g_80_filter_id = filter_num; - g_dmxParams80.pid = ntohs(params.pid); - g_dmxParams80.filter = params.filter.filter[0]; - g_dmxParams80.mask[0] = params.filter.mask[0]; - g_monHandle80 = TCCIMManagerBase.SdTSData_StartMonitor(DMX_HANDLE_LIVE, &g_dmxParams80);/*maybe add 0x00 as parameter*/ - log("ECM80 monitor started, dmxHandle=0x%08x, monHandle=0x%08x\n", g_dmxHandle, g_monHandle80); - break; - case 0x81: - g_dmxParams80.pid = 0; - g_81_demux_id = demux_index; - g_81_filter_id = filter_num; - g_dmxParams81.pid = ntohs(params.pid); - g_dmxParams81.filter = params.filter.filter[0]; - g_dmxParams81.mask[0] = params.filter.mask[0]; - g_monHandle81 = TCCIMManagerBase.SdTSData_StartMonitor(DMX_HANDLE_LIVE, &g_dmxParams81);/*maybe add 0x00 as parameter*/ - log("ECM81 monitor started, dmxHandle=0x%08x, monHandle=0x%08x\n", g_dmxHandle, g_monHandle81); - break; - default: - break; - } -} -void handle_dvbapi_server_info(unsigned char *buf) -{ - g_SID = -1; - - u8 channel[0x20]; - u32 source = 0; /*TODO Check if source is live tv 0x00 */ - TCCIMManagerBase.GetSource(*TCCIMManagerBase.g_pAppWindow, &source, 0x01); - TCCIMManagerBase.TCChannel_Create(channel); - TCCIMManagerBase.GetTvChannel(*TCCIMManagerBase.g_pAppWindow, channel, 0x01); - int scrambled = TCCIMManagerBase.FlagScrambled(channel); - if ( scrambled != 0) { - TCCIMManagerBase.SetChannelQuiet(*TCCIMManagerBase.g_pAppWindow, channel, 0x01); - } - u16 *proto_ver_ptr = (u16 *) &buf[4]; - protocol_version = ntohs(*proto_ver_ptr); - log("Got SERVER_INFO: %s, protocol_version = %d\n", &buf[6], protocol_version); - socket_connected = 1; -} -void handle_dvbapi_ecm_info(unsigned char *buf) -{ - char cardsystem[255]; - char reader[255]; - char from[255]; - char protocol[255]; - unsigned char len, hops; - int i = 4; - - u16 *sid_ptr = (u16 *) &buf[i]; //ServiceID - u16 sid = ntohs(*sid_ptr); - i += 2; - - u16 *caid_ptr = (u16 *) &buf[i]; //CAID - u16 caid = ntohs(*caid_ptr); - i += 2; - - u16 *pid_ptr = (u16 *) &buf[i]; //PID - u16 pid = ntohs(*pid_ptr); - i += 2; - - u32 *prid_ptr = (u32 *) &buf[i]; //ProviderID - u32 prid = ntohl(*prid_ptr); - i += 4; - - u32 *ecmtime_ptr = (u32 *) &buf[i]; //ECM time - u32 ecmtime = ntohl(*ecmtime_ptr); - - //cardsystem name - recv(sock, &len, 1, MSG_DONTWAIT); //string length - recv(sock, cardsystem, len, MSG_DONTWAIT); - cardsystem[len] = 0; //terminate the string - - //reader name - recv(sock, &len, 1, MSG_DONTWAIT); //string length - recv(sock, reader, len, MSG_DONTWAIT); - reader[len] = 0; //terminate the string - - //source (from) - recv(sock, &len, 1, MSG_DONTWAIT); //string length - recv(sock, from, len, MSG_DONTWAIT); - from[len] = 0; //terminate the string - - //protocol name - recv(sock, &len, 1, MSG_DONTWAIT); //string length - recv(sock, protocol, len, MSG_DONTWAIT); - protocol[len] = 0; //terminate the string - - recv(sock, &hops, 1, MSG_DONTWAIT); //hops - - log("Got ECM_INFO: adapter_index=%d, SID = %04X, CAID = %04X (%s), PID = %04X, ProvID = %06X, ECM time = %d ms, reader = %s, from = %s, protocol = %s, hops = %d\n", - adapter_index,sid, caid, cardsystem, pid, prid, ecmtime, reader, from, protocol, hops); -} -void socket_open_connection() -{ - // connecting via TCP socket to OSCam - struct addrinfo hints, *servinfo, *p; - int rv; - memset(&hints, 0, sizeof hints); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - - if ((rv = getaddrinfo(oscam_server_ip, itoa(oscam_server_port), &hints, &servinfo)) != 0) - { - log("getaddrinfo error: %s", strerror(rv)); - return; - } - - // loop through all the results and connect to the first we can - for (p = servinfo; p != NULL; p = p->ai_next) - { - int sockfd; - if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) == -1) - { - log("%s: socket error: %s", __FUNCTION__, strerror(errno)); - continue; - } - if (connect(sockfd, p->ai_addr, p->ai_addrlen) == -1) - { - close(sockfd); - log("%s: connect error: %s", __FUNCTION__, strerror(errno)); - continue; - } - sock = sockfd; - break; // if we get here, we must have connected successfully - } - - if (p == NULL) - { - // looped off the end of the list with no connection - log("Cannot connect to OSCam. Check your configuration and firewall settings."); - sock = 0; - } +/* SOCKET HANDLER */ +static void *socket_handler(void *ptr){ + log("create socket handler\n"); - freeaddrinfo(servinfo); // all done with this structure + #define MAXBUF 512 + + struct sockaddr_in dest; + char buffer[MAXBUF]; + + /*---Open socket for streaming---*/ + if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0 ) { + log("socket connection error\n"); + } else { + /*---Initialize server address/port struct---*/ + bzero(&dest, sizeof(dest)); + dest.sin_family = AF_INET; + dest.sin_port = htons(oscam_server_port); + if ( inet_pton(AF_INET, oscam_server_ip, &dest.sin_addr) <= 0 ) { + log("can't set oscam server destination\n"); + } else { + /*---Connect to server---*/ + if ( connect(sockfd, (struct sockaddr*)&dest, sizeof(dest)) != 0 ) { + log("can't connect oscam server destination\n"); + log("%s: connect error: %s", __FUNCTION__, strerror(errno)); + } else { + log("Client connected ... send DVBAPI_CLIENT_INFO ...\n"); + socket_send_client_info(); - if (sock) - log("created socket with socket_fd=%d", sock); -} -void socket_close_connection() -{ - if (sock > 0) - { - close(sock); - sock = 0; - } -} + int running = 1; + int c_read; + unsigned char buf[262]; + int skip_bytes = 0; + u32 *request; -/* SOCKET HANDLER */ -static void *socket_handler(void *ptr){ - int faults = 0; - log("create socket handler\n"); + while(running==1) { - socket_open_connection(); - if (sock > 0) - { - log("Successfully (re)connected to OSCam"); - log("Sending DVBAPI_CLIENT_INFO ...\n"); - faults = 0; - socket_send_client_info(); - //capmt sendall - } - else { - faults++; // unused for now - return NULL; - } - int running = 1; - int c_read; - unsigned char buf[262]; - int skip_bytes = 0; - u32 *request; - while(running==1) { - c_read = recv(sock, &buf[skip_bytes], sizeof(int)-skip_bytes, MSG_DONTWAIT); - if (c_read <= 0) { - //if (c_read == 0) - // break; - //log that connection is broken and everything is stopped - //cCondWait::SleepMs(20); - continue; - } + c_read = recv(sockfd, &buf[skip_bytes], sizeof(int)-skip_bytes, MSG_DONTWAIT); - request = (unsigned int *) &buf; - skip_bytes = 0; - - if (ntohl(*request) != DVBAPI_SERVER_INFO) { - // first byte -> adapter_index - c_read = recv(sock, &adapter_index, 1, MSG_DONTWAIT); - if (c_read <= 0) { - //if (cRead == 0) - // CloseConnection(); - //cCondWait::SleepMs(20); - continue; - } - //adapter_index -= AdapterIndexOffset; - } + if (c_read <= 0) { + //if (c_read == 0) + // break; - *request = ntohl(*request); - if (DVBAPI_CA_SET_DESCR == *request) { - c_read = recv(sock, buf+4, sizeof(ca_descr_t), MSG_DONTWAIT); - } else if (DVBAPI_CA_SET_PID == *request) { - /*TODO: Shall we use this?*/ - c_read = recv(sock, buf+4, sizeof(ca_pid_t), MSG_DONTWAIT); - continue; - } else if (DMX_SET_FILTER == *request) { - c_read = recv(sock, buf+4, sizeof(struct dmx_sct_filter_params), MSG_DONTWAIT); - } else if (DVBAPI_SERVER_INFO == *request) { - unsigned char len; - recv(sock, buf+4, 2, MSG_DONTWAIT); - recv(sock, &len, 1, MSG_DONTWAIT); - c_read = recv(sock, buf+6, len, MSG_DONTWAIT); - buf[6+len] = 0; - } else if (DVBAPI_ECM_INFO == *request) { - recv(sock, buf+4, 14, MSG_DONTWAIT); - } else if (CA_SET_DESCR_MODE == *request) { - /*TODO: Shall we use this?*/ - c_read = recv(sock, buf+4, sizeof(ca_descr_mode_t), MSG_DONTWAIT); - continue; - } else { - log("read failed unknown command: %08x\n", *request); - usleep(2000); - continue; - } + //log that connection is broken and everything is stopped + //cCondWait::SleepMs(20); + continue; + } - if (c_read <= 0) { - //if (c_read == 0) - // CloseConnection(); - // cCondWait::SleepMs(20); - continue; - } + request = (unsigned int *) &buf; + skip_bytes = 0; + + if (ntohl(*request) != DVBAPI_SERVER_INFO) { + // first byte -> adapter_index + c_read = recv(sockfd, &adapter_index, 1, MSG_DONTWAIT); + if (c_read <= 0) { + //if (cRead == 0) + // CloseConnection(); + //cCondWait::SleepMs(20); + continue; + } + //adapter_index -= AdapterIndexOffset; + } - if (DVBAPI_CA_SET_DESCR == *request) { - handle_dvbapi_ca_set_descr((unsigned char *)&buf); - } else if (DMX_SET_FILTER == *request) { - handle_dmx_set_filter((unsigned char *)&buf); - } else if(DVBAPI_SERVER_INFO == *request) { - handle_dvbapi_server_info((unsigned char *)&buf); - } else if (DVBAPI_ECM_INFO == *request) { - handle_dvbapi_ecm_info((unsigned char *)&buf); - } else { - log("Unknown request: %02X %02X %02X %02X\n", request[0], request[1], request[2], request[3]); - } - } - socket_close_connection(); -} -void start_capmt_server() -{ - int clientfd, running = 1; - struct sockaddr_un addr, peer_addr; - socklen_t peer_addr_size; - - unlink(SOCKET_PATH); - memset(&addr, 0, sizeof(struct sockaddr_un)); - strncpy(addr.sun_path, SOCKET_PATH, sizeof(addr.sun_path) - 1); - addr.sun_family = AF_UNIX; - - if ((sock = socket(addr.sun_family, SOCK_STREAM, 0)) == -1) - { - log("%s: socket error: %s", __FUNCTION__, strerror(sock)); - return; - } + *request = ntohl(*request); + if (*request == DVBAPI_CA_SET_DESCR) { + c_read = recv(sockfd, buf+4, sizeof(ca_descr_t), MSG_DONTWAIT); + }else if (*request == DVBAPI_CA_SET_PID) { + /*TODO: Shall we use this?*/ + c_read = recv(sockfd, buf+4, sizeof(ca_pid_t), MSG_DONTWAIT); + continue; + }else if (*request == DMX_SET_FILTER) { + c_read = recv(sockfd, buf+4, sizeof(struct dmx_sct_filter_params), MSG_DONTWAIT); + } else if (*request == DVBAPI_SERVER_INFO) { + unsigned char len; + recv(sockfd, buf+4, 2, MSG_DONTWAIT); + recv(sockfd, &len, 1, MSG_DONTWAIT); + c_read = recv(sockfd, buf+6, len, MSG_DONTWAIT); + buf[6+len] = 0; + }else if (*request == DVBAPI_ECM_INFO) { + recv(sockfd, buf+4, 14, MSG_DONTWAIT); + + }else if (*request == DVBAPI_DMX_STOP) { + c_read = recv(sockfd, buf+4, 2 + 2, MSG_DONTWAIT); + + } else if (*request == CA_SET_DESCR_MODE) { + /*TODO: Shall we use this?*/ + c_read = recv(sockfd, buf+4, sizeof(ca_descr_mode_t), MSG_DONTWAIT); + continue; + } else { + log("read failed unknown command: %08x\n", *request); + usleep(2000); + continue; + } + + if (c_read <= 0) { + //if (c_read == 0) + // CloseConnection(); + // cCondWait::SleepMs(20); + continue; + } - if (bind(sock, (struct sockaddr *) &addr, sizeof(struct sockaddr_un)) == -1) - { - log("%s: socket bind failed: %s\n", __FUNCTION__, strerror(sock)); - return; - } - listen(sock, SOCKET_BACKLOG); - log("Listening on socket...\n"); + if (*request == DVBAPI_CA_SET_DESCR) { + ca_descr_t ca_descr; + memcpy(&ca_descr, &buf[4], sizeof(ca_descr_t)); + ca_descr.index = ntohl(ca_descr.index); + ca_descr.parity = ntohl(ca_descr.parity); + log("Got CA_SET_DESCR request, index=0x%04x parity=0x%04x\n", ca_descr.index, ca_descr.parity); + + g_fltDscmb = TCCIMManagerBase.MDrv_DSCMB_FltKeySet(0 /*ca_descr.index*/ , ca_descr.parity + 1 , ca_descr.cw); + log("MDrv_DSCMB_FltKeySet=%d g_fltDscmb=%d\n", g_fltDscmb, g_fltDscmb); + } + + else if (*request == DVBAPI_DMX_STOP) { + stopMonitors(); +// unsigned char demux_index = buff[4]; +// unsigned char filter_num = buff[5]; +// +// uint16_t *pid_ptr = (uint16_t *) &buff[6]; +// uint16_t pid = ntohs(*pid_ptr); +// +// DEBUGLOG("%s: Got DMX_STOP request, adapter_index=%d, pid=%X, demux_idx=%d, filter_num=%d", __FUNCTION__, adapter_index, pid, demux_index, filter_num); +// filter->SetFilter(adapter_index, pid, 0, demux_index, filter_num, NULL, NULL); + } + + + else if (*request == DMX_SET_FILTER) { + struct dmx_sct_filter_params params; + unsigned char demux_index = buf[4]; + unsigned char filter_num = buf[5]; + memcpy(¶ms, &buf[6], sizeof(struct dmx_sct_filter_params)); + log("Got DMX_SET_FILTER request, pid=0x%02x, byte1=0x%02x, mask1=0x%02x\n", ntohs(params.pid), params.filter.filter[0], params.filter.mask[0] ); + + stopMonitors(); + + switch (params.filter.filter[0]) { + case 0x80: + + g_dmxParams81.pid = 0; + g_80_demux_id = demux_index; + g_80_filter_id = filter_num; + g_dmxParams80.pid = ntohs(params.pid); + g_dmxParams80.filter = params.filter.filter[0]; + g_dmxParams80.mask[0] = params.filter.mask[0]; + g_monHandle80 = TCCIMManagerBase.SdTSData_StartMonitor(DMX_HANDLE_LIVE, &g_dmxParams80);/*maybe add 0x00 as parameter*/ + log("ECM80 monitor started, dmxHandle=0x%08x, monHandle=0x%08x\n", g_dmxHandle, g_monHandle80); + break; + case 0x81: + + g_dmxParams80.pid = 0; + g_81_demux_id = demux_index; + g_81_filter_id = filter_num; + g_dmxParams81.pid = ntohs(params.pid); + g_dmxParams81.filter = params.filter.filter[0]; + g_dmxParams81.mask[0] = params.filter.mask[0]; + g_monHandle81 = TCCIMManagerBase.SdTSData_StartMonitor(DMX_HANDLE_LIVE, &g_dmxParams81);/*maybe add 0x00 as parameter*/ + log("ECM81 monitor started, dmxHandle=0x%08x, monHandle=0x%08x\n", g_dmxHandle, g_monHandle81); + break; + default: + break; + } + + + } else if(*request == DVBAPI_SERVER_INFO) { + + //g_SID = -1; + + u8 channel[0x20]; + u32 source = 0; /*TODO Check if source is live tv 0x00 */ + TCCIMManagerBase.GetSource(*TCCIMManagerBase.g_pAppWindow, &source, 0x01); + TCCIMManagerBase.TCChannel_Create(channel); + TCCIMManagerBase.GetTvChannel(*TCCIMManagerBase.g_pAppWindow, channel, 0x01); + int scrambled = TCCIMManagerBase.FlagScrambled(channel); + if ( scrambled != 0) { + TCCIMManagerBase.SetChannelQuiet(*TCCIMManagerBase.g_pAppWindow, channel, 0x01); + } + + u16 *proto_ver_ptr = (u16 *) &buf[4]; + protocol_version = ntohs(*proto_ver_ptr); + log("Got SERVER_INFO: %s, protocol_version = %d\n", &buf[6], protocol_version); + socket_connected = 0x01; + + }else if (*request == DVBAPI_ECM_INFO) { + + char cardsystem[255]; + char reader[255]; + char from[255]; + char protocol[255]; + unsigned char len, hops; + int i = 4; + + u16 *sid_ptr = (u16 *) &buf[i]; //ServiceID + u16 sid = ntohs(*sid_ptr); + i += 2; + + u16 *caid_ptr = (u16 *) &buf[i]; //CAID + u16 caid = ntohs(*caid_ptr); + i += 2; + + u16 *pid_ptr = (u16 *) &buf[i]; //PID + u16 pid = ntohs(*pid_ptr); + i += 2; + + u32 *prid_ptr = (u32 *) &buf[i]; //ProviderID + u32 prid = ntohl(*prid_ptr); + i += 4; + + u32 *ecmtime_ptr = (u32 *) &buf[i]; //ECM time + u32 ecmtime = ntohl(*ecmtime_ptr); + + //cardsystem name + recv(sockfd, &len, 1, MSG_DONTWAIT); //string length + recv(sockfd, cardsystem, len, MSG_DONTWAIT); + cardsystem[len] = 0; //terminate the string + + //reader name + recv(sockfd, &len, 1, MSG_DONTWAIT); //string length + recv(sockfd, reader, len, MSG_DONTWAIT); + reader[len] = 0; //terminate the string + + //source (from) + recv(sockfd, &len, 1, MSG_DONTWAIT); //string length + recv(sockfd, from, len, MSG_DONTWAIT); + from[len] = 0; //terminate the string + + //protocol name + recv(sockfd, &len, 1, MSG_DONTWAIT); //string length + recv(sockfd, protocol, len, MSG_DONTWAIT); + protocol[len] = 0; //terminate the string + + recv(sockfd, &hops, 1, MSG_DONTWAIT); //hops + + log("Got ECM_INFO: adapter_index=%d, SID = %04X, CAID = %04X (%s), PID = %04X, ProvID = %06X, ECM time = %d ms, reader = %s, from = %s, protocol = %s, hops = %d\n", adapter_index, sid, caid, cardsystem, pid, prid, ecmtime, reader, from, protocol, hops); + } else { + log("Unknown request: %02X %02X %02X %02X\n", request[0], request[1], request[2], request[3]); + } - while(running) { - peer_addr_size = sizeof(struct sockaddr_un); - clientfd = accept(sock, (struct sockaddr *) &peer_addr, &peer_addr_size); - if (clientfd == -1) - break; + } + close(sockfd); + } - log("Handling connected client...\n"); - // handle stuff - } + } + } + log("--NEVER BE HERE--\n"); + return NULL; } EXTERN_C void lib_init(void *_h, const char *libpath) { u32 argc; char *argv[100],*optstr; - unsigned long *cur_addr,ret,i,k,D, LOG_ALL=0; + unsigned long *cur_addr,ret,i,k,D, LOG_ALL=0; - if(_hooked) { - log("Injecting once is enough!\n"); - return; - } + if(_hooked) { + log("Injecting once is enough!\n"); + return; + } - unlink(LOG_FILE); + unlink(LOG_FILE); log("SamyGO "LIB_TV_MODELS" lib"LIB_NAME" "LIB_VERSION" - "BUILD_GIT_TIME" (c) element 2016\n"); void *h = dlopen(0, RTLD_LAZY); @@ -811,20 +753,20 @@ EXTERN_C void lib_init(void *_h, const char *libpath) { } tv_model = getTVModel(); - tv_type = getTVType(); - log("TV Model: %s, Type: %s\n", tvModelToStr(tv_model), tvTypeToStr(tv_type)); - + log("TV Model: %s\n", tvModelToStr(tv_model)); dlclose(h); - log("Hooking the system done ...\n"); + log("Hooking the system done ...\n"); - u32 init = TCCIMManagerBase.MDrv_DSCMB_Init(); - log("MDrc_DSCMB_Init=0x%04x\n", init); + u32 init = TCCIMManagerBase.MDrv_DSCMB_Init(); + log("MDrc_DSCMB_Init=0x%04x\n", init); - if(pthread_create(&x_thread_socket_handler, NULL, socket_handler, NULL)) { - log("error creating socket handler thread\n"); - } + if(pthread_create(&x_thread_socket_handler, NULL, socket_handler, NULL)) { + log("error creating socket handler thread\n"); + } } EXTERN_C void lib_deinit(void *_h) { - log("If you see this message you forget to specify -r when invoking hijack :)\n"); + log("If you see this message you forget to specify -r when invoking hijack :)\n"); } + + diff --git a/tv_info.c b/tv_info.c deleted file mode 100644 index b4770a6..0000000 --- a/tv_info.c +++ /dev/null @@ -1,120 +0,0 @@ -#include "tv_info.h" - -inline static int getTVType() -{ - static char pinfo[256] = { 0 }; - - FILE *f = fopen("/mtd_exe/.product", "r"); - if(!f) - { - f = fopen("/.info", "r"); //on C there is no .product - if(!f) - return 0; - } - - fseek(f, 0, SEEK_END); - long nread = ftell(f); - fseek(f, 0, SEEK_SET); - - if(nread > sizeof(pinfo) - 1) - nread = sizeof(pinfo) - 1; - - nread = fread(pinfo, 1, nread, f); - if(nread >= 0) - pinfo[nread] = 0; - - fclose(f); - - while(pinfo[nread-1] == '\n' || pinfo[nread-1] == '\r') - pinfo[--nread] = 0; - - if(strncmp("T-MST", pinfo, 5) == 0) - return TV_TYPE_MST; - else if(strncmp("T-GFS", pinfo, 5) == 0 || strncmp("T-GFP", pinfo, 5) == 0) - return TV_TYPE_GFS_GFP; - else if(strncmp("T-NT", pinfo, 4) == 0) - return TV_TYPE_NT; - - return TV_TYPE_NON_MST; -} - -inline static const char *tvTypeToStr(int t) -{ - switch(t) - { - case TV_TYPE_MST: - return "T-MST"; - case TV_TYPE_GFS_GFP: - return "T-GFS/T-GFP"; - case TV_TYPE_NT: - return "T-NT"; - case TV_TYPE_NON_MST: - return "Non-MST"; - default: - return "UNKNOWN"; - } -} - -inline static int getTVModel() -{ - static const struct - { - const char *name; - int model; - } - syms[] = - { - { "_ZNSt5dequeIN10jpegplayer6effect9SlideShow4ItemESaIS3_EE16_M_push_back_auxERKS3_", TV_MODEL_C }, - { "_ZN13CViewerNormal10t_SetSleepEv", TV_MODEL_D }, - { "_ZN13CViewerNormal11t_ShowSleepEb", TV_MODEL_E }, - { "_ZN13CViewerNormal10m_SetSleepEb", TV_MODEL_F }, //exeAPP - { "_ZN8TCTvImpl7m_TunerEN8TCWindow7EWindowE", TV_MODEL_F }, //exeTV - { "_ZN10CNormalWnd10m_SetSleepEb", TV_MODEL_H }, //exeAPP - { "_ZN8TCTvImpl27m_RecoverSettingsWithBootUpEv", TV_MODEL_H }, //exeTV - }; - - void *h = dlopen(0, RTLD_LAZY); - if(!h) - return TV_MODEL_UNK; - - int i,model; - //if(strstr(getTVInfo(),"VALDEUC")) - //{ - //dlclose(h); - //return TV_MODEL_C; - //} - - model = TV_MODEL_UNK; - for(i = 0; i < ARRAYSIZE(syms); i++) - { - if(dlsym(h, syms[i].name)) - { - model = syms[i].model; - break; - } - } - - dlclose(h); - - return model; -} - - -inline static const char *tvModelToStr(int m) -{ - switch(m) - { - case TV_MODEL_C: - return "C Series"; - case TV_MODEL_D: - return "D Series"; - case TV_MODEL_E: - return "E Series"; - case TV_MODEL_F: - return "F Series"; - case TV_MODEL_H: - return "H Series"; - default: - return 0; - } -} \ No newline at end of file diff --git a/tv_info.h b/tv_info.h index 5ccc9b7..9608fac 100644 --- a/tv_info.h +++ b/tv_info.h @@ -16,13 +16,36 @@ ////////////////////////////////////////////////////////////////////////////// -enum eTV_TYPE +static const char *getTVInfo() { - TV_TYPE_NON_MST = 0, - TV_TYPE_MST = 1, - TV_TYPE_GFS_GFP = 2, - TV_TYPE_NT = 3, -}; + static char pinfo[256] = { 0 }; + + FILE *f = fopen("/mtd_exe/.product", "r"); + if(!f) + { + f = fopen("/.info", "r"); //on C there is no .product + if(!f) + return 0; + } + + fseek(f, 0, SEEK_END); + long nread = ftell(f); + fseek(f, 0, SEEK_SET); + + if(nread > sizeof(pinfo) - 1) + nread = sizeof(pinfo) - 1; + + nread = fread(pinfo, 1, nread, f); + if(nread >= 0) + pinfo[nread] = 0; + + fclose(f); + + while(pinfo[nread-1] == '\n' || pinfo[nread-1] == '\r') + pinfo[--nread] = 0; + + return pinfo; +} enum eTV_MODEL { @@ -34,10 +57,70 @@ enum eTV_MODEL TV_MODEL_H = 4, }; -inline static int getTVType(); -inline static const char *tvTypeToStr(int t); -inline static int getTVModel(); -inline static const char *tvModelToStr(int m); +static int getTVModel() +{ + static const struct + { + const char *name; + int model; + } + syms[] = + { + { "_ZNSt5dequeIN10jpegplayer6effect9SlideShow4ItemESaIS3_EE16_M_push_back_auxERKS3_", TV_MODEL_C }, + { "_ZN13CViewerNormal10t_SetSleepEv", TV_MODEL_D }, + { "_ZN13CViewerNormal11t_ShowSleepEb", TV_MODEL_E }, + { "_ZN13CViewerNormal10m_SetSleepEb", TV_MODEL_F }, //exeAPP + { "_ZN8TCTvImpl7m_TunerEN8TCWindow7EWindowE", TV_MODEL_F }, //exeTV + { "_ZN10CNormalWnd10m_SetSleepEb", TV_MODEL_H }, //exeAPP + { "_ZN8TCTvImpl27m_RecoverSettingsWithBootUpEv", TV_MODEL_H }, //exeTV + }; + + void *h = dlopen(0, RTLD_LAZY); + if(!h) + return TV_MODEL_UNK; + + int i,model; + //if(strstr(getTVInfo(),"VALDEUC")) + //{ + //dlclose(h); + //return TV_MODEL_C; + //} + + model = TV_MODEL_UNK; + for(i = 0; i < ARRAYSIZE(syms); i++) + { + if(dlsym(h, syms[i].name)) + { + model = syms[i].model; + break; + } + } + + dlclose(h); + + return model; +} + + +static const char *tvModelToStr( + int m) +{ + switch(m) + { + case TV_MODEL_C: + return "C Series"; + case TV_MODEL_D: + return "D Series"; + case TV_MODEL_E: + return "E Series"; + case TV_MODEL_F: + return "F Series"; + case TV_MODEL_H: + return "H Series"; + default: + return 0; + } +} //////////////////////////////////////////////////////////////////////////////