[Adapt] Implement set adapter properties APIs
[platform/core/connectivity/bluetooth-frwk.git] / bt-service-adaptation / services / adapter / bt-service-core-adapter.c
1 /*
2  * Copyright (c) 2015 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Contact: Anupam Roy <anupam.r@samsung.com>
5  *
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
9  *
10  *              http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  *
18  */
19
20 #include <stdio.h>
21 #include <gio/gio.h>
22 #include <glib.h>
23 #include <dlog.h>
24 #include <string.h>
25 #include <vconf.h>
26 #include <vconf-internal-keys.h>
27 #include <syspopup_caller.h>
28 #include <aul.h>
29 #include <eventsystem.h>
30 #include <bundle_internal.h>
31
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-core-device.h"
39 #include "bt-service-event-receiver.h"
40 #include "bt-request-handler.h"
41 #include "bt-service-event.h"
42
43 /* OAL headers */
44 #include <oal-event.h>
45 #include <oal-manager.h>
46 #include <oal-adapter-mgr.h>
47
48 #define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
49
50 /*This file will contain state machines related to adapter and remote device */
51
52 /* Global variables */
53 static guint timer_id = 0;
54
55 /* Adapter default states */
56 static bt_status_t adapter_state = BT_DEACTIVATED;
57 static bt_adapter_discovery_state_t adapter_discovery_state = ADAPTER_DISCOVERY_STOPPED;
58
59 /* Forward declarations */
60 static void __bt_adapter_event_handler(int event_type, gpointer event_data);
61 static void __bt_post_oal_init(void);
62 static void __bt_handle_oal_initialisation(oal_event_t event);
63 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size);
64 static gboolean __bt_adapter_post_set_enabled(gpointer user_data);
65 static gboolean __bt_adapter_post_set_disabled(gpointer user_data);
66 static void __bt_adapter_update_bt_enabled(void);
67 static void __bt_adapter_update_bt_disabled(void);
68 static void __bt_adapter_state_set_status(bt_status_t status);
69 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status);
70 static void __bt_adapter_state_change_callback(int bt_status);
71 static int __bt_adapter_state_handle_request(gboolean enable);
72 static int __bt_adapter_state_discovery_request(gboolean enable);
73 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status);
74
75 /* Initialize BT stack (Initialize OAL layer) */
76 int _bt_stack_init(void)
77 {
78         int ret;
79
80         BT_INFO("[bt-service] Start to initialize BT stack");
81         /* Adapter enable request is successful, setup event handlers */
82         _bt_service_register_event_handler_callback(
83                         BT_ADAPTER_MODULE, __bt_adapter_event_handler);
84
85         ret = oal_bt_init(_bt_service_oal_event_receiver);
86
87         if (OAL_STATUS_PENDING == ret) {
88                 BT_INFO("OAL Initialisation Pending, Profiles Init will be done once oal initialised...");
89                 return BLUETOOTH_ERROR_NONE;
90         } else if (OAL_STATUS_SUCCESS != ret) {
91                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
92                 return BLUETOOTH_ERROR_INTERNAL;
93         }
94
95         __bt_post_oal_init();
96         return BLUETOOTH_ERROR_NONE;
97 }
98
99 int _bt_enable_adapter(void)
100 {
101         return __bt_adapter_state_handle_request(TRUE);
102 }
103
104 int _bt_disable_adapter(void)
105 {
106         return __bt_adapter_state_handle_request(FALSE);
107 }
108
109
110 int _bt_start_discovery(void)
111 {
112         return __bt_adapter_state_discovery_request(TRUE);
113 }
114
115 int _bt_cancel_discovery(void)
116 {
117         return __bt_adapter_state_discovery_request(FALSE);
118 }
119
120 gboolean _bt_is_discovering(void)
121 {
122         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED
123                         || adapter_discovery_state == ADAPTER_DISCOVERY_STARTING)
124                 return TRUE;
125         else
126                 return FALSE;
127 }
128
129 int _bt_get_local_address(void)
130 {
131         int result;
132
133         BT_DBG("+");
134
135         result =  adapter_get_address();
136         if (result != OAL_STATUS_SUCCESS) {
137                 BT_ERR("adapter_get_address failed: %d", result);
138                 result = BLUETOOTH_ERROR_INTERNAL;
139         } else
140                 result = BLUETOOTH_ERROR_NONE;
141
142         BT_DBG("-");
143         return result;
144 }
145
146 int _bt_get_local_version(void)
147 {
148         int result;
149         BT_DBG("+");
150
151         result =  adapter_get_version();
152         if (result != OAL_STATUS_SUCCESS) {
153                 BT_ERR("adapter_get_address failed: %d", result);
154                 result = BLUETOOTH_ERROR_INTERNAL;
155         } else
156                 result = BLUETOOTH_ERROR_NONE;
157
158         BT_DBG("-");
159         return result;
160 }
161
162 int _bt_get_local_name(void)
163 {
164         int result;
165
166         BT_DBG("+");
167
168         result =  adapter_get_name();
169         if (result != OAL_STATUS_SUCCESS) {
170                 BT_ERR("adapter_get_name failed: %d", result);
171                 result = BLUETOOTH_ERROR_INTERNAL;
172         } else
173                 result = BLUETOOTH_ERROR_NONE;
174
175         BT_DBG("-");
176         return result;
177 }
178
179 int _bt_set_local_name(char *local_name)
180 {
181         int result = BLUETOOTH_ERROR_NONE;
182         BT_DBG("+");
183
184         retv_if(NULL == local_name, BLUETOOTH_ERROR_INVALID_PARAM);
185
186         result =  adapter_set_name(local_name);
187         if (result != OAL_STATUS_SUCCESS) {
188                 BT_ERR("adapter_set_name failed: %d", result);
189                 result = BLUETOOTH_ERROR_INTERNAL;
190         } else
191                 result = BLUETOOTH_ERROR_NONE;
192
193         BT_DBG("-");
194         return result;
195 }
196
197 int _bt_get_discoverable_mode(int *mode)
198 {
199         int scan_mode = 0;
200         int timeout = 0;
201
202         BT_DBG("+");
203
204         retv_if(NULL == mode, BLUETOOTH_ERROR_INVALID_PARAM);
205
206         adapter_is_discoverable(&scan_mode);
207         if (TRUE == scan_mode) {
208                 adapter_get_discoverable_timeout(&timeout);
209                 if (timeout > 0)
210                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
211                 else
212                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
213         } else {
214                 adapter_is_connectable(&scan_mode);
215                 if(scan_mode == TRUE)
216                         *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
217                 else {
218                         /*
219                          * TODO: NON CONNECTABLE is not defined in bluetooth_discoverable_mode_t.
220                          * After adding BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE, set mode as
221                          * BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE. Until then return error.
222                          */
223                         return BLUETOOTH_ERROR_INTERNAL;
224                 }
225         }
226
227         BT_DBG("-");
228         return BLUETOOTH_ERROR_NONE;
229 }
230
231 gboolean _bt_is_connectable(void)
232 {
233         int connectable = 0;
234         int result;
235
236         BT_DBG("+");
237
238         adapter_is_connectable(&connectable);
239         if (connectable)
240                 result = TRUE;
241         else
242                 result = FALSE;
243
244         BT_DBG("Connectable: [%s]", result ? "TRUE":"FALSE");
245         BT_DBG("-");
246         return result;
247 }
248
249 int _bt_set_connectable(gboolean connectable)
250 {
251         int result = BLUETOOTH_ERROR_NONE;
252
253         BT_DBG("+");
254         result =  adapter_set_connectable(connectable);
255         if (result != OAL_STATUS_SUCCESS) {
256                 BT_ERR("adapter_get_address failed: %d", result);
257                 result = BLUETOOTH_ERROR_INTERNAL;
258         } else
259                 result = BLUETOOTH_ERROR_NONE;
260
261         BT_DBG("-");
262         return result;
263 }
264
265 int _bt_is_service_used(void)
266 {
267         int result;
268
269         BT_DBG("+");
270
271         result =  adapter_get_service_uuids();
272         if (result != OAL_STATUS_SUCCESS) {
273                 BT_ERR("adapter_get_service_uuids failed: %d", result);
274                 result = BLUETOOTH_ERROR_INTERNAL;
275         } else {
276                 result = BLUETOOTH_ERROR_NONE;
277         }
278
279         BT_DBG("-");
280         return result;
281 }
282
283 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
284 {
285         BT_DBG("+");
286
287         switch(event_type) {
288         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
289         case OAL_EVENT_OAL_INITIALISED_FAILED:
290                 __bt_handle_oal_initialisation(event_type);
291                 break;
292         case OAL_EVENT_ADAPTER_ENABLED:
293                 __bt_adapter_state_change_callback(BT_ACTIVATED);
294                 break;
295         case OAL_EVENT_ADAPTER_DISABLED:
296                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
297                 break;
298         case OAL_EVENT_ADAPTER_INQUIRY_STARTED:
299                 __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STARTED);
300                 break;
301         case OAL_EVENT_ADAPTER_INQUIRY_FINISHED:
302                  __bt_adapter_discovery_state_change_callback(ADAPTER_DISCOVERY_STOPPED);
303                 break;
304         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
305                 bt_address_t *bd_addr = event_data;
306                 bluetooth_device_address_t local_address;
307
308                 /* Copy data */
309                 memcpy(local_address.addr, bd_addr->addr, BT_ADDRESS_LENGTH_MAX);
310                 BT_DBG("Adapter address: [%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X]",
311                                 local_address.addr[0], local_address.addr[1], local_address.addr[2],
312                                 local_address.addr[3], local_address.addr[4], local_address.addr[5]);
313
314                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
315                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
316                 break;
317         }
318         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
319                 char *name = event_data;
320                 bluetooth_device_name_t local_name;
321
322                 memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
323                 /* Copy data */
324                 g_strlcpy(local_name.name,
325                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
326                 BT_DBG("Adapter Name: %s", local_name.name);
327
328                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
329                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
330                 break;
331         }
332         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
333                 char *ver = event_data;
334                 bluetooth_version_t local_version;
335
336                 memset(&local_version, 0x00, sizeof(bluetooth_version_t));
337                 g_strlcpy(local_version.version,
338                                 (const gchar *)ver, BLUETOOTH_VERSION_LENGTH_MAX);
339                 BT_DBG("BT Version: %s", local_version.version);
340
341                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
342                                 (void *) &local_version, sizeof(bluetooth_version_t));
343                 break;
344         }
345         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
346                 gboolean connectable = FALSE;
347
348                 BT_INFO("Adapter discoverable mode:"
349                         " BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
350                 _bt_send_event(BT_ADAPTER_EVENT,
351                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
352                                 g_variant_new("(b)", connectable));
353                 break;
354         }
355         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
356                 gboolean connectable = TRUE;
357
358                 BT_INFO("Adapter discoverable mode:"
359                         " BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
360                 _bt_send_event(BT_ADAPTER_EVENT,
361                                 BLUETOOTH_EVENT_CONNECTABLE_CHANGED,
362                                 g_variant_new("(b)", connectable));
363                 break;
364         }
365         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
366                 BT_INFO("Adapter discoverable mode:"
367                         " BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
368                 break;
369         }
370         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
371                 int *timeout = event_data;
372
373                 BT_INFO("Discoverable timeout: [%d]", *timeout);
374                 break;
375         }
376         case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
377                 int count;
378                 service_uuid_t *service_list;
379                 event_adapter_services_t *list = event_data;
380
381                 count = list->num;
382                 service_list = list->service_list;
383                 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
384                 break;
385         }
386         default:
387                 BT_ERR("Unhandled event..");
388                 break;
389         }
390
391         BT_DBG("-");
392 }
393
394 /* OAL post initialization handler */
395 static void __bt_post_oal_init(void)
396 {
397         BT_DBG("OAL initialized, Init profiles..");
398         /*TODO */
399         return;
400 }
401
402 /* OAL initialization handler */
403 static void __bt_handle_oal_initialisation(oal_event_t event)
404 {
405         BT_DBG("");
406
407         switch(event) {
408         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
409                 __bt_post_oal_init();
410                 break;
411         case OAL_EVENT_OAL_INITIALISED_FAILED:
412                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
413                 g_idle_add(_bt_terminate_service, NULL);
414                 break;
415         default:
416                 BT_ERR("Unknown Event");
417                 break;
418         }
419 }
420
421 /* Internal functions of core adapter service */
422 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
423 {
424         GSList *l;
425         GArray *out_param;
426         invocation_info_t *req_info;
427         BT_INFO("+");
428
429         /* Get method invocation context */
430         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
431                 req_info = l->data;
432                 if (req_info == NULL || req_info->service_function != service_function)
433                         continue;
434
435                 /* Create out param */
436                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
437
438                 switch(service_function) {
439                 case BT_ENABLE_ADAPTER:
440                 case BT_DISABLE_ADAPTER: {
441                         gboolean done = TRUE;
442                         g_array_append_vals(out_param, &done, sizeof(gboolean));
443                         break;
444                 }
445                 case BT_GET_LOCAL_NAME:
446                 case BT_GET_LOCAL_ADDRESS:
447                 case BT_GET_LOCAL_VERSION:
448                         g_array_append_vals(out_param, user_data, size);
449                         break;
450                 case BT_IS_SERVICE_USED: {
451                         int i;
452                         gboolean used = FALSE;
453                         unsigned char *uuid;
454                         char uuid_str[BT_UUID_STRING_SIZE];
455                         char *request_uuid = req_info->user_data;
456                         service_uuid_t *service_list = user_data;
457
458                         BT_INFO("Check for service uuid: %s", request_uuid);
459                         for (i = 0; i < size; i++) {
460                                 uuid = service_list[i].uuid;
461                                 _bt_service_convert_uuid_type_to_string(uuid_str, uuid);
462                                 BT_INFO("Adapter Service: [%s]", uuid_str);
463                                 if (strcasecmp(uuid_str, request_uuid) == 0) {
464                                         BT_INFO("UUID matched!!");
465                                         used = TRUE;
466                                         break;
467                                 }
468                         }
469
470                         g_array_append_vals(out_param, &used, sizeof(gboolean));
471                         break;
472                 }
473                 default:
474                         BT_ERR("Unknown service function[%d]", service_function);
475                 }
476
477                 _bt_service_method_return(req_info->context, out_param, req_info->result);
478                 g_array_free(out_param, TRUE);
479                 /* Now free invocation info for this request*/
480                 _bt_free_info_from_invocation_list(req_info);
481         }
482 }
483
484 /* Request return handlings */
485 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
486 {
487         BT_INFO("__bt_adapter_post_set_enabled>>");
488         /*TODO Get All properties */
489         /* Add Adapter enabled post processing codes */
490         return FALSE;
491 }
492
493 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
494 {
495         BT_INFO("_bt_adapter_post_set_disabled>>");
496         /* Add Adapter disabled post processing codes */
497         return FALSE;
498 }
499
500 static void __bt_adapter_update_bt_enabled(void)
501 {
502         int result = BLUETOOTH_ERROR_NONE;
503         BT_INFO("_bt_adapter_update_bt_enabled>>");
504         /* Update Bluetooth Status to notify other modules */
505         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
506                 BT_ERR("Set vconf failed\n");
507
508         /* TODO:Add timer function to handle any further post processing */
509         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
510
511         /*Return BT_ADAPTER_ENABLE Method invocation context */
512         __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
513         /*Send BT Enabled event to application */
514         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
515                         g_variant_new("(i)", result));
516 }
517
518 static void __bt_adapter_update_bt_disabled(void)
519 {
520         int result = BLUETOOTH_ERROR_NONE;
521         BT_INFO("_bt_adapter_update_bt_disabled>>");
522
523         int power_off_status = 0;
524         int ret;
525
526         /* Update the vconf BT status in normal Deactivation case only */
527         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
528         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
529
530         /* TODO:Add timer function to handle any further post processing */
531         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
532
533         /* Return BT_ADAPTER_DISABLE Method invocation context */
534         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
535
536         /* Send BT Disabled event to application */
537         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
538                         g_variant_new("(i)", result));
539 }
540
541
542 static void __bt_adapter_state_set_status(bt_status_t status)
543 {
544         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
545         adapter_state = status;
546 }
547
548 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
549 {
550         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
551         adapter_discovery_state = status;
552 }
553
554 static void __bt_adapter_state_change_callback(int bt_status)
555 {
556         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
557
558         switch (bt_status) {
559         case BT_DEACTIVATED:
560                 __bt_adapter_state_set_status(bt_status);
561
562                 /* Adapter is disabled, unregister event handlers */
563                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
564                 //_bt_deinit_device_event_handler();
565
566                 /* Add Adapter disabled post processing codes */
567                 __bt_adapter_update_bt_disabled();
568                 break;
569         case BT_ACTIVATED:
570                 __bt_adapter_state_set_status(bt_status);
571                 /* Add Adapter enabled post processing codes */
572                 if (timer_id > 0) {
573                         BT_DBG("g_source is removed");
574                         g_source_remove(timer_id);
575                         timer_id = 0;
576                 }
577                 __bt_adapter_update_bt_enabled();
578                 break;
579         default:
580                 BT_ERR("Incorrect Bluetooth adapter state changed status");
581
582         }
583 }
584
585 static int __bt_adapter_state_handle_request(gboolean enable)
586 {
587         int result = BLUETOOTH_ERROR_NONE;
588         BT_DBG("");
589
590         switch (adapter_state) {
591         case BT_ACTIVATING:
592         {
593                 BT_INFO("Adapter is currently in activating state, state [%d]",
594                                 adapter_state);
595                 if (enable) {
596                         return BLUETOOTH_ERROR_IN_PROGRESS;
597                 } else {
598                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
599                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
600                                 /*TODO Stop Discovery*/
601                                 if (result != OAL_STATUS_SUCCESS)
602                                         BT_ERR("Discover stop failed: %d", result);
603                                 __bt_adapter_update_discovery_status(FALSE);
604                         }
605                         result = adapter_disable();
606                         if (result != OAL_STATUS_SUCCESS) {
607                                 BT_ERR("adapter_enable failed: [%d]", result);
608                                 result = BLUETOOTH_ERROR_INTERNAL;
609                                 /*TODO: perform if anything more needs to be done to handle failure */
610                         } else {
611                                 /* TODO: To be handled */
612                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
613                                 result = BLUETOOTH_ERROR_NONE;
614                         }
615                 }
616                 break;
617         }
618         case BT_ACTIVATED:
619         {
620                 BT_INFO("Adapter is currently in activated state, state [%d]",
621                                 adapter_state);
622                 if (enable) {
623                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
624                 } else {
625                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
626                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
627                                 /*TODO Stop Discovery*/
628                                 if (result != OAL_STATUS_SUCCESS)
629                                         BT_ERR("Discover stop failed: %d", result);
630                                 __bt_adapter_update_discovery_status(FALSE);
631                         }
632                         result = adapter_disable();
633                         if (result != OAL_STATUS_SUCCESS) {
634                                 BT_ERR("adapter_enable failed: [%d]", result);
635                                 result = BLUETOOTH_ERROR_INTERNAL;
636                                 /*TODO: perform if anything more needs to be done to handle failure */
637                         } else {
638                                 /* TODO: To be handled */
639                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
640                                 result = BLUETOOTH_ERROR_NONE;
641                         }
642                 }
643                 break;
644         }
645         case BT_DEACTIVATING:
646         {
647                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
648                                 adapter_state);
649                 if (!enable) {
650                         return BLUETOOTH_ERROR_IN_PROGRESS;
651
652                 } else {
653                         result = adapter_enable();
654                         if (result != OAL_STATUS_SUCCESS) {
655                                 BT_ERR("adapter_enable failed: [%d]", result);
656                                 adapter_disable();
657                                 result = BLUETOOTH_ERROR_INTERNAL;
658                                 /*TODO: perform if anything more needs to be done to handle failure */
659                         } else {
660                                 /* TODO: To be handled */
661                                 __bt_adapter_state_set_status(BT_ACTIVATING);
662                                 result = BLUETOOTH_ERROR_NONE;
663                         }
664                 }
665                 break;
666         }
667         case BT_DEACTIVATED:
668         {
669                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
670                                 adapter_state);
671                 if (!enable) {
672                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
673                 } else {
674                         result = adapter_enable();
675                         if (result != OAL_STATUS_SUCCESS) {
676                                 BT_ERR("adapter_enable failed: [%d]", result);
677                                 adapter_disable();
678                                 result = BLUETOOTH_ERROR_INTERNAL;
679                                 /*TODO: perform if anything more needs to be done to handle failure */
680                         } else {
681                                 /* TODO: To be handled */
682                                 __bt_adapter_state_set_status(BT_ACTIVATING);
683                                 result = BLUETOOTH_ERROR_NONE;
684                         }
685                 }
686                 break;
687         }
688         }
689         if (enable && result == BLUETOOTH_ERROR_NONE) {
690                 /* Adapter enable request is successful, setup event handlers */
691                 _bt_service_register_event_handler_callback(
692                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
693                 _bt_device_state_handle_callback_set_request();
694         }
695         return result;
696 }
697
698 static int __bt_adapter_state_discovery_request(gboolean enable)
699 {
700         int result = BLUETOOTH_ERROR_NONE;
701
702         BT_DBG("+");
703         switch (adapter_discovery_state) {
704         case ADAPTER_DISCOVERY_STARTED: {
705                 BT_INFO("Adapter is currently in discovery started state, state [%d]",
706                                 adapter_discovery_state);
707                 if (enable) {
708                         return BLUETOOTH_ERROR_IN_PROGRESS;
709                 } else {
710                         result = adapter_stop_inquiry();
711                         if (result != OAL_STATUS_SUCCESS) {
712                                 BT_ERR("Discover stop failed: %d", result);
713                                 result = BLUETOOTH_ERROR_INTERNAL;
714                         } else {
715                                 BT_ERR("Stop Discovery Triggered successfully");
716                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
717                                 result = BLUETOOTH_ERROR_NONE;
718                         }
719                 }
720                 break;
721         }
722         case ADAPTER_DISCOVERY_STARTING: {
723                 BT_INFO("Adapter is currently in discovery starting state, state [%d]",
724                                 adapter_discovery_state);
725                 if (enable) {
726                         return BLUETOOTH_ERROR_IN_PROGRESS;
727                 } else {
728                         result = adapter_stop_inquiry();
729                         if (result != OAL_STATUS_SUCCESS) {
730                                 BT_ERR("Discover stop failed: %d", result);
731                                 result = BLUETOOTH_ERROR_INTERNAL;
732                         } else {
733                                 BT_ERR("Stop Discovery Triggered successfully");
734                                 __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STOPPING);
735                                 result = BLUETOOTH_ERROR_NONE;
736                         }
737                 }
738                 break;
739         }
740         case ADAPTER_DISCOVERY_STOPPED: {
741                 BT_INFO("Adapter is currently in discovery stopped state, state [%d]",
742                                 adapter_discovery_state);
743                 if (!enable)
744                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
745                 else {
746                         result = adapter_start_inquiry();
747                 if (result != OAL_STATUS_SUCCESS) {
748                                 BT_ERR("Start Discovery failed: %d", result);
749                                 result = BLUETOOTH_ERROR_INTERNAL;
750                         } else {
751                                 BT_ERR("Start Discovery Triggered successfully");
752                         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
753                                 result = BLUETOOTH_ERROR_NONE;
754                         }
755                 }
756                 break;
757         }
758         case ADAPTER_DISCOVERY_STOPPING: {
759                 BT_INFO("Adapter is currently in discovery stopping state, state [%d]",
760                                 adapter_discovery_state);
761                 if (!enable)
762                         return BLUETOOTH_ERROR_NOT_IN_OPERATION;
763                 else {
764                         result = adapter_start_inquiry();
765                         if (result != OAL_STATUS_SUCCESS) {
766                                 BT_ERR("Start Discovery failed: %d", result);
767                                 result = BLUETOOTH_ERROR_INTERNAL;
768                         } else {
769                                 BT_ERR("Start Discovery Triggered successfully");
770                         __bt_adapter_update_discovery_status(ADAPTER_DISCOVERY_STARTING);
771                                 result = BLUETOOTH_ERROR_NONE;
772                         }
773                 }
774                 break;
775         }
776         }
777
778         BT_DBG("-");
779         return result;
780 }
781
782 static void __bt_adapter_discovery_state_change_callback(int bt_discovery_status)
783 {
784         BT_INFO("__bt_adapter_discovery_state_change_callback: status [%d]", bt_discovery_status);
785         GVariant *param = NULL;
786         int result = BLUETOOTH_ERROR_NONE;
787
788         switch (bt_discovery_status) {
789         case ADAPTER_DISCOVERY_STOPPED:
790         {
791                 __bt_adapter_update_discovery_status(bt_discovery_status);
792                 param = g_variant_new("(i)", result);
793                 _bt_send_event(BT_ADAPTER_EVENT,
794                                 BLUETOOTH_EVENT_DISCOVERY_FINISHED,
795                                 param);
796                 break;
797         }
798         case ADAPTER_DISCOVERY_STARTED:
799         {
800                 __bt_adapter_update_discovery_status(bt_discovery_status);
801                 param = g_variant_new("(i)", result);
802                 _bt_send_event(BT_ADAPTER_EVENT,
803                                 BLUETOOTH_EVENT_DISCOVERY_STARTED,
804                                 param);
805                 break;
806         }
807         default:
808                 BT_ERR("Incorrect Bluetooth adapter Discovery state changed status");
809         }
810 }