linklayercontrol/networkinterfacemgr/src/MCOMM.CPP
changeset 0 af10295192d8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/linklayercontrol/networkinterfacemgr/src/MCOMM.CPP	Tue Jan 26 15:23:49 2010 +0200
@@ -0,0 +1,376 @@
+// Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// Comms reader and writer mixin
+// 
+//
+
+/**
+ @file
+*/
+
+
+#include <nifutl.h>
+#include "NI_STD.H"
+#include "Ni_Log.h"
+
+class CCommLinkStatus;
+NONSHARABLE_CLASS(CCommReader) : public CActive
+/**
+@internalComponent
+*/
+	{
+friend class MComm;
+friend class CCommLinkStatus;
+public:
+	CCommReader(MComm* aComm, TInt aPriority);
+	virtual ~CCommReader();
+	virtual void RunL();
+	virtual void DoCancel();
+private:
+	void CompleteNow(TInt aError);
+private:
+	MComm *iComm;
+	};
+
+NONSHARABLE_CLASS(CCommWriter) : public CActive
+/**
+@internalComponent
+*/
+	{
+friend class MComm;
+friend class CCommLinkStatus;
+public:
+	CCommWriter(MComm* aComm, TInt aPriority);
+	virtual ~CCommWriter();
+	virtual void RunL();
+	virtual void DoCancel();
+private:
+	void CompleteNow(TInt aError);
+private:
+	MComm *iComm;
+	};
+
+NONSHARABLE_CLASS(CCommLinkStatus) : public CActive
+/**
+@internalComponent
+*/
+	{
+friend class MComm;
+public:
+	CCommLinkStatus(MComm* aComm);
+	virtual ~CCommLinkStatus();
+	virtual void RunL();
+	virtual void DoCancel();
+	virtual void NotifyDisconnect();
+	virtual void SetRole(TCommRole aRole);
+private:
+	MComm *iComm;
+	TUint iSignals;
+	TUint iSavedSignalState;
+	TCommRole iRole;
+	TUint iNotifyChangeSignalMask;
+	};
+
+#if !defined(__EABI__) && !defined(__X86GCC__)
+EXPORT_C MComm::MComm()
+/**
+Constructor
+*/
+	{
+	}
+#endif
+
+EXPORT_C void MComm::CommDelete()
+	{
+	delete iCommReader;
+	delete iCommWriter;
+	delete iCommLinkStatus;
+	iCommPort.Close();
+	iCommServer.Close();
+	}
+
+	
+EXPORT_C TInt MComm::CommOpen(const TDesC& aDll, const TDesC& aName, TCommAccess aMode)
+	{
+	return CommOpen(aDll, aName, aMode, ECommRoleDTE);
+	}
+
+EXPORT_C TInt MComm::CommOpen(const TDesC& aDll, const TDesC& aName, TCommAccess aMode, TCommRole aRole)
+	{
+
+	LOG( NifmanLog::Printf(_L("MComm:\t\t\tOpening CSY '%S' Port '%S' Role '%d'"), &aDll, &aName, aRole); )
+	
+	__ASSERT_ALWAYS(iCommLinkStatus!=NULL, NetUtilPanic(ENuPanic_NotConstructed));
+    iCommLinkStatus->SetRole(aRole);
+
+	TInt err;
+	if (err = iCommServer.Connect(), err!=KErrNone)
+		{
+		LOG( NifmanLog::Printf(_L("MComm:\t\t\tConnect failed (error is %d)"), err); )
+		return err;
+		}
+	if (aDll.Length()>0)
+		{
+		if (err = iCommServer.LoadCommModule(aDll), err!=KErrNone)
+			{
+			LOG( NifmanLog::Printf(_L("MComm:\t\t\tCould not open CSY '%S' (error is %d)"), &aDll, err); )
+
+			iCommServer.Close();
+			return err;
+			}
+		}
+	if (err = iCommPort.Open(iCommServer, aName, aMode, aRole), err!=KErrNone)
+		{
+		LOG( NifmanLog::Printf(_L("MComm:\t\t\tCould not open Port '%S' (error is %d)"), &aName, err); )
+
+		iCommServer.Close();
+		return err;
+		}
+	return KErrNone;
+	}
+
+EXPORT_C TInt MComm::CommOpen(const TDesC& aName, TCommAccess aMode)
+	{
+
+	LOG( NifmanLog::Printf(_L("MComm:\t\t\tOpening Port '%S'"), &aName); )
+
+	TInt err;
+	if (err = iCommServer.Connect(), err!=KErrNone)
+		return err;
+	if (err = iCommPort.Open(iCommServer, aName, aMode), err!=KErrNone)
+		{
+		LOG( NifmanLog::Printf(_L("MComm:\t\t\tCould not open Port '%S' (error is %d)"), &aName, err); )
+
+		iCommServer.Close();
+		return err;
+		}
+	return KErrNone;
+	}
+
+EXPORT_C void MComm::CommClose()
+	{
+	iCommReader->Cancel();
+	iCommWriter->Cancel();
+	iCommLinkStatus->Cancel();
+	iCommPort.Close();
+	iCommServer.Close();
+	}
+
+EXPORT_C void MComm::CommConstructL(TInt aReadPriority, TInt aWritePriority)
+	{
+	iCommReader = new (ELeave) CCommReader(this, aReadPriority);
+	iCommWriter = new (ELeave) CCommWriter(this, aWritePriority);
+	iCommLinkStatus = new (ELeave) CCommLinkStatus(this);
+	}
+
+EXPORT_C void MComm::CommWrite(const TDesC8& aDes)
+	{
+	__ASSERT_ALWAYS(iCommWriter!=NULL, NetUtilPanic(ENuPanic_NotConstructed));
+	iCommPort.Write(iCommWriter->iStatus, aDes);
+	iCommWriter->SetActive();
+	iCommLinkStatus->NotifyDisconnect();
+	}
+
+EXPORT_C void MComm::CommWriteReady()
+	{
+	__ASSERT_ALWAYS(iCommWriter!=NULL, NetUtilPanic(ENuPanic_NotConstructed));
+	iCommPort.Write(iCommWriter->iStatus, TPtrC8(NULL, 0));
+	iCommWriter->SetActive();
+	iCommLinkStatus->NotifyDisconnect();
+	}
+
+EXPORT_C TBool MComm::CommIsWriting() const
+	{
+
+	return iCommWriter->IsActive();
+	}
+
+EXPORT_C void MComm::CommRead(TDes8& aDes)
+	{
+	__ASSERT_ALWAYS(iCommReader!=NULL, NetUtilPanic(ENuPanic_NotConstructed));
+	iCommPort.Read(iCommReader->iStatus, aDes, aDes.Length());
+	iCommReader->SetActive();
+	iCommLinkStatus->NotifyDisconnect();
+	}
+
+EXPORT_C void MComm::CommReadOneOrMore(TDes8& aDes)
+	{
+	__ASSERT_ALWAYS(iCommReader!=NULL, NetUtilPanic(ENuPanic_NotConstructed));
+	iCommPort.ReadOneOrMore(iCommReader->iStatus, aDes);
+	iCommReader->SetActive();
+	iCommLinkStatus->NotifyDisconnect();
+	}
+
+EXPORT_C void MComm::CommReadReady()
+	{
+	__ASSERT_ALWAYS(iCommReader!=NULL, NetUtilPanic(ENuPanic_NotConstructed));
+	iCommReader->SetActive();
+	iCommLinkStatus->NotifyDisconnect();
+	}
+
+EXPORT_C TBool MComm::CommIsReading() const
+	{
+
+	return iCommReader->IsActive();
+	}
+
+EXPORT_C void MComm::CommCancel()
+	{
+	if (iCommWriter)
+		iCommWriter->Cancel();
+	if (iCommReader)
+		iCommReader->Cancel();
+	if (iCommLinkStatus)
+		iCommLinkStatus->Cancel();
+	}
+
+EXPORT_C void MComm::CommWriteCancel()
+	{
+	if (iCommWriter)
+		iCommWriter->Cancel();
+	}
+
+EXPORT_C void MComm::CommReadCancel()
+	{
+	if (iCommReader)
+		iCommReader->Cancel();
+	}
+
+//
+
+CCommWriter::CCommWriter(MComm* aComm, TInt aPriority)
+	: CActive(aPriority), iComm(aComm)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CCommWriter::~CCommWriter()
+	{
+	Cancel();
+	}
+
+void CCommWriter::RunL()
+	{
+	iComm->CommWriteCancel();
+	iComm->CommWriteComplete(iStatus.Int());
+	}
+
+void CCommWriter::DoCancel()
+	{
+	iComm->iCommPort.WriteCancel();
+	}
+
+void CCommWriter::CompleteNow(TInt aError)
+	{
+	TRequestStatus* statusPtr=&iStatus;
+	User::RequestComplete(statusPtr,aError);
+	}
+
+//
+
+CCommReader::CCommReader(MComm* aComm, TInt aPriority)
+	: CActive(aPriority), iComm(aComm)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+CCommReader::~CCommReader()
+	{
+	Cancel();
+	}
+
+void CCommReader::RunL()
+	{
+	iComm->CommReadCancel();
+	iComm->CommReadComplete(iStatus.Int());
+	}
+
+void CCommReader::DoCancel()
+	{
+	iComm->iCommPort.ReadCancel();
+	}
+
+void CCommReader::CompleteNow(TInt aError)
+	{
+	TRequestStatus* statusPtr=&iStatus;
+	User::RequestComplete(statusPtr,aError);
+	}
+
+//
+
+CCommLinkStatus::CCommLinkStatus(MComm* aComm)
+	: CActive(EPriorityHigh), iComm(aComm)
+	{
+	iRole = ECommRoleDTE;
+	iNotifyChangeSignalMask = KSignalDCD; // Defaults to KSignalDCD
+	CActiveScheduler::Add(this);
+	}
+
+CCommLinkStatus::~CCommLinkStatus()
+	{
+	Cancel();
+	}
+
+void CCommLinkStatus::SetRole(TCommRole aRole)
+    {
+    iRole = aRole;
+	if (iRole==ECommRoleDCE)
+	    {
+	    iNotifyChangeSignalMask = KSignalDTR;
+	    }
+	else
+	    {
+	    iNotifyChangeSignalMask = KSignalDCD; // Defaults to KSignalDCD
+	    }
+    
+    }
+
+
+void CCommLinkStatus::NotifyDisconnect()
+	{
+	if(IsActive())	// if we have already set up notification
+		return;		// there is nothing to do now
+
+	// get the current state of the line so when we get notification we can tell if it really has changed	
+	iSavedSignalState = iComm->iCommPort.Signals (iNotifyChangeSignalMask) & iNotifyChangeSignalMask ;
+	iComm->iCommPort.NotifySignalChange(iStatus, iSignals, iNotifyChangeSignalMask);
+
+	SetActive();
+	}
+
+void CCommLinkStatus::RunL()
+	{
+	// We should only tear down the connection if DCD/DTR (depending on role) is low.
+	//   and if the signal has changed (i.e. it was high)
+	if (!(iNotifyChangeSignalMask & iSignals) && (iNotifyChangeSignalMask & iSavedSignalState)) 
+		{
+		if (iComm->CommIsReading())
+			{
+			iComm->CommReadCancel();
+			iComm->CommReadComplete(KErrCommsLineFail);
+			}
+
+		if (iComm->CommIsWriting())
+			{
+			iComm->CommWriteCancel();
+			iComm->CommWriteComplete(KErrCommsLineFail);
+			}
+		}
+		iSavedSignalState = iSignals & iNotifyChangeSignalMask ;	// update saved state
+	}
+
+void CCommLinkStatus::DoCancel()
+	{
+	iComm->iCommPort.NotifySignalChangeCancel();
+	}