How does the BLUETOOTH_ADDRESS structure get initialized?

Tip / Sign in to post questions, reply, level up, and achieve exciting badges. Know more

cross mob
Anonymous
Not applicable

How does the bth or m_bth variable in the Hello Client C++ sample application (type BLUETOOTH_ADDRESS) become initialized?

What function call acquires this handle under Windows 7?

As this is a Windows data structure I assume it is a call to kernel32.dll, I just do not know which .dll call it is.

I looked at the sample code, and saw that the structure was set to zero shortly after the CShellManager was set up in the HelloClient.cpp file in CHelloClientApp::InitInstance().  When I single stepped through this code I saw that the m_bth member of dlbDeviceSelect was properly set up in a call to dlgDeviceSelect.DoModal(), however I cannot see how it was done.  I dove down into the Windows code of the .DoModal() function and could not see a reference to m_bth (nor could I see where a dialog box popped up either).

So, am I looking at the right part of the code or am I completely off track?

Does anyone know precisely where and how m_bth gets initialized with the actual BLUETOOTH_ADDRESS?

Thanks in advance.

!

0 Likes
1 Solution
VictorZ_46
Employee
Employee
5 comments on blog 25 sign-ins 250 likes received

BLUETOOTH_ADDRESS represents the Bluetooth Device Address (BDADDR) of the device Windows needs to connect.  During pairing Microsoft installs an instance of the device for each service found on the peer.  The Hardware ID of the device has the GUID of the service and BDADDR of the peer.  When the Device Selection dialog is initialized the function enumerates all the device installed on the system and searches for a string representing the GUID of the service the application wants to connect to.  The BDADDR is extracted from the same string.  This is how Device Selection dialog enumerates all paired devices which have required service and show them in the list for user to select.

You do not need to go through this trouble if you are writing an application for test only and you know exactly which device you want to connect. You can set the Bluetooth address in the corresponding BTP file.  For example if you are using Tag3 with EEPROM and building for 20736, you can modify WICED-Smart-SDK/Platforms/BCM92036TAG_Q32/20736_EEPROM.btp.  By default the BDADDR is set by

DLConfigBD_ADDRBase = "20737A1*****"

This tells IDE to use 5 random digits at the end, but you can modify it to be static.  For example you can set

DLConfigBD_ADDRBase = "20737A1000001"

Then in your windows application you can initialize BLUETOOTH_ADDRESS to be reverse of 0x20, 0x73, 0x7A, 0x10, 0x00, 0x01.

Without modifying btp file you can change the Make Target to specify specific BDADDR.  This procedure is described in the QSG appendix C.

View solution in original post

11 Replies
VictorZ_46
Employee
Employee
5 comments on blog 25 sign-ins 250 likes received

BLUETOOTH_ADDRESS represents the Bluetooth Device Address (BDADDR) of the device Windows needs to connect.  During pairing Microsoft installs an instance of the device for each service found on the peer.  The Hardware ID of the device has the GUID of the service and BDADDR of the peer.  When the Device Selection dialog is initialized the function enumerates all the device installed on the system and searches for a string representing the GUID of the service the application wants to connect to.  The BDADDR is extracted from the same string.  This is how Device Selection dialog enumerates all paired devices which have required service and show them in the list for user to select.

You do not need to go through this trouble if you are writing an application for test only and you know exactly which device you want to connect. You can set the Bluetooth address in the corresponding BTP file.  For example if you are using Tag3 with EEPROM and building for 20736, you can modify WICED-Smart-SDK/Platforms/BCM92036TAG_Q32/20736_EEPROM.btp.  By default the BDADDR is set by

DLConfigBD_ADDRBase = "20737A1*****"

This tells IDE to use 5 random digits at the end, but you can modify it to be static.  For example you can set

DLConfigBD_ADDRBase = "20737A1000001"

Then in your windows application you can initialize BLUETOOTH_ADDRESS to be reverse of 0x20, 0x73, 0x7A, 0x10, 0x00, 0x01.

Without modifying btp file you can change the Make Target to specify specific BDADDR.  This procedure is described in the QSG appendix C.

lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

A problem continues: I have not yet gotten BtwGattRegister to work.

I believe I understand the role of Enumeration in obtaining a BLUETOOTH_ADDRESS.

I am loading it up and am still getting a completion code of 57 and hReg is still coming back zero when I make a call to BtwGattRegister.

I am using delegates for the 3 callbacks.

pRefData is zero.

Why is a Union used got BLUETOOTH_ADDRESS? How does the .dll take this?

What does error code 57 decimal mean in this case?

Do I still have a problem with the data in bth (pAddress)?

Could there be a problem with a callbacks?

