[Adapt] Implement is_service_used API
[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-event-receiver.h"
39 #include "bt-request-handler.h"
40 #include "bt-service-event.h"
41
42 /* OAL headers */
43 #include <oal-event.h>
44 #include <oal-manager.h>
45 #include <oal-adapter-mgr.h>
46
47 #define BT_ENABLE_TIMEOUT 20000 /* 20 seconds */
48
49 /*This file will contain state machines related to adapter and remote device */
50
51 /* Global variables */
52 static guint timer_id = 0;
53
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;
57
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);
71
72
73 /* Initialize BT stack (Initialize OAL layer) */
74 int _bt_stack_init(void)
75 {
76         int ret;
77
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);
82
83         ret = oal_bt_init(_bt_service_oal_event_receiver);
84
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;
91         }
92
93         __bt_post_oal_init();
94         return BLUETOOTH_ERROR_NONE;
95 }
96
97 int _bt_enable_adapter(void)
98 {
99         return __bt_adapter_state_handle_request(TRUE);
100 }
101
102 int _bt_disable_adapter(void)
103 {
104         return __bt_adapter_state_handle_request(FALSE);
105 }
106
107 int _bt_get_local_address(void)
108 {
109         int result;
110
111         BT_DBG("+");
112
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;
117         } else
118                 result = BLUETOOTH_ERROR_NONE;
119
120         BT_DBG("-");
121         return result;
122 }
123
124 int _bt_get_local_version(void)
125 {
126         int result;
127         BT_DBG("+");
128
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;
133         } else
134                 result = BLUETOOTH_ERROR_NONE;
135
136         BT_DBG("-");
137         return result;
138 }
139
140 int _bt_get_local_name(void)
141 {
142         int result;
143
144         BT_DBG("+");
145
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;
150         } else
151                 result = BLUETOOTH_ERROR_NONE;
152
153         BT_DBG("-");
154         return result;
155 }
156
157 int _bt_get_discoverable_mode(int *mode)
158 {
159         int scan_mode = 0;
160         int timeout = 0;
161
162         BT_DBG("+");
163
164         retv_if(NULL == mode, BLUETOOTH_ERROR_INVALID_PARAM);
165
166         adapter_is_discoverable(&scan_mode);
167         if (TRUE == scan_mode) {
168                 adapter_get_discoverable_timeout(&timeout);
169                 if (timeout > 0)
170                         *mode = BLUETOOTH_DISCOVERABLE_MODE_TIME_LIMITED_DISCOVERABLE;
171                 else
172                         *mode = BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE;
173         } else {
174                 adapter_is_connectable(&scan_mode);
175                 if(scan_mode == TRUE)
176                         *mode = BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE;
177                 else {
178                         /*
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.
182                          */
183                         return BLUETOOTH_ERROR_INTERNAL;
184                 }
185         }
186
187         BT_DBG("-");
188         return BLUETOOTH_ERROR_NONE;
189 }
190
191 int _bt_is_service_used(void)
192 {
193         int result;
194
195         BT_DBG("+");
196
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;
201         } else {
202                 result = BLUETOOTH_ERROR_NONE;
203         }
204
205         BT_DBG("-");
206         return result;
207 }
208
209 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
210 {
211         BT_DBG("+");
212
213         switch(event_type) {
214         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
215         case OAL_EVENT_OAL_INITIALISED_FAILED:
216                 __bt_handle_oal_initialisation(event_type);
217                 break;
218         case OAL_EVENT_ADAPTER_ENABLED:
219                 __bt_adapter_state_change_callback(BT_ACTIVATED);
220                 break;
221         case OAL_EVENT_ADAPTER_DISABLED:
222                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
223                 break;
224         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
225                 bt_address_t *bd_addr = event_data;
226                 bluetooth_device_address_t local_address;
227
228                 /* Copy data */
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]);
233
234                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
235                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
236                 break;
237         }
238         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
239                 char *name = event_data;
240                 bluetooth_device_name_t local_name;
241
242                 memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
243                 /* Copy data */
244                 g_strlcpy(local_name.name,
245                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
246                 BT_DBG("Adapter Name: %s", local_name.name);
247
248                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
249                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
250                 break;
251         }
252         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
253                 char *ver = event_data;
254                 bluetooth_version_t local_version;
255
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);
260
261                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
262                                 (void *) &local_version, sizeof(bluetooth_version_t));
263                 break;
264         }
265         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
266                 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
267                 break;
268         }
269         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
270                 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
271                 break;
272         }
273         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
274                 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
275                 break;
276         }
277         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
278                 int *timeout = event_data;
279
280                 BT_INFO("Discoverable timeout: [%d]", *timeout);
281                 break;
282         }
283         case OAL_EVENT_ADAPTER_PROPERTY_SERVICES: {
284                 int count;
285                 service_uuid_t *service_list;
286                 event_adapter_services_t *list = event_data;
287
288                 count = list->num;
289                 service_list = list->service_list;
290                 __bt_adapter_handle_pending_requests(BT_IS_SERVICE_USED, service_list, count);
291                 break;
292         }
293         default:
294                 BT_ERR("Unhandled event..");
295                 break;
296         }
297
298         BT_DBG("-");
299 }
300
301 /* OAL post initialization handler */
302 static void __bt_post_oal_init(void)
303 {
304         BT_DBG("OAL initialized, Init profiles..");
305         /*TODO */
306         return;
307 }
308
309 /* OAL initialization handler */
310 static void __bt_handle_oal_initialisation(oal_event_t event)
311 {
312         BT_DBG("");
313
314         switch(event) {
315         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
316                 __bt_post_oal_init();
317                 break;
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);
321                 break;
322         default:
323                 BT_ERR("Unknown Event");
324                 break;
325         }
326 }
327
328 /* Internal functions of core adapter service */
329 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
330 {
331         GSList *l;
332         GArray *out_param;
333         invocation_info_t *req_info;
334         BT_INFO("+");
335
336         /* Get method invocation context */
337         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
338                 req_info = l->data;
339                 if (req_info == NULL || req_info->service_function != service_function)
340                         continue;
341
342                 /* Create out param */
343                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
344
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));
350                         break;
351                 }
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);
356                         break;
357                 case BT_IS_SERVICE_USED: {
358                         int i;
359                         gboolean used = FALSE;
360                         unsigned char *uuid;
361                         char uuid_str[BT_UUID_STRING_SIZE];
362                         char *request_uuid = req_info->user_data;
363                         service_uuid_t *service_list = user_data;
364
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!!");
372                                         used = TRUE;
373                                         break;
374                                 }
375                         }
376
377                         g_array_append_vals(out_param, &used, sizeof(gboolean));
378                         break;
379                 }
380                 default:
381                         BT_ERR("Unknown service function[%d]", service_function);
382                 }
383
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);
388         }
389 }
390
391 /* Request return handlings */
392 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
393 {
394         BT_INFO("__bt_adapter_post_set_enabled>>");
395         /*TODO Get All properties */
396         /* Add Adapter enabled post processing codes */
397         return FALSE;
398 }
399
400 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
401 {
402         BT_INFO("_bt_adapter_post_set_disabled>>");
403         /* Add Adapter disabled post processing codes */
404         return FALSE;
405 }
406
407 static void __bt_adapter_update_bt_enabled(void)
408 {
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");
414
415         /* TODO:Add timer function to handle any further post processing */
416         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
417
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));
423 }
424
425 static void __bt_adapter_update_bt_disabled(void)
426 {
427         int result = BLUETOOTH_ERROR_NONE;
428         BT_INFO("_bt_adapter_update_bt_disabled>>");
429
430         int power_off_status = 0;
431         int ret;
432
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);
436
437         /* TODO:Add timer function to handle any further post processing */
438         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
439
440         /* Return BT_ADAPTER_DISABLE Method invocation context */
441         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
442
443         /* Send BT Disabled event to application */
444         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
445                         g_variant_new("(i)", result));
446 }
447
448
449 static void __bt_adapter_state_set_status(bt_status_t status)
450 {
451         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
452         adapter_state = status;
453 }
454
455 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
456 {
457         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
458         adapter_discovery_state = status;
459 }
460
461 static void __bt_adapter_state_change_callback(int bt_status)
462 {
463         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
464
465         switch (bt_status) {
466         case BT_DEACTIVATED:
467                 __bt_adapter_state_set_status(bt_status);
468
469                 /* Adapter is disabled, unregister event handlers */
470                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
471                 //_bt_deinit_device_event_handler();
472
473                 /* Add Adapter disabled post processing codes */
474                 __bt_adapter_update_bt_disabled();
475                 break;
476         case BT_ACTIVATED:
477                 __bt_adapter_state_set_status(bt_status);
478                 /* Add Adapter enabled post processing codes */
479                 if (timer_id > 0) {
480                         BT_DBG("g_source is removed");
481                         g_source_remove(timer_id);
482                         timer_id = 0;
483                 }
484                 __bt_adapter_update_bt_enabled();
485                 break;
486         default:
487                 BT_ERR("Incorrect Bluetooth adapter state changed status");
488
489         }
490 }
491
492 static int __bt_adapter_state_handle_request(gboolean enable)
493 {
494         int result = BLUETOOTH_ERROR_NONE;
495         BT_DBG("");
496
497         switch (adapter_state) {
498         case BT_ACTIVATING:
499         {
500                 BT_INFO("Adapter is currently in activating state, state [%d]",
501                                 adapter_state);
502                 if (enable) {
503                         return BLUETOOTH_ERROR_IN_PROGRESS;
504                 } else {
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);
511                         }
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 */
517                         } else {
518                                 /* TODO: To be handled */
519                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
520                                 result = BLUETOOTH_ERROR_NONE;
521                         }
522                 }
523                 break;
524         }
525         case BT_ACTIVATED:
526         {
527                 BT_INFO("Adapter is currently in activated state, state [%d]",
528                                 adapter_state);
529                 if (enable) {
530                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
531                 } else {
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);
538                         }
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 */
544                         } else {
545                                 /* TODO: To be handled */
546                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
547                                 result = BLUETOOTH_ERROR_NONE;
548                         }
549                 }
550                 break;
551         }
552         case BT_DEACTIVATING:
553         {
554                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
555                                 adapter_state);
556                 if (!enable) {
557                         return BLUETOOTH_ERROR_IN_PROGRESS;
558
559                 } else {
560                         result = adapter_enable();
561                         if (result != OAL_STATUS_SUCCESS) {
562                                 BT_ERR("adapter_enable failed: [%d]", result);
563                                 adapter_disable();
564                                 result = BLUETOOTH_ERROR_INTERNAL;
565                                 /*TODO: perform if anything more needs to be done to handle failure */
566                         } else {
567                                 /* TODO: To be handled */
568                                 __bt_adapter_state_set_status(BT_ACTIVATING);
569                                 result = BLUETOOTH_ERROR_NONE;
570                         }
571                 }
572                 break;
573         }
574         case BT_DEACTIVATED:
575         {
576                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
577                                 adapter_state);
578                 if (!enable) {
579                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
580                 } else {
581                         result = adapter_enable();
582                         if (result != OAL_STATUS_SUCCESS) {
583                                 BT_ERR("adapter_enable failed: [%d]", result);
584                                 adapter_disable();
585                                 result = BLUETOOTH_ERROR_INTERNAL;
586                                 /*TODO: perform if anything more needs to be done to handle failure */
587                         } else {
588                                 /* TODO: To be handled */
589                                 __bt_adapter_state_set_status(BT_ACTIVATING);
590                                 result = BLUETOOTH_ERROR_NONE;
591                         }
592                 }
593                 break;
594         }
595         }
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*/
601         }
602         return result;
603 }
604