cbsref/csyrefplugins/csy27010/src/Mux0710Protocol.cpp
branchRCL_3
changeset 19 630d2f34d719
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbsref/csyrefplugins/csy27010/src/Mux0710Protocol.cpp	Tue Aug 31 16:23:08 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