Exemple #1
0
// tx_cmds() - send all commands out to the network.
void tx_cmds() {
  // local variable instantiation
  packet tx_packet;
  volatile uint8_t local_tx_cmd_queue_size;
  volatile uint8_t tx_length = 0;
  volatile int8_t val = 0;

  // atomically get the queue size
  local_tx_cmd_queue_size = atomic_size(&g_cmd_tx_queue, g_cmd_tx_queue_mux);

  // print out task header
  if((TRUE == g_verbose) && (0 < local_tx_cmd_queue_size)) {
    nrk_kprintf(PSTR("tx_cmds...\r\n"));
  }

  // loop on queue size received above, and no more.
  for(uint8_t i = 0; i < local_tx_cmd_queue_size; i++) {
    nrk_led_set(ORANGE_LED);
    // get a packet out of the queue.
    atomic_pop(&g_cmd_tx_queue, &tx_packet, g_cmd_tx_queue_mux);

    // assemble the packet and senx
    tx_length = assemble_packet((uint8_t *)&g_net_tx_buf, &tx_packet);
    val = bmac_tx_pkt(g_net_tx_buf, tx_length);
    if(NRK_OK != val){
      nrk_kprintf( PSTR( "NO ack or Reserve Violated!\r\n" ));
    }

    nrk_led_clr(ORANGE_LED);
  }
  return;
}
Exemple #2
0
// tx_data_task() - send standard messages out to the network (i.e. handshake messages, etc.)
void tx_data() {
  // local variable initialization
  packet tx_packet;
  volatile int8_t val = 0;
  volatile uint8_t sent_heart = FALSE;
  volatile uint8_t to_send;
  volatile uint8_t tx_length = 0;
  volatile uint8_t local_tx_data_queue_size;
  volatile msg_type tx_type;

  // atomically get the queue size
  local_tx_data_queue_size = atomic_size(&g_data_tx_queue, g_data_tx_queue_mux);

  // print out task header
  if((TRUE == g_verbose) && (0 < local_tx_data_queue_size)){
    nrk_kprintf(PSTR("tx_data...\r\n"));
  }

  // loop on queue size received above, and no more.
  for(uint8_t i = 0; i < local_tx_data_queue_size; i++) {
    nrk_led_set(ORANGE_LED);
    // get a packet out of the queue.
    atomic_pop(&g_data_tx_queue, &tx_packet, g_data_tx_queue_mux);

    // get packet parameters
    tx_type = tx_packet.type;

    // only hop one heartbeat per iteration.
    if(((MSG_HEARTBEAT == tx_type) || (MSG_RESET == tx_type)) && (TRUE == sent_heart)) {
      to_send = FALSE;
    } else {
      to_send = TRUE;
    }

    if (TRUE == to_send) {
      // assembe and send packet
      tx_length = assemble_packet((uint8_t *)&g_net_tx_buf, &tx_packet);
      val = bmac_tx_pkt(g_net_tx_buf, tx_length);
      if(NRK_OK != val){
        nrk_kprintf( PSTR( "NO ack or Reserve Violated!\r\n" ));
      }
      // set flag
      if(MSG_HEARTBEAT == tx_type){
        sent_heart = TRUE;
      }
    }
    nrk_led_clr(ORANGE_LED);
  }

  return;
}
Exemple #3
0
int process_pmt(adapter *ad, unsigned char *b)
{
	int pi_len = 0, ver, pmt_len = 0, i, _pid, es_len, len, init_pi_len;
	int program_id = 0;
	int prio = 0;
	int enabled_channels = 0;
	unsigned char *pmt, *pi, tmp_pi[MAX_PI_LEN];
	unsigned char *init_b = b;
	int caid, capid, pid, spid, stype;
	uint16_t pid_list[MAX_PIDS];
	int npl = 0;
	SPid *p, *cp;
	int64_t pid_key = TABLES_ITEM + ((1 + ad->id) << 24) + 0;
	int16_t *pids;
	int opmt, old_key;

	if ((b[0] != 0x47)) // make sure we are dealing with TS
		return 0;

	if ((b[1] & 0x40) && ((b[4] != 0) || (b[5] != 2)))
		return 0;

	pid = (b[1] & 0x1F) * 256 + b[2];
	if (!(p = find_pid(ad->id, pid)))
		return -1;

	if (!p || (p->type & PMT_COMPLETE) || (p->type == 0))
		return 0;

	program_id = b[8] * 256 + b[9];
	ver = b[10] & 0x3F;

	if (((p->type & 0xF) != TYPE_PMT) && p->version == ver
			&& p->csid == program_id) // pmt processed already
		return 0;

	if (!(pmt_len = assemble_packet(&b, ad, 1)))
		return 0;

	pi_len = ((b[10] & 0xF) << 8) + b[11];

	program_id = p->csid = b[3] * 256 + b[4];
	ver = p->version = b[5] & 0x3F;

	LOG("PMT pid: %04X (%d), pmt_len %d, pi_len %d, sid %04X (%d)", pid, pid,
			pmt_len, pi_len, program_id, program_id);
	pi = b + 12;
	pmt = pi + pi_len;

	if (pmt_len > 1500)
		return 0;

	if (pi_len > pmt_len)
		pi_len = 0;

	init_pi_len = pi_len;
	pi_len = 0;

	if (init_pi_len > 0)
		find_pi(pi, init_pi_len, tmp_pi, &pi_len);

	pi = tmp_pi;

	es_len = 0;
	pids = (int16_t *) getItem(pid_key);
	if (!pids)
		return 0;

	p->type |= TYPE_PMT;
	pids[pid] = -TYPE_PMT;

	for (i = 0; i < pmt_len - init_pi_len - 17; i += (es_len) + 5) // reading streams
	{
		es_len = (pmt[i + 3] & 0xF) * 256 + pmt[i + 4];
		stype = pmt[i];
		spid = (pmt[i + 1] & 0x1F) * 256 + pmt[i + 2];
		LOG(
				"PMT pid %d - stream pid %04X (%d), type %d, es_len %d, pos %d, pi_len %d old pmt %d, old pmt for this pid %d",
				pid, spid, spid, stype, es_len, i, pi_len, pids[pid],
				pids[spid]);
		if ((es_len + i > pmt_len) || (init_pi_len + es_len == 0))
			break;
		if (stype != 2 && stype != 3 && stype != 4 && stype != 6 && stype != 27
				&& stype != 36 || spid < 64)
			continue;

		find_pi(pmt + i + 5, es_len, pi, &pi_len);

		if (pi_len == 0)
			continue;

		opmt = pids[spid];
		pids[spid] = pid;
		if ((opmt > 0) && (abs(opmt) != abs(pid))) // this pid is associated with another PMT - link this PMT with the old one (if not linked already)
		{
			if (pids[pid] == -TYPE_PMT)
			{
				pids[pid] = -opmt;
				LOG("Linking PMT pid %d with PMT pid %d for pid %d, adapter %d",
						pid, opmt, spid, ad->id);
			}
		}

		if ((cp = find_pid(ad->id, spid))) // the pid is already requested by the client
		{
			enabled_channels++;
			pid_list[npl++] = spid;
			old_key = cp->key;
		}

	}

	if ((pi_len > 0) && enabled_channels) // PMT contains CA descriptor and there are active pids
	{
		SPMT pmt =
		{ .pmt = b, .pmt_len = pmt_len, .pi = pi, .pi_len = pi_len, .p = p,
				.sid = program_id, .ver = ver, .pid = pid, .old_key = old_key };
		p->enabled_channels = enabled_channels;

		if (program_id > 0)
			run_ca_action(CA_ADD_PMT, ad, &pmt);
		else
			LOG("PMT %d, SID is 0, not running ca_action", pid);

		for (i = 0; i < npl; i++)
		{
			cp = find_pid(ad->id, pid_list[i]);
			if (cp)
				cp->key = p->key;
		}
		p->type |= PMT_COMPLETE;
	}
Exemple #4
0
int process_pat(adapter *ad, unsigned char *b)
{
	int pat_len = 0, i, tid = 0, sid, pid, ver, csid = 0;
	int64_t pid_key = TABLES_ITEM + ((1 + ad->id) << 24) + 0;
	int16_t *pids;
	unsigned char *init_b = b;
	SPid *p;

	if (((b[1] & 0x1F) != 0) || (b[2] != 0))
		return 0;

	if (b[0] != 0x47)
		return 0;

	if ((b[1] & 0x40) && ((b[4] != 0) || (b[5] != 0)))
		return 0;

//	p = find_pid(ad->id, 0);
//	if(!p)
//		return 0;

	tid = b[8] * 256 + b[9];
	ver = b[10] & 0x3E;

	if ((ad->transponder_id == tid) && (ad->pat_ver == ver)) //pat already processed
		return 0;

	if (!(pat_len = assemble_packet(&b, ad, 1)))
		return 0;

	tid = b[3] * 256 + b[4];
	ver = b[5] & 0x3E;
	if (((ad->transponder_id != tid) || (ad->pat_ver != ver)) && (pat_len > 0)
			&& (pat_len < 1500))
	{
		ad->pat_processed = 0;
	}

	if (ad->pat_processed)
		return 0;

	ad->pat_ver = ver;
	ad->transponder_id = tid;
#ifndef DISABLE_DVBAPI
	dvbapi_delete_keys_for_adapter(ad->id);
#endif
//	LOG("tid %d pat_len %d: %02X %02X %02X %02X %02X %02X %02X %02X", tid, pat_len, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7]);
	setItem(pid_key, b, 1, 0);
	setItemSize(pid_key, 8192 * sizeof(*pids));
	pids = (int16_t *) getItem(pid_key);
	memset(pids, 0, 8192 * sizeof(*pids));
	pat_len -= 9;
	b += 8;
	LOGL(2, "PAT Adapter %d, Transponder ID %d, len %d, version %d", ad->id,
			tid, pat_len, ad->pat_ver);
	if (pat_len > 1500)
		return 0;

	for (i = 0; i < pat_len; i += 4)
	{
		sid = b[i] * 256 + b[i + 1];
		pid = (b[i + 2] & 0x1F) * 256 + b[i + 3];
		LOGL(2, "Adapter %d, PMT sid %d (%04X), pid %d", ad->id, sid, sid, pid);
		if (sid > 0)
		{
			pids[pid] = -TYPE_PMT;
			p = find_pid(ad->id, pid);
			if (!p)
				mark_pid_add(-1, ad->id, pid);
			if ((p = find_pid(ad->id, pid)))
			{
				p->type = TYPE_PMT;
				csid = pid;
				if (p->flags == 3)
					p->flags = 1;
			}
		}
	}
	update_pids(ad->id);
	ad->pat_processed = 1;
	return csid;
}