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>
7 #include <lib/dvb_ci/dvbci_datetimemgr.h>
8 #include <lib/dvb_ci/dvbci_mmi.h>
10 eDVBCISession *eDVBCISession::sessions[SLMS];
12 int eDVBCISession::buildLengthField(unsigned char *pkt, int len)
23 } else if (len < 65535)
31 printf("too big length\n");
36 int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len)
44 for (int i=0; i<(pkt[0]&0x7F); ++i)
49 return (pkt[0] & 0x7F) + 1;
52 void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len)
54 unsigned char pkt[len+3+4];
57 l=buildLengthField(pkt+3, len);
59 memcpy(pkt+3+l, data, len);
60 sendSPDU(0x90, 0, 0, pkt, len+3+l);
63 void eDVBCISession::sendSPDU(unsigned char tag, const void *data, int len, const void *apdu, int alen)
65 sendSPDU(slot, tag, data, len, session_nb, apdu, alen);
68 void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen)
70 unsigned char pkt[4096];
71 unsigned char *ptr=pkt;
73 ptr+=buildLengthField(ptr, len+2);
75 memcpy(ptr, data, len);
81 memcpy(ptr, apdu, alen);
84 slot->send(pkt, ptr - pkt);
87 void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb)
90 pkt[0]=session_status;
91 printf("sendOpenSessionResponse\n");
92 memcpy(pkt + 1, resource_identifier, 4);
93 sendSPDU(slot, 0x92, pkt, 5, session_nb);
96 void eDVBCISession::recvCreateSessionResponse(const unsigned char *data)
101 printf("create Session Response, status %x\n", status);
104 void eDVBCISession::recvCloseSessionRequest(const unsigned char *data)
106 state = stateInDeletion;
108 printf("close Session Request\n");
111 eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status)
113 eDVBCISession *session;
115 unsigned short session_nb;
117 for (session_nb=1; session_nb < SLMS; ++session_nb)
118 if (!sessions[session_nb-1])
120 if (session_nb == SLMS)
126 tag = resource_identifier[0] << 24;
127 tag|= resource_identifier[1] << 16;
128 tag|= resource_identifier[2] << 8;
129 tag|= resource_identifier[3];
134 session=new eDVBCIResourceManagerSession;
135 printf("RESOURCE MANAGER\n");
136 printf("session: %p\n",session);
139 session=new eDVBCIApplicationManagerSession(slot);
140 printf("APPLICATION MANAGER\n");
143 session = new eDVBCICAManagerSession(slot);
144 printf("CA MANAGER\n");
147 session=new eDVBCIDateTimeSession;
148 printf("DATE-TIME\n");
151 session = new eDVBCIMMISession(slot);
152 printf("MMI - create session\n");
155 // session=new eDVBCIAuthSession;
156 printf("AuthSession\n");
160 printf("unknown resource type %02x %02x %02x %02x\n", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]);
167 printf("unknown session.. expect crash\n");
170 printf("new session_nb: %d\n", session_nb);
171 session->session_nb = session_nb;
175 sessions[session_nb - 1] = session;
176 session->slot = slot;
179 session->state = stateInCreation;
184 void eDVBCISession::handleClose()
186 unsigned char data[1]={0x00};
187 sendSPDU(0x96, data, 1, 0, 0);
190 int eDVBCISession::pollAll()
192 for (int session_nb=1; session_nb < SLMS; ++session_nb)
193 if (sessions[session_nb-1])
197 if (sessions[session_nb-1]->state == stateInDeletion)
199 sessions[session_nb-1]->handleClose();
200 delete sessions[session_nb-1];
201 sessions[session_nb-1]=0;
204 r=sessions[session_nb-1]->poll();
212 void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len)
214 const unsigned char *pkt = (const unsigned char*)ptr;
215 unsigned char tag = *pkt++;
218 printf("slot: %p\n",slot);
223 printf("%02x ",ptr[i]);
226 llen = parseLengthField(pkt, hlen);
229 eDVBCISession *session = NULL;
233 unsigned char status;
234 session = createSession(slot, pkt, status);
235 sendOpenSessionResponse(slot, status, pkt, session?session->session_nb:0);
239 session->state=stateStarted;
246 session_nb=pkt[hlen-2]<<8;
247 session_nb|=pkt[hlen-1]&0xFF;
249 if ((!session_nb) || (session_nb >= SLMS))
251 printf("PROTOCOL: illegal session number %x\n", session_nb);
255 session=sessions[session_nb-1];
258 printf("PROTOCOL: data on closed session %x\n", session_nb);
267 session->recvCreateSessionResponse(pkt);
270 printf("recvCloseSessionRequest\n");
271 session->recvCloseSessionRequest(pkt);
274 printf("INTERNAL: nyi, tag %02x.\n", tag);
279 hlen += llen + 1; // lengthfield and tag
281 pkt = ((const unsigned char*)ptr) + hlen;
288 const unsigned char *tag=pkt;
291 hlen=parseLengthField(pkt, alen);
295 //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength)
297 if (((len-alen) > 0) && ((len - alen) < 3))
299 printf("WORKAROUND: applying work around MagicAPDULength\n");
303 if (session->receivedAPDU(tag, pkt, alen))
310 printf("PROTOCOL: warning, TL-Data has invalid length\n");
313 eDVBCISession::~eDVBCISession()