示例#1
0
文件: netImpl.cpp 项目: Felard/MoSync
SYSCALL(MAHandle, maConnect(const char* url)) {
	TPtrC8 urlP(CBP url, SYSCALL_THIS->ValidatedStrLen(url));
	LOGST("Connect %i %s", gConnNextHandle, url);
	if(gConnections.size() >= CONN_MAX)
		return CONNERR_MAX;

	_LIT8(KLocalhost, "localhost");
	CConnection* conn = NULL;
	TPtrC8 match;
	SocketType socketType = TCP;	// initialized to placate stupid compiler
	ConnectionType type;

	// determine type of connection
	if(SSTREQ(urlP, KSocket)) {
		match.Set(KSocket);
		type = eSocket;
		socketType = TCP;
	} else if(SSTREQ(urlP, KDatagram)) {
		match.Set(KDatagram);
		type = eSocket;
		socketType = UDP;
	} else if(SSTREQ(urlP, KSsl)) {
		match.Set(KSsl);
		type = eSocket;
		socketType = SSL;
	} else if(SSTREQ(urlP, KHttp)) {
		match.Set(KHttp);
		type = eHttp;
		socketType = TCP;
	} else if(SSTREQ(urlP, KHttps)) {
		match.Set(KHttps);
		type = eHttp;
		socketType = SSL;
	} else if(SSTREQ(urlP, KBtspp)) {
		match.Set(KBtspp);
		type = eBtspp;
	} else {	//error
		return CONNERR_URL;
	}
	TPtrC8 parturl = urlP.Mid(match.Length());

	if(type == eSocket) {
		TPtrC8 hostnamePtrC8;
		int port;
		if(!splitPurl(parturl, hostnamePtrC8, port, (1<<16))) {
			return CONNERR_URL;
		}
		Smartie<CSocket> sockp(createSocket(socketType));

		_LIT8(K127, "127.");
		TInetAddr addr;
		bool localhost = false;
		if(hostnamePtrC8 == KLocalhost) {
			localhost = true;
			addr.SetAddress(INET_ADDR(127,0,0,1));
		} else if(hostnamePtrC8.Length() > K127().Length()) {
			if(hostnamePtrC8.Left(K127().Length()) == K127) {
				localhost = true;
				Smartie<HBufC16> hostname(CreateHBufC16FromDesC8LC(hostnamePtrC8));
				addr.Input(*hostname());
			}
		}
		sockp->state |= CONNOP_CONNECT;
		if(localhost) {
			StartConnOpL(CO_AddrConnect::NewL(false, *this, gConnNextHandle, *sockp(),
				addr, port, *sockp()));
		} else {
			Smartie<HBufC16> hostname(CreateHBufC16FromDesC8LC(hostnamePtrC8));
			CleanupStack::Pop(hostname());
			StartConnOpL(CO_NameConnect::NewL(gNetworkingState != EStarted,
				*this, gConnNextHandle, *sockp(), hostname, port, *sockp()));
		}
		conn = sockp.extract();
	} else if(type == eHttp) {
		CHttpConnection* http;
		TLTZ_PASS(httpCreateConnectionLC(parturl, http, HTTP_GET, socketType));
		http->state |= CONNOP_CONNECT;
		StartConnOpL(CO_HttpFinish::NewL(gNetworkingState != EStarted,
			*this, gConnNextHandle, *http, *http, true));
		http->mState = CHttpConnection::WRITING;
		conn = http;
		CleanupStack::Pop(conn);
	} else if(type == eBtspp) {
		if(gBtState != eAvailable) {
			return CONNERR_UNAVAILABLE;
		}
		TPtrC8 hostnamePtrC8;
		int port_m1_index = parturl.Locate(':');
		if(port_m1_index == KErrNotFound) {
			return false;
		}
		hostnamePtrC8.Set(parturl.Left(port_m1_index));
		if(hostnamePtrC8 == KLocalhost) {	// server
			// extract and parse uuid
			static const int KUuidLength = 32;
			int uuidStartIndex = port_m1_index + 1;
			int paramStartIndex = uuidStartIndex + KUuidLength;
			if(parturl.Length() < paramStartIndex) {
				return CONNERR_URL;
			}
			TPtrC8 uuidPtrC8(parturl.Mid(uuidStartIndex, KUuidLength));
			TUint32 us[4];
			for(int i=0; i<4; i++) {
				TPtrC8 p(uuidPtrC8.Mid(i*8, 8));
				for(int j=0; j<8; j++) {
					if(!TChar(p[j]).IsHexDigit())
						return CONNERR_URL;
				}
				LHEL(TLex8(p).Val(us[i], EHex));
			}
			TUUID uuid(us[0], us[1], us[2], us[3]);
			//TUUID uuid(KSerialPortUUID);	//temp hack

			// create listener socket
			Smartie<CBtServerSocket> sockp(new (ELeave) CBtServerSocket(gBtSdpDB));

			// extract name, if it's there. initialize the socket.
			TPtrC8 paramPtrC8(parturl.Mid(paramStartIndex));
			_LIT8(KNameParam, ";name=");
			if(SSTREQ(paramPtrC8, KNameParam)) {
				TPtrC8 namePtrC8(paramPtrC8.Mid(KNameParam().Length()));
				sockp->init(gSocketServ, uuid, true, namePtrC8);
			} else if(paramPtrC8.Length() == 0) {
				sockp->init(gSocketServ, uuid, false);
			} else {
				return CONNERR_URL;
			}
			//skip the async/connect step
			gConnections.insert(gConnNextHandle, sockp.extract());
			return gConnNextHandle++;
		} else {	// client
			// extract port number
			int port;
			if(!splitPurl(parturl, hostnamePtrC8, port, 31)) {
				return CONNERR_URL;
			}
			TRfcommSockAddr rfcsa;

			// parse address
			TBTDevAddr btaddr;
			for(int i=0; i<BTADDR_LEN; i++) {
				TLex8 btaLex(parturl.Mid(i*2, 2));
				int result = btaLex.Val(btaddr[i], EHex);
				if(result != KErrNone)
					return CONNERR_URL;
			}
			rfcsa.SetBTAddr(btaddr);

			// create socket
			Smartie<CSocket> sockp(new (ELeave) CSocket(gSocketServ, CSocket::ERfcomm));
			sockp->state |= CONNOP_CONNECT;
			StartConnOpL(CO_AddrConnect::NewL(false, *this, gConnNextHandle, *sockp(),
				rfcsa, port, *sockp()));
			conn = sockp.extract();
		}
	}
	CleanupStack::PushL(conn);
	gConnections.insert(gConnNextHandle, conn);
	CleanupStack::Pop(conn);
	return gConnNextHandle++;
}
示例#2
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")));
	}
示例#3
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;
        }
}
示例#4
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;
}