--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/obex/obexprotocol/obextransport/src/obextransportcontrollerbase.cpp Tue Oct 19 11:00:12 2010 +0800
@@ -0,0 +1,594 @@
+// Copyright (c) 2005-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 <ecom/ecom.h>
+#include <obex/transport/obextransportcontrollerbase.h>
+#include <obex/internal/mobexnotifyextend.h>
+#include <obexirtransportinfo.h>
+#include <obex/internal/obexactiverw.h>
+#include <obextransportinfo.h>
+#include <obex/internal/obexpacket.h>
+#include <obexpanics.h>
+#include "ObexTransportUtil.h"
+#include "obexconnectdata.h"
+#include "logger.h"
+#include "obextransportfaults.h"
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "OBEXCT");
+#endif
+
+//Category used for internal panics
+_LIT(KPanicCat, "TransCTBase");
+
+// The minimum allowed number of 'transport controller' implementations. If
+// NewL doesn't find at least this many, then in debug NewL panics, and in
+// release it leaves.
+const TUint KMinimumNumImplementations = 1;
+
+/**
+Constructs a CObexTransportControllerBase PlugIn object.
+
+@internalTechnology
+@return A new CObexTransportControllerBase PlugIn object
+@panic TransCTBase EInvalidNumberOfTransportImplementations if there is more than one implementation for a given interface uid and transport name (equal to the default data in the plugin resource file
+*/
+EXPORT_C CObexTransportControllerBase* CObexTransportControllerBase::NewL(TObexTransportInfo& aTransportInfo)
+ {
+ LOG_LINE
+ LOG_STATIC_FUNC_ENTRY
+
+ //Making a copy as Collapse modifies the original iTransportName
+ TBuf<60> transportName = aTransportInfo.iTransportName;
+ TPtrC8 params = transportName.Collapse();
+ TEComResolverParams resolverParams;
+ resolverParams.SetDataType(*reinterpret_cast<TDesC8*>(¶ms));
+
+ RImplInfoPtrArray implInfoArray;
+ REComSession::ListImplementationsL(TUid::Uid(KObexTransportControllerInterfaceUid), resolverParams, KRomOnlyResolverUid, implInfoArray);
+
+ CleanupResetAndDestroyPushL(implInfoArray);
+ __ASSERT_DEBUG(implInfoArray.Count() <= KMinimumNumImplementations, PANIC(KObexTransportPanicCat, EInvalidNumberOfTransportImplementations) );
+ if (implInfoArray.Count() < KMinimumNumImplementations)
+ {
+ User::Leave(KErrNotFound);
+ }
+
+ const TUid uid = implInfoArray[KMinimumNumImplementations - 1]->ImplementationUid();
+ CleanupStack::PopAndDestroy(&implInfoArray);
+
+ CObexTransportControllerBase* ptr = reinterpret_cast<CObexTransportControllerBase*>
+ (REComSession::CreateImplementationL(uid, _FOFF(CObexTransportControllerBase, iPrivateEComUID),
+ reinterpret_cast<TAny*>(&aTransportInfo)));
+
+ CleanupStack::PushL(ptr);
+ // Do any base construction here. This may in future include allocation of
+ // iFuture1.
+ ptr->BaseConstructL();
+ CleanupStack::Pop(ptr);
+ return ptr;
+ }
+
+/**
+Constructor.
+
+@publishedPartner
+@released
+*/
+EXPORT_C CObexTransportControllerBase::CObexTransportControllerBase()
+ {
+ LOG_LINE
+ LOG_FUNC
+ }
+
+/**
+This function is a place holder for future use. If iFuture1 variable is used
+it will need this function for any allocation required.
+This function is called from CObexTransportControllerBase::NewL.
+*/
+void CObexTransportControllerBase::BaseConstructL()
+ {
+ LOG_LINE
+ LOG_FUNC
+ }
+
+/**
+Sets the owner information from the received aOwner
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::SetOwner(MObexNotifyExtend& aOwner)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ __ASSERT_ALWAYS(iOwner==NULL, PANIC(KPanicCat, EOwnerAlreadySet));
+ iOwner = &aOwner;
+ }
+
+/**
+Destructor.
+
+@publishedPartner
+@released
+*/
+EXPORT_C CObexTransportControllerBase::~CObexTransportControllerBase()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ delete iConnector;
+ DeleteTransport();
+ delete iTransportInfo;
+
+ REComSession::DestroyedImplementation(iPrivateEComUID);
+ }
+/**
+Cancels outstanding reads or writes
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::CancelTransfers()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ if (iActiveReader)
+ {
+ iActiveReader->Cancel();
+ }
+ if (iActiveWriter)
+ {
+ iActiveWriter->Cancel();
+ }
+ }
+/**
+Calls on the constructor to take down the transport
+
+@internalTechnology
+@return TBool ETrue if the transport was taken down
+*/
+EXPORT_C TBool CObexTransportControllerBase::BringTransportDown()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ DeleteTransport();
+ return iConnector->BringTransportDown();
+ }
+
+/**
+Calls ConnectL on the connector
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::ConnectL ()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ iConnector->ConnectL();
+ }
+
+/**
+Ask Connector to cancel connect
+
+@see CObexTransportControllerBase::ConnectL
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::CancelConnect()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ iConnector->CancelConnect();
+ }
+
+/**
+Calls accept connection on the connector
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::AcceptConnectionL()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ iConnector->AcceptL();
+ }
+
+/**
+Calls Cancel Accept on he connector
+
+@see CObexTransportControllerBase::AcceptConnectionL
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::CancelAccept()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ if ( iConnector)
+ {
+ iConnector->CancelAccept();
+ }
+ }
+
+/**
+Calls signal transport error on the connector
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::SignalTransportError()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ // If this is called during construction, iConnector could be NULL
+ if(iConnector)
+ {
+ iConnector->SignalTransportError();
+ }
+ }
+
+/**
+returns the send packet
+
+@return CObexPacket the packet that will be sent
+@internalTechnology
+*/
+EXPORT_C CObexPacket& CObexTransportControllerBase::SendPacket ()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return *iSendPacket;
+ }
+
+/**
+Returns the packet received
+
+@return CObexPacket the packet that will be sent
+@internalTechnology
+*/
+EXPORT_C CObexPacket& CObexTransportControllerBase::ReceivePacket ()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return *iReceivePacket;
+ }
+
+/**
+Ask active writer to do a send
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::Send ()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ LOG3(_L8("Packet Sent, Opcode 0x%2x (0x%2x with final bit cleared), Length %d"), (iSendPacket->IsFinal() ? (iSendPacket->Opcode() | KObexPacketFinalBit) : iSendPacket->Opcode()), iSendPacket->Opcode(), iSendPacket->PacketSize());
+ FTRACE(iSendPacket->Dump ());
+
+ iActiveWriter->Transfer (*iSendPacket);
+ }
+
+/**
+Init the send packet wtih the received, aOpcode, set final to true, and send the packet
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::Send (TObexOpcode aOpcode)
+ {
+ LOG_LINE
+ LOG_FUNC
+ LOG1(_L8("\taOpcode = %d"), aOpcode);
+
+ iSendPacket->Init (aOpcode);
+ iSendPacket->SetFinal (ETrue);
+ Send ();
+ }
+
+/**
+Ask activer reader to do a read
+
+@internalTechnology
+*/
+EXPORT_C void CObexTransportControllerBase::Receive ()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ iActiveReader->Transfer (*iReceivePacket);
+ }
+
+/**
+Is there a write outstanding
+
+@return TBool return ETrue is there is a write activer otherwise EFalse
+@internalTechnology
+*/
+EXPORT_C TBool CObexTransportControllerBase::IsWriteActive () const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ if (iActiveWriter)
+ {
+ return (iActiveWriter->IsActive());
+ }
+ else // this has been added incase of null iActiveWriter
+ {
+ return EFalse;
+ }
+ }
+
+/**
+Insert local Connection info with the received, aVersion, aFlags and from iReceivePacket into the receive packet, aPacket
+
+@return TInt KErrNone or a symbian error
+@param aPacket the packet that is updated with local connection info
+@param aVersion
+@param aFlags
+@internalTechnology
+*/
+EXPORT_C TInt CObexTransportControllerBase::InsertLocalConnectInfo (CObexPacket &aPacket, TUint8 aVersion, TUint8 aFlags)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ if (iReceivePacket)
+ {
+ TObexConnectData localinfo;
+ localinfo.iVersion = aVersion;
+ localinfo.iFlags = aFlags;
+ localinfo.iMaxPacketLength = iReceivePacket->DataLimit(); // maximum packet length we can receive
+ return (aPacket.InsertData (localinfo));
+ }
+ else
+ {
+ return KErrGeneral;
+ }
+ }
+
+/**
+Extract the local information from the received packet
+
+@return EFalse- failed to extract the information. ETrue- extraction succeeded.
+@param aPacket The packet from which local connection info is extracted
+@param aVersion
+@param aFlags
+@internalTechnology
+*/
+EXPORT_C TBool CObexTransportControllerBase::ExtractRemoteConnectInfo(CObexPacket &aPacket, TUint8& aVersion, TUint8& aFlags)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ if (iSendPacket)
+ {
+ TObexConnectData remoteinfo;
+ if (!aPacket.ExtractData (remoteinfo))
+ {
+ return EFalse;
+ }
+ aVersion = remoteinfo.iVersion;
+ aFlags = remoteinfo.iFlags;
+
+ // Set the send buffer data limit (i.e. how much OBEX can use) to match the size of the
+ // remote receive buffer (the setter function ensures it's a legal size)
+ (void)iSendPacket->SetLegalDataLimit (remoteinfo.iMaxPacketLength);
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+/**
+@internalTechnology
+*/
+void CObexTransportControllerBase::ConstructPacketsL()
+ {
+ LOG_FUNC
+
+ // Set actual packet sizes
+ // Receive must be at least KObexPacketDefaultSize to maintain functional compatibility with previous implentations
+ // (to ensure that remote ends that ignore how big we say our receive buffer is get that same grace on buffer overflow)
+ __ASSERT_DEBUG(iTransportInfo, PANIC(KPanicCat, ETransportNullPointer));
+ TUint16 receivePacketBufferSize = Max ( iTransportInfo->iReceiveMtu, KObexPacketDefaultSize );
+ TUint16 sendPacketBufferSize = iTransportInfo->iTransmitMtu;
+
+ // Set initial "software throttle" for packets (how big OBEX says they are)
+ // Send packet is set to miniumum, so initial transmit cannot overflow remote end
+ TUint16 receivePacketDataLimit = GetReceivePacketDataLimit();
+ TUint16 sendPacketDataLimit = KObexPacketMinSize;
+
+ LOG2(_L8("CObexTransportControllerBase::ConstructPacketsL send buffer %d send data limit %d"), sendPacketBufferSize, sendPacketDataLimit);
+ LOG2(_L8("CObexTransportControllerBase::ConstructPacketsL receive buffer %d receive data limit %d"), receivePacketBufferSize, receivePacketDataLimit);
+
+ // Create the packets
+ iSendPacket = CObexPacket::NewL(sendPacketBufferSize, sendPacketDataLimit);
+ iReceivePacket = CObexPacket::NewL(receivePacketBufferSize, receivePacketDataLimit);
+ }
+
+/**
+Gets the socket associated with the connector and asks the socket for its remote name.
+This can be cast to the appropriate TSockAddr-derived class TIrdaSockAddr for IrDA.
+
+@publishedPartner
+@released
+*/
+EXPORT_C void CObexTransportControllerBase::RemoteAddr(TSockAddr& aAddr)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ DoRemoteAddr(aAddr);
+ }
+
+/**
+Returns true if the derived transport can re-connect when an obex connection is re-connected
+This is used to determine whether to take the transport down when an obex connection has been disconnected
+
+@see DoIsTransportRestartable
+@return TBool return ETrue if the derived transport can support re-connection when obex re-connects
+@publishedPartner
+@released
+*/
+EXPORT_C TBool CObexTransportControllerBase::IsTransportRestartable() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return DoIsTransportRestartable();
+ }
+
+//MObexTransport Notify Protected
+/**
+Process a Packet. Upcall to the owner
+
+@publishedPartner
+@released
+*/
+EXPORT_C void CObexTransportControllerBase::DoProcess(CObexPacket &aPacket)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ __ASSERT_DEBUG(iOwner, PANIC(KPanicCat, ETransportNullPointer));
+ iOwner->Process(aPacket);
+ }
+
+/**
+Reports and error to the owner
+
+@publishedPartner
+@released
+*/
+EXPORT_C void CObexTransportControllerBase::DoError(TInt aError)
+ {
+ LOG_LINE
+ LOG_FUNC
+ LOG1(_L8("\taError = %d"), aError);
+
+ __ASSERT_DEBUG(iOwner, PANIC(KPanicCat, ETransportNullPointer));
+ iOwner->Error(aError);
+ }
+
+/**
+Create the transport objects and reports that the transport is up to the owner
+
+@publishedPartner
+@released
+*/
+EXPORT_C void CObexTransportControllerBase::DoTransportUp(TObexConnectionInfo& aInfo)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ DeleteTransport();
+ TRAPD(err, InitialiseTransportL(aInfo));
+ if(err != KErrNone)
+ {
+ TransportUpError(err);
+ }
+ else
+ {
+ __ASSERT_DEBUG(iOwner, PANIC(KPanicCat, ETransportNullPointer));
+ iOwner->TransportUp();
+ Receive();
+ }
+ }
+
+void CObexTransportControllerBase::InitialiseTransportL(TObexConnectionInfo& aInfo)
+ {
+ NewTransportL(aInfo);
+ ConstructPacketsL();
+ }
+
+void CObexTransportControllerBase::TransportUpError(TInt aError)
+ {
+ // At this stage the transport controller will have a connection set-up.
+ // As a result if we get an error while setting up Obex we should bring
+ // the transport down (the owner has alrady been informed of the error,
+ // but we shouldn't expect them to have to bring the transport down).
+ TBool broughtDown = BringTransportDown();
+ // If we failed to bring down the transport there isn't much
+ // more we can do.
+ (void)broughtDown;
+
+ Error(aError); // Signal error indication
+ }
+
+/**
+Signals that an event related to processing the packet has occurred.
+@param aEvent The event that has occurred.
+*/
+EXPORT_C void CObexTransportControllerBase::DoSignalPacketProcessEvent(TObexPacketProcessEvent aEvent)
+ {
+ LOG_FUNC
+
+ __ASSERT_DEBUG(iOwner, PANIC(KPanicCat, ETransportNullPointer));
+ iOwner->SignalPacketProcessEvent(aEvent);
+ }
+
+/**
+Returns a pointer to the transport info being used by the transport. This may
+be cast to the transport info type associated with the known concrete
+transport controller.
+*/
+EXPORT_C const TObexTransportInfo* CObexTransportControllerBase::TransportInfo() const
+ {
+ LOG_FUNC
+
+ return iTransportInfo;
+ }
+
+/**
+This function is part of the extension pattern and must be implemented by all derived instantiable classes.
+By default this returns null. Any derived class that is required to extend its interface and that of this base
+class returns its new interface in the form of an M class, that it extends, if and only if the corresponding TUid,
+aUid, is received. Otherwise the function calls the base class implementation, returning NULL.
+
+@return The M Class representing the extension to the interface otherwise NULL
+@param aUid The uid associated with the M Class that is being implemented
+@publishedPartner
+@released
+*/
+EXPORT_C TAny* CObexTransportControllerBase::GetInterface(TUid /*aUid*/)
+ {
+ LOG_FUNC
+
+ return NULL;
+ }
+
+//private
+void CObexTransportControllerBase::DeleteTransport()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ delete iActiveWriter;
+ delete iActiveReader;
+ delete iReceivePacket;
+ delete iSendPacket;
+ iActiveWriter = NULL;
+ iActiveReader = NULL;
+ iReceivePacket = NULL;
+ iSendPacket = NULL;
+ }