--- /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();
+ }