diff --git a/sdk/modules/bluetooth/bluetooth_common.c b/sdk/modules/bluetooth/bluetooth_common.c index 54fd8097a..47d5f4197 100644 --- a/sdk/modules/bluetooth/bluetooth_common.c +++ b/sdk/modules/bluetooth/bluetooth_common.c @@ -1,7 +1,7 @@ /**************************************************************************** * modules/bluetooth/bluetooth_common.c * - * Copyright 2018 Sony Semiconductor Solutions Corporation + * Copyright 2018, 2023 Sony Semiconductor Solutions Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -339,6 +339,24 @@ static int ble_event_load_bond(struct ble_event_bondinfo_t *evt) return ret; } +static int ble_event_encryption_result(struct ble_event_encryption_result_t *evt) +{ + int ret = BT_SUCCESS; + struct ble_common_ops_s *ops = g_bt_common_state.ble_common_ops; + + if (ops && ops->encryption_result) + { + ops->encryption_result(evt->conn_handle, evt->result); + } + else + { + _err("%s [BLE][Common] callback not registered.\n", __func__); + return BT_FAIL; + } + + return ret; +} + /**************************************************************************** * Public Functions ****************************************************************************/ @@ -1063,6 +1081,33 @@ int ble_disconnect(struct ble_state_s *ble_state) return ret; } +/**************************************************************************** + * Name: ble_pairing + * + * Description: + * Bluetooth LE pairing for Central + * This function is for Central role. + * + ****************************************************************************/ + +int ble_pairing(uint16_t conn_handle) +{ + int ret = BT_SUCCESS; + struct ble_hal_common_ops_s *ops = g_bt_common_state.ble_hal_common_ops; + + if (ops && ops->pairing) + { + ret = ops->pairing(conn_handle); + } + else + { + _err("%s [BLE][Common] not supported.\n", __func__); + return BT_FAIL; + } + + return ret; +} + /**************************************************************************** * Name: ble_start_advertise * @@ -1300,6 +1345,9 @@ int ble_common_event_handler(struct bt_event_t *bt_event) case BLE_COMMON_EVENT_LOAD_BOND: return ble_event_load_bond((struct ble_event_bondinfo_t *) bt_event); + case BLE_COMMON_EVENT_ENCRYPTION_RESULT: + return ble_event_encryption_result((struct ble_event_encryption_result_t *) bt_event); + default: break; } diff --git a/sdk/modules/bluetooth/hal/nrf52/ble_comm.c b/sdk/modules/bluetooth/hal/nrf52/ble_comm.c index ed20c8b68..7ef8bb2eb 100644 --- a/sdk/modules/bluetooth/hal/nrf52/ble_comm.c +++ b/sdk/modules/bluetooth/hal/nrf52/ble_comm.c @@ -149,6 +149,7 @@ static int nrf52_ble_set_ppcp(BLE_CONN_PARAMS ppcp); static uint16_t nrf52_ble_set_mtusize(uint16_t sz); static uint16_t nrf52_ble_get_mtusize(void); static int nrf52_ble_get_negotiated_mtusize(uint16_t handle); +static int nrf52_ble_pairing(uint16_t handle); static int nrf52_bt_init(void); static int nrf52_bt_finalize(void); @@ -189,6 +190,7 @@ static struct ble_hal_common_ops_s ble_hal_common_ops = .setMtuSize = nrf52_ble_set_mtusize, .getMtuSize = nrf52_ble_get_mtusize, .getNegotiatedMtuSize = nrf52_ble_get_negotiated_mtusize, + .pairing = nrf52_ble_pairing, }; static struct bt_hal_common_ops_s bt_hal_common_ops = @@ -843,6 +845,7 @@ static void on_connected(const BLE_EvtConnected* evt) g_ble_context.conn_sts = BLE_CONN_STS_CONNECTED; g_ble_context.is_scanning = false; g_ble_context.is_advertising = false; + memcpy(g_ble_context.ble_addr.addr, evt->addr.addr, BT_ADDR_LEN); conn_stat_evt.connected = true; conn_stat_evt.handle = evt->handle; @@ -905,8 +908,20 @@ static void on_read_rsp(BLE_EvtGattcRead *readRsp) static void on_exchange_feature(const BLE_EvtExchangeFeature* exchange_feature) { - BLE_GapPairingFeature* pf = &g_ble_context.pairing_feature; - int ret = BLE_GapExchangePairingFeature(exchange_feature->handle, pf); + int ret; + BLE_GapPairingFeature* pf = NULL; + + /* In central case, pairing feature must not be set, + * because it is transmitted in the parameter of + * preceding sd_ble_gap_authenticate() + */ + + if (g_ble_context.ble_role == BLE_ROLE_PERIPHERAL) + { + pf = &g_ble_context.pairing_feature; + } + + ret = BLE_GapExchangePairingFeature(exchange_feature->handle, pf); if (BLE_SUCCESS != ret) { @@ -928,6 +943,18 @@ static void on_disp_passkey(BLE_EvtDisplayPasskey* disp_passkey) LOG_OUT("[BLE][LOG]Passkey: %s\n", disp_passkey->passkey); } +static void mk_encryption_result_event(uint16_t handle, bool result) +{ + struct ble_event_encryption_result_t evt; + + evt.group_id = BLE_GROUP_COMMON; + evt.event_id = BLE_COMMON_EVENT_ENCRYPTION_RESULT; + evt.conn_handle = handle; + evt.result = result; + + ble_common_event_handler((struct bt_event_t *) &evt); +} + static void on_auth_status(BLE_EvtAuthStatus* auth_status) { int ret = BLE_SUCCESS; @@ -936,6 +963,7 @@ static void on_auth_status(BLE_EvtAuthStatus* auth_status) if (auth_status->status != BLE_GAP_SM_STATUS_SUCCESS) { LOG_OUT("[BLE][LOG]Pairing failed! ErrCode: %x\n", auth_status->status); + mk_encryption_result_event(auth_status->handle, false); return; } else @@ -1712,16 +1740,93 @@ void onAuthKeyRequest(BLE_Evt *pBleEvent, ble_evt_t *pBleNrfEvt) on_auth_key_request((BLE_EvtAuthKey *)pBleEvent->evtData); } +static int getAddrFmConnHandle(uint16_t handle, BT_ADDR *addr) +{ + if (handle != g_ble_context.ble_conn_handle) + { + /* Invalid connection handle. */ + + return -EINVAL; + } + + memcpy(addr->address, g_ble_context.ble_addr.addr, BT_ADDR_LEN); + + return BT_SUCCESS; +} + +static int searchBondInfoIndexFmConnHandle(uint16_t handle) +{ + int i; + int ret; + uint32_t list = bleBondEnableList; + BT_ADDR addr; + + ret = getAddrFmConnHandle(handle, &addr); + if (ret != BT_SUCCESS) + { + return ret; + } + + for (i = 0; i < BLE_SAVE_BOND_DEVICE_MAX_NUM; i++, list >>= 1) + { + if (list & 1) + { + if (memcmp(addr.address, + BondInfoInFlash[i].bondInfo.addr, + BT_ADDR_LEN) + == 0) + { + break; + } + } + } + + return i; +} + +static void clearBondInfo(uint16_t handle) +{ + int ret; + + ret = searchBondInfoIndexFmConnHandle(handle); + printf("searchBondInfoIndexFmConnHandle ret = %d\n", ret); + if ((ret >= 0) && (ret < BLE_SAVE_BOND_DEVICE_MAX_NUM)) + { + memset(&BondInfoInFlash[ret], 0, sizeof(bleGapWrapperBondInfo)); + bleBondEnableList &= ~(1 << ret); + mk_save_bondinfo_event(); + } +} + static void onConnSecUpdate(BLE_Evt *pBleEvent, ble_evt_t *pBleNrfEvt) { + bool result; + ble_gap_evt_t *evt = &pBleNrfEvt->evt.gap_evt; + ble_gap_conn_sec_t *prm = &evt->params.conn_sec_update.conn_sec; + pBleEvent->evtHeader = BLE_GAP_EVENT_CONN_SEC_UPDATE; pBleEvent->evtDataSize = 0; -#ifdef BLE_DBGPRT_ENABLE - ble_gap_evt_conn_sec_update_t *sec = &pBleNrfEvt->evt.gap_evt.params.conn_sec_update; - BLE_PRT("onConnSecUpdate: keysize=%d sm=%d lv=%d\n", sec->conn_sec.encr_key_size, - sec->conn_sec.sec_mode.sm, sec->conn_sec.sec_mode.lv); -#endif + BLE_PRT("onConnSecUpdate: keysize=%d sm=%d lv=%d\n", prm->encr_key_size, + prm->sec_mode.sm, prm->sec_mode.lv); + + if (prm->encr_key_size > 0) + { + /* Positive key size means that the connection is encrypted. */ + + result = true; + } + else + { + /* Non-positive key size means that encryption fails. + * In such a case, the corresponding bond information shall be cleared. + */ + + clearBondInfo(evt->conn_handle); + result = false; + } + + mk_encryption_result_event(evt->conn_handle, result); } static @@ -2959,6 +3064,36 @@ static int nrf52_ble_get_negotiated_mtusize(uint16_t handle) return commMem.client_rx_mtu; } + +static int nrf52_ble_pairing(uint16_t handle) +{ + int ret; + + ret = searchBondInfoIndexFmConnHandle(handle); + if (ret < 0) + { + /* Invalid handle error */ + + return ret; + } + else if (ret < BLE_SAVE_BOND_DEVICE_MAX_NUM) + { + /* If pairing information about this connection is stored, + * skip pairing and only encrypt with stored key. + */ + + ret = BLE_GapEncrypt(handle, &BondInfoInFlash[ret].peerEncKey); + } + else + { + /* Otherwise, execute pairing. */ + + ret = BLE_GapAuthenticate(handle, &g_ble_context.pairing_feature); + } + + return ret; +} + /**************************************************************************** * Public Data ****************************************************************************/ diff --git a/sdk/modules/bluetooth/hal/nrf52/ble_gap.c b/sdk/modules/bluetooth/hal/nrf52/ble_gap.c index 16c68627c..fb0efdb3e 100644 --- a/sdk/modules/bluetooth/hal/nrf52/ble_gap.c +++ b/sdk/modules/bluetooth/hal/nrf52/ble_gap.c @@ -418,37 +418,38 @@ int BLE_GapExchangePairingFeature(BLE_GapConnHandle connHandle, BLE_GapPairingFe int errCode = 0; ble_gap_sec_params_t secParams = {0}; ble_gap_sec_keyset_t keysExchanged = {{0}}; + ble_gap_sec_params_t *p_sec = NULL; - if(pairingFeature == NULL) { - BLE_PRT("pairingFeature is NULL!!!\n"); - return -EINVAL; - } - if((pairingFeature->oob != BLE_GAP_OOB_AUTH_DATA_PRESENT) && - (pairingFeature->oob != BLE_GAP_OOB_AUTH_DATA_NOT_PRESENT)) { - BLE_PRT("pairingFeature->oob=%d\n", pairingFeature->oob); - return -EINVAL; - } - if((pairingFeature->maxKeySize < pairingFeature->minKeySize) || - (pairingFeature->maxKeySize > BLE_GAP_MAX_KEY_SIZE) || - (pairingFeature->minKeySize < BLE_GAP_MIN_KEY_SIZE)) { - BLE_PRT("pairingFeature->maxKeySize=%d, pairingFeature->minKeySize=%d\n", pairingFeature->maxKeySize, pairingFeature->minKeySize); - return -EINVAL; - } + if(pairingFeature != NULL) { + if((pairingFeature->oob != BLE_GAP_OOB_AUTH_DATA_PRESENT) && + (pairingFeature->oob != BLE_GAP_OOB_AUTH_DATA_NOT_PRESENT)) { + BLE_PRT("pairingFeature->oob=%d\n", pairingFeature->oob); + return -EINVAL; + } + if((pairingFeature->maxKeySize < pairingFeature->minKeySize) || + (pairingFeature->maxKeySize > BLE_GAP_MAX_KEY_SIZE) || + (pairingFeature->minKeySize < BLE_GAP_MIN_KEY_SIZE)) { + BLE_PRT("pairingFeature->maxKeySize=%d, pairingFeature->minKeySize=%d\n", pairingFeature->maxKeySize, pairingFeature->minKeySize); + return -EINVAL; + } - memset(&secParams,0,sizeof(secParams)); - memset(&keysExchanged,0,sizeof(keysExchanged)); + memset(&secParams,0,sizeof(secParams)); + memset(&keysExchanged,0,sizeof(keysExchanged)); - memset(&gapMem.wrapperBondInfo.ownEncKey,0,sizeof(gapMem.wrapperBondInfo.ownEncKey)); - memset(&gapMem.wrapperBondInfo.ownIdKey,0,sizeof(gapMem.wrapperBondInfo.ownIdKey)); - memset(&gapMem.wrapperBondInfo.peerEncKey,0,sizeof(gapMem.wrapperBondInfo.peerEncKey)); - memset(&gapMem.wrapperBondInfo.peerIdKey,0,sizeof(gapMem.wrapperBondInfo.peerIdKey)); + memset(&gapMem.wrapperBondInfo.ownEncKey,0,sizeof(gapMem.wrapperBondInfo.ownEncKey)); + memset(&gapMem.wrapperBondInfo.ownIdKey,0,sizeof(gapMem.wrapperBondInfo.ownIdKey)); + memset(&gapMem.wrapperBondInfo.peerEncKey,0,sizeof(gapMem.wrapperBondInfo.peerEncKey)); + memset(&gapMem.wrapperBondInfo.peerIdKey,0,sizeof(gapMem.wrapperBondInfo.peerIdKey)); - secParams.oob = pairingFeature->oob; - secParams.io_caps = pairingFeature->ioCap; - secParams.max_key_size = pairingFeature->maxKeySize; - secParams.min_key_size = pairingFeature->minKeySize; - secParams.mitm = (pairingFeature->authReq & BLE_GAP_AUTH_MITM) >> 1; - secParams.bond = (pairingFeature->authReq & BLE_GAP_AUTH_BOND) >> 0; + secParams.oob = pairingFeature->oob; + secParams.io_caps = pairingFeature->ioCap; + secParams.max_key_size = pairingFeature->maxKeySize; + secParams.min_key_size = pairingFeature->minKeySize; + secParams.mitm = (pairingFeature->authReq & BLE_GAP_AUTH_MITM) >> 1; + secParams.bond = (pairingFeature->authReq & BLE_GAP_AUTH_BOND) >> 0; + + p_sec = &secParams; + } secParams.kdist_own.enc = 1; secParams.kdist_own.id = 1; @@ -460,7 +461,7 @@ int BLE_GapExchangePairingFeature(BLE_GapConnHandle connHandle, BLE_GapPairingFe keysExchanged.keys_peer.p_enc_key = &gapMem.wrapperBondInfo.peerEncKey; keysExchanged.keys_peer.p_id_key = &gapMem.wrapperBondInfo.peerIdKey; - errCode = sd_ble_gap_sec_params_reply(connHandle, BLE_GAP_SEC_STATUS_SUCCESS, &secParams, &keysExchanged); + errCode = sd_ble_gap_sec_params_reply(connHandle, BLE_GAP_SEC_STATUS_SUCCESS, p_sec, &keysExchanged); ret = bleConvertErrorCode((uint32_t)errCode); memcpy(&gapMem.keySet, &keysExchanged, sizeof(ble_gap_sec_keyset_t)); #ifdef BLE_DBGPRT_ENABLE @@ -914,28 +915,11 @@ int BLE_GapGetBondInfoIdList(BLE_GapBondInfoList *bondInfo) return 0; } -int BLE_GapEncrypt(BLE_GapConnHandle connHandle) +int BLE_GapEncrypt(uint16_t handle, ble_gap_enc_key_t *key) { - int index; - uint32_t list = bleBondEnableList; - int errCode = 0; - if (gapMem.is_connected) { - for(index = 0; index < BLE_SAVE_BOND_DEVICE_MAX_NUM; index++, list >>= 1) { - if (!(list & 1)) { - continue; - } - if (BondInfoInFlash[index].bondInfo.addrType != gapMem.wrapperBondInfo.bondInfo.addrType) { - continue; - } - if(!memcmp(BondInfoInFlash[index].bondInfo.addr, - gapMem.wrapperBondInfo.bondInfo.addr, BLE_GAP_ADDR_LENGTH)) { - gapMem.wrapperBondInfo = BondInfoInFlash[index]; - break; - } - } - } - errCode = sd_ble_gap_encrypt(connHandle, - &gapMem.wrapperBondInfo.peerEncKey.master_id, &gapMem.wrapperBondInfo.peerEncKey.enc_info); + int errCode; + + errCode = sd_ble_gap_encrypt(handle, &key->master_id, &key->enc_info); return bleConvertErrorCode((uint32_t)errCode); } diff --git a/sdk/modules/bluetooth/hal/nrf52/include/ble/ble_gap.h b/sdk/modules/bluetooth/hal/nrf52/include/ble/ble_gap.h index 29018bb9f..3927e3fb0 100644 --- a/sdk/modules/bluetooth/hal/nrf52/include/ble/ble_gap.h +++ b/sdk/modules/bluetooth/hal/nrf52/include/ble/ble_gap.h @@ -55,6 +55,7 @@ #include #include +#include /**************************************************************************** * Pre-processor Definitions @@ -956,7 +957,7 @@ int BLE_GapGetBondInfoIdList(BLE_GapBondInfoList *bondInfo); * No * */ -int BLE_GapEncrypt(BLE_GapConnHandle connHandle); +int BLE_GapEncrypt(uint16_t handle, ble_gap_enc_key_t *key); /**@brief Start reporting the received signal strength * @details This call allows the application to start reporting RSSI.The following events may be triggered: @ref BLE_GAP_EVENT_RSSI_CHANGED. diff --git a/sdk/modules/include/bluetooth/bt_common.h b/sdk/modules/include/bluetooth/bt_common.h index 1ca2431c5..855d2c18e 100644 --- a/sdk/modules/include/bluetooth/bt_common.h +++ b/sdk/modules/include/bluetooth/bt_common.h @@ -208,6 +208,11 @@ struct ble_common_ops_s /** Load bonding information callback */ int (*load_bondinfo)(int num, struct ble_bondinfo_s *bond); + + /** encryption result callback */ + + void (*encryption_result)(uint16_t conn_handle, bool result); + }; /** @@ -540,6 +545,16 @@ uint16_t ble_get_request_mtusize(void); int ble_get_negotiated_mtusize(uint16_t handle); +/** + * @brief Execute pairing + * + * @param[in] handle: connection handle + * + * @retval BLE_SUCCESS or negated errno. + */ + +int ble_pairing(uint16_t handle); + /** * @brief Parse advertise data. * diff --git a/sdk/modules/include/bluetooth/hal/bt_event.h b/sdk/modules/include/bluetooth/hal/bt_event.h index f140879dd..1fc542c9c 100644 --- a/sdk/modules/include/bluetooth/hal/bt_event.h +++ b/sdk/modules/include/bluetooth/hal/bt_event.h @@ -191,6 +191,7 @@ typedef enum BLE_COMMON_EVENT_MTUSIZE, /**< MTU size event */ BLE_COMMON_EVENT_SAVE_BOND, /**< Save bonding information event */ BLE_COMMON_EVENT_LOAD_BOND, /**< Load bonding information event */ + BLE_COMMON_EVENT_ENCRYPTION_RESULT, /**< Encryption result notification */ } BLE_COMMON_EVENT_ID; /** @@ -540,6 +541,19 @@ struct ble_event_bondinfo_t struct ble_bondinfo_s *bond; /**< bonding information */ }; +/** + * @struct ble_event_encryption_result_t + * @brief Bluetooth LE encryption result event + */ + +struct ble_event_encryption_result_t +{ + uint8_t group_id; /**< Event group ID @ref BT_GROUP_ID */ + uint8_t event_id; /**< Event sub ID @ref BLE_COMMON_EVENT_ID */ + uint16_t conn_handle; /**< connection handle */ + int result; /**< encryption result */ +}; + /** * @struct BT_AVRC_SUPPORT_NOTIFY_EVENT * @brief BT avrc supported notify event diff --git a/sdk/modules/include/bluetooth/hal/bt_if.h b/sdk/modules/include/bluetooth/hal/bt_if.h index fd0b73a8d..cf7d902a1 100644 --- a/sdk/modules/include/bluetooth/hal/bt_if.h +++ b/sdk/modules/include/bluetooth/hal/bt_if.h @@ -146,6 +146,7 @@ struct ble_hal_common_ops_s int (*stopScan)(void); /**< Stop scan */ int (*connect)(const BT_ADDR *addr); /**< Create a connection */ int (*disconnect)(const uint16_t conn_handle); /**< Destroy a connection */ + int (*pairing)(uint16_t conn_handle); /**< Execute pairing */ uint16_t (*setMtuSize)(uint16_t sz); /**< Set MTU size */ uint16_t (*getMtuSize)(void); /**< Get MTU size */ int (*getNegotiatedMtuSize)(uint16_t handle); /**< Get negotiated MTU size */