//-------------------------------------------------------------------------
// Function: PnrpUnregister
//
// Purpose:  Unregister the given name from the PNRP cloud
//
// Arguments:
//   pwzIdentity : identity string originally used to register the name
//   pwzName     : name to unregister from PNRP
//   pwzCloud    : name of cloud to unregister from, NULL = global cloud
//
// Returns:  HRESULT
//
HRESULT PnrpUnregister(PCWSTR pwzIdentity, PCWSTR pwzName, PCWSTR pwzCloud)
{
    HRESULT         hr = S_OK;
    PNRPINFO        pnrpInfo = {0};
    BLOB            blPnrpData = {0};
    WSAQUERYSET     querySet = {0};
    INT             iRet;

    //
    // build the WSAQUERYSET required to unregister
    //
    pnrpInfo.dwSize = sizeof(pnrpInfo);
    pnrpInfo.dwLifetime = REGISTRATION_LIFETIME;
    pnrpInfo.lpwszIdentity = (PWSTR) pwzIdentity;

    blPnrpData.cbSize = sizeof(pnrpInfo);
    blPnrpData.pBlobData = (BYTE*)&pnrpInfo;

    querySet.dwSize = sizeof(querySet);
    querySet.dwNameSpace = NS_PNRPNAME;
    querySet.lpServiceClassId = (LPGUID)&SVCID_PNRPNAME;
    querySet.lpszServiceInstanceName = (PWSTR) pwzName;
    querySet.lpszContext = (PWSTR) pwzCloud;
    querySet.lpBlob = &blPnrpData;

    // unregister the name with PNRP
    iRet = WSASetService(&querySet, RNRSERVICE_DELETE, 0);
    if (iRet != 0)
    {
        hr = HRESULT_FROM_WIN32(WSAGetLastError());
    }

    return hr;
}
static int unregisterSDPService(ULONG sdpRecordHandle)
{
	WSAQUERYSET wqs;
	BLOB b;
	ULONG sdpVersion = BTH_SDP_VERSION;
	BTHNS_SETBLOB bthNsBlob;

	memset(&bthNsBlob, 0, sizeof(bthNsBlob));
	bthNsBlob.pRecordHandle = &sdpRecordHandle;
	bthNsBlob.ulRecordLength = sizeof(sdp_rec);
	bthNsBlob.pSdpVersion = &sdpVersion;

	b.cbSize = sizeof(bthNsBlob);
	b.pBlobData = (PBYTE) & bthNsBlob;

	memset(&wqs, 0, sizeof(WSAQUERYSET));
	wqs.dwSize = sizeof(WSAQUERYSET);
	wqs.dwNameSpace = NS_BTH;
	wqs.lpBlob = &b;

	int ret = WSASetService(&wqs, RNRSERVICE_DELETE, 0);

	if (ret == SOCKET_ERROR)
		return -1;

	return 0;
}
//      Makes this bluetooth "service" visible to anyone else searching
static int registerSDPService(ULONG * sdpRecordHandle)
{
	WSAQUERYSET wqs;
	unsigned char uuid[] = HAGGLE_BLUETOOTH_SDP_UUID;
	BLOB b;
	ULONG sdpVersion = BTH_SDP_VERSION;
	struct sdp_record *sdpRec;
	struct {
		BTHNS_SETBLOB bthNsBlob;
		char data[sizeof(struct sdp_record) - 1];
	} rec;

	*sdpRecordHandle = 0;

	memset(&rec, 0, sizeof(rec));
	rec.bthNsBlob.pRecordHandle = sdpRecordHandle;
	rec.bthNsBlob.ulRecordLength = sizeof(sdp_rec);
	rec.bthNsBlob.pSdpVersion = &sdpVersion;

	sdpRec = (struct sdp_record *) &rec.bthNsBlob.pRecord;

	/* Intitialize the record with the default values */
	memcpy(sdpRec, &sdp_rec, sizeof(sdp_rec));

	/* Add our UUID and channel */
	sdpRec->len = sizeof(struct sdp_record) - 2;
	memcpy(sdpRec->uuid, uuid, sizeof(uuid));
	sdpRec->channel = RFCOMM_DEFAULT_CHANNEL;

	b.cbSize = sizeof(rec);
	b.pBlobData = (PBYTE) & rec;

	memset(&wqs, 0, sizeof(WSAQUERYSET));
	wqs.dwSize = sizeof(WSAQUERYSET);
	wqs.dwNameSpace = NS_BTH;
	wqs.lpBlob = &b;

	int ret = WSASetService(&wqs, RNRSERVICE_REGISTER, 0);

	if (ret == SOCKET_ERROR)
		return -1;

	return 0;
}
Example #4
0
int RhoBluetoothManager::RegisterService(BYTE *rgbSdpRecord, int cSdpRecord, int iChannelOffset, UCHAR channel)
{
	ULONG recordHandle = 0;

	struct bigBlob
	{
		BTHNS_SETBLOB   b;

	}*pBigBlob;

	pBigBlob = (bigBlob *)malloc(sizeof(struct bigBlob)+cSdpRecord);
	ULONG ulSdpVersion = BTH_SDP_VERSION;
	pBigBlob->b.pRecordHandle   = &recordHandle;
	pBigBlob->b.pSdpVersion     = &ulSdpVersion;
	pBigBlob->b.fSecurity       = 0;
	pBigBlob->b.fOptions        = 0;
	pBigBlob->b.ulRecordLength  = cSdpRecord;

	memcpy (pBigBlob->b.pRecord, rgbSdpRecord, cSdpRecord);
	pBigBlob->b.pRecord[iChannelOffset] = (unsigned char)channel;
	BLOB blob;
	blob.cbSize    = sizeof(BTHNS_SETBLOB) + cSdpRecord - 1;
	blob.pBlobData = (PBYTE) pBigBlob;

	WSAQUERYSET Service;
	memset (&Service, 0, sizeof(Service));
	Service.dwSize = sizeof(Service);
	Service.lpBlob = &blob;
	Service.dwNameSpace = NS_BTH;
	if (WSASetService(&Service,RNRSERVICE_REGISTER,0) == SOCKET_ERROR)
	{
		free(pBigBlob);
		return WSAGetLastError();
	}
	else
	{
		free(pBigBlob);
		return 0;
	}
}
//-------------------------------------------------------------------------
// Function: PnrpRegister
//
// Purpose:  Register the given name in the PNRP cloud
//
// Arguments:
//   pwzIdentity : identity string created using PeerIdentityCreate
//   pwzName     : name to register in PNRP, generally the graph id
//   pwzCloud    : name of cloud to register in, NULL = global cloud
//   pNodeInfo   : local node info returned from PeerGraphGetNodeInfo
//
// Returns:  HRESULT
//
HRESULT PnrpRegister(PCWSTR pwzIdentity, PCWSTR pwzName, 
                     PCWSTR pwzCloud, __in PEER_NODE_INFO* pNodeInfo)
{
    HRESULT         hr = S_OK;
    CSADDR_INFO*    pCsaAddr = NULL;
    PNRPINFO        pnrpInfo = {0};
    BLOB            blPnrpData = {0};
    WSAQUERYSET     querySet = {0};
    ULONG           nAddrs = 0;
    ULONG           i;
    INT             iRet;

    
    //
    // build a CSADDR_INFO array from the PEER_NODE_INFO
    //
    if (pNodeInfo->cAddresses < 1)
    {
        // need at least one address to register
        hr = E_INVALIDARG;
    }

    if (SUCCEEDED(hr))
    {
        // do not attempt to register more addresses than PNRP allows
        if (pNodeInfo->cAddresses > PNRP_MAX_ENDPOINT_ADDRESSES)
        {
            nAddrs = PNRP_MAX_ENDPOINT_ADDRESSES;
        }
        else
        {
            nAddrs = pNodeInfo->cAddresses;
        }

        pCsaAddr = (CSADDR_INFO*)malloc(sizeof(CSADDR_INFO) * nAddrs);
        if (pCsaAddr != NULL)
        {
            // copy the addresses from PEER_NODE_INFO into CSADDR_INFO format
            for (i = 0; i < nAddrs; i++)
            {
                pCsaAddr[i].iProtocol = IPPROTO_TCP;
                pCsaAddr[i].iSocketType = SOCK_STREAM;
                pCsaAddr[i].LocalAddr.iSockaddrLength = sizeof(SOCKADDR_IN6);
                pCsaAddr[i].LocalAddr.lpSockaddr = (LPSOCKADDR) &pNodeInfo->pAddresses[i].sin6;
            }
        }
        else
        {
            hr = E_OUTOFMEMORY;
        }
    }

    if (SUCCEEDED(hr))
    {
        //
        // build the WSAQUERYSET required to register
        //
        pnrpInfo.dwSize = sizeof(pnrpInfo);
        pnrpInfo.dwLifetime = REGISTRATION_LIFETIME;
        pnrpInfo.lpwszIdentity = (PWSTR) pwzIdentity;

        blPnrpData.cbSize = sizeof(pnrpInfo);
        blPnrpData.pBlobData = (BYTE*)&pnrpInfo;

        querySet.dwSize = sizeof(querySet);
        querySet.dwNameSpace = NS_PNRPNAME;
        querySet.dwNumberOfCsAddrs = nAddrs;
        querySet.lpServiceClassId = (LPGUID)&SVCID_PNRPNAME;
        querySet.lpszServiceInstanceName = (PWSTR) pwzName;
        querySet.lpszContext = (PWSTR) pwzCloud;
        querySet.lpszComment = L"GraphChatMember";
        querySet.lpcsaBuffer = pCsaAddr;
        querySet.lpBlob = &blPnrpData;

        // register the name with PNRP
        iRet = WSASetService(&querySet, RNRSERVICE_REGISTER, 0);
        if (iRet != 0)
        {
            hr = HRESULT_FROM_WIN32(WSAGetLastError());
        }
    }

    if (pCsaAddr != NULL)
    {
        free(pCsaAddr);
    }

    return hr;
}
//---------------------------------------------------------------------------
//  FUNCTION: BOOL WINAPI CtrlHandler ( DWORD dwEvent )
//  Intercept CTRL-C or CTRL-BRK events and cause the server to 
//  initiate shutdown and cleanup.
//---------------------------------------------------------------------------
BOOL WINAPI CtrlHandler (   DWORD dwEvent )
{
    int nRet = 0;
    int i = 0;
    WCHAR szGuid[MAX_PATH] = {'\0'};
    HRESULT hRet;

    switch (dwEvent)
    {
    case CTRL_C_EVENT:
    case CTRL_BREAK_EVENT:
    case CTRL_LOGOFF_EVENT:
    case CTRL_SHUTDOWN_EVENT:
    case CTRL_CLOSE_EVENT:
        fEndProgram = TRUE;
        printf("CtrlHandler: cleaning up...\n");

        printf("delete service instance...\n");
        nRet = WSASetService(&g_QS, RNRSERVICE_DELETE, 0L);
        if (nRet == SOCKET_ERROR)
        {
            printf("WSASetService DELETE error %d\n", WSAGetLastError());
        } else
            printf(" Deleted.\n");
        
        printf("Removing Service class ");

        if (SUCCEEDED(hRet = StringCchPrintfW(szGuid,
                                              sizeof(szGuid)/sizeof(szGuid[0]),
                                              L"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                                              g_MyGuid.Data1,                    
                                              g_MyGuid.Data2,
                                              g_MyGuid.Data3,
                                              g_MyGuid.Data4[0],
                                              g_MyGuid.Data4[1],
                                              g_MyGuid.Data4[2],
                                              g_MyGuid.Data4[3],
                                              g_MyGuid.Data4[4],
                                              g_MyGuid.Data4[5],
                                              g_MyGuid.Data4[6],
                                              g_MyGuid.Data4[7]
                                             )))
        {
            wprintf(L"%s",szGuid);

        }

        printf("... \n");

        nRet = WSARemoveServiceClass(&g_MyGuid);
        if (nRet == SOCKET_ERROR)
        {
            printf("WSARemoveServiceClass error %d\n", WSAGetLastError());
        } else
            printf(" Removed.\n");

        for (i = 0; i < g_nMaxNumOfSocks; i++)
        {
            if ( g_aSock[i] != INVALID_SOCKET )
            {
                closesocket ( g_aSock[i] );
                g_aSock[i] = INVALID_SOCKET;
            }
        }
        break;

    default:
        // unknown type--better pass it on.
        return FALSE;
    }
    return TRUE;
}
//---------------------------------------------------------------------------
//  FUNCTION: Advertise(char* pszServerName)
//
//  PURPOSE:  Given the name of this service instance "pszServerName",
//            advertise this instance to the available name spaces.
//
//  RETURNS:
//    TRUE if succeed otherwise FALSE
//
//---------------------------------------------------------------------------
BOOL Advertise(char* pszServerName)
{
    int nRet = 0;
    int i=0;              // number of socket created           
    int nNumOfCSAddr = 0; // number of bound socket addresses 

    // Advertizing

    // Set up the WSAQuery data
    SecureZeroMemory(&g_QS,sizeof(WSAQUERYSET));
    g_QS.dwSize = sizeof(WSAQUERYSET);
    g_QS.lpszServiceInstanceName = (LPSTR)pszServerName; // service instance name
    g_QS.lpServiceClassId = &g_MyGuid; // associated service class id
    g_QS.dwNameSpace = NS_ALL;         // advertise to all name spaces
    g_QS.lpNSProviderId = NULL;
    g_QS.lpcsaBuffer = g_aCSAddr;      // our bound socket addresses
    g_QS.lpBlob = NULL;


    // Set up the g_aCSAddr data
    if (g_fNtds)
    {
        SOCKET_ADDRESS_LIST *slist=NULL;
        struct addrinfo *res=NULL,
        *resptr=NULL,
        hints;
        char            *addrbuf=NULL;
        DWORD            dwBytes=0;

        SecureZeroMemory(&hints,sizeof(hints));

        hints.ai_flags = AI_PASSIVE;
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_protocol = IPPROTO_UDP;

        nRet = getaddrinfo(NULL, "0", &hints, &res);
        if ((nRet != 0) || (res == NULL))
        {
            return FALSE;
        }

        resptr = res;
        while (resptr)
        {
            g_aSock[i] = socket(resptr->ai_family, resptr->ai_socktype, resptr->ai_protocol);
            if (g_aSock[i] == INVALID_SOCKET)
            {
                printf("socket error %d\n", WSAGetLastError());
                freeaddrinfo(res);
                return FALSE;
            }

            // bind to local host ip addresses and let system to assign a port number
            nRet = bind ( g_aSock[i], resptr->ai_addr, (int)resptr->ai_addrlen);
            if ( SOCKET_ERROR == nRet )
            {
                printf("bind error %d\n", WSAGetLastError());
                freeaddrinfo(res);
                return FALSE;
            }
            int cb = sizeof(ss_in);
            if (getsockname(g_aSock[i], (SOCKADDR *) &ss_in, &cb) == SOCKET_ERROR)
            {
                printf("getsockname error %d\n", WSAGetLastError());
                freeaddrinfo(res);
                return FALSE;
            }

            nRet = WSAIoctl(g_aSock[i], SIO_ADDRESS_LIST_QUERY, NULL, 0, NULL, 0, &dwBytes, NULL, NULL);
            if (nRet == SOCKET_ERROR)
            {
                addrbuf = (char *)HeapAlloc(GetProcessHeap(), 0, dwBytes);
                if (addrbuf == NULL)
                {
                    freeaddrinfo(res);
                    return FALSE;
                }
                nRet = WSAIoctl(g_aSock[i], SIO_ADDRESS_LIST_QUERY, NULL, 0, addrbuf, dwBytes, &dwBytes, NULL, NULL);
                if (nRet == SOCKET_ERROR)
                {
                    printf("WSAIoctl failed: %d\n", WSAGetLastError());
                    HeapFree(GetProcessHeap(), 0, addrbuf);
                    freeaddrinfo(res);
                    return FALSE;
                }
            }
            else
            {
                printf("WSAIoctl should have failed!\n");
                freeaddrinfo(res);
                return FALSE;
            }

            slist = (SOCKET_ADDRESS_LIST *)addrbuf;

            if (resptr->ai_family == AF_INET)
                printf("IPv4 addresses bound...\n");
            else if (resptr->ai_family == AF_INET6)
                printf("IPv6 addresses bound...\n");
            else
                printf("Unknown address family addresses bound...\n");

            for (int j = 0; j < slist->iAddressCount ; j++)
            {
                if (j >= g_nMaxNumOfCSAddr)
                {
                    printf("Max. number of socket address (%d) reached. We will not advertise extra ones\n", g_nMaxNumOfCSAddr);
                    break;
                }

                // Copy the address over
                memcpy(&g_aSockAddr[j], slist->Address[j].lpSockaddr, slist->Address[j].iSockaddrLength);

                // Set the port number our socket is actually bound to
                SetIpPort(&g_aSockAddr[j],&ss_in);

                char temp[128] = {'\0'};
                GetSockAddrString (&g_aSockAddr[j], slist->Address[j].iSockaddrLength, temp, 128);
                printf("Address %40s\n", temp);

                g_aCSAddr[j].iSocketType = SOCK_DGRAM;
                g_aCSAddr[j].iProtocol = IPPROTO_UDP;
                g_aCSAddr[j].LocalAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[j]; 
                g_aCSAddr[j].LocalAddr.iSockaddrLength = slist->Address[j].iSockaddrLength;
                g_aCSAddr[j].RemoteAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[j];
                g_aCSAddr[j].RemoteAddr.iSockaddrLength = slist->Address[j].iSockaddrLength;

                nNumOfCSAddr++; // increase the number SOCKADDR buffer used
            }
            i++; // increase the number of socket created

            // Go to the next address
            resptr = resptr->ai_next;

            // Free the address buffer 
            HeapFree(GetProcessHeap(), 0, addrbuf);
            addrbuf = NULL;
        }
        freeaddrinfo(res);
    }

    if (g_fSap && (nNumOfCSAddr < g_nMaxNumOfCSAddr))
    {
        // advertise into the NS_SAP name space if we still have enough
        // socket address buffer
        SecureZeroMemory(sa_ipx.sa_netnum,sizeof(sa_ipx.sa_netnum));
        SecureZeroMemory(sa_ipx.sa_nodenum,sizeof(sa_ipx.sa_nodenum));
        sa_ipx.sa_family = AF_IPX;
        sa_ipx.sa_socket = 0;

        g_aSock[i] = socket ( AF_IPX, SOCK_DGRAM, NSPROTO_IPX );
        if ( INVALID_SOCKET == g_aSock[i] )
        {
            printf("socket error %d\n", WSAGetLastError());
            return FALSE;
        }

        nRet = bind ( g_aSock[i], (SOCKADDR *) &sa_ipx, sizeof (sa_ipx) );
        if ( SOCKET_ERROR == nRet )
        {
            printf("bind error %d\n", WSAGetLastError());
            return FALSE;
        }

        //--------------Find out our bound ipx addresses------------
        int cb = 0;        // size variable
        int nAdapters = 0; // number of adapters bound with IPX

        // get the number of adapters
        cb = sizeof(nAdapters);
        nRet = getsockopt(g_aSock[i], NSPROTO_IPX, IPX_MAX_ADAPTER_NUM, (char *) &nAdapters, &cb);
        if (nRet == SOCKET_ERROR)
        {
            printf("getsockopt error %d\n", WSAGetLastError());
            return FALSE;
        }


        SOCKADDR_IPX* pSaIpx = NULL;           // a pointer to our current SOCKADDR buffer
        printf("IPX addresses bound...\n");

        for (int nIdx = 0; nIdx < nAdapters; nIdx++)
        {
            if (nNumOfCSAddr >= g_nMaxNumOfCSAddr)
            {
                printf("Max. number of socket address (%d) reached. We will not advertise extra ones\n", g_nMaxNumOfCSAddr);
                break;
            }
            // get the buffer for this SOCKADDR
            pSaIpx = (SOCKADDR_IPX *) &g_aSockAddr[nNumOfCSAddr];

            if (GetBoundIpxAddr(g_aSock[i],  pSaIpx, nIdx) == FALSE)
            {
                printf("No valid bound IPX address at adapter index %d\n", nIdx);
                // since this link is not available, nNumOfCSAddr will reuse the current SOCKADDR buffer
                continue;
            }

            char temp[DEFAULT_STRING_LEN] = {'\0'};
            GetSockAddrString (&g_aSockAddr[nNumOfCSAddr], sizeof(SOCKADDR_IPX), temp, DEFAULT_STRING_LEN);
            printf("%40s\n", temp);

            g_aCSAddr[nNumOfCSAddr].iSocketType = SOCK_DGRAM;
            g_aCSAddr[nNumOfCSAddr].iProtocol = NSPROTO_IPX;
            g_aCSAddr[nNumOfCSAddr].LocalAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[nNumOfCSAddr]; 
            g_aCSAddr[nNumOfCSAddr].LocalAddr.iSockaddrLength = sizeof(sa_ipx);
            g_aCSAddr[nNumOfCSAddr].RemoteAddr.lpSockaddr = (struct sockaddr *)&g_aSockAddr[nNumOfCSAddr];
            g_aCSAddr[nNumOfCSAddr].RemoteAddr.iSockaddrLength = sizeof(sa_ipx);

            nNumOfCSAddr++;
        }
        i++; // increase the number of socket created

        // Note: If g_fNtds is TRUE, this ipx address will be
        //       available from the NTDS name space too.

    }

    // update counters
    g_QS.dwNumberOfCsAddrs = nNumOfCSAddr;
    g_nNumOfUsedSocks = i;

    // Call WSASetService
    printf("Advertise server of instance name: %s ...\n", pszServerName);
    nRet = WSASetService(&g_QS, RNRSERVICE_REGISTER, 0L);
    if (nRet == SOCKET_ERROR)
    {
        printf("WSASetService error %d\n", WSAGetLastError());
        return FALSE;
    }
    printf("Wait for client talking to me, hit Ctrl-C to terminate...\n");
    return TRUE;

}
Example #8
0
int BtHandler::startBtServer()
{
qDebug() << "BtHandler::startBtServer()" << endl;
int retCode = 0;

WSAQUERYSET wsaQuerySet = {0};
SOCKADDR_BTH sockAddrBthLocal = {0};
int iAddrLen = sizeof(SOCKADDR_BTH);
CSADDR_INFO csAddrInfo = {0};

// Open a bluetooth socket using RFCOMM protocol
if((serverSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM)) == INVALID_SOCKET)
{
retCode = WSAGetLastError();
//emit message("Could not create bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage());
goto EXIT;
}
// Setting address family to AF_BTH indicates winsock2 to use Bluetooth port
sockAddrBthLocal.addressFamily = AF_BTH;
sockAddrBthLocal.port = BT_PORT_ANY;

