@@ -14,13 +14,9 @@
#include <stdbool.h>
#include <unistd.h>
#include <errno.h>
-#include <poll.h>
#include "lib/bluetooth.h"
#include "lib/uuid.h"
-#include "lib/iso.h"
-
-#include "btio/btio.h"
#include "src/shared/queue.h"
#include "src/shared/util.h"
@@ -29,8 +25,6 @@
#include "src/shared/gatt-client.h"
#include "src/shared/bass.h"
-#define MAX_BIS_BITMASK_IDX 31
-
#define DBG(_bass, fmt, arg...) \
bass_debug(_bass, "%s:%s() " fmt, __FILE__, __func__, ## arg)
@@ -102,9 +96,6 @@ struct bt_bcast_src {
uint8_t bad_code[BT_BASS_BCAST_CODE_SIZE];
uint8_t num_subgroups;
struct bt_bass_subgroup_data *subgroup_data;
- GIOChannel *listen_io;
- GIOChannel *pa_sync_io;
- struct queue *bises;
};
typedef void (*bass_notify_t)(struct bt_bass *bass, uint16_t value_handle,
@@ -122,35 +113,6 @@ static struct queue *bass_db;
static struct queue *bass_cbs;
static struct queue *sessions;
-#define DEFAULT_IO_QOS \
-{ \
- .interval = 10000, \
- .latency = 10, \
- .sdu = 40, \
- .phy = 0x02, \
- .rtn = 2, \
-}
-
-static struct bt_iso_qos default_qos = {
- .bcast = {
- .big = BT_ISO_QOS_BIG_UNSET,
- .bis = BT_ISO_QOS_BIS_UNSET,
- .sync_factor = 0x07,
- .packing = 0x00,
- .framing = 0x00,
- .in = DEFAULT_IO_QOS,
- .out = DEFAULT_IO_QOS,
- .encryption = 0x00,
- .bcode = {0x00},
- .options = 0x00,
- .skip = 0x0000,
- .sync_timeout = BT_ISO_SYNC_TIMEOUT,
- .sync_cte_type = 0x00,
- .mse = 0x00,
- .timeout = BT_ISO_SYNC_TIMEOUT,
- }
-};
-
struct bt_bass_src_changed {
unsigned int id;
bt_bass_src_func_t cb;
@@ -646,115 +608,6 @@ static bool bass_src_attr_match(const void *data, const void *match_data)
return (bcast_src->attr == attr);
}
-static gboolean check_io_err(GIOChannel *io)
-{
- struct pollfd fds;
-
- memset(&fds, 0, sizeof(fds));
- fds.fd = g_io_channel_unix_get_fd(io);
- fds.events = POLLERR;
-
- if (poll(&fds, 1, 0) > 0 && (fds.revents & POLLERR))
- return TRUE;
-
- return FALSE;
-}
-
-static void bass_bis_unref(void *data)
-{
- GIOChannel *io = data;
-
- g_io_channel_unref(io);
-}
-
-static void connect_cb(GIOChannel *io, GError *gerr,
- gpointer user_data)
-{
- struct bt_bcast_src *bcast_src = user_data;
- struct iovec *notif;
- int bis_idx;
- int i;
-
- /* Keep io reference */
- g_io_channel_ref(io);
- queue_push_tail(bcast_src->bises, io);
-
- for (i = 0; i < bcast_src->num_subgroups; i++) {
- struct bt_bass_subgroup_data *data =
- &bcast_src->subgroup_data[i];
-
- for (bis_idx = 0; bis_idx < MAX_BIS_BITMASK_IDX; bis_idx++) {
- if (data->pending_bis_sync & (1 << bis_idx)) {
- data->bis_sync |= (1 << bis_idx);
- data->pending_bis_sync &= ~(1 << bis_idx);
- break;
- }
- }
-
- if (bis_idx < MAX_BIS_BITMASK_IDX)
- break;
- }
-
- for (i = 0; i < bcast_src->num_subgroups; i++) {
- if (bcast_src->subgroup_data[i].pending_bis_sync)
- break;
- }
-
- /* If there are still pending bises, wait for their
- * notifications also before sending notification to
- * client
- */
- if (i != bcast_src->num_subgroups)
- return;
-
- /* All connections have been notified */
- if (check_io_err(io)) {
- DBG(bcast_src->bass, "BIG sync failed");
-
- /* Close all connected bises */
- queue_destroy(bcast_src->bises, bass_bis_unref);
- bcast_src->bises = NULL;
-
- /* Close listen io */
- g_io_channel_shutdown(bcast_src->listen_io, TRUE, NULL);
- g_io_channel_unref(bcast_src->listen_io);
- bcast_src->listen_io = NULL;
-
- /* Close pa sync io */
- if (bcast_src->pa_sync_io) {
- g_io_channel_shutdown(bcast_src->pa_sync_io,
- TRUE, NULL);
- g_io_channel_unref(bcast_src->pa_sync_io);
- bcast_src->pa_sync_io = NULL;
- }
-
- for (i = 0; i < bcast_src->num_subgroups; i++)
- bcast_src->subgroup_data[i].bis_sync =
- BT_BASS_BIG_SYNC_FAILED_BITMASK;
-
- /* If BIG sync failed because of an incorrect broadcast code,
- * inform client
- */
- if (bcast_src->enc == BT_BASS_BIG_ENC_STATE_BCODE_REQ)
- bcast_src->enc = BT_BASS_BIG_ENC_STATE_BAD_CODE;
- } else {
- if (bcast_src->enc == BT_BASS_BIG_ENC_STATE_BCODE_REQ)
- bcast_src->enc = BT_BASS_BIG_ENC_STATE_DEC;
- }
-
- /* Send notification to client */
- notif = bass_parse_bcast_src(bcast_src);
- if (!notif)
- return;
-
- gatt_db_attribute_notify(bcast_src->attr,
- notif->iov_base, notif->iov_len,
- bt_bass_get_att(bcast_src->bass));
-
- free(notif->iov_base);
- free(notif);
-}
-
static bool bass_trigger_big_sync(struct bt_bcast_src *bcast_src)
{
for (int i = 0; i < bcast_src->num_subgroups; i++) {
@@ -769,73 +622,6 @@ static bool bass_trigger_big_sync(struct bt_bcast_src *bcast_src)
return false;
}
-
-static void confirm_cb(GIOChannel *io, gpointer user_data)
-{
- struct bt_bcast_src *bcast_src = user_data;
- int sk, err;
- socklen_t len;
- struct bt_iso_qos qos;
- struct iovec *notif;
- GError *gerr = NULL;
-
- if (check_io_err(io)) {
- DBG(bcast_src->bass, "PA sync failed");
-
- /* Mark PA sync as failed and notify client */
- bcast_src->sync_state = BT_BASS_FAILED_TO_SYNCHRONIZE_TO_PA;
- goto notify;
- }
-
- bcast_src->sync_state = BT_BASS_SYNCHRONIZED_TO_PA;
- bcast_src->pa_sync_io = io;
- g_io_channel_ref(bcast_src->pa_sync_io);
-
- len = sizeof(qos);
- memset(&qos, 0, len);
-
- sk = g_io_channel_unix_get_fd(io);
-
- err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len);
- if (err < 0) {
- DBG(bcast_src->bass, "Failed to get iso qos");
- return;
- }
-
- if (!qos.bcast.encryption) {
- /* BIG is not encrypted. Try to synchronize */
- bcast_src->enc = BT_BASS_BIG_ENC_STATE_NO_ENC;
-
- if (bass_trigger_big_sync(bcast_src)) {
- if (!bt_io_bcast_accept(bcast_src->pa_sync_io,
- connect_cb, bcast_src, NULL, &gerr,
- BT_IO_OPT_INVALID)) {
- DBG(bcast_src->bass, "bt_io_bcast_accept: %s",
- gerr->message);
- g_error_free(gerr);
- }
- return;
- }
-
- goto notify;
- }
-
- /* BIG is encrypted. Wait for Client to provide the Broadcast_Code */
- bcast_src->enc = BT_BASS_BIG_ENC_STATE_BCODE_REQ;
-
-notify:
- notif = bass_parse_bcast_src(bcast_src);
- if (!notif)
- return;
-
- gatt_db_attribute_notify(bcast_src->attr,
- notif->iov_base, notif->iov_len,
- bt_bass_get_att(bcast_src->bass));
-
- free(notif->iov_base);
- free(notif);
-}
-
static struct bt_bass *bass_get_session(struct bt_att *att, struct gatt_db *db,
const bdaddr_t *adapter_bdaddr)
{
@@ -922,13 +708,7 @@ static void bass_handle_add_src_op(struct bt_bass *bass,
uint8_t src_id = 0;
struct gatt_db_attribute *attr;
uint8_t pa_sync;
- GIOChannel *io;
- GError *err = NULL;
- struct bt_iso_qos iso_qos = default_qos;
- uint8_t num_bis = 0;
- uint8_t bis[ISO_MAX_NUM_BIS];
struct iovec *notif;
- uint8_t addr_type;
gatt_db_attribute_write_result(attrib, id, 0x00);
@@ -945,8 +725,6 @@ static void bass_handle_add_src_op(struct bt_bass *bass,
queue_push_tail(bass->ldb->bcast_srcs, bcast_src);
- memset(bis, 0, ISO_MAX_NUM_BIS);
-
bcast_src->bass = bass;
/* Map the source to a Broadcast Receive State characteristic */
@@ -1028,18 +806,6 @@ static void bass_handle_add_src_op(struct bt_bass *bass,
util_iov_pull_le32(iov, &data->pending_bis_sync);
- if (data->pending_bis_sync != BIS_SYNC_NO_PREF)
- /* Iterate through the bis sync bitmask written
- * by the client and store the bis indexes that
- * the BASS server will try to synchronize to
- */
- for (int bis_idx = 0; bis_idx < 31; bis_idx++) {
- if (data->pending_bis_sync & (1 << bis_idx)) {
- bis[num_bis] = bis_idx + 1;
- num_bis++;
- }
- }
-
data->meta_len = *(uint8_t *)util_iov_pull_mem(iov,
sizeof(data->meta_len));
if (!data->meta_len)
@@ -1054,38 +820,7 @@ static void bass_handle_add_src_op(struct bt_bass *bass,
}
if (pa_sync != PA_SYNC_NO_SYNC) {
- /* Convert to three-value type */
- if (bcast_src->addr_type)
- addr_type = BDADDR_LE_RANDOM;
- else
- addr_type = BDADDR_LE_PUBLIC;
-
- /* If requested by client, try to synchronize to the source */
- io = bt_io_listen(NULL, confirm_cb, bcast_src, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR,
- &bass->ldb->adapter_bdaddr,
- BT_IO_OPT_DEST_BDADDR,
- &bcast_src->addr,
- BT_IO_OPT_DEST_TYPE,
- addr_type,
- BT_IO_OPT_MODE, BT_IO_MODE_ISO,
- BT_IO_OPT_QOS, &iso_qos,
- BT_IO_OPT_ISO_BC_SID, bcast_src->sid,
- BT_IO_OPT_ISO_BC_NUM_BIS, num_bis,
- BT_IO_OPT_ISO_BC_BIS, bis,
- BT_IO_OPT_INVALID);
-
- if (!io) {
- DBG(bass, "%s", err->message);
- g_error_free(err);
- goto err;
- }
-
- bcast_src->listen_io = io;
- g_io_channel_ref(bcast_src->listen_io);
-
- if (num_bis > 0 && !bcast_src->bises)
- bcast_src->bises = queue_new();
+ /* TODO: call BASS plugin callback to establish PA/BIG sync */
} else {
for (int i = 0; i < bcast_src->num_subgroups; i++)
bcast_src->subgroup_data[i].bis_sync =
@@ -1125,10 +860,6 @@ static void bass_handle_set_bcast_code_op(struct bt_bass *bass,
{
struct bt_bass_set_bcast_code_params *params;
struct bt_bcast_src *bcast_src;
- int sk, err;
- socklen_t len;
- struct bt_iso_qos qos;
- GError *gerr = NULL;
struct iovec *notif;
/* Get Set Broadcast Code command parameters */
@@ -1164,37 +895,7 @@ static void bass_handle_set_bcast_code_op(struct bt_bass *bass,
return;
}
- /* Try to sync to the source using the
- * received broadcast code
- */
- len = sizeof(qos);
- memset(&qos, 0, len);
-
- if (!bcast_src->pa_sync_io)
- return;
-
- sk = g_io_channel_unix_get_fd(bcast_src->pa_sync_io);
-
- err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len);
- if (err < 0) {
- DBG(bcast_src->bass, "Failed to get iso qos");
- return;
- }
-
- /* Update socket QoS with Broadcast Code */
- memcpy(qos.bcast.bcode, params->bcast_code, BT_BASS_BCAST_CODE_SIZE);
-
- if (setsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos,
- sizeof(qos)) < 0) {
- DBG(bcast_src->bass, "Failed to set iso qos");
- return;
- }
-
- if (!bt_io_bcast_accept(bcast_src->pa_sync_io, connect_cb,
- bcast_src, NULL, &gerr, BT_IO_OPT_INVALID)) {
- DBG(bcast_src->bass, "bt_io_bcast_accept: %s", gerr->message);
- g_error_free(gerr);
- }
+ /* TODO: Call BASS plugin callback to sync with required BIS */
}
#define BASS_OP(_str, _op, _size, _func) \
@@ -1378,18 +1079,6 @@ static void bass_bcast_src_free(void *data)
free(bcast_src->subgroup_data);
- if (bcast_src->listen_io) {
- g_io_channel_shutdown(bcast_src->listen_io, TRUE, NULL);
- g_io_channel_unref(bcast_src->listen_io);
- }
-
- if (bcast_src->pa_sync_io) {
- g_io_channel_shutdown(bcast_src->pa_sync_io, TRUE, NULL);
- g_io_channel_unref(bcast_src->pa_sync_io);
- }
-
- queue_destroy(bcast_src->bises, bass_bis_unref);
-
free(bcast_src);
}