1 /*
2 * Copyright (c) 2022 Nordic Semiconductor ASA
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/printk.h>
9
10 #include <zephyr/bluetooth/bluetooth.h>
11 #include <zephyr/bluetooth/conn.h>
12 #include <zephyr/bluetooth/gatt.h>
13 #include <zephyr/bluetooth/hci.h>
14
15 extern int mtu_exchange(struct bt_conn *conn);
16 extern int write_cmd(struct bt_conn *conn);
17 extern struct bt_conn *conn_connected;
18 extern uint32_t last_write_rate;
19 extern void (*start_scan_func)(void);
20
device_found(const bt_addr_le_t * addr,int8_t rssi,uint8_t type,struct net_buf_simple * ad)21 static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
22 struct net_buf_simple *ad)
23 {
24 char dev[BT_ADDR_LE_STR_LEN];
25 struct bt_conn *conn;
26 int err;
27
28 bt_addr_le_to_str(addr, dev, sizeof(dev));
29 printk("[DEVICE]: %s, AD evt type %u, AD data len %u, RSSI %i\n",
30 dev, type, ad->len, rssi);
31
32 /* We're only interested in connectable events */
33 if (type != BT_GAP_ADV_TYPE_ADV_IND &&
34 type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
35 return;
36 }
37
38 /* connect only to devices in close proximity */
39 if (rssi < -50) {
40 return;
41 }
42
43 err = bt_le_scan_stop();
44 if (err) {
45 printk("%s: Stop LE scan failed (err %d)\n", __func__, err);
46 return;
47 }
48
49 err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
50 BT_LE_CONN_PARAM_DEFAULT, &conn);
51 if (err) {
52 printk("%s: Create conn failed (err %d)\n", __func__, err);
53 start_scan_func();
54 } else {
55 bt_conn_unref(conn);
56 }
57 }
58
start_scan(void)59 static void start_scan(void)
60 {
61 int err;
62
63 err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
64 if (err) {
65 printk("%s: Scanning failed to start (err %d)\n", __func__,
66 err);
67 return;
68 }
69
70 printk("%s: Scanning successfully started\n", __func__);
71 }
72
mtu_updated(struct bt_conn * conn,uint16_t tx,uint16_t rx)73 void mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
74 {
75 printk("Updated MTU: TX: %d RX: %d bytes\n", tx, rx);
76 }
77
78 static struct bt_gatt_cb gatt_callbacks = {
79 .att_mtu_updated = mtu_updated
80 };
81
central_gatt_write(uint32_t count)82 uint32_t central_gatt_write(uint32_t count)
83 {
84 int err;
85
86 err = bt_enable(NULL);
87 if (err) {
88 printk("Bluetooth init failed (err %d)\n", err);
89 return 0U;
90 }
91 printk("Bluetooth initialized\n");
92
93 bt_gatt_cb_register(&gatt_callbacks);
94
95 conn_connected = NULL;
96 last_write_rate = 0U;
97
98 start_scan_func = start_scan;
99 start_scan_func();
100
101 while (true) {
102 struct bt_conn *conn = NULL;
103
104 if (conn_connected) {
105 /* Get a connection reference to ensure that a
106 * reference is maintained in case disconnected
107 * callback is called while we perform GATT Write
108 * command.
109 */
110 conn = bt_conn_ref(conn_connected);
111 }
112
113 if (conn) {
114 (void)write_cmd(conn);
115 bt_conn_unref(conn);
116
117 if (count) {
118 count--;
119 if (!count) {
120 break;
121 }
122 }
123
124 k_yield();
125 } else {
126 k_sleep(K_SECONDS(1));
127 }
128 }
129
130 return last_write_rate;
131 }
132