BLE bonding to Philips Hue?

Has anyone succeeded in BLE bonding with a Philips Hue lamp or a Hue smart plug with a nRF52? Directly with BLE, without a gateway.

I suppose I have all the rest figured out, but bonding fails. I know how to reset the plug: it bonds to only one device and must be reset before controlling it from another device.

The Hue GATT API is quite nice. I can use it with the nRF Connect desktop/mobile app. There are Python examples for laptop/RasPi use... All rely on laptop/iOS/Android handling the bonding, outside the example code.

I can now BLE scan for my smart plug, filtering using the manufacturer ID 0xFE0F in the advertisement package.
I can connect to it, discover the characteristics and get a handle for the correct characteristics 932c32bd-0002-47a2-835a-a8d455b859dd inside the service 932c32bd-0000-47a2-835a-a8d455b859dd

Reading/writing requires bonding, writing to the above characteristics silently fails. Writing succeeds (TX completed) to those Hue UUIDs that do not require bonding. 

I have tried multiple options for bonding. Code copied from the ble_hrs_app example. This has so far looked most promising: with the "Just works" bonding

#define SEC_PARAM_BOND                       1                                          /**< Perform bonding. */
#define SEC_PARAM_MITM                       0                                          /**< Man In The Middle protection not required. */
#define SEC_PARAM_LESC                       0                                          /**< LE Secure Connections  enabled. */
#define SEC_PARAM_KEYPRESS                   0                                          /**< Keypress notifications not enabled. */
#define SEC_PARAM_IO_CAPABILITIES            BLE_GAP_IO_CAPS_NONE                       /**< No I/O capabilities. */
#define SEC_PARAM_OOB                        0                                          /**< Out Of Band data not available. */
#define SEC_PARAM_MIN_KEY_SIZE               7                                          /**< Minimum encryption key size. */
#define SEC_PARAM_MAX_KEY_SIZE               16                                         /**< Maximum encryption key size. */


    // Security parameters to be used for all security procedures.
    sec_param.bond           = SEC_PARAM_BOND;
    sec_param.mitm           = SEC_PARAM_MITM;
    sec_param.lesc           = SEC_PARAM_LESC;
    sec_param.keypress       = SEC_PARAM_KEYPRESS;
    sec_param.io_caps        = SEC_PARAM_IO_CAPABILITIES;
    sec_param.oob            = SEC_PARAM_OOB;
    sec_param.min_key_size   = SEC_PARAM_MIN_KEY_SIZE;
    sec_param.max_key_size   = SEC_PARAM_MAX_KEY_SIZE;
    sec_param.kdist_own.enc  = 1;
    sec_param.kdist_own.id   = 1;
    sec_param.kdist_peer.enc = 1;
    sec_param.kdist_peer.id  = 1;

    err_code = pm_sec_params_set(&sec_param);
    APP_ERROR_CHECK(err_code);

    err_code = pm_register(pm_evt_handler);
    APP_ERROR_CHECK(err_code);

 calling pm_conn_secure(conn_handle, true) and pm_conn_secure(conn_handle, false) sort of work. I get an event 

         case BLE_GAP_EVT_AUTH_STATUS:
             NRF_LOG_INFO("BLE_GAP_EVT_AUTH_STATUS: status=0x%x bond=0x%x lv4: %d kdist_own:0x%x kdist_peer:0x%x",
                          p_ble_evt->evt.gap_evt.params.auth_status.auth_status,
                          p_ble_evt->evt.gap_evt.params.auth_status.bonded,
                          p_ble_evt->evt.gap_evt.params.auth_status.sm1_levels.lv4,
                          *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_own),
                          *((uint8_t *)&p_ble_evt->evt.gap_evt.params.auth_status.kdist_peer));
            break;

that logs

BLE_GAP_EVT_AUTH_STATUS: status=0x85 bond=0x0 lv4: 0 kdist_own:0x0 kdist_peer:0x0


The status 0x85 is BLE_GAP_SEC_STATUS_PAIRING_NOT_SUPP, bonding does not happen.

I googled and found out that many had tried and failed on this same bonding issue with Arduino sketches etc.
If nothing else helps, I'll maybe need to use a BLE sniffer and see how the mobile phone app handles bonding differently...
nRF Connect (desktop) does handle the bonding correctly - what might be the difference to the code above?


Related