1 #define MODULE_LOG_PREFIX "serial"
5 #include "oscam-config.h"
6 #include "oscam-client.h"
9 #include "oscam-string.h"
10 #include "oscam-time.h"
11 #include "oscam-reader.h"
13 extern int32_t exit_oscam
;
16 #define SSSP_MAX_PID 8
18 #define P_HSIC 1 // Humax Sharing Interface Client
19 #define P_SSSP 2 // Simple Serial Sharing Protocol
20 #define P_BOMBA 3 // This is not really a Protocol
21 #define P_DSR95 4 // DSR9500 with SID
22 #define P_GS 5 // GS7001
23 #define P_ALPHA 6 // AlphaStar Receivers
24 #define P_DSR95_OLD 7 // DSR9500 without SID
25 #define P_GBOX 8 // Arion with gbox
26 #define P_TWIN 9 // Twin Protocol
31 #define P_DSR_GNUSMAS 1
33 #define P_DSR_PIONEER 3
34 #define P_DSR_WITHSID 4
35 #define P_DSR_UNKNOWN 5
37 #define IS_ECM 0 // incoming data is ECM
38 #define IS_DCW 1 // incoming data is DCW
39 #define IS_PMT 2 // incoming data is PMT
40 #define IS_LGO 3 // incoming data is client logon
41 #define IS_ECHO 4 // incoming data is DCW echo from Samsung
42 #define IS_CAT 5 // incoming data is CAT
43 #define IS_BAD 0xFF // incoming data is unknown
45 static const char *const proto_txt
[] = {"unknown", "hsic", "sssp", "bomba", "dsr9500", "gs",
46 "alpha", "dsr9500old", "gbox", "twin"
48 static const char *const dsrproto_txt
[] = {"unknown", "samsung", "openbox", "pioneer",
66 //added to support multiple instances with thread
67 struct s_serial_client
72 char oscam_ser_usr
[32];
73 char oscam_ser_device
[64];
74 int32_t oscam_ser_port
;
75 speed_t oscam_ser_baud
;
76 int32_t oscam_ser_delay
;
77 int32_t oscam_ser_timeout
;
78 int32_t oscam_ser_proto
;
79 int32_t serial_errors
;
81 int32_t samsung_0a
; // number of 0A in ALL dcw sent into samsung
82 int32_t samsung_dcw
; // number of dcw sent into samsung before echo or ecm is received
85 SSSP_TAB sssp_tab
[SSSP_MAX_PID
];
91 static pthread_mutex_t mutex
;
92 static pthread_cond_t cond
;
93 static int32_t bcopy_end
= -1;
94 static struct s_module
*serial_ph
= NULL
;
99 struct s_serial_client serialdata
;
102 static int32_t chk_ser_srvid_match(uint16_t caid
, uint16_t sid
, uint32_t provid
, SIDTAB
*sidtab
)
106 if(!sidtab
->num_caid
)
109 for(i
= 0; (i
< sidtab
->num_caid
) && (!(rc
& 1)); i
++)
110 if(caid
== sidtab
->caid
[i
]) { rc
|= 1; }
112 if(!sidtab
->num_provid
)
115 for(i
= 0; (i
< sidtab
->num_provid
) && (!(rc
& 2)); i
++)
116 if(provid
== sidtab
->provid
[i
]) { rc
|= 2; }
118 if(!sidtab
->num_srvid
)
121 for(i
= 0; (i
< sidtab
->num_srvid
) && (!(rc
& 4)); i
++)
122 if(sid
== sidtab
->srvid
[i
]) { rc
|= 4; }
127 static int32_t chk_ser_srvid(struct s_client
*cl
, uint16_t caid
, uint16_t sid
, uint32_t provid
)
134 if(!cl
->sidtabs
.no
) { return (1); }
137 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
138 if(sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
)
140 if((cl
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) &&
141 (chk_ser_srvid_match(caid
, sid
, provid
, sidtab
)))
143 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
144 (chk_ser_srvid_match(caid
, sid
, provid
, sidtab
)))
150 static void oscam_wait_ser_fork(void)
152 SAFE_MUTEX_LOCK(&mutex
);
161 { SAFE_COND_WAIT(&cond
, &mutex
); }
164 SAFE_MUTEX_UNLOCK(&mutex
);
167 static int32_t oscam_ser_alpha_convert(uchar
*buf
, int32_t l
)
170 if(buf
[0] == 0x7E) // normalize
173 memmove(buf
, buf
+ 1, l
); // remove BOT/EOT
174 for(i
= 0; i
< l
; i
++)
177 memmove(buf
+ i
, buf
+ i
+ 1, --l
);
183 memmove(buf
+ 1, buf
, l
++); // insert BOT
185 for(i
= 1; i
< l
; i
++)
186 if((buf
[i
] == 0x20) || (buf
[i
] == 0x7E) || (buf
[i
] == 0x7F))
189 memmove(buf
+ i
+ 1, buf
+ i
, l
++);
192 buf
[l
++] = 0x7F; // insert EOT
197 static void oscam_ser_disconnect(void);
199 static int32_t oscam_ser_parse_url(char *url
, struct s_serial_client
*serialdata
, char *pcltype
)
201 char *service
, *usr
, *dev
, *baud
= NULL
, *dummy
, *para
;
204 cltype
= pcltype
? (*pcltype
) : cur_client()->typ
;
206 serialdata
->oscam_ser_proto
= P_AUTO
;
207 if((dummy
= strstr(url
, "://")))
213 for(i
= 1; i
<= P_MAX
; i
++)
214 if(!strcmp(service
, proto_txt
[i
]))
215 { serialdata
->oscam_ser_proto
= i
; }
217 if(!(cltype
== 'c') && (serialdata
->oscam_ser_proto
== P_AUTO
)) { return (0); }
218 switch(serialdata
->oscam_ser_proto
) // set the defaults
221 serialdata
->oscam_ser_timeout
= 500;
222 serialdata
->oscam_ser_baud
= B19200
;
225 serialdata
->oscam_ser_timeout
= 50;
227 serialdata
->oscam_ser_baud
= B115200
;
229 serialdata
->oscam_ser_baud
= B9600
;
233 switch(serialdata
->oscam_ser_proto
)
236 serialdata
->dsr9500type
= (cltype
== 'c') ? P_DSR_AUTO
: P_DSR_WITHSID
;
239 serialdata
->dsr9500type
= P_DSR_AUTO
;
240 serialdata
->oscam_ser_proto
= P_DSR95
;
244 if((dev
= strchr(usr
, '@')))
247 if((dummy
= strchr(usr
, ':'))) // fake pwd
249 if((cltype
== 'c') && (!usr
[0])) { return (0); }
253 if(cltype
== 'c') { return (0); } // user needed in server-mode
256 if((baud
= strchr(dev
, ':'))) // port = baud
258 dummy
= baud
? baud
: dev
;
259 if((para
= strchr(dummy
, '?')))
261 char *ptr1
, *ptr2
, *saveptr1
= NULL
;
263 for(ptr1
= strtok_r(para
, "&", &saveptr1
); ptr1
; ptr1
= strtok_r(NULL
, "&", &saveptr1
))
265 if(!(ptr2
= strchr(ptr1
, '='))) { continue; }
268 if(!strcmp("delay" , ptr1
)) { serialdata
->oscam_ser_delay
= atoi(ptr2
); }
269 if(!strcmp("timeout", ptr1
)) { serialdata
->oscam_ser_timeout
= atoi(ptr2
); }
276 if(!strcmp(baud
, "115200"))
277 { serialdata
->oscam_ser_baud
= B115200
; }
281 if(!strcmp(baud
, "57600"))
282 { serialdata
->oscam_ser_baud
= B57600
; }
285 if(!strcmp(baud
, "38400"))
286 { serialdata
->oscam_ser_baud
= B38400
; }
287 else if(!strcmp(baud
, "19200"))
288 { serialdata
->oscam_ser_baud
= B19200
; }
289 else if(!strcmp(baud
, "9600"))
290 { serialdata
->oscam_ser_baud
= B9600
; }
292 if((para
= strchr(dev
, ','))) // device = ip/hostname and port
295 serialdata
->oscam_ser_port
= atoi(para
);
298 { serialdata
->oscam_ser_port
= 0; }
299 cs_strncpy(serialdata
->oscam_ser_usr
, usr
, sizeof(serialdata
->oscam_ser_usr
));
300 cs_strncpy(serialdata
->oscam_ser_device
, dev
, sizeof(serialdata
->oscam_ser_device
));
301 return (serialdata
->oscam_ser_baud
);
304 static void oscam_ser_set_baud(struct termios
*tio
, speed_t baud
)
306 cfsetospeed(tio
, baud
);
307 cfsetispeed(tio
, baud
);
310 static int32_t oscam_ser_set_serial_device(int32_t fd
, speed_t baud
)
314 memset(&tio
, 0, sizeof(tio
));
315 // tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
316 tio
.c_cflag
= (CS8
| CREAD
| CLOCAL
);
317 tio
.c_iflag
= IGNPAR
;
320 //#if !defined(__CYGWIN__)
321 oscam_ser_set_baud(&tio
, B1200
);
322 tcsetattr(fd
, TCSANOW
, &tio
);
325 oscam_ser_set_baud(&tio
, baud
);
326 return (tcsetattr(fd
, TCSANOW
, &tio
));
329 static int32_t oscam_ser_poll(int32_t event
, struct s_client
*client
)
335 msec
= comp_timeb(&client
->serialdata
->tpe
, &tpc
);
338 pfds
.fd
= cur_client()->pfd
;
341 if(poll(&pfds
, 1, msec
) != 1)
344 { return (((pfds
.revents
)&event
) == event
); }
347 static int32_t oscam_ser_write(struct s_client
*client
, const uchar
*const buf
, int32_t n
)
350 for(i
= 0; (i
< n
) && (oscam_ser_poll(POLLOUT
, client
)); i
++)
352 if(client
->serialdata
->oscam_ser_delay
)
353 { cs_sleepms(client
->serialdata
->oscam_ser_delay
); }
354 if(write(client
->pfd
, buf
+ i
, 1) < 1)
360 static int32_t oscam_ser_send(struct s_client
*client
, const uchar
*const buf
, int32_t l
)
363 struct s_serial_client
*serialdata
= client
->serialdata
;
364 if(!client
->pfd
) { return (0); }
365 cs_ftime(&serialdata
->tps
);
366 serialdata
->tpe
= client
->serialdata
->tps
;
367 add_ms_to_timeb(&serialdata
->tpe
, serialdata
->oscam_ser_timeout
);
368 add_ms_to_timeb(&serialdata
->tpe
, (l
* (serialdata
->oscam_ser_delay
+ 1)));
369 n
= oscam_ser_write(client
, buf
, l
);
370 cs_ftime(&serialdata
->tpe
);
371 cs_log_dump_dbg(D_CLIENT
, buf
, l
, "send %d of %d bytes to %s in %"PRId64
" ms", n
, l
, remote_txt(),
372 comp_timeb(&serialdata
->tpe
, &serialdata
->tps
));
374 { cs_log("transmit error. send %d of %d bytes only !", n
, l
); }
378 static int32_t oscam_ser_selrec(uchar
*buf
, int32_t n
, int32_t l
, int32_t *c
)
383 if(n
<= 0) { return (0); }
384 for(i
= 0; (i
< n
) && (oscam_ser_poll(POLLIN
, cur_client())); i
++)
385 if(read(cur_client()->pfd
, buf
+ *c
, 1) < 1)
392 static int32_t oscam_ser_recv(struct s_client
*client
, uchar
*xbuf
, int32_t l
)
397 static int32_t have_lb
= 0;
398 uchar
*buf
= xbuf
+ 1;
399 struct s_serial_client
*serialdata
= client
->serialdata
;
401 if(!client
->pfd
) { return (-1); }
402 cs_ftime(&serialdata
->tps
);
403 serialdata
->tpe
= serialdata
->tps
;
404 add_ms_to_timeb(&serialdata
->tpe
, serialdata
->oscam_ser_timeout
);
406 for(s
= p
= r
= 0, n
= have_lb
; (s
< 4) && (p
>= 0); s
++)
410 case 0: // STAGE 0: skip known garbage from DSR9500
411 if(oscam_ser_selrec(buf
, 2 - n
, l
, &n
))
413 if((buf
[0] == 0x0A) && (buf
[1] == 0x0D))
415 if((buf
[0] == 0x0D) && (buf
[1] == 0x0A))
422 case 1: // STAGE 1: identify protocol
424 if(oscam_ser_selrec(buf
, 1, l
, &n
)) // now we have 3 bytes in buf
426 if((buf
[0] == 0x04) && (buf
[1] == 0x00) && (buf
[2] == 0x02)) //skip unsupported Advanced Serial Sharing Protocol HF 8900
428 oscam_ser_selrec(buf
, 2, l
, &n
); // get rest 2 bytes to buffor
437 if(client
->typ
== 'c') // HERE IS SERVER
439 job
= IS_ECM
; // assume ECM
443 if((buf
[1] == 0x01) && (buf
[2] == 0x00))
447 serialdata
->tpe
.time
++;
451 if((buf
[1] & 0xf0) == 0xb0) { p
= P_GBOX
; }
457 break; // pmt-request
462 switch(serialdata
->oscam_ser_proto
)
467 p
= serialdata
->oscam_ser_proto
;
470 p
= (buf
[1] < 0x30) ? P_SSSP
: P_DSR95
;
471 break; // auto for GS is useless !!
477 serialdata
->dsr9500type
= P_DSR_GNUSMAS
;
481 if(buf
[1] != 0x80) { job
= IS_BAD
; }
490 else // HERE IS CLIENT
492 job
= IS_DCW
; // assume DCW
493 switch(serialdata
->oscam_ser_proto
)
496 if((buf
[0] == 4) && (buf
[1] == 4)) { p
= P_HSIC
; }
502 if(buf
[0] == 4) { p
= P_DSR95
; }
505 if(buf
[0] == 0x88) { p
= P_ALPHA
; }
508 if((buf
[0] == 0xF7) && (buf
[1] == 0x00) && (buf
[2] == 0x16)) { p
= P_TWIN
; }
512 if((serialdata
->oscam_ser_proto
!= p
) && (serialdata
->oscam_ser_proto
!= P_AUTO
))
517 case 2: // STAGE 2: examine length
518 if(client
->typ
== 'c') switch(p
)
521 r
= (buf
[1] << 8) | buf
[2];
527 if(oscam_ser_selrec(buf
, 12, l
, &n
)) { r
= buf
[14]; }
533 r
= 17 * serialdata
->samsung_dcw
- 3 + serialdata
->samsung_0a
;
534 serialdata
->samsung_dcw
= serialdata
->samsung_0a
= 0;
538 if(oscam_ser_selrec(buf
, 16, l
, &n
))
541 if(cs_atob(&b
, (char *)buf
+ 17, 1) < 0)
546 r
+= (serialdata
->dsr9500type
== P_DSR_WITHSID
) ? 4 : 0;
557 if(oscam_ser_selrec(buf
, 1, l
, &n
))
558 { r
= (buf
[3] << 8) | buf
[2]; }
563 r
= -0x7F; // char specifying EOT
566 r
= ((buf
[1] & 0xf) << 8) | buf
[2];
567 serialdata
->gbox_lens
.cat_len
= r
;
570 serialdata
->dsr9500type
= P_DSR_AUTO
;
575 r
= (buf
[2] == 0x3A) ? 20 : 0;
576 break; // 3A=DCW / FC=ECM was wrong
584 r
= (buf
[1] << 8) | buf
[2];
585 break; // should be 16 always
591 case 3: // STAGE 3: get the rest ...
592 if(r
> 0) // read r additional bytes
595 if(!oscam_ser_selrec(buf
, r
, l
, &n
))
597 cs_log_dbg(D_CLIENT
, "not all data received, waiting another 50 ms");
598 add_ms_to_timeb(&serialdata
->tpe
, 50);
599 if(!oscam_ser_selrec(buf
, all
- n
, l
, &n
))
602 // auto detect DSR9500 protocol
603 if(client
->typ
== 'c' && p
== P_DSR95
&& serialdata
->dsr9500type
== P_DSR_AUTO
)
605 add_ms_to_timeb(&serialdata
->tpe
, 20);
606 if(oscam_ser_selrec(buf
, 2, l
, &n
))
608 if(cs_atoi((char *)buf
+ n
- 2, 1, 1) == 0xFFFFFFFF)
610 switch((buf
[n
- 2] << 8) | buf
[n
- 1])
613 serialdata
->dsr9500type
= P_DSR_OPEN
;
616 serialdata
->dsr9500type
= P_DSR_PIONEER
;
619 serialdata
->dsr9500type
= P_DSR_UNKNOWN
;
625 if(oscam_ser_selrec(buf
, 2, l
, &n
))
626 if(cs_atoi((char *)buf
+ n
- 2, 1, 1) == 0xFFFFFFFF)
627 { serialdata
->dsr9500type
= P_DSR_UNKNOWN
; }
629 { serialdata
->dsr9500type
= P_DSR_WITHSID
; }
632 serialdata
->dsr9500type
= P_DSR_UNKNOWN
;
638 { serialdata
->dsr9500type
= P_DSR_GNUSMAS
; }
640 cs_log("detected dsr9500-%s type receiver",
641 dsrproto_txt
[serialdata
->dsr9500type
]);
644 if(client
->typ
== 'c' && p
== P_GBOX
)
647 for(j
= 0; (j
< 3) && (p
> 0); j
++)
651 if(!oscam_ser_selrec(buf
, 3, l
, &n
))
653 else if(!(buf
[n
- 3] == 0x02 && (buf
[n
- 2] & 0xf0) == 0xb0))
656 case 1: // PMT + ECM header
657 serialdata
->gbox_lens
.pmt_len
= ((buf
[n
- 2] & 0xf) << 8) | buf
[n
- 1];
658 if(!oscam_ser_selrec(buf
, serialdata
->gbox_lens
.pmt_len
+ 3, l
, &n
))
661 case 2: // ECM + ECM PID
662 serialdata
->gbox_lens
.ecm_len
= ((buf
[n
- 2] & 0xf) << 8) | buf
[n
- 1];
663 if(!oscam_ser_selrec(buf
, serialdata
->gbox_lens
.ecm_len
+ 4, l
, &n
))
668 else if(r
< 0) // read until specified char (-r)
670 while((buf
[n
- 1] != (-r
)) && (p
> 0))
671 if(!oscam_ser_selrec(buf
, 1, l
, &n
))
677 if(p
== (-2) || p
== (-1))
679 oscam_ser_selrec(buf
, l
- n
, l
, &n
); // flush buffer
680 serialdata
->serial_errors
++;
682 cs_ftime(&serialdata
->tpe
);
683 cs_log_dump_dbg(D_CLIENT
, buf
, n
, "received %d bytes from %s in %"PRId64
" ms", n
, remote_txt(), comp_timeb(&serialdata
->tpe
, &serialdata
->tps
));
684 client
->last
= serialdata
->tpe
.time
;
688 if(client
->typ
== 'c' && (n
> 2) && (buf
[0] == 2) && (buf
[1] == 2) && (buf
[2] == 2))
690 oscam_ser_disconnect();
691 cs_log("humax powered on"); // this is nice ;)
695 if(client
->typ
== 'c' && buf
[0] == 0x1 && buf
[1] == 0x08 && buf
[2] == 0x20 && buf
[3] == 0x08)
697 oscam_ser_disconnect();
698 cs_log("ferguson powered on"); // this is nice to ;)
701 cs_log("incomplete request (%d bytes)", n
);
705 cs_log_dbg(D_CLIENT
, "unknown request or garbage");
708 xbuf
[0] = (uchar
)((job
<< 4) | p
);
709 return ((p
< 0) ? 0 : n
+ 1);
716 static void oscam_ser_disconnect_client(void)
719 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
720 switch(serialdata
->connected
? serialdata
->connected
: serialdata
->oscam_ser_proto
)
727 oscam_ser_send(cur_client(), mbuf
, 4);
730 serialdata
->dsr9500type
= P_DSR_AUTO
;
731 serialdata
->serial_errors
= 0;
734 static void oscam_ser_init_client(void)
737 switch(cur_client()->serialdata
->oscam_ser_proto
) // sure, does not work in auto-mode
740 oscam_ser_disconnect_client(); // send disconnect first
741 cs_sleepms(300); // wait a little bit
746 oscam_ser_send(cur_client(), mbuf
, 4); // send connect
751 static void oscam_ser_disconnect(void)
753 oscam_ser_disconnect_client();
754 if(cur_client()->serialdata
->connected
)
755 { cs_log("%s disconnected (%s)", username(cur_client()), proto_txt
[cur_client()->serialdata
->connected
]); }
756 cur_client()->serialdata
->connected
= 0;
759 static void oscam_ser_auth_client(int32_t proto
)
762 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
763 // After reload base account ptrs may be placed in other address,
764 // and we may can't find it in this process.
765 // Simply save valid account.
766 struct s_auth
*account
= 0;
768 if(serialdata
->connected
== proto
)
770 if(serialdata
->connected
)
771 { oscam_ser_disconnect(); }
772 serialdata
->connected
= proto
;
774 for(ok
= 0, account
= cfg
.account
; (account
) && (!ok
); account
= account
->next
)
775 if((ok
= !strcmp(serialdata
->oscam_ser_usr
, account
->usr
)))
777 cs_auth_client(cur_client(), ok
? account
: (struct s_auth
*)(-1), proto_txt
[serialdata
->connected
]);
780 static void oscam_ser_send_dcw(struct s_client
*client
, ECM_REQUEST
*er
)
785 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
786 if(er
->rc
< E_NOTFOUND
) // found
787 switch(serialdata
->connected
)
790 for(i
= 0, crc
= HSIC_CRC
; i
< 16; i
++)
791 { crc
^= er
->cw
[i
]; }
792 memset(mbuf
, 0x04 , 2);
793 memset(mbuf
+ 2 , 0x3a , 2);
794 memcpy(mbuf
+ 4 , er
->cw
, 16);
795 memcpy(mbuf
+ 20, &crc
, 1);
796 memset(mbuf
+ 21, 0x1b , 2);
797 oscam_ser_send(client
, mbuf
, 23);
803 memcpy(mbuf
+ 3, er
->cw
, 16);
804 oscam_ser_send(client
, mbuf
, 19);
805 if(!serialdata
->sssp_fix
)
810 i2b_buf(2, er
->pid
, mbuf
+ 3);
811 oscam_ser_send(client
, mbuf
, 5);
812 serialdata
->sssp_fix
= 1;
817 oscam_ser_send(client
, er
->cw
, 16);
821 memcpy(mbuf
+ 1, er
->cw
, 16);
822 oscam_ser_send(client
, mbuf
, 17);
823 if(serialdata
->dsr9500type
== P_DSR_GNUSMAS
)
825 serialdata
->samsung_0a
= 0;
826 for(i
= 1; i
< 17; i
++)
828 { serialdata
->samsung_0a
++; }
829 serialdata
->samsung_dcw
++;
837 memcpy(mbuf
+ 4, er
->cw
, 16);
838 oscam_ser_send(client
, mbuf
, 20);
844 memcpy(mbuf
+ 3, er
->cw
, 16);
845 oscam_ser_send(client
, mbuf
, 19);
849 switch(serialdata
->connected
)
856 oscam_ser_send(client
, mbuf
, 4);
859 serialdata
->serial_errors
= 0; // clear error counter
862 static void oscam_ser_process_pmt(uchar
*buf
, int32_t l
)
866 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
867 switch(serialdata
->connected
)
870 serialdata
->sssp_fix
= 0;
871 memset(serialdata
->sssp_tab
, 0, sizeof(serialdata
->sssp_tab
));
872 serialdata
->sssp_srvid
= b2i(2, buf
+ 3);
873 serialdata
->sssp_num
= 0;
876 for(i
= 9; (i
< l
) && (serialdata
->sssp_num
< SSSP_MAX_PID
); i
+= 7)
878 if(chk_ser_srvid(cur_client(), b2i(2, buf
+ i
), b2i(2, buf
+ 3), b2i(3, buf
+ i
+ 4))) // check support for pid (caid, sid and provid in oscam.services)
880 memcpy(sbuf
+ 3 + (serialdata
->sssp_num
<< 1), buf
+ i
+ 2, 2);
881 serialdata
->sssp_tab
[serialdata
->sssp_num
].caid
= b2i(2, buf
+ i
);
882 serialdata
->sssp_tab
[serialdata
->sssp_num
].pid
= b2i(2, buf
+ i
+ 2);
883 serialdata
->sssp_tab
[serialdata
->sssp_num
].prid
= b2i(3, buf
+ i
+ 4);
884 serialdata
->sssp_num
++;
889 sbuf
[2] = (serialdata
->sssp_num
<< 1);
890 oscam_ser_send(cur_client(), sbuf
, sbuf
[2] + 3);
895 static void oscam_ser_client_logon(uchar
*buf
, int32_t l
)
897 uchar gs_logon
[] = {0, 1, 0, 0, 2, 1, 0, 0};
898 switch(cur_client()->serialdata
->connected
)
901 if((l
>= 8) && (!memcmp(buf
, gs_logon
, 8)))
907 oscam_ser_send(cur_client(), buf
, 4);
913 static int32_t oscam_ser_check_ecm(ECM_REQUEST
*er
, uchar
*buf
, int32_t l
)
916 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
920 cs_log("incomplete request (%d bytes)", l
);
924 switch(serialdata
->connected
)
928 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
930 er
->caid
= b2i(2, buf
+ 1);
931 er
->prid
= b2i(3, buf
+ 3);
932 er
->pid
= b2i(2, buf
+ 6);
933 er
->srvid
= b2i(2, buf
+ 10);
934 memcpy(er
->ecm
, buf
+ 12, er
->ecmlen
);
937 er
->pid
= b2i(2, buf
+ 3);
938 for(i
= 0; (i
< 8) && (serialdata
->sssp_tab
[i
].pid
!= er
->pid
); i
++) { ; }
939 if(i
>= serialdata
->sssp_num
)
941 cs_log_dbg(D_CLIENT
, "illegal request, unknown pid=%04X", er
->pid
);
945 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
947 er
->srvid
= serialdata
->sssp_srvid
;
948 er
->caid
= serialdata
->sssp_tab
[i
].caid
;
949 er
->prid
= serialdata
->sssp_tab
[i
].prid
;
950 memcpy(er
->ecm
, buf
+ 5, er
->ecmlen
);
954 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
956 memcpy(er
->ecm
, buf
, er
->ecmlen
);
959 buf
[l
] = '\0'; // prepare for trim
960 trim((char *)buf
+ 13); // strip spc, nl, cr ...
961 er
->ecmlen
= strlen((char *)buf
+ 13) >> 1;
962 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
964 er
->prid
= cs_atoi((char *)buf
+ 3, 3, 0); // ignore errors
965 er
->caid
= cs_atoi((char *)buf
+ 9, 2, 0); // ignore errors
966 if(cs_atob(er
->ecm
, (char *)buf
+ 13, er
->ecmlen
) < 0)
968 cs_log("illegal characters in ecm-request");
971 if(serialdata
->dsr9500type
== P_DSR_WITHSID
)
976 er
->srvid
= cs_atoi((char *)buf
+ 13 + (er
->ecmlen
<< 1), 2, 0);
980 er
->ecmlen
= ((buf
[3] << 8) | buf
[2]) - 6;
981 er
->srvid
= (buf
[5] << 8) | buf
[4]; // sid
982 er
->caid
= (buf
[7] << 8) | buf
[6];
985 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
|| (10 + er
->ecmlen
> l
))
988 memcpy(er
->ecm
, buf
+ 10, er
->ecmlen
);
991 l
= oscam_ser_alpha_convert(buf
, l
);
992 er
->ecmlen
= b2i(2, buf
+ 1) - 2;
993 er
->caid
= b2i(2, buf
+ 3);
994 if((er
->ecmlen
!= l
- 5) || (er
->ecmlen
> MAX_ECM_SIZE
) || (er
->ecmlen
< 0))
996 cs_log("incomplete request (%d bytes)", l
);
999 memcpy(er
->ecm
, buf
+ 5, er
->ecmlen
);
1002 if(((serialdata
->gbox_lens
.cat_len
+ 3 + 3 + 1) > l
)
1003 || ((serialdata
->gbox_lens
.ecm_len
+ 3) > l
))
1007 er
->srvid
= b2i(2, buf
+ serialdata
->gbox_lens
.cat_len
+ 3 + 3);
1008 er
->ecmlen
= serialdata
->gbox_lens
.ecm_len
+ 3;
1010 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
1012 if(serialdata
->gbox_lens
.cat_len
+ 3 + serialdata
->gbox_lens
.pmt_len
+ 3 + er
->ecmlen
> l
)
1015 memcpy(er
->ecm
, buf
+ serialdata
->gbox_lens
.cat_len
+ 3 + serialdata
->gbox_lens
.pmt_len
+ 3, er
->ecmlen
);
1021 static void oscam_ser_process_ecm(uchar
*buf
, int32_t l
)
1025 if(!(er
= get_ecmtask()))
1028 switch(oscam_ser_check_ecm(er
, buf
, l
))
1033 //er->rc = E_CORRUPT;
1035 return; // error without log
1037 er
->rc
= E_CORRUPT
; // error with log
1040 get_cw(cur_client(), er
);
1044 static void oscam_ser_server(void)
1049 int32_t *pserial_errors
= &cur_client()->serialdata
->serial_errors
;
1051 cur_client()->serialdata
->connected
= 0;
1052 oscam_ser_init_client();
1054 while((n
= process_input(mbuf
, sizeof(mbuf
), INT_MAX
)) > 0)
1056 if((*pserial_errors
) > 3)
1058 cs_log("too many errors, reiniting...");
1061 oscam_ser_auth_client(mbuf
[0] & 0xF);
1062 switch(mbuf
[0] >> 4)
1065 oscam_ser_process_ecm(mbuf
+ 1, n
- 1);
1068 oscam_ser_process_pmt(mbuf
+ 1, n
- 1);
1071 oscam_ser_client_logon(mbuf
+ 1, n
- 1);
1075 if(cur_client()->serialdata
->oscam_ser_port
> 0)
1076 { network_tcp_connection_close(cur_client()->reader
, "error reading from socket"); }
1077 oscam_ser_disconnect();
1080 static int32_t init_oscam_ser_device(struct s_client
*cl
)
1082 char *device
= cl
->serialdata
->oscam_ser_device
;
1083 speed_t baud
= cl
->serialdata
->oscam_ser_baud
;
1084 int32_t port
= cl
->serialdata
->oscam_ser_port
;
1087 // network connection to a TCP-exposed serial port
1090 cs_strncpy(cl
->reader
->device
, device
, sizeof(cl
->reader
->device
));
1091 cl
->reader
->r_port
= cl
->port
= port
;
1092 fd
= network_tcp_connection_open(cl
->reader
);
1098 else // standard serial port connection
1100 fd
= open(device
, O_RDWR
| O_NOCTTY
| O_SYNC
| O_NONBLOCK
);
1103 fcntl(fd
, F_SETFL
, 0);
1104 if(oscam_ser_set_serial_device(fd
, baud
) < 0) { cs_log("ERROR ioctl"); }
1105 if(tcflush(fd
, TCIOFLUSH
) < 0) { cs_log("ERROR flush"); }
1110 cs_log("ERROR opening %s (errno=%d %s)", device
, errno
, strerror(errno
));
1116 static void oscam_copy_serialdata(struct s_serial_client
*dest
, struct s_serial_client
*src
)
1120 dest
->connected
= src
->connected
;
1121 memcpy(&dest
->tps
, &src
->tps
, sizeof(dest
->tps
));
1122 memcpy(&dest
->tpe
, &src
->tpe
, sizeof(dest
->tpe
));
1123 memcpy(&dest
->oscam_ser_usr
, &src
->oscam_ser_usr
, sizeof(dest
->oscam_ser_usr
));
1124 memcpy(&dest
->oscam_ser_device
, &src
->oscam_ser_device
, sizeof(dest
->oscam_ser_device
));
1125 dest
->oscam_ser_port
= src
->oscam_ser_port
;
1126 dest
->oscam_ser_baud
= src
->oscam_ser_baud
;
1127 dest
->oscam_ser_delay
= src
->oscam_ser_delay
;
1128 dest
->oscam_ser_timeout
= src
->oscam_ser_timeout
;
1129 dest
->oscam_ser_proto
= src
->oscam_ser_proto
;
1130 dest
->serial_errors
= src
->serial_errors
;
1131 dest
->dsr9500type
= src
->dsr9500type
;
1132 dest
->samsung_0a
= src
->samsung_0a
; // number of 0A in ALL dcw sent into samsung
1133 dest
->samsung_dcw
= src
->samsung_dcw
; // number of dcw sent into samsung before echo or ecm is received
1135 dest
->gbox_lens
= src
->gbox_lens
;
1136 memcpy(&dest
->sssp_tab
, &src
->sssp_tab
, sizeof(dest
->sssp_tab
));
1137 dest
->sssp_srvid
= src
->sssp_srvid
;
1138 dest
->sssp_num
= src
->sssp_num
;
1139 dest
->sssp_fix
= src
->sssp_fix
;
1143 static void oscam_init_serialdata(struct s_serial_client
*dest
)
1147 memset(dest
, 0, sizeof(struct s_serial_client
));
1148 dest
->oscam_ser_timeout
= 50;
1149 dest
->dsr9500type
= P_DSR_AUTO
;
1153 static void *oscam_ser_fork(void *pthreadparam
)
1155 struct s_thread_param
*pparam
= (struct s_thread_param
*) pthreadparam
;
1156 struct s_client
*cl
= create_client(get_null_ip());
1157 SAFE_SETSPECIFIC(getclient
, cl
);
1158 cl
->thread
= pthread_self();
1160 cl
->module_idx
= pparam
->module_idx
;
1161 cl
->account
= first_client
->account
;
1163 if(!cl
->serialdata
&& !cs_malloc(&cl
->serialdata
, sizeof(struct s_serial_client
)))
1166 set_thread_name(__func__
);
1167 oscam_init_serialdata(cl
->serialdata
);
1168 oscam_copy_serialdata(cl
->serialdata
, &pparam
->serialdata
);
1169 if(cl
->serialdata
->oscam_ser_port
> 0)
1171 // reader struct for serial network connection
1172 struct s_reader
*newrdr
;
1173 if(!cs_malloc(&newrdr
, sizeof(struct s_reader
)))
1175 memset(newrdr
, 0, sizeof(struct s_reader
));
1176 newrdr
->client
= cl
;
1177 newrdr
->ph
= *serial_ph
;
1178 cl
->reader
= newrdr
;
1179 cs_strncpy(cl
->reader
->label
, "network-socket", sizeof(cl
->reader
->label
));
1181 cs_log("serial: initialized (%s@%s)", cl
->serialdata
->oscam_ser_proto
> P_MAX
?
1182 "auto" : proto_txt
[cl
->serialdata
->oscam_ser_proto
], cl
->serialdata
->oscam_ser_device
);
1184 SAFE_MUTEX_LOCK(&mutex
);
1186 SAFE_MUTEX_UNLOCK(&mutex
);
1187 SAFE_COND_SIGNAL(&cond
);
1191 cl
->login
= time((time_t *)0);
1192 cl
->pfd
= init_oscam_ser_device(cl
);
1194 { oscam_ser_server(); }
1196 { cs_sleepms(60000); } // retry in 1 min. (USB-Device ?)
1197 if(cl
->pfd
) { close(cl
->pfd
); }
1199 NULLFREE(cl
->serialdata
);
1200 NULLFREE(cl
->reader
);
1204 void *init_oscam_ser(struct s_client
*UNUSED(cl
), uchar
*UNUSED(mbuf
), int32_t module_idx
)
1208 struct s_thread_param param
;
1209 oscam_init_serialdata(¶m
.serialdata
);
1211 { cs_strncpy(sdevice
, cfg
.ser_device
, sizeof(sdevice
)); }
1213 { memset(sdevice
, 0, sizeof(sdevice
)); }
1214 param
.module_idx
= module_idx
;
1216 char cltype
= 'c'; //now auto should work
1217 if(bcopy_end
== -1) //mutex should be initialized only once
1219 cs_pthread_cond_init(__func__
, &mutex
, &cond
);
1222 while((p
= strrchr(sdevice
, ';')))
1225 if(!(p
+ 1) || (!(p
+ 1)[0])) { return NULL
; }
1226 if(!oscam_ser_parse_url(p
+ 1, ¶m
.serialdata
, &cltype
)) { return NULL
; }
1227 ret
= start_thread("oscam_ser_fork", oscam_ser_fork
, (void *) ¶m
, NULL
, 1, 1);
1234 oscam_wait_ser_fork();
1238 if(!sdevice
[0]) { return NULL
; }
1239 if(!oscam_ser_parse_url(sdevice
, ¶m
.serialdata
, &cltype
)) { return NULL
; }
1240 ret
= start_thread("oscam_ser_fork", oscam_ser_fork
, (void *) ¶m
, NULL
, 1, 1);
1247 oscam_wait_ser_fork();
1256 static int32_t oscam_ser_client_init(struct s_client
*client
)
1258 if(!client
->serialdata
&& !cs_malloc(&client
->serialdata
, sizeof(struct s_serial_client
)))
1261 oscam_init_serialdata(client
->serialdata
);
1263 if((!client
->reader
->device
[0])) { cs_disconnect_client(client
); }
1264 if(!oscam_ser_parse_url(client
->reader
->device
, client
->serialdata
, NULL
)) { cs_disconnect_client(client
); }
1265 client
->pfd
= init_oscam_ser_device(client
);
1267 if(client
->serialdata
->oscam_ser_proto
== P_TWIN
)
1271 client
->reader
->tcp_connected
= 1;
1272 client
->reader
->card_status
= CARD_INSERTED
;
1276 return ((client
->pfd
> 0) ? 0 : 1);
1279 static int32_t oscam_ser_twin_send(struct s_client
*client
, ECM_REQUEST
*er
)
1283 cs_debug_mask(D_CLIENT
, "found channel: %04X:%06X:%04X:%04X:%04X", tw
.caid
, tw
.provid
, tw
.deg
, tw
.freq
, tw
.srvid
);
1287 wbuf
[2] = tw
.deg
>>8;
1288 wbuf
[3] = tw
.deg
&0xff;
1289 wbuf
[4] = tw
.freq
>>8;
1290 wbuf
[5] = tw
.freq
&0xff;
1291 wbuf
[6] = tw
.srvid
>>8;
1292 wbuf
[7] = tw
.srvid
&0xff;
1293 wbuf
[8] = wbuf
[0]^wbuf
[1]^wbuf
[2]^wbuf
[3]^wbuf
[4]^wbuf
[5]^wbuf
[6]^wbuf
[7];
1294 oscam_ser_send(client
, wbuf
, 9);
1298 static int32_t oscam_ser_send_ecm(struct s_client
*client
, ECM_REQUEST
*er
)
1302 if(!cs_malloc(&buf
, er
->ecmlen
+ 12))
1307 switch(client
->serialdata
->oscam_ser_proto
)
1312 i2b_buf(2, er
->caid
, buf
+ 1);
1313 i2b_buf(3, er
->prid
, buf
+ 3);
1314 i2b_buf(2, er
->pid
, buf
+ 6);
1315 i2b_buf(2, er
->srvid
, buf
+ 10);
1316 memcpy(buf
+ 12, er
->ecm
, er
->ecmlen
);
1317 oscam_ser_send(client
, buf
, 12 + er
->ecmlen
);
1320 oscam_ser_send(client
, er
->ecm
, er
->ecmlen
);
1323 if(cs_malloc(&tmp
, er
->ecmlen
* 2 + 1))
1325 if(client
->serialdata
->dsr9500type
== P_DSR_WITHSID
)
1327 snprintf((char *)buf
, 512, "%c%08X%04X%s%04X\n\r",
1328 3, er
->prid
, er
->caid
, cs_hexdump(0, er
->ecm
, er
->ecmlen
, tmp
, er
->ecmlen
* 2 + 1), er
->srvid
);
1329 oscam_ser_send(client
, buf
, (er
->ecmlen
<< 1) + 19); // 1 + 8 + 4 + l*2 + 4 + 2
1333 snprintf((char *)buf
, 512, "%c%08X%04X%s\n\r",
1334 3, er
->prid
, er
->caid
, cs_hexdump(0, er
->ecm
, er
->ecmlen
, tmp
, er
->ecmlen
* 2 + 1));
1335 oscam_ser_send(client
, buf
, (er
->ecmlen
<< 1) + 15); // 1 + 8 + 4 + l*2 + 2
1342 i2b_buf(2, 2 + er
->ecmlen
, buf
+ 1);
1343 i2b_buf(2, er
->caid
, buf
+ 3);
1344 memcpy(buf
+ 5, er
->ecm
, er
->ecmlen
);
1345 oscam_ser_send(client
, buf
, oscam_ser_alpha_convert(buf
, 5 + er
->ecmlen
));
1348 oscam_ser_twin_send(client
, er
);
1355 static void oscam_ser_process_dcw(uchar
*dcw
, int32_t *rc
, uchar
*buf
, int32_t l
, struct s_client
*client
)
1357 switch(client
->serialdata
->oscam_ser_proto
)
1360 if((l
>= 23) && (buf
[2] == 0x3A) && (buf
[3] == 0x3A))
1364 for(i
= 4, crc
= HSIC_CRC
; i
< 20; i
++)
1368 memcpy(dcw
, buf
+ 4, 16);
1376 memcpy(dcw
, buf
, 16);
1381 if((l
>= 17) && (buf
[0] == 4))
1383 memcpy(dcw
, buf
+ 1, 16);
1388 if((l
>= 19) && (buf
[0] == 0x88))
1390 memcpy(dcw
, buf
+ 3, 16);
1395 if ((l
>= 19) && (buf
[0] == 0xF7))
1397 memcpy(dcw
, buf
+ 3, 16);
1403 static int32_t oscam_ser_recv_chk(struct s_client
*client
, uchar
*dcw
, int32_t *rc
, uchar
*buf
, int32_t n
)
1409 oscam_ser_process_dcw(dcw
, rc
, buf
+ 1, n
- 1, client
);
1412 return ((*rc
< 0) ? (-1) : 0); // idx not supported in serial module
1416 * protocol structure
1419 void module_serial(struct s_module
*ph
)
1421 ph
->desc
= "serial";
1422 ph
->type
= MOD_CONN_SERIAL
;
1423 ph
->large_ecm_support
= 1;
1424 ph
->listenertype
= LIS_SERIAL
;
1425 ph
->s_handler
= init_oscam_ser
;
1426 ph
->recv
= oscam_ser_recv
;
1427 ph
->send_dcw
= oscam_ser_send_dcw
;
1428 ph
->c_init
= oscam_ser_client_init
;
1429 ph
->c_recv_chk
= oscam_ser_recv_chk
;
1430 ph
->c_send_ecm
= oscam_ser_send_ecm
;