We help IT Professionals succeed at work.
Get Started

How to get Bluetooth friendly name

1,312 Views
Last Modified: 2013-12-14
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
Comment
Watch Question
This problem has been solved!
Unlock 1 Answer and 1 Comment.
See Answer
Why Experts Exchange?

Experts Exchange always has the answer, or at the least points me in the correct direction! It is like having another employee that is extremely experienced.

Jim Murphy
Programmer at Smart IT Solutions

When asked, what has been your best career decision?

Deciding to stick with EE.

Mohamed Asif
Technical Department Head

Being involved with EE helped me to grow personally and professionally.

Carl Webster
CTP, Sr Infrastructure Consultant
Ask ANY Question

Connect with Certified Experts to gain insight and support on specific technology challenges including:

  • Troubleshooting
  • Research
  • Professional Opinions
Did You Know?

We've partnered with two important charities to provide clean water and computer science education to those who need it most. READ MORE