/** 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"))); }
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; } }
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; }