static void radegast_process_ecm(uchar *buf, int32_t l) { int32_t i, n, sl; ECM_REQUEST *er; struct s_client *cl = cur_client(); if(!(er = get_ecmtask())) { return; } for(i = 0; i+1 < l; i += (sl + 2)) { sl = buf[i + 1]; switch(buf[i]) { case 2: // CAID (upper byte only, oldstyle) if(i+2 >= l) { break; } er->caid = buf[i + 2] << 8; break; case 10: // CAID if(i+3 >= l) { break; } er->caid = b2i(2, buf + i + 2); break; case 3: // ECM DATA if(i+4 >= l) { break; } er->ecmlen = (((buf[i + 1 + 2] & 0x0F) << 8) | buf[i + 2 + 2]) + 3; if(er->ecmlen < 3 || er->ecmlen > MAX_ECM_SIZE || i+2+er->ecmlen > l) { break; } memcpy(er->ecm, buf + i + 2, er->ecmlen); break; case 6: // PROVID (ASCII) if(i+2+sl > l) { break; } n = (sl > 6) ? 3 : (sl >> 1); er->prid = cs_atoi((char *) buf + i + 2 + sl - (n << 1), n, 0); break; case 7: // KEYNR (ASCII), not needed break; case 8: // ECM PROCESS PID ?? don't know, not needed break; } } if(l != i) { cs_log("WARNING: ECM-request corrupt"); } else { get_cw(cl, er); } }
static void radegast_process_ecm(uchar *buf, int32_t l) { int32_t i, n, sl; ECM_REQUEST *er; struct s_client *cl = cur_client(); if (!(er=get_ecmtask())) return; for (i=0; i<l; i+=(sl+2)) { sl=buf[i+1]; switch(buf[i]) { case 2: // CAID (upper byte only, oldstyle) er->caid=buf[i+2]<<8; break; case 10: // CAID er->caid=b2i(2, buf+i+2); break; case 3: // ECM DATA er->ecmlen = sl; memcpy(er->ecm, buf+i+2, er->ecmlen); break; case 6: // PROVID (ASCII) n=(sl>6) ? 3 : (sl>>1); er->prid=cs_atoi((char *) buf+i+2+sl-(n<<1), n, 0); break; case 7: // KEYNR (ASCII), not needed break; case 8: // ECM PROCESS PID ?? don't know, not needed break; } } if (l!=i) cs_log("WARNING: ECM-request corrupt"); else get_cw(cl, er); }
static int32_t oscam_ser_check_ecm(ECM_REQUEST *er, uchar *buf, int32_t l) { int32_t i; struct s_serial_client *serialdata = cur_client()->serialdata; if (l<16) { cs_log(incomplete, l); return(1); } switch(serialdata->connected) { case P_HSIC: er->ecmlen = l-12; er->caid = b2i(2, buf+1 ); er->prid = b2i(3, buf+3 ); er->pid = b2i(2, buf+6 ); er->srvid= b2i(2, buf+10); memcpy(er->ecm, buf+12, er->ecmlen); break; case P_SSSP: er->pid=b2i(2, buf+3); for (i=0; (i<8) && (serialdata->sssp_tab[i].pid!=er->pid); i++); if (i>=serialdata->sssp_num) { cs_debug_mask(D_CLIENT, "illegal request, unknown pid=%04X", er->pid); return(2); } er->ecmlen = l-5; er->srvid= serialdata->sssp_srvid; er->caid = serialdata->sssp_tab[i].caid; er->prid = serialdata->sssp_tab[i].prid; memcpy(er->ecm, buf+5, er->ecmlen); break; case P_BOMBA: er->ecmlen = l; memcpy(er->ecm, buf, er->ecmlen); break; case P_DSR95: buf[l]='\0'; // prepare for trim trim((char *)buf+13); // strip spc, nl, cr ... er->ecmlen = strlen((char *)buf+13)>>1; er->prid=cs_atoi((char *)buf+3, 3, 0); // ignore errors er->caid=cs_atoi((char *)buf+9, 2, 0); // ignore errors if (cs_atob(er->ecm, (char *)buf+13, er->ecmlen)<0) { cs_log("illegal characters in ecm-request"); return(1); } if( serialdata->dsr9500type==P_DSR_WITHSID ) { er->ecmlen -= 2; er->srvid=cs_atoi((char *)buf+13+(er->ecmlen << 1), 2, 0); } break; case P_GS: er->ecmlen = ((buf[3]<<8)|buf[2]) - 6; er->srvid = (buf[5]<<8)|buf[4]; // sid er->caid = (buf[7]<<8)|buf[6]; er->prid = 0; if (er->ecmlen > 256) er->ecmlen = 256; memcpy(er->ecm, buf+10, er->ecmlen); break; case P_ALPHA: l=oscam_ser_alpha_convert(buf, l); er->ecmlen= b2i(2, buf+1 )-2; er->caid = b2i(2, buf+3 ); if ((er->ecmlen!=l-5) || (er->ecmlen>257)) { cs_log(incomplete, l); return(1); } memcpy(er->ecm, buf+5, er->ecmlen); break; case P_GBOX: er->srvid = b2i(2, buf+serialdata->gbox_lens.cat_len+3+3); er->ecmlen = serialdata->gbox_lens.ecm_len+3; memcpy(er->ecm, buf+serialdata->gbox_lens.cat_len+3+serialdata->gbox_lens.pmt_len+3, er->ecmlen); break; } return(0); }
static int32_t oscam_ser_recv(struct s_client *client, uchar *xbuf, int32_t l) { int32_t s, p, n, r; uchar job=IS_BAD; static uchar lb; static int32_t have_lb=0; uchar *buf=xbuf+1; struct s_serial_client *serialdata=client->serialdata; if (!client->pfd) return(-1); cs_ftime(&serialdata->tps); serialdata->tpe=serialdata->tps; serialdata->tpe.millitm+=serialdata->oscam_ser_timeout; serialdata->tpe.time+=(serialdata->tpe.millitm/1000); serialdata->tpe.millitm%=1000; buf[0]=lb; for (s=p=r=0, n=have_lb; (s<4) && (p>=0); s++) { switch(s) { case 0: // STAGE 0: skip known garbage from DSR9500 if (oscam_ser_selrec(buf, 2-n, l, &n)) { if ((buf[0]==0x0A) && (buf[1]==0x0D)) p=(-4); if ((buf[0]==0x0D) && (buf[1]==0x0A)) p=(-4); } else p=(-3); have_lb=0; break; case 1: // STAGE 1: identify protocol p=(-3); if (oscam_ser_selrec(buf, 1, l, &n)) // now we have 3 bytes in buf { if((buf[0] == 0x04) && (buf[1] == 0x00) && (buf[2] == 0x02)) { //skip unsupported Advanced Serial Sharing Protocol HF 8900 oscam_ser_selrec(buf, 2, l, &n); // get rest 2 bytes to buffor p=(-4); have_lb=0; break; } else { p=(-2); if (client->typ == 'c') // HERE IS SERVER { job=IS_ECM; // assume ECM switch(buf[0]) { case 0x00: if( (buf[1]==0x01)&&(buf[2]==0x00) ) { p=P_GS; job=IS_LGO; serialdata->tpe.time++; } break; case 0x01: if( (buf[1]&0xf0)==0xb0 ) p=P_GBOX; else {p=P_SSSP; job=IS_PMT;} break; // pmt-request case 0x02: p=P_HSIC; break; case 0x03: switch(serialdata->oscam_ser_proto) { case P_SSSP : case P_GS : case P_DSR95 : p=serialdata->oscam_ser_proto; break; case P_AUTO : p=(buf[1]<0x30) ? P_SSSP : P_DSR95; break; // auto for GS is useless !! } break; case 0x04: p=P_DSR95; job=IS_ECHO; serialdata->dsr9500type=P_DSR_GNUSMAS; break; case 0x7E: p=P_ALPHA; if (buf[1]!=0x80) job=IS_BAD; break; case 0x80: case 0x81: p=P_BOMBA; break; } } else // HERE IS CLIENT { job=IS_DCW; // assume DCW switch(serialdata->oscam_ser_proto) { case P_HSIC : if ((buf[0]==4) && (buf[1]==4)) p=P_HSIC; break; case P_BOMBA: p=P_BOMBA; break; case P_DSR95: if (buf[0]==4) p=P_DSR95; break; case P_ALPHA: if (buf[0]==0x88) p=P_ALPHA; break; } } if ((serialdata->oscam_ser_proto!=p) && (serialdata->oscam_ser_proto!=P_AUTO)) p=(-2); } } break; case 2: // STAGE 2: examine length if (client->typ == 'c') switch(p) { case P_SSSP : r=(buf[1]<<8)|buf[2]; break; case P_BOMBA : r=buf[2]; break; case P_HSIC : if (oscam_ser_selrec(buf, 12, l, &n)) r=buf[14]; else p=(-1); break; case P_DSR95 : if( job==IS_ECHO ) { r=17*serialdata->samsung_dcw-3+serialdata->samsung_0a; serialdata->samsung_dcw=serialdata->samsung_0a=0; } else { if (oscam_ser_selrec(buf, 16, l, &n)) { uchar b; if (cs_atob(&b, (char *)buf+17, 1)<0) p=(-2); else { r=(b<<1); r+=(serialdata->dsr9500type==P_DSR_WITHSID)?4:0; } } else p=(-1); } break; case P_GS : if (job==IS_LGO) r=5; else { if (oscam_ser_selrec(buf, 1, l, &n)) r=(buf[3]<<8)|buf[2]; else p=(-1); } break; case P_ALPHA : r=-0x7F; // char specifying EOT break; case P_GBOX : r=((buf[1]&0xf)<<8) | buf[2]; serialdata->gbox_lens.cat_len = r; break; default : serialdata->dsr9500type=P_DSR_AUTO; } else switch(p) { case P_HSIC : r=(buf[2]==0x3A) ? 20 : 0; break; // 3A=DCW / FC=ECM was wrong case P_BOMBA : r=13; break; case P_DSR95 : r=14; break; case P_ALPHA : r=(buf[1]<<8)|buf[2]; break; // should be 16 always } break; case 3: // STAGE 3: get the rest ... if (r>0) // read r additional bytes { int32_t all = n+r; if( !oscam_ser_selrec(buf, r, l, &n) ) { cs_debug_mask(D_CLIENT, "not all data received, waiting another 50 ms"); serialdata->tpe.millitm+=50; if( !oscam_ser_selrec(buf, all-n, l, &n) ) p=(-1); } // auto detect DSR9500 protocol if( client->typ == 'c' && p==P_DSR95 && serialdata->dsr9500type==P_DSR_AUTO ) { serialdata->tpe.millitm+=20; if( oscam_ser_selrec(buf, 2, l, &n) ) { if( cs_atoi((char *)buf+n-2, 1, 1)==0xFFFFFFFF ) { switch( (buf[n-2]<<8)|buf[n-1] ) { case 0x0A0D : serialdata->dsr9500type=P_DSR_OPEN; break; case 0x0D0A : serialdata->dsr9500type=P_DSR_PIONEER; break; default : serialdata->dsr9500type=P_DSR_UNKNOWN; break; } }else{ if( oscam_ser_selrec(buf, 2, l, &n) ) if( cs_atoi((char *)buf+n-2, 1, 1)==0xFFFFFFFF ) serialdata->dsr9500type=P_DSR_UNKNOWN; else serialdata->dsr9500type=P_DSR_WITHSID; else { serialdata->dsr9500type=P_DSR_UNKNOWN; p=(-1); } } } else serialdata->dsr9500type=P_DSR_GNUSMAS; if( p ) cs_log("detected dsr9500-%s type receiver", dsrproto_txt[serialdata->dsr9500type]); } // gbox if( client->typ == 'c' && p==P_GBOX ) { int32_t j; for( j=0; (j<3) && (p>0); j++) switch( j ) { case 0: // PMT head if( !oscam_ser_selrec(buf, 3, l, &n) ) p=(-1); else if( !(buf[n-3]==0x02 && (buf[n-2]&0xf0)==0xb0) ) p=(-2); break; case 1: // PMT + ECM header serialdata->gbox_lens.pmt_len=((buf[n-2]&0xf)<<8)|buf[n-1]; if( !oscam_ser_selrec(buf, serialdata->gbox_lens.pmt_len+3, l, &n) ) p=(-1); break; case 2: // ECM + ECM PID serialdata->gbox_lens.ecm_len=((buf[n-2]&0xf)<<8)|buf[n-1]; if( !oscam_ser_selrec(buf, serialdata->gbox_lens.ecm_len+4, l, &n) ) p=(-1); } } // gbox } else if (r<0) // read until specified char (-r) { while((buf[n-1]!=(-r)) && (p>0)) if (!oscam_ser_selrec(buf, 1, l, &n)) p=(-1); } break; } } if (p==(-2) || p==(-1)) { oscam_ser_selrec(buf, l-n, l, &n); // flush buffer serialdata->serial_errors++; } cs_ftime(&serialdata->tpe); cs_ddump_mask(D_CLIENT, buf, n, "received %d bytes from %s in %ld msec", n, remote_txt(), 1000*(serialdata->tpe.time-serialdata->tps.time)+serialdata->tpe.millitm-serialdata->tps.millitm); client->last=serialdata->tpe.time; switch(p) { case (-1): if (client->typ == 'c'&&(n>2)&&(buf[0]==2)&&(buf[1]==2)&&(buf[2]==2)) { oscam_ser_disconnect(); cs_log("humax powered on"); // this is nice ;) } else { if(client->typ == 'c' && buf[0] == 0x1 && buf[1] == 0x08 && buf[2] == 0x20 && buf[3] == 0x08) { oscam_ser_disconnect(); cs_log("ferguson powered on"); // this is nice to ;) } else cs_log(incomplete, n); } break; case (-2): cs_debug_mask(D_CLIENT, "unknown request or garbage"); break; } xbuf[0]=(uchar) ((job<<4) | p); return((p<0)?0:n+1); }
extern cs_status vlan_cmd_proc(int argc , char **argv); sal_cmd_result_t app_cmd_proc(int argc , char **argv) { if(strcmp(argv[0],"app")) return SAL_CMD_FAIL; if(argc == 1) { app_cmd_help(); } else { if(!strcmp(argv[1], "errevt") && argc == 5) { cs_uint8 type = cs_atoi(argv[2]); cs_uint32 win = cs_atoi(argv[3]); cs_uint32 threshold = cs_atoi(argv[4]); if(CS_E_PARAM == oam_link_event_window_set(type,win*100)){ cs_printf("set failed:wrong param \n"); cs_printf(" type:1 - error symbol, win:%d - %d \n", OAM_LINK_ERROR_SYMBOL_PERIOD_WIN_MIN/100, OAM_LINK_ERROR_SYMBOL_PERIOD_WIN_MAX/100); cs_printf(" type:2 - error frame, win:%d - %d \n", OAM_LINK_ERROR_FRAME_WIN_MIN/100, OAM_LINK_ERROR_FRAME_WIN_MAX/100); cs_printf(" type:3 - error frame period, win:%d - %d \n", OAM_LINK_ERROR_PERIOD_WIN_MIN/100, OAM_LINK_ERROR_PERIOD_WIN_MAX/100); cs_printf(" type:4 - error frame summary, win:%d - %d \n", OAM_LINK_ERROR_FRAME_SECOND_SUMMERY_WIN_MIN/100, OAM_LINK_ERROR_FRAMESECOND_SUMMERY_WIN_MAX/100); return SAL_CMD_FAIL; } cs_printf("set type = %d , really win = %d success\n", type, type == OAM_EVENT_TLV_ERR_SYM_PERIOD ? win/10*OAM_LINK_ERROR_SYMBOL_PER_SECOND: type == OAM_EVENT_TLV_ERR_FRAME_PERIOD ? win *OAM_LINK_ERROR_PERIOD_PER_SECOND/10: win*100 ); oam_link_event_threshold_set(type,threshold); cs_printf("set type = %d , threshold = %d success \n", type, threshold); } #ifdef HAVE_LOOP_DETECT else if(!strcmp(argv[1], "loop")) { if(!strcmp(argv[2], "show")) loop_detect_show(); else loop_detect_test(atoi(argv[2]), atoi(argv[3]), atoi(argv[4])); } #endif #ifdef HAVE_DHCP else if(!strcmp(argv[1], "dhcp")) { if(argc == 4 && !strcmp(argv[2], "enable")) { dhcp_enable(atoi(argv[3])); } else if(argc == 4 && !strcmp(argv[2], "test")) { dhcp_test(atoi(argv[3])); } else if(argc == 3 && !strcmp(argv[2], "show")) { dhcp_show(); } } #endif #ifdef HAVE_PPPOE else if(!strcmp(argv[1], "pppoe")) { if(!strcmp(argv[2], "auth")){ /*Set auth mode, username and password*/ pppoe_auth_mode_set(atoi(argv[3]), argv[4], argv[5]); } else if(!strcmp(argv[2], "start")){ /*start test*/ pppoe_discovery_test_start(atoi(argv[3]), atoi(argv[4]));; } else if(!strcmp(argv[2], "stop")){ /*stop pppoe simulation test*/ pppoe_simulation_stop(atoi(argv[3])); } else if(!strcmp(argv[2], "rslt")){ pppoe_cmd_result_get(atoi(argv[3])); } else{ pppoe_cmd(atoi(argv[2]), atoi(argv[3]), atoi(argv[4]), atoi(argv[5])); } } #endif else if(!strcmp(argv[1], "eesim")) { //sendOAMNotification(atoi(argv[2]), 0x28, 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000); } else if(!strcmp(argv[1], "dg")) { oam_send_dying_gasp(0); } #ifdef HAVE_DB_MANAGMENT else if(!strcmp(argv[1], "db")) { if(!strcmp(argv[2], "save")){ db_save_to_flash(); } else if(!strcmp(argv[2], "reset")){ db_reset_to_factory(); }else{ app_cmd_help(); } } #endif else if(!strcmp(argv[1], "crtcevt") && argc == 3) { //postOAMCriticalEvent(atoi(argv[2])); } #ifdef HAVE_NTT_OAM else if(!strcmp(argv[1], "sysmib")) { if(!strcmp(argv[2], "des") && argc == 4) { cs_uint8 des[32]; strncpy(des, argv[3], 32); db_common_write(DB_USER_DATA_MIB_SYS_DESC_ID, des, sizeof(des)); } else if(!strcmp(argv[2], "oid") && argc > 4) { cs_uint8 oid[12]; cs_uint8 new_oid[24]; cs_uint8 i, j; cs_uint32 len; for(i = 0; i<argc-3; i++) { oid[i] = atoi(argv[3+i]); if(i == 11) break; } len = (argc-3)<12? argc-3 : 12; new_oid[0] = oid[0]*40 + oid[1]; j = 1; for(i = 2; i < len; i++) { if(oid[i]>127) { new_oid[j] = (oid[i] >> 7) | 0x80; j++; new_oid[j] = oid[i] & 0x7f; j++; } else { new_oid[j] = oid[i]; j++; } }