7 #define P_HSIC 1 // Humax Sharing Interface Client
8 #define P_SSSP 2 // Simple Serial Sharing Protocol
9 #define P_BOMBA 3 // This is not really a Protocol
10 #define P_DSR95 4 // DSR9500 with SID
11 #define P_GS 5 // GS7001
12 #define P_ALPHA 6 // AlphaStar Receivers
13 #define P_DSR95_OLD 7 // DSR9500 without SID
14 #define P_GBOX 8 // Arion with gbox
19 #define P_DSR_GNUSMAS 1
21 #define P_DSR_PIONEER 3
22 #define P_DSR_WITHSID 4
23 #define P_DSR_UNKNOWN 5
25 #define IS_ECM 0 // incoming data is ECM
26 #define IS_DCW 1 // incoming data is DCW
27 #define IS_PMT 2 // incoming data is PMT
28 #define IS_LGO 3 // incoming data is client logon
29 #define IS_ECHO 4 // incoming data is DCW echo from Samsung
30 #define IS_CAT 5 // incoming data is CAT
31 #define IS_BAD 0xFF // incoming data is unknown
33 static char *proto_txt
[]={"unknown", "hsic", "sssp", "bomba", "dsr9500", "gs",
34 "alpha", "dsr9500old", "gbox"};
35 static char *dsrproto_txt
[]={"unknown", "samsung", "openbox", "pioneer",
36 "extended", "unknown"};
37 static char *incomplete
="incomplete request (%d bytes)";
38 static int connected
=0;
39 static struct timeb tps
, tpe
;
40 static char oscam_ser_usr
[32]={0};
41 static char oscam_ser_device
[64]={0};
42 static speed_t oscam_ser_baud
=0;
43 static int oscam_ser_delay
=0;
44 static int oscam_ser_timeout
=50;
45 static int oscam_ser_proto
=0;
47 static int dsr9500type
=P_DSR_AUTO
;
48 static int samsung_0a
=0; // number of 0A in ALL dcw sent into samsung
49 static int samsung_dcw
=0; // number of dcw sent into samsung before echo or ecm is received
67 SSSP_TAB sssp_tab
[SSSP_MAX_PID
];
69 int sssp_num
=0, sssp_fix
=0;
71 static int oscam_ser_alpha_convert(uchar
*buf
, int l
)
74 if (buf
[0]==0x7E) // normalize
77 memmove(buf
, buf
+1, l
); // remove BOT/EOT
81 memmove(buf
+i
, buf
+i
+1, --l
);
87 memmove(buf
+1, buf
, l
++); // insert BOT
90 if ((buf
[i
]==0x20) || (buf
[i
]==0x7E) || (buf
[i
]==0x7F))
93 memmove(buf
+i
+1, buf
+i
, l
++);
96 buf
[l
++]=0x7F; // insert EOT
101 static void oscam_ser_disconnect(void);
103 static int oscam_ser_parse_url(char *url
)
105 char *service
, *usr
, *dev
, *baud
=NULL
, *dummy
, *para
;
107 oscam_ser_proto
=P_AUTO
;
108 if( (dummy
=strstr(url
, "://")) )
114 for (i
=1; i
<=P_MAX
; i
++)
115 if (!strcmp(service
, proto_txt
[i
]))
118 if ((!is_server
) && (oscam_ser_proto
==P_AUTO
)) return(0);
119 switch(oscam_ser_proto
) // set the defaults
122 oscam_ser_timeout
=500;
123 oscam_ser_baud
=B19200
;
126 oscam_ser_timeout
=50;
128 oscam_ser_baud
=B115200
;
130 oscam_ser_baud
=B9600
;
134 switch( oscam_ser_proto
)
137 dsr9500type
=(is_server
)?P_DSR_AUTO
:P_DSR_WITHSID
;
140 dsr9500type
=P_DSR_AUTO
;
141 oscam_ser_proto
=P_DSR95
;
145 if( (dev
=strchr(usr
, '@')) )
148 if( (dummy
=strchr(usr
, ':')) ) // fake pwd
150 if ((is_server
) && (!usr
[0])) return(0);
154 if (is_server
) return(0); // user needed in server-mode
157 if( (baud
=strchr(dev
, ':')) )// port = baud
159 dummy
=baud
? baud
: dev
;
160 if( (para
=strchr(dummy
, '?')) )
164 for (ptr1
=strtok(para
, "&"); ptr1
; ptr1
=strtok(NULL
, "&"))
166 if (!(ptr2
=strchr(ptr1
, '='))) continue;
169 if (!strcmp("delay" , ptr1
)) oscam_ser_delay
=atoi(ptr2
);
170 if (!strcmp("timeout", ptr1
)) oscam_ser_timeout
=atoi(ptr2
);
177 if (!strcmp(baud
, "115200"))
178 oscam_ser_baud
=B115200
;
182 if (!strcmp(baud
, "57600"))
183 oscam_ser_baud
=B57600
;
186 if (!strcmp(baud
, "38400"))
187 oscam_ser_baud
=B38400
;
188 else if (!strcmp(baud
, "19200"))
189 oscam_ser_baud
=B19200
;
190 else if (!strcmp(baud
, "9600"))
191 oscam_ser_baud
=B9600
;
193 strncpy(oscam_ser_usr
, usr
, sizeof(oscam_ser_usr
)-1);
194 strncpy(oscam_ser_device
, dev
, sizeof(oscam_ser_device
)-1);
195 return(oscam_ser_baud
);
198 static void oscam_ser_set_baud(struct termios
*tio
, speed_t baud
)
200 cfsetospeed(tio
, baud
);
201 cfsetispeed(tio
, baud
);
204 static int oscam_ser_set_serial_device(int fd
)
208 memset(&tio
, 0, sizeof(tio
));
209 // tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
210 tio
.c_cflag
= (CS8
| CREAD
| CLOCAL
);
211 tio
.c_iflag
= IGNPAR
;
214 //#if !defined(OS_CYGWIN32)
215 oscam_ser_set_baud(&tio
, B1200
);
216 tcsetattr(fd
, TCSANOW
, &tio
);
219 oscam_ser_set_baud(&tio
, oscam_ser_baud
);
220 return(tcsetattr(fd
, TCSANOW
, &tio
));
223 static int oscam_ser_poll(int event
)
229 msec
=1000*(tpe
.time
-tpc
.time
)+tpe
.millitm
-tpc
.millitm
;
235 if (poll(&pfds
, 1, msec
)!=1)
238 return(((pfds
.revents
)&event
)==event
);
241 static int oscam_ser_write(uchar
*buf
, int n
)
244 for (i
=0; (i
<n
) && (oscam_ser_poll(POLLOUT
)); i
++)
247 cs_sleepms(oscam_ser_delay
);
248 if (write(pfd
, buf
+i
, 1)<1)
254 static int oscam_ser_send(uchar
*buf
, int l
)
260 tpe
.millitm
+=oscam_ser_timeout
+(l
*(oscam_ser_delay
+1));
261 tpe
.time
+=(tpe
.millitm
/1000);
263 n
=oscam_ser_write(buf
, l
);
265 cs_ddump(buf
, l
, "send %d of %d bytes to %s in %d msec", n
, l
, remote_txt(),
266 1000*(tpe
.time
-tps
.time
)+tpe
.millitm
-tps
.millitm
);
268 cs_log("transmit error. send %d of %d bytes only !", n
, l
);
272 static int oscam_ser_selrec(uchar
*buf
, int n
, int l
, int *c
)
278 for (i
=0; (i
<n
) && (oscam_ser_poll(POLLIN
)); i
++)
279 if (read(pfd
, buf
+*c
, 1)<1 )
286 static int oscam_ser_recv(uchar
*xbuf
, int l
)
291 static int have_lb
=0;
294 if (!pfd
) return(-1);
297 tpe
.millitm
+=oscam_ser_timeout
;
298 tpe
.time
+=(tpe
.millitm
/1000);
301 for (s
=p
=r
=0, n
=have_lb
; (s
<4) && (p
>=0); s
++)
305 case 0: // STAGE 0: skip known garbage from DSR9500
306 if (oscam_ser_selrec(buf
, 2-n
, l
, &n
))
308 if ((buf
[0]==0x0A) && (buf
[1]==0x0D))
310 if ((buf
[0]==0x0D) && (buf
[1]==0x0A))
317 case 1: // STAGE 1: identify protocol
319 if (oscam_ser_selrec(buf
, 1, l
, &n
)) // now we have 3 bytes in buf
322 if (is_server
) // HERE IS SERVER
324 job
=IS_ECM
; // assume ECM
327 case 0x00: if( (buf
[1]==0x01)&&(buf
[2]==0x00) )
328 { p
=P_GS
; job
=IS_LGO
; tpe
.time
++; } break;
329 case 0x01: if( (buf
[1]&0xf0)==0xb0 ) p
=P_GBOX
;
330 else {p
=P_SSSP
; job
=IS_PMT
;}
331 break; // pmt-request
332 case 0x02: p
=P_HSIC
; break;
333 case 0x03: switch(oscam_ser_proto
)
337 case P_DSR95
: p
=oscam_ser_proto
; break;
338 case P_AUTO
: p
=(buf
[1]<0x30) ? P_SSSP
: P_DSR95
;
339 break; // auto for GS is useless !!
341 case 0x04: p
=P_DSR95
; job
=IS_ECHO
; dsr9500type
=P_DSR_GNUSMAS
; break;
342 case 0x7E: p
=P_ALPHA
; if (buf
[1]!=0x80) job
=IS_BAD
; break;
344 case 0x81: p
=P_BOMBA
; break;
347 else // HERE IS CLIENT
349 job
=IS_DCW
; // assume DCW
350 switch(oscam_ser_proto
)
352 case P_HSIC
: if ((buf
[0]==4) && (buf
[1]==4)) p
=P_HSIC
; break;
353 case P_BOMBA
: p
=P_BOMBA
; break;
354 case P_DSR95
: if (buf
[0]==4) p
=P_DSR95
; break;
355 case P_ALPHA
: if (buf
[0]==0x88) p
=P_ALPHA
; break;
358 if ((oscam_ser_proto
!=p
) && (oscam_ser_proto
!=P_AUTO
))
362 case 2: // STAGE 2: examine length
363 if (is_server
) switch(p
)
365 case P_SSSP
: r
=(buf
[1]<<8)|buf
[2]; break;
366 case P_BOMBA
: r
=buf
[2]; break;
367 case P_HSIC
: if (oscam_ser_selrec(buf
, 12, l
, &n
)) r
=buf
[14];
370 case P_DSR95
: if( job
==IS_ECHO
)
372 r
=17*samsung_dcw
-3+samsung_0a
;
373 samsung_dcw
=samsung_0a
=0;
377 if (oscam_ser_selrec(buf
, 16, l
, &n
))
380 if (cs_atob(&b
, buf
+17, 1)<0)
384 r
+=(dsr9500type
==P_DSR_WITHSID
)?4:0;
390 case P_GS
: if (job
==IS_LGO
)
394 if (oscam_ser_selrec(buf
, 1, l
, &n
))
395 r
=(buf
[3]<<8)|buf
[2];
399 case P_ALPHA
: r
=-0x7F; // char specifying EOT
401 case P_GBOX
: r
=((buf
[1]&0xf)<<8) | buf
[2];
402 gbox_lens
.cat_len
= r
;
404 default : dsr9500type
=P_DSR_AUTO
;
408 case P_HSIC
: r
=(buf
[2]==0x3A) ? 20 : 0; break; // 3A=DCW / FC=ECM was wrong
409 case P_BOMBA
: r
=13; break;
410 case P_DSR95
: r
=14; break;
411 case P_ALPHA
: r
=(buf
[1]<<8)|buf
[2]; break; // should be 16 always
414 case 3: // STAGE 3: get the rest ...
415 if (r
>0) // read r additional bytes
418 if( !oscam_ser_selrec(buf
, r
, l
, &n
) )
420 cs_debug("not all data received, waiting another 50 ms");
422 if( !oscam_ser_selrec(buf
, all
-n
, l
, &n
) )
425 // auto detect DSR9500 protocol
426 if( is_server
&& p
==P_DSR95
&& dsr9500type
==P_DSR_AUTO
)
429 if( oscam_ser_selrec(buf
, 2, l
, &n
) )
431 if( cs_atoi(buf
+n
-2, 1, 1)==0xFFFFFFFF )
433 switch( (buf
[n
-2]<<8)|buf
[n
-1] )
435 case 0x0A0D : dsr9500type
=P_DSR_OPEN
; break;
436 case 0x0D0A : dsr9500type
=P_DSR_PIONEER
; break;
437 default : dsr9500type
=P_DSR_UNKNOWN
; break;
440 if( oscam_ser_selrec(buf
, 2, l
, &n
) )
441 if( cs_atoi(buf
+n
-2, 1, 1)==0xFFFFFFFF )
442 dsr9500type
=P_DSR_UNKNOWN
;
444 dsr9500type
=P_DSR_WITHSID
;
446 dsr9500type
=P_DSR_UNKNOWN
;
452 dsr9500type
=P_DSR_GNUSMAS
;
454 cs_log("detected dsr9500-%s type receiver",
455 dsrproto_txt
[dsr9500type
]);
458 if( is_server
&& p
==P_GBOX
)
461 for( j
=0; (j
<3) && (p
>0); j
++)
465 if( !oscam_ser_selrec(buf
, 3, l
, &n
) )
467 else if( !(buf
[n
-3]==0x02 && (buf
[n
-2]&0xf0)==0xb0) )
470 case 1: // PMT + ECM header
471 gbox_lens
.pmt_len
=((buf
[n
-2]&0xf)<<8)|buf
[n
-1];
472 if( !oscam_ser_selrec(buf
, gbox_lens
.pmt_len
+3, l
, &n
) )
475 case 2: // ECM + ECM PID
476 gbox_lens
.ecm_len
=((buf
[n
-2]&0xf)<<8)|buf
[n
-1];
477 if( !oscam_ser_selrec(buf
, gbox_lens
.ecm_len
+4, l
, &n
) )
482 else if (r
<0) // read until specified char (-r)
484 while((buf
[n
-1]!=(-r
)) && (p
>0))
485 if (!oscam_ser_selrec(buf
, 1, l
, &n
))
491 if (p
==(-2) || p
==(-1)) {
492 oscam_ser_selrec(buf
, l
-n
, l
, &n
); // flush buffer
496 cs_ddump(buf
, n
, "received %d bytes from %s in %d msec", n
, remote_txt(),
497 1000*(tpe
.time
-tps
.time
)+tpe
.millitm
-tps
.millitm
);
498 client
[cs_idx
].last
=tpe
.time
;
501 case (-1): if (is_server
&&(n
>2)&&(buf
[0]==2)&&(buf
[1]==2)&&(buf
[2]==2))
503 oscam_ser_disconnect();
504 cs_log("humax powered on"); // this is nice ;)
507 cs_log(incomplete
, n
);
509 case (-2): cs_debug("unknown request or garbage");
512 xbuf
[0]=(uchar
) ((job
<<4) | p
);
520 static void oscam_ser_disconnect_client()
522 switch(connected
? connected
: oscam_ser_proto
)
529 oscam_ser_send(mbuf
, 4);
532 dsr9500type
=P_DSR_AUTO
;
536 static void oscam_ser_init_client()
538 switch(oscam_ser_proto
) // sure, does not work in auto-mode
541 oscam_ser_disconnect_client(); // send disconnect first
542 cs_sleepms(300); // wait a little bit
547 oscam_ser_send(mbuf
, 4); // send connect
552 static void oscam_ser_disconnect()
554 oscam_ser_disconnect_client();
556 cs_log("%s disconnected (%s)", username(cs_idx
), proto_txt
[connected
]);
560 static void oscam_ser_auth_client(int proto
)
563 // After reload base account ptrs may be placed in other address,
564 // and we may can't find it in this process.
565 // Simply save valid account.
566 static struct s_auth
*account
=0;
568 if (connected
==proto
)
571 oscam_ser_disconnect();
575 client
[cs_idx
].usr
[0]=0;
576 for (ok
=0, account
=cfg
->account
; (account
) && (!ok
); account
=account
->next
)
577 if( (ok
=!strcmp(oscam_ser_usr
, account
->usr
)) )
580 cs_auth_client(ok
? account
: (struct s_auth
*)(-1), proto_txt
[connected
]);
583 static void oscam_ser_send_dcw(ECM_REQUEST
*er
)
587 if (er
->rc
<4) // found
591 for (i
=0, crc
=HSIC_CRC
; i
<16; i
++)
593 memset(mbuf
, 0x04 , 2);
594 memset(mbuf
+2 , 0x3a , 2);
595 memcpy(mbuf
+4 , er
->cw
, 16);
596 memcpy(mbuf
+20, &crc
, 1);
597 memset(mbuf
+21, 0x1b , 2);
598 oscam_ser_send(mbuf
, 23);
604 memcpy(mbuf
+3, er
->cw
, 16);
605 oscam_ser_send(mbuf
, 19);
611 memcpy(mbuf
+3, i2b(2, er
->pid
), 2);
612 oscam_ser_send(mbuf
, 5);
618 oscam_ser_send(er
->cw
, 16);
622 memcpy(mbuf
+1, er
->cw
, 16);
623 oscam_ser_send(mbuf
, 17);
624 if( dsr9500type
==P_DSR_GNUSMAS
)
628 for( i
=1; i
<17; i
++ )
639 memcpy(mbuf
+4, er
->cw
, 16);
640 oscam_ser_send(mbuf
, 20);
646 memcpy(mbuf
+3, er
->cw
, 16);
647 oscam_ser_send(mbuf
, 19);
658 oscam_ser_send(mbuf
, 4);
661 serial_errors
=0; // clear error counter
664 static void oscam_ser_process_pmt(uchar
*buf
, int l
)
673 memset(sssp_tab
, 0, sizeof(sssp_tab
));
674 sssp_srvid
=b2i(2, buf
+3);
675 for (i
=9, sssp_num
=0; (i
<l
) && (sssp_num
<SSSP_MAX_PID
); i
+=7, sssp_num
++)
677 memcpy(sbuf
+3+(sssp_num
<<1), buf
+i
+2, 2);
678 sssp_tab
[sssp_num
].caid
=b2i(2, buf
+i
);
679 sssp_tab
[sssp_num
].pid
=b2i(2, buf
+i
+2);
680 sssp_tab
[sssp_num
].prid
=b2i(3, buf
+i
+4);
684 sbuf
[2]=(sssp_num
<<1);
685 oscam_ser_send(sbuf
, sbuf
[2]+3);
690 static void oscam_ser_client_logon(uchar
*buf
, int l
)
692 uchar gs_logon
[]={0, 1, 0, 0, 2, 1, 0, 0};
696 if ((l
>=8) && (!memcmp(buf
, gs_logon
, 8)))
702 oscam_ser_send(buf
, 4);
708 static int oscam_ser_check_ecm(ECM_REQUEST
*er
, uchar
*buf
, int l
)
714 cs_log(incomplete
, l
);
722 er
->caid
= b2i(2, buf
+1 );
723 er
->prid
= b2i(3, buf
+3 );
724 er
->pid
= b2i(2, buf
+6 );
725 er
->srvid
= b2i(2, buf
+10);
726 memcpy(er
->ecm
, buf
+12, er
->l
);
729 er
->pid
=b2i(2, buf
+3);
730 for (i
=0; (i
<8) && (sssp_tab
[i
].pid
!=er
->pid
); i
++);
733 cs_debug("illegal request, unknown pid=%04X", er
->pid
);
737 er
->srvid
= sssp_srvid
;
738 er
->caid
= sssp_tab
[i
].caid
;
739 er
->prid
= sssp_tab
[i
].prid
;
740 memcpy(er
->ecm
, buf
+5, er
->l
);
744 memcpy(er
->ecm
, buf
, er
->l
);
747 buf
[l
]='\0'; // prepare for trim
748 trim(buf
+13); // strip spc, nl, cr ...
749 er
->l
=strlen(buf
+13)>>1;
750 er
->prid
=cs_atoi(buf
+3, 3, 0); // ignore errors
751 er
->caid
=cs_atoi(buf
+9, 2, 0); // ignore errors
752 if (cs_atob(er
->ecm
, buf
+13, er
->l
)<0)
754 cs_log("illegal characters in ecm-request");
757 if( dsr9500type
==P_DSR_WITHSID
)
760 er
->srvid
=cs_atoi(buf
+13+(er
->l
<<1), 2, 0);
764 er
->l
= ((buf
[3]<<8)|buf
[2]) - 6;
765 er
->srvid
= (buf
[5]<<8)|buf
[4]; // sid
766 er
->caid
= (buf
[7]<<8)|buf
[6];
768 if (er
->l
>256) er
->l
=256;
769 memcpy(er
->ecm
, buf
+10, er
->l
);
772 l
=oscam_ser_alpha_convert(buf
, l
);
773 er
->l
= b2i(2, buf
+1 )-2;
774 er
->caid
= b2i(2, buf
+3 );
775 if ((er
->l
!=l
-5) || (er
->l
>257))
777 cs_log(incomplete
, l
);
780 memcpy(er
->ecm
, buf
+5, er
->l
);
783 er
->srvid
= b2i(2, buf
+gbox_lens
.cat_len
+3+3);
784 er
->l
= gbox_lens
.ecm_len
+3;
785 memcpy(er
->ecm
, buf
+gbox_lens
.cat_len
+3+gbox_lens
.pmt_len
+3, er
->l
);
791 static void oscam_ser_process_ecm(uchar
*buf
, int l
)
795 if (!(er
=get_ecmtask()))
798 switch(oscam_ser_check_ecm(er
, buf
, l
))
800 case 2: er
->rc
=9; return; // error without log
801 case 1: er
->rc
=9; // error with log
807 static void oscam_ser_server()
812 oscam_ser_init_client();
814 while ((n
=process_input(mbuf
, sizeof(mbuf
), cfg
->cmaxidle
))>=0)
816 if (serial_errors
> 3)
818 cs_log("too many errors, reiniting...");
823 oscam_ser_auth_client(mbuf
[0] & 0xF);
827 oscam_ser_process_ecm(mbuf
+1, n
-1);
830 oscam_ser_process_pmt(mbuf
+1, n
-1);
833 oscam_ser_client_logon(mbuf
+1, n
-1);
838 oscam_ser_disconnect();
841 static int init_oscam_ser_device(char *device
)
845 fd
=open(device
, O_RDWR
| O_NOCTTY
| O_SYNC
| O_NONBLOCK
);
848 fcntl(fd
, F_SETFL
, 0);
849 if (oscam_ser_set_serial_device(fd
)<0) cs_log("ERROR ioctl");
850 if (tcflush(fd
, TCIOFLUSH
)<0) cs_log("ERROR flush");
855 cs_log("ERROR opening %s", device
);
860 static void oscam_ser_fork(int idx
, char *url
)
862 static char logtxt
[32];
865 if ((!url
) || (!url
[0])) return;
866 if (!oscam_ser_parse_url(url
)) return;
867 snprintf(logtxt
, sizeof(logtxt
)-1, ", %s@%s",
868 oscam_ser_proto
>P_MAX
? "auto" : proto_txt
[oscam_ser_proto
], oscam_ser_device
);
869 ph
[idx
].logtxt
=logtxt
;
870 switch(cs_fork(0, idx
))
880 client
[cs_idx
].au
=(-1);
881 client
[cs_idx
].usr
[0]='\0';
882 client
[cs_idx
].login
=time((time_t *)0);
883 if (pfd
=init_oscam_ser_device(oscam_ser_device
))
886 sleep(60); // retry in 1 min. (USB-Device ?)
891 void init_oscam_ser(int idx
)
894 while( (p
=strrchr(cfg
->ser_device
, 1)) )
897 oscam_ser_fork(idx
, p
+1);
899 oscam_ser_fork(idx
, cfg
->ser_device
);
906 static int oscam_ser_client_init()
908 if ((!reader
[ridx
].device
[0])) cs_exit(1);
909 if (!oscam_ser_parse_url(reader
[ridx
].device
)) cs_exit(1);
910 pfd
=init_oscam_ser_device(oscam_ser_device
);
911 return((pfd
>0) ? 0 : 1);
914 static int oscam_ser_send_ecm(ECM_REQUEST
*er
, uchar
*buf
)
916 switch(oscam_ser_proto
)
921 memcpy(buf
+ 1, i2b(2, er
->caid
), 2);
922 memcpy(buf
+ 3, i2b(3, er
->prid
), 3);
923 memcpy(buf
+ 6, i2b(2, er
->pid
), 2);
924 memcpy(buf
+10, i2b(2, er
->srvid
), 2);
925 memcpy(buf
+12, er
->ecm
, er
->l
);
926 oscam_ser_send(buf
, 12+er
->l
);
929 oscam_ser_send(er
->ecm
, er
->l
);
932 if( dsr9500type
==P_DSR_WITHSID
)
934 sprintf(buf
, "%c%08X%04X%s%04X\n\r",
935 3, er
->prid
, er
->caid
, cs_hexdump(0, er
->ecm
, er
->l
), er
->srvid
);
936 oscam_ser_send(buf
, (er
->l
<<1)+19); // 1 + 8 + 4 + l*2 + 4 + 2
940 sprintf(buf
, "%c%08X%04X%s\n\r",
941 3, er
->prid
, er
->caid
, cs_hexdump(0, er
->ecm
, er
->l
));
942 oscam_ser_send(buf
, (er
->l
<<1)+15); // 1 + 8 + 4 + l*2 + 2
947 memcpy(buf
+1, i2b(2, 2+er
->l
), 2);
948 memcpy(buf
+3, i2b(2, er
->caid
), 2);
949 memcpy(buf
+5, er
->ecm
, er
->l
);
950 oscam_ser_send(buf
, oscam_ser_alpha_convert(buf
, 5+er
->l
));
956 static void oscam_ser_process_dcw(uchar
*dcw
, int *rc
, uchar
*buf
, int l
)
958 switch(oscam_ser_proto
)
961 if ((l
>=23) && (buf
[2]==0x3A) && (buf
[3]==0x3A))
965 for (i
=4, crc
=HSIC_CRC
; i
<20; i
++)
969 memcpy(dcw
, buf
+4, 16);
977 memcpy(dcw
, buf
, 16);
982 if ((l
>=17) && (buf
[0]==4))
984 memcpy(dcw
, buf
+1, 16);
989 if ((l
>=19) && (buf
[0]==0x88))
991 memcpy(dcw
, buf
+3, 16);
998 static int oscam_ser_recv_chk(uchar
*dcw
, int *rc
, uchar
*buf
, int n
)
1004 oscam_ser_process_dcw(dcw
, rc
, buf
+1, n
-1);
1007 return((*rc
<0) ? (-1) : 0); // idx not supported in serial module
1011 * protocol structure
1014 void module_oscam_ser(struct s_module
*ph
)
1016 strcpy(ph
->desc
, "serial");
1017 ph
->type
=MOD_CONN_SERIAL
;
1020 ph
->s_handler
=init_oscam_ser
;
1021 ph
->recv
=oscam_ser_recv
;
1022 ph
->send_dcw
=oscam_ser_send_dcw
;
1024 ph
->c_init
=oscam_ser_client_init
;
1025 ph
->c_recv_chk
=oscam_ser_recv_chk
;
1026 ph
->c_send_ecm
=oscam_ser_send_ecm
;