--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cbsref/csyrefplugins/csy27010/src/Mux0710Protocol.cpp Tue Jul 06 15:36:38 2010 +0300
@@ -0,0 +1,1034 @@
+//
+// * 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 the Mux0710Protocol class.
+//
+
+// Mux0710Protocol.cpp
+
+/** @file Mux0710Protocol.cpp
+ *
+ */
+
+#include "Mux0710Protocol.h"
+#include "Portfactory.h"
+#include "PortC32Interface.h"
+#include "CsyMsgBufBPFrame.h"
+#include "ChannelMgrCmdData.h"
+#include "CommFrameWriterAo.h"
+#include "CommFrameReaderAo.h"
+#include "ChannelMgrCtrl.h"
+#include "CsyDebugLogger.h"
+
+// AT Commands
+_LIT8(KATCmdAttention, "ATE0\r");
+_LIT8(KATCmdDisableEcho, "ATE0Q0V1\r");
+_LIT8(KATCmdReset, "AT%b\r");
+_LIT8(KATCmdSleep, "AT%SLEEP=0\r");
+
+const TInt KRetryCount = 2;
+
+CMux0710Protocol* CMux0710Protocol::NewL(CPortFactory& aPortFactory)
+/**
+ * This static method uses 2-phase construction to create an instance of
+ * this class.
+ *
+ * @return Pointer to the created object
+ */
+ {
+ _LOG_L4C1("CMux0710Protocol::NewL");
+
+ CMux0710Protocol* p = new(ELeave) CMux0710Protocol(aPortFactory);
+ CleanupStack::PushL(p);
+ p->ConstructL();
+ CleanupStack::Pop(p);
+ return p;
+ }
+
+CMux0710Protocol::~CMux0710Protocol()
+/**
+ * Destructor.
+ */
+ {
+ _LOG_L4C1("CMux0710Protocol::~CMux0710Protocol");
+
+ // Release Free Frame Memory
+ CCsyMsgBufBpFrame* aBpFrame;
+ iFreeFrameBufIter.SetToFirst();
+ while ((aBpFrame = iFreeFrameBufIter++) != NULL)
+ {
+ iFreeFrameBufList.Remove(*aBpFrame);
+ delete aBpFrame;
+ }
+
+ delete iTimeouter;
+ }
+
+CMux0710Protocol::CMux0710Protocol(CPortFactory& aPortFactory)
+/**
+ * Constructor.
+ *
+ */
+ : iPortFactory(aPortFactory),
+ iMuxMgrState(ECsyWaitingForFlushResp),
+ iFreeFrameBufList(_FOFF(CCsyMsgBufBpFrame, iMsgLink)),
+ iFreeFrameBufIter(iFreeFrameBufList),
+ iRetryCount(KRetryCount)
+ {}
+
+void CMux0710Protocol::ConstructL()
+/**
+ * Allocate the memory for the free frames list.
+ */
+ {
+ _LOG_L4C1("CMux0710Protocol::ConstructL");
+
+ iTimeouter = CActiveTimeouter::NewL(*this);
+
+ // allocate memory for the free frame buffer
+ for (TUint i=0; i < KMaxFreeFrames; i++)
+ {
+ CCsyMsgBufBpFrame* aBpFrame = CCsyMsgBufBpFrame::NewL();
+ iFreeFrameBufList.AddLast(*aBpFrame);
+ }
+ iFreeFrameCount = KMaxFreeFrames;
+ }
+
+CCsyMsgBufBpFrame* CMux0710Protocol::GetFreeFrameBuf(TBool aCheckFlowControlThresholds)
+/**
+ * Get a free frame buffer and then remove the buffer from
+ * the free list.
+ *
+ * @return - Pointer to a frame buffer or NULL
+ */
+ {
+ _LOG_L4C2(">>CMux0710Protocol::GetFreeFrameBuf [aCheckFlowControlThresholds=%d]",
+ aCheckFlowControlThresholds);
+
+ CCsyMsgBufBpFrame* frame = NULL;
+ if (!iFreeFrameBufList.IsEmpty())
+ {
+ frame = iFreeFrameBufList.First();
+ if (frame)
+ {
+ iFreeFrameBufList.Remove(*frame);
+ iFreeFrameCount--;
+ _LOG_L4C2("iFreeFrameCount=%d",iFreeFrameCount);
+
+ if ((aCheckFlowControlThresholds)&&(iFreeFrameCount < KStopDataDlcsThreshold))
+ {
+ // Need to enforce some flow control
+ iEnforcingFlowControl = ETrue;
+
+ if (iFreeFrameCount == 1)
+ {
+ // Only one frame free - that can be used to send the MSC command
+ _LOG_L4C1("Drastic action! - 1 frame free");
+ iPortFactory.StopAnyDlc();
+ }
+ else
+ {
+ _LOG_L4C2("Less than %d frames free",KStopDataDlcsThreshold);
+ iPortFactory.FindActiveDataDlcToStop();
+ }
+ }
+
+ frame->iMsg.Zero();
+ frame->MsgDlc() = KCtrlChannelDlcNum;
+ frame->CompleteWhenSent() = ETrue;
+ }
+ }
+
+ _LOG_L4C2("<<CMux0710Protocol::GetFreeFrameBuf [frame=0x%x]",frame);
+ return frame;
+ }
+
+void CMux0710Protocol::AddFrameFreeQ(CCsyMsgBufBpFrame* aBpFrame)
+/**
+ * This method is called to add the specified frame buffer to the
+ * free frame queue.
+ *
+ * @param aBpFrame - Pointer to the frame buffer
+ */
+ {
+ _LOG_L4C2(">>CMux0710Protocol::AddFrameFreeQ [aBpFrame=0x%x]",aBpFrame);
+
+ iFreeFrameBufList.AddLast(*aBpFrame);
+
+ if (iEnforcingFlowControl)
+ {
+ if (iFreeFrameCount >= KStartDataDlcsThreshold)
+ {
+ // Release flow control
+ _LOG_L4C2("More than %d frames free",
+ KStartDataDlcsThreshold);
+
+ // re-enable a data dlc (note only re-enable one dlc at a time)
+ iEnforcingFlowControl = iPortFactory.FindDlcToEnable();
+ _LOG_L4C2("iEnforcingFlowControl=%d",iEnforcingFlowControl);
+ }
+ }
+
+ iFreeFrameCount++;
+ //MAF __ASSERT_DEBUG((iFreeFrameCount <= KMaxFreeFrames),PANIC(KPanicIllegalState));
+
+ _LOG_L4C2("<<CMux0710Protocol::AddFrameFreeQ iFreeFrameCount=%d",
+ iFreeFrameCount);
+ }
+
+TUint8 CMux0710Protocol::CalcFCS(TUint8* aBuffer, TInt aLen)
+/**
+ * This method calculates the checkSum for the specified buffer
+ * with the specified length.
+ *
+ * @param aBuffer - Pointer to the data buffer
+ * @param aLen - Length of Number of bytes in the Buffer for which CheckSum to be calculated
+ * @return checksum
+ */
+ {
+ TUint8 frameCheckSum = 0xFF;
+ aBuffer++;
+ for (TInt i=0; i < aLen; i++ )
+ {
+ frameCheckSum = crctable[(frameCheckSum ^ (*aBuffer++))];
+ }
+
+ // One's Complement
+ frameCheckSum = (TUint8) ((TUint8)(0xFF) - frameCheckSum);
+
+ return frameCheckSum;
+ }
+
+TInt CMux0710Protocol::Create0710DataFrames(TDesC8& aMsgBuf,
+ const TUint8 aDlcNum)
+/**
+ * This method is called by channel manager objects to fragment
+ * a client message into frames for transmission to the BP.
+ * The length of the client message is determined, the client message is
+ * fragment into 27.010 format, and the formatted frames are added to the
+ * write frame queue.
+ *
+ * @param aMsgBuf - Pointer to the client message
+ * @param aDlcNum - DLC number
+ * @return KErrNone, KErrArgument, or KErrNoMemory
+ */
+ {
+ _LOG_L4C2(">>CMux0710Protocol::Create0710DataFrames [aDlcNum=%d]",
+ aDlcNum);
+
+ TInt ret = KErrNone;
+
+ TInt msgLength = aMsgBuf.Length();
+ TInt offset = 0;
+ TInt frameLength = 0;
+ TInt maxFrameLength = KMaxFrameSize;
+
+ TBool beginFlag = ETrue;
+ TBool endFlag = EFalse;
+
+ _LOG_L4C2("msgLength = %d", msgLength);
+ if (msgLength > 0)
+ {
+ while ((msgLength > 0)&&(ret == KErrNone))
+ {
+ CCsyMsgBufBpFrame* bpFrame = GetFreeFrameBuf();
+ if (bpFrame)
+ {
+ // Set up the frame
+ bpFrame->MsgDlc() = aDlcNum;
+
+ if (msgLength > maxFrameLength)
+ {
+ _LOG_L4C3("Fragmenting (%d > %d)",msgLength,maxFrameLength);
+
+ frameLength = maxFrameLength;
+ bpFrame->CompleteWhenSent() = EFalse;
+ }
+ else
+ {
+ _LOG_L4C1("No Fragment");
+
+ frameLength = msgLength;
+ bpFrame->CompleteWhenSent() = ETrue;
+ endFlag = ETrue;
+ }
+
+ // Test for convergence layer 4
+ CPortC32InterfaceBase* port =
+ iPortFactory.FindPortC32Interface(aDlcNum);
+ if (port)
+ {
+ if (port->GetClientType() == CPortFactory::EC32ClientIpNif)
+ {
+ _LOG_L4C1("Layer 4 frame");
+
+ Create0710UIHLayer4FrameFromMsg(aMsgBuf, offset,
+ bpFrame, frameLength, aDlcNum, beginFlag, endFlag);
+
+ // No longer the beginning
+ beginFlag = EFalse;
+ }
+ else
+ {
+ _LOG_L4C1("Normal frame");
+
+ Create0710UIHFrameFromMsg(
+ aMsgBuf, offset, bpFrame, frameLength, aDlcNum);
+ }
+
+ _LOG_L4C1("Writing the frame");
+ ret = iCommWriter->Write(bpFrame);
+ }
+ else
+ {
+ _LOG_L1C2("** No port defined for aDlcNum=%d",
+ aDlcNum);
+ }
+ }
+ else
+ {
+ // error no free frame available
+ _LOG_L1C1("** No free frame buffer **");
+ ret = KErrNoMemory;
+ }
+
+ msgLength -= frameLength;
+ offset += maxFrameLength;
+ }
+ }
+ else
+ {
+ ret = KErrArgument;
+ }
+
+ _LOG_L4C2("<<CMux0710Protocol::Create0710DataFrames [ret=%d]",ret);
+ return ret;
+ }
+
+void CMux0710Protocol::Create0710UIHFrameFromMsg(TDesC8& aMsgBuf,
+ TInt aOffset,
+ CCsyMsgBufBpFrame* aFrameBuf,
+ TInt aLength,
+ TUint8 aDlcNum)
+/**
+ * This method creates an 27.010 UIH frame from a message.
+ * NOTE: This method assumes that a free frame buffer has been allocated.
+ *
+ * @param aMsgBuf - Pointer to a CSY memory element pointing to a Msg
+ * @param aOffset - Offset from the start of the message to be copied to the frame.
+ * This is needed if the calling method needs to defragment a long message.
+ * @param aFrameBuf - Pointer to a CSY memory elelemt pointing to a Frame
+ * @param aLength - Length of the payload to be copied.
+ * @param aDlcNum - DLC channel number.
+ */
+ {
+ _LOG_L4C3(">>CMux0710Protocol::Create0710UIHFrameFromMsg [aOffset=%d,aLength=%d]",aOffset,aLength);
+
+ aFrameBuf->iMsg.Zero();
+
+ // set initial length for headers
+#ifdef _27010ADVANCEOPTION
+ aFrameBuf->iMsg.SetLength(3);
+#else
+ aFrameBuf->iMsg.SetLength(4);
+#endif
+
+ // Octet 0 = Start Flag
+ aFrameBuf->iMsg[0] = KCsy0710StartEndFlag;
+
+ // Octet 1 = Non-extended Address, Command/Response, DLCI number
+ aFrameBuf->iMsg[1] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, C/R
+
+ // Octet 2 = Control Field = Frame Type (UIH)
+ aFrameBuf->iMsg[2] = (TUint8) KCsy0710CTLUIH;
+
+
+#ifdef _27010ADVANCEOPTION
+ TInt checksumLength = 2;
+#else
+ // Octet 3 = Length indicator
+ // ASSUME only 1 byte needed for length size
+ // 27.010 supports 7 bits in Octet 3 to indicate a length up to 128 bytes long
+ aFrameBuf->iMsg[3] = (TUint8) ((aLength << 1) | KCsy0710EA);
+
+
+ // CRC Frame check : Basic Option -> for Addr, Control, Length Fields only
+ // length = 3 bytes [Addr(1) + Control(1) + Length (1)]
+ TInt checksumLength = 3;
+#endif
+ TUint8 checksum;
+ checksum = (TUint8) CalcFCS(&aFrameBuf->iMsg[0], checksumLength);
+
+ // Octet 5-x
+ //CCsyMsgBufClient* csyMsgBufClient = STATIC_CAST(CCsyMsgBufClient*, aMsgBuf);
+ const TUint8* temp = &aMsgBuf[aOffset];
+ aFrameBuf->iMsg.Append(temp, aLength);
+ TInt tempLength = aFrameBuf->iMsg.Length();
+ aFrameBuf->iMsg.SetLength(tempLength + 2);
+ aFrameBuf->iMsg[tempLength] = checksum;
+ aFrameBuf->iMsg[tempLength+1] = KCsy0710StartEndFlag;
+
+ _LOG_L4C1("<<CMux0710Protocol::Create0710UIHFrameFromMsg");
+ }
+
+void CMux0710Protocol::Create0710UIHLayer4FrameFromMsg(TDesC8& aMsgBuf,
+ TInt aOffset,
+ CCsyMsgBufBpFrame* aFrameBuf,
+ TInt aLength,
+ TUint8 aDlcNum,
+ TBool aLayer4Begin,
+ TBool aLayer4End)
+/**
+ * This method creates an 27.010 UIH frame from a message.
+ * NOTE: This method assumes that a free frame buffer has been allocated.
+ *
+ * @param aMsgBuf - Pointer to a CSY memory element pointing to a Msg
+ * @param aOffset - Offset from the start of the message to be copied to the frame.
+ * This is needed if the calling method needs to defragment a long message.
+ * This method builds the message as a Convergence Layer 4 type, so
+ * only Advanced Option.
+ * @param aFrameBuf - Pointer to a CSY memory elelemt pointing to a Frame
+ * @param aLength - Length of the payload to be copied.
+ * @param aDlcNum - DLC channel number.
+ * @param aLayer4Begin - Beginning of Convergence Layer 4.
+ * @param aLayer4End - End of Convergence Layer 4.
+ */
+ {
+ _LOG_L4C3(">>CMux0710Protocol::Create0710UIHLayer4FrameFromMsg [aOffset=%d,aLength=%d]",aOffset,aLength);
+ _LOG_L4C3("[aLayer4Begin=%d,aLayer4End=%d]",aLayer4Begin,aLayer4End);
+
+ //aFrameBuf->iMsg.Zero(); - this is done in GetFreeFrameBuf
+
+ // set initial length for headers
+ aFrameBuf->iMsg.SetLength(3);
+
+ // Octet 0 = Start Flag
+ aFrameBuf->iMsg[0] = KCsy0710StartEndFlag;
+
+ // Octet 1 = Non-extended Address, Command/Response, DLCI number
+ aFrameBuf->iMsg[1] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, C/R
+
+ // Octet 2 = Control Field = Frame Type (UIH)
+ aFrameBuf->iMsg[2] = (TUint8) KCsy0710CTLUIH;
+
+ TInt checksumLength = 2;
+ TUint8 checksum;
+ checksum = (TUint8) CalcFCS(&aFrameBuf->iMsg[0], checksumLength);
+
+ // Octet 5-x
+ // Build the Convergence Layer 4 byte
+ TUint8 tempLayer4Byte = 0x01; // Default Middle Frame fragment
+ if (aLayer4Begin && aLayer4End) // Begin and End - Single Frame Message
+ {
+ tempLayer4Byte = 0xC1; // MAF magic numbers
+ }
+ else if (aLayer4Begin) // Begin Frame
+ {
+ tempLayer4Byte = 0x41;
+ }
+ else if (aLayer4End) // End Frame
+ {
+ tempLayer4Byte = 0x81;
+ }
+ aFrameBuf->iMsg.Append(tempLayer4Byte);
+
+ const TUint8* temp = &aMsgBuf[aOffset];
+ aFrameBuf->iMsg.Append(temp, aLength);
+ TInt tempLength = aFrameBuf->iMsg.Length();
+
+ aFrameBuf->iMsg.SetLength(tempLength + 2);
+ aFrameBuf->iMsg[tempLength] = checksum;
+ aFrameBuf->iMsg[tempLength+1] = KCsy0710StartEndFlag;
+
+ DumpFrame(aFrameBuf);
+
+ _LOG_L4C1("<<CMux0710Protocol::Create0710UIHLayer4FrameFromMsg");
+ }
+
+TInt CMux0710Protocol::Create0710ControlFrame(TCsyFrameType aFrameType,
+ TUint8 aDlcNum,
+ TCsyCtrlCommand aType,
+ TUint8 aV24Signals)
+/**
+ * This method creates an 27.010 control frame using the specified frame type
+ * and DLC number.
+ * NOTE: This method assumes that a free frame buffer has been allocated.
+ *
+ * @param aFrameType - Frame type of the control frame
+ * @param aDlcNum - DLC number of this frame
+ * @return KErrNone or KErrGeneral
+ */
+ {
+ _LOG_L4C2(">>CMux0710Protocol::Create0710ControlFrame [aDlcNum=%d]",aDlcNum);
+
+ TInt ret = KErrNone;
+
+ if (iMaxRetriesReached == EFalse)
+ {
+
+ #ifdef _27010ADVANCEOPTION
+ TUint8 tempArray[15]; // MAF magic numbers
+ #else
+ TUint8 tempArray[8];
+ #endif
+
+ // Octet 0 = Start Flag
+ tempArray[0] = KCsy0710StartEndFlag;
+
+ // Octet 1 = Non-extended Address, initiating end (Command/Response), DLCI number
+ tempArray[1] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, C/R
+
+ // Octet 2 = Frame Type
+ switch (aFrameType)
+ {
+ case ESABM:
+ _LOG_L3C1("ESABM");
+ tempArray[2] = (TUint8) KCsy0710CTLSABM;
+ tempArray[2] |= KCsy0710PollFinal;
+ break;
+ case EUA:
+ _LOG_L3C1("EUA");
+ tempArray[1] = (TUint8) ((aDlcNum << 2) | 0x01); // Set the DLCI, EA
+ tempArray[2] = (TUint8) KCsy0710CTLUA;
+ break;
+ case EDM:
+ _LOG_L3C1("EDM");
+ tempArray[1] = (TUint8) ((aDlcNum << 2) | 0x01); // Set the DLCI, EA
+ tempArray[2] = (TUint8) KCsy0710CTLDM;
+ break;
+ case EDISC:
+ _LOG_L3C1("EDISC");
+ tempArray[2] = (TUint8) KCsy0710CTLDISC;
+ tempArray[2] |= KCsy0710PollFinal;
+ break;
+ case EUIH:
+ _LOG_L3C1("EUIH");
+ tempArray[2] = (TUint8) KCsy0710CTLUIH;
+ tempArray[2] |= KCsy0710PollFinal; // no pollbit
+ break;
+ case EUI:
+ _LOG_L3C1("EUI");
+ tempArray[2] = (TUint8) KCsy0710CTLUI;
+ break;
+ default:
+ _LOG_L1C2("** Unknown FrameType=%d **",aFrameType);
+ ret = KErrGeneral;
+ break;
+ }
+
+ #ifndef _27010ADVANCEOPTION
+
+ (void) aType; //to hide warning.
+ (void) aV24Signals; //to hide warning.
+
+ // Octet 3 = Length1 indicator octet1
+ tempArray[3] = (TUint8) 0x01; // zero length and set EA bit
+
+ // CRC Frame check : Basic Option -> for Addr, Control, Length Fields only
+ // length = 4 bytes [Addr(1) + Control(1) + Length (2)]
+ TInt length = 3;
+ tempArray[4] = (TUint8) CalcFCS(tempArray, length);
+ tempArray[5] = KCsy0710StartEndFlag;
+
+ // For this call of GetFreeFrameBuf do not check the low frame threshold
+ // since control frame and it could be related to an already occurring flow
+ // control action anyway.
+ CCsyMsgBufBpFrame* ctrlFrame = GetFreeFrameBuf(EFalse);
+ if (ctrlFrame)
+ {
+ ctrlFrame->iMsg.Copy(tempArray, 6);
+ iCommWriter->Write(ctrlFrame); // MAF should be high priority frame
+ }
+ #else
+
+ if (aFrameType == EUIH)
+ {
+ // Set the DLCI to 0
+ tempArray[1] = 0x03; // Set the DLCI to 0, EA, C/R
+ }
+
+ TUint8 checkSum;
+ TInt length = 2;
+ checkSum = (TUint8) CalcFCS(tempArray, length);
+
+ if (aFrameType == EUIH)
+ {
+ // Only two types of control UIH supported
+ if (aType == EParamNeg)
+ {
+ _LOG_L3C1("Param Negotiate");
+
+ tempArray[3] = KCsy0710CTLUIH_DlcParamNegotiate;
+ tempArray[4] = 0x11; // i.e 8 bytes, EA
+ tempArray[5] = aDlcNum;
+ tempArray[6] = (KPNClBits << 4) + KPNFrameType;
+ tempArray[7] = KPNDlcPriority;
+ tempArray[8] = KPNAckTimer;
+ tempArray[9] = KPNMaxFrameSize & 0x00ff;
+ tempArray[10] = KPNMaxFrameSize >> 8;
+ tempArray[11] = KPNMaxRetransmissions;
+ tempArray[12] = KPNWindowSize;
+ tempArray[13] = checkSum;
+ tempArray[14] = KCsy0710StartEndFlag;
+
+ iParamNegotiateDlcNum = aDlcNum;
+ }
+ else
+ {
+ _LOG_L3C2("MSC aV24Signals=0x%x", aV24Signals);
+
+ tempArray[3] = KCsy0710CTLUIH_ModemStatusCmd;
+ tempArray[4] = 0x05; // i.e 2 bytes, EA
+ tempArray[5] = (TUint8) ((aDlcNum << 2) | 0x03); // Set the DLCI, EA, 1
+ tempArray[6] = aV24Signals;
+ tempArray[7] = checkSum;
+ tempArray[8] = KCsy0710StartEndFlag;
+ }
+ }
+ else
+ {
+ tempArray[3] = checkSum;
+ tempArray[4] = KCsy0710StartEndFlag;
+ }
+
+ CCsyMsgBufBpFrame* ctrlFrame = GetFreeFrameBuf(EFalse);
+ if (ctrlFrame)
+ {
+ #ifdef _27010ADVANCEOPTION
+ if (aFrameType == EUIH)
+ {
+ if (aType == EParamNeg)
+ {
+ ctrlFrame->iMsg.Copy(tempArray, 15);
+ }
+ else
+ {
+ ctrlFrame->iMsg.Copy(tempArray, 9);
+ }
+ }
+ else
+ {
+ ctrlFrame->iMsg.Copy(tempArray, 5);
+ }
+ #else
+ ctrlFrame->iMsg.Copy(tempArray, 5);
+ #endif
+
+ _LOG_L3C1("Write the frame");
+ iCommWriter->Write(ctrlFrame); // MAF should be high priority frame
+ }
+ #endif
+ else
+ { // no memory available
+ _LOG_L1C1("** No Memory Available **");
+ ret = KErrNoMemory;
+ }
+ }
+ else
+ {
+ _LOG_L1C1("** Max Retries Reached **");
+ ret = KErrTimedOut;
+ }
+ _LOG_L4C2("<<CMux0710Protocol::Create0710ControlFrame [ret=%d]",ret);
+ return ret;
+ }
+
+TInt CMux0710Protocol::SwitchToMuxMode()
+/**
+ * This method is called to switch the baseband to multiplexer mode.
+ * This method formats the AT command the buffer with the AT+CMUX command
+ * and writes to the write FrameBuf List.
+ *
+ * @return KErrNone or KErrNoMemory
+ */
+ {
+ _LOG_L4C1(">>CMux0710Protocol::SwitchToMuxMode");
+
+#ifdef __CSY_PROTOTYPE__
+ iMuxMgrState = ECsyMuxEnabled;
+#else
+
+ if(iMuxMgrState == ECsyWaitingForFlushResp)
+ {
+ //flush the read queue.
+ iTimeouter->Start(KOneSecond);
+ return KErrNone;
+ }
+ else
+ {
+ iTimeouter->Start(KTwoSeconds);
+ }
+
+ TInt ret = KErrNone;
+
+ CCsyMsgBufBpFrame* initBuf = GetFreeFrameBuf();
+ if (initBuf)
+ {
+
+#ifdef USE_TI_CONDAT_STACK
+ if(iMuxMgrState == ECsyWaitingForResetResp)
+ {
+ //when using the TI stack we first attempt to reset the board using at%b.
+ _LOG_L3C1("Sending AT reset command");
+ TBuf8<16> aBuf(KATCmdReset);
+ initBuf->iMsg.Copy(aBuf);
+ iMuxMgrState = ECsyWaitingForResetResp;
+ }
+ else if(iMuxMgrState == ECsyWaitingForSleepResp)
+ {
+ //Need to ensure that the TI stack will not timeout in the lull between commands
+ _LOG_L3C1("Sending AT sleep command");
+ TBuf8<16> aBuf(KATCmdSleep);
+ initBuf->iMsg.Copy(aBuf);
+ iMuxMgrState = ECsyWaitingForSleepResp;
+ }
+ else
+ {
+#endif
+ _LOG_L3C1("Sending AT");
+ TBuf8<16> aBuf(KATCmdAttention);
+ initBuf->iMsg.Copy(aBuf);
+ iMuxMgrState = ECsyWaitingForAttentionResp;
+
+#ifdef USE_TI_CONDAT_STACK
+ }
+#endif
+ iResponseStr.Zero();
+
+ // call comm write to xmit frame
+ // comm writer's RunL will run when frame has been xmitted by LDD
+ // and return the frame buffer to the free list
+ ret = iCommWriter->Write(initBuf);
+ }
+ else
+ {
+ _LOG_L1C1("** No Memory Available **");
+ ret = KErrNoMemory;
+ }
+#endif
+
+ _LOG_L4C2("<<CMux0710Protocol::SwitchToMuxMode [ret=%d]",ret);
+ return ret;
+ }
+
+TInt CMux0710Protocol::ParseATResponse(TDes8& aResp)
+/**
+ * This method parses the specified AT ascii response for the
+ * expected ascii "OK" string. If the string is found then set
+ * the Mux Mode to True.
+ *
+ * @param aResp - Reference to the AT response string to parse
+ * @return KErrNone, KErrGeneral or KErrNotFound
+ */
+ {
+ _LOG_L4C3(">>CMux0710Protocol::ParseATResponse [iMuxMgrState = %d, aResp=%S]",
+ iMuxMgrState,&aResp);
+
+ //Response string not always read in one go so concatonate it together to form full response string.
+ TInt appendsize = iResponseStr.MaxSize() - iResponseStr.Length();
+ iResponseStr.Append(aResp.LeftTPtr(appendsize));
+ _LOG_L4C2("Result string concatenated = %S",&iResponseStr);
+
+ if(iMuxMgrState == ECsyWaitingForFlushResp)
+ {
+ _LOG_L4C2("Flushed comm port on opening = %S",&iResponseStr);
+ return KErrNotFound;
+ }
+
+#ifdef USE_TI_CONDAT_STACK
+ if(iMuxMgrState == ECsyWaitingForResetResp)
+ {
+ if(iResponseStr.Find(KATInitialised) != KErrNotFound)
+ {
+ //got match - reset Rsp string to enter normal loop handle
+ _LOG_L3C1("Board has successfully been reset.");
+ iResponseStr = _L8("OK");
+ iRetryCount = 0; // stop retries of the reset
+ }
+ }
+
+ if(iMuxMgrState == ECsyWaitingForSleepResp)
+ {
+ if(iResponseStr.Find(_L8("OK")) != KErrNotFound)
+ {
+ //got match - sleep acknowledged
+ _LOG_L3C1("Board has had sleep timeout disabled.");
+ iRetryCount = 0; //stop retries of the sleep;
+ }
+ }
+#endif
+
+ TInt ret = KErrNone;
+
+ // all AT responses should contain an "OK" keyword
+ if ((iResponseStr.Find(_L8("OK")) != KErrNotFound) ||
+ (iResponseStr.Find(_L8("ERROR")) != KErrNotFound))
+ {
+ if (iResponseStr.Find(_L8("ERROR")) != KErrNotFound)
+ {
+#ifdef USE_TI_CONDAT_STACK
+ if(iMuxMgrState == ECsyWaitingForResetResp)
+ {
+ _LOG_L3C1("*******TI Board failed to reset (AT%b) - continue anyway as may already be in a stable state.*******");
+ iRetryCount--;
+ }
+ else if (iMuxMgrState == ECsyWaitingForSleepResp)
+ {
+ _LOG_L3C1("*******TI Board failed to acknowledge sleep disable (AT%SLEEP=0) - continue anyway as may already be in a stable state.*******");
+ iRetryCount--;
+ }
+ else
+ {
+ _LOG_L3C1("****************** Received ERROR back ****************");
+ }
+#else
+ _LOG_L3C1("****************** Received ERROR back ****************");
+#endif
+ }
+ iTimeouter->Stop();
+
+ switch (iMuxMgrState)
+ {
+#ifdef USE_TI_CONDAT_STACK
+ case ECsyWaitingForResetResp:
+ {
+ _LOG_L3C1("ECsyWaitingForResetResp - Start proper init sequence.");
+ if(iRetryCount>0)
+ iMuxMgrState = ECsyWaitingForResetResp; //try reset command again
+ else
+ {
+ iMuxMgrState = ECsyWaitingForSleepResp;
+ iRetryCount = KRetryCount;
+ }
+ SwitchToMuxMode();
+ }
+ break;
+
+ case ECsyWaitingForSleepResp:
+ {
+ iResponseStr.Zero();
+ _LOG_L3C1("ECsyWaitingForSleepResp");
+ if(iRetryCount>0)
+ iMuxMgrState = ECsyWaitingForSleepResp;
+ else
+ iMuxMgrState = ECsyWaitingForAttentionResp;
+ SwitchToMuxMode();
+ }
+ break;
+#endif
+ case ECsyWaitingForAttentionResp:
+ {
+ iResponseStr.Zero();
+ CCsyMsgBufBpFrame* atCmdBuf = GetFreeFrameBuf();
+ if (atCmdBuf)
+ {
+ _LOG_L3C1("Writing ATE0 command");
+ atCmdBuf->iMsg.Copy(KATCmdDisableEcho);
+ iCommWriter->Write(atCmdBuf);
+ iMuxMgrState = ECsyWaitingForEchoDisableResp;
+ }
+
+ iTimeouter->Start(KTwoSeconds);
+ }
+ break;
+
+ case ECsyWaitingForEchoDisableResp:
+ {
+ iResponseStr.Zero();
+ CCsyMsgBufBpFrame* atCmdBuf = GetFreeFrameBuf();
+ if (atCmdBuf)
+ {
+ _LOG_L3C1("Writing CMUX cmd");
+ atCmdBuf->iMsg.Copy(KCsyDefaultATEnterMuxModeCmd);
+ iCommWriter->Write(atCmdBuf);
+ iMuxMgrState = ECsyWaitingForCmuxResp;
+ }
+
+ iTimeouter->Start(KTwoSeconds);
+ }
+ break;
+
+ case ECsyWaitingForCmuxResp:
+ {
+ iResponseStr.Zero();
+ _LOG_L3C1("Got CMUX response");
+ iMuxMgrState = ECsyMuxEnabled;
+
+ // start the connect process for the control, command & data channels
+ iPortFactory.ConnectControlChannel();
+ }
+ break;
+
+ default:
+ _LOG_L3C2("** Invalid Mux Mgr State = %d **", iMuxMgrState);
+ ret = KErrGeneral;
+ break;
+ }
+ }
+ else
+ {
+ ret = KErrNotFound;
+ }
+
+ _LOG_L4C2("<<CMux0710Protocol::ParseATResponse [ret = %d]",ret);
+ return ret;
+ }
+
+void CMux0710Protocol::TimedOut()
+/**
+ * This resends the AT command required.
+ */
+ {
+ _LOG_L4C2(">>CMux0710Protocol::TimedOut [iMuxMgrState=%d]",iMuxMgrState);
+
+ switch (iMuxMgrState)
+ {
+
+ case ECsyWaitingForFlushResp:
+ {
+ //read queue has just been flushed, now start switch to MUX mode
+ _LOG_L3C1("ECsyWaitingForFlushResp");
+#ifdef USE_TI_CONDAT_STACK
+ iMuxMgrState = ECsyWaitingForResetResp;
+#else
+ iMuxMgrState = ECsyWaitingForAttentionResp;
+#endif
+ SwitchToMuxMode();
+ }
+ break;
+#ifdef USE_TI_CONDAT_STACK
+ case ECsyWaitingForResetResp:
+ {
+ _LOG_L3C1("ECsyWaitingForResetResp");
+ if(--iRetryCount>0)
+ iMuxMgrState = ECsyWaitingForResetResp; //try reset command again
+ else
+ iMuxMgrState = ECsyWaitingForSleepResp;
+ SwitchToMuxMode();
+ }
+ break;
+
+ case ECsyWaitingForSleepResp:
+ {
+ _LOG_L3C1("ECsyWaitingForSleepResp");
+ if(--iRetryCount>0)
+ iMuxMgrState = ECsyWaitingForSleepResp; //try sleep command again
+ else
+ iMuxMgrState = ECsyWaitingForAttentionResp;
+ SwitchToMuxMode();
+ }
+ break;
+#endif
+ case ECsyWaitingForAttentionResp:
+ {
+ if (++iAtResponseTimeout < KAtResponseTimeoutLimit)
+ {
+ _LOG_L3C2("ECsyWaitingForAttentionResp [timeout:%d]",iAtResponseTimeout);
+ SwitchToMuxMode();
+ }
+ else
+ {
+ _LOG_L3C2("Max retries [%d] reached for At Response", KAtResponseTimeoutLimit);
+
+ iMaxRetriesReached = ETrue;
+ //call to scheduler DoCancel required here
+ iPortFactory.ChannelCtrlDoCancel();
+ }
+ }
+ break;
+
+ case ECsyWaitingForEchoDisableResp:
+ {
+ _LOG_L3C1("ECsyWaitingForEchoDisableResp");
+ iResponseStr.Zero();
+ CCsyMsgBufBpFrame* atCmdBuf = NULL;
+ atCmdBuf = GetFreeFrameBuf();
+ if (atCmdBuf)
+ {
+ TBuf8<16> tempBuf(KATCmdDisableEcho);
+ atCmdBuf->iMsg.Copy(tempBuf);
+ iCommWriter->Write(atCmdBuf);
+ }
+
+ iTimeouter->Start(KOneSecond);
+ }
+ break;
+
+ case ECsyWaitingForCmuxResp:
+ {
+ _LOG_L3C1("ECsyWaitingForCmuxResp");
+ iResponseStr.Zero();
+ CCsyMsgBufBpFrame* atCmdBuf = GetFreeFrameBuf();
+ if (atCmdBuf)
+ {
+ _LOG_L3C1("Writing CMUX cmd");
+ atCmdBuf->iMsg.Copy(KCsyDefaultATEnterMuxModeCmd);
+ iCommWriter->Write(atCmdBuf);
+ iMuxMgrState = ECsyWaitingForCmuxResp;
+ }
+ iTimeouter->Start(KTwoSeconds);
+ }
+ break;
+
+ default:
+ _LOG_L1C2("** Invalid Mux Mgr State = %d **", iMuxMgrState);
+ break;
+ }
+
+ _LOG_L4C1("<<CMux0710Protocol::TimedOut");
+ }
+
+void CMux0710Protocol::DumpFrame(CCsyMsgBufBpFrame* aFrameBuf)
+/**
+ * Logs the packet into the log file.
+ *
+ * @param aPacket The incoming packet
+ */
+ {
+ _LOG_L4C1(">>CMux0710Protocol::DumpFrame");
+
+ TInt packetLen = aFrameBuf->iMsg.Length();
+ _LOG_L4C2("frame length %d",packetLen);
+
+ TBuf8<256> logBuf;
+ TBuf8<256> logBuf2;
+
+ logBuf.Copy(_L8(" "));
+ logBuf2.Copy(_L8(" "));
+ _LOG_L4C1("");
+
+ for (TInt i = 0; i <= packetLen; i++)
+ {
+ if (i >= packetLen)
+ {
+ logBuf.Append(logBuf2);
+ _LOG_L4C2("%S",&logBuf);
+ break;
+ }
+ if (((i % 16) == 0) && (i > 0))
+ {
+ logBuf.Append(logBuf2);
+ _LOG_L4C2("%S",&logBuf);
+ logBuf.Copy(_L8(" "));
+ logBuf2.Copy(_L8(" "));
+ }
+ logBuf.AppendFormat(_L8("%02X "), aFrameBuf->iMsg[i]);
+ if (TChar(aFrameBuf->iMsg[i]).IsPrint())
+ logBuf2.AppendFormat(_L8("%c"), aFrameBuf->iMsg[i]);
+ else
+ logBuf2.Append(_L8("."));
+ }
+
+ _LOG_L4C1("<<CMux0710Protocol::DumpFrame");
+ _LOG_L4C1("");
+ }
\ No newline at end of file