|
1 // Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // Name : CSIPCRServerSession.cpp |
|
15 // Part of : SIP Client Resolver |
|
16 // Version : 1.0 |
|
17 // |
|
18 |
|
19 |
|
20 |
|
21 // INCLUDES |
|
22 #include <e32math.h> |
|
23 #include "CSipCRServerSession.h" |
|
24 #include "CSIPCRRoutingTable.h" |
|
25 #include "CSIPClientResolver.h" |
|
26 #include "CSIPCRITCUtility.h" |
|
27 #include "CSIPCRSessionReceiver.h" |
|
28 #include "CSipCRServer.h" |
|
29 #include "sipCRclientserver.h" |
|
30 #include "CSIPCRRequestItem.h" |
|
31 #include "siprequest.h" |
|
32 #include "sipresponse.h" |
|
33 #include "TSipClient.h" |
|
34 #include "sipresolvedclient.h" |
|
35 #include "sipcontenttypeheader.h" |
|
36 #include "sipstrconsts.h" |
|
37 #include "sipstrings.h" |
|
38 #include "uricontainer.h" |
|
39 #include "SIPCRSerializer.h" |
|
40 #include "sipresolvedclient2.h" |
|
41 #include "sipcrworkerao.h" |
|
42 #include "sipcrrequestqueuecleanupdata.h" |
|
43 |
|
44 const TUint K480ResponseCode = 480; |
|
45 const TUint K503ResponseCode = 503; |
|
46 |
|
47 _LIT(KWorkerThreadName, "SIPClientResolverSessionWorker"); |
|
48 |
|
49 // ---------------------------------------------------------------------------- |
|
50 // CSIPCRServerSession::NewL |
|
51 // ---------------------------------------------------------------------------- |
|
52 // |
|
53 CSIPCRServerSession* CSIPCRServerSession::NewL(CSIPCRServer& aCRServer) |
|
54 { |
|
55 CSIPCRServerSession* self = CSIPCRServerSession::NewLC(aCRServer); |
|
56 CleanupStack::Pop (self); |
|
57 return self; |
|
58 } |
|
59 |
|
60 // ---------------------------------------------------------------------------- |
|
61 // CSIPCRServerSession::NewLC |
|
62 // ---------------------------------------------------------------------------- |
|
63 // |
|
64 CSIPCRServerSession* CSIPCRServerSession::NewLC(CSIPCRServer& aCRServer) |
|
65 { |
|
66 CSIPCRServerSession* self = new(ELeave)CSIPCRServerSession(aCRServer); |
|
67 CleanupStack::PushL(self); |
|
68 self->ConstructL(); |
|
69 return self; |
|
70 } |
|
71 |
|
72 // ---------------------------------------------------------------------------- |
|
73 // CSIPCRServerSession::CSIPCRServerSession |
|
74 // ---------------------------------------------------------------------------- |
|
75 // |
|
76 CSIPCRServerSession::CSIPCRServerSession(CSIPCRServer& aCRServer) |
|
77 : iClientUid(TUid::Null()), |
|
78 iClientUidSet(EFalse), |
|
79 iCRServer(aCRServer) |
|
80 { |
|
81 iCRServer.IncrementSessions(); |
|
82 } |
|
83 |
|
84 // ---------------------------------------------------------------------------- |
|
85 // CSIPCRServerSession::ConstructL |
|
86 // ---------------------------------------------------------------------------- |
|
87 // |
|
88 void CSIPCRServerSession::ConstructL() |
|
89 { |
|
90 User::LeaveIfError(iRequestQueueMutex.CreateLocal()); |
|
91 iReceiver = CSIPCRSessionReceiver::NewL(iCRServer.ITCUtility()); |
|
92 } |
|
93 |
|
94 // ---------------------------------------------------------------------------- |
|
95 // CSIPCRServerSession::~CSIPCRServerSession |
|
96 // ---------------------------------------------------------------------------- |
|
97 // |
|
98 CSIPCRServerSession::~CSIPCRServerSession () |
|
99 { |
|
100 iWorkerAos.ResetAndDestroy(); |
|
101 delete iReceiver; |
|
102 iRequestQueue.ResetAndDestroy(); |
|
103 iCRServer.DecrementSessions(); |
|
104 if (iClientUidSet) |
|
105 { |
|
106 iCRServer.RoutingTable().Remove(iClientUid); |
|
107 } |
|
108 iRequestQueueMutex.Close(); |
|
109 } |
|
110 |
|
111 // ---------------------------------------------------------------------------- |
|
112 // CSIPCRServerSession::ServiceL |
|
113 // ---------------------------------------------------------------------------- |
|
114 // |
|
115 void CSIPCRServerSession::ServiceL(const RMessage2& aMessage) |
|
116 { |
|
117 DoServiceL(aMessage.Function(),aMessage); |
|
118 } |
|
119 |
|
120 // ---------------------------------------------------------------------------- |
|
121 // CSIPCRServerSession::WorkerAoRequestCompleted |
|
122 // ---------------------------------------------------------------------------- |
|
123 // |
|
124 void CSIPCRServerSession::WorkerAoRequestCompleted(CSipCrWorkerAo* aWorkerAo) |
|
125 { |
|
126 TInt err = aWorkerAo->CompletionCode(); |
|
127 TUint32 requestId = aWorkerAo->RequestId(); |
|
128 if (err != KErrNone && requestId > 0) |
|
129 { |
|
130 TRAP_IGNORE(iReceiver->ErrorReceivedL(requestId,err)) |
|
131 } |
|
132 TInt index = iWorkerAos.Find(aWorkerAo); |
|
133 if (index >= 0) |
|
134 { |
|
135 iWorkerAos.Remove(index); |
|
136 } |
|
137 delete aWorkerAo; |
|
138 } |
|
139 |
|
140 // ---------------------------------------------------------------------------- |
|
141 // CSIPCRServerSession::RoutingEntryAddedL |
|
142 // ---------------------------------------------------------------------------- |
|
143 // |
|
144 void CSIPCRServerSession::RoutingEntryAddedL(const TUid& aUid) |
|
145 { |
|
146 CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex); |
|
147 |
|
148 // Complete pending requests for aUid |
|
149 CSIPCRRequestItem* requestItem = NULL; |
|
150 for (TInt i=iRequestQueue.Count()-1; i >= 0; i--) |
|
151 { |
|
152 requestItem = iRequestQueue[i]; |
|
153 if (requestItem->ChannelUid() == aUid) |
|
154 { |
|
155 TUint32 requestId = requestItem->RequestId(); |
|
156 TUid nextHopUid(TUid::Null()); |
|
157 if (iCRServer.RoutingTable().FindMatch(aUid,iClientUid,nextHopUid)) |
|
158 { |
|
159 iReceiver->RequestCompletedL(requestId,nextHopUid); |
|
160 } |
|
161 else |
|
162 { |
|
163 iReceiver->ErrorReceivedL(requestId,KErrNotFound); |
|
164 } |
|
165 ProtectedRemoveFromRequestQueue( requestItem ); |
|
166 delete requestItem; |
|
167 } |
|
168 } |
|
169 |
|
170 CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex |
|
171 |
|
172 CSipCrWorkerAo* workerAo = CSipCrWorkerAo::NewLC(*this); |
|
173 CreateWorkerThreadL(workerAo,ConnectWorkerThreadFunction); |
|
174 CleanupStack::Pop(workerAo); |
|
175 } |
|
176 |
|
177 // ---------------------------------------------------------------------------- |
|
178 // CSIPCRServerSession::DoServiceL |
|
179 // ---------------------------------------------------------------------------- |
|
180 // |
|
181 void CSIPCRServerSession::DoServiceL (TInt aFunction, |
|
182 const RMessage2& aMessage) |
|
183 { |
|
184 switch (aFunction) |
|
185 { |
|
186 #ifndef PLAT_SEC_TEST |
|
187 case ESIPCRIpcSetClientUid: |
|
188 SetUIDL(aMessage); break; |
|
189 |
|
190 case ESIPCRIpcRegister: |
|
191 RegisterL(iCRServer.ITCUtility().ReadUIDL(aMessage)); break; |
|
192 |
|
193 case ESIPCRIpcDeregister: |
|
194 DeregisterL(iCRServer.ITCUtility().ReadUIDL(aMessage)); break; |
|
195 |
|
196 case ESIPCRIpcClientReadyToReceive: // Async. Don't complete yet. |
|
197 ClientReadyToReceiveL(aMessage); return; |
|
198 |
|
199 case ESIPCRIpcClientCancelReceive: |
|
200 CancelClientReceiveL(); break; |
|
201 |
|
202 case ESIPCRIpcCancelRequest: |
|
203 CancelRequestL(aMessage); break; |
|
204 |
|
205 case ESIPCRIpcCancelAllRequests: |
|
206 CancelAllRequests(); break; |
|
207 |
|
208 case ESIPCRIpcChannel: |
|
209 ChannelL(aMessage); break; |
|
210 |
|
211 case ESIPCRIpcChannelWithResolver: |
|
212 ChannelWithResolverL(aMessage); break; |
|
213 |
|
214 case ESIPCRIpcClientReceiveSipResponse: |
|
215 ClientReceiveSipResponseL(aMessage); break; |
|
216 |
|
217 default: |
|
218 break; |
|
219 #endif |
|
220 } |
|
221 iCRServer.ITCUtility().Complete(aMessage,KErrNone); |
|
222 } |
|
223 |
|
224 // ---------------------------------------------------------------------------- |
|
225 // CSIPCRServerSession::ChannelWithResolverL |
|
226 // ---------------------------------------------------------------------------- |
|
227 // |
|
228 void CSIPCRServerSession::ChannelWithResolverL(const RMessage2& aMessage) |
|
229 { |
|
230 CSIPRequest* request = CSIPRequest::NewLC(); |
|
231 iCRServer.ITCUtility().ReadSIPRequestL(aMessage, *request); |
|
232 TUid resolverUid = iCRServer.ITCUtility().ReadResolverUidL(aMessage); |
|
233 TUint32 requestId = CreateRequestId(); |
|
234 TSipClient clientUid(TUid::Null(),EFalse,EFalse); |
|
235 ChannelL(requestId,*request,clientUid,resolverUid); |
|
236 CleanupStack::PopAndDestroy(request); |
|
237 iCRServer.ITCUtility().WriteRequestIdL(aMessage,requestId); |
|
238 } |
|
239 |
|
240 // ---------------------------------------------------------------------------- |
|
241 // CSIPCRServerSession::ChannelL |
|
242 // ---------------------------------------------------------------------------- |
|
243 // |
|
244 void CSIPCRServerSession::ChannelL(const RMessage2& aMessage) |
|
245 { |
|
246 CSIPRequest* request = CSIPRequest::NewLC(); |
|
247 iCRServer.ITCUtility().ReadSIPRequestL(aMessage, *request); |
|
248 |
|
249 TUint32 requestId = CreateRequestId(); |
|
250 iCRServer.ITCUtility().WriteRequestIdL(aMessage,requestId); |
|
251 |
|
252 TSipClient clientUid(TUid::Null(),EFalse,EFalse); |
|
253 |
|
254 CSIPResponse* response = ResolveClientL(*request,clientUid); |
|
255 if (response) |
|
256 { |
|
257 CleanupStack::PushL(response); |
|
258 iReceiver->AddErrorResponseL(requestId,response); |
|
259 CleanupStack::PopAndDestroy(response); |
|
260 } |
|
261 else |
|
262 { |
|
263 ChannelL(requestId,*request,clientUid,TUid::Null()); |
|
264 } |
|
265 CleanupStack::PopAndDestroy(request); |
|
266 } |
|
267 |
|
268 // ---------------------------------------------------------------------------- |
|
269 // CSIPCRServerSession::RegisterL |
|
270 // ---------------------------------------------------------------------------- |
|
271 // |
|
272 void CSIPCRServerSession::RegisterL(const TUid& aChannelUid) |
|
273 { |
|
274 iCRServer.RoutingTable().AssociateL(iClientUid, aChannelUid); |
|
275 iCRServer.RoutingEntryAddedL(aChannelUid); |
|
276 } |
|
277 |
|
278 // ---------------------------------------------------------------------------- |
|
279 // CSIPCRServerSession::DeregisterL |
|
280 // ---------------------------------------------------------------------------- |
|
281 // |
|
282 void CSIPCRServerSession::DeregisterL(const TUid& aChannelUid) |
|
283 { |
|
284 iCRServer.RoutingTable().Remove(aChannelUid); |
|
285 } |
|
286 |
|
287 // ---------------------------------------------------------------------------- |
|
288 // CSIPCRServerSession::SetUIDL |
|
289 // ---------------------------------------------------------------------------- |
|
290 // |
|
291 void CSIPCRServerSession::SetUIDL(const RMessage2& aMessage) |
|
292 { |
|
293 iClientUid = iCRServer.ITCUtility().ReadUIDL (aMessage); |
|
294 iCRServer.RoutingTable().AddL(iClientUid); |
|
295 iClientUidSet = ETrue; |
|
296 } |
|
297 |
|
298 // ---------------------------------------------------------------------------- |
|
299 // CSIPCRServerSession::ClientReadyToReceiveL |
|
300 // ---------------------------------------------------------------------------- |
|
301 // |
|
302 void CSIPCRServerSession::ClientReadyToReceiveL(const RMessage2& aMessage) |
|
303 { |
|
304 iReceiver->ClientReadyToReceiveL(aMessage); |
|
305 } |
|
306 |
|
307 // ---------------------------------------------------------------------------- |
|
308 // CSIPCRServerSession::ClientReceiveSipResponseL |
|
309 // ---------------------------------------------------------------------------- |
|
310 // |
|
311 void CSIPCRServerSession::ClientReceiveSipResponseL(const RMessage2& aMessage) |
|
312 { |
|
313 iReceiver->WriteSipResponseToClientL(aMessage); |
|
314 } |
|
315 |
|
316 // ---------------------------------------------------------------------------- |
|
317 // CSIPCRServerSession::CancelRequestL |
|
318 // ---------------------------------------------------------------------------- |
|
319 // |
|
320 void CSIPCRServerSession::CancelRequestL(const RMessage2& aMessage) |
|
321 { |
|
322 TUint32 requestId = iCRServer.ITCUtility().ReadRequestIdL(aMessage); |
|
323 TBool found = EFalse; |
|
324 |
|
325 CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex); |
|
326 |
|
327 for (TInt i=iRequestQueue.Count()-1; i >=0 && !found; i--) |
|
328 { |
|
329 CSIPCRRequestItem* requestItem = iRequestQueue[i]; |
|
330 if (requestItem->RequestId() == requestId) |
|
331 { |
|
332 CancelConnectL( requestItem ); |
|
333 ProtectedRemoveFromRequestQueue( requestItem ); |
|
334 delete requestItem; |
|
335 found = ETrue; |
|
336 } |
|
337 } |
|
338 |
|
339 CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex |
|
340 |
|
341 iReceiver->RemoveByRequestId(requestId); |
|
342 CSipCrWorkerAo* workerAo = CSipCrWorkerAo::NewLC(*this); |
|
343 CreateWorkerThreadL(workerAo,ConnectWorkerThreadFunction); |
|
344 CleanupStack::Pop(workerAo); |
|
345 } |
|
346 |
|
347 // ---------------------------------------------------------------------------- |
|
348 // CSIPCRServerSession::CancelConnectL |
|
349 // ---------------------------------------------------------------------------- |
|
350 // |
|
351 void CSIPCRServerSession::CancelConnectL( CSIPCRRequestItem* aRequestItem ) |
|
352 { |
|
353 if ( aRequestItem->Client().PluginType() == TSipClient::ESecondGeneration ) |
|
354 { |
|
355 if ( aRequestItem->ConnectCalled() ) |
|
356 { |
|
357 CSIPResolvedClient2* resolvedClient2 = |
|
358 iCRServer.LoadPlugin2LC( |
|
359 aRequestItem->Client().ImplementationUid() ); |
|
360 resolvedClient2->CancelConnect( aRequestItem->Client().Uid() ); |
|
361 CleanupStack::PopAndDestroy( resolvedClient2 ); |
|
362 } |
|
363 } |
|
364 } |
|
365 |
|
366 // --------------------------------------------------------------------------- |
|
367 // CSIPCRServerSession::AddToRequestQueueL |
|
368 // --------------------------------------------------------------------------- |
|
369 // |
|
370 template<class T> void CSIPCRServerSession::AddToRequestQueueL( |
|
371 CSIPCRRequestItem* aRequestItem, |
|
372 T& aResolvedClient ) |
|
373 { |
|
374 __ASSERT_ALWAYS ( aRequestItem, User::Leave( KErrArgument ) ); |
|
375 |
|
376 // The request item needs to be in request queue |
|
377 // in case the client connects immediately after calling ConnectL |
|
378 // and the main thread examines the request queue |
|
379 ProtectedAddToRequestQueueL( aRequestItem ); |
|
380 TSipCrRequestQueueCleanupData cleanupData; |
|
381 cleanupData.iSession = this; |
|
382 cleanupData.iRequestItem = aRequestItem; |
|
383 TCleanupItem cleanupItem( RemoveFromRequestQueue, &cleanupData ); |
|
384 CleanupStack::PushL(cleanupItem); |
|
385 TBool connectSucceeded = ConnectL( *aRequestItem, aResolvedClient ); |
|
386 CleanupStack::Pop(); // cleanupItem, leave the item to queue |
|
387 if ( !connectSucceeded ) |
|
388 { |
|
389 ProtectedRemoveFromRequestQueue( aRequestItem ); |
|
390 delete aRequestItem; |
|
391 } |
|
392 } |
|
393 |
|
394 // --------------------------------------------------------------------------- |
|
395 // CSIPCRServerSession::ConnectL |
|
396 // --------------------------------------------------------------------------- |
|
397 // |
|
398 template<class T> TBool CSIPCRServerSession::ConnectL( |
|
399 CSIPCRRequestItem& aRequestItem, |
|
400 T& aResolvedClient ) |
|
401 { |
|
402 TBool success = ETrue; |
|
403 TRAPD (err, aResolvedClient.ConnectL(aRequestItem.ChannelUid())); |
|
404 if (err == KErrNoMemory) |
|
405 { |
|
406 User::Leave(err); |
|
407 } |
|
408 else if (err != KErrNone) |
|
409 { |
|
410 CSIPResponse* response = CSIPResponse::NewLC(K480ResponseCode, |
|
411 SIPStrings::StringF(SipStrConsts::EPhraseTemporarilyNotAvailable)); |
|
412 iReceiver->AddErrorResponseL(aRequestItem.RequestId(),response); |
|
413 CleanupStack::Pop(response); |
|
414 success = EFalse; |
|
415 } |
|
416 else |
|
417 { |
|
418 aRequestItem.SetConnectCalled(); |
|
419 } |
|
420 return success; |
|
421 } |
|
422 |
|
423 // ---------------------------------------------------------------------------- |
|
424 // CSIPCRServerSession::CancelAllRequests |
|
425 // ---------------------------------------------------------------------------- |
|
426 // |
|
427 void CSIPCRServerSession::CancelAllRequests() |
|
428 { |
|
429 iRequestQueueMutex.Wait(); // Protect iRequestQueue with a mutex |
|
430 iRequestQueue.ResetAndDestroy(); |
|
431 iRequestQueueMutex.Signal(); |
|
432 iReceiver->RemoveAll(); |
|
433 } |
|
434 |
|
435 // ---------------------------------------------------------------------------- |
|
436 // CSIPCRServerSession::CancelClientReceiveL |
|
437 // ---------------------------------------------------------------------------- |
|
438 // |
|
439 void CSIPCRServerSession::CancelClientReceiveL () |
|
440 { |
|
441 iReceiver->CancelClientReceiveL(); |
|
442 } |
|
443 |
|
444 // ---------------------------------------------------------------------------- |
|
445 // CSIPCRServerSession::ResolveClientL |
|
446 // ---------------------------------------------------------------------------- |
|
447 // |
|
448 CSIPResponse* CSIPCRServerSession::ResolveClientL( |
|
449 CSIPRequest& aRequest, |
|
450 TSipClient& aUid) |
|
451 { |
|
452 RArray<TSipClient> uids; |
|
453 CleanupClosePushL(uids); |
|
454 // Always execute the client resolving code in the main thread |
|
455 // Multithreading the resolving code would be error prone and |
|
456 // there is no performance reason to create a new thread for resolving. |
|
457 CSIPResponse* response = |
|
458 iCRServer.ClientResolver().FindUidL(aRequest,uids); |
|
459 if (!response) |
|
460 { |
|
461 __ASSERT_ALWAYS(uids.Count() > 0, User::Leave(KErrNotFound)); |
|
462 if (!FindUid(uids,aUid,ETrue,ETrue) && |
|
463 !FindUid(uids,aUid,ETrue,EFalse) && |
|
464 !FindUid(uids,aUid,EFalse,ETrue) && |
|
465 !FindUid(uids,aUid,EFalse,EFalse)) |
|
466 { |
|
467 response = CSIPResponse::NewL(K503ResponseCode, |
|
468 SIPStrings::StringF(SipStrConsts::EPhraseServiceUnavailable)); |
|
469 } |
|
470 } |
|
471 CleanupStack::PopAndDestroy(1); // uids |
|
472 return response; |
|
473 } |
|
474 |
|
475 // ---------------------------------------------------------------------------- |
|
476 // CSIPCRServerSession::ChannelL |
|
477 // ---------------------------------------------------------------------------- |
|
478 // |
|
479 void CSIPCRServerSession::ChannelL( |
|
480 TUint32 aRequestId, |
|
481 CSIPRequest& aRequest, |
|
482 const TSipClient& aClient, |
|
483 const TUid& aResolverUid) |
|
484 { |
|
485 // SIP request cannot be passed as such to the worker thread because |
|
486 // the main and worker threads are using a different string pool. |
|
487 // Instead SIP request is externalized in the main thread and |
|
488 // internalized in the worker thread. |
|
489 CBufBase* serializedRequest = SIPCRSerializer::ExternalizeL(aRequest); |
|
490 CleanupStack::PushL(serializedRequest); |
|
491 HBufC8* requestBody = aRequest.TakeContentOwnershipL(); |
|
492 CleanupStack::PushL(requestBody); |
|
493 |
|
494 CSipCrWorkerAo* workerAo = |
|
495 CSipCrWorkerAo::NewL( |
|
496 aRequestId,serializedRequest,requestBody, |
|
497 aClient,aResolverUid,*this); |
|
498 |
|
499 CleanupStack::Pop(requestBody); |
|
500 CleanupStack::Pop(serializedRequest); |
|
501 |
|
502 CleanupStack::PushL(workerAo); |
|
503 CreateWorkerThreadL(workerAo,ChannelWorkerThreadFunction); |
|
504 CleanupStack::Pop(workerAo); |
|
505 } |
|
506 |
|
507 // ---------------------------------------------------------------------------- |
|
508 // CSIPCRServerSession::ChannelImplementationL |
|
509 // ---------------------------------------------------------------------------- |
|
510 // |
|
511 void CSIPCRServerSession::ChannelImplementationL( CSipCrWorkerAo& aWorkerAo ) |
|
512 { |
|
513 CSIPRequest* request = CSIPRequest::NewLC(); |
|
514 SIPCRSerializer::InternalizeL( |
|
515 aWorkerAo.SerializedSipRequest().Ptr( 0 ), *request ); |
|
516 request->SetContent( aWorkerAo.GetSipRequestBody() ); |
|
517 |
|
518 CSIPResolvedClient2* resolvedClient2 = NULL; |
|
519 CSIPResolvedClient* resolvedClient = NULL; |
|
520 |
|
521 if ( aWorkerAo.SipClient().PluginType() == TSipClient::EFirstGeneration ) |
|
522 { |
|
523 resolvedClient = |
|
524 iCRServer.LoadPlugin1LC( aWorkerAo.SipClient().Uid(), |
|
525 aWorkerAo.ResolverUid() ); |
|
526 __ASSERT_ALWAYS ( resolvedClient , User::Leave( KErrNoMemory ) ); |
|
527 } |
|
528 else |
|
529 { |
|
530 resolvedClient2 = |
|
531 iCRServer.LoadPlugin2LC( aWorkerAo.SipClient().ImplementationUid() ); |
|
532 __ASSERT_ALWAYS ( resolvedClient2 , User::Leave( KErrNoMemory ) ); |
|
533 } |
|
534 |
|
535 TUid channelUid; |
|
536 ChannelUidL( aWorkerAo.SipClient(), channelUid, request, resolvedClient ); |
|
537 |
|
538 TUid nextHopUid( TUid::Null() ); |
|
539 |
|
540 if ( iCRServer.RoutingTable().FindMatch( channelUid, |
|
541 iClientUid, |
|
542 nextHopUid ) ) |
|
543 { |
|
544 iReceiver->RequestCompletedL( aWorkerAo.RequestId(),nextHopUid ); |
|
545 } |
|
546 else // Client not running |
|
547 { |
|
548 CSIPCRRequestItem* requestItem = |
|
549 CSIPCRRequestItem::NewLC( aWorkerAo.RequestId(), |
|
550 aWorkerAo.SipClient(), |
|
551 channelUid, |
|
552 aWorkerAo.ResolverUid() ); |
|
553 if ( resolvedClient ) |
|
554 { |
|
555 AddToRequestQueueL( requestItem, *resolvedClient ); |
|
556 } |
|
557 else |
|
558 { |
|
559 AddToRequestQueueL( requestItem, *resolvedClient2 ); |
|
560 } |
|
561 CleanupStack::Pop( requestItem ); |
|
562 } |
|
563 if ( resolvedClient ) |
|
564 { |
|
565 CleanupStack::PopAndDestroy( resolvedClient ); |
|
566 } |
|
567 if ( resolvedClient2 ) |
|
568 { |
|
569 CleanupStack::PopAndDestroy( resolvedClient2 ); |
|
570 } |
|
571 |
|
572 CleanupStack::PopAndDestroy( request ); |
|
573 } |
|
574 |
|
575 // ---------------------------------------------------------------------------- |
|
576 // CSIPCRServerSession::ChannelUidL |
|
577 // ---------------------------------------------------------------------------- |
|
578 // |
|
579 void CSIPCRServerSession::ChannelUidL( |
|
580 const TSipClient& aClient, |
|
581 TUid& aChannelUid, |
|
582 CSIPRequest* aRequest, |
|
583 CSIPResolvedClient* aResolvedClient ) |
|
584 { |
|
585 if ( aClient.PluginType() == TSipClient::EFirstGeneration ) |
|
586 { |
|
587 HBufC8* uri = aRequest->RequestURI()->ToTextL(); |
|
588 CleanupStack::PushL(uri); |
|
589 |
|
590 CSIPContentTypeHeader* contenTypeHeader = |
|
591 static_cast<CSIPContentTypeHeader*>( |
|
592 aRequest->Header( |
|
593 SIPStrings::StringF(SipStrConsts::EContentTypeHeader),0)); |
|
594 |
|
595 if(aResolvedClient) |
|
596 { |
|
597 aChannelUid = aResolvedClient->ChannelL(aRequest->Method(), |
|
598 *uri, |
|
599 aRequest->AllHeadersL(), |
|
600 aRequest->Content(), |
|
601 contenTypeHeader); |
|
602 } |
|
603 CleanupStack::PopAndDestroy(uri); |
|
604 } |
|
605 else |
|
606 { |
|
607 aChannelUid = aClient.Uid(); |
|
608 } |
|
609 } |
|
610 |
|
611 // ---------------------------------------------------------------------------- |
|
612 // CSIPCRServerSession::HandleNextPendingRequestL |
|
613 // ---------------------------------------------------------------------------- |
|
614 // |
|
615 void CSIPCRServerSession::HandleNextPendingRequestL( |
|
616 CSipCrWorkerAo& /*aWorkerAo*/) |
|
617 { |
|
618 CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex); |
|
619 |
|
620 if ( iRequestQueue.Count() > 0 && !( iRequestQueue[0]->ConnectCalled() ) ) |
|
621 { |
|
622 CSIPCRRequestItem* requestItem = iRequestQueue[ 0 ]; |
|
623 if ( requestItem->Client().PluginType() == |
|
624 TSipClient::EFirstGeneration ) |
|
625 { |
|
626 CSIPResolvedClient* resolvedClient = |
|
627 iCRServer.LoadPlugin1LC( requestItem->Client().Uid(), |
|
628 requestItem->ResolverUid() ); |
|
629 ConnectL( *requestItem, *resolvedClient ); |
|
630 CleanupStack::PopAndDestroy( resolvedClient ); |
|
631 } |
|
632 else |
|
633 { |
|
634 CSIPResolvedClient2* resolvedClient2 = |
|
635 iCRServer.LoadPlugin2LC( requestItem->Client().ImplementationUid() ); |
|
636 ConnectL( *requestItem, *resolvedClient2 ); |
|
637 CleanupStack::PopAndDestroy( resolvedClient2 ); |
|
638 } |
|
639 } |
|
640 |
|
641 CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex |
|
642 } |
|
643 |
|
644 // ---------------------------------------------------------------------------- |
|
645 // CSIPCRServerSession::CreateRequestId |
|
646 // ---------------------------------------------------------------------------- |
|
647 // |
|
648 TUint32 CSIPCRServerSession::CreateRequestId() |
|
649 { |
|
650 if (iRequestIdCounter < KMaxTUint32) |
|
651 { |
|
652 iRequestIdCounter++; |
|
653 } |
|
654 else |
|
655 { |
|
656 iRequestIdCounter = 1; |
|
657 } |
|
658 return iRequestIdCounter; |
|
659 } |
|
660 |
|
661 // ---------------------------------------------------------------------------- |
|
662 // CSIPCRServerSession::FindUid |
|
663 // ---------------------------------------------------------------------------- |
|
664 // |
|
665 TBool CSIPCRServerSession::FindUid( |
|
666 const RArray<TSipClient>& aUids, |
|
667 TSipClient& aUid, |
|
668 TBool aRomBased, |
|
669 TBool aConnected) |
|
670 { |
|
671 TInt found = EFalse; |
|
672 for (TInt i=0; i < aUids.Count() && !found; i++) |
|
673 { |
|
674 const TSipClient& client = aUids[i]; |
|
675 TBool connected = iCRServer.RoutingTable().HasUid(client.Uid()); |
|
676 if ( client.RomBased() == aRomBased && connected == aConnected ) |
|
677 { |
|
678 if ( aConnected || client.AllowStarting() ) |
|
679 { |
|
680 aUid.SetUid( client.Uid() ); |
|
681 aUid.SetAllowStarting( client.AllowStarting() ); |
|
682 aUid.SetPluginType( client.PluginType() ); |
|
683 aUid.SetRomBased( client.RomBased() ); |
|
684 aUid.SetImplementationUid( client.ImplementationUid() ); |
|
685 found = ETrue; |
|
686 } |
|
687 } |
|
688 } |
|
689 return found; |
|
690 } |
|
691 |
|
692 // ---------------------------------------------------------------------------- |
|
693 // CSIPCRServerSession::CreateWorkerThreadL |
|
694 // ---------------------------------------------------------------------------- |
|
695 // |
|
696 void CSIPCRServerSession::CreateWorkerThreadL( |
|
697 CSipCrWorkerAo* aWorkerAo, |
|
698 ThreadFunctionPtr aThreadFunctionPtr) |
|
699 { |
|
700 TName threadName(KWorkerThreadName); |
|
701 threadName.AppendNum(static_cast<TUint64>(Math::Random()),EHex); |
|
702 RThread thread; |
|
703 TInt err = thread.Create(threadName, |
|
704 aThreadFunctionPtr, |
|
705 KDefaultStackSize, |
|
706 NULL, // Use the same heap as the main thread |
|
707 aWorkerAo); |
|
708 User::LeaveIfError(err); |
|
709 CleanupClosePushL(thread); |
|
710 aWorkerAo->StartThreadL(thread); |
|
711 err = iWorkerAos.Append(aWorkerAo); |
|
712 if (err != KErrNone) |
|
713 { |
|
714 aWorkerAo->Cancel(); |
|
715 User::Leave(err); |
|
716 } |
|
717 CleanupStack::PopAndDestroy(&thread); |
|
718 } |
|
719 |
|
720 // ---------------------------------------------------------------------------- |
|
721 // CSIPCRServerSession::ChannelWorkerThreadFunction |
|
722 // ---------------------------------------------------------------------------- |
|
723 // |
|
724 TInt CSIPCRServerSession::ChannelWorkerThreadFunction(TAny* aPtr) |
|
725 { |
|
726 return WorkerThreadFunctionImpl(aPtr, |
|
727 &CSIPCRServerSession::ChannelImplementationL); |
|
728 } |
|
729 |
|
730 // ---------------------------------------------------------------------------- |
|
731 // CSIPCRServerSession::ConnectWorkerThreadFunction |
|
732 // ---------------------------------------------------------------------------- |
|
733 // |
|
734 TInt CSIPCRServerSession::ConnectWorkerThreadFunction(TAny* aPtr) |
|
735 { |
|
736 return WorkerThreadFunctionImpl(aPtr, |
|
737 &CSIPCRServerSession::HandleNextPendingRequestL); |
|
738 } |
|
739 |
|
740 // ---------------------------------------------------------------------------- |
|
741 // CSIPCRServerSession::WorkerThreadFunctionImpl |
|
742 // ---------------------------------------------------------------------------- |
|
743 // |
|
744 TInt CSIPCRServerSession::WorkerThreadFunctionImpl( |
|
745 TAny* aPtr, |
|
746 WorkerFunctionPtr aWorkerFunctionPtr) |
|
747 { |
|
748 CSipCrWorkerAo* workerAo = |
|
749 reinterpret_cast<CSipCrWorkerAo*>(aPtr); |
|
750 TInt err = KErrNoMemory; |
|
751 CTrapCleanup* cleanupStack = CTrapCleanup::New(); |
|
752 if (cleanupStack) |
|
753 { |
|
754 TRAP(err, SIPStrings::OpenL()); |
|
755 if (!err) |
|
756 { |
|
757 TRAP(err, (workerAo->Session().*aWorkerFunctionPtr)(*workerAo)); |
|
758 SIPStrings::Close(); |
|
759 REComSession::FinalClose(); // For each thread separately |
|
760 } |
|
761 } |
|
762 delete cleanupStack; |
|
763 return err; |
|
764 } |
|
765 |
|
766 // ---------------------------------------------------------------------------- |
|
767 // CSIPCRServerSession::ProtectedAddToRequestQueueL |
|
768 // ---------------------------------------------------------------------------- |
|
769 // |
|
770 void CSIPCRServerSession::ProtectedAddToRequestQueueL( |
|
771 CSIPCRRequestItem* aRequestItem) |
|
772 { |
|
773 CSIPCRITCUtility::WaitForMutexLC(iRequestQueueMutex); |
|
774 iRequestQueue.AppendL(aRequestItem); |
|
775 CleanupStack::PopAndDestroy(); // signals iRequestQueueMutex |
|
776 } |
|
777 |
|
778 // ---------------------------------------------------------------------------- |
|
779 // CSIPCRServerSession::ProtectedRemoveFromRequestQueue |
|
780 // ---------------------------------------------------------------------------- |
|
781 // |
|
782 void CSIPCRServerSession::ProtectedRemoveFromRequestQueue( |
|
783 CSIPCRRequestItem* aRequestItem) |
|
784 { |
|
785 iRequestQueueMutex.Wait(); |
|
786 TInt index = iRequestQueue.Find(aRequestItem); |
|
787 if (index >= 0) |
|
788 { |
|
789 iRequestQueue.Remove(index); |
|
790 } |
|
791 iRequestQueueMutex.Signal(); |
|
792 } |
|
793 |
|
794 // ----------------------------------------------------------------------------- |
|
795 // CSIPCRServerSession::RemoveFromRequestQueue |
|
796 // ----------------------------------------------------------------------------- |
|
797 // |
|
798 void CSIPCRServerSession::RemoveFromRequestQueue(TAny* aCleanupData) |
|
799 { |
|
800 TSipCrRequestQueueCleanupData* cleanupData = |
|
801 reinterpret_cast<TSipCrRequestQueueCleanupData*>(aCleanupData); |
|
802 cleanupData->iSession->ProtectedRemoveFromRequestQueue( |
|
803 cleanupData->iRequestItem); |
|
804 } |
|
805 |
|
806 // End of File |