utilities/serviceipcserver/platform/qt/serviceipcserverlocalsocket.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 "serviceipcserverlocalsocket_p.h"
       
    20 #include "serviceipcserver.h"
       
    21 #include <QLocalSocket>
       
    22 #include <QLocalServer>
       
    23 #include <serviceipcdefs.h>
       
    24 #include <clientinfo.h>
       
    25 
       
    26 namespace WRT
       
    27 {
       
    28 /*!
       
    29  \class ServiceFwIPCServerLocalSocket
       
    30  Service Framework IPC Server using QLocalSocket
       
    31  */
       
    32 
       
    33 /*!
       
    34  Constructor
       
    35  @param aParent parent to this object
       
    36  */
       
    37 ServiceFwIPCServerLocalSocket::ServiceFwIPCServerLocalSocket(QObject* aParent) 
       
    38     : QObject(aParent)
       
    39     , m_Listener(NULL)
       
    40 {
       
    41     m_Listener = new QLocalServer(this);
       
    42     QObject::connect(m_Listener, SIGNAL(newConnection()),
       
    43     this, SLOT(handleNewConnection()) );
       
    44     m_isValidSession = true;
       
    45     m_isKeepServer = false;
       
    46     m_sessionIdTable = new SessionIdTable();
       
    47 }
       
    48 
       
    49 /*!
       
    50  Destructor
       
    51  */
       
    52 ServiceFwIPCServerLocalSocket::~ServiceFwIPCServerLocalSocket()
       
    53 {
       
    54     m_Listener->close();
       
    55     if(m_isValidSession){
       
    56         char* data = (char*) m_SharedMem.data();
       
    57         if (data) {
       
    58             strcpy(data, SERVERNOTSTARTED);
       
    59         }
       
    60     }
       
    61     m_SharedMem.detach();
       
    62 
       
    63     delete m_sessionIdTable;
       
    64 }
       
    65 
       
    66 /*!
       
    67  Start listening for new service requests
       
    68  @param aServerName name of this server
       
    69  @return true if listen was successful
       
    70  */
       
    71 bool ServiceFwIPCServerLocalSocket::listen(const QString& aServerName)
       
    72 {
       
    73     m_isValidSession = false; 
       
    74     bool firstLaunch(false);
       
    75     // Create the global chunk that this process owns
       
    76     m_SharedMem.setKey(aServerName);
       
    77 
       
    78     if (!m_SharedMem.attach()) {
       
    79         // Single byte of data + \0
       
    80         m_SharedMem.create(2);
       
    81         firstLaunch = true;
       
    82     }
       
    83 
       
    84     // Initial data is 0, ie server not started
       
    85     // Check if data is NULL, this handles the case where shared mem cannot attach or create
       
    86     //
       
    87     char* data = (char*) m_SharedMem.data();
       
    88     if ((data && (strcmp(data, SERVERNOTSTARTED)==0)) || firstLaunch) {
       
    89         strcpy(data, SERVERNOTSTARTED);
       
    90 
       
    91         //Try to listen
       
    92         for (int i=2; i>0; i--) {
       
    93             m_isValidSession = m_Listener->listen(aServerName);
       
    94             if (m_isValidSession) {
       
    95                 // Server started flag
       
    96                 strcpy(data, SERVERSTARTED);
       
    97                 break;
       
    98             } else {
       
    99                 QLocalServer::removeServer(aServerName);        
       
   100             }
       
   101         }
       
   102 
       
   103         // Signal the client to continue and that server is started
       
   104         QSystemSemaphore sem(aServerName + SERVERSEM, 0);
       
   105         sem.release(1);
       
   106     }
       
   107     return m_isValidSession;
       
   108 }
       
   109 
       
   110 /*!
       
   111  Shutdown the server and stop serving clients 
       
   112  @return void
       
   113  */
       
   114 void ServiceFwIPCServerLocalSocket::disconnect()
       
   115 {
       
   116     m_Listener->close();
       
   117 
       
   118     // Clean up all sessions
       
   119     int count = m_Sessions.count();
       
   120     for (int i = 0; i < count; ++i) {
       
   121         QObject::disconnect(m_Sessions[i], SIGNAL(disconnected( ServiceIPCSession* ) ),
       
   122         this, SLOT( handleSessionDisconnect( ServiceIPCSession* ) ) );
       
   123         m_Sessions[i]->close();
       
   124         delete m_Sessions[i];
       
   125     }
       
   126     m_Sessions.clear();
       
   127 }
       
   128 
       
   129 /*!
       
   130  Handle a new connection, this slot is connected to the socket's newConnection() signal
       
   131  @return void
       
   132  */
       
   133 void ServiceFwIPCServerLocalSocket::handleNewConnection()
       
   134 {
       
   135     // Create a new session to host the client
       
   136     //
       
   137     QLocalSocket* newSocket = m_Listener->nextPendingConnection();
       
   138     ServiceIPCSession* session = new LocalSocketSession(newSocket, Observer());
       
   139     if (session) {
       
   140         session->setParent(this);
       
   141 
       
   142         QObject::connect(session, SIGNAL(disconnected( ServiceIPCSession* ) ),
       
   143         this, SLOT( handleSessionDisconnect( ServiceIPCSession* ) ) );
       
   144         m_Sessions.append(session);
       
   145         stopExitTimer(); 
       
   146 
       
   147         ClientInfo *client = new ClientInfo();
       
   148         client->setSessionId(m_sessionIdTable->allocate());
       
   149         session->setClientInfo(client);
       
   150     }
       
   151 }
       
   152 
       
   153 /*!
       
   154  Handle the end of a session
       
   155  @param aSession session to be disconnected
       
   156  */
       
   157 void ServiceFwIPCServerLocalSocket::handleSessionDisconnect(ServiceIPCSession* aSession)
       
   158 {
       
   159     int c = m_Sessions.removeAll(aSession);
       
   160 
       
   161     if ((m_Sessions.count() == 0) && (!m_isKeepServer)) {
       
   162         startExitTimer(); 
       
   163     }  
       
   164 
       
   165     qDebug() << "Session cleaned up: " << c;
       
   166 }
       
   167  
       
   168 /*!
       
   169  Config IPC server Life time \n
       
   170  Start the shutdown timer if it is the last session and aKeepServer is trues.
       
   171  @param aKeepLife to keep or disconnect IPC server when all clients are shutdown. 
       
   172 */
       
   173 void ServiceFwIPCServerLocalSocket::configIpcServerLifetime(bool aKeepServer)
       
   174 {
       
   175     if ((m_isKeepServer) && (m_Sessions.count() == 0) && (!aKeepServer)) {
       
   176         startExitTimer(); 
       
   177     }  
       
   178     m_isKeepServer = aKeepServer;
       
   179 }
       
   180 }
       
   181 // END OF FILE