Example #1
0
/*
 * Creates a string ready to write as a token into config or WebIf for au readers. You must free the returned value through free_mk_t().
 */
char *mk_t_aureader(struct s_auth *account)
{
	int32_t pos = 0;
	char *dot = "";

	char *value;
	if(ll_count(account->aureader_list) == 0 || !cs_malloc(&value, 256)) { return ""; }
	value[0] = '\0';

	struct s_reader *rdr;
	LL_ITER itr = ll_iter_create(account->aureader_list);
	while((rdr = ll_iter_next(&itr)))
	{
		pos += snprintf(value + pos, 256 - pos, "%s%s", dot, rdr->label);
		dot = ",";
	}

	return value;
}
Example #2
0
static S_COOL_FILTER  *find_filter_by_chanhandle(S_COOL_CHANHANDLE *chanhandle, int32_t filter_num)
{
	// Find matching channel, if it exists.
	if(ll_count(ll_cool_filter) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_filter);
		S_COOL_FILTER *filter_item;

		while((filter_item = ll_iter_next(&itr)))
		{
			if(filter_item->chanhandle == chanhandle && filter_item->filter_num == filter_num)
			{
				return filter_item;
			}
		}
	}

	return NULL;
}
Example #3
0
static int32_t remove_filter(S_COOL_FILTER *filter_handle)
{
	if(ll_count(ll_cool_filter) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_filter);
		S_COOL_FILTER *filter_item;

		while((filter_item = ll_iter_next(&itr)))
		{
			if(filter_item == filter_handle)
			{
				ll_iter_remove_data(&itr);
				return 0;
			}
		}
	}

	return -1;
}
Example #4
0
static S_COOL_CHANHANDLE *find_chanhandle(int32_t demux_index, int32_t pid)
{
	// Find matching channel, if it exists.
	if(ll_count(ll_cool_chanhandle) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;

		while((handle_item = ll_iter_next(&itr)))
		{
			if(handle_item->demux_index == demux_index && handle_item->pid == pid)
			{
				return handle_item;
			}
		}
	}

	return NULL;
}
Example #5
0
int32_t cacheex_add_stats(struct s_client *cl, uint16_t caid, uint16_t srvid, uint32_t prid, uint8_t direction)
{
	if(!cfg.cacheex_enable_stats)
		{ return -1; }

	// create list if doesn't exist
	if(!cl->ll_cacheex_stats)
		{ cl->ll_cacheex_stats = ll_create("ll_cacheex_stats"); }

	time_t now = time((time_t *)0);
	LL_ITER itr = ll_iter_create(cl->ll_cacheex_stats);
	S_CACHEEX_STAT_ENTRY *cacheex_stats_entry;

	// check for existing entry
	while((cacheex_stats_entry = ll_iter_next(&itr)))
	{
		if(cacheex_stats_entry->cache_srvid == srvid &&
				cacheex_stats_entry->cache_caid == caid &&
				cacheex_stats_entry->cache_prid == prid &&
				cacheex_stats_entry->cache_direction == direction)
		{
			// we already have this entry - just add count and time
			cacheex_stats_entry->cache_count++;
			cacheex_stats_entry->cache_last = now;
			return cacheex_stats_entry->cache_count;
		}
	}

	// if we land here we have to add a new entry
	if(cs_malloc(&cacheex_stats_entry, sizeof(S_CACHEEX_STAT_ENTRY)))
	{
		cacheex_stats_entry->cache_caid = caid;
		cacheex_stats_entry->cache_srvid = srvid;
		cacheex_stats_entry->cache_prid = prid;
		cacheex_stats_entry->cache_count = 1;
		cacheex_stats_entry->cache_last = now;
		cacheex_stats_entry->cache_direction = direction;
		ll_iter_insert(&itr, cacheex_stats_entry);
		return 1;
	}
	return 0;
}
Example #6
0
static int32_t remove_chanhandle(S_COOL_CHANHANDLE *handle)
{
	// Find matching channel, if it exists.
	if(ll_count(ll_cool_chanhandle) > 0)
	{
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;

		while((handle_item = ll_iter_next(&itr)))
		{
			if(handle_item == handle)
			{
				ll_iter_remove_data(&itr);
				return 0;
			}
		}
	}

	return -1;
}
Example #7
0
void gbox_remove_cards_without_goodsids(LLIST *card_list)
{
	if(card_list)
	{
		LL_ITER it = ll_iter_create(card_list);
		struct gbox_card *card;
		while((card = ll_iter_next(&it)))
		{
			if(ll_count(card->goodsids) == 0)
			{
				ll_iter_remove(&it);
				gbox_free_card(card);
			}
			else
			{
				ll_destroy_data_NULL(card->badsids);
			}
		}
	}
	return;
}
Example #8
0
File: linker.c Project: fwum/fwum
static void continue_build(build *current, char *filename, file_contents newest) {
    slice name_slice = new_slice(filename);
    slice *boxed_slice = new(boxed_slice);
    *boxed_slice = name_slice;
    hm_put(current->declarations, slice_hash(name_slice), boxed_slice, filename);
    linked_iter iterator = ll_iter_head(newest.imports);
    while(ll_iter_has_next(&iterator)) {
        import_declaration *dec = ll_iter_next(&iterator);
        char *filename = resolve_name(dec->name);
        slice filename_slice = new_slice(filename);
        slice *boxed_filename = new(boxed_filename);
        *boxed_filename = filename_slice;
        if(!hm_has(current->declarations, slice_hash(filename_slice), &(filename_slice))) {
            file_contents contents = get_contents(filename);
            ll_concat(current->composite.structs, contents.structs);
            ll_concat(current->composite.functions, contents.functions);
            hm_put(current->declarations, slice_hash(filename_slice), boxed_filename, filename);
            continue_build(current, filename, contents);
        }
    }
}
Example #9
0
void free_joblist(struct s_client *cl)
{
	int32_t lock_status = pthread_mutex_trylock(&cl->thread_lock);
	
	LL_ITER it = ll_iter_create(cl->joblist);
	struct job_data *data;
	while((data = ll_iter_next(&it)))
	{
		free_job_data(data);
	}
	ll_destroy(&cl->joblist);
	cl->account = NULL;
	if(cl->work_job_data)  // Free job_data that was not freed by work_thread
		{ free_job_data(cl->work_job_data); }
	cl->work_job_data = NULL;
	
	if(lock_status == 0)
		{ SAFE_MUTEX_UNLOCK(&cl->thread_lock); }
	
	pthread_mutex_destroy(&cl->thread_lock);
}
void dvbapi_save_channel_cache(void)
{
	char fname[256];
	get_config_filename(fname, sizeof(fname), "oscam.ccache");
	FILE *file = fopen(fname, "w");

	if(!file)
	{
		cs_log("dvbapi channelcache can't write to file %s", fname);
		return;
	}

	LL_ITER it = ll_iter_create(channel_cache);
	struct s_channel_cache *c;
	while((c = ll_iter_next(&it)))
	{
		fprintf(file, "%04X,%06X,%04X,%04X,%06X\n", c->caid, c->prid, c->srvid, c->pid, c->chid);
	}

	fclose(file);
	cs_log("dvbapi channelcache saved to %s", fname);
}
Example #11
0
File: printing.c Project: fwum/fwum
/*
Print the created AST to stdout, mostly for debugging purposes
*/
void dump(file_contents contents) {
    {
        linked_iter iterator = ll_iter_head(contents.imports);
        while(ll_iter_has_next(&iterator)) {
            import_declaration *import = ll_iter_next(&iterator);
            printf("IMPORT: %s\n", evaluate(import->name));
        }
    }
    {
        linked_iter iterator = ll_iter_head(contents.enums);
        while(ll_iter_has_next(&iterator)) {
            enum_declaration *dec = ll_iter_next(&iterator);
            printf("ENUM: %s\n", evaluate(dec->name));
            linked_iter items = ll_iter_head(dec->options);
            while(ll_iter_has_next(&items)) {
                statement *option = ll_iter_next(&items);
                printf("\tOPTION: %s\n", evaluate(option->data));
            }
        }
    }
	{
		linked_iter iterator = ll_iter_head(contents.structs);
		while(ll_iter_has_next(&iterator)) {
            struct_declaration *current = ll_iter_next(&iterator);
			printf("STRUCT: %s\n", evaluate(current->name));
            linked_iter iterator = ll_iter_head(current->members);
			while(ll_iter_has_next(&iterator)) {
                struct_member *member = ll_iter_next(&iterator);
				printf("\tMEMBER: NAME: %s | TYPE: %s\n", evaluate(member->name), evaluate(member->type));
			}
		}
	}
	{
        linked_iter iterator = ll_iter_head(contents.functions);
        while(ll_iter_has_next(&iterator)) {
            func_declaration *current = ll_iter_next(&iterator);
			printf("FUNC: %s | TYPE : %s\n", evaluate(current->name), evaluate(current->type));
            printf("\tPARAMETERS:\n");
			dump_node(current->parameters, 2);
            printf("\tBODY:\n");
			dump_node(current->root->children, 2);
		}
	}

}
struct s_channel_cache *dvbapi_find_channel_cache(int32_t demux_id, int32_t pidindex, int8_t caid_and_prid_only)
{
	struct s_ecmpids *p = &demux[demux_id].ECMpids[pidindex];
	struct s_channel_cache *c;
	LL_ITER it;

