feat(nimble): client presentation and aggregate format descriptor support

This commit is contained in:
Sumeet Singh
2024-02-29 16:23:47 +05:30
committed by Abhinav Kudnar
parent 4712c3c890
commit c7b5c73456
3 changed files with 416 additions and 0 deletions
+236
View File
@@ -66,6 +66,8 @@ struct ble_hs_cfg;
/** GATT Client Characteristic Configuration descriptor 16-bit UUID. */
#define BLE_GATT_DSC_CLT_CFG_UUID16 0x2902
#define BLE_GATT_DSC_CLT_PRE_FMT16 0x2904
#define BLE_GATT_DSC_CLT_AGG_FMT16 0x2905
/** @} */
@@ -186,6 +188,203 @@ struct ble_hs_cfg;
#define BLE_GATT_SVC_TYPE_SECONDARY 2
/** @} */
/**
* Client Presentation Format
* GATT Format Types
* Ref: Assigned Numbers Specification
*/
#define BLE_GATT_CHR_FORMAT_BOOLEAN 0x01
#define BLE_GATT_CHR_FORMAT_UINT2 0x02
#define BLE_GATT_CHR_FORMAT_UINT4 0x03
#define BLE_GATT_CHR_FORMAT_UINT8 0x04
#define BLE_GATT_CHR_FORMAT_UINT12 0x05
#define BLE_GATT_CHR_FORMAT_UINT16 0x06
#define BLE_GATT_CHR_FORMAT_UINT24 0x07
#define BLE_GATT_CHR_FORMAT_UINT32 0x08
#define BLE_GATT_CHR_FORMAT_UINT48 0x09
#define BLE_GATT_CHR_FORMAT_UINT64 0x0A
#define BLE_GATT_CHR_FORMAT_UINT128 0x0B
#define BLE_GATT_CHR_FORMAT_SINT8 0x0C
#define BLE_GATT_CHR_FORMAT_SINT12 0x0D
#define BLE_GATT_CHR_FORMAT_SINT16 0x0E
#define BLE_GATT_CHR_FORMAT_SINT24 0x0F
#define BLE_GATT_CHR_FORMAT_SINT32 0x10
#define BLE_GATT_CHR_FORMAT_SINT48 0x11
#define BLE_GATT_CHR_FORMAT_SINT64 0x12
#define BLE_GATT_CHR_FORMAT_SINT128 0x13
#define BLE_GATT_CHR_FORMAT_FLOAT32 0x14
#define BLE_GATT_CHR_FORMAT_FLOAT64 0x15
#define BLE_GATT_CHR_FORMAT_MEDFLOAT16 0x16
#define BLE_GATT_CHR_FORMAT_MEDFLOAT32 0x17
#define BLE_GATT_CHR_FORMAT_UINT16_2 0x18
#define BLE_GATT_CHR_FORMAT_UTF8S 0x19
#define BLE_GATT_CHR_FORMAT_UTF16S 0x1A
#define BLE_GATT_CHR_FORMAT_STRUCT 0x1B
#define BLE_GATT_CHR_FORMAT_MEDASN1 0x1C
/**
* Client Presentation Format
* GATT Unit UUIDs
* Ref: Assigned Numbers Specification
*/
#define BLE_GATT_CHR_UNIT_UNITLESS 0x2700 /* Unitless */
#define BLE_GATT_CHR_UNIT_METRE 0x2701 /* Length */
#define BLE_GATT_CHR_UNIT_KILOGRAM 0x2702 /* Mass */
#define BLE_GATT_CHR_UNIT_SECOND 0x2703 /* Time */
#define BLE_GATT_CHR_UNIT_AMPERE 0x2704 /* Electric Current */
#define BLE_GATT_CHR_UNIT_KELVIN 0x2705 /* Thermodynamic Temperature */
#define BLE_GATT_CHR_UNIT_MOLE 0x2706 /* Amount Of Substance */
#define BLE_GATT_CHR_UNIT_CANDELA 0x2707 /* Luminous Intensity */
#define BLE_GATT_CHR_UNIT_SQUARE_METRES 0x2710 /* Area */
#define BLE_GATT_CHR_UNIT_CUBIC_METRES 0x2711 /* Volume */
#define BLE_GATT_CHR_UNIT_METRES_PER_SECOND 0x2712 /* Velocity */
#define BLE_GATT_CHR_UNIT_METRES_PER_SECOND_SQUARED 0x2713 /* Acceleration */
#define BLE_GATT_CHR_UNIT_RECIPROCAL_METRE 0x2714 /* Wavenumber */
#define BLE_GATT_CHR_UNIT_KILOGRAM_PER_CUBIC_METRE_DENSITY 0x2715 /* Density */
#define BLE_GATT_CHR_UNIT_KILOGRAM_PER_SQUARE_METRE 0x2716 /* Surface Density */
#define BLE_GATT_CHR_UNIT_CUBIC_METRE_PER_KILOGRAM 0x2717 /* Specific Volume */
#define BLE_GATT_CHR_UNIT_AMPERE_PER_SQUARE_METRE 0x2718 /* Current Density */
#define BLE_GATT_CHR_UNIT_AMPERE_PER_METRE 0x2719 /* Magnetic Field Strength */
#define BLE_GATT_CHR_UNIT_MOLE_PER_CUBIC_METRE 0x271A /* Amount Concentration */
#define BLE_GATT_CHR_UNIT_KILOGRAM_PER_CUBIC_METRE_MASS_CONC 0x271B /* Mass Concentration */
#define BLE_GATT_CHR_UNIT_CANDELA_PER_SQUARE_METRE 0x271C /* Luminance */
#define BLE_GATT_CHR_UNIT_REFRACTIVE_INDEX 0x271D /* Refractive Index */
#define BLE_GATT_CHR_UNIT_RELATIVE_PERMEABILITY 0x271E /* Relative Permeability */
#define BLE_GATT_CHR_UNIT_RADIAN 0x2720 /* Plane Angle */
#define BLE_GATT_CHR_UNIT_STERADIAN 0x2721 /* Solid Angle */
#define BLE_GATT_CHR_UNIT_HERTZ 0x2722 /* Frequency */
#define BLE_GATT_CHR_UNIT_NEWTON 0x2723 /* Force */
#define BLE_GATT_CHR_UNIT_PASCAL 0x2724 /* Pressure */
#define BLE_GATT_CHR_UNIT_JOULE 0x2725 /* Energy */
#define BLE_GATT_CHR_UNIT_WATT 0x2726 /* Power */
#define BLE_GATT_CHR_UNIT_COULOMB 0x2727 /* Electric Charge */
#define BLE_GATT_CHR_UNIT_VOLT 0x2728 /* Electric Potential Difference */
#define BLE_GATT_CHR_UNIT_FARAD 0x2729 /* Capacitance */
#define BLE_GATT_CHR_UNIT_OHM 0x272A /* Electric Resistance */
#define BLE_GATT_CHR_UNIT_SIEMENS 0x272B /* Electric Conductance */
#define BLE_GATT_CHR_UNIT_WEBER 0x272C /* Magnetic Flux */
#define BLE_GATT_CHR_UNIT_TESLA 0x272D /* Magnetic Flux Density */
#define BLE_GATT_CHR_UNIT_HENRY 0x272E /* Inductance */
#define BLE_GATT_CHR_UNIT_DEGREE_CELSIUS 0x272F /* celsius Temperature */
#define BLE_GATT_CHR_UNIT_LUMEN 0x2730 /* Luminous Flux */
#define BLE_GATT_CHR_UNIT_LUX 0x2731 /* Illuminance */
#define BLE_GATT_CHR_UNIT_BECQUEREL 0x2732 /* Activity Referred To A Radionuclide */
#define BLE_GATT_CHR_UNIT_GRAY 0x2733 /* Absorbed Dose */
#define BLE_GATT_CHR_UNIT_SIEVERT 0x2734 /* Dose Equivalent */
#define BLE_GATT_CHR_UNIT_KATAL 0x2735 /* Catalytic Activity */
#define BLE_GATT_CHR_UNIT_PASCAL_SECOND 0x2740 /* Dynamic Viscosity */
#define BLE_GATT_CHR_UNIT_NEWTON_METRE 0x2741 /* Moment Of Force */
#define BLE_GATT_CHR_UNIT_NEWTON_PER_METRE 0x2742 /* Surface Tension */
#define BLE_GATT_CHR_UNIT_RADIAN_PER_SECOND 0x2743 /* Angular Velocity */
#define BLE_GATT_CHR_UNIT_RADIAN_PER_SECOND_SQUARED 0x2744 /* Angular Acceleration */
#define BLE_GATT_CHR_UNIT_WATT_PER_SQUARE_METRE_HEAT 0x2745 /* Heat Flux Density */
#define BLE_GATT_CHR_UNIT_JOULE_PER_KELVIN 0x2746 /* Heat Capacity */
#define BLE_GATT_CHR_UNIT_JOULE_PER_KILOGRAM_KELVIN 0x2747 /* Specific Heat Capacity */
#define BLE_GATT_CHR_UNIT_JOULE_PER_KILOGRAM 0x2748 /* Specific Energy */
#define BLE_GATT_CHR_UNIT_WATT_PER_METRE_KELVIN 0x2749 /* Thermal Conductivity */
#define BLE_GATT_CHR_UNIT_JOULE_PER_CUBIC_METRE 0x274A /* Energy Density */
#define BLE_GATT_CHR_UNIT_VOLT_PER_METRE 0x274B /* Electric Field Strength */
#define BLE_GATT_CHR_UNIT_COULOMB_PER_CUBIC_METRE 0x274C /* Electric Charge Density */
#define BLE_GATT_CHR_UNIT_COULOMB_PER_SQUARE_METRE_CHARGE 0x274D /* Surface Charge Density */
#define BLE_GATT_CHR_UNIT_COULOMB_PER_SQUARE_METRE_FLUX 0x274E /* Electric Flux Density */
#define BLE_GATT_CHR_UNIT_FARAD_PER_METRE 0x274F /* Permittivity */
#define BLE_GATT_CHR_UNIT_HENRY_PER_METRE 0x2750 /* Permeability */
#define BLE_GATT_CHR_UNIT_JOULE_PER_MOLE 0x2751 /* Molar Energy */
#define BLE_GATT_CHR_UNIT_JOULE_PER_MOLE_KELVIN 0x2752 /* Molar Entropy */
#define BLE_GATT_CHR_UNIT_COULOMB_PER_KILOGRAM 0x2753 /* Exposure */
#define BLE_GATT_CHR_UNIT_GRAY_PER_SECOND 0x2754 /* Absorbed Dose Rate */
#define BLE_GATT_CHR_UNIT_WATT_PER_STERADIAN 0x2755 /* Radiant Intensity */
#define BLE_GATT_CHR_UNIT_WATT_PER_SQUARE_METRE_STERADIAN 0x2756 /* Radiance */
#define BLE_GATT_CHR_UNIT_KATAL_PER_CUBIC_METRE 0x2757 /* Catalytic Activity Concentration */
#define BLE_GATT_CHR_UNIT_MINUTE 0x2760 /* Time */
#define BLE_GATT_CHR_UNIT_HOUR 0x2761 /* Time */
#define BLE_GATT_CHR_UNIT_DAY 0x2762 /* Time */
#define BLE_GATT_CHR_UNIT_DEGREE 0x2763 /* Plane Angle */
#define BLE_GATT_CHR_UNIT_MINUTE_ANGLE 0x2764 /* Plane Angle */
#define BLE_GATT_CHR_UNIT_SECOND_ANGLE 0x2765 /* Plane Angle */
#define BLE_GATT_CHR_UNIT_HECTARE 0x2766 /* Area */
#define BLE_GATT_CHR_UNIT_LITRE 0x2767 /* Volume */
#define BLE_GATT_CHR_UNIT_TONNE 0x2768 /* Mass */
#define BLE_GATT_CHR_UNIT_BAR 0x2780 /* Pressure */
#define BLE_GATT_CHR_UNIT_MILLIMETRE_OF_MERCURY 0x2781 /* Pressure */
#define BLE_GATT_CHR_UNIT_ANGSTROM 0x2782 /* Length */
#define BLE_GATT_CHR_UNIT_NAUTICAL_MILE 0x2783 /* Length */
#define BLE_GATT_CHR_UNIT_BARN 0x2784 /* Area */
#define BLE_GATT_CHR_UNIT_KNOT 0x2785 /* Velocity */
#define BLE_GATT_CHR_UNIT_NEPER 0x2786 /* Logarithmic Radio Quantity */
#define BLE_GATT_CHR_UNIT_BEL 0x2787 /* Logarithmic Radio Quantity */
#define BLE_GATT_CHR_UNIT_YARD 0x27A0 /* Length */
#define BLE_GATT_CHR_UNIT_PARSEC 0x27A1 /* Length */
#define BLE_GATT_CHR_UNIT_INCH 0x27A2 /* Length */
#define BLE_GATT_CHR_UNIT_FOOT 0x27A3 /* Length */
#define BLE_GATT_CHR_UNIT_MILE 0x27A4 /* Length */
#define BLE_GATT_CHR_UNIT_POUND_FORCE_PER_SQUARE_INCH 0x27A5 /* Pressure */
#define BLE_GATT_CHR_UNIT_KILOMETRE_PER_HOUR 0x27A6 /* Velocity */
#define BLE_GATT_CHR_UNIT_MILE_PER_HOUR 0x27A7 /* Velocity */
#define BLE_GATT_CHR_UNIT_REVOLUTION_PER_MINUTE 0x27A8 /* Angular Velocity */
#define BLE_GATT_CHR_UNIT_GRAM_CALORIE 0x27A9 /* Energy */
#define BLE_GATT_CHR_UNIT_KILOGRAM_CALORIE 0x27AA /* Energy */
#define BLE_GATT_CHR_UNIT_KILOWATT_HOUR 0x27AB /* Energy */
#define BLE_GATT_CHR_UNIT_DEGREE_FAHRENHEIT 0x27AC /* Thermodynamic Temperature */
#define BLE_GATT_CHR_UNIT_PERCENTAGE 0x27AD /* Percentage */
#define BLE_GATT_CHR_UNIT_PER_MILLE 0x27AE /* Per Mille */
#define BLE_GATT_CHR_UNIT_BEATS_PER_MINUTE 0x27AF /* Period */
#define BLE_GATT_CHR_UNIT_AMPERE_HOURS 0x27B0 /* Electric Charge */
#define BLE_GATT_CHR_UNIT_MILLIGRAM_PER_DECILITRE 0x27B1 /* Mass Density */
#define BLE_GATT_CHR_UNIT_MILLIMOLE_PER_LITRE 0x27B2 /* Mass Density */
#define BLE_GATT_CHR_UNIT_YEAR 0x27B3 /* Time */
#define BLE_GATT_CHR_UNIT_MONTH 0x27B4 /* Time */
#define BLE_GATT_CHR_UNIT_COUNT_PER_CUBIC_METRE 0x27B5 /* Concentration */
#define BLE_GATT_CHR_UNIT_WATT_PER_SQUARE_METRE_IRRADIANCE 0x27B6 /* Irradiance */
#define BLE_GATT_CHR_UNIT_PER_KILOGRAM_PER_MINUTE 0x27B7 /* Milliliter */
#define BLE_GATT_CHR_UNIT_POUND 0x27B8 /* Mass */
#define BLE_GATT_CHR_UNIT_METABOLIC_EQUIVALENT 0x27B9 /* Metabolic Equivalent */
#define BLE_GATT_CHR_UNIT_PER_MINUTE_STEP 0x27BA /* Step */
#define BLE_GATT_CHR_UNIT_PER_MINUTE_STROKE 0x27BC /* Stroke */
#define BLE_GATT_CHR_UNIT_KILOMETRE_PER_MINUTE 0x27BD /* Pace */
#define BLE_GATT_CHR_UNIT_LUMEN_PER_WATT 0x27BE /* Luminous Efficacy */
#define BLE_GATT_CHR_UNIT_LUMEN_HOUR 0x27BF /* Luminous Energy */
#define BLE_GATT_CHR_UNIT_LUX_HOUR 0x27C0 /* Luminous Exposure */
#define BLE_GATT_CHR_UNIT_GRAM_PER_SECOND 0x27C1 /* Mass Flow */
#define BLE_GATT_CHR_UNIT_LITRE_PER_SECOND 0x27C2 /* Volume Flow */
#define BLE_GATT_CHR_UNIT_DECIBEL 0x27C3 /* Sound Pressure */
#define BLE_GATT_CHR_UNIT_PARTS_PER_MILLION 0x27C4 /* Concentration */
#define BLE_GATT_CHR_UNIT_PARTS_PER_BILLION 0x27C5 /* Concentration */
#define BLE_GATT_CHR_UNIT_MILLIGRAM_PER_DECILITRE_PER_MINUTE 0x27C6 /* Mass Density Rate */
#define BLE_GATT_CHR_UNIT_KILOVOLT_AMPERE_HOUR 0x27C7 /* Electrical Apparent Energy */
#define BLE_GATT_CHR_UNIT_VOLT_AMPERE 0x27C8 /* Electrical Apparent Power */
/**
* Client Presentation Format
* GATT Name Space
* Ref: Assigned Numbers Specification
*/
#define BLE_GATT_CHR_NAMESPACE_BT_SIG 0x01
/**
* Client Presentation Format
* GATT Description for Name Space BT_SIG
* Ref: Assigned Numbers Specification
*/
#define BLE_GATT_CHR_BT_SIG_DESC_UNKNOWN 0x0000
/** 0x0001 - 0x00FF represent themselves. See Ref for more info */
#define BLE_GATT_CHR_BT_SIG_DESC_FRONT 0x0100
#define BLE_GATT_CHR_BT_SIG_DESC_BACK 0x0101
#define BLE_GATT_CHR_BT_SIG_DESC_TOP 0x0102
#define BLE_GATT_CHR_BT_SIG_DESC_BOTTOM 0x0103
#define BLE_GATT_CHR_BT_SIG_DESC_UPPER 0x0104
#define BLE_GATT_CHR_BT_SIG_DESC_LOWER 0x0105
#define BLE_GATT_CHR_BT_SIG_DESC_MAIN 0x0106
#define BLE_GATT_CHR_BT_SIG_DESC_BACKUP 0x0107
#define BLE_GATT_CHR_BT_SIG_DESC_AUXILIARY 0x0108
#define BLE_GATT_CHR_BT_SIG_DESC_SUPPLEMENTARY 0x0109
#define BLE_GATT_CHR_BT_SIG_DESC_FLASH 0x010A
#define BLE_GATT_CHR_BT_SIG_DESC_INSIDE 0x010B
#define BLE_GATT_CHR_BT_SIG_DESC_OUTSIDE 0x010C
#define BLE_GATT_CHR_BT_SIG_DESC_LEFT 0x010D
#define BLE_GATT_CHR_BT_SIG_DESC_RIGHT 0x010E
#define BLE_GATT_CHR_BT_SIG_DESC_INTERNAL 0x010F
#define BLE_GATT_CHR_BT_SIG_DESC_EXTERNAL 0x0110
/*** @client. */
/** Represents a GATT error. */
@@ -752,6 +951,9 @@ struct ble_gatt_chr_def {
* attribute handle.
*/
uint16_t *val_handle;
/** Client Presentation Format Descriptors */
struct ble_gatt_cpfd *cpfd;
};
/** Represents the definition of a GATT service. */
@@ -805,6 +1007,40 @@ struct ble_gatt_dsc_def {
void *arg;
};
/**
* Client Presentation Format Descriptor
* Defines the format of the Characteristic Value.
*
* +-------------+------------+
* | Field Name | Value Size |
* +-------------+------------+
* | Format | 1 octet |
* | Exponent | 1 octet |
* | Unit | 2 octets |
* | Name Space | 1 octet |
* | Description | 2 octets |
* +-------------+------------+
*/
struct ble_gatt_cpfd {
/**
* Format of the value of this characteristic. e.g. UINT32
* Cannot be 0x00. 0x00 represents CPFD array is ended.
*/
uint8_t format;
/** Exponent field. Multiplies the value to 10^exponent. Type: sint8 */
int8_t exponent;
/** The unit of this characteristic. e.g. meters per second */
uint16_t unit;
/** The name space of the description. */
uint8_t namespace;
/** The description of this characteristic. Depends on name space. */
uint16_t description;
};
/**
* Context for an access to a GATT characteristic or descriptor. When a client
* reads or writes a locally registered characteristic or descriptor, an
+12
View File
@@ -193,6 +193,18 @@ struct ble_gatt_resources {
*/
uint16_t cccds;
/**
* Number of client presentation format descriptors. Each of
* these also contributes to the total descriptor count.
*/
uint16_t cpfds;
/**
* Number of aggregate presentation foramt descriptors. Each of
* these also contributes to the total descriptor count.
*/
uint16_t cafds;
/** Total number of ATT attributes. */
uint16_t attrs;
};
+168
View File
@@ -59,6 +59,10 @@ static const ble_uuid_t *uuid_chr =
BLE_UUID16_DECLARE(BLE_ATT_UUID_CHARACTERISTIC);
static const ble_uuid_t *uuid_ccc =
BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_CFG_UUID16);
static const ble_uuid_t *uuid_cpf =
BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_PRE_FMT16);
static const ble_uuid_t *uuid_caf =
BLE_UUID16_DECLARE(BLE_GATT_DSC_CLT_AGG_FMT16);
static const struct ble_gatt_svc_def **ble_gatts_svc_defs;
static int ble_gatts_num_svc_defs;
@@ -736,6 +740,33 @@ ble_gatts_register_dsc(const struct ble_gatt_svc_def *svc,
}
static int
ble_gatts_cpfd_is_sane(const struct ble_gatt_cpfd *cpfd)
{
/** As per Assigned Numbers Specification (2023-09-07) */
if ((cpfd->format < 0x01) || (cpfd->format > 0x1C)) {
return 0;
}
if ((cpfd->unit < 0x2700) ||
((cpfd->unit > 0x2707) && (cpfd->unit < 0x2710)) ||
(cpfd->unit == 0x271F) ||
((cpfd->unit > 0x2735) && (cpfd->unit < 0x2740)) ||
((cpfd->unit > 0x2757) && (cpfd->unit < 0x2760)) ||
((cpfd->unit > 0x2768) && (cpfd->unit < 0x2780)) ||
((cpfd->unit > 0x2787) && (cpfd->unit < 0x27A0)) ||
(cpfd->unit == 0x27BB) ||
(cpfd->unit > 0x27C8)) {
return 0;
}
if ((cpfd->namespace == BLE_GATT_CHR_NAMESPACE_BT_SIG) && (cpfd->description > 0x0110)) {
return 0;
}
return 1;
}
#if MYNEWT_VAL(BLE_DYNAMIC_SERVICE)
static struct ble_gatts_clt_cfg *
ble_gatts_clt_cfg_find(struct ble_gatts_clt_cfg_list *ble_gatts_clt_cfgs,
@@ -980,6 +1011,110 @@ ble_gatts_register_clt_cfg_dsc(uint16_t *att_handle)
return 0;
}
static int
ble_gatts_cafd_access(uint16_t conn_handle, uint16_t attr_handle,
uint8_t op, uint16_t offset, struct os_mbuf **om,
void *arg)
{
struct ble_att_svr_entry * cpfd_entry;
uint16_t handle;
int rc;
BLE_HS_DBG_ASSERT(op == BLE_ATT_ACCESS_OP_READ);
STATS_INC(ble_gatts_stats, dsc_reads);
cpfd_entry = arg;
/**
* All the Client Presentation Format Descriptors of this characteristic
* are registered just before the Client Aggregate Format Descriptor.
* The handle of the first one is retrieved from arg.
*/
rc = 0;
for (handle = cpfd_entry->ha_handle_id; handle < attr_handle; handle++) {
rc += os_mbuf_append(*om, &handle, sizeof(handle));
}
return ((rc == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES);
}
static int
ble_gatts_cpfd_access(uint16_t conn_handle, uint16_t attr_handle,
uint8_t op, uint16_t offset, struct os_mbuf **om,
void *arg)
{
struct ble_gatt_cpfd * cpfd;
int rc;
BLE_HS_DBG_ASSERT(op == BLE_ATT_ACCESS_OP_READ);
STATS_INC(ble_gatts_stats, dsc_reads);
cpfd = arg;
rc = 0;
rc += os_mbuf_append(*om, &(cpfd->format), sizeof(cpfd->format));
rc += os_mbuf_append(*om, &(cpfd->exponent), sizeof(cpfd->exponent));
rc += os_mbuf_append(*om, &(cpfd->unit), sizeof(cpfd->unit));
rc += os_mbuf_append(*om, &(cpfd->namespace), sizeof(cpfd->namespace));
rc += os_mbuf_append(*om, &(cpfd->description), sizeof(cpfd->description));
return ((rc == 0) ? 0 : BLE_ATT_ERR_INSUFFICIENT_RES);
}
static int
ble_gatts_register_cpfds(const struct ble_gatt_cpfd *cpfds)
{
int idx;
int rc;
uint16_t first_cpfd_handle;
struct ble_att_svr_entry * first_cpfd_entry;
if (cpfds == NULL) {
/** No Client Presentation Format Descriptors to add */
return 0;
}
for (idx = 0; cpfds[idx].format != 0; idx++) {
rc = ble_att_svr_register(uuid_cpf, BLE_ATT_F_READ, 0, &first_cpfd_handle,
ble_gatts_cpfd_access, (void *)(cpfds + idx));
if (rc != 0) {
return rc;
}
STATS_INC(ble_gatts_stats, dscs);
}
/**
* Client Aggregate Format Descriptor required if
* more than one CPFDs are registered for the same characteristic
*/
if (idx > 1) {
first_cpfd_handle -= (idx - 1);
first_cpfd_entry = ble_att_svr_find_by_handle(first_cpfd_handle);
if (first_cpfd_entry == NULL) {
return BLE_HS_ENOENT;
}
/**
* The First CPFD entry will contain it's handle,
* Using that and the handle of this descriptor we can
* find the handles all CPFDs.
*/
rc = ble_att_svr_register(uuid_caf, BLE_ATT_F_READ, 0, NULL,
ble_gatts_cafd_access, (void *)(first_cpfd_entry));
if (rc != 0) {
return rc;
}
STATS_INC(ble_gatts_stats, dscs);
}
return 0;
}
static int
ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
const struct ble_gatt_chr_def *chr,
@@ -1048,6 +1183,12 @@ ble_gatts_register_chr(const struct ble_gatt_svc_def *svc,
BLE_HS_DBG_ASSERT(dsc_handle == def_handle + 2);
}
/* Register each Client Presentation Format Descriptor. */
rc = ble_gatts_register_cpfds(chr->cpfd);
if (rc != 0) {
return rc;
}
/* Register each descriptor. */
if (chr->descriptors != NULL) {
for (dsc = chr->descriptors; dsc->uuid != NULL; dsc++) {
@@ -1306,6 +1447,7 @@ ble_gatts_clt_cfg_size(void)
}
#endif
/**
* Handles GATT server clean up for a terminated connection:
* o Informs the application that the peer is no longer subscribed to any
@@ -2880,6 +3022,7 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
int i;
int c;
int d;
int pf;
for (s = 0; svcs[s].type != BLE_GATT_SVC_TYPE_END; s++) {
svc = svcs + s;
@@ -2954,6 +3097,31 @@ ble_gatts_count_resources(const struct ble_gatt_svc_def *svcs,
res->attrs++;
}
}
if (chr->cpfd != NULL) {
for (pf = 0; chr->cpfd[pf].format != 0; pf++) {
if (!ble_gatts_cpfd_is_sane(chr->cpfd + pf)) {
BLE_HS_DBG_ASSERT(0);
return BLE_HS_EINVAL;
}
/** Each CPFD requires:
* o 1 descriptor
* o 1 CPFD
* o 1 attribute
*/
res->dscs++;
res->cpfds++;
res->attrs++;
}
/** If more than one CPFD is present for a characteristic, one CAFD is required. */
if (pf > 1) {
res->cafds++;
res->dscs++;
res->attrs++;
}
}
}
}
}