From: Ronny Strutz Date: Fri, 12 Aug 2005 19:38:08 +0000 (+0000) Subject: change session handling X-Git-Tag: 2.6.0~5778 X-Git-Url: https://git.cweiske.de/enigma2.git/commitdiff_plain/c4bab36eed7b9ce0ba0b16775a9d429c71c5eed7 change session handling --- diff --git a/lib/dvb_ci/Makefile.am b/lib/dvb_ci/Makefile.am index 8236cfda..ba55d9f9 100644 --- a/lib/dvb_ci/Makefile.am +++ b/lib/dvb_ci/Makefile.am @@ -3,5 +3,5 @@ INCLUDES = \ noinst_LIBRARIES = libenigma_dvb_ci.a -libenigma_dvb_ci_a_SOURCES = dvbci.cpp dvbci_session.cpp +libenigma_dvb_ci_a_SOURCES = dvbci.cpp dvbci_session.cpp dvbci_resmgr.cpp diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index d76cd341..67b2eafa 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -44,20 +44,22 @@ void eDVBCISlot::data(int) if(r < 0) eWarning("ERROR reading from CI - %m\n"); - if(!se) { + if(state != stateInserted) { + state = stateInserted; eDebug("ci inserted"); - se = new eDVBCISession(this); - + /* enable HUP to detect removal or errors */ notifier_event->start(); } if(r > 0) - se->receiveData(data, r); + eDVBCISession::receiveData(this, data, r); } void eDVBCISlot::event(int) { + state = stateRemoved; + eDebug("CI removed"); /* kill the TransportConnection */ @@ -66,7 +68,7 @@ void eDVBCISlot::event(int) notifier_event->stop(); } -eDVBCISlot::eDVBCISlot(eMainloop *context, int nr): se(0) +eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) { char filename[128]; diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index 961999e9..78c1cc8e 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -5,7 +5,7 @@ class eDVBCISession; -class eDVBCISlot: public Object +class eDVBCISlot: public iObject, public Object { DECLARE_REF(eDVBCISlot); private: @@ -14,8 +14,9 @@ private: eSocketNotifier *notifier_data; void event(int); eSocketNotifier *notifier_event; - - eDVBCISession *se; + + int state; + enum {stateRemoved, stateInserted}; public: eDVBCISlot(eMainloop *context, int nr); virtual ~eDVBCISlot(); diff --git a/lib/dvb_ci/dvbci_session.cpp b/lib/dvb_ci/dvbci_session.cpp index 1e59d2ad..b0bef25c 100644 --- a/lib/dvb_ci/dvbci_session.cpp +++ b/lib/dvb_ci/dvbci_session.cpp @@ -1,11 +1,7 @@ /* DVB CI Transport Connection */ #include - -eDVBCISession::eDVBCISession(eDVBCISlot *cislot) -{ - slot = cislot; -} +#include int eDVBCISession::buildLengthField(unsigned char *pkt, int len) { @@ -47,6 +43,17 @@ int eDVBCISession::parseLengthField(const unsigned char *pkt, int &len) return (pkt[0] & 0x7F) + 1; } +void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data, int len) +{ + unsigned char pkt[len+3+4]; + int l; + memcpy(pkt, tag, 3); + l=buildLengthField(pkt+3, len); + if (data) + memcpy(pkt+3+l, data, len); + sendSPDU(0x90, 0, 0, pkt, len+3+l); +} + void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *data, int len, unsigned short session_nb, const void *apdu,int alen) { unsigned char pkt[4096]; @@ -75,6 +82,21 @@ void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char sess sendSPDU(slot, 0x92, pkt, 5, session_nb); } +void eDVBCISession::recvCreateSessionResponse(const unsigned char *data) +{ + status = data[0]; + state = stateStarted; + action = 1; + printf("create Session Response, status %x\n", status); +} + +void eDVBCISession::recvCloseSessionRequest(const unsigned char *data) +{ + state = stateInDeletion; + action = 1; + printf("close Session Request\n"); +} + eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status) { eDVBCISession *session; @@ -97,7 +119,7 @@ eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned cha switch (tag) { case 0x00010041: -// session=new eDVBCIResourceManagerSession; + session=new eDVBCIResourceManagerSession; printf("RESOURCE MANAGER\n"); break; case 0x00020041: @@ -150,7 +172,7 @@ eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned cha return session; } -void eDVBCISession::receiveData(const unsigned char *ptr, size_t len) +void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len) { const unsigned char *pkt = (const unsigned char*)ptr; unsigned char tag = *pkt++; @@ -173,4 +195,72 @@ void eDVBCISession::receiveData(const unsigned char *ptr, size_t len) session->action=1; } } + else + { + unsigned session_nb; + session_nb=pkt[hlen-2]<<8; + session_nb|=pkt[hlen-1]&0xFF; + + if ((!session_nb) || (session_nb >= SLMS)) + { + printf("PROTOCOL: illegal session number %x\n", session_nb); + return; + } + + session=sessions[session_nb-1]; + if (!session) + { + printf("PROTOCOL: data on closed session %x\n", session_nb); + return; + } + + switch (tag) + { + case 0x90: + break; + case 0x94: + session->recvCreateSessionResponse(pkt); + break; + case 0x95: + printf("recvCloseSessionRequest\n"); + session->recvCloseSessionRequest(pkt); + break; + default: + printf("INTERNAL: nyi, tag %02x.\n", tag); + return; + } + } + + hlen += llen + 1; // lengthfield and tag + + pkt = ((const unsigned char*)ptr) + hlen; + len -= hlen; + + if (session) + while (len > 0) + { + int alen; + const unsigned char *tag=pkt; + pkt+=3; // tag + len-=3; + hlen=parseLengthField(pkt, alen); + pkt+=hlen; + len-=hlen; + + //if (eDVBCIModule::getInstance()->workarounds_active & eDVBCIModule::workaroundMagicAPDULength) + //{ + // if (((len-alen) > 0) && ((len - alen) < 3)) + // { + // printf("WORKAROUND: applying work around MagicAPDULength\n"); + // alen=len; + // } + //} + if (session->receivedAPDU(tag, pkt, alen)) + session->action = 1; + pkt+=alen; + len-=alen; + } + + if (len) + printf("PROTOCOL: warning, TL-Data has invalid length\n"); } diff --git a/lib/dvb_ci/dvbci_session.h b/lib/dvb_ci/dvbci_session.h index 426c7f82..5f95ee82 100644 --- a/lib/dvb_ci/dvbci_session.h +++ b/lib/dvb_ci/dvbci_session.h @@ -10,24 +10,25 @@ class eDVBCISession { static eDVBCISession *sessions[SLMS]; static eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned char *resource_identifier, unsigned char &status); - void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag,const void *data, int len, unsigned short session_nb, const void *apdu=0,int alen=0); - void sendOpenSessionResponse(eDVBCISlot *slot,unsigned char session_status, const unsigned char *resource_identifier,unsigned short session_nb); + static void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag,const void *data, int len, unsigned short session_nb, const void *apdu=0,int alen=0); + static void sendOpenSessionResponse(eDVBCISlot *slot,unsigned char session_status, const unsigned char *resource_identifier,unsigned short session_nb); + void recvCreateSessionResponse(const unsigned char *data); + void recvCloseSessionRequest(const unsigned char *data); protected: int state; int status; int action; eDVBCISlot *slot; //base only unsigned short session_nb; + virtual int receivedAPDU(const unsigned char *tag, const void *data, int len) = 0; + void eDVBCISession::sendAPDU(const unsigned char *tag, const void *data=0,int len=0); public: - eDVBCISession(eDVBCISlot *cislot); - ~eDVBCISession(); - enum { stateInCreation, stateBusy, stateInDeletion, stateStarted, statePrivate}; - int parseLengthField(const unsigned char *pkt, int &len); - int buildLengthField(unsigned char *pkt, int len); + static int parseLengthField(const unsigned char *pkt, int &len); + static int buildLengthField(unsigned char *pkt, int len); - void receiveData(const unsigned char *ptr, size_t len); + static void receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len); int getState() { return state; } int getStatus() { return status; }