Comments inline:

> On Apr 1, 2017, at 12:53 AM, Marcel Holtmann <[email protected]> wrote:
> 
> 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.
> 
The above comment is not based on the BLE specification, it is based on the 
IEEE standard which says that the two LSbit’s of the MSbyte are the 
universally/locally administered addres bit and the indiviual/group address 
bit. I was presuming that both of these bits need to be zero but was not sure. 
I was only referring to public addresses here.

> 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.

Marcel: you are incorrect I Ibelieve. I should have been more specific. There 
is a DEVICEADDRTYPE register in the FICR which says whether the address is 
public or random. The code was going to read that register to determine if the 
address in the FICR was public or random. I do not expect that register being 
set to public but if it is, the adress in the next two FICR registers should be 
the public 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.
I know it is not a public address! Well, it is not a public address if the 
DEVICEADDRTYPE says it is not. I was merely trying to point out the possibility 
that there is not a random address here. And yes, I have read the nordic 
devzone and I know I need to set the upper two bits accordingly.  I skipped 
that because I already know this and would not have a returned the address with 
those bits not being set. I even posted on the nordic devzone to get 
clarification on this. But I should have mentioned it here.
> 
>> 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.
> 
Was I wrong about this? I thought that one of the vendor specific additions was 
to set the public address? If not
> Regards
> 
> Marcel
> 

Reply via email to