diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btcomm/src/btcomm.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btcomm/src/btcomm.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,740 @@ +// 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: +// + +#include +#include +#include "btcomm.h" +#include "btstate.h" + +#ifdef __FLOG_ACTIVE +_LIT8(KLogComponent, LOG_COMPONENT_BT_COMM); +#endif + +//********************************************************************** +// BTCOMM CSY ENTRY POINT CODE +//********************************************************************** + +extern "C" + { + IMPORT_C CSerial* LibEntry(); // Force export + } + +EXPORT_C CSerial* LibEntry() +/** + Lib main entry point. +**/ + { + CBTPortFactory* c=NULL; + TRAPD(ret,c=CBTPortFactory::NewL()); + if (ret!=KErrNone) + return NULL; + return c; + } + + + +//********************************************************************** +// BTCOMM PORT FACTORY CODE +//********************************************************************** + +#pragma warning (disable : 4100) // Unreferenced formal parameter + +static void CleanupCObject(TAny* aCObject) +/** + Clean up a CObject. + This static callback is invoked upon destruction of factory + by c32 to close it down. +**/ + { + LOG_STATIC_FUNC + ((CObject*)aCObject)->Close(); + } + +CPort* CBTPortFactory::NewPortL(const TUint aUnit) +/** + CBTPortFactory NewPortL. + Create a new port for the supplied unit number. +**/ + { + LOG_FUNC + __ASSERT_ALWAYS(aUnit<=KCommHighUnit,User::Leave(KErrNotSupported)); + // need to pass the factory instance through to the port. + CBTPort *port=CBTPort::NewL(aUnit,iPortStateFactory); + return port; + } + +void CBTPortFactory::Info(TSerialInfo& aSerialInfo) +/** + Fill in the supplied structure. +**/ + { + LOG_FUNC + aSerialInfo.iDescription=SERIAL_DESCRIPTION; + aSerialInfo.iName=SERIAL_NAME; + aSerialInfo.iLowUnit=KCommLowUnit; + aSerialInfo.iHighUnit=KCommHighUnit; + } + +void CBTPortFactory::ConstructL() +/** + Construct CBTPort Factory. + Also construct the CBTPortStateFactory here too. +**/ + { + CONNECT_LOGGER + LOG_FUNC + + iPortStateFactory=CBTPortStateFactory::NewL(); + TName name(SERIAL_NAME); + SetNameL(&name); + } + +CBTPortFactory* CBTPortFactory::NewL() +/** + Create new CBTPortFactory. + This factory is derived from CSerial. + Corresponds to the BTCOMM in BTCOMM::0 etc. +**/ + { + LOG_STATIC_FUNC + CBTPortFactory* c=new(ELeave) CBTPortFactory; + CleanupStack::PushL(TCleanupItem(CleanupCObject, c)); + c->ConstructL(); + CleanupStack::Pop(); + return c; + } + +CBTPortFactory::CBTPortFactory() +/** + CBTPortFactory c'tor. +**/ + { + LOG_FUNC +// iVersion=TVersion(KMajorVersion,KMinorVersion,KBuild); + } + +CBTPortFactory::~CBTPortFactory() +/** + CBTPortFactory destructor. +**/ + { + LOG_FUNC + delete iPortStateFactory; + + CLOSE_LOGGER + } + +TSecurityPolicy CBTPortFactory::PortPlatSecCapability (TUint /**aPort*/) const + //return the security policy for the given port number, aPort. All the ports + //are treated the same so always return a security policy defining local services + { + LOG_FUNC + return TSecurityPolicy(ECapabilityLocalServices); + } +//********************************************************************** +// BTCOMM PORT CODE +//********************************************************************** + +CBTPort::CBTPort() +/** + C'Tor sets-up the TCommconfigV01 and TCommCapsV02 structs of the CSY. +**/ + { + LOG_FUNC + + iConfig.iRate = EBps9600; + iConfig.iDataBits = EData8; + iConfig.iStopBits = EStop1; + iConfig.iParity = EParityNone; + iConfig.iFifo = EFifoEnable; + iConfig.iHandshake = 0; // KConfigObeyCTS + iConfig.iParityError = KConfigParityErrorIgnore; + iConfig.iSIREnable = ESIRDisable; + iConfig.iTerminatorCount = 0; + iConfig.iXonChar = 0x11; // XON + iConfig.iXoffChar = 0x13; // XOFF + iConfig.iSpecialRate = 0; + iConfig.iParityErrorChar = 0; + + // set CSY TCommCapsV02 capabilities struct + iCaps.iRate = KCapsBps9600; + iCaps.iDataBits = KCapsData8; + iCaps.iStopBits = KCapsStop1; + iCaps.iParity = KCapsParityNone; + iCaps.iHandshake = 0; + iCaps.iSignals = 0; + iCaps.iFifo = KCapsHasFifo; + iCaps.iSIR = 0; + iCaps.iNotificationCaps = 0; + iCaps.iRoleCaps = 0; + iCaps.iFlowControlCaps = 0; + } + +CBTPort* CBTPort::NewL(TUint aUnit,CBTPortStateFactory* aFactory) +/** + CBTPort NewL, make a new CPort for the Comm server. + This port is derived from CPort. This CBTPort is used by + the Comms server to serve all the client RComm requests. + + @param aUnit Corresponds to the digit in BTCOMM::0 etc. + Note that each digit corresponds to a different + legacy CSY port. + @param aFactory Is the factory object used to reach each state +*/ + { + LOG_STATIC_FUNC + CBTPort* p=new(ELeave) CBTPort; + CleanupStack::PushL(TCleanupItem(CleanupCObject, p)); + p->ConstructL(aUnit,aFactory); + CleanupStack::Pop(); + return p; + } + +void CBTPort::ConstructL(TUint aUnit,CBTPortStateFactory* aFactory) +/** + ConstructL(..) is the second phase construction of CBTPort. + + This sets the CSY role to DTE, instantiates the state machine and + registers the CPort name to whatever the aUnit is. + + @param aUnit is the virtual BTComm port number + @param aFactory is the state machine factory used to access the + proxy states +**/ + { + LOG_FUNC + iRole=ECommRoleDTE; // set to DTE by default. + iPortProxy=CBTPortProxy::NewL(TUint32(aUnit),this,aFactory); + TName name; + name.Format(_L("%d"), aUnit); + SetNameL(&name); + } + +CBTPort::~CBTPort() +/** + The CBTPort destructor is either invoked immediately from destruct or + via deferred deletion mechanism via the "active shutterdowner". +**/ + { + LOG_FUNC + delete iPortProxy; + } + +void CBTPort::Destruct() +/** + CBTPort Destruct, is invoked by c32 to destroy the port. + + At this point it is necessary to either destroy the port immediately or + invoke a deferred deletion "active shutterdowner" mechanism. +**/ + { + LOG_FUNC + + if (iPortProxy) + iPortProxy->Close(); + } + +void CBTPort::DestructNow() +/** + To be called by CBTPortProxy to signal the shutdown. +*/ + { + LOG_FUNC + delete this; + } + +void CBTPort::StartRead(const TAny* aClientBuffer,TInt aLength) +/** + Reads any inbound data into the client buffer supplied. + + The read is passed over to the CBTPortProxy for completion and when it is + eventually completed to RFComm; read completion is signalled to the client + by invoking the CPort::ReadCompleted mechanism. + + @param aClientBuffer is the pointer to the client buffer to be filled + @param aLength the desired amount of bytes to be filled in the buffer +**/ + { + LOG_FUNC + iPortProxy->Read(aClientBuffer,aLength); + } + +void CBTPort::ReadCancel() +/** + Cancels the pending read. +**/ + { + LOG_FUNC + iPortProxy->ReadCancel(); + } + +TInt CBTPort::QueryReceiveBuffer(TInt& aLength) const +/** + Retrieval of the number of bytes waiting in the receive buffer. + + @param aLength is set to zero + @return KErrNone +*/ + { + LOG_FUNC + return iPortProxy->QueryReceiveBuffer(aLength); + } + +void CBTPort::ResetBuffers(TUint aFlags) +/** + Resets the Rx buffers, does nothing about the Tx buffer. + The reason why we don't do anything about the Tx buffer is + because the CSY passes the client data straight to ESock. + + @param aFlags may be KCommResetRx, KCommResetTx or KCommResetRx|KCommResetTx +**/ + { + LOG_FUNC + if((aFlags==KCommResetTx)||(aFlags==0)) //only + { + return; //nothing to do + } + iPortProxy->ResetRxBuffer();// holds true for the case > KCommResetRx|KCommResetTx + // as well, since we cannot signal the client + } + +void CBTPort::StartWrite(const TAny* aClientBuffer, TInt aLength) +/** + Uses the supplied buffer to read out data from. + These data are destined to be send to the RFComm layer of the Bluetooth stack. + + @param aClientBuffer the pointer to the clients buffer from which to read from + @param aLength the number of desired bytes to be read out. +*/ + { + LOG_FUNC + iPortProxy->Write(aClientBuffer,aLength); + } + +void CBTPort::WriteCancel() +/** + Cancels the last requested Write if possible. +*/ + { + LOG_FUNC + iPortProxy->WriteCancel(); + } + +void CBTPort::Break(TInt /*aTime*/) +/** + CBTPort Break is Not supported. +**/ + { + LOG_FUNC + } + +void CBTPort::BreakCancel() +/** + CBTPort BreakCancel is not supported. +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* BreakCancel *) used by client")); + } + +TInt CBTPort::GetConfig(TDes8& aPackage) const +/** + CBTPort GetConfig gives the CSY's configuration TCommConfigV01 to the client. + + @param aPackage is the packaged TCommConfigV01 supplied by the client, to be filled. + @return KErrNone always +*/ + { + LOG_FUNC + // copy back local iConfig + aPackage.FillZ(); + TPckg cfg(iConfig); + aPackage.Copy(cfg); + return KErrNone; + } + +TInt CBTPort::SetConfig(const TDesC8& aPackage) +/** + CBTPort SetConfig allows for the configuration of the CSY. + Currently the only configuration which is allowed and is meaningful, is the + configuration associated with terminated reads; the rest are not honoured. + + @param aPackage is a packaged TCommConfigV01 struct. + @return KErrNone or KErrNotSupported if the terminator count is + greater than KConfigMaxTerminators + +*/ + { + LOG_FUNC + TCommConfigV01 c; + Mem::FillZ(&c,sizeof(c)); + TInt len=Min(aPackage.Length(),sizeof(c)); + Mem::Copy(&c, aPackage.Ptr(),len); + if(c.iTerminatorCount) + { + if (c.iTerminatorCount>KConfigMaxTerminators) + { + return KErrNotSupported; + } + else + { + iPortProxy->iTerminatedReads=ETrue; + iPortProxy->iTerm.iTerminatorCount=c.iTerminatorCount; + for (TInt i=0;iiTerm.iTerminatorChars[i]=c.iTerminator[i]; + } + } + } + else + { + iPortProxy->iTerminatedReads=EFalse; + } + iConfig=c; + return KErrNone; + } + +TInt CBTPort::SetServerConfig(const TDesC8& /*aTCommServerConfigV01-Package*/) +/** + CBTPort SetServerConfig is not supported. + SetServerConfig is otherwise used to mandate the buffering strategy within + the CSY. The Bluetooth CSY uses it's own buffering startegy which is not + exposed to the client nor it is reconfigurable by it. + + @return KErrNotSupported +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* SetServerConfig *) used by client")); + return KErrNotSupported; + } + +TInt CBTPort::GetServerConfig(TDes8& /*aPackage*/) +/** + CBTPort GetServerConfig is not supported + + @return KErrNotSupported +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* GetServerConfig *) used by client")); + return KErrNotSupported; + } + +TInt CBTPort::GetCaps(TDes8& aPackage) +/** + Get current Bluetooth CSY serial port emulation capabilities. + Capabilities are defined in c32comm.h. + + @param aPackage can either be a packaged TCommCapsV01 or TCommCapsV02 + @return KErrNone +*/ + { + LOG_FUNC + aPackage.FillZ(); + TPckg caps(iCaps); + TInt len=Min(caps.Length(),aPackage.Length()); + //to be on the safe side just in case the package is v01 + aPackage.Copy(caps.Left(len)); + return KErrNone; + } + +TInt CBTPort::GetSignals(TUint& /*aSignals*/) +/** + GetSignal is not supported. + Would otherwise gets current signal emulation states. + + @return KErrNotSupported +*/ + { + // Signals are set as follows (from c32comm.h): + // KSignalCTS, KSignalDSR, KSignalDCD, KSignalRNG, KSignalRTS, KSignalDTR. + + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* GetSignals *) used by client")); + return KErrNotSupported; + } + +TInt CBTPort::SetSignalsToMark(TUint /*aSignals*/) +/** + SetSignalsToMark is not supported. + + @return KErrNotSupported +**/ + { + // Set signals to Mark (high). + // Signals are defined as follows (from c32comm.h): + // KSignalCTS, KSignalDSR, KSignalDCD, KSignalRNG, KSignalRTS, KSignalDTR. + + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* SetSignalsToMark *) used by client")); + return KErrNotSupported; + } + +TInt CBTPort::SetSignalsToSpace(TUint /*aSignals*/) +/** + Set Signals to Space is not supported. + + @return KErrNotSupported +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* SetSignalsToSpace *) used by client")); + // Signals are defined as follows (from c32comm.h): + // KSignalCTS, KSignalDSR, KSignalDCD, KSignalRNG, KSignalRTS, KSignalDTR. + + return KErrNotSupported; + } + +TInt CBTPort::SetReceiveBufferLength(TInt /*aLength*/) +/** + Setting of the receiver buffer length is not allowed. + + @return KErrNotSupported +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* SetReceiveBufferLength *) used by client")); + return KErrNotSupported; + } + +TInt CBTPort::GetReceiveBufferLength(TInt& aLength) const +/** + Assigns to the parameter the max length of the CSY's receive buffer. + + @param aLength the max size of the receive buffer in the CSY + @return KErrNone or an appropriate error code +*/ + { + LOG_FUNC + return iPortProxy->GetReceiveBufferLength(aLength); + } + +void CBTPort::FreeMemory() +/** + CBTPort FreeMemory, this function is called by nothing and is not supported. +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* FreeMemory *) used by client")); + } + +//*********************** EXTRAS FOR C32 v6 ************************ + +void CBTPort::NotifySignalChange(TUint /*aChange*/) +/** + Signal Change Notification is not supported by the Bluetooth CSY. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifySignalChange *) used by client")); + } + + +void CBTPort::NotifySignalChangeCancel(void) +/** + Notify Signal Change Cancel is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + + Note: this method may be called implicitly by RComm::Cancel and will + have no effect. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifySignalChangeCancel *) used by client")); + } + +void CBTPort::NotifyConfigChange(void) +/** + NotifyConfigChange is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyConfigChange *) used by client")); + } + +void CBTPort::NotifyConfigChangeCancel(void) +/** + NotifyConfigChangeCancel is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + + Note: this method may be called implicitly by RComm::Cancel and will + have no effect. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyConfigChangeCancel *) used by client")); + } + +void CBTPort::NotifyFlowControlChange(void) +/** + NotifyFlowControlChange is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyFlowControlChange *) used by client")); + } + +void CBTPort::NotifyFlowControlChangeCancel(void) +/** + NotifyFlowControlChangeCancel is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + + Note: this method may be called implicitly by RComm::Cancel and will + have no effect. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyFlowControlChangeCancel *) used by client")); + } + +void CBTPort::NotifyBreak(void) +/** + Notify Break is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyBreak *) used by client")); + } + +void CBTPort::NotifyBreakCancel(void) +/** + NotifyBreakCancel is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + + Note: this method may be called implicitly by RComm::Cancel and will + have no effect. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyBreakCancel *) used by client")); + } + +void CBTPort::NotifyDataAvailable(void) +/** + NotifyDataAvailable is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyDataAvailable *) used by client")); + } + +void CBTPort::NotifyDataAvailableCancel(void) +/** + NotifyDataAvailableCancel is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + + Note: this method may be called implicitly by RComm::Cancel and will + have no effect. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyDataAvailableCancel *)used by client")); + } + +void CBTPort::NotifyOutputEmpty(void) +/** + NotifyOutputEmptyIndication is not supported. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyOutputEmpty *) used by client")); + } + +void CBTPort::NotifyOutputEmptyCancel(void) +/** + NotifyOutputEmptyCancel. + RComm::Caps(..) should be called to read the CSY's capabilities, + which indicate that notification is not supported. + + Note: this method may be called implicitly by RComm::Cancel and will + have no effect. + +*/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* NotifyOutputEmptyCancel *) used by client")); + } + +TInt CBTPort::GetFlowControlStatus(TFlowControl& /*aFlowControl*/) +/** + Getting of serial port emulation flow control status is not supported. + + @return KErrNotSupported +**/ + { + LOG_FUNC + LOG(_L("CBTPort: [WARNING] Non-implemented feature (* GetFlowControlStatus *) used by client")); + return KErrNotSupported; + } + +TInt CBTPort::GetRole(TCommRole& aRole) +/** + Get serial port emulation mode. + Options in general are: ECommRoleDTE or ECommRoleDCE but the Bluetooth CSY + only supports the DTE role, hence aRole will always be set to DTE for now. +**/ + { + LOG_FUNC + aRole=iRole; + return KErrNone; + } + +TInt CBTPort::SetRole(TCommRole aRole) +/** + Set serial port emulation mode, options are: ECommRoleDTE only. + If the client tries to open the RComm session as a DCE then the client call + will cause a Leave in CPort::DoOpenL(..), this will subsequently be traped + and the error will be propagated to the client (which may Panic with a + EReqActiveObjectLeave if the error doesn't get handled). + + @param aRole should be ECommRoleDTE + @return KErrNone or KErrNotSupported +*/ + { + LOG_FUNC + if(aRole==ECommRoleDTE) + { + iRole=aRole; + return KErrNone; + } + return KErrNotSupported; + } + +#pragma warning (default : 4100) // Unreferenced formal parameter +