Attempt to count descramblers used properly
[oscam.git] / oscam-work.c
blob4cda9ac5817babc1c15ce038546d854bd1d48f7b
1 #define MODULE_LOG_PREFIX "work"
3 #include "globals.h"
4 #include "module-cacheex.h"
5 #include "oscam-client.h"
6 #include "oscam-ecm.h"
7 #include "oscam-emm.h"
8 #include "oscam-lock.h"
9 #include "oscam-net.h"
10 #include "oscam-reader.h"
11 #include "oscam-string.h"
12 #include "oscam-work.h"
13 #include "reader-common.h"
14 #include "module-cccam.h"
15 #include "module-cccam-data.h"
16 #include "module-cccshare.h"
17 #include "oscam-time.h"
19 extern CS_MUTEX_LOCK system_lock;
20 extern int32_t thread_pipe[2];
22 struct job_data
24 enum actions action;
25 struct s_reader *rdr;
26 struct s_client *cl;
27 void *ptr;
28 struct timeb time;
29 uint16_t len;
32 static void free_job_data(struct job_data *data)
34 if(!data)
35 { return; }
36 if(data->len && data->ptr)
38 // special free checks
39 if(data->action==ACTION_ECM_ANSWER_CACHE)
41 NULLFREE(((struct s_write_from_cache *)data->ptr)->er_cache);
44 NULLFREE(data->ptr);
46 NULLFREE(data);
49 void free_joblist(struct s_client *cl)
51 int32_t lock_status = pthread_mutex_trylock(&cl->thread_lock);
52 LL_ITER it = ll_iter_create(cl->joblist);
54 struct job_data *data;
55 while((data = ll_iter_next(&it)))
57 free_job_data(data);
60 ll_destroy(&cl->joblist);
61 cl->account = NULL;
63 if(cl->work_job_data) // Free job_data that was not freed by work_thread
64 { free_job_data(cl->work_job_data); }
66 cl->work_job_data = NULL;
68 if(lock_status == 0)
69 { SAFE_MUTEX_UNLOCK(&cl->thread_lock); }
71 pthread_mutex_destroy(&cl->thread_lock);
75 Work threads are named like this:
76 w[r|c]XX-[rdr->label|client->username]
78 w - work thread prefix
79 [r|c] - depending whether the the action is related to reader or client
80 XX - two digit action code from enum actions
81 label - reader label or client username (see username() function)
83 static void set_work_thread_name(struct job_data *data)
85 char thread_name[16 + 1];
86 snprintf(thread_name, sizeof(thread_name), "w%c%02d-%s",
87 data->action < ACTION_CLIENT_FIRST ? 'r' : 'c',
88 data->action,
89 username(data->cl)
91 set_thread_name(thread_name);
94 #define __free_job_data(client, job_data) \
95 do { \
96 client->work_job_data = NULL; \
97 if(job_data && job_data != &tmp_data) { \
98 free_job_data(job_data); \
99 } \
100 job_data = NULL; \
101 } while(0)
103 void *work_thread(void *ptr)
105 struct job_data *data = (struct job_data *)ptr;
106 struct s_client *cl = data->cl;
107 struct s_reader *reader = cl->reader;
108 struct timeb start, end; // start time poll, end time poll
110 struct job_data tmp_data;
111 struct pollfd pfd[1];
113 SAFE_SETSPECIFIC(getclient, cl);
114 cl->thread = pthread_self();
115 cl->thread_active = 1;
117 set_work_thread_name(data);
119 struct s_module *module = get_module(cl);
120 uint16_t bufsize = module->bufsize; // CCCam needs more than 1024bytes!
121 if(!bufsize)
122 { bufsize = DEFAULT_MODULE_BUFSIZE; }
124 uint8_t *mbuf;
125 if(!cs_malloc(&mbuf, bufsize))
126 { return NULL; }
128 cl->work_mbuf = mbuf; // Track locally allocated data, because some callback may call cs_exit/cs_disconect_client/pthread_exit and then mbuf would be leaked
129 int32_t n = 0, rc = 0, i, idx, s;
130 uint8_t dcw[16];
131 int8_t restart_reader = 0;
133 while(cl->thread_active)
135 cs_ftime(&start); // register start time
137 while(cl->thread_active)
139 if(!cl || cl->kill || !is_valid_client(cl))
141 SAFE_MUTEX_LOCK(&cl->thread_lock);
142 cl->thread_active = 0;
143 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
144 cs_log_dbg(D_TRACE, "ending thread (kill)");
145 __free_job_data(cl, data);
146 cl->work_mbuf = NULL; // Prevent free_client from freeing mbuf (->work_mbuf)
147 free_client(cl);
148 if(restart_reader)
149 { restart_cardreader(reader, 0); }
150 NULLFREE(mbuf);
151 pthread_exit(NULL);
152 return NULL;
155 if(data && data->action != ACTION_READER_CHECK_HEALTH)
156 { cs_log_dbg(D_TRACE, "data from add_job action=%d client %c %s", data->action, cl->typ, username(cl)); }
158 if(!data)
160 if(!cl->kill && cl->typ != 'r')
161 { client_check_status(cl); } // do not call for physical readers as this might cause an endless job loop
163 SAFE_MUTEX_LOCK(&cl->thread_lock);
164 if(cl->joblist && ll_count(cl->joblist) > 0)
166 LL_ITER itr = ll_iter_create(cl->joblist);
167 data = ll_iter_next_remove(&itr);
168 if(data)
169 { set_work_thread_name(data); }
170 //cs_log_dbg(D_TRACE, "start next job from list action=%d", data->action);
172 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
175 if(!data)
177 /* for serial client cl->pfd is file descriptor for serial port not socket
178 for example: pfd=open("/dev/ttyUSB0"); */
179 if(!cl->pfd || module->listenertype == LIS_SERIAL)
180 { break; }
182 pfd[0].fd = cl->pfd;
183 pfd[0].events = POLLIN | POLLPRI;
185 SAFE_MUTEX_LOCK(&cl->thread_lock);
186 cl->thread_active = 2;
187 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
189 rc = poll(pfd, 1, 3000);
191 SAFE_MUTEX_LOCK(&cl->thread_lock);
192 cl->thread_active = 1;
193 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
195 if(rc > 0)
197 cs_ftime(&end); // register end time
198 cs_log_dbg(D_TRACE, "[OSCAM-WORK] new event %d occurred on fd %d after %"PRId64" ms inactivity", pfd[0].revents,
199 pfd[0].fd, comp_timeb(&end, &start));
200 data = &tmp_data;
201 data->ptr = NULL;
202 cs_ftime(&start); // register start time for new poll next run
204 if(reader)
205 { data->action = ACTION_READER_REMOTE; }
206 else
208 if(cl->is_udp)
210 data->action = ACTION_CLIENT_UDP;
211 data->ptr = mbuf;
212 data->len = bufsize;
214 else
215 { data->action = ACTION_CLIENT_TCP; }
217 if(pfd[0].revents & (POLLHUP | POLLNVAL | POLLERR))
218 { cl->kill = 1; }
223 if(!data)
224 { continue; }
226 if(!reader && data->action < ACTION_CLIENT_FIRST)
228 __free_job_data(cl, data);
229 break;
232 if(!data->action)
233 { break; }
235 struct timeb actualtime;
236 cs_ftime(&actualtime);
237 int64_t gone = comp_timeb(&actualtime, &data->time);
238 if(data != &tmp_data && gone > (int) cfg.ctimeout+1000)
240 cs_log_dbg(D_TRACE, "dropping client data for %s time %"PRId64" ms", username(cl), gone);
241 __free_job_data(cl, data);
242 continue;
245 if(data != &tmp_data)
246 { cl->work_job_data = data; } // Track the current job_data
248 switch(data->action)
250 case ACTION_READER_IDLE:
251 reader_do_idle(reader);
252 break;
254 case ACTION_READER_REMOTE:
255 s = check_fd_for_data(cl->pfd);
256 if(s == 0) // no data, another thread already read from fd?
257 { break; }
258 if(s < 0)
260 if(reader->ph.type == MOD_CONN_TCP)
261 { network_tcp_connection_close(reader, "disconnect"); }
262 break;
264 rc = reader->ph.recv(cl, mbuf, bufsize);
265 if(rc < 0)
267 if(reader->ph.type == MOD_CONN_TCP)
268 { network_tcp_connection_close(reader, "disconnect on receive"); }
269 break;
271 cl->last = time(NULL); // *********************************** TO BE REPLACE BY CS_FTIME() LATER ****************
272 idx = reader->ph.c_recv_chk(cl, dcw, &rc, mbuf, rc);
273 if(idx < 0) { break; } // no dcw received
274 if(!idx) { idx = cl->last_idx; }
275 reader->last_g = time(NULL); // *********************************** TO BE REPLACE BY CS_FTIME() LATER **************** // for reconnect timeout
276 for(i = 0, n = 0; i < cfg.max_pending && n == 0; i++)
278 if(cl->ecmtask[i].idx == idx)
280 cl->pending--;
281 casc_check_dcw(reader, i, rc, dcw);
282 n++;
285 break;
287 case ACTION_READER_RESET:
288 cardreader_do_reset(reader);
289 break;
291 case ACTION_READER_ECM_REQUEST:
292 reader_get_ecm(reader, data->ptr);
293 break;
295 case ACTION_READER_EMM:
296 reader_do_emm(reader, data->ptr);
297 break;
299 case ACTION_READER_CARDINFO:
300 reader_do_card_info(reader);
301 break;
303 case ACTION_READER_POLL_STATUS:
304 cardreader_poll_status(reader);
305 break;
307 case ACTION_READER_INIT:
308 if(!cl->init_done)
309 { reader_init(reader); }
310 break;
312 case ACTION_READER_RESTART:
313 cl->kill = 1;
314 restart_reader = 1;
315 break;
317 case ACTION_READER_RESET_FAST:
318 reader->card_status = CARD_NEED_INIT;
319 cardreader_do_reset(reader);
320 break;
322 case ACTION_READER_CHECK_HEALTH:
323 cardreader_do_checkhealth(reader);
324 break;
326 case ACTION_READER_CAPMT_NOTIFY:
327 if(reader->ph.c_capmt) { reader->ph.c_capmt(cl, data->ptr); }
328 break;
330 case ACTION_CLIENT_UDP:
331 n = module->recv(cl, data->ptr, data->len);
332 if(n < 0) { break; }
333 module->s_handler(cl, data->ptr, n);
334 break;
336 case ACTION_CLIENT_TCP:
337 s = check_fd_for_data(cl->pfd);
338 if(s == 0) // no data, another thread already read from fd?
339 { break; }
340 if(s < 0) // system error or fd wants to be closed
342 cl->kill = 1; // kill client on next run
343 continue;
345 n = module->recv(cl, mbuf, bufsize);
346 if(n < 0)
348 cl->kill = 1; // kill client on next run
349 continue;
351 module->s_handler(cl, mbuf, n);
352 break;
354 case ACTION_CACHEEX1_DELAY:
355 cacheex_mode1_delay(data->ptr);
356 break;
358 case ACTION_CACHEEX_TIMEOUT:
359 cacheex_timeout(data->ptr);
360 break;
362 case ACTION_FALLBACK_TIMEOUT:
363 fallback_timeout(data->ptr);
364 break;
366 case ACTION_CLIENT_TIMEOUT:
367 ecm_timeout(data->ptr);
368 break;
370 case ACTION_ECM_ANSWER_READER:
371 chk_dcw(data->ptr);
372 break;
374 case ACTION_ECM_ANSWER_CACHE:
375 write_ecm_answer_fromcache(data->ptr);
376 break;
378 case ACTION_CLIENT_INIT:
379 if(module->s_init)
380 { module->s_init(cl); }
381 cl->is_udp = module->type == MOD_CONN_UDP;
382 cl->init_done = 1;
383 break;
385 case ACTION_CLIENT_IDLE:
386 if(module->s_idle)
387 { module->s_idle(cl); }
388 else
390 cs_log("user %s reached %d sec idle limit.", username(cl), cfg.cmaxidle);
391 cl->kill = 1;
393 break;
395 case ACTION_CACHE_PUSH_OUT:
396 cacheex_push_out(cl, data->ptr);
397 break;
399 case ACTION_CLIENT_KILL:
400 cl->kill = 1;
401 break;
403 case ACTION_CLIENT_SEND_MSG:
405 if (config_enabled(MODULE_CCCAM))
407 struct s_clientmsg *clientmsg = (struct s_clientmsg *)data->ptr;
408 cc_cmd_send(cl, clientmsg->msg, clientmsg->len, clientmsg->cmd);
410 break;
413 case ACTION_PEER_IDLE:
414 if(module->s_peer_idle)
415 { module->s_peer_idle(cl); }
416 break;
417 case ACTION_CLIENT_HIDECARDS:
419 #ifdef CS_ANTICASC
420 if(config_enabled(MODULE_CCCSHARE))
422 int32_t hidetime = (cl->account->acosc_penalty_duration == -1 ? cfg.acosc_penalty_duration : cl->account->acosc_penalty_duration);
423 if(hidetime)
425 int32_t hide_count;
426 int32_t cardsize;
427 int32_t ii, uu=0;
428 LLIST **sharelist = get_and_lock_sharelist();
429 LLIST *sharelist2 = ll_create("hidecards-sharelist");
431 for(ii = 0; ii < CAID_KEY; ii++)
433 if(sharelist[ii])
435 ll_putall(sharelist2, sharelist[ii]);
439 unlock_sharelist();
441 struct cc_card **cardarray = get_sorted_card_copy(sharelist2, 0, &cardsize);
442 ll_destroy(&sharelist2);
444 for(ii = 0; ii < cardsize; ii++)
446 if(hidecards_card_valid_for_client(cl, cardarray[ii]))
448 if (cardarray[ii]->id)
450 hide_count = hide_card_to_client(cardarray[ii], cl);
451 if(hide_count)
453 cs_log_dbg(D_TRACE, "Hiding card_%d caid=%04x remoteid=%08x from %s for %d %s",
454 uu, cardarray[ii]->caid, cardarray[ii]->remote_id, username(cl), hidetime, hidetime>1 ? "secconds" : "seccond");
455 uu += 1;
461 cs_sleepms(hidetime * 1000);
462 uu = 0;
464 for(ii = 0; ii < cardsize; ii++)
466 if(hidecards_card_valid_for_client(cl, cardarray[ii]))
468 if (cardarray[ii]->id)
470 hide_count = unhide_card_to_client(cardarray[ii], cl);
471 if(hide_count)
473 cs_log_dbg(D_TRACE, "Unhiding card_%d caid=%04x remoteid=%08x for %s",
474 uu, cardarray[ii]->caid, cardarray[ii]->remote_id, username(cl));
475 uu += 1;
481 NULLFREE(cardarray);
484 #endif
485 break;
486 } // case ACTION_CLIENT_HIDECARDS
488 } // switch
490 __free_job_data(cl, data);
493 if(thread_pipe[1] && (mbuf[0] != 0x00))
495 cs_log_dump_dbg(D_TRACE, mbuf, 1, "[OSCAM-WORK] Write to pipe:");
496 if(write(thread_pipe[1], mbuf, 1) == -1) // wakeup client check
498 cs_log_dbg(D_TRACE, "[OSCAM-WORK] Writing to pipe failed (errno=%d %s)", errno, strerror(errno));
502 // Check for some race condition where while we ended, another thread added a job
503 SAFE_MUTEX_LOCK(&cl->thread_lock);
504 if(cl->joblist && ll_count(cl->joblist) > 0)
506 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
507 continue;
509 else
511 cl->thread_active = 0;
512 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
513 break;
516 cl->thread_active = 0;
517 cl->work_mbuf = NULL; // Prevent free_client from freeing mbuf (->work_mbuf)
518 NULLFREE(mbuf);
519 pthread_exit(NULL);
520 return NULL;
524 * adds a job to the job queue
525 * if ptr should be free() after use, set len to the size
526 * else set size to 0
528 int32_t add_job(struct s_client *cl, enum actions action, void *ptr, int32_t len)
530 if(!cl || cl->kill)
532 if(!cl)
533 { cs_log("WARNING: add_job failed. Client killed!"); } // Ignore jobs for killed clients
534 if(len && ptr)
535 { NULLFREE(ptr); }
536 return 0;
539 if(action == ACTION_CACHE_PUSH_OUT && cacheex_check_queue_length(cl))
541 if(len && ptr)
542 { NULLFREE(ptr); }
543 return 0;
546 struct job_data *data;
547 if(!cs_malloc(&data, sizeof(struct job_data)))
549 if(len && ptr)
550 { NULLFREE(ptr); }
551 return 0;
554 data->action = action;
555 data->ptr = ptr;
556 data->cl = cl;
557 data->len = len;
558 cs_ftime(&data->time);
560 SAFE_MUTEX_LOCK(&cl->thread_lock);
561 if(cl && !cl->kill && cl->thread_active)
563 if(!cl->joblist)
564 { cl->joblist = ll_create("joblist"); }
565 ll_append(cl->joblist, data);
566 if(cl->thread_active == 2)
567 { pthread_kill(cl->thread, OSCAM_SIGNAL_WAKEUP); }
568 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
569 cs_log_dbg(D_TRACE, "add %s job action %d queue length %d %s",
570 action > ACTION_CLIENT_FIRST ? "client" : "reader", action,
571 ll_count(cl->joblist), username(cl));
572 return 1;
575 /* pcsc doesn't like this; segfaults on x86, x86_64 */
576 int8_t modify_stacksize = 0;
577 struct s_reader *rdr = cl->reader;
578 if(cl->typ != 'r' || !rdr || rdr->typ != R_PCSC)
579 { modify_stacksize = 1; }
581 if(action != ACTION_READER_CHECK_HEALTH)
583 cs_log_dbg(D_TRACE, "start %s thread action %d",
584 action > ACTION_CLIENT_FIRST ? "client" : "reader", action);
587 int32_t ret = start_thread("client work", work_thread, (void *)data, &cl->thread, 1, modify_stacksize);
588 if(ret)
590 cs_log("ERROR: can't create thread for %s (errno=%d %s)",
591 action > ACTION_CLIENT_FIRST ? "client" : "reader", ret, strerror(ret));
592 free_job_data(data);
595 cl->thread_active = 1;
596 SAFE_MUTEX_UNLOCK(&cl->thread_lock);
597 return 1;