/**
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")));
	}
Beispiel #2
0
bool QRfcommServer::listen(const QBluetoothAddress &address, quint16 port)
{
    Q_D(QRfcommServer);
    // listen has already been called before
    if(d->socket)
        return true;
    
    d->socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket,this);
    
    if(!d->socket)
        {
        return false;
        }
    
    d->ds = d->socket->d_ptr;
    
    if(!d->ds)
        {
        delete d->socket;
        d->socket = 0;
        return false;
        }
    
    d->ds->ensureNativeSocket(QBluetoothSocket::RfcommSocket);
    
    TRfcommSockAddr addr;
    if(!address.isNull())
        {
        // TBTDevAddr constructor may panic
        TRAPD(err,addr.SetBTAddr(TBTDevAddr(address.toUInt64())));
        if(err != KErrNone)
            {
            delete d->socket;
            d->socket = 0;
            return false;
            }
        }

    if (port == 0)
        addr.SetPort(KRfcommPassiveAutoBind);
    else
        addr.SetPort(port);

    TBTServiceSecurity security;
    switch (d->securityFlags) {
        case QBluetooth::Authentication:
            security.SetAuthentication(EMitmDesired);
            break;
        case QBluetooth::Authorization:
            security.SetAuthorisation(ETrue);
            break;
        case QBluetooth::Encryption:
        // "Secure" is BlueZ specific we just make sure the code remain compatible
        case QBluetooth::Secure:
            // authentication required
            security.SetAuthentication(EMitmDesired);
            security.SetEncryption(ETrue);
            break;
        case QBluetooth::NoSecurity:
        default:
            break;
    }
    if(d->ds->iSocket->Bind(addr) == KErrNone)
        {
        d->socket->setSocketState(QBluetoothSocket::BoundState);
        }
    else
        {
        delete d->socket;
        d->socket = 0;
        return false;
        }

    if(d->ds->iSocket->Listen(d->maxPendingConnections) != KErrNone)
        {
        delete d->socket;
        d->socket = 0;
        return false;
        }

    QBluetoothSocket *pendingSocket = new QBluetoothSocket(QBluetoothSocket::UnknownSocketType, this);
    if(!pendingSocket)
        {
        delete d->socket;
        d->socket = 0;
        return false;
        }
    QBluetoothSocketPrivate *pd = pendingSocket->d_ptr;
    pd->ensureBlankNativeSocket(QBluetoothSocket::RfcommSocket);
    connect(d->socket, SIGNAL(disconnected()), this, SLOT(_q_disconnected()));
    connect(d->socket, SIGNAL(connected()), this, SLOT(_q_connected()));
    connect(d->socket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(_q_socketError(QBluetoothSocket::SocketError)));
    if (d->ds->iSocket->Accept(*pd->iSocket) == KErrNone)
        {
        d->socket->setSocketState(QBluetoothSocket::ListeningState);
        d->activeSockets.append(pendingSocket);
        return true;
        }
    else
        {
        delete d->socket, pendingSocket;
        d->socket = 0;
        return false;
        }
}
Beispiel #3
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;
}