blob: 7271a66242eaa99733fb95e7fc3f9547c421cbd3 [file] [log] [blame]
/*
* Copyright (c) 2023 Codecoup
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdlib.h>
#include <zephyr/bluetooth/iso.h>
#include "conn.h"
#include "iso.h"
/* List of fakes used by this unit tester */
#define FFF_FAKES_LIST(FAKE) FAKE(bt_iso_chan_get_tx_sync)
static struct bt_iso_server *iso_server;
DEFINE_FAKE_VALUE_FUNC(int, bt_iso_chan_get_tx_sync, const struct bt_iso_chan *,
struct bt_iso_tx_info *);
int bt_iso_chan_send(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num)
{
if (chan->ops != NULL && chan->ops->sent != NULL) {
chan->ops->sent(chan);
}
return 0;
}
int bt_iso_chan_send_ts(struct bt_iso_chan *chan, struct net_buf *buf, uint16_t seq_num,
uint32_t ts)
{
if (chan->ops != NULL && chan->ops->sent != NULL) {
chan->ops->sent(chan);
}
return 0;
}
int bt_iso_server_register(struct bt_iso_server *server)
{
zassert_not_null(server, "server is NULL");
zassert_not_null(server->accept, "server->accept is NULL");
zassert_is_null(iso_server, "iso_server is NULL");
iso_server = server;
return 0;
}
int bt_iso_server_unregister(struct bt_iso_server *server)
{
zassert_not_null(server, "server is NULL");
zassert_equal_ptr(iso_server, server, "not registered");
iso_server = NULL;
return 0;
}
int bt_iso_chan_disconnect(struct bt_iso_chan *chan)
{
return mock_bt_iso_disconnected(chan, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
}
void mock_bt_iso_init(void)
{
FFF_FAKES_LIST(RESET_FAKE);
}
void mock_bt_iso_cleanup(void)
{
}
void mock_bt_iso_connected(struct bt_conn *iso)
{
struct bt_iso_chan *chan = iso->chan;
chan->state = BT_ISO_STATE_CONNECTED;
chan->iso = iso;
chan->ops->connected(chan);
}
int mock_bt_iso_accept(struct bt_conn *conn, uint8_t cig_id, uint8_t cis_id,
struct bt_iso_chan **chan)
{
struct bt_iso_accept_info info = {
.acl = conn,
.cig_id = cig_id,
.cis_id = cis_id,
};
struct bt_conn *iso;
int err;
zassert_not_null(iso_server, "iso_server is NULL");
err = iso_server->accept(&info, chan);
if (err != 0) {
return err;
}
zassert_not_null(*chan, "chan is NULL");
iso = malloc(sizeof(struct bt_conn));
zassert_not_null(iso);
iso->chan = (*chan);
mock_bt_iso_connected(iso);
return 0;
}
int mock_bt_iso_disconnected(struct bt_iso_chan *chan, uint8_t err)
{
chan->state = BT_ISO_STATE_DISCONNECTED;
chan->ops->disconnected(chan, err);
free(chan->iso);
chan->iso = NULL;
return 0;
}
#if defined(CONFIG_BT_BAP_BROADCAST_SOURCE)
int bt_iso_big_create(struct bt_le_ext_adv *padv, struct bt_iso_big_create_param *param,
struct bt_iso_big **out_big)
{
struct bt_iso_big *big;
zassert_not_null(out_big);
zassert_not_null(param);
zassert_not_equal(param->num_bis, 0);
big = malloc(sizeof(struct bt_iso_big));
zassert_not_null(big);
big->num_bis = 0U;
for (uint8_t i = 0U; i < param->num_bis; i++) {
struct bt_iso_chan *bis = param->bis_channels[i];
struct bt_conn *iso;
zassert_not_null(bis);
iso = malloc(sizeof(struct bt_conn));
zassert_not_null(iso);
big->bis[i] = bis;
big->num_bis++;
iso->chan = bis;
mock_bt_iso_connected(iso);
}
*out_big = big;
return 0;
}
int bt_iso_big_terminate(struct bt_iso_big *big)
{
/* TODO: Call chan->ops->disconnected(*chan); for each BIS */
zassert_not_equal(big->num_bis, 0);
for (uint8_t i = 0U; i < big->num_bis; i++) {
struct bt_iso_chan *bis = big->bis[i];
zassert_not_null(bis, "big %p", big);
mock_bt_iso_disconnected(bis, BT_HCI_ERR_LOCALHOST_TERM_CONN);
}
free(big);
return 0;
}
#endif /* CONFIG_BT_BAP_BROADCAST_SOURCE */