gas.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. *
  4. * BlueZ - Bluetooth protocol stack for Linux
  5. *
  6. * Copyright (C) 2012 Instituto Nokia de Tecnologia - INdT
  7. * Copyright (C) 2014 Google Inc.
  8. *
  9. */
  10. #ifdef HAVE_CONFIG_H
  11. #include <config.h>
  12. #endif
  13. #define _GNU_SOURCE
  14. #include <ctype.h>
  15. #include <stdbool.h>
  16. #include <stdlib.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include <fcntl.h>
  20. #include <errno.h>
  21. #include <glib.h>
  22. #include "lib/bluetooth.h"
  23. #include "lib/hci.h"
  24. #include "lib/sdp.h"
  25. #include "lib/uuid.h"
  26. #include "src/shared/util.h"
  27. #include "src/shared/att.h"
  28. #include "src/shared/queue.h"
  29. #include "src/shared/gatt-db.h"
  30. #include "src/shared/gatt-client.h"
  31. #include "src/plugin.h"
  32. #include "src/adapter.h"
  33. #include "src/device.h"
  34. #include "src/profile.h"
  35. #include "src/service.h"
  36. #include "src/log.h"
  37. #define GAP_UUID16 0x1800
  38. /* Generic Attribute/Access Service */
  39. struct gas {
  40. struct btd_device *device;
  41. struct gatt_db *db;
  42. struct bt_gatt_client *client;
  43. struct gatt_db_attribute *attr;
  44. };
  45. static void gas_free(struct gas *gas)
  46. {
  47. gatt_db_unref(gas->db);
  48. bt_gatt_client_unref(gas->client);
  49. btd_device_unref(gas->device);
  50. g_free(gas);
  51. }
  52. static char *name2utf8(const uint8_t *name, uint16_t len)
  53. {
  54. char utf8_name[HCI_MAX_NAME_LENGTH + 2];
  55. int i;
  56. if (g_utf8_validate((const char *) name, len, NULL))
  57. return g_strndup((char *) name, len);
  58. len = MIN(len, sizeof(utf8_name) - 1);
  59. memset(utf8_name, 0, sizeof(utf8_name));
  60. strncpy(utf8_name, (char *) name, len);
  61. /* Assume ASCII, and replace all non-ASCII with spaces */
  62. for (i = 0; utf8_name[i] != '\0'; i++) {
  63. if (!isascii(utf8_name[i]))
  64. utf8_name[i] = ' ';
  65. }
  66. /* Remove leading and trailing whitespace characters */
  67. g_strstrip(utf8_name);
  68. return g_strdup(utf8_name);
  69. }
  70. static void read_device_name_cb(bool success, uint8_t att_ecode,
  71. const uint8_t *value, uint16_t length,
  72. void *user_data)
  73. {
  74. struct gas *gas = user_data;
  75. char *name;
  76. if (!success) {
  77. DBG("Reading device name failed with ATT errror: %u",
  78. att_ecode);
  79. return;
  80. }
  81. if (!length)
  82. return;
  83. name = name2utf8(value, length);
  84. DBG("GAP Device Name: %s", name);
  85. btd_device_device_set_name(gas->device, name);
  86. g_free(name);
  87. }
  88. static void handle_device_name(struct gas *gas, uint16_t value_handle)
  89. {
  90. if (!bt_gatt_client_read_long_value(gas->client, value_handle, 0,
  91. read_device_name_cb, gas, NULL))
  92. DBG("Failed to send request to read device name");
  93. }
  94. static void read_appearance_cb(bool success, uint8_t att_ecode,
  95. const uint8_t *value, uint16_t length,
  96. void *user_data)
  97. {
  98. struct gas *gas = user_data;
  99. uint16_t appearance;
  100. if (!success) {
  101. DBG("Reading appearance failed with ATT error: %u", att_ecode);
  102. return;
  103. }
  104. /* The appearance value is a 16-bit unsigned integer */
  105. if (length != 2) {
  106. DBG("Malformed appearance value");
  107. return;
  108. }
  109. appearance = get_le16(value);
  110. DBG("GAP Appearance: 0x%04x", appearance);
  111. device_set_appearance(gas->device, appearance);
  112. }
  113. static void handle_appearance(struct gas *gas, uint16_t value_handle)
  114. {
  115. if (!bt_gatt_client_read_value(gas->client, value_handle,
  116. read_appearance_cb, gas, NULL))
  117. DBG("Failed to send request to read appearance");
  118. }
  119. static bool uuid_cmp(uint16_t u16, const bt_uuid_t *uuid)
  120. {
  121. bt_uuid_t lhs;
  122. bt_uuid16_create(&lhs, u16);
  123. return bt_uuid_cmp(&lhs, uuid) == 0;
  124. }
  125. static void handle_characteristic(struct gatt_db_attribute *attr,
  126. void *user_data)
  127. {
  128. struct gas *gas = user_data;
  129. uint16_t value_handle;
  130. bt_uuid_t uuid;
  131. if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL,
  132. NULL, &uuid)) {
  133. error("Failed to obtain characteristic data");
  134. return;
  135. }
  136. if (uuid_cmp(GATT_CHARAC_DEVICE_NAME, &uuid))
  137. handle_device_name(gas, value_handle);
  138. else if (uuid_cmp(GATT_CHARAC_APPEARANCE, &uuid))
  139. handle_appearance(gas, value_handle);
  140. else {
  141. char uuid_str[MAX_LEN_UUID_STR];
  142. /* TODO: Support peripheral privacy feature */
  143. bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str));
  144. DBG("Unsupported characteristic: %s", uuid_str);
  145. }
  146. }
  147. static void handle_gap_service(struct gas *gas)
  148. {
  149. gatt_db_service_foreach_char(gas->attr, handle_characteristic, gas);
  150. }
  151. static int gap_probe(struct btd_service *service)
  152. {
  153. struct btd_device *device = btd_service_get_device(service);
  154. struct gas *gas = btd_service_get_user_data(service);
  155. char addr[18];
  156. ba2str(device_get_address(device), addr);
  157. DBG("GAP profile probe (%s)", addr);
  158. /* Ignore, if we were probed for this device already */
  159. if (gas) {
  160. error("Profile probed twice for the same device!");
  161. return -1;
  162. }
  163. gas = g_new0(struct gas, 1);
  164. if (!gas)
  165. return -1;
  166. gas->device = btd_device_ref(device);
  167. btd_service_set_user_data(service, gas);
  168. return 0;
  169. }
  170. static void gap_remove(struct btd_service *service)
  171. {
  172. struct btd_device *device = btd_service_get_device(service);
  173. struct gas *gas;
  174. char addr[18];
  175. ba2str(device_get_address(device), addr);
  176. DBG("GAP profile remove (%s)", addr);
  177. gas = btd_service_get_user_data(service);
  178. if (!gas) {
  179. error("GAP service not handled by profile");
  180. return;
  181. }
  182. gas_free(gas);
  183. }
  184. static void foreach_gap_service(struct gatt_db_attribute *attr, void *user_data)
  185. {
  186. struct gas *gas = user_data;
  187. if (gas->attr) {
  188. error("More than one GAP service exists for this device");
  189. return;
  190. }
  191. gas->attr = attr;
  192. handle_gap_service(gas);
  193. }
  194. static void gas_reset(struct gas *gas)
  195. {
  196. gas->attr = NULL;
  197. gatt_db_unref(gas->db);
  198. gas->db = NULL;
  199. bt_gatt_client_unref(gas->client);
  200. gas->client = NULL;
  201. }
  202. static int gap_accept(struct btd_service *service)
  203. {
  204. struct btd_device *device = btd_service_get_device(service);
  205. struct gatt_db *db = btd_device_get_gatt_db(device);
  206. struct bt_gatt_client *client = btd_device_get_gatt_client(device);
  207. struct gas *gas = btd_service_get_user_data(service);
  208. char addr[18];
  209. bt_uuid_t gap_uuid;
  210. ba2str(device_get_address(device), addr);
  211. DBG("GAP profile accept (%s)", addr);
  212. if (!gas) {
  213. error("GAP service not handled by profile");
  214. return -1;
  215. }
  216. gas->db = gatt_db_ref(db);
  217. gas->client = bt_gatt_client_clone(client);
  218. /* Handle the GAP services */
  219. bt_uuid16_create(&gap_uuid, GAP_UUID16);
  220. gatt_db_foreach_service(db, &gap_uuid, foreach_gap_service, gas);
  221. if (!gas->attr) {
  222. error("GAP attribute not found");
  223. gas_reset(gas);
  224. return -1;
  225. }
  226. btd_service_connecting_complete(service, 0);
  227. return 0;
  228. }
  229. static int gap_disconnect(struct btd_service *service)
  230. {
  231. struct gas *gas = btd_service_get_user_data(service);
  232. gas_reset(gas);
  233. btd_service_disconnecting_complete(service, 0);
  234. return 0;
  235. }
  236. static struct btd_profile gap_profile = {
  237. .name = "gap-profile",
  238. .remote_uuid = GAP_UUID,
  239. .device_probe = gap_probe,
  240. .device_remove = gap_remove,
  241. .accept = gap_accept,
  242. .disconnect = gap_disconnect,
  243. };
  244. static int gap_init(void)
  245. {
  246. return btd_profile_register(&gap_profile);
  247. }
  248. static void gap_exit(void)
  249. {
  250. btd_profile_unregister(&gap_profile);
  251. }
  252. BLUETOOTH_PLUGIN_DEFINE(gap, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
  253. gap_init, gap_exit)