static struct gatt_db_attribute * service_insert_descriptor(struct gatt_db_service *service, uint16_t handle, const bt_uuid_t *uuid, uint32_t permissions, gatt_db_read_t read_func, gatt_db_write_t write_func, void *user_data) { int i; i = get_attribute_index(service, 0); if (!i) return NULL; /* Check if handle is in within service range */ if (handle && handle <= service->attributes[0]->handle) return NULL; if (!handle) handle = get_handle_at_index(service, i - 1) + 1; service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0); if (!service->attributes[i]) return NULL; set_attribute_data(service->attributes[i], read_func, write_func, permissions, user_data); return service->attributes[i]; }
/*!\fn void set_attribute_data(WRATHCanvas::DataHandle, int, const WRATHReferenceCountedObject::handle&, const WRATHStateBasedPackingData::handle&) const Packs the attribute data to draw a rectangle. The attribute data is to be 4 vertices packed in the order: minx_miny, minx_maxy, maxy_maxy, maxx_miny. Provided as a conveniance, equivalent to \code WRATHAttributeStore::DataSink sink(item_group.attribute_store()->data_sink()); set_attribute_data(sink, attr_location, rect, h); \endcode \param item_group location to which to pack the attribute data \param attr_location location within sink to place attribute data \param rect handle of data describing the rectangle from which to compute/create attribute data \param h handle to hold additional immutable state that affects packing */ void set_attribute_data(WRATHCanvas::DataHandle item_group, int attr_location, const WRATHReferenceCountedObject::handle &rect, const WRATHStateBasedPackingData::handle &h) const { WRATHAttributeStore::DataSink sink(item_group.attribute_store()->data_sink()); set_attribute_data(sink, attr_location, rect, h); }
struct gatt_db_attribute * gatt_db_service_add_included(struct gatt_db_attribute *attrib, struct gatt_db_attribute *include) { struct gatt_db_service *service, *included; uint8_t value[MAX_INCLUDED_VALUE_LEN]; uint16_t included_handle, len = 0; int index; if (!attrib || !include) return NULL; service = attrib->service; included = include->service; /* Adjust include to point to the first attribute */ if (include != included->attributes[0]) include = included->attributes[0]; included_handle = include->handle; put_le16(included_handle, &value[len]); len += sizeof(uint16_t); put_le16(included_handle + included->num_handles - 1, &value[len]); len += sizeof(uint16_t); /* The Service UUID shall only be present when the UUID is a 16-bit * Bluetooth UUID. Vol 2. Part G. 3.2 */ if (include->value_len == sizeof(uint16_t)) { memcpy(&value[len], include->value, include->value_len); len += include->value_len; } index = get_attribute_index(service, 0); if (!index) return NULL; service->attributes[index] = new_attribute(service, 0, &included_service_uuid, value, len); if (!service->attributes[index]) return NULL; /* The Attribute Permissions shall be read only and not require * authentication or authorization. Vol 2. Part G. 3.2 * * TODO handle permissions */ set_attribute_data(service->attributes[index], NULL, NULL, 0, NULL); return attribute_update(service, index); }
static struct gatt_db_attribute * service_insert_characteristic(struct gatt_db_service *service, uint16_t handle, const bt_uuid_t *uuid, uint32_t permissions, uint8_t properties, gatt_db_read_t read_func, gatt_db_write_t write_func, void *user_data) { uint8_t value[MAX_CHAR_DECL_VALUE_LEN]; uint16_t len = 0; int i; /* Check if handle is in within service range */ if (handle && handle <= service->attributes[0]->handle) return NULL; /* * It is not possible to allocate last handle for a Characteristic * since it would not have space for its value: * 3.3.2 Characteristic Value Declaration * The Characteristic Value declaration contains the value of the * characteristic. It is the first Attribute after the characteristic * declaration. All characteristic definitions shall have a * Characteristic Value declaration. */ if (handle == UINT16_MAX) return NULL; i = get_attribute_index(service, 1); if (!i) return NULL; if (!handle) handle = get_handle_at_index(service, i - 1) + 2; value[0] = properties; len += sizeof(properties); /* We set handle of characteristic value, which will be added next */ put_le16(handle, &value[1]); len += sizeof(uint16_t); len += uuid_to_le(uuid, &value[3]); service->attributes[i] = new_attribute(service, handle - 1, &characteristic_uuid, value, len); if (!service->attributes[i]) return NULL; i++; service->attributes[i] = new_attribute(service, handle, uuid, NULL, 0); if (!service->attributes[i]) { free(service->attributes[i - 1]); return NULL; } set_attribute_data(service->attributes[i], read_func, write_func, permissions, user_data); return service->attributes[i]; }