1 /* cs.c - Bluetooth Channel Sounding handling */
2 
3 /*
4  * Copyright (c) 2024 Nordic Semiconductor ASA
5  *
6  * SPDX-License-Identifier: Apache-2.0
7  */
8 #include <errno.h>
9 #include <stdbool.h>
10 #include <stddef.h>
11 #include <stdint.h>
12 #include <string.h>
13 
14 #include <zephyr/autoconf.h>
15 #include <zephyr/bluetooth/conn.h>
16 #include <zephyr/bluetooth/cs.h>
17 #include <zephyr/bluetooth/hci.h>
18 #include <zephyr/bluetooth/hci_types.h>
19 #include <zephyr/kernel.h>
20 #include <zephyr/logging/log.h>
21 #include <zephyr/net_buf.h>
22 #include <zephyr/sys/byteorder.h>
23 #include <zephyr/sys/slist.h>
24 #include <zephyr/sys/util.h>
25 #include <zephyr/sys/util_macro.h>
26 
27 #include "conn_internal.h"
28 
29 #define LOG_LEVEL CONFIG_BT_HCI_CORE_LOG_LEVEL
30 LOG_MODULE_REGISTER(bt_cs);
31 
32 #if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST)
33 static struct bt_le_cs_test_cb cs_test_callbacks;
34 #endif
35 
36 #define A1 (0)
37 #define A2 (1)
38 #define A3 (2)
39 #define A4 (3)
40 
41 struct reassembly_buf_meta_data {
42 	uint16_t conn_handle;
43 };
44 
45 static void clear_on_disconnect(struct bt_conn *conn, uint8_t reason);
46 
47 NET_BUF_POOL_FIXED_DEFINE(reassembly_buf_pool, CONFIG_BT_CHANNEL_SOUNDING_REASSEMBLY_BUFFER_CNT,
48 			  CONFIG_BT_CHANNEL_SOUNDING_REASSEMBLY_BUFFER_SIZE,
49 			  sizeof(struct reassembly_buf_meta_data), NULL);
50 
51 static sys_slist_t reassembly_bufs = SYS_SLIST_STATIC_INIT(&reassembly_bufs);
52 
53 struct bt_conn_le_cs_subevent_result reassembled_result;
54 
55 BT_CONN_CB_DEFINE(cs_conn_callbacks) = {
56 	.disconnected = clear_on_disconnect,
57 };
58 
59 /** @brief Allocates new reassembly buffer identified by the connection handle
60  *
61  * @param conn_handle Connection handle
62  * @return struct net_buf* Reassembly buffer, NULL if allocation fails
63  */
alloc_reassembly_buf(uint16_t conn_handle)64 static struct net_buf *alloc_reassembly_buf(uint16_t conn_handle)
65 {
66 	struct net_buf *buf = net_buf_alloc(&reassembly_buf_pool, K_NO_WAIT);
67 
68 	if (!buf) {
69 		LOG_ERR("Failed to allocate new reassembly buffer");
70 		return NULL;
71 	}
72 
73 	struct reassembly_buf_meta_data *buf_meta_data =
74 		(struct reassembly_buf_meta_data *)buf->user_data;
75 
76 	buf_meta_data->conn_handle = conn_handle;
77 	net_buf_slist_put(&reassembly_bufs, buf);
78 
79 	LOG_DBG("Allocated new reassembly buffer for conn handle %d", conn_handle);
80 	return buf;
81 }
82 
83 /** @brief Frees a reassembly buffer
84  *
85  * @note Takes the ownership of the pointer and sets it to NULL
86  *
87  * @param buf Double pointer to reassembly buffer
88  */
free_reassembly_buf(struct net_buf ** buf)89 static void free_reassembly_buf(struct net_buf **buf)
90 {
91 	if (!buf) {
92 		LOG_ERR("NULL double pointer was passed when attempting to free reassembly buffer");
93 		return;
94 	}
95 
96 	if (!(*buf)) {
97 		LOG_WRN("Attempted double free on reassembly buffer");
98 		return;
99 	}
100 
101 	struct reassembly_buf_meta_data *buf_meta_data =
102 		(struct reassembly_buf_meta_data *)((*buf)->user_data);
103 
104 	LOG_DBG("De-allocating reassembly buffer for conn handle %d", buf_meta_data->conn_handle);
105 	if (!sys_slist_find_and_remove(&reassembly_bufs, &(*buf)->node)) {
106 		LOG_WRN("The buffer was not in the list");
107 	}
108 
109 	net_buf_unref(*buf);
110 	*buf = NULL;
111 }
112 
113 /** @brief Gets the reassembly buffer identified by the connection handle
114  *
115  * @param conn_handle Connection handle
116  * @param allocate Allocates a new reassembly buffer if it's not allocated already
117  * @return struct net_buf* Reassembly buffer, NULL if it doesn't exist or failed when allocating new
118  */
get_reassembly_buf(uint16_t conn_handle,bool allocate)119 static struct net_buf *get_reassembly_buf(uint16_t conn_handle, bool allocate)
120 {
121 	sys_snode_t *node;
122 
123 	SYS_SLIST_FOR_EACH_NODE(&reassembly_bufs, node) {
124 		struct net_buf *buf = CONTAINER_OF(node, struct net_buf, node);
125 		struct reassembly_buf_meta_data *buf_meta_data =
126 			(struct reassembly_buf_meta_data *)(buf->user_data);
127 
128 		if (buf_meta_data->conn_handle == conn_handle) {
129 			return buf;
130 		}
131 	}
132 
133 	return allocate ? alloc_reassembly_buf(conn_handle) : NULL;
134 }
135 
136 /** @brief Adds step data to a reassembly buffer
137  *
138  * @param reassembly_buf Reassembly buffer
139  * @param data Step data
140  * @param data_len Step data length
141  * @return true if successful, false if there is insufficient space
142  */
add_reassembly_data(struct net_buf * reassembly_buf,const uint8_t * data,uint16_t data_len)143 static bool add_reassembly_data(struct net_buf *reassembly_buf, const uint8_t *data,
144 				uint16_t data_len)
145 {
146 	if (data_len > net_buf_tailroom(reassembly_buf)) {
147 		LOG_ERR("Not enough reassembly buffer space for subevent result");
148 		return false;
149 	}
150 
151 	net_buf_add_mem(reassembly_buf, data, data_len);
152 	return true;
153 }
154 
155 /** @brief Initializes a reassembly buffer from partial step data
156  *
157  * @note Upon first call, this function also registers the disconnection callback
158  *       to ensure any dangling reassembly buffer is freed
159  *
160  * @param conn_handle Connection handle
161  * @param steps Step data
162  * @param step_data_len Step data length
163  * @return struct net_buf* Pointer to reassembly buffer, NULL if fails to allocate or insert data
164  */
start_reassembly(uint16_t conn_handle,const uint8_t * steps,uint16_t step_data_len)165 static struct net_buf *start_reassembly(uint16_t conn_handle, const uint8_t *steps,
166 					uint16_t step_data_len)
167 {
168 	struct net_buf *reassembly_buf = get_reassembly_buf(conn_handle, true);
169 
170 	if (!reassembly_buf) {
171 		LOG_ERR("No buffer allocated for the result reassembly");
172 		return NULL;
173 	}
174 
175 	if (reassembly_buf->len) {
176 		LOG_WRN("Over-written incomplete CS subevent results");
177 	}
178 
179 	net_buf_reset(reassembly_buf);
180 
181 	bool success = add_reassembly_data(reassembly_buf, steps, step_data_len);
182 
183 	return success ? reassembly_buf : NULL;
184 }
185 
186 /** @brief Adds more step data to reassembly buffer identified by the connection handle
187  *
188  * @param conn_handle Connection handle
189  * @param steps Step data
190  * @param step_data_len Step data length
191  * @return struct net_buf* Pointer to reassembly buffer, NULL if fails to insert data
192  */
continue_reassembly(uint16_t conn_handle,const uint8_t * steps,uint16_t step_data_len)193 static struct net_buf *continue_reassembly(uint16_t conn_handle, const uint8_t *steps,
194 					   uint16_t step_data_len)
195 {
196 	struct net_buf *reassembly_buf = get_reassembly_buf(conn_handle, false);
197 
198 	if (!reassembly_buf) {
199 		LOG_ERR("No reassembly buffer was allocated for this CS procedure, possibly due to "
200 			"an out-of-order subevent result continue event");
201 		return NULL;
202 	}
203 
204 	if (!reassembly_buf->len) {
205 		LOG_WRN("Discarded out-of-order partial CS subevent results");
206 		return NULL;
207 	}
208 
209 	if (!step_data_len) {
210 		return reassembly_buf;
211 	}
212 
213 	bool success = add_reassembly_data(reassembly_buf, steps, step_data_len);
214 
215 	return success ? reassembly_buf : NULL;
216 }
217 
218 /**
219  * @brief Disconnect callback to clear any dangling reassembly buffer
220  *
221  * @param conn Connection
222  * @param reason Reason
223  */
clear_on_disconnect(struct bt_conn * conn,uint8_t reason)224 static void clear_on_disconnect(struct bt_conn *conn, uint8_t reason)
225 {
226 	struct net_buf *buf = get_reassembly_buf(conn->handle, false);
227 
228 	if (buf) {
229 		free_reassembly_buf(&buf);
230 	}
231 }
232 
233 /** @brief Invokes user callback for new subevent results
234  *
235  * @param conn Connection context, NULL for CS Test subevent results
236  * @param p_result Pointer to subevent results
237  */
invoke_subevent_result_callback(struct bt_conn * conn,struct bt_conn_le_cs_subevent_result * p_result)238 static void invoke_subevent_result_callback(struct bt_conn *conn,
239 					    struct bt_conn_le_cs_subevent_result *p_result)
240 {
241 #if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST)
242 	if (!conn) {
243 		cs_test_callbacks.le_cs_test_subevent_data_available(p_result);
244 	} else
245 #endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */
246 	{
247 		notify_cs_subevent_result(conn, p_result);
248 	}
249 }
250 
251 /** @brief Resets reassembly results
252  *
253  */
reset_reassembly_results(void)254 static void reset_reassembly_results(void)
255 {
256 	memset(&reassembled_result, 0, sizeof(struct bt_conn_le_cs_subevent_result));
257 }
258 
259 /** @brief Converts PCT to a pair of int16_t
260  *
261  */
bt_le_cs_parse_pct(const uint8_t pct[3])262 struct bt_le_cs_iq_sample bt_le_cs_parse_pct(const uint8_t pct[3])
263 {
264 	uint32_t pct_u32 = sys_get_le24(pct);
265 
266 	/* Extract I and Q. */
267 	uint16_t i_u16 = pct_u32 & BT_HCI_LE_CS_PCT_I_MASK;
268 	uint16_t q_u16 = (pct_u32 & BT_HCI_LE_CS_PCT_Q_MASK) >> 12;
269 
270 	/* Convert from 12-bit 2's complement to int16_t */
271 	int16_t i = (i_u16 ^ BIT(11)) - BIT(11);
272 	int16_t q = (q_u16 ^ BIT(11)) - BIT(11);
273 
274 	return (struct bt_le_cs_iq_sample){.i = i, .q = q};
275 }
276 
bt_le_cs_set_valid_chmap_bits(uint8_t channel_map[10])277 void bt_le_cs_set_valid_chmap_bits(uint8_t channel_map[10])
278 {
279 	memset(channel_map, 0xFF, 10);
280 
281 	/** Channels n = 0, 1, 23, 24, 25, 77, and 78 are not allowed and shall be set to zero.
282 	 *  Channel 79 is reserved for future use and shall be set to zero.
283 	 */
284 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 0, 0);
285 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 1, 0);
286 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 23, 0);
287 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 24, 0);
288 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 25, 0);
289 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 77, 0);
290 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 78, 0);
291 	BT_LE_CS_CHANNEL_BIT_SET_VAL(channel_map, 79, 0);
292 }
293 
bt_le_cs_read_remote_supported_capabilities(struct bt_conn * conn)294 int bt_le_cs_read_remote_supported_capabilities(struct bt_conn *conn)
295 {
296 	struct bt_hci_cp_le_read_remote_supported_capabilities *cp;
297 	struct net_buf *buf;
298 
299 	buf = bt_hci_cmd_alloc(K_FOREVER);
300 	if (!buf) {
301 		return -ENOBUFS;
302 	}
303 
304 	cp = net_buf_add(buf, sizeof(*cp));
305 	cp->handle = sys_cpu_to_le16(conn->handle);
306 
307 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES, buf, NULL);
308 }
309 
bt_hci_le_cs_read_remote_supported_capabilities_complete(struct net_buf * buf)310 void bt_hci_le_cs_read_remote_supported_capabilities_complete(struct net_buf *buf)
311 {
312 	struct bt_conn *conn;
313 	struct bt_conn_le_cs_capabilities remote_cs_capabilities;
314 	struct bt_hci_evt_le_cs_read_remote_supported_capabilities_complete *evt;
315 
316 	if (buf->len < sizeof(*evt)) {
317 		LOG_ERR("Unexpected end of buffer");
318 		return;
319 	}
320 
321 	evt = net_buf_pull_mem(buf, sizeof(*evt));
322 	if (evt->status) {
323 		LOG_WRN("Read Remote Supported Capabilities failed (status 0x%02X)", evt->status);
324 	}
325 
326 	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
327 	if (!conn) {
328 		LOG_ERR("Could not lookup connection handle when reading remote CS capabilities");
329 		return;
330 	}
331 
332 	if (evt->status == BT_HCI_ERR_SUCCESS) {
333 		remote_cs_capabilities.num_config_supported = evt->num_config_supported;
334 		remote_cs_capabilities.max_consecutive_procedures_supported =
335 			sys_le16_to_cpu(evt->max_consecutive_procedures_supported);
336 		remote_cs_capabilities.num_antennas_supported = evt->num_antennas_supported;
337 		remote_cs_capabilities.max_antenna_paths_supported =
338 			evt->max_antenna_paths_supported;
339 
340 		remote_cs_capabilities.initiator_supported =
341 			evt->roles_supported & BT_HCI_LE_CS_INITIATOR_ROLE_MASK;
342 		remote_cs_capabilities.reflector_supported =
343 			evt->roles_supported & BT_HCI_LE_CS_REFLECTOR_ROLE_MASK;
344 		remote_cs_capabilities.mode_3_supported =
345 			evt->modes_supported & BT_HCI_LE_CS_MODES_SUPPORTED_MODE_3_MASK;
346 
347 		remote_cs_capabilities.rtt_aa_only_n = evt->rtt_aa_only_n;
348 		remote_cs_capabilities.rtt_sounding_n = evt->rtt_sounding_n;
349 		remote_cs_capabilities.rtt_random_payload_n = evt->rtt_random_payload_n;
350 
351 		if (evt->rtt_aa_only_n) {
352 			if (evt->rtt_capability & BT_HCI_LE_CS_RTT_AA_ONLY_N_10NS_MASK) {
353 				remote_cs_capabilities.rtt_aa_only_precision =
354 					BT_CONN_LE_CS_RTT_AA_ONLY_10NS;
355 			} else {
356 				remote_cs_capabilities.rtt_aa_only_precision =
357 					BT_CONN_LE_CS_RTT_AA_ONLY_150NS;
358 			}
359 		} else {
360 			remote_cs_capabilities.rtt_aa_only_precision =
361 				BT_CONN_LE_CS_RTT_AA_ONLY_NOT_SUPP;
362 		}
363 
364 		if (evt->rtt_sounding_n) {
365 			if (evt->rtt_capability & BT_HCI_LE_CS_RTT_SOUNDING_N_10NS_MASK) {
366 				remote_cs_capabilities.rtt_sounding_precision =
367 					BT_CONN_LE_CS_RTT_SOUNDING_10NS;
368 			} else {
369 				remote_cs_capabilities.rtt_sounding_precision =
370 					BT_CONN_LE_CS_RTT_SOUNDING_150NS;
371 			}
372 		} else {
373 			remote_cs_capabilities.rtt_sounding_precision =
374 				BT_CONN_LE_CS_RTT_SOUNDING_NOT_SUPP;
375 		}
376 
377 		if (evt->rtt_random_payload_n) {
378 			if (evt->rtt_capability & BT_HCI_LE_CS_RTT_RANDOM_PAYLOAD_N_10NS_MASK) {
379 				remote_cs_capabilities.rtt_random_payload_precision =
380 					BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_10NS;
381 			} else {
382 				remote_cs_capabilities.rtt_random_payload_precision =
383 					BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_150NS;
384 			}
385 		} else {
386 			remote_cs_capabilities.rtt_random_payload_precision =
387 				BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_NOT_SUPP;
388 		}
389 
390 		remote_cs_capabilities.phase_based_nadm_sounding_supported =
391 			sys_le16_to_cpu(evt->nadm_sounding_capability) &
392 			BT_HCI_LE_CS_NADM_SOUNDING_CAPABILITY_PHASE_BASED_MASK;
393 
394 		remote_cs_capabilities.phase_based_nadm_random_supported =
395 			sys_le16_to_cpu(evt->nadm_random_capability) &
396 			BT_HCI_LE_CS_NADM_RANDOM_CAPABILITY_PHASE_BASED_MASK;
397 
398 		remote_cs_capabilities.cs_sync_2m_phy_supported =
399 			evt->cs_sync_phys_supported & BT_HCI_LE_CS_SYNC_PHYS_2M_MASK;
400 
401 		remote_cs_capabilities.cs_sync_2m_2bt_phy_supported =
402 			evt->cs_sync_phys_supported & BT_HCI_LE_CS_SYNC_PHYS_2M_2BT_MASK;
403 
404 		remote_cs_capabilities.cs_without_fae_supported =
405 			sys_le16_to_cpu(evt->subfeatures_supported) &
406 			BT_HCI_LE_CS_SUBFEATURE_NO_TX_FAE_MASK;
407 
408 		remote_cs_capabilities.chsel_alg_3c_supported =
409 			sys_le16_to_cpu(evt->subfeatures_supported) &
410 			BT_HCI_LE_CS_SUBFEATURE_CHSEL_ALG_3C_MASK;
411 
412 		remote_cs_capabilities.pbr_from_rtt_sounding_seq_supported =
413 			sys_le16_to_cpu(evt->subfeatures_supported) &
414 			BT_HCI_LE_CS_SUBFEATURE_PBR_FROM_RTT_SOUNDING_SEQ_MASK;
415 
416 		remote_cs_capabilities.t_ip1_times_supported =
417 			sys_le16_to_cpu(evt->t_ip1_times_supported);
418 		remote_cs_capabilities.t_ip2_times_supported =
419 			sys_le16_to_cpu(evt->t_ip2_times_supported);
420 		remote_cs_capabilities.t_fcs_times_supported =
421 			sys_le16_to_cpu(evt->t_fcs_times_supported);
422 		remote_cs_capabilities.t_pm_times_supported =
423 			sys_le16_to_cpu(evt->t_pm_times_supported);
424 
425 		remote_cs_capabilities.t_sw_time = evt->t_sw_time_supported;
426 		remote_cs_capabilities.tx_snr_capability = evt->tx_snr_capability;
427 
428 		notify_remote_cs_capabilities(conn, BT_HCI_ERR_SUCCESS, &remote_cs_capabilities);
429 	} else {
430 		notify_remote_cs_capabilities(conn, evt->status, NULL);
431 	}
432 
433 	bt_conn_unref(conn);
434 }
435 
bt_le_cs_set_default_settings(struct bt_conn * conn,const struct bt_le_cs_set_default_settings_param * params)436 int bt_le_cs_set_default_settings(struct bt_conn *conn,
437 				  const struct bt_le_cs_set_default_settings_param *params)
438 {
439 	struct bt_hci_cp_le_cs_set_default_settings *cp;
440 	struct net_buf *buf;
441 
442 	buf = bt_hci_cmd_alloc(K_FOREVER);
443 	if (!buf) {
444 		return -ENOBUFS;
445 	}
446 
447 	cp = net_buf_add(buf, sizeof(*cp));
448 	cp->handle = sys_cpu_to_le16(conn->handle);
449 	cp->max_tx_power = params->max_tx_power;
450 	cp->cs_sync_antenna_selection = params->cs_sync_antenna_selection;
451 	cp->role_enable = 0;
452 
453 	if (params->enable_initiator_role) {
454 		cp->role_enable |= BT_HCI_OP_LE_CS_INITIATOR_ROLE_MASK;
455 	}
456 
457 	if (params->enable_reflector_role) {
458 		cp->role_enable |= BT_HCI_OP_LE_CS_REFLECTOR_ROLE_MASK;
459 	}
460 
461 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_SET_DEFAULT_SETTINGS, buf, NULL);
462 }
463 
bt_le_cs_read_remote_fae_table(struct bt_conn * conn)464 int bt_le_cs_read_remote_fae_table(struct bt_conn *conn)
465 {
466 	struct bt_hci_cp_le_read_remote_fae_table *cp;
467 	struct net_buf *buf;
468 
469 	buf = bt_hci_cmd_alloc(K_FOREVER);
470 	if (!buf) {
471 		return -ENOBUFS;
472 	}
473 
474 	cp = net_buf_add(buf, sizeof(*cp));
475 	cp->handle = sys_cpu_to_le16(conn->handle);
476 
477 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_READ_REMOTE_FAE_TABLE, buf, NULL);
478 }
479 
bt_hci_le_cs_read_remote_fae_table_complete(struct net_buf * buf)480 void bt_hci_le_cs_read_remote_fae_table_complete(struct net_buf *buf)
481 {
482 	struct bt_conn *conn;
483 	struct bt_conn_le_cs_fae_table fae_table;
484 	struct bt_hci_evt_le_cs_read_remote_fae_table_complete *evt;
485 
486 	if (buf->len < sizeof(*evt)) {
487 		LOG_ERR("Unexpected end of buffer");
488 		return;
489 	}
490 
491 	evt = net_buf_pull_mem(buf, sizeof(*evt));
492 	if (evt->status) {
493 		LOG_WRN("Read Remote FAE Table failed with status 0x%02X", evt->status);
494 	}
495 
496 	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle), BT_CONN_TYPE_LE);
497 	if (!conn) {
498 		LOG_ERR("Could not lookup connection handle when reading remote FAE Table");
499 		return;
500 	}
501 
502 	if (evt->status == BT_HCI_ERR_SUCCESS) {
503 		fae_table.remote_fae_table = evt->remote_fae_table;
504 
505 		notify_remote_cs_fae_table(conn, BT_HCI_ERR_SUCCESS, &fae_table);
506 	} else {
507 		notify_remote_cs_fae_table(conn, evt->status, NULL);
508 	}
509 
510 	bt_conn_unref(conn);
511 }
512 
513 #if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST)
bt_le_cs_test_cb_register(struct bt_le_cs_test_cb cb)514 int bt_le_cs_test_cb_register(struct bt_le_cs_test_cb cb)
515 {
516 	cs_test_callbacks = cb;
517 	return 0;
518 }
519 
bt_le_cs_start_test(const struct bt_le_cs_test_param * params)520 int bt_le_cs_start_test(const struct bt_le_cs_test_param *params)
521 {
522 	struct bt_hci_op_le_cs_test *cp;
523 	struct net_buf *buf;
524 
525 	buf = bt_hci_cmd_alloc(K_FOREVER);
526 	if (!buf) {
527 		return -ENOBUFS;
528 	}
529 
530 	cp = net_buf_add(buf, sizeof(*cp));
531 
532 	cp->main_mode_type = BT_CONN_LE_CS_MODE_MAIN_MODE_PART(params->mode);
533 
534 	uint8_t sub_mode_type = BT_CONN_LE_CS_MODE_SUB_MODE_PART(params->mode);
535 
536 	if (sub_mode_type) {
537 		cp->sub_mode_type = sub_mode_type;
538 	} else {
539 		cp->sub_mode_type = BT_HCI_OP_LE_CS_SUB_MODE_UNUSED;
540 	}
541 
542 	cp->main_mode_repetition = params->main_mode_repetition;
543 	cp->mode_0_steps = params->mode_0_steps;
544 	cp->role = params->role;
545 	cp->rtt_type = params->rtt_type;
546 	cp->cs_sync_phy = params->cs_sync_phy;
547 	cp->cs_sync_antenna_selection = params->cs_sync_antenna_selection;
548 	sys_put_le24(params->subevent_len, cp->subevent_len);
549 	cp->subevent_interval = sys_cpu_to_le16(params->subevent_interval);
550 	cp->max_num_subevents = params->max_num_subevents;
551 	cp->transmit_power_level = params->transmit_power_level;
552 	cp->t_ip1_time = params->t_ip1_time;
553 	cp->t_ip2_time = params->t_ip2_time;
554 	cp->t_fcs_time = params->t_fcs_time;
555 	cp->t_pm_time = params->t_pm_time;
556 	cp->t_sw_time = params->t_sw_time;
557 	cp->tone_antenna_config_selection = params->tone_antenna_config_selection;
558 
559 	cp->reserved = 0;
560 
561 	cp->snr_control_initiator = params->initiator_snr_control;
562 	cp->snr_control_reflector = params->reflector_snr_control;
563 	cp->drbg_nonce = sys_cpu_to_le16(params->drbg_nonce);
564 	cp->channel_map_repetition = params->override_config_0.channel_map_repetition;
565 	cp->override_config = sys_cpu_to_le16(params->override_config);
566 
567 	uint8_t override_parameters_length = 0;
568 
569 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_0_MASK) {
570 		const uint8_t num_channels = params->override_config_0.set.num_channels;
571 
572 		net_buf_add_u8(buf, num_channels);
573 		override_parameters_length++;
574 		net_buf_add_mem(buf, params->override_config_0.set.channels, num_channels);
575 		override_parameters_length += num_channels;
576 	} else {
577 		net_buf_add_mem(buf, params->override_config_0.not_set.channel_map,
578 				sizeof(params->override_config_0.not_set.channel_map));
579 		net_buf_add_u8(buf, params->override_config_0.not_set.channel_selection_type);
580 		net_buf_add_u8(buf, params->override_config_0.not_set.ch3c_shape);
581 		net_buf_add_u8(buf, params->override_config_0.not_set.ch3c_jump);
582 
583 		override_parameters_length +=
584 			(sizeof(params->override_config_0.not_set.channel_map) +
585 			 sizeof(params->override_config_0.not_set.channel_selection_type) +
586 			 sizeof(params->override_config_0.not_set.ch3c_shape) +
587 			 sizeof(params->override_config_0.not_set.ch3c_jump));
588 	}
589 
590 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_2_MASK) {
591 		net_buf_add_mem(buf, &params->override_config_2, sizeof(params->override_config_2));
592 		override_parameters_length += sizeof(params->override_config_2);
593 	}
594 
595 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_3_MASK) {
596 		net_buf_add_mem(buf, &params->override_config_3, sizeof(params->override_config_3));
597 		override_parameters_length += sizeof(params->override_config_3);
598 	}
599 
600 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_4_MASK) {
601 		net_buf_add_mem(buf, &params->override_config_4, sizeof(params->override_config_4));
602 		override_parameters_length += sizeof(params->override_config_4);
603 	}
604 
605 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_5_MASK) {
606 		net_buf_add_le32(buf, params->override_config_5.cs_sync_aa_initiator);
607 		net_buf_add_le32(buf, params->override_config_5.cs_sync_aa_reflector);
608 		override_parameters_length += sizeof(params->override_config_5);
609 	}
610 
611 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_6_MASK) {
612 		net_buf_add_mem(buf, &params->override_config_6, sizeof(params->override_config_6));
613 		override_parameters_length += sizeof(params->override_config_6);
614 	}
615 
616 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_7_MASK) {
617 		net_buf_add_mem(buf, &params->override_config_7, sizeof(params->override_config_7));
618 		override_parameters_length += sizeof(params->override_config_7);
619 	}
620 
621 	if (params->override_config & BT_HCI_OP_LE_CS_TEST_OVERRIDE_CONFIG_8_MASK) {
622 		net_buf_add_mem(buf, &params->override_config_8, sizeof(params->override_config_8));
623 		override_parameters_length += sizeof(params->override_config_8);
624 	}
625 
626 	cp->override_parameters_length = override_parameters_length;
627 
628 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_TEST, buf, NULL);
629 }
630 #endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */
631 
bt_hci_le_cs_subevent_result(struct net_buf * buf)632 void bt_hci_le_cs_subevent_result(struct net_buf *buf)
633 {
634 	struct bt_conn *conn = NULL;
635 	struct bt_hci_evt_le_cs_subevent_result *evt;
636 	struct bt_conn_le_cs_subevent_result result;
637 	struct bt_conn_le_cs_subevent_result *p_result = &result;
638 	struct net_buf_simple step_data_buf;
639 	struct net_buf *reassembly_buf = NULL;
640 
641 	if (buf->len < sizeof(*evt)) {
642 		LOG_ERR("Unexpected end of buffer");
643 		return;
644 	}
645 
646 	evt = net_buf_pull_mem(buf, sizeof(*evt));
647 	uint16_t conn_handle = sys_le16_to_cpu(evt->conn_handle);
648 
649 #if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST)
650 	if (conn_handle == BT_HCI_LE_CS_TEST_CONN_HANDLE) {
651 		if (!cs_test_callbacks.le_cs_test_subevent_data_available) {
652 			LOG_WRN("No callback registered. Discarded subevent results from CS Test.");
653 			return;
654 		}
655 	} else
656 #endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */
657 	{
658 		conn = bt_conn_lookup_handle(conn_handle, BT_CONN_TYPE_LE);
659 		if (!conn) {
660 			LOG_ERR("Unknown connection handle when processing subevent results");
661 			return;
662 		}
663 	}
664 
665 	if (evt->subevent_done_status != BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL) {
666 		p_result->step_data_buf = NULL;
667 		if (evt->num_steps_reported) {
668 			net_buf_simple_init_with_data(&step_data_buf, evt->steps, buf->len);
669 			p_result->step_data_buf = &step_data_buf;
670 		}
671 	} else {
672 		if (evt->procedure_done_status != BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_PARTIAL) {
673 			LOG_WRN("Procedure status is inconsistent with subevent status. Discarding "
674 				"subevent results");
675 			goto abort;
676 		}
677 
678 		if (!evt->num_steps_reported) {
679 			LOG_WRN("Discarding partial results without step data");
680 			goto abort;
681 		}
682 
683 		reassembly_buf = start_reassembly(conn_handle, evt->steps, buf->len);
684 		if (!reassembly_buf) {
685 			goto abort;
686 		}
687 
688 		p_result = &reassembled_result;
689 		p_result->step_data_buf = (struct net_buf_simple *)&reassembly_buf->data;
690 	}
691 
692 	p_result->header.procedure_counter = sys_le16_to_cpu(evt->procedure_counter);
693 	p_result->header.frequency_compensation = sys_le16_to_cpu(evt->frequency_compensation);
694 	p_result->header.procedure_done_status = evt->procedure_done_status;
695 	p_result->header.subevent_done_status = evt->subevent_done_status;
696 	p_result->header.procedure_abort_reason = evt->procedure_abort_reason;
697 	p_result->header.subevent_abort_reason = evt->subevent_abort_reason;
698 	p_result->header.reference_power_level = evt->reference_power_level;
699 	p_result->header.num_antenna_paths = evt->num_antenna_paths;
700 	p_result->header.num_steps_reported = evt->num_steps_reported;
701 	p_result->header.abort_step =
702 		evt->subevent_done_status == BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_ABORTED ? 0 : 255;
703 
704 	p_result->header.config_id = 0;
705 	p_result->header.start_acl_conn_event = 0;
706 	if (conn) {
707 		p_result->header.config_id = evt->config_id;
708 		p_result->header.start_acl_conn_event =
709 			sys_le16_to_cpu(evt->start_acl_conn_event_counter);
710 	}
711 
712 	if (evt->subevent_done_status != BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL) {
713 		invoke_subevent_result_callback(conn, p_result);
714 	}
715 
716 	if (evt->procedure_done_status != BT_CONN_LE_CS_PROCEDURE_INCOMPLETE) {
717 		/* We can now clear the any reassembly buffer allocated for this procedure,
718 		 * to avoid code duplication, we're using the abort label to do so
719 		 */
720 		goto abort;
721 	}
722 
723 	if (conn) {
724 		bt_conn_unref(conn);
725 		conn = NULL;
726 	}
727 
728 	return;
729 
730 abort:
731 	if (conn) {
732 		bt_conn_unref(conn);
733 		conn = NULL;
734 	}
735 
736 	reassembly_buf = get_reassembly_buf(conn_handle, false);
737 	if (reassembly_buf) {
738 		free_reassembly_buf(&reassembly_buf);
739 	}
740 }
741 
bt_hci_le_cs_subevent_result_continue(struct net_buf * buf)742 void bt_hci_le_cs_subevent_result_continue(struct net_buf *buf)
743 {
744 	struct bt_conn *conn = NULL;
745 	struct bt_hci_evt_le_cs_subevent_result_continue *evt;
746 	struct net_buf *reassembly_buf = NULL;
747 	uint16_t conn_handle;
748 
749 	if (buf->len < sizeof(*evt)) {
750 		LOG_ERR("Unexpected end of buffer");
751 		return;
752 	}
753 
754 	evt = net_buf_pull_mem(buf, sizeof(*evt));
755 	conn_handle = sys_le16_to_cpu(evt->conn_handle);
756 
757 #if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST)
758 	if (conn_handle == BT_HCI_LE_CS_TEST_CONN_HANDLE) {
759 		if (!cs_test_callbacks.le_cs_test_subevent_data_available) {
760 			LOG_WRN("No callback registered. Discarded subevent results from CS Test.");
761 			return;
762 		}
763 	} else
764 #endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */
765 	{
766 		conn = bt_conn_lookup_handle(conn_handle, BT_CONN_TYPE_LE);
767 		if (!conn) {
768 			LOG_ERR("Unknown connection handle when processing subevent results");
769 			return;
770 		}
771 	}
772 
773 	uint16_t step_data_len = evt->num_steps_reported ? buf->len : 0;
774 
775 	reassembly_buf = continue_reassembly(conn_handle, evt->steps, step_data_len);
776 	if (!reassembly_buf) {
777 		goto abort;
778 	}
779 
780 	reassembled_result.header.procedure_done_status = evt->procedure_done_status;
781 	reassembled_result.header.subevent_done_status = evt->subevent_done_status;
782 	reassembled_result.header.procedure_abort_reason = evt->procedure_abort_reason;
783 	reassembled_result.header.subevent_abort_reason = evt->subevent_abort_reason;
784 
785 	if (evt->num_antenna_paths != reassembled_result.header.num_antenna_paths) {
786 		LOG_WRN("Received inconsistent number of antenna paths from the controller: %d, "
787 			"previous number was: %d",
788 			evt->num_antenna_paths, reassembled_result.header.num_antenna_paths);
789 	}
790 
791 	if (evt->subevent_done_status == BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_ABORTED &&
792 	    reassembled_result.header.num_steps_reported < reassembled_result.header.abort_step) {
793 		reassembled_result.header.abort_step = reassembled_result.header.num_steps_reported;
794 	}
795 
796 	reassembled_result.header.num_steps_reported += evt->num_steps_reported;
797 
798 	if (evt->subevent_done_status != BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL) {
799 		invoke_subevent_result_callback(conn, &reassembled_result);
800 		net_buf_reset(reassembly_buf);
801 		reset_reassembly_results();
802 	}
803 
804 	if (evt->procedure_done_status != BT_HCI_LE_CS_PROCEDURE_DONE_STATUS_PARTIAL) {
805 		if (evt->subevent_done_status == BT_HCI_LE_CS_SUBEVENT_DONE_STATUS_PARTIAL) {
806 			LOG_WRN("Procedure status is inconsistent with subevent status. Discarding "
807 				"subevent results");
808 			goto abort;
809 		}
810 
811 		free_reassembly_buf(&reassembly_buf);
812 	}
813 
814 	if (conn) {
815 		bt_conn_unref(conn);
816 		conn = NULL;
817 	}
818 
819 	return;
820 
821 abort:
822 	if (conn) {
823 		bt_conn_unref(conn);
824 		conn = NULL;
825 	}
826 
827 	if (reassembly_buf) {
828 		free_reassembly_buf(&reassembly_buf);
829 	}
830 }
831 
bt_hci_le_cs_config_complete_event(struct net_buf * buf)832 void bt_hci_le_cs_config_complete_event(struct net_buf *buf)
833 {
834 	struct bt_hci_evt_le_cs_config_complete *evt;
835 	struct bt_conn_le_cs_config config;
836 	struct bt_conn *conn;
837 
838 	if (buf->len < sizeof(*evt)) {
839 		LOG_ERR("Unexpected end of buffer");
840 		return;
841 	}
842 
843 	evt = net_buf_pull_mem(buf, sizeof(*evt));
844 	if (evt->status) {
845 		LOG_WRN("CS Config failed (status 0x%02X)", evt->status);
846 	}
847 
848 	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE);
849 	if (!conn) {
850 		LOG_ERR("Could not lookup connection handle when reading CS configuration");
851 		return;
852 	}
853 
854 	if (evt->status == BT_HCI_ERR_SUCCESS) {
855 		if (evt->action == BT_HCI_LE_CS_CONFIG_ACTION_REMOVED) {
856 			notify_cs_config_removed(conn, evt->config_id);
857 			bt_conn_unref(conn);
858 			return;
859 		}
860 
861 		if (evt->sub_mode_type == BT_HCI_OP_LE_CS_SUB_MODE_UNUSED) {
862 			config.mode = evt->main_mode_type;
863 		} else {
864 			config.mode = evt->main_mode_type | (evt->sub_mode_type << 4);
865 		}
866 
867 		config.id = evt->config_id;
868 		config.min_main_mode_steps = evt->min_main_mode_steps;
869 		config.max_main_mode_steps = evt->max_main_mode_steps;
870 		config.main_mode_repetition = evt->main_mode_repetition;
871 		config.mode_0_steps = evt->mode_0_steps;
872 		config.role = evt->role;
873 		config.rtt_type = evt->rtt_type;
874 		config.cs_sync_phy = evt->cs_sync_phy;
875 		config.channel_map_repetition = evt->channel_map_repetition;
876 		config.channel_selection_type = evt->channel_selection_type;
877 		config.ch3c_shape = evt->ch3c_shape;
878 		config.ch3c_jump = evt->ch3c_jump;
879 		config.t_ip1_time_us = evt->t_ip1_time;
880 		config.t_ip2_time_us = evt->t_ip2_time;
881 		config.t_fcs_time_us = evt->t_fcs_time;
882 		config.t_pm_time_us = evt->t_pm_time;
883 		memcpy(config.channel_map, evt->channel_map, ARRAY_SIZE(config.channel_map));
884 
885 		notify_cs_config_created(conn, BT_HCI_ERR_SUCCESS, &config);
886 	} else {
887 		notify_cs_config_created(conn, evt->status, NULL);
888 	}
889 
890 	bt_conn_unref(conn);
891 }
892 
bt_le_cs_create_config(struct bt_conn * conn,struct bt_le_cs_create_config_params * params,enum bt_le_cs_create_config_context context)893 int bt_le_cs_create_config(struct bt_conn *conn, struct bt_le_cs_create_config_params *params,
894 			   enum bt_le_cs_create_config_context context)
895 {
896 	struct bt_hci_cp_le_cs_create_config *cp;
897 	struct net_buf *buf;
898 
899 	buf = bt_hci_cmd_alloc(K_FOREVER);
900 	if (!buf) {
901 		return -ENOBUFS;
902 	}
903 
904 	cp = net_buf_add(buf, sizeof(*cp));
905 	cp->handle = sys_cpu_to_le16(conn->handle);
906 	cp->config_id = params->id;
907 	cp->create_context = context;
908 	cp->main_mode_type = BT_CONN_LE_CS_MODE_MAIN_MODE_PART(params->mode);
909 
910 	uint8_t sub_mode_type = BT_CONN_LE_CS_MODE_SUB_MODE_PART(params->mode);
911 
912 	if (sub_mode_type) {
913 		cp->sub_mode_type = sub_mode_type;
914 	} else {
915 		cp->sub_mode_type = BT_HCI_OP_LE_CS_SUB_MODE_UNUSED;
916 	}
917 
918 	cp->min_main_mode_steps = params->min_main_mode_steps;
919 	cp->max_main_mode_steps = params->max_main_mode_steps;
920 	cp->main_mode_repetition = params->main_mode_repetition;
921 	cp->mode_0_steps = params->mode_0_steps;
922 	cp->role = params->role;
923 	cp->rtt_type = params->rtt_type;
924 	cp->cs_sync_phy = params->cs_sync_phy;
925 	cp->channel_map_repetition = params->channel_map_repetition;
926 	cp->channel_selection_type = params->channel_selection_type;
927 	cp->ch3c_shape = params->ch3c_shape;
928 	cp->ch3c_jump = params->ch3c_jump;
929 	cp->reserved = 0;
930 	memcpy(cp->channel_map, params->channel_map, ARRAY_SIZE(cp->channel_map));
931 
932 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_CREATE_CONFIG, buf, NULL);
933 }
934 
bt_le_cs_remove_config(struct bt_conn * conn,uint8_t config_id)935 int bt_le_cs_remove_config(struct bt_conn *conn, uint8_t config_id)
936 {
937 	struct bt_hci_cp_le_cs_remove_config *cp;
938 	struct net_buf *buf;
939 
940 	buf = bt_hci_cmd_alloc(K_FOREVER);
941 	if (!buf) {
942 		return -ENOBUFS;
943 	}
944 
945 	cp = net_buf_add(buf, sizeof(*cp));
946 	cp->handle = sys_cpu_to_le16(conn->handle);
947 	cp->config_id = config_id;
948 
949 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_REMOVE_CONFIG, buf, NULL);
950 }
951 
bt_le_cs_security_enable(struct bt_conn * conn)952 int bt_le_cs_security_enable(struct bt_conn *conn)
953 {
954 	struct bt_hci_cp_le_security_enable *cp;
955 	struct net_buf *buf;
956 
957 	buf = bt_hci_cmd_alloc(K_FOREVER);
958 	if (!buf) {
959 		return -ENOBUFS;
960 	}
961 
962 	cp = net_buf_add(buf, sizeof(*cp));
963 	cp->handle = sys_cpu_to_le16(conn->handle);
964 
965 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_SECURITY_ENABLE, buf, NULL);
966 }
967 
bt_le_cs_procedure_enable(struct bt_conn * conn,const struct bt_le_cs_procedure_enable_param * params)968 int bt_le_cs_procedure_enable(struct bt_conn *conn,
969 			      const struct bt_le_cs_procedure_enable_param *params)
970 {
971 	struct bt_hci_cp_le_procedure_enable *cp;
972 	struct net_buf *buf;
973 
974 	buf = bt_hci_cmd_alloc(K_FOREVER);
975 	if (!buf) {
976 		return -ENOBUFS;
977 	}
978 
979 	cp = net_buf_add(buf, sizeof(*cp));
980 	cp->handle = sys_cpu_to_le16(conn->handle);
981 	cp->config_id = params->config_id;
982 	cp->enable = params->enable;
983 
984 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_PROCEDURE_ENABLE, buf, NULL);
985 }
986 
bt_le_cs_set_procedure_parameters(struct bt_conn * conn,const struct bt_le_cs_set_procedure_parameters_param * params)987 int bt_le_cs_set_procedure_parameters(struct bt_conn *conn,
988 				      const struct bt_le_cs_set_procedure_parameters_param *params)
989 {
990 	struct bt_hci_cp_le_set_procedure_parameters *cp;
991 	struct net_buf *buf;
992 
993 	buf = bt_hci_cmd_alloc(K_FOREVER);
994 	if (!buf) {
995 		return -ENOBUFS;
996 	}
997 
998 	cp = net_buf_add(buf, sizeof(*cp));
999 	cp->handle = sys_cpu_to_le16(conn->handle);
1000 	cp->config_id = params->config_id;
1001 	cp->max_procedure_len = sys_cpu_to_le16(params->max_procedure_len);
1002 	cp->min_procedure_interval = sys_cpu_to_le16(params->min_procedure_interval);
1003 	cp->max_procedure_interval = sys_cpu_to_le16(params->max_procedure_interval);
1004 	cp->max_procedure_count = sys_cpu_to_le16(params->max_procedure_count);
1005 	sys_put_le24(params->min_subevent_len, cp->min_subevent_len);
1006 	sys_put_le24(params->max_subevent_len, cp->max_subevent_len);
1007 	cp->tone_antenna_config_selection = params->tone_antenna_config_selection;
1008 	cp->phy = params->phy;
1009 	cp->tx_power_delta = params->tx_power_delta;
1010 	cp->preferred_peer_antenna = params->preferred_peer_antenna;
1011 	cp->snr_control_initiator = params->snr_control_initiator;
1012 	cp->snr_control_reflector = params->snr_control_reflector;
1013 
1014 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_SET_PROCEDURE_PARAMETERS, buf, NULL);
1015 }
1016 
bt_le_cs_set_channel_classification(uint8_t channel_classification[10])1017 int bt_le_cs_set_channel_classification(uint8_t channel_classification[10])
1018 {
1019 	uint8_t *cp;
1020 	struct net_buf *buf;
1021 
1022 	buf = bt_hci_cmd_alloc(K_FOREVER);
1023 	if (!buf) {
1024 		return -ENOBUFS;
1025 	}
1026 
1027 	cp = net_buf_add(buf, 10);
1028 	memcpy(cp, channel_classification, 10);
1029 
1030 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_SET_CHANNEL_CLASSIFICATION, buf, NULL);
1031 }
1032 
bt_le_cs_read_local_supported_capabilities(struct bt_conn_le_cs_capabilities * ret)1033 int bt_le_cs_read_local_supported_capabilities(struct bt_conn_le_cs_capabilities *ret)
1034 {
1035 	struct bt_hci_rp_le_read_local_supported_capabilities *rp;
1036 	struct net_buf *rsp;
1037 
1038 	int err =
1039 		bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES, NULL, &rsp);
1040 
1041 	if (err) {
1042 		return err;
1043 	}
1044 
1045 	rp = (void *)rsp->data;
1046 
1047 	uint8_t status = rp->status;
1048 
1049 	ret->num_config_supported = rp->num_config_supported;
1050 	ret->max_consecutive_procedures_supported =
1051 		sys_le16_to_cpu(rp->max_consecutive_procedures_supported);
1052 	ret->num_antennas_supported = rp->num_antennas_supported;
1053 	ret->max_antenna_paths_supported = rp->max_antenna_paths_supported;
1054 
1055 	ret->initiator_supported = rp->roles_supported & BT_HCI_LE_CS_INITIATOR_ROLE_MASK;
1056 	ret->reflector_supported = rp->roles_supported & BT_HCI_LE_CS_REFLECTOR_ROLE_MASK;
1057 	ret->mode_3_supported = rp->modes_supported & BT_HCI_LE_CS_MODES_SUPPORTED_MODE_3_MASK;
1058 
1059 	ret->rtt_aa_only_n = rp->rtt_aa_only_n;
1060 	ret->rtt_sounding_n = rp->rtt_sounding_n;
1061 	ret->rtt_random_payload_n = rp->rtt_random_payload_n;
1062 
1063 	if (rp->rtt_aa_only_n) {
1064 		if (rp->rtt_capability & BT_HCI_LE_CS_RTT_AA_ONLY_N_10NS_MASK) {
1065 			ret->rtt_aa_only_precision = BT_CONN_LE_CS_RTT_AA_ONLY_10NS;
1066 		} else {
1067 			ret->rtt_aa_only_precision = BT_CONN_LE_CS_RTT_AA_ONLY_150NS;
1068 		}
1069 	} else {
1070 		ret->rtt_aa_only_precision = BT_CONN_LE_CS_RTT_AA_ONLY_NOT_SUPP;
1071 	}
1072 
1073 	if (rp->rtt_sounding_n) {
1074 		if (rp->rtt_capability & BT_HCI_LE_CS_RTT_SOUNDING_N_10NS_MASK) {
1075 			ret->rtt_sounding_precision = BT_CONN_LE_CS_RTT_SOUNDING_10NS;
1076 		} else {
1077 			ret->rtt_sounding_precision = BT_CONN_LE_CS_RTT_SOUNDING_150NS;
1078 		}
1079 	} else {
1080 		ret->rtt_sounding_precision = BT_CONN_LE_CS_RTT_SOUNDING_NOT_SUPP;
1081 	}
1082 
1083 	if (rp->rtt_random_payload_n) {
1084 		if (rp->rtt_capability & BT_HCI_LE_CS_RTT_RANDOM_PAYLOAD_N_10NS_MASK) {
1085 			ret->rtt_random_payload_precision = BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_10NS;
1086 		} else {
1087 			ret->rtt_random_payload_precision = BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_150NS;
1088 		}
1089 	} else {
1090 		ret->rtt_random_payload_precision = BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_NOT_SUPP;
1091 	}
1092 
1093 	ret->phase_based_nadm_sounding_supported =
1094 		sys_le16_to_cpu(rp->nadm_sounding_capability) &
1095 		BT_HCI_LE_CS_NADM_SOUNDING_CAPABILITY_PHASE_BASED_MASK;
1096 
1097 	ret->phase_based_nadm_random_supported =
1098 		sys_le16_to_cpu(rp->nadm_random_capability) &
1099 		BT_HCI_LE_CS_NADM_RANDOM_CAPABILITY_PHASE_BASED_MASK;
1100 
1101 	ret->cs_sync_2m_phy_supported = rp->cs_sync_phys_supported & BT_HCI_LE_CS_SYNC_PHYS_2M_MASK;
1102 
1103 	ret->cs_sync_2m_2bt_phy_supported =
1104 		rp->cs_sync_phys_supported & BT_HCI_LE_CS_SYNC_PHYS_2M_2BT_MASK;
1105 
1106 	ret->cs_without_fae_supported =
1107 		sys_le16_to_cpu(rp->subfeatures_supported) & BT_HCI_LE_CS_SUBFEATURE_NO_TX_FAE_MASK;
1108 
1109 	ret->chsel_alg_3c_supported = sys_le16_to_cpu(rp->subfeatures_supported) &
1110 				      BT_HCI_LE_CS_SUBFEATURE_CHSEL_ALG_3C_MASK;
1111 
1112 	ret->pbr_from_rtt_sounding_seq_supported =
1113 		sys_le16_to_cpu(rp->subfeatures_supported) &
1114 		BT_HCI_LE_CS_SUBFEATURE_PBR_FROM_RTT_SOUNDING_SEQ_MASK;
1115 
1116 	ret->t_ip1_times_supported = sys_le16_to_cpu(rp->t_ip1_times_supported);
1117 	ret->t_ip2_times_supported = sys_le16_to_cpu(rp->t_ip2_times_supported);
1118 	ret->t_fcs_times_supported = sys_le16_to_cpu(rp->t_fcs_times_supported);
1119 	ret->t_pm_times_supported = sys_le16_to_cpu(rp->t_pm_times_supported);
1120 
1121 	ret->t_sw_time = rp->t_sw_time_supported;
1122 	ret->tx_snr_capability = rp->tx_snr_capability;
1123 
1124 	net_buf_unref(rsp);
1125 	return status;
1126 }
1127 
bt_le_cs_write_cached_remote_supported_capabilities(struct bt_conn * conn,const struct bt_conn_le_cs_capabilities * params)1128 int bt_le_cs_write_cached_remote_supported_capabilities(
1129 	struct bt_conn *conn, const struct bt_conn_le_cs_capabilities *params)
1130 {
1131 	struct bt_hci_cp_le_write_cached_remote_supported_capabilities *cp;
1132 	struct net_buf *buf;
1133 
1134 	buf = bt_hci_cmd_alloc(K_FOREVER);
1135 	if (!buf) {
1136 		return -ENOBUFS;
1137 	}
1138 
1139 	cp = net_buf_add(buf, sizeof(*cp));
1140 
1141 	cp->handle = sys_cpu_to_le16(conn->handle);
1142 
1143 	cp->num_config_supported = params->num_config_supported;
1144 
1145 	cp->max_consecutive_procedures_supported =
1146 		sys_cpu_to_le16(params->max_consecutive_procedures_supported);
1147 
1148 	cp->num_antennas_supported = params->num_antennas_supported;
1149 	cp->max_antenna_paths_supported = params->max_antenna_paths_supported;
1150 
1151 	cp->roles_supported = 0;
1152 	if (params->initiator_supported) {
1153 		cp->roles_supported |= BT_HCI_LE_CS_INITIATOR_ROLE_MASK;
1154 	}
1155 	if (params->reflector_supported) {
1156 		cp->roles_supported |= BT_HCI_LE_CS_REFLECTOR_ROLE_MASK;
1157 	}
1158 
1159 	cp->modes_supported = 0;
1160 	if (params->mode_3_supported) {
1161 		cp->modes_supported |= BT_HCI_LE_CS_MODES_SUPPORTED_MODE_3_MASK;
1162 	}
1163 
1164 	cp->rtt_aa_only_n = params->rtt_aa_only_n;
1165 	cp->rtt_sounding_n = params->rtt_sounding_n;
1166 	cp->rtt_random_payload_n = params->rtt_random_payload_n;
1167 
1168 	cp->rtt_capability = 0;
1169 	if (params->rtt_aa_only_precision == BT_CONN_LE_CS_RTT_AA_ONLY_10NS) {
1170 		cp->rtt_capability |= BT_HCI_LE_CS_RTT_AA_ONLY_N_10NS_MASK;
1171 	}
1172 
1173 	if (params->rtt_sounding_precision == BT_CONN_LE_CS_RTT_SOUNDING_10NS) {
1174 		cp->rtt_capability |= BT_HCI_LE_CS_RTT_SOUNDING_N_10NS_MASK;
1175 	}
1176 
1177 	if (params->rtt_random_payload_precision == BT_CONN_LE_CS_RTT_RANDOM_PAYLOAD_10NS) {
1178 		cp->rtt_capability |= BT_HCI_LE_CS_RTT_RANDOM_PAYLOAD_N_10NS_MASK;
1179 	}
1180 
1181 	cp->nadm_sounding_capability = 0;
1182 	if (params->phase_based_nadm_sounding_supported) {
1183 		cp->nadm_sounding_capability |=
1184 			sys_cpu_to_le16(BT_HCI_LE_CS_NADM_SOUNDING_CAPABILITY_PHASE_BASED_MASK);
1185 	}
1186 
1187 	cp->nadm_random_capability = 0;
1188 	if (params->phase_based_nadm_random_supported) {
1189 		cp->nadm_random_capability |=
1190 			sys_cpu_to_le16(BT_HCI_LE_CS_NADM_RANDOM_CAPABILITY_PHASE_BASED_MASK);
1191 	}
1192 
1193 	cp->cs_sync_phys_supported = 0;
1194 	if (params->cs_sync_2m_phy_supported) {
1195 		cp->cs_sync_phys_supported |= BT_HCI_LE_CS_SYNC_PHYS_2M_MASK;
1196 	}
1197 	if (params->cs_sync_2m_2bt_phy_supported) {
1198 		cp->cs_sync_phys_supported |= BT_HCI_LE_CS_SYNC_PHYS_2M_2BT_MASK;
1199 	}
1200 
1201 	cp->subfeatures_supported = 0;
1202 	if (params->cs_without_fae_supported) {
1203 		cp->subfeatures_supported |=
1204 			sys_cpu_to_le16(BT_HCI_LE_CS_SUBFEATURE_NO_TX_FAE_MASK);
1205 	}
1206 	if (params->chsel_alg_3c_supported) {
1207 		cp->subfeatures_supported |=
1208 			sys_cpu_to_le16(BT_HCI_LE_CS_SUBFEATURE_CHSEL_ALG_3C_MASK);
1209 	}
1210 	if (params->pbr_from_rtt_sounding_seq_supported) {
1211 		cp->subfeatures_supported |=
1212 			sys_cpu_to_le16(BT_HCI_LE_CS_SUBFEATURE_PBR_FROM_RTT_SOUNDING_SEQ_MASK);
1213 	}
1214 
1215 	cp->t_ip1_times_supported = sys_cpu_to_le16(params->t_ip1_times_supported);
1216 	cp->t_ip2_times_supported = sys_cpu_to_le16(params->t_ip2_times_supported);
1217 	cp->t_fcs_times_supported = sys_cpu_to_le16(params->t_fcs_times_supported);
1218 	cp->t_pm_times_supported = sys_cpu_to_le16(params->t_pm_times_supported);
1219 	cp->t_sw_time_supported = params->t_sw_time;
1220 	cp->tx_snr_capability = params->tx_snr_capability;
1221 
1222 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES, buf,
1223 				    NULL);
1224 }
1225 
bt_le_cs_write_cached_remote_fae_table(struct bt_conn * conn,int8_t remote_fae_table[72])1226 int bt_le_cs_write_cached_remote_fae_table(struct bt_conn *conn, int8_t remote_fae_table[72])
1227 {
1228 	struct bt_hci_cp_le_write_cached_remote_fae_table *cp;
1229 	struct net_buf *buf;
1230 
1231 	buf = bt_hci_cmd_alloc(K_FOREVER);
1232 	if (!buf) {
1233 		return -ENOBUFS;
1234 	}
1235 
1236 	cp = net_buf_add(buf, sizeof(*cp));
1237 
1238 	cp->handle = sys_cpu_to_le16(conn->handle);
1239 	memcpy(cp->remote_fae_table, remote_fae_table, sizeof(cp->remote_fae_table));
1240 
1241 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE, buf, NULL);
1242 }
1243 
bt_hci_le_cs_security_enable_complete(struct net_buf * buf)1244 void bt_hci_le_cs_security_enable_complete(struct net_buf *buf)
1245 {
1246 	struct bt_conn *conn;
1247 
1248 	struct bt_hci_evt_le_cs_security_enable_complete *evt;
1249 
1250 	if (buf->len < sizeof(*evt)) {
1251 		LOG_ERR("Unexpected end of buffer");
1252 		return;
1253 	}
1254 
1255 	evt = net_buf_pull_mem(buf, sizeof(*evt));
1256 	if (evt->status) {
1257 		LOG_WRN("Security Enable failed with status 0x%02X", evt->status);
1258 	}
1259 
1260 	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE);
1261 	if (!conn) {
1262 		LOG_ERR("Can't lookup conn handle when reading Security Enable Complete event");
1263 		return;
1264 	}
1265 
1266 	notify_cs_security_enable_available(conn, evt->status);
1267 
1268 	bt_conn_unref(conn);
1269 }
1270 
bt_hci_le_cs_procedure_enable_complete(struct net_buf * buf)1271 void bt_hci_le_cs_procedure_enable_complete(struct net_buf *buf)
1272 {
1273 	struct bt_conn *conn;
1274 
1275 	struct bt_hci_evt_le_cs_procedure_enable_complete *evt;
1276 	struct bt_conn_le_cs_procedure_enable_complete params;
1277 
1278 	if (buf->len < sizeof(*evt)) {
1279 		LOG_ERR("Unexpected end of buffer");
1280 		return;
1281 	}
1282 
1283 	evt = net_buf_pull_mem(buf, sizeof(*evt));
1284 	if (evt->status) {
1285 		LOG_WRN("Procedure Enable failed with status 0x%02X", evt->status);
1286 	}
1287 
1288 	conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->handle), BT_CONN_TYPE_LE);
1289 	if (!conn) {
1290 		LOG_ERR("Can't lookup conn handle when reading Procedure Enable Complete event");
1291 		return;
1292 	}
1293 
1294 	if (evt->state == BT_HCI_OP_LE_CS_PROCEDURES_DISABLED) {
1295 		struct net_buf *reassembly_buf = get_reassembly_buf(conn->handle, false);
1296 
1297 		if (reassembly_buf) {
1298 			LOG_WRN("De-allocating a dangling reassembly buffer");
1299 			free_reassembly_buf(&reassembly_buf);
1300 		}
1301 	}
1302 
1303 	if (evt->status == BT_HCI_ERR_SUCCESS) {
1304 		params.config_id = evt->config_id;
1305 		params.state = evt->state;
1306 		params.tone_antenna_config_selection = evt->tone_antenna_config_selection;
1307 		params.selected_tx_power = evt->selected_tx_power;
1308 		params.subevent_len = sys_get_le24(evt->subevent_len);
1309 		params.subevents_per_event = evt->subevents_per_event;
1310 		params.subevent_interval = sys_le16_to_cpu(evt->subevent_interval);
1311 		params.event_interval = sys_le16_to_cpu(evt->event_interval);
1312 		params.procedure_interval = sys_le16_to_cpu(evt->procedure_interval);
1313 		params.procedure_count = sys_le16_to_cpu(evt->procedure_count);
1314 		params.max_procedure_len = sys_le16_to_cpu(evt->max_procedure_len);
1315 
1316 		notify_cs_procedure_enable_available(conn, BT_HCI_ERR_SUCCESS, &params);
1317 	} else {
1318 		notify_cs_procedure_enable_available(conn, evt->status, NULL);
1319 	}
1320 
1321 	bt_conn_unref(conn);
1322 }
1323 
1324 #if defined(CONFIG_BT_CHANNEL_SOUNDING_TEST)
bt_le_cs_stop_test(void)1325 int bt_le_cs_stop_test(void)
1326 {
1327 	struct net_buf *buf;
1328 
1329 	buf = bt_hci_cmd_alloc(K_FOREVER);
1330 	if (!buf) {
1331 		return -ENOBUFS;
1332 	}
1333 
1334 	return bt_hci_cmd_send_sync(BT_HCI_OP_LE_CS_TEST_END, buf, NULL);
1335 }
1336 
bt_hci_le_cs_test_end_complete(struct net_buf * buf)1337 void bt_hci_le_cs_test_end_complete(struct net_buf *buf)
1338 {
1339 	struct bt_hci_evt_le_cs_test_end_complete *evt;
1340 
1341 	if (buf->len < sizeof(*evt)) {
1342 		LOG_ERR("Unexpected end of buffer");
1343 		return;
1344 	}
1345 
1346 	evt = net_buf_pull_mem(buf, sizeof(*evt));
1347 	if (evt->status) {
1348 		LOG_WRN("CS Test End failed with status 0x%02X", evt->status);
1349 		return;
1350 	}
1351 
1352 	struct net_buf *reassembly_buf = get_reassembly_buf(BT_HCI_LE_CS_TEST_CONN_HANDLE, false);
1353 
1354 	if (reassembly_buf) {
1355 		LOG_WRN("De-allocating a dangling reassembly buffer");
1356 		free_reassembly_buf(&reassembly_buf);
1357 	}
1358 
1359 	if (cs_test_callbacks.le_cs_test_end_complete) {
1360 		cs_test_callbacks.le_cs_test_end_complete();
1361 	}
1362 }
1363 #endif /* CONFIG_BT_CHANNEL_SOUNDING_TEST */
1364 
bt_le_cs_step_data_parse(struct net_buf_simple * step_data_buf,bool (* func)(struct bt_le_cs_subevent_step * step,void * user_data),void * user_data)1365 void bt_le_cs_step_data_parse(struct net_buf_simple *step_data_buf,
1366 			      bool (*func)(struct bt_le_cs_subevent_step *step, void *user_data),
1367 			      void *user_data)
1368 {
1369 	if (!step_data_buf) {
1370 		LOG_INF("Tried to parse empty step data.");
1371 		return;
1372 	}
1373 
1374 	while (step_data_buf->len > 1) {
1375 		struct bt_le_cs_subevent_step step;
1376 
1377 		step.mode = net_buf_simple_pull_u8(step_data_buf);
1378 		step.channel = net_buf_simple_pull_u8(step_data_buf);
1379 		step.data_len = net_buf_simple_pull_u8(step_data_buf);
1380 
1381 		if (step.data_len == 0) {
1382 			LOG_WRN("Encountered zero-length step data.");
1383 			return;
1384 		}
1385 
1386 		step.data = step_data_buf->data;
1387 
1388 		if (step.data_len > step_data_buf->len) {
1389 			LOG_WRN("Step data appears malformed.");
1390 			return;
1391 		}
1392 
1393 		if (!func(&step, user_data)) {
1394 			return;
1395 		}
1396 
1397 		net_buf_simple_pull(step_data_buf, step.data_len);
1398 	}
1399 }
1400 
1401 /* Bluetooth Core Specification 6.0, Table 4.13, Antenna Path Permutation for N_AP=2.
1402  * The last element corresponds to extension slot
1403  */
1404 static const uint8_t antenna_path_lut_n_ap_2[2][3] = {
1405 	{A1, A2, A2},
1406 	{A2, A1, A1},
1407 };
1408 
1409 /* Bluetooth Core Specification 6.0, Table 4.14, Antenna Path Permutation for N_AP=3.
1410  * The last element corresponds to extension slot
1411  */
1412 static const uint8_t antenna_path_lut_n_ap_3[6][4] = {
1413 	{A1, A2, A3, A3},
1414 	{A2, A1, A3, A3},
1415 	{A1, A3, A2, A2},
1416 	{A3, A1, A2, A2},
1417 	{A3, A2, A1, A1},
1418 	{A2, A3, A1, A1},
1419 };
1420 
1421 /* Bluetooth Core Specification 6.0, Table 4.15, Antenna Path Permutation for N_AP=4.
1422  * The last element corresponds to extension slot
1423  */
1424 static const uint8_t antenna_path_lut_n_ap_4[24][5] = {
1425 	{A1, A2, A3, A4, A4},
1426 	{A2, A1, A3, A4, A4},
1427 	{A1, A3, A2, A4, A4},
1428 	{A3, A1, A2, A4, A4},
1429 	{A3, A2, A1, A4, A4},
1430 	{A2, A3, A1, A4, A4},
1431 	{A1, A2, A4, A3, A3},
1432 	{A2, A1, A4, A3, A3},
1433 	{A1, A4, A2, A3, A3},
1434 	{A4, A1, A2, A3, A3},
1435 	{A4, A2, A1, A3, A3},
1436 	{A2, A4, A1, A3, A3},
1437 	{A1, A4, A3, A2, A2},
1438 	{A4, A1, A3, A2, A2},
1439 	{A1, A3, A4, A2, A2},
1440 	{A3, A1, A4, A2, A2},
1441 	{A3, A4, A1, A2, A2},
1442 	{A4, A3, A1, A2, A2},
1443 	{A4, A2, A3, A1, A1},
1444 	{A2, A4, A3, A1, A1},
1445 	{A4, A3, A2, A1, A1},
1446 	{A3, A4, A2, A1, A1},
1447 	{A3, A2, A4, A1, A1},
1448 	{A2, A3, A4, A1, A1},
1449 };
1450 
bt_le_cs_get_antenna_path(uint8_t n_ap,uint8_t antenna_path_permutation_index,uint8_t tone_index)1451 int bt_le_cs_get_antenna_path(uint8_t n_ap,
1452 			      uint8_t antenna_path_permutation_index,
1453 			      uint8_t tone_index)
1454 {
1455 	switch (n_ap) {
1456 	case 1:
1457 	{
1458 		uint8_t antenna_path_permutations = 1;
1459 		uint8_t num_tones = n_ap + 1; /* one additional tone extension slot */
1460 
1461 		if (antenna_path_permutation_index >= antenna_path_permutations ||
1462 		    tone_index >= num_tones) {
1463 			return -EINVAL;
1464 		}
1465 		return A1;
1466 	}
1467 	case 2:
1468 	{
1469 		if (antenna_path_permutation_index >= ARRAY_SIZE(antenna_path_lut_n_ap_2) ||
1470 		    tone_index >= ARRAY_SIZE(antenna_path_lut_n_ap_2[0])) {
1471 			return -EINVAL;
1472 		}
1473 		return antenna_path_lut_n_ap_2[antenna_path_permutation_index][tone_index];
1474 	}
1475 	case 3:
1476 	{
1477 		if (antenna_path_permutation_index >= ARRAY_SIZE(antenna_path_lut_n_ap_3) ||
1478 		    tone_index >= ARRAY_SIZE(antenna_path_lut_n_ap_3[0])) {
1479 			return -EINVAL;
1480 		}
1481 		return antenna_path_lut_n_ap_3[antenna_path_permutation_index][tone_index];
1482 	}
1483 	case 4:
1484 	{
1485 		if (antenna_path_permutation_index >= ARRAY_SIZE(antenna_path_lut_n_ap_4) ||
1486 		    tone_index >= ARRAY_SIZE(antenna_path_lut_n_ap_4[0])) {
1487 			return -EINVAL;
1488 		}
1489 		return antenna_path_lut_n_ap_4[antenna_path_permutation_index][tone_index];
1490 	}
1491 	default:
1492 		return -EINVAL;
1493 	}
1494 }
1495