int ret = BLUETOOTH_ERROR_NONE;
BT_INFO("+");
+ BT_CHECK_ENABLED(return);
BT_INIT_PARAMS();
BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
int ret = BLUETOOTH_ERROR_NONE;
BT_INFO("+");
+ BT_CHECK_ENABLED(return);
BT_INIT_PARAMS();
BT_ALLOC_PARAMS(in_param1, in_param2, in_param3, in_param4, out_param);
BT_ERR("Error returned in method call");
if (err) {
BT_ERR("Error = %s", err->message);
- if (strcmp(err->message, BT_ERROR_ALREADY_EXIST) == 0)
+ g_dbus_error_strip_remote_error(err);
+ if (g_strrstr(err->message, BT_ERROR_ALREADY_EXIST))
ret = BLUETOOTH_ERROR_IN_PROGRESS;
else
ret = BLUETOOTH_ERROR_INTERNAL;
BT_ERR("Error returned in method call");
if (err) {
BT_ERR("Error = %s", err->message);
- if (strcmp(err->message, BT_ERROR_NOT_AVAILABLE) == 0)
+ g_dbus_error_strip_remote_error(err);
+ if (g_strrstr(err->message, BT_ERROR_NOT_AVAILABLE))
ret = BLUETOOTH_ERROR_NOT_IN_OPERATION;
else
ret = BLUETOOTH_ERROR_INTERNAL;
if ((g_strcmp0(name, "org.bluez") == 0) ||
(g_strcmp0(name, "org.projectx.bt") == 0)) {
- BT_DBG("%s is terminated", name);
+ BT_INFO("%s is terminated", name);
if (_bt_check_terminating_condition() == TRUE && factory_test_mode == FALSE) {
_bt_disable_adapter();
_bt_disable_adapter_le();
uint8_t token[8];
} __attribute__((packed));
+#define HAL_EV_MESH_NETWORK_PROXY_ADDED 0xDF
+struct hal_ev_mesh_network_proxy_added {
+ uint8_t status;
+ uint8_t uuid[16];
+ uint8_t token[8];
+} __attribute__((packed));
+
+
#endif //_BT_HAL_MSG_H_
return BT_STATUS_SUCCESS;
}
+static int __bt_hal_parse_service_data(int len, char *src, uint8_t *dest)
+{
+ int total_service_len = len;
+ int service_data_len = 0;
+ char *ptr = NULL;
+ int idx = 0;
+
+ if (src == NULL || dest == NULL)
+ return 0;
+
+ ptr = src;
+
+ while (total_service_len) {
+ /* parse length1 + service_data1 + length2 + service data2*/
+ service_data_len = ptr[0];
+
+ dest[idx] = 1 + service_data_len;
+ dest[idx + 1] = 0x16; /* Fixed */
+ memcpy(dest + idx + 2, ptr +1, service_data_len);
+ idx = idx + 2 + service_data_len;
+
+ ptr = ptr + service_data_len + 1;
+ total_service_len = total_service_len - service_data_len - 1;
+ }
+
+ return idx;
+}
+
+
/* Takes care of both Scan Response and Advertising data */
int _bt_hal_set_advertising_data(btgatt_adv_param_setup_t adv_param_setup)
{
/* Service Data UUID*/
if (adv_param_setup.service_data_len > 0) {
- adv_data[index] = 1 + adv_param_setup.service_data_len;
- adv_data[index+1] = 0x16; /* Fixed */
- memcpy(&adv_data[index+2], adv_param_setup.service_data, adv_param_setup.service_data_len);
- index += (2 + adv_param_setup.service_data_len);
- length += (2 + adv_param_setup.service_data_len);
- DBG("After Service data: Index [%d]", index);
+ int l = 0;
+ l = __bt_hal_parse_service_data(adv_param_setup.service_data_len,
+ adv_param_setup.service_data, &adv_data[index]);
+
+ index = index + l;
+ length = length + l;
}
/* Set Apperance */
g_dbus_error_strip_remote_error(error);
ERR("StopLEDiscovery Fail: %s", error->message);
+#if 0
/* Abnormal case for ARTIK530 */
if (g_strrstr(error->message, "No discovery started") ||
g_strrstr(error->message, "Operation already in progress")) {
g_clear_error(&error);
return BT_STATUS_SUCCESS;
}
+#endif
g_clear_error(&error);
return BT_STATUS_FAIL;
}
} else if (!g_strcmp0(key, "LEDiscovering")) {
- GVariant *result;
-
is_le_discovering = g_variant_get_boolean(value);
DBG("##LE Discovering = [%d]", is_le_discovering);
continue;
}
- adapter_proxy = _bt_hal_get_adapter_proxy();
- if (adapter_proxy == NULL) {
- ERR("adapter_proxy == NULL");
- continue;
- }
-
- /* Need to stop searching */
- result = g_dbus_proxy_call_sync(adapter_proxy, "StopLEDiscovery",
- NULL, G_DBUS_CALL_FLAGS_NONE,
- DBUS_TIMEOUT, NULL, &err);
- if (!result) {
- ERR("Error occured in Proxy call");
- if (err) {
- ERR("(Error: %s)", err->message);
- g_clear_error(&err);
- }
- } else {
- g_variant_unref(result);
- }
-
/* Send LE discovering finished event */
size += __bt_insert_hal_properties(buf + size,
HAL_PROP_ADAPTER_LE_DISCOVERY_STOPPED, 0, NULL);
INFO("MESH: Proxy added: %s (%s)\n", interface, path);
if (!strcmp(interface, BT_HAL_MESH_NETWORK_INTERFACE)) {
+ struct hal_ev_mesh_network_proxy_added ev;
INFO("Mesh: Network Proxy added");
+
/* Save Global proxy */
net_proxy = proxy;
if (net_proxy)
INFO("Mesh: Net Proxy [%p]", net_proxy);
+
+ memset(&ev, 0, sizeof(ev));
+ ev.status = BT_STATUS_SUCCESS;
+
+ /* Send event cb */
+ if (mesh_event_cb)
+ mesh_event_cb(HAL_EV_MESH_NETWORK_PROXY_ADDED,
+ (void*)&ev, sizeof(ev));
+
return;
}
(bt_uuid_t*)&ev->uuid);
}
+static void __bt_hal_mesh_network_proxy_added(void *buf, uint16_t len)
+{
+ struct hal_ev_mesh_network_proxy_added *ev = buf;
+ if (bt_hal_mesh_cbacks->network_proxy_added_cb)
+ bt_hal_mesh_cbacks->network_proxy_added_cb(ev->status);
+}
+
static void __bt_hal_handle_network_scan_result(void *buf, uint16_t len)
{
struct hal_ev_mesh_scan_result *ev = buf;
return;
switch (message) {
+ case HAL_EV_MESH_NETWORK_PROXY_ADDED:
+ DBG("Mesh Event: HAL_EV_MESH_NETWORK_PROXY_ADDED");
+ __bt_hal_mesh_network_proxy_added(buf, len);
+ break;
case HAL_EV_MESH_NETWORK_ATTACHED:
DBG("Mesh Event: HAL_EV_MESH_NETWORK_ATTACHED");
__bt_hal_mesh_network_attached(buf, len);
} bt_mesh_key_op_e;
/** Callback Signatures */
+typedef void (*btmesh_network_proxy_added_callback)(bt_status_t status);
+
typedef void (*btmesh_network_attached_callback)(bt_status_t status,
bt_mesh_token_t *token, bt_uuid_t *uuid);
typedef struct {
/** set to sizeof(btmesh_callbacks_t) */
size_t size;
+ btmesh_network_proxy_added_callback network_proxy_added_cb;
btmesh_network_attached_callback network_attached_cb;
btmesh_network_destroyed_callback network_destroyed_cb;
btmesh_network_scan_status_callback scan_status_cb;
EVENT(OAL_EVENT_GATTC_EXECUTE_WRITE) /* gattc execute write */\
EVENT(OAL_EVENT_GATTS_REQUEST_ACQUIRE_WRITE) /* gattc acquire write */\
EVENT(OAL_EVENT_GATTS_REQUEST_ACQUIRE_NOTIFY) /* gattc acquire notify */\
+ EVENT(OAL_EVENT_MESH_NETWORK_PROXY_ADDED) /* mesh network proxy_added */\
EVENT(OAL_EVENT_MESH_NETWORK_ATTACHED) /* mesh network attached */\
EVENT(OAL_EVENT_MESH_NETWORK_DESTROYED) /* mesh network destroyed */\
EVENT(OAL_EVENT_MESH_SCAN_STARTED) /* mesh network scan start status */\
typedef struct {
oal_status_t status;
+} event_mesh_network_proxy_added_t;
+
+typedef struct {
+ oal_status_t status;
uint8_t token[8];
oal_uuid_t uuid;
} event_mesh_network_attached_t;
int ret = OAL_STATUS_SUCCESS;
- API_TRACE("Scan is stopped");
+ API_TRACE("BTGATT CLIENT SCAN STOP");
CHECK_OAL_GATT_ENABLED();
CHECK_CLIENT_REGISTRATION(client_id);
ret = gatt_api->client->scan(client_id, 0);
{
int ret;
- API_TRACE("Scan is stopped");
+ API_TRACE("GATT client set le scan param");
CHECK_OAL_GATT_ENABLED();
#ifdef TIZEN_BT_HAL
} while (0)
/* Forward declaration: Callbacks from HAL */
+static void mesh_network_proxy_added_callback(bt_status_t status);
static void mesh_network_attached_callback(bt_status_t status,
bt_mesh_token_t *token, bt_uuid_t *uuid);
static void mesh_network_destroyed_callback(bt_status_t status,
static btmesh_callbacks_t sBluetoothMeshCallbacks = {
.size = sizeof(sBluetoothMeshCallbacks),
+ .network_proxy_added_cb = mesh_network_proxy_added_callback,
.network_attached_cb = mesh_network_attached_callback,
.network_destroyed_cb = mesh_network_destroyed_callback,
.scan_status_cb = mesh_network_scan_status_callback,
};
/* Mesh HAL event handlers */
+static void mesh_network_proxy_added_callback(bt_status_t status)
+{
+ event_mesh_network_proxy_added_t *event = g_new0(event_mesh_network_proxy_added_t, 1);
+
+ event->status = convert_to_oal_status(status);
+ BT_INFO("Mesh Event: Network Proxy Added, status: [%s]",
+ status2string(status));
+
+ send_event_bda_trace(OAL_EVENT_MESH_NETWORK_PROXY_ADDED,
+ event, sizeof(event_mesh_network_proxy_added_t), NULL);
+}
+
static void mesh_network_attached_callback(bt_status_t status,
bt_mesh_token_t *token, bt_uuid_t *uuid)
{
static GSList *scanner_list = NULL;
static gboolean is_le_set_scan_parameter = FALSE;
static gboolean is_le_scanning = FALSE;
+static gboolean is_le_scan_hold = FALSE;
static gboolean scan_filter_enabled = FALSE;
+static gboolean scan_stop_requested = FALSE;
static bluetooth_le_scan_params_t le_scan_params = { BT_LE_ACTIVE_SCAN, 0, 0 };
return adapter_le_state;
}
+void _bt_set_le_scan_stop_requested(gboolean request)
+{
+ scan_stop_requested = request;
+}
+
+gboolean _bt_is_le_scan_stop_requested(void)
+{
+ return scan_stop_requested;
+}
/* Internal functions of core adapter service */
static void __bt_le_handle_pending_requests(int service_function, void *user_data, unsigned int size)
break;
}
+ if (_bt_is_le_scan_stop_requested() == FALSE) {
+ int ret = gattc_start_le_discovery(g_gatt_client_id);
+ if (OAL_STATUS_SUCCESS != ret)
+ BT_ERR("gattc_start_le_discovery failed");
+ break;
+ }
+
+ _bt_set_le_scan_stop_requested(FALSE);
+ if (is_le_scan_hold == TRUE)
+ break;
__bt_set_le_scan_status(FALSE);
_bt_disable_all_scanner_status();
__bt_adapter_le_handle_pending_request_info(
return BLUETOOTH_ERROR_NONE;
}
+void print_adv_data(unsigned char * adv_data, int len)
+{
+ char adv_data_str[(31 * 2) + 1];
+
+ for (int i = 0; i < len ; i++)
+ snprintf(&adv_data_str[i * 2], 3, "%02X", adv_data[i]);
+
+ BT_INFO("data: [%s]", adv_data_str);
+}
+
+
static int __bt_set_multi_adv_param(oal_ble_multi_adv_param_setup_t *adv_setup,
bluetooth_advertising_data_t *adv_data, int length)
{
break;
}
case 0x16: { /* Service Data */
- adv_setup->service_data = g_malloc0(sizeof(char) * (len - 1));
- memcpy(adv_setup->service_data, (ptr + 2), (len - 1));
- adv_setup->service_data_len = len - 1;
+ if (adv_setup->service_data == NULL) {
+ /* first service data */
+ adv_setup->service_data = g_malloc0(sizeof(char) * (len));
+ adv_setup->service_data[0] = len -1; /*length1 + service_data1*/
+ memcpy(adv_setup->service_data + 1, (ptr + 2), (len - 1));
+ adv_setup->service_data_len = len;
+ } else {
+ /* Next service data */
+ char *prev_service_data = adv_setup->service_data;
+ int prev_service_len = adv_setup->service_data_len;
+
+ /* create new memory */
+ adv_setup->service_data = g_malloc0(sizeof(char) * (len + prev_service_len));
+ memcpy(adv_setup->service_data, prev_service_data, prev_service_len);
+ adv_setup->service_data[prev_service_len] = len -1; /*length2 + service_data2*/
+ memcpy(adv_setup->service_data + prev_service_len + 1, (ptr + 2), (len - 1));
+
+ adv_setup->service_data_len = prev_service_len + len;
+
+ /* remove the existing memory */
+ g_free(prev_service_data);
+ }
+ BT_INFO("service data is packed:");
+ print_adv_data((unsigned char *)adv_setup->service_data, adv_setup->service_data_len);
break;
}
case 0x21: {
return _bt_convert_oal_status_to_bt_error(ret);
}
- is_le_set_scan_parameter = TRUE;
-
BT_INFO("Set scan parameters inteval %f, win %f, type %d",
itv * BT_SCAN_INTERVAL_SPLIT, win * BT_SCAN_INTERVAL_SPLIT, params->type);
} else {
if (is_le_set_scan_parameter == FALSE) {
/* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
- bluetooth_le_scan_params_t scan_params;
- scan_params.type = BT_LE_ACTIVE_SCAN;
- scan_params.interval = 5120;
- scan_params.window = 512;
- _bt_set_scan_parameters(&scan_params);
- } else
- _bt_set_scan_parameters(&le_scan_params);
+ le_scan_params.type = BT_LE_ACTIVE_SCAN;
+ le_scan_params.interval = 5120;
+ le_scan_params.window = 512;
+ is_le_set_scan_parameter = TRUE;
+ }
+ _bt_set_scan_parameters(&le_scan_params);
/* Enable scan filter if filter is exisiting */
if (scanner->filter_list == NULL) {
if (OAL_STATUS_SUCCESS != ret) {
BT_ERR("gattc_start_le_discovery failed");
- return _bt_convert_oal_status_to_bt_error(ret);
+ goto fail;
}
return BLUETOOTH_ERROR_NONE;
+
+fail:
+ _bt_unregister_all_scan_filters(sender);
+ scanner_list = g_slist_remove(scanner_list, scanner);
+ __bt_free_le_scanner(scanner);
+ return BLUETOOTH_ERROR_INTERNAL;
}
int _bt_stop_le_scan(const char *sender)
g_idle_add(__send_le_scan_reply, (void *)(intptr_t)value);
result = BLUETOOTH_ERROR_NONE;
} else {
- BT_INFO("Just stop LE scan");
- ret = gattc_stop_le_discovery(g_gatt_client_id);
-
- if (OAL_STATUS_SUCCESS != ret) {
- BT_ERR("gattc_start_le_discovery failed");
- result = _bt_convert_oal_status_to_bt_error(ret);
+ if (is_le_scan_hold == TRUE) {
+ BT_INFO("Just remove LE scan hold info");
+ _bt_set_le_scan_stop_requested(FALSE);
+ is_le_scan_hold = FALSE;
+ result = BLUETOOTH_ERROR_INTERNAL;
+ } else {
+ BT_INFO("Just stop LE scan");
+ ret = gattc_stop_le_discovery(g_gatt_client_id);
+ if (OAL_STATUS_SUCCESS == ret) {
+ _bt_set_le_scan_stop_requested(TRUE);
+ } else {
+ BT_ERR("gattc_stop_le_discovery failed");
+ result = BLUETOOTH_ERROR_INTERNAL;
+ }
}
// TODO: Disable scan filter
return result;
}
+void _bt_hold_le_scan(void)
+{
+ int ret;
+
+ if (_bt_is_le_scanning() == FALSE)
+ return;
+
+ BT_INFO("Hold le scan");
+
+ ret = gattc_stop_le_discovery(g_gatt_client_id);
+ if (OAL_STATUS_SUCCESS == ret) {
+ _bt_set_le_scan_stop_requested(TRUE);
+ is_le_scan_hold = TRUE;
+ } else
+ BT_ERR("gattc_stop_le_discovery failed");
+
+ if (scan_filter_enabled == TRUE) {
+ ret = gattc_disable_scan_filter(0);
+ if (ret != OAL_STATUS_SUCCESS)
+ BT_ERR("gattc_disable_scan_filter failed");
+ }
+}
+
+void _bt_restart_le_scan(void)
+{
+ int ret;
+
+ if (is_le_scan_hold == FALSE)
+ return;
+ is_le_scan_hold = FALSE;
+ if (_bt_is_le_scanning() == FALSE)
+ return;
+
+ BT_INFO("Restart le scan");
+
+ if (is_le_set_scan_parameter == FALSE) {
+ /* Set default scan parameter same with BT_ADAPTER_LE_SCAN_MODE_LOW_ENERGY */
+ le_scan_params.type = BT_LE_ACTIVE_SCAN;
+ le_scan_params.interval = 5120;
+ le_scan_params.window = 512;
+ is_le_set_scan_parameter = TRUE;
+ }
+ _bt_set_scan_parameters(&le_scan_params);
+
+ if (scan_filter_enabled == TRUE) {
+ ret = gattc_enable_scan_filter(0);
+ if (ret != OAL_STATUS_SUCCESS)
+ BT_ERR("gattc_enable_scan_filter failed");
+ }
+
+ ret = gattc_start_le_discovery(g_gatt_client_id);
+ if (OAL_STATUS_SUCCESS != ret)
+ BT_ERR("gattc_start_le_discovery failed");
+}
+
static void _bt_disable_all_scanner_status(void)
{
GSList *l;
if (adapter_le_cb)
adapter_le_cb(event_type, event_data);
break;
+ case OAL_EVENT_MESH_NETWORK_PROXY_ADDED:
case OAL_EVENT_MESH_NETWORK_ATTACHED:
case OAL_EVENT_MESH_NETWORK_DESTROYED:
case OAL_EVENT_MESH_SCAN_STARTED:
return gattc_conn_param_update(&dev_addr, min, max, latency, to);
}
+int _bt_le_set_default_connection_param(const char *address,
+ float interval_min, float interval_max,
+ guint16 latency, guint16 time_out)
+{
+ return __bt_le_set_conn_parameter(address, interval_min, interval_max, latency, time_out);
+}
+
int _bt_remove_le_conn_param_info(const char *address, const char *sender)
{
bt_connected_le_dev_t *dev = NULL;
BT_ERR("Local GATT Client connected event for addr[%s], but device is in connected list already", address);
__bt_add_mtu_gatt_device(address);
+
+ _bt_le_set_default_connection_param(address, 30, 35, 0, 6000);
} else
BT_ERR("GATT Client Connection failed!!");
outgoing_gatt_conn_list = g_slist_remove(outgoing_gatt_conn_list, out_conn_info);
g_free(out_conn_info->addr);
g_free(out_conn_info);
+
+ _bt_restart_le_scan();
}
g_free(address);
}
}
/* TODO Check Requirement of holding Advertisement before initiating LE connect */
+ _bt_hold_le_scan();
/* Check if app sent 0 client id for connection, in such case, use default gatt client ID */
if (client_id == 0) {
if (ret != OAL_STATUS_SUCCESS) {
BT_ERR("gattc_connect is failed. ret: %d", ret);
g_free(addr);
+ _bt_restart_le_scan();
return _bt_convert_oal_status_to_bt_error(ret);
}
int _bt_stop_le_scan(const char *sender);
+void _bt_hold_le_scan(void);
+
+void _bt_restart_le_scan(void);
+
int _bt_set_scan_parameters(bluetooth_le_scan_params_t *params);
int _bt_prepare_scan_parameters(bluetooth_le_scan_params_t *params, int scan_type);
float interval_min, float interval_max,
guint16 latency, guint16 time_out);
+int _bt_le_set_default_connection_param(const char *address,
+ float interval_min, float interval_max,
+ guint16 latency, guint16 time_out);
+
#ifdef TIZEN_FEATURE_BT_OBEX
bluetooth_trusted_profile_t _bt_get_trusted_profile_enum(const char *uuid);
#endif
_bt_mesh_msg_handler(event);
}
+static void __handle_mesh_network_proxy_added_event(
+ event_mesh_network_proxy_added_t *event)
+{
+ int result = BLUETOOTH_ERROR_NONE;
+
+ if (event->status != OAL_STATUS_SUCCESS)
+ result = BLUETOOTH_ERROR_INTERNAL;
+
+ /* Handle DBUS Context return */
+ BT_INFO("Mesh: Handle DBUS Context return");
+ __bt_mesh_handle_pending_request_info(result,
+ BT_MESH_INIT,
+ NULL, 0);
+}
+
static void __handle_mesh_network_attached_event(
event_mesh_network_attached_t *event)
{
BT_INFO("Mesh: Provisioning started event");
switch (event_type) {
+ case OAL_EVENT_MESH_NETWORK_PROXY_ADDED:
+ __handle_mesh_network_proxy_added_event(
+ (event_mesh_network_proxy_added_t*)event_data);
+ BT_PERMANENT_LOG("Mesh: Network proxy added!!");
+ break;
case OAL_EVENT_MESH_NETWORK_ATTACHED:
__handle_mesh_network_attached_event(
(event_mesh_network_attached_t*)event_data);
BLUETOOTH_ERROR_ALREADY_INITIALIZED != ret)
BT_ERR("Mesh: Mesh enable failed: %d", ret);
- /* Handle DBUS Context return */
- BT_INFO("Mesh: Handle DBUS Context return");
- __bt_mesh_handle_pending_request_info(ret,
- BT_MESH_INIT,
- NULL, 0);
-
/* Reset launch timer ID */
BT_INFO("Mesh: Timer ID after expiry [%u]", launch_timer);
launch_timer = 0;