gatt_sr_hash.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. #include "common/bt_target.h"
  2. #include "osi/allocator.h"
  3. #include <string.h>
  4. #include "gatt_int.h"
  5. #include "stack/l2c_api.h"
  6. #include "l2c_int.h"
  7. #include "smp_int.h"
  8. #if (BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE)
  9. const char *const gatt_attr_name[] = {
  10. "primary service",
  11. "secondary service",
  12. "included service",
  13. "characteristic",
  14. };
  15. const char *const gatt_char_desc_name[] = {
  16. "characteristic extended properties",
  17. "characteristic user description",
  18. "client characteristic configuration",
  19. "server characteristic configuration",
  20. "characteristic presentation format",
  21. "characteristic aggregate format",
  22. };
  23. static const char *gatt_get_attr_name(UINT16 uuid)
  24. {
  25. if (uuid >= GATT_UUID_PRI_SERVICE && uuid <= GATT_UUID_CHAR_DECLARE) {
  26. return gatt_attr_name[uuid - GATT_UUID_PRI_SERVICE];
  27. }
  28. if (uuid >= GATT_UUID_CHAR_EXT_PROP && uuid <= GATT_UUID_CHAR_AGG_FORMAT) {
  29. return gatt_char_desc_name[uuid - GATT_UUID_CHAR_EXT_PROP];
  30. }
  31. return "Unknown Attribute";
  32. }
  33. static void attr_uuid_to_bt_uuid(void *p_attr, tBT_UUID *p_uuid)
  34. {
  35. tGATT_ATTR16 *p_attr16 = (tGATT_ATTR16 *)p_attr;
  36. if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_16) {
  37. p_uuid->len = LEN_UUID_16;
  38. p_uuid->uu.uuid16 = p_attr16->uuid;
  39. } else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_32) {
  40. tGATT_ATTR32 *p_attr32 = (tGATT_ATTR32 *)p_attr;
  41. p_uuid->len = LEN_UUID_32;
  42. p_uuid->uu.uuid32 = p_attr32->uuid;
  43. } else if (p_attr16->uuid_type == GATT_ATTR_UUID_TYPE_128) {
  44. tGATT_ATTR128 *p_attr128 = (tGATT_ATTR128 *)p_attr;
  45. p_uuid->len = LEN_UUID_128;
  46. memcpy(p_uuid->uu.uuid128, p_attr128->uuid, LEN_UUID_128);
  47. }
  48. }
  49. static size_t calculate_database_info_size(void)
  50. {
  51. UINT8 i;
  52. tGATT_SVC_DB *p_db;
  53. tGATT_ATTR16 *p_attr;
  54. size_t len = 0;
  55. for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
  56. p_db = gatt_cb.sr_reg[i].p_db;
  57. if (p_db && p_db->p_attr_list) {
  58. p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
  59. while (p_attr) {
  60. if (p_attr->uuid == GATT_UUID_PRI_SERVICE ||
  61. p_attr->uuid == GATT_UUID_SEC_SERVICE) {
  62. // Service declaration
  63. len += 4 + p_attr->p_value->uuid.len;
  64. } else if (p_attr->uuid == GATT_UUID_INCLUDE_SERVICE) {
  65. // Included service declaration
  66. len += 8 + p_attr->p_value->incl_handle.service_type.len;
  67. } else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) {
  68. tBT_UUID char_uuid = {0};
  69. // Characteristic declaration
  70. p_attr = (tGATT_ATTR16 *)p_attr->p_next;
  71. attr_uuid_to_bt_uuid((void *)p_attr, &char_uuid);
  72. // Increment 1 to fetch characteristic uuid from value declaration attribute
  73. len += 7 + char_uuid.len;
  74. } else if (p_attr->uuid == GATT_UUID_CHAR_DESCRIPTION ||
  75. p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG ||
  76. p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG ||
  77. p_attr->uuid == GATT_UUID_CHAR_PRESENT_FORMAT ||
  78. p_attr->uuid == GATT_UUID_CHAR_AGG_FORMAT) {
  79. // Descriptor
  80. len += 4;
  81. } else if (p_attr->uuid == GATT_UUID_CHAR_EXT_PROP) {
  82. // Descriptor
  83. len += 6;
  84. }
  85. p_attr = (tGATT_ATTR16 *) p_attr->p_next;
  86. }
  87. }
  88. }
  89. return len;
  90. }
  91. static void fill_database_info(UINT8 *p_data)
  92. {
  93. UINT8 i;
  94. tGATT_SVC_DB *p_db;
  95. tGATT_ATTR16 *p_attr;
  96. for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
  97. p_db = gatt_cb.sr_reg[i].p_db;
  98. if (p_db && p_db->p_attr_list) {
  99. p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
  100. while (p_attr) {
  101. if (p_attr->uuid == GATT_UUID_PRI_SERVICE ||
  102. p_attr->uuid == GATT_UUID_SEC_SERVICE) {
  103. // Service declaration
  104. UINT16_TO_STREAM(p_data, p_attr->handle);
  105. UINT16_TO_STREAM(p_data, p_attr->uuid);
  106. gatt_build_uuid_to_stream(&p_data, p_attr->p_value->uuid);
  107. } else if (p_attr->uuid == GATT_UUID_INCLUDE_SERVICE) {
  108. // Included service declaration
  109. UINT16_TO_STREAM(p_data, p_attr->handle);
  110. UINT16_TO_STREAM(p_data, GATT_UUID_INCLUDE_SERVICE);
  111. UINT16_TO_STREAM(p_data, p_attr->p_value->incl_handle.s_handle);
  112. UINT16_TO_STREAM(p_data, p_attr->p_value->incl_handle.e_handle);
  113. gatt_build_uuid_to_stream(&p_data, p_attr->p_value->incl_handle.service_type);
  114. } else if (p_attr->uuid == GATT_UUID_CHAR_DECLARE) {
  115. tBT_UUID char_uuid = {0};
  116. // Characteristic declaration
  117. UINT16_TO_STREAM(p_data, p_attr->handle);
  118. UINT16_TO_STREAM(p_data, GATT_UUID_CHAR_DECLARE);
  119. UINT8_TO_STREAM(p_data, p_attr->p_value->char_decl.property);
  120. UINT16_TO_STREAM(p_data, p_attr->p_value->char_decl.char_val_handle);
  121. p_attr = (tGATT_ATTR16 *)p_attr->p_next;
  122. attr_uuid_to_bt_uuid((void *)p_attr, &char_uuid);
  123. // Increment 1 to fetch characteristic uuid from value declaration attribute
  124. gatt_build_uuid_to_stream(&p_data, char_uuid);
  125. } else if (p_attr->uuid == GATT_UUID_CHAR_DESCRIPTION ||
  126. p_attr->uuid == GATT_UUID_CHAR_CLIENT_CONFIG ||
  127. p_attr->uuid == GATT_UUID_CHAR_SRVR_CONFIG ||
  128. p_attr->uuid == GATT_UUID_CHAR_PRESENT_FORMAT ||
  129. p_attr->uuid == GATT_UUID_CHAR_AGG_FORMAT) {
  130. // Descriptor
  131. UINT16_TO_STREAM(p_data, p_attr->handle);
  132. UINT16_TO_STREAM(p_data, p_attr->uuid);
  133. } else if (p_attr->uuid == GATT_UUID_CHAR_EXT_PROP) {
  134. // Descriptor
  135. UINT16_TO_STREAM(p_data, p_attr->handle);
  136. UINT16_TO_STREAM(p_data, p_attr->uuid);
  137. // TODO: process extended properties descriptor
  138. if (p_attr->p_value->attr_val.attr_len == 2) {
  139. memcpy(p_data, p_attr->p_value->attr_val.attr_val, 2);
  140. } else {
  141. UINT16_TO_STREAM(p_data, 0x0000);
  142. }
  143. }
  144. p_attr = (tGATT_ATTR16 *) p_attr->p_next;
  145. }
  146. }
  147. }
  148. }
  149. tGATT_STATUS gatts_calculate_datebase_hash(BT_OCTET16 hash)
  150. {
  151. UINT8 tmp;
  152. UINT16 i;
  153. UINT16 j;
  154. size_t len;
  155. UINT8 *data_buf = NULL;
  156. len = calculate_database_info_size();
  157. data_buf = (UINT8 *)osi_malloc(len);
  158. if (data_buf == NULL) {
  159. GATT_TRACE_ERROR ("%s failed to allocate buffer (%u)\n", __func__, len);
  160. return GATT_NO_RESOURCES;
  161. }
  162. fill_database_info(data_buf);
  163. // reverse database info
  164. for (i = 0, j = len-1; i < j; i++, j--) {
  165. tmp = data_buf[i];
  166. data_buf[i] = data_buf[j];
  167. data_buf[j] = tmp;
  168. }
  169. #if SMP_INCLUDED == TRUE
  170. BT_OCTET16 key = {0};
  171. aes_cipher_msg_auth_code(key, data_buf, len, 16, hash);
  172. //ESP_LOG_BUFFER_HEX("db hash", hash, BT_OCTET16_LEN);
  173. #endif
  174. osi_free(data_buf);
  175. return GATT_SUCCESS;
  176. }
  177. void gatts_show_local_database(void)
  178. {
  179. UINT8 i;
  180. tGATT_SVC_DB *p_db;
  181. tGATT_ATTR16 *p_attr;
  182. printf("\n================= GATTS DATABASE DUMP START =================\n");
  183. for (i = 0; i < GATT_MAX_SR_PROFILES; i++) {
  184. p_db = gatt_cb.sr_reg[i].p_db;
  185. if (p_db && p_db->p_attr_list) {
  186. p_attr = (tGATT_ATTR16 *)p_db->p_attr_list;
  187. while (p_attr) {
  188. switch (p_attr->uuid) {
  189. case GATT_UUID_PRI_SERVICE:
  190. case GATT_UUID_SEC_SERVICE:
  191. // Service declaration
  192. printf("%s\n", gatt_get_attr_name(p_attr->uuid));
  193. printf("\tuuid %s\n", gatt_uuid_to_str(&p_attr->p_value->uuid));
  194. printf("\thandle %d\n", p_attr->handle);
  195. printf("\tend_handle %d\n",p_db->end_handle-1);
  196. break;
  197. case GATT_UUID_INCLUDE_SERVICE:
  198. // Included service declaration
  199. printf("%s\n", gatt_get_attr_name(p_attr->uuid));
  200. printf("\tuuid %s\t", gatt_uuid_to_str(&p_attr->p_value->incl_handle.service_type));
  201. printf("\thandle %d\n", p_attr->p_value->incl_handle.s_handle);
  202. printf("\tend_handle %d\n", p_attr->p_value->incl_handle.e_handle);
  203. break;
  204. case GATT_UUID_CHAR_DECLARE: {
  205. tBT_UUID char_uuid = {0};
  206. tGATT_ATTR16 *p_char_val;
  207. p_char_val = (tGATT_ATTR16 *)p_attr->p_next;
  208. attr_uuid_to_bt_uuid((void *)p_char_val, &char_uuid);
  209. printf("%s\n", gatt_get_attr_name(p_attr->uuid));
  210. printf("\tuuid %s\n", gatt_uuid_to_str(&char_uuid));
  211. printf("\tdef_handle %d\n", p_attr->handle);
  212. printf("\tval_handle %d\n", p_attr->p_value->char_decl.char_val_handle);
  213. printf("\tperm 0x%04x, prop 0x%02x\n", p_char_val->permission, p_attr->p_value->char_decl.property);
  214. break;
  215. }
  216. case GATT_UUID_CHAR_EXT_PROP:
  217. case GATT_UUID_CHAR_DESCRIPTION:
  218. case GATT_UUID_CHAR_CLIENT_CONFIG:
  219. case GATT_UUID_CHAR_SRVR_CONFIG:
  220. case GATT_UUID_CHAR_PRESENT_FORMAT:
  221. case GATT_UUID_CHAR_AGG_FORMAT:
  222. printf("%s\n", gatt_get_attr_name(p_attr->uuid));
  223. printf("\thandle %d\n", p_attr->handle);
  224. break;
  225. }
  226. p_attr = (tGATT_ATTR16 *) p_attr->p_next;
  227. }
  228. }
  229. }
  230. printf("================= GATTS DATABASE DUMP END =================\n");
  231. }
  232. #endif /* BLE_INCLUDED == TRUE && GATTS_INCLUDED == TRUE */