summaryrefslogtreecommitdiffstats
path: root/btio
diff options
context:
space:
mode:
Diffstat (limited to 'btio')
-rw-r--r--btio/btio.c58
-rw-r--r--btio/btio.h1
2 files changed, 54 insertions, 5 deletions
diff --git a/btio/btio.c b/btio/btio.c
index 3f5b69ad..6d71b90f 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -59,6 +59,7 @@ struct set_opts {
uint16_t omtu;
int master;
uint8_t mode;
+ int flushable;
};
struct connect {
@@ -485,8 +486,20 @@ static gboolean get_sec_level(int sock, BtIOType type, int *level,
return TRUE;
}
-static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu, uint16_t omtu,
- uint8_t mode, int master, GError **err)
+static int l2cap_set_flushable(int sock, gboolean flushable)
+{
+ int f;
+
+ f = flushable;
+ if (setsockopt(sock, SOL_BLUETOOTH, BT_FLUSHABLE, &f, sizeof(f)) < 0)
+ return -errno;
+
+ return 0;
+}
+
+static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu,
+ uint16_t omtu, uint8_t mode, int master,
+ int flushable, GError **err)
{
if (imtu || omtu || mode) {
struct l2cap_options l2o;
@@ -519,6 +532,11 @@ static gboolean l2cap_set(int sock, int sec_level, uint16_t imtu, uint16_t omtu,
return FALSE;
}
+ if (flushable >= 0 && l2cap_set_flushable(sock, flushable) < 0) {
+ ERROR_FAILED(err, "l2cap_set_flushable", errno);
+ return FALSE;
+ }
+
if (sec_level && !set_sec_level(sock, BT_IO_L2CAP, sec_level, err))
return FALSE;
@@ -643,6 +661,7 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
opts->master = -1;
opts->sec_level = BT_IO_SEC_MEDIUM;
opts->mode = L2CAP_MODE_BASIC;
+ opts->flushable = -1;
while (opt != BT_IO_OPT_INVALID) {
switch (opt) {
@@ -698,6 +717,9 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err,
case BT_IO_OPT_MODE:
opts->mode = va_arg(args, int);
break;
+ case BT_IO_OPT_FLUSHABLE:
+ opts->flushable = va_arg(args, gboolean);
+ break;
default:
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
"Unknown option %d", opt);
@@ -750,6 +772,24 @@ static int l2cap_get_info(int sock, uint16_t *handle, uint8_t *dev_class)
return 0;
}
+static int l2cap_get_flushable(int sock, gboolean *flushable)
+{
+ int f;
+ socklen_t len;
+
+ f = 0;
+ len = sizeof(f);
+ if (getsockopt(sock, SOL_BLUETOOTH, BT_FLUSHABLE, &f, &len) < 0)
+ return -errno;
+
+ if (f)
+ *flushable = TRUE;
+ else
+ *flushable = FALSE;
+
+ return 0;
+}
+
static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
va_list args)
{
@@ -760,6 +800,7 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
uint8_t dev_class[3];
uint16_t handle;
socklen_t len;
+ gboolean flushable;
len = sizeof(l2o);
memset(&l2o, 0, len);
@@ -842,6 +883,13 @@ static gboolean l2cap_get(int sock, GError **err, BtIOOption opt1,
case BT_IO_OPT_MODE:
*(va_arg(args, uint8_t *)) = l2o.mode;
break;
+ case BT_IO_OPT_FLUSHABLE:
+ if (l2cap_get_flushable(sock, &flushable) < 0) {
+ ERROR_FAILED(err, "get_flushable", errno);
+ return FALSE;
+ }
+ *(va_arg(args, gboolean *)) = flushable;
+ break;
default:
g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS,
"Unknown option %d", opt);
@@ -1115,7 +1163,7 @@ gboolean bt_io_set(GIOChannel *io, BtIOType type, GError **err,
case BT_IO_L2RAW:
case BT_IO_L2CAP:
return l2cap_set(sock, opts.sec_level, opts.imtu, opts.omtu,
- opts.mode, opts.master, err);
+ opts.mode, opts.master, opts.flushable, err);
case BT_IO_RFCOMM:
return rfcomm_set(sock, opts.sec_level, opts.master, err);
case BT_IO_SCO:
@@ -1156,7 +1204,7 @@ static GIOChannel *create_io(BtIOType type, gboolean server,
if (l2cap_bind(sock, &opts->src, server ? opts->psm : 0,
opts->cid, err) < 0)
goto failed;
- if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, err))
+ if (!l2cap_set(sock, opts->sec_level, 0, 0, 0, -1, -1, err))
goto failed;
break;
case BT_IO_L2CAP:
@@ -1169,7 +1217,7 @@ static GIOChannel *create_io(BtIOType type, gboolean server,
opts->cid, err) < 0)
goto failed;
if (!l2cap_set(sock, opts->sec_level, opts->imtu, opts->omtu,
- opts->mode, opts->master, err))
+ opts->mode, opts->master, opts->flushable, err))
goto failed;
break;
case BT_IO_RFCOMM:
diff --git a/btio/btio.h b/btio/btio.h
index 53e8eaa9..c6b736f0 100644
--- a/btio/btio.h
+++ b/btio/btio.h
@@ -64,6 +64,7 @@ typedef enum {
BT_IO_OPT_HANDLE,
BT_IO_OPT_CLASS,
BT_IO_OPT_MODE,
+ BT_IO_OPT_FLUSHABLE,
} BtIOOption;
typedef enum {