Sync from SPIN branch
[platform/core/telephony/tel-plugin-vconf.git] / src / vconf_handler.c
1 /*
2  * tel-plugin-vconf
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Ja-young Gu <jygu@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 #include <sys/sysinfo.h>
25
26 #include <glib.h>
27 #include <vconf.h>
28
29 #include <tcore.h>
30 #include <server.h>
31 #include <plugin.h>
32 #include <storage.h>
33 #include <co_network.h>
34
35 #include "vconf_main.h"
36 #include "vconf_handler.h"
37
38 /*
39  * Private data
40  */
41 typedef struct {
42         gboolean b_get_nck_retry_count;
43
44         enum modem_state last_modem_power_state;
45         gboolean last_flight_mode_state;
46         long last_modem_state_timestamp;
47 } VconfPrivData;
48
49 static gboolean __vconf_check_process_hook_callback(CoreObject *co)
50 {
51         const char *cp_name;
52
53         cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(co));
54         dbg("CP name: [%s]", cp_name);
55
56         if (cp_name == NULL)
57                 return FALSE;
58
59         return g_str_has_suffix(cp_name, "0");
60 }
61
62 static void __vconf_check_and_set_int(const char *in_key, const int intval)
63 {
64         int current;
65         vconf_get_int(in_key, &current);
66         if (current != intval)
67                 vconf_set_int(in_key, intval);
68 }
69
70 static void __vconf_check_and_set_str(const char *in_key, const char *strval)
71 {
72         char *current = vconf_get_str(in_key);
73
74         if (current) {
75                 if (strval && strcmp(current, strval))
76                         vconf_set_str(in_key, strval);
77
78                 free(current);
79         } else {
80                 vconf_set_str(in_key, strval);
81         }
82 }
83
84 static void __vconf_write_power_status_log(VconfPrivData *ud, enum modem_state state)
85 {
86         struct sysinfo sys_info;
87
88         if (ud == NULL)
89                 return;
90
91         if (0 != sysinfo(&sys_info))
92                 err("sysinfo failed.");
93
94         if (state == MODEM_STATE_ONLINE) {
95                 if (ud->last_modem_power_state == MODEM_STATE_LOW) {
96                         int count = 0;
97                         if (0 == vconf_get_int(VCONFKEY_TELEPHONY_PRIVATE_MODEM_ON_COUNT, &count)) {
98                                 count++;
99                                 if (0 != vconf_set_int(VCONFKEY_TELEPHONY_PRIVATE_MODEM_ON_COUNT, count))
100                                         err("vconf_set_int failed.");
101                         } else {
102                                 err("vconf_get_int failed.");
103                         }
104                         msg("[MODEM ON/OFF] MODEM LOW => ON in %d secs. (modem_on_count[%d] after boot-up. (uptime %ld secs))",
105                                         sys_info.uptime - ud->last_modem_state_timestamp, count, sys_info.uptime);
106                         ud->last_modem_power_state = state;
107                         ud->last_modem_state_timestamp = sys_info.uptime;
108                 }
109         } else if (state == MODEM_STATE_LOW) {
110                 if (ud->last_modem_power_state == MODEM_STATE_ONLINE) {
111                         int count = 0;
112                         if (0 != vconf_get_int(VCONFKEY_TELEPHONY_PRIVATE_MODEM_ON_COUNT, &count))
113                                 err("vconf_get_int failed.");
114
115                         msg("[MODEM ON/OFF] MODEM ON => LOW in %d secs. (modem_on_count=[%d] after boot-up(uptime %ld secs))",
116                                         sys_info.uptime - ud->last_modem_state_timestamp, count, sys_info.uptime);
117                         ud->last_modem_power_state = state;
118                         ud->last_modem_state_timestamp = sys_info.uptime;
119                 }
120         }
121 }
122
123 static void __vconf_update_network_name(CoreObject *o)
124 {
125         char *nwname = NULL;
126         char *spnname = NULL;
127         enum telephony_network_service_type svc_type;
128         enum telephony_network_access_technology svc_act;
129         enum tcore_network_name_priority network_name_priority;
130
131         tcore_network_get_service_type(o, &svc_type);
132         if (svc_type != NETWORK_SERVICE_TYPE_3G) {
133                 int current = 0;
134
135                 vconf_get_int(VCONFKEY_TELEPHONY_PSTYPE, &current);
136                 if (current != 0) {
137                         dbg("force hsdpa state off");
138                         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_NONE);
139                 }
140         }
141
142         tcore_network_get_access_technology(o, &svc_act);
143         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SVC_ACT, svc_act);
144
145         tcore_network_get_network_name_priority(o, &network_name_priority);
146         switch (network_name_priority) {
147         case TCORE_NETWORK_NAME_PRIORITY_SPN:
148                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, VCONFKEY_TELEPHONY_DISP_SPN);
149         break;
150
151         case TCORE_NETWORK_NAME_PRIORITY_NETWORK:
152                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, VCONFKEY_TELEPHONY_DISP_PLMN);
153         break;
154
155         case TCORE_NETWORK_NAME_PRIORITY_ANY:
156                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, VCONFKEY_TELEPHONY_DISP_SPN_PLMN);
157         break;
158
159         default:
160                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, VCONFKEY_TELEPHONY_DISP_INVALID);
161         break;
162         }
163
164         switch (svc_type) {
165         case NETWORK_SERVICE_TYPE_UNKNOWN:
166         case NETWORK_SERVICE_TYPE_NO_SERVICE:
167         case NETWORK_SERVICE_TYPE_EMERGENCY:
168         case NETWORK_SERVICE_TYPE_SEARCH:
169         break;
170
171         default:
172                 /* spn */
173                 spnname = tcore_network_get_network_name(o, TCORE_NETWORK_NAME_TYPE_SPN);
174                 if (spnname)
175                         __vconf_check_and_set_str(VCONFKEY_TELEPHONY_SPN_NAME, spnname);
176
177                 /* nitz */
178                 nwname = tcore_network_get_network_name(o, TCORE_NETWORK_NAME_TYPE_FULL);
179                 if (nwname && strlen(nwname) > 0) {
180                         dbg("SPN:[%s] FULL:[%s] prio:[%d] act:[%d] svc_type:[%d]",
181                                         spnname ? spnname : "", nwname, network_name_priority, svc_act, svc_type);
182                         __vconf_check_and_set_str(VCONFKEY_TELEPHONY_NWNAME, nwname);
183                         break;
184                 } else {
185                         if (nwname)
186                                 free(nwname);
187                         nwname = tcore_network_get_network_name(o, TCORE_NETWORK_NAME_TYPE_SHORT);
188                         if (nwname) {
189                                 dbg("SPN:[%s] SHORT:[%s] prio:[%d] act:[%d] svc_type:[%d]",
190                                         spnname ? spnname : "", nwname, network_name_priority, svc_act, svc_type);
191                                 __vconf_check_and_set_str(VCONFKEY_TELEPHONY_NWNAME, nwname);
192                                 break;
193                         }
194                 }
195                 dbg("name is not fixed yet. SPN:[%s] prio:[%d] act:[%d] svc_type:[%d]",
196                         spnname ? spnname : "", network_name_priority, svc_act, svc_type);
197
198         break;
199         }
200
201         if (spnname)
202                 free(spnname);
203
204         if (nwname)
205                 free(nwname);
206 }
207
208 static void __vconf_reset_vconfkeys()
209 {
210         vconf_set_str(VCONFKEY_TELEPHONY_NWNAME, "");
211         vconf_set_int(VCONFKEY_TELEPHONY_PLMN, 0);
212         vconf_set_int(VCONFKEY_TELEPHONY_LAC, 0);
213         vconf_set_int(VCONFKEY_TELEPHONY_CELLID, 0);
214         vconf_set_int(VCONFKEY_TELEPHONY_SVCTYPE, VCONFKEY_TELEPHONY_SVCTYPE_NONE);
215         vconf_set_int(VCONFKEY_TELEPHONY_SVC_CS, VCONFKEY_TELEPHONY_SVC_CS_UNKNOWN);
216         vconf_set_int(VCONFKEY_TELEPHONY_SVC_PS, VCONFKEY_TELEPHONY_SVC_PS_UNKNOWN);
217         vconf_set_int(VCONFKEY_TELEPHONY_SVC_ROAM, VCONFKEY_TELEPHONY_SVC_ROAM_OFF);
218 #ifdef TIZEN_FEATURE_CDMA
219         vconf_set_int(VCONFKEY_TELEPHONY_ROAM_ICON_MODE, VCONFKEY_TELEPHONY_ROAM_ICON_OFF);
220 #endif
221         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT, VCONFKEY_TELEPHONY_SIM_UNKNOWN);
222         vconf_set_int(VCONFKEY_TELEPHONY_SIM_PB_INIT, VCONFKEY_TELEPHONY_SIM_PB_INIT_NONE);
223         vconf_set_int(VCONFKEY_TELEPHONY_SPN_DISP_CONDITION, VCONFKEY_TELEPHONY_DISP_INVALID);
224         vconf_set_str(VCONFKEY_TELEPHONY_SPN_NAME, "");
225         vconf_set_int(VCONFKEY_TELEPHONY_RSSI, VCONFKEY_TELEPHONY_RSSI_0);
226         vconf_set_int(VCONFKEY_TELEPHONY_SIM_PB_INIT, VCONFKEY_TELEPHONY_SIM_PB_INIT_NONE);
227         vconf_set_int(VCONFKEY_TELEPHONY_NITZ_GMT, 0);
228         vconf_set_int(VCONFKEY_TELEPHONY_NITZ_EVENT_GMT, 0);
229         vconf_set_str(VCONFKEY_TELEPHONY_NITZ_ZONE, "");
230
231         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT2, VCONFKEY_TELEPHONY_SIM_UNKNOWN);
232 }
233
234 static void __vconf_telephony_ready_change_cb(keynode_t *node, void *data)
235 {
236         gboolean enable;
237
238         enable = vconf_keynode_get_bool(node);
239         dbg("Telephony State: [%s]", enable ? "Ready" : "NOT ready");
240
241         if (enable)
242                 vconf_set_int(VCONFKEY_TELEPHONY_TAPI_STATE, VCONFKEY_TELEPHONY_TAPI_STATE_READY);
243         else
244                 vconf_set_int(VCONFKEY_TELEPHONY_TAPI_STATE, VCONFKEY_TELEPHONY_TAPI_STATE_NONE);
245 }
246
247 static enum tcore_hook_return vconf_on_hook_network_location_cellinfo(Server *s,
248         CoreObject *source, enum tcore_notification_command command,
249         unsigned int data_len, void *data, void *user_data)
250 {
251         const struct tnoti_network_location_cellinfo *info = data;
252
253         /*
254          * Backward compatibility for Single SIM (Primary Subscription ONLY)
255          *
256          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
257          * processed
258          */
259         if (__vconf_check_process_hook_callback(source) == FALSE) {
260                 dbg("Notification NOT intended for Primary Subscription");
261                 return TCORE_HOOK_RETURN_CONTINUE;
262         }
263
264         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_CELLID, info->cell_id);
265         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_LAC, info->lac);
266
267         return TCORE_HOOK_RETURN_CONTINUE;
268 }
269
270 static enum tcore_hook_return vconf_on_hook_network_icon_info(Server *s,
271         CoreObject *source, enum tcore_notification_command command,
272         unsigned int data_len, void *data, void *user_data)
273 {
274         const struct tnoti_network_icon_info *info = data;
275
276         /*
277          * Backward compatibility for Single SIM (Primary Subscription ONLY)
278          *
279          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
280          * processed
281          */
282         if (__vconf_check_process_hook_callback(source) == FALSE) {
283                 dbg("Notification NOT intended for Primary Subscription");
284                 return TCORE_HOOK_RETURN_CONTINUE;
285         }
286 #ifdef TIZEN_FEATURE_CDMA
287         if (info->type & NETWORK_ICON_INFO_ROAM_ICON_MODE)
288                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_ROAM_ICON_MODE, info->roam_icon_mode);
289 #endif
290         if (info->type & NETWORK_ICON_INFO_RSSI)
291                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_RSSI, info->rssi);
292
293         return TCORE_HOOK_RETURN_CONTINUE;
294 }
295
296 static enum tcore_hook_return vconf_on_hook_network_registration_status(Server *s,
297         CoreObject *source, enum tcore_notification_command command,
298         unsigned int data_len, void *data, void *user_data)
299 {
300         const struct tnoti_network_registration_status *info = data;
301         int status;
302         gboolean roaming_allowed;
303
304         warn("vconf set (cs:[%d] ps:[%d] svctype:[%d] roam:[%d])",
305                 info->cs_domain_status, info->ps_domain_status, info->service_type, info->roaming_status);
306
307         /*
308          * Backward compatibility for Single SIM (Primary Subscription ONLY)
309          *
310          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
311          * processed
312          */
313         if (__vconf_check_process_hook_callback(source) == FALSE) {
314                 dbg("Notification NOT intended for Primary Subscription");
315                 return TCORE_HOOK_RETURN_CONTINUE;
316         }
317
318         /* CS */
319         if (info->cs_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
320                 status = 2;
321         else
322                 status = 1;
323
324         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SVC_CS, status);
325
326         /* PS */
327         if (info->ps_domain_status == NETWORK_SERVICE_DOMAIN_STATUS_FULL)
328                 status = 2;
329         else
330                 status = 1;
331
332         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SVC_PS, status);
333
334         /* Service type */
335         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SVCTYPE, info->service_type);
336
337         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SVC_ROAM, info->roaming_status);
338
339         __vconf_update_network_name(source);
340
341         vconf_get_bool(VCONFKEY_SETAPPL_STATE_DATA_ROAMING_BOOL, &roaming_allowed);
342         if (info->service_type > NETWORK_SERVICE_TYPE_SEARCH && !roaming_allowed && info->roaming_status) {
343                 int pkg_state;
344                 vconf_get_int(VCONFKEY_DNET_STATE, &pkg_state);
345                 if (pkg_state > 0) {
346                         dbg("Mismatch: hide PS icon.");
347                         __vconf_check_and_set_int(VCONFKEY_DNET_STATE, VCONFKEY_DNET_OFF);
348                 }
349         }
350         return TCORE_HOOK_RETURN_CONTINUE;
351 }
352
353 static enum tcore_hook_return vconf_on_hook_network_change(Server *s,
354         CoreObject *source, enum tcore_notification_command command,
355         unsigned int data_len, void *data, void *user_data)
356 {
357         const struct tnoti_network_change *info = data;
358
359         msg("vconf set (plmn:[%s] lac:[%d])", info->plmn, info->gsm.lac);
360
361         /*
362          * Backward compatibility for Single SIM (Primary Subscription ONLY)
363          *
364          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
365          * processed
366          */
367         if (__vconf_check_process_hook_callback(source) == FALSE) {
368                 dbg("Notification NOT intended for Primary Subscription");
369                 return TCORE_HOOK_RETURN_CONTINUE;
370         }
371
372         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PLMN, atoi(info->plmn));
373         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_LAC, info->gsm.lac);
374
375         __vconf_update_network_name(source);
376
377         return TCORE_HOOK_RETURN_CONTINUE;
378 }
379
380 static enum tcore_hook_return vconf_on_hook_network_identity(Server *s,
381         CoreObject *source, enum tcore_notification_command command,
382         unsigned int data_len, void *data, void *user_data)
383 {
384         const struct tnoti_network_identity *info = data;
385
386         msg("vconf set (plmn:[%s])", info->plmn);
387
388         /*
389          * Backward compatibility for Single SIM (Primary Subscription ONLY)
390          *
391          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
392          * processed
393          */
394         if (__vconf_check_process_hook_callback(source) == FALSE) {
395                 dbg("Notification NOT intended for Primary Subscription");
396                 return TCORE_HOOK_RETURN_CONTINUE;
397         }
398
399         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PLMN, atoi(info->plmn));
400
401         __vconf_update_network_name(source);
402
403         return TCORE_HOOK_RETURN_CONTINUE;
404 }
405
406 static enum tcore_hook_return vconf_on_hook_network_default_data_subs(Server *s,
407         CoreObject *source, enum tcore_notification_command command,
408         unsigned int data_len, void *data, void *user_data)
409 {
410         const struct tnoti_network_default_data_subs *info = data;
411
412         msg("vconf set (default data subs:[%d])", info->default_subs);
413         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_DB_DEFAULT_DATA_SUBS, info->default_subs);
414         return TCORE_HOOK_RETURN_CONTINUE;
415 }
416
417 static enum tcore_hook_return vconf_on_hook_sim_init(Server *s,
418         CoreObject *source, enum tcore_notification_command command,
419         unsigned int data_len, void *data, void *user_data)
420 {
421         const struct tnoti_sim_status *sim  = data;
422         const char *cp_name;
423         guint slot = 0;
424
425         cp_name = tcore_server_get_cp_name_by_plugin(tcore_object_ref_plugin(source));
426         dbg("CP name: [%s]", cp_name);
427
428         if (cp_name != NULL) {
429                 if (g_str_has_suffix(cp_name, "0")) {
430                         slot = 0;
431                 } else if (g_str_has_suffix(cp_name, "1")) {
432                         slot = 1;
433                 } else {
434                         err("Vconf keys are not supported for this CP name");
435                         return TCORE_HOOK_RETURN_CONTINUE;
436                 }
437         } else {
438                 err("CP Name is NULL");
439                 return TCORE_HOOK_RETURN_CONTINUE;
440         }
441
442         warn("vconf set (sim_status = %d), slot - (%d)", sim->sim_status, slot);
443
444         __vconf_check_and_set_int(VCONFKEY_TELEPHONY_SIM_STATUS, sim->sim_status);
445
446         switch (sim->sim_status) {
447         case SIM_STATUS_CARD_ERROR:
448         case SIM_STATUS_CARD_CRASHED:
449                 if (slot == 0)
450                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT, VCONFKEY_TELEPHONY_SIM_CARD_ERROR);
451                 else
452                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT2, VCONFKEY_TELEPHONY_SIM_CARD_ERROR);
453                 __vconf_check_and_set_str(VCONFKEY_TELEPHONY_NWNAME, "SIM Error");
454         break;
455
456         case SIM_STATUS_CARD_NOT_PRESENT:
457         case SIM_STATUS_CARD_REMOVED:
458                 if (slot == 0)
459                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT, VCONFKEY_TELEPHONY_SIM_NOT_PRESENT);
460                 else
461                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT2, VCONFKEY_TELEPHONY_SIM_NOT_PRESENT);
462                 __vconf_check_and_set_str(VCONFKEY_TELEPHONY_NWNAME, "NO SIM");
463         break;
464
465         case SIM_STATUS_INIT_COMPLETED:
466         case SIM_STATUS_INITIALIZING:
467         case SIM_STATUS_PIN_REQUIRED:
468         case SIM_STATUS_PUK_REQUIRED:
469         case SIM_STATUS_LOCK_REQUIRED:
470         case SIM_STATUS_CARD_BLOCKED:
471         case SIM_STATUS_NCK_REQUIRED:
472         case SIM_STATUS_NSCK_REQUIRED:
473         case SIM_STATUS_SPCK_REQUIRED:
474         case SIM_STATUS_CCK_REQUIRED:
475                 if (slot == 0)
476                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT, VCONFKEY_TELEPHONY_SIM_INSERTED);
477                 else
478                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT2, VCONFKEY_TELEPHONY_SIM_INSERTED);
479         break;
480
481         case SIM_STATUS_UNKNOWN:
482         default:
483                 if (slot == 0)
484                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT, VCONFKEY_TELEPHONY_SIM_UNKNOWN);
485                 else
486                         vconf_set_int(VCONFKEY_TELEPHONY_SIM_SLOT2, VCONFKEY_TELEPHONY_SIM_UNKNOWN);
487         break;
488         }
489
490         return TCORE_HOOK_RETURN_CONTINUE;
491 }
492
493 static enum tcore_hook_return vconf_on_hook_pb_init(Server *s,
494         CoreObject *source, enum tcore_notification_command command,
495         unsigned int data_len, void *data, void *user_data)
496 {
497         const struct tnoti_phonebook_status *pb  = data;
498
499         dbg("vconf set (pb->b_init = %d)", pb->b_init);
500
501         /*
502          * Backward compatibility for Single SIM (Primary Subscription ONLY)
503          *
504          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
505          * processed
506          */
507         if (__vconf_check_process_hook_callback(source) == FALSE) {
508                 dbg("Notification NOT intended for Primary Subscription");
509                 return TCORE_HOOK_RETURN_CONTINUE;
510         }
511
512         if (vconf_set_int(VCONFKEY_TELEPHONY_SIM_PB_INIT, pb->b_init) != 0)
513                 dbg("[FAIL] UPDATE VCONFKEY_TELEPHONY_SIM_PB_INIT");
514
515         return TCORE_HOOK_RETURN_CONTINUE;
516 }
517
518 static enum tcore_hook_return vconf_on_hook_ps_protocol_status(Server *s,
519         CoreObject *source, enum tcore_notification_command command,
520         unsigned int data_len, void *data, void *user_data)
521 {
522         enum telephony_network_service_type svc_type;
523         const struct tnoti_ps_protocol_status *noti = data;
524
525         dbg("vconf set (ps status = %d)", noti->status);
526
527         /*
528          * Backward compatibility for Single SIM (Primary Subscription ONLY)
529          *
530          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
531          * processed
532          */
533         if (__vconf_check_process_hook_callback(source) == FALSE) {
534                 dbg("Notification NOT intended for Primary Subscription");
535                 return TCORE_HOOK_RETURN_CONTINUE;
536         }
537
538         vconf_get_int(VCONFKEY_TELEPHONY_SVCTYPE, (int *)&svc_type);
539         if (svc_type < (enum telephony_network_service_type)VCONFKEY_TELEPHONY_SVCTYPE_2G) {
540                 dbg("service state is not available");
541                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_NONE);
542                 return TCORE_HOOK_RETURN_CONTINUE;
543         }
544
545         switch (noti->status) {
546         case TELEPHONY_HSDPA_OFF:
547                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_NONE);
548         break;
549
550         case TELEPHONY_HSDPA_ON:
551                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_HSDPA);
552         break;
553
554         case TELEPHONY_HSUPA_ON:
555                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_HSUPA);
556         break;
557
558         case TELEPHONY_HSPA_ON:
559                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_HSPA);
560         break;
561
562         case TELEPHONY_HSPAP_ON:
563                 __vconf_check_and_set_int(VCONFKEY_TELEPHONY_PSTYPE, VCONFKEY_TELEPHONY_PSTYPE_HSPAP);
564         break;
565
566         default:
567                 warn("invalid ps status");
568         break;
569         }
570
571         return TCORE_HOOK_RETURN_CONTINUE;
572 }
573
574 static enum tcore_hook_return vconf_on_hook_modem_flight_mode(Server *s,
575         CoreObject *source, enum tcore_notification_command command,
576         unsigned int data_len, void *data, void *user_data)
577 {
578         const struct tnoti_modem_flight_mode *flight_mode = data;
579         VconfPrivData *ud = user_data;
580
581         /*
582          * Backward compatibility for Single SIM (Primary Subscription ONLY)
583          *
584          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
585          * processed
586          */
587         if (__vconf_check_process_hook_callback(source) == FALSE) {
588                 dbg("Notification NOT intended for Primary Subscription");
589                 return TCORE_HOOK_RETURN_CONTINUE;
590         }
591
592         warn("vconf set (flight_mode = %d)", flight_mode->enable);
593
594         vconf_set_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, flight_mode->enable);
595
596         if (flight_mode->enable == 1) {
597                 if (ud->last_modem_power_state == MODEM_STATE_ONLINE && ud->last_flight_mode_state == FALSE) {
598                         __vconf_write_power_status_log(ud, MODEM_STATE_LOW);
599                         ud->last_flight_mode_state = TRUE;
600                 }
601         } else {
602                 if (ud->last_modem_power_state == MODEM_STATE_LOW && ud->last_flight_mode_state == TRUE) {
603                         __vconf_write_power_status_log(ud, MODEM_STATE_ONLINE);
604                         ud->last_flight_mode_state = FALSE;
605                 }
606         }
607
608         return TCORE_HOOK_RETURN_CONTINUE;
609 }
610
611 static enum tcore_hook_return vconf_on_hook_modem_power(Server *s,
612         CoreObject *source, enum tcore_notification_command command,
613         unsigned int data_len, void *data, void *user_data)
614 {
615         const struct tnoti_modem_power *power = data;
616         VconfPrivData *ud = user_data;
617
618         /*
619          * Backward compatibility for Single SIM (Primary Subscription ONLY)
620          *
621          * In case of Dual SIM, ONLY Primary Subscription's notifications would be
622          * processed
623          */
624         if (__vconf_check_process_hook_callback(source) == FALSE) {
625                 dbg("Notification NOT intended for Primary Subscription");
626                 return TCORE_HOOK_RETURN_CONTINUE;
627         }
628
629         /* TODO: check if tapi ready needs to be reset in case of cp reset
630                 Keeping current behavior
631         */
632         info("modem state : %d", power->state);
633
634         if (power->state == MODEM_STATE_RESUME) {
635                 info("tapi ready");
636                 vconf_set_int(VCONFKEY_TELEPHONY_TAPI_STATE, VCONFKEY_TELEPHONY_TAPI_STATE_READY);
637         } else if (power->state == MODEM_STATE_ERROR) {
638                 info("cp crash : all network setting will be reset");
639
640                 /*
641                  * Reset Telephony VCONF keys
642                  */
643                 __vconf_reset_vconfkeys();
644         } else if (power->state == MODEM_STATE_LOW) {
645                 vconf_set_bool(VCONFKEY_TELEPHONY_PRIVATE_MODEM_STATE, FALSE);
646                 __vconf_write_power_status_log(ud, MODEM_STATE_LOW);
647         } else if (power->state == MODEM_STATE_ONLINE) {
648                 vconf_set_bool(VCONFKEY_TELEPHONY_PRIVATE_MODEM_STATE, TRUE);
649                 __vconf_write_power_status_log(ud, MODEM_STATE_ONLINE);
650         }
651
652         return TCORE_HOOK_RETURN_CONTINUE;
653 }
654
655 static enum tcore_hook_return vconf_on_hook_bootup_complete(Server *s,
656         CoreObject *source, enum tcore_notification_command command,
657         unsigned int data_len, void *data, void *user_data)
658 {
659         info("tapi ready");
660         vconf_set_int(VCONFKEY_TELEPHONY_TAPI_STATE, VCONFKEY_TELEPHONY_TAPI_STATE_READY);
661
662         return TCORE_HOOK_RETURN_CONTINUE;
663 }
664
665 static enum tcore_hook_return vconf_on_hook_modem_plugin_removed(Server *s,
666         CoreObject *source, enum tcore_notification_command command,
667         unsigned int data_len, void *data, void *user_data)
668 {
669         dbg("vconf (Modem Plugin Removed!!!)");
670
671         /*
672          * Reset Telephony VCONF keys
673          */
674         __vconf_reset_vconfkeys();
675
676         return TCORE_HOOK_RETURN_CONTINUE;
677 }
678
679 /*
680  * Add notification hooks
681  */
682 static void __vconf_register_hooks(Server *s,
683         Storage *strg, VconfPrivData *ud)
684 {
685         /* Network related */
686         tcore_server_add_notification_hook(s, TNOTI_NETWORK_LOCATION_CELLINFO,
687                 vconf_on_hook_network_location_cellinfo, strg);
688         tcore_server_add_notification_hook(s, TNOTI_NETWORK_ICON_INFO,
689                 vconf_on_hook_network_icon_info, strg);
690         tcore_server_add_notification_hook(s, TNOTI_NETWORK_REGISTRATION_STATUS,
691                 vconf_on_hook_network_registration_status, strg);
692         tcore_server_add_notification_hook(s, TNOTI_NETWORK_CHANGE,
693                 vconf_on_hook_network_change, strg);
694         tcore_server_add_notification_hook(s, TNOTI_NETWORK_IDENTITY,
695                 vconf_on_hook_network_identity, strg);
696         tcore_server_add_notification_hook(s, TNOTI_NETWORK_DEFAULT_DATA_SUBSCRIPTION,
697                 vconf_on_hook_network_default_data_subs, strg);
698
699         /* SIM related */
700         tcore_server_add_notification_hook(s, TNOTI_SIM_STATUS,
701                 vconf_on_hook_sim_init, strg);
702
703         /* Phonebook related */
704         tcore_server_add_notification_hook(s, TNOTI_PHONEBOOK_STATUS,
705                 vconf_on_hook_pb_init, strg);
706
707         /* PS related */
708         tcore_server_add_notification_hook(s, TNOTI_PS_PROTOCOL_STATUS,
709                 vconf_on_hook_ps_protocol_status, strg);
710
711         /* Modem related */
712         tcore_server_add_notification_hook(s, TNOTI_MODEM_POWER,
713                 vconf_on_hook_modem_power, ud);
714         tcore_server_add_notification_hook(s, TNOTI_MODEM_BOOTUP,
715                 vconf_on_hook_bootup_complete, ud);
716         tcore_server_add_notification_hook(s, TNOTI_MODEM_FLIGHT_MODE,
717                 vconf_on_hook_modem_flight_mode, ud);
718
719         /* Plug-in related */
720         tcore_server_add_notification_hook(s, TNOTI_SERVER_REMOVED_MODEM_PLUGIN,
721                 vconf_on_hook_modem_plugin_removed, strg);
722
723         /*
724          * Track Telephony state change
725          *
726          * Need to update VCONFKEY_TELEPHONY_TAPI_STATE,
727          * key based on Telephony state change
728          */
729         vconf_notify_key_changed(VCONFKEY_TELEPHONY_READY,
730                 __vconf_telephony_ready_change_cb, NULL);
731 }
732
733 /*
734  * Remove notification hooks
735  */
736 static void __vconf_deregister_hooks(Server *s)
737 {
738         /* Network related */
739         tcore_server_remove_notification_hook(s, vconf_on_hook_network_location_cellinfo);
740         tcore_server_remove_notification_hook(s, vconf_on_hook_network_icon_info);
741         tcore_server_remove_notification_hook(s, vconf_on_hook_network_registration_status);
742         tcore_server_remove_notification_hook(s, vconf_on_hook_network_change);
743         tcore_server_remove_notification_hook(s, vconf_on_hook_network_identity);
744         tcore_server_remove_notification_hook(s, vconf_on_hook_network_default_data_subs);
745
746         /* SIM related */
747         tcore_server_remove_notification_hook(s, vconf_on_hook_sim_init);
748
749         /* Phonebook related */
750         tcore_server_remove_notification_hook(s, vconf_on_hook_pb_init);
751
752         /* PS related */
753         tcore_server_remove_notification_hook(s, vconf_on_hook_ps_protocol_status);
754
755         /* Modem related */
756         tcore_server_remove_notification_hook(s, vconf_on_hook_modem_power);
757         tcore_server_remove_notification_hook(s, vconf_on_hook_bootup_complete);
758         tcore_server_remove_notification_hook(s, vconf_on_hook_modem_flight_mode);
759
760         /* Plug-in related */
761         tcore_server_remove_notification_hook(s, vconf_on_hook_modem_plugin_removed);
762
763         /*
764          * Track Telephony state change
765          *
766          * Need to update VCONFKEY_TELEPHONY_TAPI_STATE,
767          * key based on Telephony state change
768          */
769         vconf_ignore_key_changed(VCONFKEY_TELEPHONY_READY,
770                 __vconf_telephony_ready_change_cb);
771
772 }
773
774 /*
775  * VCONF Handler Initialization function
776  */
777 gboolean vconf_handler_init(TcorePlugin *p)
778 {
779         Storage *strg;
780         Server *s;
781         VconfPrivData *ud;
782
783         if (!p)
784                 return FALSE;
785
786         dbg("Enter");
787
788         s = tcore_plugin_ref_server(p);
789         strg = tcore_server_find_storage(s, "vconf");
790         if (!strg)
791                 return FALSE;
792
793         ud = calloc(sizeof(VconfPrivData), 1);
794         if (ud == NULL) {
795                 err("Failed to allocate memory for user_data");
796                 tcore_storage_free(strg);
797                 return FALSE;
798         }
799
800         if (tcore_plugin_link_user_data(p, ud) != TCORE_RETURN_SUCCESS) {
801                 err("Failed to link user_data");
802                 tcore_storage_free(strg);
803                 free(ud);
804                 return FALSE;
805         }
806
807         /*
808          * Reset Telephony VCONF keys
809          */
810         __vconf_reset_vconfkeys();
811
812         /* Reset Telephony states */
813         vconf_set_int(VCONFKEY_TELEPHONY_TAPI_STATE, VCONFKEY_TELEPHONY_TAPI_STATE_NONE);
814         vconf_set_bool(VCONFKEY_TELEPHONY_READY, FALSE);
815
816         /*
817          * Register for all hook callbacks
818          */
819         __vconf_register_hooks(s, strg, ud);
820
821         return TRUE;
822 }
823
824 /*
825  * VCONF Handler De-initialization function
826  */
827 void vconf_handler_deinit(TcorePlugin *p)
828 {
829         Server *s;
830         VconfPrivData *ud;
831
832         if (!p)
833                 return;
834
835         dbg("Enter");
836
837         s = tcore_plugin_ref_server(p);
838
839         /*
840          * De-register for all hook callbacks
841          */
842         __vconf_deregister_hooks(s);
843
844         ud = tcore_plugin_ref_user_data(p);
845         if (ud)
846                 free(ud);
847 }