serialserver/c32serialserver/SCOMM/CS_PORT.CPP
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     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 
       
    18 #include "CS_STD.H"
       
    19 #include <f32file.h>
       
    20 #include "C32LOG.H"
       
    21 /** @file
       
    22  *
       
    23  * Implements CPort, CSerial and CLibUnloader
       
    24  */
       
    25 
       
    26 class CLibUnloader : public CAsyncOneShot
       
    27 /** Unloading a C32 library.
       
    28 
       
    29 This class is responsible for unloading a library loaded by C32. The library
       
    30 is specified during construction. After the library is unloaded, this object
       
    31 will destroy itself.
       
    32 
       
    33 Note: The same class is also implemented in Esock, Etel and Nifman. 
       
    34 
       
    35 @internalComponent
       
    36 @released
       
    37  */
       
    38 	{
       
    39 friend class CSerial;
       
    40 public:
       
    41 	static CLibUnloader* NewL(RLibrary &aLib);
       
    42 protected:
       
    43 	CLibUnloader();
       
    44 	virtual void RunL(); // from CActive
       
    45 private:
       
    46 	RLibrary iLib;       //< handle to library to unload
       
    47 	};
       
    48 
       
    49 
       
    50 //
       
    51 // implementation of CLibUnloader
       
    52 //
       
    53 
       
    54 CLibUnloader* CLibUnloader::NewL(RLibrary& aLib)
       
    55 /** Creates a new CLibUnloader object
       
    56 
       
    57 @param aLib reference to the library to unload. */
       
    58 	{
       
    59 	CLibUnloader *s = new(ELeave) CLibUnloader;
       
    60 	s->iLib = aLib;
       
    61 	aLib.SetHandle(0); // Transfer Complete
       
    62 	return s;
       
    63 	}
       
    64 
       
    65 
       
    66 CLibUnloader::CLibUnloader()
       
    67 /** Constructor */
       
    68 	:CAsyncOneShot(CActive::EPriorityHigh)
       
    69 	{
       
    70 	C32LOG1(KC32Shutdown, _L8("CLibUnloader::CLibUnloader"));
       
    71 	}
       
    72 
       
    73 
       
    74 void CLibUnloader::RunL()
       
    75 /** Unloads, closes and deletes a library.
       
    76 
       
    77 This function is called by the Active Scheduler when it is time to unload the
       
    78 Library. It closes the library and deletes itself. */
       
    79 	{
       
    80 	iLib.Close();
       
    81 	delete this;
       
    82 	}
       
    83 
       
    84 
       
    85 
       
    86 //
       
    87 // implementation of CPort
       
    88 //
       
    89 
       
    90 EXPORT_C CPort::CPort()
       
    91 /** Default constructor. Derived classes should implement a NewL() function to 
       
    92 perform their two-phase construction. 
       
    93 
       
    94 @see TSerialNewL */
       
    95 	{
       
    96 	C32LOG1(KC32Player, _L8("CPort::CPort()"));
       
    97 	}
       
    98 
       
    99 
       
   100 EXPORT_C CPort::~CPort()
       
   101 /** Destructor.
       
   102 
       
   103 Closes the owner (which is our CSerial) and removes any timers.
       
   104 
       
   105 Derived classes can implement the destructor but must only call synchronous 
       
   106 functions within it. Any cleanup requiring asynchronous operations must be 
       
   107 done in Destruct(). */
       
   108 	{
       
   109 	C32LOG1(KC32Player, _L8("CPort::~CPort()"));
       
   110 	if (iReadTimerPending)
       
   111 		CommTimer::Remove(iReadTimer);
       
   112 	if (iWriteTimerPending)
       
   113 		CommTimer::Remove(iWriteTimer);
       
   114 	if (Owner())
       
   115 		Owner()->Close();
       
   116 	delete iExtra;
       
   117 	}
       
   118 
       
   119 
       
   120 EXPORT_C void CPort::CPort_Reserved1()
       
   121 /** Reserved virtual function. */
       
   122 	{
       
   123 	}
       
   124 
       
   125 
       
   126 #define MergeModes( a, b ) (((a)<<3) + (b))
       
   127 
       
   128 
       
   129 void CPort::DoOpenL(CCommSession* aSession, TInternalCommAccess aMode, TCommRole aRole, TBool aIsNew)
       
   130 /** Set the access mode and signals for this port if the open request does not conflict with existing
       
   131  usage of this port by other clients.
       
   132 
       
   133 @param aSession pointer to the session
       
   134 @param aMode    access mode
       
   135 @param aRole    port role; DTE or DCE
       
   136 @param aIsNew   ETrue if new session
       
   137 @leave Leave This function may leave. 
       
   138 (Private fn, so this` doco not built into DevLibrary) */
       
   139 	{
       
   140 	C32LOG4(KC32Player,_L8("CPort::DoOpenL(), Session 0x%x, Comm Access Mode : %S, Comm Role : %S"), aSession, &TC32Log::InternalCommAccessStr(aMode), &TC32Log::CommRoleStr(aRole));
       
   141 	if (aSession == iExtra->iPreemptedSession)
       
   142 		iExtra->iPreemptedSession = NULL;  // Don't need to inform session session has been preempted any more.
       
   143 
       
   144 	switch (aMode) 
       
   145 	{
       
   146 	case EIntCommExclusive:
       
   147 	case EIntCommShared:
       
   148 	case EIntCommWaitUntilAvailable:
       
   149 	case EIntCommPreemptable:
       
   150 		break;
       
   151 	default:
       
   152 		User::Leave(KErrNotSupported);
       
   153 	}
       
   154 
       
   155 	if (aIsNew || AccessCount()==0)
       
   156 		{
       
   157 		// ask the CSY to set any signals for DCE/DTE role on this port
       
   158 		(void)User::LeaveIfError(SetRole(aRole)); // ignoring return value
       
   159 		iMode = aMode;
       
   160 		if (aMode == EIntCommPreemptable)
       
   161 			iExtra->iPreemptableOwner=aSession;
       
   162 		else if (aMode == EIntCommWaitUntilAvailable)
       
   163 			iExtra->iWaitAvailableOwner=aSession;
       
   164 		}
       
   165 
       
   166 
       
   167 	else switch (MergeModes(iMode, aMode))
       
   168 		{
       
   169 	default: 
       
   170 		User::Leave(KErrAccessDenied);
       
   171 
       
   172 	case MergeModes(EIntCommPreemptable, EIntCommWaitUntilAvailable):
       
   173 		User::Leave(KErrNotSupported);
       
   174 
       
   175 	case MergeModes(EIntCommShared, EIntCommWaitUntilAvailable):
       
   176 	case MergeModes(EIntCommExclusive, EIntCommWaitUntilAvailable):
       
   177 		if (iExtra->iWaitAvailableOwner!=NULL)
       
   178 			User::Leave(KErrAccessDenied);
       
   179 		iExtra->iWaitAvailableOwner=aSession;
       
   180 		break;
       
   181 
       
   182 	case MergeModes(EIntCommWaitUntilAvailable, EIntCommShared):
       
   183 	case MergeModes(EIntCommWaitUntilAvailable, EIntCommExclusive):
       
   184 	case MergeModes(EIntCommShared, EIntCommShared):
       
   185 		TCommRole tempRole;
       
   186 		(void)GetRole(tempRole); // return value is no use, if it fails temprole is not filled, then the next comparison fails
       
   187 		if (tempRole!=aRole)
       
   188 			User::Leave(KErrLocked);
       
   189 		iMode = aMode;
       
   190 		break;
       
   191 	
       
   192 	case MergeModes(EIntCommPreemptable, EIntCommExclusive):
       
   193 	case MergeModes(EIntCommPreemptable, EIntCommShared):
       
   194 		// Time to preempt!
       
   195 		DoPreemption();
       
   196 		// ask the CSY to set any signals for DCE/DTE role on this port
       
   197 		(void)User::LeaveIfError(SetRole(aRole)); // ignoring return value
       
   198 		iMode = aMode;
       
   199 		break;
       
   200 		}
       
   201 	}
       
   202 
       
   203 
       
   204 void CPort::DoPreemption()
       
   205 /**
       
   206  cancel all outstanding requests and setup the preemted session
       
   207  */
       
   208 	{
       
   209 	C32LOG1(KC32Player, _L8("CPort::DoPreemption()"));
       
   210 	if (iReadOwner) CommReadCancel( NULL, iReadOwner );
       
   211 	if (iWriteOwner) CommWriteCancel( NULL, iWriteOwner );
       
   212 	if (iBreakOwner) CommBreakCancel( NULL, iBreakOwner );
       
   213 	if (iSignalOwner) CommNotifySignalChangeCancel(NULL, iSignalOwner);
       
   214 	if (iConfigOwner) CommNotifyConfigChangeCancel(NULL, iConfigOwner);
       
   215 	if (iFlowControlOwner) CommNotifyFlowControlChangeCancel(NULL, iFlowControlOwner);
       
   216 	if (iBreakNotifyOwner) CommNotifyBreakCancel(NULL, iBreakNotifyOwner);
       
   217 	if (iNotifyOutputEmptyOwner) CommNotifyOutputEmptyCancel(NULL, iNotifyOutputEmptyOwner);
       
   218 	if (iNotifyDataAvailableOwner) CommNotifyDataAvailableCancel(NULL, iNotifyDataAvailableOwner);
       
   219 	
       
   220 	iExtra->iPreemptedSession = iExtra->iPreemptableOwner;
       
   221 	iExtra->iPreemptableOwner = NULL;
       
   222 	}
       
   223 
       
   224 
       
   225 TBool CPort::SessionHasBeenPreempted(CCommSession* aSession)
       
   226 /** returns true if session has been pre-empted
       
   227 
       
   228 @param aSession session to be questioned
       
   229 @return TBool pre-empted status of this session. ETrue if session has been
       
   230         pre-empted, EFalse otherwise.
       
   231 */
       
   232 	{
       
   233 	C32LOG2(KC32Player, _L8("CPort::SessionHasBeenPreempted(), Session 0x%x"), aSession);
       
   234 	return iExtra->iPreemptedSession==aSession;
       
   235 	}
       
   236 
       
   237 
       
   238 TBool CPort::SessionIsAwaitingOpen(CCommSession* aSession)
       
   239 /** returns true if session is waiting for open
       
   240 
       
   241 @param aSession session to be questioned
       
   242 @return TBool ETrue if session is awaiting open, EFalse otherwise. */
       
   243 	{
       
   244 	C32LOG2(KC32Player, _L8("CPort::SessionIsAwaitingOpen(), Session 0x%x"), aSession);
       
   245 	return (iExtra->iWaitAvailableOwner==aSession);
       
   246 	}
       
   247 
       
   248 
       
   249 void CPort::FreeSession(CCommSession* aSession)
       
   250 /** Perform CPort based housekeeping before closing a session
       
   251 
       
   252 @param aSession pointer to the session to free. */
       
   253 	{
       
   254 	C32LOG2(KC32Player, _L8("CPort::FreeSession(), Session 0x%x"), aSession);
       
   255 	// If this session is the waiting owner, NULL the pointer before closure
       
   256 	if(aSession==iExtra->iWaitAvailableOwner)
       
   257 		{
       
   258 		iExtra->iWaitAvailableOwner=NULL;
       
   259 
       
   260 		// If this session is the waiting owner *and* it has a Blocked Set Access
       
   261 		// outstanding (usually the case) complete it with KErrCancel
       
   262 		if(iExtra->iBlockedSetAccess!=RMessagePtr2())
       
   263 			{
       
   264 			SafeComplete(iExtra->iBlockedSetAccess, KErrCancel);
       
   265 			iExtra->iBlockedSetAccess=RMessagePtr2();
       
   266 			}
       
   267 		}
       
   268 	}
       
   269 
       
   270 EXPORT_C void CPort::Close()
       
   271 //Replace close so that we can go asynchronous
       
   272 /** Closes the port. 
       
   273 
       
   274 The base class implements CObject::Close() to handle reference 
       
   275 counting on the port. It decrements the reference count, and calls Destruct() 
       
   276 if the count is 0. */
       
   277 	{
       
   278 	C32LOG1(KC32Player, _L8("CPort::Close()"));
       
   279 	Dec();
       
   280 
       
   281 	__ASSERT_ALWAYS(AccessCount()>=0, Fault(ECPortEObjNegativeAccessCount));
       
   282 
       
   283 	if(iExtra)
       
   284 		{
       
   285 		if (AccessCount()==1 && iExtra->iWaitAvailableOwner != NULL)  
       
   286 			{
       
   287 			if (iExtra->iBlockedSetAccess != RMessagePtr2()) // There's an outstanding SetAccess request
       
   288 				{
       
   289 				SafeComplete(iExtra->iBlockedSetAccess, KErrNone);
       
   290 				iMode = EIntCommPreemptable;  // Only allowed async SetAccess is to Preemptable
       
   291 				iExtra->iPreemptableOwner = iExtra->iWaitAvailableOwner;
       
   292 				iExtra->iWaitAvailableOwner = NULL;
       
   293 				}
       
   294 			}
       
   295 		}
       
   296 
       
   297 	C32LOG2(KC32Player, _L8("CPort::Close() after Dec(), CPort AccessCount is %d "), AccessCount());
       
   298 	if (AccessCount()==0)
       
   299 		Destruct();
       
   300 	}
       
   301 
       
   302 
       
   303 void CPort::CommSetAccess(const RMessage2& aMessage, CCommSession& aSession)
       
   304 /** set the access mode
       
   305 
       
   306 @param aMessage message from client with the new access mode
       
   307 @param aSession handle to the session. */
       
   308 	{
       
   309 	TInternalCommAccess newMode = (TInternalCommAccess)aMessage.Int0();
       
   310 
       
   311 	switch (MergeModes(iMode, newMode))
       
   312 		{
       
   313 	default: 
       
   314 		SafeComplete(aMessage, KErrNotSupported);
       
   315 		break;
       
   316 
       
   317 	case MergeModes(EIntCommExclusive, EIntCommPreemptable): 
       
   318 	case MergeModes(EIntCommShared, EIntCommPreemptable):
       
   319 		if (AccessCount() == 1)  // No - must do close();
       
   320 			PanicClient(EMustCloseNotChangeAccessMode,aMessage);
       
   321 		else if (&aSession != iExtra->iWaitAvailableOwner)  // Wrong session.
       
   322 			PanicClient(EWrongClientForAccessRequest,aMessage);
       
   323 		else
       
   324 			iExtra->iBlockedSetAccess=aMessage;
       
   325 		break;
       
   326 
       
   327 	case MergeModes(EIntCommWaitUntilAvailable, EIntCommPreemptable):
       
   328 		ASSERT(AccessCount() == 1);
       
   329 		iMode = EIntCommPreemptable;
       
   330 		iExtra->iWaitAvailableOwner=NULL;
       
   331 		iExtra->iPreemptableOwner=&aSession;
       
   332 		SafeComplete(aMessage, KErrNone);
       
   333 		break;
       
   334 	
       
   335 	case MergeModes(EIntCommPreemptable, EIntCommExclusive):
       
   336 	case MergeModes(EIntCommPreemptable, EIntCommShared):
       
   337 		iMode = newMode;
       
   338 		SafeComplete(aMessage, KErrNone);
       
   339 		break;
       
   340 		}
       
   341 	}
       
   342 
       
   343 
       
   344 /**
       
   345  *  Checks if a CommSetAccess() request is waiting for the port.
       
   346  *
       
   347  *  @param aClient  The CCommSession client to check against.
       
   348  *  @param aHandle  Handle to the subsession.
       
   349  *
       
   350  *  @return  True if a request is pending, false otherwise.
       
   351  */
       
   352 TBool CPort::IsBlockedSetAccessWaiting(CCommSession& aClient)
       
   353 	{
       
   354 	return (&aClient == iExtra->iWaitAvailableOwner  &&
       
   355 			iExtra->iBlockedSetAccess!=RMessagePtr2());
       
   356 	} // CPort::IsBlockedSetAccessWaiting
       
   357 
       
   358 
       
   359 void CPort::CommSetAccessCancel(TInt /*aHandle*/, CCommSession* aClient)
       
   360 /** Cancels an outstanding set access request.
       
   361 
       
   362 @param aClient pointer to the CCommSession client. */
       
   363 	{
       
   364 	C32LOG2(KC32Player, _L8("CPort::CommSetAccessCancel(), Client Session : 0x%x"), aClient);
       
   365 	if (aClient == iExtra->iWaitAvailableOwner )
       
   366 		SafeComplete(iExtra->iBlockedSetAccess, KErrCancel);
       
   367 	}
       
   368 
       
   369 
       
   370 #ifdef _DEBUG
       
   371 inline TInt Count( CCommSession* a ) { return a ? 1 : 0; }
       
   372 
       
   373 void CPort::CommDebugState(const RMessage2& aMessage, CCommSession& /*aSession*/)
       
   374 /** return debug information about the state of the C32 server and CSY
       
   375 
       
   376 @param aMessage message from client
       
   377 @param aSession handle to the session. */
       
   378 	{
       
   379 	TCommDebugInfo s;
       
   380 	s.iMode = iMode;
       
   381 	s.iAccessCount = AccessCount();
       
   382 	(void)GetRole( s.iRole );
       
   383 	s.iOutstandingCommands = Count( iReadOwner ) + Count( iWriteOwner ) +
       
   384 		Count( iBreakOwner ) + Count( iSignalOwner ) + Count( iFlowControlOwner ) + 
       
   385 		Count( iConfigOwner ) + Count( iBreakNotifyOwner ) + Count( iNotifyDataAvailableOwner ) +
       
   386 		Count( iNotifyOutputEmptyOwner );
       
   387 
       
   388 	TPckgC<TCommDebugInfo> pk( s );
       
   389 	TInt ret = aMessage.Write(0, pk, 0);
       
   390 	if (ret!=KErrNone)
       
   391 		{
       
   392 		PanicClient(EBadDescriptor,aMessage);
       
   393 		}
       
   394 	SafeComplete(aMessage, ret);
       
   395 	}
       
   396 #endif // _DEBUG
       
   397 
       
   398 
       
   399 void CPort::CommRead(const RMessage2& aMessage, CCommSession* aClient)
       
   400 /** Perform a read making sure of the port's owner
       
   401 
       
   402 @param aMessage message from the client
       
   403 @param aClient handle to the client session. */
       
   404 	{ 
       
   405 	C32LOG2(KC32Player, _L8("CPort::CommRead(), Client 0x%x"), aClient);
       
   406 	if (TakeOwnershipForReading(aMessage,aClient))
       
   407 		{
       
   408 		TInt timeOut = aMessage.Int2();
       
   409 		if (timeOut > 0)
       
   410 			{
       
   411 			iReadTimerPending = ETrue;
       
   412 			TCallBack c(CPort::ReadTimerExpiredHandler,this);
       
   413 			iReadTimer.Set(c);
       
   414 			CommTimer::Queue(timeOut, iReadTimer);
       
   415 			}
       
   416 		iBlockedRead = aMessage;
       
   417 		StartRead(aMessage.Ptr0(), aMessage.Int1());
       
   418 		}
       
   419 	else if(aClient != iReadOwner)
       
   420 		SafeComplete(aMessage, KErrInUse);
       
   421 	}
       
   422 
       
   423 
       
   424 void CPort::CommWrite(const RMessage2& aMessage, CCommSession* aClient)
       
   425 /** Perform a write making sure of the port's owner
       
   426 
       
   427 @param aMessage message from the client
       
   428 @param aClient handle to the client session. */
       
   429 	{ 
       
   430 	C32LOG2(KC32Player, _L8("CPort::CommWrite(), Client 0x%x"), aClient);
       
   431 	if(!aMessage.Ptr0())
       
   432 		{
       
   433 		PanicClient(EBadDescriptor,aMessage);
       
   434 		return;
       
   435 		}
       
   436 
       
   437 	if (TakeOwnershipForWriting(aMessage,aClient))
       
   438 		{
       
   439 		TInt timeOut = aMessage.Int2();
       
   440 		if (timeOut > 0)
       
   441 			{
       
   442 			iWriteTimerPending = ETrue;
       
   443 			TCallBack c(CPort::WriteTimerExpiredHandler, this);
       
   444 			iWriteTimer.Set(c);
       
   445 			CommTimer::Queue(timeOut, iWriteTimer);
       
   446 			}
       
   447 
       
   448 		iBlockedWrite = aMessage;
       
   449 		StartWrite(aMessage.Ptr0(), aMessage.Int1());
       
   450 		}
       
   451 	else if(aClient != iWriteOwner)
       
   452 		SafeComplete(aMessage, KErrInUse);
       
   453 	}
       
   454 
       
   455 
       
   456 void CPort::CommBreak(const RMessage2& aMessage, CCommSession* aClient)
       
   457 /** Perform a break making sure of the port's owner
       
   458 
       
   459 @param aMessage message from the client
       
   460 @param aClient handle to the client session. */
       
   461 	{ 
       
   462 	C32LOG2(KC32Player, _L8("CPort::CommBreak(), Client Session 0x%x"), aClient);
       
   463 	if (TakeOwnershipForBreaking(aMessage,aClient))
       
   464 		{
       
   465 		iBlockedBreak=aMessage;
       
   466 		Break(aMessage.Int0());
       
   467 		}
       
   468 	else if(aClient != iBreakOwner)
       
   469 		SafeComplete(aMessage, KErrInUse);
       
   470 	}
       
   471 
       
   472 
       
   473 void CPort::CommConfig(const RMessage2& aMessage, CCommSession& aSession) const
       
   474 /** Get config
       
   475 
       
   476 @param aMessage message from the client
       
   477 @param aSession handle to the client session. */
       
   478 	{
       
   479 	(void)aSession;		// to disable urel warnings
       
   480 	C32LOG2(KC32Player, _L8("CPort::CommConfig(), Client 0x%x"), &aSession);
       
   481 	TInt length=aMessage.GetDesLength(0);
       
   482 	
       
   483 	if (length < 0)
       
   484 		{
       
   485 		PanicClient(EBadDescriptor,aMessage);
       
   486 		return;
       
   487 		}
       
   488 
       
   489 	TInt ret=KErrNoMemory;
       
   490 	TText8* buf=(TText8*)User::Alloc(length);
       
   491 	if (buf)
       
   492 		{
       
   493 		TPtr8 p(buf,length,length);
       
   494 		ret=GetConfig(p);
       
   495 		if (ret==KErrNone)
       
   496 			{
       
   497 			ret = aMessage.Write(0, p, 0);
       
   498 			if (ret!=KErrNone)
       
   499 				{
       
   500 				PanicClient(EBadDescriptor,aMessage);
       
   501 				}
       
   502 			}
       
   503 		User::Free(buf);
       
   504 		}
       
   505 	SafeComplete(aMessage, ret);
       
   506 	}
       
   507 
       
   508 
       
   509 void CPort::CommSetConfig(const RMessage2& aMessage, CCommSession& aSession)
       
   510 /** Set config
       
   511 
       
   512 @param aMessage message from the client
       
   513 @param aSession handle to the client session. */
       
   514 	{ 
       
   515 	(void)aSession;		// to disable urel warnings
       
   516 	C32LOG2(KC32Player, _L8("CPort::CommSetConfig(), Client 0x%x"), &aSession);
       
   517 	TInt length=aMessage.GetDesLength(0);
       
   518 
       
   519 	if (length < 0)
       
   520 		{
       
   521 		PanicClient(EBadDescriptor,aMessage);
       
   522 		return;
       
   523 		}
       
   524 
       
   525 	TInt ret=KErrNoMemory;
       
   526 	TText8* buf=(TText8*)User::Alloc(length);
       
   527 	if (buf)
       
   528 		{
       
   529 		TPtr8 p(buf,length,length);
       
   530 		ret = aMessage.Read(0, p, 0);
       
   531 		if (ret!=KErrNone)
       
   532 			{
       
   533 			C32LOG1(KC32Player, _L8("Error at the time of reading data from client"));
       
   534 			PanicClient(EBadDescriptor,aMessage);
       
   535 			}
       
   536 		if (ret == KErrNone)
       
   537 			{
       
   538 			if(AreAnyPending())
       
   539 				{
       
   540 				ret=KErrInUse;
       
   541 				}
       
   542 			else
       
   543 				ret=SetConfig(p);
       
   544 			}
       
   545 		User::Free(buf);
       
   546 		}
       
   547 	SafeComplete(aMessage, ret);
       
   548 	}
       
   549 
       
   550 
       
   551 void CPort::CommSetServerConfig(const RMessage2& aMessage, CCommSession& aSession)
       
   552 /** Set server config
       
   553 
       
   554 @param aMessage message from the client
       
   555 @param aSession handle to the client session. */
       
   556 	{ 
       
   557 	(void)aSession;		// to disable urel warnings
       
   558 	C32LOG2(KC32Player, _L8("CPort::CommSetServerConfig(), Client 0x%x"), &aSession);
       
   559 	TInt length=aMessage.GetDesLength(0);
       
   560 
       
   561 	if (length < 0)
       
   562 		{
       
   563 		PanicClient(EBadDescriptor,aMessage);		
       
   564 		return;
       
   565 		}
       
   566 
       
   567 	TInt ret=KErrNoMemory;
       
   568 	TText8* buf=(TText8*)User::Alloc(length);
       
   569 	if (buf)
       
   570 		{
       
   571 		TPtr8 p(buf,length,length);
       
   572 		ret = aMessage.Read(0, p, 0);
       
   573 		if (ret!=KErrNone)
       
   574 			{
       
   575 			C32LOG1(KC32Player, _L8("Error at the time of reading data from client"));
       
   576 			PanicClient(EBadDescriptor,aMessage);
       
   577 			}
       
   578 		if (ret == KErrNone)
       
   579 			ret=SetServerConfig(p);
       
   580 		User::Free(buf);
       
   581 		}
       
   582 	SafeComplete(aMessage, ret);
       
   583 	}
       
   584 
       
   585 
       
   586 void CPort::CommGetServerConfig(const RMessage2& aMessage, CCommSession& aSession)
       
   587 /** Get server config
       
   588 
       
   589 @param aMessage message from the client
       
   590 @param aSession handle to the client session. */
       
   591 	{
       
   592 	(void)aSession;		// to disable urel warnings
       
   593 	C32LOG2(KC32Player, _L8("CPort::CommGetServerConfig(), Client 0x%x"), &aSession);
       
   594 	TInt length=aMessage.GetDesLength(0);
       
   595 
       
   596 	if (length < 0)
       
   597 		{
       
   598 		PanicClient(EBadDescriptor,aMessage);		
       
   599 		return;
       
   600 		}
       
   601 
       
   602 	TInt ret=KErrNoMemory;
       
   603 	TText8* buf=(TText8*)User::Alloc(length);
       
   604 	if (buf)
       
   605 		{
       
   606 		TPtr8 p(buf,length,length);
       
   607 		ret=GetServerConfig(p);
       
   608 		if (ret==KErrNone)
       
   609 			{
       
   610 			ret = aMessage.Write(0, p, 0);
       
   611 			if (ret!=KErrNone)
       
   612 				{
       
   613 				PanicClient(EBadDescriptor,aMessage);
       
   614 				}
       
   615 			}
       
   616 		User::Free(buf);
       
   617 		}
       
   618 	SafeComplete(aMessage, ret);
       
   619 	}
       
   620 
       
   621 
       
   622 void CPort::CommCaps(const RMessage2& aMessage, CCommSession& aSession)
       
   623 /** Read capabilities
       
   624 
       
   625 @param aMessage message from the client
       
   626 @param aSession handle to the client session. */
       
   627 	{ 
       
   628 	(void)aSession;		// to disable urel warnings
       
   629 	C32LOG2(KC32Player, _L8("CPort::CommCaps(), Client 0x%x"), &aSession);
       
   630 	TInt length=aMessage.GetDesLength(0);
       
   631 
       
   632 	if (length < 0)
       
   633 		{
       
   634 		PanicClient(EBadDescriptor,aMessage);		
       
   635 		return;
       
   636 		}
       
   637 
       
   638 	TInt ret=KErrNoMemory;
       
   639 	TText8* buf=(TText8*)User::Alloc(length);
       
   640 	if (buf)
       
   641 		{
       
   642 		TPtr8 p(buf,length,length);
       
   643 		ret=GetCaps(p);
       
   644 		if (ret==KErrNone)
       
   645 			{
       
   646 			ret = aMessage.Write(0, p, 0);
       
   647 			if (ret!=KErrNone)
       
   648 				{
       
   649 				PanicClient(EBadDescriptor,aMessage);
       
   650 				}
       
   651 			}
       
   652 		User::Free(buf);
       
   653 		}
       
   654 	SafeComplete(aMessage, ret);
       
   655 	}
       
   656 
       
   657 
       
   658 void CPort::CommSignals(const RMessage2& aMessage, CCommSession& aSession)
       
   659 /** Read signals
       
   660 
       
   661 @param aMessage message from the client
       
   662 @param aSession handle to the client session. */
       
   663 	{
       
   664 	(void)aSession;		// to disable urel warnings
       
   665 	C32LOG2(KC32Player, _L8("CPort::CommSignals(), Client 0x%x"), &aSession);
       
   666 	TUint s;
       
   667 	TPckg<TUint> signals(s);
       
   668 	TInt ret=GetSignals(s);
       
   669 	if (ret==KErrNone)
       
   670 		{
       
   671 		ret = aMessage.Write(0, signals, 0);
       
   672 		if (ret!=KErrNone)
       
   673 			{
       
   674 			PanicClient(EBadDescriptor,aMessage);
       
   675 			}
       
   676 		}
       
   677 	SafeComplete(aMessage, ret);
       
   678 	}
       
   679 
       
   680 
       
   681 void CPort::CommSetSignalsToMark(const RMessage2& aMessage, CCommSession& /*aSession*/)
       
   682 /** Set signal lines 
       
   683 
       
   684 @param aMessage message from the client. */
       
   685 	{
       
   686 	C32LOG1(KC32Player, _L8("CPort::CommSetSignalsToMark()"));
       
   687 	SafeComplete(aMessage, SetSignalsToMark(aMessage.Int0()));
       
   688 	}
       
   689 
       
   690 
       
   691 void CPort::CommSetSignalsToSpace(const RMessage2& aMessage, CCommSession& /*aSession*/)
       
   692 /** Clear signal lines
       
   693 
       
   694 @param aMessage message from the client. */
       
   695 	{ 
       
   696 	C32LOG1(KC32Player, _L8("CPort::CommSetSignalsToSpace()"));
       
   697 	SafeComplete(aMessage, SetSignalsToSpace(aMessage.Int0()));
       
   698 	}
       
   699 
       
   700 
       
   701 void CPort::CommReceiveBufferLength(const RMessage2& aMessage, CCommSession& aSession) const
       
   702 /** read the receive buffer length
       
   703 
       
   704 @param aMessage message from the client
       
   705 @param aSession handle to the client session. */
       
   706 	{
       
   707 	(void)aSession;		// to disable urel warnings
       
   708 	C32LOG2(KC32Player, _L8("CPort::CommReceiveBufferLength(), Client 0x%x"), &aSession);
       
   709 	TInt l;
       
   710 	TPckg<TInt> len(l);
       
   711 	TInt ret=GetReceiveBufferLength(l);
       
   712 	if (ret==KErrNone)
       
   713 		{
       
   714 		ret = aMessage.Write(0, len, 0);
       
   715 		if (ret!=KErrNone)
       
   716 			{
       
   717 			PanicClient(EBadDescriptor,aMessage);
       
   718 			}
       
   719 		}
       
   720 	SafeComplete(aMessage, ret);
       
   721 	}
       
   722 
       
   723 
       
   724 void CPort::CommSetReceiveBufferLength(const RMessage2& aMessage, CCommSession& aSession)
       
   725 /** Set the receive buffer length
       
   726 
       
   727 @param aMessage message from the client
       
   728 @param aSession handle to the client session. */
       
   729 	{ 
       
   730 	(void)aSession;		// to disable urel warnings
       
   731 	C32LOG2(KC32Player, _L8("CPort::CommSetReceiveBufferLength(), Client 0x%x"), &aSession);
       
   732 	if(AreAnyPending()) // Stop RDevComm panicking us and panic client instead
       
   733 		{
       
   734 		PanicClient(ESetReceiveBufferLengthWhilePendingRequests,aMessage);
       
   735 		}
       
   736 	else
       
   737 		{
       
   738 		//
       
   739 		// Check for negative or zero length buffer size...
       
   740 		//
       
   741 		if(aMessage.Int0() <= 0)
       
   742 			{
       
   743 			PanicClient(EBadDescriptor,aMessage);			
       
   744 			}
       
   745 		else
       
   746 			{
       
   747 			SafeComplete(aMessage, SetReceiveBufferLength(aMessage.Int0()));
       
   748 			}
       
   749 		}
       
   750 	}
       
   751 
       
   752 
       
   753 void CPort::CommQueryReceiveBuffer(const RMessage2& aMessage, CCommSession& aSession) const
       
   754 /** Set the receive buffer length
       
   755 
       
   756 @param aMessage message from the client
       
   757 @param aSession handle to the client session. */
       
   758 	{
       
   759 	(void)aSession;		// to disable urel warnings
       
   760 	C32LOG2(KC32Player, _L8("CPort::CommQueryReceiveBuffer(), Client 0x%x"), &aSession);
       
   761 	TInt l;
       
   762 	TPckg<TInt> len(l);
       
   763 	TInt ret=QueryReceiveBuffer(l);
       
   764 	if (ret==KErrNone)
       
   765 		{
       
   766 		ret = aMessage.Write(0, len, 0);
       
   767 		if (ret!=KErrNone)
       
   768 			{
       
   769 			PanicClient(EBadDescriptor,aMessage);
       
   770 			}
       
   771 		}
       
   772 	SafeComplete(aMessage, ret);
       
   773 	}
       
   774 
       
   775 
       
   776 void CPort::CommResetBuffers(const RMessage2& aMessage, CCommSession& aSession)
       
   777 /** Set the receive buffer length
       
   778 
       
   779 @param aMessage message from the client
       
   780 @param aSession handle to the client session. */
       
   781 	{
       
   782 	(void)aSession;		// to disable urel warnings
       
   783 	C32LOG2(KC32Player, _L8("CPort::CommResetBuffers(), Client 0x%x"), &aSession);
       
   784 	if(AreAnyPending()) // Stop RDevComm panicking us and panic client instead
       
   785 		{
       
   786 		PanicClient(EResetBuffersWhilePendingRequests,aMessage);		
       
   787 		}
       
   788 	else
       
   789 		{
       
   790 		ResetBuffers(aMessage.Int0());
       
   791 		SafeComplete(aMessage, KErrNone);
       
   792 		}
       
   793 	}
       
   794 
       
   795 
       
   796 void CPort::CommReadCancel(TInt aHandle, CCommSession* aClient)
       
   797 /** Cancel outstanding read
       
   798 
       
   799 @param aHandle handle to the client
       
   800 @param aClient handle to the client session. */
       
   801 	{
       
   802 	C32LOG2(KC32Player, _L8("CPort::CommReadCancel(), Client 0x%x"), aClient);
       
   803 	if (iReadOwner==aClient && (!aHandle || aHandle==iReadOwnerHandle))
       
   804 		{
       
   805 		ReadCancel();
       
   806 		ReadCompleted(KErrCancel);
       
   807 		}
       
   808 	}
       
   809 
       
   810 
       
   811 void CPort::CommWriteCancel(TInt aHandle, CCommSession* aClient)
       
   812 /** Cancel outstanding write
       
   813 
       
   814 @param aHandle handle to the client
       
   815 @param aClient handle to the client session. */
       
   816 	{
       
   817 	C32LOG2(KC32Player, _L8("CPort::CommWriteCancel(), Client 0x%x"), aClient);
       
   818 	if (iWriteOwner==aClient && (!aHandle || aHandle==iWriteOwnerHandle))
       
   819 		{
       
   820 		WriteCancel();
       
   821 		WriteCompleted(KErrCancel);
       
   822 		}
       
   823 	}
       
   824 
       
   825 
       
   826 void CPort::CommBreakCancel(TInt aHandle, CCommSession* aClient)
       
   827 /** Cancel outstanding break
       
   828 
       
   829 @param aHandle handle to the client
       
   830 @param aClient handle to the client session. */
       
   831 	{
       
   832 	C32LOG2(KC32Player, _L8("CPort::CommBreakCancel(), Client 0x%x"), aClient);
       
   833 	if (iBreakOwner==aClient && (!aHandle || aHandle==iBreakOwnerHandle))
       
   834 		{
       
   835 		BreakCancel();
       
   836 		BreakCompleted(KErrCancel);
       
   837 		}
       
   838 	}
       
   839 
       
   840 
       
   841 void CPort::CommCancel(TInt aHandle, CCommSession* aClient)
       
   842 /** Cancel any outstanding requests
       
   843 
       
   844 @param aHandle handle to the client
       
   845 @param aClient handle to the client session. */
       
   846 	{ 
       
   847 	C32LOG2(KC32Player, _L8("CPort::CommCancel(), Client 0x%x"), aClient);
       
   848 	CommWriteCancel(aHandle, aClient);
       
   849 	CommBreakCancel(aHandle, aClient);
       
   850 	CommReadCancel(aHandle, aClient);
       
   851 
       
   852 	/* Extended asynchronous calls */
       
   853 	CommNotifySignalChangeCancel(aHandle, aClient);
       
   854 	CommNotifyConfigChangeCancel(aHandle, aClient);
       
   855 	CommNotifyFlowControlChangeCancel(aHandle, aClient);
       
   856 	CommNotifyBreakCancel(aHandle, aClient);
       
   857 	CommNotifyOutputEmptyCancel(aHandle, aClient);
       
   858 	CommNotifyDataAvailableCancel(aHandle, aClient);
       
   859 
       
   860 	CommSetAccessCancel( aHandle, aClient );
       
   861 	}
       
   862 
       
   863 
       
   864 void CPort::FreeMemory()
       
   865 /** Specifies a protocol by which the comms server can request the protocol to 
       
   866 release memory. Typically, an implementation may be able to do this by reducing 
       
   867 internal buffers. 
       
   868 
       
   869 The default behaviour is to do nothing. */
       
   870 	{
       
   871 	}
       
   872 
       
   873 
       
   874 TInt CPort::WriteTimerExpiredHandler(TAny* aPtr)
       
   875 /** This static function is called when the write timer expires.
       
   876 installed by CPort::CommWrite as TCallBack
       
   877 
       
   878 @param aPtr pointer to the CPort with the timedout write
       
   879 @return KErrNone always. */
       
   880 	{
       
   881 	C32LOG1(KC32Player, _L8("CPort::WriteTimerExpiredHandler()"));
       
   882 	((CPort *)aPtr)->iWriteTimerPending=EFalse;
       
   883 	((CPort *)aPtr)->WriteCancel();
       
   884 	((CPort *)aPtr)->WriteCompleted(KErrTimedOut);
       
   885 
       
   886 	return KErrNone;
       
   887 	}
       
   888 
       
   889 
       
   890 TInt CPort::ReadTimerExpiredHandler(TAny *aPtr)
       
   891 /** This static function is called when the read timer expires.
       
   892 installed by CPort::CommRead as TCallBack
       
   893 
       
   894 @param aPtr pointer to the CPort with the timedout read
       
   895 @return KErrNone always. */
       
   896 	{
       
   897 	C32LOG1(KC32Player, _L8("CPort::ReadTimerExpiredHandler()"));
       
   898 	((CPort *)aPtr)->iReadTimerPending = EFalse;
       
   899 	((CPort *)aPtr)->ReadCancel();
       
   900 	((CPort *)aPtr)->ReadCompleted(KErrTimedOut);
       
   901 	return KErrNone;
       
   902 	}
       
   903 
       
   904 
       
   905 EXPORT_C void CPort::ReadCompleted(TInt aError)
       
   906 /** Tells the comms server that a read request initiated through StartRead() is 
       
   907 complete. 
       
   908 
       
   909 The comms server will then notify the client that its read request is complete. 
       
   910 
       
   911 Called by C32 server or CSY. 
       
   912 	
       
   913 @param aError Return code to be passed back to the client through its TRequestStatus 
       
   914 argument. */
       
   915 	{
       
   916 	C32LOG2(KC32Player, _L8("CPort::ReadCompleted(), Error Code %d"), aError);
       
   917 	if (iReadOwner)
       
   918 		{
       
   919 		if(iBlockedRead.Handle())
       
   920 			SafeComplete(iBlockedRead, aError);
       
   921 		}
       
   922 	iReadOwner = 0;
       
   923 	if (iReadTimerPending)
       
   924 		{
       
   925 		CommTimer::Remove(iReadTimer);
       
   926 		iReadTimerPending = EFalse;
       
   927 		}
       
   928 	}
       
   929 
       
   930 
       
   931 EXPORT_C void CPort::WriteCompleted(TInt aError)
       
   932 /** Tells the comms server that a write request initiated through StartWrite() 
       
   933 is complete. 
       
   934 
       
   935 The comms server will then notify the client that its write request is complete. 
       
   936 
       
   937 Called by C32 server or CSY.
       
   938 	
       
   939 @param aError Return code to be passed back to the client through its TRequestStatus 
       
   940 argument. */
       
   941 	{
       
   942 	C32LOG2(KC32Player, _L8("CPort::WriteCompleted(), Error Code %d"), aError);
       
   943 	if (iWriteOwner)
       
   944 		{
       
   945 		if(iBlockedWrite.Handle())
       
   946 			SafeComplete(iBlockedWrite, aError);
       
   947 	}
       
   948 	iWriteOwner=0;
       
   949 	if (iWriteTimerPending)
       
   950 		{
       
   951 		CommTimer::Remove(iWriteTimer);
       
   952 		iWriteTimerPending=EFalse;
       
   953 		}
       
   954     }
       
   955 
       
   956 
       
   957 EXPORT_C void CPort::BreakCompleted(TInt aError)
       
   958 /** Tells the comms server that a break request initiated through Break() is complete. 
       
   959 
       
   960 The comms server will then notify the client that its break request is complete. 
       
   961 
       
   962 Called by C32 server or CSY.
       
   963 	
       
   964 @param aError Return code to be passed back to the client through its TRequestStatus 
       
   965 argument. */
       
   966 	{
       
   967 	C32LOG2(KC32Player, _L8("CPort::BreakCompleted(), Error Code %d"), aError);
       
   968 	if (iBreakOwner)
       
   969 		{
       
   970 		if(iBlockedBreak.Handle())
       
   971 			SafeComplete(iBlockedBreak, aError);		
       
   972 		}
       
   973 	iBreakOwner=0;
       
   974 	}
       
   975 
       
   976 
       
   977 TBool CPort::TakeOwnershipForReading(const RMessage2& aMessage,CCommSession* aClient)
       
   978 /** Check if a Read request is valid and take ownership of port
       
   979 
       
   980 @param aClient handle to the client session
       
   981 @return TBool ETrue if ownership granted, EFalse otherwise. */
       
   982 	{
       
   983 	C32LOG2(KC32Player, _L8("CPort::TakeOwnershipForReading(), Client 0x%x"), aClient);
       
   984 	if (!iReadOwner)
       
   985 		{
       
   986 		iReadOwner=aClient;
       
   987 		iReadOwnerHandle=aMessage.Int3();
       
   988 		return ETrue;
       
   989 		}
       
   990 	else
       
   991 		{
       
   992 		if (aClient==iReadOwner)
       
   993 			PanicClient(EReadTwice,aMessage);
       
   994 		return EFalse;
       
   995 		}
       
   996 	}
       
   997 
       
   998 
       
   999 TBool CPort::TakeOwnershipForWriting(const RMessage2& aMessage,CCommSession* aClient)
       
  1000 /** Check if a Write request is valid and take ownership of port
       
  1001 
       
  1002 @param aClient handle to the client session
       
  1003 @return TBool ETrue if ownership granted, EFalse otherwise. */
       
  1004 	{
       
  1005 	C32LOG2(KC32Player, _L8("CPort::TakeOwnershipForWriting(), Client 0x%x"), aClient);
       
  1006 	if (!iWriteOwner)
       
  1007 		{
       
  1008 		iWriteOwner=aClient;
       
  1009 		iWriteOwnerHandle=aMessage.Int3();
       
  1010 		return ETrue;
       
  1011 		}
       
  1012 	else
       
  1013 		{
       
  1014 		if (aClient==iWriteOwner)
       
  1015 			PanicClient(EWriteTwice,aMessage);
       
  1016 		return EFalse;
       
  1017 		}
       
  1018 	}
       
  1019 
       
  1020 
       
  1021 TBool CPort::TakeOwnershipForBreaking(const RMessage2& aMessage,CCommSession* aClient)
       
  1022 /** Check if a Break request is valid and take ownership of port
       
  1023 
       
  1024 @param aClient handle to the client session
       
  1025 @return TBool ETrue if ownership granted, EFalse otherwise. */
       
  1026 	{
       
  1027 	C32LOG2(KC32Player, _L8("CPort::TakeOwnershipForBreaking(), Client 0x%x"), aClient);
       
  1028 	if (!iBreakOwner)
       
  1029 		{
       
  1030 		iBreakOwner=aClient;
       
  1031 		iBreakOwnerHandle=aMessage.Int3();
       
  1032 		return ETrue;
       
  1033 		}
       
  1034 	else
       
  1035 		{
       
  1036 		if (aClient==iBreakOwner)
       
  1037 			PanicClient(EBreakTwice,aMessage);
       
  1038 		return EFalse;
       
  1039 		}
       
  1040 	}
       
  1041 
       
  1042 
       
  1043 TBool CPort::AreAnyPending()
       
  1044 /** Return true if there is an outstanding Read/Write/Break on the CSY. */
       
  1045 	{
       
  1046 	return (iBreakOwner || iWriteOwner || iReadOwner);
       
  1047 	}
       
  1048 
       
  1049 
       
  1050 EXPORT_C TInt CPort::IPCRead(const TAny* /*aPtr*/, TDes8& aDes, TInt aOffset) const
       
  1051 /** Reads data from the client's (the user of the port's) address space.
       
  1052 
       
  1053 The client address space pointer is obtained from the aClientBuffer argument to
       
  1054 StartRead().
       
  1055 
       
  1056 Note:
       
  1057 
       
  1058 This function is normally called by the CSY
       
  1059 
       
  1060 Note:
       
  1061 
       
  1062 Used as part of RComm::Write
       
  1063 
       
  1064 @see RThread::ReadL() for more information on reading data in other address spaces.
       
  1065 @param aPtr    Not Used. The client data is now obtained from iBlockedWrite.
       
  1066 @param aDes    A descriptor (8 bit variant) into which the result of the client
       
  1067                address space read operation will be stored
       
  1068 @param aOffset The read offset from the start of the client's descriptor data.
       
  1069 @return TInt   KErrNone: success
       
  1070                KErrNotReady: there is no read or write request outstanding
       
  1071                KErrBadDescriptor: the client's descriptor is not valid. 
       
  1072 */
       
  1073 	{
       
  1074 	if (!iWriteOwner)
       
  1075 		{
       
  1076 		return KErrNotReady;
       
  1077 		}
       
  1078 	TInt ret = iBlockedWrite.Read(0, aDes, aOffset);
       
  1079 	if (ret!=KErrNone)
       
  1080 		{
       
  1081 		C32LOG1(KC32Player, _L8("Error at the time of reading data from client"));
       
  1082 		PanicClient(EBadDescriptor,iBlockedWrite);
       
  1083 		}
       
  1084 	return ret;
       
  1085 	}
       
  1086 
       
  1087 
       
  1088 EXPORT_C TInt CPort::IPCWrite(const TAny* /*aPtr*/, const TDesC8& aDes, TInt aOffset) const
       
  1089 /** Writes into the client's (the user of the port's) address space. 
       
  1090 
       
  1091 The client address space pointer is obtained from the aClientBuffer argument to
       
  1092 StartWrite().
       
  1093 
       
  1094 Note:
       
  1095 
       
  1096 This function is normally called by the CSY
       
  1097 
       
  1098 Note:
       
  1099 
       
  1100 Used as part of RComm::Read
       
  1101 
       
  1102 @see RThread::WriteL() for more information on writing data to other address spaces.
       
  1103 @param aPtr    Client address space pointer
       
  1104 @param aDes    A descriptor (8 bit variant) into which the result of the client 
       
  1105 address space read will be stored
       
  1106 @param aOffset The offset from aPtr at which to start reading
       
  1107 @return TInt   KErrNone: success
       
  1108                KErrNotReady: there is no read or write request outstanding 
       
  1109                KErrBadDescriptor: the client's descriptor is not valid. */
       
  1110 	{
       
  1111 	if (!iReadOwner)
       
  1112 		return KErrNotReady;
       
  1113 	TInt ret = iBlockedRead.Write(0, aDes, aOffset);
       
  1114 	if (ret!=KErrNone)
       
  1115 		{
       
  1116 		PanicClient(EBadDescriptor, iBlockedRead);
       
  1117 		}
       
  1118 	return ret;
       
  1119 	}
       
  1120 
       
  1121 
       
  1122 
       
  1123 //
       
  1124 // implementation of CSerial
       
  1125 //
       
  1126 
       
  1127 EXPORT_C CSerial::CSerial()
       
  1128 /** Default constructor. 
       
  1129 
       
  1130 Derived classes can implement a NewL() function if they require 
       
  1131 two-phase construction. */
       
  1132 	{
       
  1133 	}
       
  1134 
       
  1135 
       
  1136 EXPORT_C CSerial::~CSerial()
       
  1137 /** Destructor. */
       
  1138 	{
       
  1139 	C32LOG1(KC32Player, _L8("CSerial::~CSerial()"));
       
  1140 	if (iLibUnloader)
       
  1141 		{
       
  1142 		iLibUnloader->Call();
       
  1143 		}
       
  1144 	// During shutdown, if a client still has a CSY loaded,
       
  1145 	// this destructor's calling of its base destructor (CObject)
       
  1146 	// will cause a panic when the kernel attempts to delete the CObject due
       
  1147 	// to the kernel seeing the outstanding access count.
       
  1148 	// There could be a better way of aiding this diagnosis than just spotting this comment
       
  1149 	// when the call stack is analysed, but we haven't found such a way yet.
       
  1150 	// In a debugger, inspecting the name of the object should reveal the CSY involved.
       
  1151 	}
       
  1152 
       
  1153 
       
  1154 EXPORT_C TBool CSerial::QueryVersionSupported(const TVersion& aVersion ) const
       
  1155 // Pass through to default QVS
       
  1156 /** Specifies the protocol for checking the supplied TVersion against the protocol's 
       
  1157 module version. 
       
  1158 
       
  1159 The default implementation calls User::QueryVersionSupported() to perform the check 
       
  1160 against the object's iVersion member.
       
  1161 
       
  1162 @param aVersion The version to be checked.
       
  1163 @return ETrue if the version is supported. */
       
  1164 	{
       
  1165 	return(User::QueryVersionSupported(iVersion,aVersion));
       
  1166 	}
       
  1167 
       
  1168 EXPORT_C TSecurityPolicy CSerial::PortPlatSecCapability(TUint /*aPort*/) const
       
  1169 /**
       
  1170 Retrieve the security policy for a requested port.
       
  1171 This base implementation sets the default policy to be an 'AlwaysFail' policy.
       
  1172 
       
  1173 @param aPort Port number.
       
  1174 @return TSecurityPolicy Security policy associated with opeing this port
       
  1175 */
       
  1176 	{
       
  1177 	return TSecurityPolicy(TSecurityPolicy::EAlwaysFail);
       
  1178 	}
       
  1179 
       
  1180 void CSerial::ConstructL(RLibrary& aLib)
       
  1181 /** Allocate a CLibrary unloader
       
  1182 
       
  1183 @param aLib reference to the library to be unloaded in the future
       
  1184 @leave OOM this function may leave if out of memory. */
       
  1185 	{
       
  1186 	iLibUnloader = CLibUnloader::NewL(aLib);
       
  1187 	}
       
  1188 
       
  1189 
       
  1190 EXPORT_C void CSerial::CSerial_Reserved1()
       
  1191 /** Reserved virtual function. */
       
  1192 	{
       
  1193 	}
       
  1194 
       
  1195 
       
  1196 void CSerial::ModuleName(TDes& aName)
       
  1197 /** Get the module name from the libary reference
       
  1198 
       
  1199 @param aName Module name will be written to this descriptor. */
       
  1200     {
       
  1201 	TFileName filename = iLibUnloader->iLib.FileName();
       
  1202 	TParsePtrC pc(filename);
       
  1203 	aName = pc.Name();
       
  1204     }
       
  1205 
       
  1206 
       
  1207 // EOF - CS_PORT.CPP