	if(!channel_cache)
		{ channel_cache = ll_create("channel cache"); }

	it = ll_iter_create(channel_cache);
	while((c = ll_iter_next(&it)))
	{

		if(caid_and_prid_only)
		{
			if(p->CAID == c->caid && (p->PROVID == c->prid || p->PROVID == 0))  // PROVID ==0 some provider no provid in PMT table
				{ return c; }
		}
		else
		{
			if(demux[demux_id].program_number == c->srvid
					&& p->CAID == c->caid
					&& p->ECM_PID == c->pid
					&& (p->PROVID == c->prid || p->PROVID == 0)) // PROVID ==0 some provider no provid in PMT table
			{

#ifdef WITH_DEBUG
				char buf[ECM_FMT_LEN];
				ecmfmt(c->caid, 0, c->prid, c->chid, c->pid, c->srvid, 0, 0, 0, 0, buf, ECM_FMT_LEN, 0, 0);
				cs_debug_mask(D_DVBAPI, "[DVBAPI] found in channel cache: %s", buf);
#endif
				return c;
			}
		}
	}
	return NULL;
}
Example #13
0
static void *arm_led_thread_main(void *UNUSED(thread_data))
{
	uint8_t running = 1;
	set_thread_name(__func__);
	while(running)
	{
		LL_ITER iter = ll_iter_create(arm_led_actions);
		struct s_arm_led *arm_led;
		while((arm_led = ll_iter_next(&iter)))
		{
			int32_t led, action;
			time_t now, start;
			led = arm_led->led;
			action = arm_led->action;
			now = time((time_t)0);
			start = arm_led->start_time;
			ll_iter_remove_data(&iter);
			if(action == LED_STOP_THREAD)
			{
				running = 0;
				break;
			}
			if(now - start < ARM_LED_TIMEOUT)
			{
				arm_switch_led_from_thread(led, action);
			}
		}
		if(running)
		{
			sleep(60);
		}
	}
	ll_clear_data(arm_led_actions);
	pthread_exit(NULL);
	return NULL;
}
Example #14
0
int32_t coolapi_set_filter (int32_t fd, int32_t num, int32_t pid, uchar * flt, uchar * mask, int32_t type)
{
	dmx_t * dmx =  find_demux(fd, 0);
	if(!dmx) {
		cs_debug_mask(D_DVBAPI, "dmx is NULL!");
		return -1;
	}

	int32_t result, channel_found=0;

	void * channel = NULL;

	if (ll_count(ll_cool_chanhandle) > 0) {
		LL_ITER itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;
		while ((handle_item=ll_iter_next(&itr))) {
			if (handle_item->demux_index == dmx->demux_index && handle_item->pid == pid) {
				channel = handle_item->channel;
				channel_found=1;
				break;
			}
		}
	}

	if (!channel) {
		buffer_open_arg_t bufarg;
		int32_t uBufferSize = 8256;
		memset(&bufarg, 0, sizeof(bufarg));

		bufarg.type = 3;
		bufarg.size = uBufferSize;
		bufarg.unknown3 = (uBufferSize * 7) / 8;

		result = cnxt_cbuf_open(&dmx->buffer1, &bufarg, NULL, NULL);
		coolapi_check_error("cnxt_cbuf_open", result);

		bufarg.type = 0;

		result = cnxt_cbuf_open(&dmx->buffer2, &bufarg, NULL, NULL);
		coolapi_check_error("cnxt_cbuf_open", result);

		channel_open_arg_t chanarg;
		memset(&chanarg, 0, sizeof(channel_open_arg_t));
		chanarg.type = 4;

		result = cnxt_dmx_channel_open(dmx->device, &dmx->channel, &chanarg, dmx_callback, dmx);
		coolapi_check_error("cnxt_dmx_channel_open", result);

		result = cnxt_dmx_set_channel_buffer(dmx->channel, 0, dmx->buffer1);
		coolapi_check_error("cnxt_dmx_set_channel_buffer", result);

		result = cnxt_dmx_channel_attach(dmx->channel, 0xB, 0, dmx->buffer2);
		coolapi_check_error("cnxt_dmx_channel_attach", result);

		result = cnxt_cbuf_attach(dmx->buffer2, 2, dmx->channel);
		coolapi_check_error("cnxt_cbuf_attach", result);

		result = cnxt_dmx_set_channel_pid(dmx->channel, pid);
		coolapi_check_error("cnxt_dmx_set_channel_pid", result);

		result = cnxt_cbuf_flush (dmx->buffer1, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);
		result = cnxt_cbuf_flush (dmx->buffer2, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);

		S_COOL_CHANHANDLE *handle_item;
		if (cs_malloc(&handle_item,sizeof(S_COOL_CHANHANDLE))) {
			handle_item->pid 			= pid;
			handle_item->channel 		= dmx->channel;
			handle_item->buffer1 		= dmx->buffer1;
			handle_item->buffer2		= dmx->buffer2;
			handle_item->demux_index 	= dmx->demux_index;
			ll_append(ll_cool_chanhandle, handle_item);
		}
		cs_debug_mask(D_DVBAPI, "opened new channel %x", (int32_t) dmx->channel);
   } else {
		channel_found=1;
		dmx->channel = channel;
		dmx->buffer1 = NULL;
		dmx->buffer2 = NULL;
	}

	cs_debug_mask(D_DVBAPI, "setting new filter fd=%08x demux=%d channel=%x num=%d pid=%04x flt=%x mask=%x", fd, dmx->demux_index, (int32_t) dmx->channel, num, pid, flt[0], mask[0]);

	pthread_mutex_lock(&dmx->mutex);

	filter_set_t filter;
	dmx->filter_num = num;
	dmx->pid = pid;
	dmx->type = type;

	memset(&filter, 0, sizeof(filter));
	filter.length = 12;
	memcpy(filter.filter, flt, 16);
	memcpy(filter.mask, mask, 16);

	result = cnxt_dmx_open_filter(dmx->device, &dmx->filter);
	coolapi_check_error("cnxt_dmx_open_filter", result);

	result = cnxt_dmx_set_filter(dmx->filter, &filter, NULL);
	coolapi_check_error("cnxt_dmx_set_filter", result);

	result = cnxt_dmx_channel_attach_filter(dmx->channel, dmx->filter);
	coolapi_check_error("cnxt_dmx_channel_attach_filter", result);

	if (channel_found) {
		result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0);
		coolapi_check_error("cnxt_dmx_channel_ctrl", result);
	}

	result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0);
	coolapi_check_error("cnxt_dmx_channel_ctrl", result);

	pthread_mutex_unlock(&dmx->mutex);

	S_COOL_FILTER *filter_item;
	if (cs_malloc(&filter_item,sizeof(S_COOL_FILTER))) {
		// fill filter item
		filter_item->fd = fd;
		filter_item->pid = pid;
		filter_item->channel = (int32_t) dmx->channel;
		memcpy(filter_item->filter16, flt, 16);
		memcpy(filter_item->mask16, mask, 16);

		//add filter item
		ll_append(ll_cool_filter, filter_item);
	}
	return 0;
}
Example #15
0
int32_t coolapi_remove_filter (int32_t fd, int32_t num)
{
	dmx_t * dmx = find_demux(fd, 0);
	if(!dmx) {
		 cs_debug_mask(D_DVBAPI, "dmx is NULL!");
		 return -1;
	}

	if(dmx->pid <= 0)
		return -1;

	int32_t result, filter_on_channel=0;

    cs_debug_mask(D_DVBAPI, "removing filter fd=%08x num=%d pid=%04x on channel=%x", fd, num, dmx->pid, (int32_t) dmx->channel);

	pthread_mutex_lock(&dmx->mutex);

	if(dmx->filter) {
		result = cnxt_dmx_channel_detach_filter(dmx->channel, dmx->filter);
		coolapi_check_error("cnxt_dmx_channel_detach_filter", result);
		result = cnxt_dmx_close_filter(dmx->filter);
		coolapi_check_error("cnxt_dmx_close_filter", result);
		dmx->filter = NULL;
		result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0);
		coolapi_check_error("cnxt_dmx_channel_ctrl", result);
	}

	LL_ITER itr = ll_iter_create(ll_cool_filter);
	S_COOL_FILTER *filter_item;
	while ((filter_item=ll_iter_next(&itr))) {
		if (filter_item->channel == (int32_t) dmx->channel)
			filter_on_channel++;
		if (filter_item->fd == fd) {
			ll_iter_remove_data(&itr);
			filter_on_channel--;
		}
	}

	if (!filter_on_channel) {
		cs_debug_mask(D_DVBAPI, "closing channel %x", (int32_t) dmx->channel);

		itr = ll_iter_create(ll_cool_chanhandle);
		S_COOL_CHANHANDLE *handle_item;
		while ((handle_item=ll_iter_next(&itr))) {
			if (handle_item->demux_index == dmx->demux_index && handle_item->pid == dmx->pid) {
				dmx->buffer1=handle_item->buffer1;
				dmx->buffer2=handle_item->buffer2;
				ll_iter_remove_data(&itr);
				break;
			}
		}

		if (!dmx->buffer1 || !dmx->buffer2)
			cs_debug_mask(D_DVBAPI, "WARNING: buffer handle not found!");

		result = cnxt_dmx_channel_ctrl(dmx->channel, 0, 0);
		coolapi_check_error("cnxt_dmx_channel_ctrl", result);

		result = cnxt_dmx_set_channel_pid(dmx->channel, 0x1FFF);
		coolapi_check_error("cnxt_dmx_set_channel_pid", result);

		result = cnxt_cbuf_flush (dmx->buffer1, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);

		result = cnxt_cbuf_flush (dmx->buffer2, 0);
		coolapi_check_error("cnxt_cbuf_flush", result);

		result = cnxt_cbuf_detach(dmx->buffer2, 2, dmx->channel);
		coolapi_check_error("cnxt_cbuf_detach", result);
		result = cnxt_dmx_channel_detach(dmx->channel, 0xB, 0, dmx->buffer1);
		coolapi_check_error("cnxt_dmx_channel_detach", result);

		result = cnxt_dmx_channel_close(dmx->channel);
		coolapi_check_error("cnxt_dmx_channel_close", result);

		result = cnxt_cbuf_close(dmx->buffer2);
		coolapi_check_error("cnxt_cbuf_close", result);

		result = cnxt_cbuf_close(dmx->buffer1);
		coolapi_check_error("cnxt_cbuf_close", result);
	}

	if (filter_on_channel) {
		result = cnxt_dmx_channel_ctrl(dmx->channel, 2, 0);
		coolapi_check_error("cnxt_dmx_channel_ctrl", result);
	}

	pthread_mutex_unlock(&dmx->mutex);

	dmx->pid = -1;
	return 0;
}
Example #16
0
static int32_t ghttp_recv_chk(struct s_client *client, uchar *dcw, int32_t *rc, uchar *buf, int32_t n)
{
	char *data;
	char *hdrstr;
	uchar *content;
	int rcode, len, clen = 0;
	s_ghttp *context = (s_ghttp *)client->ghttp;
	ECM_REQUEST *er = NULL;

	if(n < 5) { return -1; }

	data = strstr((char *)buf, "HTTP/1.1 ");
	if(!data || ll_count(context->ecm_q) > 6)
	{
		cs_debug_mask(D_CLIENT, "%s: non http or otherwise corrupt response: %s", client->reader->label, buf);
		cs_ddump_mask(D_CLIENT, buf, n, "%s: ", client->reader->label);
		network_tcp_connection_close(client->reader, "receive error");
		NULLFREE(context->session_id);
		ll_clear(context->ecm_q);
		return -1;
	}

	LL_ITER itr = ll_iter_create(context->ecm_q);
	er = (ECM_REQUEST *)ll_iter_next(&itr);

	rcode = _get_int_header(buf, "HTTP/1.1 ");
	clen = _get_int_header(buf, "Content-Length: ");

	content = (uchar *)(strstr(data, "\r\n\r\n") + 4);

	hdrstr = _get_header_substr(buf, "ETag: \"", "\"\r\n");
	if(hdrstr)
	{
		NULLFREE(context->host_id);
		context->host_id = (uchar *)hdrstr;
		cs_debug_mask(D_CLIENT, "%s: new name: %s", client->reader->label, context->host_id);
		len = b64decode(context->host_id);
		if(len == 0 || len >= 64)
		{
			NULLFREE(context->host_id);
		}
		else
		{
			cs_debug_mask(D_CLIENT, "%s: redirected...", client->reader->label);
			NULLFREE(context->session_id);
			ll_clear_data(ghttp_ignored_contexts);
			ll_clear(context->ecm_q);
			return -1;
		}
	}

	hdrstr = _get_header_substr(buf, "ETag: W/\"", "\"\r\n");
	if(hdrstr)
	{
		NULLFREE(context->fallback_id);
		context->fallback_id = (uchar *)hdrstr;
		cs_debug_mask(D_CLIENT, "%s: new fallback name: %s", client->reader->label, context->fallback_id);
		len = b64decode(context->fallback_id);
		if(len == 0 || len >= 64)
		{
			NULLFREE(context->fallback_id);
		}
	}

	hdrstr = _get_header(buf, "Set-Cookie: GSSID=");
	if(hdrstr)
	{
		NULLFREE(context->session_id);
		context->session_id = (uchar *)hdrstr;
		cs_debug_mask(D_CLIENT, "%s: set session_id to: %s", client->reader->label, context->session_id);
	}

	// buf[n] = '\0';
	// cs_ddump_mask(D_TRACE, content, clen, "%s: reply\n%s", client->reader->label, buf);

	if(rcode < 200 || rcode > 204)
	{
		cs_debug_mask(D_CLIENT, "%s: http error code %d", client->reader->label, rcode);
		data = strstr((char *)buf, "Content-Type: application/octet-stream"); // if not octet-stream, google error. need reconnect?
		if(data)    // we have error info string in the post content
		{
			if(clen > 0)
			{
				content[clen] = '\0';
				cs_debug_mask(D_CLIENT, "%s: http error message: %s", client->reader->label, content);
			}
		}
		if(rcode == 503)
		{
			if(er && _is_post_context(context->post_contexts, er, false))
			{
				if(_swap_hosts(context))
				{
					cs_debug_mask(D_CLIENT, "%s: switching to fallback", client->reader->label);
				}
				else
				{
					cs_debug_mask(D_CLIENT, "%s: recv_chk got 503 despite post, trying reconnect", client->reader->label);
					network_tcp_connection_close(client->reader, "reconnect");
					ll_clear(context->ecm_q);
				}
			}
			else
			{
				// on 503 cache timeout, retry with POST immediately (and switch to POST for subsequent)
				if(er)
				{
					_set_pid_status(context->post_contexts, er->onid, er->tsid, er->srvid, 0);
					cs_debug_mask(D_CLIENT, "%s: recv_chk got 503, trying direct post", client->reader->label);
					_ghttp_post_ecmdata(client, er);
				}
			}
		}
		else if(rcode == 401)
		{
			NULLFREE(context->session_id);
			if(er)
			{
				cs_debug_mask(D_CLIENT, "%s: session expired, trying direct post", client->reader->label);
				_ghttp_post_ecmdata(client, er);
			}
		}
		else if(rcode == 403)
		{
			client->reader->enable = 0;
			network_tcp_connection_close(client->reader, "login failure");
			ll_clear(context->ecm_q);
			cs_log("%s: invalid username/password, disabling reader.", client->reader->label);
		}

		// not sure if this is needed on failure, copied from newcamd
		*rc = 0;
		memset(dcw, 0, 16);

		return -1;
	}

	// successful http reply (200 ok or 204 no content)

	hdrstr = _get_header(buf,  "Pragma: context-ignore=");
	if(hdrstr)
	{
		if(clen > 1)
		{
			cs_ddump_mask(D_CLIENT, content, clen, "%s: pmt ignore reply - %s (%d pids)", client->reader->label, hdrstr, clen / 2);
			uint32_t onid = 0, tsid = 0, sid = 0;
			if(sscanf(hdrstr, "%4x-%4x-%4x", &onid, &tsid, &sid) == 3)
				{ _set_pids_status(ghttp_ignored_contexts, onid, tsid, sid, content, clen); }
			NULLFREE(hdrstr);
			return -1;
		}
		NULLFREE(hdrstr);
	}

	data = strstr((char *)buf, "Pragma: context-ignore-clear");
	if(data)
	{
		cs_debug_mask(D_CLIENT, "%s: clearing local ignore list (size %d)", client->reader->label, ll_count(ghttp_ignored_contexts));
		ll_clear_data(ghttp_ignored_contexts);
	}

	// switch back to cache get after rapid ecm response (arbitrary atm), only effect is a slight bw save for client
	if(!er || _is_post_context(context->post_contexts, er, false))
	{
		data = strstr((char *)buf, "Pragma: cached");
		if(data || (client->cwlastresptime > 0 && client->cwlastresptime < 640))
		{
			cs_debug_mask(D_CLIENT, "%s: probably cached cw (%d ms), switching back to cache get for next req", client->reader->label, client->cwlastresptime);
			if(er) { _is_post_context(context->post_contexts, er, true); }
		}
	}

	if(clen == 16)    // cw in content
	{
		memcpy(dcw, content, 16);
		*rc = 1;
		er = ll_remove_first(context->ecm_q);
		if(!er) { return -1; }
		cs_ddump_mask(D_TRACE, dcw, 16, "%s: cw recv chk for idx %d", client->reader->label, er->idx);
		return er->idx;
	}
	else
	{
		if(clen != 0) { cs_ddump_mask(D_CLIENT, content, clen, "%s: recv_chk fail, clen = %d", client->reader->label, clen); }
	}
	return -1;
}
Example #17
0
int32_t gbox_cmd_hello(struct s_client *cli, uchar *data, int32_t n)
{
	struct gbox_peer *peer = cli->gbox;
	int32_t i;
	int32_t ncards_in_msg = 0;
	int32_t payload_len = n;
	//TODO: checkcode_len can be made void
	int32_t checkcode_len = 0;
	int32_t hostname_len = 0;
	int32_t footer_len = 0;
	uint8_t *ptr = 0;

	if(!(data[0] == 0x48 && data[1] == 0x49))  // if not MSG_HELLO1
	{
		gbox_decompress(data, &payload_len);
	}
	cs_ddump_mask(D_READER, data, payload_len, "gbox: decompressed data (%d bytes):", payload_len);

	if((data[0x0B] == 0) | ((data[0x0A] == 1) && (data[0x0B] == 0x80)))
	{
		if(peer->gbox.cards)
			{ gbox_remove_cards_without_goodsids(peer->gbox.cards); }
		else
			{ peer->gbox.cards = ll_create("peer.cards"); }
	}
	if((data[0xB] & 0xF) == 0)
	{
		checkcode_len = 7;
		hostname_len = data[payload_len - 1];
		footer_len = hostname_len + 2;
	}

	if(data[0] == 0x48 && data[1] == 0x49)  // if MSG_HELLO1
		{ ptr = data + 11; }
	else
		{ ptr = data + 12; }

	while(ptr < data + payload_len - footer_len - checkcode_len - 1)
	{
		uint16_t caid;
		uint32_t provid;
		uint32_t provid1;

		switch(ptr[0])
		{
			//Viaccess
		case 0x05:
			caid = ptr[0] << 8;
			provid =  ptr[1] << 16 | ptr[2] << 8 | ptr[3];
			break;
			//Cryptoworks
		case 0x0D:
			caid = ptr[0] << 8 | ptr[1];
			provid =  ptr[2];
			break;
		default:
			caid = ptr[0] << 8 | ptr[1];
			provid =  ptr[2] << 8 | ptr[3];
			break;
		}

		//caid check
		if(chk_ctab(caid, &cli->reader->ctab))
		{

			provid1 =  ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
			uint8_t ncards = ptr[4];

			ptr += 5;

			for(i = 0; i < ncards; i++)
			{
				// for all n cards and current caid/provid,
				// create card info from data and add card to peer.cards
				struct gbox_card *card;
				if(!cs_malloc(&card, sizeof(struct gbox_card)))
					{ continue; }

				card->caid = caid;
				card->provid = provid;
				card->provid_1 = provid1;
				card->slot = ptr[0];
				card->dist = ptr[1] & 0xf;
				card->lvl = ptr[1] >> 4;
				card->peer_id = ptr[2] << 8 | ptr[3];
				ptr += 4;

				if((cli->reader->gbox_maxdist >= card->dist) && (card->peer_id != local_gbox.id))
				{

					LL_ITER it = ll_iter_create(peer->gbox.cards);
					struct gbox_card *card_s;
					uint8_t v_card = 0;
					while((card_s = ll_iter_next(&it)))    // don't add card if already in peer.cards list
					{
						if(card_s->peer_id == card->peer_id && card_s->provid_1 == card->provid_1)
						{
							gbox_free_card(card);
							card = NULL;
							v_card = 1;
							break;
						}
					}

					if(v_card != 1)    // new card - not in list
					{
						card->badsids = ll_create("badsids");
						card->goodsids = ll_create("goodsids");
						ll_append(peer->gbox.cards, card);
						ncards_in_msg++;
						cs_debug_mask(D_READER, "   card: caid=%04x, provid=%06x, slot=%d, level=%d, dist=%d, peer=%04x",
									  card->caid, card->provid, card->slot, card->lvl, card->dist, card->peer_id);
					}
				}
				else     // don't add card
				{
					gbox_free_card(card);
					card = NULL;
				}
				cli->reader->tcp_connected = 2; // we have card
			} // end for ncards
		}
		else
		{
Example #18
0
static int32_t cs_check_v(IN_ADDR_T ip, int32_t port, int32_t add, char *info, int32_t acosc_penalty_duration)
{
	int32_t result = 0;
	bool acosc_enabled = false;

#ifdef CS_ANTICASC
	if(cfg.acosc_enabled)
		acosc_enabled = true;
#endif

	if(!(cfg.failbantime || acosc_enabled))
		{ return 0; }

	if(!cfg.v_list)
		{ cfg.v_list = ll_create("v_list"); }

	struct timeb (now);
	cs_ftime(&now);
	LL_ITER itr = ll_iter_create(cfg.v_list);
	V_BAN *v_ban_entry;
	int32_t ftime = cfg.failbantime * 60 * 1000;

	//run over all banned entries to do housekeeping:
	while((v_ban_entry = ll_iter_next(&itr)))
	{
		// housekeeping:
		int32_t gone = comp_timeb(&now, &v_ban_entry->v_time);
		if(((gone >= ftime) && !v_ban_entry->acosc_entry) || (v_ban_entry->acosc_entry && ((gone/1000) >= v_ban_entry->acosc_penalty_dur))) // entry out of time->remove
		{
			NULLFREE(v_ban_entry->info);
			ll_iter_remove_data(&itr);
			continue;
		}

		if(IP_EQUAL(ip, v_ban_entry->v_ip) && port == v_ban_entry->v_port)
		{
			result = 1;
			if(!info)
				{ info = v_ban_entry->info; }
			else if(!v_ban_entry->info)
			{
				v_ban_entry->info = cs_strdup(info);
			}

			if(!add)
			{
				if(v_ban_entry->v_count >= cfg.failbancount)
				{
					if(!v_ban_entry->acosc_entry)
                    	{ cs_debug_mask(D_TRACE, "failban: banned ip %s:%d - %d seconds left%s%s", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port, (ftime - gone)/1000, info ? ", info: " : "", info ? info : ""); }
					else
						{ cs_debug_mask(D_TRACE, "failban: banned ip %s:%d - %d seconds left%s%s", cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port, (v_ban_entry->acosc_penalty_dur - (gone/1000)), info?", info: ":"", info?info:""); }

				}
				else
				{
					cs_debug_mask(D_TRACE, "failban: ip %s:%d chance %d of %d%s%s",
								  cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port,
								  v_ban_entry->v_count, cfg.failbancount, info ? ", info: " : "", info ? info : "");
					v_ban_entry->v_count++;
				}
			}
			else
			{
				cs_debug_mask(D_TRACE, "failban: banned ip %s:%d - already exist in list%s%s",
							  cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port, info ? ", info: " : "", info ? info : "");
			}
		}
	}

	if(add && !result)
	{
		if(cs_malloc(&v_ban_entry, sizeof(V_BAN)))
		{
			cs_ftime(&v_ban_entry->v_time);
			v_ban_entry->v_ip = ip;
			v_ban_entry->v_port = port;
			v_ban_entry->v_count = 1;
			v_ban_entry->acosc_entry = false;
			v_ban_entry->acosc_penalty_dur = 0;
			if(acosc_penalty_duration > 0)
			{
				v_ban_entry->v_count = cfg.failbancount +1; // set it to a higher level
				v_ban_entry->acosc_entry = true;
				v_ban_entry->acosc_penalty_dur = acosc_penalty_duration;
			}
			if(info)
				{ v_ban_entry->info = cs_strdup(info); }
			ll_iter_insert(&itr, v_ban_entry);
			cs_debug_mask(D_TRACE, "failban: ban ip %s:%d with timestamp %ld%s%s",
						  cs_inet_ntoa(v_ban_entry->v_ip), v_ban_entry->v_port, v_ban_entry->v_time.time,
						  info ? ", info: " : "", info ? info : "");
		}
	}

	return result;
}
Example #19
0
int32_t ICC_Async_Device_Init (struct s_reader *reader)
{
	reader->fdmc=-1;
	cs_debug_mask (D_IFD, "IFD: Opening device %s\n", reader->device);

	reader->written = 0;

	if (reader->crdr.active==1 && reader->crdr.reader_init) {
		return reader->crdr.reader_init(reader);
	}

	switch(reader->typ) {
		case R_SC8in1:
			cs_writelock(&sc8in1_lock);
			if (reader->handle != 0) {//this reader is already initialized
				cs_writeunlock(&sc8in1_lock);
				return OK;
			}

			//this reader is uninitialized, thus the first one, since the first one initializes all others

			//get physical device name
			int32_t pos = strlen(reader->device)-2; //this is where : should be located; is also valid length of physical device name
			if (reader->device[pos] != 0x3a) //0x3a = ":"
				cs_log("ERROR: '%c' detected instead of slot separator `:` at second to last position of device %s", reader->device[pos], reader->device);
			reader->slot=(int)reader->device[pos+1] - 0x30;
			reader->device[pos]= 0; //slot 1 reader now gets correct physicalname

			//open physical device
			reader->handle = open (reader->device,  O_RDWR | O_NOCTTY| O_NONBLOCK);
			if (reader->handle < 0) {
				cs_log("ERROR opening device %s",reader->device);
				cs_writeunlock(&sc8in1_lock);
				return ERROR;
			}

			//copy physical device name and file handle to other slots
			struct s_reader *rdr;
			LL_ITER itr = ll_iter_create(configured_readers);
			while((rdr = ll_iter_next(&itr))) //copy handle to other slots
				if (rdr->typ == R_SC8in1 && rdr != reader) { //we have another sc8in1 reader
					unsigned char save = rdr->device[pos];
					rdr->device[pos]=0; //set to 0 so we can compare device names
					if (!strcmp(reader->device, rdr->device)) {//we have a match to another slot with same device name
						rdr->handle = reader->handle;
						rdr->slot=(int)rdr->device[pos+1] - 0x30;
					}
					else
						rdr->device[pos] = save; //restore character
				}
			break;
		case R_MP35:
		case R_MOUSE:
			reader->handle = open (reader->device,  O_RDWR | O_NOCTTY| O_NONBLOCK);
			if (reader->handle < 0) {
				cs_log("ERROR opening device %s",reader->device);
				return ERROR;
			}
			break;
#if defined(TUXBOX) && defined(PPC)
		case R_DB2COM1:
		case R_DB2COM2:
			reader->handle = open (reader->device,  O_RDWR | O_NOCTTY| O_SYNC);
			if (reader->handle < 0) {
				cs_log("ERROR opening device %s",reader->device);
				return ERROR;
			}
			if ((reader->fdmc = open(DEV_MULTICAM, O_RDWR)) < 0) {
				close(reader->handle);
				cs_log("ERROR opening device %s",DEV_MULTICAM);
				return ERROR;
			}
			break;
#endif
		case R_SMART:
#if defined(LIBUSB)
			call (SR_Init(reader));
			break;
#else
			cs_log("ERROR, you have specified 'protocol = smartreader' in oscam.server,");
			cs_log("recompile with SmartReader support.");
			return ERROR;
#endif
		case R_INTERNAL:
#if defined(COOL)
			return Cool_Init(reader->device);
#elif defined(AZBOX)
			return Azbox_Init(reader);
#elif defined(SCI_DEV)
	#if defined(SH4) || defined(STB04SCI)
			reader->handle = open (reader->device, O_RDWR|O_NONBLOCK|O_NOCTTY);
	#else
			reader->handle = open (reader->device, O_RDWR);
	#endif
			if (reader->handle < 0) {
				cs_log("ERROR opening device %s",reader->device);
				return ERROR;
			}
#elif defined(WITH_STAPI)
			return STReader_Open(reader->device, &reader->stsmart_handle);
#else//SCI_DEV
			cs_log("ERROR, you have specified 'protocol = internal' in oscam.server,");
			cs_log("recompile with internal reader support.");
			return ERROR;
#endif//SCI_DEV
			break;
#ifdef HAVE_PCSC
		case R_PCSC:
			return (pcsc_reader_init(reader, reader->device));
			break;
#endif
		default:
			cs_log("ERROR ICC_Device_Init: unknow reader type %i",reader->typ);
			return ERROR;
	}

	if (reader->typ == R_MP35)
	{
		if (MP35_Init(reader)) {
				cs_log("ERROR: MP35_Init returns error");
				MP35_Close (reader);
				return ERROR;
		}
	}
	else if (reader->typ <= R_MOUSE)
		if (Phoenix_Init(reader)) {
				cs_log("ERROR: Phoenix_Init returns error");
				Phoenix_Close (reader);
				return ERROR;
		}

	if (reader->typ == R_SC8in1) {
		call(Sc8in1_Init(reader));
		cs_writeunlock(&sc8in1_lock);
	}

 cs_debug_mask (D_IFD, "IFD: Device %s succesfully opened\n", reader->device);
 return OK;
}
Example #20
0
static void camd35_request_emm(ECM_REQUEST *er)
{
	int32_t i;
	time_t now;
	uchar mbuf[1024];
	struct s_client *cl = cur_client();
	struct s_reader *aureader = NULL, *rdr = NULL;

	if(er->selected_reader && !er->selected_reader->audisabled && ll_contains(cl->aureader_list, er->selected_reader))
		{ aureader = er->selected_reader; }

	if(!aureader && cl->aureader_list)
	{
		LL_ITER itr = ll_iter_create(cl->aureader_list);
		while((rdr = ll_iter_next(&itr)))
		{
			if(emm_reader_match(rdr, er->caid, er->prid))
			{
				aureader = rdr;
				break;
			}
		}
	}

	if(!aureader)
		{ return; }  // TODO

	uint16_t au_caid = aureader->caid;

	if(!au_caid && caid_is_bulcrypt(er->caid)) // Bulcrypt has 2 caids and aureader->caid can't be used. Use ECM_REQUEST caid for AU.
		{ au_caid = er->caid; }

	time(&now);
	if(!memcmp(cl->lastserial, aureader->hexserial, 8))
		if(llabs(now - cl->last) < 180) { return; }

	memcpy(cl->lastserial, aureader->hexserial, 8);
	cl->last = now;

	if(au_caid)
	{
		cl->disable_counter = 0;
		cs_log("%s emm-request sent (reader=%s, caid=%04X, auprovid=%06X)",
			   username(cur_client()), aureader->label, au_caid,
			   aureader->auprovid ? aureader->auprovid : b2i(4, aureader->prid[0]));
	}
	else if(cl->disable_counter > 2)
		{ return; }
	else
		{ cl->disable_counter++; }

	memset(mbuf, 0, sizeof(mbuf));
	mbuf[2] = mbuf[3] = 0xff;           // must not be zero
	i2b_buf(2, er->srvid, mbuf + 8);

	//override request provid with auprovid if set in CMD05
	if(aureader->auprovid)
	{
		if(aureader->auprovid != er->prid)
			{ i2b_buf(4, aureader->auprovid, mbuf + 12); }
		else
			{ i2b_buf(4, er->prid, mbuf + 12); }
	}
	else
	{
		i2b_buf(4, er->prid, mbuf + 12);
	}

	i2b_buf(2, er->pid, mbuf + 16);
	mbuf[0] = 5;
	mbuf[1] = 111;
	if(au_caid)
	{
		mbuf[39] = 1;                           // no. caids
		mbuf[20] = au_caid >> 8;        // caid's (max 8)
		mbuf[21] = au_caid & 0xff;
		memcpy(mbuf + 40, aureader->hexserial, 6);  // serial now 6 bytes
		mbuf[47] = aureader->nprov;
		for(i = 0; i < aureader->nprov; i++)
		{
			if((au_caid >= 0x1700 && au_caid <= 0x1799)  ||  // Betacrypt
					(au_caid >= 0x0600 && au_caid <= 0x0699))    // Irdeto (don't know if this is correct, cause I don't own a IRDETO-Card)
			{
				mbuf[48 + (i * 5)] = aureader->prid[i][0];
				memcpy(&mbuf[50 + (i * 5)], &aureader->prid[i][1], 3);
			}
			else
			{
				mbuf[48 + (i * 5)] = aureader->prid[i][2];
				mbuf[49 + (i * 5)] = aureader->prid[i][3];
				memcpy(&mbuf[50 + (i * 5)], &aureader->sa[i][0], 4); // for conax we need at least 4 Bytes
			}
		}
		//we think client/server protocols should deliver all information, and only readers should discard EMM
		mbuf[128] = (aureader->blockemm & EMM_GLOBAL && !(aureader->saveemm & EMM_GLOBAL)) ? 0 : 1;
		mbuf[129] = (aureader->blockemm & EMM_SHARED && !(aureader->saveemm & EMM_SHARED)) ? 0 : 1;
		mbuf[130] = (aureader->blockemm & EMM_UNIQUE && !(aureader->saveemm & EMM_UNIQUE)) ? 0 : 1;
		mbuf[127] = (aureader->blockemm & EMM_UNKNOWN && !(aureader->saveemm & EMM_UNKNOWN)) ? 0 : 1;
	}
	else        // disable emm
		{ mbuf[20] = mbuf[39] = mbuf[40] = mbuf[47] = mbuf[49] = 1; }
Example #21
0
static void monitor_process_details_reader(struct s_client *cl) {
	char tbuffer1[64], tbuffer2[64], buf[256] = { 0 }, tmpbuf[256] = { 0 }, valid_to[32] = { 0 };
	struct s_reader *rdr = cl->reader;
	if (!rdr) {
		monitor_send_details("Reader do not exist or it is not started.", cl->tid);
		return;
	}

	if (rdr->card_valid_to) {
		struct tm vto_t;
		localtime_r(&rdr->card_valid_to, &vto_t);
		strftime(valid_to, sizeof(valid_to) - 1, "%Y-%m-%d", &vto_t);
	} else {
		strncpy(valid_to, "n/a", 3);
	}

	snprintf(tmpbuf, sizeof(tmpbuf) - 1, "Cardsystem: %s Reader: %s ValidTo: %s HexSerial: %s ATR: %s",
		rdr->csystem.desc,
		rdr->label,
		valid_to,
		cs_hexdump(1, rdr->hexserial, 8, tbuffer2, sizeof(tbuffer2)),
		rdr->card_atr_length
			? cs_hexdump(1, rdr->card_atr, rdr->card_atr_length, buf, sizeof(buf))
			: ""
	);
	monitor_send_details(tmpbuf, cl->tid);

	if (!rdr->ll_entitlements) {
		monitor_send_details("No entitlements for the reader.", cl->tid);
		return;
	}

	S_ENTITLEMENT *item;
	LL_ITER itr = ll_iter_create(rdr->ll_entitlements);
	time_t now = (time(NULL) / 84600) * 84600;

	while ((item = ll_iter_next(&itr))) {
		struct tm start_t, end_t;

		localtime_r(&item->start, &start_t);
		localtime_r(&item->end  , &end_t);

		strftime(tbuffer1, sizeof(tbuffer1) - 1, "%Y-%m-%d %H:%M %z", &start_t);
		strftime(tbuffer2, sizeof(tbuffer2) - 1, "%Y-%m-%d %H:%M %z", &end_t);

		char *entresname = get_tiername(item->id & 0xFFFF, item->caid, buf);
		if (!entresname[0])
			entresname = get_provider(item->caid, item->provid, buf, sizeof(buf));

		snprintf(tmpbuf, sizeof(tmpbuf) - 1, "%s Type: %s CAID: %04X Provid: %06X ID: %08X%08X Class: %08X StartDate: %s ExpireDate: %s Name: %s",
			item->end > now ? "active " : "expired",
			entitlement_type[item->type],
			item->caid,
			item->provid,
			(uint32_t)(item->id >> 32),
			(uint32_t)(item->id),
			item->class,
			tbuffer1,
			tbuffer2,
			entresname
		);
		monitor_send_details(tmpbuf, cl->tid);
	}
}
Example #22
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++;
	}
}
Example #23
0
struct gbox_card *gbox_cards_iter_next(GBOX_CARDS_ITER *gci)
{
        if (gci) { return ll_iter_next(&gci->it); }
        else { return NULL; }
}
Example #24
0
File: parser.c Project: fwum/fwum
static statement *parse_simple_expression(linked_list *tokens) {
	while(equals_string(((parse_token*)ll_get_first(tokens))->data, "(") && equals_string(((parse_token*)ll_get_last(tokens))->data, ")")) {
		ll_remove_first(tokens);
		ll_remove_last(tokens);
	}
	int size = ll_size(tokens);
	switch(size) {
	case 0:
		return NULL;
	case 1:
		return parse_single_token(tokens);
	default: {
		if(size == 2) {
			parse_token *token = ll_get_first(tokens);
			bool isStack;
	        if((isStack = equals_string(token->data, "new")) || equals_string(token->data, "newref")) {
	            statement *expression = new(expression);
	            expression->children = ll_new();
	            expression->type = isStack ? STACK_INIT : HEAP_INIT;
	            linked_list *name = ll_duplicate(tokens);
	            ll_remove_first(name);
	            ll_add_first(expression->children, parse_simple_expression(name));
	            return expression;
	        }
		}
		int paren_level = 1;
		linked_iter iterator = ll_iter_head(tokens);
		bool is_index = true, is_call = true;
		ll_iter_next(&iterator);
		parse_token *second = ll_iter_next(&iterator);
		if(equals_string(second->data, "(")) {
			is_index = false;
		} else if(equals_string(second->data, "[")) {
			is_call = false;
		} else {
			is_index = is_call = false;
		}
		while((is_index || is_call) && ll_iter_has_next(&iterator)) {
			parse_token *token = ll_iter_next(&iterator);
			if(equals_string(token->data, "(") || equals_string(token->data, "[")) {
				paren_level += 1;
			} else if(paren_level == 0) {
				is_index = false;
				is_call = false;
			} else if(equals_string(token->data, ")") || equals_string(token->data, "]")) {
				paren_level -= 1;
			}
		}
		if(is_index) {
			return parse_array_index(tokens);
		} else if(is_call) {
			return parse_func_call(tokens);
		}
		linked_list *operator = get_node();
		linked_iter level = ll_iter_head(operator);
		while(ll_iter_has_next(&level)) {
			int paren_level = 0;
			linked_list *currentLevel = ll_iter_next(&level);
			linked_iter iterator = ll_iter_head(tokens);
			for(parse_token *current = ll_iter_next(&iterator); ll_iter_has_next(&iterator); current = ll_iter_next(&iterator)) {
				char currentChar = current->data.data[0];
				if(currentChar == '(') {
					paren_level += 1;
				} else if(currentChar == ')') {
					paren_level -= 1;
				}
				if(paren_level != 0) continue;
				linked_iter innerMost = ll_iter_head(currentLevel);
				while(ll_iter_has_next(&innerMost)) {
					operator_node *currentOperator = ll_iter_next(&innerMost);
					if(equals_string(current->data, currentOperator->data)) {
						if(!is_unary_operator(new_slice(currentOperator->data))) {
							linked_list *op1 = ll_duplicate(tokens);
							while(ll_get_last(op1) != current)
								ll_remove_last(op1);
							ll_remove_last(op1);
							linked_list *op2 = tokens;
							while(ll_get_first(op2) != current)
								ll_remove_first(op2);
							ll_remove_first(op2);
							statement *expression = new(expression);
							expression->data = new_slice("");
							expression->children = ll_new();
							expression->type = currentOperator->operatorType;
							statement *op1_exp = parse_simple_expression(op1);
							statement *op2_exp = parse_simple_expression(op2);
							ll_add_last(expression->children, op1_exp);
							ll_add_last(expression->children, op2_exp);
							return expression;
						} else {
							statement *expression = new(expression);
							expression->data = new_slice(currentOperator->data);
							expression->type = currentOperator->operatorType;
							linked_list *rest = ll_duplicate(tokens);
							ll_remove_first(rest);
							expression->children = ll_new();
							ll_add_first(expression->children, parse_simple_expression(rest));
							return expression;
						}
					}
				}
			}
		}
		return NULL;
		}
	}
}