static int get_remote_service_record(bt_bdaddr_t *remote_addr, bt_uuid_t *uuid)
{
return BT_STATUS_UNSUPPORTED;
-
}
static int get_remote_services(bt_bdaddr_t *remote_addr)
{
- return BT_STATUS_UNSUPPORTED;
+ if (!remote_addr) {
+ ERR("Invalid param");
+ return BT_STATUS_PARM_INVALID;
+ }
+ return _bt_hal_dbus_get_remote_device_services(remote_addr);
}
static int start_discovery(void)
#include <termios.h>
#include <fcntl.h>
#include <unistd.h>
+#include <arpa/inet.h>
#include <dlog.h>
#include <dbus/dbus-glib-lowlevel.h>
}
void _bt_convert_uuid_string_to_type(unsigned char *uuid,
- const char *device_uuid)
+ const char *device_uuid)
{
- int i;
- int k = 0;
- uint8_t temp[2];
- uint8_t temp1[1];
+ uint32_t uuid0, uuid4;
+ uint16_t uuid1, uuid2, uuid3, uuid5;
- if (uuid == NULL || device_uuid == NULL)
- return;
- for (i = 0; i < 36; ) {
- if (device_uuid[i] != '\0') {
- if (device_uuid[i] == '-') {
- i = i+1;
- continue;
- }
- temp[0] = device_uuid[i];
- temp[1] = device_uuid[i+ 1];
- sscanf((char*)temp, "%hhx", temp1); //hexadecimal scanf format for uint8_t
- uuid[k] = temp1[0];
- i = i + 2;
- k++;
- }
- }
+ sscanf(device_uuid, "%08x-%04hx-%04hx-%04hx-%08x%04hx",
+ &uuid0, &uuid1, &uuid2, &uuid3, &uuid4, &uuid5);
+
+ uuid0 = htonl(uuid0);
+ uuid1 = htons(uuid1);
+ uuid2 = htons(uuid2);
+ uuid3 = htons(uuid3);
+ uuid4 = htonl(uuid4);
+ uuid5 = htons(uuid5);
+
+ memcpy(&(uuid[0]), &uuid0, 4);
+ memcpy(&(uuid[4]), &uuid1, 2);
+ memcpy(&(uuid[6]), &uuid2, 2);
+ memcpy(&(uuid[8]), &uuid3, 2);
+ memcpy(&(uuid[10]), &uuid4, 4);
+ memcpy(&(uuid[14]), &uuid5, 2);
+
+ return;
}
void _bt_convert_addr_string_to_type(unsigned char *addr,
static void __bt_hal_unbond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
gpointer user_data);
+static void __bt_hal_device_service_search_cb(GDBusProxy *proxy, GAsyncResult *res,
+ gpointer user_data);
+int __bt_hal_dbus_enquire_remote_device_services(char *address);
+
+static void __bt_device_parse_services(GVariant *result);
int _bt_hal_device_create_bond(const bt_bdaddr_t *bd_addr, unsigned short transport)
{
return BT_STATUS_SUCCESS;
}
+int _bt_hal_dbus_get_remote_device_services(const bt_bdaddr_t *remote_addr)
+{
+ char *device_path = NULL;
+ GDBusProxy *device_proxy = NULL;
+ GDBusConnection *conn;
+ GDBusProxy *adapter_proxy;
+ //char address[BT_HAL_ADDRESS_STRING_SIZE] = { 0 };
+ char *address = NULL;
+ int result = BT_STATUS_SUCCESS;
+ DBG("+");
+
+ address = g_malloc0(BT_HAL_ADDRESS_STRING_SIZE);
+
+ _bt_convert_addr_type_to_string(address, remote_addr->address);
+
+ if (remote_addr == NULL) {
+ result = BT_STATUS_PARM_INVALID;
+ goto fail;
+ }
+
+ adapter_proxy = _bt_get_adapter_proxy();
+ if (adapter_proxy == NULL) {
+ result = BT_STATUS_FAIL;
+ goto fail;
+ }
+
+ conn = _bt_get_system_gconn();
+ if (conn == NULL) {
+ ERR("Could not get System DBUS Connection");
+ result = BT_STATUS_FAIL;
+ goto fail;
+ }
+
+ device_path = _bt_get_device_object_path(address);
+
+ if (device_path == NULL) {
+ ERR("Remote device is not paired..can not perform SDP!!!");
+ result = BT_STATUS_FAIL;
+ goto fail;
+ }
+
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL, BT_HAL_BLUEZ_NAME,
+ device_path, BT_HAL_DEVICE_INTERFACE, NULL, NULL);
+ g_free(device_path);
+
+ if (device_proxy == NULL) {
+ ERR("Could not create Device Proxy");
+ result = BT_STATUS_FAIL;
+ goto fail;
+ }
+
+
+ g_dbus_proxy_call(device_proxy, "DiscoverServices",
+ g_variant_new("(s)", ""),
+ G_DBUS_CALL_FLAGS_NONE,
+ BT_HAL_MAX_DBUS_TIMEOUT,
+ NULL,
+ (GAsyncReadyCallback)__bt_hal_device_service_search_cb,
+ address);
+
+ return BT_STATUS_SUCCESS;
+
+fail:
+ g_free(address);
+ return result;
+}
+
+static void __bt_hal_device_service_search_cb(GDBusProxy *proxy, GAsyncResult *res,
+ gpointer user_data)
+{
+ /* Buffer and propety count management */
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
+ struct hal_ev_remote_device_props *ev = (void*) buf;;
+ size_t size = 0;
+
+ GError *err = NULL;
+ int result = BT_HAL_ERROR_NONE;
+ char *address = (char*) user_data;
+ DBG("+");
+
+ g_dbus_proxy_call_finish(proxy, res, &err);
+
+ g_object_unref(proxy);
+
+ /* Check event pointer */
+ if (!event_cb)
+ event_cb = _bt_hal_get_stack_message_handler();
+ if (!event_cb) {
+ ERR("event_cb is NULL, can not send Service search results to HAL User");
+ goto cleanup;
+ }
+
+ if (err != NULL) {
+ g_dbus_error_strip_remote_error(err);
+ ERR("Error occured in Proxy call [%s]\n", err->message);
+
+ if (g_strrstr("Operation canceled", err->message)) {
+ result = BT_HAL_ERROR_CANCEL_BY_USER;
+ } else if (g_strrstr("In Progress", err->message)) {
+ result = BT_HAL_ERROR_IN_PROGRESS;
+ } else if (g_strrstr("Host is down", err->message)) {
+ result = BT_HAL_ERROR_HOST_DOWN;
+ } else {
+ result = BT_HAL_ERROR_CONNECTION_ERROR;
+ }
+
+ if (result == BT_HAL_ERROR_HOST_DOWN ||
+ result == BT_HAL_ERROR_CONNECTION_ERROR) {
+ ERR("Service search has failed due to Host Down or connection error, attempt to find properties");
+ if (__bt_hal_dbus_enquire_remote_device_services(address) == BT_STATUS_SUCCESS)
+ goto cleanup;
+
+ }
+ goto done;
+ }
+
+ DBG("SDP is successful..lets fetch the device properties..");
+ if (__bt_hal_dbus_enquire_remote_device_services(address) == BT_STATUS_SUCCESS)
+ goto cleanup;
+done:
+ ev->status = BT_STATUS_FAIL;
+ ev->num_props = 0;
+ size = sizeof(*ev);
+ ERR("Error: Failed to get Remote device properties after SDP,"
+ " Num Prop [%d] total size [%d]",ev->num_props, size);
+ event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
+
+cleanup:
+ if (err)
+ g_error_free(err);
+ g_free(address);
+}
+
+static void __bt_device_parse_services(GVariant *result)
+{
+ /* Buffer and propety count management */
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
+ struct hal_ev_remote_device_props *ev = (void*) buf;;
+ size_t size = 0;
+
+ GVariantIter *property_iter;
+
+ const gchar *key;
+ GVariant *value;
+ const gchar *address = NULL;
+
+ memset(buf, 0, sizeof(buf));
+ size = sizeof(*ev);
+ ev->num_props = 0;
+ ev->status = BT_STATUS_SUCCESS;
+
+ g_variant_get(result, "(a{sv})", &property_iter);
+ while (g_variant_iter_loop(property_iter, "{sv}", &key, &value)) {
+ if (!g_strcmp0(key, "Address")) {
+ address = g_variant_get_string(value, NULL);
+ DBG("Address [%s]", address);
+ _bt_convert_addr_string_to_type(ev->bdaddr, address);
+ } else if (!g_strcmp0(key, "UUIDs")) {
+ char **uuid_value;
+ int uuid_count = 0;
+ gsize size1 = 0;
+ int i =0;
+ size1 = g_variant_get_size(value);
+ int num_props_tmp = ev->num_props;
+ if (size1 > 0) {
+ uuid_value = (char **)g_variant_get_strv(value, &size1);
+ for (i = 0; uuid_value[i] != NULL; i++)
+ uuid_count++;
+ /* UUID collection */
+ uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
+ for (i = 0; uuid_value[i] != NULL; i++) {
+ char *uuid_str = NULL;
+ uint8_t uuid[BT_HAL_STACK_UUID_SIZE];
+ memset(uuid, 0x00, BT_HAL_STACK_UUID_SIZE);
+ uuid_str = g_strdup(uuid_value[i]);
+ DBG("UUID string [%s]\n", uuid_str);
+ _bt_convert_uuid_string_to_type(uuid, uuid_str);
+ memcpy(uuids + i * BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
+ }
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_UUIDS,
+ (BT_HAL_STACK_UUID_SIZE * uuid_count), uuids);
+ ev->num_props = num_props_tmp + 1;
+ g_free(uuid_value);
+ }
+ } else {
+ ERR("Unhandled Property:[%s]", key);
+ }
+ }
+
+ DBG("Send Remote Device services to HAL,"
+ " Num Prop [%d] total size [%d]",ev->num_props, size);
+ event_cb(HAL_EV_REMOTE_DEVICE_PROPS, (void*) buf, size);
+
+ g_variant_unref(result);
+}
+
+int __bt_hal_dbus_enquire_remote_device_services(char *address)
+{
+ char *device_path = NULL;
+ GError *error = NULL;
+ GDBusProxy *device_proxy;
+ GDBusConnection *conn;
+ GVariant *result;
+
+ device_path = _bt_get_device_object_path(address);
+ if (!device_path) {
+ ERR("Device not paired");
+ return BT_STATUS_FAIL;
+ }
+
+ conn = _bt_get_system_gconn();
+ if (!conn) {
+ ERR("_bt_get_system_gconn failed");
+ return BT_STATUS_FAIL;
+ }
+
+ device_proxy = g_dbus_proxy_new_sync(conn, G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ BT_HAL_BLUEZ_NAME,
+ device_path,
+ BT_HAL_PROPERTIES_INTERFACE,
+ NULL, NULL);
+
+ if (!device_proxy) {
+ ERR("Error creating device_proxy");
+ g_free(device_path);
+ return BT_STATUS_FAIL;
+ }
+
+ result = g_dbus_proxy_call_sync(device_proxy,
+ "GetAll",
+ g_variant_new("(s)", BT_HAL_DEVICE_INTERFACE),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (!result) {
+ ERR("Error occured in Proxy call");
+ if (error != NULL) {
+ ERR("Error occured in Proxy call (Error: %s)", error->message);
+ g_clear_error(&error);
+ }
+ g_object_unref(device_proxy);
+ g_free(device_path);
+ return BT_STATUS_FAIL;
+ }
+
+ g_object_unref(device_proxy);
+ g_free(device_path);
+
+ /* Fetch Device Services and send to HAL User */
+ __bt_device_parse_services(result);
+
+ DBG("-");
+ return BT_STATUS_SUCCESS;
+}
+
static void __bt_hal_bond_device_cb(GDBusProxy *proxy, GAsyncResult *res,
gpointer user_data)
{
int _bt_hal_device_ssp_reply(const bt_bdaddr_t *bd_addr, bt_ssp_variant_t variant,
uint8_t accept, uint32_t passkey);
+
+int _bt_hal_dbus_get_remote_device_services(const bt_bdaddr_t *remote_addr);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
DBG("##UUID string [%s]\n", uuid_str);
_bt_convert_uuid_string_to_type(uuid, uuid_str);
memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
+ g_free(uuid_str);
}
size += __bt_insert_hal_properties(buf + size, HAL_PROP_ADAPTER_UUIDS,
(BT_HAL_STACK_UUID_SIZE * uuid_count),
{
/* UUID collection */
int i;
+#ifdef __TEST_
int z;
+#endif
int num_props_tmp = ev->num_props;
uint8_t uuids[BT_HAL_STACK_UUID_SIZE * uuid_count];
DBG("UUID string [%s]\n", uuid_str);
_bt_convert_uuid_string_to_type(uuid, uuid_str);
-
+#ifdef __TEST_
for(z=0; z < 16; z++)
DBG("[0x%x]", uuid[z]);
+#endif
memcpy(uuids+i*BT_HAL_STACK_UUID_SIZE, uuid, BT_HAL_STACK_UUID_SIZE);
g_free(uuid_str);
}
case BT_PROPERTY_UUIDS: {
uuids = (service_uuid_t *)properties[i].val;
+ BT_DBG("Length of properties from HAL [%d]", properties[i].len);
uuid_count = properties[i].len/sizeof(bt_uuid_t);
table_len += uuid_count;
for(; tmp_uuid_cnt < table_len; tmp_uuid_cnt++) {
oal_status_t device_destroy_bond(bt_address_t * addr);
/**
+ * @brief Request services supported by remote device
+ *
+ * @details List of services in form UUIDs will be provided in event data
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre Adapter must be enabled with adapter_enable() followed by OAL_EVENT_ADAPTER_ENABLED
+ *
+ * @see OAL_EVENT_DEVICE_SERVICES
+ * @see event_dev_services_t
+ */
+oal_status_t device_query_services(bt_address_t * addr);
+
+/**
+ * @brief Cancel already in-progress SDP procedure
+ *
+ * @details Based on current progress different events can be recieved.
+ *
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre SDP must be in progress by calling device_query_services()
+ *
+ */
+oal_status_t device_stop_query_sevices(bt_address_t * addr);
+
+/**
* @brief Accept PIN request as part of Bonding procedure
*
* @details Positive response to OAL_EVENT_DEVICE_PIN_REQUEST
return OAL_STATUS_SUCCESS;
}
+oal_status_t device_query_services(bt_address_t * addr)
+{
+ int res;
+ bdstr_t bdstr;
+
+ CHECK_OAL_INITIALIZED();
+
+ OAL_CHECK_PARAMETER(addr, return);
+
+ API_TRACE("[%s]", bdt_bd2str(addr, &bdstr));
+
+ res = blued_api->get_remote_services((bt_bdaddr_t *)addr);
+ if (res != BT_STATUS_SUCCESS) {
+ BT_ERR("get_remote_services error: [%s]", status2string(res));
+ return convert_to_oal_status(res);
+ }
+
+ return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t device_stop_query_sevices(bt_address_t * addr)
+{
+ CHECK_OAL_INITIALIZED();
+
+ OAL_CHECK_PARAMETER(addr, return);
+
+ API_TRACE("Stop SDP search");
+ /* Currently no HAL Interface for Stopping Service Search */
+ return BT_STATUS_UNSUPPORTED;
+}
+
oal_status_t device_set_alias(bt_address_t * addr, char * alias)
{
int res;
case BT_PROPERTY_UUIDS: {
event_dev_services_t *services_info;
bt_uuid_t *uuids = (bt_uuid_t *) properties[0].val;
+ BT_INFO("Properties len [%d] event structure size [%d]", properties[0].len, sizeof(event_dev_services_t));
services_info = g_malloc(sizeof(event_dev_services_t) + properties[0].len);
services_info->address = dev_info->address;
memcpy(services_info->service_list, uuids, properties[0].len);
services_info->num = properties[0].len/sizeof(bt_uuid_t);
+ BT_INFO("Number of UUID [%d]", services_info->num);
event = OAL_EVENT_DEVICE_SERVICES;
event_data = services_info;
size = sizeof(event_dev_services_t) + properties[0].len;
result = _bt_cancel_bonding();
break;
}
+ case BT_SEARCH_SERVICE: {
+ bluetooth_device_address_t address = { {0} };
+ __bt_service_get_parameters(in_param1,
+ &address, sizeof(bluetooth_device_address_t));
+ result = _bt_search_device(&address);
+ /* Save invocation */
+ if (result == BLUETOOTH_ERROR_NONE) {
+ char * addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+ _bt_convert_addr_type_to_string(addr, address.addr);
+ BT_DBG("BT Device Service Search Request scheduled successfully! save invocation context");
+ sender = (char*)g_dbus_method_invocation_get_sender(context);
+ _bt_save_invocation_context(context, result, sender,
+ function_name, (gpointer)addr);
+ } else
+ g_array_append_vals(*out_param1, &address,
+ sizeof(bluetooth_device_address_t));
+ break;
+ }
+ case BT_CANCEL_SEARCH_SERVICE: {
+ result = _bt_cancel_search_device();
+ break;
+ }
case BT_PASSKEY_REPLY: {
const char *passkey = NULL;
gboolean authentication_reply = FALSE;
addr[3], addr[4], addr[5]);
}
+gboolean _bt_compare_adddress(const bluetooth_device_address_t *addr1,
+ const bluetooth_device_address_t *addr2)
+{
+ if (memcmp(&addr1->addr, &addr2->addr, 6) == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
void _bt_print_device_address_t(const bluetooth_device_address_t *addr)
{
BT_INFO("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n",
for (i=0; i < dev_info->uuid_count; i++) {
dev_info->uuids[i] = g_malloc0(BLUETOOTH_UUID_STRING_MAX);
_bt_uuid_to_string((service_uuid_t *)&oal_device->uuid[i].uuid, dev_info->uuids[i]);
- BT_DBG("UUID size=%d value=%s", sizeof(dev_info->uuids[i]), dev_info->uuids[i]);
+ BT_DBG("[%s]", dev_info->uuids[i]);
}
BT_INFO("-");
dev->service_index = 0;
BT_DBG("Total UUID count [%d]", info->uuid_count);
for (i = 0; i < info->uuid_count; i++) {
- BT_DBG("UUID count [%d]", i);
g_strlcpy(dev->uuids[i], uuids[i], BLUETOOTH_UUID_STRING_MAX);
parts = g_strsplit(uuids[i], "-", -1);
case OAL_EVENT_DEVICE_PASSKEY_CONFIRMATION_REQUEST:
case OAL_EVENT_DEVICE_PASSKEY_DISPLAY:
case OAL_EVENT_DEVICE_SSP_CONSENT_REQUEST:
+ case OAL_EVENT_DEVICE_SERVICES:
if (device_cb)
device_cb(event_type, event_data);
break;
bt_remote_dev_info_t *dev_info;
} bt_bond_data_t;
+/* Searching Info structure */
+typedef struct {
+ int result;
+ char *addr;
+ gboolean is_cancelled_by_user;
+ bluetooth_device_address_t *dev_addr;
+ bt_remote_dev_info_t *dev_info;
+} bt_service_search_info_data_t;
+
/* Pairing Info structure */
typedef struct {
char *addr;
bt_bond_data_t *trigger_bond_info;
bt_bond_data_t *trigger_unbond_info;
bt_pairing_data_t *trigger_pairing_info;
-
+bt_service_search_info_data_t *service_search_info;
typedef enum {
BT_DEVICE_BOND_STATE_NONE,
static int __bt_device_handle_bond_state(void);
static void __bt_free_bond_info(uint8_t type);
+static void __bt_free_service_search_info(bt_service_search_info_data_t **p_info);
static void __bt_device_handle_bond_completion_event(bt_address_t *bd_addr);
static void __bt_device_handle_bond_removal_event(bt_address_t *bd_addr);
static void __bt_device_handle_bond_failed_event(event_dev_bond_failed_t* bond_fail_event);
static void __bt_device_ssp_passkey_confirmation_callback(event_dev_passkey_t *dev_info);
static void __bt_device_ssp_passkey_entry_callback(remote_device_t* dev_info);
+static void __bt_device_services_callback(event_dev_services_t* uuid_list);
+static void __bt_handle_ongoing_device_service_search(bt_remote_dev_info_t *remote_dev_info);
+
void _bt_device_state_handle_callback_set_request(void)
{
_bt_service_register_event_handler_callback(
switch (service_function) {
case BT_BOND_DEVICE:
+ case BT_SEARCH_SERVICE:
case BT_UNBOND_DEVICE: {
char *address = (char *)user_data;
if (strncmp((char*)req_info->user_data, address, BT_ADDRESS_STRING_SIZE)) {
}
_bt_copy_remote_device(rem_info, &dev_info);
+#ifdef __TEST_
_bt_service_print_dev_info(&dev_info);
+#endif
/* Check if app has requested for device info for already bonded devices */
__bt_device_handle_pending_requests(result, BT_GET_BONDED_DEVICES,
__bt_handle_ongoing_bond(trigger_bond_info->dev_info);
}
+ /* Handle SDP Device properties update */
+ if (service_search_info && service_search_info->dev_info) {
+ if (!strcmp(service_search_info->addr, rem_info->address)) {
+ BT_DBG("Properties received and SDP request pending, fill device properties and send event");
+ service_search_info->dev_info->class = rem_info->class;
+ service_search_info->dev_info->paired = rem_info->paired;
+ service_search_info->dev_info->connected = rem_info->connected;
+ service_search_info->dev_info->rssi = rem_info->rssi;
+ service_search_info->dev_info->addr_type = rem_info->addr_type;
+ service_search_info->dev_info->trust = rem_info->trust;
+
+ /* TODO*/
+ service_search_info->dev_info->manufacturer_data = NULL;
+ service_search_info->dev_info->manufacturer_data_len = 0;
+
+ __bt_handle_ongoing_device_service_search(service_search_info->dev_info);
+ }
+ }
+
+ BT_DBG("-");
+}
+
+static void __bt_handle_ongoing_device_service_search(bt_remote_dev_info_t *remote_dev_info)
+{
+ GVariant *param = NULL;
+ GVariant *uuids = NULL;
+ GVariantBuilder *builder = NULL;
+ GVariant *manufacturer_data;
+ int i = 0;
+ BT_INFO("Send Service Search request event");
+
+ builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+ for (i=0; i < remote_dev_info->uuid_count; i++) {
+ g_variant_builder_add(builder, "s",
+ remote_dev_info->uuids[i]);
+ }
+ uuids = g_variant_new("as", builder);
+ g_variant_builder_unref(builder);
+ manufacturer_data = g_variant_new_from_data((const GVariantType *)"ay",
+ remote_dev_info->manufacturer_data, remote_dev_info->manufacturer_data_len,
+ TRUE, NULL, NULL);
+
+ param = g_variant_new("(isunsbub@asn@ay)",
+ BLUETOOTH_ERROR_NONE,
+ remote_dev_info->address,
+ remote_dev_info->class,
+ remote_dev_info->rssi,
+ remote_dev_info->name,
+ remote_dev_info->paired,
+ remote_dev_info->connected,
+ remote_dev_info->trust,
+ uuids,
+ remote_dev_info->manufacturer_data_len,
+ manufacturer_data);
+ /* Send the event to application */
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_SERVICE_SEARCHED,
+ param);
+
+ __bt_free_service_search_info(&service_search_info);
+ BT_DBG("-");
+}
+
+static void __bt_device_services_callback(event_dev_services_t* uuid_list)
+{
+ bt_remote_dev_info_t *rem_info = NULL;
+ int i;
+ BT_DBG("+");
+
+ if (service_search_info == NULL) {
+ /* Send reply */
+ BT_DBG("searching_info == NULL");
+ return;
+ }
+
+ if (_bt_compare_adddress(service_search_info->dev_addr,
+ (bluetooth_device_address_t *)&uuid_list->address) == FALSE) {
+ BT_DBG("This device is not queried");
+ return;
+ }
+
+ rem_info = g_malloc0(sizeof(bt_remote_dev_info_t));
+ memset(rem_info, 0x00, sizeof(bt_remote_dev_info_t));
+
+ rem_info->address = g_new0(char, BT_ADDRESS_STRING_SIZE);
+ _bt_convert_addr_type_to_string(rem_info->address, uuid_list->address.addr);
+
+ rem_info->uuid_count = uuid_list->num;
+
+ BT_INFO("Address [%s]", rem_info->address);
+ BT_INFO("Number of UUID's [%d]", rem_info->uuid_count);
+ if (rem_info->uuid_count > 0)
+ rem_info->uuids = g_new0(char *, rem_info->uuid_count);
+
+ /* Fill Remote Device Service List list */
+ for (i=0; i < rem_info->uuid_count; i++) {
+ rem_info->uuids[i] = g_malloc0(BLUETOOTH_UUID_STRING_MAX);
+ _bt_uuid_to_string((service_uuid_t *)&uuid_list->service_list[i].uuid, rem_info->uuids[i]);
+ BT_DBG("UUID value=%s", rem_info->uuids[i]);
+ }
+
+ BT_DBG("DBUS return");
+ __bt_device_handle_pending_requests(BLUETOOTH_ERROR_NONE, BT_SEARCH_SERVICE,
+ service_search_info->addr, BT_ADDRESS_STRING_SIZE);
+
+ /* Save UUID List of remote devices */
+ service_search_info->dev_info = rem_info;
+
+ /* Query Other device properties */
+ if (_bt_device_get_bonded_device_info(service_search_info->dev_addr) == BLUETOOTH_ERROR_NONE) {
+ BT_DBG("Bonded device info query posted to stack successfully");
+ } else {
+ BT_DBG("Possibly internal stack error in bonded device info query, perform cleanup");
+ __bt_free_service_search_info(&service_search_info);
+ }
BT_DBG("-");
}
__bt_device_ssp_consent_callback((remote_device_t*)event_data);
break;
}
+ case OAL_EVENT_DEVICE_SERVICES: {
+ BT_INFO("Remote Device Services Received");
+ __bt_device_services_callback((event_dev_services_t*)event_data);
+ break;
+ }
default:
BT_INFO("Unhandled event..");
}
}
}
+static void __bt_free_service_search_info(bt_service_search_info_data_t **p_info)
+{
+ bt_service_search_info_data_t * info = *p_info;
+ if (info) {
+ if (info->addr) {
+ g_free(info->addr);
+ info->addr = NULL;
+ }
+
+ if (info->dev_addr) {
+ g_free(info->dev_addr);
+ info->dev_addr = NULL;
+ }
+
+ if (info->dev_info) {
+ _bt_free_device_info(info->dev_info);
+ info->dev_info = NULL;
+ }
+
+ g_free(info);
+ }
+ *p_info = NULL;
+}
+
static int __bt_device_handle_bond_state(void)
{
BT_INFO("Current Bond state: %d", bt_device_bond_state);
ret_if (trigger_bond_info == NULL);
trigger_bond_info->is_autopair = is_autopair;
}
+
+int _bt_search_device(bluetooth_device_address_t *device_address)
+{
+ int result = OAL_STATUS_SUCCESS;
+ BT_DBG("+");
+
+ BT_CHECK_PARAMETER(device_address, return);
+
+ if (trigger_bond_info) {
+ BT_ERR("Bonding in progress");
+ return BLUETOOTH_ERROR_DEVICE_BUSY;
+ }
+
+ if (service_search_info) {
+ BT_ERR("Service searching in progress");
+ return BLUETOOTH_ERROR_DEVICE_BUSY;
+ }
+
+ /* allocate user data so that it can be retrieved in callback */
+ service_search_info = g_malloc0(sizeof(bt_service_search_info_data_t));
+ service_search_info->addr = g_malloc0(BT_ADDRESS_STRING_SIZE);
+ service_search_info->dev_addr = g_memdup(device_address, sizeof(bluetooth_device_address_t));
+
+ _bt_convert_addr_type_to_string(service_search_info->addr,
+ device_address->addr);
+
+ result = device_query_services((bt_address_t *)device_address);
+
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("Device Service Search Failed..: %d", result);
+ __bt_free_service_search_info(&service_search_info);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+ return BLUETOOTH_ERROR_NONE;
+}
+
+int _bt_cancel_search_device(void)
+{
+ int ret = OAL_STATUS_SUCCESS;
+ retv_if(service_search_info == NULL, BLUETOOTH_ERROR_NOT_IN_OPERATION);
+
+ ret = device_stop_query_sevices((bt_address_t *)service_search_info->dev_addr);
+
+ if (ret != OAL_STATUS_SUCCESS) {
+ BT_ERR("SDP Cancel request failed [%d]", ret);
+ return BLUETOOTH_ERROR_INTERNAL;
+ }
+
+ __bt_device_handle_pending_requests(BLUETOOTH_ERROR_CANCEL_BY_USER, BT_SEARCH_SERVICE,
+ service_search_info->addr, BT_ADDRESS_STRING_SIZE);
+
+ __bt_free_service_search_info(&service_search_info);
+
+ return BLUETOOTH_ERROR_NONE;
+ BT_DBG("-");
+}
int _bt_byte_arr_cmp_with_mask(const char *data1, const char *data2,
const char *mask, int data_len);
+gboolean _bt_compare_adddress(const bluetooth_device_address_t *addr1,
+ const bluetooth_device_address_t *addr2);
+
void _bt_print_device_address_t(const bluetooth_device_address_t *addr);
void _bt_divide_device_class(bluetooth_device_class_t *device_class,
gboolean _bt_device_is_pairing(void);
+int _bt_cancel_search_device(void);
+
+int _bt_search_device(bluetooth_device_address_t *device_address);
+
gboolean _bt_is_bonding_device_address(const char *address);
void _bt_set_autopair_status_in_bonding_info(gboolean is_autopair);