Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 116 additions & 3 deletions nimble/host/include/host/ble_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

#include <inttypes.h>
#include "nimble/ble.h"
#include "../../host/src/ble_gatt_priv.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -40,13 +41,16 @@ extern "C" {
* @{
*/
/** Object type: Our security material. */
#define BLE_STORE_OBJ_TYPE_OUR_SEC 1
#define BLE_STORE_OBJ_TYPE_OUR_SEC 1

/** Object type: Peer security material. */
#define BLE_STORE_OBJ_TYPE_PEER_SEC 2
#define BLE_STORE_OBJ_TYPE_PEER_SEC 2

/** Object type: Client Characteristic Configuration Descriptor. */
#define BLE_STORE_OBJ_TYPE_CCCD 3
#define BLE_STORE_OBJ_TYPE_CCCD 3

/** Object type: Peer Client Supported Features. */
#define BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT 4

/** @} */

Expand Down Expand Up @@ -154,6 +158,33 @@ struct ble_store_value_cccd {
unsigned value_changed:1;
};

/**
* Used as a key for lookups of stored client supported features of specific
* peer. This struct corresponds to the BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT
* store object type.
*/
struct ble_store_key_cl_sup_feat {
/**
* Key by peer identity address;
* peer_addr=BLE_ADDR_NONE means don't key off peer.
*/
ble_addr_t peer_addr;

/** Number of results to skip; 0 means retrieve the first match. */
uint8_t idx;
};

/**
* Represents a stored client supported features of specific peer. This struct
* corresponds to the BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT store object type.
*/
struct ble_store_value_cl_sup_feat {
/** The peer address associated with the stored supported features. */
ble_addr_t peer_addr;
/** Client supported features of a specific peer. */
uint8_t peer_cl_sup_feat[BLE_GATT_CHR_CLI_SUP_FEAT_SZ];
};

/**
* Used as a key for store lookups. This union must be accompanied by an
* object type code to indicate which field is valid.
Expand All @@ -163,6 +194,8 @@ union ble_store_key {
struct ble_store_key_sec sec;
/** Key for Client Characteristic Configuration Descriptor store lookups. */
struct ble_store_key_cccd cccd;
/** Key for Peer Client Supported Features store lookpus. */
struct ble_store_key_cl_sup_feat feat;
};

/**
Expand All @@ -174,6 +207,8 @@ union ble_store_value {
struct ble_store_value_sec sec;
/** Stored Client Characteristic Configuration Descriptor. */
struct ble_store_value_cccd cccd;
/** Stored Client Supported Features. */
struct ble_store_value_cl_sup_feat feat;
};

/** Represents an event associated with the BLE Store. */
Expand Down Expand Up @@ -556,6 +591,64 @@ int ble_store_write_cccd(const struct ble_store_value_cccd *value);
*/
int ble_store_delete_cccd(const struct ble_store_key_cccd *key);

/**
* @brief Reads Client Supported Features value from a storage
*
* This function reads client supported features value from a storage based
* on the provied key and stores the retrieved value in the specified output
* structure.
*
* @param key A pointer to a 'ble_store_key_cl_sup_feat'
* struct representing the key to identify
* Client Supported Features value to be read.
* @param out_value A pointer to a 'ble_store_value_cl_sup_feat'
* struct to store the Client Supported
* Features value read from a storage
*
* @return 0 if the Client Supported Features values was
* successfully read and stored in the
* 'out_value' structure;
* Non-zero on error
*/
int
ble_store_read_peer_cl_sup_feat(const struct ble_store_key_cl_sup_feat *key,
struct ble_store_value_cl_sup_feat *out_value);

/**
* @brief Writes a Client Supported Features value to a storage.
*
* This function writes a Client Supported Features value to a storage based on
* the provided value
*
* @param value A pointer to a 'ble_store_value_cl_sup_feat'
* structure representing the Client Supported
* Features value to be written to a storage.
*
* @return 0 if the value was successfully written to
* a storage;
* Non-zero on error.
*/
int
ble_store_write_peer_cl_sup_feat(const struct ble_store_value_cl_sup_feat
*value);

