summaryrefslogtreecommitdiff
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
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>
-rw-r--r--attrib/gatt-service.c236
-rw-r--r--attrib/gatt-service.h18
-rw-r--r--client/main.c1
-rw-r--r--gdbus/client.c26
-rw-r--r--lib/mgmt.h72
-rw-r--r--lib/uuid.c4
-rw-r--r--lib/uuid.h3
-rw-r--r--monitor/broadcom.c706
-rw-r--r--monitor/display.h4
-rw-r--r--monitor/packet.c27
-rw-r--r--monitor/packet.h8
-rw-r--r--obexd/client/manager.c7
-rw-r--r--obexd/client/session.c27
-rw-r--r--obexd/client/session.h2
-rw-r--r--obexd/plugins/messages-tizen.c15
-rw-r--r--plugins/dbusoob.c73
-rw-r--r--plugins/neard.c7
-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
-rw-r--r--src/adapter.c1096
-rw-r--r--src/adapter.h58
-rw-r--r--src/adapter_le_vsc_features.c39
-rw-r--r--src/adapter_le_vsc_features.h6
-rw-r--r--src/attrib-server.c15
-rw-r--r--src/device.c648
-rw-r--r--src/device.h8
-rw-r--r--src/gatt-client.c86
-rw-r--r--src/gatt-database.c225
-rw-r--r--src/main.conf89
-rw-r--r--src/main_hive.conf87
-rw-r--r--src/profile.c143
-rw-r--r--src/shared/att.c12
-rw-r--r--src/shared/gatt-client.c232
-rw-r--r--src/shared/gatt-db.c6
-rw-r--r--src/shared/gatt-db.h4
-rw-r--r--src/shared/gatt-server.c19
44 files changed, 2406 insertions, 2027 deletions
diff --git a/attrib/gatt-service.c b/attrib/gatt-service.c
index 7b883809..2cca42f5 100644
--- a/attrib/gatt-service.c
+++ b/attrib/gatt-service.c
@@ -41,9 +41,6 @@
#include "src/attrib-server.h"
#include "attrib/gatt-service.h"
#include "src/log.h"
-#ifdef __TIZEN_PATCH__
-#include "src/device.h"
-#endif
struct gatt_info {
bt_uuid_t uuid;
@@ -78,10 +75,6 @@ static GSList *parse_opts(gatt_option opt1, va_list args)
struct attrib_cb *cb;
GSList *l = NULL;
-#ifdef __TIZEN_PATCH__
- if (opt == GATT_OPT_INVALID)
- return NULL;
-#endif
info = g_new0(struct gatt_info, 1);
l = g_slist_append(l, info);
@@ -216,62 +209,6 @@ static int find_callback(gconstpointer a, gconstpointer b)
return cb->event - event;
}
-#ifdef __TIZEN_PATCH__
-static gboolean add_descriptor(struct btd_adapter *adapter,
- uint16_t *handle, struct gatt_info *info)
-{
- uint16_t h = *handle;
- struct attribute *a;
- bt_uuid_t bt_uuid;
- uint8_t atval[ATT_MAX_VALUE_LEN];
- GSList *l;
-
- if (info->uuid.type != BT_UUID16 && info->uuid.type != BT_UUID128) {
- error("Discriptors UUID or properties are missing");
- return FALSE;
- }
-
- /* Description declaration */
- if (info->uuid.type == BT_UUID16)
- bt_uuid16_create(&bt_uuid, info->uuid.value.u16);
- else
- bt_uuid128_create(&bt_uuid, info->uuid.value.u128);
-
- put_uuid_le(&info->uuid, &atval[0]);
-/* API not available in bluez 5.25
- * att_put_uuid(info->uuid, &atval[0]);*/
-
- a = attrib_db_add(adapter, h++, &bt_uuid, ATT_AUTHENTICATION,
- ATT_AUTHENTICATION, atval, info->uuid.type / 8);
-
- if (a == NULL) {
- return FALSE;
- }
-
- for (l = info->callbacks; l != NULL; l = l->next) {
- struct attrib_cb *cb = l->data;
-
- switch (cb->event) {
- case ATTRIB_READ:
- a->read_cb = cb->fn;
- break;
- case ATTRIB_WRITE:
- a->write_cb = cb->fn;
- break;
- }
-
- a->cb_user_data = cb->user_data;
- }
-
- if (info->value_handle != NULL)
- *info->value_handle = a->handle;
-
- *handle = h;
-
- return TRUE;
-}
-#endif
-
static gboolean add_characteristic(struct btd_adapter *adapter,
uint16_t *handle, struct gatt_info *info)
{
@@ -398,179 +335,6 @@ static void service_attr_del(struct btd_adapter *adapter, uint16_t start_handle,
}
}
-#ifdef __TIZEN_PATCH__
-static int is_gatt_connected(gconstpointer a1, gconstpointer a2)
-{
- const struct btd_device *dev = a1;
-
- if (device_get_gatt_connected(dev))
- return 0;
- else
- return -1;
-}
-
-bool gatt_send_noty_ind(struct btd_adapter *adapter, const bt_uuid_t *uuid,
- uint8_t *value, size_t len)
-{
- struct attribute *a;
- GAttrib *attrib;
- GList *l, *connections;
- struct btd_device *dev;
- uint16_t desc_handle;
-
- a = attribute_find(adapter, uuid);
- if (!a)
- return FALSE;
-
- desc_handle = a->handle + 1;
-
- connections = (GList *)btd_adapter_get_connections(adapter);
-
- do {
- l = g_list_find_custom(connections, GUINT_TO_POINTER(NULL),
- is_gatt_connected);
- if (l) {
- dev = l->data;
- attrib = attrib_from_device(dev);
- if (attrib) {
- /* Send the characteristic handle and value
- * as notification or indication*/
- attrib_send_noty_ind(dev, attrib, a->handle,
- desc_handle, value, len);
- g_attrib_unref(attrib);
- }
- connections = (GList *)g_slist_next(connections);
- } else
- break;
- } while(l);
-
- return TRUE;
-}
-
-bool gatt_update_db(struct btd_adapter *adapter, const bt_uuid_t *uuid,
- uint8_t *value, size_t len)
-{
- struct attribute *a;
- uint8_t status;
-
- a = attribute_find(adapter, uuid);
- if (!a)
- return FALSE;
- status = attrib_db_update(adapter, a->handle, NULL, value, len, NULL);
-
- if (status)
- return FALSE;
-
- return TRUE;
-}
-
-bool gatt_add_descriptor(struct btd_adapter *adapter, uint16_t *handle,
- uint16_t start_handle, gatt_option opt1, ...)
-{
- va_list args;
- GSList *disc, *l;
- uint16_t disc_handle = *handle;
-
- va_start(args, opt1);
- disc = parse_opts(opt1, args);
- va_end(args);
-
- for (l = disc; l != NULL; l = l->next) {
- struct gatt_info *info = l->data;
-
- DBG("New Descriptor: handle 0x%04x, start handle 0x%04x",
- disc_handle, start_handle);
- if (!add_descriptor(adapter, &disc_handle, info)) {
- goto fail;
- }
- }
-
- g_slist_free_full(disc, free_gatt_info);
- *handle = disc_handle;
-
- return TRUE;
-
-fail:
- g_slist_free_full(disc, free_gatt_info);
- return FALSE;
-}
-
-bool gatt_add_characteristic(struct btd_adapter *adapter,
- uint16_t *handle, uint16_t start_handle,
- gatt_option opt1, ...)
-{
- va_list args;
- GSList *chrs, *l;
- uint16_t char_handle = *handle;
-
- va_start(args, opt1);
- chrs = parse_opts(opt1, args);
- va_end(args);
-
- for (l = chrs; l != NULL; l = l->next) {
- struct gatt_info *info = l->data;
-
- DBG("New characteristic: handle 0x%04x, start handle 0x%04x",
- char_handle, start_handle);
- if (!add_characteristic(adapter, &char_handle, info)) {
- service_attr_del(adapter, start_handle,
- char_handle - 1);
- goto fail;
- }
- }
-
- g_slist_free_full(chrs, free_gatt_info);
- *handle = char_handle;
-
- return TRUE;
-
-fail:
- g_slist_free_full(chrs, free_gatt_info);
- return FALSE;
-}
-
-void attrib_remove_service(struct btd_adapter *adapter, uint16_t start_handle,
- uint16_t end_handle)
-{
- DBG("gatt_remove_service");
- service_attr_del(adapter, start_handle, end_handle);
-}
-
-uint16_t gatt_prim_service_add(struct btd_adapter *adapter, uint16_t uuid,
- bt_uuid_t *svc_uuid, unsigned int size,
- uint16_t *start_handle)
-{
- char uuidstr[MAX_LEN_UUID_STR];
- uint16_t handle, h;
-
- bt_uuid_to_string(svc_uuid, uuidstr, MAX_LEN_UUID_STR);
- if (svc_uuid->type != BT_UUID16 && svc_uuid->type != BT_UUID128) {
- error("Invalid service uuid: %s", uuidstr);
- return FALSE;
- }
-
- handle = attrib_db_find_avail(adapter, svc_uuid, size);
- if (handle == 0) {
- error("Not enough free handles to register service");
- goto fail;
- }
-
- DBG("New service: handle 0x%04x, UUID %s, %d attributes",
- handle, uuidstr, size);
-
- /* service declaration */
- h = handle;
- *start_handle = handle;
- if (add_service_declaration(adapter, h++, uuid, svc_uuid) == NULL)
- goto fail;
-
- return h;
-
-fail:
- return 0;
-}
-#endif
-
gboolean gatt_service_add(struct btd_adapter *adapter, uint16_t uuid,
bt_uuid_t *svc_uuid, gatt_option opt1, ...)
{
diff --git a/attrib/gatt-service.h b/attrib/gatt-service.h
index a1b3fee2..d6c61e2c 100644
--- a/attrib/gatt-service.h
+++ b/attrib/gatt-service.h
@@ -67,21 +67,3 @@ typedef enum {
gboolean gatt_service_add(struct btd_adapter *adapter, uint16_t uuid,
bt_uuid_t *svc_uuid, gatt_option opt1, ...);
-#ifdef __TIZEN_PATCH__
-bool gatt_add_descriptor(struct btd_adapter *adapter, uint16_t *handle,
- uint16_t start_handle, gatt_option opt1, ...);
-bool gatt_add_characteristic(struct btd_adapter *adapter,
- uint16_t *handle, uint16_t start_handle,
- gatt_option opt1, ...);
-uint16_t gatt_prim_service_add(struct btd_adapter *adapter, uint16_t uuid,
- bt_uuid_t *svc_uuid, unsigned int size,
- uint16_t *start_handle);
-void attrib_remove_service(struct btd_adapter *adapter, uint16_t start_handle,
- uint16_t end_handle);
-bool gatt_update_db(struct btd_adapter *adapter, const bt_uuid_t *uuid,
- uint8_t *value, size_t len);
-bool gatt_send_noty_ind(struct btd_adapter *adapter, const bt_uuid_t *uuid,
- uint8_t *value, size_t len);
-bool gatt_send_service_changed_ind(struct btd_adapter *adapter, bt_uuid_t *uuid,
- uint16_t start_handle, uint16_t end_handle);
-#endif
diff --git a/client/main.c b/client/main.c
index 4faa9c6b..6cc97400 100644
--- a/client/main.c
+++ b/client/main.c
@@ -1170,7 +1170,6 @@ static void cmd_info(const char *arg)
print_uuids(proxy);
print_property(proxy, "Modalias");
#ifdef __TIZEN_PATCH__
- print_property(proxy, "Flag");
print_property(proxy, "ManufacturerDataLen");
#endif
print_property(proxy, "ManufacturerData");
diff --git a/gdbus/client.c b/gdbus/client.c
index 068e778c..a011e19c 100644
--- a/gdbus/client.c
+++ b/gdbus/client.c
@@ -853,28 +853,30 @@ gboolean g_dbus_proxy_method_call(GDBusProxy *proxy, const char *method,
if (client == NULL)
return FALSE;
- data = g_try_new0(struct method_call_data, 1);
- if (data == NULL)
- return FALSE;
-
- data->function = function;
- data->user_data = user_data;
- data->destroy = destroy;
-
msg = dbus_message_new_method_call(client->service_name,
proxy->obj_path, proxy->interface, method);
- if (msg == NULL) {
- g_free(data);
+ if (msg == NULL)
return FALSE;
- }
if (setup) {
DBusMessageIter iter;
dbus_message_iter_init_append(msg, &iter);
- setup(&iter, data->user_data);
+ setup(&iter, user_data);
}
+ if (!function)
+ return g_dbus_send_message(client->dbus_conn, msg);
+
+ data = g_try_new0(struct method_call_data, 1);
+ if (data == NULL)
+ return FALSE;
+
+ data->function = function;
+ data->user_data = user_data;
+ data->destroy = destroy;
+
+
if (g_dbus_send_message_with_reply(client->dbus_conn, msg,
&call, METHOD_CALL_TIMEOUT) == FALSE) {
dbus_message_unref(msg);
diff --git a/lib/mgmt.h b/lib/mgmt.h
index c89d7d05..0917c3be 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -882,7 +882,7 @@ static const char *mgmt_status[] = {
#define MGMT_MAX_ADVERTISING_LENGTH 31
-#define MGMT_MAX_MANUFACTURER_DATA_LENGTH 31
+#define MGMT_MAX_EIR_MANUFACTURER_DATA_LENGTH 100
#define MGMT_IRK_SIZE 16
@@ -970,10 +970,6 @@ struct mgmt_cp_stop_le_discovery {
uint8_t type;
} __packed;
-/* BEGIN TIZEN_Bluetooth :: LE auto connection */
-#define MGMT_OP_DISABLE_LE_AUTO_CONNECT (TIZEN_OP_CODE_BASE + 0x0c)
-/* END TIZEN_Bluetooth */
-
#define MGMT_OP_LE_CONN_UPDATE (TIZEN_OP_CODE_BASE + 0x0d)
struct mgmt_cp_le_conn_update {
uint16_t interval_min;
@@ -985,7 +981,7 @@ struct mgmt_cp_le_conn_update {
#define MGMT_OP_SET_MANUFACTURER_DATA (TIZEN_OP_CODE_BASE + 0x0e)
struct mgmt_cp_set_manufacturer_data {
- uint8_t data[MGMT_MAX_MANUFACTURER_DATA_LENGTH];
+ uint8_t data[MGMT_MAX_EIR_MANUFACTURER_DATA_LENGTH];
} __packed;
#define MGMT_OP_LE_SET_SCAN_PARAMS (TIZEN_OP_CODE_BASE + 0x0f)
@@ -1060,62 +1056,6 @@ struct mgmt_cp_set_dev_rpa_res_support {
uint8_t res_support;
} __packed;
-/* Currently there is no support in kernel for below MGMT cmd opcodes. */
-#if 0 // Not defined in kernel
-#define MGMT_OP_READ_RSSI (TIZEN_OP_CODE_BASE + 0x11)
-struct mgmt_cp_read_rssi {
- bdaddr_t bdaddr;
-} __packed;
-struct mgmt_rp_read_rssi {
- uint8_t status;
- bdaddr_t bdaddr;
- int8_t rssi;
-} __packed;
-
-#define MGMT_OP_L2CAP_CONN_PARAM_UPDATE (TIZEN_OP_CODE_BASE + 0x12)
-struct mgmt_cp_l2cap_conn_param_update {
- bdaddr_t bdaddr;
- uint16_t interval_min;
- uint16_t interval_max;
- uint16_t latency;
- uint16_t supervision_time_out;
-} __packed;
-
-#define MGMT_OP_WRITE_SEC_CONN_HOST_SUPPORT (TIZEN_OP_CODE_BASE + 0x13)
-#define MGMT_WRITE_SEC_CONN_HOST_SUPPORT_SIZE 1
-struct mgmt_cp_write_sec_conn_host_support {
- uint8_t secure_connection_host_support;
-} __packed;
-struct mgmt_rp_write_sec_conn_host_support {
- uint8_t status;
-} __packed;
-
-#define MGMT_OP_READ_SEC_CONN_HOST_SUPPORT (TIZEN_OP_CODE_BASE + 0x14)
-struct mgmt_rp_read_sec_conn_host_support {
- uint8_t status;
- uint8_t sec_conn_host_support;
-} __packed;
-
-#define MGMT_OP_WRITE_AUTH_PAYLOAD_TIMEOUT (TIZEN_OP_CODE_BASE + 0x15)
-struct mgmt_cp_write_auth_payload_timeout {
- bdaddr_t bdaddr;
- uint16_t auth_payload_timeout;
-} __packed;
-struct mgmt_rp_write_auth_payload_timeout {
- uint8_t status;
-} __packed;
-
-#define MGMT_OP_READ_AUTH_PAYLOAD_TIMEOUT (TIZEN_OP_CODE_BASE + 0x16)
-struct mgmt_cp_read_auth_payload_timeout {
- bdaddr_t bdaddr;
-} __packed;
-struct mgmt_rp_read_auth_payload_timeout {
- uint8_t status;
- uint16_t auth_payload_timeout;
-} __packed;
-#endif
-
-
/* BEGIN TIZEN_Bluetooth :: name update changes */
#define MGMT_EV_DEVICE_NAME_UPDATE (TIZEN_EV_BASE + 0x01)
struct mgmt_ev_device_name_update {
@@ -1202,14 +1142,6 @@ struct mgmt_ev_le_data_length_changed {
int16_t max_rx_time;
} __packed;
-/* Currently there is no support in kernel for below MGMT events. */
-#if 0 // Not defined in kernel
-#define MGMT_EV_NEW_LOCAL_IRK (TIZEN_EV_BASE + 0x0b)
-struct mgmt_ev_new_local_irk {
- uint8_t irk[16];
-} __packed;
-#endif
-
static const char *mgmt_tizen_op[] = {
"<0x0000>",
"Set Advertising Parameters",
diff --git a/lib/uuid.c b/lib/uuid.c
index 20b67d03..ac071fa3 100644
--- a/lib/uuid.c
+++ b/lib/uuid.c
@@ -183,14 +183,14 @@ static inline int is_uuid128(const char *string)
static inline int is_base_uuid128(const char *string)
{
uint16_t uuid;
- char dummy;
+ char dummy[2];
if (!is_uuid128(string))
return 0;
return sscanf(string,
"0000%04hx-0000-1000-8000-00805%1[fF]9%1[bB]34%1[fF]%1[bB]",
- &uuid, &dummy, &dummy, &dummy, &dummy) == 5;
+ &uuid, dummy, dummy, dummy, dummy) == 5;
}
static inline int is_uuid32(const char *string)
diff --git a/lib/uuid.h b/lib/uuid.h
index 542ef606..6ba8e124 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -91,6 +91,9 @@ extern "C" {
#define HDP_SINK_UUID "00001402-0000-1000-8000-00805f9b34fb"
#define HID_UUID "00001124-0000-1000-8000-00805f9b34fb"
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+#define HID_DEVICE_UUID "00001124-0000-1000-8000-00805f9b43bf"
+#endif
#define DUN_GW_UUID "00001103-0000-1000-8000-00805f9b34fb"
diff --git a/monitor/broadcom.c b/monitor/broadcom.c
index a3c34439..58ac37d3 100644
--- a/monitor/broadcom.c
+++ b/monitor/broadcom.c
@@ -35,6 +35,9 @@
#include "ll.h"
#include "vendor.h"
#include "broadcom.h"
+#ifdef __TIZEN_PATCH__
+#include "uuid.h"
+#endif
static void print_status(uint8_t status)
{
@@ -93,6 +96,599 @@ static void launch_ram_cmd(const void *data, uint8_t size)
print_field("Address: 0x%8.8x", addr);
}
+#ifdef __TIZEN_PATCH__
+static void set_advt_param_multi_subcmd(const void *data, uint8_t size)
+{
+ uint8_t adv_instance = get_u8(data + size - 2);
+ int8_t tx_power = *((int8_t *)(data + size - 1));
+
+ print_le_set_adv_parameters_cmd(data, size - 2);
+
+ print_field("Advertising Instance: %u", adv_instance);
+ print_field("TX Power: %d", tx_power);
+}
+
+static void set_advt_data_subcmd(const void *data, uint8_t size)
+{
+ uint8_t adv_instance = get_u8(data + size - 1);
+
+ print_le_set_adv_data_cmd(data, size - 1);
+
+ print_field("Advertising Instance: %u", adv_instance);
+}
+
+static void set_scan_rsp_data_multi_subcmd(const void *data, uint8_t size)
+{
+ uint8_t adv_instance = get_u8(data + size - 1);
+
+ print_le_set_scan_rsp_data_cmd(data, size - 1);
+
+ print_field("Advertising Instance: %u", adv_instance);
+}
+
+static void set_random_addr_multi_subcmd(const void *data, uint8_t size)
+{
+ uint8_t adv_instance = get_u8(data + size - 1);
+
+ print_le_set_random_address_cmd(data, size - 1);
+
+ print_field("Advertising Instance: %u", adv_instance);
+}
+
+static void set_adv_enable_multi_subcmd(const void *data, uint8_t size)
+{
+ uint8_t adv_instance = get_u8(data + size - 1);
+
+ print_le_set_adv_enable_cmd(data, size - 1);
+
+ print_field("Advertising Instance: %u", adv_instance);
+}
+
+static void enable_custom_feature_subcmd(const void *data, uint8_t size)
+{
+ uint8_t enable = get_u8(data);
+ const char *str;
+
+ switch (enable) {
+ case 0x00:
+ str = "Disable";
+ break;
+ case 0x01:
+ str = "Enable";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("%s offloaded RPA feature (0x%2.2x)", str, enable);
+}
+
+static void add_irk_to_list_subcmd(const void *data, uint8_t size)
+{
+ uint8_t addr_type = get_u8(data + 16);
+ const uint8_t *addr = data + 17;
+ const char *str;
+
+ print_field("LE IRK (1st byte LSB)");
+ packet_hexdump(data, 16);
+
+ switch (addr_type) {
+ case 0x00:
+ str = "Public Address";
+ break;
+ case 0x01:
+ str = "Random Address";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Address type : %s (0x%2.2x)", str, addr_type);
+ print_field("Address : %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+}
+
+static void remove_irk_from_list_subcmd(const void *data, uint8_t size)
+{
+ uint8_t addr_type = get_u8(data);
+ const uint8_t *addr = data + 1;
+ const char *str;
+
+ switch (addr_type) {
+ case 0x00:
+ str = "Public Address";
+ break;
+ case 0x01:
+ str = "Random Address";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Address type : %s (0x%2.2x)", str, addr_type);
+ print_field("Address : %2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
+ addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
+}
+
+static void read_irk_list_entry_subcmd(const void *data, uint8_t size)
+{
+ uint8_t index = get_u8(data);
+
+ print_field("LE Read IRK List entry index : %u", index);
+}
+
+static void apcf_enable_subcmd(const void *data, uint8_t size)
+{
+ uint8_t enable = get_u8(data);
+ const char *str;
+
+ switch (enable) {
+ case 0x00:
+ str = "Disable";
+ break;
+ case 0x01:
+ str = "Enable";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("%s APCF feature (0x%2.2x)", str, enable);
+}
+
+static const struct {
+ uint8_t bit;
+ const char *str;
+} apcf_feature_table[] = {
+ { 0, "Broadcast Address filter" },
+ { 1, "Service Data Change filter" },
+ { 2, "Service UUID check" },
+ { 3, "Service Solicitation UUID check" },
+ { 4, "Local Name check" },
+ { 5, "Manufacturer Data check" },
+ { 6, "Service Data check" },
+ { }
+};
+
+static void print_apcf_feature(const char *label, uint16_t feature)
+{
+ int i;
+ uint16_t mask;
+
+ mask = feature;
+
+ print_field("%s", label);
+
+ for (i = 0; apcf_feature_table[i].str; i++) {
+ if (feature & (1 << apcf_feature_table[i].bit)) {
+ print_field(" %s", apcf_feature_table[i].str);
+ mask &= ~(1 << apcf_feature_table[i].bit);
+ }
+ }
+
+ if (mask)
+ print_field(" Unknown features (0x%4.4x)", mask);
+}
+
+static void apcf_set_filtering_param_subcmd(const void *data, uint8_t size)
+{
+ uint8_t add = get_u8(data);
+ uint8_t index = get_u8(data + 1);
+ uint16_t feature_selection = get_le16(data + 2);
+ uint16_t list_logic = get_le16(data + 4);
+ uint16_t filter_logic = get_u8(data + 6);
+ uint8_t rssi_high = get_u8(data + 8);
+ uint8_t delivery_mode = get_u8(data + 9);
+ uint16_t onfound_timeout = get_le16(data + 10);
+ uint8_t onfound_timeout_cnt = get_u8(data + 12);
+ uint8_t rssi_low = get_u8(data + 13);
+ uint16_t onlost_timeout = get_le16(data + 14);
+ uint16_t no_of_tracking_entries;
+ const char *str;
+
+ switch (add) {
+ case 0x00:
+ str = "Add";
+ break;
+ case 0x01:
+ str = "Delete";
+ break;
+ case 0x02:
+ str = "Clear";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Action : %s for filter [%d]", str, index);
+
+ print_apcf_feature("Feature Selection", feature_selection);
+ print_apcf_feature("List Logic Type (OR)", ~list_logic);
+ print_apcf_feature("List Logic Type (AND)", list_logic);
+ print_apcf_feature("Filter Logic Type (OR)", ~(filter_logic << 3));
+ print_apcf_feature("Filter Logic Type (AND)", filter_logic << 3);
+ print_field("RSSI High Threshold : %d dBm", rssi_high);
+
+ switch (delivery_mode) {
+ case 0x00:
+ str = "Immediate";
+ break;
+ case 0x01:
+ str = "On Found";
+ break;
+ case 0x02:
+ str = "Batched";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Delivery_mode : %s", str);
+ print_field("On Found Timeout : %d miliseconds", onfound_timeout);
+ print_field("On Found Timeout Count : %d", onfound_timeout_cnt);
+ print_field("RSSI Low Threshold : %d dBm", rssi_low);
+ print_field("On Lost Timeout : %d miliseconds", onlost_timeout);
+
+ if (size >= 18) {
+ no_of_tracking_entries = get_le16(data + 16);
+ print_field("Number of Tracking Entries : %d",
+ no_of_tracking_entries);
+ }
+}
+
+static void apcf_broadcaster_addr_subcmd(const void *data, uint8_t size)
+{
+ uint8_t add = get_u8(data);
+ uint8_t index = get_u8(data + 1);
+ uint8_t type = get_u8(data + 7);
+ char *str;
+
+ switch (add) {
+ case 0x00:
+ str = "Add";
+ break;
+ case 0x01:
+ str = "Delete";
+ break;
+ case 0x02:
+ str = "Clear";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Action : %s for filter [%d]", str, index);
+ packet_print_addr("Address", data + 2, type == 0x00 ? false : true);
+}
+
+static void apcf_service_uuid_subcmd(const void *data, uint8_t size)
+{
+ uint8_t add = get_u8(data);
+ uint8_t index = get_u8(data + 1);
+ char *str;
+ const uint8_t *uuid;
+ uint16_t uuid16;
+ uint32_t uuid32;
+
+
+ switch (add) {
+ case 0x00:
+ str = "Add";
+ break;
+ case 0x01:
+ str = "Delete";
+ break;
+ case 0x02:
+ str = "Clear";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Action : %s for filter [%d]", str, index);
+
+ switch ((size - 2) / 2) {
+ case 2:
+ uuid16 = get_le16(data + 2);
+ print_field(" UUID : %s (0x%4.4x)",
+ uuid16_to_str(uuid16), uuid16);
+
+ uuid16 = get_le16(data + 4);
+ print_field(" UUID Mask: %s (0x%4.4x)",
+ uuid16_to_str(uuid16), uuid16);
+ break;
+ case 4:
+ uuid32 = get_le32(data + 2);
+ print_field(" UUID :%s (0x%8.8x)",
+ uuid32_to_str(uuid32), uuid32);
+
+ uuid32 = get_le32(data + 6);
+ print_field(" UUID Mask:%s (0x%8.8x)",
+ uuid32_to_str(uuid32), uuid32);
+ break;
+ case 16:
+ uuid = data + 2;
+ print_field(" UUID :%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x",
+ get_le32(&uuid[12]), get_le16(&uuid[10]),
+ get_le16(&uuid[8]), get_le16(&uuid[6]),
+ get_le32(&uuid[2]), get_le16(&uuid[0]));
+ uuid = data + 18;
+ print_field(" UUID :%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x",
+ get_le32(&uuid[12]), get_le16(&uuid[10]),
+ get_le16(&uuid[8]), get_le16(&uuid[6]),
+ get_le32(&uuid[2]), get_le16(&uuid[0]));
+ break;
+ default:
+ print_field("Invalid UUIDs");
+ packet_hexdump(data + 2, size - 2);
+ break;
+ }
+
+ return;
+}
+
+static void apcf_service_solicitation_uuid_subcmd(const void *data, uint8_t size)
+{
+ apcf_service_uuid_subcmd(data, size);
+}
+
+static void apcf_local_name_subcmd(const void *data, uint8_t size)
+{
+ uint8_t add = get_u8(data);
+ uint8_t index = get_u8(data + 1);
+ char *str;
+ char name[30] = { 0 };
+
+ switch (add) {
+ case 0x00:
+ str = "Add";
+ break;
+ case 0x01:
+ str = "Delete";
+ break;
+ case 0x02:
+ str = "Clear";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Action : %s for filter [%d]", str, index);
+
+ memcpy(name, data + 2, size - 2 < 29 ? size - 2 : 29);
+ print_field("Local Name : %s", name);
+}
+
+static void apcf_manufacturer_data_subcmd(const void *data, uint8_t size)
+{
+ uint8_t add = get_u8(data);
+ uint8_t index = get_u8(data + 1);
+ char *str;
+
+ switch (add) {
+ case 0x00:
+ str = "Add";
+ break;
+ case 0x01:
+ str = "Delete";
+ break;
+ case 0x02:
+ str = "Clear";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Action : %s for filter [%d]", str, index);
+
+ print_field("Manufacturer data");
+ packet_hexdump(data + 2, (size - 2 ) / 2);
+
+ print_field("Manufacturer data Mask");
+ packet_hexdump(data + 2 + (size - 2) / 2, (size - 2 ) / 2);
+}
+
+static void apcf_service_data_subcmd(const void *data, uint8_t size)
+{
+ uint8_t add = get_u8(data);
+ uint8_t index = get_u8(data + 1);
+ char *str;
+
+ switch (add) {
+ case 0x00:
+ str = "Add";
+ break;
+ case 0x01:
+ str = "Delete";
+ break;
+ case 0x02:
+ str = "Clear";
+ break;
+ default:
+ str = "Reserved";
+ break;
+ }
+
+ print_field("Action : %s for filter [%d]", str, index);
+
+ print_field("Service data");
+ packet_hexdump(data + 2, (size - 2 ) / 2);
+
+ print_field("Service data Mask");
+ packet_hexdump(data + 2 + (size - 2) / 2, (size - 2 ) / 2);
+}
+
+struct subcmd_data {
+ uint8_t subcmd;
+ const char *str;
+ void (*cmd_func) (const void *data, uint8_t size);
+ uint8_t cmd_size;
+ bool cmd_fixed;
+};
+
+static void print_subcmd(const struct subcmd_data *subcmd_data,
+ const void *data, uint8_t size)
+{
+ const char *subcmd_color;
+
+ if (subcmd_data->cmd_func)
+ subcmd_color = COLOR_BLUE;
+ else
+ subcmd_color = COLOR_WHITE_BG;
+
+ print_indent(6, subcmd_color, "", subcmd_data->str, COLOR_OFF,
+ " (0x%2.2x)", subcmd_data->subcmd);
+
+ if (!subcmd_data->cmd_func) {
+ packet_hexdump(data, size);
+ return;
+ }
+
+ if (subcmd_data->cmd_fixed) {
+ if (size != subcmd_data->cmd_size) {
+ print_text(COLOR_ERROR, "invalid packet size");
+ packet_hexdump(data, size);
+ return;
+ }
+ } else {
+ if (size < subcmd_data->cmd_size) {
+ print_text(COLOR_ERROR, "too short packet");
+ packet_hexdump(data, size);
+ return;
+ }
+ }
+
+ subcmd_data->cmd_func(data, size);
+}
+
+static const struct subcmd_data le_multi_advt_table[] = {
+ { 0x01, "LE Set Advertising Parameters Multi Sub Command",
+ set_advt_param_multi_subcmd, 23, true },
+ { 0x02, "LE Set Advertising Data Multi Sub Command",
+ set_advt_data_subcmd, 33, false },
+ { 0x03, "LE Set Scan Response Data Multi Sub Command",
+ set_scan_rsp_data_multi_subcmd, 33, false },
+ { 0x04, "LE Set Random Address Multi Sub Command",
+ set_random_addr_multi_subcmd, 7, true },
+ { 0x05, "LE Set Advertise Enable Multi Sub Command",
+ set_adv_enable_multi_subcmd, 2, true },
+ { }
+};
+
+static void le_multi_advt_cmd(const void *data, uint8_t size)
+{
+ uint8_t subcmd = *((const uint8_t *)data);
+ struct subcmd_data unknown;
+ const struct subcmd_data *subcmd_data = &unknown;
+ int i;
+
+ unknown.subcmd = subcmd;
+ unknown.str = "Unknown Sub Command";
+ unknown.cmd_func = NULL;
+ unknown.cmd_size = 0;
+ unknown.cmd_fixed = true;
+
+ for (i = 0; le_multi_advt_table[i].str; i++) {
+ if (le_multi_advt_table[i].subcmd == subcmd) {
+ subcmd_data = &le_multi_advt_table[i];
+ break;
+ }
+ }
+
+ print_subcmd(subcmd_data, data + 1, size - 1);
+}
+
+static const struct subcmd_data le_rpa_offload_table[] = {
+ { 0x01, "Enable customer specific feature",
+ enable_custom_feature_subcmd, 1, true },
+ { 0x02, "Add IRK to the list",
+ add_irk_to_list_subcmd, 23, true },
+ { 0x03, "Remove IRK from the list",
+ remove_irk_from_list_subcmd, 7, true },
+ { 0x04, "Clear IRK list",
+ null_cmd, 0, true },
+ { 0x05, "Read IRK list entry",
+ read_irk_list_entry_subcmd, 1, true },
+ { }
+};
+
+static void le_rpa_offload_cmd(const void *data, uint8_t size)
+{
+ uint8_t subcmd = *((const uint8_t *)data);
+ struct subcmd_data unknown;
+ const struct subcmd_data *subcmd_data = &unknown;
+ int i;
+
+ unknown.subcmd = subcmd;
+ unknown.str = "Unknown Sub Command";
+ unknown.cmd_func = NULL;
+ unknown.cmd_size = 0;
+ unknown.cmd_fixed = true;
+
+ for (i = 0; le_rpa_offload_table[i].str; i++) {
+ if (le_rpa_offload_table[i].subcmd == subcmd) {
+ subcmd_data = &le_rpa_offload_table[i];
+ break;
+ }
+ }
+
+ print_subcmd(subcmd_data, data + 1, size - 1);
+}
+
+static const struct subcmd_data le_apcf_table[] = {
+ { 0x00, "APCF Enable",
+ apcf_enable_subcmd, 1, true },
+ { 0x01, "APCF Set Filtering Parameters",
+ apcf_set_filtering_param_subcmd, 15, false },
+ { 0x02, "APCF Broadcaster Address",
+ apcf_broadcaster_addr_subcmd, 9, true },
+ { 0x03, "APCF Service UUID",
+ apcf_service_uuid_subcmd, 2, false },
+ { 0x04, "APCF Service Solicitation UUID",
+ apcf_service_solicitation_uuid_subcmd, 2, false },
+ { 0x05, "APCF Local Name",
+ apcf_local_name_subcmd, 2, false },
+ { 0x06, "APCF Manufacturer Data",
+ apcf_manufacturer_data_subcmd, 2, false },
+ { 0x07, "APCF Service Data",
+ apcf_service_data_subcmd, 2, false },
+ { }
+};
+
+static void le_apcf_cmd(const void *data, uint8_t size)
+{
+ uint8_t subcmd = *((const uint8_t *)data);
+ struct subcmd_data unknown;
+ const struct subcmd_data *subcmd_data = &unknown;
+ int i;
+
+ unknown.subcmd = subcmd;
+ unknown.str = "Unknown Sub Command";
+ unknown.cmd_func = NULL;
+ unknown.cmd_size = 0;
+ unknown.cmd_fixed = true;
+
+ for (i = 0; le_apcf_table[i].str; i++) {
+ if (le_apcf_table[i].subcmd == subcmd) {
+ subcmd_data = &le_apcf_table[i];
+ break;
+ }
+ }
+
+ print_subcmd(subcmd_data, data + 1, size - 1);
+}
+#endif
+
static void read_vid_pid_rsp(const void *data, uint8_t size)
{
uint8_t status = get_u8(data);
@@ -132,6 +728,97 @@ static void read_verbose_version_info_rsp(const void *data, uint8_t size)
print_field("Build number: %u (0x%4.4x)", build_num, build_num);
}
+#ifdef __TIZEN_PATCH__
+static void get_vendor_capabilities_rsp(const void *data, uint8_t size)
+{
+ uint8_t status = get_u8(data);
+ uint8_t max_advt_instances = get_u8(data + 1);
+ uint8_t offloaded_resolution_of_private_address = get_u8(data + 2);
+ uint16_t total_scan_results_storage = get_le16(data + 3);
+ uint8_t max_irk_list_sz = get_u8(data + 5);
+ uint8_t filtering_support = get_u8(data + 6);
+ uint8_t max_filter = get_u8(data + 7);
+ uint8_t activity_energy_info_support = get_u8(data + 8);
+ uint8_t onlost_follow_per_filter = get_u8(data + 9);
+
+ print_status(status);
+ print_field("The Number of advertisement instances supported: %u",
+ max_advt_instances);
+ print_field("BT chip capability of RPA: %s",
+ offloaded_resolution_of_private_address ?
+ "Capable" : "Not Capable");
+ print_field("Storage for scan results: %u bytes",
+ total_scan_results_storage);
+ print_field("The Number of IRK entries supported: %u", max_irk_list_sz);
+ print_field("Support Filtering in BT chip: %s",
+ filtering_support ? "Supported" : "Not Supported");
+ print_field("The Number of filters supported: %u", max_filter);
+ print_field("Supports reporting of activity and energy info: %s",
+ activity_energy_info_support ?
+ "Capable" : "Not Capable");
+ print_field("The Number of advertisers that can be analysed for "
+ "onlost per filter: %u", onlost_follow_per_filter);
+}
+
+static void le_multi_advt_rsp(const void *data, uint8_t size)
+{
+ uint8_t status = get_u8(data);
+ uint8_t subcmd = get_u8(data + 1);
+ int i;
+ const char *str = "Unknown Sub Command";
+
+ print_status(status);
+
+ for (i = 0; le_multi_advt_table[i].str; i++) {
+ if (le_multi_advt_table[i].subcmd == subcmd) {
+ str = le_multi_advt_table[i].str;
+ break;
+ }
+ }
+
+ print_field("Multi Advertise OPcode: %s (%u)", str, subcmd);
+}
+
+static void le_rpa_offload_rsp(const void *data, uint8_t size)
+{
+ uint8_t status = get_u8(data);
+ uint8_t subcmd = get_u8(data + 1);
+ int i;
+ const char *str = "Unknown Sub Command";
+
+ print_status(status);
+
+ for (i = 0; le_rpa_offload_table[i].str; i++) {
+ if (le_rpa_offload_table[i].subcmd == subcmd) {
+ str = le_rpa_offload_table[i].str;
+ break;
+ }
+ }
+
+ print_field("RPA Offload OPcode: %s (%u)", str, subcmd);
+}
+
+static void le_apcf_rsp(const void *data, uint8_t size)
+{
+ uint8_t status = get_u8(data);
+ uint8_t subcmd = get_u8(data + 1);
+ int i;
+ const char *str = "Unknown Sub Command";
+
+ print_status(status);
+
+ for (i = 0; le_apcf_table[i].str; i++) {
+ if (le_apcf_table[i].subcmd == subcmd) {
+ str = le_apcf_table[i].str;
+ break;
+ }
+ }
+
+ print_field("Advertising Packet Content Filter OPcode: %s (%u)",
+ str, subcmd);
+}
+#endif
+
static const struct vendor_ocf vendor_ocf_table[] = {
{ 0x001, "Write BD ADDR",
write_bd_addr_cmd, 6, true,
@@ -157,6 +844,25 @@ static const struct vendor_ocf vendor_ocf_table[] = {
{ 0x079, "Read Verbose Config Version Info",
null_cmd, 0, true,
read_verbose_version_info_rsp, 7, true },
+#ifdef __TIZEN_PATCH__
+ { 0x0153, "LE Get Vendor Capabilities",
+ null_cmd, 0, true,
+ get_vendor_capabilities_rsp, 10, false },
+ { 0x0154, "LE Multi Advertise",
+ le_multi_advt_cmd, 1, false,
+ le_multi_advt_rsp, 2, true },
+ { 0x0155, "LE RPA Offload",
+ le_rpa_offload_cmd, 1, false,
+ le_rpa_offload_rsp, 2, false },
+#if 0
+ { 0x0156, "LE Batch Scan",
+ le_batch_scan_cmd, 1, false,
+ le_batch_scan_rsp, 2, true },
+#endif
+ { 0x0157, "LE APCF",
+ le_apcf_cmd, 1, false,
+ le_apcf_rsp, 2, false },
+#endif
{ }
};
diff --git a/monitor/display.h b/monitor/display.h
index 36e189a3..fc75b455 100644
--- a/monitor/display.h
+++ b/monitor/display.h
@@ -43,7 +43,11 @@ bool use_color(void);
#define COLOR_INFO COLOR_OFF
#define COLOR_DEBUG COLOR_WHITE
+#ifdef __TIZEN_PATCH__
+#define FALLBACK_TERMINAL_WIDTH 130
+#else
#define FALLBACK_TERMINAL_WIDTH 80
+#endif
#define print_indent(indent, color1, prefix, title, color2, fmt, args...) \
do { \
diff --git a/monitor/packet.c b/monitor/packet.c
index 322bba69..7b7822f0 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -9073,3 +9073,30 @@ void packet_todo(void)
printf("\t%s\n", le_meta_event_table[i].str);
}
}
+
+#ifdef __TIZEN_PATCH__
+void print_le_set_adv_parameters_cmd(const void *data, uint8_t size)
+{
+ le_set_adv_parameters_cmd(data, size);
+}
+
+void print_le_set_random_address_cmd(const void *data, uint8_t size)
+{
+ le_set_random_address_cmd(data, size);
+}
+
+void print_le_set_adv_data_cmd(const void *data, uint8_t size)
+{
+ le_set_adv_data_cmd(data, size);
+}
+
+void print_le_set_scan_rsp_data_cmd(const void *data, uint8_t size)
+{
+ le_set_scan_rsp_data_cmd(data, size);
+}
+
+void print_le_set_adv_enable_cmd(const void *data, uint8_t size)
+{
+ le_set_adv_enable_cmd(data, size);
+}
+#endif
diff --git a/monitor/packet.h b/monitor/packet.h
index 322f1019..59cbd6e8 100644
--- a/monitor/packet.h
+++ b/monitor/packet.h
@@ -90,3 +90,11 @@ void packet_hci_scodata(struct timeval *tv, struct ucred *cred, uint16_t index,
bool in, const void *data, uint16_t size);
void packet_todo(void);
+
+#ifdef __TIZEN_PATCH__
+void print_le_set_adv_parameters_cmd(const void *data, uint8_t size);
+void print_le_set_random_address_cmd(const void *data, uint8_t size);
+void print_le_set_adv_data_cmd(const void *data, uint8_t size);
+void print_le_set_scan_rsp_data_cmd(const void *data, uint8_t size);
+void print_le_set_adv_enable_cmd(const void *data, uint8_t size);
+#endif
diff --git a/obexd/client/manager.c b/obexd/client/manager.c
index 8eaceafd..32853fc0 100644
--- a/obexd/client/manager.c
+++ b/obexd/client/manager.c
@@ -253,9 +253,16 @@ static DBusMessage *remove_session(DBusConnection *connection,
ERROR_INTERFACE ".NotAuthorized",
"Not Authorized");
+#ifdef __TIZEN_PATCH__
+ obc_session_update(session, message, connection);
+#endif
release_session(session);
+#ifdef __TIZEN_PATCH__
+ return NULL;
+#else
return dbus_message_new_method_return(message);
+#endif
}
static const GDBusMethodTable client_methods[] = {
diff --git a/obexd/client/session.c b/obexd/client/session.c
index 391d7130..75bc3cbd 100644
--- a/obexd/client/session.c
+++ b/obexd/client/session.c
@@ -117,6 +117,10 @@ struct obc_session {
guint process_id;
char *folder;
struct callback_data *callback;
+#ifdef __TIZEN_PATCH__
+ DBusMessage *message;
+ DBusConnection *connection;
+#endif
};
static GSList *sessions = NULL;
@@ -142,6 +146,17 @@ struct obc_session *obc_session_ref(struct obc_session *session)
return session;
}
+#ifdef __TIZEN_PATCH__
+void obc_session_update(struct obc_session *session, DBusMessage *message,
+ DBusConnection *connection)
+{
+ DBG("+");
+ session->message = dbus_message_ref(message);
+ session->connection = dbus_connection_ref(connection);
+ DBG("-");
+}
+#endif
+
static void session_unregistered(struct obc_session *session)
{
char *path;
@@ -266,6 +281,18 @@ static void disconnect_complete(GObex *obex, GError *err, GObexPacket *rsp,
if (err)
error("%s", err->message);
+#ifdef __TIZEN_PATCH__
+ if (session->message) {
+ /* Dbus reply need to be done */
+ DBG("Dbus reply for remove_session");
+ g_dbus_send_reply(session->connection, session->message,
+ DBUS_TYPE_INVALID);
+ dbus_message_unref(session->message);
+ dbus_connection_unref(session->connection);
+ session->message = NULL;
+ session->connection = NULL;
+ }
+#endif
/* Disconnect transport */
if (session->id > 0 && session->transport != NULL) {
session->transport->disconnect(session->id);
diff --git a/obexd/client/session.h b/obexd/client/session.h
index 10d0272b..14704be1 100644
--- a/obexd/client/session.h
+++ b/obexd/client/session.h
@@ -82,4 +82,6 @@ void obc_session_cancel(struct obc_session *session, guint id,
gboolean remove);
#ifdef __TIZEN_PATCH__
void release_session(struct obc_session *session);
+void obc_session_update(struct obc_session *session, DBusMessage *message,
+ DBusConnection *connection);
#endif
diff --git a/obexd/plugins/messages-tizen.c b/obexd/plugins/messages-tizen.c
index 7613484a..4797da63 100644
--- a/obexd/plugins/messages-tizen.c
+++ b/obexd/plugins/messages-tizen.c
@@ -1154,8 +1154,19 @@ int messages_push_message(void *session, const char *folder,
DBG("session->cwd %s +\n", s->cwd);
- if (folder)
- folder_path = g_strdup(folder);
+ if (g_ascii_strncasecmp(s->cwd, "/telecom/msg",
+ strlen("/telecom/msg")) != 0) {
+ DBG("Path Not Set properly");
+ return -1;
+ }
+
+ if ((folder[0] == '\0') && (g_strcmp0(s->cwd, "/telecom/msg") == 0)) {
+ DBG("Invalid Folders");
+ return -1;
+ }
+
+ if ((folder[0] != '\0'))
+ folder_path = g_strconcat("/telecom/msg/", folder, NULL);
else
folder_path = g_strdup(s->cwd);
diff --git a/plugins/dbusoob.c b/plugins/dbusoob.c
index 2563dc51..20a90f62 100644
--- a/plugins/dbusoob.c
+++ b/plugins/dbusoob.c
@@ -23,6 +23,7 @@
*
*/
+#ifdef __TIZEN_PATCH__
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
@@ -38,7 +39,6 @@
#include "src/log.h"
#include "src/dbus-common.h"
#include "src/adapter.h"
-#include "src/oob.h"
#include "src/device.h"
#include "src/eir.h"
#include "src/agent.h"
@@ -75,8 +75,10 @@ static struct oob_request *find_oob_request(struct btd_adapter *adapter)
return NULL;
}
-static void read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
- uint8_t *randomizer)
+static void read_local_data_complete(struct btd_adapter *adapter,
+ const uint8_t *hash192, const uint8_t *randomizer192,
+ const uint8_t *hash256, const uint8_t *randomizer256,
+ void *user_data)
{
struct DBusMessage *reply;
struct oob_request *oob_request;
@@ -85,10 +87,14 @@ static void read_local_data_complete(struct btd_adapter *adapter, uint8_t *hash,
if (!oob_request)
return;
- if (hash && randomizer)
+ if ((hash192 && randomizer192) || (hash256 && randomizer256))
reply = g_dbus_create_reply(oob_request->msg,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, 16,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, 16,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash192, 16,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer192, 16,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &hash256, hash256 ? 16 : 0,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
+ &randomizer256, randomizer256 ? 16 : 0,
DBUS_TYPE_INVALID);
else
reply = btd_error_failed(oob_request->msg,
@@ -126,12 +132,7 @@ static DBusMessage *read_local_data(DBusConnection *conn, DBusMessage *msg,
oob_request->msg = dbus_message_ref(msg);
handler = g_new0(struct oob_handler, 1);
-#ifdef __TIZEN_PATCH__
- handler->read_local_cb = (oob_read_local_cb_t)oob_read_local_data_complete;
-#else
- handler->read_local_cb = oob_read_local_data_complete;
-#endif
- handler->user_data = dbus_message_ref(oob_request->msg);
+ handler->read_local_cb = read_local_data_complete;
btd_adapter_set_oob_handler(oob_request->adapter, handler);
@@ -142,24 +143,39 @@ static DBusMessage *add_remote_data(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct btd_adapter *adapter = data;
- uint8_t *hash, *randomizer;
- int32_t hlen, rlen;
- const char *addr;
+ const char *addr = NULL;
+ uint8_t *hash192 = NULL;
+ uint8_t *randomizer192 = NULL;
+ int32_t h192_len = 0;
+ int32_t r192_len = 0;
+ uint8_t *hash256 = NULL;
+ uint8_t *randomizer256 = NULL;
+ int32_t h256_len = 0;
+ int32_t r256_len = 0;
bdaddr_t bdaddr;
+ uint8_t addr_type = 0;
+ bool valid_len;
if (!dbus_message_get_args(msg, NULL,
DBUS_TYPE_STRING, &addr,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash, &hlen,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer, &rlen,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash192, &h192_len,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer192, &r192_len,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &hash256, &h256_len,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &randomizer256, &r256_len,
DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
- if (hlen != 16 || rlen != 16 || bachk(addr))
+ valid_len = (h192_len == 16 && r192_len == 16) ||
+ (h256_len == 16 && r256_len == 16);
+
+ if (!valid_len || bachk(addr))
return btd_error_invalid_args(msg);
str2ba(addr, &bdaddr);
- if (btd_adapter_add_remote_oob_data(adapter, &bdaddr, hash, randomizer))
+ if (btd_adapter_add_remote_oob_ext_data(adapter, &bdaddr, addr_type,
+ hash192, randomizer192,
+ hash256, randomizer256))
return btd_error_failed(msg, "Request failed");
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
@@ -171,6 +187,7 @@ static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
struct btd_adapter *adapter = data;
const char *addr;
bdaddr_t bdaddr;
+ uint8_t addr_type = 0;
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &addr,
DBUS_TYPE_INVALID))
@@ -181,7 +198,7 @@ static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
str2ba(addr, &bdaddr);
- if (btd_adapter_remove_remote_oob_data(adapter, &bdaddr))
+ if (btd_adapter_remove_remote_oob_ext_data(adapter, &bdaddr, addr_type))
return btd_error_failed(msg, "Request failed");
return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
@@ -189,15 +206,18 @@ static DBusMessage *remove_remote_data(DBusConnection *conn, DBusMessage *msg,
static const GDBusMethodTable oob_methods[] = {
{ GDBUS_METHOD("AddRemoteData",
- GDBUS_ARGS({ "address", "s" }, { "hash", "ay" },
- { "randomizer", "ay" }), NULL,
+ GDBUS_ARGS({ "address", "s" },
+ { "hash192", "ay" }, { "randomizer192", "ay" },
+ { "hash256", "ay" }, { "randomizer256", "ay" }),
+ NULL,
add_remote_data) },
{ GDBUS_METHOD("RemoveRemoteData",
GDBUS_ARGS({ "address", "s" }), NULL,
remove_remote_data) },
{ GDBUS_ASYNC_METHOD("ReadLocalData",
- NULL, GDBUS_ARGS({ "hash", "ay" },
- { "randomizer", "ay" }),
+ NULL, GDBUS_ARGS(
+ {"hash192", "ay" }, { "randomizer192", "ay" },
+ {"hash256", "ay" }, { "randomizer256", "ay" }),
read_local_data) },
{ }
};
@@ -220,7 +240,7 @@ static int oob_probe(struct btd_adapter *adapter)
static void oob_remove(struct btd_adapter *adapter)
{
- read_local_data_complete(adapter, NULL, NULL);
+ read_local_data_complete(adapter, NULL, NULL, NULL, NULL, NULL);
g_dbus_unregister_interface(connection, adapter_get_path(adapter),
OOB_INTERFACE);
@@ -238,8 +258,6 @@ static int dbusoob_init(void)
connection = btd_get_dbus_connection();
- oob_register_cb(read_local_data_complete);
-
return btd_register_adapter_driver(&oob_driver);
}
@@ -252,3 +270,4 @@ static void dbusoob_exit(void)
BLUETOOTH_PLUGIN_DEFINE(dbusoob, VERSION, BLUETOOTH_PLUGIN_PRIORITY_DEFAULT,
dbusoob_init, dbusoob_exit)
+#endif
diff --git a/plugins/neard.c b/plugins/neard.c
index cabcf340..4f068c32 100644
--- a/plugins/neard.c
+++ b/plugins/neard.c
@@ -259,9 +259,16 @@ static DBusMessage *create_request_oob_reply(struct btd_adapter *adapter,
return reply;
}
+#ifdef __TIZEN_PATCH__
+static void read_local_complete(struct btd_adapter *adapter,
+ const uint8_t *hash, const uint8_t *randomizer,
+ const uint8_t *hash256, const uint8_t *randomizer256,
+ void *user_data)
+#else
static void read_local_complete(struct btd_adapter *adapter,
const uint8_t *hash, const uint8_t *randomizer,
void *user_data)
+#endif
{
DBusMessage *msg = user_data;
DBusMessage *reply;
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;
diff --git a/src/adapter.c b/src/adapter.c
index 7310d56a..d27fa596 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -113,7 +113,7 @@
#define check_address(address) bachk(address)
#define ADV_DATA_MAX_LENGTH 31
#define SCAN_RESPONSE_DATA_LENGTH_MAX 31
-#define MANUFACTURER_DATA_LENGTH_MAX 28
+#define EIR_MANUFACTURER_DATA_LENGTH_MAX 100
#define PRIVATE_ADDR_TIMEOUT (15 * 60)
#define BT_DISC_TYPE_BREDR 1
@@ -123,6 +123,8 @@
#define DISCOV_TYPE_BREDR 1
#define DISCOV_TYPE_LE 6
+#define LE_BEARER_POSTFIX " LE"
+#define LE_BEARER_POSTFIX_LEN 3
#endif /* __TIZEN_PATCH__ */
@@ -254,7 +256,7 @@ struct btd_adapter {
char *stored_alias; /* stored adapter name alias */
#ifdef __TIZEN_PATCH__
bool le_privacy_enabled; /* whether LE Privacy feature enabled */
- char local_irk[MGMT_IRK_SIZE]; /* adapter local IRK */
+ uint8_t *local_irk; /* adapter local IRK */
uint8_t disc_type;
bool ipsp_intialized; /* Ipsp Initialization state */
struct le_data_length_read_handler *read_handler;
@@ -303,19 +305,9 @@ struct btd_adapter {
GSList *adv_list; /* List of advertising instance */
bool advertising; /* Advertising active */
gchar *version; /* Bluetooth Version */
-#if 0 // Not used
- bool secure_connection; /* Secure Connection active*/
- uint16_t auth_payload_timeout; /* Authenticated payload timeout value*/
-
- bool set_new_rpa; /* RPA to be set */
- bool rpa_is_set; /* RPA is set */
-#endif
-
uint8_t adv_tx_power;
-
bool le_discovering; /* LE Discovery active */
GSList *le_discovery_list; /* list of LE discovery clients */
- gboolean le_auto_connect; /* LE Auto connection */
#endif
GSList *pin_callbacks;
@@ -343,15 +335,8 @@ struct btd_adapter {
bool is_default; /* true if adapter is default one */
};
-
#ifdef __TIZEN_PATCH__
enum {
- DISABLE_PRIVACY,
- ENABLE_PRIVACY,
- GEN_IRK_THEN_ENABLE_PRIVACY
-};
-
-enum {
DEINIT_6LOWPAN,
INIT_6LOWPAN
};
@@ -1564,77 +1549,6 @@ void btd_adapter_unpair_device(struct btd_adapter *adapter,
device_unpair(dev, TRUE);
DBG("-");
}
-
-gboolean adapter_clear_le_white_list(struct btd_adapter *adapter)
-{
- if (mgmt_send(adapter->mgmt, MGMT_OP_CLEAR_DEV_WHITE_LIST,
- adapter->dev_id, 0, NULL,
- NULL, NULL, NULL) > 0)
- return TRUE;
- else
- return FALSE;
-}
-
-gboolean adapter_add_le_white_list(struct btd_adapter *adapter, struct btd_device *device)
-{
- struct mgmt_cp_add_dev_white_list cp;
- const bdaddr_t *dst;
- char device_addr[18];
-
- memset(&cp, 0, sizeof(cp));
-
- dst = device_get_address(device);
-
- ba2str(device_get_address(device), device_addr);
- DBG("addr %s bdaddr type %d", device_addr, btd_device_get_bdaddr_type(device));
-
- if ( btd_device_get_bdaddr_type(device) == BDADDR_LE_PUBLIC)
- cp.bdaddr_type = 0x0;
- else
- cp.bdaddr_type = 0x1;
-
- memcpy(&cp.bdaddr, dst, sizeof(bdaddr_t));
-
- if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_DEV_WHITE_LIST,
- adapter->dev_id, sizeof(cp), &cp,
- NULL, NULL, NULL) > 0)
- return TRUE;
-
- DBG("Unable to add white list");
-
- return FALSE;
-}
-
-gboolean btd_adapter_is_le_auto_connect(struct btd_adapter *adapter)
-{
- return adapter->le_auto_connect;
-}
-
-void btd_adapter_set_le_auto_connect(struct btd_adapter *adapter, gboolean auto_connect)
-{
- adapter->le_auto_connect = auto_connect;
-}
-
-gboolean btd_adapter_disable_le_auto_connect(struct btd_adapter *adapter)
-{
- if (btd_adapter_is_le_auto_connect(adapter) == FALSE) {
- error("le auto connection is not going on");
- return FALSE;
- }
-
- DBG("disable le auto connect : %u", adapter->dev_id);
-
- if (mgmt_send(adapter->mgmt, MGMT_OP_DISABLE_LE_AUTO_CONNECT,
- adapter->dev_id, 0, NULL,
- NULL, NULL, NULL) > 0) {
- btd_adapter_set_le_auto_connect(adapter, FALSE);
- return TRUE;
- }
-
- error("Failed to disable le auto conn : %u", adapter->dev_id);
-
- return FALSE;
-}
#endif
void btd_adapter_remove_device(struct btd_adapter *adapter,
@@ -1989,6 +1903,7 @@ static void start_le_discovery_complete(uint8_t status, uint16_t length,
const struct mgmt_cp_start_discovery *rp = param;
DBG("status 0x%02x", status);
+ DBG("Discovery Type 0x%02x", rp->type);
if (length < sizeof(*rp)) {
error("Wrong size of start discovery return parameters");
return;
@@ -1998,8 +1913,6 @@ static void start_le_discovery_complete(uint8_t status, uint16_t length,
adapter->discovery_type |= rp->type;
adapter->discovery_enable = 0x01;
- DBG("Discovery Type 0x%02x", rp->type);
-
if (adapter->le_discovering)
return;
@@ -2026,40 +1939,24 @@ static void start_le_discovery_complete(uint8_t status, uint16_t length,
static gboolean start_discovery_timeout(gpointer user_data)
{
struct btd_adapter *adapter = user_data;
-#ifdef __TIZEN_PATCH__
- struct mgmt_cp_start_discovery cp;
- uint8_t new_type = 0;
-#else
+#ifndef __TIZEN_PATCH__
struct mgmt_cp_start_service_discovery *sd_cp;
- uint8_t new_type;
#endif
+ uint8_t new_type;
DBG("");
adapter->discovery_idle_timeout = 0;
#ifdef __TIZEN_PATCH__
- if (adapter->disc_type == BT_DISC_TYPE_BREDR_ONLY) {
-
- if (adapter->current_settings & MGMT_SETTING_BREDR)
- new_type = (1 << BDADDR_BREDR);
- else
- new_type = 0;
-
- } else if (adapter->disc_type == BT_DISC_TYPE_LE_ONLY) {
-
- if (adapter->current_settings & MGMT_SETTING_LE)
- new_type = (1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM);
-
- } else if (adapter->disc_type == BT_DISC_TYPE_LE_BREDR) {
-
- if (adapter->current_settings & MGMT_SETTING_BREDR)
- new_type = (1 << BDADDR_BREDR);
- else
- new_type = 0;
- if (adapter->current_settings & MGMT_SETTING_LE)
- new_type |= (1 << BDADDR_LE_PUBLIC) | (1 << BDADDR_LE_RANDOM);
- }
+ if (adapter->disc_type == BT_DISC_TYPE_BREDR_ONLY)
+ new_type = SCAN_TYPE_BREDR;
+ else if (adapter->disc_type == BT_DISC_TYPE_LE_ONLY)
+ new_type = SCAN_TYPE_LE;
+ else if (adapter->disc_type == BT_DISC_TYPE_LE_BREDR)
+ new_type = SCAN_TYPE_DUAL;
+ else
+ new_type = 0;
if (adapter->discovery_enable == 0x01) {
/*
@@ -2067,7 +1964,7 @@ static gboolean start_discovery_timeout(gpointer user_data)
* same type, then just keep it.
*/
if (adapter->disc_type == BT_DISC_TYPE_BREDR_ONLY) {
- if ((adapter->discovery_type & new_type) == 0x01) {
+ if ((adapter->discovery_type & new_type) == SCAN_TYPE_BREDR) {
if (adapter->discovering)
return FALSE;
@@ -2079,7 +1976,7 @@ static gboolean start_discovery_timeout(gpointer user_data)
}
} else if (adapter->disc_type == BT_DISC_TYPE_LE_ONLY) {
- if ((adapter->discovery_type & new_type) == 0x06) {
+ if ((adapter->discovery_type & new_type) == SCAN_TYPE_LE) {
if (adapter->le_discovering)
return FALSE;
@@ -2093,14 +1990,15 @@ static gboolean start_discovery_timeout(gpointer user_data)
}
DBG("adapter->disc_type [%d]", adapter->disc_type);
+ struct mgmt_cp_start_discovery cp;
if (adapter->disc_type == BT_DISC_TYPE_BREDR_ONLY) {
- cp.type = 0x01;
+ cp.type = new_type;
mgmt_send(adapter->mgmt, MGMT_OP_START_DISCOVERY,
adapter->dev_id, sizeof(cp), &cp,
start_discovery_complete, adapter, NULL);
} else if (adapter->disc_type == BT_DISC_TYPE_LE_ONLY) {
- cp.type = 0x06;
+ cp.type = new_type;
mgmt_send(adapter->mgmt, MGMT_OP_START_LE_DISCOVERY,
adapter->dev_id, sizeof(cp), &cp,
start_le_discovery_complete, adapter, NULL);
@@ -2203,12 +2101,6 @@ static void trigger_start_discovery(struct btd_adapter *adapter, guint delay)
if (!(adapter->current_settings & MGMT_SETTING_POWERED))
return;
-#ifdef __TIZEN_PATCH__
- if (delay == 0) {
- start_discovery_timeout((gpointer)adapter);
- return;
- }
-#endif
adapter->discovery_idle_timeout = g_timeout_add_seconds(delay,
start_discovery_timeout, adapter);
}
@@ -2222,38 +2114,15 @@ static void suspend_discovery_complete(uint8_t status, uint16_t length,
DBG("status 0x%02x", status);
if (status == MGMT_STATUS_SUCCESS) {
-#ifdef __TIZEN_PATCH__
- adapter->discovery_type &= (~0x01);
-#else
adapter->discovery_type = 0x00;
-#endif
adapter->discovery_enable = 0x00;
return;
}
}
-#ifdef __TIZEN_PATCH__
-static void suspend_le_discovery_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- struct btd_adapter *adapter = user_data;
-
- DBG("status 0x%02x", status);
-
- if (status == MGMT_STATUS_SUCCESS) {
- adapter->discovery_type &= (~0x06);
- adapter->discovery_enable = 0x00;
- return;
- }
-}
-#endif
-
static void suspend_discovery(struct btd_adapter *adapter)
{
struct mgmt_cp_stop_discovery cp;
-#ifdef __TIZEN_PATCH__
- struct mgmt_cp_stop_le_discovery le_cp;
-#endif
DBG("");
@@ -2263,14 +2132,8 @@ static void suspend_discovery(struct btd_adapter *adapter)
* If there are no clients discovering right now, then there is
* also nothing to suspend.
*/
-#ifdef __TIZEN_PATCH__
- if (adapter->discovery_list == NULL && adapter->le_discovery_list == NULL )
- return;
-#else
if (!adapter->discovery_list)
return;
-#endif
-
/*
* In case of being inside the idle phase, make sure to remove
@@ -2286,26 +2149,11 @@ static void suspend_discovery(struct btd_adapter *adapter)
if (adapter->discovery_enable == 0x00)
return;
-#ifdef __TIZEN_PATCH__
- if (adapter->discovery_list) {
- cp.type = 0x01;
- mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY,
- adapter->dev_id, sizeof(cp), &cp,
- suspend_discovery_complete, adapter, NULL);
- }
- if (adapter->le_discovery_list) {
- le_cp.type = 0x06;
- mgmt_send(adapter->mgmt, MGMT_OP_STOP_LE_DISCOVERY,
- adapter->dev_id, sizeof(le_cp), &le_cp,
- suspend_le_discovery_complete, adapter, NULL);
- }
-#else
cp.type = adapter->discovery_type;
mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY,
adapter->dev_id, sizeof(cp), &cp,
suspend_discovery_complete, adapter, NULL);
-#endif
}
static void resume_discovery(struct btd_adapter *adapter)
@@ -2326,35 +2174,8 @@ static void resume_discovery(struct btd_adapter *adapter)
* idle time for a normal discovery. So just trigger the default
* restart procedure.
*/
-#ifdef __TIZEN_PATCH__
- adapter->disc_type = BT_DISC_TYPE_BREDR_ONLY;
-#endif
trigger_start_discovery(adapter, IDLE_DISCOV_TIMEOUT);
}
-
-#ifdef __TIZEN_PATCH__
-static void resume_le_discovery(struct btd_adapter *adapter)
-{
- DBG("");
-
- adapter->discovery_suspended = false;
-
- /*
- * If there are no clients discovering right now, then there is
- * also nothing to resume.
- */
- if (adapter->le_discovery_list == NULL)
- return;
-
- /*
- * Treat a suspended discovery session the same as extra long
- * idle time for a normal discovery. So just trigger the default
- * restart procedure.
- */
- adapter->disc_type = BT_DISC_TYPE_LE_ONLY;
- trigger_start_discovery(adapter, IDLE_LE_DISCOV_TIMEOUT);
-}
-#endif
#endif
static void discovering_callback(uint16_t index, uint16_t length,
@@ -2544,7 +2365,6 @@ static void discovery_cleanup(struct btd_adapter *adapter)
adapter->discovery_found = NULL;
}
-#ifndef __TIZEN_PATCH__
static gboolean remove_temp_devices(gpointer user_data)
{
struct btd_adapter *adapter = user_data;
@@ -2565,7 +2385,6 @@ static gboolean remove_temp_devices(gpointer user_data)
return FALSE;
}
-#endif
static gint g_strcmp(gconstpointer a, gconstpointer b)
{
@@ -2800,14 +2619,8 @@ static void discovery_destroy(void *user_data)
* If there are other client discoveries in progress, then leave
* it active. If not, then make sure to stop the restart timeout.
*/
-
-#ifdef __TIZEN_PATCH__
- if (adapter->discovery_list || adapter->le_discovery_list)
- return;
-#else
if (adapter->discovery_list)
return;
-#endif
adapter->discovery_type = 0x00;
@@ -2822,10 +2635,55 @@ static void discovery_destroy(void *user_data)
}
discovery_cleanup(adapter);
-#ifndef __TIZEN_PATCH__
+
adapter->temp_devices_timeout = g_timeout_add_seconds(TEMP_DEV_TIMEOUT,
remove_temp_devices, adapter);
-#endif
+}
+
+static void discovery_disconnect(DBusConnection *conn, void *user_data)
+{
+ struct watch_client *client = user_data;
+ struct btd_adapter *adapter = client->adapter;
+ struct mgmt_cp_stop_discovery cp;
+
+ DBG("owner %s", client->owner);
+
+ adapter->set_filter_list = g_slist_remove(adapter->set_filter_list,
+ client);
+
+ adapter->discovery_list = g_slist_remove(adapter->discovery_list,
+ client);
+
+ /*
+ * There is no need for extra cleanup of the client since that
+ * will be done by the destroy callback.
+ *
+ * However in case this is the last client, the discovery in
+ * the kernel needs to be disabled.
+ */
+ if (adapter->discovery_list) {
+ update_discovery_filter(adapter);
+ return;
+ }
+
+ /*
+ * In the idle phase of a discovery, there is no need to stop it
+ * and so it is enough to send out the signal and just return.
+ */
+ if (adapter->discovery_enable == 0x00) {
+ adapter->discovering = false;
+ g_dbus_emit_property_changed(dbus_conn, adapter->path,
+ ADAPTER_INTERFACE, "Discovering");
+
+ trigger_passive_scanning(adapter);
+ return;
+ }
+
+ cp.type = adapter->discovery_type;
+
+ mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY,
+ adapter->dev_id, sizeof(cp), &cp,
+ stop_discovery_complete, adapter, NULL);
}
/*
@@ -2891,71 +2749,8 @@ static void le_discovery_destroy(void *user_data)
}
discovery_cleanup(adapter);
-#ifndef __TIZEN_PATCH__
- adapter->temp_devices_timeout = g_timeout_add_seconds(TEMP_DEV_TIMEOUT,
- remove_temp_devices, adapter);
-#endif
-}
-#endif
-
-static void discovery_disconnect(DBusConnection *conn, void *user_data)
-{
- struct watch_client *client = user_data;
- struct btd_adapter *adapter = client->adapter;
- struct mgmt_cp_stop_discovery cp;
-
- DBG("owner %s", client->owner);
-
- adapter->set_filter_list = g_slist_remove(adapter->set_filter_list,
- client);
-
- adapter->discovery_list = g_slist_remove(adapter->discovery_list,
- client);
-
- /*
- * There is no need for extra cleanup of the client since that
- * will be done by the destroy callback.
- *
- * However in case this is the last client, the discovery in
- * the kernel needs to be disabled.
- */
- if (adapter->discovery_list) {
- update_discovery_filter(adapter);
- return;
- }
-
- /*
- * In the idle phase of a discovery, there is no need to stop it
- * and so it is enough to send out the signal and just return.
- */
- if (adapter->discovery_enable == 0x00) {
- adapter->discovering = false;
- g_dbus_emit_property_changed(dbus_conn, adapter->path,
- ADAPTER_INTERFACE, "Discovering");
-
-#ifdef __TIZEN_PATCH__
- if (adapter->discovering == false && adapter->le_discovering == false) {
- trigger_passive_scanning(adapter);
- return;
- }
-#else
- trigger_passive_scanning(adapter);
- return;
-#endif
- }
-
-#ifdef __TIZEN_PATCH__
- cp.type = 0x01;
-#else
- cp.type = adapter->discovery_type;
-#endif
-
- mgmt_send(adapter->mgmt, MGMT_OP_STOP_DISCOVERY,
- adapter->dev_id, sizeof(cp), &cp,
- stop_discovery_complete, adapter, NULL);
}
-#ifdef __TIZEN_PATCH__
static void le_discovery_disconnect(DBusConnection *conn, void *user_data)
{
struct watch_client *client = user_data;
@@ -2998,74 +2793,18 @@ static void le_discovery_disconnect(DBusConnection *conn, void *user_data)
adapter->dev_id, sizeof(cp), &cp,
stop_discovery_complete, adapter, NULL);
}
-#endif
-static DBusMessage *start_discovery(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct btd_adapter *adapter = user_data;
- const char *sender = dbus_message_get_sender(msg);
- struct watch_client *client;
- bool is_discovering;
-
- DBG("sender %s", sender);
-
- if (!(adapter->current_settings & MGMT_SETTING_POWERED))
- return btd_error_not_ready(msg);
- is_discovering = get_discovery_client(adapter, sender, &client);
-
- /*
- * Every client can only start one discovery, if the client
- * already started a discovery then return an error.
- */
- if (is_discovering)
- return btd_error_busy(msg);
-
- /*
- * If there was pre-set filter, just reconnect it to discovery_list,
- * and trigger scan.
- */
- if (client) {
- adapter->set_filter_list = g_slist_remove(
- adapter->set_filter_list, client);
- adapter->discovery_list = g_slist_prepend(
- adapter->discovery_list, client);
- update_discovery_filter(adapter);
- return dbus_message_new_method_return(msg);
- }
-
- client = g_new0(struct watch_client, 1);
-
- client->adapter = adapter;
- client->owner = g_strdup(sender);
- client->discovery_filter = NULL;
- client->watch = g_dbus_add_disconnect_watch(dbus_conn, sender,
- discovery_disconnect, client,
- discovery_destroy);
- adapter->discovery_list = g_slist_prepend(adapter->discovery_list,
- client);
-
-#ifdef __TIZEN_PATCH__
- adapter->disc_type = BT_DISC_TYPE_BREDR_ONLY;
-#endif
-
- /*
- * Just trigger the discovery here. In case an already running
- * discovery in idle phase exists, it will be restarted right
- * away.
- */
- update_discovery_filter(adapter);
-
- return dbus_message_new_method_return(msg);
-}
-
-#ifdef __TIZEN_PATCH__
static int set_adv_data_flag(uint8_t *adv_data, uint8_t *data, int data_len)
{
adv_data[0] = 2;
adv_data[1] = EIR_FLAGS;
- adv_data[2] = EIR_GEN_DISC;
+#ifdef TIZEN_KITT
+ adv_data[2] = EIR_GEN_DISC | EIR_CONTROLLER |
+ EIR_SIM_HOST | EIR_BREDR_UNSUP;
+#else
+ adv_data[2] = EIR_GEN_DISC | EIR_CONTROLLER | EIR_SIM_HOST;
+#endif
memcpy(adv_data + 3, data, data_len);
return data_len + 3;
@@ -3164,11 +2903,6 @@ int adapter_le_set_missed_adv_data(uint8_t *p_data, uint8_t data_len,
int len;
data = g_malloc0(ADV_DATA_MAX_LENGTH);
- /* Fix : NULL_RETURNS */
- if (data == NULL) {
- return -1;
- }
-
memcpy(data, p_data, data_len);
len = data_len;
@@ -3383,7 +3117,7 @@ static DBusMessage *adapter_set_advertising(DBusConnection *conn,
return btd_error_invalid_args(msg);
if (adapter_le_is_supported_multi_advertising() && slot_id > 0)
- err = adapter_le_enable_multi_adv(enable, slot_id);
+ err = adapter_le_enable_multi_adv(adapter, enable, slot_id);
else
err = set_mode(adapter, MGMT_OP_SET_ADVERTISING, enable);
@@ -3493,6 +3227,8 @@ static DBusMessage *adapter_set_advertising_data(DBusConnection *conn,
dbus_int32_t slot_id;
uint8_t *adv_data = NULL;
int adv_len = 0;
+ char *adapter_name = adapter->name;
+ char le_name[MAX_NAME_LENGTH + 1] = { 0 };
DBG("Set advertising data");
@@ -3508,8 +3244,20 @@ static DBusMessage *adapter_set_advertising_data(DBusConnection *conn,
if (len > ADV_DATA_MAX_LENGTH - 3)
return btd_error_invalid_args(msg);
+ if (adapter->le_static_addr.b[5] != 0) {
+ char *ptr = NULL;
+
+ g_strlcpy(le_name, adapter_name,
+ sizeof(le_name) - LE_BEARER_POSTFIX_LEN);
+ if (!g_utf8_validate(le_name, -1, (const char **)&ptr))
+ *ptr = '\0';
+
+ g_strlcat(le_name, LE_BEARER_POSTFIX, sizeof(le_name));
+ adapter_name = le_name;
+ }
+
adapter_le_set_missed_adv_data(value, len, FALSE,
- adapter->name, adapter->adv_tx_power, &adv_data, &adv_len);
+ adapter_name, adapter->adv_tx_power, &adv_data, &adv_len);
if (adapter_le_is_supported_multi_advertising() && slot_id > 0) {
if (adapter_le_set_multi_adv_data(slot_id, FALSE, adv_len, adv_data)) {
@@ -3764,6 +3512,9 @@ static DBusMessage *adapter_set_scan_rsp_data(DBusConnection *conn,
uint8_t *adv_data = NULL;
int adv_len = 0;
+ char *adapter_name = adapter->name;
+ char le_name[MAX_NAME_LENGTH + 1] = { 0 };
+
DBG("Set scan response data");
if (!(adapter->current_settings & MGMT_SETTING_POWERED))
@@ -3778,8 +3529,20 @@ static DBusMessage *adapter_set_scan_rsp_data(DBusConnection *conn,
if (len > SCAN_RESPONSE_DATA_LENGTH_MAX)
return btd_error_invalid_args(msg);
+ if (adapter->le_static_addr.b[5] != 0) {
+ char *ptr = NULL;
+
+ g_strlcpy(le_name, adapter_name,
+ sizeof(le_name) - LE_BEARER_POSTFIX_LEN);
+ if (!g_utf8_validate(le_name, -1, (const char **)&ptr))
+ *ptr = '\0';
+
+ g_strlcat(le_name, LE_BEARER_POSTFIX, sizeof(le_name));
+ adapter_name = le_name;
+ }
+
adapter_le_set_missed_adv_data(value, len, TRUE,
- adapter->name, adapter->adv_tx_power, &adv_data, &adv_len);
+ adapter_name, adapter->adv_tx_power, &adv_data, &adv_len);
if (adapter_le_is_supported_multi_advertising() && slot_id > 0) {
if (adapter_le_set_multi_adv_data(slot_id, TRUE, adv_len, (uint8_t *)adv_data)) {
@@ -4099,85 +3862,6 @@ static DBusMessage *adapter_set_le_static_address(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
-#if 0 // Not used
-static void read_sec_conn_host_support_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_sec_conn_host_support *rp = param;
- struct btd_adapter *adapter = user_data;
-
- if (status != MGMT_STATUS_SUCCESS) {
- error("Failed to read secure conn parameter: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size of read secure connections host support");
- return;
- }
-
- if (rp->sec_conn_host_support)
- adapter->secure_connection = TRUE;
- else
- adapter->secure_connection = FALSE;
-
- g_dbus_emit_property_changed(dbus_conn, adapter->path,
- ADAPTER_INTERFACE, "SecureConnection");
-}
-
-static DBusMessage *read_sec_conn_host_support(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct btd_adapter *adapter = user_data;
-
- mgmt_send(adapter->mgmt, MGMT_OP_READ_SEC_CONN_HOST_SUPPORT,
- adapter->dev_id, 0, NULL,
- read_sec_conn_host_support_complete, adapter, NULL);
-
- return dbus_message_new_method_return(msg);
-}
-
-static void write_sec_conn_host_support_complete(uint8_t status,
- uint16_t length, const void *param, void *user_data)
-{
- const struct mgmt_rp_write_sec_conn_host_support *rp = param;
- if (status != MGMT_STATUS_SUCCESS) {
- error("Failed to write secure connections host \
- support parameter: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size of write secure connections host\
- support parameter");
- return;
- }
-}
-
-static DBusMessage *write_sec_conn_host_support(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
-
- struct mgmt_cp_write_sec_conn_host_support cp;
- dbus_bool_t enable = FALSE;
- struct btd_adapter *adapter = user_data;
-
- if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN,
- &enable, DBUS_TYPE_INVALID))
- return btd_error_invalid_args(msg);
-
- memset(&cp, 0, sizeof(cp));
- cp.secure_connection_host_support = enable;
- mgmt_send(adapter->mgmt, MGMT_OP_WRITE_SEC_CONN_HOST_SUPPORT,
- adapter->dev_id, sizeof(cp), &cp,
- write_sec_conn_host_support_complete,
- NULL, NULL);
- return dbus_message_new_method_return(msg);
-}
-#endif
-
static DBusMessage *adapter_enable_rssi(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -4320,7 +4004,7 @@ static void adapter_get_adv_tx_power(void *data)
return;
}
#endif
-
+#ifdef __BROADCOM_PATCH__
static DBusMessage *set_wbs_parameters(DBusConnection *conn,
DBusMessage *msg, void *data)
{
@@ -4405,6 +4089,7 @@ static DBusMessage *set_nb_parameters(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
+#endif /* __BROADCOM_PATCH__ */
#ifdef __TIZEN_PATCH__
void btd_adapter_set_read_le_data_length_handler(
@@ -4775,20 +4460,82 @@ static DBusMessage *adapter_set_manufacturer_data(DBusConnection *conn,
DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
- if (len > MANUFACTURER_DATA_LENGTH_MAX)
+ if (len > EIR_MANUFACTURER_DATA_LENGTH_MAX)
return btd_error_invalid_args(msg);
memcpy(&cp, value, len);
if (mgmt_send(adapter->mgmt, MGMT_OP_SET_MANUFACTURER_DATA,
- adapter->dev_id, MANUFACTURER_DATA_LENGTH_MAX,
+ adapter->dev_id, EIR_MANUFACTURER_DATA_LENGTH_MAX,
&cp, NULL, NULL, NULL) > 0)
return dbus_message_new_method_return(msg);
return btd_error_failed(msg, "Set manufacturer data failed");
}
+
#endif /* __TIZEN_PATCH__ */
+
+static DBusMessage *start_discovery(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct btd_adapter *adapter = user_data;
+ const char *sender = dbus_message_get_sender(msg);
+ struct watch_client *client;
+ bool is_discovering;
+
+ DBG("sender %s", sender);
+
+ if (!(adapter->current_settings & MGMT_SETTING_POWERED))
+ return btd_error_not_ready(msg);
+
+ is_discovering = get_discovery_client(adapter, sender, &client);
+
+ /*
+ * Every client can only start one discovery, if the client
+ * already started a discovery then return an error.
+ */
+ if (is_discovering)
+ return btd_error_busy(msg);
+
+ /*
+ * If there was pre-set filter, just reconnect it to discovery_list,
+ * and trigger scan.
+ */
+ if (client) {
+ adapter->set_filter_list = g_slist_remove(
+ adapter->set_filter_list, client);
+ adapter->discovery_list = g_slist_prepend(
+ adapter->discovery_list, client);
+ update_discovery_filter(adapter);
+ return dbus_message_new_method_return(msg);
+ }
+
+ client = g_new0(struct watch_client, 1);
+
+ client->adapter = adapter;
+ client->owner = g_strdup(sender);
+ client->discovery_filter = NULL;
+ client->watch = g_dbus_add_disconnect_watch(dbus_conn, sender,
+ discovery_disconnect, client,
+ discovery_destroy);
+ adapter->discovery_list = g_slist_prepend(adapter->discovery_list,
+ client);
+
+#ifdef __TIZEN_PATCH__
+ adapter->disc_type = BT_DISC_TYPE_BREDR_ONLY;
+#endif
+
+ /*
+ * Just trigger the discovery here. In case an already running
+ * discovery in idle phase exists, it will be restarted right
+ * away.
+ */
+ update_discovery_filter(adapter);
+
+ return dbus_message_new_method_return(msg);
+}
+
static bool parse_uuids(DBusMessageIter *value, GSList **uuids)
{
DBusMessageIter arriter;
@@ -5353,9 +5100,7 @@ static void property_set_mode(struct btd_adapter *adapter, uint32_t setting,
data->adapter = adapter;
data->id = id;
-/* Because of timing issue, sometimes pscan / iscan value was wrong. */
-#if 0
-/* #ifdef __TIZEN_PATCH__ */
+#ifdef __TIZEN_PATCH__
/*
* Use mgmt_send_nowait to avoid dbus timeout in a state of bonding.
*/
@@ -5547,7 +5292,6 @@ static void iter_append_uuid(gpointer key, gpointer value, gpointer user_data)
}
#ifdef __TIZEN_PATCH__
-
static gboolean property_get_le_discovering(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *user_data)
{
@@ -5559,20 +5303,6 @@ static gboolean property_get_le_discovering(const GDBusPropertyTable *property,
return TRUE;
}
-#if 0 // Not used
-static gboolean property_get_secure_connection(const GDBusPropertyTable
- *property, DBusMessageIter *iter, void *user_data)
-{
- struct btd_adapter *adapter = user_data;
- dbus_bool_t secure_connection = adapter->secure_connection;
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
- &secure_connection);
-
- return TRUE;
-}
-#endif
-
static gboolean property_get_connectable(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *user_data)
{
@@ -6043,15 +5773,6 @@ static const GDBusMethodTable adapter_methods[] = {
adapter_start_le_discovery) },
{ GDBUS_ASYNC_METHOD("StopLEDiscovery", NULL, NULL,
adapter_stop_le_discovery) },
-#if 0 // Not used
- { GDBUS_METHOD("EnableSecureConnection",
- GDBUS_ARGS({"enable", "b"}), NULL,
- write_sec_conn_host_support)},
-
- { GDBUS_METHOD("ReadSecureConnection", NULL,
- NULL, read_sec_conn_host_support)},
-#endif
-
{ GDBUS_METHOD("SetAdvertising",
GDBUS_ARGS({ "enable", "b" },
{ "slot_id", "i" }), NULL,
@@ -6140,7 +5861,7 @@ static const GDBusMethodTable adapter_methods[] = {
GDBUS_ARGS({ "address", "s" }),
GDBUS_ARGS({ "device", "o" }),
find_device) },
-#ifdef __TIZEN_PATCH__
+#ifdef __BROADCOM_PATCH__
{ GDBUS_METHOD("SetWbsParameters",
GDBUS_ARGS({ "role", "s" }, { "bt_address", "s" }),
NULL,
@@ -6149,10 +5870,10 @@ static const GDBusMethodTable adapter_methods[] = {
GDBUS_ARGS({ "role", "s" }, { "bt_address", "s" }),
NULL,
set_nb_parameters) },
+#endif
{ GDBUS_METHOD("SetManufacturerData",
GDBUS_ARGS({ "value", "ay" }), NULL,
adapter_set_manufacturer_data) },
-#endif
{ GDBUS_ASYNC_METHOD("CreateDevice",
GDBUS_ARGS({ "address", "s" }), NULL,
create_device) },
@@ -6219,9 +5940,6 @@ static const GDBusPropertyTable adapter_properties[] = {
{ "Modalias", "s", property_get_modalias, NULL,
property_exists_modalias },
#ifdef __TIZEN_PATCH__
-#if 0 // Not used
- { "SecureConnection", "b", property_get_secure_connection },
-#endif
{ "Connectable", "b", property_get_connectable,
property_set_connectable },
{ "Version", "s", property_get_version },
@@ -6644,21 +6362,6 @@ static void load_irks_complete(uint8_t status, uint16_t length,
DBG("IRKs loaded for hci%u", adapter->dev_id);
}
-#ifdef __TIZEN_PATCH__
-static void load_devices_rpa_res_support(struct btd_adapter *adapter)
-{
- GSList *l;
-
- DBG("%s", adapter->path);
-
- for (l = adapter->devices; l; l = l->next) {
- struct btd_device *device = l->data;
-
- btd_adapter_set_dev_rpa_res_support(adapter, device);
- }
-}
-#endif
-
static void load_irks(struct btd_adapter *adapter, GSList *irks)
{
struct mgmt_cp_load_irks *cp;
@@ -6894,6 +6597,29 @@ static void load_devices(struct btd_adapter *adapter)
goto device_exist;
}
+#ifdef __TIZEN_PATCH__
+{
+ char **techno;
+
+ techno = g_key_file_get_string_list(key_file, "General",
+ "SupportedTechnologies", NULL, NULL);
+
+ /* KITT: Encryption fail with MIC Failure error
+ Problem happend when two LTK is stored on both RPA and IDA address folder
+ Here, if IDA dev info is loaded before RPA info, both RPA dev and IDA dev
+ are created and problem happend.(If RPA info is loaded first, IDA is not
+ loaded. (upper device_exist case))
+ Fix: skip a loadding info in case of 'no technologies' */
+
+ if (!techno) {
+ DBG("No SupportedTechnologies. Skipping");
+ goto free;
+ }
+
+ g_strfreev(techno);
+}
+#endif
+
device = device_create_from_storage(adapter, entry->d_name,
key_file);
if (!device)
@@ -6965,10 +6691,6 @@ free:
g_slist_free_full(params, g_free);
g_slist_free_full(added_devices, probe_devices);
-
-#ifdef __TIZEN_PATCH__
- load_devices_rpa_res_support(adapter);
-#endif
}
int btd_adapter_block_address(struct btd_adapter *adapter,
@@ -8553,11 +8275,18 @@ static void load_config(struct btd_adapter *adapter)
str = g_key_file_get_string(key_file,
"General", "LocalIrk", &gerr);
if (gerr || !str || strlen(str) != 34) {
- memset(adapter->local_irk, 0, MGMT_IRK_SIZE);
g_error_free(gerr);
gerr = NULL;
- } else
- str2buf(&str[2], (uint8_t *)adapter->local_irk, MGMT_IRK_SIZE);
+
+ g_free(adapter->local_irk);
+ adapter->local_irk = NULL;
+ } else {
+ if (adapter->local_irk)
+ g_free(adapter->local_irk);
+
+ adapter->local_irk = g_malloc0(MGMT_IRK_SIZE);
+ str2buf(&str[2], adapter->local_irk, MGMT_IRK_SIZE);
+ }
}
#endif
@@ -8616,8 +8345,6 @@ static struct btd_adapter *btd_adapter_new(uint16_t index)
DBG("LE Privacy is enabled.");
else
DBG("LE Privacy is disabled.");
-
- adapter->central_rpa_res_support = 0x00;
#endif
adapter->auths = g_queue_new();
@@ -8737,6 +8464,24 @@ const bdaddr_t *btd_adapter_get_address(struct btd_adapter *adapter)
return &adapter->bdaddr;
}
+#ifdef __TIZEN_PATCH__
+const bdaddr_t *btd_adapter_get_le_address(struct btd_adapter *adapter)
+{
+ if (adapter->le_static_addr.b[5] != 0)
+ return &adapter->le_static_addr;
+ else
+ return &adapter->bdaddr;
+}
+
+uint8_t btd_adapter_get_le_address_type(struct btd_adapter * adapter)
+{
+ if (adapter->le_static_addr.b[5] != 0)
+ return BDADDR_LE_RANDOM;
+ else
+ return BDADDR_LE_PUBLIC;
+}
+#endif
+
static gboolean confirm_name_timeout(gpointer user_data)
{
struct btd_adapter *adapter = user_data;
@@ -9265,8 +9010,14 @@ static void adapter_remove_connection(struct btd_adapter *adapter,
return;
adapter->connections = g_slist_remove(adapter->connections, device);
-
+#ifdef __TIZEN_PATCH__
+ DBG("isPaired %d, isBonded %d", device_is_paired(device, bdaddr_type),
+ device_is_bonded(device, bdaddr_type));
+ if ((device_is_temporary(device) && !device_is_retrying(device)) ||
+ (!device_is_bonded(device, bdaddr_type))) {
+#else
if (device_is_temporary(device) && !device_is_retrying(device)) {
+#endif
const char *path = device_get_path(device);
DBG("Removing temporary device %s", path);
@@ -10096,26 +9847,6 @@ void adapter_check_version(struct btd_adapter *adapter, uint8_t hci_ver)
adapter->version = g_strdup(ver);
}
-#if 0 // Not used
-static void new_local_irk_callback(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_ev_new_local_irk *ev = param;
- struct btd_adapter *adapter = user_data;
-
- if (length < sizeof(*ev)) {
- error("Too small size of Local IRK generated");
- return;
- }
-
- DBG("Local IRK generated for hci%u", index);
-
- memset(adapter->local_irk, 0, sizeof(adapter->local_irk));
- memcpy(adapter->local_irk, (char *)ev->irk, sizeof(adapter->local_irk));
- store_adapter_info(adapter);
-}
-#endif
-
static void hardware_error_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
@@ -10187,6 +9918,7 @@ static void multi_adv_state_change_callback(uint16_t index, uint16_t length,
const void *param, void *user_data)
{
const struct mgmt_ev_vendor_specific_multi_adv_state_changed *ev = param;
+ struct btd_adapter *adapter = user_data;
if (length < sizeof(*ev)) {
error("Too small adv state change event");
@@ -10198,7 +9930,31 @@ static void multi_adv_state_change_callback(uint16_t index, uint16_t length,
if ((ev->adv_instance > 0 && ev->adv_instance < adapter_le_get_max_adv_instance()) &&
ev->state_change_reason == 0)
- adapter_le_enable_multi_adv(TRUE, ev->adv_instance);
+ adapter_le_enable_multi_adv(adapter, TRUE, ev->adv_instance);
+}
+
+static void le_conn_update_completed_callback(uint16_t index, uint16_t length,
+ const void *param, void *user_data)
+{
+ const struct mgmt_ev_conn_updated *ev = param;
+ struct btd_adapter *adapter = user_data;
+ struct btd_device *device;
+ char addr[18];
+ GSList *list;
+
+ if (length < sizeof(*ev)) {
+ error("Too small le conn update completed event");
+ return;
+ }
+
+ ba2str(&ev->addr.bdaddr, addr);
+ list = g_slist_find_custom(adapter->devices, addr,
+ device_address_cmp);
+ if (list) {
+ device = list->data;
+ if (device_get_conn_update_state(device))
+ device_set_conn_update_state(device, false);
+ }
}
static void bt_6lowpan_conn_state_change_callback(uint16_t index, uint16_t length,
@@ -10266,29 +10022,6 @@ static void bt_le_data_length_changed_callback(uint16_t index, uint16_t length,
ev->max_rx_octets, ev->max_rx_time);
}
-static void le_conn_update_completed_callback(uint16_t index, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_ev_conn_updated *ev = param;
- struct btd_adapter *adapter = user_data;
- struct btd_device *device;
- char addr[18];
- GSList *list;
-
- if (length < sizeof(*ev)) {
- error("Too small le conn update completed event");
- return;
- }
-
- ba2str(&ev->addr.bdaddr, addr);
- list = g_slist_find_custom(adapter->devices, addr,
- device_address_cmp);
- if (list) {
- device = list->data;
- if (device_get_conn_update_state(device))
- device_set_conn_update_state(device, false);
- }
-}
#endif
struct btd_adapter_pin_cb_iter *btd_adapter_pin_cb_iter_new(
@@ -10458,10 +10191,7 @@ static void bonding_complete(struct btd_adapter *adapter,
if (device != NULL)
device_bonding_complete(device, addr_type, status);
-#ifdef __TIZEN_PATCH__
- //resume_discovery(adapter);
- //resume_le_discovery(adapter);
-#else
+#ifndef __TIZEN_PATCH__
resume_discovery(adapter);
#endif
check_oob_bonding_complete(adapter, bdaddr, status);
@@ -11196,11 +10926,11 @@ static void new_irk_callback(uint16_t index, uint16_t length,
#else
device = btd_adapter_get_device(adapter, &ev->rpa,
- BDADDR_LE_RANDOM);
+ BDADDR_LE_RANDOM);
#endif
duplicate = btd_adapter_find_device(adapter, &addr->bdaddr,
- addr->type);
+ addr->type);
if (duplicate == device)
duplicate = NULL;
} else {
@@ -11271,10 +11001,6 @@ static void new_irk_callback(uint16_t index, uint16_t length,
#endif
btd_device_set_temporary(device, false);
-
-#ifdef __TIZEN_PATCH__
- btd_adapter_set_dev_rpa_res_support(adapter, device);
-#endif
}
static void store_conn_param(struct btd_adapter *adapter, const bdaddr_t *peer,
@@ -11418,6 +11144,62 @@ int btd_adapter_remove_remote_oob_data(struct btd_adapter *adapter,
return -EIO;
}
+#ifdef __TIZEN_PATCH__
+int btd_adapter_add_remote_oob_ext_data(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, uint8_t bdaddr_type,
+ uint8_t *hash192, uint8_t *randomizer192,
+ uint8_t *hash256, uint8_t *randomizer256)
+{
+ struct mgmt_cp_add_remote_oob_data cp;
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%d bdaddr %s type %d", adapter->dev_id, addr, bdaddr_type);
+
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.addr.bdaddr, bdaddr);
+ cp.addr.type = bdaddr_type;
+
+ if (hash192 && randomizer192) {
+ memcpy(cp.hash192, hash192, 16);
+ memcpy(cp.rand192, randomizer192, 16);
+ }
+
+ if (hash256 && randomizer256) {
+ memcpy(cp.hash256, hash256, 16);
+ memcpy(cp.rand256, randomizer256, 16);
+ }
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_ADD_REMOTE_OOB_DATA,
+ adapter->dev_id, sizeof(cp), &cp,
+ NULL, NULL, NULL) > 0)
+ return 0;
+
+ return -EIO;
+}
+
+int btd_adapter_remove_remote_oob_ext_data(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, uint8_t bdaddr_type)
+{
+ struct mgmt_cp_remove_remote_oob_data cp;
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%d bdaddr %s type %d", adapter->dev_id, addr, bdaddr_type);
+
+ memset(&cp, 0, sizeof(cp));
+ bacpy(&cp.addr.bdaddr, bdaddr);
+ cp.addr.type = bdaddr_type;
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+ adapter->dev_id, sizeof(cp), &cp,
+ NULL, NULL, NULL) > 0)
+ return 0;
+
+ return -EIO;
+}
+#endif
+
bool btd_adapter_ssp_enabled(struct btd_adapter *adapter)
{
if (adapter->current_settings & MGMT_SETTING_SSP)
@@ -11443,6 +11225,10 @@ static void read_local_oob_data_complete(uint8_t status, uint16_t length,
const struct mgmt_rp_read_local_oob_data *rp = param;
struct btd_adapter *adapter = user_data;
const uint8_t *hash, *randomizer;
+#ifdef __TIZEN_PATCH__
+ const uint8_t *hash256 = NULL;
+ const uint8_t *randomizer256 = NULL;
+#endif
if (status != MGMT_STATUS_SUCCESS) {
btd_error(adapter->dev_id,
@@ -11461,13 +11247,25 @@ static void read_local_oob_data_complete(uint8_t status, uint16_t length,
} else {
hash = rp->hash192;
randomizer = rp->rand192;
+#ifdef __TIZEN_PATCH__
+ if (length > 32) {
+ hash256 = rp->hash256;
+ randomizer256 = rp->rand256;
+ }
+#endif
}
if (!adapter->oob_handler || !adapter->oob_handler->read_local_cb)
return;
+#ifdef __TIZEN_PATCH__
+ adapter->oob_handler->read_local_cb(adapter, hash, randomizer,
+ hash256, randomizer256,
+ adapter->oob_handler->user_data);
+#else
adapter->oob_handler->read_local_cb(adapter, hash, randomizer,
adapter->oob_handler->user_data);
+#endif
g_free(adapter->oob_handler);
adapter->oob_handler = NULL;
@@ -11639,8 +11437,8 @@ static int adapter_register(struct btd_adapter *adapter)
#ifdef __TIZEN_PATCH__
if (adapter->le_privacy_enabled &&
- (adapter->supported_settings & MGMT_SETTING_PRIVACY))
- set_privacy(adapter, true);
+ (adapter->supported_settings & MGMT_SETTING_PRIVACY))
+ set_privacy(adapter, true);
else
DBG("LE privacy feature not configured or supported");
#endif
@@ -11966,33 +11764,47 @@ static void set_privacy_complete(uint8_t status, uint16_t length,
static bool set_privacy(struct btd_adapter *adapter, bool privacy)
{
struct mgmt_cp_set_privacy cp;
- static const char testblock[MGMT_IRK_SIZE];
memset(&cp, 0, sizeof(cp));
- if (privacy) {
- if (!memcmp(adapter->local_irk, testblock, MGMT_IRK_SIZE)) {
- cp.privacy = GEN_IRK_THEN_ENABLE_PRIVACY;
- memset(cp.irk, 0, MGMT_IRK_SIZE);
- } else {
- cp.privacy = ENABLE_PRIVACY;
- memcpy(cp.irk, adapter->local_irk, MGMT_IRK_SIZE);
+ if (privacy && !adapter->local_irk) {
+ int fd;
+
+ DBG("Generate local irk");
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0)
+ goto fail;
+
+ adapter->local_irk = g_malloc0(MGMT_IRK_SIZE);
+ if (read(fd, adapter->local_irk, MGMT_IRK_SIZE) !=
+ MGMT_IRK_SIZE) {
+ error("Cannot read local irk");
+ close(fd);
+ goto fail;
}
- } else {
- cp.privacy = DISABLE_PRIVACY;
- memset(cp.irk, 0, MGMT_IRK_SIZE);
+ close(fd);
+
+ store_adapter_info(adapter);
+ }
+
+ if (privacy) {
+ cp.privacy = 0x01;
+ memcpy(cp.irk, adapter->local_irk, MGMT_IRK_SIZE);
}
+
if (mgmt_send(adapter->mgmt, MGMT_OP_SET_PRIVACY,
- adapter->dev_id, sizeof(cp), &cp,
- set_privacy_complete, adapter, NULL) > 0)
+ adapter->dev_id, sizeof(cp), &cp,
+ set_privacy_complete, adapter, NULL) > 0)
return true;
+fail:
error("Failed to set privacy and load local irk for index %u",
- adapter->dev_id);
-
+ adapter->dev_id);
return false;
}
+
int btd_adapter_connect_ipsp(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type)
@@ -12352,13 +12164,6 @@ static void read_info_complete(uint8_t status, uint16_t length,
rssi_disabled_callback,
adapter, NULL);
-#if 0 // Not used
- mgmt_register(adapter->mgmt, MGMT_EV_NEW_LOCAL_IRK,
- adapter->dev_id,
- new_local_irk_callback,
- adapter, NULL);
-#endif
-
mgmt_register(adapter->mgmt, MGMT_EV_HARDWARE_ERROR,
adapter->dev_id,
hardware_error_callback,
@@ -12746,176 +12551,3 @@ bool btd_le_connect_before_pairing(void)
return false;
}
-
-#ifdef __TIZEN_PATCH__
-#if 0 // Not used
-static void read_rssi_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_rssi *rp = param;
- struct btd_device *device = user_data;
-
- if (status != MGMT_STATUS_SUCCESS) {
- error("read RSSI failed: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Too small read rssi response");
- return;
- }
-
- if (!rp->status) {
- device_set_rssi(device, rp->rssi);
- }
- return;
-}
-
-int btd_adapter_read_rssi(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- struct btd_device *device)
-{
- struct mgmt_cp_read_rssi cp;
-
- DBG("btd_adapter_read_rssi");
- memset(&cp, 0, sizeof(cp));
- bacpy(&cp.bdaddr, bdaddr);
-
- if (mgmt_send(adapter->mgmt, MGMT_OP_READ_RSSI,
- adapter->dev_id, sizeof(cp), &cp,
- read_rssi_complete, device, NULL) > 0)
- return 0;
- return -EIO;
-}
-
-int btd_adapter_l2cap_conn_param_update(struct btd_adapter *adapter,
- bdaddr_t *bdaddr, uint16_t interval_min,
- uint16_t interval_max, uint16_t latency,
- uint16_t supervision_time_out)
-{
- struct mgmt_cp_l2cap_conn_param_update cp;
-
- memset(&cp, 0, sizeof(cp));
- if (bdaddr)
- bacpy(&cp.bdaddr, bdaddr);
- else
- return -EIO;
-
- cp.interval_min = interval_min;
- cp.interval_max = interval_max;
- cp.latency = latency;
- cp.supervision_time_out = supervision_time_out;
- if (mgmt_send(adapter->mgmt, MGMT_OP_L2CAP_CONN_PARAM_UPDATE,
- adapter->dev_id, sizeof(cp), &cp,
- NULL, NULL, NULL) > 0)
- return 0;
-
- return -EIO;
-}
-
-static void write_auth_payload_timeout_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_write_auth_payload_timeout *rp = param;
-
- if (status != MGMT_STATUS_SUCCESS) {
- error("Failed to write auth payload timeout: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Wrong size of write auth payload timeout parameter");
- return;
- }
-}
-
-int btd_adapter_write_auth_payload_timeout(struct btd_adapter *adapter,
- bdaddr_t *bdaddr, uint32_t payload_timeout,
- struct btd_device *device)
-{
- struct mgmt_cp_write_auth_payload_timeout cp;
- memset(&cp, 0, sizeof(cp));
- bacpy(&cp.bdaddr, bdaddr);
-
- if (payload_timeout > 65536)
- return -EIO;
- else
- cp.auth_payload_timeout = payload_timeout;
-
- if (mgmt_send(adapter->mgmt, MGMT_OP_WRITE_AUTH_PAYLOAD_TIMEOUT,
- adapter->dev_id, sizeof(cp), &cp,
- write_auth_payload_timeout_complete, device, NULL) > 0)
- return 0;
- return -EIO;
-}
-
-static void read_auth_payload_timeout_complete(uint8_t status, uint16_t length,
- const void *param, void *user_data)
-{
- const struct mgmt_rp_read_auth_payload_timeout *rp = param;
- struct btd_device *device = user_data;
- if (status != MGMT_STATUS_SUCCESS) {
- error("read auth payload timeout failed: %s (0x%02x)",
- mgmt_errstr(status), status);
- return;
- }
-
- if (length < sizeof(*rp)) {
- error("Too small read payload response");
- return;
- }
-
- if (!rp->status) {
- device_set_payload_timeout(device, rp->auth_payload_timeout);
- }
- return;
-}
-
-int btd_adapter_read_auth_payload_timeout(struct btd_adapter *adapter,
- bdaddr_t *bdaddr, struct btd_device *device)
-{
- struct mgmt_cp_read_auth_payload_timeout cp;
- memset(&cp, 0, sizeof(cp));
- bacpy(&cp.bdaddr, bdaddr);
-
- if (mgmt_send(adapter->mgmt, MGMT_OP_READ_AUTH_PAYLOAD_TIMEOUT,
- adapter->dev_id, sizeof(cp), &cp,
- read_auth_payload_timeout_complete, device, NULL) > 0)
- return 0;
- return -EIO;
-}
-#endif
-
-int btd_adapter_le_conn_update(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- uint16_t interval_min, uint16_t interval_max,
- uint16_t latency, uint16_t supervision_time_out)
-{
- struct mgmt_cp_le_conn_update cp;
-
- memset(&cp, 0, sizeof(cp));
-
- if (NULL != bdaddr)
- bacpy(&cp.bdaddr, bdaddr);
- else
- return -EIO;
-
- cp.interval_min = interval_min;
- cp.interval_max = interval_max;
- cp.latency = latency;
- cp.supervision_time_out = supervision_time_out;
-
- if (mgmt_send(adapter->mgmt, MGMT_OP_LE_CONN_UPDATE,
- adapter->dev_id, sizeof(cp), &cp,
- NULL, NULL, NULL) > 0)
- return 0;
-
- return -EIO;
-}
-
-GSList *btd_adapter_get_connections(struct btd_adapter *adapter)
-{
- /* Return the connected device list */
- return adapter->connections;
-}
-#endif /* __TIZEN_PATCH__ */
diff --git a/src/adapter.h b/src/adapter.h
index ee28c0f8..71c76654 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -53,6 +53,14 @@ uint16_t btd_adapter_get_index(struct btd_adapter *adapter);
typedef void (*adapter_cb) (struct btd_adapter *adapter, gpointer user_data);
+#ifdef __TIZEN_PATCH__
+typedef void (*oob_ext_read_local_cb_t) (struct btd_adapter *adapter,
+ const uint8_t *hash192,
+ const uint8_t *randomizer192,
+ const uint8_t *hash256,
+ const uint8_t *randomizer256,
+ void *user_data);
+#endif
typedef void (*oob_read_local_cb_t) (struct btd_adapter *adapter,
const uint8_t *hash,
const uint8_t *randomizer,
@@ -62,7 +70,11 @@ typedef void (*oob_bonding_cb_t) (struct btd_adapter *adapter,
void *user_data);
struct oob_handler {
+#ifdef __TIZEN_PATCH__
+ oob_ext_read_local_cb_t read_local_cb;
+#else
oob_read_local_cb_t read_local_cb;
+#endif
oob_bonding_cb_t bonding_cb;
bdaddr_t remote_addr;
void *user_data;
@@ -115,6 +127,10 @@ struct btd_device *btd_adapter_find_device(struct btd_adapter *adapter,
const char *adapter_get_path(struct btd_adapter *adapter);
const bdaddr_t *btd_adapter_get_address(struct btd_adapter *adapter);
+#ifdef __TIZEN_PATCH__
+const bdaddr_t *btd_adapter_get_le_address(struct btd_adapter *adapter);
+uint8_t btd_adapter_get_le_address_type(struct btd_adapter * adapter);
+#endif
int adapter_set_name(struct btd_adapter *adapter, const char *name);
int adapter_service_add(struct btd_adapter *adapter, sdp_record_t *rec);
@@ -221,6 +237,16 @@ int btd_adapter_add_remote_oob_data(struct btd_adapter *adapter,
int btd_adapter_remove_remote_oob_data(struct btd_adapter *adapter,
const bdaddr_t *bdaddr);
+#ifdef __TIZEN_PATCH__
+int btd_adapter_add_remote_oob_ext_data(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, uint8_t bdaddr_type,
+ uint8_t *hash192, uint8_t *randomizer192,
+ uint8_t *hash256, uint8_t *randomizer256);
+
+int btd_adapter_remove_remote_oob_ext_data(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, uint8_t bdaddr_type);
+#endif
+
int btd_adapter_gatt_server_start(struct btd_adapter *adapter);
void btd_adapter_gatt_server_stop(struct btd_adapter *adapter);
@@ -250,33 +276,6 @@ void btd_adapter_for_each_device(struct btd_adapter *adapter,
bool btd_le_connect_before_pairing(void);
#ifdef __TIZEN_PATCH__
-#if 0 // Not used
-int btd_adapter_read_rssi(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- struct btd_device *device);
-
-int btd_adapter_l2cap_conn_param_update(struct btd_adapter *adapter,
- bdaddr_t *bdaddr, uint16_t interval_min,
- uint16_t interval_max, uint16_t latency,
- uint16_t supervision_time_out);
-
-int btd_adapter_write_auth_payload_timeout(struct btd_adapter *adapter,
- bdaddr_t *bdaddr, uint32_t payload_timeout,
- struct btd_device *device);
-int btd_adapter_read_auth_payload_timeout(struct btd_adapter *adapter,
- bdaddr_t *bdaddr, struct btd_device *device);
-#endif
-
-int btd_adapter_le_conn_update(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- uint16_t interval_min, uint16_t interval_max,
- uint16_t latency, uint16_t supervision_time_out);
-gboolean adapter_clear_le_white_list(struct btd_adapter *adapter);
-gboolean adapter_add_le_white_list(struct btd_adapter *adapter, struct btd_device *device);
-
-gboolean btd_adapter_is_le_auto_connect(struct btd_adapter *adapter);
-void btd_adapter_set_le_auto_connect(struct btd_adapter *adapter, gboolean auto_connect);
-gboolean btd_adapter_disable_le_auto_connect(struct btd_adapter *adapter);
-void adapter_check_version(struct btd_adapter *adapter, uint8_t hci_ver);
-GSList *btd_adapter_get_connections(struct btd_adapter *adapter);
int btd_adapter_connect_ipsp(struct btd_adapter *adapter,
const bdaddr_t *bdaddr,
uint8_t bdaddr_type);
@@ -289,6 +288,7 @@ uint8_t btd_adapter_get_rpa_res_support_value(
int btd_adapter_set_dev_rpa_res_support(struct btd_adapter *adapter,
struct btd_device *device);
+#endif
typedef void (*read_max_data_length_cb_t) (struct btd_adapter *adapter,
const uint16_t max_txOctects,
@@ -313,7 +313,9 @@ struct le_data_length_read_default_data_length_handler {
};
int btd_adapter_le_set_data_length(struct btd_adapter *adapter, bdaddr_t *bdaddr,
- uint16_t max_tx_octets, uint16_t max_tx_time);
+ uint16_t max_tx_octets, uint16_t max_tx_time);
+#ifdef __TIZEN_PATCH__
+void adapter_check_version(struct btd_adapter *adapter, uint8_t hci_ver);
#ifdef TIZEN_WEARABLE
charging_state_e get_charging_state(struct btd_adapter *adapter);
#endif /* TIZEN_WEARABLE */
diff --git a/src/adapter_le_vsc_features.c b/src/adapter_le_vsc_features.c
index d6a68f80..2ab3d142 100644
--- a/src/adapter_le_vsc_features.c
+++ b/src/adapter_le_vsc_features.c
@@ -11,6 +11,31 @@
static apater_le_vsc_rp_get_vendor_cap ble_vsc_cb = { -1, };
+static int update_le_address(const bdaddr_t *le_addr)
+{
+ int hdev = 0;
+ le_set_random_address_cp cp;
+
+ hdev = hci_open_dev(0);
+ if (hdev < 0) {
+ error("Cannot open hdev");
+ return -1;
+ }
+
+ bacpy(&cp.bdaddr, le_addr);
+
+ if (hci_send_cmd(hdev, OGF_LE_CTL, OCF_LE_SET_RANDOM_ADDRESS,
+ LE_SET_RANDOM_ADDRESS_CP_SIZE, &cp) < 0) {
+ error("hci_send_cmd is failed");
+ hci_close_dev(hdev);
+ return -1;
+ }
+
+ hci_close_dev(hdev);
+
+ return 0;
+}
+
static int send_vsc_command(uint16_t ocf, uint8_t *cp, uint8_t cp_len,
uint8_t *rp, uint8_t rp_len)
{
@@ -200,13 +225,23 @@ gboolean adapter_le_set_multi_adv_data(uint8_t inst_id, gboolean is_scan_rsp,
return TRUE;
}
-gboolean adapter_le_enable_multi_adv (gboolean enable, uint8_t inst_id)
+gboolean adapter_le_enable_multi_adv (struct btd_adapter *adapter,
+ gboolean enable, uint8_t inst_id)
{
int ret;
adapter_le_vsc_cp_enable_multi_adv cp;
apater_le_vsc_rp_multi_adv rp;
+ uint8_t bdaddr_type;
+ const bdaddr_t *bdaddr;
DBG("");
+ if (enable) {
+ bdaddr_type = btd_adapter_get_le_address_type(adapter);
+ if (bdaddr_type == BDADDR_LE_RANDOM) {
+ bdaddr = btd_adapter_get_le_address(adapter);
+ update_le_address(bdaddr);
+ }
+ }
memset(&cp, 0, sizeof(cp));
cp.subcode = SUB_CMD_LE_MULTI_ADV_ENB;
@@ -663,7 +698,7 @@ gboolean adapter_le_enable_offloading(gboolean enable)
return TRUE;
}
-gboolean adapter_le_add_irk_to_list(uint8_t *le_irk, const bdaddr_t *bdaddr, uint8_t bdaddr_type)
+gboolean adapter_le_add_irk_to_list(const uint8_t *le_irk, const bdaddr_t *bdaddr, uint8_t bdaddr_type)
{
int ret;
adapter_le_vsc_cp_add_irk_to_list cp;
diff --git a/src/adapter_le_vsc_features.h b/src/adapter_le_vsc_features.h
index e5ec624a..0bbc8661 100644
--- a/src/adapter_le_vsc_features.h
+++ b/src/adapter_le_vsc_features.h
@@ -476,8 +476,8 @@ gboolean adapter_le_set_multi_adv_params (adapter_le_adv_inst_info_t *p_inst,
gboolean adapter_le_set_multi_adv_data(uint8_t inst_id, gboolean is_scan_rsp,
uint8_t data_len, uint8_t *p_data);
-gboolean adapter_le_enable_multi_adv (gboolean enable, uint8_t inst_id);
-
+gboolean adapter_le_enable_multi_adv (struct btd_adapter *adapter,
+ gboolean enable, uint8_t inst_id);
gboolean adapter_le_enable_scan_filtering (gboolean enable);
@@ -496,7 +496,7 @@ gboolean adapter_le_clear_scan_filter_data(int client_if, int filter_index);
gboolean adapter_le_enable_offloading(gboolean enable);
-gboolean adapter_le_add_irk_to_list(uint8_t *le_irk, const bdaddr_t *bdaddr, uint8_t bdaddr_type);
+gboolean adapter_le_add_irk_to_list(const uint8_t *le_irk, const bdaddr_t *bdaddr, uint8_t bdaddr_type);
gboolean adapter_le_remove_irk_to_list(const bdaddr_t *bdaddr, uint8_t bdaddr_type);
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 06293fa6..31989af3 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -1049,11 +1049,6 @@ static void channel_remove(struct gatt_channel *channel)
{
channel->server->clients = g_slist_remove(channel->server->clients,
channel);
-#ifdef __TIZEN_PATCH__
- if (channel->server->clients == NULL) {
- device_set_gatt_connected(channel->device, FALSE);
- }
-#endif
channel_free(channel);
}
@@ -1292,9 +1287,6 @@ guint attrib_channel_attach(GAttrib *attrib)
channel->cleanup_id = g_io_add_watch(io, G_IO_HUP, channel_watch_cb,
channel);
-#ifdef __TIZEN_PATCH__
- device_set_attrib(device, channel->id, channel->attrib);
-#endif
channel->device = btd_device_ref(device);
server->clients = g_slist_append(server->clients, channel);
@@ -1778,15 +1770,12 @@ static uint8_t attrib_get_ccc_info(struct btd_device *device, uint16_t handle)
/* Get the CCC value */
value = g_key_file_get_string(key_file, group, "Value", NULL);
- if (!value) {
- /* Fix : RESOURCE_LEAK */
- g_free(filename);
- g_key_file_free(key_file);
+ if (!value)
return 0;
- }
sscanf(value, "%hX", &cccval);
+ g_free(value);
g_free(filename);
g_key_file_free(key_file);
diff --git a/src/device.c b/src/device.c
index 998c3ebc..6feb69d1 100644
--- a/src/device.c
+++ b/src/device.c
@@ -319,7 +319,6 @@ struct btd_device {
GIOChannel *att_io;
guint store_id;
#ifdef __TIZEN_PATCH__
- guint attachid; /* Attrib server attach */
bool legacy_pairing;
char *manufacturer_data;
int manufacturer_data_len;
@@ -331,8 +330,6 @@ struct btd_device {
uint8_t disc_reason;
uint8_t last_bdaddr_type;
uint8_t auth_bdaddr_type;
- gboolean le_auto_connect;
- guint auto_id;
gboolean ipsp_connected; /* IPSP Connection state */
char if_name[16 + 1]; /* BT interface UP after IPSP connection */
uint8_t rpa_res_support; /* RPA Resolution capability of device */
@@ -372,10 +369,6 @@ typedef enum {
static int device_browse_gatt(struct btd_device *device, DBusMessage *msg);
static int device_browse_sdp(struct btd_device *device, DBusMessage *msg);
-#ifdef __TIZEN_PATCH__
-static int device_custom_browse_sdp(struct btd_device *device,
- DBusMessage *msg, uuid_t *search);
-#endif
static struct bearer_state *get_state(struct btd_device *dev,
uint8_t bdaddr_type)
@@ -771,13 +764,6 @@ static void gatt_server_cleanup(struct btd_device *device)
static void attio_cleanup(struct btd_device *device)
{
-#ifdef __TIZEN_PATCH__
- if (device->attachid) {
- attrib_channel_detach(device->attrib, device->attachid);
- device->attachid = 0;
- }
-#endif
-
if (device->att_disconn_id)
bt_att_unregister_disconnect(device->att,
device->att_disconn_id);
@@ -870,14 +856,6 @@ static void device_free(gpointer user_data)
if (device->disconnect)
dbus_message_unref(device->disconnect);
-#ifdef __TIZEN_PATCH__
- if (device->auto_id)
- g_source_remove(device->auto_id);
-
- if (device->le_auto_connect)
- btd_adapter_disable_le_auto_connect(device->adapter);
-#endif
-
DBG("%p", device);
if (device->authr) {
@@ -909,22 +887,6 @@ gboolean device_is_bredrle(struct btd_device *device)
return (device->remote_feature_flags &
(DEV_SIMUL_CONTROLLER | DEV_SIMUL_HOST));
}
-
-#if 0 /* caller of below function exists but currently commented */
-static uint8_t device_get_paired_state(struct btd_device *device)
-{
- uint8_t paired = DEV_PAIRED_NONE;
-
- if (device->bredr_state.paired && device->le_state.paired)
- paired = DEV_PAIRED_BREDR_LE;
- else if (device->le_state.paired)
- paired = DEV_PAIRED_LE;
- else if (device->bredr_state.paired)
- paired = DEV_PAIRED_BREDR;
-
- return paired;
-}
-#endif
#endif
bool device_is_paired(struct btd_device *device, uint8_t bdaddr_type)
@@ -1039,6 +1001,24 @@ static gboolean dev_property_get_alias(const GDBusPropertyTable *property,
return TRUE;
}
+#ifdef __TIZEN_PATCH__
+static gboolean dev_property_get_alias_set(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *device = data;
+ dbus_bool_t val;
+
+ if (device->alias != NULL)
+ val = TRUE;
+ else
+ val = FALSE;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN, &val);
+
+ return TRUE;
+}
+#endif
+
static void set_alias(GDBusPendingPropertySet id, const char *alias,
void *data)
{
@@ -1330,7 +1310,6 @@ static gboolean dev_property_get_trusted_profiles(const GDBusPropertyTable *prop
(map << MAP_SHIFT_OFFSET) |
(sap << SAP_SHIFT_OFFSET);
- DBG("TrustedProfiles : %d", val);
dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT32, &val);
return TRUE;
@@ -1429,6 +1408,34 @@ static gboolean dev_property_get_last_addr_type(const GDBusPropertyTable *proper
return TRUE;
}
+static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *device = data;
+ dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
+
+ return TRUE;
+}
+
+static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
+ DBusMessageIter *iter, void *data)
+{
+ struct btd_device *device = data;
+ dbus_bool_t gatt_connected;
+
+ if (device->gatt_connected)
+ gatt_connected = TRUE;
+ else
+ gatt_connected = FALSE;
+
+ dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
+ &gatt_connected);
+
+ return TRUE;
+}
+
static gboolean dev_property_get_ipsp_conn_state(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
@@ -1458,17 +1465,6 @@ static gboolean dev_property_get_ipsp_conn_bt_iface_name(const GDBusPropertyTabl
return TRUE;
}
-
-static gboolean dev_property_get_att_mtu(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *data)
-{
- struct btd_device *device = data;
- dbus_uint16_t mtu = bt_gatt_client_get_mtu(device->client);
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &mtu);
-
- return TRUE;
-}
#endif
static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
@@ -1494,24 +1490,6 @@ static gboolean dev_property_get_connected(const GDBusPropertyTable *property,
return TRUE;
}
-#ifdef __TIZEN_PATCH__
-static gboolean dev_property_get_gatt_connected(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *data)
-{
- struct btd_device *device = data;
- dbus_bool_t gatt_connected;
-
- if (device->gatt_connected)
- gatt_connected = TRUE;
- else
- gatt_connected = FALSE;
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_BOOLEAN,
- &gatt_connected);
-
- return TRUE;
-}
-#endif
static gboolean dev_property_get_uuids(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
@@ -1572,18 +1550,8 @@ static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
return TRUE;
}
-#ifdef __TIZEN_PATCH__
-static gboolean property_get_flag(const GDBusPropertyTable *property,
- DBusMessageIter *iter, void *user_data)
-{
- struct btd_device *device = user_data;
- dbus_uint16_t val = device->le_adv_data.flags;
-
- dbus_message_iter_append_basic(iter, DBUS_TYPE_UINT16, &val);
-
- return TRUE;
-}
+#ifdef __TIZEN_PATCH__
static gboolean property_get_manufacturer_data_len(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *user_data)
{
@@ -2165,6 +2133,12 @@ static GSList *create_pending_list(struct btd_device *dev, const char *uuid)
service = find_connectable_service(dev, HSP_HS_UUID);
if (service)
return g_slist_prepend(dev->pending, service);
+ } else if (g_strcmp0(uuid, HID_UUID) == 0) {
+ DBG("HID service not found, add HID service");
+ btd_device_add_uuid(dev, uuid);
+ service = find_connectable_service(dev, HID_UUID);
+ if (service)
+ return g_slist_prepend(dev->pending, service);
}
#endif
return dev->pending;
@@ -2263,8 +2237,13 @@ static DBusMessage *connect_profiles(struct btd_device *dev, uint8_t bdaddr_type
dev->pending = create_pending_list(dev, uuid);
if (!dev->pending) {
if (dev->svc_refreshed) {
+#ifdef __TIZEN_PATCH__
+ if (!uuid && find_service_with_state(dev->services,
+ BTD_SERVICE_STATE_CONNECTED))
+#else
if (find_service_with_state(dev->services,
BTD_SERVICE_STATE_CONNECTED))
+#endif
return dbus_message_new_method_return(msg);
else
return btd_error_not_available(msg);
@@ -2666,6 +2645,9 @@ static void store_gatt_db(struct btd_device *device)
key_file = g_key_file_new();
g_key_file_load_from_file(key_file, filename, 0, NULL);
+ /* Remove current attributes since it might have changed */
+ g_key_file_remove_group(key_file, "Attributes", NULL);
+
saver.key_file = key_file;
saver.device = device;
@@ -3120,59 +3102,6 @@ static DBusMessage *cancel_pairing(DBusConnection *conn, DBusMessage *msg,
}
#ifdef __TIZEN_PATCH__
-#if 0 // Not used
-static DBusMessage *read_rssi(DBusConnection *conn, DBusMessage *msg,
- void *user_data)
-{
- struct btd_device *device = user_data;
- DBG("read_rssi");
- int status = btd_adapter_read_rssi(device->adapter,
- &device->bdaddr, device);
- if (status != 0)
- return btd_error_failed(msg, "Unable to read rssi");
- else
- return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *l2cap_conn_param_update(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct btd_device *device = user_data;
- uint32_t interval_min, interval_max, latency, time_out;
- int status;
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_UINT32, &interval_min,
- DBUS_TYPE_UINT32, &interval_max,
- DBUS_TYPE_UINT32, &latency,
- DBUS_TYPE_UINT32, &time_out,
- DBUS_TYPE_INVALID))
- return btd_error_invalid_args(msg);
-
- status = btd_adapter_l2cap_conn_param_update(device->adapter,
- &device->bdaddr, interval_min,
- interval_max, latency, time_out);
- if (status != 0)
- return btd_error_failed(msg, "Unable to update L2cap connection parameter");
- else
- return dbus_message_new_method_return(msg);
-}
-
-static DBusMessage *read_auth_payload_timeout(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct btd_device *device = user_data;
- DBG("read_auth_payload_timeout");
- int status = btd_adapter_read_auth_payload_timeout(device->adapter,
- &device->bdaddr, device);
- if (status != 0)
- return btd_error_failed(msg,
- "Unable to read auth payload timeout");
- else
- return dbus_message_new_method_return(msg);
-}
-#endif
-
static DBusMessage *discover_services(DBusConnection *conn,
DBusMessage *msg, void *user_data)
{
@@ -3306,58 +3235,6 @@ static DBusMessage *cancel_discover(DBusConnection *conn,
return dbus_message_new_method_return(msg);
}
-#ifndef __TIZEN_PATCH__
-/* Its not used */
-static DBusMessage *write_auth_payload_timeout(DBusConnection *conn,
- DBusMessage *msg, void *user_data)
-{
- struct btd_device *device = user_data;
- dbus_uint32_t payload_timeout;
-
- DBG("write_auth_payload_timeout");
-
- if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32,
- &payload_timeout, DBUS_TYPE_INVALID))
- return btd_error_invalid_args(msg);
-
- int status = btd_adapter_write_auth_payload_timeout(device->adapter,
- &device->bdaddr, payload_timeout, device);
-
- if (status != 0)
- return btd_error_failed(msg,
- "Unable to write auth payload timeout");
- else
- return dbus_message_new_method_return(msg);
-}
-#endif
-void device_set_attrib(struct btd_device *device, guint attachid, GAttrib *attrib)
-{
- if (device == NULL) {
- error("device is NULL");
- return;
- }
-
- device->attachid = attachid;
- device->attrib = g_attrib_ref(attrib);
-}
-
-void device_unset_attrib(struct btd_device *device)
-{
- if (device == NULL) {
- error("device is NULL");
- return;
- }
-
- if (device->attrib == NULL) {
- error("attrib is NULL");
- return;
- }
-
- device->attachid = 0;
-
- g_attrib_unref(device->attrib);
- device->attrib = NULL;
-}
void device_set_gatt_connected(struct btd_device *device, gboolean connected)
{
@@ -3377,103 +3254,87 @@ void device_set_gatt_connected(struct btd_device *device, gboolean connected)
DEVICE_INTERFACE, "GattConnected");
}
-static gboolean att_connect(gpointer user_data)
-{
- struct btd_device *device = user_data;
-
- device->auto_id = 0;
-
- device_connect_le(device);
-
- return FALSE;
-}
-
static DBusMessage *connect_le(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
- struct btd_device *device = user_data;
+ struct btd_device *dev = user_data;
dbus_bool_t auto_connect = FALSE;
+ int err;
- DBG("bdaddr_type %d", device->bdaddr_type);
-
- if (!device->le) {
- DBG("device->le is not set. Find or create device object");
- device = btd_adapter_get_device(device->adapter,
- &device->bdaddr, BDADDR_LE_PUBLIC);
- if (device == NULL) {
- error("Cannot create device object");
+ if (!dev->le) {
+ /*
+ * If a LE connection is requested without device discovery,
+ * we try to get device object. Here, technology can be updated
+ * if there is matched device object. Or, a new device object
+ * will be created.
+ */
+ dev = btd_adapter_get_device(dev->adapter, &dev->bdaddr,
+ BDADDR_LE_PUBLIC);
+ if (dev == NULL) {
+ error("Unable to get device object");
return btd_error_not_supported(msg);
}
}
- if (device->gatt_connected)
- return btd_error_already_connected(msg);
-
- device->auto_connect = FALSE;
+ if (dev->le_state.connected)
+ return dbus_message_new_method_return(msg);
- if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN,
- &auto_connect, DBUS_TYPE_INVALID))
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_BOOLEAN, &auto_connect,
+ DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
- if (auto_connect) {
- DBG("Start LE auto connection");
-
- if (device->le_auto_connect) {
- DBG("Already auto connection is started...");
- return btd_error_already_connected(msg);
- }
-
- if (btd_adapter_is_le_auto_connect(device->adapter)) {
- DBG("Already auto connection is started");
- return btd_error_already_connected(msg);
- }
- device->le_auto_connect = TRUE;
+ btd_device_set_temporary(dev, false);
- /* Clear White list */
- adapter_clear_le_white_list(device->adapter);
+ if (auto_connect) {
+ DBG("Start BLE auto connection");
+ dev->disable_auto_connect = FALSE;
+ device_set_auto_connect(dev, TRUE);
- /* Add device to White list */
- adapter_add_le_white_list(device->adapter, device);
+ return dbus_message_new_method_return(msg);
}
- if (device->auto_id == 0)
- device->auto_id = g_timeout_add(200, att_connect, device);
+ err = device_connect_le(dev);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
- return dbus_message_new_method_return(msg);
+ dev->connect = dbus_message_ref(msg);
+
+ return NULL;
}
static DBusMessage *disconnect_le(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
- struct btd_device *device = user_data;
+ struct btd_device *dev = user_data;
- if (!device->le)
+ if (!dev->le)
return btd_error_not_supported(msg);
- if (device->le_auto_connect && !device->le_state.connected) {
- DBG("le_auto_connect : %d, le_connected : %d, attrib : %p",
- device->le_auto_connect,
- device->le_state.connected,
- device->attrib);
-
- DBG("Cancel LE auto connection");
-
- btd_adapter_disable_le_auto_connect(device->adapter);
- device->le_auto_connect = FALSE;
+ /*
+ * Disable connections through passive sccanning
+ */
+ if (dev->auto_connect) {
+ DBG("Stop BLE auto connection");
+ dev->disable_auto_connect = FALSE;
+ device_set_auto_connect(dev, FALSE);
- return dbus_message_new_method_return(msg);
+ if (!dev->le_state.connected) {
+ g_dbus_send_reply(dbus_conn, msg, DBUS_TYPE_INVALID);
+ return NULL;
+ }
+ } else if (!dev->le_state.connected) {
+ return btd_error_not_connected(msg);
}
- if (!device->le_state.connected)
- return btd_error_not_connected(msg);
+ dev->disconnects = g_slist_append(dev->disconnects,
+ dbus_message_ref(msg));
- btd_adapter_disconnect_device(device->adapter, &device->bdaddr,
- device->bdaddr_type);
+ btd_adapter_disconnect_device(dev->adapter, &dev->bdaddr,
+ dev->bdaddr_type);
- return dbus_message_new_method_return(msg);
+ return NULL;
}
-#ifdef __TIZEN_PATCH__
static DBusMessage *connect_ipsp(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
@@ -3570,7 +3431,6 @@ static DBusMessage *set_trusted_profile(DBusConnection *conn,
dbus_bool_t profile_trusted;
const char *pattern;
char *uuid;
- uint32_t value;
uint32_t pbap = dev->trusted_profiles.pbap;
uint32_t map = dev->trusted_profiles.map;
uint32_t sap = dev->trusted_profiles.sap;
@@ -3608,7 +3468,6 @@ static DBusMessage *set_trusted_profile(DBusConnection *conn,
btd_device_set_trusted_profiles(dev, pbap, map, sap);
return dbus_message_new_method_return(msg);
}
-#endif
static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
void *user_data)
@@ -3658,38 +3517,6 @@ static DBusMessage *is_connected_profile(DBusConnection *conn, DBusMessage *msg,
return reply;
}
-static DBusMessage *le_conn_update(DBusConnection *conn, DBusMessage *msg,
- void *user_data)
-{
- struct btd_device *device = user_data;
- uint32_t interval_min, interval_max, latency, time_out;
- int status;
- char addr[BT_ADDRESS_STRING_SIZE];
-
- if (!dbus_message_get_args(msg, NULL,
- DBUS_TYPE_UINT32, &interval_min,
- DBUS_TYPE_UINT32, &interval_max,
- DBUS_TYPE_UINT32, &latency,
- DBUS_TYPE_UINT32, &time_out,
- DBUS_TYPE_INVALID))
- return btd_error_invalid_args(msg);
-
- ba2str(&device->bdaddr, addr);
-
- DBG("Remote device address: %s", addr);
- DBG("Interval min: %u, Interval max: %u, Latency: %u, Timeout: %u",
- interval_min, interval_max, latency, time_out);
-
- status = btd_adapter_le_conn_update(device->adapter,
- &device->bdaddr, interval_min,
- interval_max, latency, time_out);
-
- if (status != 0)
- return btd_error_failed(msg, "Unable to update LE connection");
- else
- return dbus_message_new_method_return(msg);
-}
-
static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
@@ -3721,12 +3548,10 @@ static DBusMessage *update_le_conn_parm(DBusConnection *conn, DBusMessage *msg,
if (fd < 0)
return btd_error_not_connected(msg);
-#ifdef __TIZEN_PATCH__
if (device_get_conn_update_state(device))
return btd_error_in_progress(msg);
else
device_set_conn_update_state(device, true);
-#endif
if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_UINT32, &param.min,
DBUS_TYPE_UINT32, &param.max,
@@ -3864,9 +3689,8 @@ static DBusMessage *device_get_ida(DBusConnection *conn, DBusMessage *msg,
id_address = g_strdup(device_idaddr);
- dbus_message_append_args(reply,
- DBUS_TYPE_STRING, &id_address,
- DBUS_TYPE_INVALID);
+ dbus_message_append_args(reply, DBUS_TYPE_STRING, &id_address,
+ DBUS_TYPE_INVALID);
return reply;
}
@@ -3892,41 +3716,25 @@ static const GDBusMethodTable device_methods[] = {
{ GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
NULL, disconnect_profile) },
#ifdef __TIZEN_PATCH__
- { GDBUS_ASYNC_METHOD("Pair",
- GDBUS_ARGS({ "conn_type", "y" }), NULL,
- pair_device) },
+ { GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
+ pair_device) },
#else
{ GDBUS_ASYNC_METHOD("Pair", NULL, NULL, pair_device) },
#endif
{ GDBUS_METHOD("CancelPairing", NULL, NULL, cancel_pairing) },
#ifdef __TIZEN_PATCH__
-#if 0 // Not used
- { GDBUS_METHOD("ReadRSSI", NULL, NULL, read_rssi) },
- { GDBUS_METHOD("L2capConnParamUpdate",
- GDBUS_ARGS({ "interval_min", "u" },
- { "interval_max", "u" }, { "latency", "u" },
- { "time_out", "u" }), NULL,
- l2cap_conn_param_update) },
- { GDBUS_METHOD("WritePayloadTimeout",
- GDBUS_ARGS({"auth_payload_timeout", "u"}),
- NULL, write_auth_payload_timeout)},
- { GDBUS_METHOD("ReadPayloadTimeout", NULL,
- NULL, read_auth_payload_timeout)},
-#endif
- { GDBUS_METHOD("ConnectLE",
- GDBUS_ARGS({ "auto_connect", "b"}),
- NULL, connect_le) },
- { GDBUS_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
+ { GDBUS_ASYNC_METHOD("ConnectLE", GDBUS_ARGS({ "auto_connect", "b"}),
+ NULL, connect_le) },
+ { GDBUS_ASYNC_METHOD("DisconnectLE", NULL, NULL, disconnect_le) },
{ GDBUS_METHOD("IsConnectedProfile", GDBUS_ARGS({ "UUID", "s" }),
- GDBUS_ARGS({ "IsConnected", "b" }), is_connected_profile)},
- { GDBUS_METHOD("LeConnUpdate",
- GDBUS_ARGS({ "interval_min", "u" },
+ GDBUS_ARGS({ "IsConnected", "b" }),
+ is_connected_profile)},
+ { GDBUS_METHOD("LeConnUpdate", GDBUS_ARGS({ "interval_min", "u" },
{ "interval_max", "u" }, { "latency", "u" },
{ "time_out", "u" }), NULL,
- update_le_conn_parm) },
- { GDBUS_ASYNC_METHOD("DiscoverServices",
- GDBUS_ARGS({ "pattern", "s" }), NULL,
- discover_services) },
+ update_le_conn_parm) },
+ { GDBUS_ASYNC_METHOD("DiscoverServices", GDBUS_ARGS({ "pattern", "s" }),
+ NULL, discover_services) },
{ GDBUS_METHOD("CancelDiscovery", NULL, NULL, cancel_discover) },
{ GDBUS_ASYNC_METHOD("ConnectIpsp", NULL, NULL, connect_ipsp) },
{ GDBUS_ASYNC_METHOD("DisconnectIpsp", NULL, NULL, disconnect_ipsp) },
@@ -3934,16 +3742,14 @@ static const GDBusMethodTable device_methods[] = {
GDBUS_ARGS({"max_tx_octets", "q" },
{ "max_tx_time", "q" }), NULL,
le_set_data_length)},
- { GDBUS_ASYNC_METHOD("RequestAttMtu",
- GDBUS_ARGS({ "mtu", "q" }),
+ { GDBUS_ASYNC_METHOD("RequestAttMtu", GDBUS_ARGS({ "mtu", "q" }),
GDBUS_ARGS({ "mtu", "q" }, { "status", "y"}),
- request_att_mtu) },
- { GDBUS_METHOD("GetIDAddress", NULL,
- GDBUS_ARGS({ "IDAdress", "s" }),
- device_get_ida) },
+ request_att_mtu) },
+ { GDBUS_METHOD("GetIDAddress", NULL, GDBUS_ARGS({ "IDAdress", "s" }),
+ device_get_ida) },
{ GDBUS_METHOD("SetTrustedProfile",
- GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}),
- NULL, set_trusted_profile) },
+ GDBUS_ARGS({ "uuid", "s"}, { "trusted", "b"}), NULL,
+ set_trusted_profile) },
#endif
{ }
};
@@ -3964,6 +3770,7 @@ static const GDBusPropertyTable device_properties[] = {
{ "LegacyPairing", "b", dev_property_get_legacy },
{ "RSSI", "n", dev_property_get_rssi, NULL, dev_property_exists_rssi },
#ifdef __TIZEN_PATCH__
+ {"IsAliasSet", "b", dev_property_get_alias_set },
{ "Connected", "y", dev_property_get_connected },
#else
{ "Connected", "b", dev_property_get_connected },
@@ -3975,7 +3782,6 @@ static const GDBusPropertyTable device_properties[] = {
#ifdef __TIZEN_PATCH__
/* To handle Failed Legacy Pairing when initiated from Remote device*/
{ "LegacyPaired", "b", dev_property_get_paired },
- { "Flag", "q", property_get_flag },
{ "ManufacturerDataLen", "q", property_get_manufacturer_data_len },
{ "ManufacturerData", "ay", property_get_manufacturer_data },
{ "GattConnected", "b", dev_property_get_gatt_connected },
@@ -4005,18 +3811,15 @@ static const GDBusPropertyTable device_properties[] = {
#ifdef __TIZEN_PATCH__
static const GDBusSignalTable device_signals[] = {
{ GDBUS_SIGNAL("Disconnected",
- GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" }, { "name", "s" })) },
- { GDBUS_SIGNAL("DeviceConnected",
- GDBUS_ARGS({ "bdaddr_type", "y"})) },
+ GDBUS_ARGS({ "bdaddr_type", "y" }, { "reason", "y" },
+ { "name", "s" })) },
+ { GDBUS_SIGNAL("DeviceConnected", GDBUS_ARGS({ "bdaddr_type", "y"})) },
{ GDBUS_SIGNAL("ProfileStateChanged",
GDBUS_ARGS({ "profile", "s"}, {"state", "i"})) },
{ GDBUS_SIGNAL("AdvReport",
- GDBUS_ARGS({"Address","s"},
- { "Address Type", "y" },
- { "Adv Type", "y"},
- { "RSSI", "i"},
- { "AdvDataLen", "i"},
- { "AdvData", "ay"})) },
+ GDBUS_ARGS({"Address","s"}, { "Address Type", "y" },
+ { "Adv Type", "y"}, { "RSSI", "i"},
+ { "AdvDataLen", "i"}, { "AdvData", "ay"})) },
{ GDBUS_SIGNAL("LEDataLengthChanged",
GDBUS_ARGS({"max_tx_octets","q"},
{ "max_tx_time", "q" },
@@ -4596,7 +4399,7 @@ static int load_chrc(char *handle, char *value,
&uuid, 0, properties,
NULL, NULL, NULL);
if (!att || gatt_db_attribute_get_handle(att) != value_handle) {
- warn("saving characteristic to db failed");
+ warn("loading characteristic to db failed");
return -EIO;
}
@@ -4623,13 +4426,13 @@ static int load_incl(struct gatt_db *db, char *handle, char *value,
att = gatt_db_get_attribute(db, start);
if (!att) {
- warn("saving included service to db failed - no such service");
+ warn("loading included service to db failed - no such service");
return -EIO;
}
att = gatt_db_service_add_included(service, att);
if (!att) {
- warn("saving included service to db failed");
+ warn("loading included service to db failed");
return -EIO;
}
@@ -4666,7 +4469,7 @@ static int load_service(struct gatt_db *db, char *handle, char *value)
att = gatt_db_insert_service(db, start, &uuid, primary,
end - start + 1);
if (!att) {
- DBG("ERROR saving service to db!");
+ error("Unable load service into db!");
return -EIO;
}
@@ -4749,8 +4552,10 @@ static int load_gatt_db_impl(GKeyFile *key_file, char **keys,
}
g_free(value);
- if (ret)
+ if (ret) {
+ gatt_db_clear(db);
return ret;
+ }
}
if (current_service)
@@ -4821,8 +4626,13 @@ static bool device_match_profile(struct btd_device *device,
return false;
if (g_slist_find_custom(uuids, profile->remote_uuid,
- bt_uuid_strcmp) == NULL)
+ bt_uuid_strcmp) == NULL) {
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (strcmp(profile->name, "hid-device") == 0)
+ return true;
+#endif
return false;
+ }
return true;
}
@@ -4904,13 +4714,13 @@ static void accept_gatt_service(struct gatt_db_attribute *attr, void *user_data)
static void device_accept_gatt_profiles(struct btd_device *device)
{
+#ifndef __TIZEN_PATCH__
GSList *l;
-#ifdef __TIZEN_PATCH__
- gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
-#else
for (l = device->services; l != NULL; l = g_slist_next(l))
service_accept(l->data);
+#else
+ gatt_db_foreach_service(device->db, NULL, accept_gatt_service, device);
#endif
}
@@ -5312,7 +5122,7 @@ void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa)
}
}
-void device_set_irk_value(struct btd_device *device, const char *val)
+void device_set_irk_value(struct btd_device *device, const uint8_t *val)
{
memcpy(&device->irk_val, val, sizeof(device->irk_val));
}
@@ -5719,7 +5529,7 @@ int device_addr_type_cmp(gconstpointer a, gconstpointer b)
#ifdef TIZEN_WEARABLE
void device_change_pkt_type(gpointer data, gpointer user_data)
{
- uint16_t pkt_type = (uint16_t)user_data;
+ int pkt_type = (int)user_data;
struct btd_device *device = data;
struct hci_conn_info_req *cr;
set_conn_ptype_cp cp;
@@ -5758,7 +5568,7 @@ void device_change_pkt_type(gpointer data, gpointer user_data)
cp.handle = cr->conn_info->handle;
g_free(cr);
- cp.pkt_type = cpu_to_le16(pkt_type);
+ cp.pkt_type = cpu_to_le16((uint16_t)pkt_type);
ba2str(&device->bdaddr, addr);
DBG("Handle %d, Addr %s", cp.handle, addr);
@@ -5829,6 +5639,10 @@ static struct btd_service *probe_service(struct btd_device *device,
return NULL;
}
+ /*
+ * Profile based auto connection is not used in Tizen.
+ * Instead, the applications request auto connection with address.
+ */
#ifndef __TIZEN_PATCH__
if (profile->auto_connect)
device_set_auto_connect(device, TRUE);
@@ -6392,13 +6206,6 @@ static void register_gatt_services(struct btd_device *device)
device_svc_resolved(device, device->bdaddr_type, 0);
}
-#ifdef __TIZEN_PATCH__
-static void gatt_client_debug_func(const char *str, void *user_data)
-{
- DBG("%s", str);
-}
-#endif
-
static void gatt_client_init(struct btd_device *device);
static void gatt_client_ready_cb(bool success, uint8_t att_ecode,
@@ -6463,15 +6270,8 @@ static void gatt_client_init(struct btd_device *device)
return;
}
-
-#ifdef __TIZEN_PATCH__
- if (!bt_gatt_client_set_debug(device->client, gatt_client_debug_func,
- NULL, NULL)) {
- error("Failed to set debug function");
- }
-#else
bt_gatt_client_set_debug(device->client, gatt_debug, NULL, NULL);
-#endif
+
/* Notify attio so it can react to notifications */
g_slist_foreach(device->attios, attio_connected, device->attrib);
@@ -6496,6 +6296,10 @@ static void gatt_client_init(struct btd_device *device)
gatt_client_cleanup(device);
return;
}
+
+ device->gatt_cache_used = !gatt_db_isempty(device->db);
+
+ btd_gatt_client_connected(device->client_dbus);
}
static void gatt_server_init(struct btd_device *device, struct gatt_db *db)
@@ -6591,7 +6395,7 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
return false;
}
-#if 0
+#ifndef __TIZEN_PATCH__
if (sec_level == BT_IO_SEC_LOW && dev->le_state.paired) {
DBG("Elevating security level since LTK is available");
@@ -6613,15 +6417,6 @@ bool device_attach_att(struct btd_device *dev, GIOChannel *io)
return false;
}
-#if 0
- dev->attachid = attrib_channel_attach(attrib);
- if (dev->attachid == 0) {
- g_attrib_unref(attrib);
- error("Attribute server attach failure!");
- return false;
- }
-#endif
-
dev->attrib = attrib;
dev->att = g_attrib_get_att(attrib);
@@ -6679,14 +6474,6 @@ static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
g_io_channel_unref(device->att_io);
device->att_io = NULL;
-#ifdef __TIZEN_PATCH__
- if (btd_adapter_is_le_auto_connect(device->adapter)) {
- DBG("LE auto connection is done");
- btd_adapter_set_le_auto_connect(device->adapter, FALSE);
- device->le_auto_connect = FALSE;
- }
-#endif
-
if (gerr) {
DBG("%s", gerr->message);
@@ -6761,10 +6548,6 @@ int device_connect_le(struct btd_device *dev)
GIOChannel *io;
GError *gerr = NULL;
char addr[18];
-#ifdef __TIZEN_PATCH__
- bdaddr_t *dba;
- bdaddr_t le_auto_connect_ba = { {0, } };
-#endif
/* There is one connection attempt going on */
if (dev->att_io)
@@ -6787,7 +6570,6 @@ int device_connect_le(struct btd_device *dev)
* This connection will help us catch any PDUs that comes before
* pairing finishes
*/
-#ifndef __TIZEN_PATCH__
io = bt_io_connect(att_connect_cb, attcb, NULL, &gerr,
BT_IO_OPT_SOURCE_BDADDR,
btd_adapter_get_address(adapter),
@@ -6797,31 +6579,6 @@ int device_connect_le(struct btd_device *dev)
BT_IO_OPT_CID, ATT_CID,
BT_IO_OPT_SEC_LEVEL, sec_level,
BT_IO_OPT_INVALID);
-#else
- if (dev->le_auto_connect)
- dba = &le_auto_connect_ba;
- else
- dba = &dev->bdaddr;
-
- io = bt_io_connect(att_connect_cb, attcb, NULL, &gerr,
- BT_IO_OPT_SOURCE_BDADDR,
- btd_adapter_get_address(adapter),
- BT_IO_OPT_SOURCE_TYPE, BDADDR_LE_PUBLIC,
- BT_IO_OPT_DEST_BDADDR, dba,
- BT_IO_OPT_DEST_TYPE, dev->bdaddr_type,
- BT_IO_OPT_CID, ATT_CID,
- BT_IO_OPT_SEC_LEVEL, sec_level,
- BT_IO_OPT_INVALID);
-
- if (dev->le_auto_connect) {
- if (io)
- btd_adapter_set_le_auto_connect(adapter, TRUE);
- else {
- btd_adapter_set_le_auto_connect(dev->adapter, FALSE);
- dev->le_auto_connect = FALSE;
- }
- }
-#endif
if (io == NULL) {
if (dev->bonding) {
@@ -6992,59 +6749,17 @@ static int device_browse_sdp(struct btd_device *device, DBusMessage *msg)
&device->bdaddr, &uuid, browse_cb, req, NULL,
req->sdp_flags);
if (err < 0) {
- browse_request_free(req);
- return err;
- }
-
- return err;
-}
-
#ifdef __TIZEN_PATCH__
-static int device_custom_browse_sdp(struct btd_device *device,
- DBusMessage *msg, uuid_t *search)
-{
- struct btd_adapter *adapter = device->adapter;
- struct browse_req *req;
- uuid_t uuid;
- int err;
-
- if (device->browse)
- return -EBUSY;
-
- req = g_new0(struct browse_req, 1);
- req->device = device;
- if (search) {
- memcpy(&uuid, search, sizeof(uuid_t));
- } else {
- sdp_uuid16_create(&uuid, uuid_list[req->search_uuid++]);
- }
-
- req->sdp_flags = get_sdp_flags(device);
-
- err = bt_search_service(btd_adapter_get_address(adapter),
- &device->bdaddr, &uuid, browse_cb, req, NULL,
- req->sdp_flags);
- if (err < 0) {
+ device->browse = NULL;
+#endif
browse_request_free(req);
return err;
}
- device->browse = req;
-
- if (msg) {
- const char *sender = dbus_message_get_sender(msg);
-
- req->msg = dbus_message_ref(msg);
- /* Track the request owner to cancel it
- * automatically if the owner exits */
- req->listener_id = g_dbus_add_disconnect_watch(dbus_conn,
- sender,
- browse_request_exit,
- req, NULL);
- }
return err;
}
+#ifdef __TIZEN_PATCH__
void device_set_last_addr_type(struct btd_device *device, uint8_t type)
{
if (!device)
@@ -7088,9 +6803,8 @@ void device_set_ipsp_connected(struct btd_device *device, gboolean connected,
DBUS_TYPE_STRING, &iface_name,
DBUS_TYPE_INVALID);
}
-
void device_le_data_length_changed(struct btd_device *device, uint16_t max_tx_octets,
- uint16_t max_tx_time, uint16_t max_rx_octets,uint16_t max_rx_time)
+ uint16_t max_tx_time, uint16_t max_rx_octets, uint16_t max_rx_time)
{
if (device == NULL) {
error("device is NULL");
@@ -8342,18 +8056,7 @@ guint btd_device_add_attio_callback(struct btd_device *device,
attio->dcfunc = dcfunc;
attio->user_data = user_data;
-#ifdef __TIZEN_PATCH__
- /*
- * User space auto connection is not used.
- * Instead of this, BT chip can trigger auto connection
- * by adding remote address to white list and
- * setting 0x01 to "Initiator_Filter_Policy"
- * when LE Create Connection is happened.
- */
- device_set_auto_connect(device, FALSE);
-#else
device_set_auto_connect(device, TRUE);
-#endif
/* Check if there is no GAttrib associated to the device created by a
* incoming connection */
@@ -8403,19 +8106,6 @@ gboolean btd_device_remove_attio_callback(struct btd_device *device, guint id)
g_free(attio);
-#ifdef __TIZEN_PATCH__
- if (device->auto_id) {
- g_source_remove(device->auto_id);
- device->auto_id = 0;
- }
-
- if (device->le_auto_connect) {
- device->le_auto_connect = FALSE;
- btd_adapter_disable_le_auto_connect(device->adapter);
- DBG("remove attio callback");
- }
-#endif
-
return TRUE;
}
diff --git a/src/device.h b/src/device.h
index cf247baa..0a185963 100644
--- a/src/device.h
+++ b/src/device.h
@@ -22,10 +22,6 @@
*
*/
-#ifdef __TIZEN_PATCH__
-#include "attrib/gattrib.h"
-#endif
-
#define DEVICE_INTERFACE "org.bluez.Device1"
struct btd_device;
@@ -98,8 +94,6 @@ void device_set_remote_feature_flag(struct btd_device *device, int flags);
gboolean device_is_bredrle(struct btd_device *device);
void device_set_disconnect_reason(struct btd_device *device, uint8_t reason);
void device_set_gatt_connected(struct btd_device *device, gboolean connected);
-void device_set_attrib(struct btd_device *device, guint attachid, GAttrib *attrib);
-void device_unset_attrib(struct btd_device *device);
void device_unpair(struct btd_device *device, gboolean remove_stored);
gboolean device_get_gatt_connected(const struct btd_device *device);
void device_set_rpa(struct btd_device *device, const bdaddr_t *rpa_addr);
@@ -109,7 +103,7 @@ int device_rpa_cmp(gconstpointer a, gconstpointer b);
int device_addr_cmp(gconstpointer a, gconstpointer b);
void device_remove_stored_folder(struct btd_device *device);
const uint8_t *device_get_irk_value(struct btd_device *device);
-void device_set_irk_value(struct btd_device *device, const char *val);
+void device_set_irk_value(struct btd_device *device, const uint8_t *val);
void device_set_conn_update_state(struct btd_device *device, bool state);
bool device_get_conn_update_state(struct btd_device *device);
void btd_device_set_trusted_profiles(struct btd_device *device,
diff --git a/src/gatt-client.c b/src/gatt-client.c
index 71b4c2d3..398e00ff 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
@@ -881,10 +881,10 @@ static void write_characteristic_cb(struct gatt_db_attribute *attr, int err,
static void notify_characteristic_cb(struct gatt_db_attribute *attr, int err,
void *user_data)
{
- struct characteristic *chrc = user_data;
-
- if (err)
+ if (err) {
+ error("Failed to notify_characteristic_cb : %d", err);
return;
+ }
}
#endif
@@ -1240,51 +1240,22 @@ static bool match_notify_sender(const void *a, const void *b)
return strcmp(client->owner, sender) == 0;
}
-#if defined __TIZEN_PATCH__ && defined GATT_NO_RELAY
-struct char_value {
- uint8_t *data;
- uint8_t len;
- char *chrc_path;
-};
-
-static void emit_value_changed_signal_to_dest(gpointer data, gpointer user_data)
+#ifdef __TIZEN_PATCH__
+void gatt_characteristic_value_changed(struct notify_client *client, const uint8_t *data, uint16_t data_len, void *user_data)
{
+ struct characteristic *chrc = user_data;
+ char *chrc_path = strdup(chrc->path);
dbus_int32_t result = 0;
- struct notify_client *notify_client = data;
- struct char_value *value = user_data;
+#ifdef GATT_NO_RELAY
g_dbus_emit_signal_to_dest(btd_get_dbus_connection(),
- notify_client->owner, value->chrc_path,
+ client->owner, chrc_path,
GATT_CHARACTERISTIC_IFACE, "GattValueChanged",
DBUS_TYPE_INT32, &result,
- DBUS_TYPE_STRING, &value->chrc_path,
- DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &value->data, value->len,
+ DBUS_TYPE_STRING, &chrc_path,
+ DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_len,
DBUS_TYPE_INVALID);
-}
-#endif
-
-#ifdef __TIZEN_PATCH__
-void gatt_characteristic_value_changed(void *data, uint8_t data_len, void *user_data)
-{
- struct characteristic *chrc = user_data;
- char *chrc_path = strdup(chrc->path);
-#ifdef GATT_NO_RELAY
- struct char_value *value;
-
- value = new0(struct char_value, 1);
- value->len = data_len;
- value->data = data;
- value->chrc_path = chrc_path;
-
- queue_foreach(chrc->notify_clients,
- emit_value_changed_signal_to_dest, value);
-
-
- if (value)
- g_free(value);
#else
- dbus_int32_t result = 0;
-
g_dbus_emit_signal(btd_get_dbus_connection(), chrc->path,
GATT_CHARACTERISTIC_IFACE, "GattValueChanged",
DBUS_TYPE_INT32, &result,
@@ -1316,7 +1287,7 @@ static void notify_cb(uint16_t value_handle, const uint8_t *value,
gatt_db_attribute_write(chrc->attr, 0, value, length, 0, NULL,
notify_characteristic_cb, chrc);
- gatt_characteristic_value_changed(value, length, chrc);
+ gatt_characteristic_value_changed(client, value, length, chrc);
#else
gatt_db_attribute_write(chrc->attr, 0, value, length, 0, NULL,
write_characteristic_cb, chrc);
@@ -1454,9 +1425,6 @@ static DBusMessage *characteristic_stop_notify(DBusConnection *conn,
const char *sender = dbus_message_get_sender(msg);
struct notify_client *client;
- if (!chrc->notifying)
- return btd_error_failed(msg, "Not notifying");
-
client = queue_remove_if(chrc->notify_clients, match_notify_sender,
(void *) sender);
if (!client)
@@ -2118,13 +2086,8 @@ static void register_notify(void *data, void *user_data)
DBG("Failed to re-register notification client");
-#ifdef __TIZEN_PATCH__
queue_remove(notify_client->chrc->notify_clients, notify_client);
queue_remove(client->all_notify_clients, notify_client);
-#else
- queue_remove(notify_client->chrc->notify_clients, client);
- queue_remove(client->all_notify_clients, client);
-#endif
notify_client_free(notify_client);
}
@@ -2183,26 +2146,17 @@ static gboolean check_all_chrcs_ready(gpointer user_data)
void btd_gatt_client_ready(struct btd_gatt_client *client)
{
- struct bt_gatt_client *gatt;
-
if (!client)
return;
- gatt = btd_device_get_gatt_client(client->device);
- if (!gatt) {
+ if (!client->gatt) {
error("GATT client not initialized");
return;
}
- bt_gatt_client_unref(client->gatt);
- client->gatt = bt_gatt_client_ref(gatt);
client->ready = true;
DBG("GATT client ready");
-#ifdef __TIZEN_PATCH__
- if (queue_isempty(client->services)) {
- DBG("Exporting services");
-#endif
create_services(client);
#ifdef __TIZEN_PATCH__
@@ -2218,17 +2172,7 @@ void btd_gatt_client_ready(struct btd_gatt_client *client)
client->wait_charcs_id = g_timeout_add(100,
check_all_chrcs_ready, client);
- return;
- }
-
- /*
- * Services have already been created before. Re-enable notifications
- * for any pre-registered notification sessions.
- */
- queue_foreach(client->all_notify_clients, register_notify, client);
- device_set_gatt_connected(client->device, TRUE);
#endif
-
}
void btd_gatt_client_connected(struct btd_gatt_client *client)
@@ -2251,10 +2195,6 @@ void btd_gatt_client_connected(struct btd_gatt_client *client)
* for any pre-registered notification sessions.
*/
queue_foreach(client->all_notify_clients, register_notify, client);
-
-#ifdef __TIZEN_PATCH__
- device_set_gatt_connected(client->device, TRUE);
-#endif
}
void btd_gatt_client_service_added(struct btd_gatt_client *client,
diff --git a/src/gatt-database.c b/src/gatt-database.c
index 989f286b..8b7b83ea 100644
--- a/src/gatt-database.c
+++ b/src/gatt-database.c
@@ -89,6 +89,7 @@ struct gatt_app {
GDBusClient *client;
bool failed;
struct queue *services;
+ struct queue *proxies;
};
struct external_service {
@@ -293,6 +294,12 @@ static struct device_state *device_state_create(bdaddr_t *bdaddr,
uint8_t bdaddr_type)
{
struct device_state *dev_state;
+#ifdef __TIZEN_PATCH__
+ char addr[18] = { 0 };
+
+ ba2str(bdaddr, addr);
+ DBG("create device_state for %s [%d]", addr, bdaddr_type);
+#endif
dev_state = new0(struct device_state, 1);
dev_state->ccc_states = queue_new();
@@ -330,6 +337,9 @@ static struct ccc_state *get_ccc_state(struct btd_gatt_database *database,
{
struct device_state *dev_state;
struct ccc_state *ccc;
+#ifdef __TIZEN_PATCH__
+ char addr[18] = { 0 };
+#endif
dev_state = get_device_state(database, bdaddr, bdaddr_type);
@@ -337,6 +347,12 @@ static struct ccc_state *get_ccc_state(struct btd_gatt_database *database,
if (ccc)
return ccc;
+#ifdef __TIZEN_PATCH__
+ ba2str(bdaddr, addr);
+ DBG("create ccc_state of handle: 0x%04x for %s [%d]",
+ handle, addr, bdaddr_type);
+#endif
+
ccc = new0(struct ccc_state, 1);
ccc->handle = handle;
queue_push_tail(dev_state->ccc_states, ccc);
@@ -423,6 +439,7 @@ static void app_free(void *data)
struct gatt_app *app = data;
queue_destroy(app->services, service_free);
+ queue_destroy(app->proxies, NULL);
if (app->client) {
g_dbus_client_set_disconnect_watch(app->client, NULL, NULL);
@@ -594,7 +611,9 @@ static void gap_device_name_read_cb(struct gatt_db_attribute *attrib,
device_name = btd_adapter_get_name(database->adapter);
#ifdef __TIZEN_PATCH__
- if (get_dst_info(att, &dst, &dst_type) && dst_type != BDADDR_BREDR) {
+ if (get_dst_info(att, &dst, &dst_type) && dst_type != BDADDR_BREDR &&
+ bacmp(btd_adapter_get_address(database->adapter),
+ btd_adapter_get_le_address(database->adapter))) {
char *ptr = NULL;
g_strlcpy(le_name, device_name,
@@ -752,14 +771,20 @@ static uint32_t database_add_record(struct btd_gatt_database *database,
return 0;
if (name != NULL)
+#ifdef __TIZEN_PATCH__
+ sdp_set_info_attr(record, name, "Samsung", NULL);
+#else
sdp_set_info_attr(record, name, "BlueZ", NULL);
+#endif
sdp_uuid16_create(&gap_uuid, UUID_GAP);
+#ifndef __TIZEN_PATCH__
if (sdp_uuid_cmp(&svc, &gap_uuid) == 0) {
sdp_set_url_attr(record, "http://www.bluez.org/",
"http://www.bluez.org/",
"http://www.bluez.org/");
}
+#endif
if (adapter_service_add(database->adapter, record) == 0)
return record->handle;
@@ -775,13 +800,7 @@ static void populate_gap_service(struct btd_gatt_database *database)
/* Add the GAP service */
bt_uuid16_create(&uuid, UUID_GAP);
-
-#ifndef __TIZEN_PATCH__
service = gatt_db_add_service(database->db, &uuid, true, 5);
-#else
- service = gatt_db_add_service(database->db, &uuid, true, 7);
-#endif
-
database->gap_handle = database_add_record(database, UUID_GAP, service,
"Generic Access Profile");
@@ -819,14 +838,25 @@ static bool get_dst_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type)
{
GIOChannel *io = NULL;
GError *gerr = NULL;
+#ifdef __TIZEN_PATCH__
+ struct btd_adapter *adapter;
+ bdaddr_t src;
+#endif
io = g_io_channel_unix_new(bt_att_get_fd(att));
if (!io)
return false;
+#ifdef __TIZEN_PATCH__
+ bt_io_get(io, &gerr, BT_IO_OPT_SOURCE_BDADDR, &src,
+ BT_IO_OPT_DEST_BDADDR, dst,
+ BT_IO_OPT_DEST_TYPE, dst_type,
+ BT_IO_OPT_INVALID);
+#else
bt_io_get(io, &gerr, BT_IO_OPT_DEST_BDADDR, dst,
BT_IO_OPT_DEST_TYPE, dst_type,
BT_IO_OPT_INVALID);
+#endif
if (gerr) {
error("gatt: bt_io_get: %s", gerr->message);
g_error_free(gerr);
@@ -835,6 +865,42 @@ static bool get_dst_info(struct bt_att *att, bdaddr_t *dst, uint8_t *dst_type)
}
g_io_channel_unref(io);
+
+#ifdef __TIZEN_PATCH__
+ adapter = adapter_find(&src);
+ if (adapter == NULL) {
+ DBG("Cannot get adapter");
+ return true;
+ }
+
+ if (*dst_type == BDADDR_LE_PUBLIC) {
+ struct btd_device *device;
+ char addr[18] = { 0 };
+ char addr_rpa[18] = { 0 };
+ const bdaddr_t *rpa;
+
+ device = btd_adapter_find_device(adapter, dst, *dst_type);
+ if (device == NULL) {
+ DBG("Cannot find device");
+ return true;
+ }
+
+ if (device_get_rpa_exist(device) == false)
+ return true;
+
+ rpa = device_get_rpa(device);
+ if (rpa == NULL)
+ return true;
+
+ ba2str(dst, addr);
+ ba2str(rpa, addr_rpa);
+ DBG("Convert IDA [%s] to RPA [%s]", addr, addr_rpa);
+
+ bacpy(dst, rpa);
+ *dst_type = BDADDR_LE_RANDOM;
+ }
+#endif
+
return true;
}
@@ -1072,7 +1138,11 @@ static void indicate_confirm_setup_cb(DBusMessageIter *iter, void *user_data)
char *addr_value = NULL;
gboolean complete = FALSE;
- ba2str(device_get_address(device), dstaddr);
+ if (device_get_rpa_exist(device) == true) {
+ ba2str(device_get_rpa(device), dstaddr);
+ } else {
+ ba2str(device_get_address(device), dstaddr);
+ }
addr_value = g_strdup(dstaddr);
dbus_message_iter_append_basic(iter, DBUS_TYPE_STRING,
@@ -1171,7 +1241,9 @@ static void send_notification_indication_to_devices(GDBusProxy *proxy,
bool indicate)
{
struct notify_indicate notify_indicate;
- DBG("");
+
+ DBG("notify for handle: 0x%04x", handle);
+
memset(&notify_indicate, 0, sizeof(notify_indicate));
notify_indicate.database = database;
@@ -1194,7 +1266,8 @@ static void send_unicast_notification_indication_to_device(GDBusProxy *proxy,
{
struct device_state *dev_state;
struct notify_indicate notify_indicate;
- DBG("");
+
+ DBG("notify for handle: 0x%04x", handle);
memset(&notify_indicate, 0, sizeof(notify_indicate));
@@ -1746,39 +1819,12 @@ static void proxy_added_cb(GDBusProxy *proxy, void *user_data)
if (app->failed)
return;
+ queue_push_tail(app->proxies, proxy);
+
iface = g_dbus_proxy_get_interface(proxy);
path = g_dbus_proxy_get_path(proxy);
- if (g_strcmp0(iface, GATT_SERVICE_IFACE) == 0) {
- struct external_service *service;
-
- service = create_service(app, proxy, path);
- if (!service) {
- app->failed = true;
- return;
- }
- } else if (g_strcmp0(iface, GATT_CHRC_IFACE) == 0) {
- struct external_chrc *chrc;
-
- chrc = chrc_create(app, proxy, path);
- if (!chrc) {
- app->failed = true;
- return;
- }
- } else if (g_strcmp0(iface, GATT_DESC_IFACE) == 0) {
- struct external_desc *desc;
-
- desc = desc_create(app, proxy);
- if (!desc) {
- app->failed = true;
- return;
- }
- } else {
- DBG("Ignoring unrelated interface: %s", iface);
- return;
- }
-
- DBG("Object added: path: %s, iface: %s", path, iface);
+ DBG("Object received: %s, iface: %s", path, iface);
}
static void proxy_removed_cb(GDBusProxy *proxy, void *user_data)
@@ -1953,12 +1999,9 @@ static struct pending_op *pending_read_new(struct queue *owner_queue,
#endif
op = new0(struct pending_op, 1);
- if (!op)
- return NULL;
#ifdef __TIZEN_PATCH__
if (!get_dst_info(att, &bdaddr, &bdaddr_type)) {
- free(op);
return NULL;
}
#endif
@@ -2016,11 +2059,6 @@ static void send_read(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
#else
op = pending_read_new(owner_queue, attrib, id);
#endif
- if (!op) {
- error("Failed to allocate memory for pending read call");
- ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
- goto error;
- }
#ifdef __TIZEN_PATCH__
if (g_dbus_proxy_method_call(proxy, "ReadValue", read_setup_cb, read_reply_cb,
@@ -2033,7 +2071,6 @@ static void send_read(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
pending_op_free(op);
-error:
gatt_db_attribute_read_result(attrib, id, ecode, NULL, 0);
}
@@ -2124,11 +2161,8 @@ static struct pending_op *pending_write_new(struct queue *owner_queue,
#endif
op = new0(struct pending_op, 1);
- if (!op)
- return NULL;
#ifdef __TIZEN_PATCH__
if (!get_dst_info(att, &bdaddr, &bdaddr_type)) {
- free(op);
return NULL;
}
#endif
@@ -2167,11 +2201,6 @@ static void send_write(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
#else
op = pending_write_new(owner_queue, attrib, id, value, len);
#endif
- if (!op) {
- error("Failed to allocate memory for pending read call");
- ecode = BT_ATT_ERROR_INSUFFICIENT_RESOURCES;
- goto error;
- }
if (g_dbus_proxy_method_call(proxy, "WriteValue", write_setup_cb,
write_reply_cb, op,
@@ -2180,7 +2209,6 @@ static void send_write(struct gatt_db_attribute *attrib, GDBusProxy *proxy,
pending_op_free(op);
-error:
gatt_db_attribute_write_result(attrib, id, ecode);
}
@@ -2768,12 +2796,92 @@ static bool database_add_app(struct gatt_app *app)
return true;
}
+static void register_service(void *data, void *user_data)
+{
+ struct gatt_app *app = user_data;
+ GDBusProxy *proxy = data;
+ const char *iface = g_dbus_proxy_get_interface(proxy);
+ const char *path = g_dbus_proxy_get_path(proxy);
+
+ if (app->failed)
+ return;
+
+ if (g_strcmp0(iface, GATT_SERVICE_IFACE) == 0) {
+ struct external_service *service;
+
+ service = create_service(app, proxy, path);
+ if (!service) {
+ app->failed = true;
+ return;
+ }
+ }
+}
+
+static void register_characteristic(void *data, void *user_data)
+{
+ struct gatt_app *app = user_data;
+ GDBusProxy *proxy = data;
+ const char *iface = g_dbus_proxy_get_interface(proxy);
+ const char *path = g_dbus_proxy_get_path(proxy);
+
+ if (app->failed)
+ return;
+
+ iface = g_dbus_proxy_get_interface(proxy);
+ path = g_dbus_proxy_get_path(proxy);
+
+ if (g_strcmp0(iface, GATT_CHRC_IFACE) == 0) {
+ struct external_chrc *chrc;
+
+ chrc = chrc_create(app, proxy, path);
+ if (!chrc) {
+ app->failed = true;
+ return;
+ }
+ }
+}
+
+static void register_descriptor(void *data, void *user_data)
+{
+ struct gatt_app *app = user_data;
+ GDBusProxy *proxy = data;
+ const char *iface = g_dbus_proxy_get_interface(proxy);
+
+ if (app->failed)
+ return;
+
+ if (g_strcmp0(iface, GATT_DESC_IFACE) == 0) {
+ struct external_desc *desc;
+
+ desc = desc_create(app, proxy);
+ if (!desc) {
+ app->failed = true;
+ return;
+ }
+ }
+}
+
static void client_ready_cb(GDBusClient *client, void *user_data)
{
struct gatt_app *app = user_data;
DBusMessage *reply;
bool fail = false;
+ /*
+ * Process received objects
+ */
+ if (queue_isempty(app->proxies)) {
+ error("No object received");
+ fail = true;
+ reply = btd_error_failed(app->reg,
+ "No object received");
+ goto reply;
+ }
+
+ queue_foreach(app->proxies, register_service, app);
+ queue_foreach(app->proxies, register_characteristic, app);
+ queue_foreach(app->proxies, register_descriptor, app);
+
if (!app->services || app->failed) {
error("No valid external GATT objects found");
fail = true;
@@ -2827,6 +2935,7 @@ static struct gatt_app *create_app(DBusConnection *conn, DBusMessage *msg,
goto fail;
app->services = queue_new();
+ app->proxies = queue_new();
app->reg = dbus_message_ref(msg);
g_dbus_client_set_disconnect_watch(app->client, client_disconnect_cb,
diff --git a/src/main.conf b/src/main.conf
new file mode 100644
index 00000000..372fd8c9
--- /dev/null
+++ b/src/main.conf
@@ -0,0 +1,89 @@
+[General]
+
+# Default adaper name
+# Defaults to 'BlueZ X.YZ'
+#Name = BlueZ
+
+# Default device class. Only the major and minor device class bits are
+# considered. Defaults to '0x000000'.
+#Class = 0x000100
+
+# How long to stay in discoverable mode before going back to non-discoverable
+# The value is in seconds. Default is 180, i.e. 3 minutes.
+# 0 = disable timer, i.e. stay discoverable forever
+#DiscoverableTimeout = 0
+
+# How long to stay in pairable mode before going back to non-discoverable
+# The value is in seconds. Default is 0.
+# 0 = disable timer, i.e. stay pairable forever
+#PairableTimeout = 0
+
+# Automatic connection for bonded devices driven by platform/user events.
+# If a platform plugin uses this mechanism, automatic connections will be
+# enabled during the interval defined below. Initially, this feature
+# intends to be used to establish connections to ATT channels. Default is 60.
+#AutoConnectTimeout = 60
+
+# Use vendor id source (assigner), vendor, product and version information for
+# DID profile support. The values are separated by ":" and assigner, VID, PID
+# and version.
+# Possible vendor id source values: bluetooth, usb (defaults to usb)
+#DeviceID = bluetooth:1234:5678:abcd
+
+# Do reverse service discovery for previously unknown devices that connect to
+# us. This option is really only needed for qualification since the BITE tester
+# doesn't like us doing reverse SDP for some test cases (though there could in
+# theory be other useful purposes for this too). Defaults to 'true'.
+#ReverseServiceDiscovery = true
+
+# Enable name resolving after inquiry. Set it to 'false' if you don't need
+# remote devices name and want shorter discovery cycle. Defaults to 'true'.
+#NameResolving = true
+
+# Enable runtime persistency of debug link keys. Default is false which
+# makes debug link keys valid only for the duration of the connection
+# that they were created for.
+#DebugKeys = false
+
+# Restricts all controllers to the specified transport. Default value
+# is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).
+# Possible values: "dual", "bredr", "le"
+#ControllerMode = dual
+
+# Enables Multi Profile Specification support. This allows to specify if
+# system supports only Multiple Profiles Single Device (MPSD) configuration
+# or both Multiple Profiles Single Device (MPSD) and Multiple Profiles Multiple
+# Devices (MPMD) configurations.
+# Possible values: "off", "single", "multiple"
+#MultiProfile = off
+
+# Permanently enables the Fast Connectable setting for adapters that
+# support it. When enabled other devices can connect faster to us,
+# however the tradeoff is increased power consumptions. This feature
+# will fully work only on kernel version 4.1 and newer. Defaults to
+# 'false'.
+#FastConnectable = false
+
+#[Policy]
+#
+# The ReconnectUUIDs defines the set of remote services that should try
+# to be reconnected to in case of a link loss (link supervision
+# timeout). The policy plugin should contain a sane set of values by
+# default, but this list can be overridden here. By setting the list to
+# empty the reconnection feature gets disabled.
+#ReconnectUUIDs=00001112-0000-1000-8000-00805f9b34fb, 0000111f-0000-1000-8000-00805f9b34fb, 0000110a-0000-1000-8000-00805f9b34fb
+
+# ReconnectAttempts define the number of attempts to reconnect after a link
+# lost. Setting the value to 0 disables reconnecting feature.
+#ReconnectAttempts=7
+
+# ReconnectIntervals define the set of intervals in seconds to use in between
+# attempts.
+# If the number of attempts defined in ReconnectAttempts is bigger than the
+# set of intervals the last interval is repeated until the last attempt.
+#ReconnectIntervals=1, 2, 4, 8, 16, 32, 64
+
+# AutoEnable defines option to enable all controllers when they are found.
+# This includes adapters present on start as well as adapters that are plugged
+# in later on. Defaults to 'false'.
+#AutoEnable=false
diff --git a/src/main_hive.conf b/src/main_hive.conf
new file mode 100644
index 00000000..4d5066d4
--- /dev/null
+++ b/src/main_hive.conf
@@ -0,0 +1,87 @@
+[General]
+
+# Default adaper name
+# %h - substituted for hostname
+# %d - substituted for adapter id
+# Defaults to 'BlueZ'
+#Name = %h-%d
+
+# Default device class. Only the major and minor device class bits are
+# considered. Defaults to '0x000000'.
+#ifdef __TIZEN_PATCH__
+Class = 0x40414 # HIVE
+#else
+#Class = 0x000100
+#endif
+
+# How long to stay in discoverable mode before going back to non-discoverable
+# The value is in seconds. Default is 180, i.e. 3 minutes.
+# 0 = disable timer, i.e. stay discoverable forever
+#DiscoverableTimeout = 0
+
+# How long to stay in pairable mode before going back to non-discoverable
+# The value is in seconds. Default is 0.
+# 0 = disable timer, i.e. stay pairable forever
+#PairableTimeout = 0
+
+# Automatic connection for bonded devices driven by platform/user events.
+# If a platform plugin uses this mechanism, automatic connections will be
+# enabled during the interval defined below. Initially, this feature
+# intends to be used to establish connections to ATT channels. Default is 60.
+#AutoConnectTimeout = 60
+
+# Use vendor id source (assigner), vendor, product and version information for
+# DID profile support. The values are separated by ":" and assigner, VID, PID
+# and version.
+# Possible vendor id source values: bluetooth, usb (defaults to usb)
+#DeviceID = bluetooth:1234:5678:abcd
+
+# Do reverse service discovery for previously unknown devices that connect to
+# us. This option is really only needed for qualification since the BITE tester
+# doesn't like us doing reverse SDP for some test cases (though there could in
+# theory be other useful purposes for this too). Defaults to 'true'.
+#ReverseServiceDiscovery = true
+
+# Enable name resolving after inquiry. Set it to 'false' if you don't need
+# remote devices name and want shorter discovery cycle. Defaults to 'true'.
+#NameResolving = true
+
+# Enable runtime persistency of debug link keys. Default is false which
+# makes debug link keys valid only for the duration of the connection
+# that they were created for.
+#DebugKeys = false
+
+# Restricts all controllers to the specified transport. Default value
+# is "dual", i.e. both BR/EDR and LE enabled (when supported by the HW).
+# Possible values: "dual", "bredr", "le"
+#ControllerMode = dual
+
+# Enables Multi Profile Specification support. This allows to specify if
+# system supports only Multiple Profiles Single Device (MPSD) configuration
+# or both Multiple Profiles Single Device (MPSD) and Multiple Profiles Multiple
+# Devices (MPMD) configurations.
+# Possible values: "off", "single", "multiple"
+#MultiProfile = off
+
+# Permanently enables the Fast Connectable setting for adapters that
+# support it. When enabled other devices can connect faster to us,
+# however the tradeoff is increased power consumptions. This feature
+# will fully work only on kernel version 4.1 and newer. Defaults to
+# 'false'.
+#FastConnectable = false
+
+#ifdef __TIZEN_PATCH__
+# Enable the LE Privacy feature. If value is true, i.e. LE Privacy is enabled
+# otherwise the feature is disabled by default for the local device.
+EnableLEPrivacy = true
+#endif
+
+#[Policy]
+#
+# The ReconnectUUIDs defines the set of remote services that should try
+# to be reconnected to in case of a link loss (link supervision
+# timeout). The policy plugin should contain a sane set of values by
+# default, but this list can be overridden here. By setting the list to
+# empty the reconnection feature gets disabled.
+#ReconnectUUIDs=
+
diff --git a/src/profile.c b/src/profile.c
index c12b57b9..26a9e19a 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -547,9 +547,6 @@
<attribute id=\"0x0314\"> \
<uint8 value=\""PBAP_ACCESS"\"/> \
</attribute> \
- <attribute id=\"0x0200\"> \
- <uint16 value=\"%u\" name=\"psm\"/> \
- </attribute> \
</record>"
#else
#define PSE_RECORD \
@@ -602,6 +599,12 @@
</record>"
#endif
+#ifdef __TIZEN_PATCH__
+#define SUPPORTED_MESSAGE_TYPES "0x03" /* EMAIL and SMS_GSM */
+#else
+#define SUPPORTED_MESSAGE_TYPES "0x0F" /* EMAIL, SMS_GSM, SMS_CDMA and MMS */
+#endif
+
#define MAS_RECORD \
"<?xml version=\"1.0\" encoding=\"UTF-8\" ?> \
<record> \
@@ -644,7 +647,7 @@
<uint8 value=\"0x00\"/> \
</attribute> \
<attribute id=\"0x0316\"> \
- <uint8 value=\"0x0F\"/> \
+ <uint8 value=\""SUPPORTED_MESSAGE_TYPES"\"/> \
</attribute> \
<attribute id=\"0x0317\"> \
<uint32 value=\"0x0000007f\"/> \
@@ -854,7 +857,7 @@
<sequence> \
<sequence> \
<uint8 value=\"0x22\" /> \
- <text encoding=\"hex\" value=\"05010902a10185010901a1000509190129031500250175019503810275059501810105010930093109381581257f750895028106c0c005010906a1018502a100050719e029e71500250175019508810295087508150025650507190029658100c0c0\" /> \
+ <text encoding=\"hex\" value=\"05010902a10185010901a100050919012903150025017501950381027505950181010501093009311581257f750895028106a10285010938950175081581257f8106c0c0c005010906a1018502a100050719e029e71500250175019508810295087508150025650507190029658100c0c0\" /> \
</sequence> \
</sequence> \
</attribute> \
@@ -921,9 +924,6 @@ struct ext_profile {
char *destination;
char *app_path;
#endif
-#ifdef TIZEN_BT_HID_DEVICE_ENABLE
- bool local_connect;
-#endif
};
struct ext_io {
@@ -1259,7 +1259,6 @@ static bool send_new_connection(struct ext_profile *ext, struct ext_io *conn)
dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &path);
fd = g_io_channel_unix_get_fd(conn->io);
-
dbus_message_iter_append_basic(&iter, DBUS_TYPE_UNIX_FD, &fd);
dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, "{sv}", &dict);
@@ -1290,16 +1289,6 @@ static bool send_new_connection(struct ext_profile *ext, struct ext_io *conn)
return true;
}
-#ifdef TIZEN_BT_HID_DEVICE_ENABLE
-static int check_connection_psm(gconstpointer a, gconstpointer b)
-{
- const struct ext_io *conn = a;
- const int *psm = b;
- DBG("conn->psm %d, psm %d", conn->psm, *psm);
- return (conn->psm == *psm ? 0 : -1);
-}
-#endif
-
static void ext_connect(GIOChannel *io, GError *err, gpointer user_data)
{
struct ext_io *conn = user_data;
@@ -1335,32 +1324,6 @@ static void ext_connect(GIOChannel *io, GError *err, gpointer user_data)
conn);
}
-#ifdef TIZEN_BT_HID_DEVICE_ENABLE
- if (g_strcmp0(ext->uuid, HID_UUID) == 0 && ext->local_connect == TRUE) {
- GSList *l = NULL;
- int psm = HID_DEVICE_CTRL_PSM;
- ext->local_connect = FALSE;
- l = g_slist_find_custom(ext->conns, &psm, check_connection_psm);
- if (l == NULL) {
- struct ext_io *conn1 = g_new0(struct ext_io, 1);
- int error = 0;
- ext->remote_psm = psm;
- conn1->ext = ext;
- conn1->psm = ext->remote_psm;
- conn1->chan = ext->remote_chan;
- error = connect_io(conn1, btd_adapter_get_address(conn->adapter),
- device_get_address(conn->device));
- DBG("error from connect_io %d", error);
- conn1->adapter = btd_adapter_ref(conn->adapter);
- conn1->device = btd_device_ref(conn->device);
- conn1->service = btd_service_ref(conn->service);
- ext->conns = g_slist_append(ext->conns, conn1);
- } else {
- DBG("Connection Already there");
- }
- }
-#endif
-
if (conn->service && service_accept(conn->service) == 0) {
if (send_new_connection(ext, conn))
return;
@@ -1571,17 +1534,11 @@ static uint32_t ext_start_servers(struct ext_profile *ext,
struct btd_adapter *adapter)
{
struct ext_io *l2cap = NULL;
-#ifdef TIZEN_BT_HID_DEVICE_ENABLE
- struct ext_io *l2cap1 = NULL;
-#endif
struct ext_io *rfcomm = NULL;
BtIOConfirm confirm;
BtIOConnect connect;
GError *err = NULL;
GIOChannel *io;
-#ifdef TIZEN_BT_HID_DEVICE_ENABLE
- GIOChannel *io1;
-#endif
if (ext->authorize) {
confirm = ext_confirm;
@@ -1627,26 +1584,6 @@ static uint32_t ext_start_servers(struct ext_profile *ext,
ext->servers = g_slist_append(ext->servers, l2cap);
DBG("%s listening on PSM %u", ext->name, psm);
}
-#ifdef TIZEN_BT_HID_DEVICE_ENABLE
- if (g_strcmp0(ext->uuid , HID_UUID) == 0) {
- psm = HID_DEVICE_CTRL_PSM;
- l2cap1 = g_new0(struct ext_io, 1);
- l2cap1->ext = ext;
- io1 = bt_io_listen(connect, confirm, l2cap, NULL, &err,
- BT_IO_OPT_SOURCE_BDADDR,
- btd_adapter_get_address(adapter),
- BT_IO_OPT_MODE, ext->mode,
- BT_IO_OPT_PSM, psm,
- BT_IO_OPT_SEC_LEVEL, ext->sec_level,
- BT_IO_OPT_INVALID);
- l2cap1->io = io1;
- l2cap1->proto = BTPROTO_L2CAP;
- l2cap1->psm = psm;
- l2cap1->adapter = btd_adapter_ref(adapter);
- ext->servers = g_slist_append(ext->servers, l2cap1);
- DBG("%s listening on PSM %u", ext->name, psm);
- }
-#endif
}
if (ext->local_chan) {
@@ -2047,7 +1984,7 @@ static int ext_connect_dev(struct btd_service *service)
conn = g_new0(struct ext_io, 1);
conn->ext = ext;
-#ifndef TIZEN_BT_HID_DEVICE_ENABLE
+
if (ext->remote_psm || ext->remote_chan) {
conn->psm = ext->remote_psm;
conn->chan = ext->remote_chan;
@@ -2060,28 +1997,7 @@ static int ext_connect_dev(struct btd_service *service)
if (err < 0)
goto failed;
-#else
- if (g_strcmp0(ext->uuid, HID_UUID) == 0) {
- ext->local_connect = TRUE;
- ext->remote_psm = HID_DEVICE_INTR_PSM;
- conn->psm = ext->remote_psm;
- conn->chan = ext->remote_chan;
- err = connect_io(conn, btd_adapter_get_address(adapter),
- device_get_address(dev));
- } else {
- if (ext->remote_psm || ext->remote_chan) {
- conn->psm = ext->remote_psm;
- conn->chan = ext->remote_chan;
- err = connect_io(conn, btd_adapter_get_address(adapter),
- device_get_address(dev));
- } else {
- err = resolve_service(conn, btd_adapter_get_address(adapter),
- device_get_address(dev));
- }
- }
- if (err < 0)
- goto failed;
-#endif
+
conn->adapter = btd_adapter_ref(adapter);
conn->device = btd_device_ref(dev);
conn->service = btd_service_ref(service);
@@ -2139,7 +2055,6 @@ static int ext_disconnect_dev(struct btd_service *service)
if (!ext)
return -ENOENT;
-#ifndef TIZEN_BT_HID_DEVICE_ENABLE
conn = find_connection(ext, dev);
if (!conn || !conn->connected)
return -ENOTCONN;
@@ -2150,30 +2065,7 @@ static int ext_disconnect_dev(struct btd_service *service)
err = send_disconn_req(ext, conn);
if (err < 0)
return err;
-#else
- if (g_strcmp0(ext->uuid, HID_UUID) != 0) {
- conn = find_connection(ext, dev);
- if (!conn || !conn->connected)
- return -ENOTCONN;
-
- if (conn->pending)
- return -EBUSY;
- err = send_disconn_req(ext, conn);
- if (err < 0)
- return err;
- } else {
- GSList *l;
- /* As HID will be using two psm we need to send disconnect
- * request for both the psms */
- for (l = ext->conns; l != NULL; l = g_slist_next(l)) {
- struct ext_io *conn1 = l->data;
- if (conn1->device == dev) {
- err = send_disconn_req(ext, conn1);
- }
- }
- }
-#endif
return 0;
}
@@ -2252,7 +2144,11 @@ static char *get_pse_record(struct ext_profile *ext, struct ext_io *l2cap,
if (rfcomm)
chan = rfcomm->chan;
+#ifdef __TIZEN_PATCH__
+ return g_strdup_printf(PSE_RECORD, chan, ext->version, ext->name);
+#else
return g_strdup_printf(PSE_RECORD, chan, ext->version, ext->name, psm);
+#endif
}
static char *get_mas_record(struct ext_profile *ext, struct ext_io *l2cap,
@@ -2460,11 +2356,7 @@ static struct default_settings {
.psm = BTD_PROFILE_PSM_AUTO,
.mode = BT_IO_MODE_ERTM,
.sec_level = BT_IO_SEC_LOW,
-#ifdef __TIZEN_PATCH__
- .authorize = true,
-#else
.authorize = false,
-#endif
.get_record = get_opp_record,
#ifdef __TIZEN_PATCH__
.version = 0x0100,
@@ -2523,7 +2415,7 @@ static struct default_settings {
.version = 0x0102
#ifdef TIZEN_BT_HID_DEVICE_ENABLE
}, {
- .uuid = HID_UUID,
+ .uuid = HID_DEVICE_UUID,
.name = "HID Device",
.psm = HID_DEVICE_INTR_PSM,
.authorize = TRUE,
@@ -2892,7 +2784,10 @@ static struct ext_profile *create_ext(const char *owner, const char *path,
}
DBG("Created \"%s\"", ext->name);
-
+#ifdef TIZEN_BT_HID_DEVICE_ENABLE
+ if (g_strcmp0(ext->uuid , HID_DEVICE_UUID) == 0)
+ ext->local_psm = 0;
+#endif
ext_profiles = g_slist_append(ext_profiles, ext);
adapter_foreach(adapter_add_profile, &ext->p);
diff --git a/src/shared/att.c b/src/shared/att.c
index 187e685b..a139660c 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -596,13 +596,19 @@ static bool change_security(struct bt_att *att, uint8_t ecode)
{
int security;
- security = bt_att_get_security(att);
- if (security != BT_ATT_SECURITY_AUTO)
+ if (att->io_sec_level != BT_ATT_SECURITY_AUTO)
return false;
+ security = bt_att_get_security(att);
+
if (ecode == BT_ATT_ERROR_INSUFFICIENT_ENCRYPTION &&
security < BT_ATT_SECURITY_MEDIUM)
security = BT_ATT_SECURITY_MEDIUM;
+#ifdef __TIZEN_PATCH__
+ else if (ecode == BT_ATT_ERROR_AUTHENTICATION &&
+ security < BT_ATT_SECURITY_MEDIUM)
+ security = BT_ATT_SECURITY_MEDIUM;
+#endif
else if (ecode == BT_ATT_ERROR_AUTHENTICATION &&
security < BT_ATT_SECURITY_HIGH)
security = BT_ATT_SECURITY_HIGH;
@@ -1009,7 +1015,7 @@ struct bt_att *bt_att_new(int fd, bool ext_signed)
att->io_on_l2cap = is_io_l2cap_based(att->fd);
if (!att->io_on_l2cap)
- att->io_sec_level = BT_SECURITY_LOW;
+ att->io_sec_level = BT_ATT_SECURITY_LOW;
return bt_att_ref(att);
diff --git a/src/shared/gatt-client.c b/src/shared/gatt-client.c
index f8e8298a..208f26c0 100644
--- a/src/shared/gatt-client.c
+++ b/src/shared/gatt-client.c
@@ -320,25 +320,6 @@ struct handle_range {
uint16_t end;
};
-static bool match_notify_data_handle_range(const void *a, const void *b)
-{
- const struct notify_data *notify_data = a;
- struct notify_chrc *chrc = notify_data->chrc;
- const struct handle_range *range = b;
-
- return chrc->value_handle >= range->start &&
- chrc->value_handle <= range->end;
-}
-
-static bool match_notify_chrc_handle_range(const void *a, const void *b)
-{
- const struct notify_chrc *chrc = a;
- const struct handle_range *range = b;
-
- return chrc->value_handle >= range->start &&
- chrc->value_handle <= range->end;
-}
-
static void notify_data_cleanup(void *data)
{
struct notify_data *notify_data = data;
@@ -349,32 +330,6 @@ static void notify_data_cleanup(void *data)
notify_data_unref(notify_data);
}
-static void gatt_client_remove_all_notify_in_range(
- struct bt_gatt_client *client,
- uint16_t start_handle, uint16_t end_handle)
-{
- struct handle_range range;
-
- range.start = start_handle;
- range.end = end_handle;
-
- queue_remove_all(client->notify_list, match_notify_data_handle_range,
- &range, notify_data_cleanup);
-}
-
-static void gatt_client_remove_notify_chrcs_in_range(
- struct bt_gatt_client *client,
- uint16_t start_handle, uint16_t end_handle)
-{
- struct handle_range range;
-
- range.start = start_handle;
- range.end = end_handle;
-
- queue_remove_all(client->notify_chrcs, match_notify_chrc_handle_range,
- &range, notify_chrc_free);
-}
-
struct discovery_op;
typedef void (*discovery_op_complete_func_t)(struct discovery_op *op,
@@ -386,11 +341,12 @@ struct discovery_op {
struct bt_gatt_client *client;
struct queue *pending_svcs;
struct queue *pending_chrcs;
- struct queue *tmp_queue;
+ struct queue *svcs;
struct gatt_db_attribute *cur_svc;
bool success;
uint16_t start;
uint16_t end;
+ uint16_t last;
int ref_count;
discovery_op_complete_func_t complete_func;
discovery_op_fail_func_t failure_func;
@@ -400,10 +356,45 @@ static void discovery_op_free(struct discovery_op *op)
{
queue_destroy(op->pending_svcs, NULL);
queue_destroy(op->pending_chrcs, free);
- queue_destroy(op->tmp_queue, NULL);
+ queue_destroy(op->svcs, NULL);
free(op);
}
+static void discovery_op_complete(struct discovery_op *op, bool success,
+ uint8_t err)
+{
+ /* Reset remaining range */
+ if (success) {
+#ifdef __TIZEN_PATCH__
+ util_debug(op->client->debug_callback, op->client->debug_data,
+ "op->start : %u, op->end : %u, op->last : %u",
+ op->start, op->end, op->last);
+
+ if (op->last != UINT16_MAX) {
+ if (op->start != op->last)
+ op->last++;
+
+ if (op->last <= op->end)
+ gatt_db_clear_range(op->client->db,
+ op->last, op->end);
+ }
+#else
+ if (op->last != UINT16_MAX)
+ gatt_db_clear_range(op->client->db, op->last + 1,
+ UINT16_MAX);
+#endif
+ } else {
+#ifdef __TIZEN_PATCH__
+ util_debug(op->client->debug_callback, op->client->debug_data,
+ "Fail to discover service. Clear DB [%d]", err);
+#endif
+ gatt_db_clear(op->client->db);
+ }
+
+ op->success = success;
+ op->complete_func(op, success, err);
+}
+
static struct discovery_op *discovery_op_create(struct bt_gatt_client *client,
uint16_t start, uint16_t end,
discovery_op_complete_func_t complete_func,
@@ -414,12 +405,15 @@ static struct discovery_op *discovery_op_create(struct bt_gatt_client *client,
op = new0(struct discovery_op, 1);
op->pending_svcs = queue_new();
op->pending_chrcs = queue_new();
- op->tmp_queue = queue_new();
+ op->svcs = queue_new();
op->client = client;
op->complete_func = complete_func;
op->failure_func = failure_func;
op->start = start;
op->end = end;
+#ifdef __TIZEN_PATCH__
+ op->last = start;
+#endif
return op;
}
@@ -530,17 +524,11 @@ next:
/* Move on to the next service */
attr = queue_pop_head(op->pending_svcs);
if (!attr) {
- struct queue *tmp_queue;
-
- tmp_queue = op->pending_svcs;
- op->pending_svcs = op->tmp_queue;
- op->tmp_queue = tmp_queue;
-
/*
* We have processed all include definitions. Move on to
* characteristics.
*/
- attr = queue_pop_head(op->pending_svcs);
+ attr = queue_pop_head(op->svcs);
if (!attr)
goto failed;
@@ -564,7 +552,7 @@ next:
goto failed;
}
- queue_push_tail(op->tmp_queue, attr);
+ queue_push_tail(op->svcs, attr);
op->cur_svc = attr;
if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
goto failed;
@@ -585,8 +573,7 @@ next:
discovery_op_unref(op);
failed:
- op->success = false;
- op->complete_func(op, false, att_ecode);
+ discovery_op_complete(op, false, att_ecode);
}
struct chrc {
@@ -617,8 +604,12 @@ static bool discover_descs(struct discovery_op *op, bool *discovering)
chrc_data->properties,
NULL, NULL, NULL);
- if (!attr)
+ if (!attr) {
+ util_debug(client->debug_callback, client->debug_data,
+ "Failed to insert characteristic at 0x%04x",
+ chrc_data->value_handle);
goto failed;
+ }
if (gatt_db_attribute_get_handle(attr) !=
chrc_data->value_handle)
@@ -727,7 +718,7 @@ next:
/* Done with the current service */
gatt_db_service_set_active(op->cur_svc, true);
- attr = queue_pop_head(op->pending_svcs);
+ attr = queue_pop_head(op->svcs);
if (!attr)
goto done;
@@ -756,8 +747,7 @@ failed:
success = false;
done:
- op->success = success;
- op->complete_func(op, success, att_ecode);
+ discovery_op_complete(op, success, att_ecode);
}
#ifdef __TIZEN_PATCH__
@@ -894,7 +884,7 @@ next:
/* Done with the current service */
gatt_db_service_set_active(op->cur_svc, true);
- attr = queue_pop_head(op->pending_svcs);
+ attr = queue_pop_head(op->svcs);
if (!attr)
goto done;
@@ -923,8 +913,7 @@ failed:
success = false;
done:
- op->success = success;
- op->complete_func(op, success, att_ecode);
+ discovery_op_complete(op, success, att_ecode);
}
static void discover_secondary_cb(bool success, uint8_t att_ecode,
@@ -974,6 +963,13 @@ static void discover_secondary_cb(bool success, uint8_t att_ecode,
start, end, uuid_str);
/* Store the service */
+#ifdef __TIZEN_PATCH__
+ if (client->in_svc_chngd) {
+ util_debug(client->debug_callback, client->debug_data,
+ "In service changed, delete service first.");
+ gatt_db_clear_range(client->db, start, end);
+ }
+#endif
attr = gatt_db_insert_service(client->db, start, &uuid, false,
end - start + 1);
if (!attr) {
@@ -992,6 +988,10 @@ static void discover_secondary_cb(bool success, uint8_t att_ecode,
/* Skip if service already active */
if (!gatt_db_service_get_active(attr))
queue_push_tail(op->pending_svcs, attr);
+
+ /* Update last handle */
+ if (end > op->last)
+ op->last = end;
}
next:
@@ -1005,10 +1005,10 @@ next:
}
/*
- * Store the service in the tmp queue to be reused during
+ * Store the service in the svcs queue to be reused during
* characteristics discovery later.
*/
- queue_push_tail(op->tmp_queue, attr);
+ queue_push_tail(op->svcs, attr);
op->cur_svc = attr;
if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) {
@@ -1029,8 +1029,7 @@ next:
discovery_op_unref(op);
done:
- op->success = success;
- op->complete_func(op, success, att_ecode);
+ discovery_op_complete(op, success, att_ecode);
}
static void discover_primary_cb(bool success, uint8_t att_ecode,
@@ -1053,7 +1052,11 @@ static void discover_primary_cb(bool success, uint8_t att_ecode,
"Primary service discovery failed."
" ATT ECODE: 0x%02x", att_ecode);
/* Reset error in case of not found */
+#ifdef __TIZEN_PATCH__
+ if (att_ecode == BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND) {
+#else
if (BT_ATT_ERROR_ATTRIBUTE_NOT_FOUND) {
+#endif
success = true;
att_ecode = 0;
}
@@ -1078,6 +1081,13 @@ static void discover_primary_cb(bool success, uint8_t att_ecode,
"start: 0x%04x, end: 0x%04x, uuid: %s",
start, end, uuid_str);
+#ifdef __TIZEN_PATCH__
+ if (client->in_svc_chngd) {
+ util_debug(client->debug_callback, client->debug_data,
+ "In service changed, delete service first.");
+ gatt_db_clear_range(client->db, start, end);
+ }
+#endif
attr = gatt_db_insert_service(client->db, start, &uuid, true,
end - start + 1);
if (!attr) {
@@ -1096,6 +1106,10 @@ static void discover_primary_cb(bool success, uint8_t att_ecode,
/* Skip if service already active */
if (!gatt_db_service_get_active(attr))
queue_push_tail(op->pending_svcs, attr);
+
+ /* Update last handle */
+ if (end > op->last)
+ op->last = end;
}
secondary:
@@ -1123,8 +1137,7 @@ secondary:
success = false;
done:
- op->success = success;
- op->complete_func(op, success, att_ecode);
+ discovery_op_complete(op, success, att_ecode);
}
static void notify_client_ready(struct bt_gatt_client *client, bool success,
@@ -1549,22 +1562,6 @@ static void process_service_changed(struct bt_gatt_client *client,
{
struct discovery_op *op;
- /* On full database reset just re-run attribute discovery */
- if (start_handle == 0x0001 && end_handle == 0xffff)
- goto discover;
-
- /* Invalidate and remove all effected notify callbacks */
- gatt_client_remove_all_notify_in_range(client, start_handle,
- end_handle);
- gatt_client_remove_notify_chrcs_in_range(client, start_handle,
- end_handle);
-
- /* Remove all services that overlap the modified range since we'll
- * rediscover them
- */
- gatt_db_clear_range(client->db, start_handle, end_handle);
-
-discover:
op = discovery_op_create(client, start_handle, end_handle,
service_changed_complete,
service_changed_failure);
@@ -1618,12 +1615,10 @@ static void service_changed_cb(uint16_t value_handle, const uint8_t *value,
"Service Changed received - start: 0x%04x end: 0x%04x",
start, end);
-#ifndef __TIZEN_PATCH__
if (!client->in_svc_chngd) {
process_service_changed(client, start, end);
return;
}
-#endif
op = new0(struct service_changed_op, 1);
@@ -1753,6 +1748,11 @@ static void complete_unregister_notify(void *data)
*/
if (notify_data->att_id) {
bt_att_cancel(notify_data->client->att, notify_data->att_id);
+ notify_data->att_id = 0;
+#ifdef __TIZEN_PATCH__
+ notify_data->chrc->ccc_write_id = 0;
+ __sync_sub_and_fetch(&notify_data->chrc->notify_count, 1);
+#endif
goto done;
}
@@ -1795,9 +1795,8 @@ static void notify_cb(uint8_t opcode, const void *pdu, uint16_t length,
{
struct bt_gatt_client *client = user_data;
struct pdu_data pdu_data;
-#ifdef __TIZEN_PATCH__
- struct service_changed_op *sc_op;
+#ifdef __TIZEN_PATCH__
if (client->ready == false) {
struct noti *noti;
@@ -1834,15 +1833,6 @@ static void notify_cb(uint8_t opcode, const void *pdu, uint16_t length,
queue_foreach(client->notify_list, notify_handler, &pdu_data);
-#ifdef __TIZEN_PATCH__
- if (client->in_svc_chngd == false &&
- (sc_op = queue_pop_head(client->svc_chngd_queue))) {
- process_service_changed(client, sc_op->start_handle,
- sc_op->end_handle);
- free(sc_op);
- }
-#endif
-
if (opcode == BT_ATT_OP_HANDLE_VAL_IND)
bt_att_send(client->att, BT_ATT_OP_HANDLE_VAL_CONF, NULL, 0,
NULL, NULL, NULL);
@@ -2387,7 +2377,9 @@ static void read_long_cb(uint8_t opcode, const void *pdu,
goto done;
}
- if (opcode != BT_ATT_OP_READ_BLOB_RSP || (!pdu && length)) {
+ if ((!op->offset && opcode != BT_ATT_OP_READ_RSP)
+ || (op->offset && opcode != BT_ATT_OP_READ_BLOB_RSP)
+ || (!pdu && length)) {
success = false;
goto done;
}
@@ -2440,7 +2432,9 @@ unsigned int bt_gatt_client_read_long_value(struct bt_gatt_client *client,
{
struct request *req;
struct read_long_op *op;
+ uint8_t att_op;
uint8_t pdu[4];
+ uint16_t pdu_len;
if (!client)
return 0;
@@ -2464,12 +2458,32 @@ unsigned int bt_gatt_client_read_long_value(struct bt_gatt_client *client,
req->destroy = destroy_read_long_op;
put_le16(value_handle, pdu);
- put_le16(offset, pdu + 2);
+ pdu_len = sizeof(value_handle);
+
+ /*
+ * Core v4.2, part F, section 1.3.4.4.5:
+ * If the attribute value has a fixed length that is less than or equal
+ * to (ATT_MTU - 3) octets in length, then an Error Response can be sent
+ * with the error code «Attribute Not Long».
+ *
+ * To remove need for caller to handle "Attribute Not Long" error when
+ * reading characteristics with short values, use Read Request for
+ * reading first part of characteristics value instead of Read Blob
+ * Request. Both are allowed in this case.
+ */
+
+ if (op->offset) {
+ att_op = BT_ATT_OP_READ_BLOB_REQ;
+ pdu_len += sizeof(op->offset);
+
+ put_le16(op->offset, pdu + 2);
+ } else {
+ att_op = BT_ATT_OP_READ_REQ;
+ }
+
+ req->att_id = bt_att_send(client->att, att_op, pdu, pdu_len,
+ read_long_cb, req, request_unref);
- req->att_id = bt_att_send(client->att, BT_ATT_OP_READ_BLOB_REQ,
- pdu, sizeof(pdu),
- read_long_cb, req,
- request_unref);
if (!req->att_id) {
op->destroy = NULL;
request_unref(req);
@@ -3257,8 +3271,14 @@ unsigned int bt_gatt_client_register_notify(struct bt_gatt_client *client,
if (!client || !client->db || !chrc_value_handle || !callback)
return 0;
+#ifdef __TIZEN_PATCH__
+ if (client->in_svc_chngd)
+ util_debug(client->debug_callback, client->debug_data,
+ "register_notify in service changed handling");
+#else
if (client->in_svc_chngd)
return 0;
+#endif
return register_notify(client, chrc_value_handle, callback, notify,
user_data, destroy);
diff --git a/src/shared/gatt-db.c b/src/shared/gatt-db.c
index d741abcb..a3f1a480 100644
--- a/src/shared/gatt-db.c
+++ b/src/shared/gatt-db.c
@@ -1745,14 +1745,14 @@ bool get_ccc_notify_indicate(const struct gatt_db_attribute *ccc)
return false;
}
-void set_ccc_unicast_address(const struct gatt_db_attribute *ccc,
+void set_ccc_unicast_address(struct gatt_db_attribute *ccc,
const char *address)
{
if (ccc)
- str2ba(address, (bdaddr_t *)&ccc->unicast_addr);
+ str2ba(address, &ccc->unicast_addr);
}
-bdaddr_t *get_ccc_unicast_address(const struct gatt_db_attribute *ccc)
+const bdaddr_t *get_ccc_unicast_address(const struct gatt_db_attribute *ccc)
{
if (ccc)
return &ccc->unicast_addr;
diff --git a/src/shared/gatt-db.h b/src/shared/gatt-db.h
index 581b7d5b..8e9e5548 100644
--- a/src/shared/gatt-db.h
+++ b/src/shared/gatt-db.h
@@ -241,8 +241,8 @@ void set_ccc_notify_indicate(struct gatt_db_attribute *ccc,
bool get_ccc_notify_indicate(const struct gatt_db_attribute *ccc);
-void set_ccc_unicast_address(const struct gatt_db_attribute *ccc,
+void set_ccc_unicast_address(struct gatt_db_attribute *ccc,
const char *address);
-bdaddr_t *get_ccc_unicast_address(const struct gatt_db_attribute *ccc);
+const bdaddr_t *get_ccc_unicast_address(const struct gatt_db_attribute *ccc);
#endif
diff --git a/src/shared/gatt-server.c b/src/shared/gatt-server.c
index 127e45b9..64c400b1 100644
--- a/src/shared/gatt-server.c
+++ b/src/shared/gatt-server.c
@@ -180,7 +180,11 @@ static bool encode_read_by_grp_type_rsp(struct gatt_db *db, struct queue *q,
int iter = 0;
uint16_t start_handle, end_handle;
struct iovec value;
+#ifdef __TIZEN_PATCH__
+ uint8_t data_val_len = 0;
+#else
uint8_t data_val_len;
+#endif
*len = 0;
@@ -519,7 +523,11 @@ static bool encode_find_info_rsp(struct gatt_db *db, struct queue *q,
uint16_t handle;
struct gatt_db_attribute *attr;
const bt_uuid_t *type;
+#ifdef __TIZEN_PATCH__
+ int uuid_len = 0, cur_uuid_len;
+#else
int uuid_len, cur_uuid_len;
+#endif
int iter = 0;
*len = 0;
@@ -926,6 +934,12 @@ static void handle_read_req(struct bt_gatt_server *server, uint8_t opcode,
ecode = BT_ATT_ERROR_UNLIKELY;
error:
+#ifdef __TIZEN_PATCH__
+ util_debug(server->debug_callback, server->debug_data,
+ "Handling \"Read %sReq\" is failed : %d",
+ (opcode == BT_ATT_OP_READ_BLOB_REQ) ? "Blob" : "",
+ ecode);
+#endif
if (op)
async_read_op_destroy(op);
@@ -1223,6 +1237,9 @@ static void exec_next_prep_write(struct bt_gatt_server *server,
err = BT_ATT_ERROR_UNLIKELY;
error:
+ queue_remove_all(server->prep_queue, NULL, NULL,
+ prep_write_data_destroy);
+
bt_att_send_error_rsp(server->att, BT_ATT_OP_EXEC_WRITE_REQ,
ehandle, err);
}
@@ -1267,6 +1284,8 @@ static void exec_write_cb(uint8_t opcode, const void *pdu,
return;
error:
+ queue_remove_all(server->prep_queue, NULL, NULL,
+ prep_write_data_destroy);
bt_att_send_error_rsp(server->att, opcode, 0, ecode);
}