fix bluescreen in ci menu when no entries in a menulist an ok is pressed
[vuplus_dvbapp] / 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 }
29
30 int eDVBCIMMISession::receivedAPDU(const unsigned char *tag, const void *data, int len)
31 {
32         printf("SESSION(%d)/MMI %02x %02x %02x: ", session_nb, tag[0], tag[1],tag[2]);
33         for (int i=0; i<len; i++)
34                 printf("%02x ", ((const unsigned char*)data)[i]);
35         printf("\n");
36
37         if ((tag[0]==0x9f) && (tag[1]==0x88))
38         {
39                 switch (tag[2])
40                 {
41                         case 0x01:
42                         printf("MMI display control\n");
43                         if (((unsigned char*)data)[0] != 1)
44                                 printf("kann ich nicht. aber das sag ich dem modul nicht.\n");
45                         state=stateDisplayReply;
46                         return 1;
47                 case 0x07:              //Tmenu_enq
48                 {
49                         unsigned char *d=(unsigned char*)data;
50                         unsigned char *max=((unsigned char*)d) + len;
51                         int textlen = len - 2;
52
53                         printf("in enq\n");
54                         
55                         if ((d+2) > max)
56                                 break;
57                                 
58                         int blind = *d++ & 1;
59                         int alen = *d++;
60
61                         printf("%d bytes text\n", textlen);
62                         if ((d+textlen) > max)
63                                 break;
64                         
65                         char str[textlen + 1];
66                         memcpy(str, ((char*)d), textlen);
67                         str[textlen] = '\0';
68                         
69                         printf("enq-text: %s\n",str);
70                         
71                         eDVBCI_UI::getInstance()->mmiScreenEnq(slot->getSlotID(), blind, alen, (char*)convertDVBUTF8(str).c_str());
72
73                         break;          
74                 }
75                 case 0x09:              //Tmenu_last
76                 case 0x0c:              //Tlist_last
77                 {
78                         unsigned char *d=(unsigned char*)data;
79                         unsigned char *max=((unsigned char*)d) + len;
80                         int pos = 0;
81                         printf("Tmenu_last\n");
82                         if (d > max)
83                                 break;
84                         int n=*d++;
85                         
86                         if(tag[2] == 0x09)      //menu
87                                 eDVBCI_UI::getInstance()->mmiScreenBegin(slot->getSlotID(), 0);
88                         else                                                            //list
89                                 eDVBCI_UI::getInstance()->mmiScreenBegin(slot->getSlotID(), 1);
90                         
91                         if (n == 0xFF)
92                                 n=0;
93                         else
94                                 n++;
95                         printf("%d texts\n", n);
96                         for (int i=0; i < (n+3); ++i)
97                         {
98                                 int textlen;
99                                 if ((d+3) > max)
100                                         break;
101                                 printf("text tag: %02x %02x %02x\n", d[0], d[1], d[2]);
102                                 d+=3;
103                                 d+=parseLengthField(d, textlen);
104                                 printf("%d bytes text\n", textlen);
105                                 if ((d+textlen) > max)
106                                         break;
107                                         
108                                 char str[textlen + 1];
109                                 memcpy(str, ((char*)d), textlen);
110                                 str[textlen] = '\0';
111                                 
112                                 eDVBCI_UI::getInstance()->mmiScreenAddText(slot->getSlotID(), pos++, (char*)convertDVBUTF8(str).c_str());
113                                         
114                                 while (textlen--)
115                                         printf("%c", *d++);
116                                 printf("\n");
117                         }
118                         eDVBCI_UI::getInstance()->mmiScreenFinish(slot->getSlotID());
119                         break;
120                 }
121                 default:
122                         printf("unknown APDU tag 9F 88 %02x\n", tag[2]);
123                         break;
124                 }
125         }
126         return 0;
127 }
128
129 int eDVBCIMMISession::doAction()
130 {
131         switch (state)
132         {
133         case stateStarted:
134                 state=stateIdle;
135                 break;
136         case stateDisplayReply:
137         {
138                 unsigned char tag[]={0x9f, 0x88, 0x02};
139                 unsigned char data[]={0x01, 0x01};
140                 sendAPDU(tag, data, 2);
141                 state=stateIdle;
142                 //state=stateFakeOK;
143                 //return 1;
144                 break;
145         }
146         case stateFakeOK:
147         {
148                 unsigned char tag[]={0x9f, 0x88, 0x0b};
149                 unsigned char data[]={5};
150                 sendAPDU(tag, data, 1);
151                 state=stateIdle;
152                 break;
153         }
154         case stateIdle:
155                 break;
156         default:
157                 break;
158         }
159         return 0;
160 }
161
162 int eDVBCIMMISession::stopMMI()
163 {
164         printf("eDVBCIMMISession::stopMMI()\n");
165
166         unsigned char tag[]={0x9f, 0x88, 0x00};
167         unsigned char data[]={0x00};
168         sendAPDU(tag, data, 1);
169         
170         return 0;
171 }
172
173 int eDVBCIMMISession::answerText(int answer)
174 {
175         printf("eDVBCIMMISession::answerText(%d)\n",answer);
176
177         unsigned char tag[]={0x9f, 0x88, 0x0B};
178         unsigned char data[]={0x00};
179         data[0] = answer & 0xff;
180         sendAPDU(tag, data, 1);
181         
182         return 0;
183 }
184
185 int eDVBCIMMISession::answerEnq(char *answer)
186 {
187         unsigned int len = strlen(answer);
188         printf("eDVBCIMMISession::answerEnq(%d bytes)\n", len);
189
190         unsigned char data[len+1];
191         data[0] = 0x01; // answer ok
192         memcpy(data+1, answer, len);
193
194         unsigned char tag[]={0x9f, 0x88, 0x08};
195         sendAPDU(tag, data, len+1);
196
197         return 0;
198 }
199
200 int eDVBCIMMISession::cancelEnq()
201 {
202         printf("eDVBCIMMISession::cancelEnq()\n");
203
204         unsigned char tag[]={0x9f, 0x88, 0x08};
205         unsigned char data[]={0x00}; // canceled
206         sendAPDU(tag, data, 1);
207         
208         return 0;
209 }
210