1 #define MODULE_LOG_PREFIX "gbox"
6 #include "module-gbox.h"
7 #include "module-gbox-helper.h"
8 #include "module-gbox-sms.h"
9 #include "module-gbox-cards.h"
10 #include "module-cccam.h"
11 #include "module-cccam-data.h"
12 #include "oscam-failban.h"
13 #include "oscam-client.h"
14 #include "oscam-ecm.h"
15 #include "oscam-lock.h"
16 #include "oscam-net.h"
17 #include "oscam-chk.h"
18 #include "oscam-string.h"
19 #include "oscam-time.h"
20 #include "oscam-reader.h"
21 #include "oscam-files.h"
22 #include "module-gbox-remm.h"
23 #include "module-dvbapi.h"
24 #include "oscam-work.h"
26 static struct gbox_data local_gbox
;
27 static int8_t local_gbox_initialized
= 0;
28 static uint8_t local_cards_initialized
= 0;
29 uint8_t local_gbx_rev
= 0x30;
32 static uint32_t gbox_add_local_cards(void);
33 static int32_t gbox_send_ecm(struct s_client
*cli
, ECM_REQUEST
*er
);
34 void start_gbx_ticker(void);
36 char *get_gbox_tmp_fname(char *fext
)
38 static char gbox_tmpfile_buf
[128];
39 memset(gbox_tmpfile_buf
, 0, sizeof(gbox_tmpfile_buf
));
40 const char *slash
= "/";
44 snprintf(gbox_tmpfile_buf
, sizeof(gbox_tmpfile_buf
), "%s%s%s",get_tmp_dir(), slash
, fext
);
48 if(cfg
.gbox_tmp_dir
[cs_strlen(cfg
.gbox_tmp_dir
) - 1] == '/') { slash
= ""; }
49 snprintf(gbox_tmpfile_buf
, sizeof(gbox_tmpfile_buf
), "%s%s%s", cfg
.gbox_tmp_dir
, slash
, fext
);
51 return gbox_tmpfile_buf
;
54 uint16_t gbox_get_local_gbox_id(void)
59 uint32_t gbox_get_local_gbox_password(void)
61 return local_gbox
.password
;
64 static uint8_t gbox_get_my_cpu_api (void)
66 return(cfg
.gbox_my_cpu_api
);
69 static void write_attack_file (struct s_client
*cli
, uint8_t txt_id
, uint16_t rcvd_id
)
71 if (cfg
.dis_attack_txt
) {return;}
73 time_t walltime
= cs_time();
74 cs_ctime_r(&walltime
, tsbuf
);
75 char *fext
= FILE_ATTACK_INFO
;
76 char *fname
= get_gbox_tmp_fname(fext
);
77 FILE *fhandle
= fopen(fname
, "a");
81 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
85 if(txt_id
== GBOX_ATTACK_UNKWN_HDR
)
87 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - peer sends unknown Header CMD - %s",
88 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
91 if(txt_id
== GBOX_ATTACK_LOCAL_PW
)
93 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - peer sends wrong local password - %s",
94 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
97 if(txt_id
== GBOX_ATTACK_PEER_IGNORE
)
99 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - peer ignored by conf - %s",
100 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
103 if(txt_id
== GBOX_ATTACK_PEER_PW
)
105 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - peer sends unknown peer password - %s",
106 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
109 if(txt_id
== GBOX_ATTACK_AUTH_FAIL
)
111 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - authentification failed - %s",
112 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
115 if(txt_id
== GBOX_ATTACK_ECM_BLOCKED
)
117 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - ECM is blocked - %s",
118 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
121 if(txt_id
== GBOX_ATTACK_REMM_REQ_BLOCKED
)
123 fprintf(fhandle
, "ATTACK ALERT FROM %04X %s - unaccepted peer sent REMM REQ - %s",
124 rcvd_id
, cs_inet_ntoa(cli
->ip
), tsbuf
);
131 void write_msg_info(struct s_client
*cli
, uint8_t msg_id
, uint8_t txt_id
, uint16_t misc
)
133 if (msg_id
== MSGID_GSMS
&& misc
== 0x31) {return;}
134 char *fext
= FILE_MSG_INFO
;
135 char *fname
= get_gbox_tmp_fname(fext
);
137 if (file_exists(fname
))
140 memset(buf
, 0, sizeof(buf
));
142 if (msg_id
== MSGID_ATTACK
)
144 snprintf(buf
, sizeof(buf
), "%s %d %04X %d %s %d",
145 fname
, msg_id
, misc
, 0, cs_inet_ntoa(cli
->ip
), txt_id
);
147 cs_log_dbg(D_READER
, "found driver %s - write msg (msg_id = %d - txt-id = %d) Attack Alert from %s %04X",
148 fname
, msg_id
, txt_id
, cs_inet_ntoa(cli
->ip
), misc
);
152 snprintf(buf
, sizeof(buf
), "%.24s %d %.24s %.24s %s %d",
153 fname
, msg_id
, username(cli
), cli
->reader
->device
, cs_inet_ntoa(cli
->ip
), misc
);
155 cs_log_dbg(D_READER
, "found driver %s - write msg (id = %d) related to %s %s",
156 fname
, msg_id
, username(cli
),cli
->reader
->device
);
161 if((p
= popen(cmd
, "w")) == NULL
)
163 cs_log("Error popen: %s",fname
);
168 cs_log("Error pclose(): %s",fname
);
175 void handle_attack(struct s_client
*cli
, uint8_t txt_id
, uint16_t rcvd_id
)
177 write_attack_file(cli
, txt_id
, rcvd_id
);
178 write_msg_info(cli
, MSGID_ATTACK
, txt_id
, rcvd_id
);
182 void gbox_write_peer_onl(void)
184 char *fext
= FILE_GBOX_PEER_ONL
;
185 char *fname
= get_gbox_tmp_fname(fext
);
186 FILE *fhandle
= fopen(fname
, "w");
189 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
193 cs_readlock(__func__
, &clientlist_lock
);
196 for(cl
= first_client
; cl
; cl
= cl
->next
)
198 if(cl
->gbox
&& cl
->typ
== 'p')
200 struct gbox_peer
*peer
= cl
->gbox
;
203 fprintf(fhandle
, "1 %s %s %04X 2.%02X %s\n", cl
->reader
->device
,
204 cs_inet_ntoa(cl
->ip
), peer
->gbox
.id
, peer
->gbox
.minor_version
, cl
->reader
->description
? cl
->reader
->description
: "");
206 if (!peer
->onlinestat
)
208 peer
->onlinestat
= 1;
209 cs_log("comeONLINE: %s %s boxid: %04X (%s) v2.%02X cards:%d", cl
->reader
->device
,
210 cs_inet_ntoa(cl
->ip
), peer
->gbox
.id
, cl
->reader
->description
? cl
->reader
->description
: "-", peer
->gbox
.minor_version
, peer
->filtered_cards
);
211 write_msg_info(cl
, MSGID_COMEONLINE
, 0, peer
->filtered_cards
);
216 fprintf(fhandle
, "0 %s %s %04X 0.00 %s\n", cl
->reader
->device
, cs_inet_ntoa(cl
->ip
),peer
->gbox
.id
, cl
->reader
->description
? cl
->reader
->description
: "");
217 if (peer
->onlinestat
)
219 peer
->onlinestat
= 0;
220 cs_log("goneOFFLINE: %s %s boxid: %04X (%s)",cl
->reader
->device
, cs_inet_ntoa(cl
->ip
),peer
->gbox
.id
, cl
->reader
->description
? cl
->reader
->description
: "-");
221 write_msg_info(cl
, MSGID_GONEOFFLINE
, 0, 0);
226 cs_readunlock(__func__
, &clientlist_lock
);
231 void gbox_write_version(void)
233 char *fext
= FILE_GBOX_VERSION
;
234 char *fname
= get_gbox_tmp_fname(fext
);
235 FILE *fhandle
= fopen(fname
, "w");
238 cs_log("Couldn't open %s: %s", get_gbox_tmp_fname(FILE_GBOX_VERSION
), strerror(errno
));
241 fprintf(fhandle
, "%02X.%02X my-id: %04X rev: %01X.%01X\n", LOCAL_GBOX_MAJOR_VERSION
, cfg
.gbox_my_vers
, local_gbox
.id
, local_gbx_rev
>> 4, local_gbx_rev
& 0xf);
245 void hostname2ip(char *hostname
, IN_ADDR_T
*ip
)
247 cs_resolve(hostname
, ip
, NULL
, NULL
);
250 uint16_t gbox_convert_password_to_id(uint32_t password
)
252 return (((password
>> 24) & 0xff) ^ ((password
>> 8) & 0xff)) << 8 | (((password
>> 16) & 0xff) ^ (password
& 0xff));
255 static int8_t gbox_remove_all_bad_sids(ECM_REQUEST
*er
, uint16_t sid
)
262 struct gbox_card_pending
*pending
= NULL
;
263 LL_LOCKITER
*li
= ll_li_create(er
->gbox_cards_pending
, 0);
265 while ((pending
= ll_li_next(li
)))
267 gbox_remove_bad_sid(pending
->id
.peer
, pending
->id
.slot
, sid
);
273 void gbox_free_cards_pending(ECM_REQUEST
*er
)
275 ll_destroy_free_data(&er
->gbox_cards_pending
);
278 void gbox_init_ecm_request_ext(struct gbox_ecm_request_ext
*ere
)
281 ere
->gbox_version
= 0;
286 struct s_client
*get_gbox_proxy(uint16_t gbox_id
)
289 struct s_client
*found
= NULL
;
290 cs_readlock(__func__
, &clientlist_lock
);
292 for(cl
= first_client
; cl
; cl
= cl
->next
)
294 if(cl
->typ
== 'p' && cl
->gbox
&& cl
->gbox_peer_id
== gbox_id
)
300 cs_readunlock(__func__
, &clientlist_lock
);
304 void remove_peer_crd_file(struct s_client
*proxy
)
307 snprintf(buff
, sizeof(buff
),"cards_to_%.24s", proxy
->reader
->label
);
308 char *fname
= get_gbox_tmp_fname(buff
);
310 if(file_exists(fname
))
312 if(unlink(fname
) < 0)
314 cs_log("Error removing peer_crd_file %s (errno=%d %s)!", fname
, errno
, strerror(errno
));
319 static int8_t gbox_peer_online(struct gbox_peer
*peer
, uint8_t online
)
321 if (!peer
) { return -1; }
323 peer
->online
= online
;
324 gbox_write_peer_onl();
328 static int8_t gbox_clear_peer(struct gbox_peer
*peer
)
336 peer
->next_hello
= 0;
339 gbox_delete_cards(GBOX_DELETE_FROM_PEER
, peer
->gbox
.id
);
340 gbox_peer_online(peer
, GBOX_PEER_OFFLINE
);
345 static int8_t gbox_reinit_proxy(struct s_client
*proxy
)
352 struct gbox_peer
*peer
= proxy
->gbox
;
353 gbox_clear_peer(peer
);
360 remove_peer_crd_file(proxy
);
361 proxy
->reader
->tcp_connected
= 0;
362 proxy
->reader
->card_status
= CARD_NEED_INIT
;
363 proxy
->reader
->last_s
= proxy
->reader
->last_g
= 0;
368 //gbox.net doesn't accept slots >18
369 static uint8_t calc_slot(uint8_t slot
)
372 uint8_t cslot
= slot
;
374 for(i
=0 ; i
< 9 ; i
++)
384 uint16_t count_send_cards(struct s_client
*proxy
)
386 uint16_t nbcards
= 0;
387 struct gbox_peer
*peer
= proxy
->gbox
;
388 struct gbox_card
*card
;
389 if(gbox_count_cards() > 0)
391 GBOX_CARDS_ITER
*gci
= gbox_cards_iter_create();
392 while((card
= gbox_cards_iter_next(gci
)))
394 if(chk_ctab(gbox_get_caid(card
->caprovid
), &peer
->my_user
->account
->ctab
) && (card
->lvl
> 0) &&
396 (card
->dist
<= peer
->my_user
->account
->cccmaxhops
) &&
398 (!card
->origin_peer
|| (card
->origin_peer
&& card
->origin_peer
->gbox
.id
!= peer
->gbox
.id
)))
400 if(card
->type
== GBOX_CARD_TYPE_GBOX
)
405 else if(card
->type
== GBOX_CARD_TYPE_CCCAM
) //&& cfg.cc_gbx_reshare_en
407 if(proxy
->reader
->gbox_cccam_reshare
< 0)
411 if(chk_ident_filter(gbox_get_caid(card
->caprovid
), gbox_get_provid(card
->caprovid
), &proxy
->reader
->ccc_gbx_reshare_ident
))
418 else if(card
->type
== GBOX_CARD_TYPE_LOCAL
|| card
->type
== GBOX_CARD_TYPE_BETUN
|| card
->type
== GBOX_CARD_TYPE_PROXY
)
420 if(proxy
->reader
->gbox_reshare
> 0)
431 if(nbcards
== MAX_GBOX_CARDS
)
436 } // while cards exist
437 gbox_cards_iter_destroy(gci
);
442 void gbox_send(struct s_client
*cli
, uint8_t *buf
, int32_t l
)
444 struct gbox_peer
*peer
= cli
->gbox
;
446 cs_log_dump_dbg(D_READER
, buf
, l
, "<- data to %s (%d bytes):", cli
->reader
->label
, l
);
448 hostname2ip(cli
->reader
->device
, &SIN_GET_ADDR(cli
->udp_sa
));
449 SIN_GET_FAMILY(cli
->udp_sa
) = AF_INET
;
450 SIN_GET_PORT(cli
->udp_sa
) = htons((uint16_t)cli
->reader
->r_port
);
452 gbox_encrypt(buf
, l
, peer
->gbox
.password
);
453 sendto(cli
->udp_fd
, buf
, l
, 0, (struct sockaddr
*)&cli
->udp_sa
, cli
->udp_sa_len
);
454 cs_log_dump_dbg(D_READER
, buf
, l
, "<- encrypted data to %s (%d bytes):", cli
->reader
->label
, l
);
457 void gbox_send_hello_packet(struct s_client
*cli
, int8_t packet
, uint8_t *outbuf
, uint8_t *ptr
, int32_t nbcards
, uint8_t hello_stat
)
459 struct gbox_peer
*peer
= cli
->gbox
;
460 int32_t hostname_len
= cs_strlen(cfg
.gbox_hostname
);
463 gbox_message_header(outbuf
, MSG_HELLO
, peer
->gbox
.password
, local_gbox
.password
);
465 if(hello_stat
> GBOX_STAT_HELLOS
) // hello_stat == HelloR
475 if((packet
& 0x0F) == 0) // first packet
477 memcpy(++ptr
, gbox_get_my_checkcode(), 7);
480 *ptr
= local_gbox
.minor_version
;
481 *(++ptr
) = local_gbox
.cpu_api
;
482 memcpy(++ptr
, cfg
.gbox_hostname
, hostname_len
);
486 len
= ptr
- outbuf
+ 1;
490 case GBOX_STAT_HELLOL
:
492 { cs_log("<- HelloL to %s", cli
->reader
->label
); }
494 { cs_log_dbg(D_READER
,"<- HelloL to %s", cli
->reader
->label
); }
497 case GBOX_STAT_HELLOS
:
499 { cs_log("<- HelloS #%d total cards %d to %s", (packet
& 0xf) +1, nbcards
, cli
->reader
->label
); }
501 { cs_log_dbg(D_READER
,"<- HelloS #%d total cards %d to %s", (packet
& 0xf) +1, nbcards
, cli
->reader
->label
); }
504 case GBOX_STAT_HELLOR
:
506 { cs_log("<- HelloR #%d total cards %d to %s", (packet
& 0xf) +1, nbcards
, cli
->reader
->label
); }
508 { cs_log_dbg(D_READER
,"<- HelloR #%d total cards %d to %s", (packet
& 0xf) +1, nbcards
, cli
->reader
->label
); }
513 { cs_log("<- hello #%d total cards %d to %s", (packet
& 0xf) +1, nbcards
, cli
->reader
->label
); }
515 { cs_log_dbg(D_READER
,"<- hello #%d total cards %d to %s", (packet
& 0xf) +1, nbcards
, cli
->reader
->label
); }
518 cs_log_dump_dbg(D_READER
, outbuf
, len
, "<- hello #%d to %s, (len=%d):", (packet
& 0xf) +1, cli
->reader
->label
, len
);
520 gbox_compress(outbuf
, len
, &len
);
521 gbox_send(cli
, outbuf
, len
);
524 void gbox_send_hello(struct s_client
*proxy
, uint8_t hello_stat
)
528 cs_log("ERROR: Invalid proxy try to call 'gbox_send_hello'");
532 struct gbox_peer
*peer
= proxy
->gbox
;
536 cs_log("ERROR: Invalid peer try to call 'gbox_send_hello'");
540 if(hello_stat
> GBOX_STAT_HELLOL
&& (!peer
->my_user
|| !peer
->my_user
->account
))
542 cs_log("ERROR: Invalid peer try to call 'gbox_send_hello'");
546 uint16_t sendcrds
= 0;
547 uint16_t nbcards
= 0;
548 uint16_t nbcards_cnt
= 0;
551 uint8_t *ptr
= buf
+ 11;
553 struct gbox_card
*card
;
554 memset(buf
, 0, sizeof(buf
));
555 if(gbox_count_cards() > 0)
557 if(hello_stat
> GBOX_STAT_HELLOL
)
559 uint16_t nb_send_cards
= count_send_cards(proxy
);
562 snprintf(buff
, sizeof(buff
),"cards_to_%.24s", proxy
->reader
->label
);
563 char *fname
= get_gbox_tmp_fname(buff
);
565 FILE *fhandle
= fopen(fname
, "w");
568 cs_log("Couldn't open %s: %s", fname
, strerror(errno
));
572 fprintf(fhandle
, "Cards forwarded to peer %04X - %s\n\n", peer
->gbox
.id
, proxy
->reader
->label
);
574 GBOX_CARDS_ITER
*gci
= gbox_cards_iter_create();
575 while((card
= gbox_cards_iter_next(gci
)))
577 //send to user only cards which matching CAID from account and lvl > 0
578 //and cccmaxhops from account
579 //do not send peer cards back
580 if(chk_ctab(gbox_get_caid(card
->caprovid
), &peer
->my_user
->account
->ctab
) && (card
->lvl
> 0) &&
582 (card
->dist
<= peer
->my_user
->account
->cccmaxhops
) &&
584 (!card
->origin_peer
|| (card
->origin_peer
&& card
->origin_peer
->gbox
.id
!= peer
->gbox
.id
)))
586 if(card
->type
== GBOX_CARD_TYPE_GBOX
)
588 // cs_log_dbg(D_READER,"send to peer gbox-card %04X - level=%d crd-owner=%04X", card->caprovid >> 16, card->lvl, card->id.peer);
589 *(++ptr
) = card
->caprovid
>> 24;
590 *(++ptr
) = card
->caprovid
>> 16;
591 *(++ptr
) = card
->caprovid
>> 8;
592 *(++ptr
) = card
->caprovid
& 0xff;
593 *(++ptr
) = 1; // note: original gbx is more efficient and sends all cards of one caid as package
594 *(++ptr
) = calc_slot(card
->id
.slot
);
595 *(++ptr
) = ((card
->lvl
- 1) << 4) + card
->dist
+ 1;
597 fprintf(fhandle
, "#%03d Peer Crd to %04X - crd %08X - level %d - dist %d - slot %02d - crd owner %04X\n", ++sendcrds
, peer
->gbox
.id
, card
->caprovid
, card
->lvl
-1, card
->dist
+ 1, calc_slot(card
->id
.slot
), card
->id
.peer
);
599 else if(card
->type
== GBOX_CARD_TYPE_CCCAM
)
601 if(proxy
->reader
->gbox_cccam_reshare
< 0)
605 if(chk_ident_filter(gbox_get_caid(card
->caprovid
), gbox_get_provid(card
->caprovid
), &proxy
->reader
->ccc_gbx_reshare_ident
))
607 if(proxy
->reader
->gbox_cccam_reshare
> proxy
->reader
->gbox_reshare
)
609 proxy
->reader
->gbox_cccam_reshare
= proxy
->reader
->gbox_reshare
;
611 // cs_log_dbg(D_READER,"send to peer %04X - ccc-card %04X - level=%d crd-owner=%04X", peer->gbox.id, card->caprovid >> 16, proxy->reader->gbox_cccam_reshare, card->id.peer);
612 *(++ptr
) = card
->caprovid
>> 24;
613 *(++ptr
) = card
->caprovid
>> 16;
614 *(++ptr
) = card
->caprovid
>> 8;
615 *(++ptr
) = card
->caprovid
& 0xff;
617 *(++ptr
) = calc_slot(card
->id
.slot
);
618 *(++ptr
) = ((proxy
->reader
->gbox_cccam_reshare
) << 4) + card
->dist
+ 1;
620 fprintf(fhandle
, "#%03d CCCM crd to %04X - crd %08X - level %d - dist %d - slot %02d - crd owner %04X\n", ++sendcrds
, peer
->gbox
.id
, card
->caprovid
, proxy
->reader
->gbox_cccam_reshare
, card
->dist
+ 1, calc_slot(card
->id
.slot
), card
->id
.peer
);
626 else if(card
->type
== GBOX_CARD_TYPE_LOCAL
|| card
->type
== GBOX_CARD_TYPE_BETUN
|| card
->type
== GBOX_CARD_TYPE_PROXY
)
628 if(proxy
->reader
->gbox_reshare
> 0)
630 //cs_log_dbg(D_READER,"send local crd %04X reshare=%d crd-owner=%04X", card->caprovid >> 16, proxy->reader->gbox_reshare, card->id.peer);
631 *(++ptr
) = card
->caprovid
>> 24;
632 *(++ptr
) = card
->caprovid
>> 16;
633 *(++ptr
) = card
->caprovid
>> 8;
634 *(++ptr
) = card
->caprovid
& 0xff;
636 *(++ptr
) = calc_slot(card
->id
.slot
);
637 *(++ptr
) = ((proxy
->reader
->gbox_reshare
- 1) << 4) + card
->dist
+ 1;
639 fprintf(fhandle
, "#%03d Locl Crd to %04X - crd %08X - level %d - dist %d - slot %02d - crd owner %04X\n", ++sendcrds
, peer
->gbox
.id
, card
->caprovid
, proxy
->reader
->gbox_reshare
- 1, card
->dist
+ 1, calc_slot(card
->id
.slot
), card
->id
.peer
);
643 cs_log_dbg(D_READER
,"WARNING: local card %04X NOT be shared - !! reshare=%d !! crd-owner=%04X", card
->caprovid
>> 16, proxy
->reader
->gbox_reshare
, card
->id
.peer
);
648 *(++ptr
) = card
->id
.peer
>> 8;
649 *(++ptr
) = card
->id
.peer
& 0xff;
653 if(nbcards_cnt
== MAX_GBOX_CARDS
)
655 cs_log("max card limit [%d] send to peer %04X is exceeded", MAX_GBOX_CARDS
, peer
->gbox
.id
);
659 if(nbcards_cnt
== nb_send_cards
)
666 gbox_send_hello_packet(proxy
, packet
, buf
, ptr
, nbcards
, hello_stat
);
670 memset(buf
, 0, sizeof(buf
));
673 } // while cards exist
675 gbox_cards_iter_destroy(gci
);
680 GBOX_CARDS_ITER
*gci
= gbox_cards_iter_create();
681 while((card
= gbox_cards_iter_next(gci
)))
683 if(card
->lvl
> 0 && card
->type
!= GBOX_CARD_TYPE_CCCAM
&& card
->type
!= GBOX_CARD_TYPE_GBOX
)
685 if(proxy
->reader
->gbox_reshare
> 0)
687 *(++ptr
) = card
->caprovid
>> 24;
688 *(++ptr
) = card
->caprovid
>> 16;
689 *(++ptr
) = card
->caprovid
>> 8;
690 *(++ptr
) = card
->caprovid
& 0xff;
692 *(++ptr
) = calc_slot(card
->id
.slot
);
693 *(++ptr
) = ((proxy
->reader
->gbox_reshare
- 1) << 4) + card
->dist
+ 1;
694 *(++ptr
) = card
->id
.peer
>> 8;
695 *(++ptr
) = card
->id
.peer
& 0xff;
698 if(nbcards
>= GBOX_MAX_LOCAL_CARDS
)
700 cs_log("gbox_send_HelloL - local crds = %d - max allowed = %d ", nbcards
, GBOX_MAX_LOCAL_CARDS
);
704 } // end while local cards exist
705 gbox_cards_iter_destroy(gci
);
707 }// end if gbox_count_cards > 0
709 gbox_send_hello_packet(proxy
, 0x80 | packet
, buf
, ptr
, nbcards
, hello_stat
); //last packet has bit 0x80 set
712 void gbox_reconnect_peer(struct s_client
*cl
)
714 struct gbox_peer
*peer
= cl
->gbox
;
715 hostname2ip(cl
->reader
->device
, &SIN_GET_ADDR(cl
->udp_sa
));
716 SIN_GET_FAMILY(cl
->udp_sa
) = AF_INET
;
717 SIN_GET_PORT(cl
->udp_sa
) = htons((uint16_t)cl
->reader
->r_port
);
718 hostname2ip(cl
->reader
->device
, &(cl
->ip
));
719 gbox_reinit_proxy(cl
);
720 cs_log("reconnect %s peer: %04X", username(cl
), peer
->gbox
.id
);
721 gbox_send_hello(cl
, GBOX_STAT_HELLOS
);
725 void restart_gbox_peer(char *rdrlabel
, uint8_t allrdr
, uint16_t gbox_id
)
728 cs_readlock(__func__
, &clientlist_lock
);
730 for(cl
= first_client
; cl
; cl
= cl
->next
)
732 if(cl
->gbox
&& cl
->typ
== 'p' &&
733 ((rdrlabel
&& !strcmp(rdrlabel
, cl
->reader
->label
)) ||
734 allrdr
|| (gbox_id
&& cl
->gbox_peer_id
== gbox_id
)))
735 { gbox_reconnect_peer(cl
); }
737 cs_readunlock(__func__
, &clientlist_lock
);
740 static void *gbox_server(struct s_client
*cli
, uint8_t *UNUSED(b
), int32_t l
)
744 cs_log("gbox_server %s/%d", cli
->reader
->label
, cli
->port
);
745 //gbox_check_header_recvd(cli, NULL, b, l);
750 char *gbox_username(struct s_client
*client
)
759 if(client
->reader
->r_usr
[0])
761 return client
->reader
->r_usr
;
767 static int8_t gbox_disconnect_double_peers(struct s_client
*cli
)
770 cs_writelock(__func__
, &clientlist_lock
);
772 for(cl
= first_client
; cl
; cl
= cl
->next
)
774 if(cl
->typ
== 'c' && cl
->gbox_peer_id
== cli
->gbox_peer_id
&& cl
!= cli
)
778 cs_log_dbg(D_READER
, "disconnected double client %s - %s", username(cl
), cs_inet_ntoa(cli
->ip
));
779 //cs_log("disconnected double client %s - %s",username(cl), cs_inet_ntoa(cli->ip));
780 cs_disconnect_client(cl
);
783 cs_writeunlock(__func__
, &clientlist_lock
);
787 static int8_t gbox_auth_client(struct s_client
*cli
, uint32_t gbox_password
)
789 if(!cli
) { return -1; }
791 uint16_t gbox_id
= gbox_convert_password_to_id(gbox_password
);
792 struct s_client
*cl
= get_gbox_proxy(gbox_id
);
794 if(cl
->typ
== 'p' && cl
->gbox
&& cl
->reader
)
796 struct gbox_peer
*peer
= cl
->gbox
;
797 struct s_auth
*account
= get_account_by_name(gbox_username(cl
));
799 if ((peer
->gbox
.password
== gbox_password
) && account
)
801 cli
->crypted
= 1; // display as crypted
802 cli
->gbox
= cl
->gbox
; // point to the same gbox as proxy
803 cli
->reader
= cl
->reader
; // point to the same reader as proxy
804 cli
->gbox_peer_id
= cl
->gbox_peer_id
; // signal authenticated
805 gbox_disconnect_double_peers(cli
);
806 cs_auth_client(cli
, account
, NULL
);
807 cli
->account
= account
;
808 cli
->grp
= account
->grp
;
809 cli
->lastecm
= time(NULL
);
817 static void gbox_server_init(struct s_client
*cl
)
819 cs_writelock(__func__
, &clientlist_lock
);
824 cs_log("new connection from %s", cs_inet_ntoa(cl
->ip
));
826 // We cannot authenticate here, because we don't know gbox pw
827 cl
->gbox_peer_id
= NO_GBOX_ID
;
829 cl
->last
= time((time_t *)0);
832 cs_writeunlock(__func__
, &clientlist_lock
);
836 static uint16_t gbox_decode_cmd(uint8_t *buf
)
838 return buf
[0] << 8 | buf
[1];
841 int8_t gbox_message_header(uint8_t *buf
, uint16_t cmd
, uint32_t peer_password
, uint32_t local_password
)
843 if (!buf
) { return -1; }
844 i2b_buf(2, cmd
, buf
);
845 i2b_buf(4, peer_password
, buf
+ 2);
846 if (cmd
== MSG_CW
) { return 0; }
847 i2b_buf(4, local_password
, buf
+ 6);
851 // returns number of cards in a hello packet or -1 in case of error
852 int16_t read_cards_from_hello(uint8_t *ptr
, uint8_t *len
, CAIDTAB
*ctab
, uint8_t maxdist
, struct gbox_peer
*peer
)
854 uint8_t *current_ptr
= 0;
856 int16_t ncards_in_msg
= 0;
860 caprovid
= ptr
[0] << 24 | ptr
[1] << 16 | ptr
[2] << 8 | ptr
[3];
862 ncards_in_msg
+= ptr
[4];
864 if(chk_ctab(gbox_get_caid(caprovid
), ctab
))
869 // for all cards of current caid/provid,
870 while (ptr
< current_ptr
+ 5 + current_ptr
[4] * 4)
872 if ((ptr
[1] & 0xf) <= maxdist
)
874 gbox_add_card(ptr
[2] << 8 | ptr
[3], caprovid
, ptr
[0], ptr
[1] >> 4, ptr
[1] & 0xf, GBOX_CARD_TYPE_GBOX
, peer
);
876 ptr
+= 4; // next card
877 } // end while cards for provider
881 ptr
+= 5 + ptr
[4] * 4; // skip cards because caid
884 return ncards_in_msg
;
887 // returns 1 if checkcode changed / 0 if not
888 static uint8_t gbox_checkcode_recvd(struct s_client
*cli
, uint8_t *checkcode
, uint8_t updcrc
)
890 struct gbox_peer
*peer
= cli
->gbox
;
891 if(memcmp(peer
->checkcode
, checkcode
, 7))
895 cs_log_dump_dbg(D_READER
, peer
->checkcode
, 7, "-> old checkcode from %04X %s:", peer
->gbox
.id
, cli
->reader
->label
);
896 cs_log_dump_dbg(D_READER
, checkcode
, 7, "-> new checkcode from %04X %s:", peer
->gbox
.id
, cli
->reader
->label
);
897 memcpy(peer
->checkcode
, checkcode
, 7);
904 static void disable_remm(struct s_client
*cli
)
906 if (cli
->reader
->blockemm
& 0x80) // if remm marker bit set
908 struct gbox_peer
*peer
= cli
->gbox
;
909 cs_log("-> Disable REMM Req for %04X %s %s", peer
->gbox
.id
, cli
->reader
->label
, cli
->reader
->device
);
910 cli
->reader
->gbox_remm_peer
= 0;
911 cli
->reader
->blockemm
= 15;
912 write_msg_info(cli
, MSGID_REMM
, 0, 0);
917 static void gbox_revd_goodnight(struct s_client
*cli
)
919 cs_log("-> Good Night received from %s %s", cli
->reader
->label
, cli
->reader
->device
);
921 write_msg_info(cli
, MSGID_GOODNIGHT
, 0, 0);
922 gbox_reinit_proxy(cli
);
923 gbox_write_share_cards_info();
924 gbox_update_my_checkcode();
925 //gbox_send_peer_crd_update();
926 cli
->last
= time((time_t *)0);
930 static void gbox_send_my_checkcode(struct s_client
*cli
)
932 struct gbox_peer
*peer
= cli
->gbox
;
934 gbox_message_header(outbuf
, MSG_CHECKCODE
, peer
->gbox
.password
, local_gbox
.password
);
935 memcpy(outbuf
+ 10, gbox_get_my_checkcode(), 7);
936 gbox_send(cli
, outbuf
, 17);
937 cs_log_dump_dbg(D_READER
, gbox_get_my_checkcode(), 7, "<- my checkcode to %s:", cli
->reader
->label
);
939 { cs_log("<- HelloC my checkcode to %s (%s:%d)", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
);}
941 { cs_log_dbg(D_READER
,"<- HelloC my checkcode to %s (%s:%d)", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
);}
945 int32_t gbox_cmd_hello_rcvd(struct s_client
*cli
, uint8_t *data
, int32_t n
)
947 if (!cli
|| !cli
->gbox
|| !cli
->reader
|| !data
) { return -1; }
949 struct gbox_peer
*peer
= cli
->gbox
;
950 int16_t cards_number
= 0;
951 int32_t payload_len
= n
;
952 int32_t hostname_len
= 0;
953 int32_t footer_len
= 0;
955 uint8_t diffcheck
= 0;
956 uint8_t is_helloL
= 0;
958 if(!(gbox_decode_cmd(data
) == MSG_HELLO1
))
960 gbox_decompress(data
, &payload_len
);
961 cs_log_dump_dbg(D_READER
, data
, payload_len
, "-> data decompressed (%d bytes):", payload_len
);
967 cs_log_dump_dbg(D_READER
, data
, payload_len
, "decrypted data (%d bytes):", payload_len
);
970 if ((data
[11] & 0xf) != peer
->next_hello
) // out of sync hellos
972 cs_log("-> out of sync hello from %s %s, expected: %02X, received: %02X",
973 username(cli
), cli
->reader
->device
, peer
->next_hello
, data
[11] & 0xf);
975 peer
->next_hello
= 0;
976 gbox_send_hello(cli
, GBOX_STAT_HELLOL
);
980 if (!(data
[11] & 0xf)) // is first packet
982 gbox_delete_cards(GBOX_DELETE_FROM_PEER
, peer
->gbox
.id
);
983 hostname_len
= data
[payload_len
- 1];
984 footer_len
= hostname_len
+ 2 + 7;
986 if(peer
->hostname
&& memcmp(peer
->hostname
, data
+ payload_len
- 1 - hostname_len
, hostname_len
))
988 cs_log("WARNING - Received Hello from Peer %04X - hostname in cfg is different to received hostname", peer
->gbox
.id
);
991 if(!peer
->hostname
|| memcmp(peer
->hostname
, data
+ payload_len
- 1 - hostname_len
, hostname_len
))
993 NULLFREE(peer
->hostname
);
994 if(!cs_malloc(&peer
->hostname
, hostname_len
+ 1))
998 memcpy(peer
->hostname
, data
+ payload_len
- 1 - hostname_len
, hostname_len
);
999 peer
->hostname
[hostname_len
] = '\0';
1002 diffcheck
=gbox_checkcode_recvd(cli
, data
+ payload_len
- footer_len
- 1, 1);
1005 peer
->crd_crc_change
= 1;
1006 cs_log_dbg(D_READER
,"-> first packet of hello from %04X - diffcheck=1 -> peer-card changed", peer
->gbox
.id
);
1008 peer
->gbox
.minor_version
= data
[payload_len
- footer_len
- 1 + 7];
1009 peer
->gbox
.cpu_api
= data
[payload_len
- footer_len
+ 7];
1010 peer
->total_cards
= 0;
1013 // read cards from hello
1014 cards_number
= read_cards_from_hello(ptr
, data
+ payload_len
- footer_len
- 1, &cli
->reader
->ctab
, cli
->reader
->gbox_maxdist
, peer
);
1016 if (cards_number
< 0)
1020 peer
->total_cards
+= cards_number
;
1021 cs_log_dbg(D_READER
,"-> Hello packet no. %d received - %d unfiltered card(s) - from %s %s", (data
[11] & 0xF) + 1, cards_number
, username(cli
), cli
->reader
->device
);
1024 if(peer
->crd_crc_change
&& cards_number
)
1025 { gbox_update_my_checkcode(); }
1027 if(data
[11] & 0x80) // last packet
1030 memset(&tmpbuf
[0], 0xff, 7);
1032 if(data
[10] == 0x01 && !memcmp(data
+ 12, tmpbuf
, 7)) // good night message
1034 gbox_revd_goodnight(cli
);
1036 else // last packet of Hello
1038 peer
->filtered_cards
= gbox_count_peer_cards(peer
->gbox
.id
);
1042 memset(&tmpbuf
[0], 0, 7);
1043 if(data
[11] == 0x80 && !memcmp(data
+ 12, tmpbuf
, 7)) //is HelloL rev < 3.0
1045 gbox_peer_online(peer
, GBOX_PEER_ONLINE
);
1047 { cs_log("-> HelloL from %s (%s:%d) v2.%02X", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
);}
1049 { cs_log_dbg(D_READER
,"-> HelloL from %s (%s:%d) v2.%02X", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
);}
1053 if(peer
->crd_crc_change
)
1055 peer
->crd_crc_change
= 0;
1056 cs_log_dbg(D_READER
,"-> last packet of HelloS from %04X, peer-card changed -> write shared cards.info", peer
->gbox
.id
);
1057 if(peer
->filtered_cards
)
1059 gbox_write_share_cards_info();
1064 gbox_peer_online(peer
, GBOX_PEER_ONLINE
);
1066 { cs_log("-> HelloL from %s (%s:%d) v2.%02X with %d cards", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
, peer
->filtered_cards
); }
1068 {cs_log_dbg(D_READER
,"-> HelloL from %s (%s:%d) v2.%02X with %d cards", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
, peer
->filtered_cards
); }
1074 { cs_log("-> HelloS from %s (%s:%d) v2.%02X with %d cards", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
, peer
->filtered_cards
); }
1076 { cs_log_dbg(D_READER
,"-> HelloS in %d packets from %s (%s:%d) v2.%02X with %d cards filtered to %d cards", (data
[0x0B] & 0x0f)+1, cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
, peer
->total_cards
, peer
->filtered_cards
); }
1079 cli
->last
= time((time_t *)0);
1080 gbox_send_hello(cli
, GBOX_STAT_HELLOR
);
1084 if(peer
->crd_crc_change
)
1086 peer
->crd_crc_change
= 0;
1087 cs_log_dbg(D_READER
,"-> last packet of HelloR from %04X, peer-card changed -> write shared cards.info", peer
->gbox
.id
);
1088 if(peer
->filtered_cards
)
1090 gbox_write_share_cards_info();
1094 gbox_peer_online(peer
, GBOX_PEER_ONLINE
);
1097 cli
->last
= time((time_t *)0);
1100 { cs_log("-> HelloR from %s (%s:%d) v2.%02X with %d cards", cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
, peer
->filtered_cards
); }
1102 { cs_log_dbg(D_READER
,"-> HelloR in %d packets from %s (%s:%d) v2.%02X with %d cards filtered to %d cards", (data
[0x0B] & 0x0f)+1, cli
->reader
->label
, cs_inet_ntoa(cli
->ip
), cli
->reader
->r_port
, peer
->gbox
.minor_version
, peer
->total_cards
, peer
->filtered_cards
);}
1103 // cs_sleepms(1000); //add some delay like gbox.net?
1104 gbox_send_my_checkcode(cli
);
1109 gbox_peer_online(peer
, GBOX_PEER_ONLINE
);
1110 gbox_send_hello(cli
, GBOX_STAT_HELLOS
);
1113 cli
->reader
->tcp_connected
= CARD_INSERTED
;
1115 if(!peer
->filtered_cards
)
1117 cli
->reader
->card_status
= NO_CARD
;
1121 cli
->reader
->card_status
= CARD_INSERTED
;
1124 peer
->crd_crc_change
= 0;
1125 peer
->next_hello
= 0;
1126 cli
->last
= time((time_t *)0);
1136 uint8_t get_peer_onl_status(uint16_t peer_id
)
1138 cs_readlock(__func__
, &clientlist_lock
);
1139 struct s_client
*cl
;
1140 for(cl
= first_client
; cl
; cl
= cl
->next
)
1142 if(cl
->gbox
&& cl
->typ
== 'p')
1144 struct gbox_peer
*peer
= cl
->gbox
;
1145 if((peer
->gbox
.id
== peer_id
) && peer
->online
)
1147 cs_readunlock(__func__
, &clientlist_lock
);
1152 cs_readunlock(__func__
, &clientlist_lock
);
1156 static int8_t is_blocked_peer(uint16_t peer_id
)
1159 if (cfg
.gbox_block_ecm_num
> 0)
1161 for (i
= 0; i
< cfg
.gbox_block_ecm_num
; i
++)
1163 if (cfg
.gbox_block_ecm
[i
] == peer_id
)
1172 int8_t check_peer_ignored(uint16_t peer_id
)
1175 if (cfg
.gbox_ignored_peer_num
> 0)
1177 for (i
= 0; i
< cfg
.gbox_ignored_peer_num
; i
++)
1179 if (cfg
.gbox_ignored_peer
[i
] == peer_id
)
1188 static int8_t validate_peerpass(uint32_t rcvd_peer_pw
)
1190 struct s_client
*cli
;
1191 cs_readlock(__func__
, &clientlist_lock
);
1193 for(cli
= first_client
; cli
; cli
= cli
->next
)
1195 if(cli
->gbox
&& cli
->typ
== 'p')
1197 struct s_reader
*rdr
= cli
->reader
;
1199 if (rcvd_peer_pw
== a2i(rdr
->r_pwd
, 4))
1201 cs_readunlock(__func__
, &clientlist_lock
);
1206 cs_readunlock(__func__
, &clientlist_lock
);
1210 static int8_t gbox_incoming_ecm(struct s_client
*cli
, uint8_t *data
, int32_t n
)
1212 if(!cli
|| !cli
->gbox
|| !data
|| !cli
->reader
) { return -1; }
1214 struct gbox_peer
*peer
;
1215 struct s_client
*cl
;
1216 uint8_t diffcheck
= 0;
1219 if (!peer
|| !peer
->my_user
)
1230 // No ECMs with length < MIN_LENGTH expected
1231 if ((((data
[19] & 0x0f) << 8) | data
[20]) < MIN_ECM_LENGTH
)
1236 // GBOX_MAX_HOPS not violated
1237 if (data
[n
- 15] + 1 > GBOX_MAXHOPS
)
1239 cs_log("-> incoming ECM distance: %d > max ECM distance: %d", data
[n
- 15] + 1, GBOX_MAXHOPS
);
1243 // ECM must not take more hops than allowed by gbox_reshare
1244 if (data
[n
- 15] + 1 > cli
->reader
->gbox_reshare
)
1246 cs_log("-> incoming ECM dist: %d more than allowed from specified gbox_reshare: %d", data
[n
- 15] + 1, cli
->reader
->gbox_reshare
);
1250 // Check for blocked peers
1251 uint16_t requesting_peer
= data
[(((data
[19] & 0x0f) << 8) | data
[20]) + 21] << 8 |
1252 data
[(((data
[19] & 0x0f) << 8) | data
[20]) + 22];
1254 if (is_blocked_peer(requesting_peer
))
1256 handle_attack(cli
, GBOX_ATTACK_ECM_BLOCKED
, requesting_peer
);
1257 cs_log("ECM from peer %04X blocked by config", requesting_peer
);
1262 if(!(er
= get_ecmtask()))
1267 struct gbox_ecm_request_ext
*ere
;
1268 if(!cs_malloc(&ere
, sizeof(struct gbox_ecm_request_ext
)))
1274 uint8_t *ecm
= data
+ 18; // offset of ECM in gbx message
1277 gbox_init_ecm_request_ext(ere
);
1279 if(peer
->ecm_idx
== 100)
1284 er
->idx
= peer
->ecm_idx
++;
1285 er
->ecmlen
= SCT_LEN(ecm
);
1287 if(er
->ecmlen
< 3 || er
->ecmlen
> MAX_ECM_SIZE
|| er
->ecmlen
+ 18 > n
)
1294 er
->pid
= b2i(2, data
+ 10);
1295 er
->srvid
= b2i(2, data
+ 12);
1297 if(ecm
[er
->ecmlen
+ 5] == 0x05)
1299 er
->caid
= (ecm
[er
->ecmlen
+ 5] << 8);
1303 er
->caid
= b2i(2, ecm
+ er
->ecmlen
+ 5);
1306 memcpy(er
->ecm
, data
+ 18, er
->ecmlen
);
1308 er
->gbox_ecm_src_peer
= b2i(2, ecm
+ er
->ecmlen
); //boxid which ORIGINALLY broadcasted the ECM
1309 ere
->gbox_version
= ecm
[er
->ecmlen
+ 2];
1310 ere
->gbox_rev
= ecm
[er
->ecmlen
+ 3];
1311 ere
->gbox_type
= ecm
[er
->ecmlen
+ 4];
1312 uint32_t caprovid
= b2i(4, ecm
+ er
->ecmlen
+ 5);
1313 er
->gbox_cw_src_peer
= b2i(2, ecm
+ er
->ecmlen
+ 10); //boxid to send ECM to (cw source peer)
1314 ere
->gbox_slot
= ecm
[er
->ecmlen
+ 12];
1315 diffcheck
= gbox_checkcode_recvd(cl
, data
+ n
- 14, 0);
1316 er
->gbox_crc
= gbox_get_checksum(&er
->ecm
[0], er
->ecmlen
);
1317 er
->gbox_ecm_dist
= data
[n
- 15] + 1;
1319 memcpy(&ere
->gbox_routing_info
[0], &data
[n
- 15 - er
->gbox_ecm_dist
+ 1], er
->gbox_ecm_dist
- 1);
1321 er
->caid
= gbox_get_caid(caprovid
);
1322 er
->prid
= gbox_get_provid(caprovid
);
1324 peer
->gbox_rev
= ecm
[er
->ecmlen
+ 3];
1326 cs_log_dbg(D_READER
,"-> ECM (->%d) - ecm-requesting-peer: %04X - cw_src_peer: %04X caid: %04X sid: %04X from_peer: %04X rev: %01X.%01X (%s:%d)",
1327 er
->gbox_ecm_dist
, er
->gbox_ecm_src_peer
, er
->gbox_cw_src_peer
, er
->caid
, er
->srvid
, peer
->gbox
.id
, peer
->gbox_rev
>> 4,
1328 peer
->gbox_rev
& 0xf, peer
->hostname
, cli
->port
);
1332 // checkcode did not match gbox->peer checkcode
1335 cs_log_dbg(D_READER
,"checkcode in ECM CHANGED - Peer %04X ", peer
->gbox
.id
);
1336 gbox_send_hello(cli
, GBOX_STAT_HELLOS
); //peer will send back HelloR with cards, new checkcode etc
1341 static uint32_t gbox_get_pending_time(ECM_REQUEST
*er
, uint16_t peer_id
, uint8_t slot
)
1348 uint32_t ret_time
= 0;
1349 struct gbox_card_pending
*pending
= NULL
;
1350 LL_LOCKITER
*li
= ll_li_create(er
->gbox_cards_pending
, 0);
1352 while((pending
= ll_li_next(li
)))
1354 if ((pending
->id
.peer
== peer_id
) && (pending
->id
.slot
== slot
))
1356 ret_time
= pending
->pending_time
;
1357 er
->gbox_cw_src_peer
= peer_id
;
1365 static int32_t gbox_chk_recvd_dcw(struct s_client
*cli
, uint8_t *dcw
, int32_t *rc
, uint8_t *data
, int32_t n
)
1367 if(!cli
|| gbox_decode_cmd(data
) != MSG_CW
|| n
< 44)
1373 uint16_t id_card
= 0;
1374 struct s_client
*proxy
;
1378 proxy
= get_gbox_proxy(cli
->gbox_peer_id
);
1385 if (!proxy
|| !proxy
->reader
)
1387 cs_log("error, gbox_chk_recvd_dcw, proxy not found");
1388 gbox_send_goodbye(cli
);
1392 proxy
->last
= time((time_t *)0);
1394 memcpy(dcw
, data
+ 14, 16);
1395 uint32_t crc
= b2i(4, data
+ 30);
1397 cs_log_dbg(D_READER
,"-> CW (->%d) received cw: %s from CW-source-peer=%04X, caid=%04X, slot= %d, ecm_pid=%04X, sid=%04X, crc=%08X, cw-src-type=%d, cw-dist=%d, hw-type=%d, rev=%01X.%01X, chid=%04X", data
[42] & 0x0f,
1398 cs_hexdump(0, dcw
, 16, tmp
, sizeof(tmp
)), data
[10] << 8 | data
[11], data
[34] << 8 | data
[35], data
[36], data
[6] << 8 | data
[7],
1399 data
[8] << 8 | data
[9], crc
, data
[41], data
[42] & 0x0f, data
[42] >> 4, data
[43] >> 4,
1400 data
[43] & 0x0f, data
[37] << 8 | data
[38]);
1404 int64_t cw_time
= GBOX_DEFAULT_CW_TIME
;
1406 for(i
= 0; i
< cfg
.max_pending
; i
++)
1408 if(proxy
->ecmtask
[i
].gbox_crc
== crc
)
1410 id_card
= b2i(2, data
+ 10);
1411 cw_time
= comp_timeb(&t_now
, &proxy
->ecmtask
[i
].tps
) - gbox_get_pending_time(&proxy
->ecmtask
[i
], id_card
, data
[36]);
1412 gbox_add_good_sid(id_card
, proxy
->ecmtask
[i
].caid
, data
[36], proxy
->ecmtask
[i
].srvid
, cw_time
);
1413 gbox_remove_all_bad_sids(&proxy
->ecmtask
[i
], proxy
->ecmtask
[i
].srvid
);
1415 if(proxy
->ecmtask
[i
].gbox_ecm_status
== GBOX_ECM_NEW_REQ
|| proxy
->ecmtask
[i
].gbox_ecm_status
== GBOX_ECM_ANSWERED
)
1420 proxy
->ecmtask
[i
].gbox_ecm_status
= GBOX_ECM_ANSWERED
;
1421 proxy
->ecmtask
[i
].gbox_cw_src_peer
= id_card
;
1422 proxy
->reader
->currenthops
= gbox_get_crd_dist_lev(id_card
) & 0xf;
1423 proxy
->reader
->gbox_cw_src_peer
= id_card
;
1424 proxy
->reader
->gbox_crd_slot_lev
= (data
[36] << 4) | ((gbox_get_crd_dist_lev(id_card
) >> 4) & 0xf);
1426 return proxy
->ecmtask
[i
].idx
;
1430 // late answers from other peers,timing not possible
1431 gbox_add_good_sid(id_card
, data
[34] << 8 | data
[35], data
[36], data
[8] << 8 | data
[9], GBOX_DEFAULT_CW_TIME
);
1432 cs_log_dbg(D_READER
, "no task found for crc=%08x", crc
);
1437 static int8_t gbox_received_dcw(struct s_client
*cli
, uint8_t *data
, int32_t n
)
1439 int32_t rc
= 0, i
= 0, idx
= 0;
1442 idx
= gbox_chk_recvd_dcw(cli
, dcw
, &rc
, data
, n
);
1444 if(idx
< 0) // no dcw received
1451 idx
= cli
->last_idx
;
1454 cli
->reader
->last_g
= time((time_t *)0); // for reconnect timeout
1456 for(i
= 0; i
< cfg
.max_pending
; i
++)
1458 if(cli
->ecmtask
[i
].idx
== idx
)
1461 casc_check_dcw(cli
->reader
, i
, rc
, dcw
);
1468 static void gbox_send_peer_crd_update(void)
1470 struct s_client
*cl
;
1471 cs_readlock(__func__
, &clientlist_lock
);
1473 for (cl
= first_client
; cl
; cl
= cl
->next
)
1475 if(cl
->gbox
&& cl
->typ
== 'p' && !check_peer_ignored(cl
->gbox_peer_id
))
1477 struct gbox_peer
*peer
= cl
->gbox
;
1480 gbox_send_hello(cl
, GBOX_STAT_HELLOS
);
1481 cl
->last
= time((time_t *)0);
1485 cs_readunlock(__func__
, &clientlist_lock
);
1489 int32_t gbox_recv_cmd_switch(struct s_client
*proxy
, uint8_t *data
, int32_t n
)
1491 if (!data
|| !proxy
)
1496 uint16_t cmd
= gbox_decode_cmd(data
);
1497 uint8_t diffcheck
= 0;
1498 //struct gbox_peer *peer = proxy->gbox;
1503 cs_log_dbg(D_READER
,"-> HERE? from %s %s - check reader port: %d might be wrong", username(proxy
), proxy
->reader
->device
, proxy
->reader
->r_port
);
1504 // todo: what to reply??
1508 cs_log("-> goodbye message from %s %s",username(proxy
), proxy
->reader
->device
);
1509 //msg goodbye is an indication from peer that requested ECM failed (not found/rejected...)
1510 //TODO: implement on suitable place - rebroadcast ECM to other peers
1511 write_msg_info(proxy
, MSGID_GOODBYE
, 0, 0);
1517 cs_log("-> MSG_GSMS from %s %s", username(proxy
), proxy
->reader
->device
);
1518 gbox_send_gsms_ack(proxy
);
1519 write_gsms_msg(proxy
, data
+16, data
[14], data
[15]);
1520 write_msg_info(proxy
, MSGID_GSMS
, 0, data
[14]);
1531 cs_log("-> MSG_GSMS_ACK from %s %s", username(proxy
), proxy
->reader
->device
);
1532 write_gsms_ack(proxy
);
1542 if(gbox_cmd_hello_rcvd(proxy
, data
, n
) < 0)
1549 gbox_received_dcw(proxy
, data
, n
);
1553 diffcheck
= gbox_checkcode_recvd(proxy
, data
+ 10, 0);
1557 cs_log("-> HelloC checkcode from %s - %s %s", username(proxy
), proxy
->reader
->device
, diffcheck
? "- crc diff":"");
1561 cs_log_dbg(D_READER
,"-> HelloC checkcode from %s - %s %s", username(proxy
), proxy
->reader
->device
, diffcheck
? "- crc diff":"");
1566 gbox_write_share_cards_info(); //need that for gbox.net peer @ local crd change
1567 cs_log_dbg(D_READER
,"peer %s - %s checkcode changed", username(proxy
), proxy
->reader
->device
);
1572 gbox_incoming_ecm(proxy
, data
, n
);
1576 //cs_log_dbg(D_EMM,"-> Incoming REMM MSG (%d bytes) from %s - %s", n, username(proxy), proxy->reader->device);
1577 cs_log_dump_dbg(D_EMM
, data
, n
, "-> gbox incoming REMM MSG - (len=%d bytes):", n
);
1578 gbox_recvd_remm_cmd_switch(proxy
, data
, n
);
1582 cs_log("-> unknown command %04X received from %s %s",
1583 cmd
, username(proxy
), proxy
->reader
->device
);
1585 write_msg_info(proxy
, MSGID_UNKNOWNMSG
, 0, 0);
1587 cs_log_dump_dbg(D_READER
, data
, n
, "unknown data (%d bytes) received from %s %s",
1588 n
, username(proxy
), proxy
->reader
->device
);
1593 uint8_t add_betatunnel_card(uint16_t caid
, uint8_t slot
)
1596 struct s_client
*cli
;
1597 cs_readlock(__func__
, &clientlist_lock
);
1599 for(cli
= first_client
; cli
; cli
= cli
->next
)
1604 for(i
= 0; i
< ttab
->ttnum
; i
++)
1606 // Check for Betatunnel on gbox account in oscam.user
1607 if(cli
->gbox
&& ttab
->ttdata
&& caid
== ttab
->ttdata
[i
].bt_caidto
)
1609 gbox_add_card(local_gbox
.id
, gbox_get_caprovid(ttab
->ttdata
[i
].bt_caidfrom
, i
), slot
, DEFAULT_GBOX_RESHARE
, 0, GBOX_CARD_TYPE_BETUN
, NULL
);
1610 cs_log_dbg(D_READER
, "gbox created betatunnel card for caid: %04X->%04X", ttab
->ttdata
[i
].bt_caidfrom
, caid
);
1611 cs_readunlock(__func__
, &clientlist_lock
);
1616 cs_readunlock(__func__
, &clientlist_lock
);
1620 static uint32_t gbox_add_local_cards(void)
1626 uint16_t cccrdnb
= 0;
1629 struct cc_card
*card
= NULL
;
1631 uint32_t checksum
= 0;
1632 uint16_t cc_peer_id
= 0;
1633 struct cc_provider
*provider
;
1634 uint8_t *node1
= NULL
;
1637 gbox_delete_cards(GBOX_DELETE_WITH_TYPE
, GBOX_CARD_TYPE_CCCAM
);
1639 gbox_delete_cards(GBOX_DELETE_WITH_ID
, local_gbox
.id
);
1640 struct s_client
*cl
;
1642 cs_readlock(__func__
, &clientlist_lock
);
1643 for(cl
= first_client
; cl
; cl
= cl
->next
)
1645 if(cl
->typ
== 'r' && cl
->reader
&& cl
->reader
->card_status
== CARD_INSERTED
&& cl
->reader
->enable
)
1647 slot
= gbox_next_free_slot(local_gbox
.id
);
1649 // SECA, Viaccess and Cryptoworks have multiple providers
1650 if(caid_is_seca(cl
->reader
->caid
) || caid_is_cryptoworks(cl
->reader
->caid
))
1652 for(i
= 0; i
< cl
->reader
->nprov
; i
++)
1654 prid
= cl
->reader
->prid
[i
][1] << 16 | cl
->reader
->prid
[i
][2] << 8 | cl
->reader
->prid
[i
][3];
1655 gbox_add_card(local_gbox
.id
, gbox_get_caprovid(cl
->reader
->caid
, prid
), slot
, DEFAULT_GBOX_RESHARE
, 0, GBOX_CARD_TYPE_LOCAL
, NULL
);
1658 else if(caid_is_viaccess(cl
->reader
->caid
))
1660 for(i
= 1; i
< cl
->reader
->nprov
; i
++) //skip via issuer
1662 prid
= cl
->reader
->prid
[i
][1] << 16 | cl
->reader
->prid
[i
][2] << 8 | cl
->reader
->prid
[i
][3];
1663 gbox_add_card(local_gbox
.id
, gbox_get_caprovid(cl
->reader
->caid
, prid
), slot
, DEFAULT_GBOX_RESHARE
, 0, GBOX_CARD_TYPE_LOCAL
, NULL
);
1668 gbox_add_card(local_gbox
.id
, gbox_get_caprovid(cl
->reader
->caid
, 0), slot
, DEFAULT_GBOX_RESHARE
, 0, GBOX_CARD_TYPE_LOCAL
, NULL
);
1669 if(chk_is_betatunnel_caid(cl
->reader
->caid
) == 1) // 1702 1722
1671 if(add_betatunnel_card(cl
->reader
->caid
, gbox_next_free_slot(local_gbox
.id
)))
1676 } // end local readers
1678 if(cfg
.cc_gbx_reshare_en
&& cfg
.cc_reshare
> -1 && cl
->typ
== 'p' && cl
->reader
&& cl
->reader
->typ
== R_CCCAM
&& cl
->cc
)
1681 it
= ll_iter_create(cc
->cards
);
1683 while((card
= ll_iter_next(&it
)))
1685 // calculate gbox id from cc node
1686 node1
= ll_has_elements(card
->remote_nodes
);
1687 checksum
= ((node1
[0] ^ node1
[7]) << 8) | ((node1
[1] ^ node1
[6]) << 24) | (node1
[2] ^ node1
[5]) | ((node1
[3] ^ node1
[4]) << 16);
1688 cc_peer_id
= ((((checksum
>> 24) & 0xFF) ^ ((checksum
>> 8) & 0xFF)) << 8 | (((checksum
>> 16) & 0xFF) ^ (checksum
& 0xFF))) + offset
;
1690 slot
= gbox_next_free_slot(cc_peer_id
);
1692 if(caid_is_seca(card
->caid
) || caid_is_viaccess(card
->caid
) || caid_is_cryptoworks(card
->caid
))
1694 it2
= ll_iter_create(card
->providers
);
1695 while((provider
= ll_iter_next(&it2
)))
1697 gbox_add_card(cc_peer_id
, gbox_get_caprovid(card
->caid
, provider
->prov
), slot
, DEFAULT_CCC_GBOX_RESHARE
, card
->hop
, GBOX_CARD_TYPE_CCCAM
, NULL
);
1702 gbox_add_card(cc_peer_id
, gbox_get_caprovid(card
->caid
, 0), slot
, DEFAULT_CCC_GBOX_RESHARE
, card
->hop
, GBOX_CARD_TYPE_CCCAM
, NULL
);
1710 offset
+= (rand() % 18) +1;
1711 //cs_log("cccrdnum: %d, slot: %d, offset: %d, caid: %04X, peer: %04X", cccrdnb, slot, offset, card->caid, cc_peer_id);
1716 } // end for clients
1718 cs_readunlock(__func__
, &clientlist_lock
);
1720 if (cfg
.gbox_proxy_cards_num
> 0)
1722 for (i
= 0; i
< cfg
.gbox_proxy_cards_num
; i
++)
1724 slot
= gbox_next_free_slot(local_gbox
.id
);
1725 gbox_add_card(local_gbox
.id
, cfg
.gbox_proxy_card
[i
], slot
, DEFAULT_GBOX_RESHARE
, 0, GBOX_CARD_TYPE_PROXY
, NULL
);
1726 cs_log_dbg(D_READER
,"add proxy card: slot %d %04X:%06X", slot
, gbox_get_caid(cfg
.gbox_proxy_card
[i
]), gbox_get_provid(cfg
.gbox_proxy_card
[i
]));
1729 } //end add proxy reader cards
1731 gbox_update_my_checkcode();
1732 gbox_write_local_cards_info();
1733 if (!local_cards_initialized
)
1735 local_cards_initialized
= 1;
1736 if(cfg
.cc_gbx_reshare_en
)
1737 { cs_log("Local gbox cards initialized - cards: %d - filtered cccards: %d", crdnb
- cccrdnb
, cccrdnb
); }
1739 { cs_log("Local gbox cards initialized - cards: %d", crdnb
); }
1741 return (cccrdnb
<< 16) | (crdnb
- cccrdnb
);
1742 } //end add local gbox cards
1744 void gbx_local_card_stat(uint8_t crdstat
, uint16_t caid
)
1746 if(crdstat
&& local_cards_initialized
)
1748 if(crdstat
== LOCALCARDEJECTED
)
1752 else if(crdstat
== LOCALCARDUP
)
1755 cs_log("New local card ready - caid = %04X", caid
);
1757 else if(crdstat
== LOCALCARDDISABLED
)
1759 cs_log_dbg(D_READER
,"Local Gbox Card disabled by WebIF");
1766 cs_log("Card update send to peer(s) online - Local/Proxy crd(s):%d", gbox_add_local_cards() & 0xffff);
1767 //gbox_write_local_cards_info(); //done by gbox_add_local_cards()
1768 gbox_send_peer_crd_update();
1773 uint8_t chk_gbx_hdr_rcvd(uint16_t rcvd_header_cmd
)
1775 switch(rcvd_header_cmd
)
1794 // returns -1 in case of error, 1 if authentication was performed, 0 else
1795 static int8_t gbox_check_header_recvd(struct s_client
*cli
, struct s_client
*proxy
, uint8_t *data
, int32_t l
)
1797 struct gbox_peer
*peer
= NULL
;
1798 if (proxy
) { peer
= proxy
->gbox
; }
1802 uint8_t authentication_done
= 0;
1803 uint16_t peer_recvd_id
= 0;
1804 uint32_t my_received_pw
= 0;
1805 uint32_t peer_received_pw
= 0;
1806 uint16_t rcvd_header_cmd
;
1808 cs_log_dump_dbg(D_READER
, data
, n
, "-> crypted data (%d bytes) from %s:", n
, cs_inet_ntoa(cli
->ip
));
1809 gbox_decrypt(data
, n
, local_gbox
.password
);
1810 cs_log_dump_dbg(D_READER
, data
, n
, "-> decrypted data (%d bytes) from %s:", n
, cs_inet_ntoa(cli
->ip
));
1812 peer_received_pw
= b2i(4, data
+ 6);
1813 my_received_pw
= b2i(4, data
+ 2);
1814 rcvd_header_cmd
= b2i(2, data
);
1816 if(!chk_gbx_hdr_rcvd(rcvd_header_cmd
))
1818 cs_log("-> ATTACK ALERT from IP %s - Received unknown Header: %02X", cs_inet_ntoa(cli
->ip
), b2i(2, data
));
1819 //cs_log_dbg(D_READER,"-> received data: %s", cs_hexdump(1, data, n, tmp, sizeof(tmp)));
1820 cs_log("-> received data: %s", cs_hexdump(1, data
, n
, tmp
, sizeof(tmp
)));
1821 handle_attack(cli
, GBOX_ATTACK_UNKWN_HDR
, 0);
1825 if (my_received_pw
== local_gbox
.password
)
1827 if (gbox_decode_cmd(data
) != MSG_CW
)
1829 //peer_received_pw = b2i(4, data + 6);
1830 peer_recvd_id
= gbox_convert_password_to_id(peer_received_pw
);
1832 //cs_log_dbg(D_READER, "-> data from IP: %s", cs_inet_ntoa(cli->ip));
1833 cs_log_dbg(D_READER
, "-> data from peer: %04X data: %s", peer_recvd_id
, cs_hexdump(0, data
, l
, tmp
, sizeof(tmp
)));
1834 //cs_log_dbg(D_READER,"my_received pw: %08X - peer_recvd pw: %08X - peer_recvd_id: %04X ", my_received_pw, peer_received_pw, peer_recvd_id);
1836 if (check_peer_ignored(peer_recvd_id
))
1838 handle_attack(cli
, GBOX_ATTACK_PEER_IGNORE
, peer_recvd_id
);
1839 cs_log("Peer blocked by conf - ignoring gbox peer_id: %04X", peer_recvd_id
);
1843 if (!validate_peerpass(peer_received_pw
))
1845 handle_attack(cli
, GBOX_ATTACK_PEER_PW
, peer_recvd_id
);
1846 cs_log("peer: %04X - peerpass: %08X unknown -> enable reader and check oscam.server->[reader]->password",
1847 peer_recvd_id
, peer_received_pw
);
1852 if (cli
->gbox_peer_id
== NO_GBOX_ID
&& gbox_decode_cmd(data
) != MSG_HERE
)
1853 //if (cli->gbox_peer_id == NO_GBOX_ID)
1855 if (gbox_auth_client(cli
, peer_received_pw
) < 0)
1857 handle_attack(cli
, GBOX_ATTACK_AUTH_FAIL
, peer_recvd_id
);
1858 cs_log ("Peer %04X:%s authentication failed. Check user in [account] or {reader] section", peer_recvd_id
, cs_inet_ntoa(cli
->ip
));
1862 authentication_done
= 1;
1863 proxy
= get_gbox_proxy(cli
->gbox_peer_id
);
1872 if (peer_received_pw
!= peer
->gbox
.password
)
1874 cs_log("gbox peer: %04X sends wrong own password", peer
->gbox
.id
);
1880 cs_log_dbg(D_READER
, "-> CW MSG from peer: %04X data: %s",
1881 cli
->gbox_peer_id
, cs_hexdump(0, data
, l
, tmp
, sizeof(tmp
)));
1883 if((data
[39] != ((local_gbox
.id
>> 8) & 0xff)) || (data
[40] != (local_gbox
.id
& 0xff)))
1885 cs_log_dbg(D_READER
,"peer: %04X sends CW not to my id: %04X -> forwarding CW to requesting peer %02X%02X ", cli
->gbox_peer_id
, local_gbox
.id
, data
[39], data
[40]);
1889 else // error my passw
1891 cs_log("-> ATTACK ALERT from IP %s - received corrupted data - local password: %08X - peer password: %08X", cs_inet_ntoa(cli
->ip
), my_received_pw
, peer_received_pw
);
1892 //cs_log_dbg(D_READER,"-> received data: %s", cs_hexdump(1, data, n, tmp, sizeof(tmp)));
1893 cs_log("-> received data: %s", cs_hexdump(1, data
, n
, tmp
, sizeof(tmp
)));
1894 handle_attack(cli
, GBOX_ATTACK_LOCAL_PW
, 0);
1903 if(!IP_EQUAL(cli
->ip
, proxy
->ip
))
1905 cs_log("IP change received - peer %04X. New IP = %s. Reconnecting...", cli
->gbox_peer_id
, cs_inet_ntoa(cli
->ip
));
1906 restart_gbox_peer(NULL
, 0, cli
->gbox_peer_id
);
1907 //gbox_reconnect_peer(proxy);
1908 write_msg_info(cli
, MSGID_IPCHANGE
, 0, 0);
1920 cli
->last
= time((time_t *)0);
1921 cs_log("peer %04X authenticated successfully", cli
->gbox_peer_id
);
1923 return authentication_done
;
1926 static int32_t gbox_recv(struct s_client
*cli
, uint8_t *buf
, int32_t l
)
1928 uint8_t data
[RECEIVE_BUFFER_SIZE
];
1929 int32_t n
= l
, chkcmd
;
1932 if(!cli
->udp_fd
|| !cli
->is_udp
|| cli
->typ
!= 'c')
1937 n
= recv_from_udpipe(buf
);
1938 if (n
< MIN_GBOX_MESSAGE_LENGTH
|| n
>= RECEIVE_BUFFER_SIZE
) // protect against too short or too long messages
1943 struct s_client
*proxy
= get_gbox_proxy(cli
->gbox_peer_id
);
1945 memcpy(&data
[0], buf
, n
);
1947 ret
= gbox_check_header_recvd(cli
, proxy
, &data
[0], n
);
1953 // in case of new authentication the proxy gbox can now be found
1956 proxy
= get_gbox_proxy(cli
->gbox_peer_id
);
1964 cli
->last
= time((time_t *)0);
1965 cli
->gbox
= proxy
->gbox
; // point to the same gbox as proxy
1966 cli
->reader
= proxy
->reader
; // point to the same reader as proxy
1967 struct gbox_peer
*peer
= proxy
->gbox
;
1968 cs_writelock(__func__
, &peer
->lock
);
1969 chkcmd
= gbox_recv_cmd_switch(proxy
, data
, n
);
1970 cs_writeunlock(__func__
, &peer
->lock
);
1980 static uint8_t check_setup( void)
1983 if (module_dvbapi_enabled())
1984 { return 0x30; } //stb
1988 return 0x50; //server
1992 static void gbox_send_dcw(struct s_client
*cl
, ECM_REQUEST
*er
)
1999 struct s_client
*cli
= get_gbox_proxy(cl
->gbox_peer_id
);
2000 if (!cli
|| !cli
->gbox
)
2004 struct gbox_peer
*peer
= cli
->gbox
;
2006 struct gbox_ecm_request_ext
*ere
= er
->src_data
;
2008 if(er
->rc
== E_NOTFOUND
&& cli
->reader
->gbox_force_remm
&& ere
->gbox_rev
>> 4)
2010 gbox_send_remm_req(cli
, er
);
2014 if(er
->rc
>= E_NOTFOUND
)
2016 cs_log_dbg(D_READER
, "unable to decode!");
2017 gbox_send_goodbye(cli
);
2022 memset(buf
, 0, sizeof(buf
));
2024 gbox_message_header(buf
, MSG_CW
, peer
->gbox
.password
, 0);
2025 i2b_buf(2, er
->pid
, buf
+ 6); // PID
2026 i2b_buf(2, er
->srvid
, buf
+ 8); // SrvID
2027 i2b_buf(2, er
->gbox_cw_src_peer
, buf
+ 10); // From peer - source of cw
2028 buf
[12] = (ere
->gbox_slot
<< 4) | (er
->ecm
[0] & 0x0f); // slot << 4 | even/odd
2029 buf
[13] = er
->caid
>> 8; // CAID first byte
2030 memcpy(buf
+ 14, er
->cw
, 16); // CW
2031 i2b_buf(4, er
->gbox_crc
, buf
+ 30); // CRC
2032 i2b_buf(2, er
->caid
, buf
+ 34); // CAID
2033 buf
[36] = ere
->gbox_slot
; // Slot
2035 if (buf
[34] == 0x06) // if irdeto
2037 i2b_buf(2, er
->chid
, buf
+ 37); // CHID
2041 if (local_gbox
.minor_version
== 0x2A)
2043 buf
[37] = 0xff; // gbox.net sends 0xff
2044 buf
[38] = 0xff; // gbox.net sends 0xff
2048 buf
[37] = 0; // gbox sends 0
2049 buf
[38] = 0; // gbox sends 0
2053 i2b_buf(2, er
->gbox_ecm_src_peer
, buf
+ 39); // Target peer to recv cw
2055 if(er
->rc
== E_CACHE1
|| er
->rc
== E_CACHE2
|| er
->rc
== E_CACHEEX
)
2056 { buf
[41] = 0x03; } // source of cw -> cache
2058 { buf
[41] = 0x01; } // source of cw -> card, emu
2060 uint8_t cw_dist
= gbox_get_crd_dist_lev(er
->gbox_cw_src_peer
) & 0xf;
2062 buf
[42] = ((check_setup()) | (cw_dist
+ 1));
2063 buf
[43] = ere
->gbox_rev
& 0xf0;
2065 // This copies the routing info from ECM to cw answer.
2066 memcpy(&buf
[44], &ere
->gbox_routing_info
, er
->gbox_ecm_dist
- 1);
2067 buf
[44 + er
->gbox_ecm_dist
- 1] = er
->gbox_ecm_dist
- 1; //act. dist
2070 for(i = 0; i < er->gbox_ecm_dist; i++)
2075 gbox_send(cli
, buf
, 44 + er
->gbox_ecm_dist
);
2079 cs_log("sending dcw to peer : %04x data: %s", er->gbox_ecm_src_peer, cs_hexdump(0, buf, er->gbox_ecm_dist + 44, tmp, sizeof(tmp)));
2082 if(ere
->gbox_rev
>> 4)
2083 { gbox_send_remm_req(cli
, er
); }
2085 cs_log_dbg(D_READER
,"<- CW (<-%d) caid; %04X from cw-source-peer: %04X forward to ecm-requesting-peer: %04X - forwarding peer: %04X %s rev:%01X.%01X port:%d",
2086 er
->gbox_ecm_dist
, er
->caid
, er
->gbox_cw_src_peer
, er
->gbox_ecm_src_peer
, peer
->gbox
.id
, cli
->reader
->label
,
2087 ere
->gbox_rev
>> 4, ere
->gbox_rev
& 0xf, cli
->port
);
2090 static int32_t gbox_send_ecm(struct s_client
*cli
, ECM_REQUEST
*er
)
2092 if(!cli
|| !cli
->reader
|| !er
|| !er
->ecmlen
)
2097 if(!cli
->gbox
|| !cli
->reader
->tcp_connected
)
2099 cs_log_dbg(D_READER
, "%s server not init!", cli
->reader
->label
);
2100 write_ecm_answer(cli
->reader
, er
, E_NOTFOUND
, 0x27, NULL
, NULL
, 0, NULL
);
2104 struct gbox_peer
*peer
= cli
->gbox
;
2106 if(!peer
->filtered_cards
)
2108 cs_log_dbg(D_READER
, "Send ECM failed, %s NO CARDS!", cli
->reader
->label
);
2109 write_ecm_answer(cli
->reader
, er
, E_NOTFOUND
, E2_CCCAM_NOCARD
, NULL
, NULL
, 0, NULL
);
2115 cs_log_dbg(D_READER
, "Send ECM failed, peer is OFFLINE!");
2116 write_ecm_answer(cli
->reader
, er
, E_NOTFOUND
, 0x27, NULL
, NULL
, 0, NULL
);
2120 if(er
->gbox_ecm_status
== GBOX_ECM_ANSWERED
)
2122 cs_log_dbg(D_READER
, "%s replied to this ecm already", cli
->reader
->label
);
2125 if(er
->gbox_ecm_status
== GBOX_ECM_NEW_REQ
)
2127 er
->gbox_cards_pending
= ll_create("pending_gbox_cards");
2130 uint8_t send_buf
[1024];
2131 int32_t buflen
, len1
;
2133 len1
= er
->ecmlen
+ 18; // length till end of ECM
2135 er
->gbox_crc
= gbox_get_checksum(&er
->ecm
[0], er
->ecmlen
);
2137 memset(send_buf
, 0, sizeof(send_buf
));
2139 uint8_t nb_matching_crds
= 0;
2140 uint32_t current_avg_card_time
= 0;
2142 gbox_message_header(send_buf
, MSG_ECM
, peer
->gbox
.password
, local_gbox
.password
);
2143 i2b_buf(2, er
->pid
, send_buf
+ 10);
2144 i2b_buf(2, er
->srvid
, send_buf
+ 12);
2145 send_buf
[14] = 0x00;
2146 send_buf
[15] = 0x00;
2147 send_buf
[17] = 0x00;
2148 memcpy(send_buf
+ 18, er
->ecm
, er
->ecmlen
);
2150 if(!er
->gbox_ecm_dist
)
2152 er
->gbox_ecm_src_peer
= local_gbox
.id
;
2153 i2b_buf(2, local_gbox
.id
, send_buf
+ len1
); //local boxid first broadcasted the ECM
2154 send_buf
[len1
+ 3] = 0x4;
2158 i2b_buf(2, er
->gbox_ecm_src_peer
, send_buf
+ len1
); //forward boxid that originally broadcasted the ECM
2159 send_buf
[len1
+ 3] = 0;
2162 send_buf
[len1
+ 2] = cfg
.gbox_my_vers
;
2164 if(check_valid_remm_peer( peer
->gbox
.id
))
2166 send_buf
[len1
+ 3] = local_gbx_rev
;
2169 send_buf
[len1
+ 4] = gbox_get_my_cpu_api();
2171 uint32_t caprovid
= gbox_get_caprovid(er
->caid
, er
->prid
);
2172 i2b_buf(4, caprovid
, send_buf
+ len1
+ 5);
2174 send_buf
[len1
+ 9] = 0x00;
2177 nb_matching_crds
= gbox_get_cards_for_ecm(&send_buf
[0], len1
+ 10, cli
->reader
->gbox_maxecmsend
, er
, ¤t_avg_card_time
, peer
->gbox
.id
, cli
->reader
->gbox_force_remm
);
2179 buflen
+= nb_matching_crds
* 3;
2181 if(!nb_matching_crds
&& er
->gbox_ecm_status
== GBOX_ECM_NEW_REQ
)
2183 cs_log_dbg(D_READER
, "no valid card found for CAID: %04X PROV: %06X", er
->caid
, er
->prid
);
2184 write_ecm_answer(cli
->reader
, er
, E_NOTFOUND
, E2_CCCAM_NOCARD
, NULL
, NULL
, 0, NULL
);
2188 if(nb_matching_crds
)
2190 send_buf
[16] = nb_matching_crds
; // Number of cards the ECM should be forwarded to
2194 for(i
= 0; i
< er
->gbox_ecm_dist
+ 1; i
++)
2196 send_buf
[buflen
] = i
;
2200 memcpy(&send_buf
[buflen
], gbox_get_my_checkcode(), 7);
2201 buflen
= buflen
+ 7;
2202 memcpy(&send_buf
[buflen
], peer
->checkcode
, 7);
2203 buflen
= buflen
+ 7;
2205 struct gbox_card_pending
*pending
= NULL
;
2209 for (i
= 0; i
< nb_matching_crds
; i
++)
2211 if(!cs_malloc(&pending
, sizeof(struct gbox_card_pending
)))
2213 cs_log("Can't allocate gbox card pending");
2216 pending
->id
.peer
= (send_buf
[len1
+10+i
*3] << 8) | send_buf
[len1
+11+i
*3];
2217 pending
->id
.slot
= send_buf
[len1
+12+i
*3];
2218 pending
->pending_time
= comp_timeb(&t_now
, &er
->tps
);
2220 ll_append(er
->gbox_cards_pending
, pending
);
2221 cs_log_dbg(D_READER
, "matching gbox card(s): %d, ID: %04X, Slot: %02X",
2222 i
+ 1, (send_buf
[len1
+ 10 + i
* 3] << 8) | send_buf
[len1
+ 11 + i
* 3], send_buf
[len1
+ 12 + i
* 3]);
2225 LL_LOCKITER
*li
= ll_li_create(er
->gbox_cards_pending
, 0);
2226 while ((pending
= ll_li_next(li
)))
2228 cs_log_dbg(D_READER
, "Pending Card ID: %04X Slot: %02X time: %d", pending
->id
.peer
, pending
->id
.slot
, pending
->pending_time
);
2229 er
->gbox_cw_src_peer
= pending
->id
.peer
;
2230 cs_log_dbg(D_READER
,"<- ECM (<-%d) - caid: %04X prov: %06X sid: %04X to cw-src-peer: %04X - ecm_src_peer: %04X",
2231 gbox_get_crd_dist_lev(er
->gbox_cw_src_peer
) & 0xf, er
->caid
, er
->prid
, er
->srvid
, er
->gbox_cw_src_peer
, er
->gbox_ecm_src_peer
);
2235 if(er
->gbox_ecm_status
== GBOX_ECM_NEW_REQ
)
2237 er
->gbox_ecm_status
++;
2241 gbox_send(cli
, send_buf
, buflen
);
2242 cli
->reader
->last_s
= time((time_t *) 0);
2247 // init my gbox with id, password etc
2248 static int8_t init_local_gbox(void)
2252 local_gbox
.password
= 0;
2253 local_gbox
.minor_version
= cfg
.gbox_my_vers
;
2254 local_gbox
.cpu_api
= gbox_get_my_cpu_api();
2255 init_gbox_cards_list();
2257 if(!cfg
.gbox_port
[0])
2259 cs_log("error, no/invalid port=%d configured in oscam.conf!", cfg
.gbox_port
[0] ? cfg
.gbox_port
[0] : 0);
2263 if(!cfg
.gbox_hostname
|| cs_strlen(cfg
.gbox_hostname
) > 128)
2265 cs_log("error, no/invalid hostname '%s' configured in oscam.conf!",
2266 cfg
.gbox_hostname
? cfg
.gbox_hostname
: "");
2270 if(!cfg
.gbox_password
)
2272 cs_log("error, 'my_password' not configured in oscam.conf!");
2276 if(!cfg
.gbox_reconnect
|| cfg
.gbox_reconnect
> GBOX_MAX_RECONNECT
|| cfg
.gbox_reconnect
< GBOX_MIN_RECONNECT
)
2278 cs_log("Invalid 'gbox_reconnect = %d' Using default: %d sec", cfg
.gbox_reconnect
, DEFAULT_GBOX_RECONNECT
);
2279 cfg
.gbox_reconnect
= DEFAULT_GBOX_RECONNECT
;
2282 local_gbox
.password
= cfg
.gbox_password
;
2283 local_gbox
.id
= gbox_convert_password_to_id(local_gbox
.password
);
2287 cs_log("invalid 'my_password' %08X -> local gbox id: %04X, choose another 'my_password'",
2288 cfg
.gbox_password
, local_gbox
.id
);
2292 local_gbox_initialized
= 1;
2294 for(i
= 0; i
< CS_MAXPORTS
; i
++)
2296 if(!cfg
.gbox_port
[i
])
2298 cs_log("we are online - %d port(s) to monitor", i
);
2303 gbox_write_version();
2305 return local_gbox_initialized
;
2308 static int32_t gbox_peer_init(struct s_client
*cli
)
2310 if(!cli
|| cli
->typ
!= 'p' || !cli
->reader
)
2312 cs_log("error, wrong call to gbox_peer_init!");
2316 if (local_gbox_initialized
< 0)
2322 if(!local_gbox_initialized
)
2324 local_gbox_initialized
= 1;
2325 ret
= init_local_gbox();
2328 local_gbox_initialized
= -1;
2329 cs_log("local gbox initialization failed");
2330 write_msg_info(cli
, MSGID_GBOXONL
, 0, 0);
2333 write_msg_info(cli
, MSGID_GBOXONL
, 0, 1);
2336 if(!cs_malloc(&cli
->gbox
, sizeof(struct gbox_peer
)))
2341 struct s_reader
*rdr
= cli
->reader
;
2342 struct gbox_peer
*peer
= cli
->gbox
;
2344 memset(peer
, 0, sizeof(struct gbox_peer
));
2346 peer
->gbox
.password
= a2i(rdr
->r_pwd
, 4);
2347 //cs_log_dbg(D_READER,"peer-reader-label: %s peer-reader-password: %s", cli->reader->label, rdr->r_pwd);
2348 peer
->gbox
.id
= gbox_convert_password_to_id(peer
->gbox
.password
);
2350 if (get_gbox_proxy(peer
->gbox
.id
) || peer
->gbox
.id
== NO_GBOX_ID
|| peer
->gbox
.id
== local_gbox
.id
)
2352 cs_log("error, double/invalid gbox id: %04X", peer
->gbox
.id
);
2355 cs_lock_create(__func__
, &peer
->lock
, "gbox_lock", 5000);
2357 gbox_clear_peer(peer
);
2359 cli
->gbox_peer_id
= peer
->gbox
.id
;
2364 rdr
->card_status
= CARD_NEED_INIT
;
2365 rdr
->tcp_connected
= 0;
2367 set_null_ip(&cli
->ip
);
2369 if((cli
->udp_fd
= socket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
)) < 0)
2371 cs_log("socket creation failed (errno=%d %s)", errno
, strerror(errno
));
2372 cs_disconnect_client(cli
);
2376 setsockopt(cli
->udp_fd
, SOL_SOCKET
, SO_REUSEADDR
, &opt
, sizeof(opt
));
2378 set_so_reuseport(cli
->udp_fd
);
2380 set_socket_priority(cli
->udp_fd
, cfg
.netprio
);
2382 memset((char *)&cli
->udp_sa
, 0, sizeof(cli
->udp_sa
));
2384 if(!hostResolve(rdr
))
2389 cli
->port
= rdr
->r_port
;
2390 SIN_GET_FAMILY(cli
->udp_sa
) = AF_INET
;
2391 SIN_GET_PORT(cli
->udp_sa
) = htons((uint16_t)rdr
->r_port
);
2392 hostname2ip(cli
->reader
->device
, &SIN_GET_ADDR(cli
->udp_sa
));
2394 cs_log("proxy %s (fd=%d, peer id=%04X, my id=%04X, my hostname=%s, peer's listen port=%d)",
2395 rdr
->device
, cli
->udp_fd
, peer
->gbox
.id
, local_gbox
.id
, cfg
.gbox_hostname
, rdr
->r_port
);
2397 cli
->pfd
= cli
->udp_fd
;
2399 if(!cli
->reader
->gbox_maxecmsend
)
2401 cli
->reader
->gbox_maxecmsend
= DEFAULT_GBOX_MAX_ECM_SEND
;
2404 if(!cli
->reader
->gbox_maxdist
)
2406 cli
->reader
->gbox_maxdist
= DEFAULT_GBOX_MAX_DIST
;
2409 // value > GBOX_MAXHOPS not allowed in gbox network
2410 if(cli
->reader
->gbox_reshare
> GBOX_MAXHOPS
)
2412 cli
->reader
->gbox_reshare
= GBOX_MAXHOPS
;
2415 if(cli
->reader
->gbox_cccam_reshare
> GBOX_MAXHOPS
)
2417 cli
->reader
->gbox_cccam_reshare
= GBOX_MAXHOPS
;
2423 static void gbox_send_HERE(struct s_client
*cli
)
2425 struct gbox_peer
*peer
= cli
->gbox
;
2427 int32_t hostname_len
= cs_strlen(cli
->reader
->device
);
2428 gbox_message_header(outbuf
, MSG_HERE
, peer
->gbox
.password
, local_gbox
.password
);
2429 outbuf
[0xA] = cfg
.gbox_my_vers
;
2430 outbuf
[0xB] = gbox_get_my_cpu_api();
2431 memcpy(&outbuf
[0xC], cli
->reader
->device
, hostname_len
);
2432 gbox_send(cli
, outbuf
, hostname_len
+ 0xC);
2434 { cs_log("<- send Keep Alive MSG HERE to boxid: %04X - %s", peer
->gbox
.id
, cli
->reader
->label
); }
2436 { cs_log_dbg(D_READER
,"<- send Keep Alive MSG HERE to boxid: %04X - %s", peer
->gbox
.id
, cli
->reader
->label
); }
2437 cs_log_dump_dbg(D_READER
, outbuf
, hostname_len
+ 0xC, "<- send HERE?, (len=%d):", hostname_len
+ 0xC);
2441 void gbox_send_idle_msg(void)
2445 struct s_client
*cl
;
2446 cs_readlock(__func__
, &clientlist_lock
);
2448 for(cl
= first_client
; cl
; cl
= cl
->next
)
2450 struct gbox_peer
*peer
= cl
->gbox
;
2451 if(cl
->gbox
&& cl
->typ
== 'p' && !peer
->online
&& !check_peer_ignored(cl
->gbox_peer_id
) && cl
->reader
->send_offline_cmd
)
2456 cs_readunlock(__func__
, &clientlist_lock
);
2462 void gbox_send_init_hello(void)
2464 if(local_gbox_initialized
)
2466 struct s_client
*cl
;
2467 gbox_add_local_cards();
2469 cs_readlock(__func__
, &clientlist_lock
);
2471 for(cl
= first_client
; cl
; cl
= cl
->next
)
2473 if(cl
->gbox
&& cl
->typ
== 'p')
2475 gbox_send_hello(cl
, GBOX_STAT_HELLOL
);
2478 cs_readunlock(__func__
, &clientlist_lock
);
2481 { cs_log("local gbox failed init"); }
2484 static void gbox_peer_idle (struct s_client
*cl
)
2486 uint32_t ptime_elapsed
, etime_elapsed
;
2487 struct s_client
*proxy
= get_gbox_proxy(cl
->gbox_peer_id
);
2488 struct gbox_peer
*peer
;
2491 if (proxy
&& proxy
->gbox
)
2493 etime_elapsed
= llabs(cl
->lastecm
- time(NULL
));
2495 if (llabs(proxy
->last
- time(NULL
)) > etime_elapsed
)
2497 ptime_elapsed
= etime_elapsed
;
2501 ptime_elapsed
= llabs(proxy
->last
- time(NULL
));
2504 if (ptime_elapsed
> (cfg
.gbox_reconnect
*2) && cl
->gbox_peer_id
!= NO_GBOX_ID
)
2506 // gbox peer apparently died without saying goodnight
2507 cs_writelock(__func__
, &peer
->lock
);
2512 cs_log("Lost connection to: %s %s - taking peer %04X %s offline",
2513 proxy
->reader
->device
, cs_inet_ntoa(proxy
->ip
), cl
->gbox_peer_id
, username(cl
));
2515 cs_log_dbg(D_READER
, "time since last proxy activity: %d sec > %d => lost connection - taking peer %04X - %s offline",
2516 ptime_elapsed
, cfg
.gbox_reconnect
*2, cl
->gbox_peer_id
, username(cl
));
2518 write_msg_info(proxy
, MSGID_LOSTCONNECT
, 0, 0);
2519 gbox_reinit_proxy(proxy
);
2520 gbox_write_share_cards_info();
2521 gbox_update_my_checkcode();
2523 cs_writeunlock(__func__
, &peer
->lock
);
2526 if (etime_elapsed
> cfg
.gbox_reconnect
&& cl
->gbox_peer_id
!= NO_GBOX_ID
)
2528 cs_writelock(__func__
, &peer
->lock
);
2530 if (!(check_peer_ignored(cl
->gbox_peer_id
)))
2532 if (!peer
->online
&& ptime_elapsed
< cfg
.gbox_reconnect
*3)
2534 cs_log_dbg(D_READER
, "%04X - %s -> offline - time since last ecm / proxy_act: %d sec / %d sec => trigger HELLOL",
2535 cl
->gbox_peer_id
, username(cl
), etime_elapsed
, ptime_elapsed
);
2536 gbox_send_hello(proxy
, GBOX_STAT_HELLOL
);
2541 cs_log_dbg(D_READER
, "%04X - %s -> online - time since last ecm /proxy activity: %d sec / %d sec => trigger keepalive HELLOS",
2542 cl
->gbox_peer_id
, username(cl
), etime_elapsed
, ptime_elapsed
);
2544 gbox_send_hello(proxy
, GBOX_STAT_HELLOS
);
2547 cs_writeunlock(__func__
, &peer
->lock
);
2550 cl
->last
= time((time_t *)0);
2553 static int8_t gbox_send_peer_good_night(struct s_client
*proxy
)
2556 int32_t hostname_len
= 0;
2558 if (cfg
.gbox_hostname
)
2560 hostname_len
= cs_strlen(cfg
.gbox_hostname
);
2563 int32_t len
= hostname_len
+ 22;
2565 if(proxy
->gbox
&& proxy
->typ
== 'p')
2567 struct gbox_peer
*peer
= proxy
->gbox
;
2568 struct s_reader
*rdr
= proxy
->reader
;
2572 gbox_message_header(outbuf
, MSG_HELLO
, peer
->gbox
.password
, local_gbox
.password
);
2575 memset(&outbuf
[12], 0xff, 7);
2576 outbuf
[19] = cfg
.gbox_my_vers
;
2577 outbuf
[20] = gbox_get_my_cpu_api();
2578 memcpy(&outbuf
[21], cfg
.gbox_hostname
, hostname_len
);
2579 outbuf
[21 + hostname_len
] = hostname_len
;
2580 cs_log("<- good night to %s:%d id: %04X", rdr
->device
, rdr
->r_port
, peer
->gbox
.id
);
2581 gbox_compress(outbuf
, len
, &len
);
2582 gbox_send(proxy
, outbuf
, len
);
2583 gbox_reinit_proxy(proxy
);
2589 void gbox_send_good_night(void)
2591 gbox_free_cardlist();
2592 struct s_client
*cli
;
2593 cs_readlock(__func__
, &clientlist_lock
);
2595 for(cli
= first_client
; cli
; cli
= cli
->next
)
2597 if(cli
->gbox
&& cli
->typ
== 'p')
2599 gbox_send_peer_good_night(cli
);
2602 cs_readunlock(__func__
, &clientlist_lock
);
2605 void gbox_send_goodbye(struct s_client
*cli
) // indication that requested ECM failed
2607 if (local_gbox
.minor_version
!= 0x2A)
2610 struct gbox_peer
*peer
= cli
->gbox
;
2611 gbox_message_header(outbuf
, MSG_GOODBYE
, peer
->gbox
.password
, local_gbox
.password
);
2612 cs_log_dbg(D_READER
,"<- goodbye - requested ecm failed. Send info to requesting boxid: %04X", peer
->gbox
.id
);
2613 gbox_send(cli
, outbuf
, 10);
2621 static void delayed_crd_update(void)
2623 struct s_client
*cli
;
2624 cs_readlock(__func__
, &clientlist_lock
);
2626 for (cli
= first_client
; cli
; cli
= cli
->next
)
2628 if(cli
->gbox
&& cli
->typ
== 'p' && !check_peer_ignored(cli
->gbox_peer_id
))
2630 uint32_t timediff
= llabs(cli
->last
- time(NULL
));
2631 struct gbox_peer
*peer
= cli
->gbox
;
2632 if(peer
->online
&& peer
->authstat
== 1 && timediff
> 3)
2635 //cs_log("<- send %d sec delayed HelloS to %04X", timediff, cli->gbox_peer_id);
2636 gbox_send_hello(cli
, GBOX_STAT_HELLOS
);
2640 cs_readunlock(__func__
, &clientlist_lock
);
2644 static pthread_t gbx_tick_thread
;
2645 static int32_t gbx_tick_active
= 0;
2646 static pthread_cond_t gbx_tick_sleep_cond
;
2647 static pthread_mutex_t gbx_tick_sleep_cond_mutex
;
2648 static pthread_mutex_t gbx_tick_mutex
;
2650 static void gbx_tick_mutex_init(void)
2652 static int8_t mutex_init
= 0;
2655 SAFE_MUTEX_INIT(&gbx_tick_mutex
, NULL
);
2656 cs_pthread_cond_init(__func__
, &gbx_tick_sleep_cond_mutex
, &gbx_tick_sleep_cond
);
2661 static void gbx_ticker(void)
2663 char *fext
= FILE_GSMS_TXT
;
2664 char *fname
= get_gbox_tmp_fname(fext
);
2666 while(gbx_tick_active
)
2668 if(file_exists(fname
) && !cfg
.gsms_dis
)
2670 gbox_init_send_gsms();
2675 if(startup
< GBOX_START_TIME
)
2677 delayed_crd_update();
2679 else if(startup
== GBOX_START_TIME
-10)
2681 gbox_add_local_cards();
2683 else if(startup
% STATS_WRITE_TIME
== 0)
2688 gbox_send_idle_msg();
2690 sleepms_on_cond(__func__
, &gbx_tick_sleep_cond_mutex
, &gbx_tick_sleep_cond
, 1000);
2695 void start_gbx_ticker(void)
2699 gbx_tick_mutex_init();
2700 SAFE_MUTEX_LOCK(&gbx_tick_mutex
);
2702 is_active
= gbx_tick_active
;
2703 if(!gbx_tick_active
)
2705 gbx_tick_active
= 1;
2710 SAFE_MUTEX_UNLOCK(&gbx_tick_mutex
);
2714 int32_t ret
= start_thread("gbox ticker", (void *)&gbx_ticker
, NULL
, &gbx_tick_thread
, 0, 1);
2717 gbx_tick_active
= 0;
2720 SAFE_MUTEX_UNLOCK(&gbx_tick_mutex
);
2723 void stop_gbx_ticker(void)
2725 gbx_tick_mutex_init();
2726 SAFE_MUTEX_LOCK(&gbx_tick_mutex
);
2730 gbx_tick_active
= 0;
2731 SAFE_COND_SIGNAL(&gbx_tick_sleep_cond
);
2732 SAFE_THREAD_JOIN(gbx_tick_thread
, NULL
);
2735 SAFE_MUTEX_UNLOCK(&gbx_tick_mutex
);
2738 void module_gbox(struct s_module
*ph
)
2742 for(i
= 0; i
< CS_MAXPORTS
; i
++)
2744 if(!cfg
.gbox_port
[i
])
2750 ph
->ptab
.ports
[i
].s_port
= cfg
.gbox_port
[i
];
2755 ph
->type
= MOD_CONN_UDP
;
2756 ph
->large_ecm_support
= 1;
2757 ph
->listenertype
= LIS_GBOX
;
2758 ph
->s_handler
= gbox_server
;
2759 ph
->s_init
= gbox_server_init
;
2760 ph
->send_dcw
= gbox_send_dcw
;
2761 ph
->recv
= gbox_recv
;
2762 ph
->c_init
= gbox_peer_init
;
2763 ph
->c_send_ecm
= gbox_send_ecm
;
2764 ph
->c_send_emm
= gbox_send_remm_data
;
2765 ph
->s_peer_idle
= gbox_peer_idle
;