// bind() associates a local address and port combination
// with the socket just created. This is most useful when
// the application is a server that has a well-known port
// that clients know about in advance.
if(bind(serverSocket, (struct sockaddr *) &sockAddrBthLocal, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
{
retCode = WSAGetLastError();
//emit message("Could not bind bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage());
goto EXIT;
}

if(getsockname(serverSocket, (struct sockaddr *)&sockAddrBthLocal, &iAddrLen) == SOCKET_ERROR)
{
retCode = WSAGetLastError();
//emit message("Could not access bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage());
goto EXIT;
}

// CSADDR_INFO
csAddrInfo.LocalAddr.iSockaddrLength = sizeof( SOCKADDR_BTH );
csAddrInfo.LocalAddr.lpSockaddr = (LPSOCKADDR)&sockAddrBthLocal;
csAddrInfo.RemoteAddr.iSockaddrLength = sizeof( SOCKADDR_BTH );
csAddrInfo.RemoteAddr.lpSockaddr = (LPSOCKADDR)&sockAddrBthLocal;
csAddrInfo.iSocketType = SOCK_STREAM;
csAddrInfo.iProtocol = BTHPROTO_RFCOMM;

// If we got an address, go ahead and advertise it.
ZeroMemory(&wsaQuerySet, sizeof(WSAQUERYSET));
wsaQuerySet.dwSize = sizeof(WSAQUERYSET);
wsaQuerySet.lpServiceClassId = (LPGUID) &LOG_VIEWS_BT_SERVICE_CLASS_GUID;
wsaQuerySet.lpszServiceInstanceName = TEXT("SmartCam Server");
wsaQuerySet.lpszComment = TEXT("Webcam over bluetooth");
wsaQuerySet.dwNameSpace = NS_BTH;
wsaQuerySet.dwNumberOfCsAddrs = 1;     // Must be 1.
wsaQuerySet.lpcsaBuffer = &csAddrInfo; // Required.

// As long as we use a blocking accept(), we will have a race
// between advertising the service and actually being ready to
// accept connections.  If we use non-blocking accept, advertise
// the service after accept has been called.
if(WSASetService(&wsaQuerySet, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
{
retCode = WSAGetLastError();
//emit message("Could not set service on bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage());
goto EXIT;
}

// listen() call indicates winsock2 to listen on a given socket for any incoming connection.
if(listen(serverSocket, SOMAXCONN) == SOCKET_ERROR)
{
retCode = WSAGetLastError();
//emit message("Could not listen on bluetooth socket: %d\n(%s)", retCode, Util::GetLastErrorMessage());
goto EXIT;
}

EXIT:

emit btStarted(retCode == 0);
return retCode;
}
Example #9
0
//extern "C"{
int hego()
{
	
    WSAData wsaData = { 0 };
    WSAStartup(MAKEWORD(2, 2), &wsaData);

    SOCKET listen_sock = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
    if (listen_sock == INVALID_SOCKET) {
        return -1;
    }

    SOCKADDR_BTH sa = { 0 };
    sa.addressFamily = AF_BTH;
    sa.port = BT_PORT_ANY;
            
    if (bind(listen_sock, (SOCKADDR *)&sa, sizeof(sa)) == SOCKET_ERROR) {
        return -1;
    }
            
    int size = sizeof(sa);
    getsockname(listen_sock, (SOCKADDR *)&sa, &size);
        
    CSADDR_INFO info = { 0 };
    info.LocalAddr.lpSockaddr = (LPSOCKADDR)&sa;
    info.LocalAddr.iSockaddrLength = sizeof(sa);
    info.iSocketType = SOCK_STREAM;
    info.iProtocol = BTHPROTO_RFCOMM;

    WSAQUERYSET set = { 0 };
    set.dwSize = sizeof(WSAQUERYSET);                              // Must be set to sizeof(WSAQUERYSET)
    set.dwOutputFlags = 0;                                         // Not used
    set.lpszServiceInstanceName = (char*)"Server";                        // Recommended.
    
    GUID guid;//cc896eaa-d8f0-d97a-c432-0301d6921a54
	guid.Data1 = 0xcc896eaa;
	guid.Data2 = 0xd8f0;
	guid.Data3 = 0xd97a;
	guid.Data4[0] = 0xc4;
	guid.Data4[1] = 0x32;
	guid.Data4[2] = 0x03;
	guid.Data4[3] = 0x01;
	guid.Data4[4] = 0xd6;
	guid.Data4[5] = 0x92;
	guid.Data4[6] = 0x1a;
	guid.Data4[7] = 0x54;
	printf("%08x-%04x-%04x", guid.Data1, guid.Data2, guid.Data3);
	int i;
	printf("-");
	for(i = 0; i < sizeof(guid.Data4); i++){
		printf("%02x", guid.Data4[i]);
		if(i == 1)
			printf("-");
	}
	printf("\n");
	
	set.lpServiceClassId = &guid;   // Requred.
	set.lpVersion = NULL;                                          // Not used.
    set.lpszComment = NULL;                                        // Optional.
    set.dwNameSpace = NS_BTH;                                      // Must be NS_BTH.
    set.lpNSProviderId = NULL;                                     // Not required.
    set.lpszContext = NULL;                                        // Not used.
    set.dwNumberOfProtocols = 0;                                   // Not used.
    set.lpafpProtocols = NULL;                                     // Not used.
    set.lpszQueryString = NULL;                                    // not used.
    set.dwNumberOfCsAddrs = 1;                                     // Must be 1.
    set.lpcsaBuffer = &info;                                       // Pointer to a CSADDR_INFO.
    set.lpBlob = NULL;                                             // Optional.

    if (WSASetService(&set, RNRSERVICE_REGISTER, 0) != 0) {
        return -1;
    }
    
    listen(listen_sock, 0);
printf("listen��accept\n");
    SOCKADDR_BTH sab2;
    int ilen = sizeof(sab2);
    SOCKET socket = accept(listen_sock, (SOCKADDR *)&sab2, &ilen);
printf("accept��recv\n");

    char buf[1024] = { 0 };
	while(0){
	    int res = recv(socket, buf, sizeof(buf), 0);
	    
	    if (res > 0)
	        printf("%s", buf);
		if(res == 0)break;
	}
printf("recv��close\n");
    closesocket(listen_sock);
    closesocket(socket);

    WSACleanup();
    return 0;
}
Example #10
0
ULONG RunServerMode(int iMaxCxnCycles)
{
	ULONG              ulRetCode = 0;
	int                iAddrLen = sizeof(SOCKADDR_BTH), iCxnCount = 0, iLengthReceived = 0, iTotalLengthReceived = 0;
	
	LPTSTR             lptstrThisComputerName = NULL;
	DWORD              dwLenComputerName = MAX_COMPUTERNAME_LENGTH + 1;
	SOCKET             LocalSocket = INVALID_SOCKET, ClientSocket = INVALID_SOCKET;
	WSAVERSION         wsaVersion = { 0 };
	WSAQUERYSET        wsaQuerySet = { 0 };
	SOCKADDR_BTH       SockAddrBthLocal = { 0 };
	LPCSADDR_INFO      lpCSAddrInfo = NULL;
	BOOL bContinue;
	char *             pszDataBufferIndex = NULL;
	char               szDataBuffer[CXN_TRANSFER_DATA_LENGTH] = { 0 };

	// Both of these fixed-size allocations can be on the stack
	if ((lpCSAddrInfo = (LPCSADDR_INFO)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(CSADDR_INFO))) == NULL)
	{
		printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n");
		ulRetCode = 1;
		goto CleanupAndExit;
	}
	else
		printf("HeapAlloc() for CSADDR_INFO (address) is OK!\n");

	if ((lptstrThisComputerName = (LPTSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLenComputerName)) == NULL)
	{
		printf("!ERROR! | Unable to allocate memory for CSADDR_INFO\n");
		ulRetCode = 1;
		goto CleanupAndExit;
	}
	else
		printf("HeapAlloc() for CSADDR_INFO (local computer name) is OK!\n");

	if (!GetComputerName(lptstrThisComputerName, &dwLenComputerName))
	{
		printf("=CRITICAL= | GetComputerName() call failed. WSAGetLastError=[%d]\n", WSAGetLastError());
		ulRetCode = 1;
		goto CleanupAndExit;
	}
	else
	{
		printf("GetComputerName() is pretty fine!\n");
		printf("Local computer name: %S\n", lptstrThisComputerName);
	}

	// Open a bluetooth socket using RFCOMM protocol
	printf("Opening local socket using socket()...\n");
	if ((LocalSocket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM)) == INVALID_SOCKET)
	{
		printf("=CRITICAL= | socket() call failed. WSAGetLastError = [%d]\n", WSAGetLastError());
		ulRetCode = 1;
		goto CleanupAndExit;
	}

	if ((2 <= g_iOutputLevel) | (LocalSocket != INVALID_SOCKET))
	{
		printf("*INFO* | socket() call succeeded! Socket = [0x%X]\n", LocalSocket);
	}

	// Setting address family to AF_BTH indicates winsock2 to use Bluetooth port
	SockAddrBthLocal.addressFamily = AF_BTH;
	// Valid ports are 1 - 31
	// SockAddrBthLocal.port = BT_PORT_ANY;
	SockAddrBthLocal.port = 1;

	// bind() associates a local address and port combination
	// with the socket just created. This is most useful when
	// the application is a server that has a well-known port
	// that clients know about in advance.
	if (bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH)) == SOCKET_ERROR)
	{
		printf("=CRITICAL= | bind() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError());
		ulRetCode = 1;
		goto CleanupAndExit;
	}

	if ((2 <= g_iOutputLevel) | (bind(LocalSocket, (struct sockaddr *) &SockAddrBthLocal, sizeof(SOCKADDR_BTH)) != SOCKET_ERROR))
	{
		printf("*INFO* | bind() call succeeded!\n");
	}

	if ((ulRetCode = getsockname(LocalSocket, (struct sockaddr *)&SockAddrBthLocal, &iAddrLen)) == SOCKET_ERROR)
	{
		printf("=CRITICAL= | getsockname() call failed w/socket = [0x%X]. WSAGetLastError=[%d]\n", LocalSocket, WSAGetLastError());
		ulRetCode = 1;
		goto CleanupAndExit;
	}
	else
	{
		printf("getsockname() is pretty fine!\n");
		printf("Local address: 0x%x\n", SockAddrBthLocal.btAddr);
	}

	// CSADDR_INFO
	lpCSAddrInfo[0].LocalAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
	lpCSAddrInfo[0].LocalAddr.lpSockaddr = (LPSOCKADDR)&SockAddrBthLocal;
	lpCSAddrInfo[0].RemoteAddr.iSockaddrLength = sizeof(SOCKADDR_BTH);
	lpCSAddrInfo[0].RemoteAddr.lpSockaddr = (LPSOCKADDR)&SockAddrBthLocal;
	lpCSAddrInfo[0].iSocketType = SOCK_STREAM;
	lpCSAddrInfo[0].iProtocol = BTHPROTO_RFCOMM;

	// If we got an address, go ahead and advertise it.
	ZeroMemory(&wsaQuerySet, sizeof(WSAQUERYSET));
	wsaQuerySet.dwSize = sizeof(WSAQUERYSET);
	wsaQuerySet.lpServiceClassId = (LPGUID)&g_guidServiceClass;
	// should be something like "Sample Bluetooth Server"
	wsaQuerySet.lpszServiceInstanceName = lptstrThisComputerName;
	wsaQuerySet.lpszComment = "Example Service instance registered in the directory service through RnR";
	wsaQuerySet.dwNameSpace = NS_BTH;
	wsaQuerySet.dwNumberOfCsAddrs = 1;      // Must be 1.
	wsaQuerySet.lpcsaBuffer = lpCSAddrInfo; // Required.

	// As long as we use a blocking accept(), we will have a race
	// between advertising the service and actually being ready to
	// accept connections.  If we use non-blocking accept, advertise
	// the service after accept has been called.
	if (WSASetService(&wsaQuerySet, RNRSERVICE_REGISTER, 0) == SOCKET_ERROR)
	{
		printf("=CRITICAL= | WSASetService() call failed. Error=[%d]\n", WSAGetLastError());
		ulRetCode = 1;
		goto CleanupAndExit;
	}
	else
		printf("WSASetService() looks fine!\n");

	// listen() call indicates winsock2 to listen on a given socket for any incoming connection.
	if (listen(LocalSocket, SOMAXCONN) == SOCKET_ERROR)
	{
		printf("=CRITICAL= | listen() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError());
		ulRetCode = 1;
		goto CleanupAndExit;
	}

	if ((2 <= g_iOutputLevel) | (listen(LocalSocket, SOMAXCONN) != SOCKET_ERROR))
	{
		printf("*INFO* | listen() call succeeded!\n");
	}

	for (iCxnCount = 0; (0 == ulRetCode) && ((iCxnCount < iMaxCxnCycles) || (iMaxCxnCycles == 0)); iCxnCount++)
	{
		printf("\n");

		// accept() call indicates winsock2 to wait for any 
		// incoming connection request from a remote socket.
		// If there are already some connection requests on the queue,
		// then accept() extracts the first request and creates a new socket and
		// returns the handle to this newly created socket. This newly created
		// socket represents the actual connection that connects the two sockets.
		if ((ClientSocket = accept(LocalSocket, NULL, NULL)) == INVALID_SOCKET)
		{
			printf("=CRITICAL= | accept() call failed. Error=[%d]\n", WSAGetLastError());
			ulRetCode = 1;
			break; // Break out of the for loop
		}

		if ((2 <= g_iOutputLevel) | (ClientSocket != INVALID_SOCKET))
		{
			printf("*INFO* | accept() call succeeded. CientSocket = [0x%X]\n", ClientSocket);
		}

		// Read data from the incoming stream
		bContinue = TRUE;
		pszDataBufferIndex = &szDataBuffer[0];
		while (bContinue && (iTotalLengthReceived < CXN_TRANSFER_DATA_LENGTH))
		{
			// recv() call indicates winsock2 to receive data
			// of an expected length over a given connection.
			// recv() may not be able to get the entire length
			// of data at once.  In such case the return value,
			// which specifies the number of bytes received,
			// can be used to calculate how much more data is
			// pending and accordingly recv() can be called again.
			iLengthReceived = recv(ClientSocket, pszDataBufferIndex, (CXN_TRANSFER_DATA_LENGTH - iTotalLengthReceived), 0);

			switch (iLengthReceived)
			{
			case 0: // socket connection has been closed gracefully
				printf("Socket connection has been closed gracefully!\n");
				bContinue = FALSE;
				break;
			case SOCKET_ERROR:
				printf("=CRITICAL= | recv() call failed. Error=[%d]\n", WSAGetLastError());
				bContinue = FALSE;
				ulRetCode = 1;
				break;
			default: // most cases when data is being read
				pszDataBufferIndex += iLengthReceived;
				iTotalLengthReceived += iLengthReceived;
				if ((2 <= g_iOutputLevel) | (iLengthReceived != SOCKET_ERROR))
				{
					//printf("*INFO* | Receiving data of length = [%d]. Current Total = [%d]\n", iLengthReceived, iTotalLengthReceived);
				}
				break;
			}
		}

		if (ulRetCode == 0)
		{
			if (CXN_TRANSFER_DATA_LENGTH != iTotalLengthReceived)
			{
				printf("+WARNING+ | Data transfer aborted mid-stream. Expected Length = [%d], Actual Length = [%d]\n",
					CXN_TRANSFER_DATA_LENGTH, iTotalLengthReceived);
			}

			printf("*INFO* | Received following data string from remote device:\n%s\n", szDataBuffer);

			// Close the connection
			if (closesocket(ClientSocket) == SOCKET_ERROR)
			{
				printf("=CRITICAL= | closesocket() call failed w/socket = [0x%X]. Error=[%d]\n", LocalSocket, WSAGetLastError());
				ulRetCode = 1;
			}
			else
			{
				// Make the connection invalid regardless
				ClientSocket = INVALID_SOCKET;

				if ((2 <= g_iOutputLevel) | (closesocket(ClientSocket) != SOCKET_ERROR))
				{
					printf("*INFO* | closesocket() call succeeded w/socket=[0x%X]\n", ClientSocket);
				}
			}
		}
	}

CleanupAndExit:
	if (INVALID_SOCKET != ClientSocket)
	{
		closesocket(ClientSocket);
		ClientSocket = INVALID_SOCKET;
	}

	if (INVALID_SOCKET != LocalSocket)
	{
		closesocket(LocalSocket);
		LocalSocket = INVALID_SOCKET;
	}

	if (NULL != lptstrThisComputerName)
	{
		HeapFree(GetProcessHeap(), 0, lptstrThisComputerName);
		lptstrThisComputerName = NULL;
	}

	if (NULL != lpCSAddrInfo)
	{
		HeapFree(GetProcessHeap(), 0, lpCSAddrInfo);
		lpCSAddrInfo = NULL;
	}

	return ulRetCode;
}