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