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
3 changes: 3 additions & 0 deletions nimble/host/include/host/ble_att.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@ struct os_mbuf;
/**Insufficient Resources to complete the request. */
#define BLE_ATT_ERR_INSUFFICIENT_RES 0x11

/** The server requests the client to rediscover the database. */
#define BLE_ATT_ERR_DATABASE_OUT_OF_SYNC 0x12

/**Requested value is not allowed. */
#define BLE_ATT_ERR_VALUE_NOT_ALLOWED 0x13

Expand Down
27 changes: 27 additions & 0 deletions nimble/host/include/host/ble_gatt.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,27 @@ struct ble_hs_cfg;
/** GATT service 16-bit UUID. */
#define BLE_GATT_SVC_UUID16 0x1801

/** GATT Service Changed characteristic 16-bit UUID. */
#define BLE_GATT_CHR_SVC_CHANGED_UUID16 0x2a05

/** GATT Client Characteristic Configuration descriptor 16-bit UUID. */
#define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902

/** GATT Characteristic Extended Porperties descriptor 16-bit UUID. */
#define BLE_GATT_DSC_EXT_PROP_UUID16 0x2900

/** GATT Characteristic User Description descriptor 16-bit UUID. */
#define BLE_GATT_DSC_USER_DESC_UUID16 0x2901

/** GATT Server Characteristic Configuration descriptor 16-bit UUID. */
#define BLE_GATT_DSC_SRV_CFG_UUID16 0x2903

/** GATT Characteristic Presentation Format descriptor 16-bit UUID. */
#define BLE_GATT_DSC_CHR_FMT_UUID16 0x2904

/** GATT Characteristic Aggregate Format descriptor 16-bit UUID. */
#define BLE_GATT_DSC_AGG_FMT_UUID16 0x2905

/** @} */

/**
Expand Down Expand Up @@ -1139,6 +1154,18 @@ typedef void (*ble_gatt_svc_foreach_fn)(const struct ble_gatt_svc_def *svc,
*/
void ble_gatts_show_local(void);

/**
* Calculates the database hash of the local GATT database (AES-CMAC over
* the attribute database; Core spec Vol 3, Part G, 7.3.1). Only available
* if the BLE_GATT_CACHING syscfg setting is enabled.
*
* @param out_hash_key Buffer to fill with the 16-byte database
* hash, in little-endian byte order.
*
* @return 0 on success; nonzero on failure.
*/
int ble_gatts_calculate_hash(uint8_t *out_hash_key);

/**
* Resets the GATT server to its initial state. On success, this function
* removes all supported services, characteristics, and descriptors. This
Expand Down
121 changes: 121 additions & 0 deletions nimble/host/include/host/ble_store.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ extern "C" {
/** Object type: Client Characteristic Configuration Descriptor. */
#define BLE_STORE_OBJ_TYPE_CCCD 3

/** Object type: Client Supported Features characteristic value. */
#define BLE_STORE_OBJ_TYPE_CSFC 4

/** Object type: local GATT database hash. */
#define BLE_STORE_OBJ_TYPE_DB_HASH 5

/** @} */

/**
Expand Down Expand Up @@ -154,6 +160,57 @@ struct ble_store_value_cccd {
unsigned value_changed:1;
};

/** Size of the stored Client Supported Features value, in bytes. */
#define BLE_STORE_CSFC_SZ 1

