// 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; }
// 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; }
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; }
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; }