Bluetooth: Implemented new DIS characteristics

Implemented new DIS characteristics:
    - UDI for medical devices
    - IEEE 11073-20601 Regulatory Certification Data List
    - System ID

Also fixed buffer overflow bug when assigning too long DIS string literals

Signed-off-by: Simen Eilevstjønn <simen.eilevstjonn@laerdal.com>
This commit is contained in:
Simen Eilevstjønn 2024-08-06 09:16:10 +02:00 committed by Alberto Escolar
commit 2c64fe7f37
3 changed files with 367 additions and 71 deletions

View file

@ -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
*/

View file

@ -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

View file

@ -25,6 +25,9 @@
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/bluetooth/byteorder.h>
#define LOG_LEVEL CONFIG_BT_SERVICE_LOG_LEVEL
#include <zephyr/logging/log.h>
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;
}