BT_PROPERTY_MODALIAS,
/**
+ * Description - BLE Device manufacturer data length
+ * Access mode - GET
+ * Data type - uint32_t
+ */
+ BT_PROPERTY_REMOTE_DEVICE_MANUFACTURER_DATA_LEN,
+
+ /**
+ * Description - BLE Device manufacturer data
+ * Access mode - GET
+ * Data type - Array of character string
+ */
+ BT_PROPERTY_REMOTE_DEVICE_MANUFACTURER_DATA,
+
+ /**
+ * Description - Remote BLE advertising data
+ * Access mode - Only received during device found callback.
+ * Data type - Array of uint8_t of remote BLE adv data.
+ * (Array size inferred from property length).
+ */
+ BT_PROPERTY_REMOTE_BLE_ADV_DATA,
+
+ /**
* Description - Local LE features
* Access mode - GET.
* Data type - bt_local_le_features_t.
#define HAL_PROP_ADAPTER_BONDED_DEVICES 0x08
#define HAL_PROP_ADAPTER_DISC_TIMEOUT 0x09
-#define HAL_PROP_ADAPTER_LOCAL_LE_FEAT 0x15
#define HAL_PROP_DEVICE_NAME 0x01
#define HAL_PROP_DEVICE_ADDR 0x02
#define HAL_PROP_ADAPTER_IPSP_INITIALIZED 0x13
#define HAL_PROP_ADAPTER_MODALIAS 0x14
+#define HAL_PROP_DEVICE_MANUFACTURER_DATA_LEN 0x15
+#define HAL_PROP_DEVICE_MANUFACTURER_DATA 0x16
+#define HAL_PROP_DEVICE_BLE_ADV_DATA 0x18
+#define HAL_PROP_ADAPTER_LOCAL_LE_FEAT 0x19
+
struct hal_prop_device_info {
uint8_t version;
uint16_t sub_version;
#include <bt-hal-adapter-dbus-handler.h>
#include <bt-hal-dbus-common-utils.h>
-#define BT_MAX_PROPERTY_BUF_SIZE 1024
#define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
#define BT_CORE_NAME "org.projectx.bt_core"
#define BT_CORE_PATH "/org/projectx/bt_core"
return BT_STATUS_SUCCESS;
}
+int _bt_hal_dbus_start_discovery(void)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result;
+ DBG("+");
+
+ proxy = _bt_get_adapter_proxy();
+ if (!proxy) {
+ DBG("_bt_hal_dbus_start_discovery: Adapter proxy get failed!!!");
+ return BT_STATUS_FAIL;
+ }
+
+ result = g_dbus_proxy_call_sync(proxy,
+ "StartDiscovery",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (!result) {
+ if (error != NULL) {
+ ERR("StartDiscovery failed (Error: %s)", error->message);
+ g_clear_error(&error);
+ } else
+ ERR("StartDiscovery failed");
+ return BT_STATUS_FAIL;
+ }
+
+ /* discovery status will be change in event */
+ DBG("-");
+ g_variant_unref(result);
+ return BT_STATUS_SUCCESS;
+}
+
+int _bt_hal_dbus_stop_discovery(void)
+{
+ GDBusProxy *proxy;
+ GError *error = NULL;
+ GVariant *result;
+ DBG("+");
+
+ proxy = _bt_get_adapter_proxy();
+ if (!proxy) {
+ DBG("_bt_hal_dbus_stop_discovery: Adapter proxy get failed!!!");
+ return BT_STATUS_FAIL;
+ }
+
+ result = g_dbus_proxy_call_sync(proxy,
+ "StopDiscovery",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ NULL,
+ &error);
+
+ if (!result) {
+ if (error != NULL) {
+ ERR("StopDiscovery failed (Error: %s)", error->message);
+ g_clear_error(&error);
+ } else
+ ERR("StopDiscovery failed");
+ return BT_STATUS_FAIL;
+ }
+
+ /* discovery status will be change in event */
+ DBG("-");
+ g_variant_unref(result);
+ return BT_STATUS_SUCCESS;
+}
+
static void ___bt_fill_le_supported_features(const char *item,
const char *value, uint8_t *le_features)
{
GVariant *value;
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;
size_t size = 0;
gchar *address = NULL;
static gboolean __bt_adapter_discovery_timeout_cb(gpointer user_data)
{
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;;
size_t size = 0;
unsigned int *timeout = user_data;
static gboolean __bt_adapter_scan_mode_cb(gpointer user_data)
{
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;;
size_t size = 0;
int *mode = user_data;
static gboolean __bt_adapter_local_version_cb(gpointer user_data)
{
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;;
size_t size = 0;
char *version = NULL;
static gboolean __bt_adapter_local_name_cb(gpointer user_data)
{
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;;
size_t size = 0;
char *name = NULL;
static gboolean __bt_adapter_local_address_cb(gpointer user_data)
{
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;
size_t size = 0;
char * address = NULL;
gchar *uuid_str;
/* Buffer and propety count management */
- uint8_t buf[BT_MAX_PROPERTY_BUF_SIZE];
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
struct hal_ev_adapter_props_changed *ev = (void*) buf;
size_t size = 0;
int _bt_hal_dbus_disable_adapter(void);
+int _bt_hal_dbus_start_discovery(void);
+
+int _bt_hal_dbus_stop_discovery(void);
+
int _bt_hal_dbus_get_adapter_property(bt_property_type_t type);
int _bt_hal_dbus_get_adapter_properties(void);
/* Forward declarations */
static void __bt_adapter_props_to_hal(bt_property_t *send_props, struct hal_property *prop, uint8_t num_props, uint16_t len);
+static void __bt_device_props_to_hal(bt_property_t *send_props,
+ struct hal_property *prop, uint8_t num_props,
+ uint16_t len);
static void __bt_hal_handle_adapter_state_changed(void *buf, uint16_t len);
static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len);
static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len);
+static void __bt_hal_handle_adapter_discovery_state_changed(void *buf, uint16_t len);
+static void __bt_hal_handle_device_found_event(void *buf, uint16_t len);
static bool interface_ready(void)
{
static int start_discovery(void)
{
- return BT_STATUS_UNSUPPORTED;
+ return _bt_hal_dbus_start_discovery();
}
static int cancel_discovery(void)
{
- return BT_STATUS_UNSUPPORTED;
+ return _bt_hal_dbus_stop_discovery();
}
static int create_bond(const bt_bdaddr_t *bd_addr, int transport)
return;
}
+static void __bt_device_props_to_hal(bt_property_t *send_props,
+ struct hal_property *prop, uint8_t num_props,
+ uint16_t len)
+{
+ void *buf = prop;
+ uint8_t i;
+
+ DBG("+");
+
+ for (i = 0; i < num_props; i++) {
+
+ if (sizeof(*prop) + prop->len > len) {
+ ERR("invalid device properties (%zu > %u), cant process further properties!!!",
+ sizeof(*prop) + prop->len, len);
+ return;
+ }
+
+ send_props[i].type = prop->type;
+
+ DBG("HAL prop Type [%d]", prop->type);
+
+ switch (prop->type) {
+ case HAL_PROP_DEVICE_TYPE:
+ {
+ DBG("Device property:HAL_PROP_DEVICE_TYPE:");
+ enum_prop_to_hal(send_props[i], prop,
+ bt_device_type_t);
+ break;
+ }
+ case HAL_PROP_DEVICE_VERSION_INFO:
+ {
+ DBG("Device property: HAL_PROP_DEVICE_VERSION_INFO");
+ static bt_remote_version_t e;
+ const struct hal_prop_device_info *p;
+ send_props[i].val = &e;
+ send_props[i].len = sizeof(e);
+ p = (struct hal_prop_device_info *) prop->val;
+ e.manufacturer = p->manufacturer;
+ e.sub_ver = p->sub_version;
+ e.version = p->version;
+ break;
+ }
+ case HAL_PROP_DEVICE_SERVICE_REC:
+ {
+ DBG("Device property: HAL_PROP_DEVICE_SERVICE_REC");
+ static bt_service_record_t e;
+ const struct hal_prop_device_service_rec *p;
+ send_props[i].val = &e;
+ send_props[i].len = sizeof(e);
+ p = (struct hal_prop_device_service_rec *) prop->val;
+ memset(&e, 0, sizeof(e));
+ memcpy(&e.channel, &p->channel, sizeof(e.channel));
+ memcpy(e.uuid.uu, p->uuid, sizeof(e.uuid.uu));
+ memcpy(e.name, p->name, p->name_len);
+ break;
+ }
+ default:
+ send_props[i].len = prop->len;
+ send_props[i].val = prop->val;
+ break;
+ }
+
+ DBG("prop[%d]: %s", i, btproperty2str(&send_props[i]));
+ len -= sizeof(*prop) + prop->len;
+ buf += sizeof(*prop) + prop->len;
+ prop = buf;
+
+ }
+
+ if (!len) {
+ DBG("-");
+ return;
+ }
+
+ ERR("invalid device properties (%u bytes left), ", len);
+}
+
static void __bt_hal_handle_adapter_property_changed(void *buf, uint16_t len)
{
struct hal_ev_adapter_props_changed *ev = (struct hal_ev_adapter_props_changed *)buf;
bt_hal_cbacks->adapter_properties_cb(ev->status, ev->num_props, props);
}
+static void __bt_hal_handle_adapter_discovery_state_changed(void *buf, uint16_t len)
+{
+ struct hal_ev_discovery_state_changed *ev = (struct hal_ev_discovery_state_changed *)buf;
+
+ DBG("+");
+
+ if (bt_hal_cbacks->discovery_state_changed_cb)
+ bt_hal_cbacks->discovery_state_changed_cb(ev->state);
+}
+
+static void __bt_hal_handle_device_found_event(void *buf, uint16_t len)
+{
+ struct hal_ev_device_found *ev = (struct hal_ev_device_found *) buf;
+ bt_property_t props[ev->num_props];
+ DBG("+");
+
+ if (!bt_hal_cbacks->device_found_cb)
+ return;
+
+ len -= sizeof(*ev);
+ __bt_device_props_to_hal(props, ev->props, ev->num_props, len);
+
+ bt_hal_cbacks->device_found_cb(ev->num_props, props);
+}
+
static void __bt_hal_handle_stack_messages(int message, void *buf, uint16_t len)
{
DBG("+");
DBG("Event: HAL_EV_ADAPTER_PROPS_CHANGED");
__bt_hal_handle_adapter_property_changed(buf, len);
break;
+ case HAL_EV_DISCOVERY_STATE_CHANGED:
+ DBG("Event: HAL_EV_DISCOVERY_STATE_CHANGED");
+ __bt_hal_handle_adapter_discovery_state_changed(buf, len);
+ break;
+ case HAL_EV_DEVICE_FOUND:
+ DBG("Event: HAL_EV_DEVICE_FOUND");
+ __bt_hal_handle_device_found_event(buf, len);
default:
DBG("Event Currently not handled!!");
break;
const char *device_uuid)
{
int i;
+ int k = 0;
uint8_t temp[2];
uint8_t temp1[1];
if (uuid == NULL || device_uuid == NULL)
return;
-
- int k=0;
-
for (i = 0; i < 36; ) {
-
if (device_uuid[i] != '\0') {
if (device_uuid[i] == '-') {
i = i+1;
"the reply timeout expired, or the network connection " \
"was broken."
+#define BT_HAL_DISCOVERY_FINISHED_DELAY 200
+
#define BT_HAL_ADDRESS_LENGTH_MAX 6
#define BT_HAL_ADDRESS_STRING_SIZE 18
#define BT_HAL_LOWER_ADDRESS_LENGTH 9
/* Global variables and structures */
static GDBusConnection *manager_conn;
static handle_stack_msg event_cb = NULL;
+static guint event_id;
/* Forward declarations */
int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
static int __bt_hal_register_manager_subscribe_signal(GDBusConnection *conn, int subscribe);
int __bt_hal_register_service_event(GDBusConnection *g_conn, int event_type);
static int __bt_hal_initialize_manager_receiver(void);
+static gboolean __bt_parse_interface(GVariant *msg);
+static void __bt_handle_device_event(GVariant *value, GVariant *parameters);
+static gboolean __bt_parse_device_properties(GVariant *item);
+static gboolean __bt_discovery_finished_cb(gpointer user_data);
+static gboolean __bt_discovery_finished_cb(gpointer user_data)
+{
+ event_id = 0;
+ DBG("+");
+ struct hal_ev_discovery_state_changed ev;
+ ev.state = HAL_DISCOVERY_STATE_STOPPED;
+ event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
+ DBG("-");
+
+ return FALSE;
+}
+
static int __bt_hal_parse_event(GVariant *msg)
{
GVariantIter iter;
{
GVariantIter value_iter;
GVariant *value = NULL;
+ GDBusProxy *adapter_proxy;
+ GError *err = NULL;
char *key = NULL;
g_variant_iter_init (&value_iter, msg);
gboolean pairable;
unsigned int pairable_timeout;
gboolean scan_mode_property_update = FALSE;
+ gboolean is_discovering;
+ gboolean is_le_discovering;
memset(buf, 0, sizeof(buf));
size = sizeof(*ev);
g_free(uuid_value);
}
} else if (!g_strcmp0(key, "Discovering")) {
+ is_discovering = g_variant_get_boolean(value);
+ DBG("##Discovering = [%d]", is_discovering);
+
+ if (is_discovering == FALSE) {
+ DBG("###### Adapter Has stopped Discovering ######");
+ /* In Tizen Bluez, this actually does not mean Discovery is stopped
+ in Bluez. Tizen Bluez sends this event after a certain timeout,
+ Therefore, we must forecefully call StopDiscovery to stop discovery in BlueZ */
+ if (event_id > 0)
+ continue;
+
+ adapter_proxy = _bt_get_adapter_proxy();
+
+ if (adapter_proxy == NULL)
+ continue;
+
+ /* Need to stop searching */
+ DBG("Event though Bluez reported DIscovering stopped, we force stop Discovery ");
+ g_dbus_proxy_call_sync(adapter_proxy, "StopDiscovery",
+ NULL,
+ G_DBUS_CALL_FLAGS_NONE,
+ DBUS_TIMEOUT, NULL,
+ &err);
+ if (err) {
+ ERR("Dbus Error : %s", err->message);
+
+ /* This error is thrown by Bluez, as Discovery is already stopped.
+ Discovery is stopped if user cancels on going discovery.
+ In order to maintain correct state of Bluetooth Discovery state,
+ simply send Discovery stopped event to HAL user */
+ struct hal_ev_discovery_state_changed ev;
+ ev.state = HAL_DISCOVERY_STATE_STOPPED;
+ event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
+ g_clear_error(&err);
+ continue;
+
+ } else {
+ event_id = g_timeout_add(BT_HAL_DISCOVERY_FINISHED_DELAY,
+ (GSourceFunc)__bt_discovery_finished_cb, NULL);
+ }
+
+ } else {
+ DBG("###### Adapter Has started Discovering ######");
+ struct hal_ev_discovery_state_changed ev;
+ ev.state = HAL_DISCOVERY_STATE_STARTED;
+ event_cb(HAL_EV_DISCOVERY_STATE_CHANGED, &ev, sizeof(ev));
+ }
+
} else if (!g_strcmp0(key, "LEDiscovering")) {
+ is_le_discovering = g_variant_get_boolean(value);
+ DBG("##LE Discovering = [%d]", is_le_discovering);
} else if (!g_strcmp0(key, "Modalias")) {
char *modalias = NULL;
g_variant_get(value, "s", &modalias);
DBG("-");
}
+static gboolean __bt_parse_device_properties(GVariant *item)
+{
+ GVariantIter iter;
+ gchar *key;
+ GVariant *val;
+ gsize len = 0;
+ if (!item)
+ return FALSE;
+ DBG("+");
+
+ /* Buffer and propety count management */
+ uint8_t buf[BT_HAL_MAX_PROPERTY_BUF_SIZE];
+ struct hal_ev_device_found *ev = (void *) buf;
+ size_t size = 0;
+ memset(buf, 0, sizeof(buf));
+ size = sizeof(*ev);
+ ev->num_props = 0;
+
+ g_variant_iter_init(&iter, item);
+ while (g_variant_iter_loop(&iter, "{sv}", &key, &val)) {
+
+ if (strcasecmp(key, "Address") == 0) {
+
+ char * address = NULL;
+ address = g_variant_dup_string(val, &len);
+ uint8_t bdaddr[6];
+ _bt_convert_addr_string_to_type(bdaddr, address);
+
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_ADDR,
+ sizeof(bdaddr), bdaddr);
+
+ ev->num_props++;
+ DBG("Device address [%s] property Num [%d]",address, ev->num_props);
+
+ } else if (strcasecmp(key, "Class") == 0) {
+ unsigned int class = g_variant_get_uint32(val);
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CLASS,
+ sizeof(unsigned int), &class);
+ ev->num_props++;
+ DBG("Device class [%d] Property num [%d]", class, ev->num_props);
+ } else if (strcasecmp(key, "name") == 0) {
+ char *name = g_variant_dup_string(val, &len);
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_NAME,
+ strlen(name) + 1, name);
+ ev->num_props++;
+ DBG("Device Name [%s] Property num [%d]", name, ev->num_props);
+ } else if (strcasecmp(key, "Connected") == 0) {
+ unsigned int connected = g_variant_get_uint32(val);
+
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_CONNECTED,
+ sizeof(unsigned int), &connected);
+ ev->num_props++;
+ DBG("Device connected [%u] Property num [%d]", connected, ev->num_props);
+ } else if (strcasecmp(key, "paired") == 0) {
+ gboolean paired = g_variant_get_boolean(val);
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_PAIRED,
+ sizeof(gboolean), &paired);
+ ev->num_props++;
+ DBG("Device Paired [%d] Property num [%d]", paired, ev->num_props);
+ } else if (strcasecmp(key, "Trusted") == 0) {
+ gboolean trust = g_variant_get_boolean(val);
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_TRUSTED,
+ sizeof(gboolean), &trust);
+ ev->num_props++;
+ DBG("Device trusted [%d] Property num [%d]", trust, ev->num_props);
+ } else if (strcasecmp(key, "RSSI") == 0) {
+ int rssi = g_variant_get_int16(val);
+ size += __bt_insert_hal_properties(buf + size, HAL_PROP_DEVICE_RSSI,
+ sizeof(int), &rssi);
+ ev->num_props++;
+ DBG("Device RSSI [%d] Property num [%d]", rssi, ev->num_props);
+ } else if (strcasecmp(key, "LastAddrType") == 0) {
+ /* TODO: To be handled later*/
+ } else if (strcasecmp(key, "UUIDs") == 0) {
+ char **uuid_value;
+ int uuid_count = 0;
+ gsize size1 = 0;
+ int i =0;
+ int z;
+ size1 = g_variant_get_size(val);
+ DBG("UUID count from size [%d]\n", size1);
+ int num_props_tmp = ev->num_props;
+
+ if (size1 > 0) {
+ uuid_value = (char **)g_variant_get_strv(val, &size1);
+ for (i = 0; uuid_value[i] != NULL; i++)
+ uuid_count++;
+ DBG("UUID count [%d]\n", 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);
+
+ DBG("UUID string from Bluez [%s]\n", uuid_value[i]);
+ uuid_str = g_strdup(uuid_value[i]);
+ DBG("UUID string [%s]\n", uuid_str);
+ _bt_convert_uuid_string_to_type(uuid, uuid_str);
+ for(z=0; z < 16; z++)
+ DBG("[0x%x]", uuid[z]);
+
+ 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_DEVICE_UUIDS,
+ (BT_HAL_STACK_UUID_SIZE * uuid_count),
+ uuids);
+ ev->num_props = num_props_tmp + 1;
+ g_free(uuid_value);
+ }
+
+ } else if (strcasecmp(key, "ManufacturerDataLen") == 0) {
+ /* TODO: To be handled later*/
+ } else if (strcasecmp(key, "ManufacturerData") == 0) {
+
+ /* TODO: To be handled later*/
+ }
+ }
+ DBG("-");
+
+ if (size > 1) {
+ DBG("Send Device found event to HAL user, Num Prop [%d] total size [%d]",ev->num_props, size);
+ event_cb(HAL_EV_DEVICE_FOUND, (void*) buf, size);
+ }
+
+ return TRUE;
+}
+
void __bt_hal_handle_property_changed_event(GVariant *msg, const char *object_path)
{
char *interface_name = NULL;
DBG("-");
}
+static void __bt_handle_device_event(GVariant *value, GVariant *parameters)
+{
+ DBG("+");
+
+ if (__bt_parse_interface(parameters) == FALSE) {
+ ERR("Fail to parse the properies");
+ g_variant_unref(value);
+ return;
+ }
+
+ DBG("-");
+}
+
+static gboolean __bt_parse_interface(GVariant *msg)
+{
+ char *path = NULL;
+ GVariant *optional_param;
+ GVariantIter iter;
+ GVariant *child;
+ char *interface_name= NULL;
+ GVariant *inner_iter = NULL;
+ g_variant_get(msg, "(&o@a{sa{sv}})",
+ &path, &optional_param);
+ g_variant_iter_init(&iter, optional_param);
+
+ while ((child = g_variant_iter_next_value(&iter))) {
+ g_variant_get(child,"{&s@a{sv}}", &interface_name, &inner_iter);
+ if (g_strcmp0(interface_name, BT_HAL_DEVICE_INTERFACE) == 0) {
+ DBG("Found a device: %s", path);
+ if (__bt_parse_device_properties(inner_iter) == FALSE) {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ g_variant_unref(optional_param);
+ ERR("Fail to parse the properies");
+ return FALSE;
+ } else {
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ g_variant_unref(optional_param);
+ return TRUE;
+ }
+ }
+ g_variant_unref(inner_iter);
+ g_variant_unref(child);
+ }
+
+ g_variant_unref(optional_param);
+
+ return FALSE;
+}
+
static void __bt_hal_manager_event_filter(GDBusConnection *connection,
const gchar *sender_name,
const gchar *object_path,
} else {
bt_event = __bt_hal_parse_event(value);
if (bt_event == BT_HAL_DEVICE_EVENT) {
- /*TODO: Handle device events from BlueZ */
DBG("Device path : %s ", obj_path);
+ __bt_handle_device_event(value, parameters);
} else if (bt_event == BT_HAL_AVRCP_CONTROL_EVENT) {
/*TODO: Handle AVRCP control events from BlueZ */
}
* See the License for the specific language governing permissions and
* limitations under the License.
*
-*/
+ */
#include <stdio.h>
#include <stdlib.h>
#define BT_UUID_STRING_SIZE 37
#define BT_UUID_LENGTH_MAX 16
-oal_status_t convert_to_oal_status(bt_status_t status) {
+void parse_device_properties(int num_properties, bt_property_t *properties,
+ remote_device_t *dev_info,
+ ble_adv_data_t * adv_info,
+ gsize *size)
+{
+ int i = 0;
+ int uuid_count = 0, table_len = 0;
+ int tmp_uuid_cnt = 0;
+ int chk = 0;
+ char lcl_uuid[BT_UUID_STRING_MAX];
+
+ bt_bdaddr_t * addr = {0};
+ bt_bdname_t *name = {0};
+ service_uuid_t *uuids;
+ bt_device_type_t dev_type;
+
+ BT_DBG("num_properties: %d", num_properties);
+
+ for(i=0; i<num_properties; i++) {
+ BT_DBG("===>Prop type: %d, Len: %d<===", properties[i].type, properties[i].len);
+
+ switch(properties[i].type)
+ {
+ case BT_PROPERTY_BDADDR: {
+ addr = (bt_bdaddr_t *)properties[i].val;
+ memcpy(dev_info->address.addr, addr->address, 6);
+ BT_DBG("%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X\n", dev_info->address.addr[0], dev_info->address.addr[1], dev_info->address.addr[2],
+ dev_info->address.addr[3], dev_info->address.addr[4], dev_info->address.addr[5]);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_CLASS_OF_DEVICE: {
+ dev_info->cod = *((int *)properties[i].val);
+ BT_DBG("CLASS: 0x%06x", dev_info->cod);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_BDNAME: {
+ name = properties[i].val;
+
+ g_strlcpy(dev_info->name, (const gchar *)name->name, BT_DEVICE_NAME_LENGTH_MAX);
+ BT_DBG("NAME: %s", dev_info->name);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME: {
+ bt_bdname_t *name = properties[i].val;
+ if (NULL != name && (0 != properties[i].len))
+ g_strlcpy(dev_info->name, (const gchar *)name->name, BT_DEVICE_NAME_LENGTH_MAX);
+ BT_DBG("FRIENDLY NAME: [%s]", dev_info->name);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_PAIRED: {
+ dev_info->is_bonded = *((gboolean*)properties[i].val);
+ BT_DBG("BONDED [%d]", dev_info->is_bonded);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_CONNECTED: {
+ dev_info->is_connected = *((int*)properties[i].val);
+ BT_DBG("CONNECTED [%d]", dev_info->is_connected);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_TRUST: {
+ dev_info->is_trusted = *((gboolean*)properties[i].val);
+ BT_DBG("TRUSTED [%d]", dev_info->is_trusted);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_RSSI: {
+ dev_info->rssi = *((int *)properties[i].val);
+ BT_DBG("RSSI: %d", dev_info->rssi);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_UUIDS: {
+ uuids = (service_uuid_t *)properties[i].val;
+ uuid_count = properties[i].len/sizeof(bt_uuid_t);
+ table_len += uuid_count;
+ for(; tmp_uuid_cnt < table_len; tmp_uuid_cnt++) {
+ uuid_to_string(&uuids[tmp_uuid_cnt], lcl_uuid);
+ chk = check_duplicate_uuid(dev_info->uuid, uuids[tmp_uuid_cnt], dev_info->uuid_count);
+ if(chk != 0) {
+ memcpy(&dev_info->uuid[dev_info->uuid_count++].uuid[0], &uuids[tmp_uuid_cnt].uuid[0], 16);
+ } else {
+ BT_DBG("Duplicate UUID found:%s\n", lcl_uuid);
+ }
+ BT_DBG("%d.BT_PROPERTY_UUIDS:%s", dev_info->uuid_count, lcl_uuid);
+ }
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_TYPE_OF_DEVICE: {
+ dev_type = *((bt_device_type_t *)properties[i].val);
+ if(dev_type == BT_DEVICE_DEVTYPE_BLE)
+ BT_DBG("Single mode BLE Device");
+ else if(dev_type == BT_DEVICE_DEVTYPE_DUAL)
+ BT_DBG("Dual mode BLE Device");
+ dev_info->type = dev_type - 1;//OAL enum starts with 0 and Bluedroid with 1
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_BLE_ADV_DATA: {
+ if(adv_info) {
+ adv_info->adv_data = properties[i].val;
+ adv_info->len = properties[i].len;
+ }
+ BT_DBG("----Advertising Data Length: %d",properties[i].len);
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: {
+ BT_INFO("BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP: Not Handled!!");
+ *size += properties[i].len;
+ break;
+ }
+ case BT_PROPERTY_SERVICE_RECORD: {
+ BT_INFO("BT_PROPERTY_SERVICE_RECORD: Not Handled!!");
+ *size += properties[i].len;
+ break;
+ }
+ default:
+ BT_WARN("Property not handled");
+ break;
+ }
+ }
+}
+
+
+oal_status_t convert_to_oal_status(bt_status_t status)
+{
oal_status_t ret = OAL_STATUS_INTERNAL_ERROR;
switch(status) {
- case BT_STATUS_SUCCESS:
+ case BT_STATUS_SUCCESS:
case BT_STATUS_DONE:
ret = OAL_STATUS_SUCCESS;
break;
"BT_STATUS_RMT_DEV_DOWN"
};
-const char * status2string(bt_status_t status) {
+int check_duplicate_uuid(oal_uuid_t *table, oal_uuid_t toMatch, int table_len)
+{
+ int i;
+ int ret = 0;
+
+ for (i = 0; i < table_len; i++) {
+ ret = memcmp(table[i].uuid, toMatch.uuid, 16);
+ if (ret == 0)
+ break;
+ }
+ return ret;
+}
+
+const char* status2string(bt_status_t status)
+{
if(status >= BT_STATUS_SUCCESS && status <= BT_STATUS_RMT_DEV_DOWN)
return status_str[status];
else {
extern "C" {
#endif
void parse_device_properties(int num_properties, bt_property_t *properties,
- remote_device_t *dev_info, ble_adv_data_t * adv_info);
+ remote_device_t *dev_info, ble_adv_data_t * adv_info,
+ gsize *size);
oal_status_t convert_to_oal_status(bt_status_t status);
const char * status2string(bt_status_t status);
+int check_duplicate_uuid(oal_uuid_t *table, oal_uuid_t toMatch, int table_len);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
return *bdstr;
}
+char* convert_bdaddr_2_str(const bt_bdaddr_t *bd_addr, char *buf)
+{
+ const uint8_t *p;
+
+ if (!bd_addr)
+ return strcpy(buf, "NULL");
+ p = bd_addr->address;
+
+ snprintf(buf, 18, "%02x:%02x:%02x:%02x:%02x:%02x",
+ p[0], p[1], p[2], p[3], p[4], p[5]);
+
+ return buf;
+}
+
+char *bdaddr_2_str(const bt_bdaddr_t *bd_addr)
+{
+ static char buf[18];
+ return convert_bdaddr_2_str(bd_addr, buf);
+}
+
void string_to_uuid(char *str, service_uuid_t *p_uuid)
{
uint32_t uuid0, uuid4;
ntohl(uuid4), ntohs(uuid5));
}
-
-static int hex2bin( const char *s )
+int hex2bin( const char *s )
{
int ret=0;
int i;
}
str_out[3*len] = 0;
}
+
+void print_bt_properties(int num_properties, bt_property_t *properties)
+{
+ int i;
+ for (i = 0; i < num_properties; i++) {
+ bt_property_t prop;
+ memcpy(&prop, properties + i, sizeof(prop));
+ BT_INFO("prop: %s\n", convert_bt_property_2_str(&prop));
+ }
+}
+
+char* convert_scan_mode_2_str(bt_scan_mode_t scan_mode)
+{
+ switch(scan_mode) {
+ case BT_SCAN_MODE_NONE:
+ return "Non Scannable";
+ case BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE:
+ return "Connectable And Discoverable";
+ case BT_SCAN_MODE_CONNECTABLE:
+ return "Connectable";
+ default:
+ return "Unknown Scan Mode";
+ }
+
+}
+
+char* convert_device_type_2_str(bt_device_type_t device_type)
+{
+ switch (device_type) {
+ case BT_DEVICE_DEVTYPE_BREDR:
+ return "BREDR Device";
+ case BT_DEVICE_DEVTYPE_BLE:
+ return "BLE Device";
+ case BT_DEVICE_DEVTYPE_DUAL:
+ return "Dual Device";
+ default:
+ return "Unknown Device Type";
+ }
+}
+
+char *convert_bt_property_2_str(const bt_property_t *property)
+{
+ static char buf[4096];
+ char *p;
+
+ p = buf + sprintf(buf, "type=%s len=%d val=",
+ convert_property_type_2_str(property->type),
+ property->len);
+
+ switch (property->type) {
+ case BT_PROPERTY_BDNAME:
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ snprintf(p, property->len + 1, "%s",
+ ((bt_bdname_t *) property->val)->name);
+ break;
+ case BT_PROPERTY_BDADDR:
+ sprintf(p, "%s", bdaddr_2_str((bt_bdaddr_t *) property->val));
+ break;
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ sprintf(p, "%06x", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ sprintf(p, "%s", convert_device_type_2_str(
+ *((bt_device_type_t *) property->val)));
+ break;
+ case BT_PROPERTY_REMOTE_RSSI:
+ sprintf(p, "%d", *((char *) property->val));
+ break;
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ sprintf(p, "%d", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ sprintf(p, "%s",
+ convert_scan_mode_2_str(*((bt_scan_mode_t *) property->val)));
+ break;
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ break;
+ case BT_PROPERTY_UUIDS:
+ break;
+ case BT_PROPERTY_SERVICE_RECORD:
+ break;
+ /* Tizen BlueZ specific Device properties */
+ case BT_PROPERTY_REMOTE_PAIRED:
+ sprintf(p, "%d", *((bool *) property->val));
+ break;
+ case BT_PROPERTY_REMOTE_CONNECTED:
+ sprintf(p, "%d", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_REMOTE_TRUST:
+ sprintf(p, "%d", *((bool *) property->val));
+ break;
+ case BT_PROPERTY_PAIRABLE:
+ sprintf(p, "%d", *((bool *) property->val));
+ break;
+ case BT_PROPERTY_VERSION:
+ snprintf(p, property->len + 1, "%s",
+ ((char *) property->val));
+ break;
+ case BT_PROPERTY_LOCAL_LE_FEATURES:
+ local_le_feat_2_string(p, property->val);
+ break;
+ case BT_PROPERTY_PAIRABLE_TIMEOUT:
+ sprintf(p, "%d", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_IPSP_INITIALIZED:
+ sprintf(p, "%d", *((bool *) property->val));
+ break;
+ case BT_PROPERTY_MODALIAS:
+ snprintf(p, property->len + 1, "%s",
+ ((char *) property->val));
+ break;
+ case BT_PROPERTY_REMOTE_DEVICE_MANUFACTURER_DATA_LEN:
+ sprintf(p, "%d", *((unsigned int *) property->val));
+ break;
+ case BT_PROPERTY_REMOTE_DEVICE_MANUFACTURER_DATA:
+ {
+ int indx;
+ char *pppp = property->val;
+ for (indx = 0; indx < property->len; indx++)
+ p += sprintf(p, " %2.2X", pppp[indx]);
+ break;
+ }
+ case BT_PROPERTY_REMOTE_BLE_ADV_DATA:
+ {
+ int indx;
+ char *pppp = property->val;
+ for (indx = 0; indx < property->len; indx++)
+ p += sprintf(p, " %2.2X", pppp[indx]);
+ break;
+ }
+ /* End of Tizen BlueZ specific device propeties */
+ case BT_PROPERTY_REMOTE_VERSION_INFO:
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ default:
+ sprintf(p, "%p", property->val);
+ break;
+ }
+ return buf;
+}
+
+void local_le_feat_2_string(char *str, const bt_local_le_features_t *f)
+{
+ uint16_t scan_num;
+
+ str += sprintf(str, "{\n");
+
+ str += sprintf(str, "Privacy supported: %s,\n",
+ f->local_privacy_enabled ? "TRUE" : "FALSE");
+
+ str += sprintf(str, "Num of advertising instances: %u,\n",
+ f->max_adv_instance);
+
+ str += sprintf(str, "PRA offloading support: %s,\n",
+ f->rpa_offload_supported ? "TRUE" : "FALSE");
+
+ str += sprintf(str, "Num of offloaded IRKs: %u,\n",
+ f->max_irk_list_size);
+
+ str += sprintf(str, "Num of offloaded scan filters: %u,\n",
+ f->max_adv_filter_supported);
+
+ scan_num = (f->scan_result_storage_size_hibyte << 8) +
+ f->scan_result_storage_size_lobyte;
+
+ str += sprintf(str, "Num of offloaded scan results: %u,\n", scan_num);
+
+ str += sprintf(str, "Activity & energy report support: %s\n",
+ f->activity_energy_info_supported ? "TRUE" : "FALSE");
+
+ sprintf(str, "}");
+}
+
+char* convert_property_type_2_str(bt_property_type_t prop_type)
+{
+ switch (prop_type) {
+ case BT_PROPERTY_BDNAME:
+ return "[Bluetooth Name]";
+ case BT_PROPERTY_BDADDR:
+ return "[Bluetooth Address]";
+ case BT_PROPERTY_UUIDS:
+ return "[UUIDS]";
+ case BT_PROPERTY_CLASS_OF_DEVICE:
+ return "[Class of Device]";
+ case BT_PROPERTY_TYPE_OF_DEVICE:
+ return "[Bluetooth Type of Device]";
+ case BT_PROPERTY_SERVICE_RECORD:
+ return "[Bluetooth Service record]";
+ case BT_PROPERTY_ADAPTER_SCAN_MODE:
+ return "[Bluetooth Adapter Scan Mode]";
+ case BT_PROPERTY_ADAPTER_BONDED_DEVICES:
+ return "[Bluetooth Bonded Devices]";
+ case BT_PROPERTY_ADAPTER_DISCOVERY_TIMEOUT:
+ return "[Bluetooth Adapter Discovery Timeout]";
+ case BT_PROPERTY_REMOTE_FRIENDLY_NAME:
+ return "[Bluetooth Friendly Name]";
+ case BT_PROPERTY_REMOTE_RSSI:
+ return "[Bluetooth Rmote RSSI]";
+ case BT_PROPERTY_REMOTE_VERSION_INFO:
+ return "[Bluetooth Version Info]";
+ case BT_PROPERTY_LOCAL_LE_FEATURES:
+ return "[Bluetooth LE Features]";
+ case BT_PROPERTY_REMOTE_PAIRED:
+ return "[Bluetooth Remote Paired]";
+ case BT_PROPERTY_REMOTE_CONNECTED:
+ return "[Bluetooth Remote Connected]";
+ case BT_PROPERTY_REMOTE_TRUST:
+ return "[Bluetooth Remote TRUST]";
+ case BT_PROPERTY_PAIRABLE:
+ return "[Bluetooth Pairable]";
+ case BT_PROPERTY_PAIRABLE_TIMEOUT:
+ return "[Bluetooth Pairable Timeout]";
+ case BT_PROPERTY_VERSION:
+ return "[Bluetooth Version]";
+ case BT_PROPERTY_IPSP_INITIALIZED:
+ return "[Bluetooth IPSP Initialized]";
+ case BT_PROPERTY_MODALIAS:
+ return "[Bluetooth ModAlias]";
+ case BT_PROPERTY_REMOTE_DEVICE_TIMESTAMP:
+ return "[Bluetooth Remote Device Timestamp]";
+ case BT_PROPERTY_REMOTE_DEVICE_MANUFACTURER_DATA_LEN:
+ return "[Bluetooth Remote Device Manufacturer Data Len]";
+ case BT_PROPERTY_REMOTE_DEVICE_MANUFACTURER_DATA:
+ return "[Bluetooth Remote Device Manufacturer Data]";
+ case BT_PROPERTY_REMOTE_BLE_ADV_DATA:
+ return "[Bluetooth Remote Device LE Advertising Data]";
+ default:
+ return "[Default Property]";
+ }
+}
+
typedef char bdstr_t[18];
/* Common/util functions */
-char *bdt_bd2str(const bt_address_t *bdaddr, bdstr_t *bdstr);
+char* bdt_bd2str(const bt_address_t *bdaddr, bdstr_t *bdstr);
+char* bdaddr_2_str(const bt_bdaddr_t *bd_addr);
void string_to_uuid(char *str, service_uuid_t *p_uuid);
void uuid_to_string(service_uuid_t *p_uuid, char *str);
void oal_print_device_address_t(const bt_address_t *addr);
void oal_convert_addr_string_to_type(unsigned char *addr, const char *address);
int oal_is_address_zero(unsigned char *addr1);
+void print_bt_properties(int num_properties, bt_property_t *properties);
+
void convert_str_2_hex(char out[],char in[]);
void convert_hex_2_str(char * hex, int len, char * str_out);
+char* convert_bt_property_2_str(const bt_property_t *property);
+char* convert_property_type_2_str(bt_property_type_t prop_type);
+char* convert_scan_mode_2_str(bt_scan_mode_t scan_mode);
+char* convert_device_type_2_str(bt_device_type_t device_type);
+char* convert_bdaddr_2_str(const bt_bdaddr_t *bd_addr, char *buf);
+
+void local_le_feat_2_string(char *str, const bt_local_le_features_t *f);
#ifdef __cplusplus
}
oal_status_t adapter_disable(void);
/**
+ * @brief Start device discovery
+ *
+ * @details For each device found either OAL_EVENT_ADAPTER_INQUIRY_RESULT_BREDR_ONLY
+ * or OAL_EVENT_ADAPTER_INQUIRY_RESULT_BLE will be generated.
+ *
+ * @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 adapter_stop_inquiry()
+ * @see OAL_EVENT_ADAPTER_INQUIRY_STARTED
+ * @see OAL_EVENT_ADAPTER_INQUIRY_RESULT_BREDR_ONLY
+ * @see OAL_EVENT_ADAPTER_INQUIRY_RESULT_BLE
+ * @see OAL_EVENT_ADAPTER_INQUIRY_FINISHED
+ */
+oal_status_t adapter_start_inquiry(void);
+
+/**
+ * @brief Stop device discovery
+ *
+ * @details OAL_EVENT_ADAPTER_INQUIRY_FINISHED will be generated by OAL
+ * @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
+ * @retval #OAL_STATUS_SUCCESS Successful
+ *
+ * @pre Discovery must be in progress by calling adapter_start_inquiry()
+ *
+ * @see adapter_start_inquiry()
+ * @see OAL_EVENT_ADAPTER_INQUIRY_FINISHED
+ */
+oal_status_t adapter_stop_inquiry(void);
+
+/**
* @brief Get local BT chip address
*
* @return OAL_STATUS_SUCCESS on success, otherwise a non-zero error value.
device_type_t type;
int uuid_count;
oal_uuid_t uuid[BT_MAX_SERVICES_FOR_DEVICE];
+ int is_trusted;
} remote_device_t;
/**
#include "oal-internal.h"
#include "oal-manager.h"
#include "oal-hardware.h"
+#include "oal-common.h"
+#include "oal-utils.h"
#define CHECK_MAX(max, x) (((max) > (x)) ? (x) : (max))
static int discoverable_timeout = 0;
/* Forward declarations */
-const char * status2string(bt_status_t status);
oal_status_t convert_to_oal_status(bt_status_t status);
-void parse_device_properties(int num_properties, bt_property_t *properties,
- remote_device_t *dev_info, ble_adv_data_t * adv_info);
static gboolean retry_enable_adapter(gpointer data);
oal_status_t oal_mgr_init_internal(void);
/* Callback registered with Stack */
static void cb_adapter_state_change(bt_state_t status);
+static void cb_adapter_discovery_state_changed(bt_discovery_state_t state);
+static void cb_adapter_device_found(int num_properties, bt_property_t *properties);
static void cb_adapter_properties (bt_status_t status,
int num_properties, bt_property_t *properties);
cb_adapter_state_change,
cb_adapter_properties,
NULL, /* remote_device_properties_callback */
- NULL, /* device_found_callback */
- NULL, /* discovery_state_changed_callback */
+ cb_adapter_device_found,
+ cb_adapter_discovery_state_changed,
NULL, /* pin_request_callback */
NULL, /* ssp_request_callback */
NULL, /* bond_state_changed_callback */
return OAL_STATUS_SUCCESS;
}
+oal_status_t adapter_start_inquiry(void)
+{
+ int ret;
+
+ API_TRACE();
+
+ CHECK_OAL_INITIALIZED();
+
+ ret = blued_api->start_discovery();
+ if (ret != BT_STATUS_SUCCESS) {
+ BT_ERR("start_discovery failed: [%s]", status2string(ret));
+ return convert_to_oal_status(ret);
+ }
+
+ return OAL_STATUS_SUCCESS;
+}
+
+oal_status_t adapter_stop_inquiry(void)
+{
+ int ret;
+
+ API_TRACE();
+
+ CHECK_OAL_INITIALIZED();
+
+ ret = blued_api->cancel_discovery();
+ if (ret != BT_STATUS_SUCCESS) {
+ BT_ERR("cancel_discovery failed: [%s]", status2string(ret));
+ return convert_to_oal_status(ret);
+ }
+
+ return OAL_STATUS_SUCCESS;
+}
+
/* Callbacks from Stack */
static void cb_adapter_state_change(bt_state_t status)
{
{
int ret;
- CHECK_OAL_INITIALIZED();
-
API_TRACE();
+ CHECK_OAL_INITIALIZED();
ret = blued_api->get_adapter_property(BT_PROPERTY_BDADDR);
if (ret != BT_STATUS_SUCCESS) {
{
int ret;
- CHECK_OAL_INITIALIZED();
-
API_TRACE();
+ CHECK_OAL_INITIALIZED();
ret = blued_api->get_adapter_property(BT_PROPERTY_VERSION);
if (ret != BT_STATUS_SUCCESS) {
return OAL_STATUS_SUCCESS;
}
-static void cb_adapter_properties (bt_status_t status,
+static void cb_adapter_properties(bt_status_t status,
int num_properties,
bt_property_t *properties)
{
break;
}
default:
- BT_WARN("Unhandled property: %d", properties[i].type);
- break;
+ BT_WARN("Unhandled property: %d", properties[i].type);
+ break;
}
}
}
+
+static void cb_adapter_discovery_state_changed(bt_discovery_state_t state)
+{
+ oal_event_t event;
+
+ event = (BT_DISCOVERY_STARTED == state)?OAL_EVENT_ADAPTER_INQUIRY_STARTED:OAL_EVENT_ADAPTER_INQUIRY_FINISHED;
+
+ BT_DBG("%d", state);
+ send_event(event, NULL, 0);
+}
+
+static void cb_adapter_device_found(int num_properties, bt_property_t *properties)
+{
+ remote_device_t dev_info;
+ ble_adv_data_t adv_info;
+ oal_event_t event;
+ gpointer event_data;
+ gsize properties_size = 0;
+ BT_DBG("+");
+
+ if (num_properties == 0) {
+ BT_ERR("Unexpected, properties count is zero!!");
+ return;
+ }
+
+ memset(&dev_info, 0x00, sizeof(remote_device_t));
+ memset(&adv_info, 0x00, sizeof(ble_adv_data_t));
+
+ print_bt_properties(num_properties, properties);
+ parse_device_properties(num_properties, properties, &dev_info, &adv_info, &properties_size);
+
+ BT_INFO("number of properties= [%d] total size [%u]", num_properties, properties_size);
+
+ if (dev_info.type != DEV_TYPE_BREDR) {
+ /* BLE Single or DUAL mode found, so it should have Adv data */
+ event_ble_dev_found_t * ble_dev_event = g_new0(event_ble_dev_found_t, 1);
+
+ ble_dev_event->adv_len = adv_info.len;
+
+ if (adv_info.len > 0 && adv_info.adv_data) {
+ memcpy(ble_dev_event->adv_data, adv_info.adv_data, adv_info.len);
+ ble_dev_event->adv_len = adv_info.len;
+ } else
+ ble_dev_event->adv_len = 0;
+
+ ble_dev_event->device_info = dev_info;
+
+ event_data = ble_dev_event;
+ event = OAL_EVENT_ADAPTER_INQUIRY_RESULT_BLE;
+ } else {
+ /* BREDR device, so No Adv data */
+ event_dev_found_t * dev_event = g_new0(event_dev_found_t, 1);
+
+ memcpy(dev_event, &dev_info, sizeof(remote_device_t));
+ event_data = dev_event;
+ event = OAL_EVENT_ADAPTER_INQUIRY_RESULT_BREDR_ONLY;
+ }
+
+ send_event(event, event_data, properties_size);
+
+ BT_DBG("-");
+}
./services/bt-service-util.c
./services/bt-request-handler.c
./services/adapter/bt-service-core-adapter.c
+./services/device/bt-service-core-device.c
./services/bt-service-event-receiver.c
)
#include "bt-service-util.h"
#include "bt-service-main.h"
#include "bt-service-core-adapter.h"
+#include "bt-service-core-device.h"
#include "bt-service-event-receiver.h"
#include "bt-request-handler.h"
#include "bt-service-event.h"
static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
static void __bt_adapter_state_change_callback(int bt_status);
static int __bt_adapter_state_handle_request(gboolean enable);
-
+static int __bt_adapter_state_discovery_request(gboolean enable);
+static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status);
/* Initialize BT stack (Initialize OAL layer) */
int _bt_stack_init(void)
return __bt_adapter_state_handle_request(FALSE);
}
+
+int _bt_start_discovery(void)
+{
+ return __bt_adapter_state_discovery_request(TRUE);
+}
+
+int _bt_cancel_discovery(void)
+{
+ return __bt_adapter_state_discovery_request(FALSE);
+}
+
+gboolean _bt_is_discovering(void)
+{
+ if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED
+ || adapter_discovery_state == ADAPTER_DISCOVERY_STARTING)
+ return TRUE;
+ else
+ return FALSE;
+}
+
int _bt_get_local_address(void)
{
int result;
case OAL_EVENT_ADAPTER_DISABLED:
__bt_adapter_state_change_callback(BT_DEACTIVATED);
break;
+ case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
+ __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STARTED);
+ break;
+ case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
+ __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STOPPED);
+ break;
case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
bt_address_t *bd_addr = event_data;
bluetooth_device_address_t local_address;
/* Adapter enable request is successful, setup event handlers */
_bt_service_register_event_handler_callback(
BT_ADAPTER_MODULE, __bt_adapter_event_handler);
- /*TODO Set Device Core Callbacks*/
+ _bt_device_state_handle_callback_set_request();
+ }
+ return result;
+}
+
+static int __bt_adapter_state_discovery_request(gboolean enable)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+
+ BT_DBG("+");
+ switch (adapter_discovery_state) {
+ case ADAPTER_DISCOVERY_STARTED: {
+ BT_INFO("Adapter is currently in discovery started state, state [%d]",
+ adapter_discovery_state);
+ if (enable) {
+ return BLUETOOTH_ERROR_IN_PROGRESS;
+ } else {
+ result = adapter_stop_inquiry();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("Discover stop failed: %d", result);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_ERR("Stop Discovery Triggered successfully");
+ __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ case ADAPTER_DISCOVERY_STARTING: {
+ BT_INFO("Adapter is currently in discovery starting state, state [%d]",
+ adapter_discovery_state);
+ if (enable) {
+ return BLUETOOTH_ERROR_IN_PROGRESS;
+ } else {
+ result = adapter_stop_inquiry();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("Discover stop failed: %d", result);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_ERR("Stop Discovery Triggered successfully");
+ __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
}
+ case ADAPTER_DISCOVERY_STOPPED: {
+ BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
+ adapter_discovery_state);
+ if (!enable)
+ return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+ else {
+ result = adapter_start_inquiry();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("Start Discovery failed: %d", result);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_ERR("Start Discovery Triggered successfully");
+ __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ case ADAPTER_DISCOVERY_STOPPING: {
+ BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
+ adapter_discovery_state);
+ if (!enable)
+ return BLUETOOTH_ERROR_NOT_IN_OPERATION;
+ else {
+ result = adapter_start_inquiry();
+ if (result != OAL_STATUS_SUCCESS) {
+ BT_ERR("Start Discovery failed: %d", result);
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_ERR("Start Discovery Triggered successfully");
+ __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
+ result = BLUETOOTH_ERROR_NONE;
+ }
+ }
+ break;
+ }
+ }
+
+ BT_DBG("-");
return result;
}
+static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
+{
+ BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
+ GVariant *param = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ switch (bt_discovery_status) {
+ case ADAPTER_DISCOVERY_STOPPED:
+ {
+ __bt_adapter_update_discovery_status(bt_discovery_status);
+ param = g_variant_new("(i)", result);
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_DISCOVERY_FINISHED,
+ param);
+ break;
+ }
+ case ADAPTER_DISCOVERY_STARTED:
+ {
+ __bt_adapter_update_discovery_status(bt_discovery_status);
+ param = g_variant_new("(i)", result);
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_DISCOVERY_STARTED,
+ param);
+ break;
+ }
+ default:
+ BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
+ }
+}
}
break;
}
+ case BT_START_DISCOVERY: {
+ result = _bt_start_discovery();
+ break;
+ }
+ case BT_CANCEL_DISCOVERY:
+ result = _bt_cancel_discovery();
+ break;
+ case BT_IS_DISCOVERYING: {
+ gboolean discovering = FALSE;
+ discovering = _bt_is_discovering();
+ g_array_append_vals(*out_param1,
+ &discovering, sizeof(gboolean));
+ break;
+ }
case BT_GET_LOCAL_ADDRESS: {
result = _bt_get_local_address();
*/
#include <stdio.h>
+#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include <dlog.h>
#include <net_connection.h>
#include <bundle.h>
#include <eventsystem.h>
+#include <arpa/inet.h>
#include "bluetooth-api.h"
#include "bt-service-common.h"
+#include <oal-manager.h>
+
static GDBusConnection *system_conn;
static GDBusConnection *session_conn;
static GDBusProxy *manager_proxy;
}
return 0;
}
+
+void _bt_copy_remote_dev(bt_remote_dev_info_t * dev_info, remote_device_t * oal_device)
+{
+ int i;
+ BT_INFO("+");
+
+ dev_info->address = g_new0(char, BT_ADDRESS_STRING_SIZE);
+ _bt_convert_addr_type_to_string(dev_info->address, oal_device->address.addr);
+ BT_INFO("Address [%s]", dev_info->address);
+
+ if(strlen(oal_device->name)== 0)
+ dev_info->name = NULL;
+ else {
+ dev_info->name = g_strdup(oal_device->name);
+ _bt_truncate_non_utf8_chars(dev_info->name);
+ BT_INFO("Name [%s]", dev_info->name);
+ }
+
+ dev_info->class = oal_device->cod;
+ BT_INFO("COD [%d]", dev_info->class);
+ dev_info->paired = oal_device->is_bonded;
+ BT_INFO("Is Bonded [%d]", dev_info->paired);
+ dev_info->connected = oal_device->is_connected;
+ BT_INFO("iS Connected [%d]", dev_info->connected);
+ dev_info->rssi = oal_device->rssi;
+ BT_INFO("RSSI [%d]", dev_info->rssi);
+ dev_info->addr_type = oal_device->type;
+ dev_info->uuid_count = oal_device->uuid_count;
+ BT_INFO("UUID Count [%d]", dev_info->uuid_count);
+ dev_info->trust = oal_device->is_trusted;
+
+ if (dev_info->uuid_count > 0)
+ dev_info->uuids = g_new0(char *, dev_info->uuid_count);
+
+ /* Fill Remote Device Service List list */
+ 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_INFO("-");
+}
+
+void _bt_uuid_to_string(service_uuid_t *p_uuid, char *str)
+{
+ uint32_t uuid0, uuid4;
+ uint16_t uuid1, uuid2, uuid3, uuid5;
+
+ memcpy(&uuid0, &(p_uuid->uuid[0]), 4);
+ memcpy(&uuid1, &(p_uuid->uuid[4]), 2);
+ memcpy(&uuid2, &(p_uuid->uuid[6]), 2);
+ memcpy(&uuid3, &(p_uuid->uuid[8]), 2);
+ memcpy(&uuid4, &(p_uuid->uuid[10]), 4);
+ memcpy(&uuid5, &(p_uuid->uuid[14]), 2);
+
+ snprintf((char *)str, BLUETOOTH_UUID_STRING_MAX, "%.8x-%.4x-%.4x-%.4x-%.8x%.4x",
+ ntohl(uuid0), ntohs(uuid1),
+ ntohs(uuid2), ntohs(uuid3),
+ ntohl(uuid4), ntohs(uuid5));
+ return;
+}
+
+/* Trim string at first non-utf8 char */
+void _bt_truncate_non_utf8_chars(char * str)
+{
+ guint i=0;
+ const char *ptr = NULL;
+
+ if (strlen(str) != 0) {
+ if (!g_utf8_validate(str, -1, &ptr)) {
+ while(*(str + i) != *ptr)
+ i++;
+ *(str + i) = '\0';
+ }
+ }
+}
#include "bt-service-event-receiver.h"
_bt_service_event_handler_callback adapter_cb;
+_bt_service_event_handler_callback device_cb;
void _bt_service_register_event_handler_callback(
bt_service_module_t module, _bt_service_event_handler_callback cb)
BT_INFO("Register BT_ADAPTER_MODULE Callback");
adapter_cb = cb;
break;
+ case BT_DEVICE_MODULE:
+ BT_INFO("Register BT_DEVICE_MODULE Callback");
+ device_cb = cb;
+ break;
default:
BT_INFO("Unknown module");
}
case OAL_EVENT_ADAPTER_MODE_CONNECTABLE:
case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE:
case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT:
+ case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
+ case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
+ case OAL_EVENT_ADAPTER_INQUIRY_RESULT_BREDR_ONLY:
+ case OAL_EVENT_ADAPTER_INQUIRY_RESULT_BLE:
if (adapter_cb)
adapter_cb(event_type, event_data);
+ if (device_cb)
+ device_cb(event_type, event_data);
break;
default:
BT_ERR("Unhandled Event: %d", event_type);
--- /dev/null
+/*
+ * Copyright (c) 2015 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#include <stdio.h>
+#include <gio/gio.h>
+#include <glib.h>
+#include <dlog.h>
+#include <string.h>
+#include <vconf.h>
+#include <vconf-internal-keys.h>
+#include <syspopup_caller.h>
+#include <aul.h>
+#include <eventsystem.h>
+#include <bundle_internal.h>
+
+/*bt-service headers */
+#include "bt-internal-types.h"
+#include "bt-service-common.h"
+#include "bt-service-util.h"
+#include "bt-service-main.h"
+#include "bt-service-core-device.h"
+#include "bt-service-core-adapter.h"
+#include "bt-service-event-receiver.h"
+#include "bt-request-handler.h"
+#include "bt-service-event.h"
+
+/* OAL headers */
+#include <oal-event.h>
+#include <oal-manager.h>
+#include <oal-adapter-mgr.h>
+
+/* Forward declaration */
+static void __bt_device_event_handler(int event_type, gpointer event_data);
+static void __bt_device_remote_device_found_callback(gpointer event_data, gboolean is_ble);
+
+
+void _bt_device_state_handle_callback_set_request(void)
+{
+ _bt_service_register_event_handler_callback(
+ BT_DEVICE_MODULE, __bt_device_event_handler);
+}
+
+static void __bt_device_event_handler(int event_type, gpointer event_data)
+{
+ int eventcheck = OAL_EVENT_DEVICE_PROPERTIES;
+ BT_INFO("event [%d] Event check = [%d]", event_type, eventcheck);
+
+ switch(event_type) {
+ case OAL_EVENT_ADAPTER_INQUIRY_RESULT_BREDR_ONLY:
+ {
+ BT_INFO("BREDR Device Found");
+ __bt_device_remote_device_found_callback(event_data, FALSE);
+ break;
+ }
+ case OAL_EVENT_ADAPTER_INQUIRY_RESULT_BLE:
+ {
+ BT_INFO("Dual Device Found");
+ __bt_device_remote_device_found_callback(event_data, FALSE);
+ break;
+ }
+ default:
+ BT_INFO("Unhandled event..");
+ }
+}
+
+static void __bt_device_remote_device_found_callback(gpointer event_data, gboolean is_ble)
+{
+ BT_INFO("+");
+ bt_remote_dev_info_t *dev_info = NULL;
+ int result = BLUETOOTH_ERROR_NONE;
+
+ ret_if(_bt_is_discovering() == FALSE);
+ ret_if(event_data == NULL);
+
+ dev_info = g_malloc0(sizeof(bt_remote_dev_info_t));
+ memset(dev_info, 0x00, sizeof(bt_remote_dev_info_t));
+
+ if(is_ble) {
+ event_ble_dev_found_t * oal_ble_dev = event_data;
+ BT_INFO("Device type [%d]",oal_ble_dev->device_info.type);
+
+ _bt_copy_remote_dev(dev_info, &oal_ble_dev->device_info);
+
+ dev_info->manufacturer_data_len = oal_ble_dev->adv_len;
+ if(dev_info->manufacturer_data_len)
+ dev_info->manufacturer_data = g_memdup(oal_ble_dev->adv_data, dev_info->manufacturer_data_len);
+ else
+ dev_info->manufacturer_data = NULL;
+ BT_DBG("----Advertising Data Length: %d",dev_info->manufacturer_data_len);
+ } else {
+ event_dev_found_t * oal_dev = event_data;
+ _bt_copy_remote_dev(dev_info, &oal_dev->device_info);
+ }
+
+ if (dev_info) {
+ GVariant *param = NULL;
+ if (dev_info->name == NULL)
+ /* If Remote device name is NULL or still RNR is not done
+ * then display address as name.
+ */
+ dev_info->name = g_strdup(dev_info->address);
+ BT_DBG("Name %s", dev_info->name);
+ GVariant *uuids = NULL;
+ GVariantBuilder *builder = NULL;
+ int i = 0;
+ builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
+ for (i=0; i < dev_info->uuid_count; i++) {
+ g_variant_builder_add(builder, "s",
+ dev_info->uuids[i]);
+ }
+ uuids = g_variant_new("as", builder);
+ g_variant_builder_unref(builder);
+ GVariant *manufacturer_data = NULL;
+ manufacturer_data = g_variant_new_from_data(G_VARIANT_TYPE_BYTESTRING,
+ dev_info->manufacturer_data,
+ dev_info->manufacturer_data_len,
+ TRUE,
+ NULL, NULL);
+ param = g_variant_new("(isunsbub@asn@ay)", result,
+ dev_info->address,
+ dev_info->class,
+ dev_info->rssi,
+ dev_info->name,
+ dev_info->paired,
+ dev_info->connected,
+ dev_info->trust,
+ uuids,
+ dev_info->manufacturer_data_len,
+ manufacturer_data);
+
+ _bt_send_event(BT_ADAPTER_EVENT,
+ BLUETOOTH_EVENT_REMOTE_DEVICE_FOUND,
+ param);
+ }
+ BT_DBG("-");
+}
#include <gio/gio.h>
#include "bluetooth-api.h"
+#include <oal-manager.h>
#ifdef __cplusplus
extern "C" {
int _bt_eventsystem_set_value(const char *event, const char *key, const char *value);
+void _bt_copy_remote_dev(bt_remote_dev_info_t * dev_info, remote_device_t * oal_device);
+
+void _bt_uuid_to_string(service_uuid_t *p_uuid, char *str);
+
+void _bt_truncate_non_utf8_chars(char * str);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
int _bt_disable_adapter(void);
+int _bt_start_discovery(void);
+
+int _bt_cancel_discovery(void);
+
+gboolean _bt_is_discovering(void);
+
int _bt_stack_init(void);
int _bt_get_local_address(void);
--- /dev/null
+/*
+ * Copyright (c) 2015 - 2016 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Anupam Roy <anupam.r@samsung.com>
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+#ifndef _BT_SERVICE_CORE_DEVICE_H_
+#define _BT_SERVICE_CORE_DEVICE_H_
+
+#include <sys/types.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void _bt_device_state_handle_callback_set_request(void);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+#endif /*_BT_SERVICE_CORE_ADAPTER_H_*/
+
typedef enum {
BT_ADAPTER_MODULE,
+ BT_DEVICE_MODULE,
} bt_service_module_t;
void _bt_service_oal_event_receiver(int event_type, gpointer event_data, gsize len);