Hi Will,

> There has been some discussion of this already on the list but nothing has 
> been done yet so I wanted to resurrect the conversation with some proposals.
> 
> What we are trying to do here is the following:
> 1) Have the controller get a public device address without it being hardcoded.
> 2) Have the ability to read a chip-specific random static address if the chip 
> has one programmed.
> 
> The proposal is the following:
> 
> 1) Add two new API. These will be platform specific and will be placed in the 
> ble_hw.c file:
> 
> /* These API will return -1 if no address available. If available, will 
> return 0 and will place the address in *addr */
> int ble_hw_get_public_addr(ble_addr_t *addr)
> int ble_hw_get_static_addr(ble_addr_t *addr)
> 
> 2) Add a syscfg variable to the controller which will allow the developer to 
> set a public address of their choosing. By default this will be all 0 (no 
> public address). More on this below.
> 
> 3) The ble_hw_get_public_addr function will do the following:
> * If the user has overridden the default public address (the syscfg variable) 
> with a non-zero public address, that address will be returned by this 
> function.
> * If the default public address in the syscfg is all zero, the code will read 
> FICR and check if the device address type in the FICR is public. If so, it 
> means the nordic chip was factory programmed with a public address and this 
> will be used.
> * If both of the above checks fail, the code will read UICR[0] and UICR[1] to 
> see if a public address has been programmed into the UICR. We are doing this 
> to make it easy for folks to program their development kits with public 
> addresses so they do not have to hardcode them. UICR[0] will contain the 
> least significant 4 bytes of the device address. UICR[1] will contain the 
> most significant two bytes. The upper 16 bits of this word should be set to 
> 0. The API will presume that this is a valid public device address as long as 
> the upper 16-bits of this 32-bit word are all zero. We will also check to see 
> if this is a valid public address (see below). If both UICR[0] and UICR[1] 
> are zero, this will not be considered a valid public address.
> 
> A note on valid public addresses. Not sure if I got this right, but I think 
> the two least significant bits of the most significant byte of the public 
> address should be zero. I think I will check this to make sure it is valid.

you got that wrong. The public address is a BD_ADDR (6 octets) and the random 
address is that (also 6 octets). If you just get 6 octets, you can not 
differentiate if it is public or random. That is why I keep that LE addresses 
are actually 49 bits instead. There is "out-of-band” telling if its public or 
random.

As far I know the FICR is just a 6 octet random value. It is neither a public 
address or a static random address (you are after the static after all since 
NRPAs and RPAs are different as well). So you even need to mask the upper 2 
bits correctly to make FICR a static address.

> 4) The ble_hw_get_static_addr() will do the following:
> * Read the FICR to see if there is a random address in the FICR. This is the 
> default programming of the nrf51dk and nrf52dk. Unless you have them program 
> a public device address in the FICR, it will have a random address.
> * If the chip does not have a random address the API returns -1.

See my comment above, the FICR is just 6 octets random data. It is surely not a 
public address. It can never be since that requires to follow IEEE assignment 
rules. And it is no static address either. It needs to be masked correctly 
first. It is just a persistence 6 octets of randomness from manufacturing.

> Some things about writing apps and the BLE spec:
> 1) I realize that it is the host that tells the controller the random address 
> to use. The controller will NOT automatically use the random address from 
> ble_hw_get_static_addr(). That API will be added as a convenience so that the 
> app developer does not have to generate their own. If the app wants to use 
> this random address it needs to tell the controller to use it using 
> LE_Set_Random_Addr.
> 
> 2) Regarding the public device address. We have an app called bletiny that 
> can set the public device address I think. If the above gets approved we are 
> going to remove g_dev_addr from the code; it will be kept in the controller 
> and not available globally. The Zephyr project is considering adding vendor 
> specific HCI commands, one of which is “set public device address”. I think 
> if we go with the above approach we should add this vendor specific command 
> and that should be the way an app can set the public device address if it so 
> chooses.

The public BD_ADDR needs to be inside the controller before the call of 
HCI_Reset. Otherwise all sort of assumptions on HCI break. Until then the 
HCI_Read_BD_ADDR has to return 00:00:00:00:00:00 to indicate the controller has 
no public address. Switching the BD_ADDR mid-flight with a backdoor is going to 
fail in the most funny ways left and right.

Regards

Marcel

Reply via email to