This patch adds support for the BT_IO_PHY socket option through BtIO. This can be used to set preference for LE TX & RX PHYs for a particular connection. Reviewed-by: Anupam Roy <anupam.r@xxxxxxxxxxx> --- btio/btio.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/btio/btio.c b/btio/btio.c index 1f1c374bc..6805ac438 100644 --- a/btio/btio.c +++ b/btio/btio.c @@ -66,6 +66,7 @@ struct set_opts { int flushable; uint32_t priority; uint16_t voice; + uint32_t phy; }; struct connect { @@ -569,6 +570,14 @@ static int set_priority(int sock, uint32_t prio) return 0; } +static int l2cap_set_le_phy(int sock, uint32_t phy) +{ + if (setsockopt(sock, SOL_BLUETOOTH, BT_PHY, &phy, sizeof(phy)) < 0) + return -errno; + + return 0; +} + static gboolean get_key_size(int sock, int *size, GError **err) { struct bt_security sec; @@ -657,7 +666,7 @@ static gboolean set_le_mode(int sock, uint8_t mode, GError **err) static gboolean l2cap_set(int sock, uint8_t src_type, int sec_level, uint16_t imtu, uint16_t omtu, uint8_t mode, int master, int flushable, uint32_t priority, - GError **err) + uint32_t phy, GError **err) { if (imtu || omtu || mode) { gboolean ret = FALSE; @@ -694,6 +703,11 @@ static gboolean l2cap_set(int sock, uint8_t src_type, int sec_level, if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err)) return FALSE; + if (phy > 0 && l2cap_set_le_phy(sock, phy) < 0) { + ERROR_FAILED(err, "l2cap_set_le_phy", errno); + return FALSE; + } + return TRUE; } @@ -834,6 +848,7 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err, opts->priority = 0; opts->src_type = BDADDR_BREDR; opts->dst_type = BDADDR_BREDR; + opts->phy = 0; while (opt != BT_IO_OPT_INVALID) { switch (opt) { @@ -904,13 +919,15 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err, case BT_IO_OPT_VOICE: opts->voice = va_arg(args, int); break; + case BT_IO_OPT_PHY: + opts->phy = va_arg(args, int); + break; case BT_IO_OPT_INVALID: case BT_IO_OPT_KEY_SIZE: case BT_IO_OPT_SOURCE_CHANNEL: case BT_IO_OPT_DEST_CHANNEL: case BT_IO_OPT_HANDLE: case BT_IO_OPT_CLASS: - case BT_IO_OPT_PHY: default: g_set_error(err, BT_IO_ERROR, EINVAL, "Unknown option %d", opt); @@ -1579,7 +1596,7 @@ gboolean bt_io_set(GIOChannel *io, GError **err, BtIOOption opt1, ...) case BT_IO_L2CAP: return l2cap_set(sock, opts.src_type, opts.sec_level, opts.imtu, opts.omtu, opts.mode, opts.master, - opts.flushable, opts.priority, err); + opts.flushable, opts.priority, opts.phy, err); case BT_IO_RFCOMM: return rfcomm_set(sock, opts.sec_level, opts.master, err); case BT_IO_SCO: @@ -1629,7 +1646,7 @@ static GIOChannel *create_io(gboolean server, struct set_opts *opts, if (!l2cap_set(sock, opts->src_type, opts->sec_level, opts->imtu, opts->omtu, opts->mode, opts->master, opts->flushable, opts->priority, - err)) + opts->phy, err)) goto failed; break; case BT_IO_RFCOMM: -- 2.17.1