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 DEFINE_REF(eDVBCISession);
12 ePtr<eDVBCISession> eDVBCISession::sessions[SLMS];
14 int eDVBCISession::buildLengthField(unsigned char *pkt, int len)
25 } else if (len < 65535)
33 printf("too big length\n");
38 int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len)
46 for (int i=0; i<(pkt[0]&0x7F); ++i)
51 return (pkt[0] & 0x7F) + 1;
54 void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len)
56 unsigned char pkt[len+3+4];
59 l=buildLengthField(pkt+3, len);
61 memcpy(pkt+3+l, data, len);
62 sendSPDU(0x90, 0, 0, pkt, len+3+l);
65 void eDVBCISession::sendSPDU(unsigned char tag, const void *data, int len, const void *apdu, int alen)
67 sendSPDU(slot, tag, data, len, session_nb, apdu, alen);
70 void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen)
72 unsigned char pkt[4096];
73 unsigned char *ptr=pkt;
75 ptr+=buildLengthField(ptr, len+2);
77 memcpy(ptr, data, len);
83 memcpy(ptr, apdu, alen);
86 slot->send(pkt, ptr - pkt);
89 void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb)
92 pkt[0]=session_status;
93 printf("sendOpenSessionResponse\n");
94 memcpy(pkt + 1, resource_identifier, 4);
95 sendSPDU(slot, 0x92, pkt, 5, session_nb);
98 void eDVBCISession::recvCreateSessionResponse(const unsigned char *data)
101 state = stateStarted;
103 printf("create Session Response, status %x\n", status);
106 void eDVBCISession::recvCloseSessionRequest(const unsigned char *data)
108 state = stateInDeletion;
110 printf("close Session Request\n");
113 void eDVBCISession::deleteSessions(const eDVBCISlot *slot)
115 ePtr<eDVBCISession> ptr;
116 for (unsigned short session_nb=0; session_nb < SLMS; ++session_nb)
118 ptr = sessions[session_nb];
119 if (ptr && ptr->slot == slot)
120 sessions[session_nb]=0;
124 void eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status, ePtr<eDVBCISession> &session)
127 unsigned short session_nb;
129 for (session_nb=1; session_nb < SLMS; ++session_nb)
130 if (!sessions[session_nb-1])
132 if (session_nb == SLMS)
138 tag = resource_identifier[0] << 24;
139 tag|= resource_identifier[1] << 16;
140 tag|= resource_identifier[2] << 8;
141 tag|= resource_identifier[3];
146 session=new eDVBCIResourceManagerSession;
147 printf("RESOURCE MANAGER\n");
150 session=new eDVBCIApplicationManagerSession(slot);
151 printf("APPLICATION MANAGER\n");
154 session = new eDVBCICAManagerSession(slot);
155 printf("CA MANAGER\n");
158 session=new eDVBCIDateTimeSession;
159 printf("DATE-TIME\n");
162 session = new eDVBCIMMISession(slot);
163 printf("MMI - create session\n");
166 // session=new eDVBCIAuthSession;
167 printf("AuthSession\n");
171 printf("unknown resource type %02x %02x %02x %02x\n", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]);
178 printf("unknown session.. expect crash\n");
182 printf("new session nb %d %p\n", session_nb, &(*session));
183 session->session_nb = session_nb;
187 sessions[session_nb - 1] = session;
188 session->slot = slot;
191 session->state = stateInCreation;
194 void eDVBCISession::handleClose()
196 unsigned char data[1]={0x00};
197 sendSPDU(0x96, data, 1, 0, 0);
200 int eDVBCISession::pollAll()
202 for (int session_nb=1; session_nb < SLMS; ++session_nb)
203 if (sessions[session_nb-1])
207 if (sessions[session_nb-1]->state == stateInDeletion)
209 sessions[session_nb-1]->handleClose();
210 sessions[session_nb-1]=0;
213 r=sessions[session_nb-1]->poll();
221 void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len)
223 const unsigned char *pkt = (const unsigned char*)ptr;
224 unsigned char tag = *pkt++;
227 printf("slot: %p\n",slot);
229 for(unsigned int i=0;i<len;i++)
230 printf("%02x ",ptr[i]);
233 llen = parseLengthField(pkt, hlen);
236 ePtr<eDVBCISession> session;
240 unsigned char status;
241 createSession(slot, pkt, status, session);
242 sendOpenSessionResponse(slot, status, pkt, session?session->session_nb:0);
246 session->state=stateStarted;
253 session_nb=pkt[hlen-2]<<8;
254 session_nb|=pkt[hlen-1]&0xFF;
256 if ((!session_nb) || (session_nb >= SLMS))
258 printf("PROTOCOL: illegal session number %x\n", session_nb);
262 session=sessions[session_nb-1];
265 printf("PROTOCOL: data on closed session %x\n", session_nb);
274 session->recvCreateSessionResponse(pkt);
277 printf("recvCloseSessionRequest\n");
278 session->recvCloseSessionRequest(pkt);
281 printf("INTERNAL: nyi, tag %02x.\n", tag);
286 hlen += llen + 1; // lengthfield and tag
288 pkt = ((const unsigned char*)ptr) + hlen;
295 const unsigned char *tag=pkt;
298 hlen=parseLengthField(pkt, alen);
302 //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength)
304 if (((len-alen) > 0) && ((len - alen) < 3))
306 printf("WORKAROUND: applying work around MagicAPDULength\n");
310 if (session->receivedAPDU(tag, pkt, alen))
317 printf("PROTOCOL: warning, TL-Data has invalid length\n");
320 eDVBCISession::~eDVBCISession()
322 printf("destroy %p\n", this);