|
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 #include "smfclientsymbian.h" |
|
17 #include <e32cmn.h> |
|
18 #include <QtGlobal> |
|
19 #include <e32svr.h> |
|
20 #include <e32base.h> |
|
21 #include <QByteArray> |
|
22 #include "smfglobal.h" |
|
23 #include "smfclientglobal.h" |
|
24 //testing purpose |
|
25 #include <QProcess> |
|
26 #include <QTextStream> |
|
27 #include <QFile> |
|
28 //testing end |
|
29 // For starting the server process |
|
30 static TInt StartServerL(); |
|
31 static TInt CreateServerProcessL(); |
|
32 |
|
33 CSmfClientSymbian::CSmfClientSymbian(smfObserver* aObserver) |
|
34 : iObserver(aObserver),CActive( EPriorityStandard ),iDataPtr(NULL, 0, 0) |
|
35 { |
|
36 CActiveScheduler::Add(this); |
|
37 } |
|
38 |
|
39 CSmfClientSymbian* CSmfClientSymbian::NewL(smfObserver* aObserver ) |
|
40 { |
|
41 CSmfClientSymbian* self = NewLC( aObserver ); |
|
42 CleanupStack::Pop( self ); |
|
43 return( self ) ; |
|
44 } |
|
45 |
|
46 CSmfClientSymbian* CSmfClientSymbian::NewLC(smfObserver* aObserver ) |
|
47 { |
|
48 CSmfClientSymbian* self = |
|
49 new ( ELeave ) CSmfClientSymbian( aObserver ); |
|
50 CleanupStack::PushL( self ); |
|
51 self->ConstructL(); |
|
52 return self; |
|
53 } |
|
54 |
|
55 void CSmfClientSymbian::ConstructL() |
|
56 { |
|
57 writeLog("CSmfClientSymbian::ConstructL"); |
|
58 |
|
59 User::LeaveIfError(iSession.connectToServer()); |
|
60 } |
|
61 void CSmfClientSymbian::writeLog(QString log) |
|
62 { |
|
63 #ifdef WRITE_LOG |
|
64 QFile file("c:\\data\\SmfClientLogs.txt"); |
|
65 if (!file.open(QIODevice::Append | QIODevice::Text)) |
|
66 return; |
|
67 QTextStream out(&file); |
|
68 out << log << "\n"; |
|
69 file.close(); |
|
70 #endif |
|
71 } |
|
72 |
|
73 void CSmfClientSymbian::DoCancel() |
|
74 { |
|
75 Cancel(); |
|
76 } |
|
77 |
|
78 TInt CSmfClientSymbian::RunError(TInt aError) |
|
79 { |
|
80 QString log2("CSmfClientSymbian::RunError="); |
|
81 |
|
82 log2 += QString::number(aError); |
|
83 writeLog(log2); |
|
84 return KErrNone; |
|
85 } |
|
86 |
|
87 void CSmfClientSymbian::RunL() |
|
88 { |
|
89 QString log2("CSmfClientSymbian::RunL="); |
|
90 log2 += QString::number(iStatus.Int()); |
|
91 writeLog(log2); |
|
92 switch ( iStatus.Int() ) |
|
93 { |
|
94 case KErrCancel: |
|
95 // The request was canceled |
|
96 writeLog("KErrCancel"); |
|
97 break ; |
|
98 |
|
99 case KErrNotReady: |
|
100 writeLog("KErrNotReady"); |
|
101 break; |
|
102 |
|
103 default: |
|
104 { |
|
105 writeLog("RunL:-SmfContactRetrievePostsComplete"); |
|
106 //This contains error followed by actual data |
|
107 QByteArray receivedData(reinterpret_cast<const char*>(iSession.iDataPtr.Ptr()),iSession.iDataPtr.Length()); |
|
108 QString errStr; |
|
109 SmfError errVal; |
|
110 int errInt; |
|
111 QByteArray data; |
|
112 QDataStream reader(&receivedData,QIODevice::ReadOnly); |
|
113 reader>>errInt; |
|
114 errVal = (SmfError)errInt; |
|
115 reader>>data; |
|
116 SmfRequestTypeID opcode = (SmfRequestTypeID)iSession.getLastRequest(); |
|
117 iObserver->resultsAvailable(data,opcode,errVal); |
|
118 } |
|
119 break; |
|
120 } |
|
121 } |
|
122 |
|
123 QByteArray CSmfClientSymbian::sendRequest(QString aInterfaceName, |
|
124 SmfRequestTypeID requestType) |
|
125 { |
|
126 //This will be a synchronous request |
|
127 //note session is opened in ctor and closed in dtor |
|
128 writeLog("CSmfClientSymbian::sendRequest="); |
|
129 writeLog(aInterfaceName); |
|
130 //Gets data synchronously from the server |
|
131 TPtr8 symbianBuf(iSession.sendSyncRequest(aInterfaceName,requestType)); |
|
132 //convert this into bytearray |
|
133 QByteArray receivedData(reinterpret_cast<const char*>(symbianBuf.Ptr()),symbianBuf.Length()); |
|
134 return receivedData; |
|
135 // |
|
136 } |
|
137 |
|
138 TInt CSmfClientSymbian::sendRequest(QByteArray& aSerializedData, |
|
139 QString aInterfaceName, |
|
140 SmfRequestTypeID requestType) |
|
141 { |
|
142 //TODO:-testing puspose only, should be removed in the release |
|
143 if(requestType == SmfTest) |
|
144 { |
|
145 QString log("Before iSesson.SendAsync"); |
|
146 writeLog(log); |
|
147 iSession.sendAsyncRequest(aSerializedData,aInterfaceName,requestType,iStatus); |
|
148 SetActive(); |
|
149 QString log2("After setactive"); |
|
150 writeLog(log2); |
|
151 } |
|
152 else |
|
153 { |
|
154 //RSessionBase objects sendreceive is called |
|
155 iSession.sendAsyncRequest(aSerializedData,aInterfaceName,requestType,iStatus); |
|
156 SetActive(); |
|
157 } |
|
158 } |
|
159 |
|
160 TInt CSmfClientSymbian::sendDummyRequest(QByteArray* provider,QString aInterfaceName, |
|
161 SmfRequestTypeID requestType) |
|
162 { |
|
163 switch(requestType) |
|
164 { |
|
165 case SmfTest: |
|
166 { |
|
167 |
|
168 } |
|
169 break; |
|
170 default: |
|
171 //should panic |
|
172 break; |
|
173 } |
|
174 } |
|
175 |
|
176 CSmfClientSymbian::~CSmfClientSymbian() |
|
177 { |
|
178 writeLog("~CSmfClientSymbian"); |
|
179 Cancel(); // Causes call to DoCancel() |
|
180 iSession.Close(); |
|
181 } |
|
182 |
|
183 RSmfClientSymbianSession::RSmfClientSymbianSession() |
|
184 :iDataPtr(NULL, 0, 0),iDataPtr16(NULL,0),iIntfNamePtr(NULL,0),iIntfNamePtr8(NULL,0),iPtrProvider(NULL,0) |
|
185 { |
|
186 // No implementation required |
|
187 } |
|
188 |
|
189 TInt RSmfClientSymbianSession::connectToServer() |
|
190 { |
|
191 writeLog("RSmfClientSymbianSession::connectToServer"); |
|
192 TInt error = ::StartServerL(); |
|
193 writeLog("StartServerL="); |
|
194 QString err = QString::number(error); |
|
195 writeLog(err); |
|
196 if ( KErrNone == error ) |
|
197 { |
|
198 |
|
199 error = CreateSession( KSmfServerName, |
|
200 Version(), |
|
201 4 ); |
|
202 QString crtSessionErr = QString::number(error); |
|
203 writeLog(crtSessionErr); |
|
204 } |
|
205 return error; |
|
206 } |
|
207 |
|
208 //testing |
|
209 void RSmfClientSymbianSession::writeLog(QString log) const |
|
210 { |
|
211 #ifdef WRITE_LOG |
|
212 QFile file("c:\\data\\SmfClientLogs.txt"); |
|
213 if (!file.open(QIODevice::Append | QIODevice::Text)) |
|
214 ; |
|
215 QTextStream out(&file); |
|
216 out << log << "\n"; |
|
217 file.close(); |
|
218 #endif |
|
219 } |
|
220 |
|
221 TPtr8 RSmfClientSymbianSession::sendSyncRequest(QString aInterfaceName, |
|
222 SmfRequestTypeID aRequestType) |
|
223 { |
|
224 iLastRequest = aRequestType; |
|
225 /** |
|
226 * The message body consists of.- |
|
227 * 1. Interface name as string ("org.symbian.smf.client.gallery") |
|
228 * 2. Data pointer to be filled by serialized data(QList<smfProvider>) |
|
229 */ |
|
230 QString log("RSmfClientSymbianSession::sendSyncRequest-start-"); |
|
231 writeLog(log); |
|
232 writeLog(QString("aInterfaceName=")+aInterfaceName); |
|
233 |
|
234 iInterfaceNamebyte.clear(); |
|
235 //Convert the interface name into TPtr |
|
236 iInterfaceName.clear(); |
|
237 iInterfaceName = aInterfaceName ; |
|
238 writeLog(QString("iInterfaceName=")+iInterfaceName); |
|
239 //lets pass serialized QString |
|
240 QDataStream intfNameStream(&iInterfaceNamebyte,QIODevice::WriteOnly); |
|
241 intfNameStream<<iInterfaceName; |
|
242 log.clear(); |
|
243 log = QString("iInterfaceNamebyte size="); |
|
244 log += QString::number(iInterfaceNamebyte.size()); |
|
245 writeLog(log); |
|
246 if(iIntfNameBuffer8) |
|
247 { |
|
248 delete iIntfNameBuffer8; |
|
249 iIntfNameBuffer8 =NULL; |
|
250 } |
|
251 TInt serializedintfsize = iInterfaceNamebyte.size(); |
|
252 writeLog("iInterfaceNamebyte.size()="); |
|
253 writeLog(QString::number(serializedintfsize)); |
|
254 iIntfNameBuffer8 = HBufC8::NewL(iInterfaceNamebyte.size()*2); |
|
255 iIntfNamePtr8.Set(iIntfNameBuffer8->Des()); |
|
256 iIntfNamePtr8.Copy(reinterpret_cast<TUint8*>(iInterfaceNamebyte.data()),iInterfaceNamebyte.length()); |
|
257 log.clear(); |
|
258 log = QString("iIntfNamePtr8 size=")+QString::number(iIntfNamePtr8.Size()); |
|
259 writeLog(log); |
|
260 |
|
261 writeLog("Before provider symbian copy"); |
|
262 |
|
263 |
|
264 iInterfaceSymbian8.Copy(iIntfNamePtr8); |
|
265 if(iBuffer) |
|
266 { |
|
267 delete iBuffer; |
|
268 iBuffer = NULL; |
|
269 } |
|
270 iMaxMessageSize = 1000 ; |
|
271 iBuffer = HBufC8::NewL(iMaxMessageSize); |
|
272 iDataPtr.Set(iBuffer->Des()); |
|
273 log.clear(); |
|
274 log = QString("After iDataPtr.Set"); |
|
275 writeLog(log); |
|
276 |
|
277 |
|
278 TIpcArgs args; |
|
279 |
|
280 args.Set(0, &iInterfaceSymbian8); |
|
281 args.Set(1, &iDataPtr); |
|
282 |
|
283 TInt err(KErrBadHandle); |
|
284 writeLog("Before handle"); |
|
285 log.clear(); |
|
286 log = QString("iInterfaceSymbian8 size=")+QString::number(iInterfaceSymbian8.Size()); |
|
287 writeLog(log); |
|
288 if (Handle()) |
|
289 { |
|
290 err = KErrNone; |
|
291 log.clear(); |
|
292 log = QString("Before sendreceive"); |
|
293 writeLog(log); |
|
294 //synchronous request |
|
295 TInt sendErr = SendReceive(aRequestType, args); |
|
296 if(sendErr) |
|
297 { |
|
298 writeLog("SendReceive error="); |
|
299 QString errStr = QString::number(sendErr); |
|
300 writeLog(errStr); |
|
301 } |
|
302 return iDataPtr; |
|
303 } |
|
304 } |
|
305 |
|
306 /** |
|
307 * Calls SendReceive() after converting into symbian descriptors |
|
308 * |
|
309 */ |
|
310 void RSmfClientSymbianSession::sendAsyncRequest(QByteArray& aSerializedData, |
|
311 QString aInterfaceName, |
|
312 SmfRequestTypeID aRequestType, |
|
313 TRequestStatus& aStatus) |
|
314 { |
|
315 iLastRequest = aRequestType; |
|
316 /** |
|
317 * The message body consists of.- |
|
318 * 1. Provider Info(SmfProvider*)+ Other common class data |
|
319 * (when applicable)-serialized |
|
320 * 2. Interface name as string ("org.symbian.smf.client.gallery") |
|
321 * 3. Data pointer to be filled by serialized data |
|
322 */ |
|
323 QString log("RSmfClientSymbianSession::sendAsyncRequest-start-"); |
|
324 writeLog(log); |
|
325 |
|
326 iBaseProvider= aSerializedData; |
|
327 iInterfaceName = aInterfaceName ; |
|
328 |
|
329 int size = aSerializedData.size(); |
|
330 log.clear(); |
|
331 log = QString("aSerializedData size=")+ QString::number(size); |
|
332 |
|
333 writeLog(log); |
|
334 if(iProviderBuf) |
|
335 { |
|
336 delete iProviderBuf; |
|
337 iProviderBuf = NULL; |
|
338 } |
|
339 //TODO:- KSmfProviderMaxSize |
|
340 iProviderBuf = HBufC8::NewL(iBaseProvider.size()*2); |
|
341 iPtrProvider.Set(iProviderBuf->Des()); |
|
342 //convert the QByteArray into TPtr |
|
343 iPtrProvider.Copy(reinterpret_cast<const TText8*>(iBaseProvider.constData()),iBaseProvider.length()); |
|
344 |
|
345 |
|
346 log.clear(); |
|
347 log = QString("iPtrProvider.Copy"); |
|
348 writeLog(log); |
|
349 |
|
350 //Convert the interface name into TPtr//////////////////////// |
|
351 iInterfaceName.clear(); |
|
352 iInterfaceName = aInterfaceName ; |
|
353 writeLog(QString("iInterfaceName=")+iInterfaceName); |
|
354 //Pass serialized QString for interface name |
|
355 QDataStream intfNameStream(&iInterfaceNamebyte,QIODevice::WriteOnly); |
|
356 intfNameStream<<iInterfaceName; |
|
357 log.clear(); |
|
358 log = QString("iInterfaceNamebyte size="); |
|
359 log += QString::number(iInterfaceNamebyte.size()); |
|
360 writeLog(log); |
|
361 if(iIntfNameBuffer8) |
|
362 { |
|
363 delete iIntfNameBuffer8; |
|
364 iIntfNameBuffer8 =NULL; |
|
365 } |
|
366 iIntfNameBuffer8 = HBufC8::NewL(aInterfaceName.size()*2); |
|
367 iIntfNamePtr8.Set(iIntfNameBuffer8->Des()); |
|
368 //Convert into symbian data type |
|
369 iIntfNamePtr8.Copy(reinterpret_cast<TUint8*>(iInterfaceNamebyte.data()),iInterfaceNamebyte.length()); |
|
370 log.clear(); |
|
371 log = QString("iIntfNamePtr8 size=")+QString::number(iIntfNamePtr8.Size()); |
|
372 writeLog(log); |
|
373 |
|
374 |
|
375 if(iBuffer) |
|
376 { |
|
377 delete iBuffer; |
|
378 iBuffer = NULL; |
|
379 } |
|
380 //TODO:-KSmfMaxDataSize |
|
381 iMaxMessageSize = 2000 ; |
|
382 iBuffer = HBufC8::NewL(iMaxMessageSize); |
|
383 iDataPtr.Set(iBuffer->Des()); |
|
384 log.clear(); |
|
385 log = QString("After iDataPtr.Set"); |
|
386 writeLog(log); |
|
387 |
|
388 |
|
389 TIpcArgs args; |
|
390 |
|
391 |
|
392 args.Set(0, &iPtrProvider); |
|
393 args.Set(1, &iIntfNamePtr8); |
|
394 args.Set(2, &iDataPtr); |
|
395 |
|
396 TInt err(KErrBadHandle); |
|
397 log.clear(); |
|
398 log = QString("Before Handle()"); |
|
399 writeLog("Before handle"); |
|
400 if (Handle()) |
|
401 { |
|
402 err = KErrNone; |
|
403 log.clear(); |
|
404 log = QString("Before sendreceive"); |
|
405 writeLog(log); |
|
406 SendReceive(aRequestType, args, aStatus); |
|
407 |
|
408 } |
|
409 } |
|
410 |
|
411 // ----------------------------------------------------------------------------- |
|
412 // StartServerL() |
|
413 // Starts the server if it is not already running |
|
414 // ----------------------------------------------------------------------------- |
|
415 // |
|
416 static TInt StartServerL() |
|
417 { |
|
418 TInt result; |
|
419 |
|
420 TFindServer findSmfServer( KSmfServerName ); |
|
421 TFullName name; |
|
422 |
|
423 result = findSmfServer.Next( name ); |
|
424 if ( result == KErrNone ) |
|
425 { |
|
426 // Server already running |
|
427 return KErrNone; |
|
428 } |
|
429 |
|
430 result = CreateServerProcessL(); |
|
431 if ( result != KErrNone ) |
|
432 { |
|
433 return result; |
|
434 } |
|
435 |
|
436 return KErrNone; |
|
437 } |
|
438 |
|
439 // ----------------------------------------------------------------------------- |
|
440 // CreateServerProcessL() |
|
441 // Creates a server process |
|
442 // ----------------------------------------------------------------------------- |
|
443 // |
|
444 static TInt CreateServerProcessL() |
|
445 { |
|
446 TInt result; |
|
447 //SmfServer SID |
|
448 TUid KSmfServerUID3 = { 0xE5027327 }; |
|
449 const TUidType serverUid( KNullUid, KNullUid, KSmfServerUID3 ); |
|
450 |
|
451 RProcess server; |
|
452 |
|
453 result = server.Create( KSmfServerFilename, KNullDesC, serverUid ); |
|
454 User::LeaveIfError(result); |
|
455 if (KErrNone != result) { |
|
456 return result; |
|
457 } |
|
458 else { |
|
459 //User::WaitForRequest going for infinite loop, temporary work-around |
|
460 //TRequestStatus status; |
|
461 //server.Rendezvous(status); |
|
462 server.Resume(); // logon OK - start the server |
|
463 //Going for infinite loop |
|
464 //User::WaitForRequest(status);// wait for start or death |
|
465 User::After(700000); |
|
466 server.Close(); |
|
467 return KErrNone; |
|
468 //return status.Int(); // return the error |
|
469 } |
|
470 return KErrNone; |
|
471 } |