[Adapt]Implement Adpater Enable\Disable
[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 static void __bt_adapter_event_handler(int event_type, gpointer event_data)
108 {
109         BT_DBG("");
110
111         switch(event_type) {
112         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
113         case OAL_EVENT_OAL_INITIALISED_FAILED:
114                 __bt_handle_oal_initialisation(event_type);
115                 break;
116         case OAL_EVENT_ADAPTER_ENABLED:
117                 __bt_adapter_state_change_callback(BT_ACTIVATED);
118                 break;
119         case OAL_EVENT_ADAPTER_DISABLED:
120                 __bt_adapter_state_change_callback(BT_DEACTIVATED);
121                 break;
122         default:
123                 BT_ERR("Unhandled event..");
124                 break;
125         }
126 }
127
128 /* OAL post initialization handler */
129 static void __bt_post_oal_init(void)
130 {
131         BT_DBG("OAL initialized, Init profiles..");
132         /*TODO */
133         return;
134 }
135
136 /* OAL initialization handler */
137 static void __bt_handle_oal_initialisation(oal_event_t event)
138 {
139         BT_DBG("");
140
141         switch(event) {
142         case OAL_EVENT_OAL_INITIALISED_SUCCESS:
143                 __bt_post_oal_init();
144                 break;
145         case OAL_EVENT_OAL_INITIALISED_FAILED:
146                 BT_ERR("OAL Initialisation Failed, terminate bt-service daemon..");
147                 g_idle_add(_bt_terminate_service, NULL);
148                 break;
149         default:
150                 BT_ERR("Unknown Event");
151                 break;
152         }
153 }
154
155 /* Internal functions of core adapter service */
156 static void __bt_adapter_handle_pending_requests(int service_function, void *user_data, unsigned int size)
157 {
158         GSList *l;
159         GArray *out_param;
160         invocation_info_t *req_info;
161         BT_INFO("+");
162
163         /* Get method invocation context */
164         for (l = _bt_get_invocation_list(); l != NULL; l = g_slist_next(l)) {
165                 req_info = l->data;
166                 if (req_info == NULL || req_info->service_function != service_function)
167                         continue;
168
169                 /* Create out param */
170                 out_param = g_array_new(FALSE, FALSE, sizeof(gchar));
171
172                 switch(service_function) {
173                         case BT_ENABLE_ADAPTER:
174                         case BT_DISABLE_ADAPTER:
175                         {
176                                 gboolean done = TRUE;
177                                 g_array_append_vals(out_param, &done, sizeof(gboolean));
178                                 break;
179                         }
180                         default:
181                                 BT_ERR("Unknown service function[%d]", service_function);
182                 }
183
184                 _bt_service_method_return(req_info->context, out_param, req_info->result);
185                 g_array_free(out_param, TRUE);
186                 /* Now free invocation info for this request*/
187                 _bt_free_info_from_invocation_list(req_info);
188         }
189 }
190
191 /* Request return handlings */
192 static gboolean __bt_adapter_post_set_enabled(gpointer user_data)
193 {
194         BT_INFO("__bt_adapter_post_set_enabled>>");
195         /*TODO Get All properties */
196         /* Add Adapter enabled post processing codes */
197         return FALSE;
198 }
199
200 static gboolean __bt_adapter_post_set_disabled(gpointer user_data)
201 {
202         BT_INFO("_bt_adapter_post_set_disabled>>");
203         /* Add Adapter disabled post processing codes */
204         return FALSE;
205 }
206
207 static void __bt_adapter_update_bt_enabled(void)
208 {
209         int result = BLUETOOTH_ERROR_NONE;
210         BT_INFO("_bt_adapter_update_bt_enabled>>");
211         /* Update Bluetooth Status to notify other modules */
212         if (vconf_set_int(VCONFKEY_BT_STATUS, VCONFKEY_BT_STATUS_ON) != 0)
213                 BT_ERR("Set vconf failed\n");
214
215         /* TODO:Add timer function to handle any further post processing */
216         g_idle_add((GSourceFunc)__bt_adapter_post_set_enabled, NULL);
217
218         /*Return BT_ADAPTER_ENABLE Method invocation context */
219         __bt_adapter_handle_pending_requests(BT_ENABLE_ADAPTER, NULL, 0);
220         /*Send BT Enabled event to application */
221         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_ENABLED,
222                         g_variant_new("(i)", result));
223 }
224
225 static void __bt_adapter_update_bt_disabled(void)
226 {
227         int result = BLUETOOTH_ERROR_NONE;
228         BT_INFO("_bt_adapter_update_bt_disabled>>");
229
230         int power_off_status = 0;
231         int ret;
232
233         /* Update the vconf BT status in normal Deactivation case only */
234         ret = vconf_get_int(VCONFKEY_SYSMAN_POWER_OFF_STATUS, &power_off_status);
235         BT_DBG("ret : %d, power_off_status : %d", ret, power_off_status);
236
237         /* TODO:Add timer function to handle any further post processing */
238         g_idle_add((GSourceFunc)__bt_adapter_post_set_disabled, NULL);
239
240         /* Return BT_ADAPTER_DISABLE Method invocation context */
241         __bt_adapter_handle_pending_requests(BT_DISABLE_ADAPTER, NULL, 0);
242
243         /* Send BT Disabled event to application */
244         _bt_send_event(BT_ADAPTER_EVENT, BLUETOOTH_EVENT_DISABLED,
245                         g_variant_new("(i)", result));
246 }
247
248
249 static void __bt_adapter_state_set_status(bt_status_t status)
250 {
251         BT_INFO("adapter_status changed [%d] -> [%d]", adapter_state, status);
252         adapter_state = status;
253 }
254
255 static void __bt_adapter_update_discovery_status(bt_adapter_discovery_state_t status)
256 {
257         BT_INFO("adapter_discovery_status changed [%d] -> [%d]", adapter_discovery_state, status);
258         adapter_discovery_state = status;
259 }
260
261 static void __bt_adapter_state_change_callback(int bt_status)
262 {
263         BT_INFO("__bt_adapter_state_change_callback: status [%d]", bt_status);
264
265         switch (bt_status) {
266         case BT_DEACTIVATED:
267                 __bt_adapter_state_set_status(bt_status);
268
269                 /* Adapter is disabled, unregister event handlers */
270                 _bt_service_unregister_event_handler_callback(BT_ADAPTER_MODULE);
271                 //_bt_deinit_device_event_handler();
272
273                 /* Add Adapter disabled post processing codes */
274                 __bt_adapter_update_bt_disabled();
275                 break;
276         case BT_ACTIVATED:
277                 __bt_adapter_state_set_status(bt_status);
278                 /* Add Adapter enabled post processing codes */
279                 if (timer_id > 0) {
280                         BT_DBG("g_source is removed");
281                         g_source_remove(timer_id);
282                         timer_id = 0;
283                 }
284                 __bt_adapter_update_bt_enabled();
285                 break;
286         default:
287                 BT_ERR("Incorrect Bluetooth adapter state changed status");
288
289         }
290 }
291
292 static int __bt_adapter_state_handle_request(gboolean enable)
293 {
294         int result = BLUETOOTH_ERROR_NONE;
295         BT_DBG("");
296
297         switch (adapter_state) {
298         case BT_ACTIVATING:
299         {
300                 BT_INFO("Adapter is currently in activating state, state [%d]",
301                                 adapter_state);
302                 if (enable) {
303                         return BLUETOOTH_ERROR_IN_PROGRESS;
304                 } else {
305                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
306                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
307                                 /*TODO Stop Discovery*/
308                                 if (result != OAL_STATUS_SUCCESS)
309                                         BT_ERR("Discover stop failed: %d", result);
310                                 __bt_adapter_update_discovery_status(FALSE);
311                         }
312                         result = adapter_disable();
313                         if (result != OAL_STATUS_SUCCESS) {
314                                 BT_ERR("adapter_enable failed: [%d]", result);
315                                 result = BLUETOOTH_ERROR_INTERNAL;
316                                 /*TODO: perform if anything more needs to be done to handle failure */
317                         } else {
318                                 /* TODO: To be handled */
319                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
320                                 result = BLUETOOTH_ERROR_NONE;
321                         }
322                 }
323                 break;
324         }
325         case BT_ACTIVATED:
326         {
327                 BT_INFO("Adapter is currently in activated state, state [%d]",
328                                 adapter_state);
329                 if (enable) {
330                         return BLUETOOTH_ERROR_DEVICE_ALREADY_ENABLED;
331                 } else {
332                         if (adapter_discovery_state == ADAPTER_DISCOVERY_STARTED ||
333                                         adapter_discovery_state == ADAPTER_DISCOVERY_STARTING) {
334                                 /*TODO Stop Discovery*/
335                                 if (result != OAL_STATUS_SUCCESS)
336                                         BT_ERR("Discover stop failed: %d", result);
337                                 __bt_adapter_update_discovery_status(FALSE);
338                         }
339                         result = adapter_disable();
340                         if (result != OAL_STATUS_SUCCESS) {
341                                 BT_ERR("adapter_enable failed: [%d]", result);
342                                 result = BLUETOOTH_ERROR_INTERNAL;
343                                 /*TODO: perform if anything more needs to be done to handle failure */
344                         } else {
345                                 /* TODO: To be handled */
346                                 __bt_adapter_state_set_status(BT_DEACTIVATING);
347                                 result = BLUETOOTH_ERROR_NONE;
348                         }
349                 }
350                 break;
351         }
352         case BT_DEACTIVATING:
353         {
354                 BT_INFO("Adapter is currently in deactivating state, state [%d]",
355                                 adapter_state);
356                 if (!enable) {
357                         return BLUETOOTH_ERROR_IN_PROGRESS;
358
359                 } else {
360                         result = adapter_enable();
361                         if (result != OAL_STATUS_SUCCESS) {
362                                 BT_ERR("adapter_enable failed: [%d]", result);
363                                 adapter_disable();
364                                 result = BLUETOOTH_ERROR_INTERNAL;
365                                 /*TODO: perform if anything more needs to be done to handle failure */
366                         } else {
367                                 /* TODO: To be handled */
368                                 __bt_adapter_state_set_status(BT_ACTIVATING);
369                                 result = BLUETOOTH_ERROR_NONE;
370                         }
371                 }
372                 break;
373         }
374         case BT_DEACTIVATED:
375         {
376                 BT_INFO("Adapter is currently in deactivated state, state [%d]",
377                                 adapter_state);
378                 if (!enable) {
379                         return BLUETOOTH_ERROR_DEVICE_NOT_ENABLED;
380                 } else {
381                         result = adapter_enable();
382                         if (result != OAL_STATUS_SUCCESS) {
383                                 BT_ERR("adapter_enable failed: [%d]", result);
384                                 adapter_disable();
385                                 result = BLUETOOTH_ERROR_INTERNAL;
386                                 /*TODO: perform if anything more needs to be done to handle failure */
387                         } else {
388                                 /* TODO: To be handled */
389                                 __bt_adapter_state_set_status(BT_ACTIVATING);
390                                 result = BLUETOOTH_ERROR_NONE;
391                         }
392                 }
393                 break;
394         }
395         }
396         if (enable && result == BLUETOOTH_ERROR_NONE) {
397                 /* Adapter enable request is successful, setup event handlers */
398                 _bt_service_register_event_handler_callback(
399                                 BT_ADAPTER_MODULE, __bt_adapter_event_handler);
400                 /*TODO Set Device Core Callbacks*/
401         }
402         return result;
403 }
404