7fabc074c4eef6ab68d5aa5f8c8a4f0418b03925
[platform/core/telephony/tel-plugin-packetservice.git] / src / ps_service.c
1 /*
2  * tel-plugin-packetservice
3  *
4  * Copyright (c) 2012 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: DongHoo Park <donghoo.park@samsung.com>
7  *          Arun Shukla <arun.shukla@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include "ps_common.h"
24 #include "generated-code.h"
25
26 #include <core_object.h>
27 #include <co_ps.h>
28 #include <co_context.h>
29 #include <storage.h>
30
31 #define PROP_DEFAULT    FALSE
32 #define PROP_DEFAULT_STR   NULL
33
34 #define TIMEOUT_DEFAULT         5
35 #define TIMEOUT_MAX                     1800
36
37
38 static void __ps_service_emit_property_changed_signal(ps_service_t *service);
39 static void __ps_service_emit_context_added_signal(ps_service_t *service, gpointer context);
40 static void __ps_service_emit_context_removed_signal(ps_service_t *service, gpointer context);
41 static void _ps_service_setup_interface(PacketServiceService *service, ps_service_t *service_data);
42
43 static char *__ps_service_act2string(enum telephony_network_access_technology act);
44 static gboolean __ps_service_check_connection_option(gpointer service, gpointer context);
45 static int __ps_service_connetion_timeout_handler(alarm_id_t alarm_id, void *context);
46
47 void __remove_service_handler(gpointer data)
48 {
49         ps_service_t *service = data;
50
51         dbg("Entered");
52         if (!service) {
53                 dbg("Service is Null");
54                 return;
55         }
56
57         /*Need to remove the compelete hash table*/
58         g_slist_free(service->contexts);
59
60         /*Need to UNexport and Unref the master Object */
61         if (service->if_obj) {
62                 g_dbus_interface_skeleton_unexport(G_DBUS_INTERFACE_SKELETON(service->if_obj));
63                 g_object_unref(service->if_obj);
64                 service->if_obj = NULL;
65         }
66
67         /*Need to free the memory of the internal structure*/
68         g_free(service->path);
69         g_free(service);
70
71         dbg("Exiting");
72         return;
73 }
74
75 static void __ps_service_emit_property_changed_signal(ps_service_t *service)
76 {
77         GVariant *gv = NULL;
78         GVariantBuilder property;
79
80         ps_dbg_ex_co(_ps_service_ref_co_network(service), "get service properties");
81
82         gv = _ps_service_get_properties(service, &property);
83         packet_service_service_emit_property_changed(service->if_obj, gv);
84
85         dbg("Exiting");
86         return;
87 }
88
89 static void __ps_service_emit_context_added_signal(ps_service_t *service, gpointer context)
90 {
91         GVariant *gv = NULL;
92         GVariantBuilder property;
93
94         ps_dbg_ex_co(_ps_service_ref_co_network(service), "get service properties");
95
96         gv = _ps_context_get_properties(context, &property);
97         packet_service_service_emit_context_added(service->if_obj, gv);
98
99         dbg("Exiting");
100         return;
101 }
102
103 static void __ps_service_emit_context_removed_signal(ps_service_t *service, gpointer context)
104 {
105         ps_context_t *pscontext = context;
106
107         dbg("Entered");
108         packet_service_service_emit_context_removed(service->if_obj, pscontext->path);
109
110         dbg("Exiting");
111         return;
112 }
113
114 static char *__ps_service_act2string(enum telephony_network_access_technology act)
115 {
116         switch (act) {
117         case NETWORK_ACT_GSM:
118         case NETWORK_ACT_GPRS:
119         case NETWORK_ACT_EGPRS:
120         case NETWORK_ACT_UMTS:
121         case NETWORK_ACT_GSM_UTRAN:
122                 return "GSM";
123
124         case NETWORK_ACT_IS95A:
125         case NETWORK_ACT_IS95B:
126         case NETWORK_ACT_CDMA_1X:
127         case NETWORK_ACT_EVDO_REV0:
128         case NETWORK_ACT_CDMA_1X_EVDO_REV0:
129         case NETWORK_ACT_EVDO_REVA:
130         case NETWORK_ACT_CDMA_1X_EVDO_REVA:
131         case NETWORK_ACT_EVDV:
132                 return "CDMA";
133
134         case NETWORK_ACT_LTE:
135                 return "LTE";
136
137         case NETWORK_ACT_UNKNOWN:
138         default:
139                 return "unknown";
140         }
141
142         return NULL;
143 }
144
145 static gboolean __ps_service_check_connection_option(gpointer object, gpointer context)
146 {
147         gboolean b_connect = TRUE;
148         gboolean power = FALSE, sim = FALSE, data = FALSE, flight = FALSE, nw_ops = FALSE;
149         gboolean profile_reset = FALSE;
150
151         enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
152         gint ps_mode;
153         guchar hook_flag;
154
155         ps_service_t *service = object;
156         ps_modem_t *modem = _ps_service_ref_modem(service);
157         ps_context_t *ps_context = context;
158         CoreObject *co_context = (CoreObject *)_ps_context_ref_co_context(context);
159         CoreObject *co_network = _ps_service_ref_co_network(service);
160
161         if (TRUE != _ps_context_get_profile_enable(ps_context)) {
162                 ps_warn_ex_co(co_network, "Profile is disabled.");
163                 return FALSE;
164         }
165
166         role = tcore_context_get_role(co_context);
167         if (service->roaming)
168                 b_connect &= _ps_modem_get_data_roaming_allowed(modem);
169
170         sim = _ps_modem_get_sim_init(modem);
171         data = _ps_modem_get_data_allowed(modem);
172         flight = _ps_modem_get_flght_mode(modem);
173         hook_flag = _ps_modem_get_hook_flag(modem);
174         profile_reset = _ps_modem_get_reset_profile(modem);
175         if (hook_flag != PS_NO_PENDING_REQUEST)
176                 nw_ops = TRUE;
177         if (PS_MODEM_STATE_ONLINE == _ps_modem_get_power(modem))
178                 power = TRUE;
179
180         b_connect &= power;
181         b_connect &= sim;
182
183         if (role == CONTEXT_ROLE_IMS || role == CONTEXT_ROLE_IMS_EMERGENCY) {
184                 dbg("Do not check data allowed value in case of IMS type");
185         } else {
186 #if defined(TIZEN_SUPPORT_MMS_CONNECT_FORCE)
187                 ps_dbg_ex_co(co_network, "csc runtime feature enabled");
188                 if (role != CONTEXT_ROLE_MMS && role != CONTEXT_ROLE_PREPAID_MMS) {
189                         b_connect &= data;
190                 } else {
191                         char *tmp_apn = NULL;
192                         tmp_apn = tcore_context_get_apn(co_context);
193                         dbg("csc runtime feature is enabled: apn[%s]", tmp_apn);
194                         if (ps_feature_get_bool(PS_FEATURE_OPERATOR_SKT)) {
195                                 if (data)
196                                         tcore_context_set_apn(co_context, "web.sktelecom.com");
197                                 else
198                                         tcore_context_set_apn(co_context, "mmsonly.sktelecom.com");
199                         }
200                 }
201 #else
202                 ps_dbg_ex_co(co_network, "csc runtime feature disabled");
203                 b_connect &= data;
204 #endif
205         }
206
207         b_connect &= !flight;
208         b_connect &= !nw_ops;
209         b_connect &= !service->restricted;
210         b_connect &= !profile_reset;
211 #ifndef TIZEN_PS_FORCE_ATTACH_DETACH
212         b_connect &= service->ps_attached;
213 #endif
214         ps_mode = _ps_modem_get_psmode(modem);
215
216         /*
217          * Kiran PLM P141017-05702
218          * Problem: PDP retry when Wifi connected.
219          * Reproducible cases:
220          * 1) Wifi auto connected but PDP has never been connected.
221          * 2) Quick switch Wifi On -> Off before PDP establishment is complete.
222          * 2nd exceptional case is handled by Connmand but 1st case should be
223          * taken care of by telephony.
224          * Solution: Do not PDP retry until initial PDP connection when Wifi connected.
225          */
226         if (service->initial_pdp_conn == FALSE) {
227                 int wifi_state = PS_WIFI_STATE_OFF;
228                 Server *s = NULL;
229                 Storage *strg = NULL;
230
231                 s = tcore_plugin_ref_server(service->plg);
232                 strg = tcore_server_find_storage(s, "vconf");
233                 wifi_state = tcore_storage_get_int(strg, KEY_WIFI_STATE);
234                 if (wifi_state == PS_WIFI_STATE_CONNECTED) {
235                         if (service->wifi_connected_checked == FALSE) {
236                                 ps_dbg_ex_co(co_network, "DO NOT set PDP retry timer when WiFi connected but PDP never been connected yet.");
237                                 b_connect &= FALSE;
238                                 service->wifi_connected_checked = TRUE;
239                         } else {
240                                 ps_dbg_ex_co(co_network, "Wifi connected state was already checked.");
241                         }
242                 }
243         }
244         ps_dbg_ex_co(co_network, "b_connect(%d), power(%d), sim init(%d), data allowed(%d), flight mode(%d) restricted(%d) ps_attached(%d), ps_mode(%d), fook_flag(%d)",
245                 b_connect, power, sim, data, flight, service->restricted, service->ps_attached, ps_mode, hook_flag);
246
247         /* In case of ME in LCD off & UPS mode.
248          * Do not allow PDP activation.
249          */
250         if (b_connect) {
251                 if (ps_mode > POWER_SAVING_MODE_NORMAL && ps_mode < POWER_SAVING_MODE_WEARABLE) {
252                         Storage *strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(service->plg), "vconf");
253                         gint pm_state = tcore_storage_get_int(strg_vconf, STORAGE_KEY_PM_STATE);
254                         if (pm_state == 3) {
255                                 ps_warn_ex_co(co_network, "PDP activation is not allowed in LCD off & UPS mode.");
256                                 b_connect = FALSE;
257                         }
258                 }
259         }
260         return b_connect;
261 }
262
263 static int __ps_service_connetion_timeout_handler(alarm_id_t alarm_id, void *context)
264 {
265         int rv = 0;
266         ps_service_t *service = _ps_context_ref_service(context);
267         if (service == NULL) {
268                 err("service is NULL!!!");
269                 return rv;
270         }
271
272         if (service->timer_src > 0) {
273                 dbg("remove connection retry timer (%d)", service->timer_src);
274                 alarmmgr_remove_alarm(service->timer_src);
275                 service->timer_src = 0;
276         }
277         rv = _ps_service_activate_context(service, context);
278         ps_dbg_ex_co(_ps_service_ref_co_network(service), "return rv(%d)", rv);
279         return rv;
280 }
281
282 void _ps_service_set_attach_apn(ps_service_t *service)
283 {
284         unsigned int index;
285
286         for (index = 0; index < g_slist_length(service->contexts); index++) {
287                 gpointer ps_context = g_slist_nth_data(service->contexts, index);
288                 CoreObject *co_context = _ps_context_ref_co_context(ps_context);
289                 gboolean attach_apn = tcore_context_get_attach_apn(co_context);
290                 if (attach_apn) {
291                         TReturn rv;
292                         char *apn = tcore_context_get_apn(co_context);
293                         dbg("'Attach APN' [%s]", apn);
294                         rv = tcore_ps_define_context(service->co_ps, co_context, NULL);
295                         if (rv != TCORE_RETURN_SUCCESS)
296                                 err("fail to define context");
297
298                         g_free(apn);
299                         /* Attach APN is only one. */
300                         break;
301                 }
302         }
303 }
304
305 gpointer _ps_service_create_service(GDBusConnection *conn, TcorePlugin *p, gpointer p_modem,
306                 CoreObject *co_network, CoreObject *co_ps, gchar *path)
307 {
308         PacketServiceService *service;
309         GError *error = NULL;
310         ps_service_t *new_service;
311
312         ps_dbg_ex_co(co_network, "service object create");
313         g_return_val_if_fail(conn != NULL, NULL);
314         g_return_val_if_fail(p_modem != NULL, NULL);
315
316         /*creating the master object for the interface com.tcore.ps.modem*/
317         service = packet_service_service_skeleton_new();
318
319         /*Initializing the modem list for internal referencing*/
320         new_service = g_try_malloc0(sizeof(ps_service_t));
321         if (NULL == new_service) {
322                 ps_err_ex_co(co_network, "Unable to allocate memory for master");
323                 goto FAILURE;
324         }
325
326         new_service->conn = conn;
327         new_service->plg = p;
328         new_service->p_modem = p_modem;
329         new_service->co_network = co_network;
330         new_service->co_ps = co_ps;
331         new_service->path = g_strdup(path);
332         new_service->if_obj = service;
333
334         /*exporting the interface object to the path mention for master*/
335         if (TRUE != g_dbus_interface_skeleton_export((G_DBUS_INTERFACE_SKELETON(service)), conn, path, &error)) {
336                 ps_err_ex_co(co_network, "Failed to export interaface with message [%s] & ID[%d] ", error->message, error->code);
337                 goto FAILURE;
338         }
339
340         _ps_hook_co_network_event(new_service);
341         _ps_get_co_network_values(new_service);
342         _ps_hook_co_ps_event(new_service);
343
344         /*Setting up the interface for the service */
345         _ps_service_setup_interface(service, new_service);
346
347         new_service->connection_timeout = TIMEOUT_DEFAULT;
348         ps_dbg_ex_co(co_network, "Successfully Created the service");
349         return new_service;
350
351 FAILURE:
352         /*To Do: Handle failure case*/
353         g_free(new_service);
354         g_assert_no_error(error);
355         return NULL;
356 }
357
358 gboolean _ps_service_ref_context(gpointer object, gpointer context)
359 {
360         gpointer tmp = NULL;
361         ps_service_t *service = object;
362         CoreObject *co_network = NULL;
363
364         dbg("service refer to context");
365         g_return_val_if_fail(service != NULL, FALSE);
366
367         co_network = _ps_service_ref_co_network(service);
368         tmp = g_slist_find(service->contexts, context);
369         if (tmp != NULL) {
370                 ps_dbg_ex_co(co_network, "context(%p) already existed", tmp);
371                 return FALSE;
372         }
373
374         _ps_context_set_service(context, service);
375         tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(context));
376         service->contexts = g_slist_append(service->contexts, context);
377
378         ps_dbg_ex_co(co_network, "context(%p) insert to linked-list", context);
379         __ps_service_emit_context_added_signal(service, context);
380
381         return TRUE;
382 }
383
384 gboolean _ps_service_ref_contexts(gpointer object, GSList *contexts, gchar *operator)
385 {
386         ps_service_t *service = object;
387         gboolean ret = TRUE;
388         int rv;
389         unsigned int index, count;
390         CoreObject *co_network = NULL;
391         g_return_val_if_fail(service != NULL, FALSE);
392         count = g_slist_length(contexts);
393         ps_dbg_ex_co(co_network, "service refer to contexts: count(%d)", count);
394         co_network = _ps_service_ref_co_network(service);
395         for (index = 0; index < count; index++) {
396                 gpointer tmp = NULL, value = NULL;
397
398                 value = g_slist_nth_data(contexts, index);
399                 tmp = g_slist_find(service->contexts, value);
400                 if (tmp != NULL) {
401                         ps_dbg_ex_co(co_network, "context(%p) already existed", tmp);
402                         continue;
403                 }
404
405                 _ps_context_set_service(value, service);
406                 tcore_ps_add_context(service->co_ps, (CoreObject *) _ps_context_ref_co_context(value));
407                 service->contexts = g_slist_append(service->contexts, value);
408
409                 ps_dbg_ex_co(co_network, "context(%p) path(%s) insert to linked-list", value, _ps_context_ref_path(value));
410                 __ps_service_emit_context_added_signal(service, value);
411
412 #ifdef PREPAID_SIM_APN_SUPPORT
413                 ret = _ps_service_connect_last_connected_context_ex(service, value, NULL, operator);
414                 dbg("ret[%d]", ret);
415                 if (ret == TRUE) {
416                         /* process next available profile */
417                         continue;
418                 }
419 #endif
420
421                 if (service->ps_attached) {
422                         gboolean f_awo = _ps_context_get_alwayson_enable(value);
423                         if (f_awo) {
424                                 rv = _ps_service_define_context(service, value);
425                                 ps_dbg_ex_co(co_network, "Always-on started, return rv(%d)", rv);
426                         }
427                 }
428         }
429         ps_dbg_ex_co(co_network, "service->contexts: count(%d)", g_slist_length(service->contexts));
430         _ps_update_cellular_state_key(service);
431         return ret;
432 }
433
434 gboolean _ps_service_get_properties_handler(gpointer object, GVariantBuilder *properties)
435 {
436         ps_service_t *service = object;
437
438         dbg("get service properties");
439         g_return_val_if_fail(service != NULL, FALSE);
440         g_return_val_if_fail(properties != NULL, FALSE);
441
442         g_variant_builder_open(properties, G_VARIANT_TYPE("a{ss}"));
443         g_variant_builder_add(properties, "{ss}", "path", service->path);
444         g_variant_builder_add(properties, "{ss}", "ps_attached", BOOL2STRING(service->ps_attached));
445         g_variant_builder_add(properties, "{ss}", "roaming", BOOL2STRING(service->roaming));
446         g_variant_builder_add(properties, "{ss}", "act", __ps_service_act2string(service->act));
447         g_variant_builder_close(properties);
448
449         dbg("Exiting");
450         return TRUE;
451 }
452
453 GVariant *_ps_service_get_properties(gpointer object, GVariantBuilder *properties)
454 {
455         ps_service_t *service = object;
456
457         dbg("get service properties ");
458         g_return_val_if_fail(service != NULL, FALSE);
459         g_return_val_if_fail(properties != NULL, FALSE);
460
461         g_variant_builder_init(properties, G_VARIANT_TYPE("a{ss}"));
462
463         g_variant_builder_add(properties, "{ss}", "path", service->path);
464         g_variant_builder_add(properties, "{ss}", "ps_attached", BOOL2STRING(service->ps_attached));
465         g_variant_builder_add(properties, "{ss}", "roaming", BOOL2STRING(service->roaming));
466         g_variant_builder_add(properties, "{ss}", "act", __ps_service_act2string(service->act));
467
468         dbg("Exiting");
469         return g_variant_builder_end(properties);
470 }
471
472 gchar *_ps_service_ref_path(gpointer object)
473 {
474         ps_service_t *service = object;
475         g_return_val_if_fail(service != NULL, NULL);
476
477         return service->path;
478 }
479
480 gpointer _ps_service_ref_plugin(gpointer object)
481 {
482         ps_service_t *service = object;
483         g_return_val_if_fail(service != NULL, NULL);
484
485         return service->plg;
486 }
487
488 gpointer _ps_service_ref_co_network(gpointer object)
489 {
490         ps_service_t *service = object;
491         g_return_val_if_fail(service != NULL, NULL);
492
493         return service->co_network;
494 }
495
496 gpointer _ps_service_ref_co_ps(gpointer object)
497 {
498         ps_service_t *service = object;
499         g_return_val_if_fail(service != NULL, NULL);
500
501         return service->co_ps;
502 }
503
504 gpointer _ps_service_ref_modem(gpointer object)
505 {
506         ps_service_t *service = object;
507         g_return_val_if_fail(service != NULL, NULL);
508
509         return service->p_modem;
510 }
511
512 gboolean _ps_service_set_context_devinfo(gpointer object, struct tnoti_ps_pdp_ipconfiguration *devinfo)
513 {
514         GSList *contexts = NULL;
515         ps_service_t *service = object;
516         CoreObject *co_context = NULL;
517
518         dbg("set context info");
519         g_return_val_if_fail(service != NULL, FALSE);
520         g_return_val_if_fail(devinfo != NULL, FALSE);
521
522         contexts = tcore_ps_ref_context_by_id(service->co_ps, devinfo->context_id);
523         if (!contexts) {
524                 ps_dbg_ex_co(_ps_service_ref_co_network(service), "fail to ref context by cid.");
525                 return FALSE;
526         }
527
528
529
530
531         while (contexts) {
532                 ps_modem_t *modem = NULL;
533                 int role = CONTEXT_ROLE_UNKNOWN;
534
535                 co_context = contexts->data;
536                 if (!co_context) {
537                         contexts = contexts->next;
538                         continue;
539                 }
540
541                 /*TEMP*/
542                 role = tcore_context_get_role(co_context);
543                 modem = _ps_service_ref_modem(service);
544                 if (g_strcmp0(modem->operator, "45005") == 0 && role == CONTEXT_ROLE_IMS) {
545                         ps_dbg_ex_co(_ps_service_ref_co_network(service), "SKT INS PDN");
546                         /*IPv4*/
547                         if (devinfo->pcscf_ipv4_count == 0) {
548                                 char ipv4[16];
549                                 snprintf(ipv4, 16, "%d.%d.%d.%d",
550                                         devinfo->ip_address[0], devinfo->ip_address[1],
551                                         devinfo->ip_address[2], devinfo->ip_address[3]);
552                                 if (!g_str_equal(ipv4, "0.0.0.0")) {
553                                         devinfo->pcscf_ipv4_count = 1;
554                                         devinfo->pcscf_ipv4 = g_try_malloc0(sizeof(char *) * devinfo->pcscf_ipv4_count);
555                                         if (devinfo->pcscf_ipv4 != NULL)
556                                                 devinfo->pcscf_ipv4[0] = g_strdup("220.103.220.10");
557                                 }
558                         }
559                         /*IPv6*/
560                         if (devinfo->pcscf_ipv6_count == 0) {
561                                 if (devinfo->ipv6_address != NULL) {
562                                         devinfo->pcscf_ipv6_count = 1;
563                                         devinfo->pcscf_ipv6 = g_try_malloc0(sizeof(char *) * devinfo->pcscf_ipv6_count);
564                                         if (devinfo->pcscf_ipv6 != NULL)
565                                                 devinfo->pcscf_ipv6[0] = g_strdup("2001:2d8:00e0:0220::10");
566                                 }
567                         }
568                 }
569
570                 tcore_context_set_devinfo(co_context, devinfo);
571
572                 contexts = contexts->next;
573         }
574
575         return TRUE;
576 }
577
578 gboolean _ps_service_set_context_bearerinfo(gpointer object, struct tnoti_ps_dedicated_bearer_info *bearer_info)
579 {
580         GSList *contexts = NULL;
581         ps_service_t *service = object;
582         CoreObject *co_context = NULL;
583
584         dbg("set context info");
585         g_return_val_if_fail(service != NULL, FALSE);
586         g_return_val_if_fail(bearer_info != NULL, FALSE);
587
588         contexts = tcore_ps_ref_context_by_id(service->co_ps, bearer_info->primary_context_id);
589         if (!contexts) {
590                 ps_dbg_ex_co(_ps_service_ref_co_network(service), "fail to ref context by cid.");
591                 return FALSE;
592         }
593
594         while (contexts) {
595                 unsigned int index;
596
597                 co_context = contexts->data;
598                 if (!co_context) {
599                         contexts = contexts->next;
600                         continue;
601                 }
602
603                 for (index = 0; index < g_slist_length(service->contexts); index++) {
604                         gpointer value = g_slist_nth_data(service->contexts, index);
605                         if (co_context == _ps_context_ref_co_context(value)) {
606                                 _ps_context_set_bearer_info(value, bearer_info);
607                                 break;
608                         }
609                 }
610
611                 contexts = contexts->next;
612         }
613
614         return TRUE;
615 }
616
617 int _ps_service_define_context(gpointer object, gpointer context)
618 {
619         ps_service_t *service = object;
620         CoreObject *co_context = NULL;
621         gboolean b_connect = TRUE;
622
623         dbg("define context(%p)", context);
624         g_return_val_if_fail(service != NULL, FALSE);
625
626         b_connect = __ps_service_check_connection_option(service, context);
627         if (!b_connect)
628                 return TCORE_RETURN_EPERM;
629
630         return tcore_ps_define_context(service->co_ps, co_context, NULL);
631 }
632
633 int _ps_service_activate_context(gpointer object, gpointer context)
634 {
635         ps_service_t *service = object;
636         ps_modem_t *modem = NULL;
637         CoreObject *co_context = NULL;
638         gboolean b_connect = TRUE;
639         gboolean ps_defined;
640         int ret = TCORE_RETURN_SUCCESS;
641         int default_data_subs = 1;
642         ps_subs_type subs_type = 1;
643         Server *s = NULL;
644         static Storage *strg;
645         CoreObject *co_network = NULL;
646
647         dbg("activate context(%p)", context);
648         g_return_val_if_fail(service != NULL, FALSE);
649
650         s = tcore_plugin_ref_server(_ps_service_ref_plugin(service));
651         strg = tcore_server_find_storage(s, "vconf");
652
653         co_network = _ps_service_ref_co_network(service);
654         modem = _ps_service_ref_modem(service);
655         ps_defined = _ps_context_get_ps_defined(context);
656         co_context = (CoreObject *)_ps_context_ref_co_context(context);
657         if (modem->hook_flag != PS_NO_PENDING_REQUEST) {
658                 ps_dbg_ex_co(co_network, "Pending request present in queue with flag %x", modem->hook_flag);
659                 ret = TCORE_RETURN_FAILURE;
660                 goto EXIT;
661         }
662
663         /* Check for default data subscription value if matchs for modem then only activate */
664         subs_type = _ps_modem_get_subs_type(modem);
665         default_data_subs = tcore_storage_get_int(strg, STORAGE_KEY_TELEPHONY_DUALSIM_DEFAULT_DATA_SERVICE_INT);
666         if ((default_data_subs != -1) && (default_data_subs != (int)subs_type)) {
667                 ps_warn_ex_co(co_network, "activation  for only [SIM%d] selected by Setting", default_data_subs + 1);
668                 ret = TCORE_RETURN_FAILURE;
669                 goto EXIT;
670         }
671
672         b_connect = __ps_service_check_connection_option(service, context);
673         if (!b_connect) {
674                 ret = TCORE_RETURN_EPERM;
675                 goto EXIT;
676         }
677
678         if (!ps_defined) {
679                 ps_dbg_ex_co(co_network, "pdp profile is not defined yet, define first. ");
680                 ret = tcore_ps_define_context(service->co_ps, co_context, NULL);
681         } else {
682                 ps_dbg_ex_co(co_network, "pdp profile is defined, activate context. ");
683                 ret = tcore_ps_activate_context(service->co_ps, co_context, NULL);
684         }
685 EXIT:
686         if (ret != TCORE_RETURN_SUCCESS) {
687                 if (ps_defined) {
688                         /*
689                          * CONTEXT_STATE_ACTIVATING : Never be happen.
690                          * CONTEXT_STATE_ACTIVATED : Never be happen.
691                          * CONTEXT_STATE_DEACTIVATING: Do not clear resources.
692                          */
693                         if (CONTEXT_STATE_DEACTIVATED == tcore_context_get_state(co_context)) {
694                                 ps_warn_ex_co(co_network, "fail to activate context after PDP define complete, clear resources.");
695                                 _ps_context_set_ps_defined(context, FALSE);
696                                 tcore_ps_clear_context_id(service->co_ps, co_context);
697                         } else {
698                                 ps_err_ex_co(co_network, "invalid context state.");
699                         }
700                 }
701         }
702         return ret;
703 }
704
705 gboolean _ps_service_deactivate_context(gpointer object, gpointer context)
706 {
707         ps_service_t *service = object;
708         CoreObject *co_context = NULL;
709
710         g_return_val_if_fail(service != NULL, FALSE);
711         dbg("deactivate context(%p)", context);
712         co_context = (CoreObject *)_ps_context_ref_co_context(context);
713
714         return tcore_ps_deactivate_context(service->co_ps, co_context, NULL);
715 }
716
717 void _ps_service_set_retry_timeout_value(gpointer object, int value)
718 {
719         ps_service_t *service = object;
720         g_return_if_fail(service != NULL);
721
722         service->connection_timeout = value;
723         dbg("current timeout (%d)", service->connection_timeout);
724         return;
725 }
726
727 void _ps_service_connection_timer(gpointer object, gpointer context)
728 {
729         int result = 0;
730         gboolean f_awo = FALSE;
731         ps_service_t *service = object;
732
733         g_return_if_fail(service != NULL);
734
735         f_awo = _ps_context_get_alwayson_enable(context);
736         if (!f_awo)
737                 return;
738
739         if (service->timer_src > 0) {
740                 warn("remove connection retry timer (%d)", service->timer_src);
741                 alarmmgr_remove_alarm(service->timer_src);
742                 service->timer_src = 0;
743         }
744         result = alarmmgr_add_alarm_withcb(ALARM_TYPE_VOLATILE, (time_t)(service->connection_timeout),
745                         0, __ps_service_connetion_timeout_handler, context, &(service->timer_src));
746         if (result != ALARMMGR_RESULT_SUCCESS) {
747                 err("Failed to add alarm(%d)", result);
748                 return;
749         }
750
751         dbg("cellular service timer started timer src(%d), timeout(%d)", service->timer_src, service->connection_timeout);
752         service->connection_timeout = (service->connection_timeout)*2;
753         if (service->connection_timeout >= TIMEOUT_MAX)
754                 service->connection_timeout = TIMEOUT_MAX;
755
756         return;
757 }
758
759 void _ps_service_reset_connection_timer(gpointer context)
760 {
761         gboolean f_awo = FALSE;
762         ps_service_t *service = NULL;
763 #ifdef PREPAID_SIM_APN_SUPPORT
764         gboolean p_awo = FALSE;
765
766         p_awo = _ps_context_get_prepaid_alwayson_enable(context);
767         f_awo = _ps_context_get_alwayson_enable(context);
768         if (!f_awo && !p_awo)
769                 return;
770 #else
771         f_awo = _ps_context_get_alwayson_enable(context);
772         if (!f_awo)
773                 return;
774 #endif
775
776         service = _ps_context_ref_service(context);
777         if (service == NULL) {
778                 err("service is NULL!!!");
779                 return;
780         }
781         service->connection_timeout = TIMEOUT_DEFAULT;
782
783         if (service->timer_src > 0) {
784                 warn("remove connection retry timer (%d)", service->timer_src);
785                 alarmmgr_remove_alarm(service->timer_src);
786                 service->timer_src = 0;
787         }
788         return;
789 }
790
791 gboolean _ps_service_unref_context(gpointer object, gpointer context)
792 {
793         ps_service_t *service = object;
794         ps_modem_t *modem = _ps_service_ref_modem(service);
795         ps_context_t *pscontext = context;
796
797         g_return_val_if_fail(service != NULL, FALSE);
798         g_return_val_if_fail(modem != NULL, FALSE);
799         g_return_val_if_fail(context != NULL, FALSE);
800         g_return_val_if_fail(pscontext->path != NULL, FALSE);
801         dbg("service unref context (%s)", pscontext->path);
802
803         _ps_service_deactivate_context(service, context);
804         /* remove context from the list (modem, service) */
805         modem->contexts = g_slist_remove(modem->contexts, pscontext);
806         __ps_service_emit_context_removed_signal(service, pscontext);
807         return TRUE;
808 }
809
810 void _ps_service_remove_contexts(gpointer object)
811 {
812         unsigned int index;
813         ps_service_t *service = object;
814         guint count;
815
816         g_return_if_fail(service != NULL);
817         count = g_slist_length(service->contexts);
818         ps_dbg_ex_co(_ps_service_ref_co_network(service), "service remove all contexts: count(%d)", count);
819
820         for (index = 0; index < count; index++) {
821                 gpointer value = NULL;
822                 value = g_slist_nth_data(service->contexts, index);
823                 ps_dbg_ex_co(_ps_service_ref_co_network(service), "path(%s), value(%p) context", _ps_context_ref_path(value), value);
824                 _ps_service_unref_context(service, value);
825                 _ps_context_remove_context(value);
826         }
827         g_slist_free(service->contexts);
828         service->contexts = NULL;
829         return;
830 }
831
832 void _ps_service_disconnect_contexts(gpointer object)
833 {
834         unsigned int index;
835         ps_service_t *service = object;
836
837         dbg("service disconnect all contexts");
838         g_return_if_fail(service != NULL);
839
840         for (index = 0; index < g_slist_length(service->contexts); index++) {
841                 gpointer value = g_slist_nth_data(service->contexts, index);
842                 _ps_service_reset_connection_timer(value);
843                 _ps_service_deactivate_context(service, value);
844         }
845
846         return;
847 }
848
849 void _ps_service_disconnect_internet_mms_contexts(gpointer object)
850 {
851         unsigned int index;
852         ps_service_t *service = object;
853         CoreObject *co_context = NULL;
854         enum co_context_role role = CONTEXT_ROLE_UNKNOWN;
855
856         dbg("Service disconnect Internet/MMS contexts");
857         g_return_if_fail(service != NULL);
858
859         for (index = 0; index < g_slist_length(service->contexts); index++) {
860                 gpointer value = g_slist_nth_data(service->contexts, index);
861                 co_context = (CoreObject *)_ps_context_ref_co_context(value);
862                 role = tcore_context_get_role(co_context);
863
864                 /*
865                  * Deactivate following type of contexts -
866                  *      - INTERNET
867                  *      - INTERNET_PREPAID
868                  *      - MMS
869                  *      - MMS_PREPAID
870                  */
871                 switch (role) {
872                 case CONTEXT_ROLE_INTERNET:
873                 case CONTEXT_ROLE_MMS:
874                 case CONTEXT_ROLE_PREPAID_INTERNET:
875                 case CONTEXT_ROLE_PREPAID_MMS:
876                         _ps_service_reset_connection_timer(value);
877                         _ps_service_deactivate_context(service, value);
878                 break;
879
880                 default: {
881                         dbg("Need not deactivate for %d PDN type", role);
882                         continue;
883                 }
884                 }
885         }
886 }
887
888 #ifdef PREPAID_SIM_APN_SUPPORT
889 gboolean _ps_service_connect_last_connected_context_ex(gpointer service, gpointer object,
890         gboolean *defined, char *operator)
891 {
892         int profile_id = -1;
893         int current_profile_id = -1;
894         Storage *strg_vconf = NULL;
895         ps_context_t *context;
896         gchar *last_connected_operator = NULL;
897         gboolean last_connected_profile = FALSE;
898         int rv;
899
900         dbg("Entry");
901         context = object;
902         strg_vconf = tcore_server_find_storage(tcore_plugin_ref_server(context->plg), "vconf");
903         if (strg_vconf) {
904                 last_connected_profile =  tcore_storage_get_bool(strg_vconf,
905                                         STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_BOOL);
906                 dbg("last_connected_profile [%s]", last_connected_profile ? "TRUE" : "FALSE");
907                 /* Last connected profile exist */
908                 if (last_connected_profile) {
909                         /* Fetch last connected profile's operator */
910                         last_connected_operator =  tcore_storage_get_string(strg_vconf,
911                                 STORAGE_KEY_TELEPHONY_LAST_CONNECTED_CONTEXT_PLMN);
912                         dbg("last_connected_operator[%s] current operator[%s]", last_connected_operator, operator);
913
914                         if (g_strcmp0(last_connected_operator, operator) != 0) {
915                                 /* different SIM, So reset STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_BOOL
916                                     and continue to activate default profile.
917                                   */
918                                  dbg("Different SIM, reset last connected context");
919                                  tcore_storage_set_bool(strg_vconf,
920                                         STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_BOOL, FALSE);
921                         } else {
922                                 /*Fetch last connected context profile id */
923                                 dbg("Fetch last connected context profile id");
924                                 profile_id = tcore_storage_get_int(strg_vconf,
925                                                 STORAGE_KEY_PDP_LAST_CONNECTED_CONTEXT_PROFILE_ID);
926
927                                 /* Fetch current context profile id */
928                                 current_profile_id = _ps_context_get_profile_id(context);
929                                 dbg("last connected context profile id[%d], current context profile id[%d]",
930                                         profile_id, current_profile_id);
931
932                                 if (profile_id  != current_profile_id) {
933                                         dbg("Current context profile id and last connected profile does not match ..");
934                                         /* Current context profile id and last connected profile does not match
935                                              Check for next available profile.
936                                            */
937                                         return TRUE;
938                                 } else {
939                                         /* activate last connected context */
940                                         dbg("activate last connected context");
941                                         rv =  _ps_service_define_context(service, context);
942                                         dbg("return rv(%d)", rv);
943                                         if (defined)
944                                                 *defined = TRUE;
945                                         return TRUE;
946                                 }
947                         }
948
949                 } else  {
950                         dbg("There is no last connected profile");
951                 }
952         } else {
953                 dbg("invalid storage handle");
954         }
955
956         return FALSE;
957 }
958
959 gboolean _ps_service_connect_last_connected_context(gpointer object)
960 {
961         gboolean ret;
962         gboolean defined = FALSE;
963         ps_service_t *service = object;
964         gchar *operator = NULL;
965         unsigned int index;
966
967         dbg("Entry");
968
969         g_return_val_if_fail(service != NULL, TCORE_RETURN_FAILURE);
970         operator = _ps_modem_ref_operator(_ps_service_ref_modem(service));
971
972         for (index = 0; index < g_slist_length(service->contexts); index++) {
973                 gpointer ps_context = g_slist_nth_data(service->contexts, index);
974                 ret = _ps_service_connect_last_connected_context_ex(service, ps_context, &defined, operator);
975                 dbg("ret[%d]", ret);
976                 if (defined == TRUE) {
977                         dbg("context[%p]", ps_context);
978                         return defined;
979                 }
980         }
981         return FALSE;
982 }
983 #endif
984
985 int _ps_service_connect_default_context(gpointer object)
986 {
987         int rv = 0;
988         unsigned int index;
989         ps_service_t *service = object;
990
991         dbg("service connect default context");
992         g_return_val_if_fail(service != NULL, TCORE_RETURN_FAILURE);
993
994         for (index = 0; index < g_slist_length(service->contexts); index++) {
995                 gpointer value = g_slist_nth_data(service->contexts, index);
996                 gboolean f_awo = FALSE;
997                 f_awo = _ps_context_get_alwayson_enable(value);
998
999                 if (f_awo) {
1000                         /*  FIX: Kiran PLM P141111-07502 */
1001                         /* _ps_service_reset_connection_timer(value); */
1002                         rv = _ps_service_activate_context(service, value);
1003                         ps_dbg_ex_co(_ps_service_ref_co_network(service), "return rv(%d)", rv);
1004                         break;
1005                 }
1006         }
1007
1008         return rv;
1009 }
1010
1011 #ifdef PREPAID_SIM_APN_SUPPORT
1012 int _ps_service_connect_default_prepaid_context(gpointer object)
1013 {
1014         int rv = 0;
1015         ps_service_t *service = object;
1016         unsigned int index;
1017         dbg("Entry");
1018
1019         g_return_val_if_fail(service != NULL, TCORE_RETURN_FAILURE);
1020
1021         for (index = 0; index < g_slist_length(service->contexts); index++) {
1022                 gpointer ps_context = g_slist_nth_data(service->contexts, index);
1023                 gboolean f_awo = FALSE;
1024                 f_awo = _ps_context_get_prepaid_alwayson_enable(ps_context);
1025                 if (f_awo) {
1026                         _ps_service_reset_connection_timer(ps_context);
1027                         rv = _ps_service_activate_context(service, ps_context);
1028                         dbg("return rv(%d)", rv);
1029                         break;
1030                 }
1031         }
1032         dbg("Exit - rv[%d]", rv);
1033         return rv;
1034 }
1035
1036 gpointer _ps_service_return_context_by_cid(gpointer object, int context_id)
1037 {
1038         ps_service_t *service = object;
1039         unsigned int index;
1040
1041         g_return_val_if_fail(service != NULL, NULL);
1042
1043         for (index = 0; index < g_slist_length(service->contexts); index++) {
1044                 gpointer ps_context = g_slist_nth_data(service->contexts, index);
1045                 int tmp_cid;
1046                 CoreObject *co_context = NULL;
1047
1048                 co_context = _ps_context_ref_co_context(ps_context);
1049                 tmp_cid = tcore_context_get_id(co_context);
1050
1051                 if (tmp_cid != context_id)
1052                         continue;
1053
1054                 return ps_context;
1055         }
1056         return NULL;
1057 }
1058 #endif
1059
1060 gpointer _ps_service_return_default_context(gpointer object, int svc_cat_id)
1061 {
1062         unsigned int index;
1063         ps_service_t *service = object;
1064
1065         g_return_val_if_fail(service != NULL, NULL);
1066
1067         for (index = 0; index < g_slist_length(service->contexts); index++) {
1068                 gpointer value = g_slist_nth_data(service->contexts, index);
1069                 gboolean b_default = FALSE;
1070                 b_default = _ps_context_get_default_context(value, svc_cat_id);
1071
1072                 if (b_default)
1073                         return value;
1074         }
1075
1076         return NULL;
1077 }
1078
1079 int _ps_service_update_roaming_apn(gpointer object)
1080 {
1081         int rv = 0;
1082         ps_service_t *service = object;
1083         ps_modem_t *modem = _ps_service_ref_modem(object);
1084         gboolean p_from = FALSE; /* default <FLASE> : Home newtwork */
1085         GSList *contexts = NULL;
1086
1087         g_return_val_if_fail(service != NULL, TCORE_RETURN_FAILURE);
1088         g_return_val_if_fail(modem != NULL, TCORE_RETURN_FAILURE);
1089
1090         dbg("roaming status: %d", service->roaming);
1091         /* 1) Remove all contexts
1092          * 2) Load Home/Roaming profiles from database.
1093
1094          * Home -> Roaming network:
1095          * 3-2) If Any roaming profile is not provided by service provider,
1096          *      load Home profiles from database.
1097          */
1098
1099         p_from = _ps_modem_get_roaming_apn_support(modem);
1100         if (p_from) {
1101                 _ps_service_remove_contexts(object);
1102                 contexts = _ps_context_create_hashtable((gpointer)modem, service->roaming);
1103                 if (contexts != NULL) {
1104                         rv = _ps_service_set_number_of_pdn_cnt(object, modem->operator);
1105                         rv = _ps_service_ref_contexts(object, contexts, modem->operator);
1106                 }
1107         }
1108         dbg("rv: %d", rv);
1109         return rv;
1110 }
1111
1112 gboolean _ps_service_processing_network_event(gpointer object, gboolean ps_attached, gboolean roaming)
1113 {
1114         gboolean ret = TRUE;
1115         ps_service_t *service = object;
1116         CoreObject *co_network = NULL;
1117         gboolean prev_roaming_status;
1118         g_return_val_if_fail(service != NULL, FALSE);
1119
1120
1121         prev_roaming_status = _ps_service_get_roaming(service);
1122
1123         co_network = _ps_service_ref_co_network(service);
1124         _ps_service_set_ps_attached(service, ps_attached);
1125         _ps_service_set_roaming(service, roaming);
1126         _ps_update_cellular_state_key(service);
1127
1128         if (prev_roaming_status != _ps_service_get_roaming(service)) {
1129                 gboolean roaming_allowed = FALSE;
1130                 roaming_allowed = _ps_modem_get_data_roaming_allowed(service->p_modem);
1131                 _ps_service_update_roaming_apn(object);
1132
1133                 if (!roaming_allowed && roaming) {
1134                         ps_dbg_ex_co(co_network, "Roaming allowed (%d), Roaming status (%d)", roaming_allowed, roaming);
1135                         _ps_service_disconnect_contexts(service);
1136                         return TRUE;
1137                 }
1138         }
1139
1140         if (service->ps_attached) {
1141 #ifdef PREPAID_SIM_APN_SUPPORT
1142                 ret = _ps_service_connect_last_connected_context(service);
1143                 dbg("ret[%d]", ret);
1144                 if (ret == TRUE)
1145                         return ret; /* No need to activate default context */
1146 #endif
1147                 _ps_service_connect_default_context(service);
1148         }
1149
1150         return ret;
1151 }
1152
1153 gboolean _ps_service_set_connected(gpointer object, gpointer cstatus, gboolean enabled)
1154 {
1155         unsigned int index;
1156         gboolean def_awo = FALSE, b_def_conn = FALSE;
1157         gpointer def_conn = NULL;
1158         gpointer requested_conn = NULL;
1159
1160         ps_service_t *service = NULL;
1161         struct tnoti_ps_call_status *call_status = NULL;
1162         CoreObject *co_network;
1163
1164         service = (ps_service_t *) object;
1165         co_network = _ps_service_ref_co_network(service);
1166         call_status = (struct tnoti_ps_call_status *)cstatus;
1167
1168         if (enabled && service->initial_pdp_conn == FALSE) {
1169                 ps_dbg_ex_co(co_network, "Initial PDP connection.");
1170                 service->initial_pdp_conn = TRUE;
1171         }
1172
1173         for (index = 0; index < g_slist_length(service->contexts); index++) {
1174                 gpointer value = g_slist_nth_data(service->contexts, index);
1175                 int tmp_cid;
1176                 gboolean b_tmp_def = FALSE;
1177                 CoreObject *context = NULL;
1178                 gpointer b_user_data = NULL;
1179
1180                 context = _ps_context_ref_co_context(value);
1181                 tmp_cid = tcore_context_get_id(context);
1182
1183                 if (tmp_cid != call_status->context_id) continue;
1184
1185                 /* if there is default context in disconnected cid, it has to retry auto connection */
1186                 b_tmp_def = _ps_context_get_default_context(value, CONTEXT_ROLE_INTERNET);
1187                 if (!b_def_conn)
1188                         b_def_conn = b_tmp_def;
1189
1190                 /* if disconnected connection has the user data, it is a priority connection. */
1191                 b_user_data = _ps_context_get_user_data(value);
1192                 if (b_user_data) {
1193                         def_conn = value;
1194                         requested_conn = b_user_data;
1195                 }
1196
1197                 if (!enabled) {
1198                         gchar *ipv4 = NULL;
1199
1200                         ps_dbg_ex_co(co_network, "Reset socket connections.");
1201
1202                         tcore_ps_clear_context_id(service->co_ps, context);
1203                         ipv4 = tcore_context_get_ipv4_addr(context);
1204                         tcore_util_reset_ipv4_socket(tcore_context_get_ipv4_devname(context), (const char *)ipv4);
1205                 }
1206
1207                 _ps_context_set_connected(value, enabled);
1208         }
1209
1210         /* connect to request profile */
1211         if (!enabled && requested_conn) {
1212                 ps_dbg_ex_co(co_network, "connect to request profile (%p)", requested_conn);
1213                 _ps_connection_hdlr(requested_conn);
1214                 _ps_service_reset_connection_timer(def_conn);
1215                 _ps_context_reset_user_data(def_conn);
1216                 return TRUE;
1217         }
1218
1219         /* default context and always on is true. - request to connect */
1220         if (!enabled) {
1221                 gint ps_mode = 0;
1222                 def_conn = _ps_service_return_default_context(service, CONTEXT_ROLE_INTERNET);
1223                 def_awo = _ps_context_get_alwayson_enable(def_conn);
1224
1225                 if (!def_awo) {
1226                         ps_dbg_ex_co(co_network, "there is no always on connection");
1227                         return TRUE;
1228                 }
1229
1230                 /* In case of ME in LCD off & UPS mode.
1231                  * Do not enable PDP retry timer for default internet context.
1232                  */
1233                 ps_mode = _ps_modem_get_psmode(_ps_service_ref_modem(service));
1234                 if (ps_mode > POWER_SAVING_MODE_NORMAL && ps_mode < POWER_SAVING_MODE_WEARABLE) {
1235                         Storage *strg_vconf = tcore_server_find_storage(_ps_service_ref_plugin(service), "vconf");
1236                         gint pm_state = tcore_storage_get_int(strg_vconf, STORAGE_KEY_PM_STATE);
1237                         if (pm_state == 3) {
1238                                 ps_warn_ex_co(co_network, "PDP retry timer is not allowed in LCD off & UPS mode.");
1239                                 return TRUE;
1240                         }
1241                 }
1242
1243                 /* always on TRUE and default connection - NORMAL RETRY */
1244                 /* always on TRUE and no default connection - WAIT 5 Secs for retry from application */
1245                 if (b_def_conn) {
1246                         /* retry connection */
1247                         _ps_service_connection_timer(service, def_conn);
1248                 } else {
1249
1250                         /* disconnect from user intention */
1251 #if defined(CONNECT_DEFAULT_CONNECTION_WITHOUT_TIMER)
1252                         if (call_status->result == 2000) {
1253                                 ps_dbg_ex_co(co_network, "user intended disconnect / connect default connection without timer");
1254                                 __ps_service_connetion_timeout_handler(service->timer_src, def_conn);
1255                                 return TRUE;
1256                         }
1257 #endif
1258                         /* with unexpected disconnection from network/me */
1259                         _ps_service_set_retry_timeout_value(service, TIMEOUT_DEFAULT);
1260                         _ps_service_connection_timer(service, def_conn);
1261                 }
1262
1263         }
1264
1265         /* To send deactivation request of default profile */
1266         if (enabled && requested_conn) {
1267                 ps_dbg_ex_co(co_network, "Send deactivation to default profile and connect to request profile (%p)", requested_conn);
1268                 return FALSE;
1269         }
1270
1271         return TRUE;
1272 }
1273
1274 void _ps_service_set_ps_defined(gpointer *object, gboolean value, int cid)
1275 {
1276         ps_service_t *service = (ps_service_t *)object;
1277         unsigned int index;
1278         CoreObject *co_network;
1279
1280         g_return_if_fail(service != NULL);
1281
1282         co_network = _ps_service_ref_co_network(service);
1283         for (index = 0; index < g_slist_length(service->contexts); index++) {
1284                 gpointer ps_context = g_slist_nth_data(service->contexts, index);
1285                 CoreObject *co_context = _ps_context_ref_co_context(ps_context);
1286                 unsigned char context_id = tcore_context_get_id(co_context);
1287                 if (context_id == cid) {
1288                         gboolean attach_apn = tcore_context_get_attach_apn(co_context);
1289                         gboolean proceed_activation = TRUE;
1290
1291                         /* Check attach apn complete */
1292                         if (value && attach_apn && !service->attach_apn_complete) {
1293                                 int role = tcore_context_get_role(co_context);
1294                                 ps_dbg_ex_co(co_network, "Initial define of attach APN is complete for profile role(%d)", role);
1295                                 service->attach_apn_complete = TRUE;
1296
1297                                 if(TRUE == _ps_context_get_default_context(ps_context, CONTEXT_ROLE_INTERNET) && service->ps_attached)
1298                                         proceed_activation = TRUE;
1299                                 else {
1300                                         proceed_activation = FALSE;
1301                                         tcore_ps_clear_context_id(service->co_ps, co_context);
1302                                 }
1303                         }
1304                         proceed_activation &= value;
1305
1306                         /* Set 'ps_defined' */
1307                         _ps_context_set_ps_defined(ps_context, proceed_activation);
1308
1309                         if (proceed_activation) {
1310                                 /* Activate if define is completed */
1311                                 ps_dbg_ex_co(co_network, "define is complete, activate context for cid(%d)", cid);
1312                                 if (_ps_service_activate_context(service, ps_context) == TCORE_RETURN_SUCCESS) {
1313                                         dbg("Successful activate context");
1314                                         tcore_ps_set_cid_active(service->co_ps, cid, TRUE);
1315                                 }
1316                         }
1317                         break;
1318                 }
1319         }
1320
1321         return;
1322 }
1323
1324 gboolean _ps_service_set_ps_attached(gpointer object, gboolean value)
1325 {
1326         ps_service_t *service = object;
1327         g_return_val_if_fail(service != NULL, FALSE);
1328
1329         service->ps_attached = value;
1330         ps_dbg_ex_co(_ps_service_ref_co_network(service), "service(%p) ps_attached(%d)", service, service->ps_attached);
1331         __ps_service_emit_property_changed_signal(service);
1332
1333         return TRUE;
1334 }
1335
1336 gboolean _ps_service_get_restricted(gpointer object)
1337 {
1338         ps_service_t *service = object;
1339         g_return_val_if_fail(service != NULL, FALSE);
1340
1341         return service->restricted;
1342 }
1343
1344 gboolean _ps_service_set_restricted(gpointer object, gboolean value)
1345 {
1346         ps_service_t *service = object;
1347         g_return_val_if_fail(service != NULL, FALSE);
1348
1349         service->restricted = value;
1350         ps_dbg_ex_co(_ps_service_ref_co_network(service), "service(%p) restricted(%d)", service, service->restricted);
1351
1352         _ps_update_cellular_state_key(service);
1353         return TRUE;
1354 }
1355
1356 gboolean _ps_service_set_number_of_pdn_cnt(gpointer object, gchar *operator)
1357 {
1358         int rv = 0;
1359         int num_of_pdn = 0;
1360         ps_service_t *service = object;
1361         g_return_val_if_fail(service != NULL, FALSE);
1362         ps_dbg_ex_co(_ps_service_ref_co_network(service), "Entered");
1363         num_of_pdn = _ps_context_get_number_of_pdn(operator, _ps_modem_ref_cp_name(_ps_service_ref_modem(object)));
1364         rv = tcore_ps_set_num_of_pdn(service->co_ps, num_of_pdn);
1365
1366         if (rv != TCORE_RETURN_SUCCESS)
1367                 ps_dbg_ex_co(_ps_service_ref_co_network(service), "error to get maximum number of pdn");
1368
1369         dbg("Exiting");
1370         return TRUE;
1371 }
1372
1373 gboolean _ps_service_get_roaming(gpointer object)
1374 {
1375         ps_service_t *service = object;
1376         g_return_val_if_fail(service != NULL, FALSE);
1377
1378         return service->roaming;
1379 }
1380
1381 gboolean _ps_service_set_roaming(gpointer object, gboolean value)
1382 {
1383         ps_service_t *service = object;
1384         g_return_val_if_fail(service != NULL, FALSE);
1385
1386         service->roaming = value;
1387         ps_dbg_ex_co(_ps_service_ref_co_network(service), "service(%p) roaming(%d)", service, service->roaming);
1388         __ps_service_emit_property_changed_signal(service);
1389
1390         return TRUE;
1391 }
1392
1393 static void _indicator_cb_dns_reply(GObject *src, GAsyncResult *res, gpointer user_data)
1394 {
1395         GList *list, *cur;
1396         GInetAddress *addr;
1397         gchar *str_addr;
1398         GError *error = NULL;
1399
1400         list = g_resolver_lookup_by_name_finish((GResolver *)src, res, &error);
1401         if (!list) {
1402                 dbg("fail to get dns resolving");
1403                 if (error) {
1404                         dbg("error:%d, %s", error->code, error->message);
1405                         g_error_free(error);
1406                 }
1407                 return;
1408         }
1409
1410         for (cur = list; cur; cur = cur->next) {
1411                 addr = cur->data;
1412                 str_addr = g_inet_address_to_string(addr);
1413                 if (!str_addr)
1414                         continue;
1415                 dbg("addr(%s)", str_addr);
1416
1417                 g_free(str_addr);
1418                 g_object_unref(cur->data);
1419                 break;
1420         }
1421
1422         g_object_unref(src);
1423         g_list_free(list);
1424         return;
1425 }
1426
1427 gboolean _ps_service_set_access_technology(gpointer object,
1428                 enum telephony_network_access_technology value)
1429 {
1430         gboolean ret = TRUE;
1431         ps_service_t *service = object;
1432         CoreObject *co_network = NULL;
1433         enum telephony_network_access_technology p_act = 0;
1434         g_return_val_if_fail(service != NULL, FALSE);
1435
1436         co_network = _ps_service_ref_co_network(service);
1437         p_act = service->act;
1438         service->act = value;
1439         ps_dbg_ex_co(co_network, "service(%p) P ACT(%d) Access Technology(%d)", service, p_act, service->act);
1440
1441         if (p_act == NETWORK_ACT_LTE && (service->act >= NETWORK_ACT_GSM && service->act < NETWORK_ACT_LTE)) {
1442                 GResolver *r = NULL;
1443
1444                 ps_dbg_ex_co(co_network, "send the dns pkt for keeping connection");
1445
1446                 r = g_resolver_get_default();
1447                 g_resolver_lookup_by_name_async(r, "www.google.com", NULL, _indicator_cb_dns_reply, NULL);
1448         }
1449
1450         if (service->act > NETWORK_ACT_UNKNOWN && service->act < NETWORK_ACT_NOT_SPECIFIED) {
1451                 _ps_update_cellular_state_key(service);
1452 #ifdef PREPAID_SIM_APN_SUPPORT
1453                 ret = _ps_service_connect_last_connected_context(service);
1454                 dbg("ret[%d]", ret);
1455                 if (ret == TRUE)
1456                         return ret; /* No need to activate default context */
1457 #endif
1458                 _ps_service_connect_default_context(service);
1459         }
1460
1461         return ret;
1462 }
1463
1464 enum telephony_ps_state _ps_service_check_cellular_state(gpointer object)
1465 {
1466         gboolean state = FALSE;
1467         ps_service_t *service = object;
1468         g_return_val_if_fail(service != NULL, TELEPHONY_PS_NO_SERVICE);
1469
1470         state = _ps_modem_get_flght_mode(service->p_modem);
1471         if (state)
1472                 return TELEPHONY_PS_FLIGHT_MODE;
1473
1474         state = _ps_modem_get_power(service->p_modem);
1475         if (!state)
1476                 return TELEPHONY_PS_NO_SERVICE;
1477
1478         state = _ps_modem_get_sim_init(service->p_modem);
1479         if (!state)
1480                 return TELEPHONY_PS_NO_SERVICE;
1481
1482         if (service->restricted)
1483                 return TELEPHONY_PS_RESTRICTED_SERVICE;
1484
1485         if (!service->ps_attached)
1486                 return TELEPHONY_PS_NO_SERVICE;
1487
1488         state = _ps_modem_get_data_allowed(service->p_modem);
1489         if (!state)
1490                 return TELEPHONY_PS_3G_OFF;
1491
1492         state = _ps_modem_get_data_roaming_allowed(service->p_modem);
1493         if (service->roaming && !state)
1494                 return TELEPHONY_PS_ROAMING_OFF;
1495
1496         return TELEPHONY_PS_ON;
1497 }
1498 static gboolean on_service_get_properties(PacketServiceService *obj_service,
1499                 GDBusMethodInvocation *invocation,
1500                 gpointer user_data)
1501 {
1502         GVariant *gv = NULL;
1503         GVariantBuilder property;
1504         ps_dbg_ex_co(_ps_service_ref_co_network(user_data), "get service properties");
1505
1506         gv = _ps_service_get_properties(user_data, &property);
1507         packet_service_service_complete_get_properties(obj_service, invocation, gv);
1508         return TRUE;
1509 }
1510
1511 static gboolean
1512 on_service_get_context(PacketServiceService *obj_service,
1513                 GDBusMethodInvocation *invocation,
1514                 gpointer user_data)
1515 {
1516         GVariantBuilder b_context;
1517         GVariant *contexts;
1518
1519         unsigned int index;
1520         ps_service_t *service = user_data;
1521         CoreObject *co_network = _ps_service_ref_co_network(service);
1522
1523         ps_dbg_ex_co(co_network, "modem get contexts interface");
1524
1525         if (service->contexts == NULL) {
1526                 ps_err_ex_co(co_network, "No context present for service");
1527                 FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1528                 return TRUE;
1529         }
1530
1531         g_variant_builder_init(&b_context, G_VARIANT_TYPE("a{sa{ss}}"));
1532         for (index = 0; index < g_slist_length(service->contexts); index++) {
1533                 gpointer value = g_slist_nth_data(service->contexts, index);
1534                 gchar *path = NULL;
1535                 g_variant_builder_open(&b_context, G_VARIANT_TYPE("{sa{ss}}"));
1536                 path = _ps_service_ref_path(value);
1537
1538                 g_variant_builder_add(&b_context, "s", g_strdup(path));
1539                 if (FALSE == _ps_context_get_properties_handler(value, &b_context)) {
1540                         ps_err_ex_co(co_network, "Failed to get property");
1541                         g_variant_builder_close(&b_context);
1542                         FAIL_RESPONSE(invocation, PS_ERR_INTERNAL);
1543                         return TRUE;
1544                 }
1545                 g_variant_builder_close(&b_context);
1546
1547         }
1548
1549         contexts = g_variant_builder_end(&b_context);
1550         packet_service_service_complete_get_contexts(obj_service, invocation, contexts);
1551         return TRUE;
1552 }
1553
1554 static void _ps_service_setup_interface(PacketServiceService *service, ps_service_t *service_data)
1555 {
1556         dbg("Entered");
1557         g_signal_connect(service,
1558                         "handle-get-properties",
1559                         G_CALLBACK(on_service_get_properties),
1560                         service_data);
1561
1562         g_signal_connect(service,
1563                         "handle-get-contexts",
1564                         G_CALLBACK(on_service_get_context),
1565                         service_data);
1566
1567         dbg("Exiting");
1568 }
1569