mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-17 09:14:32 +08:00
Make bt_l2cap_connect to take mtu as paramter.
This commit is contained in:
parent
319f3d5167
commit
f85b9560ec
@ -1590,7 +1590,7 @@ static int l2cap_connect(struct avdtp *session)
|
||||
{
|
||||
int err;
|
||||
|
||||
err = bt_l2cap_connect(&session->src, &session->dst, AVDTP_PSM,
|
||||
err = bt_l2cap_connect(&session->src, &session->dst, AVDTP_PSM, 0,
|
||||
l2cap_connect_cb, session);
|
||||
if (err < 0) {
|
||||
error("Connect failed. %s(%d)", strerror(-err), -err);
|
||||
|
@ -440,8 +440,11 @@ static int sco_connect(struct io_context *io_ctxt, const bdaddr_t *src,
|
||||
}
|
||||
|
||||
static int l2cap_connect(struct io_context *io_ctxt, const bdaddr_t *src,
|
||||
const bdaddr_t *dst, uint16_t psm)
|
||||
const bdaddr_t *dst, uint16_t psm,
|
||||
uint16_t mtu)
|
||||
{
|
||||
struct l2cap_options l2o;
|
||||
socklen_t olen;
|
||||
struct sockaddr_l2 l2a;
|
||||
int sk, err;
|
||||
|
||||
@ -449,6 +452,14 @@ static int l2cap_connect(struct io_context *io_ctxt, const bdaddr_t *src,
|
||||
if (sk < 0)
|
||||
return -errno;
|
||||
|
||||
if (mtu) {
|
||||
memset(&l2o, 0, sizeof(l2o));
|
||||
olen = sizeof(l2o);
|
||||
getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);
|
||||
l2o.imtu = l2o.omtu = mtu;
|
||||
setsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));
|
||||
}
|
||||
|
||||
memset(&l2a, 0, sizeof(l2a));
|
||||
l2a.l2_family = AF_BLUETOOTH;
|
||||
bacpy(&l2a.l2_bdaddr, src);
|
||||
@ -551,7 +562,7 @@ int bt_rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
}
|
||||
|
||||
int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
uint16_t psm, bt_io_callback_t cb, void *user_data)
|
||||
uint16_t psm, uint16_t mtu, bt_io_callback_t cb, void *user_data)
|
||||
{
|
||||
struct io_context *io_ctxt;
|
||||
int err;
|
||||
@ -560,7 +571,7 @@ int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
err = l2cap_connect(io_ctxt, src, dst, psm);
|
||||
err = l2cap_connect(io_ctxt, src, dst, psm, mtu);
|
||||
if (err < 0) {
|
||||
io_context_cleanup(io_ctxt);
|
||||
return err;
|
||||
|
@ -39,6 +39,7 @@ GSList *bt_string2list(const gchar *str);
|
||||
int bt_rfcomm_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
uint8_t channel, bt_io_callback_t cb, void *user_data);
|
||||
int bt_l2cap_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
uint16_t psm, bt_io_callback_t cb, void *user_data);
|
||||
uint16_t psm, uint16_t mtu, bt_io_callback_t cb,
|
||||
void *user_data);
|
||||
int bt_sco_connect(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
bt_io_callback_t cb, void *user_data);
|
||||
|
@ -605,7 +605,7 @@ static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data)
|
||||
idev->ctrl_sk = g_io_channel_unix_get_fd(chan);
|
||||
|
||||
/* Connect to the HID interrupt channel */
|
||||
err = bt_l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_INTR,
|
||||
err = bt_l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_INTR, 0,
|
||||
interrupt_connect_cb, idev);
|
||||
if (err < 0) {
|
||||
error("L2CAP connect failed:%s (%d)", strerror(-err), -err);
|
||||
@ -766,7 +766,7 @@ static DBusHandlerResult device_connect(DBusConnection *conn,
|
||||
}
|
||||
|
||||
/* HID devices */
|
||||
err = bt_l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_CTRL,
|
||||
err = bt_l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_CTRL, 0,
|
||||
control_connect_cb, idev);
|
||||
if (err < 0) {
|
||||
error("L2CAP connect failed: %s(%d)", strerror(-err), -err);
|
||||
|
@ -283,7 +283,7 @@ static void control_connect_cb(GIOChannel *chan, int err, gpointer user_data)
|
||||
pr->ctrl_channel = chan;
|
||||
|
||||
/* Connect to the HID interrupt channel */
|
||||
err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR,
|
||||
err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_INTR, 0,
|
||||
interrupt_connect_cb, pr);
|
||||
if (err < 0) {
|
||||
error("L2CAP connect failed:%s (%d)", strerror(-err), -err);
|
||||
@ -317,7 +317,7 @@ static void create_bonding_reply(DBusPendingCall *call, void *data)
|
||||
|
||||
dbus_message_unref(reply);
|
||||
|
||||
err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL,
|
||||
err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, 0,
|
||||
control_connect_cb, pr);
|
||||
if (err < 0) {
|
||||
error("L2CAP connect failed:%s (%d)", strerror(-err), -err);
|
||||
@ -391,7 +391,7 @@ static void hid_record_cb(sdp_list_t *recs, int err, gpointer user_data)
|
||||
}
|
||||
|
||||
/* No encryption or link key already exists -- connect control channel */
|
||||
err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL,
|
||||
err = bt_l2cap_connect(&pr->src, &pr->dst, L2CAP_PSM_HIDP_CTRL, 0,
|
||||
control_connect_cb, pr);
|
||||
if (err < 0) {
|
||||
error("L2CAP connect failed:%s (%d)", strerror(-err), -err);
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <bluetooth/hci_lib.h>
|
||||
#include <bluetooth/l2cap.h>
|
||||
#include <bluetooth/bnep.h>
|
||||
#include <bluetooth/sdp.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
@ -43,6 +44,7 @@
|
||||
#include "dbus.h"
|
||||
#include "dbus-helper.h"
|
||||
#include "textfile.h"
|
||||
#include "glib-helper.h"
|
||||
|
||||
#include "error.h"
|
||||
#include "common.h"
|
||||
@ -221,102 +223,30 @@ out:
|
||||
return err;
|
||||
}
|
||||
|
||||
static gboolean l2cap_connect_cb(GIOChannel *chan,
|
||||
GIOCondition cond, gpointer data)
|
||||
static void connect_cb(GIOChannel *chan, int err, gpointer data)
|
||||
{
|
||||
struct network_conn *nc = data;
|
||||
socklen_t len;
|
||||
int sk, ret;
|
||||
|
||||
if (cond & G_IO_NVAL)
|
||||
return FALSE;
|
||||
|
||||
if (cond & (G_IO_ERR | G_IO_HUP))
|
||||
goto failed;
|
||||
|
||||
sk = g_io_channel_unix_get_fd(chan);
|
||||
|
||||
len = sizeof(ret);
|
||||
if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) {
|
||||
error("getsockopt(SO_ERROR): %s (%d)", strerror(errno), errno);
|
||||
if (err < 0) {
|
||||
error("l2cap connect(): %s (%d)", strerror(-err), -err);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (ret != 0) {
|
||||
error("connect(): %s (%d)", strerror(errno), errno);
|
||||
nc->sk = g_io_channel_unix_get_fd(chan);
|
||||
|
||||
err = bnep_connect(nc);
|
||||
if (err < 0) {
|
||||
error("bnep connect(): %s (%d)", strerror(-err), -err);
|
||||
g_io_channel_close(chan);
|
||||
g_io_channel_unref(chan);
|
||||
goto failed;
|
||||
}
|
||||
|
||||
if (bnep_connect(nc)) {
|
||||
error("connect(): %s (%d)", strerror(errno), errno);
|
||||
goto failed;
|
||||
}
|
||||
return;
|
||||
|
||||
return FALSE;
|
||||
failed:
|
||||
nc->state = DISCONNECTED;
|
||||
error_connection_attempt_failed(connection, nc->msg, errno);
|
||||
g_io_channel_close(chan);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static int l2cap_connect(struct network_conn *nc)
|
||||
{
|
||||
struct l2cap_options l2o;
|
||||
struct sockaddr_l2 l2a;
|
||||
socklen_t olen;
|
||||
char addr[18];
|
||||
GIOChannel *io;
|
||||
|
||||
ba2str(&nc->dst, addr);
|
||||
info("Connecting to %s", addr);
|
||||
|
||||
/* Setup L2CAP options according to BNEP spec */
|
||||
memset(&l2o, 0, sizeof(l2o));
|
||||
olen = sizeof(l2o);
|
||||
getsockopt(nc->sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &olen);
|
||||
l2o.imtu = l2o.omtu = BNEP_MTU;
|
||||
setsockopt(nc->sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, sizeof(l2o));
|
||||
|
||||
memset(&l2a, 0, sizeof(l2a));
|
||||
l2a.l2_family = AF_BLUETOOTH;
|
||||
bacpy(&l2a.l2_bdaddr, &nc->src);
|
||||
|
||||
if (bind(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a)) < 0) {
|
||||
error("Bind failed. %s(%d)", strerror(errno), errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
memset(&l2a, 0, sizeof(l2a));
|
||||
l2a.l2_family = AF_BLUETOOTH;
|
||||
bacpy(&l2a.l2_bdaddr, &nc->dst);
|
||||
l2a.l2_psm = htobs(BNEP_PSM);
|
||||
|
||||
if (set_nonblocking(nc->sk) < 0) {
|
||||
error("Set non blocking: %s (%d)", strerror(errno), errno);
|
||||
return -errno;
|
||||
}
|
||||
|
||||
io = g_io_channel_unix_new(nc->sk);
|
||||
g_io_channel_set_close_on_unref(io, FALSE);
|
||||
|
||||
if (connect(nc->sk, (struct sockaddr *) &l2a, sizeof(l2a))) {
|
||||
if (!(errno == EAGAIN || errno == EINPROGRESS)) {
|
||||
error("Connect failed. %s(%d)", strerror(errno),
|
||||
errno);
|
||||
g_io_channel_close(io);
|
||||
g_io_channel_unref(io);
|
||||
return -errno;
|
||||
}
|
||||
g_io_add_watch(io, G_IO_OUT | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
|
||||
(GIOFunc) l2cap_connect_cb, nc);
|
||||
|
||||
} else {
|
||||
l2cap_connect_cb(io, G_IO_OUT, nc);
|
||||
}
|
||||
|
||||
g_io_channel_unref(io);
|
||||
return 0;
|
||||
error_connection_attempt_failed(connection, nc->msg, -err);
|
||||
}
|
||||
|
||||
static DBusHandlerResult get_adapter(DBusConnection *conn, DBusMessage *msg,
|
||||
@ -448,6 +378,7 @@ static DBusHandlerResult connection_connect(DBusConnection *conn,
|
||||
{
|
||||
struct network_conn *nc = data;
|
||||
DBusError derr;
|
||||
int err;
|
||||
|
||||
if (nc->state != DISCONNECTED) {
|
||||
error_failed(conn, msg, "Device already connected");
|
||||
@ -462,16 +393,12 @@ static DBusHandlerResult connection_connect(DBusConnection *conn,
|
||||
return DBUS_HANDLER_RESULT_HANDLED;
|
||||
}
|
||||
|
||||
nc->sk = socket(AF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
|
||||
nc->state = CONNECTING;
|
||||
if (nc->sk < 0) {
|
||||
error("Cannot create L2CAP socket. %s(%d)", strerror(errno),
|
||||
errno);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
nc->msg = dbus_message_ref(msg);
|
||||
if (l2cap_connect(nc) < 0) {
|
||||
|
||||
err = bt_l2cap_connect(&nc->src, &nc->dst, BNEP_PSM, BNEP_MTU,
|
||||
connect_cb, nc);
|
||||
if (err < 0) {
|
||||
error("Connect failed. %s(%d)", strerror(errno), errno);
|
||||
goto fail;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user