diff -r 14460bf2a402 -r f50f4094acd7 cbsref/csyrefplugins/csy27010/src/CommFrameReaderAo.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cbsref/csyrefplugins/csy27010/src/CommFrameReaderAo.cpp Tue Jul 06 15:36:38 2010 +0300 @@ -0,0 +1,594 @@ +// +// * Copyright 2004 Neusoft America Inc. +// * All rights reserved. +// * This component and the accompanying materials are made available +// * under the terms of the Eclipse Public License v1.0 +// * which accompanies this distribution, and is available +// * at the URL "http://www.eclipse.org/legal/epl-v10.html". +// * +// * Contributors: +// * Keith Collins (Neusoft America Inc.) original software development and additional code and modifications. +// * Thomas Gahagen (Neusoft America Inc.) additional code and modifications. +// * Zhen Yuan (Neusoft America Inc.) additional code and modifications. +// * +// * Description: This file contains the implementation for class CCommFrameReaderAo. +// * Class CCommFrameReaderAo is used to request a read from the serial port LDD. +// * Class CommFrameReaderAo is an active object and is run by the active +// * scheduler when the LDD has completed the read request. +// + +// CommFrameReaderAo.cpp + +/** @file CommFrameReaderAo.cpp + * + * The file contains the implementation for class CCommFrameReaderAo. + * Class CCommFrameReaderAo is used to request a read from the serial port LDD. + * Class CommFrameReaderAo is an active object and is run by the active + * scheduler when the LDD has completed the read request + */ + +// Need to add code to package together a frame and then send the +// complete frame to the Mux object for defragmentation into a client msg. + +#include "CommFrameReaderAo.h" +#include "Portfactory.h" +#include "CsyMsgBufBPFrame.h" +#include "Mux0710Protocol.h" +#include "CsyDebugLogger.h" +#include "ChannelMgrCtrl.h" +#include "ChannelMgrCmdData.h" + +CCommFrameReaderAo* CCommFrameReaderAo::NewL(CPortFactory* aParent, CMux0710Protocol* aMux0710Protocol) +/** + * This methods uses two phase construction and the cleanup stack to create + * an instance of class CCommFrameReaderAo. + * @param aParent - Pointer to parent + * @param aMux0710Protocol - Pointer to Mux 27.010 object + * @return Pointer to the created instance + */ + { + _LOG_L4C1("CCommFrameReaderAo::NewL"); + + CCommFrameReaderAo* c = new (ELeave) CCommFrameReaderAo(aParent, aMux0710Protocol); + CleanupStack::PushL(c); + c->ConstructL(); + CleanupStack::Pop(); + return c; + } + +CCommFrameReaderAo::~CCommFrameReaderAo() +/** + * Destructor. Cancel any outstanding request. + */ + { + _LOG_L4C1("CCommFrameReaderAo::~CCommFrameReaderAo"); + Cancel(); + } + +CCommFrameReaderAo::CCommFrameReaderAo(CPortFactory* aParent, CMux0710Protocol* aMux0710Protocol) +/** + * Constructor. Pass priority of active object to base class. + * @param aParent - Pointer to parent + * @param aMux0710Protocol - Pointer to Mux 27.010 object + */ +: CCommReadWriteBaseAo(aParent, aMux0710Protocol, KFrameReaderAoPriority), + iFrameReaderState(ECsyWaitingForStartFlag) + { + } + +void CCommFrameReaderAo::ConstructL() +/** + * Retrieve a pointer to the LDD comm port. + */ + { + _LOG_L4C1("CCommFrameReaderAo::ConstructL"); + SetBuffersL(); + } + +void CCommFrameReaderAo::DoCancel() +/** + * Cancel an outstanding request. + * @param void + */ + { + _LOG_L4C1("CCommFrameReaderAo::DoCancel"); + + iCommPort->ReadCancel(); + } + +void CCommFrameReaderAo::BasicOption() +/** + * Basic option frames + * Note this has not been tested since DSample/P2 do not use basic option + */ + { + TUint octet; + TBool frameData = EFalse; + + TInt len = iBuf->Length(); + TPtr8 ptr = iBuffer->Des(); + _LOG_L3C2("Received %d bytes",len); + + for (TInt loop = 0; loop < len; loop++) + { + octet = ptr[loop]; + + if (octet == KCsy0710StartEndFlag) + { + // Control bit + switch(iFrameReaderState) + { + case ECsyWaitingForStartFlag: + { + _LOG_L3C2("[0x%02x] Got start flag",octet); + iFrameReaderState = ECsyWaitingForFrameStart; + + if (iFrameBuf == NULL) + { + // There is data to process - get a new frame + iFrameBuf = iMux0710Protocol->GetFreeFrameBuf(); + if (iFrameBuf == NULL) + { + _LOG_L1C1("** No free frame buffer ** - ignoring frame"); + break; + } + } + } + break; + case ECsyWaitingForFrameStart: + { + // disregard additional flag + } + break; + case ECsyWaitingForFrameData: + { + iFrameReaderState = ECsyWaitingForStartFlag; + + // must be the end flag + _LOG_L3C2("[0x%02x] End of frame",octet); + if (iFrameBuf) + { + if(iFrameBuf->iMsg.Length()) + { + // Frame holds something + AddToReceivedFramesList(iFrameBuf); + iFrameBuf = NULL; + } + else + { + _LOG_L1C1("** zero length frame **"); + // MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState)); + } + } + else + { + _LOG_L3C1("** no frame buffer! **"); + } + } + break; + default: + // MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState)); + _LOG_L1C2("** unexpected flag ** [iFrameReaderState=%d]",iFrameReaderState); + break; + } + } + else + { + if (iFrameReaderState == ECsyWaitingForFrameStart) + { + iFrameReaderState = ECsyWaitingForFrameData; + iFrameBuf->iMsg.Append(octet); + + #ifdef _DEBUG + // This variable should only be set if it debug + // Otherwise we get warnings when compiling with ARM v5 + TUint dlcNum = octet >> 2; + #endif + + _LOG_L3C3E("[0x%02x] dlcNum=%d", octet, dlcNum); + } + else + { + _LOG_L3C2("[0x%02x]",octet); + frameData = ETrue; + } + } + + if (frameData) + { + // MAF __ASSERT_DEBUG((iFrameReaderState == ECsyWaitingForFrameData),PANIC(KPanicIllegalState)); + + TUint frameLen = (TUint) (iFrameBuf->iMsg.Length() + 1); + if (frameLen > KMaxAdvFrameSize) + { + _LOG_L1C3("** length %d will exceed max length %d **", + frameLen,KMaxFrameSize); + iFrameBuf->iMsg.Zero(); + iFrameReaderState = ECsyWaitingForStartFlag; + break; + } + + frameData = EFalse; + iFrameBuf->iMsg.Append(octet); + } + } + } + +void CCommFrameReaderAo::AdvancedOption() +/** + * Advanced option frames + */ + { + TUint octet = 0; + TBool frameData = EFalse; + + TInt len = iBuf->Length(); + TPtr8 ptr = iBuffer->Des(); + _LOG_L3C2("Received %d bytes",len); + + TInt startVal = 0; + + // Check processing (helps when we have lost sync with data due to read error) + if ((iFrameReaderState == ECsyWaitingForStartFlag)&&(len)) + { + // We are on the hunt for the start flag + if (iESCRecved) + { + _LOG_L2C1("Escape flag set - ignore first octet"); + iESCRecved = EFalse; + } + else + octet = ptr[0]; + + if (octet != KCsy0710StartEndFlag) + { + _LOG_L3C2("[0x%02x]",octet); + _LOG_L2C1("* Looking for the start flag *"); + do + { + startVal++; + if (startVal == len) + break; + + octet = ptr[startVal]; + + if (iESCRecved) + { + iESCRecved = EFalse; + continue; + } + + if (octet == KCsy0710EscapeByte) + iESCRecved = ETrue; + } + while (octet != KCsy0710StartEndFlag); + + _LOG_L2C2("Disregarded %d bytes",startVal); + } + } + + // Do processing of the received buffer + for (TInt loop = startVal; loop < len; loop++) + { + octet = ptr[loop]; + + if (iESCRecved) + { + _LOG_L3C2("[0x%02x] - Recv ESC before, change this char",octet); + octet = (TUint8) (octet^(1<<5)); + _LOG_L3C2("Changed to [0x%02x]",octet); + iESCRecved = EFalse; + frameData = ETrue; + } + else + { + if (octet == KCsy0710EscapeByte) + { + _LOG_L3C1("KCsy0710EscapeByte"); + iESCRecved = ETrue; + } + else if (octet == KCsy0710StartEndFlag) + { + // Control bit + switch(iFrameReaderState) + { + case ECsyWaitingForFrameData: + { + iFrameReaderState = ECsyWaitingForStartFlag; + + if (iFrameBuf) + { + TInt frameLen = iFrameBuf->iMsg.Length(); + if(frameLen > KAdvOptionHeaderSize) + { + TUint8 checkSum = iFrameBuf->iMsg[frameLen-1]; + if (CheckFCS(iFrameBuf->iMsg,KAdvOptionHeaderSize,checkSum)) + { + // must be the end flag + _LOG_L3C2("[0x%02x] End of frame",octet); + // Frame holds something + AddToReceivedFramesList(iFrameBuf); + iFrameBuf = NULL; + } + else + { + _LOG_L1C1("** checksum is incorrect - rejecting frame **"); + iFrameBuf->iMsg.Zero(); + } + } + else + { + _LOG_L1C2("** Rejected incorrect length frame %d **",frameLen); + iFrameBuf->iMsg.Zero(); + } + } + else + { + _LOG_L3C1("** no frame buffer! **"); + } + + TInt check = loop+1; + if (check == len) + break; + + // There are more bytes in this buffer to process + octet = ptr[check]; + if (octet != KCsy0710StartEndFlag) + { + // Frames are back to back + _LOG_L2C1("* No start flag - assuming frames back to back *"); + octet = KCsy0710StartEndFlag; + } + } + // deliberate fall through + case ECsyWaitingForStartFlag: + { + _LOG_L3C2("[0x%02x] Got start flag",octet); + iFrameReaderState = ECsyWaitingForFrameStart; + + if (iFrameBuf == NULL) + { + // There is data to process - get a new frame + iFrameBuf = iMux0710Protocol->GetFreeFrameBuf(); + if (iFrameBuf == NULL) + { + _LOG_L1C1("** No free frame buffer ** - ignoring frame"); + // Note: GetFreeFrameBuf handles the flow control + break; + } + } + } + break; + case ECsyWaitingForFrameStart: + { + // disregard additional flag + } + break; + default: + _LOG_L1C2("** unexpected flag ** [iFrameReaderState=%d]",iFrameReaderState); + // MAF __ASSERT_DEBUG(EFalse, PANIC(KPanicIllegalState)); + break; + } + } + else + { + if (iFrameReaderState == ECsyWaitingForFrameStart) + iFrameReaderState = ECsyWaitingForFrameData; + + _LOG_L3C2("[0x%02x]",octet); + frameData = ETrue; + } + } + + if (frameData) + { + frameData = EFalse; + + // MAF __ASSERT_DEBUG((iFrameReaderState == ECsyWaitingForFrameData),PANIC(KPanicIllegalState)); + + if (iFrameBuf) + { + TUint frameLen = (TUint) (iFrameBuf->iMsg.Length() + 1); + if (frameLen > KMaxAdvFrameSize) + { + _LOG_L1C2("** length will exceed max length %d **", + KMaxFrameSize); + iFrameBuf->iMsg.Zero(); + iFrameReaderState = ECsyWaitingForStartFlag; + break; + } + + iFrameBuf->iMsg.Append(octet); + } + else + { + // it should not be possible to enter this condition + + _LOG_L1C2("** No frame buffer allocated for frame ** [iFrameReaderState=%d]",iFrameReaderState); + // MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState)); + } + } + } + } + +void CCommFrameReaderAo::NonMuxed() + { + if (iMux0710Protocol->ParseATResponse(*iBuf) == KErrNone) + { + iFrameReaderState = ECsyWaitingForStartFlag; + _LOG_L3C1("ParseATResponse returned KErrNone"); + } + } + +void CCommFrameReaderAo::RunL() +/** + * This method is invoked by the active scheduler when the read request + * to the LDD has completed. + */ + { + if (iStatus.Int()) + { + _LOG_L3C1(" "); // please leave separator in + _LOG_L1C2("** CCommFrameReaderAo::RunL [iStatus %d] **",iStatus.Int()); + + // assumption here, whatever the error we will be able to repost + // another request to readoneormore from the serial device driver. + + if (iFrameBuf) + { + iMux0710Protocol->AddFrameFreeQ(iFrameBuf); + iFrameBuf = NULL; + } + + //reset state + iESCRecved = EFalse; + iFrameReaderState = ECsyWaitingForStartFlag; + + iStatus = KRequestPending; + SetActive(); + iCommPort->ReadOneOrMore(iStatus, *iBuf); + return; + } + + if (iFrameBuf == NULL) + { + // Only show this log if start of a new frame + _LOG_L3C1(" "); // please leave separator in + _LOG_L3C1("CCommFrameReaderAo::RunL - start of read"); + } + + if (!iMux0710Protocol->IsMuxModeEnabled()) + { + NonMuxed(); + } + else + { + // mux mode is enabled + // process recv data according to our current state + +#ifndef _27010ADVANCEOPTION + + BasicOption(); + +#else + AdvancedOption(); + +#endif + } + + if (!IsActive()) + { + iStatus = KRequestPending; + SetActive(); + iCommPort->ReadOneOrMore(iStatus, *iBuf); + } + } + +void CCommFrameReaderAo::Read() +/** + * This method is called to start the process to read an ascii string + * (e.g. response to initial AT+CMUX=0,0,5 command) or a frame from + * the serial port LDD. + * Note that this method will only be called once and then the RunL + * will handle the reading of the comm port. + */ + { + _LOG_L4C1(">>CCommFrameReaderAo::Read"); + + if (!IsActive()) + { + _LOG_L3C1("Read not active"); + + // Set the object active + iStatus = KRequestPending; + SetActive(); + iCommPort->ReadOneOrMore(iStatus, *iBuf); + } + else + { + _LOG_L2C1("** Already active **"); + } + + _LOG_L4C1("<>CCommFrameReaderAo::ReadCancel"); + + iCommPort->ReadCancel(); + if (iFrameBuf) + { + // return buffer to free frame queue + iMux0710Protocol->AddFrameFreeQ(iFrameBuf); + iFrameBuf = NULL; + } + + _LOG_L4C1("<>CCommFrameReaderAo::AddToReceivedFramesList"); + + TUint8 dlcNum = aBpFrame->GetDlcNum(); + + _LOG_L4C2("dlcNum=%d", dlcNum); + _LOG_L4C2("frameType=0x%x", aBpFrame->GetFrameType()); + + // check for a message for the control channel + if (dlcNum == 0) + { + iParent->GetControlChannel()->ProcessRecvFrame(aBpFrame); + } + else + { + CChannelMgrCmdData* channel = iParent->FindChannelMgrByDlcNum(dlcNum); + if (channel != NULL) + channel->ProcessRecvFrame(aBpFrame); + else + { + _LOG_L1C2("** No port defined for dlcNum=%d **", dlcNum); + iMux0710Protocol->AddFrameFreeQ(aBpFrame); + } + } + + _LOG_L4C1("<