Hello: 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. 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. 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. Comments/suggestions?
