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