| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313 |
- /* main.c - Application main entry point */
- /*
- * Copyright (c) 2015-2016 Intel Corporation
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- #include <errno.h>
- #include <stddef.h>
- #include <string.h>
- #include "base/byteorder.h"
- #include "base/types.h"
- #include <bluetooth/bluetooth.h>
- #include <bluetooth/conn.h>
- #include <bluetooth/gatt.h>
- #include <bluetooth/hci.h>
- #include <bluetooth/uuid.h>
- #include <logging/bt_log_impl.h>
- static int scan_start(void);
- static struct bt_conn *default_conn;
- static struct bt_uuid_16 uuid = BT_UUID_INIT_16(0);
- static struct bt_gatt_discover_params discover_params;
- static struct bt_gatt_subscribe_params subscribe_params;
- static double pow_cal(double x, double y)
- {
- double result = 1;
- if (y < 0)
- {
- y = -y;
- while (y--)
- {
- result /= x;
- }
- }
- else
- {
- while (y--)
- {
- result *= x;
- }
- }
- return result;
- }
- static uint8_t notify_func(struct bt_conn *conn, struct bt_gatt_subscribe_params *params,
- const void *data, uint16_t length)
- {
- double temperature;
- uint32_t mantissa;
- int8_t exponent;
- if (!data)
- {
- printk("[UNSUBSCRIBED]\n");
- params->value_handle = 0U;
- return BT_GATT_ITER_STOP;
- }
- /* temperature value display */
- mantissa = sys_get_le24(&((uint8_t *)data)[1]);
- exponent = ((uint8_t *)data)[4];
- temperature = (double)mantissa * pow_cal(10, exponent);
- printf("Temperature %gC.\n", temperature);
- return BT_GATT_ITER_CONTINUE;
- }
- static uint8_t discover_func(struct bt_conn *conn, const struct bt_gatt_attr *attr,
- struct bt_gatt_discover_params *params)
- {
- int err;
- if (!attr)
- {
- printk("Discover complete\n");
- (void)memset(params, 0, sizeof(*params));
- return BT_GATT_ITER_STOP;
- }
- printk("[ATTRIBUTE] handle %u\n", attr->handle);
- if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_HTS))
- {
- memcpy(&uuid, BT_UUID_HTS_MEASUREMENT, sizeof(uuid));
- discover_params.uuid = &uuid.uuid;
- discover_params.start_handle = attr->handle + 1;
- discover_params.type = BT_GATT_DISCOVER_CHARACTERISTIC;
- err = bt_gatt_discover(conn, &discover_params);
- if (err)
- {
- printk("Discover failed (err %d)\n", err);
- }
- }
- else if (!bt_uuid_cmp(discover_params.uuid, BT_UUID_HTS_MEASUREMENT))
- {
- memcpy(&uuid, BT_UUID_GATT_CCC, sizeof(uuid));
- discover_params.uuid = &uuid.uuid;
- discover_params.start_handle = attr->handle + 2;
- discover_params.type = BT_GATT_DISCOVER_DESCRIPTOR;
- subscribe_params.value_handle = bt_gatt_attr_value_handle(attr);
- err = bt_gatt_discover(conn, &discover_params);
- if (err)
- {
- printk("Discover failed (err %d)\n", err);
- }
- }
- else
- {
- subscribe_params.notify = notify_func;
- subscribe_params.value = BT_GATT_CCC_INDICATE;
- subscribe_params.ccc_handle = attr->handle;
- err = bt_gatt_subscribe(conn, &subscribe_params);
- if (err && err != -EALREADY)
- {
- printk("Subscribe failed (err %d)\n", err);
- }
- else
- {
- printk("[SUBSCRIBED]\n");
- }
- return BT_GATT_ITER_STOP;
- }
- return BT_GATT_ITER_STOP;
- }
- static void connected(struct bt_conn *conn, uint8_t conn_err)
- {
- char addr[BT_ADDR_LE_STR_LEN];
- int err;
- bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
- if (conn_err)
- {
- printk("Failed to connect to %s (%u)\n", addr, conn_err);
- // bt_conn_unref(default_conn);
- default_conn = NULL;
- scan_start();
- return;
- }
- printk("Connected: %s\n", addr);
- if (conn == default_conn)
- {
- memcpy(&uuid, BT_UUID_HTS, sizeof(uuid));
- discover_params.uuid = &uuid.uuid;
- discover_params.func = discover_func;
- discover_params.start_handle = BT_ATT_FIRST_ATTRIBUTE_HANDLE;
- discover_params.end_handle = BT_ATT_LAST_ATTRIBUTE_HANDLE;
- discover_params.type = BT_GATT_DISCOVER_PRIMARY;
- err = bt_gatt_discover(default_conn, &discover_params);
- if (err)
- {
- printk("Discover failed(err %d)\n", err);
- return;
- }
- }
- }
- static bool eir_found(struct bt_data *data, void *user_data)
- {
- bt_addr_le_t *addr = user_data;
- int i;
- printk("[AD]: %u data_len %u\n", data->type, data->data_len);
- switch (data->type)
- {
- case BT_DATA_UUID16_SOME:
- case BT_DATA_UUID16_ALL:
- if (data->data_len % sizeof(uint16_t) != 0U)
- {
- printk("AD malformed\n");
- return true;
- }
- for (i = 0; i < data->data_len; i += sizeof(uint16_t))
- {
- struct bt_uuid *tmp_uuid;
- uint16_t u16;
- int err;
- memcpy(&u16, &data->data[i], sizeof(u16));
- tmp_uuid = BT_UUID_DECLARE_16(sys_le16_to_cpu(u16));
- if (bt_uuid_cmp(tmp_uuid, BT_UUID_HTS))
- {
- continue;
- }
- err = bt_le_scan_stop();
- if (err)
- {
- printk("Stop LE scan failed (err %d)\n", err);
- continue;
- }
- err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN, BT_LE_CONN_PARAM_DEFAULT,
- &default_conn);
- if (err)
- {
- printk("Create connection failed (err %d)\n", err);
- scan_start();
- }
- return false;
- }
- }
- return true;
- }
- static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
- struct net_buf_simple *ad)
- {
- char dev[BT_ADDR_LE_STR_LEN];
- bt_addr_le_to_str(addr, dev, sizeof(dev));
- printk("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n", dev, type, ad->len, rssi);
- /* We're only interested in connectable events */
- if (type == BT_HCI_ADV_IND || type == BT_HCI_ADV_DIRECT_IND)
- {
- bt_data_parse(ad, eir_found, (void *)addr);
- }
- }
- static int scan_start(void)
- {
- /* Use active scanning and disable duplicate filtering to handle any
- * devices that might update their advertising data at runtime.
- */
- struct bt_le_scan_param scan_param = {
- .type = BT_LE_SCAN_TYPE_ACTIVE,
- .options = BT_LE_SCAN_OPT_NONE,
- .interval = BT_GAP_SCAN_FAST_INTERVAL,
- .window = BT_GAP_SCAN_FAST_WINDOW,
- };
- return bt_le_scan_start(&scan_param, device_found);
- }
- static void disconnected(struct bt_conn *conn, uint8_t reason)
- {
- char addr[BT_ADDR_LE_STR_LEN];
- int err;
- bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
- printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);
- if (default_conn != conn)
- {
- return;
- }
- // bt_conn_unref(default_conn);
- default_conn = NULL;
- err = scan_start();
- if (err)
- {
- printk("Scanning failed to start (err %d)\n", err);
- }
- }
- static struct bt_conn_cb conn_callbacks = {
- .connected = connected,
- .disconnected = disconnected,
- };
- void bt_ready(int err)
- {
- if (err)
- {
- printk("Bluetooth init failed (err %d)\n", err);
- return;
- }
- printk("Bluetooth initialized\n");
- bt_conn_cb_register(&conn_callbacks);
- err = scan_start();
- if (err)
- {
- printk("Scanning failed to start (err %d)\n", err);
- return;
- }
- printk("Scanning successfully started\n");
- }
- void app_polling_work(void)
- {
- }
|