|
1 /* |
|
2 * Copyright (c) 2008 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: Service IPC Session |
|
19 * |
|
20 */ |
|
21 |
|
22 #include "xqservicelog.h" |
|
23 |
|
24 #include <xqserviceclientinfo.h> |
|
25 #include "xqserviceipcobserver.h" |
|
26 #include "xqserviceipcrequest.h" |
|
27 #include "xqserviceipcserver_apasymbiansession.h" |
|
28 #include "xqrequestutil.h" |
|
29 |
|
30 namespace QtService |
|
31 { |
|
32 |
|
33 // Constants for the IPC operation id |
|
34 const TInt KIPCOperation = RApaAppServiceBase::KServiceCmdBase; |
|
35 const TInt KIPCGetBuffer = KIPCOperation+1; |
|
36 const TInt KIPCOperationWithSharableFile = KIPCOperation+2; // Sharable file support |
|
37 |
|
38 |
|
39 /*! |
|
40 \class CApaServerSymbianSession |
|
41 \brief Symbian Session class |
|
42 */ |
|
43 |
|
44 /*! |
|
45 Constructor. |
|
46 \param aObserver Observer to the server. |
|
47 */ |
|
48 CApaServerSymbianSession::CApaServerSymbianSession(MServiceIPCObserver* aObserver) : |
|
49 ServiceIPCSession(aObserver) |
|
50 { |
|
51 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::CApaServerSymbianSession"); |
|
52 } |
|
53 |
|
54 /*! |
|
55 2nd phased constructor. |
|
56 */ |
|
57 void CApaServerSymbianSession::ConstructL() |
|
58 { |
|
59 } |
|
60 |
|
61 /*! |
|
62 Two-Phased Constructor. |
|
63 \param aObserver Observer to the server. |
|
64 */ |
|
65 CApaServerSymbianSession* CApaServerSymbianSession::NewL(MServiceIPCObserver* aObserver) |
|
66 { |
|
67 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::NewL"); |
|
68 CApaServerSymbianSession* self = |
|
69 new( ELeave ) CApaServerSymbianSession(aObserver); |
|
70 CleanupStack::PushL(self); |
|
71 self->ConstructL(); |
|
72 CleanupStack::Pop(self); |
|
73 return self; |
|
74 } |
|
75 |
|
76 /*! |
|
77 Destructor. |
|
78 */ |
|
79 CApaServerSymbianSession::~CApaServerSymbianSession() |
|
80 { |
|
81 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::~CApaServerSymbianSession"); |
|
82 if (iCurRequest) { |
|
83 iObserver->handleDeleteRequest(iCurRequest); |
|
84 delete iCurRequest; |
|
85 } |
|
86 iCurRequest = NULL; |
|
87 } |
|
88 |
|
89 /*! |
|
90 Write some data in response to a request. |
|
91 \param aData Some data to write as response. |
|
92 \return bool If write was successful. |
|
93 */ |
|
94 bool CApaServerSymbianSession::write( const QByteArray& aData ) |
|
95 { |
|
96 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::write"); |
|
97 XQSERVICE_DEBUG_PRINT("aData: %s,length=%d", aData.constData(), aData.length()); |
|
98 // Implicitly shared |
|
99 iData = aData; |
|
100 return false; |
|
101 } |
|
102 |
|
103 /*! |
|
104 Complete a request. |
|
105 \return true if request completed |
|
106 */ |
|
107 bool CApaServerSymbianSession::completeRequest() |
|
108 { |
|
109 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::completeRequest"); |
|
110 TPtrC8 data(reinterpret_cast<const TUint8*> (iData.constData()), iData.length()); |
|
111 XQSERVICE_DEBUG_PRINT("data: %s, length=%d", iData.constData(), data.Length() ); |
|
112 iMessage.Complete(data.Length()); |
|
113 if (iCurRequest) { |
|
114 iObserver->handleDeleteRequest(iCurRequest); |
|
115 delete iCurRequest; |
|
116 } |
|
117 iCurRequest = NULL; |
|
118 return true; |
|
119 } |
|
120 |
|
121 /*! |
|
122 Close a session and gracefully shutdown. |
|
123 */ |
|
124 void CApaServerSymbianSession::close() |
|
125 { |
|
126 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::close"); |
|
127 // Symbian doens't really do anything |
|
128 } |
|
129 |
|
130 /*! |
|
131 From CSession2. Service request. |
|
132 \param aMessage Message object. |
|
133 */ |
|
134 void CApaServerSymbianSession::ServiceL(const RMessage2& aMessage) |
|
135 { |
|
136 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL"); |
|
137 // Default ServiceErrorL() will complete the message if this method leaves |
|
138 TInt operation(aMessage.Function()); |
|
139 XQSERVICE_DEBUG_PRINT("\toperation: %d", operation); |
|
140 switch (operation) { |
|
141 case KIPCOperation: |
|
142 case KIPCOperationWithSharableFile: |
|
143 { |
|
144 |
|
145 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL handleRequest"); |
|
146 handleRequestL(aMessage); |
|
147 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL handleRequest end"); |
|
148 //and here |
|
149 break; |
|
150 } |
|
151 case KIPCGetBuffer: { |
|
152 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL handleGetBufferL"); |
|
153 handleGetBufferL(aMessage); |
|
154 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL handleGetBufferL end"); |
|
155 break; |
|
156 } |
|
157 |
|
158 default: { |
|
159 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL default"); |
|
160 if (operation == 2 && iCurRequest) // maparnan |
|
161 { |
|
162 // Need to complete the pending request when handling the |
|
163 // the EApaAppServerCancelNotifyServerExit (2) from the client |
|
164 // It is too late to complete that in session disconnect |
|
165 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL request cancelled"); |
|
166 iMessage.Complete(KErrCancel); |
|
167 } |
|
168 |
|
169 CApaAppServiceBase::ServiceL( aMessage ); |
|
170 //aMessage.Complete(KErrNotFound); |
|
171 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ServiceL default end"); |
|
172 break; |
|
173 } |
|
174 } |
|
175 } |
|
176 |
|
177 /*! |
|
178 From CSession2. |
|
179 Handle any disconnection from the client. |
|
180 \param aMessage Message Object. |
|
181 */ |
|
182 void CApaServerSymbianSession::Disconnect(const RMessage2 &aMessage) |
|
183 { |
|
184 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::Disconnect"); |
|
185 if (iCurRequest) { |
|
186 // Inform also observer, that current pending request is about to go |
|
187 iObserver->handleCancelRequest(iCurRequest); |
|
188 } |
|
189 CApaAppServiceBase::Disconnect(aMessage); |
|
190 } |
|
191 |
|
192 /*! |
|
193 Handle an IPC request. |
|
194 \param aMessage Message Object. |
|
195 */ |
|
196 void CApaServerSymbianSession::handleRequestL( const RMessage2& aMessage ) |
|
197 { |
|
198 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::handleRequestL"); |
|
199 // Store the message |
|
200 iMessage = aMessage; |
|
201 |
|
202 // Convert from Symbian to QT |
|
203 HBufC* request = ReadDesLC(aMessage, 0); |
|
204 HBufC8* data = ReadDes8LC(aMessage, 1); |
|
205 |
|
206 XQSharableFile *file = 0; |
|
207 if (aMessage.Function() == KIPCOperationWithSharableFile) |
|
208 { |
|
209 // Only one file support now ! |
|
210 file = new XQSharableFile(); |
|
211 AdoptSharableFile(aMessage, file); |
|
212 } |
|
213 |
|
214 // Shallow copy only, we want a deep copy |
|
215 QString d = QString::fromUtf16(request->Ptr(), request->Length()); |
|
216 QString operation; |
|
217 operation += d; |
|
218 XQSERVICE_DEBUG_PRINT("operation: %s", qPrintable(operation)); |
|
219 |
|
220 /* |
|
221 //QByteArray convertData; |
|
222 TPtr8 ptr8(data->Des()); |
|
223 const char* ptrz = reinterpret_cast<const char*> (ptr8.PtrZ()); |
|
224 //convertData.append(ptrz); |
|
225 QByteArray convertData(ptrz,data->Length()); |
|
226 */ |
|
227 QByteArray convertData( reinterpret_cast<const char*>(data->Ptr()), data->Length() ); |
|
228 XQSERVICE_DEBUG_PRINT("convertData: %s", convertData.constData()); |
|
229 |
|
230 // New request |
|
231 Q_ASSERT(!iCurRequest); |
|
232 iCurRequest = new ServiceIPCRequest(this, 0, operation); |
|
233 iData.clear(); |
|
234 |
|
235 // Get client info |
|
236 ClientInfo *client = new ClientInfo(); |
|
237 client->setProcessId(aMessage.SecureId().iId); |
|
238 client->setVendorId(aMessage.VendorId().iId); |
|
239 RThread clientThread; |
|
240 aMessage.ClientL(clientThread); |
|
241 RProcess clientProc; |
|
242 User::LeaveIfError( clientThread.Process(clientProc) ); |
|
243 client->setName(QString::fromUtf16(clientProc.Name().Ptr(), |
|
244 clientProc.Name().Length())); |
|
245 client->setCapabilities(ClientCapabilities(aMessage)); |
|
246 clientThread.Close(); // close handle |
|
247 |
|
248 // Set the picked sharable file if any |
|
249 if (file != 0) |
|
250 { |
|
251 // Support only one sharable file |
|
252 iCurRequest->addSharableFile(file, 0); |
|
253 } |
|
254 |
|
255 // |
|
256 // Add data and callback to the observer |
|
257 // |
|
258 iCurRequest->addRequestdata(convertData); |
|
259 iCurRequest->setClientInfo(client); // ownership passed |
|
260 iObserver->handleRequest(iCurRequest); |
|
261 |
|
262 CleanupStack::PopAndDestroy(2, request); |
|
263 } |
|
264 |
|
265 /*! |
|
266 Handle getting the result buffer. |
|
267 \param aMessage Message Object. |
|
268 */ |
|
269 void CApaServerSymbianSession::handleGetBufferL( const RMessage2& aMessage ) |
|
270 { |
|
271 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::handleGetBufferL"); |
|
272 XQSERVICE_DEBUG_PRINT("iData: %s", iData.constData()); |
|
273 TPtrC8 data(reinterpret_cast<const TUint8*> (iData.constData()), iData.length()); |
|
274 TInt err = aMessage.Write(0, data); |
|
275 aMessage.Complete(err); |
|
276 } |
|
277 |
|
278 /*! |
|
279 Read a 16 bit descriptor from the message. |
|
280 \param aMessage Message to read from. |
|
281 \param aMsgSlot Slot to read from. |
|
282 */ |
|
283 HBufC* CApaServerSymbianSession::ReadDesLC(const RMessage2& aMessage, |
|
284 TInt aMsgSlot) |
|
285 { |
|
286 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ReadDesLC"); |
|
287 TInt length = aMessage.GetDesLengthL(aMsgSlot); |
|
288 HBufC* des = HBufC::NewLC(length); |
|
289 TPtr ptr = des->Des(); |
|
290 aMessage.ReadL(aMsgSlot, ptr); |
|
291 return des; |
|
292 } |
|
293 |
|
294 /*! |
|
295 Read a 8 bit descriptor from the message. |
|
296 \param aMessage Message to read from. |
|
297 \param aMsgSlot Slot to read from. |
|
298 */ |
|
299 HBufC8* CApaServerSymbianSession::ReadDes8LC(const RMessage2& aMessage, |
|
300 TInt aMsgSlot) |
|
301 { |
|
302 XQSERVICE_DEBUG_PRINT("CApaServerSymbianSession::ReadDes8LC"); |
|
303 TInt length = aMessage.GetDesLengthL(aMsgSlot); |
|
304 HBufC8* des = HBufC8::NewLC(length + 1); // 1 more for null terminator |
|
305 TPtr8 ptr = des->Des(); |
|
306 aMessage.ReadL(aMsgSlot, ptr); |
|
307 return des; |
|
308 } |
|
309 |
|
310 } |
|
311 |
|
312 // END OF FILE |
|
313 |