Add wrapper to send event callback
[platform/core/connectivity/libnet-client.git] / src / network-signal-handler.c
1 /*
2  * Network Client Library
3  *
4  * Copyright 2012 Samsung Electronics Co., Ltd
5  *
6  * Licensed under the Flora License, Version 1.1 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.tizenopensource.org/license
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  */
19
20 #include "network-info.h"
21 #include "network-internal.h"
22 #include "network-dbus-request.h"
23 #include "network-signal-handler.h"
24
25 static net_wifi_state_t net_wifi_state = WIFI_UNKNOWN;
26 static int net_service_error = NET_ERR_NONE;
27 static int net_dpm_wifi_state = -1;
28 static int net_dpm_wifi_profile_state = -1;
29
30 struct cs_tid_info {
31         int tid;
32         guint subscribe_id_connman_state;
33         guint subscribe_id_connman_error;
34         guint subscribe_id_netconfig_wifi;
35         guint subscribe_id_netconfig;
36 };
37
38 static GSList *cs_tid_list = NULL;
39
40 /* LCOV_EXCL_START */
41 static void __net_trigger_event_callback(network_info_t *network_info,
42                 net_event_info_t *event_data)
43 {
44         if (!network_info || !event_data || !_network_info_is_ref(network_info))
45                 return;
46
47         if (network_info->event_callback)
48                 network_info->event_callback(event_data, network_info->user_data);
49 }
50
51 static int __net_handle_wifi_power_rsp(gboolean value, network_info_t *network_info)
52 {
53         __NETWORK_FUNC_ENTER__;
54
55         net_event_info_t *event_data = NULL;
56
57         if (network_info == NULL) {
58                 __NETWORK_FUNC_EXIT__;
59                 return NET_ERR_INVALID_PARAM;
60         }
61
62         event_data = g_try_new0(net_event_info_t, 1);
63         if (event_data == NULL) {
64                 __NETWORK_FUNC_EXIT__;
65                 return NET_ERR_OUT_OF_MEMORY;
66         }
67
68         if (value == TRUE) {
69                 net_wifi_state = WIFI_ON;
70                 event_data->Error = NET_ERR_NONE;
71         } else {
72                 net_wifi_state = WIFI_OFF;
73                 event_data->Error = NET_ERR_NONE;
74
75                 if (network_info->request_table[NETWORK_REQUEST_TYPE_SCAN].flag == TRUE)
76                         memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_SCAN]),
77                                         0, sizeof(network_request_table_t));
78         }
79
80         if (network_info->request_table[NETWORK_REQUEST_TYPE_WIFI_POWER].flag == TRUE) {
81                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_WIFI_POWER]),
82                                 0, sizeof(network_request_table_t));
83
84                 event_data->Event = NET_EVENT_WIFI_POWER_RSP;
85                 NETWORK_LOG(NETWORK_LOW, "NET_EVENT_WIFI_POWER_RSP wifi state: %d",
86                                 net_wifi_state);
87         } else {
88                 event_data->Event = NET_EVENT_WIFI_POWER_IND;
89                 NETWORK_LOG(NETWORK_LOW, "NET_EVENT_WIFI_POWER_IND wifi state: %d",
90                                 net_wifi_state);
91         }
92
93         event_data->Datalength = sizeof(net_wifi_state_t);
94         event_data->Data = &(net_wifi_state);
95
96         __net_trigger_event_callback(network_info, event_data);
97         g_free(event_data);
98
99         __NETWORK_FUNC_EXIT__;
100         return NET_ERR_NONE;
101 }
102
103 static void __net_handle_state_ind(network_info_t *network_info,
104                 const char *profile_name, net_state_type_t profile_state)
105 {
106         __NETWORK_FUNC_ENTER__;
107
108         net_event_info_t *event_data = NULL;
109
110         if (network_info == NULL ||
111                 network_info->event_callback == NULL) {
112                 __NETWORK_FUNC_EXIT__;
113                 return;
114         }
115
116         event_data = g_try_new0(net_event_info_t, 1);
117         if (event_data == NULL) {
118                 __NETWORK_FUNC_EXIT__;
119                 return;
120         }
121
122         event_data->Error = NET_ERR_NONE;
123         event_data->Event = NET_EVENT_NET_STATE_IND;
124
125         g_strlcpy(event_data->ProfileName, profile_name, sizeof(event_data->ProfileName));
126
127         event_data->Datalength = sizeof(net_state_type_t);
128         event_data->Data = &profile_state;
129
130         NETWORK_LOG(NETWORK_LOW,
131                         "Sending NET_EVENT_NET_STATE_IND, state: %d, profile name: %s",
132                         profile_state, event_data->ProfileName);
133
134         __net_trigger_event_callback(network_info, event_data);
135         g_free(event_data);
136
137         __NETWORK_FUNC_EXIT__;
138 }
139
140 static void __net_handle_internet_state_ind(network_info_t *network_info,
141                 net_device_t device_type, int is_online)
142 {
143         __NETWORK_FUNC_ENTER__;
144
145         net_event_info_t *event_data = NULL;
146
147         if (network_info == NULL ||
148                 network_info->event_callback == NULL) {
149                 __NETWORK_FUNC_EXIT__;
150                 return;
151         }
152
153         event_data = g_try_new0(net_event_info_t, 1);
154         if (event_data == NULL) {
155                 __NETWORK_FUNC_EXIT__;
156                 return;
157         }
158
159         event_data->Error = NET_ERR_NONE;
160         if (is_online)
161                 event_data->Event = NET_EVENT_INTERNET_ONLINE_IND;
162         else
163                 event_data->Event = NET_EVENT_INTERNET_OFFLINE_IND;
164
165         event_data->Datalength = sizeof(net_device_t);
166         event_data->Data = &device_type;
167
168         NETWORK_LOG(NETWORK_LOW,
169                         "Sending NET_EVENT_INTERNET_%s_IND", is_online ? "ONLINE" : "OFFLINE");
170
171         __net_trigger_event_callback(network_info, event_data);
172         g_free(event_data);
173
174         __NETWORK_FUNC_EXIT__;
175 }
176
177 static void __net_handle_failure_ind(network_info_t *network_info,
178                 const char *profile_name, net_device_t device_type)
179 {
180         __NETWORK_FUNC_ENTER__;
181
182         net_event_info_t *event_data = NULL;
183
184         const char *svc_name1 = NULL;
185         const char *svc_name2 = NULL;
186         const char *svc_name3 = NULL;
187
188         if (network_info == NULL) {
189                 __NETWORK_FUNC_EXIT__;
190                 return;
191         }
192
193         event_data = g_try_new0(net_event_info_t, 1);
194         if (event_data == NULL) {
195                 __NETWORK_FUNC_EXIT__;
196                 return;
197         }
198
199         svc_name1 = network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION].ProfileName;
200         svc_name2 = network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS].ProfileName;
201         svc_name3 = network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION].ProfileName;
202
203         if (network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION].flag == TRUE &&
204                         strstr(profile_name, svc_name1) != NULL) {
205                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION]), 0,
206                                 sizeof(network_request_table_t));
207
208                 event_data->Event = NET_EVENT_OPEN_RSP;
209         } else if (network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS].flag == TRUE &&
210                         g_strcmp0(profile_name, svc_name2) == 0) {
211                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS]), 0,
212                                 sizeof(network_request_table_t));
213
214                 event_data->Event = NET_EVENT_WIFI_WPS_RSP;
215
216                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION]), 0,
217                                                 sizeof(network_request_table_t));
218         } else if (network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION].flag == TRUE &&
219                         g_strcmp0(profile_name, svc_name3) == 0) {
220                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION]), 0,
221                                 sizeof(network_request_table_t));
222
223                 event_data->Event = NET_EVENT_CLOSE_RSP;
224         } else {
225                 __net_handle_state_ind(network_info, profile_name, NET_STATE_TYPE_FAILURE);
226
227                 g_free(event_data);
228                 __NETWORK_FUNC_EXIT__;
229                 return;
230         }
231
232         g_strlcpy(event_data->ProfileName,
233                         profile_name, NET_PROFILE_NAME_LEN_MAX+1);
234
235         if (net_service_error != NET_ERR_NONE)
236                 event_data->Error = net_service_error;
237         else {
238                 event_data->Error = NET_ERR_CONNECTION_CONNECT_FAILED;
239                 NETWORK_LOG(NETWORK_ERROR, "Event error defined %d", event_data->Error);
240         }
241         event_data->Datalength = 0;
242         event_data->Data = NULL;
243
244         net_service_error = NET_ERR_NONE;
245
246         NETWORK_LOG(NETWORK_ERROR, "State failure %d", event_data->Error);
247
248         __net_trigger_event_callback(network_info, event_data);
249         g_free(event_data);
250
251         /* Reseting the state back in case of failure state */
252         network_info->state_table[device_type] = NET_STATE_TYPE_IDLE;
253
254         __NETWORK_FUNC_EXIT__;
255 }
256
257 static int string2state(const char *state)
258 {
259         if (g_strcmp0(state, "idle") == 0)
260                 return NET_STATE_TYPE_IDLE;
261         else if (g_strcmp0(state, "association") == 0)
262                 return NET_STATE_TYPE_ASSOCIATION;
263         else if (g_strcmp0(state, "configuration") == 0)
264                 return NET_STATE_TYPE_CONFIGURATION;
265         else if (g_strcmp0(state, "ready") == 0)
266                 return NET_STATE_TYPE_READY;
267         else if (g_strcmp0(state, "online") == 0)
268                 return NET_STATE_TYPE_ONLINE;
269         else if (g_strcmp0(state, "disconnect") == 0)
270                 return NET_STATE_TYPE_DISCONNECT;
271         else if (g_strcmp0(state, "failure") == 0)
272                 return NET_STATE_TYPE_FAILURE;
273
274         return NET_STATE_TYPE_UNKNOWN;
275 }
276
277 static int __net_handle_service_state_changed(network_info_t *network_info,
278                 const gchar *sig_path, const char *key, const char *state)
279 {
280         net_err_t Error = NET_ERR_NONE;
281         net_state_type_t old_state, new_state;
282
283         net_event_info_t *event_data = NULL;
284         net_device_t device_type = NET_DEVICE_UNKNOWN;
285
286         if (network_info == NULL)
287                 return NET_ERR_INVALID_PARAM;
288
289         if (sig_path == NULL)
290                 return Error;
291
292         event_data = g_try_new0(net_event_info_t, 1);
293         if (event_data == NULL)
294                 return Error;
295
296         device_type = _net_get_tech_type_from_path(sig_path);
297         if (device_type == NET_DEVICE_UNKNOWN) {
298                 g_free(event_data);
299                 return Error;
300         }
301
302         NETWORK_LOG(NETWORK_LOW, "[%s] %s", state, sig_path);
303
304         if (device_type == NET_DEVICE_WIFI && net_wifi_state == WIFI_OFF) {
305                 NETWORK_LOG(NETWORK_LOW, "Wi-Fi is off");
306                 g_free(event_data);
307                 return Error;
308         }
309
310         old_state = network_info->state_table[device_type];
311         new_state = string2state(state);
312
313         NETWORK_LOG(NETWORK_LOW, "old state[%d] new state[%d]", old_state, new_state);
314
315         if (old_state == new_state) {
316                 g_free(event_data);
317                 return Error;
318         }
319
320         network_info->state_table[device_type] = new_state;
321
322         if (old_state != NET_STATE_TYPE_ONLINE && new_state == NET_STATE_TYPE_ONLINE)
323                 __net_handle_internet_state_ind(network_info, device_type, 1);
324         else if (old_state == NET_STATE_TYPE_ONLINE && new_state != NET_STATE_TYPE_ONLINE)
325                 __net_handle_internet_state_ind(network_info, device_type, 0);
326
327         switch (new_state) {
328         case NET_STATE_TYPE_IDLE:
329                 if (device_type == NET_DEVICE_WIFI &&
330                                 net_wifi_state == WIFI_CONNECTED) {
331                         net_wifi_state = WIFI_ON;
332                 }
333                 if (old_state == NET_STATE_TYPE_DISCONNECT)
334                         break;
335         case NET_STATE_TYPE_ASSOCIATION:
336         case NET_STATE_TYPE_CONFIGURATION:
337                 __net_handle_state_ind(network_info, sig_path, new_state);
338                 break;
339
340         case NET_STATE_TYPE_READY:
341         case NET_STATE_TYPE_ONLINE:
342         {
343                 if (old_state != NET_STATE_TYPE_READY &&
344                                 old_state != NET_STATE_TYPE_ONLINE) {
345                         const char *svc_name1 =
346                                         network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION].ProfileName;
347                         const char *svc_name2 =
348                                         network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS].ProfileName;
349
350                         if (network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION].flag == TRUE &&
351                                         strstr(sig_path, svc_name1) != NULL) {
352                                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION]), 0,
353                                                 sizeof(network_request_table_t));
354
355                                 event_data->Event = NET_EVENT_OPEN_RSP;
356
357                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_OPEN_RSP");
358                         } else if (network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS].flag == TRUE &&
359                                         g_strcmp0(sig_path, svc_name2) == 0) {
360                                 memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS]), 0,
361                                                 sizeof(network_request_table_t));
362
363                                 event_data->Event = NET_EVENT_WIFI_WPS_RSP;
364
365                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_WIFI_WPS_RSP");
366                         } else {
367                                 event_data->Event = NET_EVENT_OPEN_IND;
368
369                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_OPEN_IND");
370                         }
371
372                         net_profile_info_t prof_info;
373                         if ((Error = net_get_profile_info(network_info, sig_path, &prof_info)) != NET_ERR_NONE) {
374                                 NETWORK_LOG(NETWORK_ERROR, "net_get_profile_info() failed [%s]",
375                                                 _net_print_error(Error));
376
377                                 event_data->Datalength = 0;
378                                 event_data->Data = NULL;
379                         } else {
380                                 event_data->Datalength = sizeof(net_profile_info_t);
381                                 event_data->Data = &prof_info;
382                         }
383
384                         event_data->Error = Error;
385                         g_strlcpy(event_data->ProfileName, sig_path, NET_PROFILE_NAME_LEN_MAX+1);
386
387                         __net_trigger_event_callback(network_info, event_data);
388                 }
389
390                 break;
391         }
392         case NET_STATE_TYPE_DISCONNECT:
393         {
394                 const char *svc_name1 =
395                                 network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION].ProfileName;
396                 const char *svc_name2 =
397                                 network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION].ProfileName;
398                 const char *svc_name3 =
399                                 network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS].ProfileName;
400
401                 if (network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION].flag == TRUE &&
402                                 strstr(sig_path, svc_name2) != NULL) {
403                         memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION]), 0,
404                                         sizeof(network_request_table_t));
405
406                         /** Send Open Resp */
407                         event_data->Error = NET_ERR_OPERATION_ABORTED;
408                         event_data->Event =  NET_EVENT_OPEN_RSP;
409                         g_strlcpy(event_data->ProfileName, sig_path, NET_PROFILE_NAME_LEN_MAX+1);
410
411                         event_data->Datalength = 0;
412                         event_data->Data = NULL;
413
414                         NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_OPEN_RSP");
415
416                         __net_trigger_event_callback(network_info, event_data);
417
418                         break;
419                 }
420
421                 if (network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS].flag == TRUE &&
422                                 g_strcmp0(sig_path, svc_name3) == 0) {
423                         memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS]), 0,
424                                         sizeof(network_request_table_t));
425
426                         /** Send WPS Resp */
427                         event_data->Error = NET_ERR_OPERATION_ABORTED;
428                         event_data->Event =  NET_EVENT_WIFI_WPS_RSP;
429                         g_strlcpy(event_data->ProfileName, sig_path, NET_PROFILE_NAME_LEN_MAX+1);
430
431                         event_data->Datalength = 0;
432                         event_data->Data = NULL;
433
434                         NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_WIFI_WPS_RSP");
435
436                         __net_trigger_event_callback(network_info, event_data);
437
438                         break;
439                 }
440
441                 if (network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION].flag == TRUE &&
442                                 g_strcmp0(sig_path, svc_name1) == 0) {
443                         memset(&(network_info->request_table[NETWORK_REQUEST_TYPE_CLOSE_CONNECTION]), 0,
444                                         sizeof(network_request_table_t));
445
446                         /** Send Close Resp */
447                         event_data->Error = Error;
448                         event_data->Event =  NET_EVENT_CLOSE_RSP;
449                         g_strlcpy(event_data->ProfileName, sig_path, NET_PROFILE_NAME_LEN_MAX+1);
450
451                         event_data->Datalength = 0;
452                         event_data->Data = NULL;
453
454                         NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_CLOSE_RSP");
455
456                         __net_trigger_event_callback(network_info, event_data);
457
458                         break;
459                 }
460
461                 /** Send Close Ind */
462                 event_data->Error = Error;
463                 event_data->Event = NET_EVENT_CLOSE_IND;
464                 g_strlcpy(event_data->ProfileName, sig_path, NET_PROFILE_NAME_LEN_MAX+1);
465
466                 event_data->Datalength = 0;
467                 event_data->Data = NULL;
468
469                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_CLOSE_IND");
470
471                 __net_trigger_event_callback(network_info, event_data);
472
473                 break;
474         }
475         case NET_STATE_TYPE_FAILURE:
476                 __net_handle_failure_ind(network_info, sig_path, device_type);
477                 break;
478
479         default:
480                 Error = NET_ERR_UNKNOWN_METHOD;
481                 break;
482         }
483
484         g_free(event_data);
485         return Error;
486 }
487
488 static int string2error(const char *error)
489 {
490         if (g_strcmp0(error, "out-of-range") == 0)
491                 return NET_ERR_CONNECTION_OUT_OF_RANGE;
492         else if (g_strcmp0(error, "pin-missing") == 0)
493                 return NET_ERR_CONNECTION_PIN_MISSING;
494         else if (g_strcmp0(error, "dhcp-failed") == 0)
495                 return NET_ERR_CONNECTION_DHCP_FAILED;
496         else if (g_strcmp0(error, "connect-failed") == 0)
497                 return NET_ERR_CONNECTION_CONNECT_FAILED;
498         else if (g_strcmp0(error, "login-failed") == 0)
499                 return NET_ERR_CONNECTION_LOGIN_FAILED;
500         else if (g_strcmp0(error, "auth-failed") == 0)
501                 return NET_ERR_CONNECTION_AUTH_FAILED;
502         else if (g_strcmp0(error, "invalid-key") == 0)
503                 return NET_ERR_CONNECTION_INVALID_KEY;
504
505         return NET_ERR_UNKNOWN;
506 }
507
508 static int __net_handle_service_set_error(const char *key, const char *error)
509 {
510         if (error == NULL || *error == '\0')
511                 return NET_ERR_NONE;
512
513         NETWORK_LOG(NETWORK_ERROR, "[%s] %s", key, error);
514
515         net_service_error = string2error(error);
516
517         return NET_ERR_NONE;
518 }
519
520 static int __net_handle_ethernet_cable_state_rsp(GVariant *param,
521                         network_info_t *network_info)
522 {
523         GVariantIter *iter = NULL;
524         GVariant *value = NULL;
525         const char *key = NULL;
526         const gchar *sig_value = NULL;
527         net_event_info_t *event_data = NULL;
528
529         if (network_info == NULL ||
530                 network_info->event_callback == NULL) {
531                 __NETWORK_FUNC_EXIT__;
532                 return NET_ERR_INVALID_PARAM;
533         }
534
535         g_variant_get(param, "(a{sv})", &iter);
536
537         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
538                 if (g_strcmp0(key, "key") == 0) {
539                         sig_value = g_variant_get_string(value, NULL);
540                         NETWORK_LOG(NETWORK_LOW, "Check Ethernet Monitor Result: %s",
541                                                 sig_value);
542                 }
543         }
544         g_variant_iter_free(iter);
545
546         event_data = g_try_new0(net_event_info_t, 1);
547         if (event_data == NULL) {
548                 __NETWORK_FUNC_EXIT__;
549                 return NET_ERR_OUT_OF_MEMORY;
550         }
551
552         if (g_strcmp0(sig_value, "ATTACHED") == 0) {
553                         event_data->Event = NET_EVENT_ETHERNET_CABLE_ATTACHED;
554                         event_data->Error = NET_ERR_NONE;
555         } else {
556                         event_data->Event = NET_EVENT_ETHERNET_CABLE_DETACHED;
557                         event_data->Error = NET_ERR_NONE;
558         }
559         event_data->Datalength = 0;
560         event_data->Data = NULL;
561
562         __net_trigger_event_callback(network_info, event_data);
563         g_free(event_data);
564
565         return NET_ERR_NONE;
566 }
567
568 static int __net_handle_network_dpm_wifi_event(GVariant *param,
569                         network_info_t *network_info)
570 {
571         __NETWORK_FUNC_ENTER__;
572
573         GVariantIter *iter = NULL;
574         GVariant *value = NULL;
575         const char *key = NULL;
576         const gchar *sig_value = NULL;
577
578         g_variant_get(param, "(a{sv})", &iter);
579
580         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
581                 if (g_strcmp0(key, "key") == 0) {
582                         sig_value = g_variant_get_string(value, NULL);
583                         NETWORK_LOG(NETWORK_LOW, "Wifi device policy : %s",
584                                                 sig_value);
585                         if (g_strcmp0(sig_value, "allowed") == 0)
586                                 net_dpm_wifi_state = TRUE;
587                         else
588                                 net_dpm_wifi_state = FALSE;
589                 }
590         }
591         g_variant_iter_free(iter);
592
593         __NETWORK_FUNC_EXIT__;
594         return NET_ERR_NONE;
595 }
596
597 static int __net_handle_network_dpm_wifi_profile_event(GVariant *param,
598                         network_info_t *network_info)
599 {
600         __NETWORK_FUNC_ENTER__;
601
602         GVariantIter *iter = NULL;
603         GVariant *value = NULL;
604         const char *key = NULL;
605         const gchar *sig_value = NULL;
606
607         g_variant_get(param, "(a{sv})", &iter);
608
609         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
610                 if (g_strcmp0(key, "key") == 0) {
611                         sig_value = g_variant_get_string(value, NULL);
612                         NETWORK_LOG(NETWORK_LOW, "Wifi profile device policy : %s",
613                                                 sig_value);
614                         if (g_strcmp0(sig_value, "allowed") == 0)
615                                 net_dpm_wifi_profile_state = TRUE;
616                         else
617                                 net_dpm_wifi_profile_state = FALSE;
618                 }
619         }
620         g_variant_iter_free(iter);
621
622         __NETWORK_FUNC_EXIT__;
623         return NET_ERR_NONE;
624 }
625
626 static int __net_handle_network_config_changed_event(GVariant *param,
627                         network_info_t *network_info)
628 {
629         __NETWORK_FUNC_ENTER__;
630
631         GVariantIter *iter = NULL;
632         GVariant *value = NULL;
633         const char *key = NULL;
634         const gchar *sig_value = NULL;
635         int network_status;
636         gchar *params_str = NULL;
637
638         if (network_info == NULL ||
639                 network_info->event_callback == NULL) {
640                 __NETWORK_FUNC_EXIT__;
641                 return NET_ERR_INVALID_PARAM;
642         }
643
644         params_str = g_variant_print(param, TRUE);
645         NETWORK_LOG(NETWORK_LOW, "params %s", params_str);
646         g_variant_get(param, "(a{sv})", &iter);
647
648         while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
649                 if (g_strcmp0(key, "NetworkStatus") == 0) {
650                         net_event_info_t *event_data = NULL;
651                         event_data = g_try_new0(net_event_info_t, 1);
652                         if (event_data) {
653                                 network_status = g_variant_get_int32(value);
654
655                                 event_data->Event = NET_EVENT_NETWORK_TYPE_CHANGED;
656                                 event_data->Error = NET_ERR_NONE;
657                                 event_data->Datalength = sizeof(int);
658                                 event_data->Data = &network_status;
659
660                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_NETWORK_TYPE_CHANGED");
661
662                                 __net_trigger_event_callback(network_info, event_data);
663                                 g_free(event_data);
664                         }
665                 } else if (g_strcmp0(key, "IPv4Address") == 0) {
666                         net_event_info_t *event_data = NULL;
667                         event_data = g_try_new0(net_event_info_t, 1);
668                         if (event_data) {
669                                 sig_value = g_variant_get_string(value, NULL);
670
671                                 event_data->Event = NET_EVENT_IPV4_ADDRESS_CHANGED;
672                                 event_data->Error = NET_ERR_NONE;
673                                 event_data->Data = g_strdup(sig_value);
674
675                                 if (event_data->Data)
676                                         event_data->Datalength = strlen(event_data->Data) + 1;
677                                 else
678                                         event_data->Datalength = 0;
679
680                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_IPV4_ADDRESS_CHANGED");
681
682                                 __net_trigger_event_callback(network_info, event_data);
683                                 g_free(event_data->Data);
684                                 g_free(event_data);
685                         }
686                 } else if (g_strcmp0(key, "IPv6Address") == 0) {
687                         net_event_info_t *event_data = NULL;
688                         event_data = g_try_new0(net_event_info_t, 1);
689                         if (event_data) {
690                                 sig_value = g_variant_get_string(value, NULL);
691
692                                 event_data->Event = NET_EVENT_IPV6_ADDRESS_CHANGED;
693                                 event_data->Error = NET_ERR_NONE;
694                                 event_data->Data = g_strdup(sig_value);
695
696                                 if (event_data->Data)
697                                         event_data->Datalength = strlen(event_data->Data) + 1;
698                                 else
699                                         event_data->Datalength = 0;
700
701                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_IPV6_ADDRESS_CHANGED");
702
703                                 __net_trigger_event_callback(network_info, event_data);
704                                 g_free(event_data->Data);
705                                 g_free(event_data);
706                         }
707                 } else if (g_strcmp0(key, "ProxyAddress") == 0) {
708                         net_event_info_t *event_data = NULL;
709                         event_data = g_try_new0(net_event_info_t, 1);
710                         if (event_data) {
711                                 sig_value = g_variant_get_string(value, NULL);
712
713                                 event_data->Event = NET_EVENT_PROXY_ADDRESS_CHANGED;
714                                 event_data->Error = NET_ERR_NONE;
715                                 event_data->Data = g_strdup(sig_value);
716
717                                 if (event_data->Data)
718                                         event_data->Datalength = strlen(event_data->Data) + 1;
719                                 else
720                                         event_data->Datalength = 0;
721
722                                 NETWORK_LOG(NETWORK_LOW, "Sending NET_EVENT_PROXY_ADDRESS_CHANGED");
723
724                                 __net_trigger_event_callback(network_info, event_data);
725                                 g_free(event_data->Data);
726                                 g_free(event_data);
727                         }
728                 }
729         }
730         g_variant_iter_free(iter);
731
732         __NETWORK_FUNC_EXIT__;
733         return NET_ERR_NONE;
734 }
735
736 static void __net_connman_service_signal_filter(GDBusConnection *conn,
737                 const gchar *name, const gchar *path, const gchar *interface,
738                 const gchar *sig, GVariant *param, gpointer user_data)
739 {
740         __NETWORK_FUNC_ENTER__;
741
742         const char *key = NULL;
743         const char *value = NULL;
744         GVariant *var;
745         network_info_t *network_info = (network_info_t *)user_data;
746
747         if (g_strcmp0(sig, SIGNAL_PROPERTY_CHANGED) == 0) {
748                 g_variant_get(param, "(sv)", &key, &var);
749
750                 if (g_strcmp0(key, "State") == 0) {
751                         g_variant_get(var, "s", &value);
752
753                         __net_handle_service_state_changed(network_info, path, key, value);
754                 } else if (g_strcmp0(key, "Error") == 0) {
755                         g_variant_get(var, "s", &value);
756
757                         __net_handle_service_set_error(key, value);
758                 }
759
760                 g_free((gchar *)value);
761                 g_free((gchar *)key);
762                 if (NULL != var)
763                         g_variant_unref(var);
764         }
765
766         __NETWORK_FUNC_EXIT__;
767 }
768
769 static int __net_handle_wifi_connect_fail_event(GVariant *param, network_info_t *network_info)
770 {
771         __NETWORK_FUNC_ENTER__;
772
773         net_event_info_t *event_data = NULL;
774         network_request_table_t *open_info = NULL;
775         network_request_table_t *wps_info = NULL;
776
777         if (network_info == NULL ||
778                 network_info->event_callback == NULL) {
779                 __NETWORK_FUNC_EXIT__;
780                 return NET_ERR_INVALID_PARAM;
781         }
782
783         open_info = &(network_info->request_table[NETWORK_REQUEST_TYPE_OPEN_CONNECTION]);
784         wps_info = &(network_info->request_table[NETWORK_REQUEST_TYPE_ENROLL_WPS]);
785
786         event_data = g_try_new0(net_event_info_t, 1);
787         if (event_data == NULL) {
788                 __NETWORK_FUNC_EXIT__;
789                 return NET_ERR_OUT_OF_MEMORY;
790         }
791
792         event_data->Datalength = 0;
793         event_data->Data = NULL;
794
795         NETWORK_LOG(NETWORK_HIGH, "Failed to connect WiFi");
796         g_strlcpy(event_data->ProfileName, open_info->ProfileName,
797                           NET_PROFILE_NAME_LEN_MAX+1);
798
799         if (open_info->flag == TRUE) {
800                 memset(open_info, 0, sizeof(network_request_table_t));
801                 event_data->Error = NET_ERR_CONNECTION_CONNECT_FAILED;
802                 event_data->Event = NET_EVENT_OPEN_RSP;
803                 NETWORK_LOG(NETWORK_HIGH, "Sending NET_EVENT_OPEN_RSP");
804         } else if (wps_info->flag == TRUE) {
805                 memset(wps_info, 0, sizeof(network_request_table_t));
806                 event_data->Error = NET_ERR_CONNECTION_CONNECT_FAILED;
807                 event_data->Event = NET_EVENT_WIFI_WPS_RSP;
808                 NETWORK_LOG(NETWORK_HIGH, "Sending NET_EVENT_WIFI_WPS_RSP");
809         } else {
810                 NETWORK_LOG(NETWORK_LOW, "WiFi Connection flag not set");
811                 g_free(event_data);
812                 __NETWORK_FUNC_EXIT__;
813                 return NET_ERR_NONE;
814         }
815
816         __net_trigger_event_callback(network_info, event_data);
817         g_free(event_data);
818
819         __NETWORK_FUNC_EXIT__;
820         return NET_ERR_NONE;
821 }
822
823 static void __net_netconfig_signal_filter(GDBusConnection *conn,
824                 const gchar *name, const gchar *path, const gchar *interface,
825                 const gchar *sig, GVariant *param, gpointer user_data)
826 {
827         network_info_t *network_info = (network_info_t *)user_data;
828
829         if (g_strcmp0(sig, NETCONFIG_SIGNAL_POWERON_COMPLETED) == 0)
830                 __net_handle_wifi_power_rsp(TRUE, network_info);
831         else if (g_strcmp0(sig, NETCONFIG_SIGNAL_POWEROFF_COMPLETED) == 0)
832                 __net_handle_wifi_power_rsp(FALSE, network_info);
833         else if (g_strcmp0(sig, NETCONFIG_SIGNAL_WIFI_CONNECT_FAIL) == 0)
834                 __net_handle_wifi_connect_fail_event(param, network_info);
835 }
836
837 static void __net_netconfig_network_signal_filter(GDBusConnection *conn,
838                 const gchar *name, const gchar *path, const gchar *interface,
839                 const gchar *sig, GVariant *param, gpointer user_data)
840 {
841         network_info_t *network_info = (network_info_t *)user_data;
842
843         if (g_strcmp0(sig, NETCONFIG_SIGNAL_ETHERNET_CABLE_STATE) == 0)
844                 __net_handle_ethernet_cable_state_rsp(param, network_info);
845         else if (g_strcmp0(sig, NETCONFIG_SIGNAL_DPM_WIFI) == 0)
846                 __net_handle_network_dpm_wifi_event(param, network_info);
847         else if (g_strcmp0(sig, NETCONFIG_SIGNAL_DPM_WIFI_PROFILE) == 0)
848                 __net_handle_network_dpm_wifi_profile_event(param, network_info);
849         else if (g_strcmp0(sig, NETCONFIG_SIGNAL_NETWORK_CONFIGURATION_CHANGED) == 0)
850                 __net_handle_network_config_changed_event(param, network_info);
851 }
852 /* LCOV_EXCL_STOP */
853
854 /*****************************************************************************
855  * Global Functions
856  *****************************************************************************/
857
858 net_wifi_state_t _net_get_wifi_state(void)
859 {
860         return net_wifi_state;
861 }
862
863 void _net_set_wifi_state(net_wifi_state_t state)
864 {
865         net_wifi_state = state;
866 }
867
868 /* LCOV_EXCL_START */
869 void _net_set_dpm_wifi_profile_state(int state)
870 {
871         net_dpm_wifi_profile_state = state;
872 }
873
874 void _net_set_cs_tid(int tid, network_info_t *network_info)
875 {
876         GSList *list;
877         struct cs_tid_info *tid_info = NULL;
878         struct cs_tid_info *data = NULL;
879
880         if (cs_tid_list) {
881                 for (list = cs_tid_list; list; list = list->next) {
882                         data = (struct cs_tid_info *)list->data;
883                         if (tid == data->tid) {
884                                 tid_info = data;
885                                 break;
886                         }
887                 }
888         }
889
890         if (!tid_info) {
891                 tid_info = (struct cs_tid_info *)g_try_malloc0(sizeof(struct cs_tid_info));
892                 if (!tid_info) {
893                         NETWORK_LOG(NETWORK_ERROR, "Out of memory, tid %d", tid);
894                         return;
895                 }
896
897                 tid_info->tid = tid;
898                 cs_tid_list = g_slist_prepend(cs_tid_list, tid_info);
899         }
900
901         if (network_info) {
902                 tid_info->subscribe_id_connman_state = network_info->subscribe_id_connman_state;
903                 tid_info->subscribe_id_connman_error = network_info->subscribe_id_connman_error;
904                 tid_info->subscribe_id_netconfig_wifi = network_info->subscribe_id_netconfig_wifi;
905                 tid_info->subscribe_id_netconfig = network_info->subscribe_id_netconfig;
906         }
907
908         NETWORK_LOG(NETWORK_HIGH, "tid %d, tid_info %p", tid, tid_info);
909 }
910
911 void _net_unset_cs_tid(int tid, network_info_t *network_info)
912 {
913         GSList *list;
914         struct cs_tid_info *tid_info = NULL;
915         struct cs_tid_info *data = NULL;
916
917         if (cs_tid_list) {
918                 for (list = cs_tid_list; list; list = list->next) {
919                         data = (struct cs_tid_info *)list->data;
920                         if (tid == data->tid) {
921                                 tid_info = data;
922                                 break;
923                         }
924                 }
925         }
926
927         if (!tid_info) {
928                 NETWORK_LOG(NETWORK_ERROR, "No tid_info, tid %d", tid);
929                 return;
930         }
931
932         if (network_info) {
933                 _net_dbus_unsubscribe_signal(network_info,
934                                         tid_info->subscribe_id_connman_state);
935                 _net_dbus_unsubscribe_signal(network_info,
936                                         tid_info->subscribe_id_connman_error);
937                 _net_dbus_unsubscribe_signal(network_info,
938                                         tid_info->subscribe_id_netconfig_wifi);
939                 _net_dbus_unsubscribe_signal(network_info,
940                                         tid_info->subscribe_id_netconfig);
941         }
942
943         NETWORK_LOG(NETWORK_HIGH, "tid %d, tid_info %p", tid, tid_info);
944
945         cs_tid_list = g_slist_remove(cs_tid_list, tid_info);
946         g_free(tid_info);
947 }
948 /* LCOV_EXCL_STOP */
949
950 void _net_deregister_signal(network_info_t *network_info)
951 {
952         __NETWORK_FUNC_ENTER__;
953
954         if (network_info) {
955                 _net_dbus_unsubscribe_signal(network_info,
956                                         network_info->subscribe_id_connman_state);
957                 _net_dbus_unsubscribe_signal(network_info,
958                                         network_info->subscribe_id_mesh_state);
959                 _net_dbus_unsubscribe_signal(network_info,
960                                         network_info->subscribe_id_connman_error);
961                 _net_dbus_unsubscribe_signal(network_info,
962                                         network_info->subscribe_id_netconfig_wifi);
963                 _net_dbus_unsubscribe_signal(network_info,
964                                         network_info->subscribe_id_netconfig);
965         }
966
967         __NETWORK_FUNC_EXIT__;
968 }
969
970 int _net_register_signal(network_info_t *network_info)
971 {
972         __NETWORK_FUNC_ENTER__;
973
974         if (network_info == NULL) {
975                 __NETWORK_FUNC_EXIT__;
976                 return NET_ERR_INVALID_PARAM;
977         }
978
979         /* Create connman service state connection */
980         network_info->subscribe_id_connman_state = _net_dbus_subscribe_signal(
981                         network_info,
982                         CONNMAN_SERVICE,
983                         CONNMAN_SERVICE_INTERFACE,
984                         SIGNAL_PROPERTY_CHANGED,
985                         NULL,
986                         "State",
987                         __net_connman_service_signal_filter);
988
989         /* Create connman mesh state connection */
990         network_info->subscribe_id_mesh_state = _net_dbus_subscribe_signal(
991                         network_info,
992                         CONNMAN_SERVICE,
993                         CONNMAN_MESH_INTERFACE,
994                         SIGNAL_PROPERTY_CHANGED,
995                         NULL,
996                         "State",
997                         __net_connman_service_signal_filter);
998
999         /* Create connman service error connection */
1000         network_info->subscribe_id_connman_error = _net_dbus_subscribe_signal(
1001                         network_info,
1002                         CONNMAN_SERVICE,
1003                         CONNMAN_SERVICE_INTERFACE,
1004                         SIGNAL_PROPERTY_CHANGED,
1005                         NULL,
1006                         "Error",
1007                         __net_connman_service_signal_filter);
1008
1009         /* Create net-config service connection for network */
1010         network_info->subscribe_id_netconfig = _net_dbus_subscribe_signal(
1011                         network_info,
1012                         NETCONFIG_SERVICE,
1013                         NETCONFIG_NETWORK_INTERFACE,
1014                         NULL,
1015                         NETCONFIG_NETWORK_PATH,
1016                         NULL,
1017                         __net_netconfig_network_signal_filter);
1018
1019         /* Create net-config service connection for wifi */
1020         network_info->subscribe_id_netconfig_wifi = _net_dbus_subscribe_signal(
1021                         network_info,
1022                         NETCONFIG_SERVICE,
1023                         NETCONFIG_WIFI_INTERFACE,
1024                         NULL,
1025                         NETCONFIG_WIFI_PATH,
1026                         NULL,
1027                         __net_netconfig_signal_filter);
1028
1029         __NETWORK_FUNC_EXIT__;
1030         return NET_ERR_NONE;
1031 }
1032
1033 static int __net_get_all_tech_states(GVariant *msg, net_state_type_t *state_table)
1034 {
1035         __NETWORK_FUNC_ENTER__;
1036
1037         net_err_t Error = NET_ERR_NONE;
1038         GVariantIter *iter_main = NULL;
1039         GVariantIter *var = NULL;
1040         GVariant *value = NULL;
1041         gchar *path = NULL;
1042         gchar *key = NULL;
1043         gboolean data;
1044
1045         g_variant_get(msg, "(a(oa{sv}))", &iter_main);
1046         while (g_variant_iter_loop(iter_main, "(oa{sv})", &path, &var)) {
1047
1048                 if (path == NULL)
1049                         continue; //LCOV_EXCL_LINE
1050
1051                 while (g_variant_iter_loop(var, "{sv}", &key, &value)) {
1052                         if (g_strcmp0(key, "Connected") == 0) {
1053                                 data = g_variant_get_boolean(value);
1054                                 if (!data)
1055                                         continue;
1056
1057         /* LCOV_EXCL_START */
1058                                 if (g_strcmp0(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == 0) {
1059                                         *(state_table + NET_DEVICE_WIFI) = NET_STATE_TYPE_READY;
1060                                         net_wifi_state = WIFI_CONNECTED;
1061                                 } else if (g_strcmp0(path, CONNMAN_CELLULAR_TECHNOLOGY_PREFIX) == 0)
1062                                         *(state_table + NET_DEVICE_CELLULAR) = NET_STATE_TYPE_READY;
1063                                 else if (g_strcmp0(path, CONNMAN_ETHERNET_TECHNOLOGY_PREFIX) == 0)
1064                                         *(state_table + NET_DEVICE_ETHERNET) = NET_STATE_TYPE_READY;
1065                                 else if (g_strcmp0(path, CONNMAN_BLUETOOTH_TECHNOLOGY_PREFIX) == 0)
1066                                         *(state_table + NET_DEVICE_BLUETOOTH) = NET_STATE_TYPE_READY;
1067                                 else if (g_strcmp0(path, CONNMAN_MESH_TECHNOLOGY_PREFIX) == 0)
1068                                         *(state_table + NET_DEVICE_MESH) = NET_STATE_TYPE_READY;
1069                                 else
1070                                         NETWORK_LOG(NETWORK_ERROR, "Invalid technology type");
1071                         } else if (g_strcmp0(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == 0 &&
1072                                         g_strcmp0(key, "Powered") == 0) {
1073                                 data = g_variant_get_boolean(value);
1074                                 if (data == FALSE)
1075                                         net_wifi_state = WIFI_OFF;
1076                                 else if (data == TRUE && net_wifi_state < WIFI_ON)
1077                                         net_wifi_state = WIFI_ON;
1078                         }
1079                 }
1080         }
1081         /* LCOV_EXCL_STOP */
1082         g_variant_iter_free(iter_main);
1083
1084         __NETWORK_FUNC_EXIT__;
1085         return Error;
1086 }
1087
1088 static int __net_dbus_get_all_technology_states(network_info_t *network_info)
1089 {
1090         __NETWORK_FUNC_ENTER__;
1091
1092         net_err_t Error = NET_ERR_NONE;
1093         GVariant *message = NULL;
1094
1095         message = _net_invoke_dbus_method(network_info, CONNMAN_SERVICE,
1096                         CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE,
1097                         "GetTechnologies", NULL, &Error);
1098         if (message == NULL) {
1099                 NETWORK_LOG(NETWORK_ERROR, "Failed to get technology info"); //LCOV_EXCL_LINE
1100                 goto done;
1101         }
1102
1103         Error = __net_get_all_tech_states(message, network_info->state_table);
1104
1105         g_variant_unref(message);
1106
1107 done:
1108         __NETWORK_FUNC_EXIT__;
1109         return Error;
1110 }
1111
1112 int _net_init_service_state_table(network_info_t *network_info)
1113 {
1114         __NETWORK_FUNC_ENTER__;
1115
1116         net_err_t Error = NET_ERR_NONE;
1117
1118         Error = __net_dbus_get_all_technology_states(network_info);
1119         if (Error != NET_ERR_NONE) {
1120                 __NETWORK_FUNC_EXIT__;
1121                 return Error;
1122         }
1123
1124         NETWORK_LOG(NETWORK_HIGH, "init service state table. "
1125                                 "wifi:%d, cellular:%d, ethernet:%d, bluetooth:%d, mesh:%d",
1126                                 network_info->state_table[NET_DEVICE_WIFI],
1127                                 network_info->state_table[NET_DEVICE_CELLULAR],
1128                                 network_info->state_table[NET_DEVICE_ETHERNET],
1129                                 network_info->state_table[NET_DEVICE_BLUETOOTH],
1130                                 network_info->state_table[NET_DEVICE_MESH]);
1131
1132         __NETWORK_FUNC_EXIT__;
1133         return NET_ERR_NONE;
1134 }
1135
1136 int _net_get_wifi_service_state(network_info_t *network_info)
1137 {
1138         __NETWORK_FUNC_ENTER__;
1139
1140         if (net_wifi_state == WIFI_ON) {
1141                 __NETWORK_FUNC_EXIT__;
1142                 return NET_STATE_TYPE_DISCONNECT;
1143         }
1144
1145         __NETWORK_FUNC_EXIT__;
1146         return network_info->state_table[NET_DEVICE_WIFI];
1147 }