1 /*
2  * Copyright 2023 NXP
3  * Copyright (c) 2024 Nordic Semiconductor ASA
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #include <stddef.h>
9 #include <stdint.h>
10 
11 #include <zephyr/autoconf.h>
12 #include <zephyr/bluetooth/addr.h>
13 #include <zephyr/bluetooth/audio/audio.h>
14 #include <zephyr/bluetooth/audio/bap.h>
15 #include <zephyr/bluetooth/audio/bap_lc3_preset.h>
16 #include <zephyr/bluetooth/audio/csip.h>
17 #include <zephyr/bluetooth/audio/tmap.h>
18 #include <zephyr/bluetooth/audio/cap.h>
19 #include <zephyr/bluetooth/audio/mcs.h>
20 #include <zephyr/bluetooth/bluetooth.h>
21 #include <zephyr/bluetooth/byteorder.h>
22 #include <zephyr/bluetooth/conn.h>
23 #include <zephyr/bluetooth/gap.h>
24 #include <zephyr/bluetooth/hci.h>
25 #include <zephyr/bluetooth/uuid.h>
26 #include <zephyr/kernel.h>
27 #include <zephyr/sys/byteorder.h>
28 #include <zephyr/sys/printk.h>
29 #include <zephyr/sys/util.h>
30 #include <zephyr/sys/util_macro.h>
31 #include <zephyr/types.h>
32 
33 #include "tmap_peripheral.h"
34 
35 static struct bt_conn *default_conn;
36 static struct k_work_delayable call_terminate_set_work;
37 static struct k_work_delayable media_pause_set_work;
38 
39 static uint8_t unicast_server_addata[] = {
40 	BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),    /* ASCS UUID */
41 	BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED, /* Target Announcement */
42 	BT_BYTES_LIST_LE16(AVAILABLE_SINK_CONTEXT),
43 	BT_BYTES_LIST_LE16(AVAILABLE_SOURCE_CONTEXT),
44 	0x00, /* Metadata length */
45 };
46 
47 static const uint8_t cap_addata[] = {
48 	BT_UUID_16_ENCODE(BT_UUID_CAS_VAL),
49 	BT_AUDIO_UNICAST_ANNOUNCEMENT_TARGETED,
50 };
51 
52 static uint8_t tmap_addata[] = {
53 	BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL),                    /* TMAS UUID */
54 	BT_BYTES_LIST_LE16(BT_TMAP_ROLE_UMR | BT_TMAP_ROLE_CT), /* TMAP Role */
55 };
56 
57 static uint8_t csis_rsi_addata[BT_CSIP_RSI_SIZE];
58 static bool peer_is_cg;
59 static bool peer_is_ums;
60 
61 static const struct bt_data ad[] = {
62 	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
63 	BT_DATA_BYTES(BT_DATA_GAP_APPEARANCE,
64 		      BT_BYTES_LIST_LE16(BT_APPEARANCE_WEARABLE_AUDIO_DEVICE_EARBUD)),
65 	BT_DATA_BYTES(BT_DATA_UUID16_SOME, BT_UUID_16_ENCODE(BT_UUID_ASCS_VAL),
66 		      BT_UUID_16_ENCODE(BT_UUID_CAS_VAL), BT_UUID_16_ENCODE(BT_UUID_TMAS_VAL)),
67 #if defined(CONFIG_BT_CSIP_SET_MEMBER)
68 	BT_DATA(BT_DATA_CSIS_RSI, csis_rsi_addata, ARRAY_SIZE(csis_rsi_addata)),
69 #endif /* CONFIG_BT_CSIP_SET_MEMBER */
70 	BT_DATA(BT_DATA_SVC_DATA16, tmap_addata, ARRAY_SIZE(tmap_addata)),
71 	BT_DATA(BT_DATA_SVC_DATA16, cap_addata, ARRAY_SIZE(cap_addata)),
72 	BT_DATA(BT_DATA_SVC_DATA16, unicast_server_addata, ARRAY_SIZE(unicast_server_addata)),
73 	BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
74 };
75 
76 static K_SEM_DEFINE(sem_connected, 0, 1);
77 static K_SEM_DEFINE(sem_security_updated, 0, 1);
78 static K_SEM_DEFINE(sem_disconnected, 0, 1);
79 static K_SEM_DEFINE(sem_discovery_done, 0, 1);
80 
tmap_discovery_complete(enum bt_tmap_role peer_role,struct bt_conn * conn,int err)81 void tmap_discovery_complete(enum bt_tmap_role peer_role, struct bt_conn *conn, int err)
82 {
83 	if (conn != default_conn) {
84 		return;
85 	}
86 
87 	if (err) {
88 		printk("TMAS discovery failed! (err %d)\n", err);
89 		return;
90 	}
91 
92 	peer_is_cg = (peer_role & BT_TMAP_ROLE_CG) != 0;
93 	peer_is_ums = (peer_role & BT_TMAP_ROLE_UMS) != 0;
94 	printk("TMAP discovery done\n");
95 	k_sem_give(&sem_discovery_done);
96 }
97 
98 static struct bt_tmap_cb tmap_callbacks = {
99 	.discovery_complete = tmap_discovery_complete
100 };
101 
connected(struct bt_conn * conn,uint8_t err)102 static void connected(struct bt_conn *conn, uint8_t err)
103 {
104 	char addr[BT_ADDR_LE_STR_LEN];
105 
106 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
107 
108 	if (err != 0) {
109 		printk("Failed to connect to %s %u %s\n", addr, err, bt_hci_err_to_str(err));
110 
111 		default_conn = NULL;
112 		return;
113 	}
114 
115 	printk("Connected: %s\n", addr);
116 	default_conn = bt_conn_ref(conn);
117 	k_sem_give(&sem_connected);
118 }
119 
disconnected(struct bt_conn * conn,uint8_t reason)120 static void disconnected(struct bt_conn *conn, uint8_t reason)
121 {
122 	char addr[BT_ADDR_LE_STR_LEN];
123 
124 	if (conn != default_conn) {
125 		return;
126 	}
127 
128 	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
129 
130 	printk("Disconnected: %s, reason 0x%02x %s\n", addr, reason, bt_hci_err_to_str(reason));
131 
132 	bt_conn_unref(default_conn);
133 	default_conn = NULL;
134 
135 	k_sem_give(&sem_disconnected);
136 }
137 
security_changed(struct bt_conn * conn,bt_security_t level,enum bt_security_err err)138 static void security_changed(struct bt_conn *conn, bt_security_t level,
139 			     enum bt_security_err err)
140 {
141 	if (err == 0) {
142 		printk("Security changed: %u\n", err);
143 		k_sem_give(&sem_security_updated);
144 	} else {
145 		printk("Failed to set security level: %s(%u)", bt_security_err_to_str(err), err);
146 	}
147 }
148 
149 BT_CONN_CB_DEFINE(conn_callbacks) = {
150 	.connected = connected,
151 	.disconnected = disconnected,
152 	.security_changed = security_changed,
153 };
154 
155 #if defined(CONFIG_BT_PRIVACY) && defined(CONFIG_BT_CSIP_SET_MEMBER)
adv_rpa_expired_cb(struct bt_le_ext_adv * adv)156 static bool adv_rpa_expired_cb(struct bt_le_ext_adv *adv)
157 {
158 	char rsi_str[13];
159 	int err;
160 
161 	err = csip_generate_rsi(csis_rsi_addata);
162 	if (err != 0) {
163 		printk("Failed to generate RSI (err %d)\n", err);
164 		return false;
165 	}
166 
167 	snprintk(rsi_str, ARRAY_SIZE(rsi_str), "%02x%02x%02x%02x%02x%02x",
168 		 csis_rsi_addata[0], csis_rsi_addata[1], csis_rsi_addata[2],
169 		 csis_rsi_addata[3], csis_rsi_addata[4], csis_rsi_addata[5]);
170 
171 	printk("PRSI: 0x%s\n", rsi_str);
172 
173 	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
174 	if (err) {
175 		printk("Failed to set advertising data (err %d)\n", err);
176 		return false;
177 	}
178 
179 	return true;
180 }
181 #endif /* CONFIG_BT_PRIVACY && CONFIG_BT_CSIP_SET_MEMBER */
182 
183 static const struct bt_le_ext_adv_cb adv_cb = {
184 #if defined(CONFIG_BT_PRIVACY) && defined(CONFIG_BT_CSIP_SET_MEMBER)
185 	.rpa_expired = adv_rpa_expired_cb,
186 #endif /* CONFIG_BT_PRIVACY && CONFIG_BT_CSIP_SET_MEMBER */
187 };
188 
audio_timer_timeout(struct k_work * work)189 static void audio_timer_timeout(struct k_work *work)
190 {
191 	int err = ccp_terminate_call();
192 
193 	if (err != 0) {
194 		printk("Error sending call terminate command!\n");
195 	}
196 }
197 
media_play_timeout(struct k_work * work)198 static void media_play_timeout(struct k_work *work)
199 {
200 	int err = mcp_send_cmd(BT_MCS_OPC_PAUSE);
201 
202 	if (err != 0) {
203 		printk("Error sending pause command!\n");
204 	}
205 }
206 
main(void)207 int main(void)
208 {
209 	int err;
210 	struct bt_le_ext_adv *adv;
211 
212 	err = bt_enable(NULL);
213 	if (err != 0) {
214 		printk("Bluetooth init failed (err %d)\n", err);
215 		return err;
216 	}
217 
218 	printk("Bluetooth initialized\n");
219 
220 	k_work_init_delayable(&call_terminate_set_work, audio_timer_timeout);
221 	k_work_init_delayable(&media_pause_set_work, media_play_timeout);
222 
223 	printk("Initializing TMAP and setting role\n");
224 	err = bt_tmap_register(BT_TMAP_ROLE_CT | BT_TMAP_ROLE_UMR);
225 	if (err != 0) {
226 		return err;
227 	}
228 
229 	if (IS_ENABLED(CONFIG_TMAP_PERIPHERAL_DUO)) {
230 		err = csip_set_member_init();
231 		if (err != 0) {
232 			printk("CSIP Set Member init failed (err %d)\n", err);
233 			return err;
234 		}
235 
236 		err = csip_generate_rsi(csis_rsi_addata);
237 		if (err != 0) {
238 			printk("Failed to generate RSI (err %d)\n", err);
239 			return err;
240 		}
241 	}
242 
243 	err = vcp_vol_renderer_init();
244 	if (err != 0) {
245 		return err;
246 	}
247 	printk("VCP initialized\n");
248 
249 	err = bap_unicast_sr_init();
250 	if (err != 0) {
251 		return err;
252 	}
253 	printk("BAP initialized\n");
254 
255 	err = bt_le_ext_adv_create(BT_LE_EXT_ADV_CONN, &adv_cb, &adv);
256 	if (err) {
257 		printk("Failed to create advertising set (err %d)\n", err);
258 		return err;
259 	}
260 
261 	err = bt_le_ext_adv_set_data(adv, ad, ARRAY_SIZE(ad), NULL, 0);
262 	if (err) {
263 		printk("Failed to set advertising data (err %d)\n", err);
264 		return err;
265 	}
266 
267 	err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
268 	if (err) {
269 		printk("Failed to start advertising set (err %d)\n", err);
270 		return err;
271 	}
272 
273 	printk("Advertising successfully started\n");
274 	k_sem_take(&sem_connected, K_FOREVER);
275 	k_sem_take(&sem_security_updated, K_FOREVER);
276 
277 	err = bt_tmap_discover(default_conn, &tmap_callbacks);
278 	if (err != 0) {
279 		return err;
280 	}
281 	k_sem_take(&sem_discovery_done, K_FOREVER);
282 
283 	err = ccp_call_ctrl_init(default_conn);
284 	if (err != 0) {
285 		return err;
286 	}
287 	printk("CCP initialized\n");
288 
289 	err = mcp_ctlr_init(default_conn);
290 	if (err != 0) {
291 		return err;
292 	}
293 	printk("MCP initialized\n");
294 
295 	if (peer_is_cg) {
296 		/* Initiate a call with CCP */
297 		err = ccp_originate_call();
298 		if (err != 0) {
299 			printk("Error sending call originate command!\n");
300 		}
301 		/* Start timer to send terminate call command */
302 		k_work_schedule(&call_terminate_set_work, K_MSEC(2000));
303 	}
304 
305 	if (peer_is_ums) {
306 		/* Play media with MCP */
307 		err = mcp_send_cmd(BT_MCS_OPC_PLAY);
308 		if (err != 0) {
309 			printk("Error sending media play command!\n");
310 		}
311 
312 		/* Start timer to send media pause command */
313 		k_work_schedule(&media_pause_set_work, K_MSEC(2000));
314 
315 		err = k_sem_take(&sem_disconnected, K_FOREVER);
316 		if (err != 0) {
317 			printk("failed to take sem_disconnected (err %d)\n", err);
318 		}
319 	}
320 
321 	return 0;
322 }
323