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", "extended", "unknown" };
64 // added to support multiple instances with thread
65 struct s_serial_client
70 char oscam_ser_usr
[32];
71 char oscam_ser_device
[64];
72 int32_t oscam_ser_port
;
73 speed_t oscam_ser_baud
;
74 int32_t oscam_ser_delay
;
75 int32_t oscam_ser_timeout
;
76 int32_t oscam_ser_proto
;
77 int32_t serial_errors
;
79 int32_t samsung_0a
; // number of 0A in ALL dcw sent into samsung
80 int32_t samsung_dcw
; // number of dcw sent into samsung before echo or ecm is received
83 SSSP_TAB sssp_tab
[SSSP_MAX_PID
];
89 static pthread_mutex_t mutex
;
90 static pthread_cond_t cond
;
91 static int32_t bcopy_end
= -1;
92 static struct s_module
*serial_ph
= NULL
;
97 struct s_serial_client serialdata
;
100 static int32_t chk_ser_srvid_match(uint16_t caid
, uint16_t sid
, uint32_t provid
, SIDTAB
*sidtab
)
104 if(!sidtab
->num_caid
)
107 for(i
= 0; (i
< sidtab
->num_caid
) && (!(rc
& 1)); i
++)
108 if(caid
== sidtab
->caid
[i
]) { rc
|= 1; }
110 if(!sidtab
->num_provid
)
113 for(i
= 0; (i
< sidtab
->num_provid
) && (!(rc
& 2)); i
++)
114 if(provid
== sidtab
->provid
[i
]) { rc
|= 2; }
116 if(!sidtab
->num_srvid
)
119 for(i
= 0; (i
< sidtab
->num_srvid
) && (!(rc
& 4)); i
++)
120 if(sid
== sidtab
->srvid
[i
]) { rc
|= 4; }
125 static int32_t chk_ser_srvid(struct s_client
*cl
, uint16_t caid
, uint16_t sid
, uint32_t provid
)
132 if(!cl
->sidtabs
.no
) { return (1); }
135 for(nr
= 0, sidtab
= cfg
.sidtab
; sidtab
; sidtab
= sidtab
->next
, nr
++)
136 if(sidtab
->num_caid
| sidtab
->num_provid
| sidtab
->num_srvid
)
138 if((cl
->sidtabs
.no
& ((SIDTABBITS
)1 << nr
)) &&
139 (chk_ser_srvid_match(caid
, sid
, provid
, sidtab
)))
141 if((cl
->sidtabs
.ok
& ((SIDTABBITS
)1 << nr
)) &&
142 (chk_ser_srvid_match(caid
, sid
, provid
, sidtab
)))
148 static void oscam_wait_ser_fork(void)
150 SAFE_MUTEX_LOCK(&mutex
);
159 { SAFE_COND_WAIT(&cond
, &mutex
); }
162 SAFE_MUTEX_UNLOCK(&mutex
);
165 static int32_t oscam_ser_alpha_convert(uint8_t *buf
, int32_t l
)
168 if(buf
[0] == 0x7E) // normalize
171 memmove(buf
, buf
+ 1, l
); // remove BOT/EOT
172 for(i
= 0; i
< l
; i
++)
175 memmove(buf
+ i
, buf
+ i
+ 1, --l
);
181 memmove(buf
+ 1, buf
, l
++); // insert BOT
183 for(i
= 1; i
< l
; i
++)
184 if((buf
[i
] == 0x20) || (buf
[i
] == 0x7E) || (buf
[i
] == 0x7F))
187 memmove(buf
+ i
+ 1, buf
+ i
, l
++);
190 buf
[l
++] = 0x7F; // insert EOT
195 static void oscam_ser_disconnect(void);
197 static int32_t oscam_ser_parse_url(char *url
, struct s_serial_client
*serialdata
, char *pcltype
)
199 char *service
, *usr
, *dev
, *baud
= NULL
, *dummy
, *para
;
202 cltype
= pcltype
? (*pcltype
) : cur_client()->typ
;
204 serialdata
->oscam_ser_proto
= P_AUTO
;
205 if((dummy
= strstr(url
, "://")))
211 for(i
= 1; i
<= P_MAX
; i
++)
212 if(!strcmp(service
, proto_txt
[i
]))
213 { serialdata
->oscam_ser_proto
= i
; }
215 if(!(cltype
== 'c') && (serialdata
->oscam_ser_proto
== P_AUTO
)) { return (0); }
217 switch(serialdata
->oscam_ser_proto
) // set the defaults
220 serialdata
->oscam_ser_timeout
= 500;
221 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
;
240 serialdata
->dsr9500type
= P_DSR_AUTO
;
241 serialdata
->oscam_ser_proto
= P_DSR95
;
245 if((dev
= strchr(usr
, '@')))
248 if((dummy
= strchr(usr
, ':'))) // fake pwd
250 if((cltype
== 'c') && (!usr
[0])) { return (0); }
254 if(cltype
== 'c') { return (0); } // user needed in server-mode
258 if((baud
= strchr(dev
, ':'))) // port = baud
261 dummy
= baud
? baud
: dev
;
262 if((para
= strchr(dummy
, '?')))
264 char *ptr1
, *ptr2
, *saveptr1
= NULL
;
266 for(ptr1
= strtok_r(para
, "&", &saveptr1
); ptr1
; ptr1
= strtok_r(NULL
, "&", &saveptr1
))
268 if(!(ptr2
= strchr(ptr1
, '='))) { continue; }
271 if(!strcmp("delay" , ptr1
)) { serialdata
->oscam_ser_delay
= atoi(ptr2
); }
272 if(!strcmp("timeout", ptr1
)) { serialdata
->oscam_ser_timeout
= atoi(ptr2
); }
280 if(!strcmp(baud
, "115200"))
281 { serialdata
->oscam_ser_baud
= B115200
; }
285 if(!strcmp(baud
, "57600"))
286 { serialdata
->oscam_ser_baud
= B57600
; }
289 if(!strcmp(baud
, "38400"))
290 { serialdata
->oscam_ser_baud
= B38400
; }
291 else if(!strcmp(baud
, "19200"))
292 { serialdata
->oscam_ser_baud
= B19200
; }
293 else if(!strcmp(baud
, "9600"))
294 { serialdata
->oscam_ser_baud
= B9600
; }
297 if((para
= strchr(dev
, ','))) // device = ip/hostname and port
300 serialdata
->oscam_ser_port
= atoi(para
);
303 { serialdata
->oscam_ser_port
= 0; }
304 cs_strncpy(serialdata
->oscam_ser_usr
, usr
, sizeof(serialdata
->oscam_ser_usr
));
305 cs_strncpy(serialdata
->oscam_ser_device
, dev
, sizeof(serialdata
->oscam_ser_device
));
306 return (serialdata
->oscam_ser_baud
);
309 static void oscam_ser_set_baud(struct termios
*tio
, speed_t baud
)
311 cfsetospeed(tio
, baud
);
312 cfsetispeed(tio
, baud
);
315 static int32_t oscam_ser_set_serial_device(int32_t fd
, speed_t baud
)
319 memset(&tio
, 0, sizeof(tio
));
320 //tio.c_cflag = (CS8 | CREAD | HUPCL | CLOCAL);
321 tio
.c_cflag
= (CS8
| CREAD
| CLOCAL
);
322 tio
.c_iflag
= IGNPAR
;
325 //#if !defined(__CYGWIN__)
326 oscam_ser_set_baud(&tio
, B1200
);
327 tcsetattr(fd
, TCSANOW
, &tio
);
330 oscam_ser_set_baud(&tio
, baud
);
331 return (tcsetattr(fd
, TCSANOW
, &tio
));
334 static int32_t oscam_ser_poll(int32_t event
, struct s_client
*client
)
340 msec
= comp_timeb(&client
->serialdata
->tpe
, &tpc
);
343 pfds
.fd
= cur_client()->pfd
;
346 if(poll(&pfds
, 1, msec
) != 1)
349 { return (((pfds
.revents
)&event
) == event
); }
352 static int32_t oscam_ser_write(struct s_client
*client
, const uint8_t *const buf
, int32_t n
)
355 for(i
= 0; (i
< n
) && (oscam_ser_poll(POLLOUT
, client
)); i
++)
357 if(client
->serialdata
->oscam_ser_delay
)
358 { cs_sleepms(client
->serialdata
->oscam_ser_delay
); }
359 if(write(client
->pfd
, buf
+ i
, 1) < 1)
365 static int32_t oscam_ser_send(struct s_client
*client
, const uint8_t *const buf
, int32_t l
)
368 struct s_serial_client
*serialdata
= client
->serialdata
;
369 if(!client
->pfd
) { return (0); }
370 cs_ftime(&serialdata
->tps
);
371 serialdata
->tpe
= client
->serialdata
->tps
;
372 add_ms_to_timeb(&serialdata
->tpe
, serialdata
->oscam_ser_timeout
);
373 add_ms_to_timeb(&serialdata
->tpe
, (l
* (serialdata
->oscam_ser_delay
+ 1)));
374 n
= oscam_ser_write(client
, buf
, l
);
375 cs_ftime(&serialdata
->tpe
);
376 cs_log_dump_dbg(D_CLIENT
, buf
, l
, "send %d of %d bytes to %s in %"PRId64
" ms", n
, l
, remote_txt(),
377 comp_timeb(&serialdata
->tpe
, &serialdata
->tps
));
379 { cs_log("transmit error. send %d of %d bytes only !", n
, l
); }
383 static int32_t oscam_ser_selrec(uint8_t *buf
, int32_t n
, int32_t l
, int32_t *c
)
388 if(n
<= 0) { return (0); }
389 for(i
= 0; (i
< n
) && (oscam_ser_poll(POLLIN
, cur_client())); i
++)
390 if(read(cur_client()->pfd
, buf
+ *c
, 1) < 1)
397 static int32_t oscam_ser_recv(struct s_client
*client
, uint8_t *xbuf
, int32_t l
)
400 uint8_t job
= IS_BAD
;
402 static int32_t have_lb
= 0;
403 uint8_t *buf
= xbuf
+ 1;
404 struct s_serial_client
*serialdata
= client
->serialdata
;
406 if(!client
->pfd
) { return (-1); }
407 cs_ftime(&serialdata
->tps
);
408 serialdata
->tpe
= serialdata
->tps
;
409 add_ms_to_timeb(&serialdata
->tpe
, serialdata
->oscam_ser_timeout
);
411 for(s
= p
= r
= 0, n
= have_lb
; (s
< 4) && (p
>= 0); s
++)
415 case 0: // STAGE 0: skip known garbage from DSR9500
416 if(oscam_ser_selrec(buf
, 2 - n
, l
, &n
))
418 if((buf
[0] == 0x0A) && (buf
[1] == 0x0D))
420 if((buf
[0] == 0x0D) && (buf
[1] == 0x0A))
428 case 1: // STAGE 1: identify protocol
430 if(oscam_ser_selrec(buf
, 1, l
, &n
)) // now we have 3 bytes in buf
432 // skip unsupported Advanced Serial Sharing Protocol HF 8900
433 if((buf
[0] == 0x04) && (buf
[1] == 0x00) && (buf
[2] == 0x02))
435 oscam_ser_selrec(buf
, 2, l
, &n
); // get rest 2 bytes to buffor
443 if(client
->typ
== 'c') // HERE IS SERVER
445 job
= IS_ECM
; // assume ECM
449 if((buf
[1] == 0x01) && (buf
[2] == 0x00))
453 serialdata
->tpe
.time
++;
458 if((buf
[1] & 0xf0) == 0xb0) { p
= P_GBOX
; }
464 break; // pmt-request
471 switch(serialdata
->oscam_ser_proto
)
476 p
= serialdata
->oscam_ser_proto
;
480 p
= (buf
[1] < 0x30) ? P_SSSP
: P_DSR95
;
481 break; // auto for GS is useless!!
488 serialdata
->dsr9500type
= P_DSR_GNUSMAS
;
493 if(buf
[1] != 0x80) { job
= IS_BAD
; }
502 else // HERE IS CLIENT
504 job
= IS_DCW
; // assume DCW
505 switch(serialdata
->oscam_ser_proto
)
508 if((buf
[0] == 4) && (buf
[1] == 4)) { p
= P_HSIC
; }
516 if(buf
[0] == 4) { p
= P_DSR95
; }
520 if(buf
[0] == 0x88) { p
= P_ALPHA
; }
524 if((buf
[0] == 0xF7) && (buf
[1] == 0x00) && (buf
[2] == 0x16)) { p
= P_TWIN
; }
529 if((serialdata
->oscam_ser_proto
!= p
) && (serialdata
->oscam_ser_proto
!= P_AUTO
))
535 case 2: // STAGE 2: examine length
536 if(client
->typ
== 'c')
541 r
= (buf
[1] << 8) | buf
[2];
549 if(oscam_ser_selrec(buf
, 12, l
, &n
)) { r
= buf
[14]; }
556 r
= 17 * serialdata
->samsung_dcw
- 3 + serialdata
->samsung_0a
;
557 serialdata
->samsung_dcw
= serialdata
->samsung_0a
= 0;
561 if(oscam_ser_selrec(buf
, 16, l
, &n
))
564 if(cs_atob(&b
, (char *)buf
+ 17, 1) < 0)
569 r
+= (serialdata
->dsr9500type
== P_DSR_WITHSID
) ? 4 : 0;
577 if(job
== IS_LGO
) { r
= 5; }
580 if(oscam_ser_selrec(buf
, 1, l
, &n
))
581 { r
= (buf
[3] << 8) | buf
[2]; }
587 r
= -0x7F; // char specifying EOT
591 r
= ((buf
[1] & 0xf) << 8) | buf
[2];
592 serialdata
->gbox_lens
.cat_len
= r
;
596 serialdata
->dsr9500type
= P_DSR_AUTO
;
604 r
= (buf
[2] == 0x3A) ? 20 : 0;
605 break; // 3A=DCW / FC=ECM was wrong
616 r
= (buf
[1] << 8) | buf
[2];
617 break; // should be 16 always
626 case 3: // STAGE 3: get the rest...
627 if(r
> 0) // read r additional bytes
630 if(!oscam_ser_selrec(buf
, r
, l
, &n
))
632 cs_log_dbg(D_CLIENT
, "not all data received, waiting another 50 ms");
633 add_ms_to_timeb(&serialdata
->tpe
, 50);
634 if(!oscam_ser_selrec(buf
, all
- n
, l
, &n
))
637 // auto detect DSR9500 protocol
638 if(client
->typ
== 'c' && p
== P_DSR95
&& serialdata
->dsr9500type
== P_DSR_AUTO
)
640 add_ms_to_timeb(&serialdata
->tpe
, 20);
641 if(oscam_ser_selrec(buf
, 2, l
, &n
))
643 if(cs_atoi((char *)buf
+ n
- 2, 1, 1) == 0xFFFFFFFF)
645 switch((buf
[n
- 2] << 8) | buf
[n
- 1])
648 serialdata
->dsr9500type
= P_DSR_OPEN
;
652 serialdata
->dsr9500type
= P_DSR_PIONEER
;
656 serialdata
->dsr9500type
= P_DSR_UNKNOWN
;
662 if(oscam_ser_selrec(buf
, 2, l
, &n
))
663 if(cs_atoi((char *)buf
+ n
- 2, 1, 1) == 0xFFFFFFFF)
664 { serialdata
->dsr9500type
= P_DSR_UNKNOWN
; }
666 { serialdata
->dsr9500type
= P_DSR_WITHSID
; }
669 serialdata
->dsr9500type
= P_DSR_UNKNOWN
;
675 { serialdata
->dsr9500type
= P_DSR_GNUSMAS
; }
677 cs_log("detected dsr9500-%s type receiver",
678 dsrproto_txt
[serialdata
->dsr9500type
]);
681 if(client
->typ
== 'c' && p
== P_GBOX
)
684 for(j
= 0; (j
< 3) && (p
> 0); j
++)
689 if(!oscam_ser_selrec(buf
, 3, l
, &n
))
691 else if(!(buf
[n
- 3] == 0x02 && (buf
[n
- 2] & 0xf0) == 0xb0))
695 case 1: // PMT + ECM header
696 serialdata
->gbox_lens
.pmt_len
= ((buf
[n
- 2] & 0xf) << 8) | buf
[n
- 1];
697 if(!oscam_ser_selrec(buf
, serialdata
->gbox_lens
.pmt_len
+ 3, l
, &n
))
701 case 2: // ECM + ECM PID
702 serialdata
->gbox_lens
.ecm_len
= ((buf
[n
- 2] & 0xf) << 8) | buf
[n
- 1];
703 if(!oscam_ser_selrec(buf
, serialdata
->gbox_lens
.ecm_len
+ 4, l
, &n
))
709 else if(r
< 0) // read until specified char (-r)
711 while((buf
[n
- 1] != (-r
)) && (p
> 0))
712 if(!oscam_ser_selrec(buf
, 1, l
, &n
))
719 if(p
== (-2) || p
== (-1))
721 oscam_ser_selrec(buf
, l
- n
, l
, &n
); // flush buffer
722 serialdata
->serial_errors
++;
725 cs_ftime(&serialdata
->tpe
);
726 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
));
727 client
->last
= serialdata
->tpe
.time
;
732 if(client
->typ
== 'c' && (n
> 2) && (buf
[0] == 2) && (buf
[1] == 2) && (buf
[2] == 2))
734 oscam_ser_disconnect();
735 cs_log("humax powered on"); // this is nice ;)
739 if(client
->typ
== 'c' && buf
[0] == 0x1 && buf
[1] == 0x08 && buf
[2] == 0x20 && buf
[3] == 0x08)
741 oscam_ser_disconnect();
742 cs_log("ferguson powered on"); // this is nice to ;)
745 cs_log("incomplete request (%d bytes)", n
);
750 cs_log_dbg(D_CLIENT
, "unknown request or garbage");
754 xbuf
[0] = (uint8_t)((job
<< 4) | p
);
755 return ((p
< 0) ? 0 : n
+ 1);
762 static void oscam_ser_disconnect_client(void)
765 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
767 switch(serialdata
->connected
? serialdata
->connected
: serialdata
->oscam_ser_proto
)
774 oscam_ser_send(cur_client(), mbuf
, 4);
777 serialdata
->dsr9500type
= P_DSR_AUTO
;
778 serialdata
->serial_errors
= 0;
781 static void oscam_ser_init_client(void)
784 switch(cur_client()->serialdata
->oscam_ser_proto
) // sure, does not work in auto-mode
787 oscam_ser_disconnect_client(); // send disconnect first
788 cs_sleepms(300); // wait a little bit
793 oscam_ser_send(cur_client(), mbuf
, 4); // send connect
798 static void oscam_ser_disconnect(void)
800 oscam_ser_disconnect_client();
801 if(cur_client()->serialdata
->connected
)
802 { cs_log("%s disconnected (%s)", username(cur_client()), proto_txt
[cur_client()->serialdata
->connected
]); }
803 cur_client()->serialdata
->connected
= 0;
806 static void oscam_ser_auth_client(int32_t proto
)
809 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
810 // After reload base account ptrs may be placed in other address,
811 // and we may can't find it in this process.
812 // Simply save valid account.
813 struct s_auth
*account
= 0;
815 if(serialdata
->connected
== proto
)
817 if(serialdata
->connected
)
818 { oscam_ser_disconnect(); }
819 serialdata
->connected
= proto
;
821 for(ok
= 0, account
= cfg
.account
; (account
) && (!ok
); account
= account
->next
)
822 if((ok
= !strcmp(serialdata
->oscam_ser_usr
, account
->usr
)))
824 cs_auth_client(cur_client(), ok
? account
: (struct s_auth
*)(-1), proto_txt
[serialdata
->connected
]);
827 static void oscam_ser_send_dcw(struct s_client
*client
, ECM_REQUEST
*er
)
832 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
834 if(er
->rc
< E_NOTFOUND
) // found
836 switch(serialdata
->connected
)
839 for(i
= 0, crc
= HSIC_CRC
; i
< 16; i
++)
840 { crc
^= er
->cw
[i
]; }
841 memset(mbuf
, 0x04, 2);
842 memset(mbuf
+ 2, 0x3a, 2);
843 memcpy(mbuf
+ 4, er
->cw
, 16);
844 memcpy(mbuf
+ 20, &crc
, 1);
845 memset(mbuf
+ 21, 0x1b, 2);
846 oscam_ser_send(client
, mbuf
, 23);
853 memcpy(mbuf
+ 3, er
->cw
, 16);
854 oscam_ser_send(client
, mbuf
, 19);
855 if(!serialdata
->sssp_fix
)
860 i2b_buf(2, er
->pid
, mbuf
+ 3);
861 oscam_ser_send(client
, mbuf
, 5);
862 serialdata
->sssp_fix
= 1;
868 oscam_ser_send(client
, er
->cw
, 16);
873 memcpy(mbuf
+ 1, er
->cw
, 16);
874 oscam_ser_send(client
, mbuf
, 17);
875 if(serialdata
->dsr9500type
== P_DSR_GNUSMAS
)
877 serialdata
->samsung_0a
= 0;
878 for(i
= 1; i
< 17; i
++)
880 { serialdata
->samsung_0a
++; }
881 serialdata
->samsung_dcw
++;
890 memcpy(mbuf
+ 4, er
->cw
, 16);
891 oscam_ser_send(client
, mbuf
, 20);
898 memcpy(mbuf
+ 3, er
->cw
, 16);
899 oscam_ser_send(client
, mbuf
, 19);
905 switch(serialdata
->connected
)
912 oscam_ser_send(client
, mbuf
, 4);
916 serialdata
->serial_errors
= 0; // clear error counter
919 static void oscam_ser_process_pmt(uint8_t *buf
, int32_t l
)
923 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
925 switch(serialdata
->connected
)
928 serialdata
->sssp_fix
= 0;
929 memset(serialdata
->sssp_tab
, 0, sizeof(serialdata
->sssp_tab
));
930 serialdata
->sssp_srvid
= b2i(2, buf
+ 3);
931 serialdata
->sssp_num
= 0;
933 for(i
= 9; (i
< l
) && (serialdata
->sssp_num
< SSSP_MAX_PID
); i
+= 7)
935 // check support for pid (caid, sid and provid in oscam.services)
936 if(chk_ser_srvid(cur_client(), b2i(2, buf
+ i
), b2i(2, buf
+ 3), b2i(3, buf
+ i
+ 4)))
938 memcpy(sbuf
+ 3 + (serialdata
->sssp_num
<< 1), buf
+ i
+ 2, 2);
939 serialdata
->sssp_tab
[serialdata
->sssp_num
].caid
= b2i(2, buf
+ i
);
940 serialdata
->sssp_tab
[serialdata
->sssp_num
].pid
= b2i(2, buf
+ i
+ 2);
941 serialdata
->sssp_tab
[serialdata
->sssp_num
].prid
= b2i(3, buf
+ i
+ 4);
942 serialdata
->sssp_num
++;
948 sbuf
[2] = (serialdata
->sssp_num
<< 1);
949 oscam_ser_send(cur_client(), sbuf
, sbuf
[2] + 3);
954 static void oscam_ser_client_logon(uint8_t *buf
, int32_t l
)
956 uint8_t gs_logon
[] = {0, 1, 0, 0, 2, 1, 0, 0};
958 switch(cur_client()->serialdata
->connected
)
961 if((l
>= 8) && (!memcmp(buf
, gs_logon
, 8)))
967 oscam_ser_send(cur_client(), buf
, 4);
973 static int32_t oscam_ser_check_ecm(ECM_REQUEST
*er
, uint8_t *buf
, int32_t l
)
976 struct s_serial_client
*serialdata
= cur_client()->serialdata
;
980 cs_log("incomplete request (%d bytes)", l
);
984 switch(serialdata
->connected
)
988 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
990 er
->caid
= b2i(2, buf
+ 1);
991 er
->prid
= b2i(3, buf
+ 3);
992 er
->pid
= b2i(2, buf
+ 6);
993 er
->srvid
= b2i(2, buf
+ 10);
994 memcpy(er
->ecm
, buf
+ 12, er
->ecmlen
);
998 er
->pid
= b2i(2, buf
+ 3);
1000 for(i
= 0; (i
< 8) && (serialdata
->sssp_tab
[i
].pid
!= er
->pid
); i
++) { ; }
1002 if(i
>= serialdata
->sssp_num
)
1004 cs_log_dbg(D_CLIENT
, "illegal request, unknown pid=%04X", er
->pid
);
1008 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
1010 er
->srvid
= serialdata
->sssp_srvid
;
1011 er
->caid
= serialdata
->sssp_tab
[i
].caid
;
1012 er
->prid
= serialdata
->sssp_tab
[i
].prid
;
1013 memcpy(er
->ecm
, buf
+ 5, er
->ecmlen
);
1018 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
1020 memcpy(er
->ecm
, buf
, er
->ecmlen
);
1024 buf
[l
] = '\0'; // prepare for trim
1025 trim((char *)buf
+ 13); // strip spc, nl, cr ...
1026 er
->ecmlen
= cs_strlen((char *)buf
+ 13) >> 1;
1027 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
1029 er
->prid
= cs_atoi((char *)buf
+ 3, 3, 0); // ignore errors
1030 er
->caid
= cs_atoi((char *)buf
+ 9, 2, 0); // ignore errors
1031 if(cs_atob(er
->ecm
, (char *)buf
+ 13, er
->ecmlen
) < 0)
1033 cs_log("illegal characters in ecm-request");
1036 if(serialdata
->dsr9500type
== P_DSR_WITHSID
)
1041 er
->srvid
= cs_atoi((char *)buf
+ 13 + (er
->ecmlen
<< 1), 2, 0);
1046 er
->ecmlen
= ((buf
[3] << 8) | buf
[2]) - 6;
1047 er
->srvid
= (buf
[5] << 8) | buf
[4]; // sid
1048 er
->caid
= (buf
[7] << 8) | buf
[6];
1051 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
|| (10 + er
->ecmlen
> l
))
1053 memcpy(er
->ecm
, buf
+ 10, er
->ecmlen
);
1057 l
= oscam_ser_alpha_convert(buf
, l
);
1058 er
->ecmlen
= b2i(2, buf
+ 1) - 2;
1059 er
->caid
= b2i(2, buf
+ 3);
1060 if((er
->ecmlen
!= l
- 5) || (er
->ecmlen
> MAX_ECM_SIZE
) || (er
->ecmlen
< 0))
1062 cs_log("incomplete request (%d bytes)", l
);
1065 memcpy(er
->ecm
, buf
+ 5, er
->ecmlen
);
1069 if(((serialdata
->gbox_lens
.cat_len
+ 3 + 3 + 1) > l
)
1070 || ((serialdata
->gbox_lens
.ecm_len
+ 3) > l
))
1074 er
->srvid
= b2i(2, buf
+ serialdata
->gbox_lens
.cat_len
+ 3 + 3);
1075 er
->ecmlen
= serialdata
->gbox_lens
.ecm_len
+ 3;
1077 if(er
->ecmlen
< 0 || er
->ecmlen
> MAX_ECM_SIZE
)
1079 if(serialdata
->gbox_lens
.cat_len
+ 3 + serialdata
->gbox_lens
.pmt_len
+ 3 + er
->ecmlen
> l
)
1082 memcpy(er
->ecm
, buf
+ serialdata
->gbox_lens
.cat_len
+ 3 + serialdata
->gbox_lens
.pmt_len
+ 3, er
->ecmlen
);
1088 static void oscam_ser_process_ecm(uint8_t *buf
, int32_t l
)
1092 if(!(er
= get_ecmtask()))
1095 switch(oscam_ser_check_ecm(er
, buf
, l
))
1100 //er->rc = E_CORRUPT;
1102 return; // error without log
1104 er
->rc
= E_CORRUPT
; // error with log
1107 get_cw(cur_client(), er
);
1111 static void oscam_ser_server(void)
1115 int32_t *pserial_errors
= &cur_client()->serialdata
->serial_errors
;
1117 cur_client()->serialdata
->connected
= 0;
1118 oscam_ser_init_client();
1120 while((n
= process_input(mbuf
, sizeof(mbuf
), INT_MAX
)) > 0)
1122 if((*pserial_errors
) > 3)
1124 cs_log("too many errors, reiniting...");
1128 oscam_ser_auth_client(mbuf
[0] & 0xF);
1129 switch(mbuf
[0] >> 4)
1132 oscam_ser_process_ecm(mbuf
+ 1, n
- 1);
1135 oscam_ser_process_pmt(mbuf
+ 1, n
- 1);
1138 oscam_ser_client_logon(mbuf
+ 1, n
- 1);
1143 if(cur_client()->serialdata
->oscam_ser_port
> 0)
1144 { network_tcp_connection_close(cur_client()->reader
, "error reading from socket"); }
1145 oscam_ser_disconnect();
1148 static int32_t init_oscam_ser_device(struct s_client
*cl
)
1150 char *device
= cl
->serialdata
->oscam_ser_device
;
1151 speed_t baud
= cl
->serialdata
->oscam_ser_baud
;
1152 int32_t port
= cl
->serialdata
->oscam_ser_port
;
1155 // network connection to a TCP-exposed serial port
1158 cs_strncpy(cl
->reader
->device
, device
, sizeof(cl
->reader
->device
));
1159 cl
->reader
->r_port
= cl
->port
= port
;
1160 fd
= network_tcp_connection_open(cl
->reader
);
1166 else // standard serial port connection
1168 fd
= open(device
, O_RDWR
| O_NOCTTY
| O_SYNC
| O_NONBLOCK
);
1171 fcntl(fd
, F_SETFL
, 0);
1172 if(oscam_ser_set_serial_device(fd
, baud
) < 0) { cs_log("ERROR ioctl"); }
1173 if(tcflush(fd
, TCIOFLUSH
) < 0) { cs_log("ERROR flush"); }
1178 cs_log("ERROR opening %s (errno=%d %s)", device
, errno
, strerror(errno
));
1184 static void oscam_copy_serialdata(struct s_serial_client
*dest
, struct s_serial_client
*src
)
1188 dest
->connected
= src
->connected
;
1189 memcpy(&dest
->tps
, &src
->tps
, sizeof(dest
->tps
));
1190 memcpy(&dest
->tpe
, &src
->tpe
, sizeof(dest
->tpe
));
1191 memcpy(&dest
->oscam_ser_usr
, &src
->oscam_ser_usr
, sizeof(dest
->oscam_ser_usr
));
1192 memcpy(&dest
->oscam_ser_device
, &src
->oscam_ser_device
, sizeof(dest
->oscam_ser_device
));
1193 dest
->oscam_ser_port
= src
->oscam_ser_port
;
1194 dest
->oscam_ser_baud
= src
->oscam_ser_baud
;
1195 dest
->oscam_ser_delay
= src
->oscam_ser_delay
;
1196 dest
->oscam_ser_timeout
= src
->oscam_ser_timeout
;
1197 dest
->oscam_ser_proto
= src
->oscam_ser_proto
;
1198 dest
->serial_errors
= src
->serial_errors
;
1199 dest
->dsr9500type
= src
->dsr9500type
;
1200 dest
->samsung_0a
= src
->samsung_0a
; // number of 0A in ALL dcw sent into samsung
1201 dest
->samsung_dcw
= src
->samsung_dcw
; // number of dcw sent into samsung before echo or ecm is received
1203 dest
->gbox_lens
= src
->gbox_lens
;
1204 memcpy(&dest
->sssp_tab
, &src
->sssp_tab
, sizeof(dest
->sssp_tab
));
1205 dest
->sssp_srvid
= src
->sssp_srvid
;
1206 dest
->sssp_num
= src
->sssp_num
;
1207 dest
->sssp_fix
= src
->sssp_fix
;
1211 static void oscam_init_serialdata(struct s_serial_client
*dest
)
1215 memset(dest
, 0, sizeof(struct s_serial_client
));
1216 dest
->oscam_ser_timeout
= 50;
1217 dest
->dsr9500type
= P_DSR_AUTO
;
1221 static void *oscam_ser_fork(void *pthreadparam
)
1223 struct s_thread_param
*pparam
= (struct s_thread_param
*) pthreadparam
;
1224 struct s_client
*cl
= create_client(get_null_ip());
1225 SAFE_SETSPECIFIC(getclient
, cl
);
1226 cl
->thread
= pthread_self();
1228 cl
->module_idx
= pparam
->module_idx
;
1229 cl
->account
= first_client
->account
;
1231 if(!cl
->serialdata
&& !cs_malloc(&cl
->serialdata
, sizeof(struct s_serial_client
)))
1234 set_thread_name(__func__
);
1235 oscam_init_serialdata(cl
->serialdata
);
1236 oscam_copy_serialdata(cl
->serialdata
, &pparam
->serialdata
);
1238 if(cl
->serialdata
->oscam_ser_port
> 0)
1240 // reader struct for serial network connection
1241 struct s_reader
*newrdr
;
1242 if(!cs_malloc(&newrdr
, sizeof(struct s_reader
)))
1244 memset(newrdr
, 0, sizeof(struct s_reader
));
1245 newrdr
->client
= cl
;
1246 newrdr
->ph
= *serial_ph
;
1247 cl
->reader
= newrdr
;
1248 cs_strncpy(cl
->reader
->label
, "network-socket", sizeof(cl
->reader
->label
));
1251 cs_log("serial: initialized (%s@%s)", cl
->serialdata
->oscam_ser_proto
> P_MAX
?
1252 "auto" : proto_txt
[cl
->serialdata
->oscam_ser_proto
], cl
->serialdata
->oscam_ser_device
);
1254 SAFE_MUTEX_LOCK(&mutex
);
1256 SAFE_MUTEX_UNLOCK(&mutex
);
1257 SAFE_COND_SIGNAL(&cond
);
1261 cl
->login
= time((time_t *)0);
1262 cl
->pfd
= init_oscam_ser_device(cl
);
1264 { oscam_ser_server(); }
1266 { cs_sleepms(60000); } // retry in 1 min. (USB-Device ?)
1267 if(cl
->pfd
) { close(cl
->pfd
); }
1269 NULLFREE(cl
->serialdata
);
1270 NULLFREE(cl
->reader
);
1274 void *init_oscam_ser(struct s_client
*UNUSED(cl
), uint8_t *UNUSED(mbuf
), int32_t module_idx
)
1278 struct s_thread_param param
;
1279 oscam_init_serialdata(¶m
.serialdata
);
1282 { cs_strncpy(sdevice
, cfg
.ser_device
, sizeof(sdevice
)); }
1284 { memset(sdevice
, 0, sizeof(sdevice
)); }
1286 param
.module_idx
= module_idx
;
1288 char cltype
= 'c'; // now auto should work
1290 if(bcopy_end
== -1) // mutex should be initialized only once
1292 cs_pthread_cond_init(__func__
, &mutex
, &cond
);
1296 while((p
= strrchr(sdevice
, ';')))
1301 if(!(q
) || (!(q
)[0])) { return NULL
; }
1302 if(!oscam_ser_parse_url(p
+ 1, ¶m
.serialdata
, &cltype
)) { return NULL
; }
1304 ret
= start_thread("oscam_ser_fork", oscam_ser_fork
, (void *) ¶m
, NULL
, 1, 1);
1311 oscam_wait_ser_fork();
1315 if(!sdevice
[0]) { return NULL
; }
1316 if(!oscam_ser_parse_url(sdevice
, ¶m
.serialdata
, &cltype
)) { return NULL
; }
1318 ret
= start_thread("oscam_ser_fork", oscam_ser_fork
, (void *) ¶m
, NULL
, 1, 1);
1325 oscam_wait_ser_fork();
1334 static int32_t oscam_ser_client_init(struct s_client
*client
)
1336 if(!client
->serialdata
&& !cs_malloc(&client
->serialdata
, sizeof(struct s_serial_client
)))
1339 oscam_init_serialdata(client
->serialdata
);
1341 if((!client
->reader
->device
[0])) { cs_disconnect_client(client
); }
1342 if(!oscam_ser_parse_url(client
->reader
->device
, client
->serialdata
, NULL
)) { cs_disconnect_client(client
); }
1343 client
->pfd
= init_oscam_ser_device(client
);
1345 if(client
->serialdata
->oscam_ser_proto
== P_TWIN
)
1349 client
->reader
->tcp_connected
= 1;
1350 client
->reader
->card_status
= CARD_INSERTED
;
1354 return ((client
->pfd
> 0) ? 0 : 1);
1357 static int32_t oscam_ser_twin_send(struct s_client
*client
, ECM_REQUEST
*er
)
1361 cs_debug_mask(D_CLIENT
, "found channel: %04X:%06X:%04X:%04X:%04X", tw
.caid
, tw
.provid
, tw
.deg
, tw
.freq
, tw
.srvid
);
1365 wbuf
[2] = tw
.deg
>> 8;
1366 wbuf
[3] = tw
.deg
& 0xff;
1367 wbuf
[4] = tw
.freq
>> 8;
1368 wbuf
[5] = tw
.freq
& 0xff;
1369 wbuf
[6] = tw
.srvid
>> 8;
1370 wbuf
[7] = tw
.srvid
& 0xff;
1371 wbuf
[8] = wbuf
[0] ^ wbuf
[1] ^ wbuf
[2] ^ wbuf
[3] ^ wbuf
[4] ^ wbuf
[5] ^ wbuf
[6] ^ wbuf
[7];
1372 oscam_ser_send(client
, wbuf
, 9);
1376 static int32_t oscam_ser_send_ecm(struct s_client
*client
, ECM_REQUEST
*er
)
1380 if(!cs_malloc(&buf
, er
->ecmlen
+ 12))
1385 switch(client
->serialdata
->oscam_ser_proto
)
1390 i2b_buf(2, er
->caid
, buf
+ 1);
1391 i2b_buf(3, er
->prid
, buf
+ 3);
1392 i2b_buf(2, er
->pid
, buf
+ 6);
1393 i2b_buf(2, er
->srvid
, buf
+ 10);
1394 memcpy(buf
+ 12, er
->ecm
, er
->ecmlen
);
1395 oscam_ser_send(client
, buf
, 12 + er
->ecmlen
);
1399 oscam_ser_send(client
, er
->ecm
, er
->ecmlen
);
1403 if(cs_malloc(&tmp
, er
->ecmlen
* 2 + 1))
1405 if(client
->serialdata
->dsr9500type
== P_DSR_WITHSID
)
1407 snprintf((char *)buf
, 512, "%c%08X%04X%s%04X\n\r",
1408 3, er
->prid
, er
->caid
, cs_hexdump(0, er
->ecm
, er
->ecmlen
, tmp
, er
->ecmlen
* 2 + 1), er
->srvid
);
1409 oscam_ser_send(client
, buf
, (er
->ecmlen
<< 1) + 19); // 1 + 8 + 4 + l*2 + 4 + 2
1413 snprintf((char *)buf
, 512, "%c%08X%04X%s\n\r",
1414 3, er
->prid
, er
->caid
, cs_hexdump(0, er
->ecm
, er
->ecmlen
, tmp
, er
->ecmlen
* 2 + 1));
1415 oscam_ser_send(client
, buf
, (er
->ecmlen
<< 1) + 15); // 1 + 8 + 4 + l*2 + 2
1423 i2b_buf(2, 2 + er
->ecmlen
, buf
+ 1);
1424 i2b_buf(2, er
->caid
, buf
+ 3);
1425 memcpy(buf
+ 5, er
->ecm
, er
->ecmlen
);
1426 oscam_ser_send(client
, buf
, oscam_ser_alpha_convert(buf
, 5 + er
->ecmlen
));
1430 oscam_ser_twin_send(client
, er
);
1437 static void oscam_ser_process_dcw(uint8_t *dcw
, int32_t *rc
, uint8_t *buf
, int32_t l
, struct s_client
*client
)
1439 switch(client
->serialdata
->oscam_ser_proto
)
1442 if((l
>= 23) && (buf
[2] == 0x3A) && (buf
[3] == 0x3A))
1446 for(i
= 4, crc
= HSIC_CRC
; i
< 20; i
++)
1450 memcpy(dcw
, buf
+ 4, 16);
1459 memcpy(dcw
, buf
, 16);
1465 if((l
>= 17) && (buf
[0] == 4))
1467 memcpy(dcw
, buf
+ 1, 16);
1473 if((l
>= 19) && (buf
[0] == 0x88))
1475 memcpy(dcw
, buf
+ 3, 16);
1481 if ((l
>= 19) && (buf
[0] == 0xF7))
1483 memcpy(dcw
, buf
+ 3, 16);
1489 static int32_t oscam_ser_recv_chk(struct s_client
*client
, uint8_t *dcw
, int32_t *rc
, uint8_t *buf
, int32_t n
)
1496 oscam_ser_process_dcw(dcw
, rc
, buf
+ 1, n
- 1, client
);
1499 return ((*rc
< 0) ? (-1) : 0); // idx not supported in serial module
1503 * protocol structure
1506 void module_serial(struct s_module
*ph
)
1508 ph
->desc
= "serial";
1509 ph
->type
= MOD_CONN_SERIAL
;
1510 ph
->large_ecm_support
= 1;
1511 ph
->listenertype
= LIS_SERIAL
;
1512 ph
->s_handler
= init_oscam_ser
;
1513 ph
->recv
= oscam_ser_recv
;
1514 ph
->send_dcw
= oscam_ser_send_dcw
;
1515 ph
->c_init
= oscam_ser_client_init
;
1516 ph
->c_recv_chk
= oscam_ser_recv_chk
;
1517 ph
->c_send_ecm
= oscam_ser_send_ecm
;