- reduced binary size with AES constants, there was twice included (thanks to lpm11...
[oscam.git] / module-camd35.c
blob9cce8123156c8f94054f8231bf318e5171e26e62
1 #define MODULE_LOG_PREFIX "camd35"
3 #include "globals.h"
4 #if defined MODULE_CAMD35 || defined MODULE_CAMD35_TCP
6 #include "cscrypt/md5.h"
7 #include "module-cacheex.h"
8 #include "module-camd35.h"
9 #include "module-camd35-cacheex.h"
10 #include "oscam-aes.h"
11 #include "oscam-chk.h"
12 #include "oscam-cache.h"
13 #include "oscam-client.h"
14 #include "oscam-ecm.h"
15 #include "oscam-emm.h"
16 #include "oscam-net.h"
17 #include "oscam-string.h"
18 #include "oscam-reader.h"
20 //CMD00 - ECM (request)
21 //CMD01 - ECM (response)
22 //CMD02 - EMM (in clientmode - set EMM, in server mode - EMM data) - obsolete
23 //CMD03 - ECM (cascading request)
24 //CMD04 - ECM (cascading response)
25 //CMD05 - EMM (emm request) send cardata/cardinfo to client
26 //CMD06 - EMM (incomming EMM in server mode)
27 //CMD19 - EMM (incomming EMM in server mode) only seen with caid 0x1830
28 //CMD08 - Stop sending requests to the server for current srvid, prvid, caid
29 //CMD44 - MPCS/OScam internal error notification
30 //CMD55 - connect_on_init/keepalive
32 //CMD0x3c - CACHEEX Cache-push filter request
33 //CMD0x3d - CACHEEX Cache-push id request
34 //CMD0x3e - CACHEEX Cache-push id answer
35 //CMD0x3f - CACHEEX cache-push
37 //used variable ncd_skey for storing remote node id: ncd_skey[0..7] : 8
38 //bytes node id ncd_skey[8] : 1=valid node id received
40 #define REQ_SIZE 20 + MAX_ECM_SIZE + 0x34
42 static int32_t __camd35_send(struct s_client *cl, uint8_t *buf, int32_t buflen, int answer_awaited)
44 int32_t l, status;
45 uint8_t rbuf[4 + REQ_SIZE + 15];
46 uint8_t *sbuf = rbuf + 4;
48 if(!cl->udp_fd || !cl->crypted)
50 return -1; // exit if no fd or aes key not set
53 // Fix ECM len > 255
54 if(buflen <= 0)
56 buflen = (buf[0] == 0) ? (((buf[21] & 0x0F) << 8) | buf[22]) + 3 : buf[1];
58 l = 20 + (((buf[0] == 3) || (buf[0] == 4)) ? 0x34 : 0) + buflen;
60 memcpy(rbuf, cl->ucrc, 4);
61 memcpy(sbuf, buf, l);
62 memset(sbuf + l, 0xFF, 15); // set unused space to 0xFF for newer camd3's
63 i2b_buf(4, crc32(0L, sbuf + 20, buflen), sbuf + 4);
64 l = boundary(4, l);
66 cs_log_dump_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, sbuf, l, "send %d bytes to %s", l, username(cl));
68 aes_encrypt_idx(cl->aes_keys, sbuf, l);
70 if(cl->is_udp)
72 status = sendto(cl->udp_fd, rbuf, l + 4, 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
73 if(status == -1)
75 set_null_ip(&SIN_GET_ADDR(cl->udp_sa));
78 else
80 status = send(cl->udp_fd, rbuf, l + 4, 0);
82 if(cl->typ == 'p' && cl->reader)
84 if(status == -1)
86 network_tcp_connection_close(cl->reader, "can't send");
89 else if(cl->typ == 'c')
91 if(status == -1)
93 cs_disconnect_client(cl);
98 if(status != -1)
100 if(cl->reader && answer_awaited)
102 cl->reader->last_s = time(NULL);
105 if(cl->reader && !answer_awaited)
107 cl->reader->last_s = cl->reader->last_g = time(NULL);
110 cl->last = time(NULL);
113 return status;
116 int32_t camd35_send(struct s_client *cl, uint8_t *buf, int32_t buflen)
118 // send command and set sending time because we await response
119 return __camd35_send(cl, buf, buflen, 1);
122 int32_t camd35_send_without_timeout(struct s_client *cl, uint8_t *buf, int32_t buflen)
124 // send command and do NOT set sending time because we DON'T await response
125 return __camd35_send(cl, buf, buflen, 0);
128 static int32_t camd35_auth_client(struct s_client *cl, uint8_t *ucrc)
130 int32_t rc = 1, no_delay = 1;
131 uint32_t crc;
132 struct s_auth *account;
133 uint8_t md5tmp[MD5_DIGEST_LENGTH];
135 if(cl->upwd[0])
137 return memcmp(cl->ucrc, ucrc, 4) ? 1 : 0;
140 cl->crypted = 1;
142 crc = ((ucrc[0] << 24) | (ucrc[1] << 16) | (ucrc[2] << 8) | ucrc[3]) & 0xffffffffL;
144 for(account = cfg.account; account && (!cl->upwd[0]); account = account->next)
146 if(crc == crc32(0L, MD5((uint8_t *)account->usr, cs_strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH))
148 rc = cs_auth_client(cl, account, NULL);
149 if(!rc)
151 memcpy(cl->ucrc, ucrc, 4);
152 cs_strncpy((char *)cl->upwd, account->pwd, sizeof(cl->upwd));
153 if(!aes_set_key_alloc(&cl->aes_keys, (char *) MD5(cl->upwd, cs_strlen((char *)cl->upwd), md5tmp)))
155 return 1;
158 #ifdef CS_CACHEEX
159 if(cl->account->cacheex.mode < 2)
160 #endif
161 if(!cl->is_udp && cl->tcp_nodelay == 0)
163 setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_delay, sizeof(no_delay));
164 cl->tcp_nodelay = 1;
167 return 0;
172 return (rc);
175 static int32_t camd35_recv(struct s_client *client, uint8_t *buf, int32_t l)
177 int32_t rc, s, rs, n = 0, buflen = 0, len = 0;
179 for(rc = rs = s = 0; !rc; s++)
181 switch(s)
183 case 0:
185 if(!client->udp_fd)
187 return -9;
190 if(client->is_udp && client->typ == 'c')
192 rs = recv_from_udpipe(buf);
194 else
196 // read minimum packet size (4 byte ucrc + 32 byte data)
197 // to detect packet size (tcp only)
199 //rs = cs_recv(client->udp_fd, buf, client->is_udp ? l : 36, 0);
201 if(client->is_udp)
203 while (1)
205 rs = cs_recv(client->udp_fd, buf, l, 0);
206 if(rs < 0)
208 if(errno == EINTR)
210 continue; // try again in case of interrupt
213 if(errno == EAGAIN)
215 continue; // EAGAIN needs select procedure again
218 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)",
219 __func__, errno, strerror(errno));
220 break;
222 else
224 break;
228 else
230 int32_t tot = 36, readed = 0;
231 rs = 0;
235 readed = cs_recv(client->udp_fd, buf + rs, tot, 0);
236 if(readed < 0)
238 if(errno == EINTR)
240 continue; // try again in case of interrupt
243 if(errno == EAGAIN)
245 continue; // EAGAIN needs select procedure again
248 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)",
249 __func__, errno, strerror(errno));
250 break;
253 if(readed == 0) // nothing to read left!
255 rc = -5;
256 break;
259 if(readed > 0) // received something, add it!
261 tot -= readed;
262 rs += readed;
265 while(tot != 0);
269 if(rs < 36)
271 if(rc != -5)
273 rc = -1;
276 goto out;
279 break;
282 case 1:
284 switch(camd35_auth_client(client, buf))
286 case 0:
287 #ifdef CS_CACHEEX_AIO
288 if(!client->c35_extmode)
290 camd35_send_extmode(client, false);
291 client->c35_extmode = 1;
293 #endif
294 break; // ok
296 case 1:
297 rc = -2;
298 break; // unknown user
300 default:
301 rc = -9;
302 break; // error's from cs_auth()
305 memmove(buf, buf + 4, rs -= 4);
306 break;
309 case 2:
311 aes_decrypt(client->aes_keys, buf, rs);
313 if(rs != boundary(4, rs))
315 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
316 "WARNING: packet size has wrong decryption boundary");
319 n = (buf[0] == 3) ? 0x34 : 0;
321 // Fix for ECM request size > 255 (use ecm length field)
322 if(buf[0] == 0)
324 buflen = (((buf[21] & 0x0F) << 8) | buf[22]) + 3;
326 else if(
327 #ifdef CS_CACHEEX_AIO
328 buf[0] == 0x40 || buf[0] == 0x41 || buf[0] == 0x42 ||
329 #endif
330 buf[0] == 0x3D || buf[0] == 0x3E || buf[0] == 0x3F
331 ) // cacheex-push
333 buflen = buf[1] | (buf[2] << 8);
335 else
337 buflen = buf[1];
340 n = boundary(4, n + 20 + buflen);
342 if(!(client->is_udp && client->typ == 'c') && (rs < n) && ((n - 32) > 0))
344 //len = cs_recv(client->udp_fd, buf+32, n-32, 0); // read the rest of the packet
346 int32_t tot = n - 32;
347 int32_t readed = 0;
348 len = 0;
352 readed = cs_recv(client->udp_fd, buf + 32 + len, tot, 0); // read the rest of the packet
353 if(readed < 0)
355 if(errno == EINTR)
357 continue; // try again in case of interrupt
360 if(errno == EAGAIN)
362 continue; // EAGAIN needs select procedure again
365 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)",
366 __func__, errno, strerror(errno));
367 break;
370 if(readed == 0) // nothing to read left
372 break;
375 if(readed > 0) // received something, add it
377 tot -= readed;
378 len += readed;
381 while(tot != 0);
384 if(len > 0)
386 rs += len;
387 aes_decrypt(client->aes_keys, buf + 32, len);
390 if(len < 0)
392 rc = -1;
393 goto out;
397 cs_log_dump_dbg(client->typ == 'c' ? D_CLIENT : D_READER, buf, rs, "received %d bytes from %s",
398 rs, remote_txt());
400 if(n < rs)
402 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ignoring %d bytes of garbage", rs - n);
404 else if(n > rs)
406 rc = -3;
409 break;
412 case 3:
414 if(crc32(0L, buf + 20, buflen) != b2i(4, buf + 4))
416 rc = -4;
419 if(!rc)
421 rc = n;
424 break;
429 out:
430 if((rs > 0) && ((rc == -1) || (rc == -2)))
432 cs_log_dump_dbg(client->typ == 'c' ? D_CLIENT : D_READER, buf, rs,
433 "received %d bytes from %s (native)", rs, remote_txt());
436 if(rc >= 0)
438 client->last = time(NULL); // last client action is now
441 switch(rc)
443 //case 0:
444 // break;
446 case -1:
447 cs_log("packet is too small (received %d bytes, expected %d bytes)", rs, l);
448 break;
450 case -2:
451 if(cs_auth_client(client, 0, "unknown user"))
453 cs_disconnect_client(client);
455 break;
457 case -3:
458 cs_log("incomplete request!");
459 break;
461 case -4:
462 cs_log("checksum error (wrong password?)");
463 break;
465 case -5:
466 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "connection closed");
467 break;
469 //default:
470 // cs_log_dbg(D_TRACE, "camd35_recv returns rc=%d", rc);
471 // break;
474 return (rc);
478 * server functions
481 static void camd35_request_emm(ECM_REQUEST *er)
483 int32_t i;
484 time_t now;
485 uint8_t mbuf[1024];
486 struct s_client *cl = cur_client();
487 struct s_reader *aureader = NULL, *rdr = NULL;
489 if(er->selected_reader && !er->selected_reader->audisabled
490 && ll_contains(cl->aureader_list, er->selected_reader))
492 aureader = er->selected_reader;
495 if(!aureader && cl->aureader_list)
497 LL_ITER itr = ll_iter_create(cl->aureader_list);
499 while((rdr = ll_iter_next(&itr)))
501 if(emm_reader_match(rdr, er->caid, er->prid))
503 aureader = rdr;
504 break;
509 if(!aureader)
511 return; // TODO
514 uint16_t au_caid = aureader->caid;
516 // Bulcrypt has two caids and aureader->caid can't be used.
517 // Use ECM_REQUEST caid for AU.
518 if(!au_caid && caid_is_bulcrypt(er->caid))
520 au_caid = er->caid;
523 time(&now);
525 if(!memcmp(cl->lastserial, aureader->hexserial, 8))
527 if(llabs(now - cl->last) < 180)
529 return;
533 memcpy(cl->lastserial, aureader->hexserial, 8);
534 cl->last = now;
536 if(au_caid)
538 cl->disable_counter = 0;
540 cs_log("%s emm-request sent (reader=%s, caid=%04X, auprovid=%06X)", username(cur_client()),
541 aureader->label, au_caid, aureader->auprovid ? aureader->auprovid : b2i(4, aureader->prid[0]));
543 else if(cl->disable_counter > 2)
545 return;
547 else
549 cl->disable_counter++;
552 memset(mbuf, 0, sizeof(mbuf));
553 mbuf[2] = mbuf[3] = 0xFF; // must not be zero
554 i2b_buf(2, er->srvid, mbuf + 8);
556 // override request provid with auprovid if set in CMD05
557 if(aureader->auprovid)
559 if(aureader->auprovid != er->prid)
561 i2b_buf(4, aureader->auprovid, mbuf + 12);
563 else
565 i2b_buf(4, er->prid, mbuf + 12);
568 else
570 i2b_buf(4, er->prid, mbuf + 12);
573 i2b_buf(2, er->pid, mbuf + 16);
574 mbuf[0] = 5;
575 mbuf[1] = 111;
577 if(au_caid)
579 mbuf[39] = 1; // no. caids
580 mbuf[20] = au_caid >> 8; // caid's (max 8)
581 mbuf[21] = au_caid & 0xFF;
582 memcpy(mbuf + 40, aureader->hexserial, 6); // serial now 6 bytes
583 mbuf[47] = aureader->nprov;
585 for(i = 0; i < aureader->nprov; i++)
587 if(caid_is_betacrypt(au_caid) || caid_is_irdeto(au_caid))
589 mbuf[48 + (i * 5)] = aureader->prid[i][0];
590 memcpy(&mbuf[50 + (i * 5)], &aureader->prid[i][1], 3);
592 else
594 mbuf[48 + (i * 5)] = aureader->prid[i][2];
595 mbuf[49 + (i * 5)] = aureader->prid[i][3];
596 memcpy(&mbuf[50 + (i * 5)], &aureader->sa[i][0], 4); // for conax we need at least 4 bytes
600 // we think client/server protocols should deliver
601 // all information, and only readers should discard EMM
602 mbuf[128] = (aureader->blockemm & EMM_GLOBAL && !(aureader->saveemm & EMM_GLOBAL)) ? 0 : 1;
603 mbuf[129] = (aureader->blockemm & EMM_SHARED && !(aureader->saveemm & EMM_SHARED)) ? 0 : 1;
604 mbuf[130] = (aureader->blockemm & EMM_UNIQUE && !(aureader->saveemm & EMM_UNIQUE)) ? 0 : 1;
605 mbuf[127] = (aureader->blockemm & EMM_UNKNOWN && !(aureader->saveemm & EMM_UNKNOWN)) ? 0 : 1;
607 else // disable emm
609 mbuf[20] = mbuf[39] = mbuf[40] = mbuf[47] = mbuf[49] = 1;
612 memcpy(mbuf + 10, mbuf + 20, 2);
613 camd35_send(cl, mbuf, 0); // send with data-len 111 for camd3 > 3.890
614 mbuf[1]++;
615 camd35_send(cl, mbuf, 0); // send with data-len 112 for camd3 < 3.890
618 static void camd35_send_dcw(struct s_client *client, ECM_REQUEST *er)
620 uint8_t *buf;
621 buf = er->src_data; // get orig request
623 if(!buf)
625 rdr_log(client->reader, "ERROR: src_data missing");
626 return;
629 if(er->rc == E_INVALID && !client->c35_suppresscmd08) // send normal CMD08
631 buf[0] = 0x08;
632 buf[1] = 2;
633 memset(buf + 20, 0, buf[1]);
634 buf[22] = er->rc; // put rc in byte 22 - hopefully don't break legacy camd3
636 else if(er->rc == E_STOPPED) // send sleep CMD08
638 buf[0] = 0x08;
639 buf[1] = 2;
640 buf[20] = 0;
641 buf[21] = 0xFF;
643 cs_log("%s stop request send", client->account->usr);
645 else
647 // Send CW
648 if((er->rc < E_NOTFOUND) || (er->rc == E_FAKE))
650 if(buf[0] == 3)
652 memmove(buf + 20 + 16, buf + 20 + buf[1], 0x34);
655 #ifdef CS_CACHEEX_AIO
656 if(er->localgenerated && client->c35_extmode > 1)
658 buf[0] += 0x51; // ecm response with lg-flag
660 else
662 #endif
663 buf[0]++; // ecm response (CMD01 or CMD04)
664 #ifdef CS_CACHEEX_AIO
666 #endif
667 buf[1] = 16;
668 camd35_cacheex_init_dcw(client, er);
669 memcpy(buf + 20, er->cw, buf[1]);
671 else
673 // Send old CMD44 to prevent cascading
674 // problems with older mpcs/oscam versions
675 buf[0] = 0x44;
676 buf[1] = 0;
680 camd35_send(client, buf, 0);
681 camd35_request_emm(er);
684 static void camd35_process_ecm(uint8_t *buf, int buflen)
686 ECM_REQUEST *er;
688 if(!buf || buflen < 23)
690 return;
693 uint16_t ecmlen = SCT_LEN((&buf[20]));
695 if(ecmlen > MAX_ECM_SIZE || ecmlen + 20 > buflen || ecmlen < 4)
697 return;
700 if(!(er = get_ecmtask()))
702 return;
705 er->ecmlen = ecmlen;
707 if(!cs_malloc(&er->src_data, 0x34 + 20 + er->ecmlen))
709 NULLFREE(er);
710 return;
713 memcpy(er->src_data, buf, 0x34 + 20 + er->ecmlen); // save request
714 er->srvid = b2i(2, buf + 8);
715 er->caid = b2i(2, buf + 10);
716 er->prid = b2i(4, buf + 12);
717 //er->idx = b2i(2, buf + 16); // ecmtask idx (see camd35_recv_chk)
718 memcpy(er->ecm, buf + 20, er->ecmlen);
720 get_cw(cur_client(), er);
723 static void camd35_process_emm(uint8_t *buf, int buflen, int emmlen)
725 EMM_PACKET epg;
727 if(!buf || buflen < 20 || emmlen + 20 > buflen)
729 return;
732 memset(&epg, 0, sizeof(epg));
734 epg.emmlen = emmlen;
735 if(epg.emmlen < 3 || epg.emmlen > MAX_EMM_SIZE)
737 return;
740 memcpy(epg.caid, buf + 10, 2);
741 memcpy(epg.provid, buf + 12 , 4);
742 memcpy(epg.emm, buf + 20, epg.emmlen);
744 do_emm(cur_client(), &epg);
747 int32_t camd35_tcp_connect(struct s_client *cl)
749 if(cl->is_udp) // check for udp client
751 if(!IP_ISSET(SIN_GET_ADDR(cl->udp_sa))) // check ip is set
753 if(!(hostResolve(cl->reader))) // no ip -> try to resolve ip of client
755 network_tcp_connection_close(cl->reader, "no ip");
756 return 0;
761 if(!cl->reader->tcp_connected) // client not connected
763 int32_t handle = 0;
764 handle = network_tcp_connection_open(cl->reader); // try to connect
765 if(handle < 0) // got no handle -> error!
767 cl->reader->last_s = 0; // set last send to zero
768 cl->reader->last_g = 0; // set last receive to zero
769 cl->last = 0; // set last client action to zero
771 return 0;
774 cl->reader->tcp_connected = 1;
775 cl->reader->card_status = CARD_INSERTED;
776 cl->reader->last_s = time(NULL); // reset last send
777 cl->reader->last_g = time(NULL); // reset last receive
778 cl->last = time(NULL); // reset last client action
779 cl->pfd = cl->udp_fd = handle;
782 if(!cl->udp_fd) // Check if client has no handle -> error
784 return 0;
787 // check if client reached timeout
788 if(cl->reader->tcp_rto && (cl->reader->last_s - cl->reader->last_g > cl->reader->tcp_rto))
790 if(!cl->is_udp) // tcp on timeout disconnect reader
792 network_tcp_connection_close(cl->reader, "rto");
793 return 0;
795 else //udp check to discover ip change on dynamic ip servers
797 IN_ADDR_T last_ip;
798 IP_ASSIGN(last_ip, cl->ip);
800 if(!hostResolve(cl->reader))
802 network_tcp_connection_close(cl->reader, "no ip");
803 return 0;
806 if(!IP_EQUAL(last_ip, cl->ip))
808 network_tcp_connection_close(cl->reader, "ip change");
809 return 0;
814 return 1; // all ok
818 * client functions
821 static void camd35_send_keepalive(struct s_client *cl)
823 if(cl->reader)
825 if(camd35_tcp_connect(cl))
827 if(cacheex_get_rdr_mode(cl->reader) > 1)
829 camd35_cacheex_push_request_remote_id(cl);
830 return;
833 uint8_t rbuf[32]; // minimal size
834 memset(rbuf, 0, sizeof(rbuf));
836 rbuf[0] = 55;
837 rbuf[1] = 1;
838 rbuf[2] = 0;
840 camd35_send(cl, rbuf, 1); // send adds +20
845 static void camd35_send_keepalive_answer(struct s_client *cl)
847 if(check_client(cl) && cl->account)
849 uint8_t rbuf[32]; // minimal size
850 memset(rbuf, 0, sizeof(rbuf));
852 rbuf[0] = 55;
853 rbuf[1] = 1;
854 rbuf[2] = 0;
856 camd35_send(cl, rbuf, 1); // send adds +20
860 static int32_t camd35_client_init(struct s_client *cl)
862 uint8_t md5tmp[MD5_DIGEST_LENGTH];
863 int32_t no_delay = 1;
865 cs_strncpy((char *)cl->upwd, cl->reader->r_pwd, sizeof(cl->upwd));
866 i2b_buf(4, crc32(0L, MD5((uint8_t *)cl->reader->r_usr, cs_strlen(cl->reader->r_usr), md5tmp), 16), cl->ucrc);
868 if(!aes_set_key_alloc(&cl->aes_keys, (char *)MD5(cl->upwd, cs_strlen((char *)cl->upwd), md5tmp)))
870 return 1;
873 cl->crypted = 1;
875 rdr_log(cl->reader, "proxy %s:%d", cl->reader->device, cl->reader->r_port);
877 if(!cl->is_udp && cacheex_get_rdr_mode(cl->reader) < 2)
879 setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_delay, sizeof(no_delay));
882 if(cl->reader->keepalive)
884 camd35_send_keepalive(cl);
887 if(cacheex_get_rdr_mode(cl->reader) == 2
888 #ifdef CS_CACHEEX_AIO
889 || cacheex_get_rdr_mode(cl->reader) == 1
890 #endif
893 camd35_cacheex_send_push_filter(cl, 2);
894 #ifdef CS_CACHEEX_AIO
895 camd35_cacheex_feature_request(cl);
896 #endif
899 #ifdef CS_CACHEEX_AIO
900 if(!cl->c35_extmode)
902 camd35_send_extmode(cl, false);
903 cl->c35_extmode = 1;
905 #endif
907 return 0;
910 static void camd35_idle(void)
912 struct s_client *cl = cur_client();
914 if(!cl->reader)
916 return;
919 if(cl->reader->keepalive)
921 camd35_send_keepalive(cl);
923 else if(cl->reader->tcp_ito > 0) // only check if user added an inactivity timeout
925 // inactivity timeout check
926 time_t now;
927 int32_t time_diff;
929 time(&now);
930 time_diff = llabs(now - cl->reader->last_s);
932 if(time_diff > cl->reader->tcp_ito)
934 if(check_client(cl) && cl->reader->tcp_connected && cl->reader->ph.type == MOD_CONN_TCP)
936 rdr_log_dbg(cl->reader, D_READER, "inactive_timeout, close connection (fd=%d)", cl->pfd);
937 network_tcp_connection_close(cl->reader, "inactivity");
939 else
941 cl->reader->last_s = now;
947 static void *camd35_server(struct s_client *client, uint8_t *mbuf, int32_t n)
949 if(!client || !mbuf)
951 return NULL;
954 if(client->reader)
956 client->reader->last_g = time(NULL); // last receive is now
958 if(mbuf[0] == 6 || mbuf[0] == 19) // check for emm command
960 // fixup: last send is now (if client is only
961 // sending emms, connection would be dropped!)
962 client->reader->last_s = time(NULL);
965 rdr_log(client->reader, "SERVER last = %d, last_s = %d, last_g = %d",
966 (int) client->last, (int) client->reader->last_s, (int) client->reader->last_g);
969 client->last = time(NULL); // last client action is now
971 switch(mbuf[0])
973 case 0: // ECM
974 case 3: // ECM (cascading)
975 camd35_process_ecm(mbuf, n);
976 break;
978 case 6: // EMM
979 case 19: // EMM
980 if(n > 2)
982 camd35_process_emm(mbuf, n, mbuf[1]);
984 break;
986 case 55:
987 camd35_send_keepalive_answer(client); // keepalive msg
988 break;
989 #ifdef CS_CACHEEX_AIO
990 case 0x43:
991 break;
992 case 0x50:
993 client->c35_extmode = 2;
994 break;
995 #endif
996 default:
997 if(!camd35_cacheex_server(client, mbuf))
999 cs_log("unknown [cs357x/cs378x] command from %s! (%d) n=%d", username(client), mbuf[0], n);
1003 return NULL;
1006 static int32_t camd35_send_ecm(struct s_client *client, ECM_REQUEST *er)
1008 static const char *typtext[] = { "ok", "invalid", "sleeping" };
1010 if(client->stopped)
1012 if(er->srvid == client->lastsrvid && er->caid == client->lastcaid)
1014 cs_log("%s is stopped - requested by server (%s)", client->reader->label, typtext[client->stopped]);
1015 return -1;
1017 else
1019 client->stopped = 0;
1023 client->lastsrvid = er->srvid;
1024 client->lastcaid = er->caid;
1025 client->lastpid = er->pid;
1027 if(!camd35_tcp_connect(client))
1029 return -1;
1032 client->reader->card_status = CARD_INSERTED; // for udp
1034 uint8_t *buf;
1035 if(!cs_malloc(&buf, 20 + er->ecmlen + 15))
1037 return -1;
1040 memset(buf, 0, 20);
1041 memset(buf + 20, 0xFF, er->ecmlen + 15);
1043 buf[1] = er->ecmlen;
1044 i2b_buf(2, er->srvid, buf + 8);
1045 i2b_buf(2, er->caid, buf + 10);
1046 i2b_buf(4, er->prid, buf + 12);
1047 i2b_buf(2, er->idx, buf + 16);
1048 buf[18] = 0xFF;
1049 buf[19] = 0xFF;
1050 memcpy(buf + 20, er->ecm, er->ecmlen);
1052 int32_t rc = (camd35_send(client, buf, 0) < 1) ? -1 : 0;
1054 NULLFREE(buf);
1055 return rc;
1058 static int32_t camd35_send_emm(EMM_PACKET *ep)
1060 uint8_t *buf;
1061 struct s_client *cl = cur_client();
1063 if(!camd35_tcp_connect(cl))
1065 return 0;
1068 cl->reader->card_status = CARD_INSERTED; // for udp
1070 if(!cs_malloc(&buf, ep->emmlen + 20 + 15))
1072 return -1;
1075 memset(buf, 0, 20);
1076 memset(buf + 20, 0xFF, ep->emmlen + 15);
1078 buf[0] = 0x06;
1079 buf[1] = ep->emmlen;
1080 memcpy(buf + 10, ep->caid, 2);
1081 memcpy(buf + 12, ep->provid, 4);
1082 memcpy(buf + 20, ep->emm, ep->emmlen);
1084 int32_t rc = (camd35_send_without_timeout(cl, buf, 0) < 1) ? 0 : 1;
1086 NULLFREE(buf);
1087 return rc;
1090 static int32_t camd35_recv_chk(struct s_client *client, uint8_t *dcw, int32_t *rc, uint8_t *buf, int32_t rc2 __attribute__((unused)))
1092 uint16_t idx;
1093 static const char *typtext[] = { "ok", "invalid", "sleeping" };
1094 struct s_reader *rdr = client->reader;
1096 rdr->last_g = time(NULL); // last receive is now
1098 // reading CMD05 Emm request and set serial
1099 if(buf[0] == 0x05 && buf[1] == 111)
1101 //cs_log("CMD05: %s", cs_hexdump(1, buf, buf[1], tmp, sizeof(tmp)));
1103 rdr->nprov = 0; // reset if number changes on reader change
1104 rdr->nprov = buf[47];
1105 rdr->caid = b2i(2, buf + 20);
1107 int32_t i;
1108 for(i = 0; i < rdr->nprov; i++)
1110 if(caid_is_betacrypt(rdr->caid) || caid_is_irdeto(rdr->caid))
1112 rdr->prid[i][0] = buf[48 + (i * 5)];
1113 memcpy(&rdr->prid[i][1], &buf[50 + (i * 5)], 3);
1115 else
1117 rdr->prid[i][2] = buf[48 + (i * 5)];
1118 rdr->prid[i][3] = buf[49 + (i * 5)];
1119 memcpy(&rdr->sa[i][0], &buf[50 + (i * 5)], 4);
1123 memcpy(rdr->hexserial, buf + 40, 6);
1124 rdr->hexserial[6] = 0;
1125 rdr->hexserial[7] = 0;
1127 if(cfg.getblockemmauprovid)
1129 rdr->blockemm = 0;
1130 rdr->blockemm |= (buf[128] == 1) ? 0 : EMM_GLOBAL;
1131 rdr->blockemm |= (buf[129] == 1) ? 0 : EMM_SHARED;
1132 rdr->blockemm |= (buf[130] == 1) ? 0 : EMM_UNIQUE;
1133 rdr->blockemm |= (buf[127] == 1) ? 0 : EMM_UNKNOWN;
1134 rdr->auprovid = b2i(4, buf + 12);
1137 cs_log("%s CMD05 AU request for caid: %04X auprovid: %06X",
1138 rdr->label, rdr->caid, rdr->auprovid);
1141 bool rc_invalid = 0;
1143 if(buf[0] == 0x08 && ((rdr->ph.type == MOD_CONN_TCP && !cfg.c35_tcp_suppresscmd08)
1144 || (rdr->ph.type == MOD_CONN_UDP && !cfg.c35_udp_suppresscmd08)))
1146 if(buf[21] == 0xFF)
1148 client->stopped = 2; // server says sleep
1149 rdr->card_status = NO_CARD;
1151 else
1153 if(config_enabled(WITH_LB) && cfg.lb_mode)
1155 rc_invalid = 1;
1157 else
1159 client->stopped = 1; // server says invalid
1160 rdr->card_status = CARD_FAILURE;
1164 cs_log("%s CMD08 (%02X - %d) stop request by server (%s)",
1165 rdr->label, buf[21], buf[21], typtext[client->stopped]);
1168 if(camd35_cacheex_recv_chk(client, buf))
1170 return -1;
1173 if(buf[0] == 55) // keepalive answer
1175 return -1;
1178 #ifdef CS_CACHEEX_AIO
1179 if(buf[0] == 0x50)
1181 client->c35_extmode = 2;
1183 if(buf[12] != 1) // answer
1184 camd35_send_extmode(client, true);
1185 return -1;
1187 #endif
1188 // CMD44: old reject command introduced in mpcs
1189 // keeping this for backward compatibility
1190 if((buf[0] != 1) && (buf[0] != 0x44) && (buf[0] != 0x08)
1191 #ifdef CS_CACHEEX_AIO
1192 && (buf[0] != 0x51)
1193 #endif
1196 return -1;
1199 idx = b2i(2, buf + 16);
1200 camd35_cacheex_recv_ce1_cwc_info(client, buf, idx);
1202 *rc = ((buf[0] != 0x44) && (buf[0] != 0x08));
1204 if(rc_invalid)
1206 *rc = 2; // INVALID sent by CMD08
1208 #ifdef CS_CACHEEX_AIO
1209 if(buf[0] == 0x51 || buf[0] == 0x54) // lg-flag
1211 *rc = 0x86;
1212 client->c35_extmode = 2;
1214 #endif
1216 memcpy(dcw, buf + 20, 16);
1218 return idx;
1221 #ifdef CS_CACHEEX_AIO
1222 void camd35_send_extmode(struct s_client *cl, bool answer)
1224 uint8_t rbuf[32]; // minimal size
1225 memset(rbuf, 0, sizeof(rbuf));
1227 rbuf[0] = 0x50;
1228 rbuf[1] = 1;
1229 rbuf[2] = 0;
1230 if(answer)
1231 rbuf[12] = 1;
1233 if(cl->reader)
1235 if(camd35_tcp_connect(cl))
1237 camd35_send(cl, rbuf, 1); // send adds +20
1240 else if(check_client(cl) && cl->account)
1242 camd35_send(cl, rbuf, 1); // send adds +20
1245 #endif
1248 * module definitions
1250 #ifdef MODULE_CAMD35
1251 void module_camd35(struct s_module *ph)
1253 ph->ptab.nports = 1;
1254 ph->ptab.ports[0].s_port = cfg.c35_port;
1256 ph->desc = "cs357x";
1257 ph->type = MOD_CONN_UDP;
1258 ph->large_ecm_support = 1;
1259 ph->listenertype = LIS_CAMD35UDP;
1260 IP_ASSIGN(ph->s_ip, cfg.c35_srvip);
1261 ph->s_handler = camd35_server;
1262 ph->recv = camd35_recv;
1263 ph->send_dcw = camd35_send_dcw;
1264 ph->c_init = camd35_client_init;
1265 ph->c_recv_chk = camd35_recv_chk;
1266 ph->c_send_ecm = camd35_send_ecm;
1267 ph->c_send_emm = camd35_send_emm;
1268 ph->c_idle = camd35_idle;
1269 camd35_cacheex_module_init(ph);
1270 ph->num = R_CAMD35;
1272 #endif
1274 #ifdef MODULE_CAMD35_TCP
1275 void module_camd35_tcp(struct s_module *ph)
1277 ph->desc = "cs378x";
1278 ph->type = MOD_CONN_TCP;
1279 ph->large_ecm_support = 1;
1280 ph->listenertype = LIS_CAMD35TCP;
1281 ph->ptab = cfg.c35_tcp_ptab;
1282 IP_ASSIGN(ph->s_ip, cfg.c35_tcp_srvip);
1283 ph->s_handler = camd35_server;
1284 ph->recv = camd35_recv;
1285 ph->send_dcw = camd35_send_dcw;
1286 ph->c_init = camd35_client_init;
1287 ph->c_recv_chk = camd35_recv_chk;
1288 ph->c_send_ecm = camd35_send_ecm;
1289 ph->c_send_emm = camd35_send_emm;
1290 ph->c_idle = camd35_idle;
1291 camd35_cacheex_module_init(ph);
1292 ph->num = R_CS378X;
1294 #endif
1296 #endif