Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
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);
			}
		}
	}
}