[Adapt]Added support for get adapter property 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-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 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
192 {
193         BT_DBG("+");
194
195         switch(event_type) {
196         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
197         case OAL_EVENT_OAL_INITIALISED_FAILED:
198                 __bt_handle_oal_initialisation(event_type);
199                 break;
200         case OAL_EVENT_ADAPTER_ENABLED:
201                 __bt_adapter_state_change_callback(BT_ACTIVATED);
202                 break;
203         case OAL_EVENT_ADAPTER_DISABLED:
204                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
205                 break;
206         case OAL_EVENT_ADAPTER_PROPERTY_ADDRESS: {
207                 bt_address_t *bd_addr = event_data;
208                 bluetooth_device_address_t local_address;
209
210                 /* Copy data */
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]);
215
216                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_ADDRESS,
217                                 (void *) &local_address, sizeof(bluetooth_device_address_t));
218                 break;
219         }
220         case OAL_EVENT_ADAPTER_PROPERTY_NAME: {
221                 char *name = event_data;
222                 bluetooth_device_name_t local_name;
223
224                 memset(&local_name, 0x00, sizeof(bluetooth_device_name_t));
225                 /* Copy data */
226                 g_strlcpy(local_name.name,
227                                 (const gchar *)name, BLUETOOTH_DEVICE_NAME_LENGTH_MAX);
228                 BT_DBG("Adapter Name: %s", local_name.name);
229
230                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_NAME,
231                                 (void *) &local_name, sizeof(bluetooth_device_name_t));
232                 break;
233         }
234         case OAL_EVENT_ADAPTER_PROPERTY_VERSION: {
235                 char *ver = event_data;
236                 bluetooth_version_t local_version;
237
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);
242
243                 __bt_adapter_handle_pending_requests(BT_GET_LOCAL_VERSION,
244                                 (void *) &local_version, sizeof(bluetooth_version_t));
245                 break;
246         }
247         case OAL_EVENT_ADAPTER_MODE_NON_CONNECTABLE: {
248                 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_NON_CONNECTABLE");
249                 break;
250         }
251         case OAL_EVENT_ADAPTER_MODE_CONNECTABLE: {
252                 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_CONNECTABLE");
253                 break;
254         }
255         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE: {
256                 BT_INFO("Adapter discoverable mode: BLUETOOTH_DISCOVERABLE_MODE_GENERAL_DISCOVERABLE");
257                 break;
258         }
259         case OAL_EVENT_ADAPTER_MODE_DISCOVERABLE_TIMEOUT: {
260                 int *timeout = event_data;
261
262                 BT_INFO("Discoverable timeout: [%d]", *timeout);
263                 break;
264         }
265         default:
266                 BT_ERR("Unhandled event..");
267                 break;
268         }
269
270         BT_DBG("-");
271 }
272
273 /* OAL post initialization handler */
274 static void __bt_post_oal_init(void)
275 {
276         BT_DBG("OAL initialized, Init profiles..");
277         /*TODO */
278         return;
279 }
280
281 /* OAL initialization handler */
282 static void __bt_handle_oal_initialisation(oal_event_t event)
283 {
284         BT_DBG("");
285
286         switch(event) {
287         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
288                 __bt_post_oal_init();
289                 break;
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);
293                 break;
294         default:
295                 BT_ERR("Unknown Event");
296                 break;
297         }
298 }
299
300 /* Internal functions of core adapter service */
301 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
302 {
303         GSList *l;
304         GArray *out_param;
305         invocation_info_t *req_info;
306         BT_INFO("+");
307
308         /* Get method invocation context */
309         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
310                 req_info = l->data;
311                 if (req_info == NULL || req_info->service_function != service_function)
312                         continue;
313
314                 /* Create out param */
315                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
316
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));
322                         break;
323                 }
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);
328                         break;
329                 default:
330                         BT_ERR("Unknown service function[%d]", service_function);
331                 }
332
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);
337         }
338 }
339
340 /* Request return handlings */
341 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
342 {
343         BT_INFO("__bt_adapter_post_set_enabled>>");
344         /*TODO Get All properties */
345         /* Add Adapter enabled post processing codes */
346         return FALSE;
347 }
348
349 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
350 {
351         BT_INFO("_bt_adapter_post_set_disabled>>");
352         /* Add Adapter disabled post processing codes */
353         return FALSE;
354 }
355
356 static void __bt_adapter_update_bt_enabled(void)
357 {
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");
363
364         /* TODO:Add timer function to handle any further post processing */
365         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
366
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));
372 }
373
374 static void __bt_adapter_update_bt_disabled(void)
375 {
376         int result = BLUETOOTH_ERROR_NONE;
377         BT_INFO("_bt_adapter_update_bt_disabled>>");
378
379         int power_off_status = 0;
380         int ret;
381
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);
385
386         /* TODO:Add timer function to handle any further post processing */
387         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
388
389         /* Return BT_ADAPTER_DISABLE Method invocation context */
390         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
391
392         /* Send BT Disabled event to application */
393         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
394                         g_variant_new("(i)", result));
395 }
396
397
398 static void __bt_adapter_state_set_status(bt_status_t status)
399 {
400         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
401         adapter_state = status;
402 }
403
404 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
405 {
406         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
407         adapter_discovery_state = status;
408 }
409
410 static void __bt_adapter_state_change_callback(int bt_status)
411 {
412         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
413
414         switch (bt_status) {
415         case BT_DEACTIVATED:
416                 __bt_adapter_state_set_status(bt_status);
417
418                 /* Adapter is disabled, unregister event handlers */
419                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
420                 //_bt_deinit_device_event_handler();
421
422                 /* Add Adapter disabled post processing codes */
423                 __bt_adapter_update_bt_disabled();
424                 break;
425         case BT_ACTIVATED:
426                 __bt_adapter_state_set_status(bt_status);
427                 /* Add Adapter enabled post processing codes */
428                 if (timer_id > 0) {
429                         BT_DBG("g_source is removed");
430                         g_source_remove(timer_id);
431                         timer_id = 0;
432                 }
433                 __bt_adapter_update_bt_enabled();
434                 break;
435         default:
436                 BT_ERR("Incorrect Bluetooth adapter state changed status");
437
438         }
439 }
440
441 static int __bt_adapter_state_handle_request(gboolean enable)
442 {
443         int result = BLUETOOTH_ERROR_NONE;
444         BT_DBG("");
445
446         switch (adapter_state) {
447         case BT_ACTIVATING:
448         {
449                 BT_INFO("Adapter is currently in activating state, state [%d]",
450                                 adapter_state);
451                 if (enable) {
452                         return BLUETOOTH_ERROR_IN_PROGRESS;
453                 } else {
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);
460                         }
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 */
466                         } else {
467                                 /* TODO: To be handled */
468                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
469                                 result = BLUETOOTH_ERROR_NONE;
470                         }
471                 }
472                 break;
473         }
474         case BT_ACTIVATED:
475         {
476                 BT_INFO("Adapter is currently in activated state, state [%d]",
477                                 adapter_state);
478                 if (enable) {
479                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
480                 } else {
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);
487                         }
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 */
493                         } else {
494                                 /* TODO: To be handled */
495                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
496                                 result = BLUETOOTH_ERROR_NONE;
497                         }
498                 }
499                 break;
500         }
501         case BT_DEACTIVATING:
502         {
503                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
504                                 adapter_state);
505                 if (!enable) {
506                         return BLUETOOTH_ERROR_IN_PROGRESS;
507
508                 } else {
509                         result = adapter_enable();
510                         if (result != OAL_STATUS_SUCCESS) {
511                                 BT_ERR("adapter_enable failed: [%d]", result);
512                                 adapter_disable();
513                                 result = BLUETOOTH_ERROR_INTERNAL;
514                                 /*TODO: perform if anything more needs to be done to handle failure */
515                         } else {
516                                 /* TODO: To be handled */
517                                 __bt_adapter_state_set_status(BT_ACTIVATING);
518                                 result = BLUETOOTH_ERROR_NONE;
519                         }
520                 }
521                 break;
522         }
523         case BT_DEACTIVATED:
524         {
525                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
526                                 adapter_state);
527                 if (!enable) {
528                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
529                 } else {
530                         result = adapter_enable();
531                         if (result != OAL_STATUS_SUCCESS) {
532                                 BT_ERR("adapter_enable failed: [%d]", result);
533                                 adapter_disable();
534                                 result = BLUETOOTH_ERROR_INTERNAL;
535                                 /*TODO: perform if anything more needs to be done to handle failure */
536                         } else {
537                                 /* TODO: To be handled */
538                                 __bt_adapter_state_set_status(BT_ACTIVATING);
539                                 result = BLUETOOTH_ERROR_NONE;
540                         }
541                 }
542                 break;
543         }
544         }
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*/
550         }
551         return result;
552 }
553