/**
* @brief Deletes a Client Supported Features value from a storage.
*
* This function deletes a Client Supported Features value from a storage based
* on the provided key.
*
* @param key A pointer to a 'ble_store_key_cl_sup_feat'
* structure identifying the Client Supported
* Features value to be deleted from
* a storage.
*
* @return 0 if the Client Supported Features value was
* successfully written to a storage;
* Non-zero on error.
*/
int ble_store_delete_peer_cl_sup_feat(const struct ble_store_key_cl_sup_feat
*key);

/**
* @brief Generates a storage key for a security material entry from its value.
Expand Down Expand Up @@ -587,6 +680,26 @@ void ble_store_key_from_value_sec(struct ble_store_key_sec *out_key,
void ble_store_key_from_value_cccd(struct ble_store_key_cccd *out_key,
const struct ble_store_value_cccd *value);

/**
* @brief Generates a storage key for a Client Supported Features entry from
* its value
*
* This function generates a storage key for a Client Supported Features value
* entry based on the provided value.
*
* @param out_key A pointer to a 'ble_store_key_cl_sup_feat'
* structure where the generated key will be
* stored.
* @param value A pointer to a 'ble_store_value_cl_sup_feat'
* structure containing the Client Supported
* Features value from which the key will be
* generated.
*/
void
ble_store_key_from_value_peer_cl_sup_feat(struct ble_store_key_cl_sup_feat
*out_key,
const struct ble_store_value_cl_sup_feat
*value);

