1 #define MODULE_LOG_PREFIX "camd35"
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
)
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
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);
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);
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
);
72 status
= sendto(cl
->udp_fd
, rbuf
, l
+ 4, 0, (struct sockaddr
*)&cl
->udp_sa
, cl
->udp_sa_len
);
75 set_null_ip(&SIN_GET_ADDR(cl
->udp_sa
));
80 status
= send(cl
->udp_fd
, rbuf
, l
+ 4, 0);
82 if(cl
->typ
== 'p' && cl
->reader
)
86 network_tcp_connection_close(cl
->reader
, "can't send");
89 else if(cl
->typ
== 'c')
93 cs_disconnect_client(cl
);
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
);
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;
132 struct s_auth
*account
;
133 uint8_t md5tmp
[MD5_DIGEST_LENGTH
];
137 return memcmp(cl
->ucrc
, ucrc
, 4) ? 1 : 0;
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
);
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
)))
159 if(cl
->account
->cacheex
.mode
< 2)
161 if(!cl
->is_udp
&& cl
->tcp_nodelay
== 0)
163 setsockopt(cl
->udp_fd
, IPPROTO_TCP
, TCP_NODELAY
, (void *)&no_delay
, sizeof(no_delay
));
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
++)
190 if(client
->is_udp
&& client
->typ
== 'c')
192 rs
= recv_from_udpipe(buf
);
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);
205 rs
= cs_recv(client
->udp_fd
, buf
, l
, 0);
210 continue; // try again in case of interrupt
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
));
230 int32_t tot
= 36, readed
= 0;
235 readed
= cs_recv(client
->udp_fd
, buf
+ rs
, tot
, 0);
240 continue; // try again in case of interrupt
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
));
253 if(readed
== 0) // nothing to read left!
259 if(readed
> 0) // received something, add it!
284 switch(camd35_auth_client(client
, buf
))
287 #ifdef CS_CACHEEX_AIO
288 if(!client
->c35_extmode
)
290 camd35_send_extmode(client
, false);
291 client
->c35_extmode
= 1;
298 break; // unknown user
302 break; // error's from cs_auth()
305 memmove(buf
, buf
+ 4, rs
-= 4);
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)
324 buflen
= (((buf
[21] & 0x0F) << 8) | buf
[22]) + 3;
327 #ifdef CS_CACHEEX_AIO
328 buf
[0] == 0x40 || buf
[0] == 0x41 || buf
[0] == 0x42 ||
330 buf
[0] == 0x3D || buf
[0] == 0x3E || buf
[0] == 0x3F
333 buflen
= buf
[1] | (buf
[2] << 8);
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;
352 readed
= cs_recv(client
->udp_fd
, buf
+ 32 + len
, tot
, 0); // read the rest of the packet
357 continue; // try again in case of interrupt
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
));
370 if(readed
== 0) // nothing to read left
375 if(readed
> 0) // received something, add it
387 aes_decrypt(client
->aes_keys
, buf
+ 32, len
);
397 cs_log_dump_dbg(client
->typ
== 'c' ? D_CLIENT
: D_READER
, buf
, rs
, "received %d bytes from %s",
402 cs_log_dbg(client
->typ
== 'c' ? D_CLIENT
: D_READER
, "ignoring %d bytes of garbage", rs
- n
);
414 if(crc32(0L, buf
+ 20, buflen
) != b2i(4, buf
+ 4))
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());
438 client
->last
= time(NULL
); // last client action is now
447 cs_log("packet is too small (received %d bytes, expected %d bytes)", rs
, l
);
451 if(cs_auth_client(client
, 0, "unknown user"))
453 cs_disconnect_client(client
);
458 cs_log("incomplete request!");
462 cs_log("checksum error (wrong password?)");
466 cs_log_dbg(client
->typ
== 'c' ? D_CLIENT
: D_READER
, "connection closed");
470 // cs_log_dbg(D_TRACE, "camd35_recv returns rc=%d", rc);
481 static void camd35_request_emm(ECM_REQUEST
*er
)
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
))
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
))
525 if(!memcmp(cl
->lastserial
, aureader
->hexserial
, 8))
527 if(llabs(now
- cl
->last
) < 180)
533 memcpy(cl
->lastserial
, aureader
->hexserial
, 8);
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)
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);
565 i2b_buf(4, er
->prid
, mbuf
+ 12);
570 i2b_buf(4, er
->prid
, mbuf
+ 12);
573 i2b_buf(2, er
->pid
, mbuf
+ 16);
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);
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;
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
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
)
621 buf
= er
->src_data
; // get orig request
625 rdr_log(client
->reader
, "ERROR: src_data missing");
629 if(er
->rc
== E_INVALID
&& !client
->c35_suppresscmd08
) // send normal CMD08
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
643 cs_log("%s stop request send", client
->account
->usr
);
648 if((er
->rc
< E_NOTFOUND
) || (er
->rc
== E_FAKE
))
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
663 buf
[0]++; // ecm response (CMD01 or CMD04)
664 #ifdef CS_CACHEEX_AIO
668 camd35_cacheex_init_dcw(client
, er
);
669 memcpy(buf
+ 20, er
->cw
, buf
[1]);
673 // Send old CMD44 to prevent cascading
674 // problems with older mpcs/oscam versions
680 camd35_send(client
, buf
, 0);
681 camd35_request_emm(er
);
684 static void camd35_process_ecm(uint8_t *buf
, int buflen
)
688 if(!buf
|| buflen
< 23)
693 uint16_t ecmlen
= SCT_LEN((&buf
[20]));
695 if(ecmlen
> MAX_ECM_SIZE
|| ecmlen
+ 20 > buflen
|| ecmlen
< 4)
700 if(!(er
= get_ecmtask()))
707 if(!cs_malloc(&er
->src_data
, 0x34 + 20 + er
->ecmlen
))
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
)
727 if(!buf
|| buflen
< 20 || emmlen
+ 20 > buflen
)
732 memset(&epg
, 0, sizeof(epg
));
735 if(epg
.emmlen
< 3 || epg
.emmlen
> MAX_EMM_SIZE
)
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");
761 if(!cl
->reader
->tcp_connected
) // client not connected
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
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
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");
795 else //udp check to discover ip change on dynamic ip servers
798 IP_ASSIGN(last_ip
, cl
->ip
);
800 if(!hostResolve(cl
->reader
))
802 network_tcp_connection_close(cl
->reader
, "no ip");
806 if(!IP_EQUAL(last_ip
, cl
->ip
))
808 network_tcp_connection_close(cl
->reader
, "ip change");
821 static void camd35_send_keepalive(struct s_client
*cl
)
825 if(camd35_tcp_connect(cl
))
827 if(cacheex_get_rdr_mode(cl
->reader
) > 1)
829 camd35_cacheex_push_request_remote_id(cl
);
833 uint8_t rbuf
[32]; // minimal size
834 memset(rbuf
, 0, sizeof(rbuf
));
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
));
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
)))
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
893 camd35_cacheex_send_push_filter(cl
, 2);
894 #ifdef CS_CACHEEX_AIO
895 camd35_cacheex_feature_request(cl
);
899 #ifdef CS_CACHEEX_AIO
902 camd35_send_extmode(cl
, false);
910 static void camd35_idle(void)
912 struct s_client
*cl
= cur_client();
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
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");
941 cl
->reader
->last_s
= now
;
947 static void *camd35_server(struct s_client
*client
, uint8_t *mbuf
, int32_t n
)
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
974 case 3: // ECM (cascading)
975 camd35_process_ecm(mbuf
, n
);
982 camd35_process_emm(mbuf
, n
, mbuf
[1]);
987 camd35_send_keepalive_answer(client
); // keepalive msg
989 #ifdef CS_CACHEEX_AIO
993 client
->c35_extmode
= 2;
997 if(!camd35_cacheex_server(client
, mbuf
))
999 cs_log("unknown [cs357x/cs378x] command from %s! (%d) n=%d", username(client
), mbuf
[0], n
);
1006 static int32_t camd35_send_ecm(struct s_client
*client
, ECM_REQUEST
*er
)
1008 static const char *typtext
[] = { "ok", "invalid", "sleeping" };
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
]);
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
))
1032 client
->reader
->card_status
= CARD_INSERTED
; // for udp
1035 if(!cs_malloc(&buf
, 20 + er
->ecmlen
+ 15))
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);
1050 memcpy(buf
+ 20, er
->ecm
, er
->ecmlen
);
1052 int32_t rc
= (camd35_send(client
, buf
, 0) < 1) ? -1 : 0;
1058 static int32_t camd35_send_emm(EMM_PACKET
*ep
)
1061 struct s_client
*cl
= cur_client();
1063 if(!camd35_tcp_connect(cl
))
1068 cl
->reader
->card_status
= CARD_INSERTED
; // for udp
1070 if(!cs_malloc(&buf
, ep
->emmlen
+ 20 + 15))
1076 memset(buf
+ 20, 0xFF, ep
->emmlen
+ 15);
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;
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
)))
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);
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);
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
)
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
)))
1148 client
->stopped
= 2; // server says sleep
1149 rdr
->card_status
= NO_CARD
;
1153 if(config_enabled(WITH_LB
) && cfg
.lb_mode
)
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
))
1173 if(buf
[0] == 55) // keepalive answer
1178 #ifdef CS_CACHEEX_AIO
1181 client
->c35_extmode
= 2;
1183 if(buf
[12] != 1) // answer
1184 camd35_send_extmode(client
, true);
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
1199 idx
= b2i(2, buf
+ 16);
1200 camd35_cacheex_recv_ce1_cwc_info(client
, buf
, idx
);
1202 *rc
= ((buf
[0] != 0x44) && (buf
[0] != 0x08));
1206 *rc
= 2; // INVALID sent by CMD08
1208 #ifdef CS_CACHEEX_AIO
1209 if(buf
[0] == 0x51 || buf
[0] == 0x54) // lg-flag
1212 client
->c35_extmode
= 2;
1216 memcpy(dcw
, buf
+ 20, 16);
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
));
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
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
);
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
);