static int ca_set_pmt(struct dst_state *state, struct ca_msg *p_ca_message, struct ca_msg *hw_buffer, u8 reply, u8 query) { u32 length = 0; u8 tag_length = 8; length = asn_1_decode(&p_ca_message->msg[3]); dprintk(verbose, DST_CA_DEBUG, 1, " CA Message length=[%d]", length); debug_string(&p_ca_message->msg[4], length, 0); /* length is excluding tag & length */ memset(hw_buffer->msg, '\0', length); handle_dst_tag(state, p_ca_message, hw_buffer, length); put_checksum(hw_buffer->msg, hw_buffer->msg[0]); debug_string(hw_buffer->msg, (length + tag_length), 0); /* tags too */ write_to_8820(state, hw_buffer, (length + tag_length), reply); return 0; }
void cDvbCi::slot_pollthread(void *c) { ca_slot_info_t info; unsigned char data[1024]; tSlot* slot = (tSlot*) c; while (1) { int len = 1024; unsigned char* d; eData status; switch (slot->status) { case eStatusNone: { if (slot->camIsReady) { if (sendCreateTC(slot)) { slot->status = eStatusWait; slot->camIsReady = true; } else { usleep(100000); } } else { /* wait for pollpri */ status = waitData(slot->fd, data, &len); if (status == eDataStatusChanged) { info.num = slot->slot; if (ioctl(slot->fd, CA_GET_SLOT_INFO, &info) < 0) printf("IOCTL CA_GET_SLOT_INFO failed for slot %d\n", slot->slot); //printf("flags %d %d %d ->slot %d\n", info.flags, CA_CI_MODULE_READY, info.flags & CA_CI_MODULE_READY, slot->slot); if (info.flags & CA_CI_MODULE_READY) { printf("1. cam (%d) status changed ->cam now present\n", slot->slot); slot->mmiSession = NULL; slot->hasMMIManager = false; slot->hasCAManager = false; slot->hasDateTime = false; slot->hasAppManager = false; slot->mmiOpened = false; slot->init = false; sprintf(slot->name, "unknown module %d", slot->slot); slot->status = eStatusNone; if (g_RCInput) g_RCInput->postMsg(NeutrinoMessages::EVT_CI_INSERTED, slot->slot); slot->camIsReady = true; //setSource(slot); } else { //noop } } } } /* case statusnone */ break; case eStatusWait: { status = waitData(slot->fd, data, &len); if (status == eDataReady) { //int s_id = data[0]; //int c_id = data[1]; slot->pollConnection = false; //printf("%d: s_id = %d, c_id = %d\n", slot->slot, s_id, c_id); d = data; /* taken from the dvb-apps */ int data_length = len - 2; d += 2; /* remove leading slot and connection id */ while (data_length > 0) { unsigned char tpdu_tag = d[0]; unsigned short asn_data_length; int length_field_len; if ((length_field_len = asn_1_decode(&asn_data_length, d + 1, data_length - 1)) < 0) { printf("Received data with invalid asn from module on slot %02x\n", slot->slot); break; } if ((asn_data_length < 1) || (asn_data_length > (data_length - (1 + length_field_len)))) { printf("Received data with invalid length from module on slot %02x\n", slot->slot); break; } slot->connection_id = d[1 + length_field_len]; //printf("Setting connection_id from received data to %d\n", slot->connection_id); d += 1 + length_field_len + 1; data_length -= (1 + length_field_len + 1); asn_data_length--; process_tpdu(slot, tpdu_tag, d, asn_data_length, slot->connection_id); // skip over the consumed data d += asn_data_length; data_length -= asn_data_length; } // while (data_length) } /* data ready */ else if (status == eDataWrite) { if (!slot->sendqueue.empty()) { const queueData &qe = slot->sendqueue.top(); int res = write(slot->fd, qe.data, qe.len); if (res >= 0 && (unsigned int)res == qe.len) { delete [] qe.data; slot->sendqueue.pop(); } else { printf("r = %d, %m\n", res); } } else { //printf("sendqueue emtpy\n"); if ((checkQueueSize(slot) == false) && ((!slot->hasCAManager) || (slot->mmiOpened))) slot->pollConnection = true; } } else if (status == eDataStatusChanged) { info.num = slot->slot; if (ioctl(slot->fd, CA_GET_SLOT_INFO, &info) < 0) printf("IOCTL CA_GET_SLOT_INFO failed for slot %d\n", slot->slot); printf("flags %d %d %d ->slot %d\n", info.flags, CA_CI_MODULE_READY, info.flags & CA_CI_MODULE_READY, slot->slot); if ((slot->camIsReady == false) && (info.flags & CA_CI_MODULE_READY)) { printf("2. cam (%d) status changed ->cam now present\n", slot->slot); slot->mmiSession = NULL; slot->hasMMIManager = false; slot->hasCAManager = false; slot->hasDateTime = false; slot->hasAppManager = false; slot->mmiOpened = false; slot->init = false; sprintf(slot->name, "unknown module %d", slot->slot); slot->status = eStatusNone; if (g_RCInput) g_RCInput->postMsg(NeutrinoMessages::EVT_CI_INSERTED, slot->slot); slot->camIsReady = true; } else if ((slot->camIsReady == true) && (!(info.flags & CA_CI_MODULE_READY))) { printf("cam (%d) status changed ->cam now _not_ present\n", slot->slot); eDVBCISession::deleteSessions(slot); slot->mmiSession = NULL; slot->hasMMIManager = false; slot->hasCAManager = false; slot->hasDateTime = false; slot->hasAppManager = false; slot->mmiOpened = false; slot->init = false; sprintf(slot->name, "unknown module %d", slot->slot); slot->status = eStatusNone; if (g_RCInput) g_RCInput->postMsg(NeutrinoMessages::EVT_CI_REMOVED, slot->slot); while(slot->sendqueue.size()) { delete [] slot->sendqueue.top().data; slot->sendqueue.pop(); } slot->camIsReady = false; usleep(100000); } } if (!checkQueueSize(slot) && slot->pollConnection) { //printf("poll\n"); sendData(slot, NULL, 0); } } break; default: printf("unknown state %d\n", slot->status); break; } if (slot->hasCAManager && slot->hasAppManager && !slot->init) //declare this as init, but remeber we are still not complete! { slot->init = true; if (g_RCInput) g_RCInput->postMsg(NeutrinoMessages::EVT_CI_INIT_OK, slot->slot); //resend a capmt if we have one. this is not very proper but I cant any mechanism in //neutrino currently. so if a cam is inserted a pmt is not resend if (slot->caPmt != NULL) { SendCaPMT(slot->caPmt, slot->source); } } } }