1 /* Copyright (c) 2023 Nordic Semiconductor ASA
2  * SPDX-License-Identifier: Apache-2.0
3  */
4 
5 #include <zephyr/bluetooth/att.h>
6 #include <zephyr/bluetooth/bluetooth.h>
7 #include <zephyr/bluetooth/gatt.h>
8 #include <zephyr/bluetooth/l2cap.h>
9 #include <zephyr/sys/__assert.h>
10 #include <zephyr/sys/byteorder.h>
11 #include <zephyr/logging/log.h>
12 
13 #include <testlib/att_read.h>
14 #include <testlib/conn.h>
15 #include <testlib/scan.h>
16 #include <testlib/security.h>
17 
18 #include "../bs_macro.h"
19 #include "../common_defs.h"
20 
21 LOG_MODULE_REGISTER(client, LOG_LEVEL_DBG);
22 
23 #define BT_LOCAL_ATT_MTU_EATT MIN(BT_L2CAP_SDU_RX_MTU, BT_L2CAP_SDU_TX_MTU)
24 #define BT_LOCAL_ATT_MTU_UATT MIN(BT_L2CAP_RX_MTU, BT_L2CAP_TX_MTU)
25 #define BT_ATT_BUF_SIZE       MAX(BT_LOCAL_ATT_MTU_UATT, BT_LOCAL_ATT_MTU_EATT)
26 
test_long_read(struct bt_conn * conn,enum bt_att_chan_opt bearer)27 void test_long_read(struct bt_conn *conn, enum bt_att_chan_opt bearer)
28 {
29 	/* The handle will be discovered in the first switch case. */
30 	uint16_t handle = 0;
31 
32 	/* Loop over the switch cases. */
33 	for (int i = 0; i < 3; i++) {
34 		int err;
35 		uint16_t actual_read_len;
36 		uint16_t remote_read_send_len;
37 
38 		NET_BUF_SIMPLE_DEFINE(attr_value, sizeof(remote_read_send_len));
39 
40 		/* Exercise various ATT read operations. */
41 		switch (i) {
42 		case 0:
43 			LOG_INF("ATT_READ_BY_TYPE");
44 			/* Aka. "read by uuid". */
45 			err = bt_testlib_att_read_by_type_sync(&attr_value, &actual_read_len,
46 							       &handle, NULL, conn, bearer,
47 							       MTU_VALIDATION_CHRC, 1, 0xffff);
48 			break;
49 		case 1:
50 			LOG_INF("ATT_READ");
51 			/* Arg `offset == 0`: the stack should choose ATT_READ PDU. */
52 			err = bt_testlib_att_read_by_handle_sync(&attr_value, &actual_read_len,
53 								 NULL, conn, bearer, handle, 0);
54 			break;
55 		case 2:
56 			LOG_INF("ATT_READ_BLOB");
57 			/* Arg `offset != 0`: the stack should choose ATT_READ_BLOB PDU. */
58 			err = bt_testlib_att_read_by_handle_sync(&attr_value, &actual_read_len,
59 								 NULL, conn, bearer, handle, 1);
60 			break;
61 		}
62 
63 		__ASSERT_NO_MSG(!err);
64 		__ASSERT(attr_value.len >= sizeof(remote_read_send_len),
65 			 "Remote sent too little data.");
66 		remote_read_send_len = net_buf_simple_pull_le16(&attr_value);
67 		__ASSERT(remote_read_send_len == actual_read_len, "Length mismatch. %u %u",
68 			 remote_read_send_len, actual_read_len);
69 	}
70 }
71 
the_test(void)72 void the_test(void)
73 {
74 	bt_addr_le_t scan_result;
75 	int err;
76 	struct bt_conn *conn = NULL;
77 
78 	err = bt_enable(NULL);
79 	__ASSERT_NO_MSG(!err);
80 
81 	err = bt_testlib_scan_find_name(&scan_result, "d1");
82 	__ASSERT_NO_MSG(!err);
83 
84 	err = bt_testlib_connect(&scan_result, &conn);
85 	__ASSERT_NO_MSG(!err);
86 
87 	/* Establish EATT bearers. */
88 	err = bt_testlib_secure(conn, BT_SECURITY_L2);
89 	__ASSERT_NO_MSG(!err);
90 
91 	while (bt_eatt_count(conn) == 0) {
92 		LOG_DBG("E..");
93 		k_msleep(100);
94 	};
95 	LOG_DBG("EATT");
96 
97 	test_long_read(conn, BT_ATT_CHAN_OPT_UNENHANCED_ONLY);
98 	test_long_read(conn, BT_ATT_CHAN_OPT_ENHANCED_ONLY);
99 
100 	err = bt_conn_disconnect(conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
101 	__ASSERT_NO_MSG(!err);
102 
103 	bt_conn_unref(conn);
104 	conn = NULL;
105 
106 	PASS("PASS\n");
107 }
108