1 /*
2  * Copyright (c) 2023 Codecoup
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <stdlib.h>
8 #include <zephyr/bluetooth/iso.h>
9 
10 #include "conn.h"
11 #include "iso.h"
12 
13 /* List of fakes used by this unit tester */
14 #define FFF_FAKES_LIST(FAKE) FAKE(bt_iso_chan_get_tx_sync)
15 
16 static struct bt_iso_server *iso_server;
17 
18 DEFINE_FAKE_VALUE_FUNC(int, bt_iso_chan_get_tx_sync, const struct bt_iso_chan *,
19 		       struct bt_iso_tx_info *);
20 
bt_iso_chan_send(struct bt_iso_chan * chan,struct net_buf * buf,uint16_t seq_num,uint32_t ts)21 int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num, uint32_t ts)
22 {
23 	if (chan->ops != NULL && chan->ops->sent != NULL) {
24 		chan->ops->sent(chan);
25 	}
26 
27 	return 0;
28 }
29 
bt_iso_server_register(struct bt_iso_server * server)30 int bt_iso_server_register(struct bt_iso_server *server)
31 {
32 	zassert_not_null(server, "server is NULL");
33 	zassert_not_null(server->accept, "server->accept is NULL");
34 	zassert_is_null(iso_server, "iso_server is NULL");
35 
36 	iso_server = server;
37 
38 	return 0;
39 }
40 
bt_iso_server_unregister(struct bt_iso_server * server)41 int bt_iso_server_unregister(struct bt_iso_server *server)
42 {
43 	zassert_not_null(server, "server is NULL");
44 	zassert_equal_ptr(iso_server, server, "not registered");
45 
46 	iso_server = NULL;
47 
48 	return 0;
49 }
50 
bt_iso_chan_disconnect(struct bt_iso_chan * chan)51 int bt_iso_chan_disconnect(struct bt_iso_chan *chan)
52 {
53 	return mock_bt_iso_disconnected(chan, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
54 }
55 
mock_bt_iso_init(void)56 void mock_bt_iso_init(void)
57 {
58 	FFF_FAKES_LIST(RESET_FAKE);
59 }
60 
mock_bt_iso_cleanup(void)61 void mock_bt_iso_cleanup(void)
62 {
63 
64 }
65 
mock_bt_iso_connected(struct bt_conn * iso)66 void mock_bt_iso_connected(struct bt_conn *iso)
67 {
68 	struct bt_iso_chan *chan = iso->chan;
69 
70 	chan->state = BT_ISO_STATE_CONNECTED;
71 	chan->iso = iso;
72 
73 	chan->ops->connected(chan);
74 }
75 
mock_bt_iso_accept(struct bt_conn * conn,uint8_t cig_id,uint8_t cis_id,struct bt_iso_chan ** chan)76 int mock_bt_iso_accept(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id,
77 		       struct bt_iso_chan **chan)
78 {
79 	struct bt_iso_accept_info info = {
80 		.acl = conn,
81 		.cig_id = cig_id,
82 		.cis_id = cis_id,
83 	};
84 	struct bt_conn *iso;
85 	int err;
86 
87 	zassert_not_null(iso_server, "iso_server is NULL");
88 
89 	err = iso_server->accept(&info, chan);
90 	if (err != 0) {
91 		return err;
92 	}
93 
94 	zassert_not_null(*chan, "chan is NULL");
95 
96 	iso = malloc(sizeof(struct bt_conn));
97 	zassert_not_null(iso);
98 
99 	iso->chan = (*chan);
100 	mock_bt_iso_connected(iso);
101 
102 	return 0;
103 }
104 
mock_bt_iso_disconnected(struct bt_iso_chan * chan,uint8_t err)105 int mock_bt_iso_disconnected(struct bt_iso_chan *chan, uint8_t err)
106 {
107 	chan->state = BT_ISO_STATE_DISCONNECTED;
108 	chan->ops->disconnected(chan, err);
109 	free(chan->iso);
110 	chan->iso = NULL;
111 
112 	return 0;
113 }
114 
115 #if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
bt_iso_big_create(struct bt_le_ext_adv * padv,struct bt_iso_big_create_param * param,struct bt_iso_big ** out_big)116 int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param,
117 		      struct bt_iso_big **out_big)
118 {
119 	struct bt_iso_big *big;
120 
121 	zassert_not_null(out_big);
122 	zassert_not_null(param);
123 	zassert_not_equal(param->num_bis, 0);
124 
125 	big = malloc(sizeof(struct bt_iso_big));
126 	zassert_not_null(big);
127 	big->num_bis = 0U;
128 
129 	for (uint8_t i = 0U; i < param->num_bis; i++) {
130 		struct bt_iso_chan *bis = param->bis_channels[i];
131 		struct bt_conn *iso;
132 
133 		zassert_not_null(bis);
134 
135 		iso = malloc(sizeof(struct bt_conn));
136 		zassert_not_null(iso);
137 		big->bis[i] = bis;
138 		big->num_bis++;
139 
140 		iso->chan = bis;
141 		mock_bt_iso_connected(iso);
142 	}
143 
144 	*out_big = big;
145 
146 	return 0;
147 }
148 
bt_iso_big_terminate(struct bt_iso_big * big)149 int bt_iso_big_terminate(struct bt_iso_big *big)
150 {
151 	/* TODO: Call chan->ops->disconnected(*chan); for each BIS */
152 	zassert_not_equal(big->num_bis, 0);
153 
154 	for (uint8_t i = 0U; i < big->num_bis; i++) {
155 		struct bt_iso_chan *bis = big->bis[i];
156 
157 		zassert_not_null(bis, "big %p", big);
158 
159 		mock_bt_iso_disconnected(bis, BT_HCI_ERR_LOCALHOST_TERM_CONN);
160 	}
161 
162 	free(big);
163 
164 	return 0;
165 }
166 #endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */
167