/**
* Used as a key for lookups of stored Client Supported Features characteristic
* (CSFC) values. This struct corresponds to the BLE_STORE_OBJ_TYPE_CSFC store
* object type.
*/
struct ble_store_key_csfc {
/**
* 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 characteristic (CSFC) value
* along with the associated GATT caching state. This struct corresponds to
* the BLE_STORE_OBJ_TYPE_CSFC store object type.
*/
struct ble_store_value_csfc {
/** The peer address associated with the stored value. */
ble_addr_t peer_addr;
/** The Client Supported Features bits written by the peer. */
uint8_t csfc[BLE_STORE_CSFC_SZ];
/** Flag indicating whether the peer is change-aware. */
unsigned change_aware:1;
};

/**
* Used as a key for lookups of the stored local GATT database hash. This
* struct corresponds to the BLE_STORE_OBJ_TYPE_DB_HASH store object type.
*/
struct ble_store_key_db_hash {
/** Number of results to skip; 0 means retrieve the first match. */
uint8_t idx;
};

/**
* Represents the stored local GATT database hash. This struct corresponds to
* the BLE_STORE_OBJ_TYPE_DB_HASH store object type.
*/
struct ble_store_value_db_hash {
/** The database hash, in little-endian byte order. */
uint8_t hash[16];
};

/**
* 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 +220,10 @@ 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 Client Supported Features store lookups. */
struct ble_store_key_csfc csfc;
/** Key for local GATT database hash store lookups. */
struct ble_store_key_db_hash db_hash;
};

/**
Expand All @@ -174,6 +235,10 @@ 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 value. */
struct ble_store_value_csfc csfc;
/** Stored local GATT database hash. */
struct ble_store_value_db_hash db_hash;
};

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

/**
* Reads a Client Supported Features characteristic (CSFC) value from storage.
*
* @param key The key identifying the CSFC value to read.
* @param out_value On success, filled with the stored value.
*
* @return 0 on success; nonzero on error.
*/
int ble_store_read_csfc(const struct ble_store_key_csfc *key,
struct ble_store_value_csfc *out_value);

/**
* Writes a Client Supported Features characteristic (CSFC) value to storage.
*
* @param value The value to persist.
*
* @return 0 on success; nonzero on error.
*/
int ble_store_write_csfc(const struct ble_store_value_csfc *value);

/**
* Deletes a Client Supported Features characteristic (CSFC) value from
* storage.
*
* @param key The key identifying the CSFC value to delete.
*
* @return 0 on success; nonzero on error.
*/
int ble_store_delete_csfc(const struct ble_store_key_csfc *key);

/**
* Reads the stored local GATT database hash.
*
* @param out_value On success, filled with the stored hash.
*
* @return 0 on success; nonzero on error.
*/
int ble_store_read_db_hash(struct ble_store_value_db_hash *out_value);

/**
* Writes the local GATT database hash to storage.
*
* @param value The hash to persist.
*
* @return 0 on success; nonzero on error.
*/
int ble_store_write_db_hash(const struct ble_store_value_db_hash *value);

/**
* @brief Generates a storage key for a security material entry from its value.
Expand Down Expand Up @@ -587,6 +699,15 @@ 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);

/**
* Generates a storage key for a Client Supported Features entry from its
* value.
*
* @param out_key On return, the generated key.
* @param value The value to generate a key from.
*/
void ble_store_key_from_value_csfc(struct ble_store_key_csfc *out_key,
const struct ble_store_value_csfc *value);

/**
* @brief Generates a storage key from a value based on the object type.
Expand Down
3 changes: 3 additions & 0 deletions nimble/host/pkg.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pkg.deps.BLE_SM_LEGACY:
pkg.deps.BLE_SM_SC:
- "@apache-mynewt-core/crypto/mbedtls"

pkg.deps.BLE_GATT_CACHING:
- "@apache-mynewt-core/crypto/mbedtls"

pkg.deps.BLE_MESH:
- nimble/host/mesh

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ extern "C" {
struct ble_hs_cfg;

#define BLE_SVC_GATT_CHR_SERVICE_CHANGED_UUID16 0x2a05
#define BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16 0x2b2a
#define BLE_SVC_GATT_CHR_SERVER_SUPPORTED_FEAT_UUID16 0x2b3a
#define BLE_SVC_GATT_CHR_CLIENT_SUPPORTED_FEAT_UUID16 0x2b29

Expand Down
41 changes: 41 additions & 0 deletions nimble/host/services/gatt/src/ble_svc_gatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ static int
ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);

#if MYNEWT_VAL(BLE_GATT_CACHING)
static int
ble_svc_gatt_db_hash_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg);
#endif

static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = {
{
/*** Service: GATT */
Expand All @@ -73,6 +79,13 @@ static const struct ble_gatt_svc_def ble_svc_gatt_defs[] = {
.access_cb = ble_svc_gatt_cl_sup_feat_access,
.flags = BLE_GATT_CHR_F_READ | BLE_GATT_CHR_F_WRITE,
},
#if MYNEWT_VAL(BLE_GATT_CACHING)
{
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GATT_CHR_DATABASE_HASH_UUID16),
.access_cb = ble_svc_gatt_db_hash_access,
.flags = BLE_GATT_CHR_F_READ,
},
#endif
{
0, /* No more characteristics in this service. */
}
Expand Down Expand Up @@ -122,6 +135,34 @@ ble_svc_gatt_cl_sup_feat_access(uint16_t conn_handle, uint16_t attr_handle,
return 0;
}

