nimble/gap: Make appearance optionally writable

As it turns out, spec allows appearance characteristic to be writable
so let us allow configure it this way. Also we need API to set this
from app so it can read new appearance value, store it and then restore
after reboot.

X-Original-Commit: b1b1c785b6f7968588aec68cad897711539552d5
This commit is contained in:
Andrzej Kaczmarek
2018-02-23 23:05:05 +01:00
parent 5f5b248e34
commit 48ec4798d5
3 changed files with 74 additions and 7 deletions
@@ -41,6 +41,7 @@ void ble_svc_gap_set_chr_changed_cb(ble_svc_gap_chr_changed_fn *cb);
const char *ble_svc_gap_device_name(void);
int ble_svc_gap_device_name_set(const char *name);
uint16_t ble_svc_gap_device_appearance(void);
int ble_svc_gap_device_appearance_set(uint16_t appearance);
void ble_svc_gap_init(void);
+64 -7
View File
@@ -39,8 +39,7 @@ static ble_svc_gap_chr_changed_fn *ble_svc_gap_chr_changed_cb_fn;
static char ble_svc_gap_name[BLE_SVC_GAP_NAME_MAX_LEN + 1] =
MYNEWT_VAL(BLE_SVC_GAP_DEVICE_NAME);
static const uint16_t ble_svc_gap_appearance =
MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE);
static uint16_t ble_svc_gap_appearance = MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE);
static int
ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
@@ -65,7 +64,12 @@ static const struct ble_gatt_svc_def ble_svc_gap_defs[] = {
/*** Characteristic: Appearance. */
.uuid = BLE_UUID16_DECLARE(BLE_SVC_GAP_CHR_UUID16_APPEARANCE),
.access_cb = ble_svc_gap_access,
.flags = BLE_GATT_CHR_F_READ,
.flags = BLE_GATT_CHR_F_READ |
#if MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) >= 0
BLE_GATT_CHR_F_WRITE |
MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) |
#endif
0,
}, {
#if PPCP_ENABLED
/*** Characteristic: Peripheral Preferred Connection Parameters. */
@@ -131,12 +135,52 @@ ble_svc_gap_device_name_write_access(struct ble_gatt_access_ctxt *ctxt)
#endif
}
static int
ble_svc_gap_appearance_read_access(struct ble_gatt_access_ctxt *ctxt)
{
uint16_t appearance = htole16(ble_svc_gap_appearance);
int rc;
rc = os_mbuf_append(ctxt->om, &appearance, sizeof(appearance));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
}
static int
ble_svc_gap_appearance_write_access(struct ble_gatt_access_ctxt *ctxt)
{
#if MYNEWT_VAL(BLE_SVC_GAP_APPEARANCE_WRITE_PERM) < 0
assert(0);
return 0;
#else
uint16_t om_len;
int rc;
om_len = OS_MBUF_PKTLEN(ctxt->om);
if (om_len != sizeof(ble_svc_gap_appearance)) {
return BLE_ATT_ERR_INVALID_ATTR_VALUE_LEN;
}
rc = ble_hs_mbuf_to_flat(ctxt->om, ble_svc_gap_appearance, om_len, NULL);
if (rc != 0) {
return BLE_ATT_ERR_UNLIKELY;
}
ble_svc_gap_appearance = le16toh(ble_svc_gap_appearance);
if (ble_svc_gap_chr_changed_cb_fn) {
ble_svc_gap_chr_changed_cb_fn(BLE_SVC_GAP_CHR_UUID16_APPEARANCE);
}
return rc;
#endif
}
static int
ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
struct ble_gatt_access_ctxt *ctxt, void *arg)
{
uint16_t uuid16;
uint16_t appearance = htole16(ble_svc_gap_appearance);
#if MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION) >= 0
uint8_t central_ar = MYNEWT_VAL(BLE_SVC_GAP_CENTRAL_ADDRESS_RESOLUTION);
#endif
@@ -165,9 +209,14 @@ ble_svc_gap_access(uint16_t conn_handle, uint16_t attr_handle,
return rc;
case BLE_SVC_GAP_CHR_UUID16_APPEARANCE:
assert(ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR);
rc = os_mbuf_append(ctxt->om, &appearance, sizeof(appearance));
return rc == 0 ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES;
if (ctxt->op == BLE_GATT_ACCESS_OP_READ_CHR) {
rc = ble_svc_gap_appearance_read_access(ctxt);
} else if (ctxt->op == BLE_GATT_ACCESS_OP_WRITE_CHR) {
rc = ble_svc_gap_appearance_write_access(ctxt);
} else {
assert(0);
}
return rc;
#if PPCP_ENABLED
case BLE_SVC_GAP_CHR_UUID16_PERIPH_PREF_CONN_PARAMS:
@@ -217,6 +266,14 @@ ble_svc_gap_device_appearance(void)
return ble_svc_gap_appearance;
}
int
ble_svc_gap_device_appearance_set(uint16_t appearance)
{
ble_svc_gap_appearance = appearance;
return 0;
}
void
ble_svc_gap_set_chr_changed_cb(ble_svc_gap_chr_changed_fn *cb)
{
+9
View File
@@ -36,6 +36,15 @@ syscfg.defs:
BLE_SVC_GAP_APPEARANCE:
description: 'Device appearance'
value: 0
BLE_SVC_GAP_APPEARANCE_WRITE_PERM:
description: >
Defines permissions for writing "Appearance" characteristics. Can
be zero to allow write without extra permissions or combination of:
BLE_GATT_CHR_F_WRITE_ENC
BLE_GATT_CHR_F_WRITE_AUTHEN
BLE_GATT_CHR_F_WRITE_AUTHOR
Set to '-1' to make characteristic read only.
value: -1
# Setting all values for PPCP to '0' will disable characteristic!
BLE_SVC_GAP_PPCP_MIN_CONN_INTERVAL: