utilities/serviceipcserver/platform/qt/serviceipclocalsocketsession.cpp
changeset 16 3c88a81ff781
equal deleted inserted replaced
14:6aeb7a756187 16:3c88a81ff781
       
     1 /**
       
     2    This file is part of CWRT package **
       
     3 
       
     4    Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). **
       
     5 
       
     6    This program is free software: you can redistribute it and/or modify
       
     7    it under the terms of the GNU (Lesser) General Public License as
       
     8    published by the Free Software Foundation, version 2.1 of the License.
       
     9    This program is distributed in the hope that it will be useful, but
       
    10    WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
       
    12    (Lesser) General Public License for more details. You should have
       
    13    received a copy of the GNU (Lesser) General Public License along
       
    14    with this program. If not, see <http://www.gnu.org/licenses/>.
       
    15 */
       
    16 
       
    17 
       
    18 #include "serviceipclocalsocketsession.h"
       
    19 #include "serviceipcobserver.h"
       
    20 #include "serviceipcrequest.h"
       
    21 #include <QtNetwork>
       
    22 #include <clientinfo.h>
       
    23 
       
    24 namespace WRT
       
    25 {
       
    26 const char KIPCSeparator = ';';
       
    27 const char* REQUEST_COMPLETE_TOKEN = ";ROK";
       
    28 
       
    29 /*!
       
    30  \class LocalSocketSession
       
    31  Class managing local socket server side sessions
       
    32  */
       
    33 
       
    34 /*!
       
    35  Destructor
       
    36  */
       
    37 LocalSocketSession::~LocalSocketSession()
       
    38 {
       
    39     delete m_curRequest;
       
    40     m_curRequest = NULL;
       
    41     if (m_clientInfo) {
       
    42         delete m_clientInfo;
       
    43         m_clientInfo = NULL;
       
    44     }
       
    45 }
       
    46 
       
    47 /*!
       
    48  Constructor
       
    49  @param aNewSocket new socket connection to be handled
       
    50  @param aObserver observer to the IPC module
       
    51  */
       
    52 LocalSocketSession::LocalSocketSession(QLocalSocket* aNewSocket,
       
    53                                        MServiceIPCObserver* aObserver) 
       
    54     : ServiceIPCSession(aObserver)
       
    55     , m_socket(aNewSocket)
       
    56 {
       
    57     // Take ownership of the socket
       
    58     m_socket->setParent(this);
       
    59     QObject::connect(m_socket, SIGNAL( readyRead() ),
       
    60     this, SLOT( handleRequest() ) );
       
    61 
       
    62     QObject::connect(m_socket, SIGNAL( disconnected() ),
       
    63     this, SLOT( handleDisconnect() ) );
       
    64 }
       
    65 
       
    66 /*!
       
    67  Handle a new request
       
    68  */
       
    69 void LocalSocketSession::handleRequest()
       
    70 {
       
    71     // Process data
       
    72     QByteArray data = m_socket->readAll();
       
    73     // TODO: Get Client info
       
    74     ClientInfo *client = new ClientInfo();
       
    75 
       
    76     // New Request
       
    77     if (!m_curRequest) {
       
    78         // Should be very fast, the sperator is at the front
       
    79         int separator = data.indexOf(KIPCSeparator);
       
    80         int separator2 = data.indexOf(KIPCSeparator, separator + 1);
       
    81 
       
    82         // How long is the data, ensure separators are found, ie valid data
       
    83         //
       
    84         if (separator != -1 && separator2 != -1) {
       
    85 
       
    86             bool lengthConverted;
       
    87             QByteArray lengthData = data.left(separator);
       
    88             qint64 length = lengthData.toLong(&lengthConverted);
       
    89             if (lengthConverted) {
       
    90                 // Compute the data 
       
    91                 QByteArray operation = data.mid(separator + 1, separator2
       
    92                                 - separator - 1);
       
    93                 QByteArray requestData = data.right(data.length() - separator2
       
    94                                 - 1);
       
    95 
       
    96                 // New request
       
    97                 delete m_curRequest;
       
    98                 m_curRequest = NULL;
       
    99                 m_curRequest = new ServiceIPCRequest(this, length, operation);
       
   100 
       
   101                 // Call to observer with request if the length is correct
       
   102                 // Otherwise wait until the data packet is re-assembled
       
   103                 //
       
   104                 if (m_curRequest->addRequestdata(requestData)) {
       
   105                     client->setSessionId(m_clientInfo->sessionId());
       
   106                     m_curRequest->setClientInfo(client); // ownership passed
       
   107                     //m_observer->handleRequest(m_curRequest);
       
   108                     handleReq();
       
   109                 }
       
   110             }
       
   111         }
       
   112     }
       
   113     // More data available from the buffer
       
   114     else {
       
   115         // If all the data has been added, call back to the observer
       
   116         //
       
   117         if (m_curRequest->addRequestdata(data)) {
       
   118             m_curRequest->setClientInfo(client); // ownership passed
       
   119             //m_observer->handleRequest(m_curRequest);
       
   120             handleReq();
       
   121         }
       
   122     }
       
   123 }
       
   124 
       
   125 /*!
       
   126  Write data to the socket to send to the client
       
   127  @param aData data to write to the socket
       
   128  */
       
   129 bool LocalSocketSession::write(const QByteArray& aData)
       
   130 {
       
   131     int written = m_socket->write(aData);
       
   132     return (written != -1);
       
   133 }
       
   134 
       
   135 /*!
       
   136  Complete the outstanding IPC request
       
   137  */
       
   138 bool LocalSocketSession::completeRequest()
       
   139 {
       
   140     // Write a request complete token and wait until all data has been written to the socket
       
   141     m_socket->write(REQUEST_COMPLETE_TOKEN);
       
   142     bool done = m_socket->waitForBytesWritten(-1);
       
   143     delete m_curRequest;
       
   144     m_curRequest = NULL;
       
   145     return done;
       
   146 }
       
   147 
       
   148 /*!
       
   149  Handles when a client disconnect
       
   150  This slot function is connected to the underlying QLocalSocket
       
   151  */
       
   152 void LocalSocketSession::handleDisconnect()
       
   153 {
       
   154     if (m_appendToBList) {
       
   155         ((ServiceFwIPCServerLocalSocket*) parent())->removeBroadcastList(m_clientInfo->sessionId());  
       
   156     }
       
   157     doCancelRequest();
       
   158 
       
   159     // Emit signal back to server to cleanup
       
   160     emit disconnected(this);
       
   161     
       
   162     m_observer->handleClientDisconnect(m_clientInfo);
       
   163     
       
   164     ((ServiceFwIPCServerLocalSocket*) parent())->releaseSessionId(m_clientInfo->sessionId()); //release sessionId
       
   165 }
       
   166 
       
   167 /*!
       
   168  Closes and shutsdown the local socket session
       
   169  */
       
   170 void LocalSocketSession::close()
       
   171 {
       
   172     doCancelRequest();
       
   173 
       
   174     // Close the socket connection
       
   175     m_socket->abort();
       
   176 }
       
   177 
       
   178 /*! 
       
   179  Sends the cancel request callback to the client if a request was pending
       
   180  */
       
   181 void LocalSocketSession::doCancelRequest()
       
   182 {
       
   183     // If we had a request pending, make sure the client handles this
       
   184     // gracefully
       
   185     if (m_curRequest) {
       
   186         // TODO: Get client info
       
   187         ClientInfo *client = new ClientInfo();
       
   188         m_curRequest->setClientInfo(client); // ownership passed
       
   189         m_observer->handleCancelRequest(m_curRequest);
       
   190         delete m_curRequest;
       
   191         m_curRequest = NULL;
       
   192     }
       
   193 }
       
   194 
       
   195 }
       
   196 
       
   197 /*!
       
   198  \fn WRT::LocalSocketSession::disconnected( ServiceIPCSession* aSession )
       
   199  
       
   200  Signal emitted when the session has been disconnected by the client
       
   201  @param aSession the session that is disconnected
       
   202  */
       
   203 
       
   204 // END OF FILE