tizen 2.4 release
[framework/connectivity/mobileap-agent.git] / src / mobileap_handler.c
1 /*
2  * mobileap-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the License);
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 #include <glib.h>
19 #include <dbus/dbus.h>
20 #include <stdlib.h>
21
22 #include "mobileap_softap.h"
23 #include "mobileap_common.h"
24 #include "mobileap_bluetooth.h"
25 #include "mobileap_wifi.h"
26 #include "mobileap_usb.h"
27 #include "mobileap_notification.h"
28 #include "mobileap_handler.h"
29
30 #define VCONF_IS_DEVICE_RENAMED_IN_UG "file/private/libug-setting-mobileap-efl/is_device_rename_local"
31
32 typedef struct {
33         alarm_id_t alarm_id;
34         time_t end_time;
35         GSourceFunc func;
36         void *user_data;
37 } sp_timeout_handler_t;
38
39 static gboolean __wifi_timeout_cb(gpointer user_data);
40 static gboolean __bt_timeout_cb(gpointer user_data);
41
42 static sp_timeout_handler_t sp_timeout_handler[MOBILE_AP_TYPE_MAX] = {
43         {0, 0, __wifi_timeout_cb, NULL},
44         {0, 0, NULL, NULL},
45         {0, 0, __bt_timeout_cb, NULL},
46         {0, 0, NULL, NULL}};
47
48 static void __handle_network_cellular_state_changed_cb(keynode_t *key, void *data)
49 {
50         if (key == NULL) {
51                 ERR("Parameter is NULL\n");
52                 return;
53         }
54
55         Tethering *obj = (Tethering *)data;
56         int vconf_key = 0;
57
58         if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI | MOBILE_AP_STATE_WIFI_AP)) {
59                 return;
60         }
61
62         if (vconf_keynode_get_type(key) != VCONF_TYPE_INT) {
63                 ERR("Invalid vconf key type\n");
64                 return;
65         }
66
67         vconf_key = vconf_keynode_get_int(key);
68         SDBG("key = %s, value = %d(int)\n",
69                         vconf_keynode_get_name(key), vconf_key);
70
71         if (vconf_key != VCONFKEY_NETWORK_CELLULAR_FLIGHT_MODE)
72                 return;
73
74         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI))
75                 _disable_wifi_tethering(obj);
76         else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP))
77                 _disable_wifi_ap(obj);
78         if (_mobileap_is_enabled(MOBILE_AP_STATE_USB))
79                 _disable_usb_tethering(obj);
80
81         tethering_emit_flight_mode(obj);
82
83         return;
84 }
85
86 static void __handle_device_name_changed_cb(keynode_t *key, void *data)
87 {
88         if (key == NULL || data == NULL) {
89                 ERR("Parameter is NULL\n");
90                 return;
91         }
92
93         Tethering *obj = (Tethering *)data;
94         char *vconf_key = NULL;
95         softap_settings_t *new_settings = _get_softap_settings();
96         softap_security_type_e sec_type;
97
98         if (!_mobileap_is_enabled(MOBILE_AP_STATE_WIFI | MOBILE_AP_STATE_WIFI_AP)) {
99                 return;
100         }
101
102         if (vconf_keynode_get_type(key) != VCONF_TYPE_STRING) {
103                 ERR("Invalid vconf key type\n");
104                 return;
105         }
106         vconf_key = vconf_keynode_get_str(key);
107
108         if (g_strcmp0(vconf_key, new_settings->ssid) != 0) {
109                 DBG("Device name is changed\n");
110                 if (!g_strcmp0(new_settings->security_type, SOFTAP_SECURITY_TYPE_WPA2_PSK_STR)) {
111                         sec_type = SOFTAP_SECURITY_TYPE_WPA2_PSK;
112                 } else {
113                         sec_type = SOFTAP_SECURITY_TYPE_OPEN;
114                 }
115                 if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI)) {
116                         _reload_softap_settings(obj, vconf_key, new_settings->key,
117                                         new_settings->hide_mode, sec_type);
118                 } else if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI_AP)) {
119                         _reload_softap_settings_for_ap(obj, vconf_key, new_settings->key,
120                                         new_settings->hide_mode, sec_type);
121                 }
122         }
123         return;
124 }
125
126 static void __handle_language_changed_cb(keynode_t *key, void *data)
127 {
128         if (key == NULL || data == NULL) {
129                 ERR("Parameter is NULL\n");
130                 return;
131         }
132
133         char *language = NULL;
134
135         if (vconf_keynode_get_type(key) != VCONF_TYPE_STRING) {
136                 ERR("Invalid vconf key type\n");
137                 return;
138         }
139
140         language = vconf_get_str(VCONFKEY_LANGSET);
141         if (language) {
142                 setenv("LANG", language, 1);
143                 setenv("LC_MESSAGES",  language, 1);
144                 setlocale(LC_ALL, language);
145                 free(language);
146         }
147
148         return;
149 }
150
151 gboolean _is_power_save_survival_mode(void)
152 {
153         int ret;
154         int status;
155
156         ret = vconf_get_int(VCONFKEY_SETAPPL_PSMODE, &status);
157         if (ret != 0) {
158                 ERR("vconf_get_int is failed : %d\n", ret);
159                 return FALSE;
160         }
161
162         DBG(" PS mode status : %d", status);
163         if (status == SETTING_PSMODE_SURVIVAL)
164                 return TRUE;
165         else
166                 return FALSE;
167 }
168
169 void _register_vconf_cb(void *user_data)
170 {
171         if (user_data == NULL) {
172                 ERR("Invalid param\n");
173                 return;
174         }
175
176         vconf_reg_t vconf_reg[] = {
177                 {VCONFKEY_NETWORK_CELLULAR_STATE,
178                         __handle_network_cellular_state_changed_cb, NULL},
179                 {VCONFKEY_SETAPPL_DEVICE_NAME_STR,
180                         __handle_device_name_changed_cb, NULL},
181                 {VCONFKEY_LANGSET,
182                         __handle_language_changed_cb, NULL},
183                 {NULL, NULL, NULL}
184         };
185
186         int i = 0;
187         int ret = 0;
188
189         while (vconf_reg[i].key != NULL && vconf_reg[i].cb != NULL) {
190                 ret = vconf_notify_key_changed(vconf_reg[i].key,
191                                         vconf_reg[i].cb, user_data);
192                 if (ret != 0) {
193                         ERR("vconf_notify_key_changed is failed : %d\n", ret);
194                 }
195
196                 if (vconf_reg[i].value) {
197                         ret = vconf_get_int(vconf_reg[i].key,
198                                         vconf_reg[i].value);
199                         if (ret != 0) {
200                                 ERR("vconf_get_int is failed : %d\n", ret);
201                         }
202                 }
203
204                 i++;
205         }
206
207         return;
208 }
209
210 void _unregister_vconf_cb(void)
211 {
212         vconf_reg_t vconf_reg[] = {
213                 {VCONFKEY_NETWORK_CELLULAR_STATE,
214                         __handle_network_cellular_state_changed_cb, NULL},
215                 {VCONFKEY_SETAPPL_DEVICE_NAME_STR,
216                         __handle_device_name_changed_cb, NULL},
217                 {VCONFKEY_LANGSET,
218                         __handle_language_changed_cb, NULL},
219                 {NULL, NULL, NULL}
220         };
221
222         int i = 0;
223         int ret = 0;
224
225         while (vconf_reg[i].key != NULL && vconf_reg[i].cb != NULL) {
226                 ret = vconf_ignore_key_changed(vconf_reg[i].key,
227                                 vconf_reg[i].cb);
228                 if (ret != 0) {
229                         ERR("vconf_notify_key_changed is failed : %d\n", ret);
230                 }
231
232                 i++;
233         }
234
235         return;
236 }
237
238 static gboolean __wifi_timeout_cb(gpointer data)
239 {
240         DBG("+\n");
241         if (data == NULL) {
242                 ERR("data is NULL\n");
243                 return FALSE;
244         }
245
246         Tethering *obj = (Tethering *)data;
247
248         if (_mobileap_is_enabled(MOBILE_AP_STATE_WIFI) == FALSE) {
249                 ERR("There is no conn. via Wi-Fi tethernig. But nothing to do\n");
250                 return FALSE;
251         }
252
253         _disable_wifi_tethering(obj);
254         tethering_emit_wifi_off(obj, SIGNAL_MSG_TIMEOUT);
255         //_launch_toast_popup(MOBILE_AP_TETHERING_TIMEOUT_TOAST_POPUP);
256         _create_timeout_noti(MH_NOTI_ICON_WIFI);
257         DBG("-\n");
258         return FALSE;
259 }
260
261 static gboolean __bt_timeout_cb(gpointer data)
262 {
263         DBG("+\n");
264         if (data == NULL) {
265                 ERR("data is NULL\n");
266                 return FALSE;
267         }
268
269         Tethering *obj = (Tethering *)data;
270
271         if (_mobileap_is_enabled(MOBILE_AP_STATE_BT) == FALSE) {
272                 ERR("There is no conn. via BT tethering. But nothing to do\n");
273                 return FALSE;
274         }
275
276         _disable_bt_tethering(obj);
277         tethering_emit_bluetooth_off(obj, SIGNAL_MSG_TIMEOUT);
278         //_launch_toast_popup(MOBILE_AP_TETHERING_TIMEOUT_TOAST_POPUP);
279         _create_timeout_noti(MH_NOTI_ICON_BT);
280         DBG("-\n");
281         return FALSE;
282 }
283
284 static sp_timeout_handler_t *__find_next_timeout(void)
285 {
286         sp_timeout_handler_t *next_timeout = &sp_timeout_handler[MOBILE_AP_TYPE_WIFI];
287         mobile_ap_type_e i;
288
289         for (i = MOBILE_AP_TYPE_USB; i < MOBILE_AP_TYPE_MAX; i++) {
290                 if (sp_timeout_handler[i].end_time == 0)
291                         continue;
292
293                 if (sp_timeout_handler[i].end_time < next_timeout->end_time ||
294                                 next_timeout->end_time == 0)
295                         next_timeout = &sp_timeout_handler[i];
296         }
297
298         return next_timeout;
299 }
300
301 static void __expire_timeout(sp_timeout_handler_t *sp)
302 {
303         if (sp->alarm_id > 0) {
304                 alarmmgr_remove_alarm(sp->alarm_id);
305                 sp->alarm_id = 0;
306         }
307
308         sp->end_time = 0;
309
310         if (sp->func)
311                 sp->func(sp->user_data);
312 }
313
314 static void __reset_timeout(sp_timeout_handler_t *sp)
315 {
316         if (sp->alarm_id > 0) {
317                 alarmmgr_remove_alarm(sp->alarm_id);
318                 sp->alarm_id = 0;
319         }
320
321         sp->end_time = 0;
322 }
323
324 int _sp_timeout_handler(alarm_id_t alarm_id, void *user_param)
325 {
326         DBG("+\n");
327
328         int ret;
329         time_t now;
330         time_t interval;
331         mobile_ap_type_e i;
332         sp_timeout_handler_t *next_timeout;
333
334         now = time(NULL);
335         for (i = MOBILE_AP_TYPE_WIFI; i < MOBILE_AP_TYPE_MAX; i++) {
336                 if (sp_timeout_handler[i].end_time == 0)
337                         continue;
338
339                 if (sp_timeout_handler[i].alarm_id == alarm_id) {
340                         sp_timeout_handler[i].alarm_id = 0;
341                         __expire_timeout(&sp_timeout_handler[i]);
342                         continue;
343                 }
344
345                 interval = (time_t)difftime(sp_timeout_handler[i].end_time, now);
346                 if (interval > 0)
347                         continue;
348
349                 __expire_timeout(&sp_timeout_handler[i]);
350         }
351
352         next_timeout = __find_next_timeout();
353         if (next_timeout->end_time == 0)
354                 return 0;
355
356         interval = (time_t)difftime(next_timeout->end_time, now);
357         ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, interval, 0, NULL,
358                         &next_timeout->alarm_id);
359         if (ret != ALARMMGR_RESULT_SUCCESS) {
360                 ERR("alarmmgr_add_alarm is failed. end_time : %d\n",
361                                 next_timeout->end_time);
362                 return 0;
363         }
364
365         DBG("-\n");
366         return 0;
367 }
368
369 void _init_timeout_cb(mobile_ap_type_e type, void *user_data)
370 {
371         DBG("+\n");
372
373         if (sp_timeout_handler[type].func == NULL) {
374                 return;
375         }
376
377         if (user_data == NULL) {
378                 ERR("Invalid param\n");
379                 return;
380         }
381
382         sp_timeout_handler[type].alarm_id = 0;
383         sp_timeout_handler[type].end_time = 0;
384         sp_timeout_handler[type].user_data = user_data;
385
386         DBG("-\n");
387         return;
388 }
389
390 void _start_timeout_cb(mobile_ap_type_e type, time_t end_time)
391 {
392         int ret;
393         time_t interval;
394         mobile_ap_type_e i;
395         sp_timeout_handler_t *next_timeout;
396
397         if (sp_timeout_handler[type].func == NULL) {
398                 return;
399         }
400
401         __reset_timeout(&sp_timeout_handler[type]);
402         sp_timeout_handler[type].end_time = end_time;
403
404         next_timeout = __find_next_timeout();
405         if (next_timeout->alarm_id > 0) {
406                 return;
407         }
408
409         for (i = MOBILE_AP_TYPE_WIFI; i < MOBILE_AP_TYPE_MAX; i++) {
410                 if (sp_timeout_handler[i].alarm_id == 0)
411                         continue;
412
413                 __reset_timeout(&sp_timeout_handler[i]);
414         }
415
416         interval = (time_t)difftime(next_timeout->end_time, time(NULL));
417         if (interval <= 0) {
418                 __expire_timeout(next_timeout);
419                 return;
420         }
421
422         ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, interval, 0, NULL,
423                         &next_timeout->alarm_id);
424         if (ret != ALARMMGR_RESULT_SUCCESS) {
425                 ERR("alarmmgr_add_alarm is failed. type : %d, end_time : %d\n",
426                                 type, end_time);
427                 return;
428         }
429
430         return;
431 }
432
433 void _stop_timeout_cb(mobile_ap_type_e type)
434 {
435         DBG("+\n");
436
437         int ret;
438         time_t interval;
439         mobile_ap_type_e i;
440         sp_timeout_handler_t *next_timeout;
441
442         if (sp_timeout_handler[type].func == NULL) {
443                 return;
444         }
445
446         if (sp_timeout_handler[type].alarm_id == 0) {
447                 sp_timeout_handler[type].end_time = 0;
448                 return;
449         }
450
451         for (i = MOBILE_AP_TYPE_WIFI; i < MOBILE_AP_TYPE_MAX; i++) {
452                 if (sp_timeout_handler[i].end_time != sp_timeout_handler[type].end_time ||
453                                 type == i)
454                         continue;
455
456                 sp_timeout_handler[i].alarm_id = sp_timeout_handler[type].alarm_id;
457                 sp_timeout_handler[type].alarm_id = 0;
458                 sp_timeout_handler[type].end_time = 0;
459                 return;
460         }
461         __reset_timeout(&sp_timeout_handler[type]);
462
463         next_timeout = __find_next_timeout();
464         if (next_timeout->end_time == 0)
465                 return;
466
467         interval = (time_t)difftime(next_timeout->end_time, time(NULL));
468         if (interval <= 0) {
469                 __expire_timeout(next_timeout);
470                 return;
471         }
472
473         ret = alarmmgr_add_alarm(ALARM_TYPE_VOLATILE, interval, 0, NULL,
474                         &next_timeout->alarm_id);
475         if (ret != ALARMMGR_RESULT_SUCCESS) {
476                 ERR("alarmmgr_add_alarm is failed. type : %d, end_time : %d\n",
477                                 type, next_timeout->end_time);
478         }
479
480         DBG("-\n");
481         return;
482 }
483
484 void _deinit_timeout_cb(mobile_ap_type_e type) {
485         DBG("+\n");
486
487         if (sp_timeout_handler[type].func == NULL) {
488                 return;
489         }
490
491         if (sp_timeout_handler[type].alarm_id > 0) {
492                 _stop_timeout_cb(type);
493         }
494
495         sp_timeout_handler[type].user_data = NULL;
496         sp_timeout_handler[type].end_time = 0;
497
498         DBG("-\n");
499         return;
500 }