#if MYNEWT_VAL(BLE_GATT_CACHING)
static int
ble_svc_gatt_db_hash_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
uint8_t db_hash[16];
int rc;

if (ctxt->op != BLE_GATT_ACCESS_OP_READ_CHR) {
return BLE_ATT_ERR_WRITE_NOT_PERMITTED;
}

rc = ble_gatts_calculate_hash(db_hash);
if (rc != 0) {
return BLE_ATT_ERR_UNLIKELY;
}

rc = os_mbuf_append(ctxt->om, db_hash, sizeof(db_hash));
if (rc != 0) {
return BLE_ATT_ERR_INSUFFICIENT_RES;
}

ble_gatts_caching_hash_read(conn_handle);

return 0;
}
#endif

static int
ble_svc_gatt_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
Expand Down
18 changes: 18 additions & 0 deletions nimble/host/src/ble_att.c
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,24 @@ ble_att_rx_extended(uint16_t conn_handle, uint16_t cid, struct os_mbuf **om)
/* Strip L2CAP ATT header from the front of the mbuf. */
os_mbuf_adj(*om, 1);

#if MYNEWT_VAL(BLE_GATT_CACHING)
switch (ble_gatts_caching_rx_gate(conn_handle, cid, op, *om)) {
case BLE_GATTS_CACHING_GATE_PASS:
break;

case BLE_GATTS_CACHING_GATE_ERROR:
/* Reuse the request buffer for the error response. */
os_mbuf_adj(*om, OS_MBUF_PKTLEN(*om));
ble_att_svr_tx_error_rsp(conn_handle, cid, *om, op, 0,
BLE_ATT_ERR_DATABASE_OUT_OF_SYNC);
*om = NULL;
return 0;

case BLE_GATTS_CACHING_GATE_DROP:
return 0;
}
#endif

rc = entry->bde_fn(conn_handle, cid, om);
if (rc != 0) {
if (rc == BLE_HS_ENOTSUP) {
Expand Down
6 changes: 6 additions & 0 deletions nimble/host/src/ble_eatt.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,12 @@ ble_eatt_find_by_conn_handle(uint16_t conn_handle)
return NULL;
}

bool
ble_eatt_has_chan(uint16_t conn_handle)
{
return ble_eatt_find_by_conn_handle(conn_handle) != NULL;
}

static struct ble_eatt *
ble_eatt_find_by_conn_handle_and_busy_op(uint16_t conn_handle, uint8_t op)
{
Expand Down
3 changes: 3 additions & 0 deletions nimble/host/src/ble_eatt_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* under the License.
*/

#include <stdbool.h>

#include "syscfg/syscfg.h"
#include "os/os_mbuf.h"
#include "host/ble_l2cap.h"
Expand All @@ -36,6 +38,7 @@ void ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn);
uint16_t ble_eatt_get_available_chan_cid(uint16_t conn_handle, uint8_t op);
void ble_eatt_release_chan(uint16_t conn_handle, uint8_t op);
int ble_eatt_tx(uint16_t conn_handle, uint16_t cid, struct os_mbuf *txom);
bool ble_eatt_has_chan(uint16_t conn_handle);
#else
static inline void
ble_eatt_init(ble_eatt_att_rx_fn att_rx_fn)
Expand Down
Loading
Loading