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>
9 int eDVBCISession::buildLengthField(unsigned char *pkt, int len)
20 } else if (len < 65535)
28 printf("too big length\n");
33 int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len)
41 for (int i=0; i<(pkt[0]&0x7F); ++i)
46 return (pkt[0] & 0x7F) + 1;
49 void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len)
51 unsigned char pkt[len+3+4];
54 l=buildLengthField(pkt+3, len);
56 memcpy(pkt+3+l, data, len);
57 sendSPDU(0x90, 0, 0, pkt, len+3+l);
60 void eDVBCISession::sendSPDU(unsigned char tag, const void *data, int len, const void *apdu, int alen)
62 sendSPDU(slot, tag, data, len, session_nb, apdu, alen);
65 void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen)
67 unsigned char pkt[4096];
68 unsigned char *ptr=pkt;
70 ptr+=buildLengthField(ptr, len+2);
72 memcpy(ptr, data, len);
78 memcpy(ptr, apdu, alen);
81 slot->write(pkt, ptr - pkt);
84 void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb)
87 pkt[0]=session_status;
88 printf("sendOpenSessionResponse\n");
89 memcpy(pkt + 1, resource_identifier, 4);
90 sendSPDU(slot, 0x92, pkt, 5, session_nb);
93 void eDVBCISession::recvCreateSessionResponse(const unsigned char *data)
98 printf("create Session Response, status %x\n", status);
101 void eDVBCISession::recvCloseSessionRequest(const unsigned char *data)
103 state = stateInDeletion;
105 printf("close Session Request\n");
108 eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status)
110 eDVBCISession *session;
112 unsigned short session_nb;
113 for (session_nb=1; session_nb < SLMS; ++session_nb)
114 if (!sessions[session_nb-1])
116 if (session_nb == SLMS)
122 tag = resource_identifier[0] << 24;
123 tag|= resource_identifier[1] << 16;
124 tag|= resource_identifier[2] << 8;
125 tag|= resource_identifier[3];
130 session=new eDVBCIResourceManagerSession;
131 printf("RESOURCE MANAGER\n");
134 session=slot->application_manager = new eDVBCIApplicationManagerSession;
135 printf("APPLICATION MANAGER\n");
138 session=slot->ca_manager=new eDVBCICAManagerSession;
139 printf("CA MANAGER\n");
142 session=new eDVBCIDateTimeSession;
143 printf("DATE-TIME\n");
146 // session=new eDVBCIMMISession;
150 // session=new eDVBCIAuthSession;
151 printf("AuthSession\n");
155 printf("unknown resource type %02x %02x %02x %02x\n", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]);
162 printf("unknown session.. expect crash\n");
165 printf("new session_nb: %d\n", session_nb);
166 session->session_nb = session_nb;
169 printf("session ok, status %02x\n", session->status);
170 status = session->getStatus();
176 sessions[session_nb - 1] = session;
177 session->slot = slot;
179 session->state = stateInCreation;
183 void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len)
185 const unsigned char *pkt = (const unsigned char*)ptr;
186 unsigned char tag = *pkt++;
189 llen = parseLengthField(pkt, hlen);
192 eDVBCISession *session = NULL;
196 unsigned char status;
197 session = createSession(slot, pkt, status);
198 sendOpenSessionResponse(slot, status, pkt, session?session->session_nb:0);
202 session->state=stateStarted;
209 session_nb=pkt[hlen-2]<<8;
210 session_nb|=pkt[hlen-1]&0xFF;
212 if ((!session_nb) || (session_nb >= SLMS))
214 printf("PROTOCOL: illegal session number %x\n", session_nb);
218 session=sessions[session_nb-1];
221 printf("PROTOCOL: data on closed session %x\n", session_nb);
230 session->recvCreateSessionResponse(pkt);
233 printf("recvCloseSessionRequest\n");
234 session->recvCloseSessionRequest(pkt);
237 printf("INTERNAL: nyi, tag %02x.\n", tag);
242 hlen += llen + 1; // lengthfield and tag
244 pkt = ((const unsigned char*)ptr) + hlen;
251 const unsigned char *tag=pkt;
254 hlen=parseLengthField(pkt, alen);
258 //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength)
260 // if (((len-alen) > 0) && ((len - alen) < 3))
262 // printf("WORKAROUND: applying work around MagicAPDULength\n");
266 if (session->receivedAPDU(tag, pkt, alen))
273 printf("PROTOCOL: warning, TL-Data has invalid length\n");