bluetooth/btexample/example/btsocket/src/cbtservice.cpp
changeset 0 29b1cd4cb562
equal deleted inserted replaced
-1:000000000000 0:29b1cd4cb562
       
     1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // Name     : CBtService.cpp
       
    15 // Part of  : ex_btsocket
       
    16 // Created  : 17/11/2004 by Shane Kearns
       
    17 // Server "smart connector" class
       
    18 // Version  :
       
    19 // 
       
    20 //
       
    21 
       
    22 #include "cbtservice.h"
       
    23 
       
    24 /**
       
    25 Standard Symbian style 2 phase construction
       
    26 @param aServiceUUID a universally unique identifier for this application.
       
    27 @param aSdpSession a constructed sdp session owned by the application
       
    28 @param aSocketServer a constructed socket server session owned by the application
       
    29 @param aOwner the owning class which should receive notification of new connections
       
    30 @param aProtocol the protocol (RFCOMM or L2CAP) to register
       
    31 @param aSecurity optional security settings to use on the socket instead of system defaults
       
    32 */
       
    33 EXPORT_C CBtService* CBtService::NewL(const TUUID& aServiceUUID, 
       
    34 							 RSdp& aSdpSession, 
       
    35 							 RSocketServ& aSocketServer, 
       
    36 							 MConnectionObserver& aOwner,
       
    37 							 TUint aProtocol,
       
    38 							 const TBTServiceSecurity* aSecurity=NULL)
       
    39 	{
       
    40 	LOG_FN_TRACE((_L("+CBtService::NewL")));
       
    41 	__ASSERT_ALWAYS(aProtocol == KL2CAP || aProtocol == KRFCOMM, ExBtSocket::Panic(ExBtSocket::EUnsupportedProtocol));
       
    42 	CBtService* self = new(ELeave) CBtService(aSocketServer, aOwner, aProtocol);
       
    43 	CleanupStack::PushL(self);
       
    44 	self->ConstructL(aServiceUUID, aSdpSession, aSecurity);
       
    45 	CleanupStack::Pop(self);
       
    46 	LOG_FN_TRACE((_L("-CBtService::NewL")));
       
    47 	return self;
       
    48 	}
       
    49 
       
    50 /**
       
    51 Standard 1st phase constructor, inialise member variables
       
    52 */
       
    53 CBtService::CBtService(RSocketServ& aSocketServer, MConnectionObserver& aOwner, TUint aProtocol) :
       
    54 	iSocketServer(aSocketServer),
       
    55 	iOwner(aOwner),
       
    56 	iProtocol(aProtocol)
       
    57 	{
       
    58 	}
       
    59 
       
    60 /**
       
    61 Standard 2nd phase constructor, perform initialisation which could leave
       
    62 */
       
    63 void CBtService::ConstructL(const TUUID& aServiceUUID, RSdp& aSdpSession, const TBTServiceSecurity* aSecurity)
       
    64 	{
       
    65 	LOG_FN_TRACE((_L("+CBtService::ConstructL")));
       
    66 
       
    67 	//open handle so it is certain to be valid in the destructor
       
    68 	iServiceRecord.Open(aSdpSession);
       
    69 
       
    70 	//First, create a listening socket
       
    71 	if(iProtocol == KL2CAP)
       
    72 		{
       
    73 		iAcceptorSocket = CBluetoothSocket::NewL(*this, iSocketServer, KSockSeqPacket, KL2CAP);
       
    74 		//bind the socket to a port
       
    75 		TL2CAPSockAddr addr;
       
    76 		addr.SetPort(KL2CAPPassiveAutoBind); //allow the stack to choose a free port automatically
       
    77 		if(aSecurity)
       
    78 			{
       
    79 			addr.SetSecurity(*aSecurity); //set security requirements, if present
       
    80 			}
       
    81 		User::LeaveIfError(iAcceptorSocket->Bind(addr));
       
    82 		}
       
    83 	else if(iProtocol == KRFCOMM)
       
    84 		{
       
    85 		iAcceptorSocket = CBluetoothSocket::NewL(*this, iSocketServer, KSockStream, KRFCOMM);
       
    86 		//bind the socket to a port
       
    87 		TRfcommSockAddr addr;
       
    88 		addr.SetPort(KRfcommPassiveAutoBind); //allow the stack to choose a free port automatically
       
    89 		if(aSecurity)
       
    90 			{
       
    91 			addr.SetSecurity(*aSecurity); //set security requirements, if present
       
    92 			}
       
    93 		User::LeaveIfError(iAcceptorSocket->Bind(addr));
       
    94 		}
       
    95 	User::LeaveIfError(iAcceptorSocket->Listen(1)); 
       
    96 
       
    97 	//Now, register in the SDP database
       
    98 	TUint port = iAcceptorSocket->LocalPort(); //get the port chosen by the stack
       
    99 	LOG_INFO((_L("Listening for connections on port %d"), port));
       
   100 	iServiceRecord.CreateServiceRecordL(aServiceUUID, iServiceRecordHandle);
       
   101 	
       
   102 	// Set attr 4 (protocol list) to L2CAP, and RFCOMM
       
   103 	CSdpAttrValueDES *attrValDES;
       
   104 
       
   105 	//This following code is doing these steps
       
   106 	//1. create a DES (data element set) attribute
       
   107 	//2. within that list, create a DES for each protocol, L2CAP and optionally RFCOMM
       
   108 	//3. each protocol is a list of elements, the UUID of the protocol, and the port to connect to.
       
   109 	//4. the service record is updated to include the new attribute
       
   110 	//5. discard the attribute we built, as it has been copied to the SDP server
       
   111 	attrValDES = CSdpAttrValueDES::NewDESL(NULL);
       
   112 	CleanupStack::PushL(attrValDES);
       
   113 	if(iProtocol == KL2CAP)
       
   114 		{
       
   115 		LOG_INFO((_L("Registering SDP PDL for L2CAP")));
       
   116 		//This code will register an L2CAP (datagram) service
       
   117 		attrValDES
       
   118 			->StartListL()
       
   119 				->BuildDESL()
       
   120 					->StartListL()
       
   121 						->BuildUUIDL(TUUID(TUint16(KL2CAP)))	// L2CAP
       
   122 						->BuildUintL(TSdpIntBuf<TUint16>(TUint16(port)))	// The Protocol Service Multiplexor (port) for our service
       
   123 					->EndListL()
       
   124 			->EndListL();
       
   125 		}
       
   126 	else if(iProtocol == KRFCOMM)
       
   127 		{
       
   128 		LOG_INFO((_L("Registering SDP PDL for RFCOMM")));
       
   129 		//This code will register an RFCOMM (stream) service
       
   130 		attrValDES
       
   131 			->StartListL()
       
   132 				->BuildDESL()
       
   133 					->StartListL()
       
   134 						->BuildUUIDL(TUUID(TUint16(KL2CAP))) // L2CAP
       
   135 					->EndListL()
       
   136 				->BuildDESL()
       
   137 					->StartListL()
       
   138 						->BuildUUIDL(TUUID(TUint16(KRFCOMM))) // RFCOMM
       
   139 						->BuildUintL(TSdpIntBuf<TUint8>(TUint8(port)))
       
   140 					->EndListL()
       
   141 			->EndListL();
       
   142 		}
       
   143 	iServiceRecord.UpdateAttributeL(iServiceRecordHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES);
       
   144 	CleanupStack::PopAndDestroy(attrValDES);
       
   145 	attrValDES = NULL;
       
   146 	LOG_FN_TRACE((_L("-CBtService::ConstructL")));
       
   147 	}
       
   148 
       
   149 EXPORT_C CBtService::~CBtService()
       
   150 	{
       
   151 	LOG_FN_TRACE((_L("+CBtService::~CBtService")));
       
   152 	//attempt to remove the SDP record
       
   153 	TRAP_IGNORE(iServiceRecord.DeleteRecordL(iServiceRecordHandle));
       
   154 	iServiceRecord.Close();
       
   155 	delete iAcceptorSocket;
       
   156 	LOG_FN_TRACE((_L("-CBtService::~CBtService")));
       
   157 	}
       
   158 
       
   159 /**
       
   160 Accept a new connection.
       
   161 When the incoming connection has been made, HandleAcceptCompleteL() will be called
       
   162 in this class.
       
   163 That function informs the owner by calling HandleNewConnection() or HandleConnectFailed()
       
   164 @param aBlankSocket an empty socket to receive the incoming connection. 
       
   165 */
       
   166 EXPORT_C void CBtService::AcceptConnection(CBluetoothSocket& aBlankSocket)
       
   167 	{
       
   168 	LOG_FN_TRACE((_L("+CBtService::AcceptConnection")));
       
   169 	__ASSERT_ALWAYS(iConnectionSocket == NULL, ExBtSocket::Panic(ExBtSocket::EReEntrant));
       
   170 	iConnectionSocket = &aBlankSocket;
       
   171 	iAcceptorSocket->Accept(*iConnectionSocket);
       
   172 	LOG_FN_TRACE((_L("-CBtService::AcceptConnection")));
       
   173 	}
       
   174 
       
   175 /**
       
   176 Callback from CBluetoothSocket when a new incoming connection is complete.
       
   177 Inform the owner 
       
   178 */
       
   179 void CBtService::HandleAcceptCompleteL(TInt aErr)
       
   180 	{
       
   181 	LOG_FN_TRACE((_L("+CBtService::HandleAcceptCompleteL")));
       
   182 	if(aErr == KErrNone)
       
   183 		{
       
   184 		iOwner.HandleNewConnection(iConnectionSocket); 
       
   185 		}
       
   186 	else
       
   187 		{
       
   188 		iOwner.HandleConnectFailed(aErr);
       
   189 		}
       
   190 	iConnectionSocket = NULL;
       
   191 	LOG_FN_TRACE((_L("-CBtService::HandleAcceptCompleteL")));
       
   192 	}
       
   193 
       
   194 /**
       
   195 This function is not used but must be implemented as it is pure virtual
       
   196 */
       
   197 void CBtService::HandleConnectCompleteL(TInt /*aErr*/)
       
   198 	{
       
   199 	LOG_FN_TRACE((_L("+CBtService::HandleConnectCompleteL")));
       
   200 	ExBtSocket::Panic(ExBtSocket::EBadCallback);
       
   201 	}
       
   202 
       
   203 /**
       
   204 This function is not used but must be implemented as it is pure virtual
       
   205 */
       
   206 void CBtService::HandleShutdownCompleteL(TInt /*aErr*/)
       
   207 	{
       
   208 	LOG_FN_TRACE((_L("+CBtService::HandleShutdownCompleteL")));
       
   209 	ExBtSocket::Panic(ExBtSocket::EBadCallback);
       
   210 	}
       
   211 
       
   212 /**
       
   213 This function is not used but must be implemented as it is pure virtual
       
   214 */
       
   215 void CBtService::HandleSendCompleteL(TInt /*aErr*/)
       
   216 	{
       
   217 	LOG_FN_TRACE((_L("+CBtService::HandleSendCompleteL")));
       
   218 	ExBtSocket::Panic(ExBtSocket::EBadCallback);
       
   219 	}
       
   220 
       
   221 /**
       
   222 This function is not used but must be implemented as it is pure virtual
       
   223 */
       
   224 void CBtService::HandleReceiveCompleteL(TInt /*aErr*/)
       
   225 	{
       
   226 	LOG_FN_TRACE((_L("+CBtService::HandleReceiveCompleteL")));
       
   227 	ExBtSocket::Panic(ExBtSocket::EBadCallback);
       
   228 	}
       
   229 
       
   230 /**
       
   231 This function is not used but must be implemented as it is pure virtual
       
   232 */
       
   233 void CBtService::HandleIoctlCompleteL(TInt /*aErr*/)
       
   234 	{
       
   235 	LOG_FN_TRACE((_L("+CBtService::HandleIoctlCompleteL")));
       
   236 	ExBtSocket::Panic(ExBtSocket::EBadCallback);
       
   237 	}
       
   238 
       
   239 /**
       
   240 This function is not used but must be implemented as it is pure virtual
       
   241 */
       
   242 void CBtService::HandleActivateBasebandEventNotifierCompleteL(TInt /*aErr*/, TBTBasebandEventNotification& /*aEventNotification*/)
       
   243 	{
       
   244 	LOG_FN_TRACE((_L("+CBtService::HandleActivateBasebandEventNotifierCompleteL")));
       
   245 	ExBtSocket::Panic(ExBtSocket::EBadCallback);
       
   246 	}
       
   247