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