@@ -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:
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@samsung.com> --- btio/btio.c | 25 +++++++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-)