예제 #1
0
/**
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>(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>(TUint8(port)))
					->EndListL()
			->EndListL();
		}
	iServiceRecord.UpdateAttributeL(iServiceRecordHandle, KSdpAttrIdProtocolDescriptorList, *attrValDES);
	CleanupStack::PopAndDestroy(attrValDES);
	attrValDES = NULL;
	LOG_FN_TRACE((_L("-CBtService::ConstructL")));
	}
예제 #2
0
TInt CStatTransportBT::StartSocketL()
{
	TUint error;

	//make sure we are in the correct state
	asserte( iBTTransportStatus == EConnectingRegisterMgr );

	// connect to the socket server (as we are the receiver and not the initiator), create a socket, bind, listen, accept
	User::LeaveIfError( iSocketServ.Connect() );

	//now select the protocol to use (RFCOMM (serial emulation - boo.  Problems with demultiplexing if 1 generic serial port is used for multiple BT connections) or L2CAP)
	TProtocolDesc pInfo;	
	User::LeaveIfError( iSocketServ.FindProtocol(_L("RFCOMM"),pInfo ) ); 

	//open the listener socket
	User::LeaveIfError( iListenSocket.Open(iSocketServ, pInfo.iAddrFamily, pInfo.iSockType, pInfo.iProtocol) );


	//	RFComm Socket
	TRfcommSockAddr addr;
	
	//	Get First available server channel
	addr.SetPort(KRfcommPassiveAutoBind);

	//	Set the service security	
	//Set user defined EPOC TUid to internally represent the service
	iServiceSecurity.SetUid( TUid::Uid( 0x1234 ) );
	
	//Define security requirements
	iServiceSecurity.SetAuthentication( EFalse );
	iServiceSecurity.SetEncryption( EFalse ); 
	iServiceSecurity.SetAuthorisation( EFalse );
	addr.SetSecurity(iServiceSecurity);
	
	//bind
	User::LeaveIfError( iListenSocket.Bind( addr ) );

	//	Get the assigned port
	iPort=iListenSocket.LocalPort();
		
	// register with the SDP database
	error = RegWithSDPDatabaseL();
	
	if( error != KSTErrSuccess ) 
	{
		iTransport->HandleError( error, (void*)iStatus.Int() );
		return KSTErrGeneralFailure;
	}

	//listen
	User::LeaveIfError( iListenSocket.Listen( KLittleStatBTListenQueue ) );

	// create a blank socket which is used as the data socket
	User::LeaveIfError( iDataSocket.Open(iSocketServ) );

	// everything should now be set up, we just wait for a stat connection
	asserte( !IsActive() );
	iListenSocket.Accept( iDataSocket, iStatus );
	SetActive();
	return KSTErrSuccess;
}