summaryrefslogtreecommitdiffstats
path: root/input/server.c
diff options
context:
space:
mode:
authorClaudio Takahasi <claudio.takahasi@openbossa.org>2007-06-21 22:06:33 +0000
committerClaudio Takahasi <claudio.takahasi@openbossa.org>2007-06-21 22:06:33 +0000
commit0bf3861da5ad7f4f2310029e2b42ae964a9e3aa5 (patch)
tree1e60662755451e4812798a0601763b5887d728ef /input/server.c
parent5fcad6abebf97c6a06d9eb5c206d5c10bcf14eb7 (diff)
input: removed session_data structure and added watch for Disconnect signal
Diffstat (limited to 'input/server.c')
-rw-r--r--input/server.c200
1 files changed, 35 insertions, 165 deletions
diff --git a/input/server.c b/input/server.c
index 2a9e08d4..0f04b06a 100644
--- a/input/server.c
+++ b/input/server.c
@@ -42,103 +42,12 @@
#include "logging.h"
#include "dbus.h"
+#include "device.h"
#include "server.h"
#include "storage.h"
-struct session_data {
- bdaddr_t src;
- bdaddr_t dst;
- int ctrl_sk;
- int intr_sk;
-};
-
-static GSList *sessions = NULL;
static DBusConnection *connection = NULL;
-static struct session_data *find_session(bdaddr_t *src, bdaddr_t *dst)
-{
- GSList *list;
-
- for (list = sessions; list != NULL; list = list->next) {
- struct session_data *session = list->data;
-
- if (!bacmp(&session->src, src) && !bacmp(&session->dst, dst))
- return session;
- }
-
- return NULL;
-}
-
-static gboolean session_event(GIOChannel *chan, GIOCondition cond, gpointer data)
-{
- if (cond & G_IO_NVAL)
- return FALSE;
-
- if (cond & (G_IO_HUP | G_IO_ERR)) {
- g_io_channel_close(chan);
- return FALSE;
- }
-
- return TRUE;
-}
-
-static void create_device(struct session_data *session)
-{
- struct hidp_connadd_req req;
- char addr[18];
- int ctl, err, timeout = 30;
-
- ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
- if (ctl < 0) {
- error("Can't open HIDP interface");
- goto cleanup;
- }
-
- ba2str(&session->dst, addr);
-
- memset(&req, 0, sizeof(req));
- req.ctrl_sock = session->ctrl_sk;
- req.intr_sock = session->intr_sk;
- req.flags = 0;
- req.idle_to = timeout * 60;
-
- if (get_stored_device_info(&session->src, &session->dst, &req) < 0) {
- error("Rejected connection from unknown device %s", addr);
- goto cleanup;
- }
-
- if (req.subclass & 0x40) {
- err = encrypt_link(&session->src, &session->dst);
- if (err < 0 && err != -ENOKEY) {
- if (req.rd_data)
- free(req.rd_data);
- goto cleanup;
- }
- }
-
- info("New input device %s (%s)", addr, req.name);
-
- if (req.vendor == 0x054c && req.product == 0x0268) {
- unsigned char buf[] = { 0x53, 0xf4, 0x42, 0x03, 0x00, 0x00 };
- err = write(session->ctrl_sk, buf, sizeof(buf));
- }
-
- err = ioctl(ctl, HIDPCONNADD, &req);
-
- close(ctl);
-
- if (req.rd_data)
- free(req.rd_data);
-
-cleanup:
- sessions = g_slist_remove(sessions, session);
-
- close(session->intr_sk);
- close(session->ctrl_sk);
-
- g_free(session);
-}
-
static void cancel_authorization(const char *addr)
{
DBusMessage *msg;
@@ -160,38 +69,39 @@ static void cancel_authorization(const char *addr)
send_message_and_unref(connection, msg);
}
+struct authorization_data {
+ bdaddr_t src;
+ bdaddr_t dst;
+};
+
static void authorization_callback(DBusPendingCall *pcall, void *data)
{
- struct session_data *session = data;
+ struct authorization_data *auth = data;
DBusMessage *reply = dbus_pending_call_steal_reply(pcall);
DBusError derr;
dbus_error_init(&derr);
- if (dbus_set_error_from_message(&derr, reply)) {
- error("Access denied: %s", derr.message);
- if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) {
- char addr[18];
- memset(addr, 0, sizeof(addr));
- ba2str(&session->dst, addr);
- cancel_authorization(addr);
- }
- dbus_error_free(&derr);
-
- sessions = g_slist_remove(sessions, session);
-
- close(session->intr_sk);
- close(session->ctrl_sk);
-
- g_free(session);
- } else {
- create_device(session);
+ if (dbus_set_error_from_message(&derr, reply) != TRUE) {
+ dbus_message_unref(reply);
+ input_device_connadd(&auth->src, &auth->dst);
+ return;
+ }
+
+ error("Authorization denied: %s", derr.message);
+ if (dbus_error_has_name(&derr, DBUS_ERROR_NO_REPLY)) {
+ char addr[18];
+ memset(addr, 0, sizeof(addr));
+ ba2str(&auth->dst, addr);
+ cancel_authorization(addr);
}
+ dbus_error_free(&derr);
dbus_message_unref(reply);
}
-static int authorize_device(struct session_data *session)
+static int authorize_device(bdaddr_t *src, bdaddr_t *dst)
{
+ struct authorization_data *auth;
DBusMessage *msg;
DBusPendingCall *pending;
char addr[18];
@@ -206,7 +116,7 @@ static int authorize_device(struct session_data *session)
}
memset(addr, 0, sizeof(addr));
- ba2str(&session->dst, addr);
+ ba2str(dst, addr);
dbus_message_append_args(msg,
DBUS_TYPE_STRING, &paddr,
DBUS_TYPE_STRING, &uuid,
@@ -216,28 +126,18 @@ static int authorize_device(struct session_data *session)
msg, &pending, -1) == FALSE)
return -EACCES;
- dbus_pending_call_set_notify(pending, authorization_callback, session, NULL);
+ auth = g_new0(struct authorization_data, 1);
+ bacpy(&auth->src, src);
+ bacpy(&auth->dst, dst);
+ dbus_pending_call_set_notify(pending, authorization_callback, auth, g_free);
dbus_pending_call_unref(pending);
dbus_message_unref(msg);
return 0;
}
-static void create_watch(int sk, struct session_data *session)
-{
- GIOChannel *io;
-
- io = g_io_channel_unix_new(sk);
-
- g_io_add_watch(io, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
- session_event, session);
-
- g_io_channel_unref(io);
-}
-
static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data)
{
- struct session_data *session;
struct sockaddr_l2 addr;
socklen_t addrlen;
bdaddr_t src, dst;
@@ -268,44 +168,14 @@ static gboolean connect_event(GIOChannel *chan, GIOCondition cond, gpointer data
debug("Incoming connection on PSM %d", psm);
- session = find_session(&src, &dst);
- if (session) {
- if (psm == 19) {
- session->intr_sk = nsk;
- if (authorize_device(session) < 0) {
- error("Authorization request failed");
- sessions = g_slist_remove(sessions, session);
-
- close(session->intr_sk);
- close(session->ctrl_sk);
-
- g_free(session);
-
- return TRUE;
- }
- debug("Waiting authorization ...");
- } else {
- error("Control channel already established");
- close(nsk);
- }
- } else {
- if (psm == 17) {
- session = g_new0(struct session_data, 1);
-
- bacpy(&session->src, &src);
- bacpy(&session->dst, &dst);
- session->ctrl_sk = nsk;
- session->intr_sk = -1;
-
- sessions = g_slist_append(sessions, session);
-
- create_watch(nsk, session);
- } else {
- error("No control channel available");
- close(nsk);
- }
+ if (input_device_set_channel(&src, &dst, psm, nsk) < 0) {
+ input_device_close_channels(&src, &dst);
+ return TRUE;
}
+ if ((psm == L2CAP_PSM_HIDP_INTR) && (authorize_device(&src, &dst) < 0))
+ input_device_close_channels(&src, &dst);
+
return TRUE;
}
@@ -347,14 +217,14 @@ static GIOChannel *intr_io = NULL;
int server_start(DBusConnection *conn)
{
- ctrl_io = setup_l2cap(17);
+ ctrl_io = setup_l2cap(L2CAP_PSM_HIDP_CTRL);
if (!ctrl_io) {
error("Failed to listen on control channel");
return -1;
}
g_io_channel_set_close_on_unref(ctrl_io, TRUE);
- intr_io = setup_l2cap(19);
+ intr_io = setup_l2cap(L2CAP_PSM_HIDP_INTR);
if (!intr_io) {
error("Failed to listen on interrupt channel");
g_io_channel_unref(ctrl_io);