Changeset 4293 for trunk/module-serial.c
- Timestamp:
- 01/03/11 09:56:13 (13 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/module-serial.c
r4245 r4293 1 //FIXME Not threadsafe & running multiple instances !!!2 1 #include "globals.h" 3 2 #include <termios.h> … … 32 31 #define IS_BAD 0xFF // incoming data is unknown 33 32 34 static const char * proto_txt[]={"unknown", "hsic", "sssp", "bomba", "dsr9500", "gs",33 static const char * const proto_txt[]={"unknown", "hsic", "sssp", "bomba", "dsr9500", "gs", 35 34 "alpha", "dsr9500old", "gbox"}; 36 static const char * dsrproto_txt[]={"unknown", "samsung", "openbox", "pioneer",35 static const char * const dsrproto_txt[]={"unknown", "samsung", "openbox", "pioneer", 37 36 "extended", "unknown"}; 38 static const char *incomplete="incomplete request (%d bytes)"; 39 static int connected=0; 40 static struct timeb tps, tpe; 41 static char oscam_ser_usr[32]={0}; 42 static char oscam_ser_device[64]={0}; 43 static speed_t oscam_ser_baud=0; 44 static int oscam_ser_delay=0; 45 static int oscam_ser_timeout=50; 46 static int oscam_ser_proto=0; 47 int serial_errors=0; 48 static int dsr9500type=P_DSR_AUTO; 49 static int samsung_0a=0; // number of 0A in ALL dcw sent into samsung 50 static int samsung_dcw=0; // number of dcw sent into samsung before echo or ecm is received 37 static const char * const incomplete="incomplete request (%d bytes)"; 51 38 52 39 typedef struct s_gbox … … 64 51 } GCC_PACK SSSP_TAB; 65 52 66 67 GBOX_LENS gbox_lens; 68 SSSP_TAB sssp_tab[SSSP_MAX_PID]; 69 ushort sssp_srvid; 70 int sssp_num=0, sssp_fix=0; 53 //added to support multiple instances with thread 54 struct s_serial_client 55 { 56 int connected; 57 struct timeb tps; 58 struct timeb tpe; 59 char oscam_ser_usr[32]; 60 char oscam_ser_device[64]; 61 speed_t oscam_ser_baud; 62 int oscam_ser_delay; 63 int oscam_ser_timeout; 64 int oscam_ser_proto; 65 int serial_errors; 66 int dsr9500type; 67 int samsung_0a; // number of 0A in ALL dcw sent into samsung 68 int samsung_dcw; // number of dcw sent into samsung before echo or ecm is received 69 70 GBOX_LENS gbox_lens; 71 SSSP_TAB sssp_tab[SSSP_MAX_PID]; 72 ushort sssp_srvid; 73 int sssp_num; 74 int sssp_fix; 75 }; 76 77 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; 78 pthread_cond_t cond = PTHREAD_COND_INITIALIZER; 79 int bcopy_end = 0; 80 81 struct s_thread_param 82 { 83 int ctyp; 84 struct s_serial_client serialdata; 85 }; 86 87 static void oscam_ser_disconnect(void); 88 89 static void oscam_wait_ser_fork(void) 90 { 91 pthread_mutex_lock(&mutex); 92 do { 93 if (bcopy_end) { 94 bcopy_end = 0; 95 break; 96 } 97 else 98 pthread_cond_wait(&cond, &mutex); 99 } while (1); 100 pthread_mutex_unlock(&mutex); 101 } 71 102 72 103 static int oscam_ser_alpha_convert(uchar *buf, int l) … … 102 133 static void oscam_ser_disconnect(void); 103 134 104 static int oscam_ser_parse_url(char *url )135 static int oscam_ser_parse_url(char *url, struct s_serial_client *serialdata, char *pcltype) 105 136 { 106 137 char *service, *usr, *dev, *baud=NULL, *dummy, *para; 107 108 oscam_ser_proto=P_AUTO; 138 char cltype; 139 140 cltype = pcltype?(*pcltype):cur_client()->typ; 141 142 serialdata->oscam_ser_proto=P_AUTO; 109 143 if( (dummy=strstr(url, "://")) ) 110 144 { … … 115 149 for (i=1; i<=P_MAX; i++) 116 150 if (!strcmp(service, proto_txt[i])) 117 oscam_ser_proto=i;118 } 119 if (( !cur_client()->typ == 'c') && (oscam_ser_proto==P_AUTO)) return(0);120 switch( oscam_ser_proto) // set the defaults151 serialdata->oscam_ser_proto=i; 152 } 153 if ((cltype == 'c') && (serialdata->oscam_ser_proto==P_AUTO)) return(0); 154 switch(serialdata->oscam_ser_proto) // set the defaults 121 155 { 122 156 case P_GS: 123 oscam_ser_timeout=500;124 oscam_ser_baud=B19200;157 serialdata->oscam_ser_timeout=500; 158 serialdata->oscam_ser_baud=B19200; 125 159 break; 126 160 default: 127 oscam_ser_timeout=50;161 serialdata->oscam_ser_timeout=50; 128 162 #ifdef B115200 129 oscam_ser_baud=B115200;163 serialdata->oscam_ser_baud=B115200; 130 164 #else 131 oscam_ser_baud=B9600;165 serialdata->oscam_ser_baud=B9600; 132 166 #endif 133 167 } 134 168 135 switch( oscam_ser_proto )169 switch( serialdata->oscam_ser_proto ) 136 170 { 137 171 case P_DSR95: 138 dsr9500type=(cur_client()->typ== 'c')?P_DSR_AUTO:P_DSR_WITHSID;172 serialdata->dsr9500type=(cltype == 'c')?P_DSR_AUTO:P_DSR_WITHSID; 139 173 break; 140 174 case P_DSR95_OLD: 141 dsr9500type=P_DSR_AUTO;142 oscam_ser_proto=P_DSR95;175 serialdata->dsr9500type=P_DSR_AUTO; 176 serialdata->oscam_ser_proto=P_DSR95; 143 177 } 144 178 … … 149 183 if( (dummy=strchr(usr, ':')) ) // fake pwd 150 184 *dummy++='\0'; 151 if ((c ur_client()->typ== 'c') && (!usr[0])) return(0);185 if ((cltype == 'c') && (!usr[0])) return(0); 152 186 } 153 187 else 154 188 { 155 if (c ur_client()->typ== 'c') return(0); // user needed in server-mode189 if (cltype == 'c') return(0); // user needed in server-mode 156 190 dev=usr; 157 191 } … … 168 202 *ptr2++='\0'; 169 203 strtolower(ptr1); 170 if (!strcmp("delay" , ptr1)) oscam_ser_delay =atoi(ptr2);171 if (!strcmp("timeout", ptr1)) oscam_ser_timeout=atoi(ptr2);204 if (!strcmp("delay" , ptr1)) serialdata->oscam_ser_delay =atoi(ptr2); 205 if (!strcmp("timeout", ptr1)) serialdata->oscam_ser_timeout=atoi(ptr2); 172 206 } 173 207 } … … 177 211 #ifdef B115200 178 212 if (!strcmp(baud, "115200")) 179 oscam_ser_baud=B115200;213 serialdata->oscam_ser_baud=B115200; 180 214 else 181 215 #endif 182 216 #ifdef B57600 183 217 if (!strcmp(baud, "57600")) 184 oscam_ser_baud=B57600;218 serialdata->oscam_ser_baud=B57600; 185 219 else 186 220 #endif 187 221 if (!strcmp(baud, "38400")) 188 oscam_ser_baud=B38400;222 serialdata->oscam_ser_baud=B38400; 189 223 else if (!strcmp(baud, "19200")) 190 oscam_ser_baud=B19200;224 serialdata->oscam_ser_baud=B19200; 191 225 else if (!strcmp(baud, "9600")) 192 oscam_ser_baud=B9600;193 } 194 cs_strncpy( oscam_ser_usr, usr, sizeof(oscam_ser_usr));195 cs_strncpy( oscam_ser_device, dev, sizeof(oscam_ser_device));196 return( oscam_ser_baud);226 serialdata->oscam_ser_baud=B9600; 227 } 228 cs_strncpy(serialdata->oscam_ser_usr, usr, sizeof(serialdata->oscam_ser_usr)); 229 cs_strncpy(serialdata->oscam_ser_device, dev, sizeof(serialdata->oscam_ser_device)); 230 return(serialdata->oscam_ser_baud); 197 231 } 198 232 … … 203 237 } 204 238 205 static int oscam_ser_set_serial_device(int fd )239 static int oscam_ser_set_serial_device(int fd, speed_t baud) 206 240 { 207 241 struct termios tio; … … 218 252 cs_sleepms(500); 219 253 //#endif 220 oscam_ser_set_baud(&tio, oscam_ser_baud);254 oscam_ser_set_baud(&tio, baud); 221 255 return(tcsetattr(fd, TCSANOW, &tio)); 222 256 } 223 257 224 static int oscam_ser_poll(int event )258 static int oscam_ser_poll(int event, struct s_client *client) 225 259 { 226 260 int msec; … … 228 262 struct timeb tpc; 229 263 cs_ftime(&tpc); 230 msec=1000*( tpe.time-tpc.time)+tpe.millitm-tpc.millitm;264 msec=1000*(client->serialdata->tpe.time-tpc.time)+client->serialdata->tpe.millitm-tpc.millitm; 231 265 if (msec<0) 232 266 return(0); … … 240 274 } 241 275 242 static int oscam_ser_write(struct s_client *client, uchar *buf, int n)276 static int oscam_ser_write(struct s_client *client, const uchar * const buf, int n) 243 277 { 244 278 int i; 245 for (i=0; (i<n) && (oscam_ser_poll(POLLOUT )); i++)246 { 247 if ( oscam_ser_delay)248 cs_sleepms( oscam_ser_delay);279 for (i=0; (i<n) && (oscam_ser_poll(POLLOUT, client)); i++) 280 { 281 if (client->serialdata->oscam_ser_delay) 282 cs_sleepms(client->serialdata->oscam_ser_delay); 249 283 if (write(client->pfd, buf+i, 1)<1) 250 284 break; … … 253 287 } 254 288 255 static int oscam_ser_send(struct s_client *client, uchar *buf, int l)289 static int oscam_ser_send(struct s_client *client, const uchar * const buf, int l) 256 290 { 257 291 int n; 292 struct s_serial_client *serialdata=client->serialdata ; 258 293 if (!client->pfd) return(0); 259 cs_ftime(& tps);260 tpe=tps;261 tpe.millitm+=oscam_ser_timeout+(l*(oscam_ser_delay+1));262 tpe.time+=(tpe.millitm/1000);263 tpe.millitm%=1000;294 cs_ftime(&serialdata->tps); 295 serialdata->tpe=client->serialdata->tps; 296 serialdata->tpe.millitm+=serialdata->oscam_ser_timeout+(l*(serialdata->oscam_ser_delay+1)); 297 serialdata->tpe.time+=(serialdata->tpe.millitm/1000); 298 serialdata->tpe.millitm%=1000; 264 299 n=oscam_ser_write(client, buf, l); 265 cs_ftime(& tpe);300 cs_ftime(&serialdata->tpe); 266 301 cs_ddump_mask(D_CLIENT, buf, l, "send %d of %d bytes to %s in %d msec", n, l, remote_txt(), 267 1000*( tpe.time-tps.time)+tpe.millitm-tps.millitm);302 1000*(serialdata->tpe.time-serialdata->tps.time)+serialdata->tpe.millitm-serialdata->tps.millitm); 268 303 if (n!=l) 269 304 cs_log("transmit error. send %d of %d bytes only !", n, l); … … 277 312 n=l-*c; 278 313 if (n<=0) return(0); 279 for (i=0; (i<n) && (oscam_ser_poll(POLLIN )); i++)314 for (i=0; (i<n) && (oscam_ser_poll(POLLIN, cur_client())); i++) 280 315 if (read(cur_client()->pfd, buf+*c, 1)<1 ) 281 316 return(0); … … 292 327 static int have_lb=0; 293 328 uchar *buf=xbuf+1; 329 struct s_serial_client *serialdata=client->serialdata; 294 330 295 331 if (!client->pfd) return(-1); 296 cs_ftime(& tps);297 tpe=tps;298 tpe.millitm+=oscam_ser_timeout;299 tpe.time+=(tpe.millitm/1000);300 tpe.millitm%=1000;332 cs_ftime(&serialdata->tps); 333 serialdata->tpe=serialdata->tps; 334 serialdata->tpe.millitm+=serialdata->oscam_ser_timeout; 335 serialdata->tpe.time+=(serialdata->tpe.millitm/1000); 336 serialdata->tpe.millitm%=1000; 301 337 buf[0]=lb; 302 338 for (s=p=r=0, n=have_lb; (s<4) && (p>=0); s++) … … 327 363 { 328 364 case 0x00: if( (buf[1]==0x01)&&(buf[2]==0x00) ) 329 { p=P_GS; job=IS_LGO; tpe.time++; } break;365 { p=P_GS; job=IS_LGO; serialdata->tpe.time++; } break; 330 366 case 0x01: if( (buf[1]&0xf0)==0xb0 ) p=P_GBOX; 331 367 else {p=P_SSSP; job=IS_PMT;} 332 368 break; // pmt-request 333 369 case 0x02: p=P_HSIC; break; 334 case 0x03: switch( oscam_ser_proto)370 case 0x03: switch(serialdata->oscam_ser_proto) 335 371 { 336 372 case P_SSSP : 337 373 case P_GS : 338 case P_DSR95 : p= oscam_ser_proto; break;374 case P_DSR95 : p=serialdata->oscam_ser_proto; break; 339 375 case P_AUTO : p=(buf[1]<0x30) ? P_SSSP : P_DSR95; 340 376 break; // auto for GS is useless !! 341 377 } break; 342 case 0x04: p=P_DSR95; job=IS_ECHO; dsr9500type=P_DSR_GNUSMAS; break;378 case 0x04: p=P_DSR95; job=IS_ECHO; serialdata->dsr9500type=P_DSR_GNUSMAS; break; 343 379 case 0x7E: p=P_ALPHA; if (buf[1]!=0x80) job=IS_BAD; break; 344 380 case 0x80: … … 349 385 { 350 386 job=IS_DCW; // assume DCW 351 switch( oscam_ser_proto)387 switch(serialdata->oscam_ser_proto) 352 388 { 353 389 case P_HSIC : if ((buf[0]==4) && (buf[1]==4)) p=P_HSIC; break; … … 357 393 } 358 394 } 359 if (( oscam_ser_proto!=p) && (oscam_ser_proto!=P_AUTO))395 if ((serialdata->oscam_ser_proto!=p) && (serialdata->oscam_ser_proto!=P_AUTO)) 360 396 p=(-2); 361 397 } … … 371 407 case P_DSR95 : if( job==IS_ECHO ) 372 408 { 373 r=17*s amsung_dcw-3+samsung_0a;374 s amsung_dcw=samsung_0a=0;409 r=17*serialdata->samsung_dcw-3+serialdata->samsung_0a; 410 serialdata->samsung_dcw=serialdata->samsung_0a=0; 375 411 } 376 else 412 else 377 413 { 378 414 if (oscam_ser_selrec(buf, 16, l, &n)) … … 383 419 else { 384 420 r=(b<<1); 385 r+=( dsr9500type==P_DSR_WITHSID)?4:0;421 r+=(serialdata->dsr9500type==P_DSR_WITHSID)?4:0; 386 422 } 387 423 } … … 401 437 break; 402 438 case P_GBOX : r=((buf[1]&0xf)<<8) | buf[2]; 403 gbox_lens.cat_len = r;439 serialdata->gbox_lens.cat_len = r; 404 440 break; 405 default : dsr9500type=P_DSR_AUTO;441 default : serialdata->dsr9500type=P_DSR_AUTO; 406 442 } 407 443 else switch(p) … … 420 456 { 421 457 cs_debug_mask(D_CLIENT, "not all data received, waiting another 50 ms"); 422 tpe.millitm+=50;458 serialdata->tpe.millitm+=50; 423 459 if( !oscam_ser_selrec(buf, all-n, l, &n) ) 424 460 p=(-1); 425 461 } 426 462 // auto detect DSR9500 protocol 427 if( client->typ == 'c' && p==P_DSR95 && dsr9500type==P_DSR_AUTO )463 if( client->typ == 'c' && p==P_DSR95 && serialdata->dsr9500type==P_DSR_AUTO ) 428 464 { 429 tpe.millitm+=20;465 serialdata->tpe.millitm+=20; 430 466 if( oscam_ser_selrec(buf, 2, l, &n) ) 431 467 { … … 434 470 switch( (buf[n-2]<<8)|buf[n-1] ) 435 471 { 436 case 0x0A0D : dsr9500type=P_DSR_OPEN; break;437 case 0x0D0A : dsr9500type=P_DSR_PIONEER; break;438 default : dsr9500type=P_DSR_UNKNOWN; break;472 case 0x0A0D : serialdata->dsr9500type=P_DSR_OPEN; break; 473 case 0x0D0A : serialdata->dsr9500type=P_DSR_PIONEER; break; 474 default : serialdata->dsr9500type=P_DSR_UNKNOWN; break; 439 475 } 440 476 }else{ 441 477 if( oscam_ser_selrec(buf, 2, l, &n) ) 442 478 if( cs_atoi((char *)buf+n-2, 1, 1)==0xFFFFFFFF ) 443 dsr9500type=P_DSR_UNKNOWN;479 serialdata->dsr9500type=P_DSR_UNKNOWN; 444 480 else 445 dsr9500type=P_DSR_WITHSID;481 serialdata->dsr9500type=P_DSR_WITHSID; 446 482 else { 447 dsr9500type=P_DSR_UNKNOWN;483 serialdata->dsr9500type=P_DSR_UNKNOWN; 448 484 p=(-1); 449 485 } … … 451 487 } 452 488 else 453 dsr9500type=P_DSR_GNUSMAS;489 serialdata->dsr9500type=P_DSR_GNUSMAS; 454 490 if( p ) 455 491 cs_log("detected dsr9500-%s type receiver", 456 dsrproto_txt[ dsr9500type]);492 dsrproto_txt[serialdata->dsr9500type]); 457 493 } 458 494 // gbox … … 470 506 break; 471 507 case 1: // PMT + ECM header 472 gbox_lens.pmt_len=((buf[n-2]&0xf)<<8)|buf[n-1];473 if( !oscam_ser_selrec(buf, gbox_lens.pmt_len+3, l, &n) )508 serialdata->gbox_lens.pmt_len=((buf[n-2]&0xf)<<8)|buf[n-1]; 509 if( !oscam_ser_selrec(buf, serialdata->gbox_lens.pmt_len+3, l, &n) ) 474 510 p=(-1); 475 511 break; 476 512 case 2: // ECM + ECM PID 477 gbox_lens.ecm_len=((buf[n-2]&0xf)<<8)|buf[n-1];478 if( !oscam_ser_selrec(buf, gbox_lens.ecm_len+4, l, &n) )513 serialdata->gbox_lens.ecm_len=((buf[n-2]&0xf)<<8)|buf[n-1]; 514 if( !oscam_ser_selrec(buf, serialdata->gbox_lens.ecm_len+4, l, &n) ) 479 515 p=(-1); 480 516 } 481 517 } // gbox 482 } 518 } 483 519 else if (r<0) // read until specified char (-r) 484 520 { … … 492 528 if (p==(-2) || p==(-1)) { 493 529 oscam_ser_selrec(buf, l-n, l, &n); // flush buffer 494 serial _errors++;495 } 496 cs_ftime(& tpe);530 serialdata->serial_errors++; 531 } 532 cs_ftime(&serialdata->tpe); 497 533 cs_ddump_mask(D_CLIENT, buf, n, "received %d bytes from %s in %d msec", n, remote_txt(), 498 1000*( tpe.time-tps.time)+tpe.millitm-tps.millitm);499 client->last= tpe.time;534 1000*(serialdata->tpe.time-serialdata->tps.time)+serialdata->tpe.millitm-serialdata->tps.millitm); 535 client->last=serialdata->tpe.time; 500 536 switch(p) 501 537 { … … 508 544 cs_log(incomplete, n); 509 545 break; 510 case (-2): cs_debug_mask(D_CLIENT, "unknown request or garbage"); 546 case (-2): cs_debug_mask(D_CLIENT, "unknown request or garbage"); 511 547 break; 512 548 } … … 522 558 { 523 559 uchar mbuf[1024]; 524 switch(connected ? connected : oscam_ser_proto) 560 struct s_serial_client *serialdata=cur_client()->serialdata; 561 switch(serialdata->connected ? serialdata->connected : serialdata->oscam_ser_proto) 525 562 { 526 563 case P_GS: … … 532 569 break; 533 570 } 534 dsr9500type=P_DSR_AUTO;535 serial _errors=0;571 serialdata->dsr9500type=P_DSR_AUTO; 572 serialdata->serial_errors=0; 536 573 } 537 574 538 575 static void oscam_ser_init_client() 539 576 { 540 uchar mbuf[ 1024];541 switch( oscam_ser_proto) // sure, does not work in auto-mode577 uchar mbuf[4]; 578 switch(cur_client()->serialdata->oscam_ser_proto) // sure, does not work in auto-mode 542 579 { 543 580 case P_GS: … … 556 593 { 557 594 oscam_ser_disconnect_client(); 558 if (c onnected)559 cs_log("%s disconnected (%s)", username(cur_client()), proto_txt[c onnected]);560 c onnected=0;595 if (cur_client()->serialdata->connected) 596 cs_log("%s disconnected (%s)", username(cur_client()), proto_txt[cur_client()->serialdata->connected]); 597 cur_client()->serialdata->connected=0; 561 598 } 562 599 … … 564 601 { 565 602 int ok = 0; 603 struct s_serial_client *serialdata=cur_client()->serialdata; 566 604 // After reload base account ptrs may be placed in other address, 567 // and we may can't find it in this process. 605 // and we may can't find it in this process. 568 606 // Simply save valid account. 569 struct s_auth *account=0; 570 571 if ( connected==proto)607 struct s_auth *account=0; 608 609 if (serialdata->connected==proto) 572 610 return; 573 if ( connected)611 if (serialdata->connected) 574 612 oscam_ser_disconnect(); 575 connected=proto;613 serialdata->connected=proto; 576 614 if( !account ) 577 615 { 578 616 cur_client()->account=NULL; 579 617 for (ok=0, account=cfg->account; (account) && (!ok); account=account->next) 580 if( (ok=!strcmp( oscam_ser_usr, account->usr)) )618 if( (ok=!strcmp(serialdata->oscam_ser_usr, account->usr)) ) 581 619 break; 582 620 } 583 cs_auth_client(cur_client(), ok ? account : (struct s_auth *)(-1), proto_txt[ connected]);621 cs_auth_client(cur_client(), ok ? account : (struct s_auth *)(-1), proto_txt[serialdata->connected]); 584 622 } 585 623 586 624 static void oscam_ser_send_dcw(struct s_client *client, ECM_REQUEST *er) 587 625 { 588 uchar mbuf[ 1024];626 uchar mbuf[23]; 589 627 int i; 590 628 uchar crc; 629 struct s_serial_client *serialdata=cur_client()->serialdata; 591 630 if (er->rc<4) // found 592 switch( connected)631 switch(serialdata->connected) 593 632 { 594 633 case P_HSIC: … … 608 647 memcpy(mbuf+3, er->cw, 16); 609 648 oscam_ser_send(client, mbuf, 19); 610 if (!s ssp_fix)649 if (!serialdata->sssp_fix) 611 650 { 612 651 mbuf[0]=0xF1; … … 615 654 memcpy(mbuf+3, i2b(2, er->pid), 2); 616 655 oscam_ser_send(client, mbuf, 5); 617 s ssp_fix=1;656 serialdata->sssp_fix=1; 618 657 } 619 658 break; … … 626 665 memcpy(mbuf+1, er->cw, 16); 627 666 oscam_ser_send(client, mbuf, 17); 628 if( dsr9500type==P_DSR_GNUSMAS )667 if( serialdata->dsr9500type==P_DSR_GNUSMAS ) 629 668 { 630 669 int i; 631 s amsung_0a=0;670 serialdata->samsung_0a=0; 632 671 for( i=1; i<17; i++ ) 633 672 if( mbuf[i]==0x0A ) 634 s amsung_0a++;635 s amsung_dcw++;673 serialdata->samsung_0a++; 674 serialdata->samsung_dcw++; 636 675 } 637 676 break; … … 651 690 oscam_ser_send(client, mbuf, 19); 652 691 break; 653 } 692 } 654 693 else // not found 655 switch( connected)694 switch(serialdata->connected) 656 695 { 657 696 case P_GS: … … 663 702 break; 664 703 } 665 serial _errors=0; // clear error counter704 serialdata->serial_errors=0; // clear error counter 666 705 } 667 706 … … 670 709 int i; 671 710 uchar sbuf[32]; 672 673 switch( connected)711 struct s_serial_client *serialdata=cur_client()->serialdata; 712 switch(serialdata->connected) 674 713 { 675 714 case P_SSSP: 676 s ssp_fix=0;677 memset(s ssp_tab, 0, sizeof(sssp_tab));678 s ssp_srvid=b2i(2, buf+3);679 for (i=9, s ssp_num=0; (i<l) && (sssp_num<SSSP_MAX_PID); i+=7,sssp_num++)680 { 681 memcpy(sbuf+3+(s ssp_num<<1), buf+i+2, 2);682 s ssp_tab[sssp_num].caid=b2i(2, buf+i );683 s ssp_tab[sssp_num].pid =b2i(2, buf+i+2);684 s ssp_tab[sssp_num].prid=b2i(3, buf+i+4);715 serialdata->sssp_fix=0; 716 memset(serialdata->sssp_tab, 0, sizeof(serialdata->sssp_tab)); 717 serialdata->sssp_srvid=b2i(2, buf+3); 718 for (i=9, serialdata->sssp_num=0; (i<l) && (serialdata->sssp_num<SSSP_MAX_PID); i+=7, serialdata->sssp_num++) 719 { 720 memcpy(sbuf+3+(serialdata->sssp_num<<1), buf+i+2, 2); 721 serialdata->sssp_tab[serialdata->sssp_num].caid=b2i(2, buf+i ); 722 serialdata->sssp_tab[serialdata->sssp_num].pid =b2i(2, buf+i+2); 723 serialdata->sssp_tab[serialdata->sssp_num].prid=b2i(3, buf+i+4); 685 724 } 686 725 sbuf[0]=0xF1; 687 726 sbuf[1]=0; 688 sbuf[2]=(s ssp_num<<1);727 sbuf[2]=(serialdata->sssp_num<<1); 689 728 oscam_ser_send(cur_client(), sbuf, sbuf[2]+3); 690 729 break; … … 695 734 { 696 735 uchar gs_logon[]={0, 1, 0, 0, 2, 1, 0, 0}; 697 switch(c onnected)736 switch(cur_client()->serialdata->connected) 698 737 { 699 738 case P_GS: … … 713 752 { 714 753 int i; 754 struct s_serial_client *serialdata = cur_client()->serialdata; 715 755 716 756 if (l<16) … … 720 760 } 721 761 722 switch( connected)762 switch(serialdata->connected) 723 763 { 724 764 case P_HSIC: … … 732 772 case P_SSSP: 733 773 er->pid=b2i(2, buf+3); 734 for (i=0; (i<8) && (s ssp_tab[i].pid!=er->pid); i++);735 if (i>=s ssp_num)774 for (i=0; (i<8) && (serialdata->sssp_tab[i].pid!=er->pid); i++); 775 if (i>=serialdata->sssp_num) 736 776 { 737 777 cs_debug_mask(D_CLIENT, "illegal request, unknown pid=%04X", er->pid); … … 739 779 } 740 780 er->l = l-5; 741 er->srvid= s ssp_srvid;742 er->caid = s ssp_tab[i].caid;743 er->prid = s ssp_tab[i].prid;781 er->srvid= serialdata->sssp_srvid; 782 er->caid = serialdata->sssp_tab[i].caid; 783 er->prid = serialdata->sssp_tab[i].prid; 744 784 memcpy(er->ecm, buf+5, er->l); 745 785 break; … … 759 799 return(1); 760 800 } 761 if( dsr9500type==P_DSR_WITHSID )801 if( serialdata->dsr9500type==P_DSR_WITHSID ) 762 802 { 763 803 er->l-=2; … … 785 825 break; 786 826 case P_GBOX: 787 er->srvid = b2i(2, buf+ gbox_lens.cat_len+3+3);788 er->l = gbox_lens.ecm_len+3;789 memcpy(er->ecm, buf+ gbox_lens.cat_len+3+gbox_lens.pmt_len+3, er->l);827 er->srvid = b2i(2, buf+serialdata->gbox_lens.cat_len+3+3); 828 er->l = serialdata->gbox_lens.ecm_len+3; 829 memcpy(er->ecm, buf+serialdata->gbox_lens.cat_len+3+serialdata->gbox_lens.pmt_len+3, er->l); 790 830 break; 791 831 } … … 813 853 int n; 814 854 uchar mbuf[1024]; 815 816 connected=0; 855 856 int * pserial_errors = &cur_client()->serialdata->serial_errors; 857 858 cur_client()->serialdata->connected=0; 817 859 oscam_ser_init_client(); 818 860 819 861 while ((n=process_input(mbuf, sizeof(mbuf), cfg->cmaxidle))>=0) 820 862 { 821 if ( serial_errors> 3)863 if ((*pserial_errors) > 3) 822 864 { 823 865 cs_log("too many errors, reiniting..."); … … 844 886 } 845 887 846 static int init_oscam_ser_device(char *device )888 static int init_oscam_ser_device(char *device, speed_t baud) 847 889 { 848 890 int fd; … … 852 894 { 853 895 fcntl(fd, F_SETFL, 0); 854 if (oscam_ser_set_serial_device(fd )<0) cs_log("ERROR ioctl");896 if (oscam_ser_set_serial_device(fd, baud)<0) cs_log("ERROR ioctl"); 855 897 if (tcflush(fd, TCIOFLUSH)<0) cs_log("ERROR flush"); 856 898 } … … 863 905 } 864 906 865 static void * oscam_ser_fork(void *url2) 866 { 867 //static char logtxt[32]; 868 char *url = (char *) url2; 869 struct s_client *cl=cs_fork(0); 870 pthread_setspecific(getclient, cl); 871 cl->thread=pthread_self(); 872 cl->typ='c'; 873 //FIXME this can be made simpler: 874 int i; 875 for (i=0; i<CS_MAX_MOD; i++) 876 if (ph[i].type & MOD_CONN_SERIAL) // for look for oscam_ser 877 cl->ctyp=i; 878 879 //cl->ctyp=ctyp; //FIXME this param should be passed to thread... 880 881 if ((!url) || (!url[0])) return NULL; 882 if (!oscam_ser_parse_url(url)) return NULL; 883 // snprintf(logtxt, sizeof(logtxt)-1, ", %s@%s", 884 // oscam_ser_proto>P_MAX ? "auto" : proto_txt[oscam_ser_proto], oscam_ser_device); 885 // ph[idx].logtxt=logtxt; 907 static void oscam_copy_serialdata(struct s_serial_client *dest, struct s_serial_client *src) 908 { 909 if( dest && src ) 910 { 911 dest->connected = src->connected; 912 memcpy(&dest->tps, &src->tps, sizeof(dest->tps)); 913 memcpy(&dest->tpe, &src->tpe, sizeof(dest->tpe)); 914 memcpy(&dest->oscam_ser_usr, &src->oscam_ser_usr, sizeof(dest->oscam_ser_usr)); 915 memcpy(&dest->oscam_ser_device, &src->oscam_ser_device, sizeof(dest->oscam_ser_device)); 916 dest->oscam_ser_baud = src->oscam_ser_baud; 917 dest->oscam_ser_delay = src->oscam_ser_delay; 918 dest->oscam_ser_timeout = src->oscam_ser_timeout; 919 dest->oscam_ser_proto = src->oscam_ser_proto; 920 dest->serial_errors = src->serial_errors; 921 dest->dsr9500type = src->dsr9500type; 922 dest->samsung_0a = src->samsung_0a; // number of 0A in ALL dcw sent into samsung 923 dest->samsung_dcw = src->samsung_dcw; // number of dcw sent into samsung before echo or ecm is received 924 925 dest->gbox_lens = src->gbox_lens; 926 memcpy(&dest->sssp_tab, &src->sssp_tab, sizeof(dest->sssp_tab)); 927 dest->sssp_srvid = src->sssp_srvid; 928 dest->sssp_num = src->sssp_num; 929 dest->sssp_fix = src->sssp_fix; 930 } 931 } 932 933 static void oscam_init_serialdata(struct s_serial_client *dest) 934 { 935 if(dest) 936 { 937 memset(dest, 0, sizeof(struct s_serial_client)); 938 dest->oscam_ser_timeout = 50; 939 dest->dsr9500type=P_DSR_AUTO; 940 } 941 } 942 943 static void * oscam_ser_fork(void *pthreadparam) 944 { 945 struct s_thread_param *pparam = (struct s_thread_param *) pthreadparam; 946 struct s_client *cl=cs_fork(0); 947 pthread_setspecific(getclient, cl); 948 cl->thread=pthread_self(); 949 cl->typ='c'; 950 cl->ctyp = pparam->ctyp; 951 952 if(!cl->serialdata) 953 cl->serialdata = malloc(sizeof(struct s_serial_client)); 954 oscam_init_serialdata(cl->serialdata); 955 oscam_copy_serialdata(cl->serialdata, &pparam->serialdata); 956 pthread_mutex_lock(&mutex); 957 bcopy_end = 1; 958 pthread_mutex_unlock(&mutex); 959 pthread_cond_signal(&cond); 886 960 887 961 while(1) 888 962 { 889 c ur_client()->aureader=NULL;890 c ur_client()->account=NULL;891 c ur_client()->login=time((time_t *)0);892 c ur_client()->pfd=init_oscam_ser_device(oscam_ser_device);893 if (c ur_client()->pfd)963 cl->aureader=NULL; 964 cl->account=NULL; 965 cl->login=time((time_t *)0); 966 cl->pfd=init_oscam_ser_device(cl->serialdata->oscam_ser_device, cl->serialdata->oscam_ser_baud); 967 if (cl->pfd) 894 968 oscam_ser_server(); 895 969 else 896 970 cs_sleepms(60000); // retry in 1 min. (USB-Device ?) 897 if (cur_client()->pfd) close(cur_client()->pfd); 898 } 971 if (cl->pfd) close(cl->pfd); 972 } 973 NULLFREE(cl->serialdata); 899 974 return NULL; 900 975 } … … 903 978 { 904 979 char sdevice[512]; 980 struct s_thread_param param; 981 oscam_init_serialdata(¶m.serialdata); 905 982 cs_strncpy(sdevice, cfg->ser_device, sizeof(sdevice)); 906 ctyp=ctyp; //suppress compiler warning 907 //TODO: untested (threaded) 983 param.ctyp=ctyp; 908 984 char *p; 909 985 pthread_t temp; 986 char cltype = '\0'; //now auto should work 910 987 while( (p=strrchr(sdevice, 1)) ) 911 988 { 912 989 *p = 0; 913 if ((!p + 1) || (!(p + 1)[0])) return NULL; 914 if (!oscam_ser_parse_url(p + 1)) return NULL; 915 pthread_create(&temp, NULL, oscam_ser_fork, (void *) p + 1); //FIXME value of p does not survive thread 990 if (!(p + 1) || (!(p + 1)[0])) return NULL; 991 if (!oscam_ser_parse_url(p + 1, ¶m.serialdata, &cltype)) return NULL; 992 pthread_create(&temp, NULL, oscam_ser_fork, (void *) ¶m); 993 oscam_wait_ser_fork(); 916 994 pthread_detach(temp); 917 995 } 918 996 919 997 if (!sdevice[0]) return NULL; 920 if (!oscam_ser_parse_url(sdevice)) return NULL; 921 pthread_create(&temp, NULL, oscam_ser_fork, (void *) sdevice);//FIXME value of sdevice does not survive thread 998 if (!oscam_ser_parse_url(sdevice, ¶m.serialdata, &cltype)) return NULL; 999 pthread_create(&temp, NULL, oscam_ser_fork, (void *) ¶m); 1000 oscam_wait_ser_fork(); 922 1001 pthread_detach(temp); 923 1002 return NULL; … … 930 1009 static int oscam_ser_client_init(struct s_client *client) 931 1010 { 1011 if(!client->serialdata) 1012 client->serialdata = malloc(sizeof(struct s_serial_client)); 1013 oscam_init_serialdata(client->serialdata); 1014 932 1015 if ((!client->reader->device[0])) cs_exit(1); 933 if (!oscam_ser_parse_url(client->reader->device )) cs_exit(1);934 client->pfd=init_oscam_ser_device( oscam_ser_device);1016 if (!oscam_ser_parse_url(client->reader->device, client->serialdata, NULL)) cs_exit(1); 1017 client->pfd=init_oscam_ser_device(client->serialdata->oscam_ser_device, client->serialdata->oscam_ser_baud); 935 1018 return((client->pfd>0) ? 0 : 1); 936 1019 } … … 938 1021 static int oscam_ser_send_ecm(struct s_client *client, ECM_REQUEST *er, uchar *buf) 939 1022 { 940 switch( oscam_ser_proto)1023 switch(client->serialdata->oscam_ser_proto) 941 1024 { 942 1025 case P_HSIC: … … 954 1037 break; 955 1038 case P_DSR95: 956 if( dsr9500type==P_DSR_WITHSID )1039 if( client->serialdata->dsr9500type==P_DSR_WITHSID ) 957 1040 { 958 1041 sprintf((char *)buf, "%c%08lX%04X%s%04X\n\r", … … 978 1061 } 979 1062 980 static void oscam_ser_process_dcw(uchar *dcw, int *rc, uchar *buf, int l )981 { 982 switch( oscam_ser_proto)1063 static void oscam_ser_process_dcw(uchar *dcw, int *rc, uchar *buf, int l, struct s_client *client) 1064 { 1065 switch(client->serialdata->oscam_ser_proto) 983 1066 { 984 1067 case P_HSIC: … … 1022 1105 static int oscam_ser_recv_chk(struct s_client *client, uchar *dcw, int *rc, uchar *buf, int n) 1023 1106 { 1024 *client = *client; //prevent compiler message1025 1107 *rc=(-1); 1026 1108 switch (buf[0]>>4) 1027 1109 { 1028 1110 case IS_DCW: 1029 oscam_ser_process_dcw(dcw, rc, buf+1, n-1 );1111 oscam_ser_process_dcw(dcw, rc, buf+1, n-1, client); 1030 1112 break; 1031 1113 }
Note:
See TracChangeset
for help on using the changeset viewer.