#ifndef ATTM_H_ #define ATTM_H_ /** **************************************************************************************** * @addtogroup ATTM Attribute Manager * @ingroup ATT * @brief Attribute Manager * * The ATTM is the attribute manager of the Attribute Profile block and * is responsible for managing messages and providing generic attribute * functionalities to @ref ATTC "ATTC" and @ref ATTS "ATTS". * * * @{ * **************************************************************************************** */ /* * INCLUDE FILES **************************************************************************************** */ #include "rwip_config.h" #include #include #include "co_error.h" #include "att.h" #include "ke_task.h" /* * DEFINES **************************************************************************************** */ /// update attribute permission on specific handle #define ATTMDB_UPDATE_PERM(handle, access, right)\ attm_att_update_perm(handle, (PERM_MASK_ ## access), PERM(access, right)) #define ATTMDB_UPDATE_PERM_VAL(handle, access, val)\ attm_att_update_perm(handle, (PERM_MASK_ ## access), ((val) << (PERM_POS_ ## access))) /* * DATA STRUCTURES **************************************************************************************** */ /// Internal 16bits UUID service description struct attm_desc { /// 16 bits UUID LSB First uint16_t uuid; /// Attribute Permissions (@see enum attm_perm_mask) uint16_t perm; /// Attribute Extended Permissions (@see enum attm_value_perm_mask) uint16_t ext_perm; /// Attribute Max Size /// note: for characteristic declaration contains handle offset /// note: for included service, contains target service handle uint16_t max_size; }; /// Internal 128bits UUID service description struct attm_desc_128 { /// 128 bits UUID LSB First uint8_t uuid[ATT_UUID_128_LEN]; /// Attribute Permissions (@see enum attm_perm_mask) uint16_t perm; /// Attribute Extended Permissions (@see enum attm_value_perm_mask) uint16_t ext_perm; /// Attribute Max Size /// note: for characteristic declaration contains handle offset /// note: for included service, contains target service handle uint16_t max_size; }; #if (BLE_CENTRAL || BLE_PERIPHERAL) /* * GLOBAL VARIABLE DECLARATIONS **************************************************************************************** */ /* * FUNCTION DECLARATIONS **************************************************************************************** */ /** **************************************************************************************** * @brief Compare if two UUIDs matches * * @param[in] uuid_a UUID A value * @param[in] uuid_a_len UUID A length * @param[in] uuid_b UUID B value * @param[in] uuid_b_len UUID B length * * @return true if UUIDs matches, false otherwise **************************************************************************************** */ bool attm_uuid_comp(uint8_t *uuid_a, uint8_t uuid_a_len, uint8_t *uuid_b, uint8_t uuid_b_len); /** **************************************************************************************** * @brief Check if two UUIDs matches (2nd UUID is a 16 bits UUID with LSB First) * * @param[in] uuid_a UUID A value * @param[in] uuid_a_len UUID A length * @param[in] uuid_b UUID B 16 bit value * * @return true if UUIDs matches, false otherwise **************************************************************************************** */ bool attm_uuid16_comp(uint8_t *uuid_a, uint8_t uuid_a_len, uint16_t uuid_b); /** **************************************************************************************** * @brief Convert UUID value to 128 bit UUID * * @param[out] uuid128 converted 32-bit Bluetooth UUID to 128-bit UUID * @param[in] uuid UUID to convert to 128-bit UUID * @param[in] uuid_len UUID length * **************************************************************************************** */ void attm_convert_to128(uint8_t *uuid128, uint8_t *uuid, uint8_t uuid_len); /** **************************************************************************************** * @brief Check if it's a Bluetooth 16-bits UUID for 128-bit input * * @param[in] uuid 128-bit UUID * * @return true if uuid is a Bluetooth 16-bit UUID, false else. **************************************************************************************** */ bool attm_is_bt16_uuid(uint8_t *uuid); /** **************************************************************************************** * @brief Check if it's a Bluetooth 32 bits UUID for 128-bit input * * @param[in] uuid 128-bit UUID * * @return true if uuid is a Bluetooth 32-bits UUID, false else. **************************************************************************************** */ bool attm_is_bt32_uuid(uint8_t *uuid); #if (BLE_ATTS) /** **************************************************************************************** * @brief Function use to ease service database creation. * Use @see attmdb_add_service function of attmdb module to create service database, * then use @see attmdb_add_attribute function of attmdb module to create attributes * according to database description array given in parameter. * * @note: database description array shall be const to reduce memory consumption (only ROM) * @note: It supports only 16 bits UUIDs * * @note: If shdl = 0, it return handle using first available handle (shdl is * modified); else it verifies if start handle given can be used to allocates handle range. * * @param[in|out] shdl Service start handle. * @param[in] uuid Service UUID * @param[in|out] cfg_flag Configuration Flag, each bit matches with an attribute of * att_db (Max: 32 attributes); if the bit is set to 1, the * attribute will be added in the service. * @param[in] max_nb_att Number of attributes in the service * @param[in|out] att_tbl Array which will be fulfilled with the difference between * each characteristic handle and the service start handle. * This array is useful if several characteristics are optional * within the service, can be set to NULL if not needed. * @param[in] dest_id Task ID linked to the service. This task will be notified * each time the service content is modified by a peer device. * @param[in|out] att_db Table containing all attributes information * @param[in] svc_perm Service permission (@see enum attm_svc_perm_mask) * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override * some existing services handles. * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. * or of new attribute cannot be added because all expected * attributes already added or buffer overflow detected during * allocation **************************************************************************************** */ uint8_t attm_svc_create_db(uint16_t *shdl, uint16_t uuid, uint8_t *cfg_flag, uint8_t max_nb_att, uint8_t *att_tbl, ke_task_id_t const dest_id, const struct attm_desc *att_db, uint8_t svc_perm); /** **************************************************************************************** * @brief Function use to ease service database creation. * Use @see attmdb_add_service function of attmdb module to create service database, * then use @see attmdb_add_attribute function of attmdb module to create attributes * according to database description array given in parameter. * * @note: database description array shall be const to reduce memory consumption (only ROM) * @note: It supports 128, 32 and 16 bits UUIDs * * @note: If shdl = 0, it return handle using first available handle (shdl is * modified); else it verifies if start handle given can be used to allocates handle range. * * @param[in|out] shdl Service start handle. * @param[in] uuid Service UUID * @param[in|out] cfg_flag Configuration Flag, each bit matches with an attribute of * att_db (Max: 32 attributes); if the bit is set to 1, the * attribute will be added in the service. * @param[in] max_nb_att Number of attributes in the service * @param[in|out] att_tbl Array which will be fulfilled with the difference between * each characteristic handle and the service start handle. * This array is useful if several characteristics are optional * within the service, can be set to NULL if not needed. * @param[in] dest_id Task ID linked to the service. This task will be notified * each time the service content is modified by a peer device. * @param[in|out] att_db Table containing all attributes information * @param[in] svc_perm Service permission (@see enum attm_svc_perm_mask) * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override * some existing services handles. * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. * or of new attribute cannot be added because all expected * attributes already added or buffer overflow detected during * allocation **************************************************************************************** */ uint8_t attm_svc_create_db_128(uint16_t *shdl, const uint8_t* uuid, uint8_t *cfg_flag, uint8_t max_nb_att, uint8_t *att_tbl, ke_task_id_t const dest_id, const struct attm_desc_128 *att_db, uint8_t svc_perm); /** **************************************************************************************** * @brief Function use to verify if several services can be allocated on a contiguous * handle range. If this command succeed, it means that service allocation will succeed. * * If start_hdl = 0, it return handle using first available handle (start_hdl is * modified); else it verifies if start handle given can be used to allocates handle range. * * @param[in|out] start_hdl Service start handle. * @param[in] nb_att Number of handle to allocate (containing service handles) * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If service allocation succeeds. * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid **************************************************************************************** */ uint8_t attm_reserve_handle_range(uint16_t* start_hdl, uint8_t nb_att); /** **************************************************************************************** * @brief Update attribute value * * Updating attribute value do not trigger any notification or indication, this shall be * handled by GATT task. * * @param[in] handle Attribute handle. * @param[in] length Size of new attribute value * @param[in] offset Data offset of in the payload to set * @param[in] value Attribute value payload * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If attribute value update succeeds * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database or * cannot be modified * - @ref ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN: If new value length exceeds maximum attribute * value length. * **************************************************************************************** */ uint8_t attm_att_set_value(uint16_t handle, att_size_t length, att_size_t offset, uint8_t* value); /** **************************************************************************************** * @brief Retrieve attribute value * * @param[in] handle Attribute handle. * @param[out] length Size of attribute value * @param[out] value Pointer to attribute value payload * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If request succeeds * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database **************************************************************************************** */ uint8_t attm_get_value(uint16_t handle, att_size_t* length, uint8_t** value); /** **************************************************************************************** * @brief Update attribute permission * * @param[in] handle Attribute handle. * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database * @param[in] perm New attribute permission * @param[in] ext_perm New attribute extended permission * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If request succeeds * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed **************************************************************************************** */ uint8_t attm_att_set_permission(uint16_t handle, uint16_t perm, uint16_t ext_perm); /** **************************************************************************************** * @brief Reset some permissions bit in the Handle passed as parameter. * * @param[in] handle Attribute handle. * @param[in] access_mask Access mask of permission to update * @param[in] perm New value of the permission to update * * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If request succeeds * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed **************************************************************************************** */ uint8_t attm_att_update_perm(uint16_t handle, uint16_t access_mask, uint16_t perm); /** **************************************************************************************** * @brief Update attribute service permission * * @param[in] handle Attribute handle. * @param[in] perm New attribute permission * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If request succeeds * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database **************************************************************************************** */ uint8_t attm_svc_set_permission(uint16_t handle, uint8_t perm); /** **************************************************************************************** * @brief Retrieve attribute service permission * * @param[in] handle Attribute handle. * @param[out] perm Permission value to return * * @return Command status code: * - @ref ATT_ERR_NO_ERROR: If request succeeds * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database **************************************************************************************** */ uint8_t attm_svc_get_permission(uint16_t handle, uint8_t* perm); /** **************************************************************************************** * @brief Clear database * * For debug purpose only, this function clear the database and unalloc all services * within database. * * This function shall be used only for qualification and tests in order to manually * change database without modifying software. **************************************************************************************** */ void attmdb_destroy(void); /** **************************************************************************************** * @brief Initialize Attribute Database (clear it) * * @param[in] reset true if it's requested by a reset; false if it's boot initialization **************************************************************************************** */ void attm_init(bool reset); #endif // (BLE_ATTS) #endif // #if (BLE_CENTRAL || BLE_PERIPHERAL) /// @} ATTM #endif // ATTM_H_