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