diff -r 000000000000 -r af10295192d8 linklayercontrol/networkinterfacemgr/src/MCOMM.CPP --- /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 +#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(); + }