mirror of
https://git.kernel.org/pub/scm/bluetooth/bluez.git
synced 2024-11-25 21:24:16 +08:00
input: Add support for handling sixaxis devices
This allows to handle incoming connection from unknown devices. If device happens to be sixaxis input device is created after SDP was queried and then connection is authorized.
This commit is contained in:
parent
7c6acd4cad
commit
9828feef4c
@ -63,6 +63,100 @@ static int server_cmp(gconstpointer s, gconstpointer user_data)
|
||||
return bacmp(&server->src, src);
|
||||
}
|
||||
|
||||
struct sixaxis_data {
|
||||
GIOChannel *chan;
|
||||
uint16_t psm;
|
||||
};
|
||||
|
||||
static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data);
|
||||
|
||||
static void sixaxis_sdp_cb(struct btd_device *dev, int err, void *user_data)
|
||||
{
|
||||
struct sixaxis_data *data = user_data;
|
||||
struct input_server *server;
|
||||
GError *gerr = NULL;
|
||||
const bdaddr_t *src;
|
||||
GSList *l;
|
||||
|
||||
DBG("err %d (%s)", err, strerror(-err));
|
||||
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
src = btd_adapter_get_address(device_get_adapter(dev));
|
||||
|
||||
l = g_slist_find_custom(servers, src, server_cmp);
|
||||
if (!l)
|
||||
goto fail;
|
||||
|
||||
server = l->data;
|
||||
|
||||
err = input_device_set_channel(src, device_get_address(dev),
|
||||
data->psm, data->chan);
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
|
||||
if (server->confirm) {
|
||||
if (!bt_io_accept(server->confirm, connect_event_cb, server,
|
||||
NULL, &gerr)) {
|
||||
error("bt_io_accept: %s", gerr->message);
|
||||
g_error_free(gerr);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
g_io_channel_unref(server->confirm);
|
||||
server->confirm = NULL;
|
||||
}
|
||||
|
||||
g_io_channel_unref(data->chan);
|
||||
g_free(data);
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
g_io_channel_shutdown(data->chan, TRUE, NULL);
|
||||
g_io_channel_unref(data->chan);
|
||||
g_free(data);
|
||||
}
|
||||
|
||||
static void sixaxis_browse_sdp(const bdaddr_t *src, const bdaddr_t *dst,
|
||||
GIOChannel *chan, uint16_t psm)
|
||||
{
|
||||
struct btd_device *device;
|
||||
struct sixaxis_data *data;
|
||||
|
||||
if (psm != L2CAP_PSM_HIDP_CTRL)
|
||||
return;
|
||||
|
||||
device = btd_adapter_find_device(adapter_find(src), dst);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
data = g_new0(struct sixaxis_data, 1);
|
||||
data->chan = g_io_channel_ref(chan);
|
||||
data->psm = psm;
|
||||
|
||||
device_discover_services(device);
|
||||
device_wait_for_svc_complete(device, sixaxis_sdp_cb, data);
|
||||
}
|
||||
|
||||
static bool check_sixaxis(const bdaddr_t *src, const bdaddr_t *dst)
|
||||
{
|
||||
struct btd_device *device;
|
||||
|
||||
device = btd_adapter_find_device(adapter_find(src), dst);
|
||||
if (!device)
|
||||
return false;
|
||||
|
||||
if (btd_device_get_vendor(device) != 0x054c)
|
||||
return false;
|
||||
|
||||
if (btd_device_get_product(device) != 0x0268)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data)
|
||||
{
|
||||
uint16_t psm;
|
||||
@ -95,6 +189,11 @@ static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data)
|
||||
if (ret == 0)
|
||||
return;
|
||||
|
||||
if (ret == -ENOENT && check_sixaxis(&src, &dst)) {
|
||||
sixaxis_browse_sdp(&src, &dst, chan, psm);
|
||||
return;
|
||||
}
|
||||
|
||||
error("Refusing input device connect: %s (%d)", strerror(-ret), -ret);
|
||||
|
||||
/* Send unplug virtual cable to unknown devices */
|
||||
@ -129,6 +228,9 @@ static void auth_callback(DBusError *derr, void *user_data)
|
||||
goto reject;
|
||||
}
|
||||
|
||||
if (!input_device_exists(&src, &dst) && check_sixaxis(&src, &dst))
|
||||
return;
|
||||
|
||||
if (!bt_io_accept(server->confirm, connect_event_cb, server,
|
||||
NULL, &err)) {
|
||||
error("bt_io_accept: %s", err->message);
|
||||
@ -175,7 +277,7 @@ static void confirm_event_cb(GIOChannel *chan, gpointer user_data)
|
||||
goto drop;
|
||||
}
|
||||
|
||||
if (!input_device_exists(&src, &dst)) {
|
||||
if (!input_device_exists(&src, &dst) && !check_sixaxis(&src, &dst)) {
|
||||
error("Refusing connection from %s: unknown device", addr);
|
||||
goto drop;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user