|
1 // Copyright (c) 1997-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 // |
|
15 |
|
16 /** |
|
17 @file SS_PROT.CPP |
|
18 */ |
|
19 |
|
20 #include <ss_std.h> |
|
21 #include <ss_glob.h> |
|
22 #include <comms-infras/ss_roles.h> |
|
23 #include <comms-infras/ss_log.h> |
|
24 #include <ss_protprov.h> |
|
25 #include <ss_sock.h> |
|
26 |
|
27 |
|
28 #ifdef _DEBUG |
|
29 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module |
|
30 // (if it could happen through user error then you should give it an explicit, documented, category + code) |
|
31 _LIT(KSpecAssert_ESockSSockS_PROT, "ESockSSockS_PROT"); |
|
32 #endif |
|
33 |
|
34 using namespace ESock; |
|
35 |
|
36 NONSHARABLE_CLASS(CLibUnloader) : public CAsyncOneShot |
|
37 /** |
|
38 @internalComponent |
|
39 */ |
|
40 { |
|
41 public: |
|
42 static CLibUnloader* NewL(RLibrary &aLibrary); |
|
43 inline void Unload(); |
|
44 protected: |
|
45 CLibUnloader(); |
|
46 ~CLibUnloader(); |
|
47 virtual void RunL(); |
|
48 private: |
|
49 RLibrary iLib; |
|
50 }; |
|
51 |
|
52 CLibUnloader::CLibUnloader() |
|
53 /** |
|
54 Constructor |
|
55 */ |
|
56 :CAsyncOneShot(ECAsyncDeferredPriority) |
|
57 { |
|
58 __DECLARE_NAME(_S("CLibUnloader")); |
|
59 } |
|
60 |
|
61 CLibUnloader* CLibUnloader::NewL(RLibrary &aLibrary) |
|
62 { |
|
63 CLibUnloader* u=new(ELeave)CLibUnloader; |
|
64 u->iLib=aLibrary; |
|
65 return u; |
|
66 } |
|
67 |
|
68 inline void CLibUnloader::Unload() |
|
69 { |
|
70 Call(); |
|
71 } |
|
72 |
|
73 CLibUnloader::~CLibUnloader() |
|
74 { |
|
75 Cancel(); |
|
76 iLib.Close(); |
|
77 } |
|
78 |
|
79 void CLibUnloader::RunL() |
|
80 { |
|
81 delete this; |
|
82 } |
|
83 |
|
84 EXPORT_C CServProviderBase::CServProviderBase() |
|
85 { |
|
86 } |
|
87 |
|
88 EXPORT_C CServProviderBase::~CServProviderBase() |
|
89 { |
|
90 delete iV1ShimDataOut; |
|
91 delete iV1ShimDataIn; |
|
92 } |
|
93 |
|
94 EXPORT_C void CServProviderBase::SetNotify(MSocketNotify* aSocket) |
|
95 /** |
|
96 Set notification for transport services to a single protocol |
|
97 |
|
98 @param aSocket, notify the socket server that various events have occurred |
|
99 */ |
|
100 { |
|
101 iSocket = aSocket; |
|
102 } |
|
103 |
|
104 EXPORT_C void CServProviderBase::SetSockType(TUint aSockType) |
|
105 { |
|
106 iSockType = aSockType; |
|
107 } |
|
108 |
|
109 EXPORT_C TUint CServProviderBase::SockType() const |
|
110 { |
|
111 return iSockType; |
|
112 } |
|
113 |
|
114 EXPORT_C void CServProviderBase::JoinSubConnectionL(CSubConnectionProviderBase& /*aSubConnProvider*/) |
|
115 { |
|
116 User::Leave(KErrNotSupported); |
|
117 } |
|
118 |
|
119 EXPORT_C void CServProviderBase::LeaveSubConnection(CSubConnectionProviderBase& /*aSubConnProvider*/) |
|
120 { |
|
121 __ASSERT_DEBUG(EFalse, User::Panic(KSpecAssert_ESockSSockS_PROT, 1)); |
|
122 } |
|
123 |
|
124 EXPORT_C TUint CServProviderBase::Write(const TDesC8& /*aDesc*/, TUint /*options*/, TSockAddr* /*anAddr*/) |
|
125 { |
|
126 Panic(EProviderIncomplete); |
|
127 return 0; |
|
128 } |
|
129 |
|
130 EXPORT_C void CServProviderBase::GetData(TDes8& /*aDesc*/, TUint /*options*/, TSockAddr* /*anAddr*/) |
|
131 { |
|
132 Panic(EProviderIncomplete); |
|
133 } |
|
134 |
|
135 EXPORT_C TInt CServProviderBase::Write(RMBufChain& aData, TUint aOptions, TSockAddr* anAddr) |
|
136 { |
|
137 // This version only gets called when the provider neglects to provide a better v1.5 |
|
138 // implementation; efficiency is not paramount |
|
139 if(!iV1ShimDataOut) |
|
140 { |
|
141 iV1ShimDataOut = HBufC8::New(aData.Length()); |
|
142 if(!iV1ShimDataOut) |
|
143 { |
|
144 return KErrNoMemory; |
|
145 } |
|
146 } |
|
147 else if(iV1ShimDataOut->Size() < aData.Length()) |
|
148 { |
|
149 // We need extra room for data. As ReAlloc returns NULL if fails, we |
|
150 // need to temporary save the previous storage in order to clear it |
|
151 // in the case of ReAlloc failure. |
|
152 HBufC8* aTempPtr = iV1ShimDataOut; |
|
153 iV1ShimDataOut = iV1ShimDataOut->ReAlloc(aData.Length()); |
|
154 if(!iV1ShimDataOut) |
|
155 { |
|
156 delete aTempPtr; |
|
157 return KErrNoMemory; |
|
158 } |
|
159 } |
|
160 |
|
161 TPtr8 des = iV1ShimDataOut->Des(); |
|
162 des.SetLength(aData.Length()); |
|
163 aData.CopyOut(des, 0); |
|
164 TInt ret = Write(des, aOptions, anAddr); |
|
165 if(ret > 0) |
|
166 { |
|
167 if(iSockType == KSockStream) |
|
168 { |
|
169 aData.TrimStart(ret); |
|
170 } |
|
171 else |
|
172 { |
|
173 aData.Free(); |
|
174 } |
|
175 } |
|
176 return ret; |
|
177 } |
|
178 |
|
179 EXPORT_C TInt CServProviderBase::GetData(RMBufChain& aData, TUint aLength, TUint aOptions, TSockAddr* anAddr) |
|
180 { |
|
181 // This version only gets called when the provider neglects to provide a better v1.5 |
|
182 // implementation; efficiency is not paramount |
|
183 |
|
184 // With datagram continuation reads it is important that the provider returns the whole datagram even when |
|
185 // the client's transfer buffer is too small for this to be done as a single read. Because legacy protocols |
|
186 // may respect the length field ESOCK sets a high-order bit to make it look like a large buffer. Continuation |
|
187 // reads aren't supported with this descriptor interface (due to the need to allocate an arbitarily large |
|
188 // buffer) so here the bit is reset |
|
189 aLength &= ~KGetDataWholeDatagram; |
|
190 |
|
191 if(!iV1ShimDataIn) |
|
192 { |
|
193 iV1ShimDataIn = HBufC8::New(aLength); |
|
194 if(!iV1ShimDataIn) |
|
195 { |
|
196 return KErrNoMemory; |
|
197 } |
|
198 } |
|
199 else if(iV1ShimDataIn->Size() < TInt(aLength)) |
|
200 { |
|
201 // We need extra room for data. As ReAlloc returns NULL if fails, we |
|
202 // need to temporary save the previous storage in order to clear it |
|
203 // in the case of ReAlloc failure. |
|
204 HBufC8* aTempPtr = iV1ShimDataIn; |
|
205 iV1ShimDataIn = iV1ShimDataIn->ReAlloc(aLength); |
|
206 if(!iV1ShimDataIn) |
|
207 { |
|
208 delete aTempPtr; |
|
209 return KErrNoMemory; |
|
210 } |
|
211 } |
|
212 |
|
213 TInt extraNeeded = aLength - aData.Length(); |
|
214 if(extraNeeded > 0) |
|
215 { |
|
216 TInt err = aData.Append(extraNeeded); |
|
217 if(err != KErrNone) |
|
218 { |
|
219 return KErrNoMBufs; |
|
220 } |
|
221 } |
|
222 |
|
223 TPtr8 des = iV1ShimDataIn->Des(); |
|
224 des.SetLength(aLength); |
|
225 GetData(des, aOptions, anAddr); |
|
226 aData.CopyIn(des, 0); |
|
227 // Handle protocol reneging (eg when read being cancelled) |
|
228 if(des.Length() < TInt(aLength)) |
|
229 { |
|
230 aData.TrimEnd(des.Length()); |
|
231 } |
|
232 |
|
233 if(iSockType == KSockStream) |
|
234 { |
|
235 return des.Length(); |
|
236 } |
|
237 else |
|
238 { |
|
239 return 1; // datagrams are counted as "atoms" not bytes |
|
240 } |
|
241 } |
|
242 |
|
243 |
|
244 EXPORT_C CServProviderBase * CProtocolBase::NewSAPL(TUint /*aProtocol*/) |
|
245 // |
|
246 // Default socket creation |
|
247 // |
|
248 /** Creates a new service access point. |
|
249 |
|
250 If the protocol cannot create the CServProviderBase for any reason, it should leave. |
|
251 |
|
252 @param aProtocol Protocol. |
|
253 */ |
|
254 { |
|
255 |
|
256 Fault(EOddSock); |
|
257 return (CServProviderBase*)NULL; //lint !e527 // unreachable |
|
258 } |
|
259 |
|
260 EXPORT_C TInt CHostResolvProvdBase::SetOption(TUint /*level*/, TUint /*name*/, const TDesC8& /*anOption*/) |
|
261 /** |
|
262 Default Set Option for Host Resolver |
|
263 |
|
264 Sets options for the protocol on behalf of socket server clients |
|
265 |
|
266 @param level, The level in the stack the option request is ‘aimed’ at |
|
267 @param name, The name of the option |
|
268 @param anOption, Descriptor to hold the option data |
|
269 @return KErrNotSupported if the option is not supported. |
|
270 */ |
|
271 { |
|
272 return KErrNotSupported; |
|
273 } |
|
274 |
|
275 |
|
276 EXPORT_C void CHostResolvProvdBase::Query(const TDesC8& /*aQryBuf*/, TDes8& /*aResBuf*/, TInt /*aCounter*/) |
|
277 /** |
|
278 * Make a query to the protocol. |
|
279 * @param aQryBuf descriptor representing query data. |
|
280 * @param aResBuf descriptor representing query response data. |
|
281 * @param aCounter query sequential number counter. From the client's point of view it will be 0 for "Query" call |
|
282 * and increased by 1 for each "QueryGetNext" call. |
|
283 * @note for aCounter > 0 data in aQryBuf are not supposed to be used. |
|
284 */ |
|
285 { |
|
286 if(iNotify) |
|
287 { |
|
288 iNotify->QueryComplete(KErrNotSupported); |
|
289 } |
|
290 } |
|
291 |
|
292 |
|
293 EXPORT_C TInt CServProviderBase::SecurityCheck(MProvdSecurityChecker* /*aChecker*/) |
|
294 /** |
|
295 Ask the socket provider to perform a security policy check on the originating process |
|
296 (default implementation). |
|
297 |
|
298 Called when a socket is opened or transferred, and after the PRT presents a new accepting |
|
299 socket to ESOCK. |
|
300 |
|
301 @param aChecker class instance that socket provider can use to check capabilities of originating |
|
302 process. |
|
303 @return KErrNone if check passes, KErrPermissionDenied if check fails, else a system-wide error code. |
|
304 */ |
|
305 { |
|
306 // ******************************************************************** |
|
307 // NOTE: KErrNone for now, but this should be changed to KErrNotSupported to |
|
308 // turn on strict checking and fail PRTs that have not been secured. |
|
309 // ******************************************************************** |
|
310 return KErrNone; |
|
311 } |
|
312 |
|
313 EXPORT_C TInt CResolverProvdBase::SecurityCheck(MProvdSecurityChecker* /*aChecker*/) |
|
314 /** |
|
315 Ask the resolver provider to perform a security policy check on the originating process |
|
316 (default implementation). |
|
317 |
|
318 Called when a resolver is opened. |
|
319 |
|
320 @param aChecker class instance that resolver can use to check capabilities of originating process. |
|
321 @return KErrNone if check passes, KErrPermissionDenied if check fails, else a system-wide error code. |
|
322 */ |
|
323 { |
|
324 // ******************************************************************** |
|
325 // NOTE: KErrNone for now, but this should be changed to KErrNotSupported to |
|
326 // turn on strict checking and fail PRTs that have not been secured. |
|
327 // ******************************************************************** |
|
328 return KErrNone; |
|
329 } |
|
330 |
|
331 |
|
332 |
|
333 EXPORT_C void CProtocolBase::StartSending(CProtocolBase* /*aProtocol*/) |
|
334 // |
|
335 // Default StartSending - ignored |
|
336 // |
|
337 /** Indicates that data can now be sent. Implementations can call bound higher-level |
|
338 protocols and service access points in turn. |
|
339 |
|
340 With Send(), this function forms a flow control pair. A zero return from a |
|
341 Send() should flow control off the calling protocol. StartSending() acts as |
|
342 a flow control on. |
|
343 |
|
344 @note This implementation does nothing. |
|
345 |
|
346 @param aProtocol The calling protocol */ |
|
347 { |
|
348 } |
|
349 |
|
350 EXPORT_C void CProtocolBase::InitL(TDesC &/*aTag*/) |
|
351 // |
|
352 // Default InitL - ignored |
|
353 // |
|
354 /** Initialises a protocol before any binding is performed. A protocol can override |
|
355 it to create any further resources it may require - this might include allocating |
|
356 buffers, opening devices or reading more configuration information. |
|
357 |
|
358 If the protocol encounters any errors it should leave. |
|
359 |
|
360 @note This implementation does nothing. |
|
361 |
|
362 @param aTag The string identifier for the protocol as given by its section |
|
363 header in esock.ini */ |
|
364 { |
|
365 } |
|
366 |
|
367 EXPORT_C void CProtocolBase::StartL(void) |
|
368 // |
|
369 // Default StartL - ignored |
|
370 // |
|
371 /** Indicates to a protocol that all binding has completed successfully and it |
|
372 can start processing datagrams. This is mainly of interest to the lowest levels |
|
373 of a protocol stack which would queue a read on the network media device driver |
|
374 in response to this call. |
|
375 |
|
376 If a protocol cannot start to process data (for example it may not have bound |
|
377 correctly) it should leave. |
|
378 |
|
379 @note This implementation does nothing. |
|
380 */ |
|
381 { |
|
382 } |
|
383 |
|
384 EXPORT_C void CProtocolBase::BindL(CProtocolBase* /*protocol*/, TUint /*id*/) |
|
385 // |
|
386 // Default BindL - Panic |
|
387 // |
|
388 /** This function panics with a panic number of EDoesNotBindBelow. |
|
389 |
|
390 @param protocol The higher level protocol requesting to bind |
|
391 @param id The ID number of the protocol requesting to bind */ |
|
392 { |
|
393 Panic(EDoesNotBindBelow); |
|
394 } |
|
395 |
|
396 EXPORT_C void CProtocolBase::BindToL(CProtocolBase* /*protocol*/) |
|
397 // |
|
398 // Default BindToL - Panic |
|
399 // |
|
400 /** This function panics with a panic number of EDoesNotBindAbove. |
|
401 |
|
402 @param protocol The lower level protocol whose bind function must be called. |
|
403 */ |
|
404 { |
|
405 Panic(EDoesNotBindAbove); |
|
406 } |
|
407 |
|
408 EXPORT_C TInt CProtocolBase::Send(RMBufChain& /*aPDU*/,CProtocolBase* /*aSourceProtocol=NULL*/) |
|
409 /** |
|
410 This function panics with a panic number of ECantSendMBufs. |
|
411 |
|
412 @param aPDU, MBuf chain |
|
413 @param aSourceProtocol, The protocol from which the data has been sent |
|
414 */ |
|
415 { |
|
416 Panic(ECantSendMBufs); |
|
417 return 0; |
|
418 } |
|
419 |
|
420 EXPORT_C TInt CProtocolBase::Send(TDes8& /*aPDU*/,TSockAddr* /*to*/,TSockAddr* /*from=NULL*/,CProtocolBase* /*aSourceProtocol=NULL*/) |
|
421 /** |
|
422 This function panics with a panic number of ECantSendDescriptors. |
|
423 |
|
424 @param aPDU The datagram to be sent. |
|
425 @param aTo The address to send the datagram to. |
|
426 @param aFrom The address originating the send. |
|
427 @param aSourceProtocol The protocol from which the data has been sent. |
|
428 @return KErrNone or another of the system wide error codes. |
|
429 */ |
|
430 { |
|
431 Panic(ECantSendDescriptors); |
|
432 return 0; |
|
433 } |
|
434 |
|
435 EXPORT_C void CProtocolBase::Process(RMBufChain &,CProtocolBase* /*aSourceProtocol=NULL*/) |
|
436 /** |
|
437 This function panics with a panic number of ECantProcessMbufs. |
|
438 |
|
439 @param MBuf Chain |
|
440 @param aSourceProtocol, The datagram to be sent |
|
441 */ |
|
442 { |
|
443 Panic(ECantProcessMbufs); |
|
444 } |
|
445 |
|
446 EXPORT_C void CProtocolBase::Process(TDes8& /*aPDU*/,TSockAddr* /*from*/,TSockAddr* /*to=NULL*/,CProtocolBase* /*aSourceProtocol=NULL*/) |
|
447 /** |
|
448 This function panics with a panic number of ECantProcessDescriptors. |
|
449 |
|
450 @param aPDU The datagram to process. |
|
451 @param aFrom The address the datagram is from. |
|
452 @param aTo The address the datagram is to. |
|
453 @param aSourceProtocol The higher level protocol which we want to |
|
454 process our incoming datagram. |
|
455 */ |
|
456 { |
|
457 Panic(ECantProcessDescriptors); |
|
458 } |
|
459 |
|
460 EXPORT_C TInt CProtocolBase::GetOption(TUint /*level*/,TUint /*name*/,TDes8& /*option*/,CProtocolBase* /*aSourceProtocol=NULL*/) |
|
461 // |
|
462 // default Getoption - return KErrNotSupported |
|
463 // |
|
464 /** Gets options for the protocol on behalf of socket server clients. |
|
465 |
|
466 The option parameter is protocol-defined - this is a generic API. |
|
467 The protocol is passed in because you might get GetOption() calls from |
|
468 multiple bindees - this is actually more meaningful for SetOption(). |
|
469 |
|
470 @param aLevel The level in the stack the option request is aimed at. |
|
471 @param aName The name of the option. |
|
472 @param anOption Descriptor to hold the option data. |
|
473 @param aSourceProtocol The protocol making the request. |
|
474 @return KErrNone or another of the system wide error codes; this version returns KErrNotSupported. |
|
475 */ |
|
476 { |
|
477 return KErrNotSupported; |
|
478 } |
|
479 |
|
480 EXPORT_C TInt CProtocolBase::SetOption(TUint /*level*/,TUint /*name*/,const TDesC8& /*option*/,CProtocolBase* /*aSourceProtocol=NULL*/) |
|
481 // |
|
482 // default SetOption - return KErrNotSupported |
|
483 // |
|
484 /** Sets options for the protocol on behalf of socket server clients. |
|
485 |
|
486 The option parameter is protocol-defined - this is a generic API. |
|
487 |
|
488 The protocol is passed in because you might get SetOption() calls from |
|
489 multiple bindees and need to distinguish who is setting what. |
|
490 |
|
491 @param aLevel The level in the stack the option request is aimed at. |
|
492 @param aName The name of the option. |
|
493 @param anOption Descriptor to hold the option data. |
|
494 @param aSourceProtocol The protocol making the request. |
|
495 @return KErrNone or another of the system wide error codes; this version returns KErrNotSupported. |
|
496 */ |
|
497 { |
|
498 return KErrNotSupported; |
|
499 } |
|
500 |
|
501 EXPORT_C void CProtocolBase::Error(TInt anError,CProtocolBase* aSourceProtocol) |
|
502 /** |
|
503 This function panics with a panic number of EErrorCallNotHandled unless the error is KErrCancel |
|
504 which is simply ignored. |
|
505 |
|
506 @param anError The error code |
|
507 @param aSourceProtocol The protocol raising the error */ |
|
508 { |
|
509 #ifdef ESOCK_LOGGING_ACTIVE |
|
510 _LIT(KUnknownProtocolTag, "unknown"); |
|
511 |
|
512 TPtrC tagPtr(KUnknownProtocolTag); |
|
513 if (iManagerRef) |
|
514 { |
|
515 tagPtr.Set(iManagerRef->Tag()); |
|
516 } |
|
517 |
|
518 TPtrC srcTagPtr(KUnknownProtocolTag); |
|
519 if (aSourceProtocol && aSourceProtocol->iManagerRef) |
|
520 { |
|
521 srcTagPtr.Set(aSourceProtocol->iManagerRef->Tag()); |
|
522 } |
|
523 |
|
524 TPtrC panicCatPtr(KESockProtocolPanic); |
|
525 |
|
526 if(anError == KErrCancel) |
|
527 { |
|
528 LOG( ESockLog::Printf(KESockErrorTag, _L("CProtocolBase %08x:\tError() - error: KErrCancel, protocol: %S, source protocol: %S (%08X)"), this, &srcTagPtr, &tagPtr, aSourceProtocol ) ); |
|
529 } |
|
530 else |
|
531 { |
|
532 LOG( ESockLog::Printf(KESockErrorTag, _L("CProtocolBase %08x:\tError() - error: %d, source protocol: %S (%08X), %S protocol panicing with category: %S, reason: EErrorCallNotHandled"), this, anError, &srcTagPtr, aSourceProtocol, &tagPtr, &panicCatPtr ) ); |
|
533 } |
|
534 #else |
|
535 (void)anError; |
|
536 (void)aSourceProtocol; |
|
537 #endif |
|
538 |
|
539 // We do not panic if an operation (e.g., StartSending in tcpip6) was merely cancelled. |
|
540 if(anError != KErrCancel) |
|
541 { |
|
542 Panic(EErrorCallNotHandled); |
|
543 } |
|
544 } |
|
545 |
|
546 CProtocolFamilyBase * CProtocolBase::ProtocolFamily() |
|
547 /** |
|
548 Get our family - through the manager ref. |
|
549 |
|
550 @return protocol family |
|
551 */ |
|
552 { |
|
553 return iManagerRef->Family(); |
|
554 } |
|
555 |
|
556 EXPORT_C CHostResolvProvdBase *CProtocolBase::NewHostResolverL() |
|
557 /** |
|
558 This function panics with a panic number of EBadHostResolver. |
|
559 |
|
560 @return The host name resolver service */ |
|
561 { |
|
562 Fault(EBadHostResolver); |
|
563 return (CHostResolvProvdBase*)NULL; //lint !e527 // unreachable |
|
564 } |
|
565 |
|
566 EXPORT_C CServiceResolvProvdBase *CProtocolBase::NewServiceResolverL() |
|
567 /** |
|
568 This function panics with a panic number of EBadServiceResolver. |
|
569 |
|
570 @return The service resolver service */ |
|
571 { |
|
572 Fault(EBadServiceResolver); |
|
573 return (CServiceResolvProvdBase*)NULL; //lint !e527 // unreachable |
|
574 } |
|
575 |
|
576 |
|
577 EXPORT_C CNetDBProvdBase *CProtocolBase::NewNetDatabaseL() |
|
578 /** |
|
579 This function panics with a panic number of EBadNetDBRequest. |
|
580 |
|
581 @return The network database access service */ |
|
582 { |
|
583 |
|
584 Fault(EBadNetDBRequest); |
|
585 return (CNetDBProvdBase*)NULL; //lint !e527 // unreachable |
|
586 } |
|
587 |
|
588 EXPORT_C CProtocolBase::~CProtocolBase() |
|
589 /** |
|
590 Destroy the Protocol Base |
|
591 */ |
|
592 { |
|
593 LOG( ESockLog::Printf(KESockProvChoresTag, _L("CProtocolBase %08x:\t~CProtocolBase()"), this ) ); |
|
594 |
|
595 if (iManagerRef) |
|
596 { |
|
597 iManagerRef->ProtocolClosed(); |
|
598 } |
|
599 } |
|
600 |
|
601 EXPORT_C CProtocolBase::CProtocolBase() |
|
602 /** |
|
603 Constructor for the Protocol Base |
|
604 */ |
|
605 :CBase() |
|
606 { |
|
607 LOG( ESockLog::Printf(KESockProvChoresTag, _L("CProtocolBase %08x:\tCProtocolBase()"), this ) ); |
|
608 } |
|
609 |
|
610 EXPORT_C void CProtocolBase::Open() |
|
611 // |
|
612 // C'Tor for the Protocol Base |
|
613 // |
|
614 /** Opens a client connection. |
|
615 |
|
616 The default implementation simply increments the reference count. |
|
617 |
|
618 Any implementations by derived classes should call this base |
|
619 class implementation. */ |
|
620 { |
|
621 iRefCount++; |
|
622 LOG ( |
|
623 const TDesC& tag(Tag()); |
|
624 ESockLog::Printf(KESockProvChoresTag, _L("CProtocolBase %08x:\tOpen() '%S' RefCount %d"), this , &tag, iRefCount) |
|
625 ); |
|
626 } |
|
627 |
|
628 EXPORT_C void CProtocolBase::Close() |
|
629 // |
|
630 // C'Tor for the Protocol Base |
|
631 // |
|
632 /** Closes a client connection. |
|
633 |
|
634 The default implementation decrements the reference count and calls |
|
635 CloseNow() if no clients are connected. |
|
636 |
|
637 Any implementations by derived classes should call this base class implementation. */ |
|
638 { |
|
639 iRefCount--; |
|
640 LOG ( |
|
641 const TDesC& tag(Tag()); |
|
642 ESockLog::Printf(KESockProvChoresTag, _L("CProtocolBase %08x:\tClose() '%S' RefCount %d"), this, &tag, iRefCount) |
|
643 ); |
|
644 |
|
645 if (iRefCount<=0) |
|
646 { |
|
647 if (SocketServer::IsShuttingDown()) |
|
648 { |
|
649 delete this; |
|
650 } |
|
651 else |
|
652 { |
|
653 CloseNow(); |
|
654 } |
|
655 } |
|
656 } |
|
657 |
|
658 EXPORT_C void CProtocolBase::CloseNow() |
|
659 // |
|
660 // Default CloseNow function - just delete the protocol |
|
661 // |
|
662 /** Closes the protocol. |
|
663 |
|
664 Called by Close() when all clients referencing a protocol have disconnected. |
|
665 |
|
666 The default implementation simply deletes the object. Derived classes can implement |
|
667 this function to provide a delayed closedown: for example, to allow reliable |
|
668 protocols to ensure that all data has drained from the stack before it is deleted. |
|
669 When an acceptable closedown condition has been reached, the protocol should call |
|
670 CanClose(). */ |
|
671 { |
|
672 delete this; |
|
673 } |
|
674 |
|
675 EXPORT_C void CProtocolBase::CanClose() |
|
676 // |
|
677 // Up call from derived classes |
|
678 // |
|
679 /** Called by derived classes when an acceptable closedown condition has been reached. |
|
680 |
|
681 Derived classes should not override this function. |
|
682 |
|
683 @see CloseNow() for more details. */ |
|
684 { |
|
685 delete this; |
|
686 } |
|
687 |
|
688 void CProtocolBase::TryDelete() |
|
689 /** |
|
690 delete Protocol Base if ref count <0 |
|
691 Used from Protocol manager cleanup stack entries |
|
692 */ |
|
693 { |
|
694 if (iRefCount<=0) |
|
695 { |
|
696 delete this; |
|
697 } |
|
698 } |
|
699 |
|
700 EXPORT_C TBool CProtocolFamilyBase::QueryVersionSupported( TVersion const & aVersion ) const |
|
701 /** |
|
702 Queries whether the version is supported by the protocol |
|
703 |
|
704 @param aVersion, version information |
|
705 @return ETrue if supported else EFalse |
|
706 */ |
|
707 { |
|
708 return(User::QueryVersionSupported(iVersion,aVersion)); |
|
709 } |
|
710 |
|
711 void CProtocolFamilyBase::SetLibraryL(RLibrary& aLib) |
|
712 /** |
|
713 Sets the Protocol Family's resource library to dynamically loadable DLL. |
|
714 |
|
715 @param aLib, a handle to a dynamically loadable DLL |
|
716 */ |
|
717 { |
|
718 iLibUnloader=CLibUnloader::NewL(aLib); |
|
719 } |
|
720 |
|
721 EXPORT_C CProtocolFamilyBase::~CProtocolFamilyBase() |
|
722 /** |
|
723 Destructor for the protocol family |
|
724 Calling this means that all protocols have been unloaded and we can close the |
|
725 library after our death. |
|
726 */ |
|
727 { |
|
728 |
|
729 if (iManagerRef) |
|
730 { |
|
731 iManagerRef->FamilyClosed(); |
|
732 } |
|
733 |
|
734 // Can't close the library because of the ret instruction for this function is in it. |
|
735 // Ask a CAsync to unload the library for us. |
|
736 if(iLibUnloader) |
|
737 { |
|
738 LOG( ESockLog::Printf(KESockProvChoresTag, _L8("~CProtocolFamilyBase(%08x) - unload of PRT requested"), this ) ); |
|
739 iLibUnloader->Unload(); |
|
740 } |
|
741 |
|
742 CSockManData * globals=SockManGlobals::Get(); |
|
743 globals->iNumFamilies--; |
|
744 |
|
745 if (globals->iShutdownGracefully) |
|
746 { |
|
747 // if (globals->iNumSessions<=0 && globals->iNumFamilies<=0) |
|
748 // { |
|
749 // globals->iShutdownWatchDog->Shutdown(); |
|
750 // } |
|
751 // else |
|
752 // { |
|
753 // LOG( ESockLog::Printf(_L8("CProtocolFamilyBase::~CProtocolFamilyBase() - shutdown requested: %d sessions, %d families remaining"), globals->iNumSessions, globals->iNumFamilies ) ); |
|
754 // } |
|
755 LOG( ESockLog::Printf(KESockProvChoresTag, _L8("~CProtocolFamilyBase(%08x) - shutdown requested: %d families remaining"), this, globals->iNumFamilies ) ); |
|
756 if (globals->iNumFamilies <= 0) |
|
757 { |
|
758 // globals->SelfWorker()->PlayerShutdownComplete(); |
|
759 CWorkerThread* selfWorker = globals->SelfWorker(); |
|
760 selfWorker->Player()->MaybeSetPlayerShutdownComplete(EFalse); |
|
761 selfWorker->MaybeTriggerThreadShutdownCallback(); |
|
762 } |
|
763 else |
|
764 { |
|
765 #ifdef _DEBUG |
|
766 globals->LogActiveProtocols(); |
|
767 #endif |
|
768 } |
|
769 } |
|
770 } |
|
771 |
|
772 EXPORT_C TPtrC CProtocolBase::Tag() |
|
773 // |
|
774 // return the tag name |
|
775 // |
|
776 /** Gets a TPtrC to the protocol's tag name. The default implementation returns |
|
777 the tag passed to Init(). |
|
778 |
|
779 @return Protocol's tag name */ |
|
780 { |
|
781 return iManagerRef->Tag(); |
|
782 } |
|
783 |
|
784 EXPORT_C CProtocolFamilyBase::CProtocolFamilyBase() :CBase() |
|
785 /** |
|
786 Constructor for the protocol family |
|
787 */ |
|
788 { |
|
789 |
|
790 SockManGlobals::Get()->iNumFamilies++; |
|
791 } |
|
792 |
|
793 EXPORT_C void CProtocolFamilyBase::Open() |
|
794 // |
|
795 // C'Tor for the Protocol Base |
|
796 // |
|
797 /** Opens a protocol family. |
|
798 |
|
799 When a socket is created, the socket server first calls this function on |
|
800 the protocol family. It is not compulsory for the protocol |
|
801 family to implement this function - the default behaviour of the socket |
|
802 server, which is to increment an access count for the protocol family, may |
|
803 be sufficient. */ |
|
804 { |
|
805 iRefCount++; |
|
806 } |
|
807 |
|
808 EXPORT_C void CProtocolFamilyBase::Close( ) |
|
809 /** |
|
810 replacment close gives any derived class chance to delete anything it wants |
|
811 or to signal an error. |
|
812 |
|
813 Closes this reference counting object |
|
814 */ |
|
815 { |
|
816 |
|
817 iRefCount--; |
|
818 if (iRefCount<=0) |
|
819 { |
|
820 if (Remove()==KErrNone) |
|
821 { |
|
822 delete this; |
|
823 } |
|
824 else |
|
825 { |
|
826 Panic(ERemoveRefused); |
|
827 } |
|
828 } |
|
829 } |
|
830 |
|
831 EXPORT_C TInt CProtocolFamilyBase::Remove( ) |
|
832 /** Prepares the protocol family to be removed in a derived class. |
|
833 |
|
834 The socket server calls Remove() before unloading the library for a given |
|
835 protocol family. |
|
836 |
|
837 @note This implementation returns KErrNone. |
|
838 |
|
839 @return System-wide error code. The socket server guarantees that the protocol |
|
840 family will always be in a suitable position to perform closedown. If this |
|
841 is not the case, for example there are still active connections, then this |
|
842 function should return an error code other that KErrNone. */ |
|
843 { |
|
844 |
|
845 return(KErrNone); |
|
846 } |