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 } |
|