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 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
196 case OAL_EVENT_OAL_INITIALISED_SUCCESS:
197 case OAL_EVENT_OAL_INITIALISED_FAILED:
198 __bt_handle_oal_initialisation(event_type);
200 case OAL_EVENT_ADAPTER_ENABLED:
201 __bt_adapter_state_change_callback(BT_ACTIVATED);
203 case OAL_EVENT_ADAPTER_DISABLED:
204 __bt_adapter_state_change_callback(BT_DEACTIVATED);
206 case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
207 bt_address_t *bd_addr = event_data;
208 bluetooth_device_address_t local_address;
211 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
212 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
213 local_address.addr[0], local_address.addr[1], local_address.addr[2],
214 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
216 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
217 (void *) &local_address, sizeof(bluetooth_device_address_t));
220 case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
221 char *name = event_data;
222 bluetooth_device_name_t local_name;
224 memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
226 g_strlcpy(local_name.name,
227 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
228 BT_DBG("Adapter Name: %s", local_name.name);
230 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
231 (void *) &local_name, sizeof(bluetooth_device_name_t));
234 case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
235 char *ver = event_data;
236 bluetooth_version_t local_version;
238 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
239 g_strlcpy(local_version.version,
240 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
241 BT_DBG("BT Version: %s", local_version.version);
243 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
244 (void *) &local_version, sizeof(bluetooth_version_t));
247 case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
248 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
251 case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
252 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
255 case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
256 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
259 case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
260 int *timeout = event_data;
262 BT_INFO("Discoverable timeout: [%d]", *timeout);
266 BT_ERR("Unhandled event..");
273 /* OAL post initialization handler */
274 static void __bt_post_oal_init(void)
276 BT_DBG("OAL initialized, Init profiles..");
281 /* OAL initialization handler */
282 static void __bt_handle_oal_initialisation(oal_event_t event)
287 case OAL_EVENT_OAL_INITIALISED_SUCCESS:
288 __bt_post_oal_init();
290 case OAL_EVENT_OAL_INITIALISED_FAILED:
291 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
292 g_idle_add(_bt_terminate_service, NULL);
295 BT_ERR("Unknown Event");
300 /* Internal functions of core adapter service */
301 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
305 invocation_info_t *req_info;
308 /* Get method invocation context */
309 for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
311 if (req_info == NULL || req_info->service_function != service_function)
314 /* Create out param */
315 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
317 switch(service_function) {
318 case BT_ENABLE_ADAPTER:
319 case BT_DISABLE_ADAPTER: {
320 gboolean done = TRUE;
321 g_array_append_vals(out_param, &done, sizeof(gboolean));
324 case BT_GET_LOCAL_NAME:
325 case BT_GET_LOCAL_ADDRESS:
326 case BT_GET_LOCAL_VERSION:
327 g_array_append_vals(out_param, user_data, size);
330 BT_ERR("Unknown service function[%d]", service_function);
333 _bt_service_method_return(req_info->context, out_param, req_info->result);
334 g_array_free(out_param, TRUE);
335 /* Now free invocation info for this request*/
336 _bt_free_info_from_invocation_list(req_info);
340 /* Request return handlings */
341 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
343 BT_INFO("__bt_adapter_post_set_enabled>>");
344 /*TODO Get All properties */
345 /* Add Adapter enabled post processing codes */
349 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
351 BT_INFO("_bt_adapter_post_set_disabled>>");
352 /* Add Adapter disabled post processing codes */
356 static void __bt_adapter_update_bt_enabled(void)
358 int result = BLUETOOTH_ERROR_NONE;
359 BT_INFO("_bt_adapter_update_bt_enabled>>");
360 /* Update Bluetooth Status to notify other modules */
361 if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
362 BT_ERR("Set vconf failed\n");
364 /* TODO:Add timer function to handle any further post processing */
365 g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
367 /*Return BT_ADAPTER_ENABLE Method invocation context */
368 __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
369 /*Send BT Enabled event to application */
370 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
371 g_variant_new("(i)", result));
374 static void __bt_adapter_update_bt_disabled(void)
376 int result = BLUETOOTH_ERROR_NONE;
377 BT_INFO("_bt_adapter_update_bt_disabled>>");
379 int power_off_status = 0;
382 /* Update the vconf BT status in normal Deactivation case only */
383 ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
384 BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
386 /* TODO:Add timer function to handle any further post processing */
387 g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
389 /* Return BT_ADAPTER_DISABLE Method invocation context */
390 __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
392 /* Send BT Disabled event to application */
393 _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
394 g_variant_new("(i)", result));
398 static void __bt_adapter_state_set_status(bt_status_t status)
400 BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
401 adapter_state = status;
404 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
406 BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
407 adapter_discovery_state = status;
410 static void __bt_adapter_state_change_callback(int bt_status)
412 BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
416 __bt_adapter_state_set_status(bt_status);
418 /* Adapter is disabled, unregister event handlers */
419 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
420 //_bt_deinit_device_event_handler();
422 /* Add Adapter disabled post processing codes */
423 __bt_adapter_update_bt_disabled();
426 __bt_adapter_state_set_status(bt_status);
427 /* Add Adapter enabled post processing codes */
429 BT_DBG("g_source is removed");
430 g_source_remove(timer_id);
433 __bt_adapter_update_bt_enabled();
436 BT_ERR("Incorrect Bluetooth adapter state changed status");
441 static int __bt_adapter_state_handle_request(gboolean enable)
443 int result = BLUETOOTH_ERROR_NONE;
446 switch (adapter_state) {
449 BT_INFO("Adapter is currently in activating state, state [%d]",
452 return BLUETOOTH_ERROR_IN_PROGRESS;
454 if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
455 adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
456 /*TODO Stop Discovery*/
457 if (result != OAL_STATUS_SUCCESS)
458 BT_ERR("Discover stop failed: %d", result);
459 __bt_adapter_update_discovery_status(FALSE);
461 result = adapter_disable();
462 if (result != OAL_STATUS_SUCCESS) {
463 BT_ERR("adapter_enable failed: [%d]", result);
464 result = BLUETOOTH_ERROR_INTERNAL;
465 /*TODO: perform if anything more needs to be done to handle failure */
467 /* TODO: To be handled */
468 __bt_adapter_state_set_status(BT_DEACTIVATING);
469 result = BLUETOOTH_ERROR_NONE;
476 BT_INFO("Adapter is currently in activated state, state [%d]",
479 return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
481 if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
482 adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
483 /*TODO Stop Discovery*/
484 if (result != OAL_STATUS_SUCCESS)
485 BT_ERR("Discover stop failed: %d", result);
486 __bt_adapter_update_discovery_status(FALSE);
488 result = adapter_disable();
489 if (result != OAL_STATUS_SUCCESS) {
490 BT_ERR("adapter_enable failed: [%d]", result);
491 result = BLUETOOTH_ERROR_INTERNAL;
492 /*TODO: perform if anything more needs to be done to handle failure */
494 /* TODO: To be handled */
495 __bt_adapter_state_set_status(BT_DEACTIVATING);
496 result = BLUETOOTH_ERROR_NONE;
501 case BT_DEACTIVATING:
503 BT_INFO("Adapter is currently in deactivating state, state [%d]",
506 return BLUETOOTH_ERROR_IN_PROGRESS;
509 result = adapter_enable();
510 if (result != OAL_STATUS_SUCCESS) {
511 BT_ERR("adapter_enable failed: [%d]", result);
513 result = BLUETOOTH_ERROR_INTERNAL;
514 /*TODO: perform if anything more needs to be done to handle failure */
516 /* TODO: To be handled */
517 __bt_adapter_state_set_status(BT_ACTIVATING);
518 result = BLUETOOTH_ERROR_NONE;
525 BT_INFO("Adapter is currently in deactivated state, state [%d]",
528 return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
530 result = adapter_enable();
531 if (result != OAL_STATUS_SUCCESS) {
532 BT_ERR("adapter_enable failed: [%d]", result);
534 result = BLUETOOTH_ERROR_INTERNAL;
535 /*TODO: perform if anything more needs to be done to handle failure */
537 /* TODO: To be handled */
538 __bt_adapter_state_set_status(BT_ACTIVATING);
539 result = BLUETOOTH_ERROR_NONE;
545 if (enable && result == BLUETOOTH_ERROR_NONE) {
546 /* Adapter enable request is successful, setup event handlers */
547 _bt_service_register_event_handler_callback(
548 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
549 /*TODO Set Device Core Callbacks*/