1 #include "socket_mmi.h"
7 #include <lib/base/ebase.h>
8 #include <lib/base/init.h>
9 #include <lib/base/init_num.h>
10 #include <lib/base/eerror.h>
11 #include <lib/base/estring.h>
12 #include <lib/dvb_ci/dvbci_session.h>
14 #define MAX_LENGTH_BYTES 4
15 #define MIN_LENGTH_BYTES 1
18 eSocket_UI *eSocket_UI::instance;
20 eSocket_UI::eSocket_UI()
25 CONNECT(handler.mmi_progress, eMMI_UI::processMMIData);
28 eSocket_UI *eSocket_UI::getInstance()
33 void eSocket_UI::setInit(int)
38 void eSocket_UI::setReset(int)
43 int eSocket_UI::startMMI(int)
45 unsigned char buf[]={0x9F,0x80,0x22,0x00}; // ENTER MMI
46 if (handler.send_to_mmisock( buf, 4 ))
48 eDebug("eSocket_UI::startMMI failed");
54 int eSocket_UI::stopMMI(int)
56 unsigned char buf[]={0x9F,0x88,0x00,0x00}; // CLOSE MMI
57 if (handler.send_to_mmisock( buf, 4 ))
59 eDebug("eSocket_UI::stopMMI failed");
65 int eSocket_UI::answerMenu(int, int answer)
67 unsigned char data[]={0x9f,0x88,0x0B,0x01,0x00};
68 data[4] = answer & 0xff;
69 if (handler.send_to_mmisock( data, 5 ))
71 eDebug("eSocket_UI::answerMenu failed");
77 int eSocket_UI::answerEnq(int, char *answer)
79 unsigned int len = strlen(answer);
80 unsigned char data[4+len+MAX_LENGTH_BYTES];
84 int LengthBytes=eDVBCISession::buildLengthField(data+3, len+1);
85 data[3+LengthBytes] = 0x01;
86 memcpy(data+4+LengthBytes, answer, len);
87 if (handler.send_to_mmisock( data, len+4+LengthBytes ))
89 eDebug("eSocket_UI::answerEnq failed");
95 int eSocket_UI::cancelEnq(int)
97 unsigned char data[]={0x9f,0x88,0x08,0x01,0x00};
98 if (handler.send_to_mmisock( data, 5 ))
100 eDebug("eSocket_UI::cancelEnq failed");
106 int eSocket_UI::getState(int)
108 return handler.connected() ? 2 : 0;
111 int eSocket_UI::getMMIState(int)
113 return handler.connected();
116 //FIXME: correct "run/startlevel"
117 eAutoInitP0<eSocket_UI> init_socketui(eAutoInitNumbers::rc, "Socket MMI");
119 int eSocketMMIHandler::send_to_mmisock( void* buf, size_t len)
121 int ret = write(connfd, buf, len);
123 eDebug("[eSocketMMIHandler] write (%m)");
124 else if ( (uint)ret != len )
125 eDebug("[eSocketMMIHandler] only %d bytes sent.. %d bytes should be sent", ret, len );
131 eSocketMMIHandler::eSocketMMIHandler()
132 :buffer(512), connfd(-1), connsn(0), sockname("/tmp/mmi.socket"), name(0)
134 memset(&servaddr, 0, sizeof(struct sockaddr_un));
135 servaddr.sun_family = AF_UNIX;
137 strcpy(servaddr.sun_path, sockname);
138 clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path);
139 if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0)
141 eDebug("[eSocketMMIHandler] socket (%m)");
146 if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1)
147 eDebug("[eSocketMMIHandler] SO_REUSEADDR (%m)");
148 else if ((val = fcntl(listenfd, F_GETFL)) == -1)
149 eDebug("[eSocketMMIHandler] F_GETFL (%m)");
150 else if (fcntl(listenfd, F_SETFL, val | O_NONBLOCK) == -1)
151 eDebug("[eSocketMMIHandler] F_SETFL (%m)");
152 else if (bind(listenfd, (struct sockaddr *) &servaddr, clilen) == -1)
153 eDebug("[eSocketMMIHandler] bind (%m)");
154 else if (listen(listenfd, 0) == -1)
155 eDebug("[eSocketMMIHandler] listen (%m)");
157 listensn = new eSocketNotifier( eApp, listenfd, POLLIN );
159 CONNECT( listensn->activated, eSocketMMIHandler::listenDataAvail );
160 eDebug("[eSocketMMIHandler] created successfully");
168 #define CMD_SET_NAME "\x01\x02\x03\x04"
170 void eSocketMMIHandler::listenDataAvail(int what)
174 eDebug("[eSocketMMIHandler] connsn != NULL");
177 connfd = accept(listenfd, (struct sockaddr *) &servaddr, (socklen_t *) &clilen);
179 eDebug("[eSocketMMIHandler] accept (%m)");
184 if ((val = fcntl(connfd, F_GETFL)) == -1)
185 eDebug("[eSocketMMIHandler] F_GETFL (%m)");
186 else if (fcntl(connfd, F_SETFL, val | O_NONBLOCK) == -1)
187 eDebug("[eSocketMMIHandler] F_SETFL (%m)");
189 connsn = new eSocketNotifier( eApp, connfd, POLLIN|POLLHUP|POLLERR );
190 CONNECT( connsn->activated, eSocketMMIHandler::connDataAvail );
199 void eSocketMMIHandler::connDataAvail(int what)
201 if (what & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) {
202 char msgbuffer[4096];
203 ssize_t length = read(connfd, msgbuffer, sizeof(msgbuffer));
206 if (errno != EAGAIN && errno != EINTR && errno != EBUSY) {
207 eDebug("[eSocketMMIHandler] read (%m)");
210 } else if (length == 0){
212 } else if ((!name) && (length > 4) && (!memcmp(msgbuffer, CMD_SET_NAME, 4))) {
215 name = new char[length + 1];
216 memcpy(name, &msgbuffer[4], length);
218 eDebug("MMI NAME %s", name);
221 unsigned char *data = (unsigned char*)msgbuffer;
223 // If a new message starts, then the previous message
224 // should already have been processed. Otherwise the
225 // previous message was incomplete and should therefore
227 if ((len >= 1) && (data[0] != 0x9f))
229 if ((len >= 2) && (data[1] != 0x88))
235 eDebug("clear buffer");
239 eDebug("Put to buffer:");
240 for (int i=0; i < len; ++i)
241 eDebugNoNewLine("%02x ", data[i]);
242 eDebug("\n--------");
244 buffer.write( data, len );
246 while ( buffer.size() >= (3 + MIN_LENGTH_BYTES) )
248 unsigned char tmp[3+MAX_LENGTH_BYTES];
249 buffer.peek(tmp, 3+MIN_LENGTH_BYTES);
250 if (tmp[0] != 0x9f || tmp[1] != 0x88)
254 eDebug("skip %02x", tmp[0]);
259 int peekLength = (tmp[3] & 0x7f) + 4;
260 if (buffer.size() < peekLength)
262 buffer.peek(tmp, peekLength);
265 int LengthBytes=eDVBCISession::parseLengthField(tmp+3, size);
266 int messageLength = 3+LengthBytes+size;
267 if ( buffer.size() >= messageLength )
269 unsigned char dest[messageLength];
270 buffer.read(dest, messageLength);
273 for (int i=0; i < messageLength; ++i)
274 eDebugNoNewLine("%02x ", dest[i]);
275 eDebug("\n--------");
277 /*emit*/ mmi_progress(0, dest, (const void*)(dest+3+LengthBytes), messageLength-3-LengthBytes);
283 if (what & (POLLERR | POLLHUP)) {
284 eDebug("pollhup/pollerr");
286 /*emit*/ mmi_progress(0, (const unsigned char*)"\x9f\x88\x00", "\x00", 1);
290 void eSocketMMIHandler::closeConn()
309 eSocketMMIHandler::~eSocketMMIHandler()
319 socketmmi_get_socket_state_changed_cb_list(PyObject *self)
321 return eSocket_UI::getInstance()->socketStateChanged.get();
325 socketmmi_set_init(PyObject *self, PyObject *args)
328 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
330 eSocket_UI::getInstance()->setInit(slot);
335 socketmmi_set_reset(PyObject *self, PyObject *args)
338 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
340 eSocket_UI::getInstance()->setReset(slot);
345 socketmmi_available_mmi(PyObject *self, PyObject *args)
348 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
350 return PyInt_FromLong(eSocket_UI::getInstance()->availableMMI(slot));
354 socketmmi_get_mmi_screen(PyObject *self, PyObject *args)
357 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
359 return eSocket_UI::getInstance()->getMMIScreen(slot);
363 socketmmi_start_mmi(PyObject *self, PyObject *args)
366 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
368 return PyInt_FromLong(eSocket_UI::getInstance()->startMMI(slot));
372 socketmmi_stop_mmi(PyObject *self, PyObject *args)
375 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
377 return PyInt_FromLong(eSocket_UI::getInstance()->stopMMI(slot));
381 socketmmi_answer_menu(PyObject *self, PyObject *args)
384 if (PyTuple_Size(args) != 2 || !PyArg_ParseTuple(args, "ii", &slot, &answer))
386 return PyInt_FromLong(eSocket_UI::getInstance()->answerMenu(slot, answer));
390 socketmmi_answer_enq(PyObject *self, PyObject *args)
394 if (PyTuple_Size(args) != 2 || !PyArg_ParseTuple(args, "is", &slot, &answer))
396 return PyInt_FromLong(eSocket_UI::getInstance()->answerEnq(slot, answer));
400 socketmmi_cancel_enq(PyObject *self, PyObject *args)
403 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
405 return PyInt_FromLong(eSocket_UI::getInstance()->cancelEnq(slot));
409 socketmmi_get_state(PyObject *self, PyObject *args)
412 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
414 return PyInt_FromLong(eSocket_UI::getInstance()->getState(slot));
418 socketmmi_get_mmi_state(PyObject *self, PyObject *args)
421 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
423 return PyInt_FromLong(eSocket_UI::getInstance()->getMMIState(slot));
427 socketmmi_get_name(PyObject *self, PyObject *args)
430 if (PyTuple_Size(args) != 1 || !PyArg_ParseTuple(args, "i", &slot))
432 return PyString_FromString(eSocket_UI::getInstance()->getName(slot));
435 static PyMethodDef module_methods[] = {
436 {"getSocketStateChangedCallbackList", (PyCFunction)socketmmi_get_socket_state_changed_cb_list, METH_NOARGS,
437 "get socket state change callback list"
439 {"setInit", (PyCFunction)socketmmi_set_init, METH_VARARGS,
442 {"setReset", (PyCFunction)socketmmi_set_reset, METH_VARARGS,
445 {"availableMMI", (PyCFunction)socketmmi_available_mmi, METH_VARARGS,
448 {"getMMIScreen", (PyCFunction)socketmmi_get_mmi_screen, METH_VARARGS,
451 {"startMMI", (PyCFunction)socketmmi_start_mmi, METH_VARARGS,
454 {"stopMMI", (PyCFunction)socketmmi_stop_mmi, METH_VARARGS,
457 {"answerMenu", (PyCFunction)socketmmi_answer_menu, METH_VARARGS,
460 {"answerEnq", (PyCFunction)socketmmi_answer_enq, METH_VARARGS,
463 {"cancelEnq", (PyCFunction)socketmmi_cancel_enq, METH_VARARGS,
466 {"getState", (PyCFunction)socketmmi_get_state, METH_VARARGS,
467 "get state of socket"
469 {"getMMIState", (PyCFunction)socketmmi_get_mmi_state, METH_VARARGS,
472 {"getName", (PyCFunction)socketmmi_get_name, METH_VARARGS,
473 "get name of socket user"
475 {NULL, NULL, 0, NULL} /* Sentinel */
481 Py_InitModule3("socketmmi", module_methods,
482 "Module that implements mmi via unix domain socket.");