serialserver/serialportcsy/ECUART.CPP
changeset 0 dfb7c4ff071f
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2002-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 // Implements a complete CSY for physical serial ports
       
    15 // 
       
    16 //
       
    17 
       
    18 /**
       
    19  @file
       
    20 */
       
    21 
       
    22 #include <cs_port.h>
       
    23 #include <d32comm.h>
       
    24 #include <c32comm.h>
       
    25 #include <e32hal.h>
       
    26 // new header file introduced in C32 V2, old ecuart had no header file
       
    27 #include "ECUART.H"
       
    28 #include <c32comm_internal.h>
       
    29 
       
    30 // This header import is new for C32 V2 but is not configured since then we don't need to configure all
       
    31 // the logging we've added to this file during V2. The ecuartlog header file when pre-processed for pre-V2
       
    32 // will resolve all the logging to nothing since all its log macros for pre-V2 are defined empty.
       
    33 #include "ECUARTLOG.H"
       
    34 
       
    35 const TUint KCommLowUnit=0;  //< lowest port unit number for this CSY (i.e. COMM::0)
       
    36 
       
    37 #if defined(__WINS__)
       
    38 const TUint KCommHighUnit=1; //< highest port unit number for this CSY (i.e. COMM::1)
       
    39 #else // _MARM_
       
    40 const TUint KCommHighUnit=0; //< highest port unit number for this CSY (i.e. COMM::0)
       
    41 #endif
       
    42 
       
    43 const TUint KDefaultBufSize = 0x100; //< size of the Tx/Rx buffers used in CCommWriter and CCommReader
       
    44 
       
    45 _LIT(KSerialDescription, "Built in Serial ports"); //< CSY description returned by RCommServ::GetPortInfo
       
    46 #define SERIAL_NAME _S("COMM")  //< name of prefix for each com port
       
    47 
       
    48 const TInt KReaderPriority=100; //< priority for the CCommReader active object
       
    49 const TInt KWriterPriority=50;  //< priority for the CCommWriter active object
       
    50 const TInt KBreakerPriority=0;  //< priority for the CCommBreaker active object
       
    51 const TInt KNotifyPriority=0;   //< priority for CCommNotifyBase derived active objects
       
    52 
       
    53 
       
    54 //Security policy for a port.
       
    55 class TPortSecurityPolicy
       
    56 	{
       
    57 public:
       
    58 	//Port number which this policy will apply.
       
    59 	TInt iPort;
       
    60 	//Security policy.
       
    61 	TStaticSecurityPolicy iPolicy;
       
    62 	};
       
    63 
       
    64 _LIT_SECURITY_POLICY_PASS(KDefaultPortPassPolicy);
       
    65 _LIT_SECURITY_POLICY_FAIL(KPortAlwaysFailPolicy);
       
    66 
       
    67 #define KPlaceholderPortNumber -1	//a place holder port number used to initiliase KExplicitPortSecurityPolicies when no other ports require a policy different than the default.
       
    68 
       
    69 //Define policy for ports which are different from default policy (KDefaultPortPolicy) here.
       
    70 //Default policy is EAlwaysPass but to provide example ports 0-1 are explicitly set to EAlwaysPass as well.
       
    71 //Port policies must only apply for port number 0-(KMaxUnits-1).
       
    72 //Add to this array for other ports that need policing with capabilities.
       
    73 const TUint KExplicitPortPoliciesCount = 0;	//Count of the number of entries in KExplicitPortSecurityPolicies.  Currently only a place holder entry exists so the count = 0.
       
    74 const struct TPortSecurityPolicy KExplicitPortSecurityPolicies[]=
       
    75 	{
       
    76 	{KPlaceholderPortNumber, _INIT_SECURITY_POLICY_FAIL}	//this is a place holder entry which should be replaced with proper port policy when required to police a port with different capabiltiies to default policy.
       
    77 //	{0, _INIT_SECURITY_POLICY_C1( ECapabilityCommDD)},	//Example showing explicitly setting a policy different than default for Port 0
       
    78 //	{1, _INIT_SECURITY_POLICY_C2( ECapabilityReadUserData, ECapabilityWriteUserData)}	//Example showing explicitly setting a policy different than default for Port 1
       
    79 	};
       
    80 
       
    81 
       
    82 // #define _DEBUG_CONSOLE_
       
    83 
       
    84 #if defined(_DEBUG_CONSOLE_)
       
    85 #include <e32twin.h>
       
    86 class RDebugConsole : public RConsole
       
    87 	{
       
    88 public:
       
    89 	RDebugConsole();
       
    90 public:
       
    91 	void Printf(TRefByValue<const TDesC> aFmt,...);
       
    92 	};
       
    93 
       
    94 #define DEBUG_TRACE(m) m
       
    95 
       
    96 #else	// (_DEBUG)
       
    97 
       
    98 // debug trace (disabled in Release builds)
       
    99 #define DEBUG_TRACE(m)
       
   100 //
       
   101 #endif
       
   102 
       
   103 //
       
   104 // CCommReader CCommWriter and CCommBreaker are active objects which wait on
       
   105 // completion from the serial channel for various actions.
       
   106 //
       
   107 class CHWPort;
       
   108 
       
   109 /**
       
   110  * base class for CCommReader and CCommWriter
       
   111  *
       
   112  */
       
   113 class CCommReadWriteBase : public CActive
       
   114 	{
       
   115 public:
       
   116 	CCommReadWriteBase(TInt aPriority, CHWPort* aParent);
       
   117 	~CCommReadWriteBase();
       
   118 	TInt SetServerConfig(TCommServerConfig& aConfig);
       
   119 	void GetServerConfig(TCommServerConfig& aConfig) const;
       
   120 	void FreeMemory();
       
   121 	 // set the role of this port unit @param aRole new role
       
   122 	inline void SetRole(TCommRole aRole){iRole=aRole;};
       
   123 protected:
       
   124 	void SetBuffersL();
       
   125 	// return ETrue if partial buffering used
       
   126 	TBool UsePartial() {return ((iBufFlags & KCommBufferPartial)==KCommBufferPartial);}
       
   127 protected:
       
   128 	HBufC8* iBuffer;  //< pointer to the Tx/Rx buffer
       
   129 	TPtr8* iBuf;      //< pointer to a TPtr8 that points to the current buffer
       
   130 	TUint iBufFlags;  //< contains buffer flags e.g for partial read/write
       
   131 	TInt iBufSize;    //< size of the Tx/Rx buffer
       
   132 	TCommRole iRole;  //< DTE or DCE role for this port unit
       
   133 	CHWPort* iParent; //< pointer to the CHWPort object
       
   134 	};
       
   135 
       
   136 
       
   137 #if defined (_DEBUG_DEVCOMM) && defined (_DEBUG_CONSOLE_)
       
   138 class CCommDebugDumper : public CActive
       
   139 	{
       
   140 public:
       
   141 	static CCommDebugDumper* NewL(RDebugConsole &aConsole);
       
   142 	virtual void RunL();
       
   143 	virtual void DoCancel();
       
   144 	CCommDebugDumper::~CCommDebugDumper();
       
   145 	 // set the role of this port unit @param aRole new role
       
   146 	inline void SetRole(TCommRole aRole){iRole=aRole;};
       
   147 private:
       
   148 	CCommDebugDumper(RDebugConsole &aConsole);
       
   149 private:
       
   150 	TCommRole iRole;         //< DTE or DCE role for this port unit
       
   151 	RDebugConsole *iConsole;
       
   152 	TConsoleKey iKeystroke;
       
   153 	};
       
   154 #endif
       
   155 
       
   156 
       
   157 /**
       
   158  * Active Comm port Reader
       
   159  *
       
   160  * This class is responsible for reading data from the physical
       
   161  * comm port.
       
   162  */
       
   163 class CCommReader : public CCommReadWriteBase
       
   164 	{
       
   165 public:
       
   166 	static CCommReader* NewL(CHWPort* aParent);
       
   167 	~CCommReader();
       
   168 	// from CActive
       
   169 	virtual void DoCancel();
       
   170 	virtual void RunL();
       
   171 	//
       
   172 	void Read(const TAny* aClientBuffer, TInt aLength);
       
   173 	void ReadCancel();
       
   174 private:
       
   175 	CCommReader(CHWPort* aParent);
       
   176 	void InitL();
       
   177 private:
       
   178 	TUint iLength;          //< number of bytes to read
       
   179 	TAny* iClientBuffer;    //< pointer to Client's buffer
       
   180 	TUint iBufPos;          //< position in Client's buffer to read into (write)
       
   181 	TUint iBufActive;       //< TRUE if partial buffering active
       
   182 	TInt iBufOneOrMoreSize; //< buffer size of ReadOneOrMore method
       
   183 	};
       
   184 
       
   185 
       
   186 /**
       
   187  * Active Comm port Writer
       
   188  *
       
   189  * This class is responsible for writing data to the physical
       
   190  * comm port.
       
   191  */
       
   192 class CCommWriter : public CCommReadWriteBase
       
   193 	{
       
   194 public:
       
   195 	static CCommWriter* NewL(CHWPort* aParent);
       
   196 	~CCommWriter();
       
   197 	// from CActive
       
   198 	virtual void DoCancel();
       
   199 	virtual void RunL();
       
   200 	//
       
   201 	void Write(const TAny* aClientBuffer, TInt aLength);
       
   202 	void WriteCancel();
       
   203 	inline void NotificationEnable();
       
   204 	inline void NotificationDisable();
       
   205 	inline TBool IsNotificationEnabled();
       
   206 private:
       
   207 	CCommWriter(CHWPort* aParent);
       
   208 	void InitL();
       
   209 private:
       
   210 	TUint iLength;              //< number of bytes to write
       
   211 	TAny* iClientBuffer;        //< pointer to Client's buffer
       
   212 	TUint iBufPos;              //< position in Client's buffer to read from
       
   213 	TUint iBufActive;           //< TRUE if partial buffering active
       
   214 	TBool iNotificationEnabled; //< true if notification is enabled
       
   215 	};
       
   216 
       
   217 
       
   218 
       
   219 /**
       
   220  * Active Comm port Breaker
       
   221  *
       
   222  * This class is responsible for handling breaks on the physical
       
   223  * comm port.
       
   224  */
       
   225 class CCommBreaker : public CActive
       
   226 	{
       
   227 public:
       
   228 	static CCommBreaker * NewL(CHWPort* aParent);
       
   229 	~CCommBreaker();
       
   230 	// from CActive
       
   231 	virtual void DoCancel();
       
   232 	virtual void RunL();
       
   233 	//
       
   234 	void Break(TInt aTime);
       
   235 	 // set the role of this port unit @param aRole new role
       
   236 	inline void SetRole(TCommRole aRole){iRole=aRole;};
       
   237 private:
       
   238 	CCommBreaker(CHWPort* aParent);
       
   239 private:
       
   240 	TCommRole iRole;  //< DTE or DCE role for this port unit
       
   241 	CHWPort* iParent; //< pointer to the CHWPort object
       
   242 	};
       
   243 
       
   244 
       
   245 /**
       
   246  * Base class for Notifiers
       
   247  *
       
   248  */
       
   249 class CCommNotifyBase : public CActive
       
   250 	{
       
   251 public:
       
   252 	 // set the role of this port unit @param aRole new role
       
   253 	inline void SetRole(TCommRole aRole){iRole=aRole;};
       
   254 protected:
       
   255 	CCommNotifyBase(CHWPort* aParent);
       
   256 	~CCommNotifyBase();
       
   257 protected:
       
   258 	TCommRole iRole;  //< DTE or DCE role for this port unit
       
   259 	CHWPort* iParent; //< pointer to the CHWPort object
       
   260 	};
       
   261 
       
   262 
       
   263 /**
       
   264  * This class is responsible for notifying the client when
       
   265  * the signal control lines are changing, including breaks.
       
   266  */
       
   267 class CCommSignalNotifier : public CCommNotifyBase
       
   268 	{
       
   269 public:
       
   270 	CCommSignalNotifier(CHWPort* aParent);
       
   271 	~CCommSignalNotifier();
       
   272 	// from CActive
       
   273 	virtual void DoCancel();
       
   274 	virtual void RunL();
       
   275 	//
       
   276 	void Start();
       
   277 	void NotifySignal(TUint aSignalMask);
       
   278 	void NotifySignalCancel();
       
   279 	void NotifyBreak();
       
   280 	void NotifyBreakCancel();
       
   281 private:
       
   282 	TUint iSignals;     //< bitmask with the new signal after notification completed
       
   283 	TUint iSignalMask;  //< bitmask with the signals to be notified
       
   284 	TInt iNotifyCount;	//< increased when either NotifySignals or NotifyBreak is using this class
       
   285 						//< decreased when RunL is called. Ensures that RComm::NotifyBreak will not
       
   286 						//< interfere with operation of RComm::NotifySignalsChange
       
   287 	};
       
   288 
       
   289 
       
   290 /**
       
   291  * this class is responsible for notifying the client when
       
   292  * there are some incoming data available.
       
   293  */
       
   294 class CCommAvailableDataNotifier : public CCommNotifyBase
       
   295 	{
       
   296 public:
       
   297 	CCommAvailableDataNotifier(CHWPort* aParent);
       
   298 	~CCommAvailableDataNotifier();
       
   299 	// from CActive
       
   300 	virtual void DoCancel();
       
   301 	virtual void RunL();
       
   302 	//
       
   303 	void Start();
       
   304 	};
       
   305 
       
   306 
       
   307 /**
       
   308  * this class is responsible for notifying the client when
       
   309  * the flow control is changing.
       
   310  */
       
   311 class CCommFlowControlChangeNotifier : public CCommNotifyBase
       
   312 	{
       
   313 public:
       
   314 	CCommFlowControlChangeNotifier(CHWPort* aParent);
       
   315 	~CCommFlowControlChangeNotifier();
       
   316 	// from CActive
       
   317 	virtual void DoCancel();
       
   318 	virtual void RunL();
       
   319 	//
       
   320 	void Start();
       
   321 private:
       
   322 	TFlowControl iFlowControl; //< current flow control settings
       
   323 	};
       
   324 
       
   325 
       
   326 /**
       
   327  * this class is responsible for notifying the client when
       
   328  * the configuration is changing.
       
   329  */
       
   330 class CCommConfigChangeNotifier : public CCommNotifyBase
       
   331 	{
       
   332 public:
       
   333 	CCommConfigChangeNotifier(CHWPort* aParent);
       
   334 	~CCommConfigChangeNotifier();
       
   335 	void Start();
       
   336 	// from CActive
       
   337 	virtual void DoCancel();
       
   338 	virtual void RunL();
       
   339 private:
       
   340 	TCommNotificationPckg iConfig; //< current configuration package
       
   341 	};
       
   342 
       
   343 
       
   344 /**
       
   345  * CPort is the object which interfaces to the commserver
       
   346  */
       
   347 class CHWPort : public CPort
       
   348 	{
       
   349 public:
       
   350 	static CHWPort* NewL(TUint aUnit);
       
   351 private:
       
   352 	 CHWPort();
       
   353 public:
       
   354 	virtual void StartRead(const TAny* aClientBuffer,TInt aLength);
       
   355 	virtual void ReadCancel();
       
   356 	virtual TInt QueryReceiveBuffer(TInt& aLength) const;
       
   357 	virtual void ResetBuffers(TUint aFlags);
       
   358 	virtual void StartWrite(const TAny* aClientBuffer,TInt aLength);
       
   359 	virtual void WriteCancel();
       
   360 	virtual void Break(TInt aTime);
       
   361 	virtual void BreakCancel();
       
   362 	virtual TInt GetConfig(TDes8& aDes) const;
       
   363 	virtual TInt SetConfig(const TDesC8& aDes);
       
   364 	virtual TInt SetServerConfig(const TDesC8& aDes);
       
   365 	virtual TInt GetServerConfig(TDes8& aDes);
       
   366 	virtual TInt GetCaps(TDes8& aDes);
       
   367 	virtual TInt GetSignals(TUint& aSignals);
       
   368 	virtual TInt SetSignalsToMark(TUint aSignals);
       
   369 	virtual TInt SetSignalsToSpace(TUint aSignals);
       
   370 	virtual TInt GetReceiveBufferLength(TInt& aLength) const;
       
   371 	virtual TInt SetReceiveBufferLength(TInt aSignals);
       
   372 	virtual void Destruct();
       
   373 	virtual void FreeMemory();
       
   374 	virtual void NotifySignalChange(TUint aSignalMask);
       
   375 	virtual void NotifySignalChangeCancel();
       
   376 	virtual void NotifyConfigChange();
       
   377 	virtual void NotifyConfigChangeCancel();
       
   378 	virtual void NotifyFlowControlChange();
       
   379 	virtual void NotifyFlowControlChangeCancel();
       
   380 	virtual void NotifyBreak();
       
   381 	virtual void NotifyBreakCancel();
       
   382 	virtual void NotifyDataAvailable();
       
   383 	virtual void NotifyDataAvailableCancel();
       
   384 	virtual void NotifyOutputEmpty();
       
   385 	virtual void NotifyOutputEmptyCancel();
       
   386 	virtual TInt GetFlowControlStatus(TFlowControl& aFlowControl);
       
   387 	virtual TInt GetRole(TCommRole& aRole);
       
   388 	virtual TInt SetRole(TCommRole aRole);
       
   389 
       
   390 	virtual ~CHWPort();
       
   391 #if defined (_DEBUG_DEVCOMM)
       
   392 	virtual void DoDumpDebugInfo(const RMessage2 &aMessage);
       
   393 #endif
       
   394 	RBusDevComm& DTEPort();
       
   395 	RBusDevCommDCE& DCEPort();
       
   396 private:
       
   397 	CCommReader* iReader;                                       //< pointer to the Active Reader
       
   398 	CCommWriter* iWriter;                                       //< pointer to the Active Writer
       
   399 	CCommBreaker* iBreaker;                                     //< pointer to the Active Breaker
       
   400 	CCommSignalNotifier* iSignalNotifier;                       //< pointer to the Active Signal Notifier
       
   401 	CCommAvailableDataNotifier* iDataAvailableNotifier;         //< pointer to the Active Data available notifier
       
   402 	CCommFlowControlChangeNotifier* iFlowControlChangeNotifier; //< pointer to the Active Flow Control notifier
       
   403 	CCommConfigChangeNotifier* iConfigChangeNotifier;           //< pointer to the Active Config Change notifier
       
   404 
       
   405 	RBusDevComm iPort;           //< interface to the logical Comm port device (DTE role)
       
   406 	RBusDevCommDCE iPortDCE;     //< interface to the logical Comm port device (DCE role)
       
   407 	TCommRole iRole;             //< DTE or DCE role for this port unit
       
   408 	TUint iPortName;             //< contains the port unit number (i.e. 0 for COMM::0)
       
   409 	TBool iEarlyWriteCompletion; //< ETrue if early write completion enabled
       
   410 #if defined (_DEBUG_CONSOLE_)
       
   411 #if defined (_DEBUG_DEVCOMM)
       
   412 	CCommDebugDumper *iDumper;
       
   413 #endif
       
   414 public:
       
   415 	RDebugConsole iConsole;
       
   416 #endif
       
   417 	};
       
   418 
       
   419 
       
   420 /**
       
   421  * "Entry point object" makes the objects which do the work
       
   422  */
       
   423 class CHWPortFactory : public CSerial
       
   424 	{
       
   425 public:
       
   426     CHWPortFactory();
       
   427 	virtual CPort* NewPortL(const TUint aUnit);
       
   428 	virtual void Info(TSerialInfo &aSerialInfo);
       
   429 
       
   430 public:	//from CSerial
       
   431 	TSecurityPolicy PortPlatSecCapability(TUint aPort) const;
       
   432 	};
       
   433 
       
   434 
       
   435 /**
       
   436  * this class handles the 'Read one or more' method
       
   437  * for ports with role DTE
       
   438  */
       
   439 class RMaxComm : public RBusDevComm
       
   440 	{
       
   441 public:
       
   442 	static void ReadOneOrMore(RBusDevComm& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen);
       
   443 	};
       
   444 
       
   445 
       
   446 void RMaxComm::ReadOneOrMore(RBusDevComm& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen)
       
   447 /**
       
   448  * reads one or more bytes from the physical DTE com port
       
   449  *
       
   450  * @param aComm   handle to the logical com port device
       
   451  * @param aStatus handle for asyncronous communications
       
   452  * @param aDes    buffer to be read into
       
   453  * @param aLen    max number of bytes to read
       
   454  */
       
   455     {
       
   456 	LOGECUART2(_L8("RMaxComm::ReadOneOrMore(), (max. bytes to read) aLen = %d"), aLen);
       
   457 	RMaxComm& r = (RMaxComm&)aComm;
       
   458 	aLen = -aLen; // Note: negative length here means ReadOneOrMore
       
   459 	              //       see RComm::ReadOneOrMore in CC_CLI.CPP
       
   460 	r.DoRequest(ERequestRead, aStatus, &aDes, &aLen);
       
   461     }
       
   462 
       
   463 
       
   464 /**
       
   465  * this class handles the 'Read one or more' method
       
   466  * for ports with role DCE
       
   467  */
       
   468 class RMaxCommDCE : public RBusDevCommDCE
       
   469 	{
       
   470 public:
       
   471 	static void ReadOneOrMore(RBusDevCommDCE& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen);
       
   472 	};
       
   473 
       
   474 
       
   475 void RMaxCommDCE::ReadOneOrMore(RBusDevCommDCE& aComm, TRequestStatus& aStatus, TDes8& aDes, TInt aLen)
       
   476 /**
       
   477  * reads one or more bytes from the physical DCE com port
       
   478  *
       
   479  * @param aComm   handle to the logical com port device
       
   480  * @param aStatus handle for asyncronous communications
       
   481  * @param aDes    buffer to be read into
       
   482  * @param aLen    max number of bytes to read
       
   483  */
       
   484     {
       
   485 	LOGECUART2(_L8("RMaxCommDCE::ReadOneOrMore(), (max. bytes to read) aLen = %d"), aLen);
       
   486 	RMaxCommDCE& r = (RMaxCommDCE&)aComm;
       
   487 	aLen = -aLen; // Note: negative length here means ReadOneOrMore
       
   488 	              //       see RComm::ReadOneOrMore in CC_CLI.CPP
       
   489 	r.DoRequest(ERequestRead, aStatus, &aDes, &aLen);
       
   490     }
       
   491 
       
   492 
       
   493 
       
   494 
       
   495 void Fault(TCommFault aFault)
       
   496 /**
       
   497  * Panic the comm module (us)
       
   498  *
       
   499  * @param aFault Panic code
       
   500  */
       
   501 	{
       
   502 	LOGECUART3(_L8("Fault(), (TCommFault) aFault = %d (%S)"), aFault, &TECUARTLOG::CommFaultStr(aFault));
       
   503 	_LIT(KCsyPanicCategory, "CHWComm" );
       
   504 	User::Panic(KCsyPanicCategory, aFault);
       
   505 	}
       
   506 
       
   507 
       
   508 //
       
   509 // implementation of CCommReadWriteBase
       
   510 //
       
   511 
       
   512 
       
   513 CCommReadWriteBase::CCommReadWriteBase(TInt aPriority, CHWPort* aParent)
       
   514 /**
       
   515  * C'tor
       
   516  *
       
   517  * @param aPriority priority of the Active Object
       
   518  * @param aParent   pointer to the owner, the CHWPort object
       
   519  */
       
   520 	:CActive(aPriority)
       
   521 	,iBufSize(KDefaultBufSize)
       
   522 	,iRole(ECommRoleDTE)
       
   523 	,iParent(aParent)
       
   524 	{
       
   525 	LOGECUART1(_L8("CCommReadWriteBase::CCommReadWriteBase()"));
       
   526 	}
       
   527 
       
   528 
       
   529 CCommReadWriteBase::~CCommReadWriteBase()
       
   530 /**
       
   531  * D'tor
       
   532  */
       
   533 	{
       
   534 	LOGECUART1(_L8("CCommReadWriteBase::~CCommReadWriteBase()"));
       
   535 	delete iBuffer;
       
   536 	delete iBuf;
       
   537 	}
       
   538 
       
   539 
       
   540 TInt CCommReadWriteBase::SetServerConfig(TCommServerConfig& aConfig)
       
   541 /**
       
   542  * Set the port to use partial reads/writes or the bungee buffer
       
   543  *
       
   544  * @param aConfig new Comm server configurations
       
   545  * @return TInt error code. KErrNone for sucess
       
   546  */
       
   547 	{
       
   548 	LOGECUART1(_L8("CCommReadWriteBase::SetServerConfig()"));
       
   549 	TCommServerConfigV01& c = aConfig();
       
   550 	TInt res = KErrNone;
       
   551 	if (c.iBufFlags & KCommBufferPartial)
       
   552 		{
       
   553 		TInt bufSave = iBufSize;
       
   554 		iBufSize = c.iBufSize;
       
   555 		TRAP(res, SetBuffersL();)
       
   556 		if (res==KErrNone)
       
   557 			iBufFlags = c.iBufFlags;
       
   558 		else
       
   559 			iBufSize = bufSave;
       
   560 		}
       
   561 	return res;
       
   562 	}
       
   563 
       
   564 
       
   565 void CCommReadWriteBase::GetServerConfig(TCommServerConfig& aConfig) const
       
   566 /**
       
   567  * read the comm server buffer config from the reader
       
   568  *
       
   569  * @param aConfig reference to Comm server configurations to be changed
       
   570  */
       
   571 	{
       
   572 	LOGECUART1(_L8("CCommReadWriteBase::GetServerConfig()"));
       
   573 	aConfig().iBufFlags = iBufFlags;
       
   574 	aConfig().iBufSize = iBufSize;
       
   575 	}
       
   576 
       
   577 
       
   578 void CCommReadWriteBase::FreeMemory()
       
   579 /**
       
   580  * Reduce allocation levels by order of the comm server
       
   581  */
       
   582 	{
       
   583 	LOGECUART1(_L8("CCommReadWriteBase::FreeMemory()"));
       
   584 	TRAP_IGNORE(SetBuffersL());
       
   585 	}
       
   586 
       
   587 
       
   588 void CCommReadWriteBase::SetBuffersL()
       
   589 /**
       
   590  * Attempt to free up some memory
       
   591  *
       
   592  * @leave This function may leave in case of OOM
       
   593  */
       
   594 	{
       
   595 	LOGECUART1(_L8("CCommReadWriteBase::SetBuffersL()"));
       
   596 	if (!IsActive())
       
   597 		{
       
   598 		TInt allocLen = Align4(iBufSize);
       
   599 		delete iBuffer;
       
   600 		delete iBuf;
       
   601 		iBuf = NULL;   // set to NULL, in case new leaves
       
   602 		iBuffer = NULL;
       
   603 		iBuffer = HBufC8::NewMaxL(allocLen);
       
   604 		iBuf = new (ELeave) TPtr8((TText8*)iBuffer->Des().Ptr(), allocLen, allocLen);
       
   605 		}
       
   606 	}
       
   607 
       
   608 
       
   609 //
       
   610 // implementation of CCommReader
       
   611 //
       
   612 
       
   613 
       
   614 CCommReader* CCommReader::NewL(CHWPort* aParent)
       
   615 /**
       
   616  * static function, create and init a comm reader active object
       
   617  *
       
   618  * @param aParent pointer to the CHWPort object
       
   619  * @return a newly created CCommReader object
       
   620  */
       
   621 	{
       
   622 	LOGECUART1(_L8("CCommReader::NewL()"));
       
   623 	CCommReader* c = new (ELeave) CCommReader(aParent);
       
   624 	CleanupStack::PushL(c);
       
   625 	c->InitL();
       
   626 	CleanupStack::Pop();
       
   627 	CActiveScheduler::Add(c);
       
   628 	return c;
       
   629 	}
       
   630 
       
   631 
       
   632 CCommReader::~CCommReader()
       
   633 /**
       
   634  * D'tor
       
   635  */
       
   636 	{
       
   637 	LOGECUART1(_L8("CCommReader::~CCommReader()"));
       
   638 	Cancel();
       
   639 	}
       
   640 
       
   641 
       
   642 void CCommReader::DoCancel()
       
   643 /**
       
   644  * Cancel an outstanding request
       
   645  */
       
   646 	{
       
   647 	LOGECUART1(_L8("CCommReader::DoCancel()"));
       
   648 	__ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding));
       
   649 	if (iRole==ECommRoleDTE)
       
   650 		iParent->DTEPort().ReadCancel();
       
   651 	else
       
   652 		iParent->DCEPort().ReadCancel();
       
   653 	}
       
   654 
       
   655 
       
   656 void CCommReader::RunL()
       
   657 /**
       
   658  * Read request has completed
       
   659  */
       
   660 	{
       
   661 	LOGECUART2(_L8("CCommReader::RunL(), iStatus = %d"), iStatus.Int());
       
   662 	DEBUG_TRACE((iParent->iConsole.Printf(_L("CCommReader::RunL\n\r"))));
       
   663 
       
   664 	TInt len = iLength;
       
   665 
       
   666 	DEBUG_TRACE((iParent->iConsole.Printf(_L("Write %x bytes to 0x%x+%x\n\r"),iBuf->Size(),iPendingRead.Ptr0(),iBufPos)));
       
   667 	iParent->IPCWrite(iClientBuffer,*iBuf, iBufPos);
       
   668 
       
   669 	if (iBufActive)
       
   670 		{
       
   671 		iBufPos+=iBufSize;
       
   672 		TInt left;
       
   673 
       
   674 		if (iBufOneOrMoreSize)
       
   675 			{
       
   676 			//
       
   677 			//	We are in ReadOneOrMore HELL
       
   678 			//
       
   679 			left=iBufOneOrMoreSize-iBufPos;
       
   680 			if (left<iBufSize)
       
   681 				{
       
   682 				len=left;
       
   683 				iBufActive=EFalse;
       
   684 				}
       
   685 			else
       
   686 				len=iBufSize;
       
   687 			}
       
   688 		else
       
   689 			{
       
   690 			left=len-iBufPos;
       
   691 			if (left<iBufSize)
       
   692 				{
       
   693 				len=left;
       
   694 				iBufActive=EFalse;
       
   695 				}
       
   696 			else
       
   697 				len=iBufSize;
       
   698 			}
       
   699 		//
       
   700 		//	Next block
       
   701 		//
       
   702 		iBuf->SetLength(0);
       
   703 
       
   704 		LOGECUART2(_L8("Read %d bytes from serial"), len);
       
   705 		DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len)));
       
   706 		if (iRole==ECommRoleDTE)
       
   707 			iParent->DTEPort().Read(iStatus,*iBuf,len);
       
   708 		else
       
   709 			iParent->DCEPort().Read(iStatus,*iBuf,len);;
       
   710 		SetActive();
       
   711 		return;
       
   712 		}
       
   713 	LOGECUART1(_L8("Read Completed"));
       
   714 	DEBUG_TRACE((iParent->iConsole.Write(_L("readCompleted \n\r"))));
       
   715 
       
   716 	iParent->ReadCompleted(iStatus.Int());
       
   717 	}
       
   718 
       
   719 
       
   720 
       
   721 void CCommReader::Read(const TAny* aClientBuffer, TInt aLength)
       
   722 /**
       
   723  * resize the buffer and queue a read
       
   724  *
       
   725  * @param aClientBuffer pointer to the Client's buffer
       
   726  * @param aLength number of bytes to read
       
   727  */
       
   728 	{
       
   729 	LOGECUART2(_L8("CCommReader::Read(), aLength (number of Bytes to read) = %d"), aLength);
       
   730 	iClientBuffer=(TAny*)aClientBuffer;
       
   731 	iLength=aLength;
       
   732 	TInt& len=aLength;
       
   733 	if (len==0)
       
   734 		{
       
   735 		iParent->ReadCompleted(KErrNone);
       
   736 		return;
       
   737 		}
       
   738 
       
   739 	TBool doOneOrMore=EFalse;
       
   740 	if (len<0)
       
   741 		{
       
   742 		doOneOrMore=ETrue;
       
   743 		len=-len;
       
   744 		}
       
   745 
       
   746 
       
   747 	if ((UsePartial() && len>iBufSize) || (UsePartial()==EFalse && len>iBuf->MaxLength()))
       
   748 		{
       
   749 		if (UsePartial()==EFalse)
       
   750 			{
       
   751 			TInt allocLen=Align4(len);
       
   752 
       
   753 			TRAPD(res, iBuffer=iBuffer->ReAllocL(allocLen));
       
   754 			if(res != KErrNone)
       
   755 				{
       
   756 				delete iBuffer;
       
   757 				iBuffer=NULL;
       
   758 				LOGECUART1(_L8("Read Completed"));
       
   759 				DEBUG_TRACE((iParent->iConsole.Write(_L("readCompleted \n\r"))));
       
   760 				iParent->ReadCompleted(res);
       
   761 				return;
       
   762 				}
       
   763 
       
   764 			delete iBuf;
       
   765 			iBuf=NULL;
       
   766 			iBuf=new TPtr8((TText8*)iBuffer->Des().Ptr(), allocLen, allocLen);
       
   767 			if (iBuf == NULL)
       
   768 				{
       
   769 				iParent->ReadCompleted(KErrNoMemory);
       
   770 				return;
       
   771 				}
       
   772 			}
       
   773 		else
       
   774 			{
       
   775 			iBufActive=ETrue;
       
   776 			iBufPos=0;
       
   777 			len=iBufSize;
       
   778 			}
       
   779 		}
       
   780 
       
   781 
       
   782 	iBuf->SetLength(0);
       
   783 	if (iBufActive)
       
   784 		{
       
   785 		if (doOneOrMore)
       
   786 			{
       
   787 			if (iRole==ECommRoleDTE)
       
   788 				{
       
   789 				RBusDevComm port = iParent->DTEPort();
       
   790 				iBufOneOrMoreSize = port.QueryReceiveBuffer();
       
   791 				if (iBufOneOrMoreSize < iBuffer->Length())
       
   792 					{
       
   793 					RMaxComm::ReadOneOrMore(port, iStatus, *iBuf, len);
       
   794 					iBufActive = EFalse; // Not needed
       
   795 					}
       
   796 				else
       
   797 					{
       
   798 					//	Just do normal reads on it
       
   799 					LOGECUART2(_L8("Read %d bytes from serial"), len);
       
   800 					DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len)));
       
   801 					port.Read(iStatus,*iBuf,len);
       
   802 					}
       
   803 				}
       
   804 			else
       
   805 				{
       
   806 				RBusDevCommDCE port = iParent->DCEPort();
       
   807 				iBufOneOrMoreSize=port.QueryReceiveBuffer();
       
   808 				if (iBufOneOrMoreSize<iBuffer->Length())
       
   809 					{
       
   810 					RMaxCommDCE::ReadOneOrMore(port,iStatus,*iBuf,len);
       
   811 					iBufActive=EFalse; // Not needed
       
   812 					}
       
   813 				else
       
   814 					{
       
   815 					//	Just do normal reads on it
       
   816 					LOGECUART2(_L8("Read %d bytes from serial"), len);
       
   817 					DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len)));
       
   818 					port.Read(iStatus,*iBuf,len);
       
   819 					}
       
   820 				}
       
   821 			}
       
   822 		else
       
   823 			{
       
   824 			LOGECUART2(_L8("Read %d bytes from serial"), len);
       
   825 			DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len)));
       
   826 			if (iRole==ECommRoleDTE)
       
   827 				iParent->DTEPort().Read(iStatus,*iBuf,len);
       
   828 			else
       
   829 				iParent->DCEPort().Read(iStatus,*iBuf,len);
       
   830 			}
       
   831 		}
       
   832 	else
       
   833 		{
       
   834 		if (iRole==ECommRoleDTE)
       
   835 			{
       
   836 			RBusDevComm port = iParent->DTEPort();
       
   837 			if (doOneOrMore)
       
   838 				RMaxComm::ReadOneOrMore(port,iStatus,*iBuf,len);
       
   839 			else
       
   840 				{
       
   841 				LOGECUART2(_L8("Read %d bytes from serial"), len);
       
   842 				DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len)));
       
   843 				port.Read(iStatus,*iBuf,len);
       
   844 				}
       
   845 			}
       
   846 		else
       
   847 			{
       
   848 			RBusDevCommDCE port = iParent->DCEPort();
       
   849 			if (doOneOrMore)
       
   850 				RMaxCommDCE::ReadOneOrMore(port,iStatus,*iBuf,len);
       
   851 			else
       
   852 				{
       
   853 				LOGECUART2(_L8("Read %d bytes from serial"), len);
       
   854 				DEBUG_TRACE((iParent->iConsole.Printf(_L("read %x bytes from serial\n\r"),len)));
       
   855 				port.Read(iStatus,*iBuf,len);
       
   856 				}
       
   857 			}
       
   858 		}
       
   859 
       
   860 	SetActive();
       
   861 	}
       
   862 
       
   863 
       
   864 void CCommReader::ReadCancel()
       
   865 /**
       
   866  * Cancel a read
       
   867  */
       
   868 	{
       
   869 	LOGECUART1(_L8("CCommReader::ReadCancel()"));
       
   870 	if(IsActive())
       
   871 		{
       
   872 		Cancel();
       
   873 		if(iBuf->Length()) // Copy any data to client
       
   874 			iParent->IPCWrite(iClientBuffer, *iBuf, iBufPos); // todo check return value ?
       
   875 		}
       
   876 	}
       
   877 
       
   878 
       
   879 CCommReader::CCommReader(CHWPort* aParent)
       
   880 /**
       
   881  * C'tor - pass priority up to CActive
       
   882  */
       
   883 	:CCommReadWriteBase(KReaderPriority, aParent)
       
   884 	{
       
   885 	}
       
   886 
       
   887 
       
   888 void CCommReader::InitL()
       
   889 /**
       
   890  * Allocate buffers
       
   891  */
       
   892 	{
       
   893 	SetBuffersL();
       
   894 	}
       
   895 
       
   896 
       
   897 //
       
   898 // implementation of CCommWriter
       
   899 //
       
   900 
       
   901 
       
   902 CCommWriter* CCommWriter::NewL(CHWPort* aParent)
       
   903 /**
       
   904  * static function, create and init a comm writer active object
       
   905  *
       
   906  * @param aParent pointer to the CHWPort object
       
   907  * @return a newly created CCommWriter object
       
   908  */
       
   909 	{
       
   910 	LOGECUART1(_L8("CCommWriter::NewL()"));
       
   911 	CCommWriter* c = new (ELeave) CCommWriter(aParent);
       
   912 	CleanupStack::PushL(c);
       
   913 	c->InitL();
       
   914 	CleanupStack::Pop();
       
   915 	CActiveScheduler::Add(c);
       
   916 	return c;
       
   917 	}
       
   918 
       
   919 
       
   920 CCommWriter::~CCommWriter()
       
   921 /**
       
   922  * D'tor
       
   923  */
       
   924 	{
       
   925 	LOGECUART1(_L8("CCommWriter::~CCommWriter()"));
       
   926 	Cancel();
       
   927 	}
       
   928 
       
   929 
       
   930 void CCommWriter::DoCancel()
       
   931 /**
       
   932  * Cancel a pending write
       
   933  */
       
   934 	{
       
   935 	LOGECUART1(_L8("CCommWriter::DoCancel()"));
       
   936 	__ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding));
       
   937 	if (iRole==ECommRoleDTE)
       
   938 		iParent->DTEPort().WriteCancel();
       
   939 	else
       
   940 		iParent->DCEPort().WriteCancel();
       
   941 	}
       
   942 
       
   943 
       
   944 void CCommWriter::RunL()
       
   945 /**
       
   946  * a write has completed
       
   947  */
       
   948 	{
       
   949 	LOGECUART2(_L8("CCommWriter::RunL(), iStatus = %d"), iStatus.Int());
       
   950 	DEBUG_TRACE((iParent->iConsole.Write(_L("CCommWriter::RunL\n\r"))));
       
   951 	if (iBufActive)
       
   952 		{
       
   953 		//
       
   954 		//	Did the last chunk get through OK ?
       
   955 		//
       
   956 		if (iStatus.Int() != KErrNone)
       
   957 			{
       
   958 			iBufActive=EFalse;
       
   959 			iBufPos=0;
       
   960 			iParent->WriteCompleted(iStatus.Int());
       
   961 			return;
       
   962 			}
       
   963 
       
   964 		TInt len=iLength;
       
   965 		TInt left=len-iBufPos;
       
   966 		//
       
   967 		//	Read the next chunk into our buffer
       
   968 		//
       
   969 		DEBUG_TRACE((iParent->iConsole.Printf(_L("Read %x bytes from 0x%x+%x\n\r"),iBuf->Size(),iPendingWrite.Ptr0(),iBufPos)));
       
   970 		TInt res;
       
   971 		if((res=iParent->IPCRead(iClientBuffer,*iBuf, iBufPos))!=KErrNone)
       
   972 			{
       
   973 			iParent->WriteCompleted(res);
       
   974 			return;
       
   975 			}
       
   976 		//
       
   977 		//	Still need buffering ?
       
   978 		//
       
   979 		if (left<iBufSize)
       
   980 			{
       
   981 			iBufActive=EFalse;
       
   982 			iBufPos=0;
       
   983 			len=left;
       
   984 			}
       
   985 		else
       
   986 			{
       
   987 			iBufPos+=iBufSize;
       
   988 			len=iBufSize;
       
   989 			}
       
   990 		iBuf->SetLength(len);
       
   991 		LOGECUART2(_L8("Write %x bytes to serial"), len);
       
   992 		DEBUG_TRACE((iParent->iConsole.Printf(_L("Write %x bytes to serial\n\r"),len)));
       
   993 		if (iRole==ECommRoleDTE)
       
   994 			iParent->DTEPort().Write(iStatus,*iBuf,len);
       
   995 		else
       
   996 			iParent->DCEPort().Write(iStatus,*iBuf,len);
       
   997 		SetActive();
       
   998 		return;
       
   999 		}
       
  1000 	LOGECUART1(_L8("Write Completed"));
       
  1001 	DEBUG_TRACE((iParent->iConsole.Write(_L("writeCompleted \n\r"))));
       
  1002 
       
  1003 	if (iNotificationEnabled)
       
  1004 		{
       
  1005 		iParent->NotifyOutputEmptyCompleted(iStatus.Int());
       
  1006 		iNotificationEnabled=EFalse;
       
  1007 		}
       
  1008 	iParent->WriteCompleted(iStatus.Int());
       
  1009 	}
       
  1010 
       
  1011 
       
  1012 void CCommWriter::Write(const TAny* aClientBuffer, TInt aLength)
       
  1013 /**
       
  1014  * resize the buffer and queue a write
       
  1015  *
       
  1016  * @param aClientBuffer pointer to the Client's buffer
       
  1017  * @param aLength number of bytes to write
       
  1018  */
       
  1019 	{
       
  1020 	LOGECUART2(_L8("CCommWriter::Write(), aLength = %d"), aLength);
       
  1021 	iClientBuffer = (TAny*)aClientBuffer;
       
  1022 	iLength = aLength;
       
  1023 
       
  1024 	TInt& len = aLength;
       
  1025 	if (len==0)
       
  1026 		{
       
  1027 		if (iRole==ECommRoleDTE)
       
  1028 			iParent->DTEPort().Write(iStatus, TPtrC8(NULL,0));
       
  1029 		else
       
  1030 			iParent->DCEPort().Write(iStatus, TPtrC8(NULL,0));
       
  1031 		}
       
  1032 	else
       
  1033 		{
       
  1034 		if ((UsePartial() && len>iBufSize) || (UsePartial()==EFalse && len>iBuf->MaxLength()))
       
  1035 			{
       
  1036 			if (UsePartial()==EFalse)
       
  1037 				{
       
  1038 				TInt allocLen=Align4(len);
       
  1039 
       
  1040 				TRAPD(res, iBuffer=iBuffer->ReAllocL(allocLen));
       
  1041 				if(res!=KErrNone)
       
  1042 					{
       
  1043 					delete iBuffer;
       
  1044 					iBuffer=NULL;
       
  1045 					iParent->WriteCompleted(res);
       
  1046 					return;
       
  1047 					}
       
  1048 
       
  1049 				delete iBuf;
       
  1050 				iBuf=NULL;
       
  1051 				iBuf = new TPtr8((TText8*)iBuffer->Des().Ptr(), allocLen, allocLen);
       
  1052 				if (iBuf == NULL)
       
  1053 					{
       
  1054 					iParent->WriteCompleted(KErrNoMemory);
       
  1055 					return;
       
  1056 					}
       
  1057 				}
       
  1058 			else
       
  1059 				{
       
  1060 				iBufActive=ETrue;
       
  1061 				len=iBufSize;
       
  1062 				iBufPos=len;
       
  1063 				}
       
  1064 			}
       
  1065 
       
  1066 		iBuf->SetLength(len);
       
  1067 		LOGECUART4(_L8("Read %d bytes from 0x%x+%x"), iBuf->Size(), aClientBuffer, iBufPos);
       
  1068 		DEBUG_TRACE((iParent->iConsole.Printf(_L("Read %x bytes from 0x%x+%x\n\r"),iBuf->Size(),aClientBuffer,iBufPos)));
       
  1069 		TInt res;
       
  1070 		if((res=iParent->IPCRead(aClientBuffer,*iBuf))!=KErrNone)
       
  1071 			{
       
  1072 			iParent->WriteCompleted(res);
       
  1073 			return;
       
  1074 			}
       
  1075 		LOGECUART2(_L8("Write %x bytes to serial"), len);
       
  1076 		DEBUG_TRACE((iParent->iConsole.Printf(_L("Write %x bytes to serial\n\r"),len)));
       
  1077 
       
  1078 		if (iRole==ECommRoleDTE)
       
  1079 			iParent->DTEPort().Write(iStatus, *iBuf, len);
       
  1080 		else
       
  1081 			iParent->DCEPort().Write(iStatus, *iBuf, len);
       
  1082 		}
       
  1083 
       
  1084 	SetActive();
       
  1085 	}
       
  1086 
       
  1087 
       
  1088 void CCommWriter::WriteCancel()
       
  1089 /**
       
  1090  * Cancel a write
       
  1091  */
       
  1092 	{
       
  1093 	LOGECUART1(_L8("CCommWriter::WriteCancel()"));
       
  1094 	Cancel();
       
  1095 	}
       
  1096 
       
  1097 
       
  1098 void CCommWriter::NotificationEnable()
       
  1099 /**
       
  1100  * enables notification when output buffer is empty.
       
  1101  * activated when a clients calls RComm::NotifyOutputEmpty
       
  1102  */
       
  1103 	{
       
  1104 	LOGECUART1(_L8("CCommWriter::NotificationEnable()"));
       
  1105 	iNotificationEnabled = ETrue;
       
  1106 	}
       
  1107 
       
  1108 
       
  1109 void CCommWriter::NotificationDisable()
       
  1110 /**
       
  1111  * disables notification when output buffer is empty
       
  1112  * deactivated when a clients calls RComm::NotifyOutputEmptyCancel
       
  1113  */
       
  1114 	{
       
  1115 	LOGECUART1(_L8("CCommWriter::NotificationDisable()"));
       
  1116 	iNotificationEnabled = EFalse;
       
  1117 	}
       
  1118 
       
  1119 
       
  1120 TBool CCommWriter::IsNotificationEnabled()
       
  1121 /**
       
  1122  * returns ETrue if notification on output buffer empty is enabled
       
  1123  */
       
  1124 	{
       
  1125 	LOGECUART2(_L8("CCommWriter::IsNotificationEnabled(), iNotificationEnabled = %d"), iNotificationEnabled);
       
  1126 	return iNotificationEnabled;
       
  1127 	}
       
  1128 
       
  1129 
       
  1130 CCommWriter::CCommWriter(CHWPort* aParent)
       
  1131 /**
       
  1132  * C'Tor
       
  1133  */
       
  1134 	:CCommReadWriteBase(KWriterPriority, aParent)
       
  1135 	{
       
  1136 	}
       
  1137 
       
  1138 
       
  1139 void CCommWriter::InitL()
       
  1140 /**
       
  1141  * Allocate buffers
       
  1142  */
       
  1143 	{
       
  1144 	SetBuffersL();
       
  1145 	}
       
  1146 
       
  1147 
       
  1148 //
       
  1149 // implementation of CCommBreaker
       
  1150 //
       
  1151 
       
  1152 
       
  1153 CCommBreaker* CCommBreaker::NewL(CHWPort* aParent)
       
  1154 /**
       
  1155  * static function, create a comm breaker object
       
  1156  *
       
  1157  * @param aParent pointer to the CHWPort object
       
  1158  * @return a newly created CCommBreaker object
       
  1159  */
       
  1160 	{
       
  1161 	LOGECUART1(_L8("CCommBreaker::NewL()"));
       
  1162 	CCommBreaker* c = new (ELeave) CCommBreaker(aParent);
       
  1163 	CActiveScheduler::Add(c);
       
  1164 	return c;
       
  1165 	}
       
  1166 
       
  1167 
       
  1168 CCommBreaker::~CCommBreaker()
       
  1169 /**
       
  1170  * D'Tor
       
  1171  */
       
  1172 	{
       
  1173 	LOGECUART1(_L8("CCommBreaker::~CCommBreaker()"));
       
  1174 	Cancel();
       
  1175 	}
       
  1176 
       
  1177 
       
  1178 void CCommBreaker::DoCancel()
       
  1179 /**
       
  1180  * Cancel a pending break.
       
  1181  */
       
  1182 	{
       
  1183 	LOGECUART1(_L8("CCommBreaker::DoCancel()"));
       
  1184 	__ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding));
       
  1185 	if (iRole==ECommRoleDTE)
       
  1186 		iParent->DTEPort().BreakCancel();
       
  1187 	else
       
  1188 		iParent->DCEPort().BreakCancel();
       
  1189 	}
       
  1190 
       
  1191 
       
  1192 void CCommBreaker::RunL()
       
  1193 /**
       
  1194  * a break has completed. forward the news to the parent
       
  1195  */
       
  1196 	{
       
  1197 	TInt status = iStatus.Int();
       
  1198 	LOGECUART2(_L8("CCommBreaker::RunL(), iStatus = %d"), status);
       
  1199 	iParent->BreakCompleted(status);
       
  1200 	}
       
  1201 
       
  1202 
       
  1203 void CCommBreaker::Break(TInt aTime)
       
  1204 /**
       
  1205  * Queue a break operation
       
  1206  *
       
  1207  * @param aTime Length of break in micro seconds
       
  1208  */
       
  1209 	{
       
  1210 	LOGECUART2(_L8("CCommBreaker::Break(), aTime (length of break in micro secs) = %d"), aTime);
       
  1211 	if (aTime==0)
       
  1212 		{
       
  1213 		iParent->BreakCompleted(KErrNone);
       
  1214 		}
       
  1215 	if (iRole==ECommRoleDTE)
       
  1216 		iParent->DTEPort().Break(iStatus, aTime);
       
  1217 	else
       
  1218 		iParent->DCEPort().Break(iStatus, aTime);
       
  1219 	SetActive();
       
  1220 	}
       
  1221 
       
  1222 
       
  1223 CCommBreaker::CCommBreaker(CHWPort* aParent)
       
  1224 /**
       
  1225  * C'Tor
       
  1226  *
       
  1227  * @param aParent pointer to the CHWPort object
       
  1228  */
       
  1229 	:CActive(KBreakerPriority)
       
  1230 	,iRole(ECommRoleDTE)
       
  1231 	,iParent(aParent)
       
  1232 	{
       
  1233 	}
       
  1234 
       
  1235 
       
  1236 //
       
  1237 // implementation of CCommNotifyBase
       
  1238 //
       
  1239 
       
  1240 
       
  1241 CCommNotifyBase::CCommNotifyBase(CHWPort* aParent)
       
  1242 /**
       
  1243  * C'tor
       
  1244  *
       
  1245  * @param aParent pointer to the CHWPort object
       
  1246  */
       
  1247 	:CActive(KNotifyPriority)
       
  1248 	,iRole(ECommRoleDTE)
       
  1249 	,iParent(aParent)
       
  1250 	{
       
  1251 	CActiveScheduler::Add(this);
       
  1252 	}
       
  1253 
       
  1254 
       
  1255 CCommNotifyBase::~CCommNotifyBase()
       
  1256 /**
       
  1257  * D'tor
       
  1258  */
       
  1259 	{
       
  1260 	LOGECUART1(_L8("CCommNotifyBase::~CCommNotifyBase()"));
       
  1261 	}
       
  1262 
       
  1263 
       
  1264 //
       
  1265 // implementation of CCommSignalNotifier
       
  1266 //
       
  1267 
       
  1268 
       
  1269 CCommSignalNotifier::CCommSignalNotifier(CHWPort* aParent)
       
  1270 /**
       
  1271  * C'tor
       
  1272  *
       
  1273  * @param aParent pointer to the CHWPort object
       
  1274  */
       
  1275 	:CCommNotifyBase(aParent)
       
  1276 	{
       
  1277 	LOGECUART1(_L8("CCommSignalNotifier::CCommSignalNotifier()"));
       
  1278 	}
       
  1279 
       
  1280 
       
  1281 CCommSignalNotifier::~CCommSignalNotifier()
       
  1282 /**
       
  1283  * D'tor
       
  1284  */
       
  1285 	{
       
  1286 	LOGECUART1(_L8("CCommSignalNotifier::~CCommSignalNotifier()"));
       
  1287 	}
       
  1288 
       
  1289 
       
  1290 void CCommSignalNotifier::DoCancel()
       
  1291 /**
       
  1292  * Cancel a pending notification.
       
  1293  */
       
  1294 	{
       
  1295 	LOGECUART1(_L8("CCommSignalNotifier::DoCancel()"));
       
  1296 	__ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding));
       
  1297 	if (iRole==ECommRoleDTE)
       
  1298 		iParent->DTEPort().NotifySignalChangeCancel();
       
  1299 	else
       
  1300 		iParent->DCEPort().NotifySignalChangeCancel();
       
  1301 	}
       
  1302 
       
  1303 
       
  1304 void CCommSignalNotifier::RunL()
       
  1305 /**
       
  1306  * a notification has completed
       
  1307  */
       
  1308 	{
       
  1309 	LOGECUART2(_L8("CCommSignalNotifier::RunL(), iStatus = %d"), iStatus.Int());
       
  1310 	if (iStatus.Int())
       
  1311 		{
       
  1312 		iParent->SignalChangeCompleted(iSignals,iStatus.Int());
       
  1313 		iParent->BreakNotifyCompleted(iStatus.Int());
       
  1314 		iSignalMask = 0;
       
  1315 		iNotifyCount = 0;
       
  1316 		return;
       
  1317 		}
       
  1318 
       
  1319 	if (iSignals & ((KSignalDTEOutputs|KSignalDTEInputs)*KSignalChanged))	// these don't include BREAK
       
  1320 		{
       
  1321 		iNotifyCount--;
       
  1322 		iParent->SignalChangeCompleted(iSignals,iStatus.Int());
       
  1323 		iSignalMask &= (KSignalBreak);	// mask out everything but the BREAK signal
       
  1324 		}
       
  1325 	if (iSignals & KBreakChanged)
       
  1326 		{
       
  1327 		iNotifyCount--;
       
  1328 		iParent->BreakNotifyCompleted(iStatus.Int());
       
  1329 		iSignalMask&=(~KSignalBreak);
       
  1330 		}
       
  1331 	__ASSERT_ALWAYS(iNotifyCount>=0, Fault(ENegativeCount));
       
  1332 	if (iNotifyCount>0)
       
  1333 		Start();
       
  1334 	}
       
  1335 
       
  1336 void CCommSignalNotifier::Start()
       
  1337 /**
       
  1338  * start the notification
       
  1339  */
       
  1340 	{
       
  1341 	LOGECUART1(_L8("CCommSignalNotifier::Start()"));
       
  1342 	if (IsActive())
       
  1343 		Cancel();
       
  1344 	if (iRole==ECommRoleDTE)
       
  1345 		iParent->DTEPort().NotifySignalChange(iStatus, iSignals, iSignalMask);
       
  1346 	else
       
  1347 		iParent->DCEPort().NotifySignalChange(iStatus, iSignals, iSignalMask);
       
  1348 	SetActive();
       
  1349 	}
       
  1350 
       
  1351 
       
  1352 void CCommSignalNotifier::NotifySignal(TUint aSignalMask)
       
  1353 /**
       
  1354  * notify client when signal changes
       
  1355  *
       
  1356  * @param aSignalMask bitmask with the signals to be notified on
       
  1357  */
       
  1358 	{
       
  1359 	LOGECUART2(_L8("CCommSignalNotifier::NotifySignal(), aSignalMask = %d"), aSignalMask);
       
  1360 	TUint reqSigs = aSignalMask & ~KSignalBreak;
       
  1361 	if (!reqSigs)
       
  1362 		{// User has only asked to be notified of break.
       
  1363 		iParent->SignalChangeCompleted(iSignals, KErrArgument);
       
  1364 		return;
       
  1365 		}
       
  1366 	iNotifyCount++;
       
  1367 	iSignalMask |= reqSigs;
       
  1368 	Start();
       
  1369 	}
       
  1370 
       
  1371 
       
  1372 void CCommSignalNotifier::NotifySignalCancel()
       
  1373 /**
       
  1374  * cancel an outstanding signal change notification
       
  1375  */
       
  1376 	{
       
  1377 	LOGECUART1(_L8("CCommSignalNotifier::NotifySignalCancel()"));
       
  1378 	Cancel();
       
  1379 	iSignalMask &= (KSignalBreak);	// set mask to zero, excluding BREAK
       
  1380 	if (--iNotifyCount>0)	// NotifyBreak may still be outstanding
       
  1381 		Start();
       
  1382 	}
       
  1383 
       
  1384 
       
  1385 void CCommSignalNotifier::NotifyBreak()
       
  1386 /**
       
  1387  * notify client if break occurs
       
  1388  */
       
  1389 	{
       
  1390 	LOGECUART1(_L8("CCommSignalNotifier::NotifyBreak()"));
       
  1391 	iNotifyCount++;
       
  1392 	iSignalMask |= KSignalBreak;
       
  1393 	Start();
       
  1394 	}
       
  1395 
       
  1396 
       
  1397 void CCommSignalNotifier::NotifyBreakCancel()
       
  1398 /**
       
  1399  * cancel an outstanding break notification
       
  1400  */
       
  1401 	{
       
  1402 	LOGECUART1(_L8("CCommSignalNotifier::NotifyBreakCancel()"));
       
  1403 	Cancel();
       
  1404 	iSignalMask &= (~KSignalBreak);	// mask out the BREAK signal
       
  1405 	if (--iNotifyCount>0)					// NotifySignals may still be outstanding
       
  1406 		Start();
       
  1407 	}
       
  1408 
       
  1409 
       
  1410 //
       
  1411 // implementation of CCommAvailableDataNotifier
       
  1412 //
       
  1413 
       
  1414 
       
  1415 CCommAvailableDataNotifier::CCommAvailableDataNotifier(CHWPort* aParent)
       
  1416 /**
       
  1417  * C'tor
       
  1418  *
       
  1419  * @param aParent pointer to the CHWPort object
       
  1420  */
       
  1421 	:CCommNotifyBase(aParent)
       
  1422 	{
       
  1423 	}
       
  1424 
       
  1425 
       
  1426 CCommAvailableDataNotifier::~CCommAvailableDataNotifier()
       
  1427 /**
       
  1428  * D'tor
       
  1429  */
       
  1430 	{
       
  1431 	LOGECUART1(_L8("CCommAvailableDataNotifier::~CCommAvailableDataNotifier()"));
       
  1432 	}
       
  1433 
       
  1434 
       
  1435 void CCommAvailableDataNotifier::DoCancel()
       
  1436 /**
       
  1437  * Cancel a pending data available notification.
       
  1438  */
       
  1439 	{
       
  1440 	__ASSERT_ALWAYS(IsActive(), Fault(ECancelNotOutstanding));
       
  1441 	if (iRole==ECommRoleDTE)
       
  1442 		iParent->DTEPort().NotifyReceiveDataAvailableCancel();
       
  1443 	else
       
  1444 		iParent->DCEPort().NotifyReceiveDataAvailableCancel();
       
  1445 	}
       
  1446 
       
  1447 
       
  1448 void CCommAvailableDataNotifier::RunL()
       
  1449 /**
       
  1450  * the notification has completed, and data is available
       
  1451  */
       
  1452 	{
       
  1453 	LOGECUART2(_L8("CCommAvailableDataNotifier::RunL(), iStatus = %d"), iStatus.Int());
       
  1454 	iParent->NotifyDataAvailableCompleted(iStatus.Int());
       
  1455 	}
       
  1456 
       
  1457 
       
  1458 void CCommAvailableDataNotifier::Start()
       
  1459 /**
       
  1460  * start notification on data available
       
  1461  */
       
  1462 	{
       
  1463 	LOGECUART1(_L8("CCommAvailableDataNotifier::Start()"));
       
  1464 	if (iRole==ECommRoleDTE)
       
  1465 		iParent->DTEPort().NotifyReceiveDataAvailable(iStatus);
       
  1466 	else
       
  1467 		iParent->DCEPort().NotifyReceiveDataAvailable(iStatus);
       
  1468 	SetActive();
       
  1469 	}
       
  1470 
       
  1471 
       
  1472 //
       
  1473 // implementation of CCommFlowControlChangeNotifier
       
  1474 //
       
  1475 
       
  1476 
       
  1477 CCommFlowControlChangeNotifier::CCommFlowControlChangeNotifier(CHWPort* aParent)
       
  1478 /**
       
  1479  * C'tor
       
  1480  *
       
  1481  * @param aParent pointer to the CHWPort object
       
  1482  */
       
  1483 	:CCommNotifyBase(aParent)
       
  1484 	{
       
  1485 	}
       
  1486 
       
  1487 
       
  1488 CCommFlowControlChangeNotifier::~CCommFlowControlChangeNotifier()
       
  1489 /**
       
  1490  * D'tor
       
  1491  */
       
  1492 	{
       
  1493 	LOGECUART1(_L8("CCommFlowControlChangeNotifier::~CCommFlowControlChangeNotifier()"));
       
  1494 	}
       
  1495 
       
  1496 
       
  1497 void CCommFlowControlChangeNotifier::DoCancel()
       
  1498 /**
       
  1499  * Cancel a pending flow control change notification.
       
  1500  */
       
  1501 	{
       
  1502 	LOGECUART1(_L8("CCommFlowControlChangeNotifier::DoCancel()"));
       
  1503 	__ASSERT_ALWAYS(iRole==ECommRoleDCE,Fault(EWrongRole));
       
  1504 	__ASSERT_ALWAYS(IsActive(),Fault(ECancelNotOutstanding));
       
  1505 	iParent->DCEPort().NotifyFlowControlChangeCancel();
       
  1506 	}
       
  1507 
       
  1508 
       
  1509 void CCommFlowControlChangeNotifier::RunL()
       
  1510 /**
       
  1511  *	The device driver does not give the new value of flow control status when the notification
       
  1512  *	completes so we go and ask for it. If this impedes performance, it may be worth taking the
       
  1513  *  plunge and working out the value ourselves - it should just be the opposite (ON/OFF) each time
       
  1514  *  it completes.
       
  1515  */
       
  1516 	{
       
  1517 	LOGECUART2(_L8("CCommFlowControlChangeNotifier::RunL(), iStatus = %d"), iStatus.Int());
       
  1518 	__ASSERT_ALWAYS(iRole==ECommRoleDCE, Fault(EWrongRole));
       
  1519 	iParent->DCEPort().GetFlowControlStatus(iFlowControl);
       
  1520 	iParent->FlowControlChangeCompleted(iFlowControl,iStatus.Int());
       
  1521 	}
       
  1522 
       
  1523 
       
  1524 void CCommFlowControlChangeNotifier::Start()
       
  1525 /**
       
  1526  * start notification on flow control change
       
  1527  *
       
  1528  * @note Only supported for DCE role
       
  1529  */
       
  1530 	{
       
  1531 	LOGECUART1(_L8("CCommFlowControlChangeNotifier::Start()"));
       
  1532 	if (iRole==ECommRoleDTE)
       
  1533 		iParent->FlowControlChangeCompleted(iFlowControl, KErrNotSupported);
       
  1534 	else
       
  1535 		{
       
  1536 		iParent->DCEPort().NotifyFlowControlChange(iStatus);
       
  1537 		SetActive();
       
  1538 		}
       
  1539 	}
       
  1540 
       
  1541 
       
  1542 //
       
  1543 // implementation of CCommConfigChangeNotifier
       
  1544 //
       
  1545 
       
  1546 
       
  1547 CCommConfigChangeNotifier::CCommConfigChangeNotifier(CHWPort* aParent)
       
  1548 /**
       
  1549  * C'tor
       
  1550  *
       
  1551  * @param aParent pointer to the CHWPort object
       
  1552  */
       
  1553 	:CCommNotifyBase(aParent)
       
  1554 	{
       
  1555 	LOGECUART1(_L8("CCommConfigChangeNotifier::CCommConfigChangeNotifier()"));
       
  1556 	}
       
  1557 
       
  1558 
       
  1559 CCommConfigChangeNotifier::~CCommConfigChangeNotifier()
       
  1560 /**
       
  1561  * D'tor
       
  1562  */
       
  1563 	{
       
  1564 	LOGECUART1(_L8("CCommConfigChangeNotifier::~CCommConfigChangeNotifier()"));
       
  1565 	}
       
  1566 
       
  1567 
       
  1568 void CCommConfigChangeNotifier::Start()
       
  1569 /**
       
  1570  * start notification on config change
       
  1571  *
       
  1572  * @note Only supported for DCE role
       
  1573  */
       
  1574 	{
       
  1575 	LOGECUART1(_L8("CCommConfigChangeNotifier::Start()"));
       
  1576 	if (iRole==ECommRoleDTE)
       
  1577 		iParent->ConfigChangeCompleted(iConfig, KErrNotSupported);
       
  1578 	else
       
  1579 		{
       
  1580 		iParent->DCEPort().NotifyConfigChange(iStatus, iConfig);
       
  1581 		SetActive();
       
  1582 		}
       
  1583 	}
       
  1584 
       
  1585 
       
  1586 void CCommConfigChangeNotifier::DoCancel()
       
  1587 /**
       
  1588  * Cancel a pending config change notification.
       
  1589  */
       
  1590 	{
       
  1591 	LOGECUART1(_L8("CCommConfigChangeNotifier::DoCancel()"));
       
  1592 	__ASSERT_ALWAYS(iRole==ECommRoleDCE,Fault(EWrongRole));
       
  1593 	__ASSERT_ALWAYS(IsActive(),Fault(ECancelNotOutstanding));
       
  1594 	iParent->DCEPort().NotifyConfigChangeCancel();
       
  1595 	}
       
  1596 
       
  1597 
       
  1598 void CCommConfigChangeNotifier::RunL()
       
  1599 /**
       
  1600  * the config change notification has completed,
       
  1601  * forward the news to the client.
       
  1602  */
       
  1603 	{
       
  1604 	LOGECUART2(_L8("CCommConfigChangeNotifier::RunL(), iStatus = %d"), iStatus.Int());
       
  1605 	iParent->ConfigChangeCompleted(iConfig, iStatus.Int());
       
  1606 	}
       
  1607 
       
  1608 
       
  1609 void CloseObject(TAny* aObject)
       
  1610 /**
       
  1611  * Close an object from the cleanup stack
       
  1612  *
       
  1613  * @param aObject pointer to the object to close
       
  1614  */
       
  1615 	{
       
  1616 	LOGECUART1(_L8("CloseObject()"));
       
  1617 	((CObject*)aObject)->Close();
       
  1618 	}
       
  1619 
       
  1620 
       
  1621 //
       
  1622 // implementation of CHWPort
       
  1623 //
       
  1624 
       
  1625 
       
  1626 CHWPort* CHWPort::NewL(TUint aUnit)
       
  1627 /**
       
  1628  * Make a new CPort for the comm server
       
  1629  *
       
  1630  * @param aUnit unit number of comm port (i.e. 0 for COMM::0)
       
  1631  * @return a newly created CHWPort object
       
  1632  */
       
  1633 	{
       
  1634 	LOGECUART2(_L8("CHWPort::NewL(), aUint = %d (unit number of comm port)"), aUnit);
       
  1635 	CHWPort* p = new (ELeave) CHWPort;
       
  1636 	TCleanupItem closePort(CloseObject, p);
       
  1637 
       
  1638 	CleanupStack::PushL(closePort);
       
  1639 
       
  1640 	p->iReader=CCommReader::NewL(p);
       
  1641 	p->iWriter=CCommWriter::NewL(p);
       
  1642 	p->iBreaker=CCommBreaker::NewL(p);
       
  1643 	p->iSignalNotifier=new (ELeave) CCommSignalNotifier(p);
       
  1644 	p->iDataAvailableNotifier=new (ELeave) CCommAvailableDataNotifier(p);
       
  1645 	p->iFlowControlChangeNotifier=new (ELeave) CCommFlowControlChangeNotifier(p);
       
  1646 	p->iConfigChangeNotifier=new (ELeave) CCommConfigChangeNotifier(p);
       
  1647 
       
  1648 	TName name;
       
  1649 	name.Format(_L("%d"), aUnit);
       
  1650 	p->SetName(&name); // todo check return value?
       
  1651 
       
  1652 	// the C32 server does not check for the port number beeing to big.
       
  1653 	// this is up to the CSY. If the aUnit number passed to the Logical
       
  1654 	// device driver is greater than KMaxUnits, the kernel will Panic.
       
  1655 	// We want to avoid this by gracefully leaving with Not Supported instead.
       
  1656 	if(aUnit >= (TUint)KMaxUnits)
       
  1657 		User::Leave(KErrNotSupported);
       
  1658 
       
  1659 	p->iPortName = aUnit;
       
  1660 #if defined (_DEBUG_CONSOLE_)
       
  1661 	name.Format(_L("Comm::%d"),aUnit);
       
  1662 	p->iConsole.SetTitle(name);
       
  1663 #if defined (_DEBUG_DEVCOMM)
       
  1664 	p->iDumper=CCommDebugDumper::NewL(p->iConsole);
       
  1665 #endif
       
  1666 #endif
       
  1667 	CleanupStack::Pop();
       
  1668 	return p;
       
  1669 	}
       
  1670 
       
  1671 
       
  1672 CHWPort::CHWPort()
       
  1673 /**
       
  1674  * C'Tor
       
  1675  */
       
  1676 	{
       
  1677 	}
       
  1678 
       
  1679 
       
  1680 void CHWPort::StartRead(const TAny* aClientBuffer, TInt aLength)
       
  1681 /**
       
  1682  * Queue a read
       
  1683  *
       
  1684  * @param aClientBuffer pointer to the Client's buffer
       
  1685  * @param aLength number of bytes to read
       
  1686  */
       
  1687 	{
       
  1688 	LOGECUART2(_L8("CHWPort::StartRead(), aLength = %d"), aLength);
       
  1689 	DEBUG_TRACE((iConsole.Write(_L("DoRead \n\r"))));
       
  1690 	if(iDataAvailableNotifier->IsActive())
       
  1691 		{
       
  1692 		ReadCompleted(KErrInUse);
       
  1693 		return;
       
  1694 		}
       
  1695 	iReader->Read(aClientBuffer, aLength);
       
  1696 	}
       
  1697 
       
  1698 
       
  1699 void CHWPort::ReadCancel()
       
  1700 /**
       
  1701  * Cancel a read
       
  1702  */
       
  1703 	{
       
  1704 	LOGECUART1(_L8("CHWPort::ReadCancel()"));
       
  1705 	iReader->ReadCancel();
       
  1706 	}
       
  1707 
       
  1708 
       
  1709 TInt CHWPort::QueryReceiveBuffer(TInt& aLength) const
       
  1710 /**
       
  1711  * Get the size of the receive buffer from the real serial port
       
  1712  *
       
  1713  * @param aLength reference to where the size will be written to
       
  1714  * @return KErrNone always
       
  1715  */
       
  1716 	{
       
  1717 	LOGECUART1(_L8("CHWPort::QueryReceiveBuffer()"));
       
  1718 	// casting away constness with (CHWPort *)this
       
  1719 	if (iRole==ECommRoleDTE)
       
  1720 		aLength=((CHWPort *)this)->iPort.QueryReceiveBuffer();
       
  1721 	else
       
  1722 		aLength=((CHWPort *)this)->iPortDCE.QueryReceiveBuffer();
       
  1723 	return KErrNone;
       
  1724 	}
       
  1725 
       
  1726 
       
  1727 void CHWPort::ResetBuffers(TUint)
       
  1728 /**
       
  1729  * reset Tx and Rx buffers
       
  1730  *
       
  1731  * @note both Tx and Rx buffers are reset here
       
  1732  */
       
  1733 	{
       
  1734 	LOGECUART1(_L8("CHWPort::ResetBuffers()"));
       
  1735 	if (iRole==ECommRoleDTE)
       
  1736 		iPort.ResetBuffers();
       
  1737 	else
       
  1738 		iPortDCE.ResetBuffers();
       
  1739 	}
       
  1740 
       
  1741 
       
  1742 void CHWPort::StartWrite(const TAny* aClientBuffer, TInt aLength)
       
  1743 /**
       
  1744  * Queue a write
       
  1745  *
       
  1746  * @param aClientBuffer pointer to the Client's buffer
       
  1747  * @param aLength number of bytes to write
       
  1748  */
       
  1749 	{
       
  1750 	LOGECUART2(_L8("CHWPort::StartWrite(), aLength = %d"), aLength);
       
  1751 	DEBUG_TRACE((iConsole.Write(_L("DoWrite \n\r"))));
       
  1752 	iWriter->Write(aClientBuffer,aLength);
       
  1753 	}
       
  1754 
       
  1755 
       
  1756 void CHWPort::WriteCancel()
       
  1757 /**
       
  1758  * Cancel a pending write
       
  1759  */
       
  1760 	{
       
  1761 	LOGECUART1(_L8("CHWPort::WriteCancel()"));
       
  1762 	iWriter->WriteCancel();
       
  1763 	}
       
  1764 
       
  1765 
       
  1766 void CHWPort::Break(TInt aTime)
       
  1767 /**
       
  1768  * Queue a break
       
  1769  *
       
  1770  * @param aTime Length of break in micro seconds
       
  1771  */
       
  1772 	{
       
  1773 	LOGECUART2(_L8("CHWPort::Break(), aTime = %d"), aTime);
       
  1774 	iBreaker->Break(aTime);
       
  1775 	}
       
  1776 
       
  1777 
       
  1778 void CHWPort::BreakCancel()
       
  1779 /**
       
  1780  * Cancel a pending break
       
  1781  */
       
  1782 	{
       
  1783 	LOGECUART1(_L8("CHWPort::BreakCancel()"));
       
  1784 	iBreaker->Cancel();
       
  1785 	}
       
  1786 
       
  1787 
       
  1788 TInt CHWPort::GetConfig(TDes8& aDes) const
       
  1789 /**
       
  1790  * Pass a config request
       
  1791  *
       
  1792  * @param aDes config will be written to this descriptor
       
  1793  * @return KErrNone always
       
  1794  */
       
  1795 	{
       
  1796 	LOGECUART1(_L8("CHWPort::GetConfig()"));
       
  1797 	if (iRole==ECommRoleDTE)
       
  1798 		((CHWPort*)this)->iPort.Config(aDes);
       
  1799 	else
       
  1800 		((CHWPort*)this)->iPortDCE.Config(aDes);
       
  1801 	return KErrNone;
       
  1802 	}
       
  1803 
       
  1804 
       
  1805 TInt CHWPort::SetConfig(const TDesC8& aDes)
       
  1806 /**
       
  1807  * Set up the Comm LDD/PDD
       
  1808  *
       
  1809  * @param aDes descriptor containing the new config
       
  1810  * @return TInt error code
       
  1811  */
       
  1812 	{
       
  1813 	LOGECUART1(_L8("CHWPort::SetConfig()"));
       
  1814 	if (aDes.Length()<(TInt)sizeof(TCommConfigV01))
       
  1815 		return KErrGeneral;
       
  1816 	TCommConfigV01 config(*(TCommConfigV01*)aDes.Ptr());
       
  1817 
       
  1818 	if (config.iHandshake & KConfigWriteBufferedComplete)
       
  1819 		{
       
  1820 		if (iWriter->IsNotificationEnabled())
       
  1821 			return KErrAccessDenied;
       
  1822 		iEarlyWriteCompletion = ETrue;
       
  1823 		}
       
  1824 	else
       
  1825 		{
       
  1826 		iEarlyWriteCompletion = EFalse;
       
  1827 		}
       
  1828 	if (iRole==ECommRoleDTE)
       
  1829 		return iPort.SetConfig(aDes);
       
  1830 	else
       
  1831 		return iPortDCE.SetConfig(aDes);
       
  1832 	}
       
  1833 
       
  1834 
       
  1835 TInt CHWPort::SetServerConfig(const TDesC8& aDes)
       
  1836 /**
       
  1837  * Set the port to use partial reads/writes or the bungee buffer
       
  1838  *
       
  1839  * @param aDes package with new server configurations
       
  1840  * @return TInt error code
       
  1841  */
       
  1842 	{
       
  1843 	LOGECUART1(_L8("CHWPort::SetServerConfig()"));
       
  1844 	if (aDes.Length()<(TInt)sizeof(TCommServerConfigV01))
       
  1845 		return KErrGeneral;
       
  1846 	TCommServerConfig c(*(TCommServerConfigV01*)aDes.Ptr());
       
  1847 	TInt r=0;
       
  1848 	if ((r=iReader->SetServerConfig(c))==KErrNone)
       
  1849 		r=iWriter->SetServerConfig(c);
       
  1850 	return r;
       
  1851 	}
       
  1852 
       
  1853 
       
  1854 TInt CHWPort::GetServerConfig(TDes8& aDes)
       
  1855 /**
       
  1856  * Get the server configs
       
  1857  *
       
  1858  * @param aDes server configs will be written to this descriptor
       
  1859  * @return TInt error code
       
  1860  */
       
  1861 	{
       
  1862 	LOGECUART1(_L8("CHWPort::GetServerConfig()"));
       
  1863 	if (aDes.Length()<(TInt)sizeof(TCommServerConfigV01))
       
  1864 		return KErrGeneral;
       
  1865 	TCommServerConfig c;
       
  1866 
       
  1867 	iReader->GetServerConfig(c);
       
  1868 	aDes=c;
       
  1869 
       
  1870 	return KErrNone;
       
  1871 	}
       
  1872 
       
  1873 
       
  1874 TInt CHWPort::GetCaps(TDes8& aDes)
       
  1875 /**
       
  1876  * Read capabilities from the driver
       
  1877  *
       
  1878  * @param aDes caps will be written to this descriptor
       
  1879  * @return KErrNone always
       
  1880  */
       
  1881 	{
       
  1882 	LOGECUART1(_L8("CHWPort::GetCaps()"));
       
  1883 	if (iRole==ECommRoleDTE)
       
  1884 		iPort.Caps(aDes);
       
  1885 	else
       
  1886 		iPortDCE.Caps(aDes);
       
  1887 	if (aDes.Length()==sizeof(TCommCapsV02))
       
  1888 		{
       
  1889 		TCommCapsV02* commcaps = (TCommCapsV02*)(aDes.Ptr());
       
  1890 		commcaps->iNotificationCaps |= KNotifyOutputEmptySupported;
       
  1891 		commcaps->iRoleCaps = KCapsRoleSwitchSupported;
       
  1892 		}
       
  1893 	return KErrNone;
       
  1894 	}
       
  1895 
       
  1896 
       
  1897 TInt CHWPort::GetSignals(TUint& aSignals)
       
  1898 /**
       
  1899  * get the status of the signal pins
       
  1900  *
       
  1901  * @param aSignals signals will be written to this descriptor
       
  1902  * @return KErrNone always
       
  1903  */
       
  1904 	{
       
  1905 	LOGECUART1(_L8("CHWPort::GetSignals()"));
       
  1906 	if (iRole==ECommRoleDTE)
       
  1907 		aSignals=iPort.Signals();
       
  1908 	else
       
  1909 		aSignals=iPortDCE.Signals();
       
  1910 	return KErrNone;
       
  1911 	}
       
  1912 
       
  1913 
       
  1914 TInt CHWPort::SetSignalsToMark(TUint aSignals)
       
  1915 /**
       
  1916  * set selected signals to high (logical 1)
       
  1917  *
       
  1918  * @param aSignals bitmask with the signals to be set
       
  1919  * @return KErrNone always
       
  1920  */
       
  1921 	{
       
  1922 	LOGECUART2(_L8("CHWPort::SetSignalsToMark(), aSignals = %d"), aSignals);
       
  1923 	if (iRole==ECommRoleDTE)
       
  1924 		iPort.SetSignals(aSignals,0);
       
  1925 	else
       
  1926 		iPortDCE.SetSignals(aSignals,0);
       
  1927 	return KErrNone;
       
  1928 	}
       
  1929 
       
  1930 
       
  1931 TInt CHWPort::SetSignalsToSpace(TUint aSignals)
       
  1932 /**
       
  1933  * set selected signals to low (logical 0)
       
  1934  *
       
  1935  * @param aSignals bitmask with the signals to be cleared
       
  1936  * @return KErrNone always
       
  1937  */
       
  1938 	{
       
  1939 	LOGECUART2(_L8("CHWPort::SetSignalsToSpace(), aSignals = %d"), aSignals);
       
  1940 	if (iRole==ECommRoleDTE)
       
  1941 		iPort.SetSignals(0,aSignals);
       
  1942 	else
       
  1943 		iPortDCE.SetSignals(0,aSignals);
       
  1944 	return KErrNone;
       
  1945 	}
       
  1946 
       
  1947 
       
  1948 TInt CHWPort::GetReceiveBufferLength(TInt& aLength) const
       
  1949 /**
       
  1950  * get size of Tx and Rx buffer
       
  1951  *
       
  1952  * @param aLength reference to where the length will be written to
       
  1953  * @return KErrNone always
       
  1954  */
       
  1955 	{
       
  1956 	LOGECUART1(_L8("CHWPort::GetReceiveBufferLength()"));
       
  1957 	// casting away constness with (CHWPort *)this
       
  1958 	if (iRole==ECommRoleDTE)
       
  1959 		aLength=((CHWPort *)this)->iPort.ReceiveBufferLength();
       
  1960 	else
       
  1961 		aLength=((CHWPort *)this)->iPortDCE.ReceiveBufferLength();
       
  1962 	return KErrNone;
       
  1963 	}
       
  1964 
       
  1965 
       
  1966 TInt CHWPort::SetReceiveBufferLength(TInt aLength)
       
  1967 /**
       
  1968  * set the size of Tx and Rx buffer
       
  1969  *
       
  1970  * @param aLength new length of Tx and Rx buffer
       
  1971  * @return TInt error code
       
  1972  */
       
  1973 	{
       
  1974 	LOGECUART2(_L8("CHWPort::SetReceiveBufferLength(), aLength = %d"), aLength);
       
  1975 	if (iRole==ECommRoleDTE)
       
  1976 		return iPort.SetReceiveBufferLength(aLength);
       
  1977 	else
       
  1978 		return iPortDCE.SetReceiveBufferLength(aLength);
       
  1979 	}
       
  1980 
       
  1981 
       
  1982 void CHWPort::Destruct()
       
  1983 /**
       
  1984  * Destruct - we must (eventually) call delete this
       
  1985  */
       
  1986 	{
       
  1987 	LOGECUART1(_L8("CHWPort::Destruct()"));
       
  1988 	delete this;
       
  1989 	}
       
  1990 
       
  1991 
       
  1992 void CHWPort::FreeMemory()
       
  1993 /**
       
  1994  * Attempt to reduce out memory foot print.
       
  1995  */
       
  1996 	{
       
  1997 	LOGECUART1(_L8("CHWPort::FreeMemory()"));
       
  1998 	iReader->FreeMemory();
       
  1999 	iWriter->FreeMemory();
       
  2000 	}
       
  2001 
       
  2002 
       
  2003 void CHWPort::NotifySignalChange(TUint aSignalMask)
       
  2004 /**
       
  2005  * notify client when the signals change
       
  2006  *
       
  2007  * @param aSignalMask bitmask with signal to be notified on
       
  2008  */
       
  2009 	{
       
  2010 	LOGECUART2(_L8("CHWPort::NotifySignalChange(), aSignalMask = %d"), aSignalMask);
       
  2011 	iSignalNotifier->NotifySignal(aSignalMask);
       
  2012 	}
       
  2013 
       
  2014 
       
  2015 void CHWPort::NotifySignalChangeCancel()
       
  2016 /**
       
  2017  * cancel an outstanding signal change notification
       
  2018  */
       
  2019 	{
       
  2020 	LOGECUART1(_L8("CHWPort::NotifySignalChangeCancel()"));
       
  2021 	iSignalNotifier->NotifySignalCancel();
       
  2022 	}
       
  2023 
       
  2024 
       
  2025 void CHWPort::NotifyConfigChange()
       
  2026 /**
       
  2027  * notify client when the configation changes
       
  2028  */
       
  2029 	{
       
  2030 	LOGECUART1(_L8("CHWPort::NotifyConfigChange()"));
       
  2031 	iConfigChangeNotifier->Start();
       
  2032 	}
       
  2033 
       
  2034 
       
  2035 void CHWPort::NotifyConfigChangeCancel()
       
  2036 /**
       
  2037  * cancel an outstanding config change notification
       
  2038  */
       
  2039 	{
       
  2040 	LOGECUART1(_L8("CHWPort::NotifyConfigChangeCancel()"));
       
  2041 	iConfigChangeNotifier->Cancel();
       
  2042 	}
       
  2043 
       
  2044 
       
  2045 void CHWPort::NotifyFlowControlChange()
       
  2046 /**
       
  2047  * notify client when the flow control changes
       
  2048  */
       
  2049 	{
       
  2050 	LOGECUART1(_L8("CHWPort::NotifyFlowControlChange()"));
       
  2051 	iFlowControlChangeNotifier->Start();
       
  2052 	}
       
  2053 
       
  2054 
       
  2055 void CHWPort::NotifyFlowControlChangeCancel()
       
  2056 /**
       
  2057  * cancel an outstanding flow control change notification
       
  2058  */
       
  2059 	{
       
  2060 	LOGECUART1(_L8("CHWPort::NotifyFlowControlChangeCancel()"));
       
  2061 	iFlowControlChangeNotifier->Cancel();
       
  2062 	}
       
  2063 
       
  2064 
       
  2065 void CHWPort::NotifyBreak()
       
  2066 /**
       
  2067  * notify client when a break occurs
       
  2068  */
       
  2069 	{
       
  2070 	LOGECUART1(_L8("CHWPort::NotifyBreak()"));
       
  2071 	iSignalNotifier->NotifyBreak();
       
  2072 	}
       
  2073 
       
  2074 
       
  2075 void CHWPort::NotifyBreakCancel()
       
  2076 /**
       
  2077  * cancel an outstanding break notification
       
  2078  */
       
  2079 	{
       
  2080 	LOGECUART1(_L8("CHWPort::NotifyBreakCancel()"));
       
  2081 	iSignalNotifier->NotifyBreakCancel();
       
  2082 	}
       
  2083 
       
  2084 
       
  2085 void CHWPort::NotifyDataAvailable()
       
  2086 /**
       
  2087  * notify client when data is available
       
  2088  */
       
  2089 	{
       
  2090 	LOGECUART1(_L8("CHWPort::NotifyDataAvailable()"));
       
  2091 	if(iReader->IsActive())
       
  2092 		{
       
  2093 		NotifyDataAvailableCompleted(KErrInUse);
       
  2094 		return;
       
  2095 		}
       
  2096 	iDataAvailableNotifier->Start();
       
  2097 	}
       
  2098 
       
  2099 
       
  2100 void CHWPort::NotifyDataAvailableCancel()
       
  2101 /**
       
  2102  * cancel an outstanding data availalbe notification
       
  2103  */
       
  2104 	{
       
  2105 	LOGECUART1(_L8("CHWPort::NotifyDataAvailableCancel()"));
       
  2106 	iDataAvailableNotifier->Cancel();
       
  2107 	}
       
  2108 
       
  2109 
       
  2110 void CHWPort::NotifyOutputEmpty()
       
  2111 /**
       
  2112  * notify client when output buffer is empty
       
  2113  */
       
  2114 	{
       
  2115 	LOGECUART1(_L8("CHWPort::NotifyOutputEmpty()"));
       
  2116 	if (iEarlyWriteCompletion)
       
  2117 		NotifyOutputEmptyCompleted(KErrAccessDenied);
       
  2118 	else
       
  2119 		iWriter->NotificationEnable();
       
  2120 	}
       
  2121 
       
  2122 
       
  2123 void CHWPort::NotifyOutputEmptyCancel()
       
  2124 /**
       
  2125  * cancel an outstanding output empty notification
       
  2126  */
       
  2127 	{
       
  2128 	LOGECUART1(_L8("CHWPort::NotifyOutputEmptyCancel()"));
       
  2129 	iWriter->NotificationDisable();
       
  2130 	}
       
  2131 
       
  2132 
       
  2133 TInt CHWPort::GetFlowControlStatus(TFlowControl& aFlowControl)
       
  2134 /**
       
  2135  * get the flow control status
       
  2136  *
       
  2137  * @param aFlowControl flow control status will be written to this descriptor
       
  2138  * @return TInt error code
       
  2139  *
       
  2140  * @note only supported for DCE role
       
  2141  */
       
  2142 	{
       
  2143 	if (iRole==ECommRoleDTE)
       
  2144 		return KErrNotSupported;
       
  2145 	else
       
  2146 		iPortDCE.GetFlowControlStatus(aFlowControl);
       
  2147 	return KErrNone;
       
  2148 	}
       
  2149 
       
  2150 
       
  2151 TInt CHWPort::GetRole(TCommRole& aRole)
       
  2152 /**
       
  2153  * get the role of this port unit
       
  2154  *
       
  2155  * @param aRole reference to where the role will be written to
       
  2156  * @return KErrNone always
       
  2157  */
       
  2158 	{
       
  2159 	aRole = iRole;
       
  2160 	return KErrNone;
       
  2161 	}
       
  2162 
       
  2163 
       
  2164 TInt CHWPort::SetRole(TCommRole aRole)
       
  2165 /**
       
  2166  * set the role of this port unit
       
  2167  *
       
  2168  * @param aRole the new role
       
  2169  * @return TInt error code
       
  2170  */
       
  2171 	{
       
  2172 	iRole=aRole;
       
  2173 	TInt ret=KErrNone;
       
  2174 	if (aRole==ECommRoleDTE)
       
  2175 		ret = iPort.Open(iPortName);
       
  2176 	else
       
  2177 		ret = iPortDCE.Open(iPortName);
       
  2178 	if (ret!=KErrNone)
       
  2179 		{
       
  2180 		LOGECUART3(_L8("CHWPort::SetRole - failed with %d when attempting to open hardware port unit: %d"),ret,iPortName);
       
  2181 		return ret;
       
  2182 		}
       
  2183 	iReader->SetRole(aRole);
       
  2184 	iWriter->SetRole(aRole);
       
  2185 	iBreaker->SetRole(aRole);
       
  2186 	iSignalNotifier->SetRole(aRole);
       
  2187 	iDataAvailableNotifier->SetRole(aRole);
       
  2188 	iFlowControlChangeNotifier->SetRole(aRole);
       
  2189 	iConfigChangeNotifier->SetRole(aRole);
       
  2190 
       
  2191 #if defined (_DEBUG_DEVCOMM) && defined (_DEBUG_CONSOLE_)
       
  2192 	iDumper->SetRole(aRole);
       
  2193 #endif
       
  2194 	return KErrNone;
       
  2195 	}
       
  2196 
       
  2197 
       
  2198 CHWPort::~CHWPort()
       
  2199 /**
       
  2200  * D'tor
       
  2201  */
       
  2202 	{
       
  2203 	LOGECUART1(_L8("CHWPort::~CHWPort()"));
       
  2204 	delete iReader;
       
  2205 	delete iWriter;
       
  2206 	delete iBreaker;
       
  2207 	delete iSignalNotifier;
       
  2208 	delete iDataAvailableNotifier;
       
  2209 	delete iFlowControlChangeNotifier;
       
  2210 	delete iConfigChangeNotifier;
       
  2211 
       
  2212 	iPort.Close();
       
  2213 	iPortDCE.Close();
       
  2214 
       
  2215 #if defined (_DEBUG_CONSOLE_)
       
  2216 #if defined (_DEBUG_DEVCOMM)
       
  2217 	delete iDumper;
       
  2218 #endif
       
  2219 	iConsole.Close();
       
  2220 #endif
       
  2221 	}
       
  2222 
       
  2223 
       
  2224 #ifdef _DEBUG_DEVCOMM
       
  2225 void CHWPort::DoDumpDebugInfo(const RMessage2 &aMessage)
       
  2226 	{
       
  2227 	TCommDebugInfoPckg d;
       
  2228 	if (iRole==ECommRoleDTE)
       
  2229 		iPort.DebugInfo(d);
       
  2230 	else
       
  2231 		iPortDCE.DebugInfo(d);
       
  2232 	TRAPD(ret, aMessage.WriteL(0,aMessage,d) );
       
  2233 	aMessage.Complete(ret);
       
  2234 	}
       
  2235 #endif
       
  2236 
       
  2237 
       
  2238 RBusDevComm& CHWPort::DTEPort()
       
  2239 /**
       
  2240  * return the handle to the logical DTE port
       
  2241  */
       
  2242 	{
       
  2243 	return iPort;
       
  2244 	}
       
  2245 
       
  2246 
       
  2247 RBusDevCommDCE& CHWPort::DCEPort()
       
  2248 /**
       
  2249  * return the handle to the logical DCE port
       
  2250  */
       
  2251 	{
       
  2252 	return iPortDCE;
       
  2253 	}
       
  2254 
       
  2255 
       
  2256 //
       
  2257 // todo implement this - for further improvements
       
  2258 //
       
  2259 #if 0
       
  2260 RBusWhatever& CHWPort::Port()
       
  2261 /**
       
  2262  * return a handle to our port
       
  2263  */
       
  2264 	{
       
  2265 	if (iRole==ECommRoleDTE)
       
  2266 		return iPort;
       
  2267 	else
       
  2268 		return iPortDCE;
       
  2269 	}
       
  2270 #endif
       
  2271 
       
  2272 
       
  2273 //
       
  2274 // implementation of CHWPortFactory
       
  2275 //
       
  2276 
       
  2277 
       
  2278 CHWPortFactory::CHWPortFactory()
       
  2279 /**
       
  2280  * C'tor
       
  2281  */
       
  2282 	{
       
  2283 	TName name(SERIAL_NAME);
       
  2284 	SetName(&name); // todo check return value?
       
  2285 	iVersion = TVersion(KEC32MajorVersionNumber, KEC32MinorVersionNumber, KEC32BuildVersionNumber);
       
  2286 	}
       
  2287 
       
  2288 
       
  2289 CPort* CHWPortFactory::NewPortL(const TUint aUnit)
       
  2290 /**
       
  2291  * Create a new port for the supplied unit number
       
  2292  *
       
  2293  * @param aUnit port unit number (i.e. 0 for COMM::0)
       
  2294  */
       
  2295 	{
       
  2296 	LOGECUART2(_L8("CHWPortFactory::NewPortL(), aUnit = %d"), aUnit);
       
  2297 //	__ASSERT_ALWAYS(aUnit>=KCommLowUnit,User::Leave(KErrNotSupported));
       
  2298 //	__ASSERT_ALWAYS(aUnit<=KCommHighUnit,User::Leave(KErrNotSupported));
       
  2299 	return (CPort *)CHWPort::NewL(aUnit);
       
  2300 	}
       
  2301 
       
  2302 
       
  2303 void CHWPortFactory::Info(TSerialInfo& aSerialInfo)
       
  2304 /**
       
  2305  * get info about this CSY, fill in the supplied structure.
       
  2306  *
       
  2307  * @param aSerialInfo where info will be written to
       
  2308  */
       
  2309 	{
       
  2310 	aSerialInfo.iDescription = KSerialDescription;
       
  2311 	aSerialInfo.iName = SERIAL_NAME;
       
  2312 	aSerialInfo.iLowUnit = KCommLowUnit;
       
  2313 	aSerialInfo.iHighUnit = KCommHighUnit;
       
  2314 	}
       
  2315 
       
  2316 /**
       
  2317 Returns capabilities for requested port
       
  2318 */
       
  2319 TSecurityPolicy CHWPortFactory::PortPlatSecCapability(TUint aPort) const
       
  2320 	{
       
  2321 	LOGECUART2(_L8("CHWPortFactory::PortPlatSecCapability(), aPort = %d"), aPort);
       
  2322 	TSecurityPolicy csySecurityPolicy(KDefaultPortPassPolicy);
       
  2323 
       
  2324 	if(aPort >= (TUint)KMaxUnits)	//if greater than KMaxUnits it is an invalid port so fail.
       
  2325 		{
       
  2326 		csySecurityPolicy = KPortAlwaysFailPolicy;
       
  2327 		}
       
  2328 	else //see if it is defined in explicit policy list.
       
  2329 		{
       
  2330 		for(int i = 0;i < KExplicitPortPoliciesCount; i++)
       
  2331 			{
       
  2332 			// coverity [dead_error_line] : KExplicitPortPoliciesCount is currently 0, but this could change.
       
  2333 			if(aPort == KExplicitPortSecurityPolicies[i].iPort)
       
  2334 				{
       
  2335 				csySecurityPolicy = KExplicitPortSecurityPolicies[i].iPolicy;
       
  2336 				break;
       
  2337 				}
       
  2338 			}
       
  2339 		}
       
  2340 	return csySecurityPolicy;
       
  2341 	}
       
  2342 
       
  2343 extern "C"
       
  2344 	{
       
  2345 	IMPORT_C CSerial* LibEntry(void);   // Force export
       
  2346 	};
       
  2347 
       
  2348 
       
  2349 EXPORT_C CSerial* LibEntry()
       
  2350 /**
       
  2351  * Lib main entry point
       
  2352  */
       
  2353 	{
       
  2354 	LOGECUART1(_L8("LibEntry()"));
       
  2355 	return new CHWPortFactory;
       
  2356 	}
       
  2357 
       
  2358 
       
  2359 #if defined(_DEBUG_CONSOLE_)
       
  2360 
       
  2361 RDebugConsole::RDebugConsole()
       
  2362 	{
       
  2363 	Create();
       
  2364 	Set(_L(""),TSize(64,15));
       
  2365 
       
  2366 	}
       
  2367 
       
  2368 void RDebugConsole::Printf(TRefByValue<const TDesC> aFmt,...)
       
  2369 //
       
  2370 // Print to a console screen.
       
  2371 //
       
  2372 	{
       
  2373 
       
  2374 	VA_LIST list;
       
  2375 	VA_START(list,aFmt);
       
  2376 	TBuf<0x100> aBuf;
       
  2377 	aBuf.AppendFormatList(aFmt,list);
       
  2378 	Write(aBuf);
       
  2379 	}
       
  2380 #endif
       
  2381 
       
  2382 #if defined (_DEBUG_DEVCOMM) && defined (_DEBUG_CONSOLE_)
       
  2383 CCommDebugDumper* CCommDebugDumper::NewL(RDebugConsole &aConsole)
       
  2384 	{
       
  2385 	CCommDebugDumper* p=new CCommDebugDumper(aConsole);
       
  2386 	return p;
       
  2387 	}
       
  2388 
       
  2389 CCommDebugDumper::CCommDebugDumper(RDebugConsole &aConsole)
       
  2390 	:CActive(EPriorityStandard)
       
  2391 	{
       
  2392 	iRole=ECommRoleDTE;
       
  2393 	iConsole=&aConsole;
       
  2394 	CActiveScheduler::Add(this);
       
  2395 	SetActive();
       
  2396 	iConsole->Read(iKeystroke,iStatus);
       
  2397 	};
       
  2398 
       
  2399 CCommDebugDumper::~CCommDebugDumper()
       
  2400 	{
       
  2401 	Cancel();
       
  2402 	}
       
  2403 
       
  2404 void CCommDebugDumper::RunL()
       
  2405 	{
       
  2406 	TInt key=iKeystroke.Code();
       
  2407 	switch(key)
       
  2408 		{
       
  2409 		case 'd':
       
  2410 		case 'D':
       
  2411 			{
       
  2412 			TCommDebugInfoPckg d;
       
  2413 			if (iRole==ECommRoleDTE)
       
  2414 				iParent->DTEPort().DebugInfo(d);
       
  2415 			else
       
  2416 				iParent->DCEPort().DebugInfo(d);
       
  2417 			TCommDebugInfo& debug=d();
       
  2418 			iConsole->Printf(_L("rxbusy  : 0x%04x, rxHeld   : 0x%04x, \n\r"),debug.iRxBusy,debug.iRxHeld);
       
  2419 			iConsole->Printf(_L("txbusy  : 0x%04x, txHeld   : 0x%04x, \n\r"),debug.iTxBusy,debug.iTxHeld);
       
  2420 			iConsole->Printf(_L("drainRx : 0x%04x, fillTx   : 0x%04x\n\r"),debug.iDrainingRxBuf,debug.iFillingTxBuf);
       
  2421 			iConsole->Printf(_L("Txonchar: 0x%04x, TxOffchar: 0x%04x\n\r"),debug.iTxXon,debug.iTxXoff);
       
  2422 			iConsole->Printf(_L("RxonChar: 0x%04x, RxOffchar: 0x%04x\n\r"),debug.iRxXon,debug.iRxXoff);
       
  2423 			iConsole->Printf(_L("NumTX   : 0x%04x, NumRx    : 0x%04x\n\r"),debug.iTxChars,debug.iRxChars);
       
  2424 			iConsole->Printf(_L("TxLen   : 0x%04x, RxLen    : 0x%04x\n\r"),debug.iTxLength,debug.iRxLength);
       
  2425 			iConsole->Printf(_L("TxOffset: 0x%04x, RxOffset : 0x%04x\n\r"),debug.iTxOffset,debug.iRxOffset);
       
  2426 			iConsole->Printf(_L("TxInts  : 0x%04x, RxInts   : 0x%04x\n\r"),debug.iTxIntCount,debug.iRxIntCount);
       
  2427 			}
       
  2428 			break;
       
  2429 		case 's':
       
  2430 		case 'S':
       
  2431 			{
       
  2432 			TUint signals=0;
       
  2433 			if (iRole==ECommRoleDTE)
       
  2434 				signals=iParent->DTEPort().Signals();
       
  2435 			else
       
  2436 				signals=iParent->DCEPort().Signals();
       
  2437 			iConsole->Printf(_L("Signals: "));
       
  2438 			if (signals&KSignalCTS)
       
  2439 				iConsole->Printf(_L("CTS "));
       
  2440 			if (signals&KSignalDSR)
       
  2441 				iConsole->Printf(_L("DSR "));
       
  2442 			if (signals&KSignalDCD)
       
  2443 				iConsole->Printf(_L("DCD "));
       
  2444 			if (signals&KSignalRTS)
       
  2445 				iConsole->Printf(_L("RTS "));
       
  2446 			if (signals&KSignalDTR)
       
  2447 				iConsole->Printf(_L("DTR "));
       
  2448 			iConsole->Printf(_L("\n\r"));
       
  2449 			}
       
  2450 			break;
       
  2451 		default:
       
  2452 			break;
       
  2453 		}
       
  2454 
       
  2455 	SetActive();
       
  2456 	iConsole->Read(iKeystroke,iStatus);
       
  2457 	};
       
  2458 
       
  2459 void CCommDebugDumper::DoCancel()
       
  2460 	{
       
  2461 	iConsole->ReadCancel();
       
  2462 	}
       
  2463 
       
  2464 #endif
       
  2465 
       
  2466 // EOF - ECUART.CPP