1 /* DVB CI Transport Connection */
3 #include <lib/dvb_ci/dvbci_session.h>
4 #include <lib/dvb_ci/dvbci_resmgr.h>
5 #include <lib/dvb_ci/dvbci_appmgr.h>
6 #include <lib/dvb_ci/dvbci_camgr.h>
8 int eDVBCISession::buildLengthField(unsigned char *pkt, int len)
19 } else if (len < 65535)
27 printf("too big length\n");
32 int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len)
40 for (int i=0; i<(pkt[0]&0x7F); ++i)
45 return (pkt[0] & 0x7F) + 1;
48 void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len)
50 unsigned char pkt[len+3+4];
53 l=buildLengthField(pkt+3, len);
55 memcpy(pkt+3+l, data, len);
56 sendSPDU(0x90, 0, 0, pkt, len+3+l);
59 void eDVBCISession::sendSPDU(unsigned char tag, const void *data, int len, const void *apdu, int alen)
61 sendSPDU(slot, tag, data, len, session_nb, apdu, alen);
64 void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen)
66 unsigned char pkt[4096];
67 unsigned char *ptr=pkt;
69 ptr+=buildLengthField(ptr, len+2);
71 memcpy(ptr, data, len);
77 memcpy(ptr, apdu, alen);
80 slot->write(pkt, ptr - pkt);
83 void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb)
86 pkt[0]=session_status;
87 printf("sendOpenSessionResponse\n");
88 memcpy(pkt + 1, resource_identifier, 4);
89 sendSPDU(slot, 0x92, pkt, 5, session_nb);
92 void eDVBCISession::recvCreateSessionResponse(const unsigned char *data)
97 printf("create Session Response, status %x\n", status);
100 void eDVBCISession::recvCloseSessionRequest(const unsigned char *data)
102 state = stateInDeletion;
104 printf("close Session Request\n");
107 eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status)
109 eDVBCISession *session;
111 unsigned short session_nb;
112 for (session_nb=1; session_nb < SLMS; ++session_nb)
113 if (!sessions[session_nb-1])
115 if (session_nb == SLMS)
121 tag = resource_identifier[0] << 24;
122 tag|= resource_identifier[1] << 16;
123 tag|= resource_identifier[2] << 8;
124 tag|= resource_identifier[3];
129 session=new eDVBCIResourceManagerSession;
130 printf("RESOURCE MANAGER\n");
133 session=slot->application_manager = new eDVBCIApplicationManagerSession;
134 printf("APPLICATION MANAGER\n");
137 session=slot->ca_manager=new eDVBCICAManagerSession;
138 printf("CA MANAGER\n");
141 // session=new eDVBCIDateTimeSession;
142 printf("DATE-TIME\n");
145 // session=new eDVBCIMMISession;
149 // session=new eDVBCIAuthSession;
150 printf("AuthSession\n");
154 printf("unknown resource type %02x %02x %02x %02x\n", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]);
161 printf("unknown session.. expect crash\n");
164 printf("new session_nb: %d\n", session_nb);
165 session->session_nb = session_nb;
168 printf("session ok, status %02x\n", session->status);
169 status = session->getStatus();
175 sessions[session_nb - 1] = session;
176 session->slot = slot;
178 session->state = stateInCreation;
182 void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len)
184 const unsigned char *pkt = (const unsigned char*)ptr;
185 unsigned char tag = *pkt++;
188 llen = parseLengthField(pkt, hlen);
191 eDVBCISession *session = NULL;
195 unsigned char status;
196 session = createSession(slot, pkt, status);
197 sendOpenSessionResponse(slot, status, pkt, session?session->session_nb:0);
201 session->state=stateStarted;
208 session_nb=pkt[hlen-2]<<8;
209 session_nb|=pkt[hlen-1]&0xFF;
211 if ((!session_nb) || (session_nb >= SLMS))
213 printf("PROTOCOL: illegal session number %x\n", session_nb);
217 session=sessions[session_nb-1];
220 printf("PROTOCOL: data on closed session %x\n", session_nb);
229 session->recvCreateSessionResponse(pkt);
232 printf("recvCloseSessionRequest\n");
233 session->recvCloseSessionRequest(pkt);
236 printf("INTERNAL: nyi, tag %02x.\n", tag);
241 hlen += llen + 1; // lengthfield and tag
243 pkt = ((const unsigned char*)ptr) + hlen;
250 const unsigned char *tag=pkt;
253 hlen=parseLengthField(pkt, alen);
257 //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength)
259 // if (((len-alen) > 0) && ((len - alen) < 3))
261 // printf("WORKAROUND: applying work around MagicAPDULength\n");
265 if (session->receivedAPDU(tag, pkt, alen))
272 printf("PROTOCOL: warning, TL-Data has invalid length\n");