From 61402686fd1130b5b183fbe853927180be1ba1e1 Mon Sep 17 00:00:00 2001 From: Ronny Strutz Date: Sat, 13 Aug 2005 00:39:24 +0000 Subject: [PATCH] fixes - ci inits now completely --- lib/dvb_ci/dvbci.cpp | 90 ++++++++++++++++++++++++++---------- lib/dvb_ci/dvbci.h | 11 ++--- lib/dvb_ci/dvbci_appmgr.cpp | 28 +++++++++++ lib/dvb_ci/dvbci_resmgr.cpp | 9 +++- lib/dvb_ci/dvbci_session.cpp | 54 ++++++++++++++++++---- lib/dvb_ci/dvbci_session.h | 5 ++ 6 files changed, 156 insertions(+), 41 deletions(-) diff --git a/lib/dvb_ci/dvbci.cpp b/lib/dvb_ci/dvbci.cpp index 67b2eafa..cb533342 100644 --- a/lib/dvb_ci/dvbci.cpp +++ b/lib/dvb_ci/dvbci.cpp @@ -1,5 +1,8 @@ #include +#include +#include + #include #include #include @@ -9,6 +12,7 @@ eDVBCIInterfaces::eDVBCIInterfaces() int num_ci = 0; eDebug("scanning for common interfaces.."); + while (1) { struct stat s; @@ -29,45 +33,80 @@ eDVBCIInterfaces::eDVBCIInterfaces() eDebug("done, found %d common interfaces"); } -int eDVBCISlot::write(const unsigned char *data, size_t len) +eDVBCIInterfaces::~eDVBCIInterfaces() +{ +} + +int eDVBCISlot::send(const unsigned char *data, size_t len) { - return ::write(fd, data, len); + int res; + int i; + + printf("< "); + for(i=0;isetRequested(eSocketNotifier::Read|eSocketNotifier::Hungup|eSocketNotifier::Write); + + return res; } -void eDVBCISlot::data(int) +void eDVBCISlot::data(int what) { - eDebug("ci talks to us"); + if(what == eSocketNotifier::Hungup) { + if(state != stateRemoved) { + state = stateRemoved; + printf("ci removed\n"); + notifier->setRequested(eSocketNotifier::Read); + } + return; + } + __u8 data[4096]; int r; r = ::read(fd, data, 4096); - if(r < 0) - eWarning("ERROR reading from CI - %m\n"); + //if(r < 0) + // eWarning("ERROR reading from CI - %m\n"); if(state != stateInserted) { state = stateInserted; eDebug("ci inserted"); /* enable HUP to detect removal or errors */ - notifier_event->start(); + //notifier_event->start(); + notifier->setRequested(eSocketNotifier::Read|eSocketNotifier::Hungup|eSocketNotifier::Write); } - if(r > 0) + if(r > 0) { + int i; + printf("> "); + for(i=0;isetRequested(eSocketNotifier::Read|eSocketNotifier::Hungup|eSocketNotifier::Write); + return; + } - eDebug("CI removed"); - - /* kill the TransportConnection */ - - /* we know about and disable HUP */ - notifier_event->stop(); + if(what == eSocketNotifier::Write) { + printf("pollall\n"); + if(eDVBCISession::pollAll() == 0) { + printf("disable pollout\n"); + notifier->setRequested(eSocketNotifier::Read | eSocketNotifier::Hungup); + } + return; + } } +DEFINE_REF(eDVBCISlot); + eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) { char filename[128]; @@ -80,15 +119,16 @@ eDVBCISlot::eDVBCISlot(eMainloop *context, int nr) if (fd >= 0) { - //read callback - notifier_data = new eSocketNotifier(context, fd, eSocketNotifier::Read); - CONNECT(notifier_data->activated, eDVBCISlot::data); - //remove callback - notifier_event = new eSocketNotifier(context, fd, eSocketNotifier::Hungup); - CONNECT(notifier_event->activated, eDVBCISlot::event); + notifier = new eSocketNotifier(context, fd, eSocketNotifier::Read | eSocketNotifier::Hungup); + CONNECT(notifier->activated, eDVBCISlot::data); } else { perror(filename); } } +eDVBCISlot::~eDVBCISlot() +{ +} + +eAutoInitP0 init_eDVBCIInterfaces(eAutoInitNumbers::dvb, "CI Slots"); diff --git a/lib/dvb_ci/dvbci.h b/lib/dvb_ci/dvbci.h index b72b21b1..eb4b6b04 100644 --- a/lib/dvb_ci/dvbci.h +++ b/lib/dvb_ci/dvbci.h @@ -13,17 +13,15 @@ DECLARE_REF(eDVBCISlot); private: int fd; void data(int); - eSocketNotifier *notifier_data; - void event(int); - eSocketNotifier *notifier_event; + eSocketNotifier *notifier; int state; enum {stateRemoved, stateInserted}; public: eDVBCISlot(eMainloop *context, int nr); - virtual ~eDVBCISlot(); + ~eDVBCISlot(); - int eDVBCISlot::write(const unsigned char *data, size_t len); + int send(const unsigned char *data, size_t len); eDVBCIApplicationManagerSession *application_manager; eDVBCICAManagerSession *ca_manager; @@ -31,11 +29,12 @@ public: class eDVBCIInterfaces { +DECLARE_REF(eDVBCIInterfaces); private: eSmartPtrList m_slots; public: eDVBCIInterfaces(); - virtual ~eDVBCIInterfaces(); + ~eDVBCIInterfaces(); }; #endif diff --git a/lib/dvb_ci/dvbci_appmgr.cpp b/lib/dvb_ci/dvbci_appmgr.cpp index 92472d87..4c468a8d 100644 --- a/lib/dvb_ci/dvbci_appmgr.cpp +++ b/lib/dvb_ci/dvbci_appmgr.cpp @@ -40,3 +40,31 @@ int eDVBCIApplicationManagerSession::receivedAPDU(const unsigned char *tag,const } return 0; } + +int eDVBCIApplicationManagerSession::doAction() +{ + switch (state) + { + case stateStarted: + { + const unsigned char tag[3]={0x9F, 0x80, 0x20}; // application manager info e sendAPDU(tag); + sendAPDU(tag); + state=stateFinal; + return 1; + } + case stateFinal: + printf("in final state.\n"); + wantmenu = 0; + if (wantmenu) + { + printf("wantmenu: sending Tenter_menu\n"); + const unsigned char tag[3]={0x9F, 0x80, 0x22}; // Tenter_menu + sendAPDU(tag); + wantmenu=0; + return 0; + } else + return 0; + default: + return 0; + } +} diff --git a/lib/dvb_ci/dvbci_resmgr.cpp b/lib/dvb_ci/dvbci_resmgr.cpp index df0fb8d0..7f716d61 100644 --- a/lib/dvb_ci/dvbci_resmgr.cpp +++ b/lib/dvb_ci/dvbci_resmgr.cpp @@ -24,6 +24,7 @@ int eDVBCIResourceManagerSession::receivedAPDU(const unsigned char *tag,const vo else for (int i=0; i #include +eDVBCISession *eDVBCISession::sessions[SLMS]; + int eDVBCISession::buildLengthField(unsigned char *pkt, int len) { if (len < 127) @@ -79,7 +81,7 @@ void eDVBCISession::sendSPDU(eDVBCISlot *slot, unsigned char tag, const void *da memcpy(ptr, apdu, alen); ptr+=alen; - slot->write(pkt, ptr - pkt); + slot->send(pkt, ptr - pkt); } void eDVBCISession::sendOpenSessionResponse(eDVBCISlot *slot, unsigned char session_status, const unsigned char *resource_identifier, unsigned short session_nb) @@ -111,6 +113,7 @@ eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned cha eDVBCISession *session; unsigned long tag; unsigned short session_nb; + for (session_nb=1; session_nb < SLMS; ++session_nb) if (!sessions[session_nb-1]) break; @@ -130,6 +133,7 @@ eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned cha case 0x00010041: session=new eDVBCIResourceManagerSession; printf("RESOURCE MANAGER\n"); + printf("session: %p\n",session); break; case 0x00020041: session=slot->application_manager = new eDVBCIApplicationManagerSession; @@ -165,27 +169,59 @@ eDVBCISession *eDVBCISession::createSession(eDVBCISlot *slot, const unsigned cha } printf("new session_nb: %d\n", session_nb); session->session_nb = session_nb; + if (session) { - printf("session ok, status %02x\n", session->status); - status = session->getStatus(); - if (status) - { - delete session; - session = 0; - } sessions[session_nb - 1] = session; session->slot = slot; + status = 0; } session->state = stateInCreation; + return session; } +void eDVBCISession::handleClose() +{ + unsigned char data[1]={0x00}; + sendSPDU(0x96, data, 1, 0, 0); +} + +int eDVBCISession::pollAll() +{ + for (int session_nb=1; session_nb < SLMS; ++session_nb) + if (sessions[session_nb-1]) + { + int r; + + if (sessions[session_nb-1]->state == stateInDeletion) + { + sessions[session_nb-1]->handleClose(); + delete sessions[session_nb-1]; + sessions[session_nb-1]=0; + r=1; + } else + r=sessions[session_nb-1]->poll(); + + if (r) + return 1; + } + return 0; +} + void eDVBCISession::receiveData(eDVBCISlot *slot, const unsigned char *ptr, size_t len) { const unsigned char *pkt = (const unsigned char*)ptr; unsigned char tag = *pkt++; int llen, hlen; + + printf("slot: %p\n",slot); + + int i; + + for(i=0;isession_nb:0); - + if (session) { session->state=stateStarted; diff --git a/lib/dvb_ci/dvbci_session.h b/lib/dvb_ci/dvbci_session.h index dd123eee..187be290 100644 --- a/lib/dvb_ci/dvbci_session.h +++ b/lib/dvb_ci/dvbci_session.h @@ -23,7 +23,10 @@ protected: 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); void eDVBCISession::sendSPDU(unsigned char tag, const void *data, int len,const void *apdu=0, int alen=0); + virtual doAction()=0; + void handleClose(); public: + int poll() { if (action) { action=doAction(); return 1; } return 0; } enum { stateInCreation, stateBusy, stateInDeletion, stateStarted, statePrivate}; static int parseLengthField(const unsigned char *pkt, int &len); @@ -33,6 +36,8 @@ public: int getState() { return state; } int getStatus() { return status; } + + static int pollAll(); }; #endif -- 2.30.2