1 /* 2 * Copyright (c) 2021 Chipsea Technologies (Shenzhen) Corp., Ltd. All rights reserved. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 #ifndef _HAL_ATTM_H 16 #define _HAL_ATTM_H 17 18 #include "ble_ip_config.h" 19 #include <string.h> 20 #include <stdbool.h> 21 22 #include "hal_att.h" 23 #include "ble_ke_task.h" 24 25 /// update attribute permission on specific handle 26 #define ATTMDB_UPDATE_PERM(handle, access, right)\ 27 attm_att_update_perm(handle, (PERM_MASK_ ## access), PERM(access, right)) 28 29 #define ATTMDB_UPDATE_PERM_VAL(handle, access, val)\ 30 attm_att_update_perm(handle, (PERM_MASK_ ## access), ((val) << (PERM_POS_ ## access))) 31 32 33 34 /* 35 * DATA STRUCTURES 36 **************************************************************************************** 37 */ 38 39 /// Internal 16bits UUID service description 40 struct attm_desc 41 { 42 /// 16 bits UUID LSB First 43 uint16_t uuid; 44 /// Attribute Permissions (@see enum attm_perm_mask) 45 uint16_t perm; 46 /// Attribute Extended Permissions (@see enum attm_value_perm_mask) 47 uint16_t ext_perm; 48 /// Attribute Max Size 49 /// note: for characteristic declaration contains handle offset 50 /// note: for included service, contains target service handle 51 uint16_t max_size; 52 }; 53 54 55 /// Internal 128bits UUID service description 56 struct attm_desc_128 57 { 58 /// 128 bits UUID LSB First 59 uint8_t uuid[ATT_UUID_128_LEN]; 60 /// Attribute Permissions (@see enum attm_perm_mask) 61 uint16_t perm; 62 /// Attribute Extended Permissions (@see enum attm_value_perm_mask) 63 uint16_t ext_perm; 64 /// Attribute Max Size 65 /// note: for characteristic declaration contains handle offset 66 /// note: for included service, contains target service handle 67 uint16_t max_size; 68 }; 69 70 71 72 #if (BLE_CENTRAL || BLE_PERIPHERAL) 73 /* 74 * GLOBAL VARIABLE DECLARATIONS 75 **************************************************************************************** 76 */ 77 78 /* 79 * FUNCTION DECLARATIONS 80 **************************************************************************************** 81 */ 82 83 84 /** 85 **************************************************************************************** 86 * @brief Compare if two UUIDs matches 87 * 88 * @param[in] uuid_a UUID A value 89 * @param[in] uuid_a_len UUID A length 90 * @param[in] uuid_b UUID B value 91 * @param[in] uuid_b_len UUID B length 92 * 93 * @return true if UUIDs matches, false otherwise 94 **************************************************************************************** 95 */ 96 bool attm_uuid_comp(uint8_t *uuid_a, uint8_t uuid_a_len, 97 uint8_t *uuid_b, uint8_t uuid_b_len); 98 99 100 /** 101 **************************************************************************************** 102 * @brief Check if two UUIDs matches (2nd UUID is a 16 bits UUID with LSB First) 103 * 104 * @param[in] uuid_a UUID A value 105 * @param[in] uuid_a_len UUID A length 106 * @param[in] uuid_b UUID B 16 bit value 107 * 108 * @return true if UUIDs matches, false otherwise 109 **************************************************************************************** 110 */ 111 bool attm_uuid16_comp(uint8_t *uuid_a, uint8_t uuid_a_len, uint16_t uuid_b); 112 113 114 /** 115 **************************************************************************************** 116 * @brief Convert UUID value to 128 bit UUID 117 * 118 * @param[out] uuid128 converted 32-bit Bluetooth UUID to 128-bit UUID 119 * @param[in] uuid UUID to convert to 128-bit UUID 120 * @param[in] uuid_len UUID length 121 * 122 **************************************************************************************** 123 */ 124 void attm_convert_to128(uint8_t *uuid128, uint8_t *uuid, uint8_t uuid_len); 125 126 /** 127 **************************************************************************************** 128 * @brief Check if it's a Bluetooth 16-bits UUID for 128-bit input 129 * 130 * @param[in] uuid 128-bit UUID 131 * 132 * @return true if uuid is a Bluetooth 16-bit UUID, false else. 133 **************************************************************************************** 134 */ 135 bool attm_is_bt16_uuid(uint8_t *uuid); 136 137 /** 138 **************************************************************************************** 139 * @brief Check if it's a Bluetooth 32 bits UUID for 128-bit input 140 * 141 * @param[in] uuid 128-bit UUID 142 * 143 * @return true if uuid is a Bluetooth 32-bits UUID, false else. 144 **************************************************************************************** 145 */ 146 bool attm_is_bt32_uuid(uint8_t *uuid); 147 148 149 #if (BLE_ATTS) 150 /** 151 **************************************************************************************** 152 * @brief Function use to ease service database creation. 153 * Use @see attmdb_add_service function of attmdb module to create service database, 154 * then use @see attmdb_add_attribute function of attmdb module to create attributes 155 * according to database description array given in parameter. 156 * 157 * @note: database description array shall be const to reduce memory consumption (only ROM) 158 * @note: It supports only 16 bits UUIDs 159 * 160 * @note: If shdl = 0, it return handle using first available handle (shdl is 161 * modified); else it verifies if start handle given can be used to allocates handle range. 162 * 163 * @param[in|out] shdl Service start handle. 164 * @param[in] uuid Service UUID 165 * @param[in|out] cfg_flag Configuration Flag, each bit matches with an attribute of 166 * att_db (Max: 32 attributes); if the bit is set to 1, the 167 * attribute will be added in the service. 168 * @param[in] max_nb_att Number of attributes in the service 169 * @param[in|out] att_tbl Array which will be fulfilled with the difference between 170 * each characteristic handle and the service start handle. 171 * This array is useful if several characteristics are optional 172 * within the service, can be set to NULL if not needed. 173 * @param[in] dest_id Task ID linked to the service. This task will be notified 174 * each time the service content is modified by a peer device. 175 * @param[in|out] att_db Table containing all attributes information 176 * @param[in] svc_perm Service permission (@see enum attm_svc_perm_mask) 177 * 178 * @return Command status code: 179 * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. 180 * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override 181 * some existing services handles. 182 * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. 183 * or of new attribute cannot be added because all expected 184 * attributes already added or buffer overflow detected during 185 * allocation 186 **************************************************************************************** 187 */ 188 uint8_t attm_svc_create_db(uint16_t *shdl, uint16_t uuid, uint8_t *cfg_flag, uint8_t max_nb_att, 189 uint8_t *att_tbl, ke_task_id_t const dest_id, 190 const struct attm_desc *att_db, uint8_t svc_perm); 191 192 193 /** 194 **************************************************************************************** 195 * @brief Function use to ease service database creation. 196 * Use @see attmdb_add_service function of attmdb module to create service database, 197 * then use @see attmdb_add_attribute function of attmdb module to create attributes 198 * according to database description array given in parameter. 199 * 200 * @note: database description array shall be const to reduce memory consumption (only ROM) 201 * @note: It supports 128, 32 and 16 bits UUIDs 202 * 203 * @note: If shdl = 0, it return handle using first available handle (shdl is 204 * modified); else it verifies if start handle given can be used to allocates handle range. 205 * 206 * @param[in|out] shdl Service start handle. 207 * @param[in] uuid Service UUID 208 * @param[in|out] cfg_flag Configuration Flag, each bit matches with an attribute of 209 * att_db (Max: 32 attributes); if the bit is set to 1, the 210 * attribute will be added in the service. 211 * @param[in] max_nb_att Number of attributes in the service 212 * @param[in|out] att_tbl Array which will be fulfilled with the difference between 213 * each characteristic handle and the service start handle. 214 * This array is useful if several characteristics are optional 215 * within the service, can be set to NULL if not needed. 216 * @param[in] dest_id Task ID linked to the service. This task will be notified 217 * each time the service content is modified by a peer device. 218 * @param[in|out] att_db Table containing all attributes information 219 * @param[in] svc_perm Service permission (@see enum attm_svc_perm_mask) 220 * 221 * @return Command status code: 222 * - @ref ATT_ERR_NO_ERROR: If database creation succeeds. 223 * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter + nb of attribute override 224 * some existing services handles. 225 * - @ref ATT_ERR_INSUFF_RESOURCE: There is not enough memory to allocate service buffer. 226 * or of new attribute cannot be added because all expected 227 * attributes already added or buffer overflow detected during 228 * allocation 229 **************************************************************************************** 230 */ 231 uint8_t attm_svc_create_db_128(uint16_t *shdl, const uint8_t* uuid, uint8_t *cfg_flag, uint8_t max_nb_att, 232 uint8_t *att_tbl, ke_task_id_t const dest_id, 233 const struct attm_desc_128 *att_db, uint8_t svc_perm); 234 235 /** 236 **************************************************************************************** 237 * @brief Control visibility of a service from peer device. service present in database 238 * but cannot be access by a peer device. 239 * 240 * @param[in] handle Service handle. 241 * @param[in] hide True to hide the service, False to restore visibility 242 * 243 * @return Command status code: 244 * - @ref ATT_ERR_NO_ERROR: If service allocation succeeds. 245 * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid 246 **************************************************************************************** 247 */ 248 uint8_t attmdb_svc_visibility_set(uint16_t handle, bool hide); 249 250 /** 251 **************************************************************************************** 252 * @brief Function use to verify if several services can be allocated on a contiguous 253 * handle range. If this command succeed, it means that service allocation will succeed. 254 * 255 * If start_hdl = 0, it return handle using first available handle (start_hdl is 256 * modified); else it verifies if start handle given can be used to allocates handle range. 257 * 258 * @param[in|out] start_hdl Service start handle. 259 * @param[in] nb_att Number of handle to allocate (containing service handles) 260 * 261 * @return Command status code: 262 * - @ref ATT_ERR_NO_ERROR: If service allocation succeeds. 263 * - @ref ATT_ERR_INVALID_HANDLE: If start_hdl given in parameter or UUIDs value invalid 264 **************************************************************************************** 265 */ 266 uint8_t attm_reserve_handle_range(uint16_t* start_hdl, uint8_t nb_att); 267 268 269 270 /** 271 **************************************************************************************** 272 * @brief Update attribute value 273 * 274 * Updating attribute value do not trigger any notification or indication, this shall be 275 * handled by GATT task. 276 * 277 * @param[in] handle Attribute handle. 278 * @param[in] length Size of new attribute value 279 * @param[in] offset Data offset of in the payload to set 280 * @param[in] value Attribute value payload 281 * 282 * @return Command status code: 283 * - @ref ATT_ERR_NO_ERROR: If attribute value update succeeds 284 * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database 285 * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database or 286 * cannot be modified 287 * - @ref ATT_ERR_INVALID_ATTRIBUTE_VAL_LEN: If new value length exceeds maximum attribute 288 * value length. 289 * 290 **************************************************************************************** 291 */ 292 uint8_t attm_att_set_value(uint16_t handle, att_size_t length, att_size_t offset, uint8_t* value); 293 294 /** 295 **************************************************************************************** 296 * @brief Retrieve attribute value 297 298 * 299 * @param[in] handle Attribute handle. 300 * @param[out] length Size of attribute value 301 * @param[out] value Pointer to attribute value payload 302 * 303 * @return Command status code: 304 * - @ref ATT_ERR_NO_ERROR: If request succeeds 305 * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database 306 * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database 307 **************************************************************************************** 308 */ 309 uint8_t attm_get_value(uint16_t handle, att_size_t* length, uint8_t** value); 310 311 312 /** 313 **************************************************************************************** 314 * @brief Update attribute permission 315 * 316 * @param[in] handle Attribute handle. 317 * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute data not present in database 318 * @param[in] perm New attribute permission 319 * @param[in] ext_perm New attribute extended permission 320 * 321 * @return Command status code: 322 * - @ref ATT_ERR_NO_ERROR: If request succeeds 323 * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database 324 * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed 325 **************************************************************************************** 326 */ 327 uint8_t attm_att_set_permission(uint16_t handle, uint16_t perm, uint16_t ext_perm); 328 329 330 /** 331 **************************************************************************************** 332 * @brief Reset some permissions bit in the Handle passed as parameter. 333 * 334 * @param[in] handle Attribute handle. 335 * @param[in] access_mask Access mask of permission to update 336 * @param[in] perm New value of the permission to update 337 * 338 * 339 * @return Command status code: 340 * - @ref ATT_ERR_NO_ERROR: If request succeeds 341 * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database 342 * - @ref ATT_ERR_REQUEST_NOT_SUPPORTED: If attribute permission is fixed 343 **************************************************************************************** 344 */ 345 uint8_t attm_att_update_perm(uint16_t handle, uint16_t access_mask, uint16_t perm); 346 347 /** 348 **************************************************************************************** 349 * @brief Update attribute service permission 350 * 351 * @param[in] handle Attribute handle. 352 * @param[in] perm New attribute permission 353 * 354 * @return Command status code: 355 * - @ref ATT_ERR_NO_ERROR: If request succeeds 356 * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database 357 **************************************************************************************** 358 */ 359 uint8_t attm_svc_set_permission(uint16_t handle, uint8_t perm); 360 361 362 /** 363 **************************************************************************************** 364 * @brief Retrieve attribute service permission 365 * 366 * @param[in] handle Attribute handle. 367 * @param[out] perm Permission value to return 368 * 369 * @return Command status code: 370 * - @ref ATT_ERR_NO_ERROR: If request succeeds 371 * - @ref ATT_ERR_INVALID_HANDLE: If handle doesn't exist in database 372 **************************************************************************************** 373 */ 374 uint8_t attm_svc_get_permission(uint16_t handle, uint8_t* perm); 375 376 377 /** 378 **************************************************************************************** 379 * @brief Clear database 380 * 381 * For debug purpose only, this function clear the database and unalloc all services 382 * within database. 383 * 384 * This function shall be used only for qualification and tests in order to manually 385 * change database without modifying software. 386 **************************************************************************************** 387 */ 388 void attmdb_destroy(void); 389 390 /** 391 **************************************************************************************** 392 * @brief Initialize Attribute Database (clear it) 393 * 394 * @param[in] init_type Type of initialization (@see enum rwip_init_type) 395 **************************************************************************************** 396 */ 397 void attm_init(uint8_t init_type); 398 #endif // (BLE_ATTS) 399 400 #endif // #if (BLE_CENTRAL || BLE_PERIPHERAL) 401 402 #endif // _HAL_ATTM_H 403