Exemple #1
0
void client_check_status(struct s_client *cl) {
    if (!cl || cl->kill || !cl->init_done)
        return;
    switch (cl->typ) {
    case 'm':
    case 'c':
        // Check clients for exceeding cmaxidle by checking cl->last
        if (!(cl->ncd_keepalive && (get_module(cl)->listenertype & LIS_NEWCAMD)) &&
                cl->last && cfg.cmaxidle && (time(NULL) - cl->last) > (time_t)cfg.cmaxidle)
        {
            add_job(cl, ACTION_CLIENT_IDLE, NULL, 0);
        }
        break;
    case 'r':
        cardreader_checkhealth(cl, cl->reader);
        break;
    case 'p': {
        struct s_reader *rdr = cl->reader;
        if (!rdr || !rdr->enable || !rdr->active) //reader is disabled or restarting at this moment
            break;
        // execute reader do idle on proxy reader after a certain time (rdr->tcp_ito = inactivitytimeout)
        // disconnect when no keepalive available
        if ((rdr->tcp_ito && is_cascading_reader(rdr)) || rdr->typ == R_CCCAM) {
            time_t now = time(NULL);
            int32_t time_diff = abs(now - rdr->last_check);
            if (time_diff > 60 || (time_diff > 30 && rdr->typ == R_CCCAM)) { //check 1x per minute or every 30s for cccam
                add_job(rdr->client, ACTION_READER_IDLE, NULL, 0);
                rdr->last_check = now;
            }
        }
        break;
    }
    }
}
Exemple #2
0
static void cs_waitforcardinit(void)
{
	if (cfg.waitforcards)
	{
		cs_log("waiting for local card init");
		int32_t card_init_done;
		do {
			card_init_done = 1;
			struct s_reader *rdr;
			LL_ITER itr = ll_iter_create(configured_readers);
			while((rdr = ll_iter_next(&itr))) {
				if (rdr->enable && !is_cascading_reader(rdr) && (rdr->card_status == CARD_NEED_INIT || rdr->card_status == UNKNOWN)) {
					card_init_done = 0;
					break;
				}
			}

			if (!card_init_done)
				cs_sleepms(300); // wait a little bit
			//alarm(cfg.cmaxidle + cfg.ctimeout / 1000 + 1);
		} while (!card_init_done && !exit_oscam);
		if (cfg.waitforcards_extra_delay>0 && !exit_oscam)
			cs_sleepms(cfg.waitforcards_extra_delay);
		cs_log("init for all local cards done");
	}
}
Exemple #3
0
void client_check_status(struct s_client *cl)
{
	if(!cl || cl->kill || !cl->init_done)
		{ return; }
	switch(cl->typ)
	{
	case 'm':
	case 'c':

		if((get_module(cl)->listenertype & LIS_CCCAM) && cl->last && (time(NULL) - cl->last) > (time_t)12)
		{
			add_job(cl, ACTION_CLIENT_IDLE, NULL, 0);
		}

		//Check umaxidle to avoid client is killed for inactivity, it has priority than cmaxidle
		if(!cl->account->umaxidle)
			break;

		// Check user for exceeding umaxidle by checking cl->last
		if(!(cl->ncd_keepalive && (get_module(cl)->listenertype & LIS_NEWCAMD)) && cl->account->umaxidle>0 &&
				cl->last && (time(NULL) - cl->last) > (time_t)cl->account->umaxidle)
		{
			add_job(cl, ACTION_CLIENT_IDLE, NULL, 0);
		}

		// Check clients for exceeding cmaxidle by checking cl->last
		if(!(cl->ncd_keepalive && (get_module(cl)->listenertype & LIS_NEWCAMD)) &&
				cl->last && cl->account->umaxidle==-1 && cfg.cmaxidle && (time(NULL) - cl->last) > (time_t)cfg.cmaxidle)
		{
			add_job(cl, ACTION_CLIENT_IDLE, NULL, 0);
		}

		break;
	case 'r':
		cardreader_checkhealth(cl, cl->reader);
		break;
	case 'p':
	{
		struct s_reader *rdr = cl->reader;
		if(!rdr || !rdr->enable || !rdr->active)  //reader is disabled or restarting at this moment
			{ break; }
		// execute reader do idle on proxy reader after a certain time (rdr->tcp_ito = inactivitytimeout)
		// disconnect when no keepalive available
		if((rdr->tcp_ito && is_cascading_reader(rdr)) || (rdr->typ == R_CCCAM) || (rdr->typ == R_CAMD35) || (rdr->typ == R_CS378X) || (rdr->typ == R_SCAM) || (rdr->tcp_ito != 0 && rdr->typ == R_RADEGAST))
		{
			time_t now = time(NULL);
			int32_t time_diff = llabs(now - rdr->last_check);
			if(time_diff > 60 || (time_diff > 12 && (rdr->typ == R_CCCAM || rdr->typ == R_CAMD35 || rdr->typ == R_CS378X)) || ((time_diff > (rdr->tcp_rto?rdr->tcp_rto:60)) && rdr->typ == R_RADEGAST))     //check 1x per minute or every 10s for cccam/camd35 or reconnecttimeout radegast if 0 defaut 60s
			{
				add_job(rdr->client, ACTION_READER_IDLE, NULL, 0);
				rdr->last_check = now;
			}
		}
		break;
	}
	}
}
Exemple #4
0
void module_reader_set(struct s_reader *rdr)
{
	int i;
	if(!is_cascading_reader(rdr))
		{ return; }
	for(i = 0; i < CS_MAX_MOD; i++)
	{
		struct s_module *module = &modules[i];
		if(module->num && module->num == rdr->typ)
			rdr->ph = *module;
	}
}
Exemple #5
0
int32_t reader_do_emm(struct s_reader * reader, EMM_PACKET *ep)
{
	int32_t i, rc, ecs;
	unsigned char md5tmp[MD5_DIGEST_LENGTH];
	struct timeb tps;
	struct s_client *cl = reader->client;

	if(!cl)
		return 0;

	cs_ftime(&tps);

	MD5(ep->emm, ep->emm[2], md5tmp);

	for (i = ecs = 0; i < CS_EMMCACHESIZE; i++) {
		if (!memcmp(cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
			cl->emmcache[i].count++;
			if (reader->cachemm) {
				if (cl->emmcache[i].count > reader->rewritemm) {
					ecs = 2; //skip emm
				} else {
					ecs = 1; //rewrite emm
				}
			}
			break;
		}
	}

	// Ecs=0 not found in cache
	// Ecs=1 found in cache, rewrite emm
	// Ecs=2 skip
	if ((rc = ecs) < 2) {
		if (is_cascading_reader(reader)) {
			rdr_debug_mask(reader, D_READER, "network emm reader");
			if (reader->ph.c_send_emm) {
				rc = reader->ph.c_send_emm(ep);
			} else {
				rdr_debug_mask(reader, D_READER, "send_emm() support missing");
				rc = 0;
			}
		} else {
			rdr_debug_mask(reader, D_READER, "local emm reader");
			rc = cardreader_do_emm(reader, ep);
		}
		if (!ecs)
			i = reader_store_emm(ep->type, md5tmp);
	}

	reader_log_emm(reader, ep, i, rc, &tps);

	return rc;
}
Exemple #6
0
void module_reader_set(struct s_reader *rdr) {
	int i;
	if (!is_cascading_reader(rdr))
		return;
	for (i = 0; i < CS_MAX_MOD; i++) {
		struct s_module *module = &modules[i];
		if (module->num && module->num == rdr->typ) {
			rdr->ph = *module;
			if (rdr->device[0])
				rdr->ph.active = 1;
		}
	}
}
Exemple #7
0
static void reader_log_emm(struct s_reader * reader, EMM_PACKET *ep, int32_t i, int32_t rc, struct timeb *tps) {
	char *rtxt[] = {
		"error",
		is_cascading_reader(reader) ? "sent" : "written",
		"skipped",
		"blocked" };
	char *typedesc[] = { "unknown", "unique", "shared", "global" };
	struct s_client *cl = reader->client;
	struct timeb tpe;

	if (reader->logemm & (1 << rc)) {
		cs_ftime(&tpe);
		if (!tps)
			tps = &tpe;

		rdr_log(reader, "%s emmtype=%s, len=%d, idx=%d, cnt=%d: %s (%ld ms)",
				username(ep->client), typedesc[cl->emmcache[i].type], ep->emm[2],
				i, cl->emmcache[i].count, rtxt[rc],
				1000 * (tpe.time - tps->time) + tpe.millitm - tps->millitm);
	}

	if (rc) {
		cl->lastemm = time(NULL);
		led_status_emm_ok();
	}

#if defined(WEBIF) || defined(LCDSUPPORT)
	//counting results
	switch (rc) {
	case 0: reader->emmerror[ep->type]++; break;
	case 1: reader->emmwritten[ep->type]++; break;
	case 2: reader->emmskipped[ep->type]++; break;
	case 3: reader->emmblocked[ep->type]++; break;
	}
#endif
}
Exemple #8
0
void do_emm(struct s_client * client, EMM_PACKET *ep)
{
	char *typtext[]={"unknown", "unique", "shared", "global"};
	char tmp[17];
	int32_t emmnok=0;

	struct s_reader *aureader = NULL;
	cs_ddump_mask(D_EMM, ep->emm, ep->emmlen, "emm:");

	int8_t cl_dvbapi = 0, assemble = 0;
#ifdef HAVE_DVBAPI
	cl_dvbapi = streq(cfg.dvbapi_usr, client->account->usr);
#endif
	if (client->account->emm_reassembly > 1 || (client->account->emm_reassembly && cl_dvbapi))
		assemble = 1;

	LL_ITER itr = ll_iter_create(client->aureader_list);
	while ((aureader = ll_iter_next(&itr))) {
		if (!aureader->enable)
			continue;

		uint16_t caid = b2i(2, ep->caid);
		uint32_t provid = b2i(4, ep->provid);

		if (aureader->audisabled) {
			rdr_debug_mask(aureader, D_EMM, "AU is disabled");
			/* we have to write the log for blocked EMM here because
			 this EMM never reach the reader module where the rest
			 of EMM log is done. */
			if (aureader->logemm & 0x10)  {
				rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=1: audisabled (0 ms)",
						client->account->usr,
						typtext[ep->type],
						ep->emm[2]);
			}
			continue;
		}

		if (!(aureader->grp & client->grp)) {
			rdr_debug_mask(aureader, D_EMM, "skip emm, group mismatch");
			continue;
		}

		//TODO: provider possibly not set yet, this is done in get_emm_type()
		if (!emm_reader_match(aureader, caid, provid))
			continue;

		struct s_cardsystem *cs = NULL;

		if (is_cascading_reader(aureader)) { // network reader (R_CAMD35 R_NEWCAMD R_CS378X R_CCCAM)
			if (!aureader->ph.c_send_emm) // no emm support
				continue;

			cs = get_cardsystem_by_caid(caid);
			if (!cs) {
				rdr_debug_mask(aureader, D_EMM, "unable to find cardsystem for caid %04X", caid);
				continue;
			}
		} else { // local reader
			if (aureader->csystem.active)
				cs=&aureader->csystem;
		}

		if (cs && cs->get_emm_type) {
			if (!cs->get_emm_type(ep, aureader)) {
				rdr_debug_mask(aureader, D_EMM, "emm skipped, get_emm_type() returns error");
				emmnok++;
				continue;
			}
		}

		if (cs && cs->get_emm_filter) {
			if (!do_simple_emm_filter(aureader, cs, ep)) {
				rdr_debug_mask(aureader, D_EMM, "emm skipped, emm_filter() returns invalid");
				emmnok++;
				continue;
			}
		}

		if (cs && cs->do_emm_reassembly) {
			if (assemble) {
				if (!cs->do_emm_reassembly(client, ep))
					return;
			} else {
				rdr_debug_mask(aureader, D_EMM, "processing raw emm");
			}
		}

		rdr_debug_mask_sensitive(aureader, D_EMM, "emmtype %s. Reader serial {%s}.", typtext[ep->type],
			cs_hexdump(0, aureader->hexserial, 8, tmp, sizeof(tmp)));
		rdr_debug_mask_sensitive(aureader, D_EMM, "emm UA/SA: {%s}.",
			cs_hexdump(0, ep->hexserial, 8, tmp, sizeof(tmp)));

		client->last = time(NULL);
		saveemm(aureader, ep);

		int32_t is_blocked = 0;
		switch (ep->type) {
			case UNKNOWN: is_blocked = (aureader->blockemm & EMM_UNKNOWN) == EMM_UNKNOWN; break;
			case UNIQUE : is_blocked = (aureader->blockemm & EMM_UNIQUE ) == EMM_UNIQUE;  break;
			case SHARED : is_blocked = (aureader->blockemm & EMM_SHARED ) == EMM_SHARED;  break;
			case GLOBAL : is_blocked = (aureader->blockemm & EMM_GLOBAL ) == EMM_GLOBAL;  break;
		}

		// if not already blocked we check for block by len
		if (!is_blocked) is_blocked = cs_emmlen_is_blocked( aureader, ep->emm[2] ) ;

		if (is_blocked != 0) {
#ifdef WEBIF
			aureader->emmblocked[ep->type]++;
			is_blocked = aureader->emmblocked[ep->type];
#endif
			/* we have to write the log for blocked EMM here because
			 this EMM never reach the reader module where the rest
			 of EMM log is done. */
			if (aureader->logemm & 0x08)  {
				rdr_log(aureader, "%s emmtype=%s, len=%d, idx=0, cnt=%d: blocked (0 ms)",
						client->account->usr,
						typtext[ep->type],
						ep->emm[2],
						is_blocked);
			}
			continue;
		}

		client->lastemm = time((time_t*)0);

		client->emmok++;
		if (client->account)
			client->account->emmok++;
		first_client->emmok++;

		//Check emmcache early:
		int32_t i;
		unsigned char md5tmp[CS_EMMSTORESIZE];
		struct s_client *au_cl = aureader->client;

		MD5(ep->emm, ep->emm[2], md5tmp);
		ep->client = client;

		for (i=0; i<CS_EMMCACHESIZE; i++) {
			if (!memcmp(au_cl->emmcache[i].emmd5, md5tmp, CS_EMMSTORESIZE)) {
				rdr_debug_mask(aureader, D_EMM, "emm found in cache: count %d rewrite %d",
					au_cl->emmcache[i].count, aureader->rewritemm);
				if (aureader->cachemm && (au_cl->emmcache[i].count > aureader->rewritemm)) {
					reader_log_emm(aureader, ep, i, 2, NULL);
					return;
				}
				break;
			}
		}

		EMM_PACKET *emm_pack;
		if (cs_malloc(&emm_pack, sizeof(EMM_PACKET))) {
			rdr_debug_mask(aureader, D_EMM, "emm is being sent to reader");
			memcpy(emm_pack, ep, sizeof(EMM_PACKET));
			add_job(aureader->client, ACTION_READER_EMM, emm_pack, sizeof(EMM_PACKET));
		}
	}
	if (emmnok > 0 && emmnok == ll_count(client->aureader_list)) {
		client->emmnok++;
		if (client->account)
			client->account->emmnok++;
		first_client->emmnok++;
	}
}
void azbox_send_dcw(struct s_client *client, ECM_REQUEST *er) {
	cs_debug_mask(D_DVBAPI, LOG_PREFIX "send_dcw");

	FILE *ecmtxt;
	if ((ecmtxt = fopen(ECMINFO_FILE, "w"))) {
		char tmp[25];
		if(er->rc <= E_CACHEEX) {
			fprintf(ecmtxt, "caid: 0x%04X\npid: 0x%04X\nprov: 0x%06X\n", er->caid, er->pid, (uint) er->prid);
			fprintf(ecmtxt, "reader: %s\n", er->selected_reader->label);
			if (is_cascading_reader(er->selected_reader))
				fprintf(ecmtxt, "from: %s\n", er->selected_reader->device);
			else
				fprintf(ecmtxt, "from: local\n");
			fprintf(ecmtxt, "protocol: %s\n", reader_get_type_desc(er->selected_reader, 1));
			fprintf(ecmtxt, "hops: %d\n", er->selected_reader->currenthops);
			fprintf(ecmtxt, "ecm time: %.3f\n", (float) client->cwlastresptime/1000);
			fprintf(ecmtxt, "cw0: %s\n", cs_hexdump(1,demux[0].lastcw[0],8, tmp, sizeof(tmp)));
			fprintf(ecmtxt, "cw1: %s\n", cs_hexdump(1,demux[0].lastcw[1],8, tmp, sizeof(tmp)));
			fclose(ecmtxt);
			ecmtxt = NULL;
		} else {
			fprintf(ecmtxt, "ECM information not found\n");
			fclose(ecmtxt);
		}
	}

	openxcas_busy = 0;

	int32_t i;
	for (i=0; i < MAX_DEMUX; i++) {
		if (er->rc >= E_NOTFOUND) {
			cs_debug_mask(D_DVBAPI, "cw not found");

			if (demux[i].pidindex==-1)
			  dvbapi_try_next_caid(i);

			openxcas_stop_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);
			openxcas_remove_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM);

			unsigned char mask[12];
			unsigned char comp[12];
			memset(&mask, 0x00, sizeof(mask));
			memset(&comp, 0x00, sizeof(comp));

			mask[0] = 0xfe;
			comp[0] = 0x80;

			if (openxcas_add_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM, 0, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback) < 0) {
				cs_log(LOG_PREFIX "unable to add ecm filter (0)");
				if (openxcas_add_filter(openxcas_stream_id, OPENXCAS_FILTER_ECM, openxcas_caid, 0xffff, openxcas_ecm_pid, mask, comp, (void *)azbox_openxcas_ecm_callback) < 0)
					cs_log(LOG_PREFIX "unable to add ecm filter (%04x)", openxcas_caid);
				else
					cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, openxcas_caid);
			} else
				cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter added, pid = %x, caid = %x", openxcas_ecm_pid, 0);

			if (openxcas_start_filter(openxcas_stream_id, openxcas_seq, OPENXCAS_FILTER_ECM) < 0)
				cs_log(LOG_PREFIX "unable to start ecm filter");
			else
				cs_debug_mask(D_DVBAPI, LOG_PREFIX "ecm filter started");

			return;
		}
	}

	unsigned char nullcw[8];
	memset(nullcw, 0, 8);

	int32_t n;
	for (n=0;n<2;n++) {
		if (memcmp(er->cw + (n * 8), demux[0].lastcw[n], 8) && memcmp(er->cw + (n * 8), nullcw, 8)) {
			memcpy(demux[0].lastcw[n], er->cw + (n * 8), 8);
			memcpy(openxcas_cw + (n * 8), er->cw + (n * 8), 8);
		}
	}

	if (openxcas_set_key(openxcas_stream_id, openxcas_seq, 0, openxcas_cipher_idx, openxcas_cw, openxcas_cw + 8) != 1)
		cs_log(LOG_PREFIX "set cw failed");
	else
		cs_ddump_mask(D_DVBAPI, openxcas_cw, 16, LOG_PREFIX "write cws to descrambler");
}