diff --git a/bluez/btio/btio.c b/bluez/btio/btio.c index a95e33b..909fd08 100644 --- a/bluez/btio/btio.c +++ b/bluez/btio/btio.c @@ -65,6 +65,7 @@ struct set_opts { uint8_t mode; int flushable; uint32_t priority; + int timeout; }; struct connect { @@ -172,11 +173,27 @@ static int l2cap_bind(int sock, const bdaddr_t *src, uint16_t psm, } static int l2cap_connect(int sock, const bdaddr_t *dst, uint8_t dst_type, - uint16_t psm, uint16_t cid) + uint16_t psm, uint16_t cid, uint16_t timeout) { int err; struct sockaddr_l2 addr; + if (timeout > 0) { + struct timeval timeout; + timeout.tv_sec = 2; + timeout.tv_usec = 0; + + if (setsockopt (sock, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout, sizeof(timeout)) < 0) { + fprintf(stderr, "l2cap_connect: Failed to setsockopt for receive timeout.\n"); + return -1; + } + + if (setsockopt (sock, SOL_SOCKET, SO_SNDTIMEO, (char *)&timeout, sizeof(timeout)) < 0) { + fprintf(stderr, "l2cap_connect: Failed to setsockopt for sending timeout.\n"); + return -1; + } + } + memset(&addr, 0, sizeof(addr)); addr.l2_family = AF_BLUETOOTH; bacpy(&addr.l2_bdaddr, dst); @@ -599,6 +616,7 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err, opts->flushable = -1; opts->priority = 0; opts->dst_type = BDADDR_BREDR; + opts->timeout = 0; while (opt != BT_IO_OPT_INVALID) { switch (opt) { @@ -660,6 +678,9 @@ static gboolean parse_set_opts(struct set_opts *opts, GError **err, case BT_IO_OPT_PRIORITY: opts->priority = va_arg(args, int); break; + case BT_IO_OPT_TIMEOUT: + opts->timeout = va_arg(args, int); + break; default: g_set_error(err, BT_IO_ERROR, BT_IO_ERROR_INVALID_ARGS, "Unknown option %d", opt); @@ -1245,12 +1266,12 @@ GIOChannel *bt_io_connect(BtIOType type, BtIOConnect connect, switch (type) { case BT_IO_L2RAW: err = l2cap_connect(sock, &opts.dst, opts.dst_type, 0, - opts.cid); + opts.cid, opts.timeout); break; case BT_IO_L2CAP: case BT_IO_L2ERTM: err = l2cap_connect(sock, &opts.dst, opts.dst_type, - opts.psm, opts.cid); + opts.psm, opts.cid, opts.timeout); break; case BT_IO_RFCOMM: err = rfcomm_connect(sock, &opts.dst, opts.channel); diff --git a/bluez/btio/btio.h b/bluez/btio/btio.h index d4d1489..6b0962f 100644 --- a/bluez/btio/btio.h +++ b/bluez/btio/btio.h @@ -70,6 +70,7 @@ typedef enum { BT_IO_OPT_MODE, BT_IO_OPT_FLUSHABLE, BT_IO_OPT_PRIORITY, + BT_IO_OPT_TIMEOUT } BtIOOption; typedef enum { diff --git a/src/gattlib_connect.c b/src/gattlib_connect.c index 1af7b80..febefd4 100644 --- a/src/gattlib_connect.c +++ b/src/gattlib_connect.c @@ -207,6 +207,7 @@ static gatt_connection_t *initialize_gattlib_connection(const gchar *src, const BT_IO_OPT_DEST_TYPE, dest_type, BT_IO_OPT_CID, ATT_CID, BT_IO_OPT_SEC_LEVEL, sec_level, + BT_IO_OPT_TIMEOUT, 2, BT_IO_OPT_INVALID); else conn->io = bt_io_connect(BT_IO_L2CAP, io_connect_cb, io_connect_arg, NULL, &err, @@ -215,6 +216,7 @@ static gatt_connection_t *initialize_gattlib_connection(const gchar *src, const BT_IO_OPT_PSM, psm, BT_IO_OPT_IMTU, mtu, BT_IO_OPT_SEC_LEVEL, sec_level, + BT_IO_OPT_TIMEOUT, 2, BT_IO_OPT_INVALID); if (err) {