1 /*
2  * Copyright (c) 2023 Nordic Semiconductor ASA
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/sys/byteorder.h>
9 #include <zephyr/sys/__assert.h>
10 
11 #include <zephyr/net_buf.h>
12 #include <zephyr/bluetooth/buf.h>
13 
14 #include <zephyr/bluetooth/bluetooth.h>
15 #include <zephyr/bluetooth/hci.h>
16 #include <zephyr/bluetooth/hci_raw.h>
17 #include <zephyr/bluetooth/hci_types.h>
18 
19 #include "common/hci_common_internal.h"
20 #include "common/bt_str.h"
21 
22 #include "host/conn_internal.h"
23 #include "host/l2cap_internal.h"
24 
25 #include "babblekit/testcase.h"
26 #include "babblekit/flags.h"
27 
28 #include "common_defs.h"
29 
30 #include <zephyr/logging/log.h>
31 LOG_MODULE_REGISTER(bt_tinyhost, LOG_LEVEL_INF);
32 
33 #define BT_ATT_OP_MTU_REQ   0x02
34 #define BT_ATT_OP_MTU_RSP   0x03
35 #define BT_ATT_OP_WRITE_REQ 0x12
36 #define BT_ATT_OP_WRITE_RSP 0x13
37 #define BT_ATT_OP_NOTIFY    0x1b
38 #define BT_ATT_OP_INDICATE  0x1d
39 #define BT_ATT_OP_CONFIRM   0x1e
40 #define BT_ATT_OP_WRITE_CMD 0x52
41 #define BT_L2CAP_CID_ATT    0x0004
42 
43 DEFINE_FLAG_STATIC(is_connected);
44 DEFINE_FLAG_STATIC(flag_data_length_updated);
45 DEFINE_FLAG_STATIC(flag_handle);
46 DEFINE_FLAG_STATIC(flag_write_ack);
47 DEFINE_FLAG_STATIC(flag_indication_ack);
48 
49 static uint16_t server_write_handle;
50 
51 static K_FIFO_DEFINE(rx_queue);
52 
53 #define CMD_BUF_SIZE MAX(BT_BUF_EVT_RX_SIZE, BT_BUF_CMD_TX_SIZE)
54 NET_BUF_POOL_FIXED_DEFINE(hci_cmd_pool, BT_BUF_CMD_TX_COUNT,
55 			  CMD_BUF_SIZE, 8, NULL);
56 
57 static K_SEM_DEFINE(cmd_sem, 1, 1);
58 static struct k_sem acl_pkts;
59 static uint16_t conn_handle;
60 
61 static volatile uint16_t active_opcode = 0xFFFF;
62 static struct net_buf *cmd_rsp;
63 
bt_hci_cmd_create(uint16_t opcode,uint8_t param_len)64 struct net_buf *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len)
65 {
66 	struct bt_hci_cmd_hdr *hdr;
67 	struct net_buf *buf;
68 
69 	LOG_DBG("opcode 0x%04x param_len %u", opcode, param_len);
70 
71 	buf = net_buf_alloc(&hci_cmd_pool, K_FOREVER);
72 	TEST_ASSERT(buf, "failed allocation");
73 
74 	LOG_DBG("buf %p", buf);
75 
76 	net_buf_reserve(buf, BT_BUF_RESERVE);
77 
78 	bt_buf_set_type(buf, BT_BUF_CMD);
79 
80 	hdr = net_buf_add(buf, sizeof(*hdr));
81 	hdr->opcode = sys_cpu_to_le16(opcode);
82 	hdr->param_len = param_len;
83 
84 	return buf;
85 }
86 
handle_cmd_complete(struct net_buf * buf)87 static void handle_cmd_complete(struct net_buf *buf)
88 {
89 	struct bt_hci_evt_hdr *hdr;
90 	uint8_t status, ncmd;
91 	uint16_t opcode;
92 	struct net_buf_simple_state state;
93 
94 	net_buf_simple_save(&buf->b, &state);
95 
96 	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
97 
98 	if (hdr->evt == BT_HCI_EVT_CMD_COMPLETE) {
99 		struct bt_hci_evt_cmd_complete *evt;
100 
101 		evt = net_buf_pull_mem(buf, sizeof(*evt));
102 		status = 0;
103 		ncmd = evt->ncmd;
104 		opcode = sys_le16_to_cpu(evt->opcode);
105 
106 	} else if (hdr->evt == BT_HCI_EVT_CMD_STATUS) {
107 		struct bt_hci_evt_cmd_status *evt;
108 
109 		evt = net_buf_pull_mem(buf, sizeof(*evt));
110 		status = buf->data[0];
111 		ncmd = evt->ncmd;
112 		opcode = sys_le16_to_cpu(evt->opcode);
113 
114 	} else {
115 		TEST_FAIL("unhandled event 0x%x", hdr->evt);
116 	}
117 
118 	LOG_DBG("opcode 0x%04x status %x", opcode, status);
119 
120 	TEST_ASSERT(status == 0x00, "cmd status: %x", status);
121 
122 	TEST_ASSERT(active_opcode == opcode, "unexpected opcode %x != %x", active_opcode, opcode);
123 
124 	if (active_opcode) {
125 		active_opcode = 0xFFFF;
126 		cmd_rsp = net_buf_ref(buf);
127 		net_buf_simple_restore(&buf->b, &state);
128 	}
129 
130 	if (ncmd) {
131 		k_sem_give(&cmd_sem);
132 	}
133 }
134 
handle_meta_event(struct net_buf * buf)135 static void handle_meta_event(struct net_buf *buf)
136 {
137 	uint8_t code = buf->data[2];
138 
139 	switch (code) {
140 	case BT_HCI_EVT_LE_ENH_CONN_COMPLETE:
141 	case BT_HCI_EVT_LE_ENH_CONN_COMPLETE_V2:
142 		conn_handle = sys_get_le16(&buf->data[4]);
143 		LOG_DBG("connected: handle: %d", conn_handle);
144 		SET_FLAG(is_connected);
145 		break;
146 	case BT_HCI_EVT_LE_DATA_LEN_CHANGE:
147 		SET_FLAG(flag_data_length_updated);
148 		break;
149 	case BT_HCI_EVT_LE_CHAN_SEL_ALGO:
150 		/* do nothing */
151 		break;
152 	default:
153 		LOG_ERR("unhandled meta event %x", code);
154 		LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI META EVT");
155 	}
156 }
157 
handle_ncp(struct net_buf * buf)158 static void handle_ncp(struct net_buf *buf)
159 {
160 	struct bt_hci_evt_num_completed_packets *evt;
161 	struct bt_hci_evt_hdr *hdr;
162 	uint16_t handle, count;
163 
164 	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
165 
166 	evt = (void *)buf->data;
167 	handle = sys_le16_to_cpu(evt->h[0].handle);
168 	count = sys_le16_to_cpu(evt->h[0].count);
169 
170 	LOG_DBG("sent %d packets", count);
171 
172 	while (count--) {
173 		k_sem_give(&acl_pkts);
174 	}
175 }
176 
handle_att_notification(struct net_buf * buf)177 static void handle_att_notification(struct net_buf *buf)
178 {
179 	uint16_t handle = net_buf_pull_le16(buf);
180 
181 	LOG_INF("Got notification for 0x%04x len %d", handle, buf->len);
182 	LOG_HEXDUMP_DBG(buf->data, buf->len, "payload");
183 
184 	server_write_handle = net_buf_pull_le16(buf);
185 	LOG_INF("Retrieved handle to write to: 0x%x", server_write_handle);
186 	SET_FLAG(flag_handle);
187 }
188 
189 struct net_buf *alloc_l2cap_pdu(void);
190 static void send_l2cap_packet(struct net_buf *buf, uint16_t cid);
191 
send_write_rsp(void)192 static void send_write_rsp(void)
193 {
194 	struct net_buf *buf = alloc_l2cap_pdu();
195 
196 	net_buf_add_u8(buf, BT_ATT_OP_WRITE_RSP);
197 	send_l2cap_packet(buf, BT_L2CAP_CID_ATT);
198 }
199 
handle_att_write(struct net_buf * buf)200 static void handle_att_write(struct net_buf *buf)
201 {
202 	uint16_t handle = net_buf_pull_le16(buf);
203 
204 	LOG_INF("Got write for 0x%04x len %d", handle, buf->len);
205 	LOG_HEXDUMP_DBG(buf->data, buf->len, "payload");
206 
207 	send_write_rsp();
208 }
209 
handle_att(struct net_buf * buf)210 static void handle_att(struct net_buf *buf)
211 {
212 	uint8_t op = net_buf_pull_u8(buf);
213 
214 	switch (op) {
215 	case BT_ATT_OP_NOTIFY:
216 		handle_att_notification(buf);
217 		return;
218 	case BT_ATT_OP_WRITE_REQ:
219 		handle_att_write(buf);
220 		return;
221 	case BT_ATT_OP_WRITE_RSP:
222 		LOG_INF("got ATT write RSP");
223 		SET_FLAG(flag_write_ack);
224 		return;
225 	case BT_ATT_OP_CONFIRM:
226 		LOG_INF("got ATT indication confirm");
227 		SET_FLAG(flag_indication_ack);
228 		return;
229 	case BT_ATT_OP_MTU_RSP:
230 		LOG_INF("got ATT MTU RSP");
231 		return;
232 	default:
233 		LOG_HEXDUMP_ERR(buf->data, buf->len, "payload");
234 		TEST_FAIL("unhandled opcode %x", op);
235 		return;
236 	}
237 }
238 
handle_l2cap(struct net_buf * buf)239 static void handle_l2cap(struct net_buf *buf)
240 {
241 	struct bt_l2cap_hdr *hdr;
242 	uint16_t cid;
243 
244 	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
245 	cid = sys_le16_to_cpu(hdr->cid);
246 
247 	LOG_DBG("Packet for CID %u len %u", cid, buf->len);
248 	LOG_HEXDUMP_DBG(buf->data, buf->len, "l2cap");
249 
250 	/* Make sure we don't have to recombine packets */
251 	TEST_ASSERT(buf->len == hdr->len, "buflen = %d != hdrlen %d",
252 	       buf->len, hdr->len);
253 
254 	TEST_ASSERT(cid == BT_L2CAP_CID_ATT, "We only support (U)ATT");
255 
256 	/* (U)ATT PDU */
257 	handle_att(buf);
258 }
259 
handle_acl(struct net_buf * buf)260 static void handle_acl(struct net_buf *buf)
261 {
262 	struct bt_hci_acl_hdr *hdr;
263 	uint16_t len, handle;
264 	uint8_t flags;
265 
266 	hdr = net_buf_pull_mem(buf, sizeof(*hdr));
267 	len = sys_le16_to_cpu(hdr->len);
268 	handle = sys_le16_to_cpu(hdr->handle);
269 
270 	flags = bt_acl_flags(handle);
271 	handle = bt_acl_handle(handle);
272 
273 	TEST_ASSERT(flags == BT_ACL_START,
274 	       "Fragmentation not supported");
275 
276 	LOG_DBG("ACL: conn %d len %d flags %d", handle, len, flags);
277 	LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI ACL");
278 
279 	handle_l2cap(buf);
280 }
281 
recv(struct net_buf * buf)282 static void recv(struct net_buf *buf)
283 {
284 	LOG_HEXDUMP_DBG(buf->data, buf->len, "HCI RX");
285 
286 	uint8_t code = buf->data[0];
287 
288 	if (bt_buf_get_type(buf) == BT_BUF_EVT) {
289 		switch (code) {
290 		case BT_HCI_EVT_CMD_COMPLETE:
291 		case BT_HCI_EVT_CMD_STATUS:
292 			handle_cmd_complete(buf);
293 			break;
294 		case BT_HCI_EVT_LE_META_EVENT:
295 			handle_meta_event(buf);
296 			break;
297 		case BT_HCI_EVT_DISCONN_COMPLETE:
298 			UNSET_FLAG(is_connected);
299 			break;
300 		case BT_HCI_EVT_NUM_COMPLETED_PACKETS:
301 			handle_ncp(buf);
302 			break;
303 		default:
304 			LOG_ERR("unhandled msg %x", code);
305 			LOG_HEXDUMP_ERR(buf->data, buf->len, "HCI EVT");
306 		}
307 
308 		/* handlers should take a ref if they want to access the buffer
309 		 * later
310 		 */
311 		net_buf_unref(buf);
312 		return;
313 	}
314 
315 	if (bt_buf_get_type(buf) == BT_BUF_ACL_IN) {
316 		handle_acl(buf);
317 		net_buf_unref(buf);
318 		return;
319 	}
320 
321 	LOG_ERR("HCI RX (not data or event)");
322 	net_buf_unref(buf);
323 }
324 
send_cmd(uint16_t opcode,struct net_buf * cmd,struct net_buf ** rsp)325 static void send_cmd(uint16_t opcode, struct net_buf *cmd, struct net_buf **rsp)
326 {
327 	LOG_DBG("opcode %x", opcode);
328 
329 	if (!cmd) {
330 		cmd = bt_hci_cmd_create(opcode, 0);
331 	}
332 
333 	k_sem_take(&cmd_sem, K_FOREVER);
334 	TEST_ASSERT_NO_MSG(active_opcode == 0xFFFF);
335 
336 	active_opcode = opcode;
337 
338 	LOG_HEXDUMP_DBG(cmd->data, cmd->len, "HCI TX");
339 	bt_send(cmd);
340 
341 	/* Wait until the command completes */
342 	k_sem_take(&cmd_sem, K_FOREVER);
343 	k_sem_give(&cmd_sem);
344 
345 	net_buf_unref(cmd);
346 
347 	/* return response. it's okay if cmd_rsp gets overwritten, since the app
348 	 * gets the ref to the underlying buffer when this fn returns.
349 	 */
350 	if (rsp) {
351 		*rsp = cmd_rsp;
352 	} else {
353 		net_buf_unref(cmd_rsp);
354 		cmd_rsp = NULL;
355 	}
356 }
357 
358 static K_THREAD_STACK_DEFINE(rx_thread_stack, 1024);
359 static struct k_thread rx_thread_data;
360 
rx_thread(void * p1,void * p2,void * p3)361 static void rx_thread(void *p1, void *p2, void *p3)
362 {
363 	LOG_DBG("start HCI rx");
364 
365 	while (true) {
366 		struct net_buf *buf;
367 
368 		/* Wait until a buffer is available */
369 		buf = k_fifo_get(&rx_queue, K_FOREVER);
370 		recv(buf);
371 	}
372 }
373 
le_read_buffer_size_complete(struct net_buf * rsp)374 static void le_read_buffer_size_complete(struct net_buf *rsp)
375 {
376 	struct bt_hci_rp_le_read_buffer_size *rp = (void *)rsp->data;
377 
378 	LOG_DBG("status 0x%02x", rp->status);
379 	LOG_DBG("max len %d max num %d", rp->le_max_len, rp->le_max_num);
380 
381 	k_sem_init(&acl_pkts, rp->le_max_num, rp->le_max_num);
382 	net_buf_unref(rsp);
383 }
384 
read_max_data_len(uint16_t * tx_octets,uint16_t * tx_time)385 static void read_max_data_len(uint16_t *tx_octets, uint16_t *tx_time)
386 {
387 	struct bt_hci_rp_le_read_max_data_len *rp;
388 	struct net_buf *rsp;
389 
390 	send_cmd(BT_HCI_OP_LE_READ_MAX_DATA_LEN, NULL, &rsp);
391 
392 	rp = (void *)rsp->data;
393 	*tx_octets = sys_le16_to_cpu(rp->max_tx_octets);
394 	*tx_time = sys_le16_to_cpu(rp->max_tx_time);
395 	net_buf_unref(rsp);
396 }
397 
write_default_data_len(uint16_t tx_octets,uint16_t tx_time)398 static void write_default_data_len(uint16_t tx_octets, uint16_t tx_time)
399 {
400 	struct bt_hci_cp_le_write_default_data_len *cp;
401 	struct net_buf *buf = bt_hci_cmd_create(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, sizeof(*cp));
402 
403 	TEST_ASSERT_NO_MSG(buf);
404 
405 	cp = net_buf_add(buf, sizeof(*cp));
406 	cp->max_tx_octets = sys_cpu_to_le16(tx_octets);
407 	cp->max_tx_time = sys_cpu_to_le16(tx_time);
408 
409 	send_cmd(BT_HCI_OP_LE_WRITE_DEFAULT_DATA_LEN, buf, NULL);
410 }
411 
set_data_len(void)412 static void set_data_len(void)
413 {
414 	uint16_t tx_octets, tx_time;
415 
416 	read_max_data_len(&tx_octets, &tx_time);
417 	write_default_data_len(tx_octets, tx_time);
418 }
419 
set_event_mask(uint16_t opcode)420 static void set_event_mask(uint16_t opcode)
421 {
422 	struct bt_hci_cp_set_event_mask *cp_mask;
423 	struct net_buf *buf;
424 	uint64_t mask = 0U;
425 
426 	/* The two commands have the same length/params */
427 	buf = bt_hci_cmd_create(opcode, sizeof(*cp_mask));
428 	TEST_ASSERT_NO_MSG(buf);
429 
430 	/* Forward all events */
431 	cp_mask = net_buf_add(buf, sizeof(*cp_mask));
432 	mask = UINT64_MAX;
433 	sys_put_le64(mask, cp_mask->events);
434 
435 	send_cmd(opcode, buf, NULL);
436 }
437 
set_random_address(void)438 static void set_random_address(void)
439 {
440 	struct net_buf *buf;
441 	bt_addr_le_t addr = {BT_ADDR_LE_RANDOM, {{0x0A, 0x89, 0x67, 0x45, 0x23, 0xC1}}};
442 
443 	LOG_DBG("%s", bt_addr_str(&addr.a));
444 
445 	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, sizeof(addr.a));
446 	TEST_ASSERT_NO_MSG(buf);
447 
448 	net_buf_add_mem(buf, &addr.a, sizeof(addr.a));
449 	send_cmd(BT_HCI_OP_LE_SET_RANDOM_ADDRESS, buf, NULL);
450 }
451 
start_adv(void)452 void start_adv(void)
453 {
454 	struct bt_hci_cp_le_set_adv_param set_param;
455 	struct net_buf *buf;
456 	uint16_t interval = 60; /* Interval doesn't matter */
457 
458 	(void)memset(&set_param, 0, sizeof(set_param));
459 
460 	set_param.min_interval = sys_cpu_to_le16(interval);
461 	set_param.max_interval = sys_cpu_to_le16(interval);
462 	set_param.channel_map = 0x07;
463 	set_param.filter_policy = BT_LE_ADV_FP_NO_FILTER;
464 	set_param.type = BT_HCI_ADV_IND;
465 	set_param.own_addr_type = BT_HCI_OWN_ADDR_RANDOM;
466 
467 	/* configure */
468 	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_PARAM, sizeof(set_param));
469 	net_buf_add_mem(buf, &set_param, sizeof(set_param));
470 	send_cmd(BT_HCI_OP_LE_SET_ADV_PARAM, buf, NULL);
471 
472 	/* start */
473 	buf = bt_hci_cmd_create(BT_HCI_OP_LE_SET_ADV_ENABLE, 1);
474 	net_buf_add_u8(buf, BT_HCI_LE_ADV_ENABLE);
475 	send_cmd(BT_HCI_OP_LE_SET_ADV_ENABLE, buf, NULL);
476 }
477 
478 NET_BUF_POOL_DEFINE(acl_tx_pool, 5, BT_L2CAP_BUF_SIZE(200), 8, NULL);
479 
alloc_l2cap_pdu(void)480 struct net_buf *alloc_l2cap_pdu(void)
481 {
482 	struct net_buf *buf;
483 	uint16_t reserve;
484 
485 	buf = net_buf_alloc(&acl_tx_pool, K_FOREVER);
486 	TEST_ASSERT(buf, "failed ACL allocation");
487 
488 	reserve = sizeof(struct bt_l2cap_hdr);
489 	reserve += sizeof(struct bt_hci_acl_hdr) + BT_BUF_RESERVE;
490 
491 	net_buf_reserve(buf, reserve);
492 
493 	return buf;
494 }
495 
send_acl(struct net_buf * buf)496 static int send_acl(struct net_buf *buf)
497 {
498 	struct bt_hci_acl_hdr *hdr;
499 	uint8_t flags = BT_ACL_START_NO_FLUSH;
500 
501 	hdr = net_buf_push(buf, sizeof(*hdr));
502 	hdr->handle = sys_cpu_to_le16(bt_acl_handle_pack(conn_handle, flags));
503 	hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr));
504 
505 	bt_buf_set_type(buf, BT_BUF_ACL_OUT);
506 
507 	k_sem_take(&acl_pkts, K_FOREVER);
508 
509 	return bt_send(buf);
510 }
511 
send_l2cap_packet(struct net_buf * buf,uint16_t cid)512 static void send_l2cap_packet(struct net_buf *buf, uint16_t cid)
513 {
514 	struct bt_l2cap_hdr *hdr;
515 
516 	hdr = net_buf_push(buf, sizeof(*hdr));
517 	hdr->len = sys_cpu_to_le16(buf->len - sizeof(*hdr));
518 	hdr->cid = sys_cpu_to_le16(cid);
519 
520 	/* Always entire packets, no HCI fragmentation */
521 	TEST_ASSERT(buf->len <= CONFIG_BT_BUF_ACL_TX_SIZE,
522 	       "Fragmentation not supported");
523 
524 	send_acl(buf);
525 }
526 
gatt_write(uint16_t op)527 static void gatt_write(uint16_t op)
528 {
529 	static uint8_t data[] = "write";
530 	uint16_t handle = server_write_handle;
531 	struct net_buf *buf = alloc_l2cap_pdu();
532 
533 	net_buf_add_u8(buf, op);
534 	net_buf_add_le16(buf, handle);
535 	net_buf_add_mem(buf, data, sizeof(data));
536 
537 	LOG_INF("send ATT write %s",
538 		op == BT_ATT_OP_WRITE_REQ ? "REQ" : "CMD");
539 
540 	send_l2cap_packet(buf, BT_L2CAP_CID_ATT);
541 }
542 
gatt_notify(void)543 static void gatt_notify(void)
544 {
545 	static uint8_t data[] = NOTIFICATION_PAYLOAD;
546 	uint16_t handle = HVX_HANDLE;
547 	struct net_buf *buf = alloc_l2cap_pdu();
548 
549 	net_buf_add_u8(buf, BT_ATT_OP_NOTIFY);
550 	net_buf_add_le16(buf, handle);
551 	net_buf_add_mem(buf, data, sizeof(data));
552 
553 	LOG_INF("send ATT notification");
554 	send_l2cap_packet(buf, BT_L2CAP_CID_ATT);
555 }
556 
gatt_indicate(void)557 static void gatt_indicate(void)
558 {
559 	static uint8_t data[] = INDICATION_PAYLOAD;
560 	uint16_t handle = HVX_HANDLE;
561 	struct net_buf *buf = alloc_l2cap_pdu();
562 
563 	net_buf_add_u8(buf, BT_ATT_OP_INDICATE);
564 	net_buf_add_le16(buf, handle);
565 	net_buf_add_mem(buf, data, sizeof(data));
566 
567 	LOG_INF("send ATT indication");
568 	send_l2cap_packet(buf, BT_L2CAP_CID_ATT);
569 }
570 
prepare_controller(void)571 static void prepare_controller(void)
572 {
573 	/* Initialize controller */
574 	struct net_buf *rsp;
575 
576 	send_cmd(BT_HCI_OP_RESET, NULL, NULL);
577 	send_cmd(BT_HCI_OP_LE_READ_BUFFER_SIZE, NULL, &rsp);
578 	le_read_buffer_size_complete(rsp);
579 
580 	set_data_len();
581 	set_event_mask(BT_HCI_OP_SET_EVENT_MASK);
582 	set_event_mask(BT_HCI_OP_LE_SET_EVENT_MASK);
583 	set_random_address();
584 }
585 
init_tinyhost(void)586 static void init_tinyhost(void)
587 {
588 	bt_enable_raw(&rx_queue);
589 
590 	/* Start the RX thread */
591 	k_thread_create(&rx_thread_data, rx_thread_stack,
592 			K_THREAD_STACK_SIZEOF(rx_thread_stack), rx_thread,
593 			NULL, NULL, NULL, K_PRIO_PREEMPT(0), 0, K_NO_WAIT);
594 	k_thread_name_set(&rx_thread_data, "HCI RX");
595 
596 	k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(0));
597 
598 	prepare_controller();
599 }
600 
test_procedure_0(void)601 void test_procedure_0(void)
602 {
603 	init_tinyhost();
604 
605 	/* Start advertising & wait for a connection */
606 	start_adv();
607 	WAIT_FOR_FLAG(is_connected);
608 	LOG_INF("connected");
609 
610 	/* We need this to be able to send whole L2CAP PDUs on-air. */
611 	WAIT_FOR_FLAG(flag_data_length_updated);
612 
613 	/* Get handle we will write to */
614 	WAIT_FOR_FLAG(flag_handle);
615 
616 	LOG_INF("##################### START TEST #####################");
617 
618 	gatt_write(BT_ATT_OP_WRITE_REQ);	/* will prompt a response PDU */
619 	gatt_indicate();			/* will prompt a confirmation PDU */
620 
621 	gatt_notify();
622 	gatt_write(BT_ATT_OP_WRITE_CMD);
623 
624 	gatt_notify();
625 	gatt_write(BT_ATT_OP_WRITE_CMD);
626 
627 	WAIT_FOR_FLAG(flag_write_ack);
628 	WAIT_FOR_FLAG(flag_indication_ack);
629 
630 	TEST_PASS("Tester done");
631 }
632 
633 static const struct bst_test_instance test_to_add[] = {
634 	{
635 		.test_id = "tester",
636 		.test_main_f = test_procedure_0,
637 	},
638 	BSTEST_END_MARKER,
639 };
640 
install(struct bst_test_list * tests)641 static struct bst_test_list *install(struct bst_test_list *tests)
642 {
643 	return bst_add_tests(tests, test_to_add);
644 };
645 
646 bst_test_install_t test_installers[] = {install, NULL};
647 
648 
main(void)649 int main(void)
650 {
651 	bst_main();
652 
653 	return 0;
654 }
655