Avatar of A_Ridiculously_Long_Unique_Name
A_Ridiculously_Long_Unique_Name
Flag for Australia asked on

How to get Bluetooth friendly name

This is a programming question.

We are presently using the WSALookupServiceBegin and WSALookupServiceNext functions to retrieve the Bluetooth address and Friendly Name. The idea is that performing a query with ulFlags set to LUP_CONTAINERS, LUP_RETURN_NAME, LUP_RETURN_ADDR we should be able to iterate over the collection to build a list of available devices and present the list of friendly names to the user.

The problem is the friendly name is not always populated. About 50% of the time we will get the friendly name and the other 50% of the time we get the Address only.

I have used the LUP_FLUSHCACHE flag with ulFlags but this has not helped. I have experimented with inserting Sleep statements in various parts of the loop but that hasn't worked either.

I am basically copying the sample program from the SDK "bthcxn.cpp".

Can someone tell me what is going wrong?

Also if I have a Bluetooth address (which is pretty reliably returned), how can I query that device directly for it's friendly name?


Sample Code:



//-----------------------------------------------------------------------------
// Get a collection of bluetooth devices in range
// Formatted as friendly name, compatible mac address (without CRC)
//
CDeviceNumberList GetDeviceNumbers()
{
    CDeviceNumberList devicesInRange;

    PWSAQUERYSET      pWSAQuerySet;
    ULONG           ulPQSSize = sizeof(WSAQUERYSET);
    pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulPQSSize);

    if (!pWSAQuerySet) return devicesInRange;


    // There is some a glitch in the WSALookupServiceBegin function, where on the first
    // time through the collection, the lpszServiceInstanceName field is not populated.
    // As per the SDK sample, performe the query twice, second time flushing the cache
    // this seems to reliably return the lpszServiceInstanceName.
    //
    int success = 0;    // number of successful iterations
    int retry = 0;
    while (retry < 5 && success < 2 && pWSAQuerySet)
    {
        //
        // WSALookupService is used for both service search and device inquiry
        // LUP_CONTAINERS is the flag which signals that we're doing a device inquiry.
        //
        ULONG ulFlags = LUP_CONTAINERS;

        //
        // Friendly device name (if available) will be returned in lpszServiceInstanceName
        //
        ulFlags |= LUP_RETURN_NAME;

        //
        // BTH_ADDR will be returned in lpcsaBuffer member of WSAQUERYSET
        //
        ulFlags |= LUP_RETURN_ADDR;

        // As per the SDK example, on the 2nd query, flush the cache
        if (retry)
        {
            // Perform a fresh lookup instead of using the device cache.
            //
            ulFlags |= LUP_FLUSHCACHE;

            Sleep(2000);
        }

        //
        // Start the lookup service
        //
        HANDLE hLookup = 0;
        ZeroMemory(pWSAQuerySet, ulPQSSize);
        pWSAQuerySet->dwNameSpace = NS_BTH;
        pWSAQuerySet->dwSize = sizeof(WSAQUERYSET);

        int iResult = WSALookupServiceBegin(pWSAQuerySet, ulFlags, &hLookup);
        if (iResult == NO_ERROR && hLookup)
        {
            // If this is the second successful query, use the results
            // Note: i will be non-zero on the subsequent query
            while (pWSAQuerySet && success)
            //while (pWSAQuerySet)
            {
                iResult = WSALookupServiceNext(hLookup, ulFlags, &ulPQSSize, pWSAQuerySet);
                if (iResult == NO_ERROR)
                {                
                    CDeviceNumber   deviceNumber;

                    CString temp(pWSAQuerySet->lpszServiceInstanceName);
                    deviceNumber.friendlyName = temp;

                    const char *macAddr = pWSAQuerySet->lpcsaBuffer->RemoteAddr.lpSockaddr->sa_data;
                    //for (int i = 6; i >= 0; i--)
                    //    deviceNumber.macAddress.append( CHex::ByteToHexString(macAddr[i]) );
                    deviceNumber.macAddress.append("AA:BB:CC");

                    devicesInRange.push_back(deviceNumber);                    
                }
                else
                {
                    iResult = WSAGetLastError();
                    if (iResult == WSAEFAULT)
                    {
                        //
                        // The buffer size for QUERYSET was insufficient.
                        // In such case 3rd parameter "ulPQSSize" of function "WSALookupServiceNext()" receives
                        // the required size.  So we can use this parameter to reallocate memory for QUERYSET.
                        //
                        HeapFree(GetProcessHeap(), 0, pWSAQuerySet);
                        pWSAQuerySet = (PWSAQUERYSET) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, ulPQSSize);
                    }
                    else
                    {
                        // End of the collection
                        break;
                    }
                }
            }
            WSALookupServiceEnd(hLookup);
            success++;
        }
        else
        {
            iResult = WSAGetLastError();
        }
        retry++;
    }


    if (pWSAQuerySet)
        HeapFree(GetProcessHeap(), 0, pWSAQuerySet);

    return devicesInRange;
}




Thanks
Wireless NetworkingMicrosoft DevelopmentC

Avatar of undefined
Last Comment
A_Ridiculously_Long_Unique_Name

8/22/2022 - Mon
ASKER CERTIFIED SOLUTION
A_Ridiculously_Long_Unique_Name

Log in or sign up to see answer
Become an EE member today7-DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform
Sign up - Free for 7 days
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.
Not exactly the question you had in mind?
Sign up for an EE membership and get your own personalized solution. With an EE membership, you can ask unlimited troubleshooting, research, or opinion questions.
ask a question
I started with Experts Exchange in 2004 and it's been a mainstay of my professional computing life since. It helped me launch a career as a programmer / Oracle data analyst
William Peck