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 int eDVBCISession::buildLengthField(unsigned char *pkt, int len)
21 } else if (len < 65535)
29 printf("too big length\n");
34 int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len)
42 for (int i=0; i<(pkt[0]&0x7F); ++i)
47 return (pkt[0] & 0x7F) + 1;
50 void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len)
52 unsigned char pkt[len+3+4];
55 l=buildLengthField(pkt+3, len);
57 memcpy(pkt+3+l, data, len);
58 sendSPDU(0x90, 0, 0, pkt, len+3+l);
61 void eDVBCISession::sendSPDU(unsigned char tag, const void *data, int len, const void *apdu, int alen)
63 sendSPDU(slot, tag, data, len, session_nb, apdu, alen);
66 void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen)
68 unsigned char pkt[4096];
69 unsigned char *ptr=pkt;
71 ptr+=buildLengthField(ptr, len+2);
73 memcpy(ptr, data, len);
79 memcpy(ptr, apdu, alen);
82 slot->write(pkt, ptr - pkt);
85 void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb)
88 pkt[0]=session_status;
89 printf("sendOpenSessionResponse\n");
90 memcpy(pkt + 1, resource_identifier, 4);
91 sendSPDU(slot, 0x92, pkt, 5, session_nb);
94 void eDVBCISession::recvCreateSessionResponse(const unsigned char *data)
99 printf("create Session Response, status %x\n", status);
102 void eDVBCISession::recvCloseSessionRequest(const unsigned char *data)
104 state = stateInDeletion;
106 printf("close Session Request\n");
109 eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status)
111 eDVBCISession *session;
113 unsigned short session_nb;
114 for (session_nb=1; session_nb < SLMS; ++session_nb)
115 if (!sessions[session_nb-1])
117 if (session_nb == SLMS)
123 tag = resource_identifier[0] << 24;
124 tag|= resource_identifier[1] << 16;
125 tag|= resource_identifier[2] << 8;
126 tag|= resource_identifier[3];
131 session=new eDVBCIResourceManagerSession;
132 printf("RESOURCE MANAGER\n");
135 session=slot->application_manager = new eDVBCIApplicationManagerSession;
136 printf("APPLICATION MANAGER\n");
139 session=slot->ca_manager=new eDVBCICAManagerSession;
140 printf("CA MANAGER\n");
143 session=new eDVBCIDateTimeSession;
144 printf("DATE-TIME\n");
147 session=new eDVBCIMMISession;
151 // session=new eDVBCIAuthSession;
152 printf("AuthSession\n");
156 printf("unknown resource type %02x %02x %02x %02x\n", resource_identifier[0], resource_identifier[1], resource_identifier[2],resource_identifier[3]);
163 printf("unknown session.. expect crash\n");
166 printf("new session_nb: %d\n", session_nb);
167 session->session_nb = session_nb;
170 printf("session ok, status %02x\n", session->status);
171 status = session->getStatus();
177 sessions[session_nb - 1] = session;
178 session->slot = slot;
180 session->state = stateInCreation;
184 void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len)
186 const unsigned char *pkt = (const unsigned char*)ptr;
187 unsigned char tag = *pkt++;
190 llen = parseLengthField(pkt, hlen);
193 eDVBCISession *session = NULL;
197 unsigned char status;
198 session = createSession(slot, pkt, status);
199 sendOpenSessionResponse(slot, status, pkt, session?session->session_nb:0);
203 session->state=stateStarted;
210 session_nb=pkt[hlen-2]<<8;
211 session_nb|=pkt[hlen-1]&0xFF;
213 if ((!session_nb) || (session_nb >= SLMS))
215 printf("PROTOCOL: illegal session number %x\n", session_nb);
219 session=sessions[session_nb-1];
222 printf("PROTOCOL: data on closed session %x\n", session_nb);
231 session->recvCreateSessionResponse(pkt);
234 printf("recvCloseSessionRequest\n");
235 session->recvCloseSessionRequest(pkt);
238 printf("INTERNAL: nyi, tag %02x.\n", tag);
243 hlen += llen + 1; // lengthfield and tag
245 pkt = ((const unsigned char*)ptr) + hlen;
252 const unsigned char *tag=pkt;
255 hlen=parseLengthField(pkt, alen);
259 //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength)
261 // if (((len-alen) > 0) && ((len - alen) < 3))
263 // printf("WORKAROUND: applying work around MagicAPDULength\n");
267 if (session->receivedAPDU(tag, pkt, alen))
274 printf("PROTOCOL: warning, TL-Data has invalid length\n");