diff --git a/include/zephyr/bluetooth/uuid.h b/include/zephyr/bluetooth/uuid.h index 24232f04a29..df1af452a3d 100644 --- a/include/zephyr/bluetooth/uuid.h +++ b/include/zephyr/bluetooth/uuid.h @@ -5090,6 +5090,16 @@ struct bt_uuid_128 { #define BT_UUID_GATT_SL \ BT_UUID_DECLARE_16(BT_UUID_GATT_SL_VAL) +/** + * @brief GATT Characteristic UDI for Medical Devices UUID Value + */ +#define BT_UUID_UDI_FOR_MEDICAL_DEVICES_VAL 0x2bff +/** + * @brief GATT Characteristic UDI for Medical Devices + */ +#define BT_UUID_UDI_FOR_MEDICAL_DEVICES \ + BT_UUID_DECLARE_16(BT_UUID_UDI_FOR_MEDICAL_DEVICES_VAL) + /** * @brief Gaming Service UUID value */ diff --git a/subsys/bluetooth/services/Kconfig.dis b/subsys/bluetooth/services/Kconfig.dis index 2a6c6bba74e..e1056a250d1 100644 --- a/subsys/bluetooth/services/Kconfig.dis +++ b/subsys/bluetooth/services/Kconfig.dis @@ -144,4 +144,74 @@ config BT_DIS_SW_REV_STR help Enable software revision characteristic in Device Information Service. +config BT_DIS_UDI + bool "DIS UDI for Medical Devices characteristic" + help + Enable UDI for Medical Devices characteristic in Device Information Service. + +if BT_DIS_UDI +config BT_DIS_UDI_LABEL_STR + string "UDI Label" + help + String value matching the UDI in human readable form + as assigned to the product by a recognized UDI Issuer. + +config BT_DIS_UDI_DI_STR + string "UDI Device Identifier" + help + A fixed portion of a UDI that identifies the labeler and the + specific version or model of a device. + +config BT_DIS_UDI_ISSUER_STR + string "UDI Issuer" + help + OID representing the UDI Issuing Organization, such as GS1. + +config BT_DIS_UDI_AUTHORITY_STR + string "UDI Authority" + help + OID representing the regional UDI Authority, such as the US FDA. +endif # BT_DIS_UDI + +config BT_DIS_SYSTEM_ID + bool "DIS System ID characteristic [experimental]" + select EXPERIMENTAL + help + Enable System ID characteristic in Device Information Service. + The System ID characteristic is used to represent an extended unique identifier (EUI) of the system + implementing the service that contains this characteristic. This 64-bit structure is an EUI-64 which consists + of an Organizationally Unique Identifier (OUI) concatenated with a manufacturer-defined identifier. + + This will be transmitted as the 40 bit identifier followed by the 24-bit OUI. + Both in little-endian format. + +if BT_DIS_SYSTEM_ID +config BT_DIS_SYSTEM_ID_OUI + hex "Organizationally Unique Identifier (OUI) of the manufacturer." + range 0 0xFFFFFF + default 0 + help + The OUI is a 24-bit number issued by the IEEE Registration Authority. + System ID characteristic in Device Information Service. + Shall contain an Organisationally Unique Identifier (OUI) followed by a manufacturer-defined indentifier unique for the device. + +config BT_DIS_SYSTEM_ID_IDENTIFIER + hex "Manufacturer-defined unique identifier." + range 0 0xFFFFFFFFFF + default 0 + help + The manufacturer-defined unique identifier is 40 bits long. +endif # BT_DIS_SYSTEM_ID + +config BT_DIS_IEEE_RCDL + bool "DIS IEEE 11073-20601 Regulatory Certification Data List characteristic" + help + Enable IEEE 11073-20601 Regulatory Certification Data List characteristic in Device Information Service. + +config BT_DIS_IEEE_RCDL_STR + string "IEEE 11073-20601 Regulatory Certification Data List" + depends on BT_DIS_IEEE_RCDL + help + IEEE 11073-20601 Regulatory Certification Data List characteristic in Device Information Service string contents. + endif # BT_DIS diff --git a/subsys/bluetooth/services/dis.c b/subsys/bluetooth/services/dis.c index 9af78df9b66..27676600b17 100644 --- a/subsys/bluetooth/services/dis.c +++ b/subsys/bluetooth/services/dis.c @@ -25,6 +25,9 @@ #include #include +#include +#include + #define LOG_LEVEL CONFIG_BT_SERVICE_LOG_LEVEL #include LOG_MODULE_REGISTER(bt_dis); @@ -45,105 +48,262 @@ static struct dis_pnp dis_pnp_id = { }; #endif -#if defined(CONFIG_BT_DIS_SETTINGS) -static uint8_t dis_model[CONFIG_BT_DIS_STR_MAX] = CONFIG_BT_DIS_MODEL; -static uint8_t dis_manuf[CONFIG_BT_DIS_STR_MAX] = CONFIG_BT_DIS_MANUF; -#if defined(CONFIG_BT_DIS_SERIAL_NUMBER) -static uint8_t dis_serial_number[CONFIG_BT_DIS_STR_MAX] = - CONFIG_BT_DIS_SERIAL_NUMBER_STR; -#endif -#if defined(CONFIG_BT_DIS_FW_REV) -static uint8_t dis_fw_rev[CONFIG_BT_DIS_STR_MAX] = - CONFIG_BT_DIS_FW_REV_STR; -#endif -#if defined(CONFIG_BT_DIS_HW_REV) -static uint8_t dis_hw_rev[CONFIG_BT_DIS_STR_MAX] = - CONFIG_BT_DIS_HW_REV_STR; -#endif -#if defined(CONFIG_BT_DIS_SW_REV) -static uint8_t dis_sw_rev[CONFIG_BT_DIS_STR_MAX] = - CONFIG_BT_DIS_SW_REV_STR; +#if defined(CONFIG_BT_DIS_SYSTEM_ID) +/* + * Casting to uint64_t since the value is at most 5 bytes, but will appear as a 32-bit literal if it + * is less, giving a warning when right-shifting by 32. + */ +static uint8_t dis_system_id[8] = {BT_BYTES_LIST_LE40((uint64_t)CONFIG_BT_DIS_SYSTEM_ID_IDENTIFIER), + BT_BYTES_LIST_LE24(CONFIG_BT_DIS_SYSTEM_ID_OUI)}; #endif -#define BT_DIS_MODEL_REF dis_model -#define BT_DIS_MANUF_REF dis_manuf -#define BT_DIS_SERIAL_NUMBER_STR_REF dis_serial_number -#define BT_DIS_FW_REV_STR_REF dis_fw_rev -#define BT_DIS_HW_REV_STR_REF dis_hw_rev -#define BT_DIS_SW_REV_STR_REF dis_sw_rev +#if defined(CONFIG_BT_DIS_SETTINGS) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_MODEL) <= CONFIG_BT_DIS_STR_MAX + 1); +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_MANUF) <= CONFIG_BT_DIS_STR_MAX + 1); +static uint8_t dis_model[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_MODEL; +static uint8_t dis_manuf[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_MANUF; +#if defined(CONFIG_BT_DIS_SERIAL_NUMBER) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_SERIAL_NUMBER_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +static uint8_t dis_serial_number[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_SERIAL_NUMBER_STR; +#endif +#if defined(CONFIG_BT_DIS_FW_REV) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_FW_REV_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +static uint8_t dis_fw_rev[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_FW_REV_STR; +#endif +#if defined(CONFIG_BT_DIS_HW_REV) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_HW_REV_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +static uint8_t dis_hw_rev[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_HW_REV_STR; +#endif +#if defined(CONFIG_BT_DIS_SW_REV) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_SW_REV_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +static uint8_t dis_sw_rev[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_SW_REV_STR; +#endif +#if defined(CONFIG_BT_DIS_UDI) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_UDI_LABEL_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_UDI_DI_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_UDI_ISSUER_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_UDI_AUTHORITY_STR) <= CONFIG_BT_DIS_STR_MAX + 1); + +static uint8_t dis_udi_label[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_UDI_LABEL_STR; +static uint8_t dis_udi_di[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_UDI_DI_STR; +static uint8_t dis_udi_issuer[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_UDI_ISSUER_STR; +static uint8_t dis_udi_authority[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_UDI_AUTHORITY_STR; +#endif +#if defined(CONFIG_BT_DIS_IEEE_RCDL) +BUILD_ASSERT(sizeof(CONFIG_BT_DIS_IEEE_RCDL_STR) <= CONFIG_BT_DIS_STR_MAX + 1); +static uint8_t dis_ieee_rcdl[CONFIG_BT_DIS_STR_MAX + 1] = CONFIG_BT_DIS_IEEE_RCDL_STR; +#endif + +#define BT_DIS_MODEL_REF dis_model +#define BT_DIS_MANUF_REF dis_manuf +#define BT_DIS_SERIAL_NUMBER_STR_REF dis_serial_number +#define BT_DIS_FW_REV_STR_REF dis_fw_rev +#define BT_DIS_HW_REV_STR_REF dis_hw_rev +#define BT_DIS_SW_REV_STR_REF dis_sw_rev +#define BT_DIS_UDI_LABEL_STR_REF dis_udi_label +#define BT_DIS_UDI_DI_STR_REF dis_udi_di +#define BT_DIS_UDI_ISSUER_STR_REF dis_udi_issuer +#define BT_DIS_UDI_AUTHORITY_STR_REF dis_udi_authority +#define BT_DIS_IEEE_RCDL_STR_REF dis_ieee_rcdl + +/* + * When assigning too long string literals to the arrays, + * the literals may be truncated, removing the null terminator. + * Using strnlen to avoid sending data outside the array. + */ #else /* CONFIG_BT_DIS_SETTINGS */ -#define BT_DIS_MODEL_REF CONFIG_BT_DIS_MODEL -#define BT_DIS_MANUF_REF CONFIG_BT_DIS_MANUF -#define BT_DIS_SERIAL_NUMBER_STR_REF CONFIG_BT_DIS_SERIAL_NUMBER_STR -#define BT_DIS_FW_REV_STR_REF CONFIG_BT_DIS_FW_REV_STR -#define BT_DIS_HW_REV_STR_REF CONFIG_BT_DIS_HW_REV_STR -#define BT_DIS_SW_REV_STR_REF CONFIG_BT_DIS_SW_REV_STR +#define BT_DIS_MODEL_REF CONFIG_BT_DIS_MODEL +#define BT_DIS_MANUF_REF CONFIG_BT_DIS_MANUF +#define BT_DIS_SERIAL_NUMBER_STR_REF CONFIG_BT_DIS_SERIAL_NUMBER_STR +#define BT_DIS_FW_REV_STR_REF CONFIG_BT_DIS_FW_REV_STR +#define BT_DIS_HW_REV_STR_REF CONFIG_BT_DIS_HW_REV_STR +#define BT_DIS_SW_REV_STR_REF CONFIG_BT_DIS_SW_REV_STR +#define BT_DIS_UDI_LABEL_STR_REF CONFIG_BT_DIS_UDI_LABEL_STR +#define BT_DIS_UDI_DI_STR_REF CONFIG_BT_DIS_UDI_DI_STR +#define BT_DIS_UDI_ISSUER_STR_REF CONFIG_BT_DIS_UDI_ISSUER_STR +#define BT_DIS_UDI_AUTHORITY_STR_REF CONFIG_BT_DIS_UDI_AUTHORITY_STR +#define BT_DIS_IEEE_RCDL_STR_REF CONFIG_BT_DIS_IEEE_RCDL_STR #endif /* CONFIG_BT_DIS_SETTINGS */ -static ssize_t read_str(struct bt_conn *conn, - const struct bt_gatt_attr *attr, void *buf, - uint16_t len, uint16_t offset) +static ssize_t read_str(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) { return bt_gatt_attr_read(conn, attr, buf, len, offset, attr->user_data, strlen(attr->user_data)); } #if CONFIG_BT_DIS_PNP -static ssize_t read_pnp_id(struct bt_conn *conn, - const struct bt_gatt_attr *attr, void *buf, +static ssize_t read_pnp_id(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, uint16_t len, uint16_t offset) { - return bt_gatt_attr_read(conn, attr, buf, len, offset, &dis_pnp_id, - sizeof(dis_pnp_id)); + return bt_gatt_attr_read(conn, attr, buf, len, offset, &dis_pnp_id, sizeof(dis_pnp_id)); +} +#endif + +#if CONFIG_BT_DIS_SYSTEM_ID +static ssize_t read_system_id(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + return bt_gatt_attr_read(conn, attr, buf, len, offset, dis_system_id, + sizeof(dis_system_id)); +} +#endif + +#if CONFIG_BT_DIS_UDI +#define DIS_STR_SIZE(x) ((x[0]) != '\0' ? strlen(x) + sizeof('\0') : 0) +#define BT_DIS_UDI_FLAG_LABEL (!!BT_DIS_UDI_LABEL_STR_REF[0]) +#define BT_DIS_UDI_FLAG_DI (!!BT_DIS_UDI_DI_STR_REF[0]) +#define BT_DIS_UDI_FLAG_ISSUER (!!BT_DIS_UDI_ISSUER_STR_REF[0]) +#define BT_DIS_UDI_FLAG_AUTHORITY (!!BT_DIS_UDI_AUTHORITY_STR_REF[0]) +#define BT_DIS_UDI_FLAGS \ + (BT_DIS_UDI_FLAG_LABEL | (BT_DIS_UDI_FLAG_DI << 1) | (BT_DIS_UDI_FLAG_ISSUER << 2) | \ + (BT_DIS_UDI_FLAG_AUTHORITY << 3)) + +/* + * UDI for medical devices contains a flag and 4 different null-terminated strings that may have + * unknown length. This requires its own encode method. + */ +static void read_udi_subval(const char *str, uint16_t val_len, char *buf, uint16_t *bytes_read, + uint16_t *index, uint16_t len, uint16_t offset) +{ + /* String should not be with included null-terminator if empty */ + if (val_len == sizeof('\0')) { + return; + } + + if (*bytes_read == len) { + return; + } + + if (*index + val_len < offset) { + *index += val_len; + return; + } + + for (uint16_t i = 0; i < val_len; i++) { + if (*index >= offset && *bytes_read < len) { + buf[*bytes_read] = str[i]; + + (*bytes_read)++; + } + + (*index)++; + } +} + +static ssize_t read_udi(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf, + uint16_t len, uint16_t offset) +{ + uint16_t bytes_read = 0; + + char *buf_i = (char *)buf; + + /* Flag */ + uint16_t index = sizeof(uint8_t); + + if (offset == 0) { + buf_i[0] = BT_DIS_UDI_FLAGS; + bytes_read = 1U; + } + + read_udi_subval(BT_DIS_UDI_LABEL_STR_REF, DIS_STR_SIZE(BT_DIS_UDI_LABEL_STR_REF), buf_i, + &bytes_read, &index, len, offset); + read_udi_subval(BT_DIS_UDI_DI_STR_REF, DIS_STR_SIZE(BT_DIS_UDI_DI_STR_REF), buf_i, + &bytes_read, &index, len, offset); + read_udi_subval(BT_DIS_UDI_ISSUER_STR_REF, DIS_STR_SIZE(BT_DIS_UDI_ISSUER_STR_REF), buf_i, + &bytes_read, &index, len, offset); + read_udi_subval(BT_DIS_UDI_AUTHORITY_STR_REF, DIS_STR_SIZE(BT_DIS_UDI_AUTHORITY_STR_REF), + buf_i, &bytes_read, &index, len, offset); + + return bytes_read; } #endif /* Device Information Service Declaration */ -BT_GATT_SERVICE_DEFINE(dis_svc, - BT_GATT_PRIMARY_SERVICE(BT_UUID_DIS), +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, + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_MODEL_NUMBER, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_str, NULL, BT_DIS_MODEL_REF), - BT_GATT_CHARACTERISTIC(BT_UUID_DIS_MANUFACTURER_NAME, - BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_MANUFACTURER_NAME, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_str, NULL, BT_DIS_MANUF_REF), #if CONFIG_BT_DIS_PNP - BT_GATT_CHARACTERISTIC(BT_UUID_DIS_PNP_ID, - BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + 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_DIS_SERIAL_NUMBER) - BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SERIAL_NUMBER, - BT_GATT_CHRC_READ, BT_GATT_PERM_READ, - read_str, NULL, - BT_DIS_SERIAL_NUMBER_STR_REF), + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SERIAL_NUMBER, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_str, NULL, BT_DIS_SERIAL_NUMBER_STR_REF), #endif #if defined(CONFIG_BT_DIS_FW_REV) - BT_GATT_CHARACTERISTIC(BT_UUID_DIS_FIRMWARE_REVISION, - BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_FIRMWARE_REVISION, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_str, NULL, BT_DIS_FW_REV_STR_REF), #endif #if defined(CONFIG_BT_DIS_HW_REV) - BT_GATT_CHARACTERISTIC(BT_UUID_DIS_HARDWARE_REVISION, - BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_HARDWARE_REVISION, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_str, NULL, BT_DIS_HW_REV_STR_REF), #endif #if defined(CONFIG_BT_DIS_SW_REV) - BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SOFTWARE_REVISION, - BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SOFTWARE_REVISION, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, read_str, NULL, BT_DIS_SW_REV_STR_REF), #endif +#if defined(CONFIG_BT_DIS_UDI) + BT_GATT_CHARACTERISTIC(BT_UUID_UDI_FOR_MEDICAL_DEVICES, BT_GATT_CHRC_READ, + BT_GATT_PERM_READ, read_udi, NULL, NULL), +#endif +#if defined(CONFIG_BT_DIS_SYSTEM_ID) + BT_GATT_CHARACTERISTIC(BT_UUID_DIS_SYSTEM_ID, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_system_id, NULL, NULL), +#endif +#if defined(CONFIG_BT_DIS_IEEE_RCDL) + BT_GATT_CHARACTERISTIC(BT_UUID_GATT_IEEE_RCDL, BT_GATT_CHRC_READ, BT_GATT_PERM_READ, + read_str, NULL, BT_DIS_IEEE_RCDL_STR_REF), +#endif ); #if defined(CONFIG_BT_DIS_SETTINGS) -static int dis_set(const char *name, size_t len_rd, - settings_read_cb read_cb, void *store) +#if defined(CONFIG_BT_DIS_UDI) +static void dis_update_udi_value(const char *new, char *old, settings_read_cb read_cb, + const char *logkey) +{ + /* + * The characteristic contains 1 one-byte flag and 4-null-terminated. + * The null-terminators are only present for strings that are in the flags. + */ + const size_t merged_size = sizeof(uint8_t) + DIS_STR_SIZE(BT_DIS_UDI_LABEL_STR_REF) + + DIS_STR_SIZE(BT_DIS_UDI_DI_STR_REF) + + DIS_STR_SIZE(BT_DIS_UDI_ISSUER_STR_REF) + + DIS_STR_SIZE(BT_DIS_UDI_AUTHORITY_STR_REF); + + size_t without_old = merged_size - DIS_STR_SIZE(old); + + bool valid = BT_ATT_MAX_ATTRIBUTE_LEN >= without_old + DIS_STR_SIZE(new); + + if (!valid) { + LOG_ERR("Failed to set UDI %s. Not enough space. The sum of the 4 DIS UDI for " + "Medical Devices strings may not exceed the maximum attribute length.", + logkey); + return; + } + + int16_t len = read_cb((void *)new, (void *)old, CONFIG_BT_DIS_STR_MAX); + + if (len < 0) { + LOG_ERR("Failed to read UDI %s from storage (err %zd)", logkey, len); + } else { + old[len] = '\0'; + + LOG_DBG("UDI %s set to %s", logkey, old); + } +} +#endif + +static int dis_set(const char *name, size_t len_rd, settings_read_cb read_cb, void *store) { ssize_t len; int nlen; @@ -153,8 +313,7 @@ static int dis_set(const char *name, size_t len_rd, if (!strncmp(name, "manuf", nlen)) { len = read_cb(store, &dis_manuf, sizeof(dis_manuf) - 1); if (len < 0) { - LOG_ERR("Failed to read manufacturer from storage" - " (err %zd)", len); + LOG_ERR("Failed to read manufacturer from storage (err %zd)", len); } else { dis_manuf[len] = '\0'; @@ -165,8 +324,7 @@ static int dis_set(const char *name, size_t len_rd, if (!strncmp(name, "model", nlen)) { len = read_cb(store, &dis_model, sizeof(dis_model) - 1); if (len < 0) { - LOG_ERR("Failed to read model from storage" - " (err %zd)", len); + LOG_ERR("Failed to read model from storage (err %zd)", len); } else { dis_model[len] = '\0'; @@ -176,11 +334,9 @@ static int dis_set(const char *name, size_t len_rd, } #if defined(CONFIG_BT_DIS_SERIAL_NUMBER) if (!strncmp(name, "serial", nlen)) { - len = read_cb(store, &dis_serial_number, - sizeof(dis_serial_number) - 1); + len = read_cb(store, &dis_serial_number, sizeof(dis_serial_number) - 1); if (len < 0) { - LOG_ERR("Failed to read serial number from storage" - " (err %zd)", len); + LOG_ERR("Failed to read serial number from storage (err %zd)", len); } else { dis_serial_number[len] = '\0'; @@ -193,8 +349,7 @@ static int dis_set(const char *name, size_t len_rd, if (!strncmp(name, "fw", nlen)) { len = read_cb(store, &dis_fw_rev, sizeof(dis_fw_rev) - 1); if (len < 0) { - LOG_ERR("Failed to read firmware revision from storage" - " (err %zd)", len); + LOG_ERR("Failed to read firmware revision from storage (err %zd)", len); } else { dis_fw_rev[len] = '\0'; @@ -207,8 +362,7 @@ static int dis_set(const char *name, size_t len_rd, if (!strncmp(name, "hw", nlen)) { len = read_cb(store, &dis_hw_rev, sizeof(dis_hw_rev) - 1); if (len < 0) { - LOG_ERR("Failed to read hardware revision from storage" - " (err %zd)", len); + LOG_ERR("Failed to read hardware revision from storage (err %zd)", len); } else { dis_hw_rev[len] = '\0'; @@ -221,8 +375,7 @@ static int dis_set(const char *name, size_t len_rd, if (!strncmp(name, "sw", nlen)) { len = read_cb(store, &dis_sw_rev, sizeof(dis_sw_rev) - 1); if (len < 0) { - LOG_ERR("Failed to read software revision from storage" - " (err %zd)", len); + LOG_ERR("Failed to read software revision from storage (err %zd)", len); } else { dis_sw_rev[len] = '\0'; @@ -230,6 +383,69 @@ static int dis_set(const char *name, size_t len_rd, } return 0; } +#endif +#if defined(CONFIG_BT_DIS_UDI) + if (!strncmp(name, "udi_label", nlen)) { + dis_update_udi_value(store, BT_DIS_UDI_LABEL_STR_REF, read_cb, "label"); + return 0; + } + + if (!strncmp(name, "udi_di", nlen)) { + dis_update_udi_value(store, BT_DIS_UDI_DI_STR_REF, read_cb, "device information"); + return 0; + } + + if (!strncmp(name, "udi_issuer", nlen)) { + dis_update_udi_value(store, BT_DIS_UDI_ISSUER_STR_REF, read_cb, "issuer"); + return 0; + } + + if (!strncmp(name, "udi_authority", nlen)) { + dis_update_udi_value(store, BT_DIS_UDI_AUTHORITY_STR_REF, read_cb, "authority"); + return 0; + } +#endif +#if defined(CONFIG_BT_DIS_SYSTEM_ID) + if (!strncmp(name, "sysid_oui", nlen)) { + uint32_t oui = 0; + + len = read_cb(store, &oui, sizeof(oui)); + if (len < 0) { + LOG_ERR("Failed to read System ID OUI from storage (err %zd)", len); + } else { + sys_put_le24(oui, &dis_system_id[5]); + LOG_DBG("System ID OUI set to %06X", oui); + } + return 0; + } + if (!strncmp(name, "sysid_identifier", nlen)) { + uint64_t identifier = 0; + + len = read_cb(store, &identifier, sizeof(identifier)); + if (len < 0) { + LOG_ERR("Failed to read System ID identifier from storage (err %zd)", len); + } else { + sys_put_le40(identifier, &dis_system_id[0]); + LOG_DBG("System ID identifier set to %10llX", identifier); + } + return 0; + } +#endif +#if defined(CONFIG_BT_DIS_IEEE_RCDL) + if (!strncmp(name, "ieeercdl", nlen)) { + len = read_cb(store, &dis_ieee_rcdl, sizeof(dis_ieee_rcdl) - 1); + if (len < 0) { + LOG_ERR("Failed to read IEEE 11073-20601 Regulatory Certification Data " + "List from storage (err %zd)", + len); + } else { + dis_ieee_rcdl[len] = '\0'; + + LOG_DBG("IEEE 11073-20601 Regulatory Certification Data List set to %s", + dis_ieee_rcdl); + } + return 0; + } #endif return 0; }