cancel
Showing results for 
Search instead for 
Did you mean: 

STM32WB55 advertising dynamic switch from just works / legacy pincode

lgrosbois_WTK
Associate II

Hi,
I need to implement the following behavior on a STM32WB55.

Upon a command, device must advertise in 2 different modes:

  • Just works. No bonding, connection is accepted without any authentication requirements. All characteristics can be read and written.
  • Legacy pincode. No bonding, a fixed pincode shall be required by the host at every connection.

To acheive that, I followed scrupulously the ST wiki & configured the following:

  • aci_gap_set_io_capability
  • aci_gap_set_authentication_requirement
  • characteristic security permissions

I am able to have either one of the 2 scenarii, but I cannot switch dynamically from one another.


The key difference resides in the security permission of each characteristic.

  • With ATTR_PERMISSION_NONE, characteristics can be read & written without authentication (just works mode)
  • With ATTR_PERMISSION_AUTHEN_READ | ATTR_PERMISSION_AUTHEN_WRITE, pincode is properly required at each connection.

Unfortunately, I cannot switch dynamically between the 2.

I tried the following: 

  • A call to aci_gatt_set_access_permission. This returns 0x0C - command disallowed
  • I tried to telete all characteristics and re-create them calling aci_gatt_del_char and aci_gatt_add_char_desc but I have the error code 0x98 Out of memory.
    The stack fails to recreate the the last characteristic as if there was some king of memory leak in the stack (if called repeatedly, the last characteristic goes up in the creation loop ...)

Here are my questions:

  • Is there a way to achieve this without changing the permissions of the characteristics ?
  • If no, can I change the permissions dynamically ?
  • If no, do you think of any way that would not need deleting characteristics ?
  • If no, can ST investigate the possible memory leak at characteristic deletion ?

 

Code snippet of the authentication requirements:

 

    /**
     * Configuration that differs upon advertizing mode
     */
    switch (mode)
    {
    case ble_advertize_justworks:
        io_capability = IO_CAP_NO_INPUT_NO_OUTPUT;
        MITM_Mode = CFG_MITM_PROTECTION_NOT_REQUIRED;
        break;
    case ble_advertize_passkey:
        io_capability = IO_CAP_DISPLAY_ONLY;
        MITM_Mode = CFG_MITM_PROTECTION_REQUIRED;
        break;
    default:
        assert(FALSE); // should not reach here
        break;
    }

    /**
     * Set I/O capability
     */
    ret = aci_gap_set_io_capability(io_capability);
    if (ret != BLE_STATUS_SUCCESS) {
        APP_DBG_MSG("aci_gap_set_io_capability failed with status %x", ret);
        return ret;
    }
    /**
     * Configure authentication
     */
    ret = aci_gap_set_authentication_requirement(0, // No bonding required
                                                 MITM_Mode,
                                                 CFG_SECURE_NOT_SUPPORTED,
                                                 CFG_KEYPRESS_NOT_SUPPORTED,
                                                 CFG_ENCRYPTION_KEY_SIZE_MIN,
                                                 CFG_ENCRYPTION_KEY_SIZE_MAX,
                                                 0,                // use a fixed pin
                                                 passkey,          // fixed pin value
                                                 GAP_PUBLIC_ADDR); // identity address type
    if (ret != BLE_STATUS_SUCCESS)
    {
        APP_DBG_MSG("aci_gap_set_authentication_requirement failed with status %x", ret);
        return ret;
    }

    /**
     * Fill UUID with UUID
     */
    memcpy(&(ble_adv_uuid[1]), ble_get_uuid(), sizeof(ble_uuid_t));

    /**
     * Start advertising
     */
    ret = aci_gap_set_discoverable(
        ADV_IND,
        CFG_FAST_CONN_ADV_INTERVAL_MIN,
        CFG_FAST_CONN_ADV_INTERVAL_MAX,
        BLE_ADDR_TYPE,
        NO_WHITE_LIST_USE,
        sizeof(ble_local_name) - 1,    /* Don't count the 0 byte at the end */
        (uint8_t*) ble_local_name,
        sizeof(ble_adv_uuid),
        (uint8_t*) ble_adv_uuid,
        0,  /* No specific minimum connection interval */
        0   /* No specific maximum connection interval */
    );
    if (ret != BLE_STATUS_SUCCESS) {
        APP_DBG_MSG("aci_gap_set_discoverable failed with status %x", ret);
        return ret;
    }

 

11 REPLIES 11
lgrosbois_WTK
Associate II

Dear @Lubos KOUDELKA ,

 

Great news, thanks for your reply !

 

Regarding the workround, I am surprised as @grohmano stated the following on  ‎2025-09-16 4:27 AM.

Has this been changed in recent versions ?

 


2) aci_gat_set_access_permission and aci_gat_set_security_permission, can change security properties only of attributes, not entire characteristics


No it was not changed in recent version, but we clarified correctly with development the functionality and possible usage