feat(nimble): Added LE GATT Security Levels Characteristic

This commit is contained in:
Sumeet Singh
2024-11-28 12:33:01 +05:30
committed by Rahul Tank
parent a690a05965
commit 21f8986388
6 changed files with 98 additions and 0 deletions
+8
View File
@@ -1376,6 +1376,14 @@ typedef void (*ble_gatt_svc_foreach_fn)(const struct ble_gatt_svc_def *svc,
*/
void ble_gatts_show_local(void);
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
/**
* Calculates and returns the maximum
* Security Mode 1 Level requirement.
*/
uint8_t ble_gatts_security_mode_1_level(void);
#endif
/**
* Resets the GATT server to its initial state. On success, this function
* removes all supported services, characteristics, and descriptors. This
@@ -34,6 +34,7 @@ extern "C" {
#define BLE_SVC_GAP_CHR_UUID16_APPEARANCE 0x2a01
#define BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS 0x2a04
#define BLE_SVC_GAP_CHR_UUID16_CENTRAL_ADDRESS_RESOLUTION 0x2aa6
#define BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS 0x2BF5
#if MYNEWT_VAL(ENC_ADV_DATA)
#define BLE_SVC_GAP_CHR_UUID16_KEY_MATERIAL 0x2B88
@@ -99,6 +99,13 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = {
.access_cb = ble_svc_gap_access,
.flags = BLE_GATT_CHR_F_READ,
}, {
#endif
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
/*** Characteristic: LE GATT Security Levels. */
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS),
.access_cb = ble_svc_gap_access,
.flags = BLE_GATT_CHR_F_READ,
}, {
#endif
0, /* No more characteristics in this service. */
} },
@@ -190,6 +197,26 @@ ble_svc_gap_appearance_write_access(struct ble_gatt_access_ctxt *ctxt)
#endif
}
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
static int
ble_svc_gap_security_level_read_access(uint16_t conn_handle, struct os_mbuf * om)
{
uint8_t security_level[2];
int rc;
/* Currently this characteristic is only supported for
* Security Mode 1
*/
security_level[0] = 0x01; //Mode 1
security_level[1] = ble_gatts_security_mode_1_level(); //Mode 1 Level
rc = os_mbuf_append(om, security_level, sizeof(security_level));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
#endif
static int
ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
@@ -256,6 +283,13 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
#endif
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
case BLE_SVC_GAP_CHR_UUID16_LE_GATT_SECURITY_LEVELS:
assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
rc = ble_svc_gap_security_level_read_access(conn_handle, ctxt->om);
return rc;
#endif
default:
assert(0);
return BLE_ATT_ERR_UNLIKELY;
+3
View File
@@ -240,6 +240,9 @@ void ble_att_svr_restore_range(uint16_t start_handle, uint16_t end_handle);
int ble_att_svr_tx_error_rsp(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom,
uint8_t req_op, uint16_t handle,
uint8_t error_code);
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
uint8_t ble_att_svr_security_mode_1_level(void);
#endif
/*** $clt */
/** An information-data entry in a find information response. */
+41
View File
@@ -3415,4 +3415,45 @@ int ble_att_fill_database_info(uint8_t *out_data)
return 0;
}
#endif
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
/**
* Return the highest Security Mode 1 Level requirement.
*
* @return Maximum level requirement
*/
uint8_t
ble_att_svr_security_mode_1_level()
{
struct ble_att_svr_entry *entry;
uint8_t highest_security_level = 0x01; //No Security
uint8_t sec_level;
uint8_t flags;
for (entry = STAILQ_FIRST(&ble_att_svr_list);
entry != NULL;
entry = STAILQ_NEXT(entry, ha_next)) {
flags = entry->ha_flags;
if ((flags & BLE_ATT_F_READ_AUTHEN) || (flags & BLE_ATT_F_WRITE_AUTHEN)) {
sec_level = 0x03; //Authenticated pairing with encryption
/* This is the highest currently supported value.
* Break here.
*/
highest_security_level = 0x03;
break;
} else if ((flags & BLE_ATT_F_READ_ENC) || (flags & BLE_ATT_F_WRITE_ENC)) {
sec_level = 0x02; //Unauthenticated pairing with encryption
} else {
sec_level = 0x01; //No security (No authentication and no encryption)
}
if (sec_level > highest_security_level) {
highest_security_level = sec_level;
}
}
return highest_security_level;
}
#endif
#endif
+11
View File
@@ -3185,6 +3185,17 @@ ble_gatts_lcl_svc_foreach(ble_gatt_svc_foreach_fn cb, void *arg)
#endif
}
#if MYNEWT_VAL(BLE_SVC_GAP_GATT_SECURITY_LEVEL)
uint8_t
ble_gatts_security_mode_1_level() {
uint8_t security_level;
security_level = ble_att_svr_security_mode_1_level();
return security_level;
}
#endif
int
ble_gatts_reset(void)
{