2 * Copyright (c) 2015 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Contact: Anupam Roy <anupam.r@samsung.com>
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
26 #include <vconf-internal-keys.h>
27 #include <syspopup_caller.h>
29 #include <eventsystem.h>
30 #include <bundle_internal.h>
32 /*bt-service headers */
33 #include "bt-internal-types.h"
34 #include "bt-service-common.h"
35 #include "bt-service-util.h"
36 #include "bt-service-main.h"
37 #include "bt-service-core-adapter.h"
38 #include "bt-service-event-receiver.h"
39 #include "bt-request-handler.h"
40 #include "bt-service-event.h"
43 #include <oal-event.h>
44 #include <oal-manager.h>
45 #include <oal-adapter-mgr.h>
47 #define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
49 /*This file will contain state machines related to adapter and remote device */
51 /* Global variables */
52 static guint timer_id = 0;
54 /* Adapter default states */
55 static bt_status_t adapter_state = BT_DEACTIVATED;
56 static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
58 /* Forward declarations */
59 static void __bt_adapter_event_handler(int event_type, gpointer event_data);
60 static void __bt_post_oal_init(void);
61 static void __bt_handle_oal_initialisation(oal_event_t event);
62 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size);
63 static gboolean __bt_adapter_post_set_enabled(gpointer user_data);
64 static gboolean __bt_adapter_post_set_disabled(gpointer user_data);
65 static void __bt_adapter_update_bt_enabled(void);
66 static void __bt_adapter_update_bt_disabled(void);
67 static void __bt_adapter_state_set_status(bt_status_t status);
68 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
69 static void __bt_adapter_state_change_callback(int bt_status);
70 static int __bt_adapter_state_handle_request(gboolean enable);
73 /* Initialize BT stack (Initialize OAL layer) */
74 int _bt_stack_init(void)
78 BT_INFO("[bt-service] Start to initialize BT stack");
79 /* Adapter enable request is successful, setup event handlers */
80 _bt_service_register_event_handler_callback(
81 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
83 ret = oal_bt_init(_bt_service_oal_event_receiver);
85 if (OAL_STATUS_PENDING == ret) {
86 BT_INFO("OAL Initialisation Pending, Profiles Init will be done once oal initialised...");
87 return BLUETOOTH_ERROR_NONE;
88 } else if (OAL_STATUS_SUCCESS != ret) {
89 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
90 return BLUETOOTH_ERROR_INTERNAL;
94 return BLUETOOTH_ERROR_NONE;
97 int _bt_enable_adapter(void)
99 return __bt_adapter_state_handle_request(TRUE);
102 int _bt_disable_adapter(void)
104 return __bt_adapter_state_handle_request(FALSE);
107 int _bt_get_local_address(void)
113 result = adapter_get_address();
114 if (result != OAL_STATUS_SUCCESS) {
115 BT_ERR("adapter_get_address failed: %d", result);
116 result = BLUETOOTH_ERROR_INTERNAL;
118 result = BLUETOOTH_ERROR_NONE;
124 int _bt_get_local_version(void)
129 result = adapter_get_version();
130 if (result != OAL_STATUS_SUCCESS) {
131 BT_ERR("adapter_get_address failed: %d", result);
132 result = BLUETOOTH_ERROR_INTERNAL;
134 result = BLUETOOTH_ERROR_NONE;
140 int _bt_get_local_name(void)
146 result = adapter_get_name();
147 if (result != OAL_STATUS_SUCCESS) {
148 BT_ERR("adapter_get_name failed: %d", result);
149 result = BLUETOOTH_ERROR_INTERNAL;
151 result = BLUETOOTH_ERROR_NONE;
157 int _bt_get_discoverable_mode(int *mode)
164 retv_if(NULL == mode, BLUETOOTH_ERROR_INVALID_PARAM);
166 adapter_is_discoverable(&scan_mode);
167 if (TRUE == scan_mode) {
168 adapter_get_discoverable_timeout(&timeout);
170 *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
172 *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
174 adapter_is_connectable(&scan_mode);
175 if(scan_mode == TRUE)
176 *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
179 * TODO: NON CONNECTABLE is not defined in bluetooth_discoverable_mode_t.
180 * After adding BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE, set mode as
181 * BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE. Until then return error.
183 return BLUETOOTH_ERROR_INTERNAL;
188 return BLUETOOTH_ERROR_NONE;
191 int _bt_is_service_used(void)
197 result = adapter_get_service_uuids();
198 if (result != OAL_STATUS_SUCCESS) {
199 BT_ERR("adapter_get_service_uuids failed: %d", result);
200 result = BLUETOOTH_ERROR_INTERNAL;
202 result = BLUETOOTH_ERROR_NONE;
209 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
214 case OAL_EVENT_OAL_INITIALISED_SUCCESS:
215 case OAL_EVENT_OAL_INITIALISED_FAILED:
216 __bt_handle_oal_initialisation(event_type);
218 case OAL_EVENT_ADAPTER_ENABLED:
219 __bt_adapter_state_change_callback(BT_ACTIVATED);
221 case OAL_EVENT_ADAPTER_DISABLED:
222 __bt_adapter_state_change_callback(BT_DEACTIVATED);
224 case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
225 bt_address_t *bd_addr = event_data;
226 bluetooth_device_address_t local_address;
229 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
230 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
231 local_address.addr[0], local_address.addr[1], local_address.addr[2],
232 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
234 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
235 (void *) &local_address, sizeof(bluetooth_device_address_t));
238 case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
239 char *name = event_data;
240 bluetooth_device_name_t local_name;
242 memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
244 g_strlcpy(local_name.name,
245 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
246 BT_DBG("Adapter Name: %s", local_name.name);
248 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
249 (void *) &local_name, sizeof(bluetooth_device_name_t));
252 case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
253 char *ver = event_data;
254 bluetooth_version_t local_version;
256 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
257 g_strlcpy(local_version.version,
258 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
259 BT_DBG("BT Version: %s", local_version.version);
261 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
262 (void *) &local_version, sizeof(bluetooth_version_t));
265 case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
266 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
269 case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
270 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
273 case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
274 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
277 case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
278 int *timeout = event_data;
280 BT_INFO("Discoverable timeout: [%d]", *timeout);
283 case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
285 service_uuid_t *service_list;
286 event_adapter_services_t *list = event_data;
289 service_list = list->service_list;
290 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
294 BT_ERR("Unhandled event..");
301 /* OAL post initialization handler */
302 static void __bt_post_oal_init(void)
304 BT_DBG("OAL initialized, Init profiles..");
309 /* OAL initialization handler */
310 static void __bt_handle_oal_initialisation(oal_event_t event)
315 case OAL_EVENT_OAL_INITIALISED_SUCCESS:
316 __bt_post_oal_init();
318 case OAL_EVENT_OAL_INITIALISED_FAILED:
319 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
320 g_idle_add(_bt_terminate_service, NULL);
323 BT_ERR("Unknown Event");
328 /* Internal functions of core adapter service */
329 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
333 invocation_info_t *req_info;
336 /* Get method invocation context */
337 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
339 if (req_info == NULL || req_info->service_function != service_function)
342 /* Create out param */
343 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
345 switch(service_function) {
346 case BT_ENABLE_ADAPTER:
347 case BT_DISABLE_ADAPTER: {
348 gboolean done = TRUE;
349 g_array_append_vals(out_param, &done, sizeof(gboolean));
352 case BT_GET_LOCAL_NAME:
353 case BT_GET_LOCAL_ADDRESS:
354 case BT_GET_LOCAL_VERSION:
355 g_array_append_vals(out_param, user_data, size);
357 case BT_IS_SERVICE_USED: {
359 gboolean used = FALSE;
361 char uuid_str[BT_UUID_STRING_SIZE];
362 char *request_uuid = req_info->user_data;
363 service_uuid_t *service_list = user_data;
365 BT_INFO("Check for service uuid: %s", request_uuid);
366 for (i = 0; i < size; i++) {
367 uuid = service_list[i].uuid;
368 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
369 BT_INFO("Adapter Service: [%s]", uuid_str);
370 if (strcasecmp(uuid_str, request_uuid) == 0) {
371 BT_INFO("UUID matched!!");
377 g_array_append_vals(out_param, &used, sizeof(gboolean));
381 BT_ERR("Unknown service function[%d]", service_function);
384 _bt_service_method_return(req_info->context, out_param, req_info->result);
385 g_array_free(out_param, TRUE);
386 /* Now free invocation info for this request*/
387 _bt_free_info_from_invocation_list(req_info);
391 /* Request return handlings */
392 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
394 BT_INFO("__bt_adapter_post_set_enabled>>");
395 /*TODO Get All properties */
396 /* Add Adapter enabled post processing codes */
400 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
402 BT_INFO("_bt_adapter_post_set_disabled>>");
403 /* Add Adapter disabled post processing codes */
407 static void __bt_adapter_update_bt_enabled(void)
409 int result = BLUETOOTH_ERROR_NONE;
410 BT_INFO("_bt_adapter_update_bt_enabled>>");
411 /* Update Bluetooth Status to notify other modules */
412 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
413 BT_ERR("Set vconf failed\n");
415 /* TODO:Add timer function to handle any further post processing */
416 g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
418 /*Return BT_ADAPTER_ENABLE Method invocation context */
419 __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
420 /*Send BT Enabled event to application */
421 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
422 g_variant_new("(i)", result));
425 static void __bt_adapter_update_bt_disabled(void)
427 int result = BLUETOOTH_ERROR_NONE;
428 BT_INFO("_bt_adapter_update_bt_disabled>>");
430 int power_off_status = 0;
433 /* Update the vconf BT status in normal Deactivation case only */
434 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
435 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
437 /* TODO:Add timer function to handle any further post processing */
438 g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
440 /* Return BT_ADAPTER_DISABLE Method invocation context */
441 __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
443 /* Send BT Disabled event to application */
444 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
445 g_variant_new("(i)", result));
449 static void __bt_adapter_state_set_status(bt_status_t status)
451 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
452 adapter_state = status;
455 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
457 BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
458 adapter_discovery_state = status;
461 static void __bt_adapter_state_change_callback(int bt_status)
463 BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
467 __bt_adapter_state_set_status(bt_status);
469 /* Adapter is disabled, unregister event handlers */
470 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
471 //_bt_deinit_device_event_handler();
473 /* Add Adapter disabled post processing codes */
474 __bt_adapter_update_bt_disabled();
477 __bt_adapter_state_set_status(bt_status);
478 /* Add Adapter enabled post processing codes */
480 BT_DBG("g_source is removed");
481 g_source_remove(timer_id);
484 __bt_adapter_update_bt_enabled();
487 BT_ERR("Incorrect Bluetooth adapter state changed status");
492 static int __bt_adapter_state_handle_request(gboolean enable)
494 int result = BLUETOOTH_ERROR_NONE;
497 switch (adapter_state) {
500 BT_INFO("Adapter is currently in activating state, state [%d]",
503 return BLUETOOTH_ERROR_IN_PROGRESS;
505 if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
506 adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
507 /*TODO Stop Discovery*/
508 if (result != OAL_STATUS_SUCCESS)
509 BT_ERR("Discover stop failed: %d", result);
510 __bt_adapter_update_discovery_status(FALSE);
512 result = adapter_disable();
513 if (result != OAL_STATUS_SUCCESS) {
514 BT_ERR("adapter_enable failed: [%d]", result);
515 result = BLUETOOTH_ERROR_INTERNAL;
516 /*TODO: perform if anything more needs to be done to handle failure */
518 /* TODO: To be handled */
519 __bt_adapter_state_set_status(BT_DEACTIVATING);
520 result = BLUETOOTH_ERROR_NONE;
527 BT_INFO("Adapter is currently in activated state, state [%d]",
530 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
532 if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
533 adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
534 /*TODO Stop Discovery*/
535 if (result != OAL_STATUS_SUCCESS)
536 BT_ERR("Discover stop failed: %d", result);
537 __bt_adapter_update_discovery_status(FALSE);
539 result = adapter_disable();
540 if (result != OAL_STATUS_SUCCESS) {
541 BT_ERR("adapter_enable failed: [%d]", result);
542 result = BLUETOOTH_ERROR_INTERNAL;
543 /*TODO: perform if anything more needs to be done to handle failure */
545 /* TODO: To be handled */
546 __bt_adapter_state_set_status(BT_DEACTIVATING);
547 result = BLUETOOTH_ERROR_NONE;
552 case BT_DEACTIVATING:
554 BT_INFO("Adapter is currently in deactivating state, state [%d]",
557 return BLUETOOTH_ERROR_IN_PROGRESS;
560 result = adapter_enable();
561 if (result != OAL_STATUS_SUCCESS) {
562 BT_ERR("adapter_enable failed: [%d]", result);
564 result = BLUETOOTH_ERROR_INTERNAL;
565 /*TODO: perform if anything more needs to be done to handle failure */
567 /* TODO: To be handled */
568 __bt_adapter_state_set_status(BT_ACTIVATING);
569 result = BLUETOOTH_ERROR_NONE;
576 BT_INFO("Adapter is currently in deactivated state, state [%d]",
579 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
581 result = adapter_enable();
582 if (result != OAL_STATUS_SUCCESS) {
583 BT_ERR("adapter_enable failed: [%d]", result);
585 result = BLUETOOTH_ERROR_INTERNAL;
586 /*TODO: perform if anything more needs to be done to handle failure */
588 /* TODO: To be handled */
589 __bt_adapter_state_set_status(BT_ACTIVATING);
590 result = BLUETOOTH_ERROR_NONE;
596 if (enable && result == BLUETOOTH_ERROR_NONE) {
597 /* Adapter enable request is successful, setup event handlers */
598 _bt_service_register_event_handler_callback(
599 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
600 /*TODO Set Device Core Callbacks*/