Is something expected for pRefData?

I have some C# snippets below

Thanks for your help.

********************************

What I am getting from the enumeration is the following:

Device: 221

Guid=00000000-0000-0000-0000-000000000000

Name=

Description=

Instance Id=BTHENUM\{2320567C-05CF-6EB4-C341-772851827E1B}_LOCALMFG&000F\8&2D4BDE6&0&20736A189877_C00000000

From your explanation below that would lead me to believe we have an BLUETOOTU_ADDRESS of:

0x20 0x73 0x6A 0x18 0x98 0x77.

What I see in the m_bth.rgBytes variable in the C++ code is the following:

0x77 0x98 0x18 0x6A 0x73 0x20

I load up bth.ullLong = 0x20736A189877; //%DEBUG Manually obtained from Enumeration code

rgBytes and ullLong look like they took this correctly the data.

My C# version of the union is:

public unsafe struct BLUETOOTH_ADDRESS

{

internal UInt64 ullLong; // easier to compare again BLUETOOTH_NULL_ADDRESS

internal fixed byte rgBytes[6]; // easier to format when broken out

};

The C# version of the definition of the registration function is:

/*******************************************************************************

**

    • Function BtwGattRegister

**

    • Description This function is called to register application callback

    • functions with GATT

**

    • Parameter

    • pAddress: A pointer to a BLUETOOTH_DEVICE_INFO structure. GATT will indicate

    • callbacks for this device. Application can register to receive

    • notification for all devices by passing NULL in the registration.

**

    • pfnConnectCallback: callback when connection to device goes up or down.

**

    • pfnCompleteCallback: indicates completion of read/write operation

**

    • pfnRequestCallback: indicates request from the client

**

    • pRefData: A void pointer which will be returned to the application

    • in the Connection Callback, if bWait is requested. Bluetooth core will

    • not interpret or modify this value in any way.

**

    • hReg: Output of the operation, application should call Deregister passing

    • this handle not to receive callbacks anymore.

**

    • Returns. ERROR_SUCCESS if operation succeeds

**

*******************************************************************************/

[DllImport("btwleapi.dll")]

internal static extern System.UIntPtr BtwGattRegister

(

ref BLUETOOTH_ADDRESS pAddress, //Was const to a pointer.

PFN_GATT_CONNECT_CALLBACK pfnConnectCallback,

PFN_GATT_COMPLETE_CALLBACK pfnCompleteCallback,

PFN_GATT_REQUEST_CALLBACK pfnRequestCallback,

System.IntPtr pRefData, //was PVOID These are pointers!

System.IntPtr phReg //was HANDLE: this is a pointer!

);

//[DllImport("btwleapi.dll")]

public delegate System.UIntPtr BtwGattRegister //(WINAPI *FPBtwGattRegister)

(

ref BLUETOOTH_ADDRESS pAddress, //This was a pointer to said structure

PFN_GATT_CONNECT_CALLBACK pfnConnectCallback,

PFN_GATT_COMPLETE_CALLBACK pfnCompleteCallback,

PFN_GATT_REQUEST_CALLBACK pfnRequestCallback,

System.IntPtr pRefData,

System.IntPtr phReg

);

//And now we have a function pointer to our .dll, which will be cast to what we get back from

//device. The problem is that C# does not like casts much.

BtwGattRegister FPBtwGattRegister = new _BtwGattRegister(BtwGattRegister);

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

BAE Systems; 7822 S. 46st Street Phoenix AZ 85044 USA

0 Likes

BtwGattRegister function prints out some traces to debug output.  Please download the DebugView and try to collect traces.

I am not sure about 57 decimal but 57 hex is invalid parameters.  The function returns it if you pass NULL as BDADDR or as a place where you the function needs to return the registration HANDLE.  Please note that it is C, the address rather than reference is used.

0 Likes
Anonymous
Not applicable

Probably is 57hex, I will check again.

In C# the “ref” keyword is the only way I know of passing an address of something.

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

BAE Systems; 7822 S. 46st Street Phoenix AZ 85044 USA

0 Likes

That probably means that you need to build another C dll which will be C# friendly on the top and talk to BTWLeApi at the bottom.

lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

I took a look again and changed my C# definition to include a by reference pointer.

When I did that the access to BtwGattRegister and BtwGattReadCharacteristic did work.

Thanks for your help in this matter.

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

BAE Systems; 7822 S. 46st Street Phoenix AZ 85044 USA

lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

What are the Broadcom function calls to manage the BLE whitelist?

Which header file and .dll do we use append, remove and clear MAC addresses from BLE whitelist?

I did not see anything promising in btwleapis.h, how do we access the whitelist in the Broadcom stack?

