diff --git a/src/shared/mgmt.c b/src/shared/mgmt.c
index b869fa6..cec8993 100644
--- a/src/shared/mgmt.c
+++ b/src/shared/mgmt.c
bool in_notify;
void *buf;
uint16_t len;
+ uint16_t mtu;
mgmt_debug_func_t debug_callback;
mgmt_destroy_func_t debug_destroy;
void *debug_data;
return true;
}
+static void mgmt_set_mtu(struct mgmt *mgmt)
+{
+ socklen_t len = 0;
+
+ /* Check if kernel support BT_SNDMTU to read the current MTU set */
+ if (getsockopt(mgmt->fd, SOL_BLUETOOTH, BT_SNDMTU, &mgmt->mtu,
+ &len) < 0) {
+ /* If BT_SNDMTU is not supported then MTU cannot be changed and
+ * MTU is fixed to HCI_MAX_ACL_SIZE.
+ */
+ mgmt->mtu = HCI_MAX_ACL_SIZE;
+ return;
+ }
+
+ if (mgmt->mtu < UINT16_MAX) {
+ uint16_t mtu = UINT16_MAX;
+
+ /* Try increasing the MTU since some commands may go
+ * over HCI_MAX_ACL_SIZE (1024)
+ */
+ if (!setsockopt(mgmt->fd, SOL_BLUETOOTH, BT_SNDMTU, &mtu,
+ sizeof(mtu)))
+ mgmt->mtu = mtu;
+ }
+}
+
struct mgmt *mgmt_new(int fd)
{
struct mgmt *mgmt;
mgmt->writer_active = false;
+ mgmt_set_mtu(mgmt);
+
return mgmt_ref(mgmt);
}
return true;
}
-static struct mgmt_request *create_request(uint16_t opcode, uint16_t index,
- uint16_t length, const void *param,
- mgmt_request_func_t callback,
+static struct mgmt_request *create_request(struct mgmt *mgmt, uint16_t opcode,
+ uint16_t index, uint16_t length,
+ const void *param, mgmt_request_func_t callback,
void *user_data, mgmt_destroy_func_t destroy)
{
struct mgmt_request *request;
if (length > 0 && !param)
return NULL;
+ if (length > mgmt->mtu) {
+ printf("length %u > %u mgmt->mtu", length, mgmt->mtu);
+ return NULL;
+ }
+
request = new0(struct mgmt_request, 1);
request->len = length + MGMT_HDR_SIZE;
request->buf = malloc(request->len);
if (!mgmt)
return 0;
- request = create_request(opcode, index, length, param,
+ request = create_request(mgmt, opcode, index, length, param,
callback, user_data, destroy);
if (!request)
return 0;
if (!mgmt)
return 0;
- request = create_request(opcode, index, length, param,
+ request = create_request(mgmt, opcode, index, length, param,
callback, user_data, destroy);
if (!request)
return 0;
if (!mgmt)
return 0;
- request = create_request(opcode, index, length, param,
+ request = create_request(mgmt, opcode, index, length, param,
callback, user_data, destroy);
if (!request)
return 0;