mirror of git://git.sysmocom.de/ofono
btio: add BT_IO_OPT_PRIORITY option
BT_IO_OPT_PRIORITY uses SO_PRIORITY to set the priority of the socket
This commit is contained in:
parent
5086f5f43a
commit
177f45bb91
47
btio/btio.c
47
btio/btio.c
|
@ -64,6 +64,7 @@ struct set_opts {
|
||||||
int master;
|
int master;
|
||||||
uint8_t mode;
|
uint8_t mode;
|
||||||
int flushable;
|
int flushable;
|
||||||
|
uint32_t priority;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct connect {
|
struct connect {
|
||||||
|
@ -502,9 +503,17 @@ static int l2cap_set_flushable(int sock, gboolean flushable)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_priority(int sock, uint32_t prio)
|
||||||
|
{
|
||||||
|
if (setsockopt(sock, SOL_SOCKET, SO_PRIORITY, &prio, sizeof(prio)) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu,
|
static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu,
|
||||||
uint16_t omtu, uint8_t mode, int master,
|
uint16_t omtu, uint8_t mode, int master,
|
||||||
int flushable, GError **err)
|
int flushable, uint32_t priority, GError **err)
|
||||||
{
|
{
|
||||||
if (imtu || omtu || mode) {
|
if (imtu || omtu || mode) {
|
||||||
struct l2cap_options l2o;
|
struct l2cap_options l2o;
|
||||||
|
@ -542,6 +551,11 @@ static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu,
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (priority > 0 && set_priority(sock, priority) < 0) {
|
||||||
|
ERROR_FAILED(err, "set_priority", errno);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err))
|
if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
|
@ -669,6 +683,7 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
|
||||||
opts->sec_level = BT_IO_SEC_MEDIUM;
|
opts->sec_level = BT_IO_SEC_MEDIUM;
|
||||||
opts->mode = L2CAP_MODE_BASIC;
|
opts->mode = L2CAP_MODE_BASIC;
|
||||||
opts->flushable = -1;
|
opts->flushable = -1;
|
||||||
|
opts->priority = 0;
|
||||||
|
|
||||||
while (opt != BT_IO_OPT_INVALID) {
|
while (opt != BT_IO_OPT_INVALID) {
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
@ -727,6 +742,9 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
|
||||||
case BT_IO_OPT_FLUSHABLE:
|
case BT_IO_OPT_FLUSHABLE:
|
||||||
opts->flushable = va_arg(args, gboolean);
|
opts->flushable = va_arg(args, gboolean);
|
||||||
break;
|
break;
|
||||||
|
case BT_IO_OPT_PRIORITY:
|
||||||
|
opts->priority = va_arg(args, int);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
|
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
|
||||||
"Unknown option %d", opt);
|
"Unknown option %d", opt);
|
||||||
|
@ -797,6 +815,17 @@ static int l2cap_get_flushable(int sock, gboolean *flushable)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int get_priority(int sock, uint32_t *prio)
|
||||||
|
{
|
||||||
|
socklen_t len;
|
||||||
|
|
||||||
|
len = sizeof(*prio);
|
||||||
|
if (getsockopt(sock, SOL_SOCKET, SO_PRIORITY, prio, &len) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
|
static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
|
||||||
va_list args)
|
va_list args)
|
||||||
{
|
{
|
||||||
|
@ -808,6 +837,7 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
|
||||||
uint16_t handle;
|
uint16_t handle;
|
||||||
socklen_t len;
|
socklen_t len;
|
||||||
gboolean flushable = FALSE;
|
gboolean flushable = FALSE;
|
||||||
|
uint32_t priority;
|
||||||
|
|
||||||
len = sizeof(l2o);
|
len = sizeof(l2o);
|
||||||
memset(&l2o, 0, len);
|
memset(&l2o, 0, len);
|
||||||
|
@ -897,6 +927,13 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
|
||||||
}
|
}
|
||||||
*(va_arg(args, gboolean *)) = flushable;
|
*(va_arg(args, gboolean *)) = flushable;
|
||||||
break;
|
break;
|
||||||
|
case BT_IO_OPT_PRIORITY:
|
||||||
|
if (get_priority(sock, &priority) < 0) {
|
||||||
|
ERROR_FAILED(err, "get_priority", errno);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
*(va_arg(args, uint32_t *)) = priority;
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
|
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
|
||||||
"Unknown option %d", opt);
|
"Unknown option %d", opt);
|
||||||
|
@ -1172,7 +1209,8 @@ gboolean bt_io_set(GIOChannel *io, BtIOType type, GError **err,
|
||||||
case BT_IO_L2RAW:
|
case BT_IO_L2RAW:
|
||||||
case BT_IO_L2CAP:
|
case BT_IO_L2CAP:
|
||||||
return l2cap_set(sock, opts.sec_level, opts.imtu, opts.omtu,
|
return l2cap_set(sock, opts.sec_level, opts.imtu, opts.omtu,
|
||||||
opts.mode, opts.master, opts.flushable, err);
|
opts.mode, opts.master, opts.flushable,
|
||||||
|
opts.priority, err);
|
||||||
case BT_IO_RFCOMM:
|
case BT_IO_RFCOMM:
|
||||||
return rfcomm_set(sock, opts.sec_level, opts.master, err);
|
return rfcomm_set(sock, opts.sec_level, opts.master, err);
|
||||||
case BT_IO_SCO:
|
case BT_IO_SCO:
|
||||||
|
@ -1213,7 +1251,7 @@ static GIOChannel *create_io(BtIOType type, gboolean server,
|
||||||
if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0,
|
if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0,
|
||||||
opts->cid, err) < 0)
|
opts->cid, err) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, -1, err))
|
if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, -1, 0, err))
|
||||||
goto failed;
|
goto failed;
|
||||||
break;
|
break;
|
||||||
case BT_IO_L2CAP:
|
case BT_IO_L2CAP:
|
||||||
|
@ -1226,7 +1264,8 @@ static GIOChannel *create_io(BtIOType type, gboolean server,
|
||||||
opts->cid, err) < 0)
|
opts->cid, err) < 0)
|
||||||
goto failed;
|
goto failed;
|
||||||
if (!l2cap_set(sock, opts->sec_level, opts->imtu, opts->omtu,
|
if (!l2cap_set(sock, opts->sec_level, opts->imtu, opts->omtu,
|
||||||
opts->mode, opts->master, opts->flushable, err))
|
opts->mode, opts->master, opts->flushable,
|
||||||
|
opts->priority, err))
|
||||||
goto failed;
|
goto failed;
|
||||||
break;
|
break;
|
||||||
case BT_IO_RFCOMM:
|
case BT_IO_RFCOMM:
|
||||||
|
|
|
@ -65,6 +65,7 @@ typedef enum {
|
||||||
BT_IO_OPT_CLASS,
|
BT_IO_OPT_CLASS,
|
||||||
BT_IO_OPT_MODE,
|
BT_IO_OPT_MODE,
|
||||||
BT_IO_OPT_FLUSHABLE,
|
BT_IO_OPT_FLUSHABLE,
|
||||||
|
BT_IO_OPT_PRIORITY,
|
||||||
} BtIOOption;
|
} BtIOOption;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
|
Loading…
Reference in New Issue