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 #if defined(CONFIG_BT_USER_PHY_UPDATE)
71 	err = bt_conn_le_set_default_phy(BT_GAP_LE_PHY_1M, BT_GAP_LE_PHY_1M);
72 	if (err) {
73 		printk("Failed to set default PHY (err %d)\n", err);
74 		return 0U;
75 	}
76 #endif /* CONFIG_BT_USER_PHY_UPDATE */
77 
78 	err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
79 	if (err) {
80 		printk("Advertising failed to start (err %d)\n", err);
81 		return 0U;
82 	}
83 
84 	printk("Advertising successfully started\n");
85 
86 	conn_connected = NULL;
87 	last_write_rate = 0U;
88 
89 	while (true) {
90 		struct bt_conn *conn = NULL;
91 
92 		if (conn_connected) {
93 			/* Get a connection reference to ensure that a
94 			 * reference is maintained in case disconnected
95 			 * callback is called while we perform GATT Write
96 			 * command.
97 			 */
98 			conn = bt_conn_ref(conn_connected);
99 		}
100 
101 		if (conn) {
102 			write_cmd(conn);
103 			bt_conn_unref(conn);
104 
105 			if (count) {
106 				count--;
107 				if (!count) {
108 					break;
109 				}
110 			}
111 
112 			k_yield();
113 		} else {
114 			k_sleep(K_SECONDS(1));
115 		}
116 	}
117 
118 	return last_write_rate;
119 }
120