diff --git a/samples/bluetooth/peripheral_dis/prj.conf b/samples/bluetooth/peripheral_dis/prj.conf index af565471703..137471d8f97 100644 --- a/samples/bluetooth/peripheral_dis/prj.conf +++ b/samples/bluetooth/peripheral_dis/prj.conf @@ -1,5 +1,26 @@ CONFIG_BT=y CONFIG_BT_PERIPHERAL=y + CONFIG_BT_GATT_DIS=y CONFIG_BT_GATT_DIS_PNP=n +CONFIG_BT_GATT_DIS_MODEL="Zephyr Model" +CONFIG_BT_GATT_DIS_MANUF="Zephyr" +CONFIG_BT_GATT_DIS_SERIAL_NUMBER=y +CONFIG_BT_GATT_DIS_FW_REV=y +CONFIG_BT_GATT_DIS_HW_REV=y +CONFIG_BT_GATT_DIS_SW_REV=y +CONFIG_BT_GATT_DIS_SERIAL_NUMBER_STR="Zephyr Serial" +CONFIG_BT_GATT_DIS_FW_REV_STR="Zephyr Firmware" +CONFIG_BT_GATT_DIS_HW_REV_STR="Zephyr Hardware" +CONFIG_BT_GATT_DIS_SW_REV_STR="Zephyr Software" + CONFIG_BT_DEVICE_NAME="DIS peripheral" + +# Below is setup to let DIS information be read from settings +CONFIG_SETTINGS_RUNTIME=y +CONFIG_SETTINGS_CUSTOM=y +CONFIG_SETTINGS=y +CONFIG_BT_SETTINGS=y + +CONFIG_BT_GATT_DIS_SETTINGS=y +CONFIG_BT_GATT_DIS_STR_MAX=21 diff --git a/samples/bluetooth/peripheral_dis/src/main.c b/samples/bluetooth/peripheral_dis/src/main.c index 4571d0df356..cb2191703bc 100644 --- a/samples/bluetooth/peripheral_dis/src/main.c +++ b/samples/bluetooth/peripheral_dis/src/main.c @@ -19,6 +19,7 @@ #include #include #include +#include static const struct bt_data ad[] = { BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), @@ -44,6 +45,56 @@ static struct bt_conn_cb conn_callbacks = { .disconnected = disconnected, }; +static int zephyr_settings_fw_load(struct settings_store *cs); + +static const struct settings_store_itf zephyr_settings_fw_itf = { + .csi_load = zephyr_settings_fw_load, +}; + +static struct settings_store zephyr_settings_fw_store = { + .cs_itf = &zephyr_settings_fw_itf +}; + +static int zephyr_settings_fw_load(struct settings_store *cs) +{ + +#if defined(CONFIG_BT_GATT_DIS_SETTINGS) + settings_runtime_set("bt/dis/model", + "Zephyr Model", + sizeof("Zephyr Model")); + settings_runtime_set("bt/dis/manuf", + "Zephyr Manufacturer", + sizeof("Zephyr Manufacturer")); +#if defined(CONFIG_BT_GATT_DIS_SERIAL_NUMBER) + settings_runtime_set("bt/dis/serial", + CONFIG_BT_GATT_DIS_SERIAL_NUMBER_STR, + sizeof(CONFIG_BT_GATT_DIS_SERIAL_NUMBER_STR)); +#endif +#if defined(CONFIG_BT_GATT_DIS_SW_REV) + settings_runtime_set("bt/dis/sw", + CONFIG_BT_GATT_DIS_SW_REV_STR, + sizeof(CONFIG_BT_GATT_DIS_SW_REV_STR)); +#endif +#if defined(CONFIG_BT_GATT_DIS_FW_REV) + settings_runtime_set("bt/dis/fw", + CONFIG_BT_GATT_DIS_FW_REV_STR, + sizeof(CONFIG_BT_GATT_DIS_FW_REV_STR)); +#endif +#if defined(CONFIG_BT_GATT_DIS_HW_REV) + settings_runtime_set("bt/dis/hw", + CONFIG_BT_GATT_DIS_HW_REV_STR, + sizeof(CONFIG_BT_GATT_DIS_HW_REV_STR)); +#endif +#endif + return 0; +} + +int settings_backend_init(void) +{ + settings_src_register(&zephyr_settings_fw_store); + return 0; +} + void main(void) { int err; @@ -53,6 +104,7 @@ void main(void) printk("Bluetooth init failed (err %d)\n", err); return; } + settings_load(); printk("Bluetooth initialized\n"); diff --git a/subsys/bluetooth/services/Kconfig.dis b/subsys/bluetooth/services/Kconfig.dis index 0c646017070..d7edac72998 100644 --- a/subsys/bluetooth/services/Kconfig.dis +++ b/subsys/bluetooth/services/Kconfig.dis @@ -10,6 +10,20 @@ menuconfig BT_GATT_DIS if BT_GATT_DIS +config BT_GATT_DIS_SETTINGS + bool "Enable Settings usage in Device Information Service" + help + Enable Settings usage in Device Information Service. + +config BT_GATT_DIS_STR_MAX + int "Maximum size in bytes for DIS strings" + depends on BT_GATT_DIS_SETTINGS + default 21 + range 2 248 + help + Bluetooth DIS string storage size. Storage can be up to 248 bytes + long (excluding NULL termination). + config BT_GATT_DIS_MODEL string "Model name" default SOC @@ -85,4 +99,47 @@ config BT_GATT_DIS_PNP_VER endif #BT_GATT_DIS_PNP +config BT_GATT_DIS_SERIAL_NUMBER + bool "Enable DIS Serial number characteristic" + help + Enable Serial Number characteristic in Device Information Service. + +config BT_GATT_DIS_SERIAL_NUMBER_STR + string "Serial Number" + depends on BT_GATT_DIS_SERIAL_NUMBER + help + Enable Serial Number characteristic in Device Information Service. + +config BT_GATT_DIS_FW_REV + bool "Enable DIS Firmware Revision characteristic" + help + Enable Firmware Revision characteristic in Device Information Service. + +config BT_GATT_DIS_FW_REV_STR + string "Firmware revision" + depends on BT_GATT_DIS_FW_REV + help + Enable firmware revision characteristic in Device Information Service. + +config BT_GATT_DIS_HW_REV + bool "Enable DIS Hardware Revision characteristic" + help + Enable Hardware Revision characteristic in Device Information Service. + +config BT_GATT_DIS_HW_REV_STR + string "Hardware revision" + depends on BT_GATT_DIS_HW_REV + help + Enable hardware revision characteristic in Device Information Service. + +config BT_GATT_DIS_SW_REV + bool "Enable DIS Software Revision characteristic" + help + Enable Softwar Revision characteristic in Device Information Service. + +config BT_GATT_DIS_SW_REV_STR + string "Software revision" + depends on BT_GATT_DIS_SW_REV + help + Enable software revision characteristic in Device Information Service. endif #BT_GATT_DIS diff --git a/subsys/bluetooth/services/dis.c b/subsys/bluetooth/services/dis.c index 3d56c80b04c..c98615a84fb 100644 --- a/subsys/bluetooth/services/dis.c +++ b/subsys/bluetooth/services/dis.c @@ -3,6 +3,7 @@ */ /* + * Copyright (c) 2019 Demant * Copyright (c) 2018 Nordic Semiconductor ASA * Copyright (c) 2016 Intel Corporation * @@ -16,12 +17,20 @@ #include #include +#include + #include #include #include #include #include +#include "../host/settings.h" + +#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_SERVICE) +#define LOG_MODULE_NAME bt_dis +#include "common/log.h" + #if CONFIG_BT_GATT_DIS_PNP struct dis_pnp { u8_t pnp_vid_src; @@ -38,6 +47,44 @@ static struct dis_pnp dis_pnp_id = { }; #endif +#if defined(CONFIG_BT_GATT_DIS_SETTINGS) +static u8_t dis_model[CONFIG_BT_GATT_DIS_STR_MAX] = CONFIG_BT_GATT_DIS_MODEL; +static u8_t dis_manuf[CONFIG_BT_GATT_DIS_STR_MAX] = CONFIG_BT_GATT_DIS_MANUF; +#if defined(CONFIG_BT_GATT_DIS_SERIAL_NUMBER) +static u8_t dis_serial_number[CONFIG_BT_GATT_DIS_STR_MAX] = + CONFIG_BT_GATT_DIS_SERIAL_NUMBER_STR; +#endif +#if defined(CONFIG_BT_GATT_DIS_FW_REV) +static u8_t dis_fw_rev[CONFIG_BT_GATT_DIS_STR_MAX] = + CONFIG_BT_GATT_DIS_FW_REV_STR; +#endif +#if defined(CONFIG_BT_GATT_DIS_HW_REV) +static u8_t dis_hw_rev[CONFIG_BT_GATT_DIS_STR_MAX] = + CONFIG_BT_GATT_DIS_HW_REV_STR; +#endif +#if defined(CONFIG_BT_GATT_DIS_SW_REV) +static u8_t dis_sw_rev[CONFIG_BT_GATT_DIS_STR_MAX] = + CONFIG_BT_GATT_DIS_SW_REV_STR; +#endif + +#define BT_GATT_DIS_MODEL_REF dis_model +#define BT_GATT_DIS_MANUF_REF dis_manuf +#define BT_GATT_DIS_SERIAL_NUMBER_STR_REF dis_serial_number +#define BT_GATT_DIS_FW_REV_STR_REF dis_fw_rev +#define BT_GATT_DIS_HW_REV_STR_REF dis_hw_rev +#define BT_GATT_DIS_SW_REV_STR_REF dis_sw_rev + +#else /* CONFIG_BT_GATT_DIS_SETTINGS */ + +#define BT_GATT_DIS_MODEL_REF CONFIG_BT_GATT_DIS_MODEL +#define BT_GATT_DIS_MANUF_REF CONFIG_BT_GATT_DIS_MANUF +#define BT_GATT_DIS_SERIAL_NUMBER_STR_REF CONFIG_BT_GATT_DIS_SERIAL_NUMBER_STR +#define BT_GATT_DIS_FW_REV_STR_REF CONFIG_BT_GATT_DIS_FW_REV_STR +#define BT_GATT_DIS_HW_REV_STR_REF CONFIG_BT_GATT_DIS_HW_REV_STR +#define BT_GATT_DIS_SW_REV_STR_REF CONFIG_BT_GATT_DIS_SW_REV_STR + +#endif /* CONFIG_BT_GATT_DIS_SETTINGS */ + static ssize_t read_str(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, u16_t len, u16_t offset) @@ -59,15 +106,132 @@ static ssize_t read_pnp_id(struct bt_conn *conn, /* Device Information Service Declaration */ BT_GATT_SERVICE_DEFINE(dis_svc, BT_GATT_PRIMARY_SERVICE(BT_UUID_DIS), + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_MODEL_NUMBER, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, - read_str, NULL, CONFIG_BT_GATT_DIS_MODEL), + read_str, NULL, BT_GATT_DIS_MODEL_REF), BT_GATT_CHARACTERISTIC(BT_UUID_DIS_MANUFACTURER_NAME, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, - read_str, NULL, CONFIG_BT_GATT_DIS_MANUF), + read_str, NULL, BT_GATT_DIS_MANUF_REF), #if CONFIG_BT_GATT_DIS_PNP BT_GATT_CHARACTERISTIC(BT_UUID_DIS_PNP_ID, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_pnp_id, NULL, &dis_pnp_id), #endif + +#if defined(CONFIG_BT_GATT_DIS_SERIAL_NUMBER) + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SERIAL_NUMBER, + BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_str, NULL, + BT_GATT_DIS_SERIAL_NUMBER_STR_REF), +#endif +#if defined(CONFIG_BT_GATT_DIS_FW_REV) + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_FIRMWARE_REVISION, + BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_str, NULL, BT_GATT_DIS_FW_REV_STR_REF), +#endif +#if defined(CONFIG_BT_GATT_DIS_HW_REV) + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_HARDWARE_REVISION, + BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_str, NULL, BT_GATT_DIS_HW_REV_STR_REF), +#endif +#if defined(CONFIG_BT_GATT_DIS_SW_REV) + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SOFTWARE_REVISION, + BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_str, NULL, BT_GATT_DIS_SW_REV_STR_REF), +#endif + ); + +#if defined(CONFIG_BT_SETTINGS) && defined(CONFIG_BT_GATT_DIS_SETTINGS) +static int dis_set(int argc, char **argv, size_t len_rd, + settings_read_cb read_cb, void *store) +{ + int len; + + if (!strcmp(argv[0], "manuf")) { + len = read_cb(store, &dis_manuf, sizeof(dis_manuf) - 1); + if (len < 0) { + BT_ERR("Failed to read manufacturer from storage" + " (err %d)", len); + } else { + dis_manuf[len] = '\0'; + + BT_DBG("Manufacturer set to %s", dis_manuf); + } + return 0; + } + if (!strcmp(argv[0], "model")) { + len = read_cb(store, &dis_model, sizeof(dis_model) - 1); + if (len < 0) { + BT_ERR("Failed to read model from storage" + " (err %d)", len); + } else { + dis_model[len] = '\0'; + + BT_DBG("Model set to %s", dis_model); + } + return 0; + } +#if defined(CONFIG_BT_GATT_DIS_SERIAL_NUMBER) + if (!strcmp(argv[0], "serial")) { + len = read_cb(store, &dis_serial_number, + sizeof(dis_serial_number) - 1); + if (len < 0) { + BT_ERR("Failed to read serial number from storage" + " (err %d)", len); + } else { + dis_serial_number[len] = '\0'; + + BT_DBG("Serial number set to %s", dis_serial_number); + } + return 0; + } +#endif +#if defined(CONFIG_BT_GATT_DIS_FW_REV) + if (!strcmp(argv[0], "fw")) { + len = read_cb(store, &dis_fw_rev, sizeof(dis_fw_rev) - 1); + if (len < 0) { + BT_ERR("Failed to read firmware revision from storage" + " (err %d)", len); + } else { + dis_fw_rev[len] = '\0'; + + BT_DBG("Firmware revision set to %s", dis_fw_rev); + } + return 0; + } +#endif +#if defined(CONFIG_BT_GATT_DIS_HW_REV) + if (!strcmp(argv[0], "hw")) { + len = read_cb(store, &dis_hw_rev, sizeof(dis_hw_rev) - 1); + if (len < 0) { + BT_ERR("Failed to read hardware revision from storage" + " (err %d)", len); + } else { + dis_hw_rev[len] = '\0'; + + BT_DBG("Hardware revision set to %s", dis_hw_rev); + } + return 0; + } +#endif +#if defined(CONFIG_BT_GATT_DIS_SW_REV) + if (!strcmp(argv[0], "sw")) { + len = read_cb(store, &dis_sw_rev, sizeof(dis_sw_rev) - 1); + if (len < 0) { + BT_ERR("Failed to read software revision from storage" + " (err %d)", len); + } else { + dis_sw_rev[len] = '\0'; + + BT_DBG("Software revision set to %s", dis_sw_rev); + } + return 0; + } +#endif + return 0; +} + +BT_SETTINGS_DEFINE(dis, dis_set, NULL, NULL); +#endif /* CONFIG_BT_GATT_DIS_SETTINGS && CONFIG_BT_SETTINGS*/