org.bluez.Error.NotSupported
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ void DisconnectExtProfile(object profile)
+
+ This method disconnects a specific profile of
+ this device. The profile needs to be added by
+ RegisterProfile method call.
+
+ This method could be used when multiple profiles with
+ same UUID are registered and it needs to disconnect one
+ of them.
+
+ There is no connection tracking for a profile, so
+ as long as the profile is registered this will always
+ succeed.
+
+ Possible errors: org.bluez.Error.Failed
+ org.bluez.Error.InProgress
+ org.bluez.Error.InvalidArguments
+ org.bluez.Error.NotSupported
+#endif
+
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
void Pair(uint8 conn_type)
#else
void Pair()
uint8_t res_support;
} __packed;
+#define MGMT_OP_SET_STREAMING_MODE (TIZEN_OP_CODE_BASE + 0x1b)
+struct mgmt_cp_set_streaming_mode {
+ uint8_t streaming_mode;
+ bdaddr_t bdaddr;
+} __packed;
+
/* BEGIN TIZEN_Bluetooth :: name update changes */
#define MGMT_EV_DEVICE_NAME_UPDATE (TIZEN_EV_BASE + 0x01)
struct mgmt_ev_device_name_update {
DBusMessageIter entry;
DBusError derr;
const char *name = NULL;
- struct message_folder *parent = {0,}, *child = {0,};
+ struct message_folder *parent = folder_tree, *child = NULL;
GSList *l;
- DBG("+\n");
+ DBG("+");
- for (l = folder_tree->subfolders; l != NULL; l = parent->subfolders)
+ for (l = folder_tree->subfolders; l != NULL; l = parent->subfolders) {
parent = l->data;
+ if (parent == NULL) {
+ error("folder list is corrupted");
+ dbus_message_unref(reply);
+ return;
+ }
+ }
- DBG("Last child folder = %s \n", parent->name);
+ DBG("Last child folder = %s", parent->name);
dbus_error_init(&derr);
if (dbus_set_error_from_message(&derr, reply)) {
dbus_message_iter_recurse(&iter_struct, &entry);
dbus_message_iter_get_basic(&entry, &name);
- DBG("Folder name = %s \n", name);
+ DBG("Folder name = %s", name);
child = create_folder(name);
parent->subfolders = g_slist_append(parent->subfolders,
child);
}
}
dbus_message_unref(reply);
- DBG("-\n");
+ DBG("-");
}
static void message_get_msg_list(DBusPendingCall *call, void *user_data)
struct session *session = user_data;
struct messages_message *data = g_new0(struct messages_message, 1);
- DBG("+\n");
+ DBG("+");
DBG("parameter_mask = %x; type = %d; period_begin = %s;"
"period_end = %s; read_status = %d; recipient = %s;"
"originator = %s; priority = %d",
continue;
}
- DBG("Msg handle = %s \n", msg_handle);
+ DBG("Msg handle = %s", msg_handle);
data->handle = g_strdup(msg_handle);
dbus_message_iter_next(&entry);
dbus_message_iter_get_basic(&entry, &subject);
if (mask & PMASK_SUBJECT) {
- DBG("subject = %s\n", subject);
+ DBG("subject = %s", subject);
data->subject = g_strndup(subject,
BT_MAP_LIST_ITEM_MAX_LEN);
data->mask |= PMASK_SUBJECT;
dbus_message_iter_get_basic(&entry, &datetime);
if ((mask & PMASK_DATETIME) && (NULL != datetime)) {
- DBG("datetime = %s\n", datetime);
+ DBG("datetime = %s", datetime);
char *begin = g_strdup(session->filter->period_begin);
char *end = g_strdup(session->filter->period_end);
char *time = g_strdup(datetime);
if ((mask & PMASK_SENDER_NAME) &&
(NULL != session->filter->originator)) {
- DBG("sender_name = %s \n", sender_name);
+ DBG("sender_name = %s", sender_name);
if (g_strstr_len(sender_name, -1,
session->filter->originator)) {
if ((mask & PMASK_SENDER_ADDRESSING) &&
(NULL != sender_addressing)) {
- DBG("sender_addressing = %s \n", sender_addressing);
+ DBG("sender_addressing = %s", sender_addressing);
data->sender_addressing = g_strndup(sender_addressing,
BT_MAP_LIST_ITEM_MAX_LEN);
if ((mask & PMASK_RECIPIENT_NAME) &&
(NULL != session->filter->recipient)) {
- DBG("recipient_name = %s \n", recipient_name);
+ DBG("recipient_name = %s", recipient_name);
if (g_strstr_len(recipient_name, -1,
session->filter->recipient)) {
if ((mask & PMASK_RECIPIENT_ADDRESSING) &&
(NULL != recipient_addressing)) {
- DBG("recipient_addressing=%s\n", recipient_addressing);
+ DBG("recipient_addressing=%s", recipient_addressing);
data->recipient_addressing =
g_strndup(recipient_addressing,
dbus_message_iter_get_basic(&entry, &type);
if ((mask & PMASK_TYPE) && (NULL != type)) {
- DBG("type = %s \n", type);
+ DBG("type = %s", type);
type_val = get_type_val(type);
if (!(session->filter->type & type_val)) {
dbus_message_iter_get_basic(&entry, &size);
if ((mask & PMASK_SIZE) && (NULL != size)) {
- DBG("size = %s \n", size);
+ DBG("size = %s", size);
data->size = g_strdup(size);
data->mask |= PMASK_SIZE;
dbus_message_iter_get_basic(&entry, &reception_status);
if (mask & PMASK_RECEPTION_STATUS) {
- DBG("reception_status = %s \n", reception_status);
+ DBG("reception_status = %s", reception_status);
data->reception_status = g_strdup(reception_status);
data->mask |= PMASK_RECEPTION_STATUS;
dbus_message_iter_get_basic(&entry, &text);
if (mask & PMASK_TEXT) {
- DBG("text = %d \n", text);
+ DBG("text = %d", text);
data->text = text;
data->mask |= PMASK_TEXT;
}
dbus_message_iter_get_basic(&entry, &attachment_size);
if (mask & PMASK_ATTACHMENT_SIZE) {
- DBG("attachment_size = %s\n", attachment_size);
+ DBG("attachment_size = %s", attachment_size);
data->attachment_size = g_strdup(attachment_size);
data->mask |= PMASK_ATTACHMENT_SIZE;
dbus_message_iter_get_basic(&entry, &priority);
if (mask & PMASK_PRIORITY) {
- DBG("priority = %d \n", priority);
+ DBG("priority = %d", priority);
priority_val = get_priority_val(priority);
if ((session->filter->priority == 0) ||
dbus_message_iter_get_basic(&entry, &read);
if (mask & PMASK_READ) {
- DBG("read = %d \n", read);
+ DBG("read = %d", read);
read_val = get_read_status_val(read);
dbus_message_iter_get_basic(&entry, &sent);
if (mask & PMASK_SENT) {
- DBG("sent = %d \n", sent);
+ DBG("sent = %d", sent);
data->sent = sent;
data->mask |= PMASK_SENT;
}
dbus_message_iter_get_basic(&entry, &protect);
if (mask & PMASK_PROTECTED) {
- DBG("protect = %d \n", protect);
+ DBG("protect = %d", protect);
data->protect = protect;
data->mask |= PMASK_PROTECTED;
}
if ((mask & PMASK_REPLYTO_ADDRESSING) &&
(0x04 == get_type_val(type))) {
- DBG("replyto_addressing = %s \n", replyto_addressing);
+ DBG("replyto_addressing = %s", replyto_addressing);
if (replyto_addressing)
data->replyto_addressing =
g_strdup(replyto_addressing);
g_free(session->name);
session_filter_free(session->filter);
dbus_message_unref(reply);
- DBG("-\n");
+ DBG("-");
}
static void message_get_msg(DBusPendingCall *call, void *user_data)
char *msg_body;
gboolean fraction_deliver;
- DBG("+\n");
+ DBG("+");
dbus_error_init(&derr);
if (dbus_set_error_from_message(&derr, reply)) {
dbus_message_iter_get_basic(&iter, &fraction_deliver);
dbus_message_iter_next(&iter);
dbus_message_iter_get_basic(&iter, &msg_body);
- DBG("msg_body %s\n", msg_body);
+ DBG("msg_body %s", msg_body);
session->get_msg_cb(session, -EAGAIN, fraction_deliver,
msg_body, session->user_data);
NULL, session->user_data);
}
dbus_message_unref(reply);
- DBG("-\n");
+ DBG("-");
}
int messages_connect(void **s)
DBusMessage *message;
DBusMessage *reply;
DBusError err;
- DBG("+\n");
+ DBG("+");
struct session *session = g_new0(struct session, 1);
QUERY_GET_FOLDER_TREE);
if (!message) {
error("Can't allocate new message");
+ g_free(session->cwd);
+ g_free(session);
+ *s = NULL;
return -1;
}
}
dbus_message_unref(message);
+
+ g_free(session->cwd);
+ g_free(session);
+ *s = NULL;
return -1;
}
message_get_folder_list(reply, session);
dbus_message_unref(message);
- DBG("-\n");
+ DBG("-");
return 0;
}
{
DBusMessage *message;
struct session *session = s;
- DBG("+\n");
+ DBG("+");
destroy_folder_tree(folder_tree);
folder_tree = NULL;
dbus_message_unref(message);
- DBG("-\n");
+ DBG("-");
}
static gboolean notification_registration(gpointer user_data)
{
- DBG("+\n");
+ DBG("+");
DBusMessage *message = NULL;
gboolean reg;
struct mns_reg_data *data = (struct mns_reg_data *)user_data;
goto done;
}
- DBG("data->notification_status = %d\n", data->notification_status);
+ DBG("data->notification_status = %d", data->notification_status);
if (data->notification_status == 1)
reg = TRUE;
g_free(data->remote_addr);
g_free(data);
- DBG("-\n");
+ DBG("-");
return FALSE;
}
char *address, uint8_t status,
void *user_data)
{
- DBG("+\n");
+ DBG("+");
struct mns_reg_data *data = g_new0(struct mns_reg_data, 1);
data->notification_status = status;
data->remote_addr = g_strdup(address);
- DBG("status = %d\n", status);
+ DBG("status = %d", status);
g_idle_add(notification_registration, data);
- DBG("-\n");
+ DBG("-");
return 1;
}
messages_folder_listing_cb callback,
void *user_data)
{
- DBG("+\n");
+ DBG("+");
struct session *session = s;
session->name = g_strdup(name);
session->max = max;
g_idle_add_full(G_PRIORITY_DEFAULT_IDLE, async_get_folder_listing,
session, NULL);
- DBG("-\n");
+ DBG("-");
return 0;
}
DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
- if (filter->parameter_mask)
+ if (s->filter->parameter_mask)
dict_append_entry(&dict, "ParameterMask", DBUS_TYPE_UINT32,
- &filter->parameter_mask);
- if (filter->type)
+ &s->filter->parameter_mask);
+ if (s->filter->type)
dict_append_entry(&dict, "FilterMessageType", DBUS_TYPE_BYTE,
- &filter->type);
- if (filter->period_begin)
+ &s->filter->type);
+ if (s->filter->period_begin)
dict_append_entry(&dict, "FilterPeriodBegin", DBUS_TYPE_STRING,
- &filter->period_begin);
- if (filter->period_end)
+ &s->filter->period_begin);
+ if (s->filter->period_end)
dict_append_entry(&dict, "FilterPeriodEnd", DBUS_TYPE_STRING,
- &filter->period_end);
- if (filter->read_status)
+ &s->filter->period_end);
+ if (s->filter->read_status)
dict_append_entry(&dict, "FilterReadStatus", DBUS_TYPE_BYTE,
- &filter->read_status);
- if (filter->recipient)
+ &s->filter->read_status);
+ if (s->filter->recipient)
dict_append_entry(&dict, "FilterRecipient", DBUS_TYPE_STRING,
- &filter->recipient);
- if (filter->originator)
+ &s->filter->recipient);
+ if (s->filter->originator)
dict_append_entry(&dict, "FilterOriginator", DBUS_TYPE_STRING,
- &filter->originator);
- if (filter->priority)
+ &s->filter->originator);
+ if (s->filter->priority)
dict_append_entry(&dict, "FilterPriority", DBUS_TYPE_BYTE,
- &filter->priority);
+ &s->filter->priority);
dbus_message_iter_close_container(&iter, &dict);
}
dbus_pending_call_set_notify(call, message_get_msg_list, s, NULL);
dbus_message_unref(message);
- DBG("-\n");
+ DBG("-");
return 1;
}
gchar *folder_path = NULL;
guint64 handle = 0;
- DBG("+\n");
+ DBG("+");
- DBG("session->cwd %s +\n", s->cwd);
+ DBG("session->cwd %s +", s->cwd);
if (g_ascii_strncasecmp(s->cwd, "/telecom/msg",
strlen("/telecom/msg")) != 0) {
if (!(retry & 0x1)) {
retry_send = FALSE;
- DBG("Retry send %d\n", retry_send);
+ DBG("Retry send %d", retry_send);
}
if (charset & 0x1) {
native = TRUE;
- DBG("native send %d\n", native);
+ DBG("native send %d", native);
}
- DBG("save_copy %d\n", save_copy);
- DBG("retry_send %d\n", retry_send);
- DBG("native %d\n", native);
+ DBG("save_copy %d", save_copy);
+ DBG("retry_send %d", retry_send);
+ DBG("native %d", native);
message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
BT_MAP_SERVICE_OBJECT_PATH,
if (!dbus_message_get_args(reply, &err, DBUS_TYPE_UINT64,
&handle, DBUS_TYPE_INVALID)) {
if (dbus_error_is_set(&err)) {
- error("err %s\n", err.message);
+ error("err %s", err.message);
dbus_error_free(&err);
}
g_free(folder_path);
return -1;
}
- DBG("uint64 handle %"G_GUINT64_FORMAT"\n", handle);
+ DBG("uint64 handle %"G_GUINT64_FORMAT"", handle);
s->push_msg_cb(s, 0, handle, s->user_data);
g_free(folder_path);
dbus_message_unref(message);
dbus_message_unref(reply);
- DBG("-\n");
+ DBG("-");
return 1;
}
{
DBusMessage *message;
- DBG("+\n");
+ DBG("+");
message = dbus_message_new_method_call(BT_MAP_SERVICE_NAME,
BT_MAP_SERVICE_OBJECT_PATH,
}
dbus_message_unref(message);
- DBG("-\n");
+ DBG("-");
return 1;
}
gboolean transcode = FALSE;
gboolean first_request = TRUE;
- DBG("+\n");
+ DBG("+");
if (NULL != handle) {
message_name = g_strdup(handle);
- DBG("Message handle = %s\n", handle);
+ DBG("Message handle = %s", handle);
} else {
return -1;
}
dbus_pending_call_set_notify(call, message_get_msg, s, NULL);
dbus_message_unref(message);
g_free(message_name);
- DBG("-\n");
+ DBG("-");
return 1;
}
DBusError derr;
struct session *session = user_data;
int err;
- DBG("+\n");
+ DBG("+");
dbus_error_init(&derr);
if (dbus_set_error_from_message(&derr, reply)) {
if (dbus_message_iter_get_arg_type(&iter) ==
DBUS_TYPE_INT32) {
dbus_message_iter_get_basic(&iter, &err);
- DBG("Error : %d\n", err);
+ DBG("Error : %d", err);
session->msg_update_cb(session, err,
session->user_data);
}
}
dbus_message_unref(reply);
- DBG("-\n");
+ DBG("-");
}
int messages_update_inbox(void *session,
DBusMessage *message;
struct session *s = session;
- DBG("+\n");
+ DBG("+");
s->msg_update_cb = callback;
s->user_data = user_data;
}
dbus_pending_call_set_notify(call, message_update_msg, s, NULL);
dbus_message_unref(message);
- DBG("-\n");
+ DBG("-");
return 1;
}
struct session *session = user_data;
int err;
- DBG("+\n");
+ DBG("+");
dbus_error_init(&derr);
if (dbus_set_error_from_message(&derr, reply)) {
if (dbus_message_iter_get_arg_type(&iter) ==
DBUS_TYPE_INT32) {
dbus_message_iter_get_basic(&iter, &err);
- DBG("Error : %d\n", err);
+ DBG("Error : %d", err);
session->msg_status_cb(session, err,
session->user_data);
}
}
dbus_message_unref(reply);
- DBG("-\n");
+ DBG("-");
}
int messages_set_read(void *session, const char *handle, uint8_t value,
char *message_name;
gboolean read;
- DBG("+\n");
+ DBG("+");
if (NULL == handle)
return -1;
- DBG("Message handle = %s\n", handle);
+ DBG("Message handle = %s", handle);
message_name = g_strdup(handle);
s->msg_status_cb = callback;
dbus_pending_call_set_notify(call, message_status_msg, s, NULL);
dbus_message_unref(message);
g_free(message_name);
- DBG("-\n");
+ DBG("-");
return 1;
}
char *message_name;
gboolean del;
- DBG("+\n");
+ DBG("+");
if (NULL == handle)
return -1;
- DBG("Message handle = %s\n", handle);
+ DBG("Message handle = %s", handle);
message_name = g_strdup(handle);
s->msg_status_cb = callback;
dbus_pending_call_set_notify(call, message_status_msg, s, NULL);
dbus_message_unref(message);
g_free(message_name);
- DBG("-\n");
+ DBG("-");
return 1;
}
--libexecdir=%{_libexecdir} \
--enable-debug \
--enable-pie \
- --enable-serial \
--enable-usb=no \
--enable-tools \
--disable-bccmd \
g_free(server);
return -1;
}
+
+/* Tizen doesn't support AVRCP BROWSING CHANNEL */
+#ifndef TIZEN_FEATURE_BLUEZ_MODIFY
server->browsing_io = avctp_server_socket(src, master, L2CAP_MODE_ERTM,
AVCTP_BROWSING_PSM);
if (!server->browsing_io) {
g_free(server);
return -1;
}
+#endif
server->adapter = btd_adapter_ref(adapter);
{
struct avdtp_stream *stream = sep->stream;
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ struct btd_adapter *adapter = device_get_adapter(session->device);
const bdaddr_t *dst;
- if (TIZEN_FEATURE_BLUEZ_SPRD_QOS)
- dst = device_get_address(session->device);
- else if (TIZEN_FEATURE_BLUEZ_BRCM_QOS || TIZEN_FEATURE_BLUEZ_ROLE_CHANGE)
- dst = device_get_address(session->device);
+
+ dst = device_get_address(session->device);
#endif
avdtp_state_t old_state;
struct avdtp_error err, *err_ptr = NULL;
if (TIZEN_FEATURE_BLUEZ_ROLE_CHANGE)
fix_role_to_master(dst, FALSE);
+
+ btd_adapter_set_streaming_mode(adapter, dst, FALSE);
#endif /* TIZEN_FEATURE_BLUEZ_MODIFY */
break;
case AVDTP_STATE_STREAMING:
}
if (TIZEN_FEATURE_BLUEZ_ROLE_CHANGE)
fix_role_to_master(dst, TRUE);
+
+ btd_adapter_set_streaming_mode(adapter, dst, TRUE);
#endif /* TIZEN_FEATURE_BLUEZ_MODIFY */
stream->open_acp = FALSE;
break;
DBG("Don't initiate avrcp connection with this headset");
return -ENOTSUP;
}
+
+ /* Device unpairing failed if AVRCP connection is triggered
+ during unpairing*/
+ if (device_is_temporary(dev))
+ return -EPERM;
#endif
return control_connect(service);
}
return NULL;
service = btd_device_get_service(device, HID_DEVICE_UUID);
- if (service == NULL)
- return NULL;
+ if (service == NULL) {
+ DBG("Service not found, Probe Hid device profile for device");
+ /* This will make sure we have hid device service for device */
+ device_probe_profiles(device, NULL);
+ service = btd_device_get_service(device, HID_DEVICE_UUID);
+ }
return btd_service_get_user_data(service);
}
int input_device_role_close_channels(const bdaddr_t *src, const bdaddr_t *dst)
{
- struct input_device *idev = find_device(src, dst);
+ struct input_device *idev = find_device_role(src, dst);
if (!idev)
return -ENOENT;
if (nc->state == CONNECTED)
bnep_disconnect(nc->session);
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ else {
+ /* In error case we need to free session */
+ DBG("Cancel Connection state %d", nc->state);
+ bnep_free(nc->session);
+ nc->session = NULL;
+ }
+#endif
#ifndef TIZEN_FEATURE_BLUEZ_MODIFY
bnep_free(nc->session);
dbus_bool_t enable = FALSE;
dbus_int32_t slot_id;
- DBG("adapter_set_advertising");
-
if (!(adapter->current_settings & MGMT_SETTING_POWERED))
return btd_error_not_ready(msg);
DBUS_TYPE_INVALID))
return btd_error_invalid_args(msg);
+ DBG("%s advertising slot_id %d", enable ? "Enable" : "Disable", slot_id);
+
if (adapter_le_is_supported_multi_advertising() && slot_id > 0)
err = adapter_le_enable_multi_adv(adapter, enable, slot_id);
else
{
struct btd_adapter *adapter = user_data;
const struct mgmt_rp_le_read_maximum_data_length *rp = param;
- uint16_t max_tx_octects, max_tx_time;
- uint16_t max_rx_octects, max_rx_time;
+ uint16_t max_tx_octects = 0;
+ uint16_t max_tx_time = 0;
+ uint16_t max_rx_octects = 0;
+ uint16_t max_rx_time = 0;
+ int err = 0;
if (!rp) {
error("Error ocurred in Reading maximum data length, rp is NULL");
- g_free(adapter->read_handler);
- return;
+ err = -EIO;
+ goto done;
}
if (status != MGMT_STATUS_SUCCESS) {
error("le read maximum data length failed: %s (0x%02x)",
mgmt_errstr(status), status);
- max_tx_octects = 0;
- max_tx_time =0;
- max_rx_octects = 0;
- max_rx_time = 0;
-
- g_free(adapter->read_handler);
- return;
+ err = -EIO;
+ goto done;
}
if (length < sizeof(*rp)) {
error("Too small le read maximum data length response");
- g_free(adapter->read_handler);
- return;
+ err = -EIO;
+ goto done;
} else {
max_tx_octects = rp->max_tx_octets;
max_tx_time =rp->max_tx_time;
max_rx_time = rp->max_rx_time;
}
+done:
if (!adapter->read_handler ||
!adapter->read_handler->read_callback) {
g_free(adapter->read_handler);
return;
}
- adapter->read_handler->read_callback(adapter,
+ adapter->read_handler->read_callback(adapter, err,
max_tx_octects, max_tx_time,
max_rx_octects, max_rx_time,
adapter->read_handler->user_data);
static void le_read_data_length_complete(
struct btd_adapter *adapter,
+ int err,
uint16_t max_tx_octects, uint16_t max_tx_time,
uint16_t max_rx_octects, uint16_t max_rx_time,
void *user_data)
struct le_data_length_read_request *read_request;
read_request = find_read_le_data_length_request(adapter);
+
if (!read_request)
return;
- reply = g_dbus_create_reply(read_request->msg,
- DBUS_TYPE_UINT16, &max_tx_octects,
- DBUS_TYPE_UINT16, &max_tx_time,
- DBUS_TYPE_UINT16, &max_rx_octects,
- DBUS_TYPE_UINT16, &max_rx_time,
- DBUS_TYPE_INVALID);
-
- if (!reply) {
- btd_error_failed(read_request->msg,
- "Failed to read max data length.");
- return;
+ if (err) {
+ DBG("Failed to read max data length. errno[%d]", err);
+ reply = btd_error_failed(read_request->msg,
+ "Failed to read max data length");
+ } else {
+ reply = g_dbus_create_reply(read_request->msg,
+ DBUS_TYPE_UINT16, &max_tx_octects,
+ DBUS_TYPE_UINT16, &max_tx_time,
+ DBUS_TYPE_UINT16, &max_rx_octects,
+ DBUS_TYPE_UINT16, &max_rx_time,
+ DBUS_TYPE_INVALID);
+
+ if (!reply) {
+ reply = btd_error_failed(read_request->msg,
+ "Failed to create reply.");
+ }
}
read_requests = g_slist_remove(read_requests, read_request);
return false;
}
+
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+int btd_adapter_set_streaming_mode(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, gboolean enable)
+{
+ struct mgmt_cp_set_streaming_mode cp;
+ char addr[18];
+
+ ba2str(bdaddr, addr);
+ DBG("hci%u device %s", adapter->dev_id, addr);
+
+ memset(&cp, 0, sizeof(cp));
+
+ cp.streaming_mode = enable ? 1 : 0;
+ bacpy(&cp.bdaddr, bdaddr);
+
+ if (mgmt_send(adapter->mgmt, MGMT_OP_SET_STREAMING_MODE,
+ adapter->dev_id, sizeof(cp), &cp,
+ NULL, NULL, NULL) > 0)
+ return 0;
+
+ return -EIO;
+}
+#endif
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,
+ int result,
const uint16_t max_txOctects,
const uint16_t max_txTime,
const uint16_t max_rxOctects,
int btd_adapter_le_set_data_length(struct btd_adapter *adapter, bdaddr_t *bdaddr,
uint16_t max_tx_octets, uint16_t max_tx_time);
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+
void adapter_check_version(struct btd_adapter *adapter, uint8_t hci_ver);
+
+int btd_adapter_set_streaming_mode(struct btd_adapter *adapter,
+ const bdaddr_t *bdaddr, gboolean enable);
+
#ifdef TIZEN_FEATURE_BLUEZ_BATTERY_WATCH
charging_state_e get_charging_state(struct btd_adapter *adapter);
#endif /* TIZEN_FEATURE_BLUEZ_BATTERY_WATCH */
return btd_error_failed(msg, strerror(-err));
}
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static DBusMessage *disconnect_ext_profile(DBusConnection *conn,
+ DBusMessage *msg, void *user_data)
+{
+ struct btd_device *dev = user_data;
+ struct btd_profile *profile;
+ struct btd_service *service;
+ const char *sender, *path;
+ GSList *l;
+ int err;
+
+ sender = dbus_message_get_sender(msg);
+
+ DBG("sender %s", sender);
+
+ if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path,
+ DBUS_TYPE_INVALID))
+ return btd_error_invalid_args(msg);
+
+ profile = btd_profile_find_ext(sender, path);
+ if (!profile)
+ return btd_error_invalid_args(msg);
+
+ l = find_service_with_profile(dev->services, profile);
+ if (!l)
+ return btd_error_invalid_args(msg);
+
+ service = l->data;
+
+ if (dev->disconnect)
+ return btd_error_in_progress(msg);
+
+ dev->disconnect = dbus_message_ref(msg);
+
+ err = btd_service_disconnect(service);
+ if (err == 0)
+ return NULL;
+
+ if (dev->disconnect)
+ dbus_message_unref(dev->disconnect);
+ dev->disconnect = NULL;
+
+ if (err == -ENOTSUP)
+ return btd_error_not_supported(msg);
+
+ return btd_error_failed(msg, strerror(-err));
+}
+#endif
+
static void store_services(struct btd_device *device)
{
struct btd_adapter *adapter = device->adapter;
if (!conn_info->io) {
error("OTC Connect failed : %s", gerr->message);
g_error_free(gerr);
- g_io_channel_unref(conn_info->io);
g_free(conn_info);
return -EIO;
}
if (!conn_info->io) {
error("OTC Listen failed : %s", gerr->message);
g_error_free(gerr);
+ g_free(conn_info);
return -EIO;
}
{ GDBUS_ASYNC_METHOD("DisconnectProfile", GDBUS_ARGS({ "UUID", "s" }),
NULL, disconnect_profile) },
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ { GDBUS_ASYNC_METHOD("DisconnectExtProfile",
+ GDBUS_ARGS({ "profile", "o" }), NULL,
+ disconnect_ext_profile) },
{ GDBUS_ASYNC_METHOD("Pair", GDBUS_ARGS({ "conn_type", "y" }), NULL,
pair_device) },
#else
str = g_key_file_get_string(key_file, "General", "ManufacturerData", NULL);
if (str) {
- load_manufacturer_data_2digit(str,
- device->manufacturer_data_len, buf);
- device->manufacturer_data = g_memdup(buf,
- device->manufacturer_data_len);
+ if (device->manufacturer_data_len < DEV_MAX_MANUFACTURER_DATA_LEN ) {
+ load_manufacturer_data_2digit(str,
+ device->manufacturer_data_len, buf);
+ device->manufacturer_data = g_memdup(buf,
+ device->manufacturer_data_len);
+ }
g_free(str);
}
}
bool chrcs_ready;
struct queue *pending_ext_props;
guint idle_id;
- guint idle_id2;
#endif
};
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
if (service->idle_id)
g_source_remove(service->idle_id);
-
- if (service->idle_id2)
- g_source_remove(service->idle_id2);
#endif
queue_remove_all(service->chrcs, NULL, NULL, unregister_characteristic);
}
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+static void notify_service_added(struct service *service)
+{
+ char *svc_path;
+
+ if (service == NULL) {
+ error("service is NULL");
+ return;
+ }
+
+ if (service->path == NULL) {
+ error("service->path is NULL");
+ return;
+ }
+ if (!service->chrcs_ready) {
+ error("service is not ready");
+ return;
+ }
+
+ svc_path = g_strdup(service->path);
+
+ g_dbus_emit_signal(btd_get_dbus_connection(), service->path,
+ GATT_SERVICE_IFACE, "GattServiceAdded",
+ DBUS_TYPE_STRING, &svc_path,
+ DBUS_TYPE_INVALID);
+
+ g_free(svc_path);
+
+ return;
+}
+#endif
+
static void notify_chrcs(struct service *service)
{
g_dbus_emit_property_changed(btd_get_dbus_connection(), service->path,
GATT_SERVICE_IFACE,
"Characteristics");
-}
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ if (service->primary == true) {
+ DBG("Notify Service Added");
+ notify_service_added(service);
+ }
#endif
+}
struct export_data {
void *root;
gatt_db_service_foreach_char(attr, export_char, &data);
- return !data.failed;
+ if (data.failed)
+ return false;
+
+ return true;
}
-#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
static gboolean set_chrcs_ready(gpointer user_data)
{
struct service *service = user_data;
return FALSE;
}
-static gboolean notify_service_added_complete(gpointer user_data)
-{
- struct service *service = user_data;
- char *svc_path;
-
- if (service == NULL || service->path == NULL)
- return FALSE;
-
- svc_path = g_strdup(service->path);
-
- g_dbus_emit_signal(btd_get_dbus_connection(), service->path,
- GATT_SERVICE_IFACE, "GattServiceAdded",
- DBUS_TYPE_STRING, &svc_path,
- DBUS_TYPE_INVALID);
-
- g_free(svc_path);
-
- return FALSE;
-}
-#endif
-
static void export_service(struct gatt_db_attribute *attr, void *user_data)
{
struct btd_gatt_client *client = user_data;
*/
if (!service->chrcs_ready && queue_isempty(service->pending_ext_props))
service->idle_id = g_idle_add(set_chrcs_ready, service);
-
- if (service->primary == true)
- service->idle_id2 = g_idle_add(notify_service_added_complete, service);
#endif
}
if (confirm) {
/* Send confirmation to application */
- if (g_dbus_proxy_method_call(confirm->proxy, "IndicateConfirm",
+ g_dbus_proxy_method_call(confirm->proxy, "IndicateConfirm",
indicate_confirm_setup_cb,
indicate_confirm_reply_cb, confirm->device,
- NULL) == TRUE)
- return;
+ NULL);
+ g_dbus_proxy_unref(confirm->proxy);
+ confirm->proxy = NULL;
}
#endif
}
return;
confirm = new0(struct notify_indicate_cb, 1);
- confirm->proxy = notify_indicate->proxy;
+ confirm->proxy = g_dbus_proxy_ref(notify_indicate->proxy);
confirm->device = device;
/*
* TODO: If the device is not connected but bonded, send the
<attribute id=\"0x0009\"> \
<sequence> \
<sequence> \
- <uuid value=\"0x0011\" /> \
- <uint16 value=\"0x0100\" /> \
+ <uuid value=\"0x1124\" /> \
+ <uint16 value=\"0x%04x\" /> \
</sequence> \
</sequence> \
</attribute> \
<attribute id=\"0x020b\"> \
<uint16 value=\"0x0100\" /> \
</attribute> \
+ <attribute id=\"0x020d\"> \
+ <boolean value=\"true\" /> \
+ </attribute> \
<attribute id=\"0x020e\"> \
<boolean value=\"true\" /> \
</attribute> \
return NULL;
}
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+struct btd_profile *btd_profile_find_ext(const char *owner, const char *path)
+{
+ struct ext_profile *ext;
+
+ if (!owner || !path)
+ return NULL;
+
+ ext = find_ext_profile(owner, path);
+ if (!ext)
+ return NULL;
+
+ return &ext->p;
+}
+#endif
+
static void ext_io_destroy(gpointer p)
{
struct ext_io *ext_io = p;
static char *get_hid_device_record(struct ext_profile *ext, struct ext_io *l2cap,
struct ext_io *rfcomm)
{
- return g_strdup(HID_DEVICE_RECORD);
+ return g_strdup_printf(HID_DEVICE_RECORD, ext->version);
}
#endif
#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
gboolean ext_profile_is_registered_as_client_role(struct btd_profile *p);
+struct btd_profile *btd_profile_find_ext(const char *owner, const char *path);
#endif
void btd_profile_init(void);
struct bt_gatt_client *client;
struct queue *pending_svcs;
struct queue *pending_chrcs;
- struct queue *svcs;
struct queue *ext_prop_desc;
struct gatt_db_attribute *cur_svc;
bool success;
uint16_t start;
uint16_t end;
uint16_t last;
+ uint16_t svc_first;
+ uint16_t svc_last;
int ref_count;
discovery_op_complete_func_t complete_func;
discovery_op_fail_func_t failure_func;
{
queue_destroy(op->pending_svcs, NULL);
queue_destroy(op->pending_chrcs, free);
- queue_destroy(op->svcs, NULL);
queue_destroy(op->ext_prop_desc, NULL);
free(op);
}
op = new0(struct discovery_op, 1);
op->pending_svcs = queue_new();
op->pending_chrcs = queue_new();
- op->svcs = queue_new();
op->ext_prop_desc = queue_new();
op->client = client;
op->complete_func = complete_func;
struct discovery_op *op = user_data;
struct bt_gatt_client *client = op->client;
struct bt_gatt_iter iter;
- struct gatt_db_attribute *attr, *tmp;
+ struct gatt_db_attribute *attr;
uint16_t handle, start, end;
uint128_t u128;
bt_uuid_t uuid;
goto failed;
}
- /* Get the currently processed service */
- attr = op->cur_svc;
- if (!attr)
- goto failed;
-
if (!result || !bt_gatt_iter_init(&iter, result))
goto failed;
"handle: 0x%04x, start: 0x%04x, end: 0x%04x,"
"uuid: %s", handle, start, end, uuid_str);
- tmp = gatt_db_get_attribute(client->db, start);
- if (!tmp)
+ attr = gatt_db_get_attribute(client->db, start);
+ if (!attr)
goto failed;
- tmp = gatt_db_service_add_included(attr, tmp);
- if (!tmp)
+ attr = gatt_db_insert_included(client->db, handle, attr);
+ if (!attr)
goto failed;
/*
* these entries, the correct handle must be assigned to the new
* attribute.
*/
- if (gatt_db_attribute_get_handle(tmp) != handle)
+ if (gatt_db_attribute_get_handle(attr) != handle)
goto failed;
}
next:
- /* Move on to the next service */
- attr = queue_pop_head(op->pending_svcs);
- if (!attr) {
- /*
- * We have processed all include definitions. Move on to
- * characteristics.
- */
- attr = queue_pop_head(op->svcs);
- if (!attr)
- goto failed;
-
- if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
- goto failed;
-
- op->cur_svc = attr;
-
- client->discovery_req = bt_gatt_discover_characteristics(
- client->att,
- start, end,
+ client->discovery_req = bt_gatt_discover_characteristics(client->att,
+ op->svc_first,
+ op->svc_last,
discover_chrcs_cb,
discovery_op_ref(op),
discovery_op_unref);
- if (client->discovery_req)
- return;
-
- util_debug(client->debug_callback, client->debug_data,
- "Failed to start characteristic discovery");
- discovery_op_unref(op);
- goto failed;
- }
-
- queue_push_tail(op->svcs, attr);
- op->cur_svc = attr;
- if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
- goto failed;
-
- if (start == end)
- goto next;
-
- client->discovery_req = bt_gatt_discover_included_services(client->att,
- start, end,
- discover_incl_cb,
- discovery_op_ref(op),
- discovery_op_unref);
if (client->discovery_req)
return;
util_debug(client->debug_callback, client->debug_data,
- "Failed to start included discovery");
+ "Failed to start characteristic discovery");
discovery_op_unref(op);
-
failed:
discovery_op_complete(op, false, att_ecode);
}
*discovering = false;
while ((chrc_data = queue_pop_head(op->pending_chrcs))) {
- attr = gatt_db_service_insert_characteristic(op->cur_svc,
+ struct gatt_db_attribute *svc;
+ uint16_t start, end;
+
+ attr = gatt_db_insert_characteristic(client->db,
chrc_data->value_handle,
&chrc_data->uuid, 0,
chrc_data->properties,
chrc_data->value_handle)
goto failed;
+ /* Adjust current service */
+ svc = gatt_db_get_service(client->db, chrc_data->value_handle);
+ if (op->cur_svc != svc) {
+ queue_remove(op->pending_svcs, svc);
+
+ /* Done with the current service */
+ gatt_db_service_set_active(op->cur_svc, true);
+ op->cur_svc = svc;
+ }
+
+ gatt_db_attribute_get_service_handles(svc, &start, &end);
+
+ /*
+ * Ajust end_handle in case the next chrc is not within the
+ * same service.
+ */
+ if (chrc_data->end_handle > end)
+ chrc_data->end_handle = end;
+
/*
* check for descriptors presence, before initializing the
* desc_handle and avoid integer overflow during desc_handle
free(chrc_data);
continue;
}
+
desc_start = chrc_data->value_handle + 1;
client->discovery_req = bt_gatt_discover_descriptors(
struct bt_gatt_client *client = op->client;
bool discovering;
struct gatt_db_attribute *desc_attr = NULL;
- struct gatt_db_attribute *next_srv;
- uint16_t start, end;
util_debug(client->debug_callback, client->debug_data,
"Ext. prop value: 0x%04x", (uint16_t)value[0]);
if (read_ext_prop_desc(op))
return;
- /* Continue with discovery */
- do {
- if (!discover_descs(op, &discovering))
- goto failed;
-
- if (discovering)
- return;
-
- /* Done with the current service */
- gatt_db_service_set_active(op->cur_svc, true);
-
- next_srv = queue_pop_head(op->svcs);
- if (!next_srv)
- goto done;
-
- if (!gatt_db_attribute_get_service_handles(next_srv, &start,
- &end))
- goto failed;
-
- } while (start == end);
-
- /* Move on to the next service */
- op->cur_svc = next_srv;
+ if (!discover_descs(op, &discovering))
+ goto failed;
- client->discovery_req = bt_gatt_discover_characteristics(client->att,
- start, end,
- discover_chrcs_cb,
- discovery_op_ref(op),
- discovery_op_unref);
- if (client->discovery_req)
+ if (discovering)
return;
- util_debug(client->debug_callback, client->debug_data,
- "Failed to start characteristic discovery");
-
- discovery_op_unref(op);
+ /* Done with the current service */
+ gatt_db_service_set_active(op->cur_svc, true);
+ goto done;
failed:
success = false;
struct bt_gatt_client *client = op->client;
struct bt_gatt_iter iter;
struct gatt_db_attribute *attr;
- uint16_t handle, start, end;
+ uint16_t handle;
uint128_t u128;
bt_uuid_t uuid;
char uuid_str[MAX_LEN_UUID_STR];
"handle: 0x%04x, uuid: %s",
handle, uuid_str);
- attr = gatt_db_service_insert_descriptor(op->cur_svc, handle,
+ attr = gatt_db_insert_descriptor(client->db, handle,
&uuid, 0, NULL, NULL,
NULL);
- if (!attr)
+ if (!attr) {
+ util_debug(client->debug_callback, client->debug_data,
+ "Failed to insert descriptor at 0x%04x",
+ handle);
goto failed;
+ }
if (gatt_db_attribute_get_handle(attr) != handle)
goto failed;
/* Done with the current service */
gatt_db_service_set_active(op->cur_svc, true);
- attr = queue_pop_head(op->svcs);
- if (!attr)
- goto done;
-
- if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
- goto failed;
-
- if (start == end)
- goto next;
-
- /* Move on to the next service */
- op->cur_svc = attr;
-
- client->discovery_req = bt_gatt_discover_characteristics(client->att,
- start, end,
- discover_chrcs_cb,
- discovery_op_ref(op),
- discovery_op_unref);
- if (client->discovery_req)
- return;
-
- util_debug(client->debug_callback, client->debug_data,
- "Failed to start characteristic discovery");
- discovery_op_unref(op);
+ goto done;
failed:
success = false;
struct discovery_op *op = user_data;
struct bt_gatt_client *client = op->client;
struct bt_gatt_iter iter;
- struct gatt_db_attribute *attr;
struct chrc *chrc_data;
uint16_t start, end, value;
uint8_t properties;
goto done;
}
- if (!op->cur_svc || !result || !bt_gatt_iter_init(&iter, result))
+ if (!result || !bt_gatt_iter_init(&iter, result))
goto failed;
chrc_count = bt_gatt_result_characteristic_count(result);
/* Done with the current service */
gatt_db_service_set_active(op->cur_svc, true);
- attr = queue_pop_head(op->svcs);
- if (!attr)
- goto done;
-
- if (!gatt_db_attribute_get_service_handles(attr, &start, &end))
- goto failed;
-
- if (start == end)
- goto next;
-
- /* Move on to the next service */
- op->cur_svc = attr;
-
- client->discovery_req = bt_gatt_discover_characteristics(client->att,
- start, end,
- discover_chrcs_cb,
- discovery_op_ref(op),
- discovery_op_unref);
- if (client->discovery_req)
- return;
-
- util_debug(client->debug_callback, client->debug_data,
- "Failed to start characteristic discovery");
- discovery_op_unref(op);
+ goto done;
failed:
success = false;
discovery_op_complete(op, success, att_ecode);
}
+static void discovery_found_service(struct discovery_op *op,
+ struct gatt_db_attribute *attr,
+ uint16_t start, uint16_t end)
+{
+ /* Skip if service already active */
+ if (!gatt_db_service_get_active(attr)) {
+ queue_push_tail(op->pending_svcs, attr);
+
+ /* Update discovery range */
+ if (!op->svc_first || op->svc_first > start)
+ op->svc_first = start;
+ if (op->svc_last < end)
+ op->svc_last = end;
+ }
+
+ /* Update last handle */
+ if (end > op->last)
+ op->last = end;
+}
+
static void discover_secondary_cb(bool success, uint8_t att_ecode,
struct bt_gatt_result *result,
void *user_data)
}
}
- /* 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;
+ /* Update pending list */
+ discovery_found_service(op, attr, start, end);
}
next:
- /* Sequentially discover included services */
- attr = queue_pop_head(op->pending_svcs);
-
- /* Complete with success if queue is empty */
- if (!attr) {
- success = true;
- goto done;
- }
-
- /*
- * Store the service in the svcs queue to be reused during
- * characteristics discovery later.
- */
- queue_push_tail(op->svcs, attr);
- op->cur_svc = attr;
-
- if (!gatt_db_attribute_get_service_handles(attr, &start, &end)) {
- success = false;
- goto done;
- }
-
client->discovery_req = bt_gatt_discover_included_services(client->att,
- start, end,
+ op->svc_first,
+ op->svc_last,
discover_incl_cb,
discovery_op_ref(op),
discovery_op_unref);
}
}
- /* 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;
+ /* Update pending list */
+ discovery_found_service(op, attr, start, end);
}
secondary:
}
struct gatt_db_attribute *
+gatt_db_insert_characteristic(struct gatt_db *db,
+ uint16_t handle,
+ const bt_uuid_t *uuid,
+ uint32_t permissions,
+ uint8_t properties,
+ gatt_db_read_t read_func,
+ gatt_db_write_t write_func,
+ void *user_data)
+{
+ struct gatt_db_attribute *attrib;
+
+ attrib = gatt_db_get_service(db, handle);
+ if (!attrib)
+ return NULL;
+
+ return service_insert_characteristic(attrib->service, handle, uuid,
+ permissions, properties,
+ read_func, write_func,
+ user_data);
+}
+
+struct gatt_db_attribute *
gatt_db_service_insert_characteristic(struct gatt_db_attribute *attrib,
uint16_t handle,
const bt_uuid_t *uuid,
}
struct gatt_db_attribute *
+gatt_db_insert_descriptor(struct gatt_db *db,
+ uint16_t handle,
+ const bt_uuid_t *uuid,
+ uint32_t permissions,
+ gatt_db_read_t read_func,
+ gatt_db_write_t write_func,
+ void *user_data)
+{
+ struct gatt_db_attribute *attrib;
+
+ attrib = gatt_db_get_service(db, handle);
+ if (!attrib)
+ return NULL;
+
+ return service_insert_descriptor(attrib->service, handle, uuid,
+ permissions, read_func, write_func,
+ user_data);
+}
+
+struct gatt_db_attribute *
gatt_db_service_insert_descriptor(struct gatt_db_attribute *attrib,
uint16_t handle,
const bt_uuid_t *uuid,
user_data);
}
-struct gatt_db_attribute *
-gatt_db_service_add_included(struct gatt_db_attribute *attrib,
+static struct gatt_db_attribute *
+service_insert_included(struct gatt_db_service *service, uint16_t handle,
struct gatt_db_attribute *include)
{
- struct gatt_db_service *service, *included;
+ struct gatt_db_service *included;
uint8_t value[MAX_INCLUDED_VALUE_LEN];
uint16_t included_handle, len = 0;
int index;
- if (!attrib || !include)
- return NULL;
-
- service = attrib->service;
included = include->service;
/* Adjust include to point to the first attribute */
if (!index)
return NULL;
- service->attributes[index] = new_attribute(service, 0,
+ /* Check if handle is in within service range */
+ if (handle && handle <= service->attributes[0]->handle)
+ return NULL;
+
+ if (!handle)
+ handle = get_handle_at_index(service, index - 1) + 1;
+
+ service->attributes[index] = new_attribute(service, handle,
&included_service_uuid,
value, len);
if (!service->attributes[index])
return attribute_update(service, index);
}
+struct gatt_db_attribute *
+gatt_db_service_add_included(struct gatt_db_attribute *attrib,
+ struct gatt_db_attribute *include)
+{
+ if (!attrib || !include)
+ return NULL;
+
+ return service_insert_included(attrib->service, 0, include);
+}
+
+struct gatt_db_attribute *
+gatt_db_service_insert_included(struct gatt_db_attribute *attrib,
+ uint16_t handle,
+ struct gatt_db_attribute *include)
+{
+ if (!attrib || !handle || !include)
+ return NULL;
+
+ return service_insert_included(attrib->service, handle, include);
+}
+
+struct gatt_db_attribute *
+gatt_db_insert_included(struct gatt_db *db, uint16_t handle,
+ struct gatt_db_attribute *include)
+{
+ struct gatt_db_attribute *attrib;
+
+ attrib = gatt_db_get_service(db, handle);
+ if (!attrib)
+ return NULL;
+
+ return service_insert_included(attrib->service, handle, include);
+}
+
bool gatt_db_service_set_active(struct gatt_db_attribute *attrib, bool active)
{
struct gatt_db_service *service;
return (start <= handle) && (handle <= end);
}
-struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db,
+struct gatt_db_attribute *gatt_db_get_service(struct gatt_db *db,
uint16_t handle)
{
struct gatt_db_service *service;
- int i;
if (!db || !handle)
return NULL;
service = queue_find(db->services, find_service_for_handle,
- UINT_TO_PTR(handle));
+ UINT_TO_PTR(handle));
if (!service)
return NULL;
+ return service->attributes[0];
+}
+
+struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db,
+ uint16_t handle)
+{
+ struct gatt_db_attribute *attrib;
+ struct gatt_db_service *service;
+ int i;
+
+ attrib = gatt_db_get_service(db, handle);
+ if (!attrib)
+ return NULL;
+
+ service = attrib->service;
+
for (i = 0; i < service->num_handles; i++) {
if (!service->attributes[i])
continue;
void *user_data);
struct gatt_db_attribute *
+gatt_db_insert_characteristic(struct gatt_db *db,
+ uint16_t handle,
+ const bt_uuid_t *uuid,
+ uint32_t permissions,
+ uint8_t properties,
+ gatt_db_read_t read_func,
+ gatt_db_write_t write_func,
+ void *user_data);
+
+struct gatt_db_attribute *
+gatt_db_insert_descriptor(struct gatt_db *db,
+ uint16_t handle,
+ const bt_uuid_t *uuid,
+ uint32_t permissions,
+ gatt_db_read_t read_func,
+ gatt_db_write_t write_func,
+ void *user_data);
+
+struct gatt_db_attribute *
gatt_db_service_add_descriptor(struct gatt_db_attribute *attrib,
const bt_uuid_t *uuid,
uint32_t permissions,
void *user_data);
struct gatt_db_attribute *
+gatt_db_insert_included(struct gatt_db *db, uint16_t handle,
+ struct gatt_db_attribute *include);
+
+struct gatt_db_attribute *
gatt_db_service_add_included(struct gatt_db_attribute *attrib,
struct gatt_db_attribute *include);
+struct gatt_db_attribute *
+gatt_db_service_insert_included(struct gatt_db_attribute *attrib,
+ uint16_t handle,
+ struct gatt_db_attribute *include);
bool gatt_db_service_set_active(struct gatt_db_attribute *attrib, bool active);
bool gatt_db_service_get_active(struct gatt_db_attribute *attrib);
gatt_db_destroy_func_t destroy);
bool gatt_db_unregister(struct gatt_db *db, unsigned int id);
+struct gatt_db_attribute *gatt_db_get_service(struct gatt_db *db,
+ uint16_t handle);
+
struct gatt_db_attribute *gatt_db_get_attribute(struct gatt_db *db,
uint16_t handle);
case 's':
command = SPLIT;
input_path = optarg;
+ break;
#endif
case 't':
type = optarg;
len = write_n(fd, buf, frm.data_len + hdr_size);
if (len < 0) {
perror("Write error");
+ close(fd);
return -1;
}
written += len;
"AMP Status Change",
};
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+#define LE_EV_NUM 11
+#else
#define LE_EV_NUM 5
+#endif
static char *ev_le_meta_str[LE_EV_NUM + 1] = {
"Unknown",
"LE Connection Complete",
"LE Connection Update Complete",
"LE Read Remote Used Features Complete",
"LE Long Term Key Request",
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ "LE Remote Connection Parameter Request",
+ "LE Data Length Change",
+ "LE Read Local P-256 Public Key Complete",
+ "LE Generate DHKey Complete",
+ "LE Enhanced Connection Complete",
+ "LE Direct Advertising Report",
+#endif
};
#define CMD_LINKCTL_NUM 60
frm->len -= EVT_LE_META_EVENT_SIZE;
p_indent(level, frm);
+#ifdef TIZEN_FEATURE_BLUEZ_MODIFY
+ if (subevent <= LE_EV_NUM)
+ printf("%s\n", ev_le_meta_str[subevent]);
+ else
+ printf("%s\n", ev_le_meta_str[0]);
+#else
printf("%s\n", ev_le_meta_str[subevent]);
+#endif
switch (mevt->subevent) {
case EVT_LE_CONN_COMPLETE: