From 2aef8d2784813195c7a888d2be77af3fbc392615 Mon Sep 17 00:00:00 2001 From: Andreas Monzner Date: Fri, 23 Nov 2007 18:26:34 +0000 Subject: [PATCH 1/1] add missing files --- lib/mmi/socket_mmi.cpp | 314 +++++++++++++++++++++++++++++++++++++++++ lib/mmi/socket_mmi.h | 0 2 files changed, 314 insertions(+) create mode 100644 lib/mmi/socket_mmi.cpp create mode 100644 lib/mmi/socket_mmi.h diff --git a/lib/mmi/socket_mmi.cpp b/lib/mmi/socket_mmi.cpp new file mode 100644 index 00000000..d91c83ff --- /dev/null +++ b/lib/mmi/socket_mmi.cpp @@ -0,0 +1,314 @@ +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#define MAX_LENGTH_BYTES 4 +#define MIN_LENGTH_BYTES 1 +#define MMIDEBUG + +eSocket_UI *eSocket_UI::instance; + +eSocket_UI::eSocket_UI() + :eMMI_UI(1) +{ + ASSERT(!instance); + instance = this; + CONNECT(handler.mmi_progress, eMMI_UI::processMMIData); +} + +eSocket_UI *eSocket_UI::getInstance() +{ + return instance; +} + +void eSocket_UI::setInit(int slot) +{ + //NYI +} + +void eSocket_UI::setReset(int slot) +{ + //NYI +} + +int eSocket_UI::startMMI(int slot) +{ + unsigned char buf[]={0x9F,0x80,0x22,0x00}; // ENTER MMI + if (handler.send_to_mmisock( buf, 4 )) + { + eDebug("eSocket_UI::startMMI failed"); + return -1; + } + return 0; +} + +int eSocket_UI::stopMMI(int slot) +{ + unsigned char buf[]={0x9F,0x88,0x00,0x00}; // CLOSE MMI + if (handler.send_to_mmisock( buf, 4 )) + { + eDebug("eSocket_UI::stopMMI failed"); + return -1; + } + return 0; +} + +int eSocket_UI::answerMenu(int slot, int answer) +{ + unsigned char data[]={0x9f,0x88,0x0B,0x01,0x00}; + data[4] = answer & 0xff; + if (handler.send_to_mmisock( data, 5 )) + { + eDebug("eSocket_UI::answerMenu failed"); + return -1; + } + return 0; +} + +int eSocket_UI::answerEnq(int slot, char *answer) +{ + unsigned int len = strlen(answer); + unsigned char data[4+len+MAX_LENGTH_BYTES]; + data[0] = 0x9f; + data[1] = 0x88; + data[2] = 0x08; + int LengthBytes=eDVBCISession::buildLengthField(data+3, len+1); + data[3+LengthBytes] = 0x01; + memcpy(data+4+LengthBytes, answer, len); + if (handler.send_to_mmisock( data, len+4+LengthBytes )) + { + eDebug("eSocket_UI::answerEnq failed"); + return -1; + } + return 0; +} + +int eSocket_UI::cancelEnq(int slot) +{ + unsigned char data[]={0x9f,0x88,0x08,0x01,0x00}; + if (handler.send_to_mmisock( data, 5 )) + { + eDebug("eSocket_UI::cancelEnq failed"); + return -1; + } + return 0; +} + +int eSocket_UI::getState(int slot) +{ + return handler.connected() ? 2 : 0; +} + +int eSocket_UI::getMMIState(int slot) +{ + return handler.connected(); +} + +//FIXME: correct "run/startlevel" +eAutoInitP0 init_socketui(eAutoInitNumbers::rc, "Socket MMI"); + +int eSocketMMIHandler::send_to_mmisock( void* buf, size_t len) +{ + int ret = write(connfd, buf, len); + if ( ret < 0 ) + eDebug("[eSocketMMIHandler] write (%m)"); + else if ( (uint)ret != len ) + eDebug("[eSocketMMIHandler] only %d bytes sent.. %d bytes should be sent", ret, len ); + else + return 0; + return ret; +} + +eSocketMMIHandler::eSocketMMIHandler() + :buffer(512), connfd(-1), connsn(0), sockname("/tmp/mmi.socket"), name(0) +{ + memset(&servaddr, 0, sizeof(struct sockaddr_un)); + servaddr.sun_family = AF_UNIX; + unlink(sockname); + strcpy(servaddr.sun_path, sockname); + clilen = sizeof(servaddr.sun_family) + strlen(servaddr.sun_path); + if ((listenfd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) + { + eDebug("[eSocketMMIHandler] socket (%m)"); + return; + } + + int val = 1; + if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)) == -1) + eDebug("[eSocketMMIHandler] SO_REUSEADDR (%m)"); + else if ((val = fcntl(listenfd, F_GETFL)) == -1) + eDebug("[eSocketMMIHandler] F_GETFL (%m)"); + else if (fcntl(listenfd, F_SETFL, val | O_NONBLOCK) == -1) + eDebug("[eSocketMMIHandler] F_SETFL (%m)"); + else if (bind(listenfd, (struct sockaddr *) &servaddr, clilen) == -1) + eDebug("[eSocketMMIHandler] bind (%m)"); + else if (listen(listenfd, 0) == -1) + eDebug("[eSocketMMIHandler] listen (%m)"); + else { + listensn = new eSocketNotifier( eApp, listenfd, POLLIN ); + listensn->start(); + CONNECT( listensn->activated, eSocketMMIHandler::listenDataAvail ); + eDebug("[eSocketMMIHandler] created successfully"); + return; + } + + close(listenfd); + listenfd = -1; +} + +#define CMD_SET_NAME "\x01\x02\x03\x04" + +void eSocketMMIHandler::listenDataAvail(int what) +{ + if (what & POLLIN) { + if ( connsn ) { + eDebug("[eSocketMMIHandler] connsn != NULL"); + return; + } + connfd = accept(listenfd, (struct sockaddr *) &servaddr, (socklen_t *) &clilen); + if (connfd == -1) { + eDebug("[eSocketMMIHandler] accept (%m)"); + return; + } + + int val; + if ((val = fcntl(connfd, F_GETFL)) == -1) + eDebug("[eSocketMMIHandler] F_GETFL (%m)"); + else if (fcntl(connfd, F_SETFL, val | O_NONBLOCK) == -1) + eDebug("[eSocketMMIHandler] F_SETFL (%m)"); + else { + connsn = new eSocketNotifier( eApp, connfd, POLLIN|POLLHUP|POLLERR ); + CONNECT( connsn->activated, eSocketMMIHandler::connDataAvail ); + return; + } + + close(connfd); + connfd = -1; + } +} + +void eSocketMMIHandler::connDataAvail(int what) +{ + if (what & (POLLIN | POLLPRI | POLLRDNORM | POLLRDBAND)) { + char msgbuffer[4096]; + ssize_t length = read(connfd, msgbuffer, sizeof(msgbuffer)); + + if (length == -1) { + if (errno != EAGAIN) { + eDebug("[eSocketMMIHandler] read (%m)"); + what |= POLLERR; + } + } else if (length == 0){ + what |= POLLHUP; + } else if ((!name) && (length > 4) && (!memcmp(msgbuffer, CMD_SET_NAME, 4))) { + length -= 4; + delete [] name; + name = new char[length + 1]; + memcpy(name, &msgbuffer[4], length); + name[length] = '\0'; + eDebug("MMI NAME %s", name); + } else { + int len = length; + unsigned char *data = (unsigned char*)msgbuffer; + int clear = 1; + // If a new message starts, then the previous message + // should already have been processed. Otherwise the + // previous message was incomplete and should therefore + // be deleted. + if ((len >= 1) && (data[0] != 0x9f)) + clear = 0; + if ((len >= 2) && (data[1] != 0x88)) + clear = 0; + if (clear) + { + buffer.clear(); +#ifdef MMIDEBUG + eDebug("clear buffer"); +#endif + } +#ifdef MMIDEBUG + eDebug("Put to buffer:"); + for (int i=0; i < len; ++i) + eDebugNoNewLine("%02x ", data[i]); + eDebug("\n--------"); +#endif + buffer.write( data, len ); + + while ( buffer.size() >= (3 + MIN_LENGTH_BYTES) ) + { + unsigned char tmp[3+MAX_LENGTH_BYTES]; + buffer.peek(tmp, 3+MIN_LENGTH_BYTES); + if (tmp[0] != 0x9f || tmp[1] != 0x88) + { + buffer.skip(1); +#ifdef MMIDEBUG + eDebug("skip %02x", tmp[0]); +#endif + continue; + } + if (tmp[3] & 0x80) { + int peekLength = (tmp[3] & 0x7f) + 4; + if (buffer.size() < peekLength) + continue; + buffer.peek(tmp, peekLength); + } + int size=0; + int LengthBytes=eDVBCISession::parseLengthField(tmp+3, size); + int messageLength = 3+LengthBytes+size; + if ( buffer.size() >= messageLength ) + { + unsigned char dest[messageLength]; + buffer.read(dest, messageLength); +#ifdef MMIDEBUG + eDebug("dump mmi:"); + for (int i=0; i < messageLength; ++i) + eDebugNoNewLine("%02x ", dest[i]); + eDebug("\n--------"); +#endif + /*emit*/ mmi_progress(0, dest, (const void*)(dest+3+LengthBytes), messageLength-3-LengthBytes); + } + } + } + } + + if (what & (POLLERR | POLLHUP)) { + eDebug("pollhup/pollerr"); + closeConn(); + /*emit*/ mmi_progress(0, (const unsigned char*)"\x9f\x88\x00", "\x00", 1); + } +} + +void eSocketMMIHandler::closeConn() +{ + if ( connfd != -1 ) + { + close(connfd); + connfd=-1; + } + if ( connsn ) + { + delete connsn; + connsn=0; + } + if ( name ) + { + delete [] name; + name=0; + } +} + +eSocketMMIHandler::~eSocketMMIHandler() +{ + closeConn(); + delete listensn; + unlink(sockname); +} diff --git a/lib/mmi/socket_mmi.h b/lib/mmi/socket_mmi.h new file mode 100644 index 00000000..e69de29b -- 2.30.2