/**
* @brief Generates a storage key from a value based on the object type.
Expand Down
23 changes: 21 additions & 2 deletions nimble/host/src/ble_gatts.c
Original file line number Diff line number Diff line change
Expand Up @@ -1612,6 +1612,8 @@ int
ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat, uint8_t len)
{
struct ble_hs_conn *conn;
struct ble_store_key_cl_sup_feat feat_key;
struct ble_store_value_cl_sup_feat feat_val;
int rc = 0;

if (out_supported_feat == NULL) {
Expand All @@ -1629,8 +1631,16 @@ ble_gatts_peer_cl_sup_feat_get(uint16_t conn_handle, uint8_t *out_supported_feat
len = BLE_GATT_CHR_CLI_SUP_FEAT_SZ;
}

memcpy(out_supported_feat, conn->bhc_gatt_svr.peer_cl_sup_feat,
sizeof(uint8_t) * len);
if (conn->bhc_sec_state.bonded) {
feat_key.peer_addr = conn->bhc_peer_addr;
feat_key.idx = 0;
ble_store_read_peer_cl_sup_feat(&feat_key, &feat_val);
memcpy(out_supported_feat, feat_val.peer_cl_sup_feat,
sizeof(uint8_t) * len);
} else {
memcpy(out_supported_feat, conn->bhc_gatt_svr.peer_cl_sup_feat,
sizeof(uint8_t) * len);
}

done:
ble_hs_unlock();
Expand All @@ -1641,6 +1651,7 @@ int
ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om)
{
struct ble_hs_conn *conn;
struct ble_store_value_cl_sup_feat store_feat;
uint8_t feat[BLE_GATT_CHR_CLI_SUP_FEAT_SZ] = {};
uint16_t len;
int rc = 0;
Expand Down Expand Up @@ -1686,6 +1697,14 @@ ble_gatts_peer_cl_sup_feat_update(uint16_t conn_handle, struct os_mbuf *om)

memcpy(conn->bhc_gatt_svr.peer_cl_sup_feat, feat, BLE_GATT_CHR_CLI_SUP_FEAT_SZ);

if (conn->bhc_sec_state.bonded) {
store_feat.peer_addr = conn->bhc_peer_addr;
memcpy(store_feat.peer_cl_sup_feat,
feat,
BLE_GATT_CHR_CLI_SUP_FEAT_SZ);
ble_store_write_peer_cl_sup_feat(&store_feat);
}

done:
ble_hs_unlock();
return rc;
Expand Down
57 changes: 57 additions & 0 deletions nimble/host/src/ble_store.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,6 +249,44 @@ ble_store_write_peer_sec(const struct ble_store_value_sec *value_sec)
return 0;
}

int
ble_store_read_peer_cl_sup_feat(const struct ble_store_key_cl_sup_feat *key,
struct ble_store_value_cl_sup_feat *out_value)
{
union ble_store_value *store_value;
union ble_store_key *store_key;
int rc;

store_key = (void *)key;
store_value = (void *)out_value;
rc = ble_store_read(BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT, store_key,
store_value);
return rc;
}

int
ble_store_write_peer_cl_sup_feat(const struct ble_store_value_cl_sup_feat
*value)
{
union ble_store_value *store_value;
int rc;

store_value = (void *)value;
rc = ble_store_write(BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT, store_value);
return rc;
}

int
ble_store_delete_peer_cl_sup_feat(const struct ble_store_key_cl_sup_feat *key)
{
union ble_store_key *store_key;
int rc;

store_key = (void *)key;
rc = ble_store_delete(BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT, store_key);
return rc;
}

int
ble_store_read_cccd(const struct ble_store_key_cccd *key,
struct ble_store_value_cccd *out_value)
Expand Down Expand Up @@ -302,6 +340,16 @@ ble_store_key_from_value_sec(struct ble_store_key_sec *out_key,
out_key->idx = 0;
}

void
ble_store_key_from_value_peer_cl_sup_feat(struct ble_store_key_cl_sup_feat
*out_key,
const struct ble_store_value_cl_sup_feat
*value)
{
out_key->peer_addr = value->peer_addr;
out_key->idx = 0;
}

void
ble_store_key_from_value(int obj_type,
union ble_store_key *out_key,
Expand All @@ -317,6 +365,10 @@ ble_store_key_from_value(int obj_type,
ble_store_key_from_value_cccd(&out_key->cccd, &value->cccd);
break;

case BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT:
ble_store_key_from_value_peer_cl_sup_feat(&out_key->feat,
&value->feat);

default:
BLE_HS_DBG_ASSERT(0);
break;
Expand Down Expand Up @@ -346,6 +398,10 @@ ble_store_iterate(int obj_type,
key.cccd.peer_addr = *BLE_ADDR_ANY;
pidx = &key.cccd.idx;
break;
case BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT:
key.feat.peer_addr = *BLE_ADDR_ANY;
pidx = &key.feat.idx;
break;
default:
BLE_HS_DBG_ASSERT(0);
return BLE_HS_EINVAL;
Expand Down Expand Up @@ -390,6 +446,7 @@ ble_store_clear(void)
BLE_STORE_OBJ_TYPE_OUR_SEC,
BLE_STORE_OBJ_TYPE_PEER_SEC,
BLE_STORE_OBJ_TYPE_CCCD,
BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT,
};
union ble_store_key key;
int obj_type;
Expand Down
9 changes: 9 additions & 0 deletions nimble/host/src/ble_store_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,14 @@ ble_store_util_delete_peer(const ble_addr_t *peer_id_addr)
return rc;
}

memset(&key, 0, sizeof key);
key.feat.peer_addr = *peer_id_addr;

rc = ble_store_util_delete_all(BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT, &key);
if (rc != 0) {
return rc;
}

return 0;
}

Expand Down Expand Up @@ -192,6 +200,7 @@ ble_store_util_status_rr(struct ble_store_status_event *event, void *arg)
switch (event->overflow.obj_type) {
case BLE_STORE_OBJ_TYPE_OUR_SEC:
case BLE_STORE_OBJ_TYPE_PEER_SEC:
case BLE_STORE_OBJ_TYPE_PEER_CL_SUP_FEAT:
return ble_gap_unpair_oldest_peer();
case BLE_STORE_OBJ_TYPE_CCCD:
/* Try unpairing oldest peer except current peer */
Expand Down
Loading