app_main.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. /* main.c - Application main entry point */
  2. /*
  3. * Copyright (c) 2015-2016 Intel Corporation
  4. *
  5. * SPDX-License-Identifier: Apache-2.0
  6. */
  7. #include <errno.h>
  8. #include <stddef.h>
  9. #include <string.h>
  10. #include "base/types.h"
  11. #include <bluetooth/bluetooth.h>
  12. #include <bluetooth/conn.h>
  13. #include <bluetooth/gatt.h>
  14. #include <bluetooth/hci.h>
  15. #include <bluetooth/uuid.h>
  16. #include <logging/bt_log_impl.h>
  17. static void start_scan(void);
  18. static struct bt_conn *default_conn;
  19. static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
  20. static struct bt_gatt_discover_params discover_params;
  21. static struct bt_gatt_subscribe_params subscribe_params;
  22. static uint8_t notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params,
  23. const void *data, uint16_t length)
  24. {
  25. if (!data)
  26. {
  27. printk("[UNSUBSCRIBED]\n");
  28. params->value_handle = 0U;
  29. return BT_GATT_ITER_STOP;
  30. }
  31. printk("[NOTIFICATION] data %p length %u\n", data, length);
  32. return BT_GATT_ITER_CONTINUE;
  33. }
  34. static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
  35. struct bt_gatt_discover_params *params)
  36. {
  37. int err;
  38. if (!attr)
  39. {
  40. printk("Discover complete\n");
  41. (void)memset(params, 0, sizeof(*params));
  42. return BT_GATT_ITER_STOP;
  43. }
  44. printk("[ATTRIBUTE] handle %u\n", attr->handle);
  45. if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_HRS))
  46. {
  47. memcpy(&uuid, BT_UUID_HRS_MEASUREMENT, sizeof(uuid));
  48. discover_params.uuid = &uuid.uuid;
  49. discover_params.start_handle = attr->handle + 1;
  50. discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
  51. err = bt_gatt_discover(conn, &discover_params);
  52. if (err)
  53. {
  54. printk("Discover failed (err %d)\n", err);
  55. }
  56. }
  57. else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_HRS_MEASUREMENT))
  58. {
  59. memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
  60. discover_params.uuid = &uuid.uuid;
  61. discover_params.start_handle = attr->handle + 2;
  62. discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
  63. subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
  64. err = bt_gatt_discover(conn, &discover_params);
  65. if (err)
  66. {
  67. printk("Discover failed (err %d)\n", err);
  68. }
  69. }
  70. else
  71. {
  72. subscribe_params.notify = notify_func;
  73. subscribe_params.value = BT_GATT_CCC_NOTIFY;
  74. subscribe_params.ccc_handle = attr->handle;
  75. err = bt_gatt_subscribe(conn, &subscribe_params);
  76. if (err && err != -EALREADY)
  77. {
  78. printk("Subscribe failed (err %d)\n", err);
  79. }
  80. else
  81. {
  82. printk("[SUBSCRIBED]\n");
  83. }
  84. return BT_GATT_ITER_STOP;
  85. }
  86. return BT_GATT_ITER_STOP;
  87. }
  88. static bool eir_found(struct bt_data *data, void *user_data)
  89. {
  90. bt_addr_le_t *addr = user_data;
  91. int i;
  92. printk("[AD]: %u data_len %u\n", data->type, data->data_len);
  93. switch (data->type)
  94. {
  95. case BT_DATA_UUID16_SOME:
  96. case BT_DATA_UUID16_ALL:
  97. if (data->data_len % sizeof(uint16_t) != 0U)
  98. {
  99. printk("AD malformed\n");
  100. return true;
  101. }
  102. for (i = 0; i < data->data_len; i += sizeof(uint16_t))
  103. {
  104. struct bt_le_conn_param *param;
  105. struct bt_uuid *tmp_uuid;
  106. uint16_t u16;
  107. int err;
  108. memcpy(&u16, &data->data[i], sizeof(u16));
  109. tmp_uuid = BT_UUID_DECLARE_16(u16);
  110. if (bt_uuid_cmp(tmp_uuid, BT_UUID_HRS))
  111. {
  112. continue;
  113. }
  114. err = bt_le_scan_stop();
  115. if (err)
  116. {
  117. printk("Stop LE scan failed (err %d)\n", err);
  118. continue;
  119. }
  120. param = BT_LE_CONN_PARAM_DEFAULT;
  121. err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, param, &default_conn);
  122. if (err)
  123. {
  124. printk("Create conn failed (err %d)\n", err);
  125. start_scan();
  126. }
  127. return false;
  128. }
  129. }
  130. return true;
  131. }
  132. static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
  133. struct net_buf_simple *ad)
  134. {
  135. char dev[BT_ADDR_LE_STR_LEN];
  136. bt_addr_le_to_str(addr, dev, sizeof(dev));
  137. printk("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n", dev, type, ad->len, rssi);
  138. /* We're only interested in connectable events */
  139. if (type == BT_GAP_ADV_TYPE_ADV_IND || type == BT_GAP_ADV_TYPE_ADV_DIRECT_IND)
  140. {
  141. bt_data_parse(ad, eir_found, (void *)addr);
  142. }
  143. }
  144. static void start_scan(void)
  145. {
  146. int err;
  147. /* Use active scanning and disable duplicate filtering to handle any
  148. * devices that might update their advertising data at runtime. */
  149. struct bt_le_scan_param scan_param = {
  150. .type = BT_LE_SCAN_TYPE_ACTIVE,
  151. .options = BT_LE_SCAN_OPT_NONE,
  152. .interval = BT_GAP_SCAN_FAST_INTERVAL,
  153. .window = BT_GAP_SCAN_FAST_WINDOW,
  154. };
  155. err = bt_le_scan_start(&scan_param, device_found);
  156. if (err)
  157. {
  158. printk("Scanning failed to start (err %d)\n", err);
  159. return;
  160. }
  161. printk("Scanning successfully started\n");
  162. }
  163. static void connected(struct bt_conn *conn, uint8_t conn_err)
  164. {
  165. char addr[BT_ADDR_LE_STR_LEN];
  166. int err;
  167. bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
  168. if (conn_err)
  169. {
  170. printk("Failed to connect to %s (%u)\n", addr, conn_err);
  171. // bt_conn_unref(default_conn);
  172. default_conn = NULL;
  173. start_scan();
  174. return;
  175. }
  176. printk("Connected: %s\n", addr);
  177. if (conn == default_conn)
  178. {
  179. memcpy(&uuid, BT_UUID_HRS, sizeof(uuid));
  180. discover_params.uuid = &uuid.uuid;
  181. discover_params.func = discover_func;
  182. discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
  183. discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
  184. discover_params.type = BT_GATT_DISCOVER_PRIMARY;
  185. err = bt_gatt_discover(default_conn, &discover_params);
  186. if (err)
  187. {
  188. printk("Discover failed(err %d)\n", err);
  189. return;
  190. }
  191. }
  192. }
  193. static void disconnected(struct bt_conn *conn, uint8_t reason)
  194. {
  195. char addr[BT_ADDR_LE_STR_LEN];
  196. bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
  197. printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
  198. if (default_conn != conn)
  199. {
  200. return;
  201. }
  202. // bt_conn_unref(default_conn);
  203. default_conn = NULL;
  204. start_scan();
  205. }
  206. static struct bt_conn_cb conn_callbacks = {
  207. .connected = connected,
  208. .disconnected = disconnected,
  209. };
  210. void bt_ready(int err)
  211. {
  212. if (err)
  213. {
  214. printk("Bluetooth init failed (err %d)\n", err);
  215. return;
  216. }
  217. printk("Bluetooth initialized\n");
  218. bt_conn_cb_register(&conn_callbacks);
  219. start_scan();
  220. }
  221. void app_polling_work(void)
  222. {
  223. }