cbsref/csyrefplugins/csy27010/src/CommFrameWriterAo.cpp
branchRCL_3
changeset 19 630d2f34d719
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cbsref/csyrefplugins/csy27010/src/CommFrameWriterAo.cpp	Tue Aug 31 16:23:08 2010 +0300
@@ -0,0 +1,518 @@
+//
+// * 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 implemenation for the CCommFrameWriterAo class.
+// *               This class is used to handle the write operations to the serial port
+// *               logical device driver.
+//
+
+// CommFrameWriterAo.cpp
+
+/** @file CommFrameWriterAo.cpp
+ *
+ * This file contains the implemenation for the CCommFrameWriterAo class.
+ * This class is used to handle the write operations to the serial port
+ * logical device driver.
+ */
+
+#include "CommFrameWriterAo.h"
+#include "CsyMsgBufBPFrame.h"
+#include "Mux0710Protocol.h"
+#include "CsyDebugLogger.h"
+#include "PortC32InterfaceBase.h"
+
+CCommFrameWriterAo* CCommFrameWriterAo::NewL(CPortFactory* aParent, CMux0710Protocol* aMux0710Protocol)
+/**
+ * This method uses two phase construction and the cleanup stack to
+ * create an instance of class CCommFrameWriterAo. 
+ *
+ * @param aParent - Pointer to the parent object
+ * @param aMux0710Protocol - Pointer to mux protocol object
+ * @return Pointer to new instance of CCommFrameWriterAo
+ */
+    {
+	_LOG_L4C1("CCommFrameWriterAo::NewL");
+
+    CCommFrameWriterAo* obj = new (ELeave) CCommFrameWriterAo(aParent, aMux0710Protocol);
+    CleanupStack::PushL(obj);
+    obj->ConstructL();
+    CleanupStack::Pop();
+    return (obj);
+    }
+
+
+CCommFrameWriterAo::~CCommFrameWriterAo()
+/**
+ * Destructor.
+ */
+    {
+	_LOG_L4C1("CCommFrameWriterAo::~CCommFrameWriterAo");
+
+    Cancel();
+
+ 	// Remove the frames in Write Buf List
+	CCsyMsgBufBpFrame* frame;
+	iWriteFrameBufIter.SetToFirst();
+	while ((frame = iWriteFrameBufIter++) != NULL)
+		{
+		iWriteFrameBufList.Remove(*frame);
+		delete frame;
+	 	}
+
+ 	// Remove the frames in waiting list
+	iWaitingForFcOffIter.SetToFirst();
+	while ((frame = iWaitingForFcOffIter++) != NULL)
+		{
+		iWaitingForFcOffList.Remove(*frame);
+		delete frame;
+	 	}
+   }
+
+CCommFrameWriterAo::CCommFrameWriterAo(CPortFactory* aParent, CMux0710Protocol* aMux0710Protocol)
+/**
+ * Constructor.
+ * @param aParent - Pointer to the parent object
+ * @param aMux0710Protocol - Pointer to mux protocol object
+ */
+:	CCommReadWriteBaseAo(aParent, aMux0710Protocol, KFrameWriterAoPriority),
+	iWriteFrameBufList(_FOFF(CCsyMsgBufBpFrame, iMsgLink)),
+	iWriteFrameBufIter(iWriteFrameBufList),
+	iWaitingForFcOffList(_FOFF(CCsyMsgBufBpFrame, iMsgLink)),
+	iWaitingForFcOffIter(iWaitingForFcOffList)
+	{}
+
+
+void CCommFrameWriterAo::ConstructL()
+/**
+ * Safe constructor
+ */
+    {
+	_LOG_L4C1("CCommFrameWriterAo::ConstructL");
+	SetBuffersL();
+    }
+
+void CCommFrameWriterAo::RunL()
+/**
+ * This method is called when a write to the LDD completes.
+ */
+	{
+	_LOG_L4C1(" ");
+	_LOG_L4C2(">>CCommFrameWriterAo::RunL [iStatus=%d] - written to LDD",
+		iStatus.Int());
+
+	if (iStatus.Int())
+		{
+		_LOG_L1C2("** Error writing to LDD ** [iStatus=%d]",iStatus.Int());
+
+		if (!iCompleteWhenSent)
+			{
+			// The frame being sent was not the last or only one for this dlc, other
+			// frames exist
+
+			// go through list and remove other frames to send for this dlc
+			RemoveAnyDlcFramesOnWriteList(iDlcNum, EFalse);
+
+			iCompleteWhenSent = ETrue;
+			}
+		}
+
+	if (iCompleteWhenSent)
+		{
+		iCompleteWhenSent = EFalse;
+
+		_LOG_L3C2("Complete write [iDlcNum=%d]",iDlcNum);
+		CompleteWrite(iDlcNum,iStatus.Int());
+		}
+
+	// check for another message that needs to be sent to the baseband
+	CCsyMsgBufBpFrame* bpFrame = GetFrameToWrite();
+	if (bpFrame)
+		{
+		TInt ret = KErrNone;
+		do
+			{
+			ret = WriteFrame(bpFrame);
+			if (ret)
+				{
+				_LOG_L1C2("** Write frame failed [ret=%d] **",ret);
+				if (!iCompleteWhenSent)
+					{
+					// go through list and remove other frames to send for this dlc
+					RemoveAnyDlcFramesOnWriteList(iDlcNum, EFalse);
+					}
+				}
+
+			// Loop around if there is an error and try and send the next frame
+			}
+			while (ret);
+		}
+	else
+		{
+		_LOG_L3C1("Finished all writes - nothing more to send to LDD");
+		}
+
+	_LOG_L4C1("<<CCommFrameWriterAo::RunL");
+	_LOG_L3C1(" "); // please leave this separator in
+	}
+
+void CCommFrameWriterAo::DoCancel()
+/**
+ * Cancel a pending write
+ */
+    {
+	_LOG_L4C1("CCommFrameWriterAo::DoCancel - cancelling LDD write");
+
+	iCommPort->WriteCancel();
+
+ 	// Remove the frames in Write Buf List
+	CCsyMsgBufBpFrame* frame;
+	iWriteFrameBufIter.SetToFirst();
+	while ((frame = iWriteFrameBufIter++) != NULL)
+		{
+		iWriteFrameBufList.Remove(*frame);
+		iMux0710Protocol->AddFrameFreeQ(frame);
+	 	}
+
+ 	// Remove the frames in waiting list
+	iWaitingForFcOffIter.SetToFirst();
+	while ((frame = iWaitingForFcOffIter++) != NULL)
+		{
+		iWaitingForFcOffList.Remove(*frame);
+		iMux0710Protocol->AddFrameFreeQ(frame);
+	 	}
+    }
+
+TInt CCommFrameWriterAo::Write(CCsyMsgBufBpFrame* aBpFrame,
+							   TBool aHighPriority)
+/**
+ * This method is called to transmit a frame to the baseband.
+ *
+ * @param aBpFrame - Pointer to frame
+ * @param aHighPriority - Flag to indicate a high priority frame
+ */
+    {
+	_LOG_L4C3(">>CCommFrameWriterAo::Write [aBpFrame=0x%x, aHighPriority=%d]",
+		aBpFrame,aHighPriority);
+
+	TInt ret = KErrNone;
+
+	// 1st check if we are already transmitting a frame
+	if (!IsActive())
+		{
+		_LOG_L4C1("Not currently writing a frame");
+		ret = WriteFrame(aBpFrame);
+		}
+	else
+		{
+		// add frame to the list of frames that need to be sent to the BP
+		_LOG_L2C1("Already writing a frame - add to queue");
+		AddToWaitingToSendList(aBpFrame, aHighPriority);
+		}
+
+	_LOG_L4C2("<<CCommFrameWriterAo::Write [ret=%d]",ret);
+	return ret;
+	}
+
+TInt CCommFrameWriterAo::WriteFrame(CCsyMsgBufBpFrame* aBpFrame)
+/**
+ * This method is called to transmit a frame to the baseband.
+ *
+ * @param aBpFrame - Pointer to frame
+ */
+    {
+	_LOG_L4C2(">>CCommFrameWriterAo::WriteFrame [aBpFrame=0x%x]",
+		aBpFrame);
+
+	TInt ret = KErrNone;
+
+	iDlcNum = aBpFrame->MsgDlc();
+	iCompleteWhenSent = aBpFrame->CompleteWhenSent();
+
+	if (iBuf == NULL)
+		{
+		_LOG_L1C1("** Failure to alloc iBuf **");
+
+		ret = KErrNoMemory;
+		_LOG_L4C2("<<CCommFrameWriterAo::WriteFrame [ret=%d]",ret);
+		return ret;
+		}
+
+//*********************************************************
+// MAF tidy up
+#ifdef _DEBUG
+	//log out frame
+	TInt len = aBpFrame->iMsg.Length();
+	_LOG_L3C3("[0x%02x] Tx Got Start dlc=%d", aBpFrame->iMsg[0], aBpFrame->MsgDlc());
+	for(TInt k = 1; k < len-1; k++)
+		{
+		_LOG_L3C2("[0x%02x]",aBpFrame->iMsg[k]);
+		}
+	_LOG_L3C2("[0x%02x] Tx Frame End", aBpFrame->iMsg[len-1]);
+	if (iMux0710Protocol->IsMuxModeEnabled())
+		{
+		if ((aBpFrame->iMsg[2] & 0xEF) == KCsy0710CTLUIH)
+			{
+#ifdef __DEBUGLOGFILE__
+			TBuf8<200> tt;
+#else
+			TBuf16<200> tt;
+#endif
+			tt.Copy(aBpFrame->iMsg);
+
+			TInt ttLength = tt.Length();
+			tt.SetLength(ttLength);
+#ifdef __LOGDEBUGLEVELMINOR__
+			_LOG_L3C3("Sent >>>> %d: %S", aBpFrame->iMsg[1] >> 2, &tt);
+#endif
+			}
+		}
+#endif
+//*********************************************************
+
+	// copy message to local buffer
+#ifdef _27010ADVANCEOPTION
+
+	if (iMux0710Protocol->IsMuxModeEnabled())
+		{
+		TInt length = aBpFrame->iMsg.Length() - 1;
+		TUint8 mask = 1<<5;
+
+		iBuf->Zero();
+
+		 // start flag
+		iBuf->Append(aBpFrame->iMsg[0]);
+
+		// check data for flag or escape character
+		for (TInt i=1; i < length; i++)
+			{
+			TUint8 tmp = aBpFrame->iMsg[i];
+			if ((tmp == KCsy0710StartEndFlag)||(tmp== KCsy0710EscapeByte))
+				{
+				_LOG_L3C1("Adding escape byte");
+				iBuf->Append(KCsy0710EscapeByte);
+				tmp = (TUint8) (tmp^mask);
+				}
+			iBuf->Append(tmp);
+			}
+
+		//ending flag
+		iBuf->Append(aBpFrame->iMsg[length]);  
+		}
+	else
+		iBuf->Copy(aBpFrame->iMsg);
+
+#else
+
+	// Basic option - no escape chars
+	iBuf->Copy(aBpFrame->iMsg);
+
+#endif
+
+	// free the caller's frame buffer
+	iMux0710Protocol->AddFrameFreeQ(aBpFrame);
+
+	// invoke LDD
+	_LOG_L3C1("Sending to LDD");
+	iStatus = KRequestPending; //MAF why is this being set to KRequestPending?
+ 	SetActive();
+	iCommPort->Write(iStatus, *iBuf, iBuf->Length());
+
+	_LOG_L4C2("<<CCommFrameWriterAo::WriteFrame [ret=%d]",ret);
+	return ret;
+	}
+
+void CCommFrameWriterAo::WriteCancel()
+/**
+ * Cancel the current write operation.
+ * @return void
+ */
+    {
+    _LOG_L4C1("CCommFrameWriterAo::WriteCancel");
+	Cancel();
+    }
+
+void CCommFrameWriterAo::AddToWaitingToSendList(CCsyMsgBufBpFrame* aBpFrame, TBool aHighPriority)
+/**
+ * This method is called to by C32 Interface objects to add
+ * the specified frame to the baseband queue.
+ *
+ * @param aBpFrame - Pointer to the frame buffer
+ * @param aHighPriority - Flag to indicate a high priority frame
+ */
+	{
+	_LOG_L4C3(">>CCommFrameWriterAo::AddToWaitingToSendList [aBpFrame=0x%x,aHighPriority=%d]",
+		aBpFrame, aHighPriority);
+
+	if (aHighPriority)
+		iWriteFrameBufList.AddFirst(*aBpFrame);
+	else
+		iWriteFrameBufList.AddLast(*aBpFrame);
+
+	_LOG_L4C1("<<CCommFrameWriterAo::AddToWaitingToSendList");
+	}
+
+CCsyMsgBufBpFrame* CCommFrameWriterAo::GetFrameToWrite()
+/**
+ * This method checks the queue for a frame that needs to be sent
+ * to the baseband.  If there is a message then deque it from the queue and
+ * return a pointer to it, else return NULL.
+ *
+ * @return Pointer to the frame to be written or NULL
+ */
+	{
+	_LOG_L4C1(">>CCommFrameWriterAo::GetFrameToWrite");
+
+	CCsyMsgBufBpFrame* frame = NULL;
+	if (!iWriteFrameBufList.IsEmpty())
+		{
+		frame = iWriteFrameBufList.First();
+		if (frame)
+			iWriteFrameBufList.Remove(*frame);
+		}
+
+	_LOG_L4C2("<<CCommFrameWriterAo::GetFrameToWrite [frame=0x%x]",frame);
+	return frame;
+	}
+
+void CCommFrameWriterAo::RemoveAnyDlcFramesOnWriteList(TUint8 aDlcNum, TBool aPlaceOnWaitList)
+/**
+ * This method transfers any frames on the write list from the dlc specified
+ * to the waiting list.
+ *
+ * @param aDlcNum is the dlc number of the frames to move to the waiting list
+ * @param aPlaceOnWaitList indicates whether to free the frame or place onto the
+ *        wait list.
+ */
+	{
+	_LOG_L4C3(">>CCommFrameWriterAo::RemoveAnyDlcFramesOnWriteList [aDlcNum=%d, aPlaceOnWaitList=%d]",
+		aDlcNum,aPlaceOnWaitList);
+
+	if (iWriteFrameBufList.IsEmpty())
+		{
+		// No frames to transfer
+		_LOG_L4C1("No frames on write list");
+		}
+	else
+		{
+		CCsyMsgBufBpFrame* frame = NULL;
+		iWriteFrameBufIter.SetToFirst();
+		while ((frame = iWriteFrameBufIter++) != NULL)
+			{
+			if (frame->GetDlcNum() == aDlcNum)
+				{
+				iWriteFrameBufList.Remove(*frame);
+				if (aPlaceOnWaitList)
+					{
+					_LOG_L4C1("Transferring frame to wait list");
+					iWaitingForFcOffList.AddLast(*frame);
+					}
+				else
+					{
+					// Adding frame to the free list
+					iMux0710Protocol->AddFrameFreeQ(frame);
+					}
+				}
+			}
+		}
+
+	_LOG_L4C1("<<CCommFrameWriterAo::RemoveAnyDlcFramesOnWriteList");
+	}
+
+void CCommFrameWriterAo::RemoveAnyDlcFramesFromWaitList(TUint8 aDlcNum, TBool aPlaceOnWriteList)
+/**
+ * This method transfers any frames on the waiting list from the dlc specified
+ * to the write list.
+ *
+ * @param aDlcNum is the dlc number of the frames to move to the write list
+ */
+	{
+	_LOG_L4C3(">>CCommFrameWriterAo::RemoveAnyDlcFramesFromWaitList [aDlcNum=%d,aPlaceOnWriteList=%d]",
+		aDlcNum,aPlaceOnWriteList);
+
+	if (iWaitingForFcOffList.IsEmpty())
+		{
+		// No frames to transfer
+		_LOG_L4C1("No frames on waiting list");
+		}
+	else
+		{
+		TBool writeQueueWasEmpty = iWriteFrameBufList.IsEmpty();
+
+		CCsyMsgBufBpFrame* frame = NULL;
+		iWaitingForFcOffIter.SetToFirst();
+		while ((frame = iWaitingForFcOffIter++) != NULL)
+			{
+			if (frame->GetDlcNum() == aDlcNum)
+				{
+				iWaitingForFcOffList.Remove(*frame);
+				if (aPlaceOnWriteList)
+					{
+					_LOG_L4C1("Transferring frame to write list");
+					iWriteFrameBufList.AddLast(*frame);
+					}
+				else
+					{
+					// Adding frame to the free list
+					iMux0710Protocol->AddFrameFreeQ(frame);
+					}
+				}
+			}
+
+		if ((!iWriteFrameBufList.IsEmpty())&&(writeQueueWasEmpty)&&(!IsActive()))
+			{
+			_LOG_L4C1("Write queue was empty and not active - triggering write");
+			frame = GetFrameToWrite();
+			TInt ret = WriteFrame(frame);
+			if (ret)
+				{
+				_LOG_L1C2("Write delayed frame failed [ret=%d]",ret);
+
+				// Place the failed frame back on the list.
+				iWriteFrameBufList.AddFirst(*frame);
+				}
+			}
+		}
+
+	_LOG_L4C1("<<CCommFrameWriterAo::RemoveAnyDlcFramesFromWaitList");
+	}
+
+void CCommFrameWriterAo::CompleteWrite(const TUint8 aDlcNum, TInt aStatus)
+/**
+ * This method calls the DLC port interface to complete the write request.
+ *
+ * @param aDlcNum - DLC number of the port
+ */
+	{
+	_LOG_L4C3(">>CCommFrameWriterAo::CompleteWrite [aDlcNum=%d,aStatus=%d]",
+		aDlcNum,aStatus);
+
+	if (aDlcNum)
+		{
+		CPortC32InterfaceBase* port = iParent->FindPortC32Interface(aDlcNum);
+		if (port)
+			port->CompleteWriteRequest(aStatus);
+		else
+			{
+			_LOG_L1C2("** Port does not exist for aDlcNum=%d **",
+				aDlcNum);
+			// MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState));
+			}
+		}
+	else
+		{
+		// MAF tell mux control channel of send result
+		}
+
+	_LOG_L4C1("<<CCommFrameWriterAo::CompleteWrite");
+	}
+