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 
20 static const struct bt_data ad[] = {
21 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
22 };
23 
24 static const struct bt_data sd[] = {
25 	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
26 };
27 
mtu_updated(struct bt_conn * conn,uint16_t tx,uint16_t rx)28 static void mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
29 {
30 	printk("Updated MTU: TX: %d RX: %d bytes\n", tx, rx);
31 }
32 
33 #if defined(CONFIG_BT_SMP)
auth_cancel(struct bt_conn * conn)34 static void auth_cancel(struct bt_conn *conn)
35 {
36 	char addr[BT_ADDR_LE_STR_LEN];
37 
38 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
39 
40 	printk("Pairing cancelled: %s\n", addr);
41 }
42 
43 static struct bt_conn_auth_cb auth_callbacks = {
44 	.cancel = auth_cancel,
45 };
46 #endif /* CONFIG_BT_SMP */
47 
48 static struct bt_gatt_cb gatt_callbacks = {
49 	.att_mtu_updated = mtu_updated
50 };
51 
peripheral_gatt_write(uint32_t count)52 uint32_t peripheral_gatt_write(uint32_t count)
53 {
54 	int err;
55 
56 	err = bt_enable(NULL);
57 	if (err) {
58 		printk("Bluetooth init failed (err %d)\n", err);
59 		return 0U;
60 	}
61 
62 	printk("Bluetooth initialized\n");
63 
64 	bt_gatt_cb_register(&gatt_callbacks);
65 
66 #if defined(CONFIG_BT_SMP)
67 	(void)bt_conn_auth_cb_register(&auth_callbacks);
68 #endif /* CONFIG_BT_SMP */
69 
70 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
71 	if (err) {
72 		printk("Advertising failed to start (err %d)\n", err);
73 		return 0U;
74 	}
75 
76 	printk("Advertising successfully started\n");
77 
78 	conn_connected = NULL;
79 	last_write_rate = 0U;
80 
81 	while (true) {
82 		struct bt_conn *conn = NULL;
83 
84 		if (conn_connected) {
85 			/* Get a connection reference to ensure that a
86 			 * reference is maintained in case disconnected
87 			 * callback is called while we perform GATT Write
88 			 * command.
89 			 */
90 			conn = bt_conn_ref(conn_connected);
91 		}
92 
93 		if (conn) {
94 			write_cmd(conn);
95 			bt_conn_unref(conn);
96 
97 			if (count) {
98 				count--;
99 				if (!count) {
100 					break;
101 				}
102 			}
103 
104 			k_yield();
105 		} else {
106 			k_sleep(K_SECONDS(1));
107 		}
108 	}
109 
110 	return last_write_rate;
111 }
112