fixed CMake warnings on Debian 11
[oscam.git] / module-gbox.c
blob1b0697d00addfde840dcc20118566e84cf75d7b5
1 #define MODULE_LOG_PREFIX "gbox"
3 #include "globals.h"
4 #ifdef MODULE_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;
30 uint32_t startup = 0;
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 = "/";
42 if(!cfg.gbox_tmp_dir)
44 snprintf(gbox_tmpfile_buf, sizeof(gbox_tmpfile_buf), "%s%s%s",get_tmp_dir(), slash, fext);
46 else
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)
56 return local_gbox.id;
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;}
72 char tsbuf[28];
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");
79 if(!fhandle)
81 cs_log("Couldn't open %s: %s", fname, strerror(errno));
82 return;
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);
127 fclose(fhandle);
128 return;
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))
139 char buf[120];
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);
150 else
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);
159 char *cmd = buf;
160 FILE *p;
161 if((p = popen(cmd, "w")) == NULL)
163 cs_log("Error popen: %s",fname);
164 return;
166 if(pclose(p) == -1)
168 cs_log("Error pclose(): %s",fname);
169 return;
172 return;
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);
179 return;
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");
187 if(!fhandle)
189 cs_log("Couldn't open %s: %s", fname, strerror(errno));
190 return;
193 cs_readlock(__func__, &clientlist_lock);
195 struct s_client *cl;
196 for(cl = first_client; cl; cl = cl->next)
198 if(cl->gbox && cl->typ == 'p')
200 struct gbox_peer *peer = cl->gbox;
201 if (peer->online)
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);
214 else
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);
227 fclose(fhandle);
228 return;
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");
236 if(!fhandle)
238 cs_log("Couldn't open %s: %s", get_gbox_tmp_fname(FILE_GBOX_VERSION), strerror(errno));
239 return;
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);
242 fclose(fhandle);
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)
257 if (!er)
259 return -1;
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);
269 ll_li_destroy(li);
270 return 0;
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)
280 ere->gbox_slot = 0;
281 ere->gbox_version = 0;
282 ere->gbox_rev = 0;
283 ere->gbox_type = 0;
286 struct s_client *get_gbox_proxy(uint16_t gbox_id)
288 struct s_client *cl;
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)
296 found = cl;
297 break;
300 cs_readunlock(__func__, &clientlist_lock);
301 return found;
304 void remove_peer_crd_file(struct s_client *proxy)
306 char buff[64];
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();
325 return 0;
328 static int8_t gbox_clear_peer(struct gbox_peer *peer)
330 if (!peer)
332 return -1;
335 peer->ecm_idx = 0;
336 peer->next_hello = 0;
337 peer->authstat = 0;
339 gbox_delete_cards(GBOX_DELETE_FROM_PEER, peer->gbox.id);
340 gbox_peer_online(peer, GBOX_PEER_OFFLINE);
342 return 0;
345 static int8_t gbox_reinit_proxy(struct s_client *proxy)
347 if (!proxy)
349 return -1;
352 struct gbox_peer *peer = proxy->gbox;
353 gbox_clear_peer(peer);
355 if (!proxy->reader)
357 return -1;
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;
365 return 0;
368 //gbox.net doesn't accept slots >18
369 static uint8_t calc_slot(uint8_t slot)
371 int8_t i;
372 uint8_t cslot = slot;
374 for(i=0 ; i < 9 ; i++)
376 if(slot > i*18)
378 cslot = slot - i*18;
381 return cslot;
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) &&
395 #ifdef MODULE_CCCAM
396 (card->dist <= peer->my_user->account->cccmaxhops) &&
397 #endif
398 (!card->origin_peer || (card->origin_peer && card->origin_peer->gbox.id != peer->gbox.id)))
400 if(card->type == GBOX_CARD_TYPE_GBOX)
402 nbcards++;
403 continue;
405 else if(card->type == GBOX_CARD_TYPE_CCCAM) //&& cfg.cc_gbx_reshare_en
407 if(proxy->reader->gbox_cccam_reshare < 0)
408 { continue; }
409 else
411 if(chk_ident_filter(gbox_get_caid(card->caprovid), gbox_get_provid(card->caprovid), &proxy->reader->ccc_gbx_reshare_ident))
413 nbcards++;
414 continue;
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)
422 nbcards++;
423 continue;
425 else
427 continue;
431 if(nbcards == MAX_GBOX_CARDS )
433 break;
436 } // while cards exist
437 gbox_cards_iter_destroy(gci);
439 return nbcards;
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);
461 int32_t len;
463 gbox_message_header(outbuf, MSG_HELLO, peer->gbox.password, local_gbox.password);
465 if(hello_stat > GBOX_STAT_HELLOS) // hello_stat == HelloR
467 outbuf[10] = 1;
469 else
471 outbuf[10] = 0;
473 outbuf[11] = packet;
475 if((packet & 0x0F) == 0) // first packet
477 memcpy(++ptr, gbox_get_my_checkcode(), 7);
479 ptr += 7;
480 *ptr = local_gbox.minor_version;
481 *(++ptr) = local_gbox.cpu_api;
482 memcpy(++ptr, cfg.gbox_hostname, hostname_len);
483 ptr += hostname_len;
484 *ptr = hostname_len;
486 len = ptr - outbuf + 1;
488 switch(hello_stat)
490 case GBOX_STAT_HELLOL:
491 if(cfg.log_hello)
492 { cs_log("<- HelloL to %s", cli->reader->label); }
493 else
494 { cs_log_dbg(D_READER,"<- HelloL to %s", cli->reader->label); }
495 break;
497 case GBOX_STAT_HELLOS:
498 if(cfg.log_hello)
499 { cs_log("<- HelloS #%d total cards %d to %s", (packet & 0xf) +1, nbcards, cli->reader->label); }
500 else
501 { cs_log_dbg(D_READER,"<- HelloS #%d total cards %d to %s", (packet & 0xf) +1, nbcards, cli->reader->label); }
502 break;
504 case GBOX_STAT_HELLOR:
505 if(cfg.log_hello)
506 { cs_log("<- HelloR #%d total cards %d to %s", (packet & 0xf) +1, nbcards, cli->reader->label); }
507 else
508 { cs_log_dbg(D_READER,"<- HelloR #%d total cards %d to %s", (packet & 0xf) +1, nbcards, cli->reader->label); }
509 break;
511 default:
512 if(cfg.log_hello)
513 { cs_log("<- hello #%d total cards %d to %s", (packet & 0xf) +1, nbcards, cli->reader->label); }
514 else
515 { cs_log_dbg(D_READER,"<- hello #%d total cards %d to %s", (packet & 0xf) +1, nbcards, cli->reader->label); }
516 break;
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)
526 if(!proxy)
528 cs_log("ERROR: Invalid proxy try to call 'gbox_send_hello'");
529 return;
532 struct gbox_peer *peer = proxy->gbox;
534 if(!peer)
536 cs_log("ERROR: Invalid peer try to call 'gbox_send_hello'");
537 return;
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'");
543 return;
546 uint16_t sendcrds = 0;
547 uint16_t nbcards = 0;
548 uint16_t nbcards_cnt = 0;
549 uint8_t packet = 0;
550 uint8_t buf[1024];
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);
561 char buff[64];
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");
566 if(!fhandle)
568 cs_log("Couldn't open %s: %s", fname, strerror(errno));
569 return;
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) &&
581 #ifdef MODULE_CCCAM
582 (card->dist <= peer->my_user->account->cccmaxhops) &&
583 #endif
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)
602 { continue; }
603 else
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;
616 *(++ptr) = 1;
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);
622 else
623 { continue; }
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;
635 *(++ptr) = 1;
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);
641 else
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);
644 continue;
648 *(++ptr) = card->id.peer >> 8;
649 *(++ptr) = card->id.peer & 0xff;
650 nbcards++;
651 nbcards_cnt++;
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);
656 break;
659 if(nbcards_cnt == nb_send_cards)
661 break;
664 if(nbcards == 74)
666 gbox_send_hello_packet(proxy, packet, buf, ptr, nbcards, hello_stat);
667 packet++;
668 nbcards = 0;
669 ptr = buf + 11;
670 memset(buf, 0, sizeof(buf));
673 } // while cards exist
675 gbox_cards_iter_destroy(gci);
676 fclose(fhandle);
677 } // end if > HelloL
678 else
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;
691 *(++ptr) = 1;
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;
697 nbcards++;
698 if(nbcards >= GBOX_MAX_LOCAL_CARDS )
700 cs_log("gbox_send_HelloL - local crds = %d - max allowed = %d ", nbcards, GBOX_MAX_LOCAL_CARDS);
701 break;
704 } // end while local cards exist
705 gbox_cards_iter_destroy(gci);
706 } // end if HelloL
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);
722 return;
725 void restart_gbox_peer(char *rdrlabel, uint8_t allrdr, uint16_t gbox_id)
727 struct s_client *cl;
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)
742 if(l > 0)
744 cs_log("gbox_server %s/%d", cli->reader->label, cli->port);
745 //gbox_check_header_recvd(cli, NULL, b, l);
747 return NULL;
750 char *gbox_username(struct s_client *client)
752 if(!client)
754 return "anonymous";
757 if(client->reader)
759 if(client->reader->r_usr[0])
761 return client->reader->r_usr;
764 return "anonymous";
767 static int8_t gbox_disconnect_double_peers(struct s_client *cli)
769 struct s_client *cl;
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)
776 cl->reader = NULL;
777 cl->gbox = NULL;
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);
784 return 0;
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);
810 peer->my_user = cli;
811 return 0;
814 return -1;
817 static void gbox_server_init(struct s_client *cl)
819 cs_writelock(__func__, &clientlist_lock);
820 if(!cl->init_done)
822 if(IP_ISSET(cl->ip))
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;
828 cl->init_done = 1;
829 cl->last = time((time_t *)0);
830 start_gbx_ticker();
832 cs_writeunlock(__func__, &clientlist_lock);
833 return;
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);
848 return 0;
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;
855 uint32_t caprovid;
856 int16_t ncards_in_msg = 0;
858 while(ptr < len)
860 caprovid = ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
862 ncards_in_msg += ptr[4];
863 //caid check
864 if(chk_ctab(gbox_get_caid(caprovid), ctab))
866 current_ptr = ptr;
867 ptr += 5;
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
879 else
881 ptr += 5 + ptr[4] * 4; // skip cards because caid
883 } // end while < len
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))
893 if (updcrc)
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);
899 return 1;
901 return 0;
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);
914 return;
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);
920 disable_remm(cli);
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);
927 return;
930 static void gbox_send_my_checkcode(struct s_client *cli)
932 struct gbox_peer *peer = cli->gbox;
933 uint8_t outbuf[20];
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);
938 if (cfg.log_hello)
939 { cs_log("<- HelloC my checkcode to %s (%s:%d)", cli->reader->label, cs_inet_ntoa(cli->ip), cli->reader->r_port);}
940 else
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);}
942 return;
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;
954 uint8_t *ptr = 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);
962 ptr = data + 12;
964 else
966 ptr = data + 11;
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);
977 return 0;
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))
996 return -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);
1003 if(diffcheck)
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)
1017 { return -1; }
1018 else
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
1029 uint8_t tmpbuf[8];
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);
1040 if(!data[10])
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);
1046 if(cfg.log_hello)
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);}
1048 else
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);}
1051 else
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();
1061 if(!peer->online)
1063 is_helloL = 1;
1064 gbox_peer_online(peer, GBOX_PEER_ONLINE);
1065 if(cfg.log_hello)
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); }
1067 else
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); }
1071 if(!is_helloL)
1073 if(cfg.log_hello)
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); }
1075 else
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);
1082 else
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();
1092 if(!peer->online)
1094 gbox_peer_online(peer, GBOX_PEER_ONLINE);
1097 cli->last = time((time_t *)0);
1099 if (cfg.log_hello)
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); }
1101 else
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);
1107 if(!peer->online)
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;
1119 else
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);
1128 else
1130 peer->next_hello++;
1133 return 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);
1148 return 1;
1152 cs_readunlock(__func__, &clientlist_lock);
1153 return 0;
1156 static int8_t is_blocked_peer(uint16_t peer_id)
1158 int i;
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)
1165 return 1;
1169 return 0;
1172 int8_t check_peer_ignored(uint16_t peer_id)
1174 int i;
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)
1181 return 1;
1185 return 0;
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);
1202 return 1;
1203 } // valid peerpass
1206 cs_readunlock(__func__, &clientlist_lock);
1207 return 0;
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;
1218 peer = cli->gbox;
1219 if (!peer || !peer->my_user)
1221 return -1;
1223 cl = peer->my_user;
1225 if(n < 21)
1227 return -1;
1230 // No ECMs with length < MIN_LENGTH expected
1231 if ((((data[19] & 0x0f) << 8) | data[20]) < MIN_ECM_LENGTH)
1233 return -1;
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);
1240 return -1;
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);
1247 return -1;
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);
1258 return -1;
1261 ECM_REQUEST *er;
1262 if(!(er = get_ecmtask()))
1264 return -1;
1267 struct gbox_ecm_request_ext *ere;
1268 if(!cs_malloc(&ere, sizeof(struct gbox_ecm_request_ext)))
1270 NULLFREE(er);
1271 return -1;
1274 uint8_t *ecm = data + 18; // offset of ECM in gbx message
1276 er->src_data = ere;
1277 gbox_init_ecm_request_ext(ere);
1279 if(peer->ecm_idx == 100)
1281 peer->ecm_idx = 0;
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)
1289 NULLFREE(ere);
1290 NULLFREE(er);
1291 return -1;
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);
1301 else
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);
1330 get_cw(cl, er);
1332 // checkcode did not match gbox->peer checkcode
1333 if(diffcheck)
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
1338 return 0;
1341 static uint32_t gbox_get_pending_time(ECM_REQUEST *er, uint16_t peer_id, uint8_t slot)
1343 if(!er)
1345 return 0;
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;
1358 break;
1361 ll_li_destroy(li);
1362 return ret_time;
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)
1369 return -1;
1372 int i;
1373 uint16_t id_card = 0;
1374 struct s_client *proxy;
1376 if(cli->typ != 'p')
1378 proxy = get_gbox_proxy(cli->gbox_peer_id);
1380 else
1382 proxy = cli;
1385 if (!proxy || !proxy->reader)
1387 cs_log("error, gbox_chk_recvd_dcw, proxy not found");
1388 gbox_send_goodbye(cli);
1389 return -1;
1392 proxy->last = time((time_t *)0);
1393 *rc = 1;
1394 memcpy(dcw, data + 14, 16);
1395 uint32_t crc = b2i(4, data + 30);
1396 char tmp[33];
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]);
1402 struct timeb t_now;
1403 cs_ftime(&t_now);
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)
1417 return -1;
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);
1425 *rc = 1;
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);
1434 return -1;
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;
1440 uint8_t dcw[16];
1442 idx = gbox_chk_recvd_dcw(cli, dcw, &rc, data, n);
1444 if(idx < 0) // no dcw received
1446 return -1;
1449 if(!idx)
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)
1460 cli->pending--;
1461 casc_check_dcw(cli->reader, i, rc, dcw);
1462 return 0;
1465 return -1;
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;
1478 if(peer->online)
1480 gbox_send_hello(cl, GBOX_STAT_HELLOS);
1481 cl->last = time((time_t *)0);
1485 cs_readunlock(__func__, &clientlist_lock);
1486 return;
1489 int32_t gbox_recv_cmd_switch(struct s_client *proxy, uint8_t *data, int32_t n)
1491 if (!data || !proxy)
1493 return -1;
1496 uint16_t cmd = gbox_decode_cmd(data);
1497 uint8_t diffcheck = 0;
1498 //struct gbox_peer *peer = proxy->gbox;
1500 switch(cmd)
1502 case MSG_HERE:
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??
1505 break;
1507 case MSG_GOODBYE:
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);
1512 break;
1514 case MSG_GSMS:
1515 if(!cfg.gsms_dis)
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]);
1522 else
1524 gsms_unavail();
1526 break;
1528 case MSG_GSMS_ACK:
1529 if(!cfg.gsms_dis)
1531 cs_log("-> MSG_GSMS_ACK from %s %s", username(proxy), proxy->reader->device);
1532 write_gsms_ack(proxy);
1534 else
1536 gsms_unavail();
1538 break;
1540 case MSG_HELLO1:
1541 case MSG_HELLO:
1542 if(gbox_cmd_hello_rcvd(proxy, data, n) < 0)
1544 return -1;
1546 break;
1548 case MSG_CW:
1549 gbox_received_dcw(proxy, data, n);
1550 break;
1552 case MSG_CHECKCODE:
1553 diffcheck = gbox_checkcode_recvd(proxy, data + 10, 0);
1555 if (cfg.log_hello)
1557 cs_log("-> HelloC checkcode from %s - %s %s", username(proxy), proxy->reader->device, diffcheck ? "- crc diff":"");
1559 else
1561 cs_log_dbg(D_READER,"-> HelloC checkcode from %s - %s %s", username(proxy), proxy->reader->device, diffcheck ? "- crc diff":"");
1564 if(diffcheck)
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);
1569 break;
1571 case MSG_ECM:
1572 gbox_incoming_ecm(proxy, data, n);
1573 break;
1575 case MSG_REM_EMM:
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);
1579 break;
1581 default:
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);
1589 } // end switch
1590 return 0;
1593 uint8_t add_betatunnel_card(uint16_t caid, uint8_t slot)
1595 int32_t i;
1596 struct s_client *cli;
1597 cs_readlock(__func__, &clientlist_lock);
1599 for(cli = first_client; cli; cli = cli->next)
1601 TUNTAB *ttab;
1602 ttab = &cli->ttab;
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);
1612 return 1;
1616 cs_readunlock(__func__, &clientlist_lock);
1617 return 0;
1620 static uint32_t gbox_add_local_cards(void)
1622 int32_t i;
1623 uint32_t prid = 0;
1624 uint8_t slot = 0;
1625 uint16_t crdnb = 0;
1626 uint16_t cccrdnb = 0;
1627 #ifdef MODULE_CCCAM
1628 LL_ITER it, it2;
1629 struct cc_card *card = NULL;
1630 struct cc_data *cc;
1631 uint32_t checksum = 0;
1632 uint16_t cc_peer_id = 0;
1633 struct cc_provider *provider;
1634 uint8_t *node1 = NULL;
1635 uint8_t offset = 0;
1637 gbox_delete_cards(GBOX_DELETE_WITH_TYPE, GBOX_CARD_TYPE_CCCAM);
1638 #endif
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);
1666 else
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)))
1672 { crdnb++; }
1675 crdnb++;
1676 } // end local readers
1677 #ifdef MODULE_CCCAM
1678 if(cfg.cc_gbx_reshare_en && cfg.cc_reshare > -1 && cl->typ == 'p' && cl->reader && cl->reader->typ == R_CCCAM && cl->cc)
1680 cc = 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);
1700 else
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);
1704 cccrdnb++;
1705 crdnb++;
1707 if(slot % 18 == 0)
1709 //offset++;
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);
1714 } // end cccam
1715 #endif
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]));
1727 crdnb++;
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); }
1738 else
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)
1750 cs_sleepms(100);
1752 else if(crdstat == LOCALCARDUP)
1754 cs_sleepms(2000);
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");
1761 else
1763 return;
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();
1770 return;
1773 uint8_t chk_gbx_hdr_rcvd(uint16_t rcvd_header_cmd)
1775 switch(rcvd_header_cmd)
1777 case MSG_HERE:
1778 case MSG_HELLO1:
1779 case MSG_HELLO:
1780 case MSG_GOODBYE:
1781 case MSG_GSMS:
1782 case MSG_GSMS_ACK:
1783 case MSG_CW:
1784 case MSG_CHECKCODE:
1785 case MSG_ECM:
1786 case MSG_REM_EMM:
1787 return 1;
1789 default:
1790 return 0;
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; }
1800 char tmp[128];
1801 int32_t n = l;
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);
1822 return -1;
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);
1840 return -1;
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);
1849 return -1;
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));
1859 return -1;
1862 authentication_done = 1;
1863 proxy = get_gbox_proxy(cli->gbox_peer_id);
1864 peer = proxy->gbox;
1867 if (!peer)
1869 return -1;
1872 if (peer_received_pw != peer->gbox.password)
1874 cs_log("gbox peer: %04X sends wrong own password", peer->gbox.id);
1875 return -1;
1878 else // is MSG_CW
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);
1895 return -1;
1898 if(!proxy)
1900 return -1;
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);
1909 return -1;
1912 if(!peer)
1914 return -1;
1917 if(!peer->authstat)
1919 peer->authstat = 1;
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;
1930 int8_t ret = 0;
1932 if(!cli->udp_fd || !cli->is_udp || cli->typ != 'c')
1934 return -1;
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
1940 return -1;
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);
1948 if (ret < 0)
1950 return -1;
1953 // in case of new authentication the proxy gbox can now be found
1954 if (ret)
1956 proxy = get_gbox_proxy(cli->gbox_peer_id);
1959 if (!proxy)
1961 return -1;
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);
1972 if(chkcmd < 0)
1974 return -1;
1977 return 0;
1980 static uint8_t check_setup( void)
1982 #ifdef HAVE_DVBAPI
1983 if (module_dvbapi_enabled())
1984 { return 0x30; } //stb
1985 else
1986 { return 0x50; }
1987 #else
1988 return 0x50; //server
1989 #endif
1992 static void gbox_send_dcw(struct s_client *cl, ECM_REQUEST *er)
1994 if (!cl || !er)
1996 return;
1999 struct s_client *cli = get_gbox_proxy(cl->gbox_peer_id);
2000 if (!cli || !cli->gbox)
2002 return;
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);
2011 return;
2014 if(er->rc >= E_NOTFOUND)
2016 cs_log_dbg(D_READER, "unable to decode!");
2017 gbox_send_goodbye(cli);
2018 return;
2021 uint8_t buf[60];
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
2039 else
2041 if (local_gbox.minor_version == 0x2A)
2043 buf[37] = 0xff; // gbox.net sends 0xff
2044 buf[38] = 0xff; // gbox.net sends 0xff
2046 else
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
2057 else
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
2069 uint8_t i;
2070 for(i = 0; i < er->gbox_ecm_dist; i++)
2072 buf[44 +i] = i;
2075 gbox_send(cli, buf, 44 + er->gbox_ecm_dist);
2078 char tmp[0x50];
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)
2094 return -1;
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);
2101 return -1;
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);
2110 return -1;
2113 if(!peer->online)
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);
2117 return -1;
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;
2156 else
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;
2175 buflen = len1 + 10;
2177 nb_matching_crds = gbox_get_cards_for_ecm(&send_buf[0], len1 + 10, cli->reader->gbox_maxecmsend, er, &current_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);
2185 return -1;
2188 if(nb_matching_crds)
2190 send_buf[16] = nb_matching_crds; // Number of cards the ECM should be forwarded to
2192 // distance ECM
2193 uint8_t i;
2194 for(i = 0; i < er->gbox_ecm_dist + 1; i++)
2196 send_buf[buflen] = i;
2197 buflen++;
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;
2206 struct timeb t_now;
2207 cs_ftime(&t_now);
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");
2214 return -1;
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);
2233 ll_li_destroy(li);
2235 if(er->gbox_ecm_status == GBOX_ECM_NEW_REQ)
2237 er->gbox_ecm_status++;
2238 cli->pending++;
2241 gbox_send(cli, send_buf, buflen);
2242 cli->reader->last_s = time((time_t *) 0);
2244 return 0;
2247 // init my gbox with id, password etc
2248 static int8_t init_local_gbox(void)
2250 int32_t i;
2251 local_gbox.id = 0;
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);
2260 return -1;
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 : "");
2267 return -1;
2270 if(!cfg.gbox_password)
2272 cs_log("error, 'my_password' not configured in oscam.conf!");
2273 return -1;
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);
2285 if(!local_gbox.id)
2287 cs_log("invalid 'my_password' %08X -> local gbox id: %04X, choose another 'my_password'",
2288 cfg.gbox_password, local_gbox.id);
2289 return -1;
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);
2299 break;
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!");
2313 return -1;
2316 if (local_gbox_initialized < 0)
2318 return -1;
2321 int8_t ret;
2322 if(!local_gbox_initialized)
2324 local_gbox_initialized = 1;
2325 ret = init_local_gbox();
2326 if (ret < 0)
2328 local_gbox_initialized = -1;
2329 cs_log("local gbox initialization failed");
2330 write_msg_info(cli, MSGID_GBOXONL, 0, 0);
2331 return -1;
2333 write_msg_info(cli, MSGID_GBOXONL, 0, 1);
2336 if(!cs_malloc(&cli->gbox, sizeof(struct gbox_peer)))
2338 return -1;
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);
2353 return -1;
2355 cs_lock_create(__func__, &peer->lock, "gbox_lock", 5000);
2357 gbox_clear_peer(peer);
2359 cli->gbox_peer_id = peer->gbox.id;
2361 cli->pfd = 0;
2362 cli->crypted = 1;
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);
2375 int32_t opt = 1;
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))
2386 return 0;
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;
2420 return 0;
2423 static void gbox_send_HERE(struct s_client *cli)
2425 struct gbox_peer *peer = cli->gbox;
2426 uint8_t outbuf[64];
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);
2433 if(cfg.log_hello)
2434 { cs_log("<- send Keep Alive MSG HERE to boxid: %04X - %s", peer->gbox.id, cli->reader->label); }
2435 else
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);
2440 uint8_t k = 0;
2441 void gbox_send_idle_msg(void)
2443 if(k > 8) //10s
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)
2453 gbox_send_HERE(cl);
2456 cs_readunlock(__func__, &clientlist_lock);
2457 k = 0;
2459 else { k++; }
2462 void gbox_send_init_hello(void)
2464 if(local_gbox_initialized)
2466 struct s_client *cl;
2467 gbox_add_local_cards();
2468 cs_sleepms(1000);
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);
2480 else
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;
2489 peer = proxy->gbox;
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;
2499 else
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);
2509 if (peer->online)
2511 disable_remm(cl);
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);
2539 if (peer->online)
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)
2555 uint8_t outbuf[64];
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;
2570 if (peer->online)
2572 gbox_message_header(outbuf, MSG_HELLO, peer->gbox.password, local_gbox.password);
2573 outbuf[10] = 0x01;
2574 outbuf[11] = 0x80;
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);
2586 return 0;
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)
2609 uint8_t outbuf[15];
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);
2615 else
2617 return;
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)
2634 peer->authstat = 2;
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);
2641 return;
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;
2653 if(!mutex_init)
2655 SAFE_MUTEX_INIT(&gbx_tick_mutex, NULL);
2656 cs_pthread_cond_init(__func__, &gbx_tick_sleep_cond_mutex, &gbx_tick_sleep_cond);
2657 mutex_init = 1;
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();
2673 startup++;
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)
2685 gbox_write_stats();
2688 gbox_send_idle_msg();
2690 sleepms_on_cond(__func__, &gbx_tick_sleep_cond_mutex, &gbx_tick_sleep_cond, 1000);
2692 pthread_exit(NULL);
2695 void start_gbx_ticker(void)
2697 int32_t is_active;
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;
2708 if(is_active)
2710 SAFE_MUTEX_UNLOCK(&gbx_tick_mutex);
2711 return;
2714 int32_t ret = start_thread("gbox ticker", (void *)&gbx_ticker, NULL, &gbx_tick_thread, 0, 1);
2715 if(ret)
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);
2728 if(gbx_tick_active)
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)
2740 int32_t i;
2742 for(i = 0; i < CS_MAXPORTS; i++)
2744 if(!cfg.gbox_port[i])
2746 break;
2749 ph->ptab.nports++;
2750 ph->ptab.ports[i].s_port = cfg.gbox_port[i];
2753 ph->desc = "gbox";
2754 ph->num = R_GBOX;
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;
2767 #endif