1 /** |
|
2 * Copyright (c) 2010 Sasken Communication Technologies Ltd. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html" |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Chandradeep Gandhi, Sasken Communication Technologies Ltd - Initial contribution |
|
11 * |
|
12 * Contributors: |
|
13 * Manasij Roy, Nalina Hariharan |
|
14 * |
|
15 * |
|
16 * Description: Private implementation for Symbian OS |
|
17 * |
|
18 */ |
|
19 #ifdef WRITE_LOG |
|
20 #include <QFile> |
|
21 #include <QTextStream> |
|
22 #endif |
|
23 #include <QDataStream> |
|
24 #include <QStringList> |
|
25 #include <QString> |
|
26 |
|
27 #include "smfserversymbian_p.h" |
|
28 |
|
29 |
|
30 SmfServerSymbian* SmfServerSymbian::NewL(CActive::TPriority aActiveObjectPriority,SmfServer* aWrapper) |
|
31 { |
|
32 SmfServerSymbian* self = new(ELeave) SmfServerSymbian(aActiveObjectPriority,aWrapper); |
|
33 CleanupStack::PushL(self); |
|
34 self->ConstructL(); |
|
35 CleanupStack::Pop(); // self |
|
36 return self; |
|
37 } |
|
38 |
|
39 void SmfServerSymbian::ConstructL() |
|
40 { |
|
41 } |
|
42 |
|
43 |
|
44 SmfServerSymbian::SmfServerSymbian( CActive::TPriority aActiveObjectPriority,SmfServer* aWrapper ) |
|
45 : CPolicyServer(0,myPolicy, ESharableSessions), iWrapper(aWrapper) |
|
46 { |
|
47 Q_UNUSED(aActiveObjectPriority); |
|
48 } |
|
49 |
|
50 |
|
51 |
|
52 TInt SmfServerSymbian::addToSessionMap(SmfServerSymbianSession* aSession,const RMessage2& aMsg) |
|
53 { |
|
54 writeLog("SmfServerSymbian::addToSessionMap"); |
|
55 if(iSessionCount) |
|
56 { |
|
57 //The key generation |
|
58 TInt key = qrand(); |
|
59 //in case qrand generates any duplicate key |
|
60 while(iMap.Find(key)) |
|
61 { |
|
62 key = qrand(); |
|
63 } |
|
64 |
|
65 CSessionStruct session; |
|
66 session.iMsg = aMsg; |
|
67 session.iSession = aSession; |
|
68 iMap.Insert(key,session); |
|
69 |
|
70 return key; |
|
71 } |
|
72 |
|
73 return (-1); |
|
74 } |
|
75 |
|
76 |
|
77 TInt SmfServerSymbian::removeFromSessionMap(SmfServerSymbianSession* aSession,RMessage2& aMsg) |
|
78 { |
|
79 Q_UNUSED(aSession); |
|
80 Q_UNUSED(aMsg); |
|
81 return 0; |
|
82 } |
|
83 |
|
84 //TODO - change this to a macro using qdebug to avoid file opening and closing |
|
85 void SmfServerSymbian::writeLog(QString log) const |
|
86 { |
|
87 #ifdef WRITE_LOG |
|
88 QFile file("c:\\data\\SmfServerLogs.txt"); |
|
89 if (!file.open(QIODevice::Append | QIODevice::Text)) |
|
90 return; |
|
91 QTextStream out(&file); |
|
92 out << log << "\n"; |
|
93 file.close(); |
|
94 #else |
|
95 Q_UNUSED(log) |
|
96 #endif |
|
97 } |
|
98 |
|
99 |
|
100 SmfServerSymbian::~SmfServerSymbian() |
|
101 { |
|
102 |
|
103 } |
|
104 |
|
105 SmfServer* SmfServerSymbian::wrapper() |
|
106 { |
|
107 return iWrapper; |
|
108 } |
|
109 |
|
110 |
|
111 CSession2* SmfServerSymbian::NewSessionL(const TVersion& aVersion, const RMessage2& /*aMessage*/) const |
|
112 { |
|
113 |
|
114 // Check that the version is OK |
|
115 // TVersion v( 0, 1, 0 ); |
|
116 // if (!User::QueryVersionSupported( v, aVersion )) |
|
117 // User::Leave( KErrNotSupported ); |
|
118 // Create the session. |
|
119 Q_UNUSED(aVersion); |
|
120 QString log("New session created"); |
|
121 writeLog(log); |
|
122 return new (ELeave) SmfServerSymbianSession( const_cast<SmfServerSymbian*>(this) ); |
|
123 } |
|
124 |
|
125 SmfServerSymbianSession* SmfServerSymbian::findSession(TInt id) |
|
126 { |
|
127 writeLog("SmfServerSymbian::findSession"); |
|
128 CSessionStruct* sessionStruct = iMap.Find(id); |
|
129 if(sessionStruct) |
|
130 { |
|
131 writeLog("Session id found"); |
|
132 return sessionStruct->iSession; |
|
133 } |
|
134 else |
|
135 { |
|
136 writeLog("Session id not found"); |
|
137 return NULL; |
|
138 } |
|
139 } |
|
140 |
|
141 TInt SmfServerSymbian::findAndServiceclient(TInt requestID,QByteArray* parsedData,SmfError error) |
|
142 { |
|
143 writeLog("SmfServerSymbian::findAndServiceclient"); |
|
144 SmfServerSymbianSession* sessionToservice = findSession(requestID); |
|
145 if(sessionToservice) |
|
146 { |
|
147 sessionToservice->resultsAvailable(parsedData,error); |
|
148 } |
|
149 return 0; |
|
150 } |
|
151 |
|
152 SmfServerSymbianSession::SmfServerSymbianSession(SmfServerSymbian* aServer): |
|
153 iServer(aServer),iPtrToBuf(NULL,0) ,iIntfNmaeSymbian(NULL,0), iProviderSymbian(NULL,0),iIntfNameSymbian16(NULL,0) |
|
154 { |
|
155 iServer->iSessionCount++; |
|
156 } |
|
157 |
|
158 SmfServerSymbianSession::~SmfServerSymbianSession() |
|
159 { |
|
160 //cleanup of client resources |
|
161 iServer->iSessionCount--; |
|
162 } |
|
163 |
|
164 |
|
165 void SmfServerSymbianSession::clientathorizationFinished(bool success) |
|
166 { |
|
167 //Client authorization failed |
|
168 if(!success) |
|
169 { |
|
170 //TODO:- Should use smf wide error instead |
|
171 iMessage.Complete(KErrPermissionDenied); |
|
172 } |
|
173 else |
|
174 { |
|
175 HandleClientMessageL(iMessage); |
|
176 } |
|
177 } |
|
178 |
|
179 |
|
180 void SmfServerSymbianSession::resultsAvailable(QByteArray* parsedData,SmfError error) |
|
181 { |
|
182 |
|
183 //Note:- The order of serialization of parsedData - Error value followed by the data |
|
184 //parsedData is already serialized by PM |
|
185 iServer->writeLog("SmfServerSymbianSession::resultsAvailable"); |
|
186 //We should remove the request from the map as soon its no longer outstanding |
|
187 iServer->removeFromSessionMap(this,iMessage); |
|
188 |
|
189 byteArrayToClnt.clear(); |
|
190 byteArrayToClnt.append(*(parsedData)); |
|
191 iPtrToBuf.Copy(reinterpret_cast<TUint8*>(byteArrayToClnt.data()),byteArrayToClnt.length()); |
|
192 |
|
193 TInt writeErr = iMessage.Write(2,iPtrToBuf); |
|
194 |
|
195 iServer->writeLog("Write="); |
|
196 QString wrErr = QString::number(writeErr); |
|
197 iServer->writeLog(wrErr); |
|
198 |
|
199 //signal completion for the last request |
|
200 iMessage.Complete(error); |
|
201 } |
|
202 |
|
203 |
|
204 void SmfServerSymbianSession::ServiceL(const RMessage2& aMessage) |
|
205 { |
|
206 |
|
207 iServer->writeLog("SmfServerSymbianSession::ServiceL="); |
|
208 iMessage = aMessage ; |
|
209 |
|
210 QString log; |
|
211 log = QString::number(iMessage.Function()); |
|
212 iServer->writeLog(log); |
|
213 |
|
214 SmfClientAuthID clientAuthID; |
|
215 clientAuthID.pid = aMessage.SecureId(); |
|
216 clientAuthID.session = this; |
|
217 //check whether the client is authorized |
|
218 if(!iServer->wrapper()->isClientAuthorized(clientAuthID)) |
|
219 { |
|
220 //Client is yet to be authorized |
|
221 //It should start authorization or simply return err value is yet TBD, so the following code may change |
|
222 //start authorization of client, session will be blocked untill its authorized |
|
223 //HandleclientMessageL will be called in that fn |
|
224 iServer->wrapper()->authorizeClient(clientAuthID); |
|
225 } |
|
226 else |
|
227 { |
|
228 //client is authorized, so proceed |
|
229 HandleClientMessageL(iMessage); |
|
230 } |
|
231 } |
|
232 |
|
233 void SmfServerSymbianSession::HandleClientMessageL(const RMessage2& aMessage) |
|
234 { |
|
235 iServer->writeLog("HandleClientMessageL"); |
|
236 iLastRequest = aMessage.Function(); |
|
237 |
|
238 |
|
239 /**Note:- Only ESmfGetService needs to be taken care separately as it doesn't involve createrequest for PM |
|
240 *See SmfRequestTypeID for list of opcodes |
|
241 * |
|
242 *Two cases,- |
|
243 *1.for ESmfGetServices we donno the provider info |
|
244 *2. for rest of the cases, we know the provider info |
|
245 *so it seems PM needs to provide two overloaded getPlugins API But for every client intf instanciation |
|
246 *we would execute the same things twice. |
|
247 *TODO:- to be changed after GetServices returns SmfProvider+pluginID |
|
248 * |
|
249 */ |
|
250 if(iLastRequest == SmfGetService) |
|
251 { |
|
252 HandleGetService(aMessage); |
|
253 } |
|
254 else |
|
255 { |
|
256 HandleCommonServiceL(aMessage); |
|
257 } |
|
258 } |
|
259 |
|
260 void SmfServerSymbianSession::HandleGetService(const RMessage2 & aMessage) |
|
261 { |
|
262 iServer->writeLog("SmfServerSymbianSession::HandleGetService"); |
|
263 /** |
|
264 * Note:- client sends message for this opcode in the following format,- |
|
265 * Slot 0:- Interface Name buffer |
|
266 * Slot 1:- Ptr to data block to be filled with SmfProvideList* serialized into QByteArray |
|
267 */ |
|
268 iInterfaceNametbuf.Zero(); |
|
269 |
|
270 TInt readerr = aMessage.Read(0,iInterfaceNametbuf); |
|
271 |
|
272 iServer->writeLog(QString::number(readerr)); |
|
273 |
|
274 QByteArray bytearray(reinterpret_cast<const char*>(iInterfaceNametbuf.Ptr()),iInterfaceNametbuf.Length()) ; |
|
275 QDataStream stream3(&bytearray,QIODevice::ReadOnly); |
|
276 stream3>>iInterfaceID; |
|
277 |
|
278 iServer->writeLog("iInterfaceID="); |
|
279 iServer->writeLog(iInterfaceID); |
|
280 |
|
281 iServer->wrapper()->getPlugins(iInterfaceID,iPluginIDMap); |
|
282 //form the plugin id list from the map |
|
283 QMapIterator<SmfPluginID, SmfProvider> iter(iPluginIDMap); |
|
284 iPluginIDList.clear(); |
|
285 while (iter.hasNext()) |
|
286 { |
|
287 iter.next(); |
|
288 iPluginIDList<<iter.key(); |
|
289 } |
|
290 |
|
291 //iAuthList will be filled by credential manager |
|
292 iServer->wrapper()->getAuthorizedPlugins(iPluginIDList,iAuthList); |
|
293 |
|
294 //iPluginIDMap now contains SmfProvider info to return to the client |
|
295 //No need to add this to session map, as we are not requesting PM for this |
|
296 QMap<SmfPluginID, SmfProvider> tempMap; |
|
297 QMapIterator<SmfPluginID, SmfProvider> i(iPluginIDMap); |
|
298 |
|
299 while (i.hasNext()) |
|
300 { |
|
301 i.next(); |
|
302 if(iAuthList.contains(i.key())) |
|
303 { |
|
304 tempMap.insert(i.key(),i.value()); |
|
305 } |
|
306 } |
|
307 |
|
308 iPluginIDMap.clear(); |
|
309 iPluginIDMap = tempMap; |
|
310 |
|
311 //form list of smfprovider from this map,- |
|
312 QList<SmfProvider> providerList; |
|
313 i = iPluginIDMap; |
|
314 while(i.hasNext()) |
|
315 { |
|
316 i.next(); |
|
317 providerList.append(i.value()); |
|
318 } |
|
319 |
|
320 byteArrayToClnt.clear(); |
|
321 QDataStream stream(&byteArrayToClnt,QIODevice::WriteOnly); |
|
322 stream<<providerList; |
|
323 |
|
324 iPtrToBuf.Copy(reinterpret_cast<TUint8*>(byteArrayToClnt.data()),byteArrayToClnt.length()); |
|
325 TInt writeErr = aMessage.Write(1,iPtrToBuf); |
|
326 |
|
327 iServer->writeLog("Write="); |
|
328 QString wrErr = QString::number(writeErr); |
|
329 iServer->writeLog(wrErr); |
|
330 //signal completion |
|
331 |
|
332 TInt completion = SmfGetServiceComplete ; |
|
333 aMessage.Complete(completion); |
|
334 } |
|
335 |
|
336 void SmfServerSymbianSession::HandleCommonServiceL(const RMessage2& aMessage) |
|
337 { |
|
338 /** |
|
339 * Note:- client sends message in the following format,- |
|
340 * Slot 0:- SmfProvider* serialized |
|
341 * Slot 1:- Interface Name buffer |
|
342 * Slot 2:- Ptr to data block to be filled |
|
343 */ |
|
344 TInt providerSize = aMessage.GetDesLength(0); |
|
345 if(iProviderBuf) |
|
346 { |
|
347 delete iProviderBuf; |
|
348 iProviderBuf = NULL; |
|
349 } |
|
350 iProviderBuf = HBufC8::NewL(providerSize); |
|
351 iProviderSymbian.Set(iProviderBuf->Des()); |
|
352 |
|
353 TInt intfNameSize = aMessage.GetDesLength(1); |
|
354 if(iIntfNameBuf) |
|
355 { |
|
356 delete iIntfNameBuf; |
|
357 iIntfNameBuf = NULL; |
|
358 } |
|
359 iIntfNameBuf = HBufC8::NewL(intfNameSize*2);//for safeside |
|
360 iIntfNmaeSymbian.Set(iIntfNameBuf->Des()); |
|
361 |
|
362 |
|
363 //read it into iProviderSymbian |
|
364 aMessage.ReadL(0,iProviderSymbian); |
|
365 //read it into iIntfNmaeSymbian |
|
366 aMessage.ReadL(1,iIntfNmaeSymbian); |
|
367 |
|
368 //convert SmfProvider info from Symbian into bytearray |
|
369 QByteArray providerBufQt(reinterpret_cast<const char*>(iProviderSymbian.Ptr()),iProviderSymbian.Length()); |
|
370 iServer->writeLog("After providerBufQt"); |
|
371 |
|
372 //now de-serialize it |
|
373 QDataStream stream(&providerBufQt,QIODevice::ReadOnly); |
|
374 SmfProvider provider; |
|
375 stream>>provider ; |
|
376 QByteArray bytearray(reinterpret_cast<const char*>(iIntfNmaeSymbian.Ptr()),iIntfNmaeSymbian.Length()) ; |
|
377 QDataStream intfNameStream(&bytearray,QIODevice::ReadOnly); |
|
378 iInterfaceID.clear(); |
|
379 intfNameStream>>iInterfaceID; |
|
380 |
|
381 iServer->writeLog("After de-serializing into iInterfaceID="); |
|
382 iServer->writeLog(iInterfaceID); |
|
383 |
|
384 //Get the plugin ID who matches provider info for a given intf name |
|
385 SmfPluginID pluginID = iServer->wrapper()->getPlugin(iInterfaceID,provider); |
|
386 |
|
387 iServer->writeLog("pluginID from PM="); |
|
388 iServer->writeLog(pluginID); |
|
389 |
|
390 iPluginIDList.clear(); |
|
391 //we need to check only this pluginID is authorized |
|
392 iPluginIDList<<pluginID; |
|
393 |
|
394 //iAuthList will contain pluginID for a successfull case |
|
395 iAuthList.clear(); |
|
396 iServer->wrapper()->getAuthorizedPlugins(iPluginIDList,iAuthList); |
|
397 if(iAuthList.contains(pluginID)) |
|
398 { |
|
399 //Plugin ID is authorised, service the request |
|
400 //Gnerate request id only if the plugin ID is authorised |
|
401 TInt id = iServer->addToSessionMap(this,aMessage); |
|
402 //request PM to get the data |
|
403 SmfRequestTypeID opcode = (SmfRequestTypeID)iLastRequest; |
|
404 iServer->wrapper()->getRequestedData(id,pluginID,iInterfaceID,opcode,providerBufQt); |
|
405 } |
|
406 else |
|
407 { |
|
408 //TODO:-Plugin ID is not authorized, throw some error |
|
409 } |
|
410 } |
|