cbsref/csyrefplugins/csy27010/src/CommFrameReaderAo.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 class CCommFrameReaderAo.
       
    15 // *               Class CCommFrameReaderAo is used to request a read from the serial port LDD.
       
    16 // *               Class CommFrameReaderAo is an active object and is run by the active
       
    17 // *               scheduler when the LDD has completed the read request.
       
    18 //
       
    19 
       
    20 // CommFrameReaderAo.cpp
       
    21 
       
    22 /** @file CommFrameReaderAo.cpp
       
    23  *
       
    24  * The file contains the implementation for class CCommFrameReaderAo.
       
    25  * Class CCommFrameReaderAo is used to request a read from the serial port LDD.
       
    26  * Class CommFrameReaderAo is an active object and is run by the active
       
    27  * scheduler when the LDD has completed the read request
       
    28  */
       
    29 
       
    30 // Need to add code to package together a frame and then send the
       
    31 // complete frame to the Mux object for defragmentation into a client msg.
       
    32 
       
    33 #include "CommFrameReaderAo.h"
       
    34 #include "Portfactory.h"
       
    35 #include "CsyMsgBufBPFrame.h"
       
    36 #include "Mux0710Protocol.h"
       
    37 #include "CsyDebugLogger.h"
       
    38 #include "ChannelMgrCtrl.h"
       
    39 #include "ChannelMgrCmdData.h"
       
    40 
       
    41 CCommFrameReaderAo* CCommFrameReaderAo::NewL(CPortFactory* aParent, CMux0710Protocol* aMux0710Protocol)
       
    42 /**
       
    43  * This methods uses two phase construction and the cleanup stack to create
       
    44  * an instance of class CCommFrameReaderAo.
       
    45  * @param aParent - Pointer to parent
       
    46  * @param aMux0710Protocol - Pointer to Mux 27.010 object
       
    47  * @return Pointer to the created instance
       
    48  */
       
    49 	{
       
    50 	_LOG_L4C1("CCommFrameReaderAo::NewL");
       
    51 
       
    52 	CCommFrameReaderAo* c = new (ELeave) CCommFrameReaderAo(aParent, aMux0710Protocol);
       
    53 	CleanupStack::PushL(c);
       
    54 	c->ConstructL();
       
    55 	CleanupStack::Pop();
       
    56 	return c;
       
    57 	}
       
    58 
       
    59 CCommFrameReaderAo::~CCommFrameReaderAo()
       
    60 /**
       
    61  * Destructor. Cancel any outstanding request.
       
    62  */
       
    63 	{
       
    64 	_LOG_L4C1("CCommFrameReaderAo::~CCommFrameReaderAo");
       
    65 	Cancel();
       
    66 	}
       
    67 
       
    68 CCommFrameReaderAo::CCommFrameReaderAo(CPortFactory* aParent, CMux0710Protocol* aMux0710Protocol)
       
    69 /**
       
    70  * Constructor.  Pass priority of active object to base class.
       
    71  * @param aParent - Pointer to parent
       
    72  * @param aMux0710Protocol - Pointer to Mux 27.010 object
       
    73  */
       
    74 : CCommReadWriteBaseAo(aParent, aMux0710Protocol, KFrameReaderAoPriority),
       
    75   iFrameReaderState(ECsyWaitingForStartFlag)
       
    76 	{
       
    77 	}
       
    78 
       
    79 void CCommFrameReaderAo::ConstructL()
       
    80 /**
       
    81  * Retrieve a pointer to the LDD comm port.
       
    82  */
       
    83     {
       
    84 	_LOG_L4C1("CCommFrameReaderAo::ConstructL");
       
    85 	SetBuffersL();
       
    86 	}
       
    87 
       
    88 void CCommFrameReaderAo::DoCancel()
       
    89 /**
       
    90  * Cancel an outstanding request.
       
    91  * @param void
       
    92  */
       
    93 	{
       
    94 	_LOG_L4C1("CCommFrameReaderAo::DoCancel");
       
    95 
       
    96 	iCommPort->ReadCancel();
       
    97 	}
       
    98 
       
    99 void CCommFrameReaderAo::BasicOption()
       
   100 /**
       
   101  * Basic option frames
       
   102  * Note this has not been tested since DSample/P2 do not use basic option
       
   103  */
       
   104 	{
       
   105 	TUint octet;
       
   106 	TBool frameData = EFalse;
       
   107 
       
   108 	TInt len = iBuf->Length();
       
   109 	TPtr8 ptr = iBuffer->Des();
       
   110 	_LOG_L3C2("Received %d bytes",len);
       
   111 
       
   112 	for (TInt loop = 0; loop < len; loop++)
       
   113 		{
       
   114 		octet = ptr[loop];
       
   115 
       
   116 		if (octet == KCsy0710StartEndFlag)
       
   117 			{
       
   118 			// Control bit
       
   119 			switch(iFrameReaderState)
       
   120 				{
       
   121 			case ECsyWaitingForStartFlag:
       
   122 				{
       
   123 				_LOG_L3C2("[0x%02x] Got start flag",octet);
       
   124 				iFrameReaderState = ECsyWaitingForFrameStart;
       
   125 
       
   126 				if (iFrameBuf == NULL)
       
   127 					{
       
   128 					// There is data to process - get a new frame
       
   129 					iFrameBuf = iMux0710Protocol->GetFreeFrameBuf();
       
   130 					if (iFrameBuf == NULL)
       
   131 						{
       
   132 						_LOG_L1C1("** No free frame buffer ** - ignoring frame");
       
   133 						break;
       
   134 						}
       
   135 					}
       
   136 				}
       
   137 				break;
       
   138 			case ECsyWaitingForFrameStart:
       
   139 				{
       
   140 				// disregard additional flag
       
   141 				}
       
   142 				break;
       
   143 			case ECsyWaitingForFrameData:
       
   144 				{
       
   145 				iFrameReaderState = ECsyWaitingForStartFlag;
       
   146 
       
   147 				// must be the end flag
       
   148 				_LOG_L3C2("[0x%02x] End of frame",octet);
       
   149 				if (iFrameBuf)
       
   150 					{
       
   151 					if(iFrameBuf->iMsg.Length())
       
   152 						{
       
   153 						// Frame holds something
       
   154 						AddToReceivedFramesList(iFrameBuf);
       
   155 						iFrameBuf = NULL;
       
   156 						}
       
   157 					else
       
   158 						{
       
   159 						_LOG_L1C1("** zero length frame **");
       
   160 						// MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState));
       
   161 						}
       
   162 					}
       
   163 				else
       
   164 					{
       
   165 					_LOG_L3C1("** no frame buffer! **");
       
   166 					}
       
   167 				}
       
   168 				break;
       
   169 			default:
       
   170 				// MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState));
       
   171 				_LOG_L1C2("** unexpected flag ** [iFrameReaderState=%d]",iFrameReaderState);
       
   172 				break;
       
   173 				}
       
   174 			}
       
   175 		else
       
   176 			{
       
   177 			if (iFrameReaderState == ECsyWaitingForFrameStart)
       
   178 				{
       
   179 				iFrameReaderState = ECsyWaitingForFrameData;
       
   180 				iFrameBuf->iMsg.Append(octet);
       
   181 				
       
   182 				#ifdef _DEBUG
       
   183 				// This variable should only be set if it debug
       
   184 				// Otherwise we get warnings when compiling with ARM v5
       
   185 				TUint dlcNum = octet >> 2;
       
   186 				#endif
       
   187 
       
   188 				_LOG_L3C3E("[0x%02x] dlcNum=%d", octet, dlcNum);
       
   189 				}
       
   190 			else
       
   191 				{
       
   192 				_LOG_L3C2("[0x%02x]",octet);
       
   193 				frameData = ETrue;
       
   194 				}
       
   195 			}
       
   196 
       
   197 		if (frameData)
       
   198 			{
       
   199 			// MAF __ASSERT_DEBUG((iFrameReaderState == ECsyWaitingForFrameData),PANIC(KPanicIllegalState));
       
   200 
       
   201 			TUint frameLen = (TUint) (iFrameBuf->iMsg.Length() + 1);
       
   202 			if (frameLen > KMaxAdvFrameSize)
       
   203 				{
       
   204 				_LOG_L1C3("** length %d will exceed max length %d **",
       
   205 					frameLen,KMaxFrameSize);
       
   206 				iFrameBuf->iMsg.Zero();		
       
   207 				iFrameReaderState = ECsyWaitingForStartFlag;
       
   208 				break;
       
   209 				}
       
   210 
       
   211 			frameData = EFalse;
       
   212 			iFrameBuf->iMsg.Append(octet);
       
   213 			}
       
   214 		}
       
   215 	}
       
   216 
       
   217 void CCommFrameReaderAo::AdvancedOption()
       
   218 /**
       
   219  * Advanced option frames
       
   220  */
       
   221 	{
       
   222 	TUint octet = 0;
       
   223 	TBool frameData = EFalse;
       
   224 
       
   225 	TInt len = iBuf->Length();
       
   226 	TPtr8 ptr = iBuffer->Des();
       
   227 	_LOG_L3C2("Received %d bytes",len);
       
   228 
       
   229 	TInt startVal = 0;
       
   230 
       
   231 	// Check processing (helps when we have lost sync with data due to read error)
       
   232 	if ((iFrameReaderState == ECsyWaitingForStartFlag)&&(len))
       
   233 		{
       
   234 		// We are on the hunt for the start flag
       
   235 		if (iESCRecved)
       
   236 			{
       
   237 			_LOG_L2C1("Escape flag set - ignore first octet");
       
   238 			iESCRecved = EFalse;
       
   239 			}
       
   240 		else
       
   241 			octet = ptr[0];
       
   242 
       
   243 		if (octet != KCsy0710StartEndFlag)
       
   244 			{
       
   245 			_LOG_L3C2("[0x%02x]",octet);
       
   246 			_LOG_L2C1("* Looking for the start flag *");
       
   247 			do
       
   248 				{
       
   249 				startVal++;
       
   250 				if (startVal == len)
       
   251 					break;
       
   252 
       
   253 				octet = ptr[startVal];
       
   254 
       
   255 				if (iESCRecved)
       
   256 					{
       
   257 					iESCRecved = EFalse;
       
   258 					continue;
       
   259 					}
       
   260 
       
   261 				if (octet == KCsy0710EscapeByte)
       
   262 					iESCRecved = ETrue;
       
   263 				}
       
   264 			while (octet != KCsy0710StartEndFlag);
       
   265 
       
   266 			_LOG_L2C2("Disregarded %d bytes",startVal);
       
   267 			}
       
   268 		}
       
   269 
       
   270 	// Do processing of the received buffer
       
   271 	for (TInt loop = startVal; loop < len; loop++)
       
   272 		{
       
   273 		octet = ptr[loop];
       
   274 
       
   275 		if (iESCRecved)
       
   276 			{
       
   277 			_LOG_L3C2("[0x%02x] - Recv ESC before, change this char",octet);
       
   278 			octet = (TUint8) (octet^(1<<5));
       
   279 			_LOG_L3C2("Changed to [0x%02x]",octet);
       
   280 			iESCRecved = EFalse;
       
   281 			frameData = ETrue;
       
   282 			}
       
   283 		else
       
   284 			{
       
   285 			if (octet == KCsy0710EscapeByte)
       
   286 				{
       
   287 				_LOG_L3C1("KCsy0710EscapeByte");
       
   288 				iESCRecved = ETrue;
       
   289 				}
       
   290 			else if (octet == KCsy0710StartEndFlag)
       
   291 				{
       
   292 				// Control bit
       
   293 				switch(iFrameReaderState)
       
   294 					{
       
   295 				case ECsyWaitingForFrameData:
       
   296 					{
       
   297 					iFrameReaderState = ECsyWaitingForStartFlag;
       
   298 					
       
   299 					if (iFrameBuf)
       
   300 						{
       
   301 						TInt frameLen = iFrameBuf->iMsg.Length();
       
   302 						if(frameLen > KAdvOptionHeaderSize)
       
   303 							{
       
   304 							TUint8 checkSum = iFrameBuf->iMsg[frameLen-1];
       
   305 							if (CheckFCS(iFrameBuf->iMsg,KAdvOptionHeaderSize,checkSum))
       
   306 								{
       
   307 								// must be the end flag
       
   308 								_LOG_L3C2("[0x%02x] End of frame",octet);
       
   309 								// Frame holds something
       
   310 								AddToReceivedFramesList(iFrameBuf);
       
   311 								iFrameBuf = NULL;
       
   312 								}
       
   313 							else
       
   314 								{
       
   315 								_LOG_L1C1("** checksum is incorrect - rejecting frame **");
       
   316 								iFrameBuf->iMsg.Zero();		
       
   317 								}
       
   318 							}
       
   319 						else
       
   320 							{
       
   321 							_LOG_L1C2("** Rejected incorrect length frame %d **",frameLen);
       
   322 							iFrameBuf->iMsg.Zero();		
       
   323 							}
       
   324 						}
       
   325 					else
       
   326 						{
       
   327 						_LOG_L3C1("** no frame buffer! **");
       
   328 						}
       
   329 
       
   330 					TInt check = loop+1;
       
   331 					if (check == len)
       
   332 						break;
       
   333 
       
   334 					// There are more bytes in this buffer to process
       
   335 					octet = ptr[check];
       
   336 					if (octet != KCsy0710StartEndFlag)
       
   337 						{
       
   338 						// Frames are back to back
       
   339 						_LOG_L2C1("* No start flag - assuming frames back to back *");
       
   340 						octet = KCsy0710StartEndFlag;
       
   341 						}
       
   342 					}
       
   343 					// deliberate fall through
       
   344 				case ECsyWaitingForStartFlag:
       
   345 					{
       
   346 					_LOG_L3C2("[0x%02x] Got start flag",octet);
       
   347 					iFrameReaderState = ECsyWaitingForFrameStart;
       
   348 
       
   349 					if (iFrameBuf == NULL)
       
   350 						{
       
   351 						// There is data to process - get a new frame
       
   352 						iFrameBuf = iMux0710Protocol->GetFreeFrameBuf();
       
   353 						if (iFrameBuf == NULL)
       
   354 							{
       
   355 							_LOG_L1C1("** No free frame buffer ** - ignoring frame");
       
   356 							// Note: GetFreeFrameBuf handles the flow control
       
   357 							break;
       
   358 							}
       
   359 						}
       
   360 					}
       
   361 					break;
       
   362 				case ECsyWaitingForFrameStart:
       
   363 					{
       
   364 					// disregard additional flag
       
   365 					}
       
   366 					break;
       
   367 				default:
       
   368 					_LOG_L1C2("** unexpected flag ** [iFrameReaderState=%d]",iFrameReaderState);
       
   369 					// MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState));
       
   370 					break;
       
   371 					}
       
   372 				}
       
   373 			else
       
   374 				{
       
   375 				if (iFrameReaderState == ECsyWaitingForFrameStart)
       
   376 					iFrameReaderState = ECsyWaitingForFrameData;
       
   377 
       
   378 				_LOG_L3C2("[0x%02x]",octet);
       
   379 				frameData = ETrue;
       
   380 				}
       
   381 			}
       
   382 
       
   383 		if (frameData)
       
   384 			{
       
   385 			frameData = EFalse;
       
   386 
       
   387 			// MAF __ASSERT_DEBUG((iFrameReaderState == ECsyWaitingForFrameData),PANIC(KPanicIllegalState));
       
   388 
       
   389 			if (iFrameBuf)
       
   390 				{
       
   391 				TUint frameLen = (TUint) (iFrameBuf->iMsg.Length() + 1);
       
   392 				if (frameLen > KMaxAdvFrameSize)
       
   393 					{
       
   394 					_LOG_L1C2("** length will exceed max length %d **",
       
   395 						KMaxFrameSize);
       
   396 					iFrameBuf->iMsg.Zero();		
       
   397 					iFrameReaderState = ECsyWaitingForStartFlag;
       
   398 					break;
       
   399 					}
       
   400 
       
   401 				iFrameBuf->iMsg.Append(octet);
       
   402 				}
       
   403 			else
       
   404 				{
       
   405 				// it should not be possible to enter this condition
       
   406 
       
   407 				_LOG_L1C2("** No frame buffer allocated for frame ** [iFrameReaderState=%d]",iFrameReaderState);
       
   408 				// MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState));
       
   409 				}
       
   410 			}
       
   411 		}
       
   412 	}
       
   413 
       
   414 void CCommFrameReaderAo::NonMuxed()
       
   415 	{
       
   416 	if (iMux0710Protocol->ParseATResponse(*iBuf) == KErrNone)
       
   417 		{
       
   418 		iFrameReaderState = ECsyWaitingForStartFlag;
       
   419 		_LOG_L3C1("ParseATResponse returned KErrNone");
       
   420 		}
       
   421 	}
       
   422 
       
   423 void CCommFrameReaderAo::RunL()
       
   424 /**
       
   425  * This method is invoked by the active scheduler when the read request
       
   426  * to the LDD has completed.
       
   427  */
       
   428     {
       
   429 	if (iStatus.Int())
       
   430 		{
       
   431 		_LOG_L3C1(" "); // please leave separator in
       
   432 		_LOG_L1C2("** CCommFrameReaderAo::RunL [iStatus %d] **",iStatus.Int());
       
   433 
       
   434 		// assumption here, whatever the error we will be able to repost
       
   435 		// another request to readoneormore from the serial device driver.
       
   436 
       
   437 		if (iFrameBuf)
       
   438 			{
       
   439 			iMux0710Protocol->AddFrameFreeQ(iFrameBuf);
       
   440 			iFrameBuf = NULL;
       
   441 			}
       
   442 
       
   443 		//reset state
       
   444 		iESCRecved = EFalse;
       
   445 		iFrameReaderState = ECsyWaitingForStartFlag;
       
   446 
       
   447 		iStatus = KRequestPending;
       
   448  		SetActive();
       
   449 		iCommPort->ReadOneOrMore(iStatus, *iBuf);
       
   450 		return;
       
   451 		}
       
   452 
       
   453 	if (iFrameBuf == NULL)
       
   454 		{
       
   455 		// Only show this log if start of a new frame
       
   456 		_LOG_L3C1(" "); // please leave separator in
       
   457 		_LOG_L3C1("CCommFrameReaderAo::RunL - start of read");
       
   458 		}
       
   459 
       
   460 	if (!iMux0710Protocol->IsMuxModeEnabled())
       
   461 		{
       
   462 		NonMuxed();
       
   463 		}
       
   464 	else
       
   465 		{
       
   466 		// mux mode is enabled
       
   467 		// process recv data according to our current state
       
   468 
       
   469 #ifndef _27010ADVANCEOPTION
       
   470 
       
   471 		BasicOption();
       
   472 
       
   473 #else
       
   474 		AdvancedOption();
       
   475 
       
   476 #endif
       
   477 		}
       
   478 
       
   479 	if (!IsActive())
       
   480 		{
       
   481 		iStatus = KRequestPending;
       
   482  		SetActive();
       
   483 		iCommPort->ReadOneOrMore(iStatus, *iBuf);
       
   484 		}
       
   485 	}
       
   486 
       
   487 void CCommFrameReaderAo::Read()
       
   488 /**
       
   489  * This method is called to start the process to read an ascii string
       
   490  * (e.g. response to initial AT+CMUX=0,0,5 command) or a frame from 
       
   491  * the serial port LDD. 
       
   492  * Note that this method will only be called once and then the RunL
       
   493  * will handle the reading of the comm port.
       
   494  */
       
   495 	{
       
   496 	_LOG_L4C1(">>CCommFrameReaderAo::Read");
       
   497 
       
   498 	if (!IsActive())
       
   499 		{
       
   500 		_LOG_L3C1("Read not active");
       
   501 
       
   502 		// Set the object active
       
   503 		iStatus = KRequestPending;
       
   504  		SetActive();
       
   505 		iCommPort->ReadOneOrMore(iStatus, *iBuf);
       
   506 		}
       
   507 	else
       
   508 		{
       
   509 		_LOG_L2C1("** Already active **");
       
   510 		}
       
   511 
       
   512 	_LOG_L4C1("<<CCommFrameReaderAo::Read");
       
   513     }
       
   514 
       
   515 void CCommFrameReaderAo::ReadCancel()
       
   516 /**
       
   517  * Cancel a read request.
       
   518  */
       
   519 	{
       
   520 	_LOG_L4C1(">>CCommFrameReaderAo::ReadCancel");
       
   521 
       
   522 	iCommPort->ReadCancel();
       
   523 	if (iFrameBuf)
       
   524 		{
       
   525 		// return buffer to free frame queue
       
   526 		iMux0710Protocol->AddFrameFreeQ(iFrameBuf);
       
   527 		iFrameBuf = NULL;
       
   528 		}
       
   529 
       
   530 	_LOG_L4C1("<<CCommFrameReaderAo::ReadCancel");
       
   531 	}
       
   532 
       
   533 TBool CCommFrameReaderAo::CheckFCS(TDes8& aBuffer, TInt aLen, TUint8 aSuppliedChecksum)
       
   534 /**
       
   535  * This method checks the checksum for the specified buffer with the 
       
   536  * specified length.
       
   537  *
       
   538  * @param aBuffer - Data 
       
   539  * @param aLen    - Number of bytes in the Buffer for which CheckSum to be calculated
       
   540  * @return ETrue if checksum is okay
       
   541  */
       
   542 	{
       
   543 	TUint8 frameCheckSum = 0xFF;
       
   544 
       
   545 	for (TInt i=0; i < aLen; i++)
       
   546 		{
       
   547 		frameCheckSum = crctable[(frameCheckSum ^ aBuffer[i])];
       
   548 		}
       
   549 
       
   550 	// One's Complement
       
   551 	frameCheckSum = crctable[(frameCheckSum ^ aSuppliedChecksum)];
       
   552 
       
   553 	if (frameCheckSum == 0xCF)
       
   554 		return ETrue;
       
   555 
       
   556 	return EFalse;
       
   557 	}
       
   558 
       
   559 void CCommFrameReaderAo::AddToReceivedFramesList(CCsyMsgBufBpFrame* aBpFrame)
       
   560 /**
       
   561  * This method is called by the comm frame reader to add the specified
       
   562  * received frame to a c32 port interface queue. The specific C32 port 
       
   563  * interface object is determined from the DLC number embedded in the frame.
       
   564  *
       
   565  * @param aBpFrame - Pointer to the received frame
       
   566  */
       
   567 	{
       
   568 	_LOG_L4C1(">>CCommFrameReaderAo::AddToReceivedFramesList");
       
   569 
       
   570 	TUint8 dlcNum = aBpFrame->GetDlcNum();
       
   571 
       
   572 	_LOG_L4C2("dlcNum=%d", dlcNum);
       
   573 	_LOG_L4C2("frameType=0x%x", aBpFrame->GetFrameType());
       
   574 
       
   575 	// check for a message for the control channel
       
   576 	if (dlcNum == 0)
       
   577 		{
       
   578 		iParent->GetControlChannel()->ProcessRecvFrame(aBpFrame);
       
   579 		}
       
   580 	else
       
   581 		{
       
   582 		CChannelMgrCmdData* channel = iParent->FindChannelMgrByDlcNum(dlcNum);
       
   583 		if (channel != NULL)
       
   584 			channel->ProcessRecvFrame(aBpFrame);
       
   585 		else
       
   586 			{
       
   587 			_LOG_L1C2("** No port defined for dlcNum=%d **", dlcNum);
       
   588 			iMux0710Protocol->AddFrameFreeQ(aBpFrame);
       
   589 			}
       
   590 		}
       
   591 
       
   592 	_LOG_L4C1("<<CCommFrameReaderAo::AddToReceivedFramesList");
       
   593 	}
       
   594