From: Andreas Monzner Date: Thu, 22 Nov 2007 22:18:50 +0000 (+0000) Subject: make MMI code more reusable X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=commitdiff_plain;h=e6fc6c4c345bee12b57a76392abf95c92b29aa3b make MMI code more reusable --- diff --git a/configure.ac b/configure.ac index a184fe8..9d8478a 100644 --- a/configure.ac +++ b/configure.ac @@ -72,6 +72,7 @@ lib/dvb/Makefile lib/dvb_ci/Makefile lib/gdi/Makefile lib/gui/Makefile +lib/mmi/Makefile lib/nav/Makefile lib/python/Makefile lib/python/Components/Makefile diff --git a/lib/dvb_ci/dvbci_mmi.cpp b/lib/dvb_ci/dvbci_mmi.cpp index c39d0ed..f266e5d 100644 --- a/lib/dvb_ci/dvbci_mmi.cpp +++ b/lib/dvb_ci/dvbci_mmi.cpp @@ -2,7 +2,8 @@ #include #include -#include + +#include /* PyObject *list = PyList_New(len); @@ -36,113 +37,12 @@ int eDVBCIMMISession::receivedAPDU(const unsigned char *tag, const void *data, i eDebug(""); if ((tag[0]==0x9f) && (tag[1]==0x88)) - { - switch (tag[2]) - { - case 0x00: //Tmmi_close + if (eDVBCI_UI::getInstance()->processMMIData(slot->getSlotID(), tag, data, len) == 1) { - unsigned char *d=(unsigned char*)data; - int timeout=0; - if (d[3] == 1) - { - if (len > 4) - timeout = d[4]; - else - { - eDebug("mmi close tag incorrect.. no timeout given.. assume 5 seconds"); - timeout = 5; - } - } - else if (d[3] > 1) - eDebug("mmi close tag incorrect.. byte 4 should be 0 or 1"); - eDVBCI_UI::getInstance()->mmiScreenClose(slot->getSlotID(), timeout); - break; - } - case 0x01: - eDebug("MMI display control"); - if (((unsigned char*)data)[0] != 1) - eDebug("kann ich nicht. aber das sag ich dem modul nicht."); state=stateDisplayReply; return 1; - case 0x07: //Tmenu_enq - { - unsigned char *d=(unsigned char*)data; - unsigned char *max=((unsigned char*)d) + len; - int textlen = len - 2; - - eDebug("in enq"); - - if ((d+2) > max) - break; - - int blind = *d++ & 1; - int alen = *d++; - - eDebug("%d bytes text", textlen); - if ((d+textlen) > max) - break; - - char str[textlen + 1]; - memcpy(str, ((char*)d), textlen); - str[textlen] = '\0'; - - eDebug("enq-text: %s",str); - - eDVBCI_UI::getInstance()->mmiScreenEnq(slot->getSlotID(), blind, alen, (char*)convertDVBUTF8(str).c_str()); - - break; } - case 0x09: //Tmenu_last - case 0x0c: //Tlist_last - { - unsigned char *d=(unsigned char*)data; - unsigned char *max=((unsigned char*)d) + len; - int pos = 0; - eDebug("Tmenu_last"); - if (d > max) - break; - int n=*d++; - - if(tag[2] == 0x09) //menu - eDVBCI_UI::getInstance()->mmiScreenBegin(slot->getSlotID(), 0); - else //list - eDVBCI_UI::getInstance()->mmiScreenBegin(slot->getSlotID(), 1); - - if (n == 0xFF) - n=0; - else - n++; - eDebug("%d texts", n); - for (int i=0; i < (n+3); ++i) - { - int textlen; - if ((d+3) > max) - break; - eDebug("text tag: %02x %02x %02x", d[0], d[1], d[2]); - d+=3; - d+=parseLengthField(d, textlen); - eDebug("%d bytes text", textlen); - if ((d+textlen) > max) - break; - - char str[textlen + 1]; - memcpy(str, ((char*)d), textlen); - str[textlen] = '\0'; - - eDVBCI_UI::getInstance()->mmiScreenAddText(slot->getSlotID(), pos++, (char*)convertDVBUTF8(str).c_str()); - - while (textlen--) - eDebugNoNewLine("%c", *d++); - eDebug(""); - } - eDVBCI_UI::getInstance()->mmiScreenFinish(slot->getSlotID()); - break; - } - default: - eDebug("unknown APDU tag 9F 88 %02x", tag[2]); - break; - } - } + return 0; } diff --git a/lib/dvb_ci/dvbci_ui.cpp b/lib/dvb_ci/dvbci_ui.cpp index 47eb13d..af613c4 100644 --- a/lib/dvb_ci/dvbci_ui.cpp +++ b/lib/dvb_ci/dvbci_ui.cpp @@ -5,33 +5,20 @@ #include #include -#include - #include #include #include +#include + +#define MAX_SLOTS 4 eDVBCI_UI *eDVBCI_UI::instance; eDVBCI_UI::eDVBCI_UI() + :eMMI_UI(MAX_SLOTS) { ASSERT(!instance); instance = this; - for(int i=0;iinitialize(slot); @@ -108,166 +66,10 @@ int eDVBCI_UI::cancelEnq(int slot) return 0; } -int eDVBCI_UI::availableMMI(int slot) -{ - if (slot < MAX_SLOTS) - return slotdata[slot].mmiScreenReady; - return false; -} - -int eDVBCI_UI::mmiScreenClose(int slot, int timeout) -{ - if (slot >= MAX_SLOTS) - return 0; - - slot_ui_data &data = slotdata[slot]; - - data.mmiScreenReady = 0; - - if (data.mmiScreen) - Py_DECREF(data.mmiScreen); - data.mmiScreen = PyList_New(1); - - ePyObject tuple = PyTuple_New(2); - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("CLOSE")); - PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(timeout)); - PyList_SET_ITEM(data.mmiScreen, 0, tuple); - data.mmiScreenReady = 1; - /*emit*/ ciStateChanged(slot); - return 0; -} - -int eDVBCI_UI::mmiScreenEnq(int slot, int blind, int answerLen, char *text) -{ - if (slot >= MAX_SLOTS) - return 0; - - slot_ui_data &data = slotdata[slot]; - - data.mmiScreenReady = 0; - - if (data.mmiScreen) - Py_DECREF(data.mmiScreen); - data.mmiScreen = PyList_New(2); - - ePyObject tuple = PyTuple_New(1); - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("ENQ")); - PyList_SET_ITEM(data.mmiScreen, 0, tuple); - - tuple = PyTuple_New(4); - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("PIN")); - PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(answerLen)); - PyTuple_SET_ITEM(tuple, 2, PyString_FromString(text)); - PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(blind)); - - PyList_SET_ITEM(data.mmiScreen, 1, tuple); - - data.mmiScreenReady = 1; - - /*emit*/ ciStateChanged(slot); - - return 0; -} - -int eDVBCI_UI::mmiScreenBegin(int slot, int listmenu) -{ - if (slot >= MAX_SLOTS) - return 0; - - eDebug("eDVBCI_UI::mmiScreenBegin"); - - slot_ui_data &data = slotdata[slot]; - - data.mmiScreenReady = 0; - - if (data.mmiScreen) - Py_DECREF(data.mmiScreen); - - data.mmiScreen = PyList_New(1); - - ePyObject tuple = PyTuple_New(1); - if (listmenu == 0) //menu - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("MENU")); - else //list - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("LIST")); - - PyList_SET_ITEM(data.mmiScreen, 0, tuple); - - data.mmiTuplePos = 1; - - return 0; -} - -int eDVBCI_UI::mmiScreenAddText(int slot, int type, char *value) -{ - if (slot >= MAX_SLOTS) - return 0; - - eDebug("eDVBCI_UI::mmiScreenAddText(%s)",value ? value : ""); - - slot_ui_data &data = slotdata[slot]; - - ePyObject tuple = PyTuple_New(3); - - if (type == 0) //title - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("TITLE")); - else if (type == 1) //subtitle - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("SUBTITLE")); - else if (type == 2) //bottom - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("BOTTOM")); - else - PyTuple_SET_ITEM(tuple, 0, PyString_FromString("TEXT")); - - eDebug("addText %s with id %d", value, type); - - PyTuple_SET_ITEM(tuple, 1, PyString_FromString(value)); - - if (type > 2) - PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(type-2)); - else - PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(-1)); - - PyList_Append(data.mmiScreen, tuple); - Py_DECREF(tuple); - - return 0; -} - -int eDVBCI_UI::mmiScreenFinish(int slot) -{ - if (slot < MAX_SLOTS) - { - eDebug("eDVBCI_UI::mmiScreenFinish"); - slotdata[slot].mmiScreenReady = 1; - /*emit*/ ciStateChanged(slot); - } - return 0; -} - -void eDVBCI_UI::mmiSessionDestroyed(int slot) -{ - /*emit*/ ciStateChanged(slot); -} - int eDVBCI_UI::getMMIState(int slot) { return eDVBCIInterfaces::getInstance()->getMMIState(slot); } -PyObject *eDVBCI_UI::getMMIScreen(int slot) -{ - if (slot < MAX_SLOTS) - { - slot_ui_data &data = slotdata[slot]; - if (data.mmiScreenReady) - { - data.mmiScreenReady = 0; - Py_INCREF(data.mmiScreen); - return data.mmiScreen; - } - } - Py_RETURN_NONE; -} - //FIXME: correct "run/startlevel" eAutoInitP0 init_dvbciui(eAutoInitNumbers::rc, "DVB-CI UI"); diff --git a/lib/dvb_ci/dvbci_ui.h b/lib/dvb_ci/dvbci_ui.h index 8018e89..b53ab02 100644 --- a/lib/dvb_ci/dvbci_ui.h +++ b/lib/dvb_ci/dvbci_ui.h @@ -2,65 +2,30 @@ #define __dvbci_ui_h #include - /* avoid warnigs :) */ -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 200112L -#include +#include #include -#define MAX_SLOTS 4 - -#ifndef SWIG -struct slot_ui_data -{ - std::string appName; - int state; - ePyObject mmiScreen; - int mmiTuplePos; - int mmiScreenReady; -}; -#endif - -class eDVBCI_UI +class eDVBCI_UI: public eMMI_UI { static eDVBCI_UI *instance; -#ifndef SWIG - slot_ui_data slotdata[MAX_SLOTS]; -#else +#ifdef SWIG eDVBCI_UI(); - ~eDVBCI_UI(); #endif + void stateChanged(int val) { ciStateChanged(val); } public: PSignal1 ciStateChanged; #ifndef SWIG eDVBCI_UI(); - ~eDVBCI_UI(); #endif static eDVBCI_UI *getInstance(); - - int getState(int slot); - void setState(int slot, int state); - std::string getAppName(int slot); - void setAppName(int slot, const char *name); void setInit(int slot); void setReset(int slot); int startMMI(int slot); int stopMMI(int slot); - int availableMMI(int slot); int getMMIState(int slot); int answerMenu(int slot, int answer); int answerEnq(int slot, char *val); int cancelEnq(int slot); - - PyObject *getMMIScreen(int slot); -#ifndef SWIG - int mmiScreenClose(int slot, int timeout); - int mmiScreenEnq(int slot, int blind, int answerLen, char *text); - int mmiScreenBegin(int slot, int listmenu); - int mmiScreenAddText(int slot, int type, char *value); - int mmiScreenFinish(int slot); - void mmiSessionDestroyed(int slot); -#endif }; #endif diff --git a/lib/mmi/Makefile.am b/lib/mmi/Makefile.am new file mode 100644 index 0000000..020c988 --- /dev/null +++ b/lib/mmi/Makefile.am @@ -0,0 +1,6 @@ +INCLUDES = \ + -I$(top_srcdir)/include + +noinst_LIBRARIES = libenigma_mmi.a + +libenigma_mmi_a_SOURCES = mmi_ui.cpp diff --git a/lib/mmi/mmi_ui.cpp b/lib/mmi/mmi_ui.cpp new file mode 100644 index 0000000..54b220c --- /dev/null +++ b/lib/mmi/mmi_ui.cpp @@ -0,0 +1,314 @@ +#include +#include // for parseLengthField + +#include +#include +#include + +#include +#include +#include +#include + +eMMI_UI::eMMI_UI(int max_slots) + :m_max_slots(max_slots) +{ + slotdata = new slot_ui_data[m_max_slots]; + for(int i=0;i 4) + timeout = d[4]; + else + { + eDebug("mmi close tag incorrect.. no timeout given.. assume 5 seconds"); + timeout = 5; + } + } + else if (d[3] > 1) + eDebug("mmi close tag incorrect.. byte 4 should be 0 or 1"); + mmiScreenClose(slot_id, timeout); + break; + } + case 0x01: + eDebug("MMI display control"); + if (((unsigned char*)data)[0] != 1) + eDebug("kann ich nicht. aber das sag ich dem modul nicht."); + return 1; + case 0x07: //Tmenu_enq + { + unsigned char *d=(unsigned char*)data; + unsigned char *max=((unsigned char*)d) + len; + int textlen = len - 2; + eDebug("in enq"); + if ((d+2) > max) + break; + int blind = *d++ & 1; + int alen = *d++; + eDebug("%d bytes text", textlen); + if ((d+textlen) > max) + break; + char str[textlen + 1]; + memcpy(str, ((char*)d), textlen); + str[textlen] = '\0'; + eDebug("enq-text: %s",str); + mmiScreenEnq(slot_id, blind, alen, (char*)convertDVBUTF8(str).c_str()); + break; + } + case 0x09: //Tmenu_last + case 0x0c: //Tlist_last + { + unsigned char *d=(unsigned char*)data; + unsigned char *max=((unsigned char*)d) + len; + int pos = 0; + eDebug("Tmenu_last"); + if (d > max) + break; + int n=*d++; + if(tag[2] == 0x09) //menu + mmiScreenBegin(slot_id, 0); + else //list + mmiScreenBegin(slot_id, 1); + if (n == 0xFF) + n=0; + else + n++; + eDebug("%d texts", n); + for (int i=0; i < (n+3); ++i) + { + int textlen; + if ((d+3) > max) + break; + eDebug("text tag: %02x %02x %02x", d[0], d[1], d[2]); + d+=3; + d+=eDVBCISession::parseLengthField(d, textlen); + eDebug("%d bytes text", textlen); + if ((d+textlen) > max) + break; + char str[textlen + 1]; + memcpy(str, ((char*)d), textlen); + str[textlen] = '\0'; + mmiScreenAddText(slot_id, pos++, (char*)convertDVBUTF8(str).c_str()); + while (textlen--) + eDebugNoNewLine("%c", *d++); + eDebug(""); + } + mmiScreenFinish(slot_id); + break; + } + default: + eDebug("unknown APDU tag 9F 88 %02x", tag[2]); + break; + } + return 0; +} + +int eMMI_UI::getState(int slot) +{ + if (slot < m_max_slots) + return slotdata[slot].state; + return 0; +} + +void eMMI_UI::setState(int slot, int newState) +{ + if (slot < m_max_slots) + { + slotdata[slot].state = newState; + stateChanged(slot); + } +} + +std::string eMMI_UI::getAppName(int slot) +{ + if (slot < m_max_slots) + return slotdata[slot].appName; + return ""; +} + +void eMMI_UI::setAppName(int slot, const char *name) +{ + if (slot < m_max_slots) + slotdata[slot].appName = name; +} + +int eMMI_UI::availableMMI(int slot) +{ + if (slot < m_max_slots) + return slotdata[slot].mmiScreenReady; + return false; +} + +int eMMI_UI::mmiScreenClose(int slot, int timeout) +{ + if (slot >= m_max_slots) + return 0; + + slot_ui_data &data = slotdata[slot]; + + data.mmiScreenReady = 0; + + if (data.mmiScreen) + Py_DECREF(data.mmiScreen); + data.mmiScreen = PyList_New(1); + + ePyObject tuple = PyTuple_New(2); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("CLOSE")); + PyTuple_SET_ITEM(tuple, 1, PyLong_FromLong(timeout)); + PyList_SET_ITEM(data.mmiScreen, 0, tuple); + data.mmiScreenReady = 1; + stateChanged(slot); + return 0; +} + +int eMMI_UI::mmiScreenEnq(int slot, int blind, int answerLen, char *text) +{ + if (slot >= m_max_slots) + return 0; + + slot_ui_data &data = slotdata[slot]; + + data.mmiScreenReady = 0; + + if (data.mmiScreen) + Py_DECREF(data.mmiScreen); + data.mmiScreen = PyList_New(2); + + ePyObject tuple = PyTuple_New(1); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("ENQ")); + PyList_SET_ITEM(data.mmiScreen, 0, tuple); + + tuple = PyTuple_New(4); + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("PIN")); + PyTuple_SET_ITEM(tuple, 1, PyInt_FromLong(answerLen)); + PyTuple_SET_ITEM(tuple, 2, PyString_FromString(text)); + PyTuple_SET_ITEM(tuple, 3, PyInt_FromLong(blind)); + + PyList_SET_ITEM(data.mmiScreen, 1, tuple); + + data.mmiScreenReady = 1; + + stateChanged(slot); + + return 0; +} + +int eMMI_UI::mmiScreenBegin(int slot, int listmenu) +{ + if (slot >= m_max_slots) + return 0; + + eDebug("eMMI_UI::mmiScreenBegin"); + + slot_ui_data &data = slotdata[slot]; + + data.mmiScreenReady = 0; + + if (data.mmiScreen) + Py_DECREF(data.mmiScreen); + + data.mmiScreen = PyList_New(1); + + ePyObject tuple = PyTuple_New(1); + if (listmenu == 0) //menu + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("MENU")); + else //list + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("LIST")); + + PyList_SET_ITEM(data.mmiScreen, 0, tuple); + + data.mmiTuplePos = 1; + + return 0; +} + +int eMMI_UI::mmiScreenAddText(int slot, int type, char *value) +{ + if (slot >= m_max_slots) + return 0; + + eDebug("eMMI_UI::mmiScreenAddText(%s)",value ? value : ""); + + slot_ui_data &data = slotdata[slot]; + + ePyObject tuple = PyTuple_New(3); + + if (type == 0) //title + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("TITLE")); + else if (type == 1) //subtitle + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("SUBTITLE")); + else if (type == 2) //bottom + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("BOTTOM")); + else + PyTuple_SET_ITEM(tuple, 0, PyString_FromString("TEXT")); + + eDebug("addText %s with id %d", value, type); + + PyTuple_SET_ITEM(tuple, 1, PyString_FromString(value)); + + if (type > 2) + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(type-2)); + else + PyTuple_SET_ITEM(tuple, 2, PyInt_FromLong(-1)); + + PyList_Append(data.mmiScreen, tuple); + Py_DECREF(tuple); + + return 0; +} + +int eMMI_UI::mmiScreenFinish(int slot) +{ + if (slot < m_max_slots) + { + eDebug("eMMI_UI::mmiScreenFinish"); + slotdata[slot].mmiScreenReady = 1; + stateChanged(slot); + } + return 0; +} + +void eMMI_UI::mmiSessionDestroyed(int slot) +{ + stateChanged(slot); +} + +PyObject *eMMI_UI::getMMIScreen(int slot) +{ + if (slot < m_max_slots) + { + slot_ui_data &data = slotdata[slot]; + if (data.mmiScreenReady) + { + data.mmiScreenReady = 0; + Py_INCREF(data.mmiScreen); + return data.mmiScreen; + } + } + Py_RETURN_NONE; +} diff --git a/lib/mmi/mmi_ui.h b/lib/mmi/mmi_ui.h new file mode 100644 index 0000000..d43dc70 --- /dev/null +++ b/lib/mmi/mmi_ui.h @@ -0,0 +1,57 @@ +#ifndef __mmi_ui_h +#define __mmi_ui_h + +#include + /* avoid warnigs :) */ +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#include + +#ifndef SWIG +struct slot_ui_data +{ + std::string appName; + int state; + ePyObject mmiScreen; + int mmiTuplePos; + int mmiScreenReady; +}; +#endif + +class eMMI_UI: public Object +{ + int m_max_slots; + virtual void stateChanged(int)=0; +protected: + slot_ui_data *slotdata; + eMMI_UI(int max_slots); + virtual ~eMMI_UI(); +public: + int getState(int slot); + void setState(int slot, int state); + std::string getAppName(int slot); + void setAppName(int slot, const char *name); +#ifndef SWIG + virtual void setInit(int slot)=0; + virtual void setReset(int slot)=0; + virtual int startMMI(int slot)=0; + virtual int stopMMI(int slot)=0; + virtual int answerMenu(int slot, int answer)=0; + virtual int answerEnq(int slot, char *val)=0; + virtual int cancelEnq(int slot)=0; + virtual int getMMIState(int slot)=0; +#endif + int availableMMI(int slot); + PyObject *getMMIScreen(int slot); +#ifndef SWIG + int processMMIData(int slot, const unsigned char *tag, const void *data, int len); + int mmiScreenClose(int slot, int timeout); + int mmiScreenEnq(int slot, int blind, int answerLen, char *text); + int mmiScreenBegin(int slot, int listmenu); + int mmiScreenAddText(int slot, int type, char *value); + int mmiScreenFinish(int slot); + void mmiSessionDestroyed(int slot); +#endif +}; + +#endif diff --git a/lib/python/enigma_python.i b/lib/python/enigma_python.i index 9ef269b..77d9496 100644 --- a/lib/python/enigma_python.i +++ b/lib/python/enigma_python.i @@ -92,6 +92,7 @@ is usually caused by not marking PSignals as immutable. #include #include #include +#include #include #include #include @@ -207,6 +208,7 @@ typedef long time_t; %include %include %include +%include %include %include %include diff --git a/main/Makefile.am b/main/Makefile.am index 9bc728a..7cb08b2 100644 --- a/main/Makefile.am +++ b/main/Makefile.am @@ -27,6 +27,7 @@ enigma2_LDADD_WHOLE = \ $(top_builddir)/lib/base/libenigma_base.a \ $(top_builddir)/lib/components/libenigma_components.a \ $(top_builddir)/lib/driver/libenigma_driver.a \ + $(top_builddir)/lib/mmi/libenigma_mmi.a \ $(top_builddir)/lib/dvb/libenigma_dvb.a \ $(top_builddir)/lib/dvb_ci/libenigma_dvb_ci.a \ $(top_builddir)/lib/gdi/libenigma_gdi.a \