qthighway/xqservice/src/xqservicethreaddata.cpp
branchRCL_3
changeset 10 cd2778e5acfe
parent 9 5d007b20cfd0
child 11 19a54be74e5e
equal deleted inserted replaced
9:5d007b20cfd0 10:cd2778e5acfe
     1 /*
       
     2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 *
       
     5 * This program is free software: you can redistribute it and/or modify
       
     6 * it under the terms of the GNU Lesser General Public License as published by
       
     7 * the Free Software Foundation, version 2.1 of the License.
       
     8 * 
       
     9 * This program is distributed in the hope that it will be useful,
       
    10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
       
    12 * GNU Lesser General Public License for more details.
       
    13 *
       
    14 * You should have received a copy of the GNU Lesser General Public License
       
    15 * along with this program.  If not, 
       
    16 * see "http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html/".
       
    17 *
       
    18 * Description:                                                         
       
    19 *
       
    20 */
       
    21 
       
    22 #include "xqservicelog.h"
       
    23 
       
    24 #include "xqservicethreaddata.h"
       
    25 #include "xqservicechannel.h"
       
    26 #include "xqserviceipcclient.h"
       
    27 
       
    28 #include <QThreadStorage>
       
    29 #include <qthread.h>
       
    30 
       
    31 #ifndef QT_NO_THREAD
       
    32 
       
    33 static QThreadStorage<XQServiceThreadData *> xqserviceThreadStorage;
       
    34 
       
    35 XQServiceThreadData *XQService::serviceThreadData()
       
    36 {
       
    37     XQSERVICE_DEBUG_PRINT("XQService::serviceThreadData");
       
    38     if (!xqserviceThreadStorage.hasLocalData()) {
       
    39         xqserviceThreadStorage.setLocalData(new XQServiceThreadData());
       
    40     }
       
    41     return xqserviceThreadStorage.localData() ;
       
    42 }
       
    43 
       
    44 #else
       
    45 
       
    46 Q_GLOBAL_STATIC(XQServiceThreadData, serviceThreadData);
       
    47 
       
    48 #endif
       
    49 
       
    50 
       
    51 XQServiceThreadData *XQServiceThreadData::instance()
       
    52 {
       
    53     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::instance");
       
    54     return XQService::serviceThreadData();
       
    55 }
       
    56 
       
    57 XQServiceThreadData::~XQServiceThreadData()
       
    58 {
       
    59     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::~XQServiceThreadData");
       
    60     qDeleteAll(ipcConnMap);
       
    61     ipcConnMap.clear();
       
    62 }
       
    63 
       
    64 QString XQServiceThreadData::getIpcConnectioName(const QString& channel)
       
    65 {
       
    66     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::getIpcConnectioName");
       
    67     XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel));
       
    68 /*
       
    69     // name of the connection is the name of application without interface
       
    70     int pos = channel.lastIndexOf('.');
       
    71     return pos != -1 ? channel.left(pos) : channel;
       
    72 */
       
    73     //TODO: this should avoid to have multiple connection in the same application if provide multiple interfaces
       
    74     return channel;
       
    75 }
       
    76 
       
    77 // Get the client connection object for this thread.
       
    78 bool XQServiceThreadData::createClientConnection(const QString& channel, bool isServer, 
       
    79                                                  bool isSync, XQServiceRequestCompletedAsync* rc,
       
    80                                                 const void *userData)
       
    81 {
       
    82     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::createClientConnection start");
       
    83     XQSERVICE_DEBUG_PRINT("channel: %s, isServer: %d, isSync: %d", qPrintable(channel), isServer, isSync);
       
    84     XQSERVICE_DEBUG_PRINT("userdata: %x", (int)userData);
       
    85     
       
    86     QString ipcConName = getIpcConnectioName(channel);
       
    87     XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName));
       
    88     XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName);
       
    89     if (it == ipcConnMap.end()) {
       
    90         XQSERVICE_DEBUG_PRINT("Create new connection");
       
    91         // userData may be NULL !
       
    92         XQServiceIpcClient* conn = new XQServiceIpcClient(ipcConName,isServer,isSync,rc, userData);
       
    93         if (conn) {
       
    94             XQSERVICE_DEBUG_PRINT("conn created");
       
    95             bool ret=true;
       
    96             if (isServer) {
       
    97                 XQSERVICE_DEBUG_PRINT("Listen server");
       
    98                 ret=conn->listen();
       
    99             }
       
   100             else {
       
   101                 XQSERVICE_DEBUG_PRINT("Connect to server");
       
   102                 ret=conn->connectToServer();        
       
   103             }
       
   104             if (ret) {
       
   105                 XQSERVICE_DEBUG_PRINT("Add connection to mapping");
       
   106                 it = ipcConnMap.insert(ipcConName, conn);
       
   107             }
       
   108             else {
       
   109                 XQSERVICE_DEBUG_PRINT("Couldn't connect");
       
   110                 delete conn;        
       
   111             }
       
   112             XQSERVICE_DEBUG_PRINT("\t ret: %d", ret);
       
   113             XQSERVICE_DEBUG_PRINT("XQServiceThreadData::createClientConnection end (1)");
       
   114             return ret;
       
   115         }
       
   116     }
       
   117     
       
   118     XQSERVICE_DEBUG_PRINT("\t Connection already exists or creation failed");
       
   119     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::createClientConnection end (2)");
       
   120     return false;
       
   121 }
       
   122 
       
   123 // Get the client connection object for this thread.
       
   124 XQServiceIpcClient *XQServiceThreadData::clientConnection(const QString& channel)
       
   125 {
       
   126     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::clientConnection");
       
   127     XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel));
       
   128     QString ipcConName = getIpcConnectioName(channel);
       
   129     XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName));
       
   130     XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName);
       
   131     if (it == ipcConnMap.end()) {
       
   132         XQSERVICE_DEBUG_PRINT("No client connection");
       
   133         return NULL;
       
   134     }
       
   135     return it.value();
       
   136 }
       
   137 
       
   138 void XQServiceThreadData::closeClientConnection(const QString& channel)
       
   139 {
       
   140     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::closeClientConnection");
       
   141     XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel));
       
   142     QString ipcConName = getIpcConnectioName(channel);
       
   143     XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName));
       
   144     XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName);
       
   145     if (it != ipcConnMap.end()) {
       
   146         XQSERVICE_DEBUG_PRINT("disconnect");
       
   147         it.value()->disconnected();
       
   148         ipcConnMap.erase(it);
       
   149     }
       
   150 }
       
   151 
       
   152 // Determine if we have a client connection object for this thread.
       
   153 bool XQServiceThreadData::hasClientConnection(const QString& channel)
       
   154 {
       
   155     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::hasClientConnection");
       
   156     XQSERVICE_DEBUG_PRINT("channel: %s", qPrintable(channel));
       
   157     QString ipcConName = getIpcConnectioName(channel);
       
   158     XQSERVICE_DEBUG_PRINT("ipcConName: %s", qPrintable(ipcConName));
       
   159     XQServiceIpcClientMap::Iterator it = ipcConnMap.find(ipcConName);
       
   160     XQSERVICE_DEBUG_PRINT("hasClientConnection: %d", it != ipcConnMap.end());
       
   161     return it != ipcConnMap.end();
       
   162 }
       
   163 
       
   164 int XQServiceThreadData::latestError()
       
   165 {
       
   166     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::latestError");
       
   167     XQSERVICE_DEBUG_PRINT("m_latestError: %d", m_latestError);
       
   168     return m_latestError;
       
   169 }
       
   170 
       
   171 void XQServiceThreadData::setLatestError(int latestError)
       
   172 {
       
   173     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::setLatestError %d", latestError);
       
   174     m_latestError = latestError;
       
   175 }
       
   176 
       
   177 QByteArray XQServiceThreadData::serializeRetData(const QVariant &value, int error)
       
   178 {
       
   179     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::serializeRetData");
       
   180     XQSERVICE_DEBUG_PRINT("value type: %d, null?=%d, valid?=%d, error: %d", value.type(), value.isNull(), value.isValid(), error);
       
   181     QByteArray array;
       
   182     // if (!value.isNull() && (value.type() != QVariant::Invalid)) {    maparnan
       
   183     if (value.isValid()) {    // 
       
   184         QDataStream stream(&array, QIODevice::WriteOnly | QIODevice::Append);
       
   185         
       
   186         stream << CmdRetData;
       
   187         stream << value;
       
   188     }
       
   189     else {
       
   190         if (error)
       
   191             {
       
   192             QVariant value(error);
       
   193             QDataStream stream(&array, 
       
   194                         QIODevice::WriteOnly | QIODevice::Append);
       
   195             stream << CmdErrData;
       
   196             stream << value;
       
   197             }
       
   198         }
       
   199     return array;
       
   200 }
       
   201 
       
   202 QVariant XQServiceThreadData::deserializeRetData(const QByteArray &retData)
       
   203 {
       
   204     XQSERVICE_DEBUG_PRINT("XQServiceThreadData::deserializeRetData");
       
   205     XQSERVICE_DEBUG_PRINT("retData: %s", retData.constData());
       
   206     if (retData.length()) 
       
   207         {
       
   208         QDataStream stream(retData);
       
   209         int cmd ;
       
   210         stream >> cmd ;
       
   211         if (cmd == CmdRetData) 
       
   212             {
       
   213             QVariant retServiceData(stream);
       
   214             return retServiceData;
       
   215         }
       
   216         else
       
   217             {
       
   218             if (cmd == CmdErrData)
       
   219                 {
       
   220                 QVariant retServiceData(stream);
       
   221                 int error = retServiceData.toInt();
       
   222                 XQService::serviceThreadData()->setLatestError(error);
       
   223                 }
       
   224             }
       
   225     }
       
   226     return QVariant();
       
   227 }