diff -r 000000000000 -r d11fb78c4374 ImagePrint/ImagePrintEngine/DeviceProtocols/btprotocol/src/cbtobjectserver.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ImagePrint/ImagePrintEngine/DeviceProtocols/btprotocol/src/cbtobjectserver.cpp Thu Dec 17 08:45:53 2009 +0200 @@ -0,0 +1,950 @@ +/* +* Copyright (c) 2004-2007 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 "cbtprintingdevice.h" +#include "cbtobjectserver.h" +#include "btprotocolconsts.h" +#include "clog.h" +#include "printmessagecodes.h" +#include "tbtmapper.h" +#include "xhtmlfilecomposerconst.h" +#include "rsutils.h" + + +// ---------------------------------------------------------------------------- +// CBtObjectServer::NewL() +// Creates a new instance of the class +// ---------------------------------------------------------------------------- + +CBtObjectServer* CBtObjectServer::NewL(const TBTDevAddr& aDeviceAddress, + RArray &aImgArray, + MBtObjectServerObserver &aObs) +{ + + CBtObjectServer* self = CBtObjectServer::NewLC( aDeviceAddress, aImgArray, aObs ); + CleanupStack::Pop( self ); + return self; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::NewLC() +// Creates a new instance of the class +// ---------------------------------------------------------------------------- + +CBtObjectServer* CBtObjectServer::NewLC(const TBTDevAddr& aDeviceAddress, + RArray &aImgArray, + MBtObjectServerObserver &aObs) +{ + + CBtObjectServer* self = new ( ELeave ) CBtObjectServer( aDeviceAddress, aObs ); + CleanupStack::PushL( self ); + self->ConstructL(aImgArray); + return self; + +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::CBtObjectServer +// The actual constructor of the class +// ---------------------------------------------------------------------------- + +CBtObjectServer::CBtObjectServer(const TBTDevAddr& aDeviceAddress, MBtObjectServerObserver& aObs ) +: iAllowedAddress ( aDeviceAddress ), + iObs ( aObs ), + iStarted(EFalse), + iConnected(EFalse), + iTransportUp(EFalse) +{ + LOG("CBtObjectServer::CBtObjectServer]\t default constructor"); + + iImgArray.Reset(); + iImgArray.Close(); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::~CBtObjectServer() +// Destructor. +// ---------------------------------------------------------------------------- +// +CBtObjectServer::~CBtObjectServer() +{ + LOG("CBtObjectServer::~CBtObjectServer]\t"); + + iStarted = EFalse; + iOperation = EIdle; + + if ( iObexServer && iObexServer->IsStarted() ) + { + iObexServer->Stop(); + } + + iFs.Close(); + + if (iObexServer) + delete iObexServer; + iObexServer = NULL; + + if(iObexBufObject) + delete iObexBufObject; + iObexBufObject = NULL; + + // This must be deleted after the iObexBufObject who uses it. + if (iObexBody) + delete iObexBody; + iObexBody = NULL; + + if(iAdvertiser) + delete iAdvertiser; + iAdvertiser = NULL; + + iImgArray.Close(); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::Cancel() +// Sends current file to the server and then stops the server +// ---------------------------------------------------------------------------- +void CBtObjectServer::Cancel() +{ + LOG("[CBtObjectServer::Cancel]\t"); + + if (!IsSendingData()) + { + LOG("[CBtObjectServer::Cancel]\t - not sending data - stopping server now! \n"); + Stop(); + } + else + { + iOperation = EIdle; + } +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::ConstructL() +// Constucts everything that can leave in the class +// ---------------------------------------------------------------------------- +void CBtObjectServer::ConstructL(RArray &aImgArray) +{ + LOG("[CBtObjectServer::ConstructL]\t"); + + LOG1("[CBtObjectServer::ConstructL]\t aImgArray.Count(): %d", aImgArray.Count()); + for(TInt i = 0; i < aImgArray.Count(); ++i) + { + iImgArray.Append(aImgArray[i]); + +/* For debug +#ifdef ENABLE_LOGGING + TFileName8 uri; + aImgArray[i].GetUri(uri); + TFileName8 log; + CImageInfo::UriLog(uri, log); + LOG1("[CBtObjectServer::ConstructL]\t uri: %d", log); +#endif // ENABLE_LOGGING +*/ + } + + iAdvertiser = CBtDprServiceAdvertiser::NewL(); + + // create OBEX object to receive obex transfer. 8 for reserving data in 8 bytes segments + iObexBody = CBufFlat::NewL( 8 ); + + User::LeaveIfError(iFs.Connect()); + + InitTransferData(); + iRemoteAddress.Reset(); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::Stop() +// Disconnects the server. +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::Stop() +{ + LOG("[CBtObjectServer::Stop]\t"); + + // already stopping + if(!iStarted) + return; + + iOperation = ETerminating; + + LOG("[CBtObjectServer::Stop]\t cont..."); + iRemoteAddress.Reset(); + + //cannot delete here. Stop called from iObexServer Callback function. + if ( iObexServer && iObexServer->IsStarted()) + { + LOG("[CBtObjectServer::Stop]\t stopping iObexServer..."); + iObexServer->Stop(); + } + + // Trap this: if it fails, we cannot do anything. + TInt leave; // for remove compiling warnings + TRAP(leave, iAdvertiser->StopAdvertisingL()); + LOG1("[CBtObjectServer::Stop]\t iAdvertiser->StopAdvertising() leaves with %d", leave); + + LOG1("[CBtObjectServer::Stop]\t iObexServer: %d", iObexServer); + + iOperation = EIdle; + iStarted = EFalse; + iConnected = EFalse; + iTransportUp = EFalse; + + /* Sending 'stopped' status */ + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerStopped); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::StartL() +// Starts the server. +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::StartL() +{ + LOG("[CBtObjectServer::StartL]\t"); + + TBool btOn = RsUtils::IsBluetoothOn(); + LOG1("[CBtObjectServer::StartL]\t btOn: %d", btOn); + if( !btOn ) + User::Leave(KErrCancel); + + TRAPD( err, InitialiseServerL() ); + LOG1("CBtObjectServer::StartL]\t InitialiseServerL leaves with %d", err); + + if ( err != KErrNone ) + { + Stop(); + User::Leave(err); + } + + iStarted = ETrue; + + /* Send 'server started' status */ + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerStarted); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::InitialiseServerL() +// Initialises the server. +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::InitialiseServerL() +{ + LOG("CBtObjectServer::InitialiseServerL]\t"); + + if ( iObexServer ) + { + ASSERT( IsConnected() ); // server already running + return; + } + + LOG("[CBtObjectServer::InitialiseServerL]\t - getting channel"); + + // Set the Socket's security with parameters, + // Authentication, Encryption, Authorisation and Denied + // Method also return the channel available to listen to. + TInt channel = SetSecurityWithChannelL( EFalse, EFalse, EFalse, EFalse ); + + // start the OBEX server + TObexBluetoothProtocolInfo obexProtocolInfo; + + LOG1("[CBtObjectServer::InitialiseServerL]\t setting %S ", &KRFCOMMDesC); + obexProtocolInfo.iTransport.Copy( KRFCOMMDesC() ); + + LOG1("[CBtObjectServer::InitialiseServerL]\t setting port %d", channel); + obexProtocolInfo.iAddr.SetPort( channel ); + + LOG("[CBtObjectServer::InitialiseServerL]\t CObexServer::NewL()"); + if(iObexServer) + { + delete iObexServer; + iObexServer = NULL; + } + iObexServer = CObexServer::NewL( obexProtocolInfo ); + + LOG("[CBtObjectServer::InitialiseServerL]\t iObexServer->Start()"); + User::LeaveIfError(iObexServer->Start( this ) ); + + TUUID who(KBTSDPDPROService); + User::LeaveIfError(iObexServer->SetLocalWho(who.LongForm())); + + // advertise this service + LOG("[CBtObjectServer::InitialiseServerL]\t iAdvertiser->StartAdvertisingL()"); + iAdvertiser->StartAdvertisingL( channel ); + LOG("[CBtObjectServer::InitialiseServerL]\t iAdvertiser->UpdateAvailabilityL()"); + iAdvertiser->UpdateAvailabilityL( ETrue ); + +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::InitTransferData() +// Initialises the variables needed for progressing and processing the printing +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::InitTransferData() +{ + LOG("CBtObjectServer::InitTransferData]\t"); + + InitHeaderVariables(); + iProgress = 0; + + // delete this to be ready to send NULL object. + if(iObexBufObject) + delete iObexBufObject; + iObexBufObject = NULL; + + // no need to delete. Reset is enough. + iObexBody->Reset(); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::InitHeaderVariables() +// Initialises the variables needed for progressing and processing the printing +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::InitHeaderVariables() +{ + LOG("CBtObjectServer::InitHeaderVariables]\t"); + + iOffset = 0; + iCount = 0; // KErrNotFound indicates "the rest" + iSize = KErrNotFound; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::SetSecurityWithChannelL() +// Sets the security on the channel port and returns the available port. +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::SetSecurityWithChannelL( TBool aAuthentication, + TBool aEncryption, + TBool aAuthorisation, + TBool aDenied ) + +{ + + LOG("CBtObjectServer::SetSecurityWithChannelL]\t"); + + // Local variable to channel to listen to. + TInt channel; + + RSocketServ socketServer; + + // Connect to SocetServer + LOG("[CBtObjectServer::SetSecurityWithChannelL]\t - connecting to socketServer"); + User::LeaveIfError( socketServer.Connect() ); + CleanupClosePushL( socketServer ); + + RSocket socket; + + // Open the Socket connection + LOG("[CBtObjectServer::SetSecurityWithChannelL]\t - opening a socket"); + User::LeaveIfError( socket.Open( socketServer, KRFCOMMDesC() ) ); + CleanupClosePushL( socket ); + + // Retreive to one channel that is available. + LOG("[CBtObjectServer::SetSecurityWithChannelL]\t - get one channel"); + User::LeaveIfError( socket.GetOpt( KRFCOMMGetAvailableServerChannel,KSolBtRFCOMM, channel ) ); + + // Set the Socket's Port. + TBTSockAddr sockaddr; + sockaddr.SetPort( channel ); + + LOG("[CBtObjectServer::SetSecurityWithChannelL]\t - setting security settings"); + + // Set the security according to. + TBTServiceSecurity serviceSecurity; + + serviceSecurity.SetUid ( KBtProtocolUid ); // UID for _this_ security service; internal inside the phone + serviceSecurity.SetAuthentication ( aAuthentication ); + serviceSecurity.SetEncryption ( aEncryption ); + serviceSecurity.SetAuthorisation ( aAuthorisation ); + serviceSecurity.SetDenied( aDenied ); + + // Attach the security settings. + sockaddr.SetSecurity(serviceSecurity); + + LOG("[CBtObjectServer::SetSecurityWithChannelL]\t - binding socket to a address"); + + // Bind and start listeing the port with security set, + User::LeaveIfError(socket.Bind(sockaddr)); + User::LeaveIfError(socket.Listen(KSimultainousSocketsOpen ) ); + + // now close the socket and the socket server + CleanupStack::PopAndDestroy(2); // socket, socketServer + + LOG("[CBtObjectServer::SetSecurityWithChannelL]\t - returning"); + + return channel; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::IsConnected() +// Results true if the server is connected. +// ---------------------------------------------------------------------------- +// +TBool CBtObjectServer::IsConnected() +{ + LOG1("CBtObjectServer::IsConnected]\t %d", iConnected); + return iConnected; +} + + +// ---------------------------------------------------------------------------- +// CBtObjectServer::IsTransporting() +// Results true if the transport connection is up. +// ---------------------------------------------------------------------------- +// +TBool CBtObjectServer::IsTransporting() +{ + LOG1("CBtObjectServer::IsTransporting]\t %d", iTransportUp); + return iTransportUp; +} +// ---------------------------------------------------------------------------- +// IsSendingData() +// @return ETrue if the server is sending data to a Bluetooth device +// ---------------------------------------------------------------------------- +TBool CBtObjectServer::IsSendingData() +{ + LOG("CBtObjectServer::IsSendingData]\t"); + + if(ESending == iOperation) + return ETrue; + + return EFalse; +} + +// ---------------------------------------------------------------------------- +// IsSendingData() +// @return ETrue if the server is finished and can be deleted +// ---------------------------------------------------------------------------- +TBool CBtObjectServer::IsFinished() +{ + LOG("CBtObjectServer::IsFinished]\t"); + + if(ESending != iOperation) + return ETrue; + + return EFalse; +} + +/*****************************************************************************/ +/* Following methods implement the Obex Observer callbacks in this class */ +/*****************************************************************************/ + +// ---------------------------------------------------------------------------- +// CBtObjectServer::ErrorIndication() +// Receive error indication. +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::ErrorIndication( TInt aError ) +{ + LOG2("CBtObjectServer::ErrorIndication]\t iOperation: %d, aError: %d", iOperation, aError); + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerError, aError); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::TransportUpIndication() +// Called when the underlying socket transport connection is made from +// a remote client to the server +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::TransportUpIndication() +{ + LOG1("CBtObjectServer::TransportUpIndication]\t iOperation: %d", iOperation); + + iTransportUp = ETrue; + + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerTransportUp); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::TransportDownIndication() +// Transport connection is dropped. +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::TransportDownIndication() +{ + LOG1("[CBtObjectServer::TransportDownIndication]\t iOperation: %d", iOperation); + + iTransportUp = EFalse; + + if(ETerminating != iOperation) + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerTransportDown); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::ObexConnectIndication() +// Invoked when an OBEX connection is made from a remote client. +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::ObexConnectIndication( + const TObexConnectInfo& /*aRemoteInfo*/, const TDesC8& /*aInfo*/ ) +{ + LOG("CBtObjectServer::ObexConnectIndication]\t"); + + TInt message = KErrAccessDenied; + + /* Check the address of the remote device */ + if(AllowConnection()) + { + message = KErrNone; + iConnected = ETrue; + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerConnected); + } + + LOG1("CBtObjectServer::ObexConnectIndication]\t returns %d", message); + return message; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::ObexDisconnectIndication() +// OBEX server has been disconnected. +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::ObexDisconnectIndication( const TDesC8& /*aInfo*/ ) +{ + LOG("CBtObjectServer::ObexDisconnectIndication]\t"); + + if(ETerminating != iOperation) + { + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerDisconnected); + } + iConnected = EFalse; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::PutRequestIndication() +// ---------------------------------------------------------------------------- +// +CObexBufObject* CBtObjectServer::PutRequestIndication() +{ + LOG("CBtObjectServer::PutRequestIndication]\t"); + + /* This is the object where server receives the client request over OBEX */ + return iObexBufObject; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::PutPacketIndication() +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::PutPacketIndication() +{ + LOG("CBtObjectServer::PutPacketIndication]\t"); + + return KErrNone; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::PutCompleteIndication() +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::PutCompleteIndication() +{ + LOG("CBtObjectServer::PutCompleteIndication]\t"); + + return KErrNone; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::GetRequestIndication() +// Called when a full get request has been received from the client. +// ---------------------------------------------------------------------------- +// +CObexBufObject* CBtObjectServer::GetRequestIndication( CObexBaseObject* aRequestedObject ) +{ + LOG("[CBtObjectServer::GetRequestIndication]\t"); + + CObexBufObject* object = NULL; + + /* Check if connection allowed for the remote device */ + if(AllowConnection()) + { + iOperation = ESending; + TRAPD(leave, object = HandleGetRequestL(aRequestedObject)); + if(KErrNone != leave) + LOG1("[CBtObjectServer::GetRequestIndication]\t HandleGetRequestL leaves with %d", leave ); + + // Stop advertising if still advertisig... + TRAP(leave, iAdvertiser->StopAdvertisingL()); + if(KErrNone != leave) + LOG1("[CBtObjectServer::GetRequestIndication]\t StopAdvertisingL leaves with %d", leave); + } + + LOG1("[CBtObjectServer::GetRequestIndication]\t return object pointer %d", object ); + return object; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::GetPacketIndication() +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::GetPacketIndication() +{ + LOG("[CBtObjectServer::GetPacketIndication]\t"); + + /* Setting that we are now sending data */ + iOperation = ESending; + + return KErrNone; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::GetCompleteIndication() +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::GetCompleteIndication() +{ + LOG("[CBtObjectServer::GetCompleteIndication]\t"); + + if(iProgress >= 100) + // Sending status that the whole file sent to BT-device + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerFileSent, iProgress); + else + // Sending status that one package sent to BT-device + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerPackageSent, iProgress); + + // We are finished for one package - init + SetCompleted(); + + return KErrNone; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::SetPathIndication() +// ---------------------------------------------------------------------------- +// +TInt CBtObjectServer::SetPathIndication( const CObex::TSetPathInfo& /*aPathInfo*/, + const TDesC8& /*aInfo*/ ) +{ + LOG("CBtObjectServer::SetPathIndication]\t"); + return KErrNone; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::AbortIndication() +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::AbortIndication() +{ + LOG("CBtObjectServer::AbortIndication]\t"); + + SetCompleted(); + + /* Sending status that one file sent to BT-device */ + iObs.HandleObjectServerEvent(KErrAbort); + +} + +/*****************************************************************************/ +/* Own privates */ +/*****************************************************************************/ + +// ---------------------------------------------------------------------------- +// CBtObjectServer::AllowConnection() +// Checks if the connection should allow. +// ---------------------------------------------------------------------------- +// +TBool CBtObjectServer::AllowConnection() +{ + LOG("CBtObjectServer::AllowConnection]\t"); + + // Return immediatedly if addresses macth + if( iRemoteAddress != 0 && iRemoteAddress == iAllowedAddress) + return ETrue; + + TBool allow = EFalse; + + if( iRemoteAddress == 0 ) + { + /* Getting address of the remote device */ + TBTSockAddr remoteAddress; + iObexServer->RemoteAddr(remoteAddress); + + /* Getting the actual bluetooth address */ + iRemoteAddress = remoteAddress.BTAddr(); + + /* Comparing the two bluetooth device addresses */ + allow = (iRemoteAddress == iAllowedAddress); + +#ifdef _DEBUG + + TBuf<100> origName; + iAllowedAddress.GetReadable(origName); + TBuf<100> remoteName; + iRemoteAddress.GetReadable(remoteName); + + LOG1("[CBtObjectServer::AllowConnection]\t btAddressOrig: %S", &origName); + LOG1("[CBtObjectServer::AllowConnection]\t btAddressRemote: %S", &remoteName); +#endif + } + + + if (!allow) + { + LOG("[CBtObjectServer::AllowConnection]\t BT addresses DON'T match!"); + iObs.HandleObjectServerEvent(MBtObjectServerObserver::KObjectServerBTDeviceMismatch); + } + else + { + LOG("[CBtObjectServer::AllowConnection]\t BT addresses match!"); + } + + return allow; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::HandleGetRequestL() +// Called when a full get request has been received from the client. +// ---------------------------------------------------------------------------- +// +CObexBufObject* CBtObjectServer::HandleGetRequestL( CObexBaseObject* aRequestedObject ) +{ + User::LeaveIfNull(aRequestedObject); + + TFileName name(aRequestedObject->Name()); + + TFileName log; + CImageInfo::UriLog(name, log); + LOG1("[CBtObjectServer::HandleGetRequestL]\t file requested: \"%S\"", &log); + + /* get application parameters header */ + GetAppHeaderL(aRequestedObject); + + //Append obex header start in uri + _LIT(KObex, "obex:"); + _LIT(KSlash, "/"); + TFileName scheme(KObex()); + // Note here: the correct format would be uuid.LongForm(), + // but in currently supported services it is not required. + scheme.AppendNum(KBTSDPDPROService, EHex); + scheme.Append(KSlash()); + + TInt pos = name.Find(scheme); + if(KErrNotFound == pos) + name.Insert(0, scheme); + + return CreateObexObjectL(name); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::GetAppHeaderL() +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::GetAppHeaderL(CObexBaseObject* aRequestedObject) +{ + LOG("CBtObjectServer::GetAppHeaderL]\t"); + + /* get header parameters */ + InitHeaderVariables(); + + TInt indx = 0; // grows cumulatively during GetTriplet + TInt tmp = 0; + + // offset + TUint tag = 0; + TInt len = KBtTripletLength; + HBufC8* params = (aRequestedObject->AppParam()).AllocLC(); + + if(len <= params->Des().Length()) + { + tmp = TBtMapper::TripletValue(params->Des(), indx, tag); + } + if(KBtObexTagOffset == tag) + iOffset = tmp; + + LOG1("CBtObjectServer::GetAppHeaderL]\t offset: %d", iOffset); + + // count + tag = 0; + len += KBtTripletLength; + if(len <= params->Des().Length()) + { + tmp = TBtMapper::TripletValue(params->Des(), indx, tag); + } + if(KBtObexTagCount == tag) + iCount = tmp; + + LOG1("CBtObjectServer::GetAppHeaderL]\t count: %d", iCount); + + // size + tag = 0; + len += KBtTripletLength; + if(len <= params->Des().Length()) + { + tmp = TBtMapper::TripletValue(params->Des(), indx, tag); + } + if(KBtObexTagSize == tag) + iSize = tmp; + + LOG1("CBtObjectServer::GetAppHeaderL]\t size: %d", iSize); + + CleanupStack::PopAndDestroy(params); +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer +// +// ---------------------------------------------------------------------------- +CObexBufObject* CBtObjectServer::CreateObexObjectL(const TDesC& aUri) +{ + TFileName log; + CImageInfo::UriLog(aUri, log); + LOG1("[CBtObjectServer::CreateObexObjectL]\t file requested: \"%S\"", &log); + + if(iObexBufObject) + delete iObexBufObject; + iObexBufObject = NULL; + + TInt size = KErrNotFound; + + for(TInt i = 0; i < iImgArray.Count(); ++i) + { + if(iImgArray[i].CompareUri(aUri)) + { + TFileName file; + iImgArray[i].GetFilePathL(file); + LOG1("[CBtObjectServer::CreateObexObject]\t file = \"%S\"", &file ); + + GetDataSequenceL(file, size); + LOG2("[CBtObjectServer::CreateObexObject]\t data len: %d, file size: %d", iObexBody->Size(), size); + if(iObexBody) + iObexBufObject = CObexBufObject::NewL(iObexBody); + + break; + } + } + if(!iObexBufObject) + { + LOG1("[CBtObjectServer::CreateObexObject]\t return NULL: %d", iObexBufObject); + return iObexBufObject; + } + + // Fill headers + // File size (application parameters) + + TBuf8<20> triplet; + + triplet.Zero(); + triplet.Append((TChar)KBtObexTagSize); + triplet.Append((TChar)KBtDataLength4); + //append value + triplet.Append((TChar) ((size & 0xFF000000) >> 24) ); + triplet.Append((TChar) ((size & 0xFF0000) >> 16) ); + triplet.Append((TChar) ((size & 0xFF00) >> 8) ); + triplet.Append((TChar) (size & 0xFF) ); + triplet.ZeroTerminate(); + + iObexBufObject->SetAppParamL(triplet); + + return iObexBufObject; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::GetDataSequenceL() +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::GetDataSequenceL(const TFileName& aFileName, TInt& aFileSize) +{ + //LOG1("[CBtObjectServer::GetDataSequenceL]\t for file \"%S\"", aFileName); + + RFile file; + CleanupClosePushL(file); + TInt err = file.Open(iFs, aFileName, EFileRead|EFileShareReadersOnly); + if(KErrNone != err) + User::LeaveIfError(file.Open(iFs, aFileName, EFileRead|EFileShareAny)); + + // Get file size + aFileSize = KErrNotFound; + file.Size(aFileSize); + + if(!iObexBody) + { + iObexBody = static_cast(User::LeaveIfNull(CBufFlat::NewL(8))); + } + iObexBody->Reset(); + + // if iCount is zero, return empty body... + if(0 == iCount) + return; + + // count to send + TInt len = iCount; + + // ...if iCount is -1, return the rest of the file + // (http://www.bluetooth.com/NR/rdonlyres/276DE16A-BDB9-48BF-8123-AF01E3730E5F/925/BPP_SPEC_V10.pdf) + if(KErrNotFound == len) + { + len = aFileSize - iOffset; + } + //LOG2("[CBtObjectServer::GetDataSequenceL]\t iOffset: %d, len: %d", iOffset, len); + + HBufC8* data = static_cast(User::LeaveIfNull(HBufC8::NewLC(len))); + TPtr8 dataPtr( data->Des() ); + + dataPtr.Zero(); + User::LeaveIfError( file.Read(iOffset, dataPtr, len) ); + //LOG1("[CBtObjectServer::GetDataSequenceL]\t read data->Des().Length(): %d", data->Des().Length()); + + iObexBody->InsertL(0, data->Des()); + + CleanupStack::PopAndDestroy(2); // data, file + + //count proggress of this file + if(!iOffset) + iProgress = iOffset; + else + iProgress = (((iOffset << 8) / aFileSize) * 100) >> 8; + + LOG1("[CBtObjectServer::GetDataSequenceL]\t Progress: %d", iProgress); + return; +} + +// ---------------------------------------------------------------------------- +// CBtObjectServer::SetCompleted() +// ---------------------------------------------------------------------------- +// +void CBtObjectServer::SetCompleted() +{ + // method to indicate a package is sent + LOG("[CBtObjectServer::SetCompleted]\t"); + + // init requested parameters + InitTransferData(); + + /* If the user of the server called Cancel() */ + if(ETerminating == iOperation) + { + LOG("[CBtObjectServer::SetCompleted]\t to stop..."); + Stop(); + } + else + { + LOG("[CBtObjectServer::SetCompleted]\t package sent..."); + iOperation = EIdle; + } + + return; +} + +// End of File