#endif
#include <stdio.h>
+#include <stdbool.h>
#include <errno.h>
#include <ctype.h>
#include <fcntl.h>
}
}
+static int getopts(int sk, struct l2cap_options *opts, bool connected)
+{
+ socklen_t optlen;
+ int err;
+
+ memset(opts, 0, sizeof(*opts));
+
+ if (bdaddr_type == BDADDR_BREDR || cid) {
+ optlen = sizeof(*opts);
+ return getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts, &optlen);
+ }
+
+ optlen = sizeof(opts->imtu);
+ err = getsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU, &opts->imtu, &optlen);
+ if (err < 0 || !connected)
+ return err;
+
+ optlen = sizeof(opts->omtu);
+ return getsockopt(sk, SOL_BLUETOOTH, BT_SNDMTU, &opts->omtu, &optlen);
+}
+
+static int setopts(int sk, struct l2cap_options *opts)
+{
+ if (bdaddr_type == BDADDR_BREDR || cid)
+ return setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, opts,
+ sizeof(opts));
+
+ return setsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU, &opts->imtu,
+ sizeof(opts->imtu));
+}
+
static int do_connect(char *svr)
{
struct sockaddr_l2 addr;
}
/* Get default options */
- memset(&opts, 0, sizeof(opts));
- optlen = sizeof(opts);
-
- if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+ if (getopts(sk, &opts, false) < 0) {
syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)",
- strerror(errno), errno);
+ strerror(errno), errno);
goto error;
}
opts.txwin_size = txwin_size;
opts.max_tx = max_transmit;
- if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) {
+ if (setopts(sk, &opts) < 0) {
syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)",
strerror(errno), errno);
goto error;
}
/* Get current options */
- memset(&opts, 0, sizeof(opts));
- optlen = sizeof(opts);
-
- if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+ if (getopts(sk, &opts, true) < 0) {
syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)",
strerror(errno), errno);
goto error;
}
/* Get default options */
- memset(&opts, 0, sizeof(opts));
- optlen = sizeof(opts);
-
- if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+ if (getopts(sk, &opts, false) < 0) {
syslog(LOG_ERR, "Can't get default L2CAP options: %s (%d)",
strerror(errno), errno);
goto error;
opts.txwin_size = txwin_size;
opts.max_tx = max_transmit;
- if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &opts, sizeof(opts)) < 0) {
+ if (setopts(sk, &opts) < 0) {
syslog(LOG_ERR, "Can't set L2CAP options: %s (%d)",
strerror(errno), errno);
goto error;
}
/* Get current options */
- memset(&opts, 0, sizeof(opts));
- optlen = sizeof(opts);
-
- if (getsockopt(nsk, SOL_L2CAP, L2CAP_OPTIONS, &opts, &optlen) < 0) {
+ if (getopts(nsk, &opts, true) < 0) {
syslog(LOG_ERR, "Can't get L2CAP options: %s (%d)",
strerror(errno), errno);
if (!defer_setup) {