From c8260c5acb07379b7de9754b65ec677ae96907d4 Mon Sep 17 00:00:00 2001 From: Szymon Janc Date: Mon, 20 Jan 2014 12:08:32 +0100 Subject: [PATCH] lib: Add flag to force large MTU size used for SDP connection This will allow to workaround Dualshock4 not respecting L2CAP MTU size while sending SDP response. Use same L2CAP MTU value base on RFCOMM. --- lib/sdp.c | 27 +++++++++++++++++++++++++++ lib/sdp_lib.h | 1 + 2 files changed, 28 insertions(+) diff --git a/lib/sdp.c b/lib/sdp.c index 886e7cffa..3b26ec3f3 100644 --- a/lib/sdp.c +++ b/lib/sdp.c @@ -67,6 +67,9 @@ static uint128_t bluetooth_base_uuid = { #define SDP_MAX_ATTR_LEN 65535 +/* match MTU used by RFCOMM */ +#define SDP_LARGE_L2CAP_MTU 1013 + static sdp_data_t *sdp_copy_seq(sdp_data_t *data); static int sdp_attr_add_new_with_length(sdp_record_t *rec, uint16_t attr, uint8_t dtd, const void *value, uint32_t len); @@ -4644,6 +4647,26 @@ static int sdp_connect_local(sdp_session_t *session) return connect(session->sock, (struct sockaddr *) &sa, sizeof(sa)); } +static int set_l2cap_mtu(int sk, uint16_t mtu) +{ + struct l2cap_options l2o; + socklen_t len; + + memset(&l2o, 0, sizeof(l2o)); + len = sizeof(l2o); + + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) + return -1; + + l2o.imtu = mtu; + l2o.omtu = mtu; + + if (setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o)) < 0) + return -1; + + return 0; +} + static int sdp_connect_l2cap(const bdaddr_t *src, const bdaddr_t *dst, sdp_session_t *session) { @@ -4678,6 +4701,10 @@ static int sdp_connect_l2cap(const bdaddr_t *src, setsockopt(sk, SOL_SOCKET, SO_LINGER, &l, sizeof(l)); } + if ((flags & SDP_LARGE_MTU) && + set_l2cap_mtu(sk, SDP_LARGE_L2CAP_MTU) < 0) + return -1; + sa.l2_psm = htobs(SDP_PSM); sa.l2_bdaddr = *dst; diff --git a/lib/sdp_lib.h b/lib/sdp_lib.h index 6e1eb91a6..3ded3934c 100644 --- a/lib/sdp_lib.h +++ b/lib/sdp_lib.h @@ -81,6 +81,7 @@ static inline void sdp_list_foreach(sdp_list_t *list, sdp_list_func_t f, void *u #define SDP_RETRY_IF_BUSY 0x01 #define SDP_WAIT_ON_CLOSE 0x02 #define SDP_NON_BLOCKING 0x04 +#define SDP_LARGE_MTU 0x08 /* * a session with an SDP server -- 2.47.3