align lengths given by playback spans
[enigma2.git] / lib / dvb_ci / dvbci_mmi.cpp
1 /* DVB CI MMI */
2
3 #include <lib/dvb_ci/dvbci_mmi.h>
4 #include <lib/dvb_ci/dvbci_ui.h>
5 #include <lib/base/estring.h>
6
7 /*
8 PyObject *list = PyList_New(len);
9 for (i=0; i<len; ++i) {
10         PyObject *tuple = PyTuple_New(3); // 3 eintrge im tuple
11         PyTuple_SetItem(tuple, 0, PyString_FromString("eintrag 1"))
12         PyTuple_SetItem(tuple, 1, PyInt_FromLong(31337));
13         PyTuple_SetItem(tuple, 2, PyString_FromString("eintrag 3"))
14         PyList_SetItem(list, i, tuple);
15 }
16 return list;
17 */
18
19 eDVBCIMMISession::eDVBCIMMISession(eDVBCISlot *tslot)
20 {
21         slot = tslot;
22         slot->setMMIManager(this);
23 }
24
25 eDVBCIMMISession::~eDVBCIMMISession()
26 {
27         slot->setMMIManager(NULL);
28         eDVBCI_UI::getInstance()->mmiSessionDestroyed(slot->getSlotID());
29 }
30
31 int eDVBCIMMISession::receivedAPDU(const unsigned char *tag, const void *data, int len)
32 {
33         eDebugNoNewLine("SESSION(%d)/MMI %02x %02x %02x: ", session_nb, tag[0], tag[1],tag[2]);
34         for (int i=0; i<len; i++)
35                 eDebugNoNewLine("%02x ", ((const unsigned char*)data)[i]);
36         eDebug("");
37
38         if ((tag[0]==0x9f) && (tag[1]==0x88))
39         {
40                 switch (tag[2])
41                 {
42                 case 0x00:              //Tmmi_close
43                 {
44                         unsigned char *d=(unsigned char*)data;
45                         int timeout=0;
46                         if (d[3] == 1)
47                         {
48                                 if (len > 4)
49                                         timeout = d[4];
50                                 else
51                                 {
52                                         eDebug("mmi close tag incorrect.. no timeout given.. assume 5 seconds");
53                                         timeout = 5;
54                                 }
55                         }
56                         else if (d[3] > 1)
57                                 eDebug("mmi close tag incorrect.. byte 4 should be 0 or 1");
58                         eDVBCI_UI::getInstance()->mmiScreenClose(slot->getSlotID(), timeout);
59                         break;
60                 }
61                 case 0x01:
62                         eDebug("MMI display control");
63                         if (((unsigned char*)data)[0] != 1)
64                                 eDebug("kann ich nicht. aber das sag ich dem modul nicht.");
65                         state=stateDisplayReply;
66                         return 1;
67                 case 0x07:              //Tmenu_enq
68                 {
69                         unsigned char *d=(unsigned char*)data;
70                         unsigned char *max=((unsigned char*)d) + len;
71                         int textlen = len - 2;
72
73                         eDebug("in enq");
74                         
75                         if ((d+2) > max)
76                                 break;
77                                 
78                         int blind = *d++ & 1;
79                         int alen = *d++;
80
81                         eDebug("%d bytes text", textlen);
82                         if ((d+textlen) > max)
83                                 break;
84                         
85                         char str[textlen + 1];
86                         memcpy(str, ((char*)d), textlen);
87                         str[textlen] = '\0';
88                         
89                         eDebug("enq-text: %s",str);
90                         
91                         eDVBCI_UI::getInstance()->mmiScreenEnq(slot->getSlotID(), blind, alen, (char*)convertDVBUTF8(str).c_str());
92
93                         break;          
94                 }
95                 case 0x09:              //Tmenu_last
96                 case 0x0c:              //Tlist_last
97                 {
98                         unsigned char *d=(unsigned char*)data;
99                         unsigned char *max=((unsigned char*)d) + len;
100                         int pos = 0;
101                         eDebug("Tmenu_last");
102                         if (d > max)
103                                 break;
104                         int n=*d++;
105                         
106                         if(tag[2] == 0x09)      //menu
107                                 eDVBCI_UI::getInstance()->mmiScreenBegin(slot->getSlotID(), 0);
108                         else                                                            //list
109                                 eDVBCI_UI::getInstance()->mmiScreenBegin(slot->getSlotID(), 1);
110                         
111                         if (n == 0xFF)
112                                 n=0;
113                         else
114                                 n++;
115                         eDebug("%d texts", n);
116                         for (int i=0; i < (n+3); ++i)
117                         {
118                                 int textlen;
119                                 if ((d+3) > max)
120                                         break;
121                                 eDebug("text tag: %02x %02x %02x", d[0], d[1], d[2]);
122                                 d+=3;
123                                 d+=parseLengthField(d, textlen);
124                                 eDebug("%d bytes text", textlen);
125                                 if ((d+textlen) > max)
126                                         break;
127                                         
128                                 char str[textlen + 1];
129                                 memcpy(str, ((char*)d), textlen);
130                                 str[textlen] = '\0';
131                                 
132                                 eDVBCI_UI::getInstance()->mmiScreenAddText(slot->getSlotID(), pos++, (char*)convertDVBUTF8(str).c_str());
133                                         
134                                 while (textlen--)
135                                         eDebugNoNewLine("%c", *d++);
136                                 eDebug("");
137                         }
138                         eDVBCI_UI::getInstance()->mmiScreenFinish(slot->getSlotID());
139                         break;
140                 }
141                 default:
142                         eDebug("unknown APDU tag 9F 88 %02x", tag[2]);
143                         break;
144                 }
145         }
146         return 0;
147 }
148
149 int eDVBCIMMISession::doAction()
150 {
151         switch (state)
152         {
153         case stateStarted:
154                 state=stateIdle;
155                 break;
156         case stateDisplayReply:
157         {
158                 unsigned char tag[]={0x9f, 0x88, 0x02};
159                 unsigned char data[]={0x01, 0x01};
160                 sendAPDU(tag, data, 2);
161                 state=stateIdle;
162                 //state=stateFakeOK;
163                 //return 1;
164                 break;
165         }
166         case stateFakeOK:
167         {
168                 unsigned char tag[]={0x9f, 0x88, 0x0b};
169                 unsigned char data[]={5};
170                 sendAPDU(tag, data, 1);
171                 state=stateIdle;
172                 break;
173         }
174         case stateIdle:
175                 break;
176         default:
177                 break;
178         }
179         return 0;
180 }
181
182 int eDVBCIMMISession::stopMMI()
183 {
184         eDebug("eDVBCIMMISession::stopMMI()");
185
186         unsigned char tag[]={0x9f, 0x88, 0x00};
187         unsigned char data[]={0x00};
188         sendAPDU(tag, data, 1);
189         
190         return 0;
191 }
192
193 int eDVBCIMMISession::answerText(int answer)
194 {
195         eDebug("eDVBCIMMISession::answerText(%d)",answer);
196
197         unsigned char tag[]={0x9f, 0x88, 0x0B};
198         unsigned char data[]={0x00};
199         data[0] = answer & 0xff;
200         sendAPDU(tag, data, 1);
201         
202         return 0;
203 }
204
205 int eDVBCIMMISession::answerEnq(char *answer)
206 {
207         unsigned int len = strlen(answer);
208         eDebug("eDVBCIMMISession::answerEnq(%d bytes)", len);
209
210         unsigned char data[len+1];
211         data[0] = 0x01; // answer ok
212         memcpy(data+1, answer, len);
213
214         unsigned char tag[]={0x9f, 0x88, 0x08};
215         sendAPDU(tag, data, len+1);
216
217         return 0;
218 }
219
220 int eDVBCIMMISession::cancelEnq()
221 {
222         eDebug("eDVBCIMMISession::cancelEnq()");
223
224         unsigned char tag[]={0x9f, 0x88, 0x08};
225         unsigned char data[]={0x00}; // canceled
226         sendAPDU(tag, data, 1);
227         
228         return 0;
229 }
230