- Add support of ORF P4 Irdeto mode
[oscam.git] / module-camd35.c
blob16eec279d861e84583a8c564bce6e7618bc93380
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 MAX_ECM_SIZE + 20 + 0x34
42 static int32_t __camd35_send(struct s_client *cl, uchar *buf, int32_t buflen, int answer_awaited)
44 int32_t l;
45 unsigned char rbuf[REQ_SIZE + 15 + 4], *sbuf = rbuf + 4;
47 if(!cl->udp_fd || !cl->crypted) { return (-1); } //exit if no fd or aes key not set!
49 //Fix ECM len > 255
50 if(buflen <= 0)
51 { buflen = ((buf[0] == 0) ? (((buf[21] & 0x0f) << 8) | buf[22]) + 3 : buf[1]); }
52 l = 20 + (((buf[0] == 3) || (buf[0] == 4)) ? 0x34 : 0) + buflen;
53 memcpy(rbuf, cl->ucrc, 4);
54 memcpy(sbuf, buf, l);
55 memset(sbuf + l, 0xff, 15); // set unused space to 0xff for newer camd3's
56 i2b_buf(4, crc32(0L, sbuf + 20, buflen), sbuf + 4);
57 l = boundary(4, l);
58 cs_log_dump_dbg(cl->typ == 'c' ? D_CLIENT : D_READER, sbuf, l, "send %d bytes to %s", l, username(cl));
59 aes_encrypt_idx(cl->aes_keys, sbuf, l);
61 int32_t status;
62 if(cl->is_udp)
64 status = sendto(cl->udp_fd, rbuf, l + 4, 0, (struct sockaddr *)&cl->udp_sa, cl->udp_sa_len);
65 if(status == -1) { set_null_ip(&SIN_GET_ADDR(cl->udp_sa)); }
67 else
69 status = send(cl->udp_fd, rbuf, l + 4, 0);
71 if(cl->typ == 'p' && cl->reader)
73 if(status == -1) { network_tcp_connection_close(cl->reader, "can't send"); }
75 else if(cl->typ == 'c')
77 if(status == -1) { cs_disconnect_client(cl); }
80 if(status != -1)
82 if(cl->reader && answer_awaited)
84 cl->reader->last_s = time(NULL);
86 if(cl->reader && !answer_awaited)
88 cl->reader->last_s = cl->reader->last_g = time(NULL);
90 cl->last = time(NULL);
93 return status;
96 int32_t camd35_send(struct s_client *cl, uchar *buf, int32_t buflen)
98 // send command and set sending time because we await response
99 return __camd35_send(cl, buf, buflen, 1);
102 int32_t camd35_send_without_timeout(struct s_client *cl, uchar *buf, int32_t buflen)
104 // send command and do NOT set sending time because we DON'T await response
105 return __camd35_send(cl, buf, buflen, 0);
108 static int32_t camd35_auth_client(struct s_client *cl, uchar *ucrc)
110 int32_t rc = 1, no_delay = 1;
111 uint32_t crc;
112 struct s_auth *account;
113 unsigned char md5tmp[MD5_DIGEST_LENGTH];
115 if(cl->upwd[0])
116 { return (memcmp(cl->ucrc, ucrc, 4) ? 1 : 0); }
117 cl->crypted = 1;
118 crc = (((ucrc[0] << 24) | (ucrc[1] << 16) | (ucrc[2] << 8) | ucrc[3]) & 0xffffffffL);
119 for(account = cfg.account; (account) && (!cl->upwd[0]); account = account->next)
120 if(crc == crc32(0L, MD5((unsigned char *)account->usr, strlen(account->usr), md5tmp), MD5_DIGEST_LENGTH))
122 rc = cs_auth_client(cl, account, NULL);
123 if(!rc)
125 memcpy(cl->ucrc, ucrc, 4);
126 cs_strncpy((char *)cl->upwd, account->pwd, sizeof(cl->upwd));
127 if (!aes_set_key_alloc(&cl->aes_keys, (char *) MD5(cl->upwd, strlen((char *)cl->upwd), md5tmp)))
129 return 1;
132 #ifdef CS_CACHEEX
133 if(cl->account->cacheex.mode < 2)
134 #endif
135 if(!cl->is_udp && cl->tcp_nodelay == 0)
137 setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_delay, sizeof(no_delay));
138 cl->tcp_nodelay = 1;
141 return 0;
144 return (rc);
147 static int32_t camd35_recv(struct s_client *client, uchar *buf, int32_t l)
149 int32_t rc, s, rs, n = 0, buflen = 0, len = 0;
150 for(rc = rs = s = 0; !rc; s++)
152 switch(s)
154 case 0:
155 if(!client->udp_fd) { return (-9); }
156 if(client->is_udp && client->typ == 'c')
158 rs = recv_from_udpipe(buf);
160 else
162 //read minimum packet size (4 byte ucrc + 32 byte data) to detect packet size (tcp only)
164 //rs = cs_recv(client->udp_fd, buf, client->is_udp ? l : 36, 0);
165 if(client->is_udp){
166 while (1){
167 rs = cs_recv(client->udp_fd, buf, l, 0);
168 if (rs < 0){
169 if(errno == EINTR) { continue; } // try again in case of interrupt
170 if(errno == EAGAIN) { continue; } //EAGAIN needs select procedure again
171 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
172 break;
173 }else {break;}
175 }else{
176 int32_t tot=36, readed=0;
177 rs = 0;
180 readed = cs_recv(client->udp_fd, buf+rs, tot, 0);
181 if (readed < 0){
182 if(errno == EINTR) { continue; } // try again in case of interrupt
183 if(errno == EAGAIN) { continue; } //EAGAIN needs select procedure again
184 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
185 break;
187 if (readed == 0){ // nothing to read left!
188 rc = -5;
189 break;
191 if (readed > 0){ // received something, add it!
192 tot-=readed;
193 rs+=readed;
196 while(tot!=0);
200 if(rs < 36)
202 if(rc != -5)
203 { rc = -1; }
204 goto out;
206 break;
207 case 1:
208 switch(camd35_auth_client(client, buf))
210 case 0:
211 break; // ok
212 case 1:
213 rc = -2;
214 break; // unknown user
215 default:
216 rc = -9;
217 break; // error's from cs_auth()
219 memmove(buf, buf + 4, rs -= 4);
220 break;
221 case 2:
222 aes_decrypt(client->aes_keys, buf, rs);
223 if(rs != boundary(4, rs))
224 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
225 "WARNING: packet size has wrong decryption boundary");
227 n = (buf[0] == 3) ? 0x34 : 0;
229 //Fix for ECM request size > 255 (use ecm length field)
230 if(buf[0] == 0)
231 { buflen = (((buf[21] & 0x0f) << 8) | buf[22]) + 3; }
232 else if(buf[0] == 0x3d || buf[0] == 0x3e || buf[0] == 0x3f) //cacheex-push
233 { buflen = buf[1] | (buf[2] << 8); }
234 else
235 { buflen = buf[1]; }
237 n = boundary(4, n + 20 + buflen);
238 if(!(client->is_udp && client->typ == 'c') && (rs < n) && ((n - 32) > 0))
241 //len = cs_recv(client->udp_fd, buf+32, n-32, 0); // read the rest of the packet
242 int32_t tot=n-32, readed=0;
243 len = 0;
245 readed = cs_recv(client->udp_fd, buf+32+len, tot, 0); // read the rest of the packet
246 if (readed < 0){
247 if(errno == EINTR) { continue; } // try again in case of interrupt
248 if(errno == EAGAIN) { continue; } //EAGAIN needs select procedure again
249 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "ERROR: %s (errno=%d %s)", __func__, errno, strerror(errno));
250 break;
252 if (readed == 0){ // nothing to read left!
253 break;
255 if (readed > 0){ // received something, add it!
256 tot-=readed;
257 len+=readed;
260 while(tot!=0);
263 if(len > 0)
265 rs += len;
266 aes_decrypt(client->aes_keys, buf + 32, len);
268 if(len < 0)
270 rc = -1;
271 goto out;
275 cs_log_dump_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
276 buf, rs, "received %d bytes from %s", rs, remote_txt());
278 if(n < rs)
279 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER,
280 "ignoring %d bytes of garbage", rs - n);
281 else if(n > rs) { rc = -3; }
282 break;
283 case 3:
284 if(crc32(0L, buf + 20, buflen) != b2i(4, buf + 4)) { rc = -4; }
285 if(!rc) { rc = n; }
286 break;
290 out:
291 if((rs > 0) && ((rc == -1) || (rc == -2)))
293 cs_log_dump_dbg(client->typ == 'c' ? D_CLIENT : D_READER, buf, rs,
294 "received %d bytes from %s (native)", rs, remote_txt());
296 if(rc >= 0) { client->last = time(NULL); } // last client action is now
297 switch(rc)
299 //case 0: break;
300 case -1:
301 cs_log("packet is too small (received %d bytes, expected %d bytes)", rs, l);
302 break;
303 case -2:
304 if(cs_auth_client(client, 0, "unknown user"))
305 { cs_disconnect_client(client); }
306 break;
307 case -3:
308 cs_log("incomplete request !");
309 break;
310 case -4:
311 cs_log("checksum error (wrong password ?)");
312 break;
313 case -5:
314 cs_log_dbg(client->typ == 'c' ? D_CLIENT : D_READER, "connection closed");
315 break;
316 //default: cs_log_dbg(D_TRACE, "camd35_recv returns rc=%d", rc); break;
319 return (rc);
323 * server functions
326 static void camd35_request_emm(ECM_REQUEST *er)
328 int32_t i;
329 time_t now;
330 uchar mbuf[1024];
331 struct s_client *cl = cur_client();
332 struct s_reader *aureader = NULL, *rdr = NULL;
334 if(er->selected_reader && !er->selected_reader->audisabled && ll_contains(cl->aureader_list, er->selected_reader))
335 { aureader = er->selected_reader; }
337 if(!aureader && cl->aureader_list)
339 LL_ITER itr = ll_iter_create(cl->aureader_list);
340 while((rdr = ll_iter_next(&itr)))
342 if(emm_reader_match(rdr, er->caid, er->prid))
344 aureader = rdr;
345 break;
350 if(!aureader)
351 { return; } // TODO
353 uint16_t au_caid = aureader->caid;
355 if(!au_caid && caid_is_bulcrypt(er->caid)) // Bulcrypt has 2 caids and aureader->caid can't be used. Use ECM_REQUEST caid for AU.
356 { au_caid = er->caid; }
358 time(&now);
359 if(!memcmp(cl->lastserial, aureader->hexserial, 8))
360 if(llabs(now - cl->last) < 180) { return; }
362 memcpy(cl->lastserial, aureader->hexserial, 8);
363 cl->last = now;
365 if(au_caid)
367 cl->disable_counter = 0;
368 cs_log("%s emm-request sent (reader=%s, caid=%04X, auprovid=%06X)",
369 username(cur_client()), aureader->label, au_caid,
370 aureader->auprovid ? aureader->auprovid : b2i(4, aureader->prid[0]));
372 else if(cl->disable_counter > 2)
373 { return; }
374 else
375 { cl->disable_counter++; }
377 memset(mbuf, 0, sizeof(mbuf));
378 mbuf[2] = mbuf[3] = 0xff; // must not be zero
379 i2b_buf(2, er->srvid, mbuf + 8);
381 //override request provid with auprovid if set in CMD05
382 if(aureader->auprovid)
384 if(aureader->auprovid != er->prid)
385 { i2b_buf(4, aureader->auprovid, mbuf + 12); }
386 else
387 { i2b_buf(4, er->prid, mbuf + 12); }
389 else
391 i2b_buf(4, er->prid, mbuf + 12);
394 i2b_buf(2, er->pid, mbuf + 16);
395 mbuf[0] = 5;
396 mbuf[1] = 111;
397 if(au_caid)
399 mbuf[39] = 1; // no. caids
400 mbuf[20] = au_caid >> 8; // caid's (max 8)
401 mbuf[21] = au_caid & 0xff;
402 memcpy(mbuf + 40, aureader->hexserial, 6); // serial now 6 bytes
403 mbuf[47] = aureader->nprov;
404 for(i = 0; i < aureader->nprov; i++)
406 if((au_caid >= 0x1700 && au_caid <= 0x1799) || // Betacrypt
407 (au_caid >= 0x0600 && au_caid <= 0x0699)) // Irdeto (don't know if this is correct, cause I don't own a IRDETO-Card)
409 mbuf[48 + (i * 5)] = aureader->prid[i][0];
410 memcpy(&mbuf[50 + (i * 5)], &aureader->prid[i][1], 3);
412 else
414 mbuf[48 + (i * 5)] = aureader->prid[i][2];
415 mbuf[49 + (i * 5)] = aureader->prid[i][3];
416 memcpy(&mbuf[50 + (i * 5)], &aureader->sa[i][0], 4); // for conax we need at least 4 Bytes
419 //we think client/server protocols should deliver all information, and only readers should discard EMM
420 mbuf[128] = (aureader->blockemm & EMM_GLOBAL && !(aureader->saveemm & EMM_GLOBAL)) ? 0 : 1;
421 mbuf[129] = (aureader->blockemm & EMM_SHARED && !(aureader->saveemm & EMM_SHARED)) ? 0 : 1;
422 mbuf[130] = (aureader->blockemm & EMM_UNIQUE && !(aureader->saveemm & EMM_UNIQUE)) ? 0 : 1;
423 mbuf[127] = (aureader->blockemm & EMM_UNKNOWN && !(aureader->saveemm & EMM_UNKNOWN)) ? 0 : 1;
425 else // disable emm
426 { mbuf[20] = mbuf[39] = mbuf[40] = mbuf[47] = mbuf[49] = 1; }
428 memcpy(mbuf + 10, mbuf + 20, 2);
429 camd35_send(cl, mbuf, 0); // send with data-len 111 for camd3 > 3.890
430 mbuf[1]++;
431 camd35_send(cl, mbuf, 0); // send with data-len 112 for camd3 < 3.890
434 static void camd35_send_dcw(struct s_client *client, ECM_REQUEST *er)
436 uchar *buf;
437 buf = er->src_data; // get orig request
439 if(!buf)
441 rdr_log(client->reader, "ERROR: src_data missing");
442 return;
445 if(er->rc == E_INVALID && !client->c35_suppresscmd08) //send normal CMD08
447 buf[0] = 0x08;
448 buf[1] = 2;
449 memset(buf + 20, 0, buf[1]);
450 buf[22] = er->rc; //put rc in byte 22 - hopefully don't break legacy camd3
452 else if(er->rc == E_STOPPED) //send sleep CMD08
454 buf[0] = 0x08;
455 buf[1] = 2;
456 buf[20] = 0;
457 buf[21] = 0xFF;
458 cs_log("%s stop request send", client->account->usr);
460 else
462 // Send CW
463 if((er->rc < E_NOTFOUND) || (er->rc == E_FAKE))
465 if(buf[0] == 3)
466 { memmove(buf + 20 + 16, buf + 20 + buf[1], 0x34); }
467 buf[0]++;
468 buf[1] = 16;
469 camd35_cacheex_init_dcw(client, er);
470 memcpy(buf + 20, er->cw, buf[1]);
472 else
474 // Send old CMD44 to prevent cascading problems with older mpcs/oscam versions
475 buf[0] = 0x44;
476 buf[1] = 0;
479 camd35_send(client, buf, 0);
480 camd35_request_emm(er);
483 static void camd35_process_ecm(uchar *buf, int buflen)
485 ECM_REQUEST *er;
487 if(!buf || buflen < 23)
488 { return; }
490 uint16_t ecmlen = SCT_LEN((&buf[20]));
492 if(ecmlen > MAX_ECM_SIZE || ecmlen + 20 > buflen)
493 { return; }
495 if(!(er = get_ecmtask()))
496 { return; }
498 er->ecmlen = ecmlen;
500 if(!cs_malloc(&er->src_data, 0x34 + 20 + er->ecmlen))
501 { NULLFREE(er); return; }
503 memcpy(er->src_data, buf, 0x34 + 20 + er->ecmlen); // save request
504 er->srvid = b2i(2, buf + 8);
505 er->caid = b2i(2, buf + 10);
506 er->prid = b2i(4, buf + 12);
507 //er->pid = b2i(2, buf+16); value is ecmtask idx see camd35_recv_chk 941
508 memcpy(er->ecm, buf + 20, er->ecmlen);
509 get_cw(cur_client(), er);
512 static void camd35_process_emm(uchar *buf, int buflen, int emmlen)
514 EMM_PACKET epg;
515 if(!buf || buflen < 20 || emmlen + 20 > buflen)
516 { return; }
517 memset(&epg, 0, sizeof(epg));
518 epg.emmlen = emmlen;
519 if(epg.emmlen < 3 || epg.emmlen > MAX_EMM_SIZE)
520 { return; }
521 memcpy(epg.caid, buf + 10, 2);
522 memcpy(epg.provid, buf + 12 , 4);
523 memcpy(epg.emm, buf + 20, epg.emmlen);
524 do_emm(cur_client(), &epg);
527 int32_t camd35_tcp_connect(struct s_client *cl)
529 if(cl->is_udp) // check for udp client
531 if(!IP_ISSET(SIN_GET_ADDR(cl->udp_sa))) // check ip is set
533 if(!(hostResolve(cl->reader))) // no ip -> try to resolve ip of client
535 network_tcp_connection_close(cl->reader, "no ip");
536 return 0;
541 if(!cl->reader->tcp_connected) // client not connected
543 int32_t handle = 0;
544 handle = network_tcp_connection_open(cl->reader); // try to connect
545 if(handle < 0) // got no handle -> error!
547 cl->reader->last_s = 0; // set last send to zero
548 cl->reader->last_g = 0; // set last receive to zero
549 cl->last = 0; // set last client action to zero
550 return (0);
553 cl->reader->tcp_connected = 1;
554 cl->reader->card_status = CARD_INSERTED;
555 cl->reader->last_s = time(NULL); // reset last send
556 cl->reader->last_g = time(NULL); // reset last receive
557 cl->last = time(NULL); // reset last client action
558 cl->pfd = cl->udp_fd = handle;
560 if(!cl->udp_fd) { return (0); } // Check if client has no handle -> error
562 // check if client reached timeout
563 if(cl->reader->tcp_rto && (cl->reader->last_s - cl->reader->last_g > cl->reader->tcp_rto))
565 if(!cl->is_udp) //tcp on timeout disconnect reader
567 network_tcp_connection_close(cl->reader, "rto");
568 return 0;
570 else //udp check to discover ip change on dynamic ip servers
572 IN_ADDR_T last_ip;
573 IP_ASSIGN(last_ip, cl->ip);
574 if(!hostResolve(cl->reader))
576 network_tcp_connection_close(cl->reader, "no ip");
577 return 0;
579 if(!IP_EQUAL(last_ip, cl->ip))
581 network_tcp_connection_close(cl->reader, "ip change");
582 return 0;
587 return (1); // all ok
591 * client functions
593 static void camd35_send_keepalive(struct s_client *cl)
596 if(cl->reader)
598 if(camd35_tcp_connect(cl))
600 if(cacheex_get_rdr_mode(cl->reader) > 1)
602 camd35_cacheex_push_request_remote_id(cl);
603 return;
605 uint8_t rbuf[32];//minimal size
606 memset(rbuf, 0, sizeof(rbuf));
607 rbuf[0] = 55;
608 rbuf[1] = 1;
609 rbuf[2] = 0;
610 camd35_send(cl, rbuf, 1); //send adds +20
616 static void camd35_send_keepalive_answer(struct s_client *cl)
618 if(check_client(cl) && cl->account)
620 uint8_t rbuf[32];//minimal size
621 memset(rbuf, 0, sizeof(rbuf));
622 rbuf[0] = 55;
623 rbuf[1] = 1;
624 rbuf[2] = 0;
625 camd35_send(cl, rbuf, 1); //send adds +20
630 static int32_t camd35_client_init(struct s_client *cl)
632 unsigned char md5tmp[MD5_DIGEST_LENGTH];
633 int32_t no_delay = 1;
635 cs_strncpy((char *)cl->upwd, cl->reader->r_pwd, sizeof(cl->upwd));
636 i2b_buf(4, crc32(0L, MD5((unsigned char *)cl->reader->r_usr, strlen(cl->reader->r_usr), md5tmp), 16), cl->ucrc);
637 if (!aes_set_key_alloc(&cl->aes_keys, (char *)MD5(cl->upwd, strlen((char *)cl->upwd), md5tmp)))
639 return 1;
641 cl->crypted=1;
643 rdr_log(cl->reader, "proxy %s:%d", cl->reader->device, cl->reader->r_port);
645 if(!cl->is_udp && cacheex_get_rdr_mode(cl->reader) < 2)
646 setsockopt(cl->udp_fd, IPPROTO_TCP, TCP_NODELAY, (void *)&no_delay, sizeof(no_delay));
648 if(cl->reader->keepalive)
649 camd35_send_keepalive(cl);
651 if(cacheex_get_rdr_mode(cl->reader) == 2)
652 camd35_cacheex_send_push_filter(cl, 2);
654 return(0);
658 static void camd35_idle(void)
660 struct s_client *cl = cur_client();
662 if(!cl->reader)
663 { return; }
665 if(cl->reader->keepalive)
667 camd35_send_keepalive(cl);
669 else if(cl->reader->tcp_ito>0) // only check if user added an inactivity timeout
671 //inactivity timeout check
672 time_t now;
673 int32_t time_diff;
674 time(&now);
675 time_diff = llabs(now - cl->reader->last_s);
676 if(time_diff>cl->reader->tcp_ito)
678 if(check_client(cl) && cl->reader->tcp_connected && cl->reader->ph.type==MOD_CONN_TCP)
680 rdr_log_dbg(cl->reader, D_READER, "inactive_timeout, close connection (fd=%d)", cl->pfd);
681 network_tcp_connection_close(cl->reader, "inactivity");
683 else
684 { cl->reader->last_s = now; }
689 static void *camd35_server(struct s_client *client, uchar *mbuf, int32_t n)
691 if(!client || !mbuf)
692 { return NULL; }
694 if(client->reader)
696 client->reader->last_g = time(NULL); // last receive is now
697 if(mbuf[0] == 6 || mbuf[0] == 19) // check for emm command
699 client->reader->last_s = time(NULL); // fixup: last send is now (if client is only sending emms connection would be dropped!)
701 rdr_log(client->reader, "SERVER last = %d, last_s = %d, last_g = %d", (int) client->last, (int) client->reader->last_s, (int) client->reader->last_g);
703 client->last = time(NULL); // last client action is now
706 switch(mbuf[0])
708 case 0: // ECM
709 case 3: // ECM (cascading)
710 camd35_process_ecm(mbuf, n);
711 break;
712 case 6: // EMM
713 case 19: // EMM
714 if(n > 2)
715 { camd35_process_emm(mbuf, n, mbuf[1]); }
716 break;
717 case 55:
718 //keepalive msg
719 camd35_send_keepalive_answer(client);
720 break;
721 default:
722 if (!camd35_cacheex_server(client, mbuf))
723 cs_log("unknown [cs357x/cs378x] command from %s! (%d) n=%d", username(client), mbuf[0], n);
726 return NULL; //to prevent compiler message
729 static int32_t camd35_send_ecm(struct s_client *client, ECM_REQUEST *er)
731 static const char *typtext[] = {"ok", "invalid", "sleeping"};
733 if(client->stopped)
735 if(er->srvid == client->lastsrvid && er->caid == client->lastcaid)
737 cs_log("%s is stopped - requested by server (%s)",
738 client->reader->label, typtext[client->stopped]);
739 return (-1);
741 else
743 client->stopped = 0;
747 client->lastsrvid = er->srvid;
748 client->lastcaid = er->caid;
749 client->lastpid = er->pid;
751 if(!camd35_tcp_connect(client)) { return -1; }
753 client->reader->card_status = CARD_INSERTED; //for udp
755 uint8_t *buf;
756 if(!cs_malloc(&buf, er->ecmlen + 20 + 15))
757 { return -1; }
759 memset(buf, 0, 20);
760 memset(buf + 20, 0xff, er->ecmlen + 15);
761 buf[1] = er->ecmlen;
762 i2b_buf(2, er->srvid, buf + 8);
763 i2b_buf(2, er->caid, buf + 10);
764 i2b_buf(4, er->prid, buf + 12);
765 i2b_buf(2, er->idx, buf + 16);
766 buf[18] = 0xff;
767 buf[19] = 0xff;
768 memcpy(buf + 20, er->ecm, er->ecmlen);
769 int32_t rc = ((camd35_send(client, buf, 0) < 1) ? (-1) : 0);
771 NULLFREE(buf);
772 return rc;
775 static int32_t camd35_send_emm(EMM_PACKET *ep)
777 uint8_t *buf;
778 struct s_client *cl = cur_client();
780 if(!camd35_tcp_connect(cl)) { return 0; }
781 cl->reader->card_status = CARD_INSERTED; //for udp
783 if(!cs_malloc(&buf, ep->emmlen + 20 + 15))
784 { return -1; }
786 memset(buf, 0, 20);
787 memset(buf + 20, 0xff, ep->emmlen + 15);
789 buf[0] = 0x06;
790 buf[1] = ep->emmlen;
791 memcpy(buf + 10, ep->caid, 2);
792 memcpy(buf + 12, ep->provid, 4);
793 memcpy(buf + 20, ep->emm, ep->emmlen);
795 int32_t rc = ((camd35_send_without_timeout(cl, buf, 0) < 1) ? 0 : 1);
797 NULLFREE(buf);
798 return rc;
801 static int32_t camd35_recv_chk(struct s_client *client, uchar *dcw, int32_t *rc, uchar *buf, int32_t rc2 __attribute__((unused)))
803 uint16_t idx;
804 static const char *typtext[] = {"ok", "invalid", "sleeping"};
805 struct s_reader *rdr = client->reader;
806 rdr->last_g = time(NULL); // last receive is now
808 // reading CMD05 Emm request and set serial
809 if(buf[0] == 0x05 && buf[1] == 111)
812 //cs_log("CMD05: %s", cs_hexdump(1, buf, buf[1], tmp, sizeof(tmp)));
813 rdr->nprov = 0; //reset if number changes on reader change
814 rdr->nprov = buf[47];
815 rdr->caid = b2i(2, buf + 20);
817 int32_t i;
818 for(i = 0; i < rdr->nprov; i++)
820 if(((rdr->caid >= 0x1700) && (rdr->caid <= 0x1799)) || // Betacrypt
821 ((rdr->caid >= 0x0600) && (rdr->caid <= 0x0699))) // Irdeto (don't know if this is correct, cause I don't own a IRDETO-Card)
823 rdr->prid[i][0] = buf[48 + (i * 5)];
824 memcpy(&rdr->prid[i][1], &buf[50 + (i * 5)], 3);
826 else
828 rdr->prid[i][2] = buf[48 + (i * 5)];
829 rdr->prid[i][3] = buf[49 + (i * 5)];
830 memcpy(&rdr->sa[i][0], &buf[50 + (i * 5)], 4);
834 memcpy(rdr->hexserial, buf + 40, 6);
835 rdr->hexserial[6] = 0;
836 rdr->hexserial[7] = 0;
838 if(cfg.getblockemmauprovid)
840 rdr->blockemm = 0;
841 rdr->blockemm |= (buf[128] == 1) ? 0 : EMM_GLOBAL;
842 rdr->blockemm |= (buf[129] == 1) ? 0 : EMM_SHARED;
843 rdr->blockemm |= (buf[130] == 1) ? 0 : EMM_UNIQUE;
844 rdr->blockemm |= (buf[127] == 1) ? 0 : EMM_UNKNOWN;
845 rdr->auprovid = b2i(4, buf + 12);
847 cs_log("%s CMD05 AU request for caid: %04X auprovid: %06X",
848 rdr->label,
849 rdr->caid,
850 rdr->auprovid);
853 bool rc_invalid = 0;
854 if(buf[0] == 0x08
855 && ((rdr->ph.type == MOD_CONN_TCP && !cfg.c35_tcp_suppresscmd08)
856 || (rdr->ph.type == MOD_CONN_UDP
857 && !cfg.c35_udp_suppresscmd08)))
859 if(buf[21] == 0xFF)
861 client->stopped = 2; // server says sleep
862 rdr->card_status = NO_CARD;
864 else
866 if(config_enabled(WITH_LB) && cfg.lb_mode)
868 rc_invalid = 1;
869 }else{
870 client->stopped = 1; // server says invalid
871 rdr->card_status = CARD_FAILURE;
875 cs_log("%s CMD08 (%02X - %d) stop request by server (%s)", rdr->label, buf[21], buf[21], typtext[client->stopped]);
878 if (camd35_cacheex_recv_chk(client, buf))
879 { return -1; }
881 if(buf[0] == 55) //keepalive answer
882 { return -1; }
884 // CMD44: old reject command introduced in mpcs
885 // keeping this for backward compatibility
886 if((buf[0] != 1) && (buf[0] != 0x44) && (buf[0] != 0x08))
887 { return (-1); }
889 idx = b2i(2, buf + 16);
891 camd35_cacheex_recv_ce1_cwc_info(client, buf, idx);
893 *rc = ((buf[0] != 0x44) && (buf[0] != 0x08));
894 if(rc_invalid){
895 *rc = 2; // INVALID sent by CMD08
898 memcpy(dcw, buf + 20, 16);
899 return (idx);
903 * module definitions
905 #ifdef MODULE_CAMD35
906 void module_camd35(struct s_module *ph)
908 ph->ptab.nports = 1;
909 ph->ptab.ports[0].s_port = cfg.c35_port;
911 ph->desc = "cs357x";
912 ph->type = MOD_CONN_UDP;
913 ph->large_ecm_support = 1;
914 ph->listenertype = LIS_CAMD35UDP;
915 IP_ASSIGN(ph->s_ip, cfg.c35_srvip);
916 ph->s_handler = camd35_server;
917 ph->recv = camd35_recv;
918 ph->send_dcw = camd35_send_dcw;
919 ph->c_init = camd35_client_init;
920 ph->c_recv_chk = camd35_recv_chk;
921 ph->c_send_ecm = camd35_send_ecm;
922 ph->c_send_emm = camd35_send_emm;
923 ph->c_idle = camd35_idle;
924 camd35_cacheex_module_init(ph);
925 ph->num = R_CAMD35;
927 #endif
929 #ifdef MODULE_CAMD35_TCP
930 void module_camd35_tcp(struct s_module *ph)
932 ph->desc = "cs378x";
933 ph->type = MOD_CONN_TCP;
934 ph->large_ecm_support = 1;
935 ph->listenertype = LIS_CAMD35TCP;
936 ph->ptab = cfg.c35_tcp_ptab;
937 IP_ASSIGN(ph->s_ip, cfg.c35_tcp_srvip);
938 ph->s_handler = camd35_server;
939 ph->recv = camd35_recv;
940 ph->send_dcw = camd35_send_dcw;
941 ph->c_init = camd35_client_init;
942 ph->c_recv_chk = camd35_recv_chk;
943 ph->c_send_ecm = camd35_send_ecm;
944 ph->c_send_emm = camd35_send_emm;
945 ph->c_idle = camd35_idle;
946 camd35_cacheex_module_init(ph);
947 ph->num = R_CS378X;
949 #endif
951 #endif