1 /* DVB CI Transport Connection */
3 #include <lib/dvb_ci/dvbci_session.h>
4 #include <lib/dvb_ci/dvbci_resmgr.h>
6 int eDVBCISession::buildLengthField(unsigned char *pkt, int len)
17 } else if (len < 65535)
25 printf("too big length\n");
30 int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len)
38 for (int i=0; i<(pkt[0]&0x7F); ++i)
43 return (pkt[0] & 0x7F) + 1;
46 void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len)
48 unsigned char pkt[len+3+4];
51 l=buildLengthField(pkt+3, len);
53 memcpy(pkt+3+l, data, len);
54 sendSPDU(0x90, 0, 0, pkt, len+3+l);
57 void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen)
59 unsigned char pkt[4096];
60 unsigned char *ptr=pkt;
62 ptr+=buildLengthField(ptr, len+2);
64 memcpy(ptr, data, len);
70 memcpy(ptr, apdu, alen);
73 slot->write(pkt, ptr - pkt);
76 void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb)
79 pkt[0]=session_status;
80 printf("sendOpenSessionResponse\n");
81 memcpy(pkt + 1, resource_identifier, 4);
82 sendSPDU(slot, 0x92, pkt, 5, session_nb);
85 void eDVBCISession::recvCreateSessionResponse(const unsigned char *data)
90 printf("create Session Response, status %x\n", status);
93 void eDVBCISession::recvCloseSessionRequest(const unsigned char *data)
95 state = stateInDeletion;
97 printf("close Session Request\n");
100 eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status)
102 eDVBCISession *session;
104 unsigned short session_nb;
105 for (session_nb=1; session_nb < SLMS; ++session_nb)
106 if (!sessions[session_nb-1])
108 if (session_nb == SLMS)
114 tag = resource_identifier[0] << 24;
115 tag|= resource_identifier[1] << 16;
116 tag|= resource_identifier[2] << 8;
117 tag|= resource_identifier[3];
122 session=new eDVBCIResourceManagerSession;
123 printf("RESOURCE MANAGER\n");
126 // session=eDVBCIModule::getInstance()->application_manager = new eDVBCIApplicationManagerSession;
127 printf("APPLICATION MANAGER\n");
130 // session=eDVBCIModule::getInstance()->ca_manager=new eDVBCICAManagerSession;
131 printf("CA MANAGER\n");
134 // session=new eDVBCIDateTimeSession;
135 printf("DATE-TIME\n");
138 // session=new eDVBCIMMISession;
142 // session=new eDVBCIAuthSession;
143 printf("AuthSession\n");
147 printf("unknown resource type %02x %02x %02x %02x\n", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]);
154 printf("unknown session.. expect crash\n");
157 printf("new session_nb: %d\n", session_nb);
158 session->session_nb = session_nb;
161 printf("session ok, status %02x\n", session->status);
162 status = session->getStatus();
168 sessions[session_nb - 1] = session;
169 session->slot = slot;
171 session->state = stateInCreation;
175 void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len)
177 const unsigned char *pkt = (const unsigned char*)ptr;
178 unsigned char tag = *pkt++;
181 llen = parseLengthField(pkt, hlen);
184 eDVBCISession *session = NULL;
188 unsigned char status;
189 session = createSession(slot, pkt, status);
190 sendOpenSessionResponse(slot, status, pkt, session?session->session_nb:0);
194 session->state=stateStarted;
201 session_nb=pkt[hlen-2]<<8;
202 session_nb|=pkt[hlen-1]&0xFF;
204 if ((!session_nb) || (session_nb >= SLMS))
206 printf("PROTOCOL: illegal session number %x\n", session_nb);
210 session=sessions[session_nb-1];
213 printf("PROTOCOL: data on closed session %x\n", session_nb);
222 session->recvCreateSessionResponse(pkt);
225 printf("recvCloseSessionRequest\n");
226 session->recvCloseSessionRequest(pkt);
229 printf("INTERNAL: nyi, tag %02x.\n", tag);
234 hlen += llen + 1; // lengthfield and tag
236 pkt = ((const unsigned char*)ptr) + hlen;
243 const unsigned char *tag=pkt;
246 hlen=parseLengthField(pkt, alen);
250 //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength)
252 // if (((len-alen) > 0) && ((len - alen) < 3))
254 // printf("WORKAROUND: applying work around MagicAPDULength\n");
258 if (session->receivedAPDU(tag, pkt, alen))
265 printf("PROTOCOL: warning, TL-Data has invalid length\n");