esp_err_t esp_ble_gap_set_security_param(esp_ble_sm_param_t param_type,
void *value, uint8_t len)
{
+ if(param_type >= ESP_BLE_SM_MAX_PARAM) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ if((param_type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY) && ( value == NULL || len < sizeof(uint8_t) || len > sizeof(uint32_t))) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ if((param_type == ESP_BLE_SM_SET_STATIC_PASSKEY)) {
+ uint32_t passkey = 0;
+ for(uint8_t i = 0; i < len; i++)
+ {
+ passkey += (((uint8_t *)value)[i]<<(8*i));
+ }
+ if(passkey > 999999) {
+ return ESP_ERR_INVALID_ARG;
+ }
+ }
+
btc_msg_t msg;
btc_ble_gap_args_t arg;
ESP_BLE_SM_SET_INIT_KEY,
ESP_BLE_SM_SET_RSP_KEY,
ESP_BLE_SM_MAX_KEY_SIZE,
+ ESP_BLE_SM_SET_STATIC_PASSKEY,
+ ESP_BLE_SM_CLEAR_STATIC_PASSKEY,
+ ESP_BLE_SM_MAX_PARAM,
} esp_ble_sm_param_t;
/// Advertising parameters
}
+void bta_dm_ble_set_static_passkey(tBTA_DM_MSG *p_data)
+{
+ BTM_BleSetStaticPasskey(p_data->ble_set_static_passkey.add, p_data->ble_set_static_passkey.static_passkey);
+}
/*******************************************************************************
**
** Function bta_dm_ble_confirm_reply
bta_sys_sendmsg(p_msg);
}
}
+
+void BTA_DmBleSetStaticPasskey(bool add, uint32_t passkey)
+{
+ tBTA_DM_API_SET_DEFAULT_PASSKEY *p_msg;
+
+ if ((p_msg = (tBTA_DM_API_SET_DEFAULT_PASSKEY *) osi_malloc(sizeof(tBTA_DM_API_SET_DEFAULT_PASSKEY))) != NULL) {
+ memset(p_msg, 0, sizeof(tBTA_DM_API_SET_DEFAULT_PASSKEY));
+
+ p_msg->hdr.event = BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT;
+ p_msg->add = add;
+ p_msg->static_passkey = passkey;
+ bta_sys_sendmsg(p_msg);
+ }
+}
+
/*******************************************************************************
**
** Function BTA_DmBleConfirmReply
#if BLE_INCLUDED == TRUE
#if SMP_INCLUDED == TRUE
- bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */
- bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */
- bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */
- bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */
+ bta_dm_add_blekey, /* BTA_DM_API_ADD_BLEKEY_EVT */
+ bta_dm_add_ble_device, /* BTA_DM_API_ADD_BLEDEVICE_EVT */
+ bta_dm_ble_passkey_reply, /* BTA_DM_API_BLE_PASSKEY_REPLY_EVT */
+ bta_dm_ble_set_static_passkey, /* BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT */
+ bta_dm_ble_confirm_reply, /* BTA_DM_API_BLE_CONFIRM_REPLY_EVT */
bta_dm_security_grant,
#endif ///SMP_INCLUDED == TRUE
bta_dm_ble_set_bg_conn_type,
BTA_DM_API_ADD_BLEKEY_EVT,
BTA_DM_API_ADD_BLEDEVICE_EVT,
BTA_DM_API_BLE_PASSKEY_REPLY_EVT,
+ BTA_DM_API_BLE_SET_STATIC_PASSKEY_EVT,
BTA_DM_API_BLE_CONFIRM_REPLY_EVT,
BTA_DM_API_BLE_SEC_GRANT_EVT,
#endif ///SMP_INCLUDED == TRUE
UINT32 passkey;
} tBTA_DM_API_PASSKEY_REPLY;
+typedef struct {
+ BT_HDR hdr;
+ BOOLEAN add;
+ UINT32 static_passkey;
+} tBTA_DM_API_SET_DEFAULT_PASSKEY;
+
typedef struct {
BT_HDR hdr;
BD_ADDR bd_addr;
tBTA_DM_API_ADD_BLEKEY add_ble_key;
tBTA_DM_API_ADD_BLE_DEVICE add_ble_device;
tBTA_DM_API_PASSKEY_REPLY ble_passkey_reply;
+ tBTA_DM_API_SET_DEFAULT_PASSKEY ble_set_static_passkey;
tBTA_DM_API_BLE_SEC_GRANT ble_sec_grant;
tBTA_DM_API_BLE_SET_BG_CONN_TYPE ble_set_bd_conn_type;
tBTA_DM_API_BLE_CONN_PARAMS ble_set_conn_params;
extern void bta_dm_add_blekey (tBTA_DM_MSG *p_data);
extern void bta_dm_add_ble_device (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_passkey_reply (tBTA_DM_MSG *p_data);
+extern void bta_dm_ble_set_static_passkey(tBTA_DM_MSG *p_data);
extern void bta_dm_ble_confirm_reply (tBTA_DM_MSG *p_data);
extern void bta_dm_security_grant (tBTA_DM_MSG *p_data);
extern void bta_dm_ble_set_bg_conn_type (tBTA_DM_MSG *p_data);
*******************************************************************************/
extern void BTA_DmBlePasskeyReply(BD_ADDR bd_addr, BOOLEAN accept, UINT32 passkey);
+/*******************************************************************************
+**
+** Function BTA_DmBleSetStaticPasskey
+**
+** Description Set BLE SMP static passkey.
+**
+** Parameters: add - add static passkey when add is true
+** clear static passkey when add is false
+** passkey - static passkey value
+**
+**
+** Returns void
+**
+*******************************************************************************/
+extern void BTA_DmBleSetStaticPasskey(bool add, uint32_t passkey);
+
/*******************************************************************************
**
** Function BTA_DmBleConfirmReply
bta_dm_co_ble_set_max_key_size(key_size);
break;
}
+ case ESP_BLE_SM_SET_STATIC_PASSKEY: {
+ uint32_t passkey = 0;
+ for(uint8_t i = 0; i < arg->set_security_param.len; i++)
+ {
+ passkey += (((uint8_t *)value)[i]<<(8*i));
+ }
+ BTA_DmBleSetStaticPasskey(true, passkey);
+ break;
+ }
+ case ESP_BLE_SM_CLEAR_STATIC_PASSKEY: {
+ BTA_DmBleSetStaticPasskey(false, 0);
+ break;
+ }
default:
break;
}
#endif
}
+void BTM_BleSetStaticPasskey(BOOLEAN add, UINT32 passkey)
+{
+#if SMP_INCLUDED == TRUE
+ SMP_SetStaticPasskey(add, passkey);
+#endif
+}
/*******************************************************************************
**
** Function BTM_BleConfirmReply
//extern
void BTM_BlePasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey);
+/*******************************************************************************
+**
+** Function BTM_BleSetStaticPasskey
+**
+** Description This function is called to set static passkey
+**
+**
+** Parameters: add - set static passkey when add is TRUE
+** clear static passkey when add is FALSE
+** passkey - static passkey
+**
+**
+*******************************************************************************/
+void BTM_BleSetStaticPasskey(BOOLEAN add, UINT32 passkey);
+
/*******************************************************************************
**
** Function BTM_BleConfirmReply
*******************************************************************************/
extern void SMP_PasskeyReply (BD_ADDR bd_addr, UINT8 res, UINT32 passkey);
+/*******************************************************************************
+**
+** Function SMP_SetStaticPasskey
+**
+** Description This function is called to set static passkey
+**
+**
+** Parameters: add - set static passkey when add is TRUE
+** clear static passkey when add is FALSE
+** passkey - static passkey
+**
+**
+*******************************************************************************/
+extern void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey);
+
/*******************************************************************************
**
** Function SMP_ConfirmReply
/* Assumption it's only using the low 8 bits, if bigger than that, need to expand it to 16 bits */
#define SMP_SEC_KEY_MASK 0x00ff
+#define SMP_PASSKEY_MASK 0xfff00000
+
/* SMP pairing state */
enum {
SMP_STATE_IDLE,
UINT8 rcvd_cmd_len;
UINT16 total_tx_unacked;
BOOLEAN wait_for_authorization_complete;
+ BOOLEAN use_static_passkey;
+ UINT32 static_passkey;
} tSMP_CB;
/* Server Action functions are of this type */
return;
}
+void SMP_SetStaticPasskey (BOOLEAN add, UINT32 passkey)
+{
+ SMP_TRACE_DEBUG("static passkey %6d", passkey);
+ tSMP_CB *p_cb = & smp_cb;
+ if(add) {
+ p_cb->static_passkey = passkey;
+ p_cb->use_static_passkey = true;
+ } else {
+ p_cb->static_passkey = 0;
+ p_cb->use_static_passkey = false;
+ }
+}
/*******************************************************************************
**
** Function SMP_ConfirmReply
smp_generate_rand_cont /* SMP_GEN_SRAND_MRAND_CONT */
};
-#define SMP_PASSKEY_MASK 0xfff00000
-
void smp_debug_print_nbyte_little_endian(UINT8 *p, const UINT8 *key_name, UINT8 len)
{
#if SMP_DEBUG == TRUE
return TRUE;
}
+void smp_use_static_passkey(void)
+{
+ tSMP_CB *p_cb = &smp_cb;
+ UINT8 *tt = p_cb->tk;
+ tSMP_KEY key;
+ UINT32 passkey = p_cb->static_passkey;
+ /* save the TK */
+ memset(p_cb->tk, 0, BT_OCTET16_LEN);
+ UINT32_TO_STREAM(tt, passkey);
+
+ key.key_type = SMP_KEY_TYPE_TK;
+ key.p_data = p_cb->tk;
+
+ if (p_cb->p_callback) {
+ (*p_cb->p_callback)(SMP_PASSKEY_NOTIF_EVT, p_cb->pairing_bda, (tSMP_EVT_DATA *)&passkey);
+ }
+
+ if (p_cb->selected_association_model == SMP_MODEL_SEC_CONN_PASSKEY_DISP) {
+ smp_sm_event(&smp_cb, SMP_KEY_READY_EVT, &passkey);
+ } else {
+ smp_sm_event(p_cb, SMP_KEY_READY_EVT, (tSMP_INT_DATA *)&key);
+ }
+}
/*******************************************************************************
**
** Function smp_generate_passkey
{
UNUSED(p_data);
- SMP_TRACE_DEBUG ("%s", __func__);
+ if(p_cb->use_static_passkey) {
+ SMP_TRACE_DEBUG ("%s use static passkey %6d", __func__, p_cb->static_passkey);
+ smp_use_static_passkey();
+ return;
+ }
+ SMP_TRACE_DEBUG ("%s generate rand passkey", __func__);
p_cb->rand_enc_proc_state = SMP_GEN_TK;
/* generate MRand or SRand */
** Returns void
**
*******************************************************************************/
-void smp_cb_cleanup(tSMP_CB *p_cb)
+void smp_cb_cleanup(tSMP_CB *p_cb)
{
tSMP_CALLBACK *p_callback = p_cb->p_callback;
UINT8 trace_level = p_cb->trace_level;
-
+ UINT32 static_passkey = p_cb->static_passkey;
+ BOOLEAN use_static_passkey = p_cb->use_static_passkey;
SMP_TRACE_EVENT("smp_cb_cleanup\n");
memset(p_cb, 0, sizeof(tSMP_CB));
p_cb->p_callback = p_callback;
p_cb->trace_level = trace_level;
+ if(use_static_passkey) {
+ p_cb->use_static_passkey = use_static_passkey;
+ p_cb->static_passkey = static_passkey;
+ }
}
/*******************************************************************************
TEST_ASSERT(ECC_CheckPointIsInElliCur_P256(&public_key));
}
}
+
+TEST_CASE("ble_smp_set_clear_static_passkey", "[ble_smp]")
+{
+ /* We wait init finish 200ms here */
+ vTaskDelay(200 / portTICK_PERIOD_MS);
+ esp_ble_auth_req_t auth_req = ESP_LE_AUTH_BOND;
+ uint32_t passkey = 123456;
+ /* test len = 0 when type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, 0) == ESP_ERR_INVALID_ARG);
+ /* test function */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(esp_ble_auth_req_t)) != ESP_ERR_INVALID_ARG);
+ /* test type >= ESP_BLE_SM_MAX_PARAM */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_PARAM, &passkey, sizeof(uint32_t)) == ESP_ERR_INVALID_ARG);
+ /* test len < sizeof(uint32_t) when type is ESP_BLE_SM_SET_STATIC_PASSKEY */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint8_t)) != ESP_ERR_INVALID_ARG);
+ /* test value is NULL when type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, NULL, sizeof(uint8_t)) == ESP_ERR_INVALID_ARG);
+ /* test value is NULL and len is 0 when type != ESP_BLE_SM_CLEAR_STATIC_PASSKEY */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, NULL, 0) == ESP_ERR_INVALID_ARG);
+ /* test function */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t)) != ESP_ERR_INVALID_ARG);
+ /* test function */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_CLEAR_STATIC_PASSKEY, &passkey, sizeof(uint32_t)) != ESP_ERR_INVALID_ARG);
+ /* test function */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_CLEAR_STATIC_PASSKEY, NULL, sizeof(uint32_t)) != ESP_ERR_INVALID_ARG);
+ /* test function */
+ TEST_ASSERT(esp_ble_gap_set_security_param(ESP_BLE_SM_CLEAR_STATIC_PASSKEY, NULL, 0) != ESP_ERR_INVALID_ARG);
+}
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer deivce.
- ESP_LOGI(GATTC_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey);
+ ESP_LOGI(GATTC_TAG, "The passkey Notify number:%06d", param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
break;
case ESP_GAP_BLE_PASSKEY_NOTIF_EVT: ///the app will receive this evt when the IO has Output capability and the peer device IO has Input capability.
///show the passkey number to the user to input it in the peer deivce.
- ESP_LOGI(GATTS_TABLE_TAG, "The passkey Notify number:%d", param->ble_security.key_notif.passkey);
+ ESP_LOGI(GATTS_TABLE_TAG, "The passkey Notify number:%06d", param->ble_security.key_notif.passkey);
break;
case ESP_GAP_BLE_KEY_EVT:
//shows the ble key info share with peer device to the user.
uint8_t key_size = 16; //the key size should be 7~16 bytes
uint8_t init_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
uint8_t rsp_key = ESP_BLE_ENC_KEY_MASK | ESP_BLE_ID_KEY_MASK;
+ //set static passkey
+ uint32_t passkey = 123456;
+ esp_ble_gap_set_security_param(ESP_BLE_SM_SET_STATIC_PASSKEY, &passkey, sizeof(uint32_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_AUTHEN_REQ_MODE, &auth_req, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_IOCAP_MODE, &iocap, sizeof(uint8_t));
esp_ble_gap_set_security_param(ESP_BLE_SM_MAX_KEY_SIZE, &key_size, sizeof(uint8_t));