summaryrefslogtreecommitdiff
path: root/profiles
diff options
context:
space:
mode:
authorDoHyun Pyun <dh79.pyun@samsung.com>2016-08-12 17:51:55 +0900
committerDoHyun Pyun <dh79.pyun@samsung.com>2016-08-12 18:02:20 +0900
commit0407e3f0b7b799c7b0d831291ee4577419f1dcee (patch)
tree4c09f1a6b1d28c8577bcb00d2beb9c22768e831c /profiles
parent94de77a7568dcd267b5b5e47206a40d1bbfc0f92 (diff)
downloadbluez-0407e3f0b7b799c7b0d831291ee4577419f1dcee.tar.gz
bluez-0407e3f0b7b799c7b0d831291ee4577419f1dcee.tar.bz2
bluez-0407e3f0b7b799c7b0d831291ee4577419f1dcee.zip
Merge the code from private
branch:devel/bluetooth/master ================================================= commit 2fca83fc8992b0475434b40f911eba47e623935e Author: Anurag Biradar <biradar.a@samsung.com> Date: Fri Aug 5 15:11:55 2016 +0530 HID: Adding support for dual HID Roles ================================================== Change-Id: I06b445bddbba372d3977904e5225d6ca54b12cb7 Signed-off-by: DoHyun Pyun <dh79.pyun@samsung.com>
Diffstat (limited to 'profiles')
-rw-r--r--profiles/audio/a2dp.c13
-rw-r--r--profiles/audio/avdtp.c35
-rw-r--r--profiles/audio/avrcp.c5
-rw-r--r--profiles/audio/player.c8
-rw-r--r--profiles/health/hdp.c1
-rw-r--r--profiles/input/device.c232
-rw-r--r--profiles/input/device.h9
-rw-r--r--profiles/input/manager.c35
-rw-r--r--profiles/input/server.c84
-rw-r--r--profiles/network/bnep.c2
10 files changed, 398 insertions, 26 deletions
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 2d5c7469..47f6be91 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -166,6 +166,7 @@ static void setup_free(struct a2dp_setup *s)
avdtp_unref(s->session);
g_slist_free_full(s->cb, g_free);
g_slist_free_full(s->caps, g_free);
+
g_free(s);
}
@@ -210,11 +211,21 @@ static void finalize_setup_errno(struct a2dp_setup *s, int err,
{
GSourceFunc finalize;
va_list args;
+#ifdef __TIZEN_PATCH__
+ struct avdtp_error *avdtp_err;
+#else
struct avdtp_error avdtp_err;
+#endif
if (err < 0) {
+#ifdef __TIZEN_PATCH__
+ avdtp_err = g_new(struct avdtp_error, 1);
+ avdtp_error_init(avdtp_err, AVDTP_ERRNO, -err);
+ s->err = avdtp_err;
+#else
avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err);
s->err = &avdtp_err;
+#endif
}
va_start(args, cb1);
@@ -901,7 +912,7 @@ static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
DBG("Source %p: Suspend_Ind", sep);
#ifdef __TIZEN_PATCH__
- a2dp_sep->remote_suspended = TRUE;
+ a2dp_sep->remote_suspended = TRUE;
#endif
if (a2dp_sep->suspend_timer) {
diff --git a/profiles/audio/avdtp.c b/profiles/audio/avdtp.c
index 07337027..6e7410b5 100644
--- a/profiles/audio/avdtp.c
+++ b/profiles/audio/avdtp.c
@@ -103,11 +103,7 @@ static unsigned int seids;
#endif
#define ABORT_TIMEOUT 2
#define DISCONNECT_TIMEOUT 1
-#ifdef __TIZEN_PATCH__
-#define START_TIMEOUT 2
-#else
#define START_TIMEOUT 1
-#endif
#if __BYTE_ORDER == __LITTLE_ENDIAN
@@ -849,13 +845,23 @@ static void handle_transport_connect(struct avdtp *session, GIOChannel *io,
goto proceed;
DBG("sk %d, omtu %d, send buffer size %d", sk, omtu, buf_size);
+#ifdef __TIZEN_PATCH__
+ min_buf_size = omtu * 10;
+#else
min_buf_size = omtu * 2;
+#endif
if (buf_size < min_buf_size) {
DBG("send buffer size to be increassed to %d",
min_buf_size);
set_send_buffer_size(sk, min_buf_size);
}
-
+#ifdef __TIZEN_PATCH__
+ else {
+ DBG("send buffer size to be decreassed to %d",
+ min_buf_size);
+ set_send_buffer_size(sk, min_buf_size);
+ }
+#endif
proceed:
if (!stream->open_acp && sep->cfm && sep->cfm->open)
sep->cfm->open(session, sep, stream, NULL, sep->user_data);
@@ -1130,7 +1136,6 @@ static void avdtp_sep_set_state(struct avdtp *session,
avdtp_state_t state)
{
struct avdtp_stream *stream = sep->stream;
-
#ifdef __TIZEN_PATCH__
#if (defined(__BROADCOM_QOS_PATCH__) || defined(TIZEN_WEARABLE)) || \
defined(__SPRD_QOS_PATCH__)
@@ -1337,7 +1342,6 @@ static void connection_lost(struct avdtp *session, int err)
if (service)
btd_service_connecting_complete(service, -err);
#endif
-
g_slist_foreach(session->streams, (GFunc) release_stream, session);
session->streams = NULL;
@@ -1379,9 +1383,9 @@ static gboolean disconnect_timeout(gpointer user_data)
struct btd_device *device = NULL;
struct btd_adapter *adapter = NULL;
const bdaddr_t *bdaddr = NULL;
-#endif
DBG("");
+#endif
/* Fix : REVERSE_INULL */
#ifdef __TIZEN_PATCH__
@@ -2471,6 +2475,21 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
}
if (session->in.message_type == AVDTP_MSG_TYPE_COMMAND) {
+#ifdef __TIZEN_PATCH__
+ struct btd_service *service;
+
+ service = btd_device_get_service(session->device, A2DP_SINK_UUID);
+ if (service != NULL) {
+ DBG("A2dp state %d", btd_service_get_state(
+ btd_device_get_service(session->device, A2DP_SINK_UUID)));
+
+ if (btd_service_get_state(btd_device_get_service(session->device,
+ A2DP_SINK_UUID)) == BTD_SERVICE_STATE_DISCONNECTING) {
+ DBG("avdtp:%p , disconnect timer is going on", session);
+ return FALSE;
+ }
+ }
+#endif
if (!avdtp_parse_cmd(session, session->in.transaction,
session->in.signal_id,
session->in.buf,
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 72d49069..dafa974c 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -3893,9 +3893,12 @@ static char *avrcp_event_to_string(uint8_t event)
}
}
-static gboolean avrcp_get_playback_status(struct avrcp *session)
+static gboolean avrcp_get_playback_status(gpointer user_data)
{
+ struct avrcp *session = user_data;
+
avrcp_get_play_status(session);
+
return TRUE;
}
#endif
diff --git a/profiles/audio/player.c b/profiles/audio/player.c
index e7ee747f..436d193d 100644
--- a/profiles/audio/player.c
+++ b/profiles/audio/player.c
@@ -1413,16 +1413,18 @@ void media_player_set_metadata(struct media_player *mp,
struct media_item *item, const char *key,
void *data, size_t len)
{
- char *value, *curval;
#ifdef __TIZEN_PATCH__
+ char *value;
char *end, *temp;
+#else
+ char *value, *curval;
#endif
value = g_strndup(data, len);
#ifdef __TIZEN_PATCH__
temp = value;
- while (g_utf8_validate(temp, -1, &end) == FALSE) {
+ while (g_utf8_validate(temp, -1, (const gchar **)&end) == FALSE) {
temp = g_utf8_find_next_char(end, NULL);
if (temp == NULL) {
*end = '\0';
@@ -1435,8 +1437,8 @@ void media_player_set_metadata(struct media_player *mp,
DBG("%s: %s", key, value);
- curval = g_hash_table_lookup(mp->track, key);
#ifndef __TIZEN_PATCH__
+ curval = g_hash_table_lookup(mp->track, key);
if (g_strcmp0(curval, value) == 0) {
g_free(value);
return;
diff --git a/profiles/health/hdp.c b/profiles/health/hdp.c
index fbead13d..bc3b38ad 100644
--- a/profiles/health/hdp.c
+++ b/profiles/health/hdp.c
@@ -603,7 +603,6 @@ static DBusMessage *channel_acquire_continue(struct hdp_tmp_dc_data *data,
}
fd = mcap_mdl_get_fd(data->hdp_chann->mdl);
-
if (fd >= 0)
return g_dbus_create_reply(data->msg, DBUS_TYPE_UNIX_FD, &fd,
DBUS_TYPE_INVALID);
diff --git a/profiles/input/device.c b/profiles/input/device.c
index a494ea2e..99abadbd 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -87,6 +87,9 @@ struct input_device {
uint8_t report_req_pending;
guint report_req_timer;
uint32_t report_rsp_id;
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ char *role;
+#endif
};
static int idle_timeout = 0;
@@ -308,7 +311,6 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data
if (hidp_recv_intr_data(chan, idev) && (cond == G_IO_IN))
return TRUE;
}
-
ba2str(&idev->dst, address);
DBG("Device %s disconnected", address);
@@ -333,8 +335,12 @@ static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data
btd_service_disconnecting_complete(idev->service, 0);
/* Enter the auto-reconnect mode if needed */
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (idev->role == NULL)
+ input_device_enter_reconnect_mode(idev);
+#else
input_device_enter_reconnect_mode(idev);
-
+#endif
return FALSE;
}
@@ -522,7 +528,6 @@ static gboolean ctrl_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data
/* Close interrupt channel */
if (idev->intr_io && !(cond & G_IO_NVAL))
g_io_channel_shutdown(idev->intr_io, TRUE, NULL);
-
return FALSE;
}
@@ -1002,10 +1007,21 @@ cleanup:
static bool is_connected(struct input_device *idev)
{
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (idev->role == NULL) {
+ if (idev->uhid)
+ return (idev->intr_io != NULL && idev->ctrl_io != NULL);
+ else
+ return ioctl_is_connected(idev);
+ } else {
+ return (idev->intr_io != NULL && idev->ctrl_io != NULL);
+ }
+#else
if (idev->uhid)
return (idev->intr_io != NULL && idev->ctrl_io != NULL);
else
return ioctl_is_connected(idev);
+#endif
}
static int connection_disconnect(struct input_device *idev, uint32_t flags)
@@ -1016,9 +1032,14 @@ static int connection_disconnect(struct input_device *idev, uint32_t flags)
/* Standard HID disconnect */
if (idev->intr_io)
g_io_channel_shutdown(idev->intr_io, TRUE, NULL);
+
if (idev->ctrl_io)
g_io_channel_shutdown(idev->ctrl_io, TRUE, NULL);
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (idev->role != NULL)
+ btd_service_disconnecting_complete(idev->service, 0);
+#endif
if (idev->uhid)
return 0;
else
@@ -1031,10 +1052,17 @@ static int input_device_connected(struct input_device *idev)
if (idev->intr_io == NULL || idev->ctrl_io == NULL)
return -ENOTCONN;
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (idev->role == NULL) {
+ err = hidp_add_connection(idev);
+ if (err < 0)
+ return err;
+ }
+#else
err = hidp_add_connection(idev);
if (err < 0)
return err;
+#endif
btd_service_connecting_complete(idev->service, 0);
@@ -1052,11 +1080,19 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
err = -EIO;
goto failed;
}
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (idev->role == NULL) {
+ err = input_device_connected(idev);
+ if (err < 0)
+ goto failed;
+ } else {
+ btd_service_connecting_complete(idev->service, 0);
+ }
+#else
err = input_device_connected(idev);
if (err < 0)
goto failed;
-
+#endif
if (idev->uhid)
cond |= G_IO_IN;
@@ -1109,7 +1145,6 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
g_error_free(err);
goto failed;
}
-
idev->intr_io = io;
if (idev->uhid)
@@ -1230,7 +1265,9 @@ int input_device_connect(struct btd_service *service)
DBG("");
idev = btd_service_get_user_data(service);
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ DBG("Role=%s", idev->role);
+#endif
if (idev->ctrl_io)
return -EBUSY;
@@ -1251,7 +1288,9 @@ int input_device_disconnect(struct btd_service *service)
flags = device_is_temporary(idev->device) ?
(1 << HIDP_VIRTUAL_CABLE_UNPLUG) : 0;
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ DBG("Role=%s", idev->role);
+#endif
err = connection_disconnect(idev, flags);
if (err < 0)
return err;
@@ -1328,6 +1367,28 @@ static struct input_device *input_device_new(struct btd_service *service)
return idev;
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+static struct input_device *input_device_role_new(struct btd_service *service)
+{
+ struct btd_device *device = btd_service_get_device(service);
+ struct btd_profile *p = btd_service_get_profile(service);
+ const char *path = device_get_path(device);
+ struct btd_adapter *adapter = device_get_adapter(device);
+ struct input_device *idev;
+
+ idev = g_new0(struct input_device, 1);
+ bacpy(&idev->src, btd_adapter_get_address(adapter));
+ bacpy(&idev->dst, device_get_address(device));
+ idev->service = btd_service_ref(service);
+ idev->device = btd_device_ref(device);
+ idev->path = g_strdup(path);
+ idev->role = g_strdup("device");
+ idev->disable_sdp = 0;
+ idev->uhid = NULL;
+ return idev;
+}
+#endif
+
static gboolean property_get_reconnect_mode(
const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
@@ -1345,6 +1406,37 @@ static const GDBusPropertyTable input_properties[] = {
{ }
};
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+static DBusMessage *hid_device_fd(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct input_device *idev = user_data;
+ GError *gerr = NULL;
+ DBusMessage *reply;
+ int ctrl_fd = -1;
+ int intr_fd = -1;
+ if (idev->ctrl_io == NULL || idev->intr_io == NULL) {
+ DBG("Return error reply");
+ reply = g_dbus_create_error(msg, ERROR_INTERFACE ".InputError",
+ "%s", "NotConnected");
+ g_error_free(gerr);
+ } else {
+ ctrl_fd = g_io_channel_unix_get_fd(idev->ctrl_io);
+ intr_fd = g_io_channel_unix_get_fd(idev->intr_io);
+ reply = g_dbus_create_reply(msg, DBUS_TYPE_UNIX_FD,
+ &ctrl_fd, DBUS_TYPE_UNIX_FD, &intr_fd ,DBUS_TYPE_INVALID);
+ }
+
+ return reply;
+}
+static const GDBusMethodTable input_device_methods[] = {
+ { GDBUS_ASYNC_METHOD("GetFD",
+ NULL, GDBUS_ARGS({ "fd", "h" } , {"fd", "h"}),
+ hid_device_fd) },
+ { }
+};
+#endif
+
int input_device_register(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
@@ -1381,6 +1473,34 @@ int input_device_register(struct btd_service *service)
return 0;
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+int input_device_role_register(struct btd_service *service)
+{
+ struct btd_device *device = btd_service_get_device(service);
+ const char *path = device_get_path(device);
+ struct input_device *idev;
+
+ DBG("%s", path);
+
+ idev = input_device_role_new(service);
+ if (!idev)
+ return -EINVAL;
+ if (g_dbus_register_interface(btd_get_dbus_connection(),
+ idev->path, INPUT_INTERFACE,
+ input_device_methods, NULL,
+ NULL, idev,
+ NULL) == FALSE) {
+ error("Unable to register %s interface", INPUT_INTERFACE);
+ input_device_free(idev);
+ return -EINVAL;
+ }
+ btd_service_set_user_data(service, idev);
+
+ return 0;
+}
+
+#endif
+
static struct input_device *find_device(const bdaddr_t *src,
const bdaddr_t *dst)
{
@@ -1398,6 +1518,25 @@ static struct input_device *find_device(const bdaddr_t *src,
return btd_service_get_user_data(service);
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+static struct input_device *find_device_role(const bdaddr_t *src,
+ const bdaddr_t *dst)
+{
+ struct btd_device *device;
+ struct btd_service *service;
+
+ device = btd_adapter_find_device(adapter_find(src), dst, BDADDR_BREDR);
+ if (device == NULL)
+ return NULL;
+
+ service = btd_device_get_service(device, HID_DEVICE_UUID);
+ if (service == NULL)
+ return NULL;
+
+ return btd_service_get_user_data(service);
+}
+#endif
+
void input_device_unregister(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
@@ -1412,6 +1551,19 @@ void input_device_unregister(struct btd_service *service)
input_device_free(idev);
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+void input_device_role_unregister(struct btd_service *service)
+{
+ struct btd_device *device = btd_service_get_device(service);
+ const char *path = device_get_path(device);
+ struct input_device *idev = btd_service_get_user_data(service);
+
+ DBG("%s", path);
+
+ input_device_free(idev);
+}
+#endif
+
static int input_device_connadd(struct input_device *idev)
{
int err;
@@ -1443,6 +1595,16 @@ bool input_device_exists(const bdaddr_t *src, const bdaddr_t *dst)
return false;
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+bool input_device_role_exists(const bdaddr_t *src, const bdaddr_t *dst)
+{
+ if (find_device_role(src, dst))
+ return true;
+
+ return false;
+}
+#endif
+
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
GIOChannel *io)
{
@@ -1480,6 +1642,58 @@ int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
return 0;
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+int input_device_role_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
+ GIOChannel *io)
+{
+ struct input_device *idev = find_device_role(src, dst);
+ GIOCondition cond = G_IO_HUP | G_IO_ERR | G_IO_NVAL;
+
+ DBG("idev %p psm %d", idev, psm);
+
+ if (!idev)
+ return -ENOENT;
+
+ switch (psm) {
+ case L2CAP_PSM_HIDP_CTRL:
+ if (idev->ctrl_io)
+ return -EALREADY;
+ idev->ctrl_io = g_io_channel_ref(io);
+ idev->ctrl_watch = g_io_add_watch(idev->ctrl_io, cond,
+ ctrl_watch_cb, idev);
+ break;
+ case L2CAP_PSM_HIDP_INTR:
+ if (idev->intr_io)
+ return -EALREADY;
+ idev->intr_io = g_io_channel_ref(io);
+ idev->intr_watch = g_io_add_watch(idev->intr_io, cond,
+ intr_watch_cb, idev);
+ break;
+ }
+ if (idev->intr_io && idev->ctrl_io) {
+ btd_service_connecting_complete(idev->service, 0);
+ }
+ return 0;
+}
+
+int input_device_role_close_channels(const bdaddr_t *src, const bdaddr_t *dst)
+{
+ struct input_device *idev = find_device(src, dst);
+
+ if (!idev)
+ return -ENOENT;
+
+ if (idev->intr_io)
+ g_io_channel_shutdown(idev->intr_io, TRUE, NULL);
+
+ if (idev->ctrl_io)
+ g_io_channel_shutdown(idev->ctrl_io, TRUE, NULL);
+
+ return 0;
+}
+
+#endif
+
int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst)
{
struct input_device *idev = find_device(src, dst);
diff --git a/profiles/input/device.h b/profiles/input/device.h
index 51a9aee1..20aba315 100644
--- a/profiles/input/device.h
+++ b/profiles/input/device.h
@@ -33,6 +33,15 @@ void input_enable_userspace_hid(bool state);
int input_device_register(struct btd_service *service);
void input_device_unregister(struct btd_service *service);
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+int input_device_role_register(struct btd_service *service);
+void input_device_role_unregister(struct btd_service *service);
+bool input_device_role_exists(const bdaddr_t *src, const bdaddr_t *dst);
+int input_device_role_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
+ GIOChannel *io);
+int input_device_role_close_channels(const bdaddr_t *src, const bdaddr_t *dst);
+#endif
+
bool input_device_exists(const bdaddr_t *src, const bdaddr_t *dst);
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
GIOChannel *io);
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 1d31b065..6d96c86c 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -53,7 +53,19 @@ static void hid_server_remove(struct btd_profile *p,
{
server_stop(btd_adapter_get_address(adapter));
}
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+static int hid_device_probe(struct btd_profile *p, struct btd_adapter *adapter)
+{
+ DBG("hid device probe");
+ return server_start(btd_adapter_get_address(adapter));
+}
+static void hid_device_remove(struct btd_profile *p,
+ struct btd_adapter *adapter)
+{
+ server_stop(btd_adapter_get_address(adapter));
+}
+#endif
static struct btd_profile input_profile = {
.name = "input-hid",
.local_uuid = HID_UUID,
@@ -69,7 +81,23 @@ static struct btd_profile input_profile = {
.adapter_probe = hid_server_probe,
.adapter_remove = hid_server_remove,
};
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+static struct btd_profile input_device_profile = {
+ .name = "hid-device",
+ .local_uuid = HID_DEVICE_UUID,
+ .remote_uuid = HID_DEVICE_UUID,
+ .auto_connect = false,
+ .connect = input_device_connect,
+ .disconnect = input_device_disconnect,
+
+ .device_probe = input_device_role_register,
+ .device_remove = input_device_role_unregister,
+
+ .adapter_probe = hid_device_probe,
+ .adapter_remove = hid_device_remove,
+};
+#endif
static GKeyFile *load_config_file(const char *file)
{
GKeyFile *keyfile;
@@ -117,7 +145,9 @@ static int input_init(void)
}
btd_profile_register(&input_profile);
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ btd_profile_register(&input_device_profile);
+#endif
if (config)
g_key_file_free(config);
@@ -127,6 +157,9 @@ static int input_init(void)
static void input_exit(void)
{
btd_profile_unregister(&input_profile);
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ btd_profile_unregister(&input_device_profile);
+#endif
}
BLUETOOTH_PLUGIN_DEFINE(input, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
diff --git a/profiles/input/server.c b/profiles/input/server.c
index eb3fcf84..2ee3b9bc 100644
--- a/profiles/input/server.c
+++ b/profiles/input/server.c
@@ -57,6 +57,9 @@ struct input_server {
GIOChannel *ctrl;
GIOChannel *intr;
struct confirm_data *confirm;
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ char *role;
+#endif
};
static int server_cmp(gconstpointer s, gconstpointer user_data)
@@ -182,7 +185,14 @@ static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data)
sixaxis_browse_sdp(&src, &dst, chan, psm);
return;
}
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (ret == -ENOENT) {
+ DBG("Connection request for device role");
+ ret = input_device_role_set_channel(&src, &dst, psm, chan);
+ if (ret == 0)
+ return;
+ }
+#endif
error("Refusing input device connect: %s (%d)", strerror(-ret), -ret);
/* Send unplug virtual cable to unknown devices */
@@ -208,8 +218,15 @@ static void auth_callback(DBusError *derr, void *user_data)
}
if (!input_device_exists(&server->src, &confirm->dst) &&
- !dev_is_sixaxis(&server->src, &confirm->dst))
+ !dev_is_sixaxis(&server->src, &confirm->dst)) {
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (!input_device_role_exists(&server->src, &confirm->dst)) {
+ return;
+ }
+#else
return;
+#endif
+ }
if (!bt_io_accept(confirm->io, connect_event_cb, server, NULL, &err)) {
error("bt_io_accept: %s", err->message);
@@ -260,8 +277,15 @@ static void confirm_event_cb(GIOChannel *chan, gpointer user_data)
}
if (!input_device_exists(&src, &dst) && !dev_is_sixaxis(&src, &dst)) {
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (!input_device_role_exists(&src, &dst)) {
+ error("Refusing connection from %s: unknown device", addr);
+ goto drop;
+ }
+#else
error("Refusing connection from %s: unknown device", addr);
goto drop;
+#endif
}
server->confirm = g_new0(struct confirm_data, 1);
@@ -344,3 +368,59 @@ void server_stop(const bdaddr_t *src)
servers = g_slist_remove(servers, server);
g_free(server);
}
+
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+int server_device_start(const bdaddr_t *src)
+{
+ struct input_server *server;
+ GError *err = NULL;
+
+ server = g_new0(struct input_server, 1);
+ bacpy(&server->src, src);
+
+ server->ctrl = bt_io_listen(connect_event_cb, NULL,
+ server, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (!server->ctrl) {
+ error("Failed to listen on control channel");
+ }
+
+ server->intr = bt_io_listen(NULL, confirm_event_cb,
+ server, NULL, &err,
+ BT_IO_OPT_SOURCE_BDADDR, src,
+ BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR,
+ BT_IO_OPT_SEC_LEVEL, BT_IO_SEC_LOW,
+ BT_IO_OPT_INVALID);
+ if (!server->intr) {
+ error("Failed to listen on interrupt channel");
+ }
+ server->role = strdup("device");
+ servers = g_slist_append(servers, server);
+
+ return 0;
+}
+
+void server_device_stop(const bdaddr_t *src)
+{
+ struct input_server *server;
+ GSList *l;
+
+ l = g_slist_find_custom(servers, src, server_cmp);
+ if (!l)
+ return;
+
+ server = l->data;
+
+ g_io_channel_shutdown(server->intr, TRUE, NULL);
+ g_io_channel_unref(server->intr);
+
+ g_io_channel_shutdown(server->ctrl, TRUE, NULL);
+ g_io_channel_unref(server->ctrl);
+ g_free(server->role);
+ servers = g_slist_remove(servers, server);
+ g_free(server);
+}
+#endif
diff --git a/profiles/network/bnep.c b/profiles/network/bnep.c
index 95a8e74f..c03c2c8a 100644
--- a/profiles/network/bnep.c
+++ b/profiles/network/bnep.c
@@ -780,7 +780,9 @@ int bnep_server_add(int sk, char *bridge, char *iface, const bdaddr_t *addr,
failed_bridge:
bnep_del_from_bridge(iface, bridge);
+#ifndef __TIZEN_PATCH__
failed_conn:
+#endif
bnep_conndel(addr);
return err;