Destroy profile handle when all connection handle is deinitialized
[platform/core/api/connection.git] / src / libnetwork.c
1 /*
2  * Copyright (c) 2011-2013 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <glib.h>
18 #include <stdio.h>
19 #include <stdarg.h>
20 #include <string.h>
21 #include <vconf/vconf.h>
22 #include <system_info.h>
23 #include <arpa/inet.h>
24
25 #include "net_connection_private.h"
26
27 static GSList *prof_handle_list = NULL;
28 static GHashTable *profile_cb_table = NULL;
29 static pthread_mutex_t g_conn_thread_mutex = PTHREAD_MUTEX_INITIALIZER;
30
31 struct _profile_cb_s {
32         connection_profile_state_changed_cb callback;
33         connection_profile_state_e state;
34         void *user_data;
35 };
36
37 struct _profile_list_s {
38         int next;
39         int count;
40         net_profile_info_t *profiles;
41 };
42
43 static struct _profile_list_s profile_iterator = {0, 0, NULL};
44 static bool connection_is_feature_checked[CONNECTION_SUPPORTED_FEATURE_MAX] = {0, };
45 static bool connection_feature_supported[CONNECTION_SUPPORTED_FEATURE_MAX] = {0, };
46
47 //LCOV_EXCL_START
48 static connection_error_e __libnet_convert_to_cp_error_type(net_err_t err_type)
49 {
50         switch (err_type) {
51         case NET_ERR_NONE:
52                 return CONNECTION_ERROR_NONE;
53         case NET_ERR_APP_ALREADY_REGISTERED:
54                 return CONNECTION_ERROR_INVALID_OPERATION;
55         case NET_ERR_APP_NOT_REGISTERED:
56                 return CONNECTION_ERROR_INVALID_OPERATION;
57         case NET_ERR_NO_ACTIVE_CONNECTIONS:
58                 return CONNECTION_ERROR_NO_CONNECTION;
59         case NET_ERR_ACTIVE_CONNECTION_EXISTS:
60                 return CONNECTION_ERROR_ALREADY_EXISTS;
61         case NET_ERR_CONNECTION_DHCP_FAILED:
62                 return CONNECTION_ERROR_DHCP_FAILED;
63         case NET_ERR_CONNECTION_INVALID_KEY:
64                 return CONNECTION_ERROR_INVALID_KEY;
65         case NET_ERR_IN_PROGRESS:
66                 return CONNECTION_ERROR_NOW_IN_PROGRESS;
67         case NET_ERR_OPERATION_ABORTED:
68                 return CONNECTION_ERROR_OPERATION_ABORTED;
69         case NET_ERR_TIME_OUT:
70                 return CONNECTION_ERROR_NO_REPLY;
71         case NET_ERR_ACCESS_DENIED:
72                 return CONNECTION_ERROR_PERMISSION_DENIED;
73         default:
74                 return CONNECTION_ERROR_OPERATION_FAILED;
75         }
76 }
77
78 static const char *__libnet_convert_cp_error_type_to_string(connection_error_e err_type)
79 {
80         switch (err_type) {
81         case CONNECTION_ERROR_NONE:
82                 return "NONE";
83         case CONNECTION_ERROR_INVALID_PARAMETER:
84                 return "INVALID_PARAMETER";
85         case CONNECTION_ERROR_OUT_OF_MEMORY:
86                 return "OUT_OF_MEMORY";
87         case CONNECTION_ERROR_INVALID_OPERATION:
88                 return "INVALID_OPERATION";
89         case CONNECTION_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
90                 return "ADDRESS_FAMILY_NOT_SUPPORTED";
91         case CONNECTION_ERROR_OPERATION_FAILED:
92                 return "OPERATION_FAILED";
93         case CONNECTION_ERROR_ITERATOR_END:
94                 return "ITERATOR_END";
95         case CONNECTION_ERROR_NO_CONNECTION:
96                 return "NO_CONNECTION";
97         case CONNECTION_ERROR_NOW_IN_PROGRESS:
98                 return "NOW_IN_PROGRESS";
99         case CONNECTION_ERROR_ALREADY_EXISTS:
100                 return "ALREADY_EXISTS";
101         case CONNECTION_ERROR_OPERATION_ABORTED:
102                 return "OPERATION_ABORTED";
103         case CONNECTION_ERROR_DHCP_FAILED:
104                 return "DHCP_FAILED";
105         case CONNECTION_ERROR_INVALID_KEY:
106                 return "INVALID_KEY";
107         case CONNECTION_ERROR_NO_REPLY:
108                 return "NO_REPLY";
109         case CONNECTION_ERROR_PERMISSION_DENIED:
110                 return "PERMISSION_DENIED";
111         case CONNECTION_ERROR_NOT_SUPPORTED:
112                 return "NOT_SUPPORTED";
113         case CONNECTION_ERROR_ALREADY_INITIALIZED:
114                 return "ALREADY_INITIALIZED";
115         case CONNECTION_ERROR_NOT_INITIALIZED:
116                 return "NOT_INITIALIZED";
117         }
118
119         return "UNKNOWN";
120 }
121
122 static const char *__libnet_convert_cp_state_to_string(connection_profile_state_e state)
123 {
124         switch (state) {
125         case CONNECTION_PROFILE_STATE_DISCONNECTED:
126                 return "DISCONNECTED";
127         case CONNECTION_PROFILE_STATE_ASSOCIATION:
128                 return "ASSOCIATION";
129         case CONNECTION_PROFILE_STATE_CONFIGURATION:
130                 return "CONFIGURATION";
131         case CONNECTION_PROFILE_STATE_CONNECTED:
132                 return "CONNECTED";
133         default:
134                 return "UNKNOWN";
135         }
136 }
137
138 static void __libnet_state_changed_cb(char *profile_name, connection_profile_state_e state)
139 {
140         struct _profile_cb_s *cb_info;
141
142         if (profile_name == NULL)
143                 return;
144
145         cb_info = g_hash_table_lookup(profile_cb_table, profile_name);
146         if (cb_info == NULL)
147                 return;
148
149         if (cb_info->state == state)
150                 return;
151
152         cb_info->state = state;
153
154         if (state < 0 || cb_info->callback == NULL)
155                 return;
156
157         cb_info->callback(cb_info->state, cb_info->user_data);
158 }
159
160 static void __libnet_clear_profile_list(struct _profile_list_s *profile_list)
161 {
162         if (profile_list->count > 0)
163                 g_free(profile_list->profiles);
164
165         profile_list->count = 0;
166         profile_list->next = 0;
167         profile_list->profiles = NULL;
168 }
169
170 static void __libnet_evt_cb(net_event_info_t *event_cb, void *user_data)
171 {
172         bool is_requested = false;
173         connection_error_e result = CONNECTION_ERROR_NONE;
174         connection_handle_s *conn_handle = (connection_handle_s *)user_data;
175
176         switch (event_cb->Event) {
177         case NET_EVENT_OPEN_RSP:
178                 is_requested = true;
179                 /* fall through */
180         case NET_EVENT_OPEN_IND:
181                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
182                 CONNECTION_LOG(CONNECTION_INFO, "Connection opened %s[%s]",
183                                         (is_requested) ? "RSP" : "IND",
184                                         __libnet_convert_cp_error_type_to_string(result));
185
186                 if (is_requested) {
187                         if (conn_handle->opened_callback) {
188                                 conn_handle->opened_callback(result,
189                                         conn_handle->opened_user_data);
190
191                                 conn_handle->opened_callback = NULL;
192                                 conn_handle->opened_user_data = NULL;
193                         }
194                 }
195
196                 switch (event_cb->Error) {
197                 case NET_ERR_NONE:
198                 case NET_ERR_ACTIVE_CONNECTION_EXISTS:
199                         CONNECTION_LOG(CONNECTION_INFO, "Successfully open connection");
200
201                         __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_CONNECTED);
202                         return;
203                 default:
204                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to open connection[%s]",
205                                                 __libnet_convert_cp_error_type_to_string(result));
206                 }
207
208                 __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_DISCONNECTED);
209
210                 break;
211         case NET_EVENT_CLOSE_RSP:
212                 is_requested = true;
213                 /* fall through */
214         case NET_EVENT_CLOSE_IND:
215                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
216                 CONNECTION_LOG(CONNECTION_INFO, "Connection closed %s[%s]",
217                                         (is_requested) ? "RSP" : "IND",
218                                         __libnet_convert_cp_error_type_to_string(result));
219
220                 if (is_requested) {
221                         if (conn_handle->closed_callback) {
222                                 conn_handle->closed_callback(result,
223                                         conn_handle->closed_user_data);
224
225                                 conn_handle->closed_callback = NULL;
226                                 conn_handle->closed_user_data = NULL;
227                         }
228                 }
229
230                 switch (event_cb->Error) {
231                 case NET_ERR_NONE:
232                         CONNECTION_LOG(CONNECTION_INFO, "Successfully closed connection");
233
234                         __libnet_state_changed_cb(event_cb->ProfileName, CONNECTION_PROFILE_STATE_DISCONNECTED);
235                         return;
236                 default:
237                         CONNECTION_LOG(CONNECTION_ERROR, "Failed to close connection[%s]",
238                                                         __libnet_convert_cp_error_type_to_string(result));
239                 }
240
241                 break;
242         case NET_EVENT_NET_STATE_IND:
243                 CONNECTION_LOG(CONNECTION_INFO, "State changed IND");
244
245                 if (event_cb->Datalength != sizeof(net_state_type_t))
246                         return;
247
248                 net_state_type_t *profile_state = (net_state_type_t *)event_cb->Data;
249                 connection_profile_state_e cp_state = _profile_convert_to_cp_state(*profile_state);
250
251                 CONNECTION_LOG(CONNECTION_INFO, "state: %s", __libnet_convert_cp_state_to_string(cp_state));
252                 SECURE_CONNECTION_LOG(CONNECTION_INFO, "profile name: %s", event_cb->ProfileName);
253
254                 __libnet_state_changed_cb(event_cb->ProfileName, cp_state);
255
256                 break;
257         case NET_EVENT_CELLULAR_SET_DEFAULT_RSP:
258                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
259                 CONNECTION_LOG(CONNECTION_INFO, "Got set default profile RSP %d", result);
260                 if (conn_handle->set_default_callback) {
261                         conn_handle->set_default_callback(result,
262                                 conn_handle->set_default_user_data);
263
264                         conn_handle->set_default_callback = NULL;
265                         conn_handle->set_default_user_data = NULL;
266                 }
267                 break;
268         case NET_EVENT_CELLULAR_RESET_DEFAULT_RSP:
269                 result = __libnet_convert_to_cp_error_type(event_cb->Error);
270                 CONNECTION_LOG(CONNECTION_INFO, "Got reset default profile RSP %d", result);
271                 if (conn_handle->reset_callback) {
272                         conn_handle->reset_callback(result,
273                                 conn_handle->reset_user_data);
274
275                         conn_handle->reset_callback = NULL;
276                         conn_handle->reset_user_data = NULL;
277                 }
278                 break;
279         case NET_EVENT_ETHERNET_CABLE_ATTACHED:
280                 CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable Attached Indication\n");
281                 if (conn_handle->ethernet_cable_state_changed_callback) {
282                         conn_handle->ethernet_cable_state_changed_callback(CONNECTION_ETHERNET_CABLE_ATTACHED,
283                                 conn_handle->ethernet_cable_state_changed_user_data);
284                 }
285                 break;
286         case NET_EVENT_ETHERNET_CABLE_DETACHED:
287                 CONNECTION_LOG(CONNECTION_INFO, "Got Ethernet cable detached Indication\n");
288                 if (conn_handle->ethernet_cable_state_changed_callback) {
289                         conn_handle->ethernet_cable_state_changed_callback(CONNECTION_ETHERNET_CABLE_DETACHED,
290                                 conn_handle->ethernet_cable_state_changed_user_data);
291                 }
292                 break;
293         case NET_EVENT_NETWORK_TYPE_CHANGED:
294                 CONNECTION_LOG(CONNECTION_INFO, "Got Network Type Changed Indication");
295                 int *state = (int *) event_cb->Data;
296                 if (conn_handle->type_changed_callback) {
297                         int type = CONNECTION_TYPE_DISCONNECTED;
298
299                         switch (*state) {
300                         case VCONFKEY_NETWORK_CELLULAR:
301                                 type = CONNECTION_TYPE_CELLULAR;
302                                 break;
303                         case VCONFKEY_NETWORK_WIFI:
304                                 type = CONNECTION_TYPE_WIFI;
305                                 break;
306                         case VCONFKEY_NETWORK_ETHERNET:
307                                 type = CONNECTION_TYPE_ETHERNET;
308                                 break;
309                         case VCONFKEY_NETWORK_BLUETOOTH:
310                                 type = CONNECTION_TYPE_BT;
311                                 break;
312                         case VCONFKEY_NETWORK_DEFAULT_PROXY:
313                                 type = CONNECTION_TYPE_NET_PROXY;
314                                 break;
315                         default:
316                                 type = CONNECTION_TYPE_DISCONNECTED;
317                                 break;
318                         }
319
320                         conn_handle->type_changed_callback(type,
321                                 conn_handle->type_changed_user_data);
322                 }
323                 break;
324         case NET_EVENT_IPV4_ADDRESS_CHANGED:
325                 CONNECTION_LOG(CONNECTION_INFO, "Got IPv4 Address Changed Indication");
326                 if (conn_handle->ip_changed_callback) {
327                         char *ipv4_addr = NULL;
328                         char *ipv6_addr = NULL;
329                         char *addr = (char *)event_cb->Data;
330
331                         ipv4_addr = g_strdup(addr);
332                         ipv6_addr = vconf_get_str(VCONFKEY_NETWORK_IP6);
333                         if (ipv6_addr == NULL)
334                                 CONNECTION_LOG(CONNECTION_ERROR, //LCOV_EXCL_LINE
335                                                 "vconf_get_str(VCONFKEY_NETWORK_IP6) failed");
336
337                         conn_handle->ip_changed_callback(ipv4_addr, ipv6_addr,
338                                 conn_handle->ip_changed_user_data);
339
340                         g_free(ipv4_addr);
341                         g_free(ipv6_addr);
342                 }
343                 break;
344         case NET_EVENT_IPV6_ADDRESS_CHANGED:
345                 CONNECTION_LOG(CONNECTION_INFO, "Got IPv6 Address Changed Indication");
346                 if (conn_handle->ip_changed_callback) {
347                         char *ipv4_addr = NULL;
348                         char *ipv6_addr = NULL;
349                         char *addr = (char *)event_cb->Data;
350
351                         ipv6_addr = g_strdup(addr);
352                         ipv4_addr = vconf_get_str(VCONFKEY_NETWORK_IP);
353                         if (ipv4_addr == NULL)
354                                 CONNECTION_LOG(CONNECTION_ERROR, //LCOV_EXCL_LINE
355                                                 "vconf_get_str(VCONFKEY_NETWORK_IP) failed");
356
357                         conn_handle->ip_changed_callback(ipv4_addr, ipv6_addr,
358                                 conn_handle->ip_changed_user_data);
359
360                         g_free(ipv4_addr);
361                         g_free(ipv6_addr);
362                 }
363                 break;
364         case NET_EVENT_PROXY_ADDRESS_CHANGED:
365                 CONNECTION_LOG(CONNECTION_INFO, "Got Proxy Changed Indication");
366                 char *proxy_addr = (char *)event_cb->Data;
367
368                 if (conn_handle->proxy_changed_callback) {
369                         conn_handle->proxy_changed_callback(proxy_addr, NULL,
370                                 conn_handle->proxy_changed_user_data);
371                 }
372                 break;
373         case NET_EVENT_INTERNET_ONLINE_IND:
374         case NET_EVENT_INTERNET_OFFLINE_IND:
375                 CONNECTION_LOG(CONNECTION_INFO, "Got Internet State Changed Indication: %s",
376                                 event_cb->Event == NET_EVENT_INTERNET_ONLINE_IND ? "Online" : "Offline");
377                 net_device_t *device_type = (net_device_t *) event_cb->Data;
378
379                 if (conn_handle->internet_state_changed_callback) {
380                         net_profile_info_t active_profile;
381                         int rv;
382
383                         rv = net_get_active_net_info(conn_handle->network_info_handle, &active_profile);
384
385                         if (rv == NET_ERR_NO_SERVICE && event_cb->Event == NET_EVENT_INTERNET_OFFLINE_IND) {
386                                 conn_handle->internet_state_changed_callback(CONNECTION_INTERNET_STATE_OFFLINE,
387                                         conn_handle->internet_state_changed_user_data); //LCOV_EXCL_LINE
388                                 break;
389                         } else if (rv == NET_ERR_ACCESS_DENIED) {
390                                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
391                                 break;
392                         } else if (rv != NET_ERR_NONE) {
393                                 CONNECTION_LOG(CONNECTION_ERROR, "Unable to get Default profile handle"); //LCOV_EXCL_LINE
394                                 break; //LCOV_EXCL_LINE
395                         }
396
397                         if (event_cb->Event == NET_EVENT_INTERNET_ONLINE_IND) {
398                                 if (active_profile.ProfileState == NET_STATE_TYPE_ONLINE &&
399                                                 active_profile.profile_type == *device_type)
400                                         conn_handle->internet_state_changed_callback(CONNECTION_INTERNET_STATE_ONLINE,
401                                                         conn_handle->internet_state_changed_user_data);
402                         } else {
403                                 if (active_profile.ProfileState != NET_STATE_TYPE_ONLINE)
404                                         conn_handle->internet_state_changed_callback(CONNECTION_INTERNET_STATE_OFFLINE,
405                                                         conn_handle->internet_state_changed_user_data);
406                         }
407                 }
408                 break;
409
410         default:
411                 break;
412         }
413 }
414 //LCOV_EXCL_STOP
415
416 static int __libnet_get_connected_count(struct _profile_list_s *profile_list)
417 {
418         int count = 0;
419         int i = 0;
420
421         for (; i < profile_list->count; i++) {
422                 if (profile_list->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
423                     profile_list->profiles[i].ProfileState == NET_STATE_TYPE_READY)
424                         count++;
425         }
426
427         return count;
428 }
429
430 static void __libnet_copy_connected_profile(net_profile_info_t **dest, struct _profile_list_s *source)
431 {
432         int i = 0;
433
434         for (; i < source->count; i++) {
435                 if (source->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
436                     source->profiles[i].ProfileState == NET_STATE_TYPE_READY) {
437                         memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
438                         (*dest)++;
439                 }
440         }
441 }
442
443 //LCOV_EXCL_START
444 static int __libnet_get_default_count(struct _profile_list_s *profile_list)
445 {
446         int count = 0;
447         int i = 0;
448
449         for (; i < profile_list->count; i++) {
450                 if (profile_list->profiles[i].profile_type == NET_DEVICE_CELLULAR) {
451                         if (profile_list->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE)
452                                 count++;
453                 }
454         }
455
456         return count;
457 }
458
459 static void __libnet_copy_default_profile(net_profile_info_t **dest, struct _profile_list_s *source)
460 {
461         int i = 0;
462
463         for (; i < source->count; i++) {
464                 if (source->profiles[i].profile_type == NET_DEVICE_CELLULAR) {
465                         if (source->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE) {
466                                 memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
467                                 (*dest)++;
468                         }
469                 }
470         }
471 }
472 //LCOV_EXCL_STOP
473
474 int _connection_libnet_init(connection_handle_s *conn_handle)
475 {
476         int rv;
477
478         rv = net_register_client(&(conn_handle->network_info_handle),
479                                 (net_event_cb_t)__libnet_evt_cb, conn_handle);
480         if (rv != NET_ERR_NONE)
481                 return rv;
482
483         if (profile_cb_table == NULL)
484                 profile_cb_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
485
486         return NET_ERR_NONE;
487 }
488
489 bool _connection_libnet_deinit(connection_handle_s *conn_handle, bool is_empty)
490 {
491         net_deregister_client(conn_handle->network_info_handle);
492
493         if (is_empty) {
494                 if (profile_cb_table) {
495                         g_hash_table_destroy(profile_cb_table);
496                         profile_cb_table = NULL;
497                 }
498
499                 __libnet_clear_profile_list(&profile_iterator);
500
501                 if (prof_handle_list) {
502                         g_slist_free_full(prof_handle_list, g_free);
503                         prof_handle_list = NULL;
504                 }
505         }
506
507         return true;
508 }
509
510 void _connection_set_cs_tid(int tid, connection_handle_s *conn_handle)
511 {
512         net_set_cs_tid(tid, conn_handle->network_info_handle);
513 }
514
515 void _connection_unset_cs_tid(int tid, connection_handle_s *conn_handle)
516 {
517         net_unset_cs_tid(tid, conn_handle->network_info_handle);
518 }
519
520 bool _connection_libnet_check_profile_validity(connection_profile_h profile)
521 {
522         GSList *list;
523         int i = 0;
524
525         if (profile == NULL)
526                 return false;
527
528         for (list = prof_handle_list; list; list = list->next)
529                 if (profile == list->data) return true;
530
531         for (; i < profile_iterator.count; i++)
532                 if (profile == &profile_iterator.profiles[i]) return true;
533
534         return false;
535 }
536
537 int _connection_libnet_get_metered_state(connection_handle_s *conn_handle, bool* is_metered)
538 {
539         int rv = 0;
540         int status = 0;
541
542         rv = net_get_metered_state(conn_handle->network_info_handle, &status);
543         if (rv == NET_ERR_ACCESS_DENIED) {
544                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
545                 return CONNECTION_ERROR_PERMISSION_DENIED;
546         } else if (rv != NET_ERR_NONE) {
547                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get metered state[%d]", rv);
548                 return CONNECTION_ERROR_OPERATION_FAILED;
549         }
550
551         if (status == 1)
552                 *is_metered = true;
553         else
554                 *is_metered = false;
555         return CONNECTION_ERROR_NONE;
556 }
557
558 int _connection_libnet_get_wifi_state(connection_handle_s *conn_handle, connection_wifi_state_e *state)
559 {
560         int rv;
561         net_wifi_state_t wlan_state;
562
563         rv = net_get_wifi_state(conn_handle->network_info_handle, &wlan_state);
564         if (rv == NET_ERR_ACCESS_DENIED) {
565                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
566                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
567         } else if (rv != NET_ERR_NONE) {
568                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi state[%d]", rv); //LCOV_EXCL_LINE
569                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
570         }
571
572         switch (wlan_state) {
573         case WIFI_OFF:
574                 *state = CONNECTION_WIFI_STATE_DEACTIVATED;
575                 break;
576         case WIFI_ON:
577         case WIFI_ASSOCIATION:
578         case WIFI_CONFIGURATION:
579                 *state = CONNECTION_WIFI_STATE_DISCONNECTED;
580                 break;
581         case WIFI_CONNECTED:
582         case WIFI_DISCONNECTING:
583                 *state = CONNECTION_WIFI_STATE_CONNECTED;
584                 break;
585         default:
586                 CONNECTION_LOG(CONNECTION_ERROR, "Unknown Wi-Fi state"); //LCOV_EXCL_LINE
587                 return CONNECTION_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
588         }
589
590         return CONNECTION_ERROR_NONE;
591 }
592
593 //LCOV_EXCL_START
594 int _connection_libnet_get_ethernet_state(connection_handle_s *conn_handle,
595                         connection_ethernet_state_e *state)
596 {
597         int rv;
598         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
599         rv = net_get_profile_list(conn_handle->network_info_handle,
600                         NET_DEVICE_ETHERNET, &ethernet_profiles.profiles,
601                         &ethernet_profiles.count);
602         if (rv == NET_ERR_ACCESS_DENIED) {
603                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
604                 return CONNECTION_ERROR_PERMISSION_DENIED;
605         }
606
607         if (ethernet_profiles.count == 0) {
608                 *state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
609                 return CONNECTION_ERROR_NONE;
610         }
611
612         switch (ethernet_profiles.profiles->ProfileState) {
613         case NET_STATE_TYPE_ONLINE:
614         case NET_STATE_TYPE_READY:
615                 *state = CONNECTION_ETHERNET_STATE_CONNECTED;
616                 break;
617         case NET_STATE_TYPE_IDLE:
618         case NET_STATE_TYPE_FAILURE:
619         case NET_STATE_TYPE_ASSOCIATION:
620         case NET_STATE_TYPE_CONFIGURATION:
621         case NET_STATE_TYPE_DISCONNECT:
622                 *state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
623                 break;
624         default:
625                 __libnet_clear_profile_list(&ethernet_profiles);
626                 return CONNECTION_ERROR_OPERATION_FAILED;
627         }
628
629         __libnet_clear_profile_list(&ethernet_profiles);
630
631         return CONNECTION_ERROR_NONE;
632 }
633
634 int _connection_libnet_get_ethernet_cable_state(connection_handle_s *conn_handle,
635                         connection_ethernet_cable_state_e* state)
636 {
637         int rv = 0;
638         int status = 0;
639
640         rv = net_get_ethernet_cable_state(conn_handle->network_info_handle, &status);
641         if (rv == NET_ERR_ACCESS_DENIED) {
642                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
643                 return CONNECTION_ERROR_PERMISSION_DENIED;
644         } else if (rv != NET_ERR_NONE) {
645                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get ethernet cable state[%d]", rv);
646                 return CONNECTION_ERROR_OPERATION_FAILED;
647         }
648
649         if (status == 1)
650                 *state = CONNECTION_ETHERNET_CABLE_ATTACHED;
651         else
652                 *state = CONNECTION_ETHERNET_CABLE_DETACHED;
653         return CONNECTION_ERROR_NONE;
654 }
655 //LCOV_EXCL_STOP
656
657 int _connection_libnet_get_bluetooth_state(connection_handle_s *conn_handle, connection_bt_state_e *state)
658 {
659         int i = 0;
660         int rv = 0;
661         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
662         rv = net_get_profile_list(conn_handle->network_info_handle,
663                         NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles,
664                         &bluetooth_profiles.count);
665         if (rv == NET_ERR_ACCESS_DENIED) {
666                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
667                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
668         }
669
670         if (bluetooth_profiles.count == 0) {
671                 *state = CONNECTION_BT_STATE_DEACTIVATED;
672                 return CONNECTION_ERROR_NONE;
673         }
674
675         //LCOV_EXCL_START
676         for (; i < bluetooth_profiles.count; i++) {
677                 switch (bluetooth_profiles.profiles[i].ProfileState) {
678                 case NET_STATE_TYPE_ONLINE:
679                 case NET_STATE_TYPE_READY:
680                         *state = CONNECTION_BT_STATE_CONNECTED;
681                         goto done;
682                 case NET_STATE_TYPE_IDLE:
683                 case NET_STATE_TYPE_FAILURE:
684                 case NET_STATE_TYPE_ASSOCIATION:
685                 case NET_STATE_TYPE_CONFIGURATION:
686                 case NET_STATE_TYPE_DISCONNECT:
687                         *state = CONNECTION_BT_STATE_DISCONNECTED;
688                         break;
689                 default:
690                         __libnet_clear_profile_list(&bluetooth_profiles);
691                         return CONNECTION_ERROR_OPERATION_FAILED;
692                 }
693         }
694         //LCOV_EXCL_STOP
695
696 done:
697         __libnet_clear_profile_list(&bluetooth_profiles);
698
699         return CONNECTION_ERROR_NONE;
700 }
701
702 int _connection_libnet_get_profile_iterator(connection_handle_s *conn_handle,
703                         connection_iterator_type_e type, connection_profile_iterator_h* profile_iter_h)
704 {
705         int count = 0;
706         int rv;
707         net_profile_info_t *profiles = NULL;
708
709         struct _profile_list_s profile_list = {0, 0, NULL};
710
711         __libnet_clear_profile_list(&profile_iterator);
712
713         rv = net_get_all_profile_list(conn_handle->network_info_handle,
714                         &profile_list.profiles, &profile_list.count);
715         if (rv == NET_ERR_ACCESS_DENIED) {
716                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
717                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
718         } else if (rv != NET_ERR_NO_SERVICE && rv != NET_ERR_NONE)
719                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
720
721         *profile_iter_h = &profile_iterator;
722
723         switch (type) {
724         case CONNECTION_ITERATOR_TYPE_REGISTERED:
725                 count = profile_list.count;
726                 CONNECTION_LOG(CONNECTION_INFO, "Total profile count : %d", count);
727                 if (count == 0)
728                         return CONNECTION_ERROR_NONE;
729
730                 profiles = g_try_new0(net_profile_info_t, count);
731                 if (profiles == NULL) {
732                         __libnet_clear_profile_list(&profile_list);
733                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
734                 }
735
736                 profile_iterator.profiles = profiles;
737
738                 memcpy(profiles, profile_list.profiles, sizeof(net_profile_info_t) * count);
739
740                 break;
741         case CONNECTION_ITERATOR_TYPE_CONNECTED:
742                 count = __libnet_get_connected_count(&profile_list);
743                 CONNECTION_LOG(CONNECTION_INFO, "Total connected profile count : %d", count);
744                 if (count == 0)
745                         return CONNECTION_ERROR_NONE;
746
747                 profiles = g_try_new0(net_profile_info_t, count);
748                 if (profiles == NULL) {
749                         __libnet_clear_profile_list(&profile_list);
750                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
751                 }
752
753                 profile_iterator.profiles = profiles;
754
755                 __libnet_copy_connected_profile(&profiles, &profile_list);
756
757                 break;
758         case CONNECTION_ITERATOR_TYPE_DEFAULT:
759                 count = __libnet_get_default_count(&profile_list);
760                 CONNECTION_LOG(CONNECTION_INFO, "Total default profile count : %d", count); //LCOV_EXCL_LINE
761                 if (count == 0)
762                         return CONNECTION_ERROR_NONE;
763
764                 profiles = g_try_new0(net_profile_info_t, count);
765                 if (profiles == NULL) {
766                         __libnet_clear_profile_list(&profile_list);
767                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
768                 }
769
770                 profile_iterator.profiles = profiles;
771
772                 __libnet_copy_default_profile(&profiles, &profile_list);
773
774                 break;
775         }
776
777         __libnet_clear_profile_list(&profile_list);
778
779         profile_iterator.count = count;
780
781         return CONNECTION_ERROR_NONE;
782 }
783
784 int _connection_libnet_get_iterator_next(connection_profile_iterator_h profile_iter_h, connection_profile_h *profile)
785 {
786         if (profile_iter_h != &profile_iterator)
787                 return CONNECTION_ERROR_INVALID_PARAMETER;
788
789         if (profile_iterator.count <= profile_iterator.next)
790                 return CONNECTION_ERROR_ITERATOR_END;
791
792         *profile = &profile_iterator.profiles[profile_iterator.next];
793         profile_iterator.next++;
794
795         return CONNECTION_ERROR_NONE;
796 }
797
798 bool _connection_libnet_iterator_has_next(connection_profile_iterator_h profile_iter_h)
799 {
800         if (profile_iter_h != &profile_iterator)
801                 return false;
802
803         if (profile_iterator.count <= profile_iterator.next)
804                 return false;
805
806         return true;
807 }
808
809 int _connection_libnet_destroy_iterator(connection_profile_iterator_h profile_iter_h)
810 {
811         if (profile_iter_h != &profile_iterator)
812                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
813
814         __libnet_clear_profile_list(&profile_iterator);
815
816         return CONNECTION_ERROR_NONE;
817 }
818
819 int _connection_libnet_get_current_profile(connection_handle_s *conn_handle,
820                         connection_profile_h *profile)
821 {
822         net_profile_info_t active_profile;
823         int rv;
824
825         rv = net_get_active_net_info(conn_handle->network_info_handle, &active_profile);
826         if (rv == NET_ERR_NO_SERVICE)
827                 return CONNECTION_ERROR_NO_CONNECTION; //LCOV_EXCL_LINE
828         else if (rv == NET_ERR_ACCESS_DENIED) {
829                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
830                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
831         } else if (rv != NET_ERR_NONE)
832                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
833
834         *profile = g_try_malloc0(sizeof(net_profile_info_t));
835         if (*profile == NULL)
836                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
837
838         memcpy(*profile, &active_profile, sizeof(net_profile_info_t));
839         prof_handle_list = g_slist_append(prof_handle_list, *profile);
840
841         return CONNECTION_ERROR_NONE;
842 }
843
844 int _connection_libnet_reset_profile(connection_handle_s *conn_handle,
845                 connection_reset_option_e type, connection_cellular_subscriber_id_e id)
846 {
847         int rv;
848
849         rv = net_reset_profile(conn_handle->network_info_handle, type, id);
850         if (rv == NET_ERR_ACCESS_DENIED)
851                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
852         else if (rv != NET_ERR_NONE)
853                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
854
855         return CONNECTION_ERROR_NONE;
856 }
857
858 int _connection_libnet_open_profile(connection_handle_s *conn_handle,
859                         connection_profile_h profile)
860 {
861         int rv;
862
863         if (!(_connection_libnet_check_profile_validity(profile))) {
864                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
865                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
866         }
867
868         net_profile_info_t *profile_info = profile;
869
870         if (profile_info->profile_type == NET_DEVICE_MESH)
871                 rv = net_open_mesh_connection_with_profile(conn_handle->network_info_handle,
872                                 profile_info->ProfileName);
873         else
874                 rv = net_open_connection_with_profile(conn_handle->network_info_handle,
875                                 profile_info->ProfileName);
876
877         if (rv == NET_ERR_ACCESS_DENIED)
878                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
879         else if (rv != NET_ERR_NONE)
880                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
881
882         return CONNECTION_ERROR_NONE;
883 }
884
885 int _connection_libnet_get_cellular_service_profile(connection_handle_s *conn_handle,
886                 connection_cellular_service_type_e type, connection_profile_h *profile)
887 {
888         int i = 0, j = 0;
889         int rv = NET_ERR_NONE;
890 #if defined TIZEN_DUALSIM_ENABLE
891         int default_subscriber_id = 0;
892         char subscriber_id[3];
893 #endif
894
895         struct _profile_list_s cellular_profiles = { 0, 0, NULL };
896         net_service_type_t service_type = _connection_profile_convert_to_libnet_cellular_service_type(type);
897
898         rv = net_get_profile_list(conn_handle->network_info_handle,
899                         NET_DEVICE_CELLULAR, &cellular_profiles.profiles,
900                         &cellular_profiles.count);
901         if (rv == NET_ERR_ACCESS_DENIED) {
902                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
903                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
904         } else if (rv != NET_ERR_NONE) {
905                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get profile list (%d)", rv); //LCOV_EXCL_LINE
906                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
907         }
908
909 #if defined TIZEN_DUALSIM_ENABLE
910         if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE,
911                                                 &default_subscriber_id) != 0) {
912                 CONNECTION_LOG(CONNECTION_ERROR,
913                                                 "Failed to get VCONF_TELEPHONY_DEFAULT_DATA_SERVICE");
914                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
915                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
916         }
917
918         g_snprintf(subscriber_id, sizeof(subscriber_id), "%d", default_subscriber_id);
919 #endif
920
921         for (i = 0; i < cellular_profiles.count; i++)
922                 if (cellular_profiles.profiles[i].ProfileInfo.Pdp.ServiceType == service_type)
923 #if defined TIZEN_DUALSIM_ENABLE
924                         if (g_str_has_suffix(
925                                         cellular_profiles.profiles[i].ProfileInfo.Pdp.PSModemPath,
926                                         subscriber_id) == TRUE)
927 #endif
928                                 break;
929
930         if (i >= cellular_profiles.count) {
931                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
932                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
933         }
934
935         *profile = g_try_malloc0(sizeof(net_profile_info_t));
936         if (*profile == NULL) {
937                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
938                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
939         }
940
941         memcpy(*profile, &cellular_profiles.profiles[i], sizeof(net_profile_info_t));
942
943         if (cellular_profiles.profiles[i].ProfileInfo.Pdp.DefaultConn)
944                 goto done;
945
946         //LCOV_EXCL_START
947         if (type != CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET &&
948             type != CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_INTERNET)
949                 goto done;
950
951         for (j = 0; j < cellular_profiles.count; j++) {
952                 if (i == j)
953                         continue;
954
955                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.ServiceType != service_type)
956                         continue;
957
958                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.DefaultConn) {
959                         memcpy(*profile, &cellular_profiles.profiles[j], sizeof(net_profile_info_t));
960                         goto done;
961                 }
962         }
963         //LCOV_EXCL_STOP
964
965 done:
966         __libnet_clear_profile_list(&cellular_profiles);
967         prof_handle_list = g_slist_append(prof_handle_list, *profile);
968
969         return CONNECTION_ERROR_NONE;
970 }
971
972 int _connection_libnet_set_cellular_service_profile_sync(connection_handle_s *conn_handle,
973                         connection_cellular_service_type_e type, connection_profile_h profile)
974 {
975         int rv;
976
977         if (!(_connection_libnet_check_profile_validity(profile))) {
978                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
979                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
980         }
981
982         net_profile_info_t *profile_info = profile;
983         connection_cellular_service_type_e service_type;
984
985         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
986
987         if (service_type != type)
988                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
989
990         rv = net_set_default_cellular_service_profile(conn_handle->network_info_handle,
991                                 profile_info->ProfileName);
992         if (rv == NET_ERR_ACCESS_DENIED) {
993                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
994                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
995         } else if (rv != NET_ERR_NONE)
996                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
997
998         return CONNECTION_ERROR_NONE;
999 }
1000
1001 int _connection_libnet_set_cellular_service_profile_async(connection_handle_s *conn_handle,
1002                         connection_cellular_service_type_e type, connection_profile_h profile)
1003 {
1004         int rv;
1005
1006         if (!(_connection_libnet_check_profile_validity(profile))) {
1007                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1008                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1009         }
1010
1011         net_profile_info_t *profile_info = profile;
1012         connection_cellular_service_type_e service_type;
1013
1014         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1015
1016         if (service_type != type)
1017                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1018
1019         rv = net_set_default_cellular_service_profile_async(conn_handle->network_info_handle,
1020                                 profile_info->ProfileName);
1021         if (rv == NET_ERR_ACCESS_DENIED) {
1022                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1023         } else if (rv != NET_ERR_NONE)
1024                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1025
1026         return CONNECTION_ERROR_NONE;
1027 }
1028
1029 int _connection_libnet_close_profile(connection_handle_s *conn_handle, connection_profile_h profile)
1030 {
1031         int rv;
1032
1033         if (!(_connection_libnet_check_profile_validity(profile))) {
1034                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1035                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1036         }
1037
1038         net_profile_info_t *profile_info = profile;
1039
1040         if (profile_info->profile_type == NET_DEVICE_MESH)
1041                 rv = net_close_mesh_connection(conn_handle->network_info_handle, profile_info->ProfileName);
1042         else
1043                 rv = net_close_connection(conn_handle->network_info_handle, profile_info->ProfileName);
1044
1045         if (rv == NET_ERR_ACCESS_DENIED)
1046                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1047         else if (rv != NET_ERR_NONE)
1048                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1049
1050         return CONNECTION_ERROR_NONE;
1051 }
1052
1053 int _connection_libnet_add_route(connection_handle_s *conn_handle,
1054                         const char *interface_name, const char *host_address)
1055 {
1056         int rv;
1057         char *endstr = NULL;
1058         int address_family = 0;
1059
1060         address_family = AF_INET;
1061
1062         endstr = strrchr(host_address, '.');
1063         if (endstr == NULL ||
1064                         strcmp(endstr, ".0") == 0 ||
1065                         strncmp(host_address, "0.", 2) == 0 ||
1066                         strstr(host_address, "255") != NULL) {
1067                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1068                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1069         }
1070
1071         rv = net_add_route(conn_handle->network_info_handle,
1072                                 host_address, interface_name, address_family);
1073         if (rv == NET_ERR_ACCESS_DENIED) {
1074                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1075                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1076         } else if (rv != NET_ERR_NONE)
1077                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1078
1079         return CONNECTION_ERROR_NONE;
1080 }
1081
1082 int _connection_libnet_remove_route(connection_handle_s *conn_handle,
1083                         const char *interface_name, const char *host_address)
1084 {
1085         int rv;
1086         char *endstr = strrchr(host_address, '.');
1087         int address_family = 0;
1088
1089         address_family = AF_INET;
1090
1091         endstr = strrchr(host_address, '.');
1092         if (endstr == NULL ||
1093                 strcmp(endstr, ".0") == 0 ||
1094                 strncmp(host_address, "0.", 2) == 0 ||
1095                 strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1096                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1097                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1098         }
1099
1100         rv = net_remove_route(conn_handle->network_info_handle,
1101                                 host_address, interface_name, address_family);
1102         if (rv == NET_ERR_ACCESS_DENIED) {
1103                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1104                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1105         } else if (rv != NET_ERR_NONE)
1106                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1107
1108         return CONNECTION_ERROR_NONE;
1109 }
1110
1111 int _connection_libnet_add_route_ipv6(connection_handle_s *conn_handle,
1112                         const char *interface_name, const char *host_address, const char *gateway)
1113 {
1114         int rv;
1115         int address_family = 0;
1116
1117         address_family = AF_INET6;
1118
1119         if (strncmp(host_address, "fe80:", 5) == 0 ||
1120                 strncmp(host_address, "ff00:", 5) == 0 ||
1121                 strncmp(host_address, "::", 2) == 0) {
1122                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1123                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1124         }
1125
1126         rv = net_add_route_ipv6(conn_handle->network_info_handle,
1127                                 host_address, interface_name, address_family, gateway);
1128         if (rv == NET_ERR_ACCESS_DENIED) {
1129                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1130                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1131         } else if (rv != NET_ERR_NONE)
1132                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1133
1134         return CONNECTION_ERROR_NONE;
1135 }
1136
1137 int _connection_libnet_remove_route_ipv6(connection_handle_s *conn_handle,
1138                         const char *interface_name, const char *host_address, const char *gateway)
1139 {
1140         int rv;
1141         int address_family = 0;
1142
1143         address_family = AF_INET6;
1144
1145         if (strncmp(host_address, "fe80:", 5) == 0 ||
1146                 strncmp(host_address, "ff00:", 5) == 0 ||
1147                 strncmp(host_address, "::", 2) == 0) {
1148                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1149                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1150         }
1151
1152         rv = net_remove_route_ipv6(conn_handle->network_info_handle,
1153                                 host_address, interface_name, address_family, gateway);
1154         if (rv == NET_ERR_ACCESS_DENIED) {
1155                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1156                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1157         } else if (rv != NET_ERR_NONE)
1158                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1159
1160         return CONNECTION_ERROR_NONE;
1161 }
1162
1163 int _connection_libnet_add_route_entry(connection_handle_s *conn_handle,
1164                 connection_address_family_e address_family, const char *interface_name,
1165                 const char *host_address, const char *gateway)
1166 {
1167         int rv;
1168         char *endstr = NULL;
1169         int address_family_type = 0;
1170
1171         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1172                 address_family_type = AF_INET;
1173         else
1174                 address_family_type = AF_INET6;
1175
1176         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1177
1178                 endstr = strrchr(host_address, '.');
1179                 if (endstr == NULL ||
1180                                 strcmp(endstr, ".0") == 0 ||
1181                                 strncmp(host_address, "0.", 2) == 0 ||
1182                                 strstr(host_address, "255") != NULL) {
1183                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1184                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1185                 }
1186
1187                 rv = net_add_route_entry(conn_handle->network_info_handle,
1188                                 host_address, interface_name, address_family_type, gateway);
1189                 if (rv == NET_ERR_ACCESS_DENIED) {
1190                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1191                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1192                 } else if (rv != NET_ERR_NONE)
1193                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1194
1195         } else {
1196
1197                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1198                         strncmp(host_address, "ff00:", 5) == 0 ||
1199                         strncmp(host_address, "::", 2) == 0) {
1200                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1201                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1202                 }
1203
1204                 rv = net_add_route_ipv6(conn_handle->network_info_handle,
1205                                 host_address, interface_name, address_family_type, gateway);
1206                 if (rv == NET_ERR_ACCESS_DENIED) {
1207                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1208                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1209                 } else if (rv != NET_ERR_NONE)
1210                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1211         }
1212
1213         return CONNECTION_ERROR_NONE;
1214 }
1215
1216 int _connection_libnet_remove_route_entry(connection_handle_s *conn_handle,
1217                 connection_address_family_e address_family, const char *interface_name,
1218                 const char *host_address, const char *gateway)
1219 {
1220         int rv;
1221         char *endstr = strrchr(host_address, '.');
1222         int address_family_type = 0;
1223
1224         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1225                 address_family_type = AF_INET;
1226         else
1227                 address_family_type = AF_INET6;
1228
1229         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1230                 endstr = strrchr(host_address, '.');
1231                 if (endstr == NULL ||
1232                         strcmp(endstr, ".0") == 0 ||
1233                         strncmp(host_address, "0.", 2) == 0 ||
1234                         strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1235                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1236                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1237                 }
1238
1239                 rv = net_remove_route_entry(conn_handle->network_info_handle, host_address,
1240                                         interface_name, address_family_type, gateway);
1241                 if (rv == NET_ERR_ACCESS_DENIED) {
1242                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1243                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1244                 } else if (rv != NET_ERR_NONE)
1245                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1246
1247         } else {
1248
1249                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1250                         strncmp(host_address, "ff00:", 5) == 0 ||
1251                         strncmp(host_address, "::", 2) == 0) {
1252                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1253                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1254                 }
1255
1256                 rv = net_remove_route_ipv6(conn_handle->network_info_handle, host_address,
1257                                         interface_name, address_family_type, gateway);
1258                 if (rv == NET_ERR_ACCESS_DENIED) {
1259                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1260                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1261                 } else if (rv != NET_ERR_NONE)
1262                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1263         }
1264
1265         return CONNECTION_ERROR_NONE;
1266 }
1267
1268 void _connection_libnet_add_to_profile_list(connection_profile_h profile)
1269 {
1270         prof_handle_list = g_slist_append(prof_handle_list, profile);
1271 }
1272
1273 void _connection_libnet_remove_from_profile_list(connection_profile_h profile)
1274 {
1275         prof_handle_list = g_slist_remove(prof_handle_list, profile);
1276         g_free(profile);
1277 }
1278
1279 bool _connection_libnet_add_to_profile_cb_list(connection_profile_h profile,
1280                 connection_profile_state_changed_cb callback, void *user_data)
1281 {
1282         net_profile_info_t *profile_info = profile;
1283         char *profile_name = g_strdup(profile_info->ProfileName);
1284
1285         struct _profile_cb_s *profile_cb_info = g_try_malloc0(sizeof(struct _profile_cb_s));
1286         if (profile_cb_info == NULL) {
1287                 g_free(profile_name); //LCOV_EXCL_LINE
1288                 return false; //LCOV_EXCL_LINE
1289         }
1290
1291         profile_cb_info->callback = callback;
1292         profile_cb_info->user_data = user_data;
1293         profile_cb_info->state = _profile_convert_to_cp_state(profile_info->ProfileState);
1294
1295         g_hash_table_replace(profile_cb_table, profile_name, profile_cb_info);
1296
1297         return true;
1298 }
1299
1300 bool _connection_libnet_remove_from_profile_cb_list(connection_profile_h profile)
1301 {
1302         net_profile_info_t *profile_info = profile;
1303
1304         if (g_hash_table_remove(profile_cb_table, profile_info->ProfileName) == TRUE)
1305                 return true;
1306
1307         return false; //LCOV_EXCL_LINE
1308 }
1309
1310 int _connection_libnet_set_statistics(connection_handle_s *conn_handle,
1311                         net_device_t device_type, net_statistics_type_e statistics_type)
1312 {
1313         int rv;
1314         rv = net_set_statistics(conn_handle->network_info_handle,
1315                                 device_type, statistics_type);
1316         if (rv == NET_ERR_ACCESS_DENIED) {
1317                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1318                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1319         } else if (rv != NET_ERR_NONE)
1320                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1321
1322         return CONNECTION_ERROR_NONE;
1323 }
1324
1325 int _connection_libnet_get_statistics(connection_handle_s *conn_handle,
1326                         net_statistics_type_e statistics_type, unsigned long long *size)
1327 {
1328         int rv;
1329         rv = net_get_statistics(conn_handle->network_info_handle,
1330                                 NET_DEVICE_WIFI, statistics_type, size);
1331         if (rv == NET_ERR_ACCESS_DENIED) {
1332                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1333                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1334         } else if (rv != NET_ERR_NONE)
1335                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1336
1337         return CONNECTION_ERROR_NONE;
1338 }
1339
1340 int _connection_libnet_set_cellular_subscriber_id(connection_profile_h profile,
1341                 connection_cellular_subscriber_id_e sim_id)
1342 {
1343         char *modem_path = NULL;
1344         net_profile_info_t *profile_info = (net_profile_info_t *)profile;
1345
1346         if (net_get_cellular_modem_object_path(&modem_path, sim_id) != NET_ERR_NONE) {
1347                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get subscriber[%d]", sim_id); //LCOV_EXCL_LINE
1348                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1349         }
1350
1351         if (!modem_path) {
1352                 CONNECTION_LOG(CONNECTION_ERROR, "NULL modem object path"); //LCOV_EXCL_LINE
1353                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1354         }
1355
1356         g_strlcpy(profile_info->ProfileInfo.Pdp.PSModemPath, modem_path,
1357                                 NET_PROFILE_NAME_LEN_MAX);
1358         g_free(modem_path);
1359
1360         return CONNECTION_ERROR_NONE;
1361 }
1362
1363 int _connection_libnet_check_get_privilege(void)
1364 {
1365         int rv;
1366
1367         rv = net_check_get_privilege();
1368         if (rv == NET_ERR_ACCESS_DENIED) {
1369                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1370                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1371         } else if (rv != NET_ERR_NONE)
1372                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1373
1374         return CONNECTION_ERROR_NONE;
1375 }
1376
1377 int _connection_libnet_check_profile_privilege(void)
1378 {
1379         int rv;
1380
1381         rv = net_check_profile_privilege();
1382         if (rv == NET_ERR_ACCESS_DENIED) {
1383                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1384                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1385         } else if (rv != NET_ERR_NONE)
1386                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1387
1388         return CONNECTION_ERROR_NONE;
1389 }
1390
1391 bool __libnet_check_feature_supported(const char *key, connection_supported_feature_e feature)
1392 {
1393         if (!connection_is_feature_checked[feature]) {
1394                 if (system_info_get_platform_bool(key, &connection_feature_supported[feature]) < 0) {
1395                         CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature getting from System Info"); //LCOV_EXCL_LINE
1396                         set_last_result(CONNECTION_ERROR_OPERATION_FAILED); //LCOV_EXCL_LINE
1397                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1398                 }
1399                 connection_is_feature_checked[feature] = true;
1400         }
1401         return connection_feature_supported[feature];
1402 }
1403
1404 int _connection_check_feature_supported(const char *feature_name, ...)
1405 {
1406         va_list list;
1407         const char *key;
1408         bool value = false;
1409         bool feature_supported = false;
1410
1411         va_start(list, feature_name);
1412         key = feature_name;
1413         while (1) {
1414                 if (strcmp(key, TELEPHONY_FEATURE) == 0)
1415                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TELEPHONY);
1416                 if (strcmp(key, WIFI_FEATURE) == 0)
1417                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_WIFI);
1418                 if (strcmp(key, TETHERING_BLUETOOTH_FEATURE) == 0)
1419                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TETHERING_BLUETOOTH);
1420                 if (strcmp(key, ETHERNET_FEATURE) == 0)
1421                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_ETHERNET);
1422
1423                 feature_supported |= value;
1424                 key = va_arg(list, const char *);
1425                 if (!key) break;
1426         }
1427         if (!feature_supported) {
1428                 CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature is not supported");
1429                 set_last_result(CONNECTION_ERROR_NOT_SUPPORTED);
1430                 va_end(list);
1431                 return CONNECTION_ERROR_NOT_SUPPORTED;
1432         }
1433
1434         va_end(list);
1435         set_last_result(CONNECTION_ERROR_NONE);
1436         return CONNECTION_ERROR_NONE;
1437 }
1438
1439 int _connection_libnet_start_tcpdump(connection_handle_s *conn_handle)
1440 {
1441         connection_error_e result = CONNECTION_ERROR_NONE;
1442         net_err_t ret = NET_ERR_NONE;
1443
1444         ret = net_start_tcpdump(conn_handle->network_info_handle);
1445         result = __libnet_convert_to_cp_error_type(ret);
1446
1447         return result;
1448 }
1449
1450 int _connection_libnet_stop_tcpdump(connection_handle_s *conn_handle)
1451 {
1452         connection_error_e result = CONNECTION_ERROR_NONE;
1453         net_err_t ret = NET_ERR_NONE;
1454
1455         ret = net_stop_tcpdump(conn_handle->network_info_handle);
1456         result = __libnet_convert_to_cp_error_type(ret);
1457
1458         return result;
1459 }
1460
1461 int _connection_libnet_get_tcpdump_state(connection_handle_s *conn_handle,
1462                         gboolean *tcpdump_state)
1463 {
1464         connection_error_e result = CONNECTION_ERROR_NONE;
1465         net_err_t ret = NET_ERR_NONE;
1466
1467         ret = net_get_tcpdump_state(conn_handle->network_info_handle, tcpdump_state);
1468         result = __libnet_convert_to_cp_error_type(ret);
1469
1470         return result;
1471 }
1472
1473 void _connection_lock(void)
1474 {
1475         pthread_mutex_lock(&g_conn_thread_mutex);
1476 }
1477
1478 void _connection_unlock(void)
1479 {
1480         pthread_mutex_unlock(&g_conn_thread_mutex);
1481 }