Please see the BlueGiga excerpt below, in particular the 3 whitelist related functions in the red box.

We have a requirement to pre-define whitelists to improve security under BLE.

This is a matter of some urgency for us, if we could know today that would be very helpful.

Thanks.

BLUETOOTH LOW ENERGY 4.0 WHITELIST STACK CALLS IN C#

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

BAE Systems; 7822 S. 46st Street Phoenix AZ 85044 USA

0 Likes

See blecm.h:

/// Enables adding items to the whitelist at the stack layer. Needs

/// to be done once during application creation.

void blecm_enableAddressSelection( void );

/// Allows the application to add BD_ADDR to the whitelist.

/// \param  p_select_addr Pointer to the first element in the array of BD_ADDRs to be added.

/// \param num Number of BD_ADDRs in this list. Max = 5. Setting num = 0 will clear the list.

/// \return 1 on success; 0 on failure.

int blecm_SelectAddress (BLECM_SELECT_ADDR *p_select_addr, UINT8 num);

0 Likes
lock attach
Attachments are accessible only for community members.
Anonymous
Not applicable

As a follow-up, please see below the BlueGiga function equivalents we are looking for:

public delegate void WhitelistAppendEventHandler(object sender, Bluegiga.BLE.Responses.System.WhitelistAppendEventArgs e);

public class WhitelistAppendEventArgs : EventArgs

{

public readonly Byte[] address;

public readonly Byte address_type;

public WhitelistAppendEventArgs(Byte[] address, Byte address_type)

{

this.address = address;

this.address_type = address_type;

}

}

public delegate void WhitelistRemoveEventHandler(object sender, Bluegiga.BLE.Responses.System.WhitelistRemoveEventArgs e);

public class WhitelistRemoveEventArgs : EventArgs

{

public readonly Byte[] address;

public readonly Byte address_type;

public WhitelistRemoveEventArgs(Byte[] address, Byte address_type)

{

this.address = address;

this.address_type = address_type;

}

}

public delegate void WhitelistClearEventHandler(object sender, Bluegiga.BLE.Responses.System.WhitelistClearEventArgs e);

public class WhitelistClearEventArgs : EventArgs

{

public WhitelistClearEventArgs() { }

}

Thanks.

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

BAE Systems; 7822 S. 46st Street Phoenix AZ 85044 USA

0 Likes
Anonymous
Not applicable

1. In which .dll are blecm_enableAddressSelection and blecm_SelectAddress functions located?

2. Where can I find a definition for the BD_ADDR structure?

a. I assume that BLECM_SELECT_ADDR is just an array of these structures, correct?

b. Is BD_ADDR the same as BLUETOOTH_ADDRESS?

i. This was defined as an extern in bleprofile.h

3. It also looks like we set the entire list at once, we load up all 5 MAC addresses with one function call, is that correct?

4. What is the purpose of blecm_needToSelectAddress?

5. What is the purpose of blecm_SelectTargetAddress?

6. Are 5 MAC address the absolute limit of the Broadcom Stack?

Thanks again for your help.

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

BAE Systems; 7822 S. 46st Street Phoenix AZ 85044 USA

0 Likes
Anonymous
Not applicable

Hello Victor and Frank,

Thank you very much for your inputs. This answers some of our questions. To facilitate the information exchanged, I would like to provide you with context. So let me provide you with some background.

We are working a major Army contract that has the potential to field 6 Bluetooth equipped sensors per soldier for every soldier in the Army. The suite of 6 soldier sensors will communicate with a Panasonic Toughbook laptop via Bluetooth. Our team is writing the software for the Bluetooth radio in Panasonic Toughbook laptops (as well as the firmware for the Bluetooth radios in the sensors). We are, today, using the Broadcom solution for the sensors and the Broadcom stack for the Toughbook. However, we are running into significant problems because we do not understand the API with associated Bluetooth Commands to setup white lists and other actions for both the laptop as well as the individual sensors. We are out of time to address this issue and would request a phone call to discuss with you directly to ensure that what we need is clearly conveyed. Are you available today for a conference call with our engineers? Can we suggest a conference call for 1:30 Pacific Time?

Steve Bingham

BAE Systems

IPT Technical Lead

Protection Systems

T 602 643 7261

M 480 415 6749

steve.bingham@baesystems.com<mailto:steve.bingham@baesystems.com>

7822 S 46th Street, Phoenix, Arizona 85044

David Sheh

Senior Staff Software Engineer

Platforms & Services

T 602-643-7430 | F 602-643-7698

david.sheh@baesystems.com<mailto:david.sheh@baesystems.com> / www.baesystems.com<http://www.baesystems.com/>

0 Likes