cbsref/csyrefplugins/csy27010/src/PortC32Interface.cpp
changeset 49 f50f4094acd7
equal deleted inserted replaced
48:14460bf2a402 49:f50f4094acd7
       
     1 //
       
     2 // * Copyright 2004 Neusoft America Inc.
       
     3 // * All rights reserved.
       
     4 // * This component and the accompanying materials are made available
       
     5 // * under the terms of the Eclipse Public License v1.0
       
     6 // * which accompanies this distribution, and is available
       
     7 // * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // *
       
     9 // * Contributors:
       
    10 // * Keith Collins (Neusoft America Inc.)  original software development and additional code and modifications.
       
    11 // * Thomas Gahagen (Neusoft America Inc.)  additional code and modifications.
       
    12 // * Zhen Yuan (Neusoft America Inc.)  additional code and modifications.
       
    13 // *
       
    14 // * Description:  This file contains the implementation for the CPortC32Interface class.
       
    15 // *               This class contains methods which are invoked by C32 when the
       
    16 // *               associated client RComm public API is invoked. These methods
       
    17 // *               are used to create, configure, read, write, and close logical
       
    18 // *               serial ports. Instances of this class are created by the CSY's
       
    19 // *               Port Factory.
       
    20 //
       
    21 
       
    22 // PortC32Interface.cpp
       
    23 
       
    24 /** @file PortC32Interface.cpp
       
    25  *
       
    26  */
       
    27 
       
    28 #include <cdbcols.h>
       
    29 #include "PortC32Interface.h"
       
    30 #include "Portfactory.h"
       
    31 #include "Mux0710Protocol.h"
       
    32 #include "CsyMsgBufBPFrame.h"
       
    33 #include "ChannelMgrCmdData.h"
       
    34 #include "CommFrameReaderAo.h"
       
    35 #include "CsyDebugLogger.h"
       
    36 #include "CsyGlobals.h"
       
    37 #include "CommFrameWriterAo.h"
       
    38 
       
    39 CPortC32Interface* CPortC32Interface::NewL(CPortFactory& aPortFactory, 
       
    40 										   CPortFactory::TC32PortInfo& aPortInfo)
       
    41 /**
       
    42  * This method uses two phase construction and the cleanup stack to create
       
    43  * an instance of class CPortC32Interface.
       
    44  *
       
    45  * @param aPortFactory - Reference to the port factory
       
    46  * @param aPortInfo - Reference to the port information
       
    47  * @return Pointer to the created instance
       
    48  */
       
    49 	{
       
    50 	_LOG_L4C1( "CPortC32Interface::NewL");
       
    51 
       
    52 	CPortC32Interface* self = new(ELeave) CPortC32Interface(aPortFactory, aPortInfo);
       
    53 	TCleanupItem closeSelf(CPortFactory::CloseObject, self);
       
    54 	CleanupStack::PushL(closeSelf);
       
    55 	self->ConstructL();
       
    56 	CleanupStack::Pop(self);
       
    57 
       
    58 	return self;
       
    59 	}
       
    60 
       
    61 CPortC32Interface::~CPortC32Interface()
       
    62 /**
       
    63  * Destructor.
       
    64  */
       
    65 	{
       
    66 	_LOG_L4C1( ">>CPortC32Interface::~CPortC32Interface");
       
    67 
       
    68 	// let port factory know we are deleted
       
    69 	iPortFactory.RemoveC32Port(this);
       
    70 	CompleteOutstandingRequest();
       
    71 
       
    72 	iMuxChannel->Close(this);
       
    73 
       
    74 	if (iReadBuf)
       
    75 		{
       
    76 		_LOG_L3C1("Delete read buffer");
       
    77 		delete iReadBuf;
       
    78 		}
       
    79 
       
    80 	_LOG_L4C1( "<<CPortC32Interface::~CPortC32Interface");
       
    81 	}
       
    82 
       
    83 CPortC32Interface::CPortC32Interface(CPortFactory& aPortFactory,
       
    84 									 CPortFactory::TC32PortInfo& aPortInfo)
       
    85 /**
       
    86  * Constructor.
       
    87  *
       
    88  * @param aPortFactory - Reference to the port factory
       
    89  * @param aPortInfo - Reference to the port information
       
    90  */
       
    91 : CPortC32InterfaceBase(aPortFactory, aPortInfo)
       
    92 	{}
       
    93 
       
    94 void CPortC32Interface::ConstructL(void)
       
    95 /**
       
    96  * Safe constructor
       
    97  */
       
    98 	{
       
    99 	_LOG_L4C1( "CPortC32Interface::ConstructL");
       
   100 	CPortC32InterfaceBase::ConstructL();
       
   101 	}
       
   102 
       
   103 /********************************************************************************/
       
   104 /*               Start of utility methods for CPortC32InterfaceBase                 */
       
   105 /********************************************************************************/
       
   106 
       
   107 TInt CPortC32Interface::QueryReceiveBuffer(TInt& aLength) const
       
   108 /**
       
   109  * Called by C32 when the client queries the size of the receive buffer,
       
   110  * which returns the number of receive characters available to be read by
       
   111  * the C32 client RComm instance.
       
   112  *
       
   113  * @param aLength - Reference to client's buffer length variable
       
   114  * @return KErrNone
       
   115  */
       
   116 	{
       
   117 	_LOG_L4C2( "CPortC32Interface::QueryReceiveBuffer [port=%d]", GetPortNumber());
       
   118 
       
   119 	aLength = 0;
       
   120 	if (iReadBuf)
       
   121 		{
       
   122 		aLength = iReadBuf->iMsg.Length();
       
   123 		_LOG_L4C2("iReadBuf aLength=%d", aLength);
       
   124 		}
       
   125 	else if (!iFramesWaitingToBeReadList.IsEmpty())
       
   126 		{
       
   127 		CCsyMsgBufBpFrame* frame = iFramesWaitingToBeReadList.First();
       
   128 		if ((frame)&&(frame->iMsg.Length() >= (KAdvOptionHeaderSize + KChecksumSize)))
       
   129 			{
       
   130 #ifdef _27010ADVANCEOPTION
       
   131 			aLength = frame->iMsg.Length() - (KAdvOptionHeaderSize + KChecksumSize);
       
   132 #else
       
   133 			aLength = frame->iMsg.Length() - (KBasicOptionHeaderSize + KChecksumSize);
       
   134 #endif
       
   135 			_LOG_L4C2("iFramesWaitingToBeReadList aLength=%d", aLength);
       
   136 			}
       
   137 		}
       
   138 
       
   139 	return KErrNone;
       
   140 	}
       
   141 
       
   142 void CPortC32Interface::ResetBuffers(TUint aFlags)
       
   143 /**
       
   144  * Called by C32 when the client requests to reset the buffers,
       
   145  * by removing all receive and/or transmit messages according to
       
   146  * the specified flags.
       
   147  *
       
   148  * @param aFlags Indicate which buffers (receive and/or transmit) should be reset
       
   149  */
       
   150 	{
       
   151 	_LOG_L4C2(">>CPortC32Interface::ResetBuffers [aFlags=%d]", aFlags);
       
   152 	_LOG_L4C2("[port=%d]", GetPortNumber());
       
   153 
       
   154 	if (aFlags & KCommResetRx)
       
   155 		{
       
   156 		_LOG_L4C1("Removing all messages intended for the C32 client");
       
   157 
       
   158 		RemoveWaitingAllFrames();
       
   159 		}
       
   160 
       
   161 	if (aFlags & KCommResetTx)
       
   162 		{
       
   163 		_LOG_L4C1("Removing all messages intended for the modem");
       
   164 
       
   165 		GetMuxChannel()->WriteCancel();
       
   166 		}
       
   167 
       
   168 	_LOG_L4C1("<<CPortC32Interface::ResetBuffers");
       
   169 	}
       
   170 
       
   171 void CPortC32Interface::SendFrameToClient(CCsyMsgBufBpFrame* aFrame)
       
   172 /**
       
   173  * This method is called by a CSY Channel object when it has a single
       
   174  * frame to send to a C32 client RComm object.
       
   175  *
       
   176  * @param aFrame - Pointer to message to send to client
       
   177  */
       
   178 	{
       
   179 	_LOG_L4C2( "CPortC32Interface::SendFrameToClient [port=%d]", GetPortNumber());
       
   180 
       
   181 	if (aFrame)
       
   182 		{
       
   183 		// check if queue is empty
       
   184 		TBool trigger = iFramesWaitingToBeReadList.IsEmpty();
       
   185 
       
   186 		iFramesWaitingToBeReadList.AddLast(*aFrame);
       
   187 		if (trigger)
       
   188 			{
       
   189 			_LOG_L4C1("No packets already waiting");
       
   190 			if (iIsReadInProgress)
       
   191 				{
       
   192 				_LOG_L4C1("A read is outstanding");
       
   193 				ReadFromBufOrQueue();
       
   194 				}
       
   195 			}
       
   196 
       
   197 		// inform client new data is available
       
   198 		SetDataAvailable();
       
   199 		}
       
   200 	else
       
   201 		{
       
   202 		//MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState));
       
   203 		}
       
   204 	}
       
   205 
       
   206 TBool CPortC32Interface::ReadFromBufOrQueue()
       
   207 /**
       
   208  * This method is called to read from buffer or the frame list
       
   209  * It will read as much as possible.
       
   210  *
       
   211  * @return ETrue if complete the read request
       
   212  */
       
   213 	{
       
   214 	_LOG_L4C2( ">>CPortC32Interface::ReadFromBufOrQueue [port=%d]",GetPortNumber());
       
   215 
       
   216 	TBool completedTheReadRequest = EFalse;
       
   217 
       
   218 	TInt err = KErrGeneral;
       
   219 	TBool cont;
       
   220 	do
       
   221 		{
       
   222 		cont = EFalse;
       
   223 		if(iReadBuf==NULL)
       
   224 			{
       
   225 			//Read data from the frame list
       
   226 			if (!iFramesWaitingToBeReadList.IsEmpty())
       
   227 				{
       
   228 				_LOG_L4C1("Set to first item");
       
   229 				iReadBuf = iFramesWaitingToBeReadList.First();
       
   230 				if (iReadBuf)
       
   231 					{
       
   232 					_LOG_L4C1("iReadBuf not null");
       
   233 					// remove msg buf from client list
       
   234 					iFramesWaitingToBeReadList.Remove(*iReadBuf);
       
   235 
       
   236 					// subtract checksum field
       
   237 					TInt frameLength = iReadBuf->iMsg.Length();
       
   238 					_LOG_L4C2("New read buffer frameLength=%d",frameLength);
       
   239 
       
   240 					if (frameLength >= KBasicOptionHeaderSize)
       
   241 						{
       
   242 						iReadBuf->iMsg.SetLength(frameLength - KChecksumSize);
       
   243 
       
   244 						// remove leading header ints from frame
       
   245 #ifdef _27010ADVANCEOPTION
       
   246 						iReadBuf->iMsg.Delete(0, KAdvOptionHeaderSize);
       
   247 #else
       
   248 						iReadBuf->iMsg.Delete(0, KBasicOptionHeaderSize);
       
   249 #endif
       
   250 						}
       
   251 					else
       
   252 						{
       
   253 						_LOG_L4C1("Incorrect frame size - freeing read buffer");
       
   254 						iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(iReadBuf);
       
   255 						iReadBuf = NULL;
       
   256 						}
       
   257 					}
       
   258 				}
       
   259 			}
       
   260 		if (iReadBuf)
       
   261 			{
       
   262 			TInt length = -1;
       
   263 			if (iClientLength - iPos < iReadBuf->iMsg.Length())
       
   264 				{
       
   265 				length = iClientLength - iPos;
       
   266 				_LOG_L4C2("length = %d",length);
       
   267 				}
       
   268 
       
   269 			if (iConfig.iTerminatorCount > 0)
       
   270 				{
       
   271 				_LOG_L4C2("iTerminatorCount = %d",iConfig.iTerminatorCount);
       
   272 
       
   273 				// First find terminator
       
   274 				TInt terminatorLoc = -1;
       
   275 				TInt loc;
       
   276 				for (TInt i=0; i< iConfig.iTerminatorCount;i++)
       
   277 					{
       
   278 					loc = iReadBuf->iMsg.LocateF(iConfig.iTerminator[i]);
       
   279 					if (loc > KErrNotFound)
       
   280 						{
       
   281 						if (terminatorLoc == KErrNotFound)
       
   282 							{
       
   283 							terminatorLoc = loc;
       
   284 							}
       
   285 						else
       
   286 							{
       
   287 							terminatorLoc = Min(loc,terminatorLoc);
       
   288 							}
       
   289 						}
       
   290 					}
       
   291 				if (terminatorLoc>KErrNotFound)
       
   292 					{
       
   293 					if (length > KErrNotFound)
       
   294 						length = Min(terminatorLoc + 1,length);
       
   295 					else
       
   296 						length = terminatorLoc + 1;
       
   297 					}
       
   298 				_LOG_L4C2("length = %d",length);
       
   299 				}
       
   300 
       
   301 			_LOG_L4C2("Read buf length %d",iReadBuf->iMsg.Length());
       
   302 
       
   303 			if ((iReadBuf->iMsg.Length() >= length) && (length > -1))
       
   304 				{
       
   305 				_LOG_L2C2("complete partial read: # %d ", length);
       
   306 
       
   307 				iPartialReadBuf.Copy(&iReadBuf->iMsg[0], length);
       
   308 				iReadBuf->iMsg.Delete(0, length);
       
   309 
       
   310 				err = IPCWrite(iClientBuffer, iPartialReadBuf, iPos); 
       
   311 				if (err)
       
   312 					{
       
   313 					_LOG_L1C2("** IPCWrite Error %d **",err);
       
   314 					}
       
   315 
       
   316 				CompleteReadRequest(err);
       
   317 				err = KErrGeneral;
       
   318 
       
   319 				completedTheReadRequest = ETrue;
       
   320 				iPos = 0;
       
   321 
       
   322 				if (iReadBuf->iMsg.Length()==0)
       
   323 					{
       
   324 					_LOG_L4C1("All data used - freeing read buffer");
       
   325 					iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(iReadBuf);
       
   326 					iReadBuf = NULL;
       
   327 					}
       
   328 				}
       
   329 			else
       
   330 				{
       
   331 				err = IPCWrite(iClientBuffer, iReadBuf->iMsg, iPos);
       
   332 				if (err)
       
   333 					{
       
   334 					_LOG_L1C2("** IPCWrite Error %d **",err);
       
   335 					}
       
   336 
       
   337 				_LOG_L4C3( "Read: iPos = %d, add %d bytes", iPos, iReadBuf->iMsg.Length());
       
   338 
       
   339 				//try read next frame in the list
       
   340 				cont = ETrue; 
       
   341 				iPos += iReadBuf->iMsg.Length();
       
   342 
       
   343 				_LOG_L4C1("Freeing read buffer");
       
   344 				iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(iReadBuf);
       
   345 				iReadBuf = NULL;
       
   346 				}
       
   347 			}
       
   348 		}
       
   349 	while (cont);
       
   350 
       
   351 	if (iPos>0)
       
   352 		{
       
   353 		if (iOneOrMore)
       
   354 			{
       
   355 			CompleteReadRequest(err);
       
   356 			iPos = 0;
       
   357 			completedTheReadRequest = ETrue;
       
   358 			}
       
   359 		else 
       
   360 			{
       
   361 			//normal read and have not filled the buffer yet
       
   362 			_LOG_L4C3( "Not filled buffer yet iPos = %d, iClientLength = %d", iPos, iClientLength);
       
   363 			}
       
   364 		}
       
   365 
       
   366 	_LOG_L4C2( "<<CPortC32Interface::ReadFromBufOrQueue [completedTheReadRequest=%d]",completedTheReadRequest);
       
   367 	return completedTheReadRequest;
       
   368 	}