diff -r 000000000000 -r 29b1cd4cb562 bluetooth/btexample/example/btsocket/src/cbtservice.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/bluetooth/btexample/example/btsocket/src/cbtservice.cpp Fri Jan 15 08:13:17 2010 +0200 @@ -0,0 +1,247 @@ +// Copyright (c) 2004-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: +// Name : CBtService.cpp +// Part of : ex_btsocket +// Created : 17/11/2004 by Shane Kearns +// Server "smart connector" class +// Version : +// +// + +#include "cbtservice.h" + +/** +Standard Symbian style 2 phase construction +@param aServiceUUID a universally unique identifier for this application. +@param aSdpSession a constructed sdp session owned by the application +@param aSocketServer a constructed socket server session owned by the application +@param aOwner the owning class which should receive notification of new connections +@param aProtocol the protocol (RFCOMM or L2CAP) to register +@param aSecurity optional security settings to use on the socket instead of system defaults +*/ +EXPORT_C CBtService* CBtService::NewL(const TUUID& aServiceUUID, + RSdp& aSdpSession, + RSocketServ& aSocketServer, + MConnectionObserver& aOwner, + TUint aProtocol, + const TBTServiceSecurity* aSecurity=NULL) + { + LOG_FN_TRACE((_L("+CBtService::NewL"))); + __ASSERT_ALWAYS(aProtocol == KL2CAP || aProtocol == KRFCOMM, ExBtSocket::Panic(ExBtSocket::EUnsupportedProtocol)); + CBtService* self = new(ELeave) CBtService(aSocketServer, aOwner, aProtocol); + CleanupStack::PushL(self); + self->ConstructL(aServiceUUID, aSdpSession, aSecurity); + CleanupStack::Pop(self); + LOG_FN_TRACE((_L("-CBtService::NewL"))); + return self; + } + +/** +Standard 1st phase constructor, inialise member variables +*/ +CBtService::CBtService(RSocketServ& aSocketServer, MConnectionObserver& aOwner, TUint aProtocol) : + iSocketServer(aSocketServer), + iOwner(aOwner), + iProtocol(aProtocol) + { + } + +/** +Standard 2nd phase constructor, perform initialisation which could leave +*/ +void CBtService::ConstructL(const TUUID& aServiceUUID, RSdp& aSdpSession, const TBTServiceSecurity* aSecurity) + { + LOG_FN_TRACE((_L("+CBtService::ConstructL"))); + + //open handle so it is certain to be valid in the destructor + iServiceRecord.Open(aSdpSession); + + //First, create a listening socket + if(iProtocol == KL2CAP) + { + iAcceptorSocket = CBluetoothSocket::NewL(*this, iSocketServer, KSockSeqPacket, KL2CAP); + //bind the socket to a port + TL2CAPSockAddr addr; + addr.SetPort(KL2CAPPassiveAutoBind); //allow the stack to choose a free port automatically + if(aSecurity) + { + addr.SetSecurity(*aSecurity); //set security requirements, if present + } + User::LeaveIfError(iAcceptorSocket->Bind(addr)); + } + else if(iProtocol == KRFCOMM) + { + iAcceptorSocket = CBluetoothSocket::NewL(*this, iSocketServer, KSockStream, KRFCOMM); + //bind the socket to a port + TRfcommSockAddr addr; + addr.SetPort(KRfcommPassiveAutoBind); //allow the stack to choose a free port automatically + if(aSecurity) + { + addr.SetSecurity(*aSecurity); //set security requirements, if present + } + User::LeaveIfError(iAcceptorSocket->Bind(addr)); + } + User::LeaveIfError(iAcceptorSocket->Listen(1)); + + //Now, register in the SDP database + TUint port = iAcceptorSocket->LocalPort(); //get the port chosen by the stack + LOG_INFO((_L("Listening for connections on port %d"), port)); + iServiceRecord.CreateServiceRecordL(aServiceUUID, iServiceRecordHandle); + + // Set attr 4 (protocol list) to L2CAP, and RFCOMM + CSdpAttrValueDES *attrValDES; + + //This following code is doing these steps + //1. create a DES (data element set) attribute + //2. within that list, create a DES for each protocol, L2CAP and optionally RFCOMM + //3. each protocol is a list of elements, the UUID of the protocol, and the port to connect to. + //4. the service record is updated to include the new attribute + //5. discard the attribute we built, as it has been copied to the SDP server + attrValDES = CSdpAttrValueDES::NewDESL(NULL); + CleanupStack::PushL(attrValDES); + if(iProtocol == KL2CAP) + { + LOG_INFO((_L("Registering SDP PDL for L2CAP"))); + //This code will register an L2CAP (datagram) service + attrValDES + ->StartListL() + ->BuildDESL() + ->StartListL() + ->BuildUUIDL(TUUID(TUint16(KL2CAP))) // L2CAP + ->BuildUintL(TSdpIntBuf(TUint16(port))) // The Protocol Service Multiplexor (port) for our service + ->EndListL() + ->EndListL(); + } + else if(iProtocol == KRFCOMM) + { + LOG_INFO((_L("Registering SDP PDL for RFCOMM"))); + //This code will register an RFCOMM (stream) service + attrValDES + ->StartListL() + ->BuildDESL() + ->StartListL() + ->BuildUUIDL(TUUID(TUint16(KL2CAP))) // L2CAP + ->EndListL() + ->BuildDESL() + ->StartListL() + ->BuildUUIDL(TUUID(TUint16(KRFCOMM))) // RFCOMM + ->BuildUintL(TSdpIntBuf(TUint8(port))) + ->EndListL() + ->EndListL(); + } + iServiceRecord.UpdateAttributeL(iServiceRecordHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES); + CleanupStack::PopAndDestroy(attrValDES); + attrValDES = NULL; + LOG_FN_TRACE((_L("-CBtService::ConstructL"))); + } + +EXPORT_C CBtService::~CBtService() + { + LOG_FN_TRACE((_L("+CBtService::~CBtService"))); + //attempt to remove the SDP record + TRAP_IGNORE(iServiceRecord.DeleteRecordL(iServiceRecordHandle)); + iServiceRecord.Close(); + delete iAcceptorSocket; + LOG_FN_TRACE((_L("-CBtService::~CBtService"))); + } + +/** +Accept a new connection. +When the incoming connection has been made, HandleAcceptCompleteL() will be called +in this class. +That function informs the owner by calling HandleNewConnection() or HandleConnectFailed() +@param aBlankSocket an empty socket to receive the incoming connection. +*/ +EXPORT_C void CBtService::AcceptConnection(CBluetoothSocket& aBlankSocket) + { + LOG_FN_TRACE((_L("+CBtService::AcceptConnection"))); + __ASSERT_ALWAYS(iConnectionSocket == NULL, ExBtSocket::Panic(ExBtSocket::EReEntrant)); + iConnectionSocket = &aBlankSocket; + iAcceptorSocket->Accept(*iConnectionSocket); + LOG_FN_TRACE((_L("-CBtService::AcceptConnection"))); + } + +/** +Callback from CBluetoothSocket when a new incoming connection is complete. +Inform the owner +*/ +void CBtService::HandleAcceptCompleteL(TInt aErr) + { + LOG_FN_TRACE((_L("+CBtService::HandleAcceptCompleteL"))); + if(aErr == KErrNone) + { + iOwner.HandleNewConnection(iConnectionSocket); + } + else + { + iOwner.HandleConnectFailed(aErr); + } + iConnectionSocket = NULL; + LOG_FN_TRACE((_L("-CBtService::HandleAcceptCompleteL"))); + } + +/** +This function is not used but must be implemented as it is pure virtual +*/ +void CBtService::HandleConnectCompleteL(TInt /*aErr*/) + { + LOG_FN_TRACE((_L("+CBtService::HandleConnectCompleteL"))); + ExBtSocket::Panic(ExBtSocket::EBadCallback); + } + +/** +This function is not used but must be implemented as it is pure virtual +*/ +void CBtService::HandleShutdownCompleteL(TInt /*aErr*/) + { + LOG_FN_TRACE((_L("+CBtService::HandleShutdownCompleteL"))); + ExBtSocket::Panic(ExBtSocket::EBadCallback); + } + +/** +This function is not used but must be implemented as it is pure virtual +*/ +void CBtService::HandleSendCompleteL(TInt /*aErr*/) + { + LOG_FN_TRACE((_L("+CBtService::HandleSendCompleteL"))); + ExBtSocket::Panic(ExBtSocket::EBadCallback); + } + +/** +This function is not used but must be implemented as it is pure virtual +*/ +void CBtService::HandleReceiveCompleteL(TInt /*aErr*/) + { + LOG_FN_TRACE((_L("+CBtService::HandleReceiveCompleteL"))); + ExBtSocket::Panic(ExBtSocket::EBadCallback); + } + +/** +This function is not used but must be implemented as it is pure virtual +*/ +void CBtService::HandleIoctlCompleteL(TInt /*aErr*/) + { + LOG_FN_TRACE((_L("+CBtService::HandleIoctlCompleteL"))); + ExBtSocket::Panic(ExBtSocket::EBadCallback); + } + +/** +This function is not used but must be implemented as it is pure virtual +*/ +void CBtService::HandleActivateBasebandEventNotifierCompleteL(TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/) + { + LOG_FN_TRACE((_L("+CBtService::HandleActivateBasebandEventNotifierCompleteL"))); + ExBtSocket::Panic(ExBtSocket::EBadCallback); + } +