--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/obex/obexprotocol/obex/src/OBEX.CPP Tue Feb 02 01:11:40 2010 +0200
@@ -0,0 +1,962 @@
+// 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:
+//
+
+/**
+ @file
+ @internalComponent
+*/
+
+
+#include <charconv.h>
+#include <utf.h>
+#include <obex.h>
+#include <obex/internal/obexinternalheader.h>
+#include <obextransportinfo.h>
+#include <obexirtransportinfo.h>
+#include <obex/transport/obextransportcontrollerbase.h>
+#include <obex/internal/obexpacket.h>
+#include "logger.h"
+#include "obexsetpathdata.h"
+#include "OBEXUTIL.H"
+#include "authentication.h"
+#include <ecom/ecom.h>
+
+#ifdef __FLOG_ACTIVE
+_LIT8(KLogComponent, "OBEX");
+#endif
+
+/**
+Constructor - set initial values and copy in protocol policy information
+@internalComponent
+*/
+CObex::CObex()
+ {
+#ifdef _DEBUG
+ CObexLog::Connect();
+#endif
+ FLOG(_L("Creating CObex"));
+ SetConnectState(EConnIdle);
+ }
+
+void CObex::ConstructL(TObexTransportInfo& aObexTransportInfo)
+ {
+ iTransportController = CObexTransportControllerBase::NewL(aObexTransportInfo);
+ iAuthEngine = CObexAuthenticator::NewL();
+ iSuppressedObexAuthElements = EObexNoSuppressedAuthElements;
+ }
+
+/**
+Destructor.
+*/
+CObex::~CObex()
+ {
+
+ delete iTransportController;
+ delete iAuthEngine;
+ delete iChallPassword;
+ delete iRespPassword;
+ delete iRemoteUID;
+ delete iRemoteRealm;
+ delete iRxChallenge;
+
+ // This must be done AFTER destroying the transport controller.
+ REComSession::FinalClose();
+
+ // iNotifyHandler is deleted in the derived classes where it is instantiated
+
+#ifdef _DEBUG
+ CObexLog::Close();
+#endif
+ }
+
+/**
+Get the socket address of the remote device.
+
+This is the address of the device OBEX is connected to over an IrDA or Bluetooth
+socket.
+
+@param aAddr Socket address.
+
+@publishedAll
+@released
+*/
+EXPORT_C void CObex::RemoteAddr(TSockAddr& aAddr)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ // iTransportController must be valid for all the CObex life cycle
+ __ASSERT_DEBUG(iTransportController, IrOBEXUtil::Fault(ETransportControllerNotCreated));
+
+ iTransportController->RemoteAddr(aAddr);
+ }
+
+/**
+Sets the local Who field.
+
+This is used to identify the local end of the OBEX session when the OBEX connection
+is made. If it is required, set it before establishing the connection.
+
+@param aInfo Who field
+@return KErrNone or KErrArgument if aInfo is empty
+
+@publishedAll
+@released
+*/
+EXPORT_C TInt CObex::SetLocalWho(const TDesC8& aInfo)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ if(aInfo.Length())
+ { iLocalInfo.iWho.Copy(aInfo); return KErrNone;}
+ else
+ return KErrArgument;
+ }
+
+/**
+Indicates if the Server / Client is currently authenticating the OBEX
+connection.
+
+@return ETrue if the Server / Client is currently authenticating the OBEX connection otherwise EFalse.
+
+@publishedAll
+@released
+*/
+EXPORT_C TBool CObex::IsAuthenticating() const
+ {
+ return (ConnectState() >= EConnChallRxed && ConnectState() <= EWaitForUserInput);
+ }
+
+
+/**
+@param aPassword Password to use in challenge response
+@internalComponent
+*/
+void CObex::PrepareChallResponseL(const TDesC& aPassword)
+ {
+
+ FLOG(_L("CObex::PrepareChallResponse\r\n"));
+ iOutgoingChallResp.Zero();
+ TRequestDigest response;
+ delete iRespPassword;
+ iRespPassword = NULL;
+ iRespPassword = HBufC8::NewL(aPassword.Length());
+ TPtr8 ptr = iRespPassword->Des();
+ CnvUtfConverter::ConvertFromUnicodeToUtf8(ptr, aPassword);
+
+ iAuthEngine->GenerateResponseL(ptr, iIncomingNonce, response);
+ FLOG(_L("PrepareChallResponse: Digest response generated"));
+
+ FLOG(_L("PrepareChallResponse: Adding response hash"));
+ iOutgoingChallResp.Append(KObexRespTag); //0x00
+ iOutgoingChallResp.Append(KObexRespSize); //16
+ iOutgoingChallResp.Append(response);
+
+ //only reply with UserID if requested
+ if (iUserIDRequested )
+ {
+ FLOG(_L("PrepareChallResponse: User ID required, adding zero length field"));
+ iOutgoingChallResp.Append(KObexRespUserIDTag); //0x01
+ //Fixme, add in the size of the user ID
+ iOutgoingChallResp.Append(0); //assume no UserID size of 0
+ //any user ID would have to be inserted here
+ //iOutgoingChallResp.Append(userID); //Fixme what is the user ID?
+ }
+
+ FLOG(_L("PrepareChallResponse: Adding nonce of challenge we're replying to"));
+ iOutgoingChallResp.Append(KObexRespNonceTag);
+ iOutgoingChallResp.Append(KObexNonceSize);
+ iOutgoingChallResp.Append(iIncomingNonce);
+
+ FLOG(_L(" PrepareChallResponse - complete response generated"));
+ }
+
+/**
+@internalComponent
+*/
+TInt CObex::GenerateChallenge(CObexPacket& aPacket)
+ {
+ TInt retValue = KErrNone;
+
+ FLOG(_L("CObex::GenerateChallenge\r\n"));
+ iOutgoingNonce.Zero();
+ iAuthEngine->GenerateNonce(iOutgoingNonce);
+ //now pack all the data together for the overall challenge
+ TBuf8<KObexChallHeaderSize> outGoingHeader; //this size assumes no Realm data
+ outGoingHeader.Zero();
+ outGoingHeader.Append(KObexChallNonceTag);
+ outGoingHeader.Append(KObexNonceSize);
+ outGoingHeader.Append(iOutgoingNonce);
+
+ // Add authentication header only if the client has not disallowed it
+ if (!(iSuppressedObexAuthElements & EObexSuppressChallengeOptionsAuthElement))
+ {
+ outGoingHeader.Append(KObexChallOptionsTag);
+ outGoingHeader.Append(1); //size is always 1
+ outGoingHeader.Append(0); //all options off
+ }
+
+ // Add realm header only if the client has not disallowed it
+ if (!(iSuppressedObexAuthElements & EObexSuppressRealmAuthElement))
+ {
+ outGoingHeader.Append(KObexChallRealmTag);
+ outGoingHeader.Append(0); //no realm so size = 0
+ }
+
+ TObexInternalHeader hdr;
+ hdr.Set(TObexInternalHeader::EAuthChallenge, (const_cast<TUint8*> (outGoingHeader.Ptr())), outGoingHeader.Size());
+ if(!aPacket.InsertData(hdr))
+ retValue = KErrOverflow;
+
+ return (retValue);
+ }
+
+/**
+@internalComponent
+*/
+void CObex::ProcessChallResponseL(const TObexInternalHeader& hdr)
+ {
+ FLOG(_L("CObex::ProcessChallResponse"));
+ TBool retValue = ETrue;
+ TInt responseSize = hdr.HVSize();
+ TInt elementsLeft = responseSize; //keep track of how many elements still to be removed
+
+ if ( responseSize > KChallResponseSize )
+ {
+ retValue = EFalse;
+ FLOG(_L("ProcessChallResponse - Response header too big FAILED"));
+ }
+ else if (responseSize < KMinChallResponseSize)
+ {
+ retValue = EFalse;
+ FLOG(_L("ProcessChallResponse - Response header too small FAILED"));
+ }
+
+ //get the response
+ iIncomingChallResp.Zero();
+ iIncomingChallResp.Copy(hdr.HVByteSeq(), responseSize);
+
+ //there is no reason to assume that the data is going to arrive
+ //in any particular order
+ TInt extractionPosn = 0;
+
+ //ensure space enough for the tag and size
+ while ((extractionPosn < (responseSize-1) ) && retValue)
+ {
+ switch (iIncomingChallResp[extractionPosn++])
+ {
+ case KObexRespTag:
+ {
+ elementsLeft--; //moved passed the tag
+ if ((iIncomingChallResp[extractionPosn++] == KObexRespSize)&&
+ (elementsLeft > KObexRespSize)) //must be greater to allow for size field
+ {
+ elementsLeft--; //moved passed the size
+ FLOG(_L("ProcessChallResponse - iIncoming Request Response extracted"));
+ iIncomingRequestDigest.Zero();
+ iIncomingRequestDigest.Append((TUint8*)iIncomingChallResp.Ptr() + extractionPosn, KObexRespSize);
+ extractionPosn += KObexRespSize;
+ elementsLeft -= KObexRespSize;
+ }
+ else
+ {
+ FLOG(_L("ProcessChallResponse - iIncoming Request Response extraction FAILED"));
+ retValue = EFalse;
+ }
+ }
+ break;
+ case KObexRespUserIDTag:
+ {
+ elementsLeft--; //moved passed the tag
+ TInt userIDSize = iIncomingChallResp[extractionPosn++];
+ if ( userIDSize > 0)
+ {
+ elementsLeft--; //moved passed the User ID size
+ if (( userIDSize > 0 )&&(userIDSize <= elementsLeft ))
+ {
+ elementsLeft -= userIDSize;
+ FLOG(_L("ProcessChallResponse - iIncoming ASCII UserID Extracted"));
+ delete iRemoteUID;
+ iRemoteUID = NULL;
+ iRemoteUID = HBufC::NewL(userIDSize);
+ TPtrC8 ptr((TUint8*)iIncomingChallResp.Ptr() + extractionPosn, userIDSize);
+ TPtr ptrUID((TUint16*)iRemoteUID->Ptr(), userIDSize);
+ CnvUtfConverter::ConvertToUnicodeFromUtf8(ptrUID, ptr);
+ extractionPosn += userIDSize;
+ }
+ }
+ else
+ {
+ retValue = EFalse;
+ FLOG(_L("ProcessChallResponse - iIncoming UserID Extraction FAILED"));
+ }
+ }
+ break;
+ //don't bother extracting the Nonce as we do not support multiple Nonce replies
+ //the assumption is the reply received is for the Nonce we sent out
+ case KObexRespNonceTag:
+ {
+ FLOG(_L("ProcessChallResponse: extracting incoming nonce"));
+ elementsLeft--; //moved passed the tag
+ TInt nonceSize = iIncomingChallResp[extractionPosn++];
+ if ( nonceSize > 0 )
+ {
+ elementsLeft--; //moved passed size
+ if ( nonceSize <= elementsLeft )
+ {
+ FTRACE(
+ TPtrC8 incomingNonce(iIncomingChallResp.Ptr() + extractionPosn, nonceSize);
+ if (incomingNonce != iOutgoingNonce)
+ {
+ FLOG(_L("ProcessChallResponse: incoming nonce does not match our challenge. Continuing anyway."));
+ }
+ );
+
+ elementsLeft -= nonceSize;
+ extractionPosn += nonceSize;
+ }
+ else
+ {
+ FLOG(_L("ProcessChallResponse - iIncoming Request Response extraction, bad nonce size FAILED"));
+ retValue = EFalse;
+ }
+ }
+ }
+ break;
+ default:
+ {
+ FLOG(_L("ProcessChallResponse - iIncoming Request Response extraction,unknown tag type FAILED"));
+ retValue = EFalse;
+ }
+ break;
+
+ }
+ TRAPD(err, iAuthEngine->ChallengeResponseL(*iChallPassword, iOutgoingNonce, iIncomingRequestDigest));
+ if ( err != KErrNone)
+ {
+ FLOG(_L("ProcessChallResponse - Responsed Denied"));
+ User::Leave(err);
+ }
+ }
+ if (!retValue )
+ User::Leave(KErrGeneral);
+ }
+
+/**
+@internalComponent
+*/
+void CObex::ProcessChallengeL(const TObexInternalHeader& hdr)
+ {
+ FLOG(_L("CObex::ProcessChallenge\n\r"));
+
+ //extract all the necessary data
+ TInt challengeSize = hdr.HVSize();
+ TInt extractionPosn = 0;
+ TInt elementsLeft = challengeSize;
+ TBool nonceExtracted = EFalse;
+
+ delete iRxChallenge;
+ iRxChallenge = NULL;
+ iRxChallenge = HBufC8::NewL(challengeSize);
+ iRxChallenge->Des().Copy(hdr.HVByteSeq(), challengeSize);
+ delete iRemoteRealm;
+ iRemoteRealm = NULL;
+
+
+
+ //can't make any assumptions about the order
+ //in which anything may arrive, so allow any old order
+ TBool exit = EFalse;
+ if ( challengeSize < (KObexNonceSize + 2))
+ {
+ FLOG(_L("CObex::ProcessChallenge incoming Challenge too small\n\r"));
+ User::Leave(KErrGeneral);
+ }
+
+ //must be space for Tag and size
+ while ((elementsLeft > 2) && (!exit))
+ {
+ switch (iRxChallenge->Des()[extractionPosn++])
+ {
+ case KObexChallNonceTag: //check the Nonce tag has arrived
+ {
+ elementsLeft--; //passed the tag posn
+ if (( iRxChallenge->Des()[extractionPosn++] == KObexNonceSize )
+ && (elementsLeft > KObexNonceSize))
+ {
+ FLOG(_L("CObex::ProcessChallenge incoming Nonce Extracted\n\r"));
+ iIncomingNonce.Zero();
+ //extract the Nonce data
+ TPtr8 ptr((TUint8*)iRxChallenge->Ptr() + extractionPosn
+ ,KObexNonceSize, KObexNonceSize);
+ iIncomingNonce.Append(ptr);
+ elementsLeft -= (KObexNonceSize + 1);
+ nonceExtracted = ETrue;
+ extractionPosn += KObexNonceSize;
+ }
+ else
+ {
+ FLOG(_L("CObex::ProcessChallenge Incorrect Nonce size\n\r"));
+ exit = ETrue;
+ }
+ }
+ break;
+ case KObexChallOptionsTag:
+ {
+ elementsLeft--; //passed the tag posn
+ //check the options flag
+ iUserIDRequested = EFalse;
+ if (( iRxChallenge->Des()[extractionPosn++] == KObexChallOptionSize )
+ && (elementsLeft > KObexChallOptionSize))
+ {
+ //check if the user ID is required in the reply
+ if ( iRxChallenge->Des()[extractionPosn++] & KObexRequireUID )
+ {
+ //the userID has been requested so it MUST be sent back in the chall response
+ iUserIDRequested = ETrue;
+ FLOG(_L("CObex::ProcessChallenge User ID Requested\n\r"));
+ }
+ elementsLeft -= (KObexChallOptionSize + 1);
+
+ }
+ else
+ {
+ FLOG(_L("CObex::ProcessChallenge Incorrect Options size\n\r"));
+ exit = ETrue;
+ }
+ }
+ break;
+ case KObexChallRealmTag:
+ {
+ elementsLeft--; //passed the tag posn
+ TInt size = iRxChallenge->Des()[ extractionPosn++ ];
+ elementsLeft--;
+ if ( (size > 0 ) && (size <= elementsLeft ) )
+ {
+ elementsLeft -= size;
+ size--; //remove the first byte
+ //check which format the data is in
+ TUint convertType=0;
+ switch(iRxChallenge->Des()[extractionPosn++])
+ {
+ case 0:
+ convertType=KCharacterSetIdentifierAscii;
+ break;
+ case 1:
+ convertType=KCharacterSetIdentifierIso88591;
+ break;
+ case 2:
+ convertType=KCharacterSetIdentifierIso88592;
+ break;
+ case 3:
+ convertType=KCharacterSetIdentifierIso88593;
+ break;
+ case 4:
+ convertType=KCharacterSetIdentifierIso88594;
+ break;
+ case 5:
+ convertType=KCharacterSetIdentifierIso88595;
+ break;
+ case 6:
+ convertType=KCharacterSetIdentifierIso88596;
+ break;
+ case 7:
+ convertType=KCharacterSetIdentifierIso88597;
+ break;
+ case 8:
+ convertType=KCharacterSetIdentifierIso88598;
+ break;
+ case 9:
+ convertType=KCharacterSetIdentifierIso88599;
+ break;
+ case 0xFF:
+ // Unicode, no conversion needed
+ break;
+ default:
+ User::Leave(KErrGeneral);
+ }
+
+ if(convertType)
+ {
+ RFs fs;
+ LEAVEIFERRORL(fs.Connect());
+ CleanupClosePushL(fs);
+ CCnvCharacterSetConverter* converter = CCnvCharacterSetConverter::NewLC();
+ if (converter->PrepareToConvertToOrFromL(convertType, fs) != CCnvCharacterSetConverter::EAvailable)
+ User::Leave(KErrGeneral);
+
+ iRemoteRealm = HBufC::NewL(size);
+ TPtr16 dest = iRemoteRealm->Des();
+ TInt state=CCnvCharacterSetConverter::KStateDefault;
+ TInt err = converter->ConvertToUnicode(dest, iRxChallenge->Mid(extractionPosn, size), state);
+ if (err < 0)
+ User::Leave(err);
+ CleanupStack::PopAndDestroy(2); // fs, converter
+ }
+ else //can only be unicode
+ { //if unicode
+ FLOG(_L("CObex::ProcessChallenge incoming UNICODE Realm extracted\n\r"));
+ size = size/2; //if it's UNICODE then should be an even number
+ iRemoteRealm = HBufC::NewMaxL(size);
+ TPtr16 dest = iRemoteRealm->Des();
+ for ( TInt x = 0; x < size; x++ )
+ dest[x] = LittleEndian::Get16((TUint8*)iRxChallenge->Ptr() + extractionPosn + (2*x));
+ extractionPosn += size * 2;
+ }
+
+ }
+ else
+ {
+ FLOG(_L("CObex::ProcessChallenge Incorrect Realm size\n\r"));
+ exit = ETrue;
+ }
+ }
+ break;
+ default:
+ {
+ FLOG(_L("CObex::ProcessChallenge Unknown Tag type\n\r"));
+ exit = ETrue;
+ }
+ break;
+ }
+ }
+ if ( !nonceExtracted) //the nonce is mandatory so must exist
+ {
+ FLOG(_L("CObex::ProcessChallenge Nonce was not extracted\n\r"));
+ exit = ETrue;
+ }
+ if ( exit )
+ User::Leave(KErrGeneral);
+ }
+
+
+/**
+Sets the authentication challenge handler.
+
+The caller must supply a MObexAuthChallengeHandler implementation to handle
+calls from the Server/Client for a request for a password.
+
+@param aCallBack Authentication challenge handler
+
+@publishedAll
+@released
+*/
+EXPORT_C void CObex::SetCallBack(MObexAuthChallengeHandler& aCallBack)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ iCallBack = &aCallBack;
+ }
+
+/**
+@internalTechnology
+
+This function is retained for backwards compatibility and should not be called.
+
+Calling this function has undefined behaviour.
+*/
+void CObex::Process(CObexPacket& aPacket)
+ {
+ NotifyProcess(aPacket);
+ }
+
+/**
+@internalTechnology
+
+This function is retained for backwards compatibility and should not be called.
+
+Calling this function has undefined behaviour.
+*/
+void CObex::Error(TInt aError)
+ {
+ NotifyError(aError);
+ }
+
+/**
+@internalTechnology
+
+This function is retained for backwards compatibility and should not be called.
+
+Calling this function has undefined behaviour.
+*/
+void CObex::TransportUp()
+ {
+ NotifyTransportUp();
+ }
+
+/**
+@internalTechnology
+
+This function is retained for backwards compatibility and should not be called.
+Use ControlledTransportDown() or ForcedTransportDown() to disconnect the transport layer.
+Calling this function will result in an ETransportDownCalled panic.
+
+@panic ObexFault ETransportDownCalled
+@see ControlledTransportDown()
+@see ForcedTransportDown()
+*/
+void CObex::TransportDown(TBool)
+ {
+ IrOBEXUtil::Fault(ETransportDownCalled);
+ }
+
+
+void CObex::NotifyProcess(CObexPacket& aPacket)
+ {
+ LOG2(_L8("Packet Received, opcode: 0x%2X, Length: %d"),
+ aPacket.Opcode(), aPacket.PacketSize());
+ FTRACE(aPacket.Dump());
+ OnPacketReceive(aPacket);
+ // The queuing of the next read packet varies between Server and Client
+ // Client is done at the end of CObexClient::OnPacketReceive
+ // Server is done once the write packet completes in CObexServer::SignalPacketProcessEvent
+ // This is because the Server may be mid-way through an asynchronous operation after OnPacketReceive
+ // so we have to keep the current read packet
+ if ((GetConnectState() == EWaitForUserInput )&&(iCallBack))
+ {
+ TRAPD(err, iCallBack->GetUserPasswordL(iRemoteRealm ? static_cast<TDesC&>(*iRemoteRealm) : KNullDesC()));
+ if ( err )
+ {
+ Error(err);
+ }
+ }
+ }
+
+void CObex::NotifyError(TInt aError)
+ {
+ LOG1(_L8("Error Called: %d"), aError);
+
+ // This call has been moved to before ForcedTransportDown(), because it
+ // needs to check whether the current operation is "disconnect" or
+ // not, and ForcedTransportDown() sets it to "idle".
+ OnError(aError);
+
+ if(iConnectState >= EConnTransport)
+ {
+ ForcedTransportDown();
+ }
+ }
+
+void CObex::NotifyTransportUp()
+ {
+ FLOG(_L("CObex::NotifyTransportUp\n\r"));
+ SetConnectState(EConnTransport);
+ OnTransportUp();
+ }
+
+void CObex::NotifyTransportDown(TBool)
+ {
+ IrOBEXUtil::Fault(ETransportDownCalled);
+ }
+
+/**
+This function forces the transport to be taken down
+regardless of whether or not the underlying transport can recover without
+restarting obex applications
+However if the transport controller fails to bring the transport down, then only
+the obex connection is cancelled.
+This is called in error conditions
+
+@see ControlledTransportDown()
+@internalComponent
+*/
+void CObex::ForcedTransportDown()
+ {
+ // iTransportController must be valid for all the CObex life cycle
+ __ASSERT_DEBUG(iTransportController, IrOBEXUtil::Fault(ETransportControllerNotCreated));
+
+ if (iTransportController->BringTransportDown())
+ {
+ SetConnectState(EConnIdle);
+ OnTransportDown();
+ }
+ else
+ {
+ //the transport failed to be taken down
+ CancelObexConnection();
+ }
+ RemoteInfoCleanup();
+ }
+
+/**
+This function will tear down the transport if the transport layer supports
+transport reconnection on obex reconnection
+This is called in conditions other than error conditions
+
+@see ForcedTransportDown()
+@internalComponent
+*/
+void CObex::ControlledTransportDown()
+ {
+ // iTransportController must be valid for all the CObex life cycle
+ __ASSERT_DEBUG(iTransportController, IrOBEXUtil::Fault(ETransportControllerNotCreated));
+
+ TBool canBringTransportDown = iTransportController->IsTransportRestartable();
+ if (canBringTransportDown)
+ {
+ ForcedTransportDown();
+ }
+ else
+ {
+ CancelObexConnection();
+ RemoteInfoCleanup();
+ }
+
+ }
+
+/**
+General cleanup of iRemoteInfo
+@internalComponent
+*/
+void CObex::RemoteInfoCleanup()
+ {
+ // Some general cleanup here.
+ iRemoteInfo.iTargetHeader.SetLength(0);
+ iRemoteInfo.iWho.SetLength(0);
+ }
+
+/**
+Put into transport connected state but cancel any outstanding transfers and operations
+@internalComponent
+*/
+void CObex::CancelObexConnection()
+ {
+ // iTransportController must be valid for all the CObex life cycle
+ __ASSERT_DEBUG(iTransportController, IrOBEXUtil::Fault(ETransportControllerNotCreated));
+
+ iTransportController->CancelTransfers();
+ SetConnectState(EConnTransport);
+ iCurrentOperation = EOpIdle;
+ }
+
+/**
+Change the state of the authentication state machine
+@param aNewState New state
+@internalComponent
+*/
+void CObex::SetConnectState(TConnectState aNewState)
+ {
+ switch(iConnectState = aNewState)
+ {
+ case EConnIdle:
+ FLOG(_L("### Connection State EConnIdle\r\n"));
+ break;
+ case EConnTransport:
+ FLOG(_L("###### Connection State EConnTransport\r\n"));
+ break;
+ case ESimpleConnRequest:
+ FLOG(_L("######### Connection State ESimpleConnRequest\r\n"));
+ break;
+ case EConnObex:
+ FLOG(_L("######### Connection State EConnObex\r\n"));
+ break;
+ case EConnChallRxed:
+ FLOG(_L("######### Connection State EConnChallRxed\r\n"));
+ break;
+ case ESimpleConnChallIssued:
+ FLOG(_L("######### Connection State ESimpleConnChallIssued\r\n"));
+ break;
+ case EChallConnRequested:
+ FLOG(_L("######### Connection State EChallConnRequested\r\n"));
+ break;
+ case EChallConnChallIssued:
+ FLOG(_L("######### Connection State EChallConnChallIssued\r\n"));
+ break;
+ case EWaitForFinalResponse:
+ FLOG(_L("######### Connection State EWaitForFinalResponse\r\n"));
+ break;
+ case EFinalChallRxed:
+ FLOG(_L("######### Connection State EConnChallReIssued\r\n"));
+ break;
+ case EDropLink:
+ FLOG(_L("######### Connection State EDropLink\r\n"));
+ break;
+ default:
+ break;
+ }
+ }
+
+// CObex::TSetPathInfo
+/**
+Constructor.
+
+This is the path information used in the SETPATH command.
+The variable iFlags is set to zero by default. The variable iConstants is always set to zero as this is a reserved
+varaible. The path name is NOT present by default.
+
+@publishedAll
+@released
+*/
+EXPORT_C CObex::TSetPathInfo::TSetPathInfo()
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ iFlags = 0;
+ iConstants = 0;
+ iNamePresent = EFalse;
+ }
+
+/**
+@internalComponent
+*/
+CObex::TSetPathInfo::TSetPathInfo(const TObexSetPathData& aData)
+ : iFlags(aData.iFlags), iConstants(aData.iConstants), iNamePresent(EFalse)
+ {
+ }
+
+/**
+Returns true if the flags are set so that the receiver will backup a level before applying the path name
+
+@return ETrue if the flags are set so that the receiver will backup a level before applying the path name othewise EFalse.
+
+@publishedAll
+@released
+*/
+EXPORT_C TBool CObex::TSetPathInfo::Parent() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return(iFlags & KObexSetPathParent);
+ }
+
+// CObex
+/**
+Returns ETrue if this CObex is connected at an OBEX level, merely having
+a transport connected does not satisfy this condition. I.e. the two devices
+must have completed the OBEX connection request/response . All other states
+return EFalse. This will be unreliable if either the server blindly
+returns the client’s who header (always reporting ETrue), or if neither
+supply "who" headers (always reporting EFalse).
+
+@return ETrue if this CObex is connected at an OBEX level. EFalse otherwise.
+@publishedAll
+@released
+*/
+EXPORT_C TBool CObex::IsConnected() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return(GetConnectState() == EConnObex);
+ }
+
+/**
+@return ETrue if the "who" header specified in the server’s connect response
+ matched that of the client’s connect request, and both had a length greater
+ than 0 (i.e. both specified a "who" field). Undefined if IsConnected() == EFalse.
+
+@publishedAll
+@released
+*/
+EXPORT_C TBool CObex::IsStrictPeer() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return((iLocalInfo.iWho.Length()>0) && (iLocalInfo.iWho==iRemoteInfo.iWho));
+ }
+
+/**
+Use this member to gain access to (and alter, if necessary) the
+CObex::TConnectInfo structure which will be sent to the OBEX peer as part
+of the connection process. Only alter the contents of this having read and
+understood the purpose of the fields, as defined in the OBEX spec. Altering
+this structure after a connection has been made will have no effect on the
+current session, but will be used for future connection attempts.
+
+@return The connect info which will be sent to the OBEX peer.
+@publishedAll
+@released
+*/
+EXPORT_C const TObexConnectInfo& CObex::LocalInfo() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return(iLocalInfo);
+ }
+
+/**
+Use this member to read the details of the remote machine’s connection
+information, as specified by it in during OBEX connection. This data can
+not be altered, as this serves no purpose.
+The content of this structure is undefined when @see IsConnected () ==
+EFalse.
+
+@return The connect info from the remote machine.
+@publishedAll
+@released
+*/
+EXPORT_C const TObexConnectInfo& CObex::RemoteInfo() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return(iRemoteInfo);
+ }
+
+/**
+This function is in the protected scope of CObex and so is not externally usable
+@publishedAll
+@released
+*/
+EXPORT_C CObex::TConnectState CObex::ConnectState() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ // This function is exported but protected, making it not much use
+ // Making it public, and exposing more information about the authentication
+ // state machine is undesirable, but a public function is required for other
+ // classes in the DLL. Thus another public, unexported function has been defined
+ // on to which this function chains.
+ return GetConnectState();
+ };
+
+/**
+Get the current state of the authentication state machine
+@internalComponent
+*/
+CObex::TConnectState CObex::GetConnectState() const
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ return iConnectState;
+ };
+
+/**
+Must be called by an application that wishes to suppress the authentication or(not excusive) the realm of the authentication challenge
+@param aSuppressedObexAuthElements enum TObexSuppressedAuthElements to indicate which header elements to surpress (if any)
+@panic KErrArgument if invalid value is passed in for enum
+@publishedAll
+@released
+*/
+EXPORT_C void CObex::SuppressAuthenticationHeaderElements(TObexSuppressedAuthElements aSuppressedObexAuthElements)
+ {
+ LOG_LINE
+ LOG_FUNC
+
+ // If the value passed in is not a valid bitmask then panic
+ _LIT(panicText, "Invalid bitmask passed to CObex::SuppressAuthenticationHeaderElements");
+ __ASSERT_ALWAYS((!(aSuppressedObexAuthElements > EObexSuppressAllAuthElements)), User::Panic(panicText, KErrArgument));
+
+ iSuppressedObexAuthElements = aSuppressedObexAuthElements;
+
+ };