Add mutex lock/unlock
[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 count;
39         int next;
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
374         default:
375                 break;
376         }
377 }
378 //LCOV_EXCL_STOP
379
380 int __libnet_get_connected_count(struct _profile_list_s *profile_list)
381 {
382         int count = 0;
383         int i = 0;
384
385         for (; i < profile_list->count; i++) {
386                 if (profile_list->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
387                     profile_list->profiles[i].ProfileState == NET_STATE_TYPE_READY)
388                         count++;
389         }
390
391         return count;
392 }
393
394 void __libnet_copy_connected_profile(net_profile_info_t **dest, struct _profile_list_s *source)
395 {
396         int i = 0;
397
398         for (; i < source->count; i++) {
399                 if (source->profiles[i].ProfileState == NET_STATE_TYPE_ONLINE ||
400                     source->profiles[i].ProfileState == NET_STATE_TYPE_READY) {
401                         memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
402                         (*dest)++;
403                 }
404         }
405 }
406
407 //LCOV_EXCL_START
408 int __libnet_get_default_count(struct _profile_list_s *profile_list)
409 {
410         int count = 0;
411         int i = 0;
412
413         for (; i < profile_list->count; i++) {
414                 if (profile_list->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE)
415                         count++;
416         }
417
418         return count;
419 }
420
421 void __libnet_copy_default_profile(net_profile_info_t **dest, struct _profile_list_s *source)
422 {
423         int i = 0;
424
425         for (; i < source->count; i++) {
426                 if (source->profiles[i].ProfileInfo.Pdp.DefaultConn == TRUE) {
427                         memcpy(*dest, &source->profiles[i], sizeof(net_profile_info_t));
428                         (*dest)++;
429                 }
430         }
431 }
432 //LCOV_EXCL_STOP
433
434 int _connection_libnet_init(connection_handle_s *conn_handle)
435 {
436         int rv;
437
438         rv = net_register_client(&(conn_handle->network_info_handle),
439                                 (net_event_cb_t)__libnet_evt_cb, conn_handle);
440         if (rv != NET_ERR_NONE)
441                 return rv;
442
443         if (profile_cb_table == NULL)
444                 profile_cb_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
445
446         return NET_ERR_NONE;
447 }
448
449 bool _connection_libnet_deinit(connection_handle_s *conn_handle)
450 {
451         net_deregister_client(conn_handle->network_info_handle);
452
453         if (profile_cb_table) {
454                 g_hash_table_destroy(profile_cb_table);
455                 profile_cb_table = NULL;
456         }
457
458         __libnet_clear_profile_list(&profile_iterator);
459
460         if (prof_handle_list) {
461                 g_slist_free_full(prof_handle_list, g_free);
462                 prof_handle_list = NULL;
463         }
464
465         return true;
466 }
467
468 void _connection_set_cs_tid(int tid, connection_handle_s *conn_handle)
469 {
470         net_set_cs_tid(tid, conn_handle->network_info_handle);
471 }
472
473 void _connection_unset_cs_tid(int tid, connection_handle_s *conn_handle)
474 {
475         net_unset_cs_tid(tid, conn_handle->network_info_handle);
476 }
477
478 bool _connection_libnet_check_profile_validity(connection_profile_h profile)
479 {
480         GSList *list;
481         int i = 0;
482
483         if (profile == NULL)
484                 return false;
485
486         for (list = prof_handle_list; list; list = list->next)
487                 if (profile == list->data) return true;
488
489         for (; i < profile_iterator.count; i++)
490                 if (profile == &profile_iterator.profiles[i]) return true;
491
492         return false;
493 }
494
495 int _connection_libnet_get_metered_state(connection_handle_s *conn_handle, bool* is_metered)
496 {
497         int rv = 0;
498         int status = 0;
499
500         rv = net_get_metered_state(conn_handle->network_info_handle, &status);
501         if (rv == NET_ERR_ACCESS_DENIED) {
502                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
503                 return CONNECTION_ERROR_PERMISSION_DENIED;
504         } else if (rv != NET_ERR_NONE) {
505                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get metered state[%d]", rv);
506                 return CONNECTION_ERROR_OPERATION_FAILED;
507         }
508
509         if (status == 1)
510                 *is_metered = true;
511         else
512                 *is_metered = false;
513         return CONNECTION_ERROR_NONE;
514 }
515
516 int _connection_libnet_get_wifi_state(connection_handle_s *conn_handle, connection_wifi_state_e *state)
517 {
518         int rv;
519         net_wifi_state_t wlan_state;
520
521         rv = net_get_wifi_state(conn_handle->network_info_handle, &wlan_state);
522         if (rv == NET_ERR_ACCESS_DENIED) {
523                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
524                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
525         } else if (rv != NET_ERR_NONE) {
526                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get Wi-Fi state[%d]", rv); //LCOV_EXCL_LINE
527                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
528         }
529
530         switch (wlan_state) {
531         case WIFI_OFF:
532                 *state = CONNECTION_WIFI_STATE_DEACTIVATED;
533                 break;
534         case WIFI_ON:
535         case WIFI_ASSOCIATION:
536         case WIFI_CONFIGURATION:
537                 *state = CONNECTION_WIFI_STATE_DISCONNECTED;
538                 break;
539         case WIFI_CONNECTED:
540         case WIFI_DISCONNECTING:
541                 *state = CONNECTION_WIFI_STATE_CONNECTED;
542                 break;
543         default:
544                 CONNECTION_LOG(CONNECTION_ERROR, "Unknown Wi-Fi state"); //LCOV_EXCL_LINE
545                 return CONNECTION_ERROR_INVALID_OPERATION; //LCOV_EXCL_LINE
546         }
547
548         return CONNECTION_ERROR_NONE;
549 }
550
551 //LCOV_EXCL_START
552 int _connection_libnet_get_ethernet_state(connection_handle_s *conn_handle,
553                         connection_ethernet_state_e *state)
554 {
555         int rv;
556         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
557         rv = net_get_profile_list(conn_handle->network_info_handle,
558                         NET_DEVICE_ETHERNET, &ethernet_profiles.profiles,
559                         &ethernet_profiles.count);
560         if (rv == NET_ERR_ACCESS_DENIED) {
561                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
562                 return CONNECTION_ERROR_PERMISSION_DENIED;
563         }
564
565         if (ethernet_profiles.count == 0) {
566                 *state = CONNECTION_ETHERNET_STATE_DEACTIVATED;
567                 return CONNECTION_ERROR_NONE;
568         }
569
570         switch (ethernet_profiles.profiles->ProfileState) {
571         case NET_STATE_TYPE_ONLINE:
572         case NET_STATE_TYPE_READY:
573                 *state = CONNECTION_ETHERNET_STATE_CONNECTED;
574                 break;
575         case NET_STATE_TYPE_IDLE:
576         case NET_STATE_TYPE_FAILURE:
577         case NET_STATE_TYPE_ASSOCIATION:
578         case NET_STATE_TYPE_CONFIGURATION:
579         case NET_STATE_TYPE_DISCONNECT:
580                 *state = CONNECTION_ETHERNET_STATE_DISCONNECTED;
581                 break;
582         default:
583                 __libnet_clear_profile_list(&ethernet_profiles);
584                 return CONNECTION_ERROR_OPERATION_FAILED;
585         }
586
587         __libnet_clear_profile_list(&ethernet_profiles);
588
589         return CONNECTION_ERROR_NONE;
590 }
591
592 int _connection_libnet_get_ethernet_cable_state(connection_handle_s *conn_handle,
593                         connection_ethernet_cable_state_e* state)
594 {
595         int rv = 0;
596         int status = 0;
597
598         rv = net_get_ethernet_cable_state(conn_handle->network_info_handle, &status);
599         if (rv == NET_ERR_ACCESS_DENIED) {
600                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied");
601                 return CONNECTION_ERROR_PERMISSION_DENIED;
602         } else if (rv != NET_ERR_NONE) {
603                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get ethernet cable state[%d]", rv);
604                 return CONNECTION_ERROR_OPERATION_FAILED;
605         }
606
607         if (status == 1)
608                 *state = CONNECTION_ETHERNET_CABLE_ATTACHED;
609         else
610                 *state = CONNECTION_ETHERNET_CABLE_DETACHED;
611         return CONNECTION_ERROR_NONE;
612 }
613 //LCOV_EXCL_STOP
614
615 int _connection_libnet_get_bluetooth_state(connection_handle_s *conn_handle, connection_bt_state_e *state)
616 {
617         int i = 0;
618         int rv = 0;
619         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
620         rv = net_get_profile_list(conn_handle->network_info_handle,
621                         NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles,
622                         &bluetooth_profiles.count);
623         if (rv == NET_ERR_ACCESS_DENIED) {
624                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
625                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
626         }
627
628         if (bluetooth_profiles.count == 0) {
629                 *state = CONNECTION_BT_STATE_DEACTIVATED;
630                 return CONNECTION_ERROR_NONE;
631         }
632
633         //LCOV_EXCL_START
634         for (; i < bluetooth_profiles.count; i++) {
635                 switch (bluetooth_profiles.profiles[i].ProfileState) {
636                 case NET_STATE_TYPE_ONLINE:
637                 case NET_STATE_TYPE_READY:
638                         *state = CONNECTION_BT_STATE_CONNECTED;
639                         goto done;
640                 case NET_STATE_TYPE_IDLE:
641                 case NET_STATE_TYPE_FAILURE:
642                 case NET_STATE_TYPE_ASSOCIATION:
643                 case NET_STATE_TYPE_CONFIGURATION:
644                 case NET_STATE_TYPE_DISCONNECT:
645                         *state = CONNECTION_BT_STATE_DISCONNECTED;
646                         break;
647                 default:
648                         __libnet_clear_profile_list(&bluetooth_profiles);
649                         return CONNECTION_ERROR_OPERATION_FAILED;
650                 }
651         }
652         //LCOV_EXCL_STOP
653
654 done:
655         __libnet_clear_profile_list(&bluetooth_profiles);
656
657         return CONNECTION_ERROR_NONE;
658 }
659
660 int _connection_libnet_get_profile_iterator(connection_handle_s *conn_handle,
661                         connection_iterator_type_e type, connection_profile_iterator_h* profile_iter_h)
662 {
663         int count = 0;
664         int rv1, rv2, rv3, rv4, rv5;
665         net_profile_info_t *profiles = NULL;
666
667         struct _profile_list_s wifi_profiles = {0, 0, NULL};
668         struct _profile_list_s cellular_profiles = {0, 0, NULL};
669         struct _profile_list_s ethernet_profiles = {0, 0, NULL};
670         struct _profile_list_s bluetooth_profiles = {0, 0, NULL};
671         struct _profile_list_s mesh_profiles = {0, 0, NULL};
672
673         __libnet_clear_profile_list(&profile_iterator);
674
675         rv1 = net_get_profile_list(conn_handle->network_info_handle,
676                 NET_DEVICE_WIFI, &wifi_profiles.profiles, &wifi_profiles.count);
677         if (rv1 == NET_ERR_ACCESS_DENIED) {
678                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
679                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
680         } else if (rv1 != NET_ERR_NO_SERVICE && rv1 != NET_ERR_NONE)
681                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
682
683         CONNECTION_LOG(CONNECTION_INFO, "Wi-Fi profile count: %d", wifi_profiles.count);
684
685         rv2 = net_get_profile_list(conn_handle->network_info_handle,
686                 NET_DEVICE_CELLULAR, &cellular_profiles.profiles, &cellular_profiles.count);
687         if (rv2 == NET_ERR_ACCESS_DENIED) {
688                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
689                 __libnet_clear_profile_list(&wifi_profiles);
690                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
691         } else if (rv2 != NET_ERR_NO_SERVICE && rv2 != NET_ERR_NONE) {
692                 __libnet_clear_profile_list(&wifi_profiles);
693                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
694         }
695         CONNECTION_LOG(CONNECTION_INFO, "Cellular profile count: %d", cellular_profiles.count);
696
697         rv3 = net_get_profile_list(conn_handle->network_info_handle,
698                 NET_DEVICE_ETHERNET, &ethernet_profiles.profiles, &ethernet_profiles.count);
699         if (rv3 == NET_ERR_ACCESS_DENIED) {
700                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
701                 __libnet_clear_profile_list(&wifi_profiles);
702                 __libnet_clear_profile_list(&cellular_profiles);
703                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
704         } else if (rv3 != NET_ERR_NO_SERVICE && rv3 != NET_ERR_NONE) {
705                 __libnet_clear_profile_list(&wifi_profiles);
706                 __libnet_clear_profile_list(&cellular_profiles);
707                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
708         }
709         CONNECTION_LOG(CONNECTION_INFO, "Ethernet profile count : %d", ethernet_profiles.count);
710
711         rv4 = net_get_profile_list(conn_handle->network_info_handle,
712                 NET_DEVICE_BLUETOOTH, &bluetooth_profiles.profiles, &bluetooth_profiles.count);
713         if (rv4 == NET_ERR_ACCESS_DENIED) {
714                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
715                 __libnet_clear_profile_list(&wifi_profiles);
716                 __libnet_clear_profile_list(&cellular_profiles);
717                 __libnet_clear_profile_list(&ethernet_profiles);
718                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
719         } else if (rv4 != NET_ERR_NO_SERVICE && rv4 != NET_ERR_NONE) {
720                 __libnet_clear_profile_list(&wifi_profiles);
721                 __libnet_clear_profile_list(&cellular_profiles);
722                 __libnet_clear_profile_list(&ethernet_profiles);
723                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
724         }
725         CONNECTION_LOG(CONNECTION_INFO, "Bluetooth profile count : %d", bluetooth_profiles.count);
726
727         rv5 = net_get_profile_list(conn_handle->network_info_handle,
728                 NET_DEVICE_MESH, &mesh_profiles.profiles, &mesh_profiles.count);
729         if (rv5 == NET_ERR_ACCESS_DENIED) {
730                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
731                 __libnet_clear_profile_list(&wifi_profiles);
732                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
733         } else if (rv5 != NET_ERR_NO_SERVICE && rv5 != NET_ERR_NONE) {
734                 __libnet_clear_profile_list(&wifi_profiles);
735                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
736         }
737
738         CONNECTION_LOG(CONNECTION_INFO, "Mesh profile count: %d", mesh_profiles.count);
739         *profile_iter_h = &profile_iterator;
740
741         switch (type) {
742         case CONNECTION_ITERATOR_TYPE_REGISTERED:
743                 count = wifi_profiles.count + cellular_profiles.count + ethernet_profiles.count + bluetooth_profiles.count + mesh_profiles.count;
744                 CONNECTION_LOG(CONNECTION_INFO, "Total profile count : %d", count);
745                 if (count == 0)
746                         return CONNECTION_ERROR_NONE;
747
748                 profiles = g_try_new0(net_profile_info_t, count);
749                 if (profiles == NULL) {
750                         __libnet_clear_profile_list(&wifi_profiles);
751                         __libnet_clear_profile_list(&cellular_profiles);
752                         __libnet_clear_profile_list(&ethernet_profiles);
753                         __libnet_clear_profile_list(&bluetooth_profiles);
754                         __libnet_clear_profile_list(&mesh_profiles);
755                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
756                 }
757
758                 profile_iterator.profiles = profiles;
759
760                 if (wifi_profiles.count > 0) {
761                         memcpy(profiles, wifi_profiles.profiles,
762                                         sizeof(net_profile_info_t) * wifi_profiles.count);
763                         profiles += wifi_profiles.count;
764                 }
765
766                 if (cellular_profiles.count > 0) {
767                         memcpy(profiles, cellular_profiles.profiles,
768                                         sizeof(net_profile_info_t) * cellular_profiles.count);
769                         profiles += cellular_profiles.count;
770                 }
771
772                 if (ethernet_profiles.count > 0) {
773                         memcpy(profiles, ethernet_profiles.profiles,
774                                         sizeof(net_profile_info_t) * ethernet_profiles.count);
775                         profiles += ethernet_profiles.count;
776                 }
777
778                 if (mesh_profiles.count > 0) {
779                         memcpy(profiles, mesh_profiles.profiles,
780                                         sizeof(net_profile_info_t) * mesh_profiles.count);
781                         profiles += mesh_profiles.count;
782                 }
783
784                 if (bluetooth_profiles.count > 0)
785                         memcpy(profiles, bluetooth_profiles.profiles,
786                                         sizeof(net_profile_info_t) * bluetooth_profiles.count);
787
788                 break;
789         case CONNECTION_ITERATOR_TYPE_CONNECTED:
790                 count = __libnet_get_connected_count(&wifi_profiles);
791                 count += __libnet_get_connected_count(&cellular_profiles);
792                 count += __libnet_get_connected_count(&ethernet_profiles);
793                 count += __libnet_get_connected_count(&bluetooth_profiles);
794                 count += __libnet_get_connected_count(&mesh_profiles);
795                 CONNECTION_LOG(CONNECTION_INFO, "Total connected profile count : %d", count);
796                 if (count == 0)
797                         return CONNECTION_ERROR_NONE;
798
799                 profiles = g_try_new0(net_profile_info_t, count);
800                 if (profiles == NULL) {
801                         __libnet_clear_profile_list(&wifi_profiles);
802                         __libnet_clear_profile_list(&cellular_profiles);
803                         __libnet_clear_profile_list(&ethernet_profiles);
804                         __libnet_clear_profile_list(&bluetooth_profiles);
805                         __libnet_clear_profile_list(&mesh_profiles);
806                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
807                 }
808
809                 profile_iterator.profiles = profiles;
810
811                 if (wifi_profiles.count > 0)
812                         __libnet_copy_connected_profile(&profiles, &wifi_profiles);
813
814                 if (cellular_profiles.count > 0)
815                         __libnet_copy_connected_profile(&profiles, &cellular_profiles);
816
817                 if (ethernet_profiles.count > 0)
818                         __libnet_copy_connected_profile(&profiles, &ethernet_profiles);
819
820                 if (bluetooth_profiles.count > 0)
821                         __libnet_copy_connected_profile(&profiles, &bluetooth_profiles);
822
823                 if (mesh_profiles.count > 0)
824                         __libnet_copy_connected_profile(&profiles, &mesh_profiles);
825
826                 break;
827         case CONNECTION_ITERATOR_TYPE_DEFAULT:
828                 count = __libnet_get_default_count(&cellular_profiles);
829                 CONNECTION_LOG(CONNECTION_INFO, "Total default profile count : %d", count); //LCOV_EXCL_LINE
830                 if (count == 0)
831                         return CONNECTION_ERROR_NONE;
832
833                 profiles = g_try_new0(net_profile_info_t, count);
834                 if (profiles == NULL) {
835                         __libnet_clear_profile_list(&wifi_profiles);
836                         __libnet_clear_profile_list(&cellular_profiles);
837                         __libnet_clear_profile_list(&ethernet_profiles);
838                         __libnet_clear_profile_list(&bluetooth_profiles);
839                         __libnet_clear_profile_list(&mesh_profiles);
840                         return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
841                 }
842
843                 profile_iterator.profiles = profiles;
844
845                 if (cellular_profiles.count > 0)
846                         __libnet_copy_default_profile(&profiles, &cellular_profiles);
847                 break;
848         }
849
850         __libnet_clear_profile_list(&wifi_profiles);
851         __libnet_clear_profile_list(&cellular_profiles);
852         __libnet_clear_profile_list(&ethernet_profiles);
853         __libnet_clear_profile_list(&bluetooth_profiles);
854         __libnet_clear_profile_list(&mesh_profiles);
855
856         profile_iterator.count = count;
857
858         return CONNECTION_ERROR_NONE;
859 }
860
861 int _connection_libnet_get_iterator_next(connection_profile_iterator_h profile_iter_h, connection_profile_h *profile)
862 {
863         if (profile_iter_h != &profile_iterator)
864                 return CONNECTION_ERROR_INVALID_PARAMETER;
865
866         if (profile_iterator.count <= profile_iterator.next)
867                 return CONNECTION_ERROR_ITERATOR_END;
868
869         *profile = &profile_iterator.profiles[profile_iterator.next];
870         profile_iterator.next++;
871
872         return CONNECTION_ERROR_NONE;
873 }
874
875 bool _connection_libnet_iterator_has_next(connection_profile_iterator_h profile_iter_h)
876 {
877         if (profile_iter_h != &profile_iterator)
878                 return false;
879
880         if (profile_iterator.count <= profile_iterator.next)
881                 return false;
882
883         return true;
884 }
885
886 int _connection_libnet_destroy_iterator(connection_profile_iterator_h profile_iter_h)
887 {
888         if (profile_iter_h != &profile_iterator)
889                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
890
891         __libnet_clear_profile_list(&profile_iterator);
892
893         return CONNECTION_ERROR_NONE;
894 }
895
896 int _connection_libnet_get_current_profile(connection_handle_s *conn_handle,
897                         connection_profile_h *profile)
898 {
899         net_profile_info_t active_profile;
900         int rv;
901
902         rv = net_get_active_net_info(conn_handle->network_info_handle, &active_profile);
903         if (rv == NET_ERR_NO_SERVICE)
904                 return CONNECTION_ERROR_NO_CONNECTION; //LCOV_EXCL_LINE
905         else if (rv == NET_ERR_ACCESS_DENIED) {
906                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
907                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
908         } else if (rv != NET_ERR_NONE)
909                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
910
911         *profile = g_try_malloc0(sizeof(net_profile_info_t));
912         if (*profile == NULL)
913                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
914
915         memcpy(*profile, &active_profile, sizeof(net_profile_info_t));
916         prof_handle_list = g_slist_append(prof_handle_list, *profile);
917
918         return CONNECTION_ERROR_NONE;
919 }
920
921 int _connection_libnet_reset_profile(connection_handle_s *conn_handle,
922                 connection_reset_option_e type, connection_cellular_subscriber_id_e id)
923 {
924         int rv;
925
926         rv = net_reset_profile(conn_handle->network_info_handle, type, id);
927         if (rv == NET_ERR_ACCESS_DENIED)
928                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
929         else if (rv != NET_ERR_NONE)
930                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
931
932         return CONNECTION_ERROR_NONE;
933 }
934
935 int _connection_libnet_open_profile(connection_handle_s *conn_handle,
936                         connection_profile_h profile)
937 {
938         int rv;
939
940         if (!(_connection_libnet_check_profile_validity(profile))) {
941                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
942                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
943         }
944
945         net_profile_info_t *profile_info = profile;
946
947         if (profile_info->profile_type == NET_DEVICE_MESH)
948                 rv = net_open_mesh_connection_with_profile(conn_handle->network_info_handle,
949                                 profile_info->ProfileName);
950         else
951                 rv = net_open_connection_with_profile(conn_handle->network_info_handle,
952                                 profile_info->ProfileName);
953
954         if (rv == NET_ERR_ACCESS_DENIED)
955                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
956         else if (rv != NET_ERR_NONE)
957                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
958
959         return CONNECTION_ERROR_NONE;
960 }
961
962 int _connection_libnet_get_cellular_service_profile(connection_handle_s *conn_handle,
963                 connection_cellular_service_type_e type, connection_profile_h *profile)
964 {
965         int i = 0, j = 0;
966         int rv = NET_ERR_NONE;
967 #if defined TIZEN_DUALSIM_ENABLE
968         int default_subscriber_id = 0;
969         char subscriber_id[3];
970 #endif
971
972         struct _profile_list_s cellular_profiles = { 0, 0, NULL };
973         net_service_type_t service_type = _connection_profile_convert_to_libnet_cellular_service_type(type);
974
975         rv = net_get_profile_list(conn_handle->network_info_handle,
976                         NET_DEVICE_CELLULAR, &cellular_profiles.profiles,
977                         &cellular_profiles.count);
978         if (rv == NET_ERR_ACCESS_DENIED) {
979                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
980                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
981         } else if (rv != NET_ERR_NONE) {
982                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get profile list (%d)", rv); //LCOV_EXCL_LINE
983                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
984         }
985
986 #if defined TIZEN_DUALSIM_ENABLE
987         if (vconf_get_int(VCONF_TELEPHONY_DEFAULT_DATA_SERVICE,
988                                                 &default_subscriber_id) != 0) {
989                 CONNECTION_LOG(CONNECTION_ERROR,
990                                                 "Failed to get VCONF_TELEPHONY_DEFAULT_DATA_SERVICE");
991                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
992                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
993         }
994
995         g_snprintf(subscriber_id, sizeof(subscriber_id), "%d", default_subscriber_id);
996 #endif
997
998         for (i = 0; i < cellular_profiles.count; i++)
999                 if (cellular_profiles.profiles[i].ProfileInfo.Pdp.ServiceType == service_type)
1000 #if defined TIZEN_DUALSIM_ENABLE
1001                         if (g_str_has_suffix(
1002                                         cellular_profiles.profiles[i].ProfileInfo.Pdp.PSModemPath,
1003                                         subscriber_id) == TRUE)
1004 #endif
1005                                 break;
1006
1007         if (i >= cellular_profiles.count) {
1008                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1009                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1010         }
1011
1012         *profile = g_try_malloc0(sizeof(net_profile_info_t));
1013         if (*profile == NULL) {
1014                 __libnet_clear_profile_list(&cellular_profiles); //LCOV_EXCL_LINE
1015                 return CONNECTION_ERROR_OUT_OF_MEMORY; //LCOV_EXCL_LINE
1016         }
1017
1018         memcpy(*profile, &cellular_profiles.profiles[i], sizeof(net_profile_info_t));
1019
1020         if (cellular_profiles.profiles[i].ProfileInfo.Pdp.DefaultConn)
1021                 goto done;
1022
1023         //LCOV_EXCL_START
1024         if (type != CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET &&
1025             type != CONNECTION_CELLULAR_SERVICE_TYPE_PREPAID_INTERNET)
1026                 goto done;
1027
1028         for (j = 0; j < cellular_profiles.count; j++) {
1029                 if (i == j)
1030                         continue;
1031
1032                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.ServiceType != service_type)
1033                         continue;
1034
1035                 if (cellular_profiles.profiles[j].ProfileInfo.Pdp.DefaultConn) {
1036                         memcpy(*profile, &cellular_profiles.profiles[j], sizeof(net_profile_info_t));
1037                         goto done;
1038                 }
1039         }
1040         //LCOV_EXCL_STOP
1041
1042 done:
1043         __libnet_clear_profile_list(&cellular_profiles);
1044         prof_handle_list = g_slist_append(prof_handle_list, *profile);
1045
1046         return CONNECTION_ERROR_NONE;
1047 }
1048
1049 int _connection_libnet_set_cellular_service_profile_sync(connection_handle_s *conn_handle,
1050                         connection_cellular_service_type_e type, connection_profile_h profile)
1051 {
1052         int rv;
1053
1054         if (!(_connection_libnet_check_profile_validity(profile))) {
1055                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1056                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1057         }
1058
1059         net_profile_info_t *profile_info = profile;
1060         connection_cellular_service_type_e service_type;
1061
1062         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1063
1064         if (service_type != type)
1065                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1066
1067         rv = net_set_default_cellular_service_profile(conn_handle->network_info_handle,
1068                                 profile_info->ProfileName);
1069         if (rv == NET_ERR_ACCESS_DENIED) {
1070                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1071                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1072         } else if (rv != NET_ERR_NONE)
1073                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1074
1075         return CONNECTION_ERROR_NONE;
1076 }
1077
1078 int _connection_libnet_set_cellular_service_profile_async(connection_handle_s *conn_handle,
1079                         connection_cellular_service_type_e type, connection_profile_h profile)
1080 {
1081         int rv;
1082
1083         if (!(_connection_libnet_check_profile_validity(profile))) {
1084                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1085                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1086         }
1087
1088         net_profile_info_t *profile_info = profile;
1089         connection_cellular_service_type_e service_type;
1090
1091         service_type = _profile_convert_to_connection_cellular_service_type(profile_info->ProfileInfo.Pdp.ServiceType);
1092
1093         if (service_type != type)
1094                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1095
1096         rv = net_set_default_cellular_service_profile_async(conn_handle->network_info_handle,
1097                                 profile_info->ProfileName);
1098         if (rv == NET_ERR_ACCESS_DENIED) {
1099                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1100         } else if (rv != NET_ERR_NONE)
1101                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1102
1103         return CONNECTION_ERROR_NONE;
1104 }
1105
1106 int _connection_libnet_close_profile(connection_handle_s *conn_handle, connection_profile_h profile)
1107 {
1108         int rv;
1109
1110         if (!(_connection_libnet_check_profile_validity(profile))) {
1111                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid parameter"); //LCOV_EXCL_LINE
1112                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1113         }
1114
1115         net_profile_info_t *profile_info = profile;
1116
1117         if (profile_info->profile_type == NET_DEVICE_MESH)
1118                 rv = net_close_mesh_connection(conn_handle->network_info_handle, profile_info->ProfileName);
1119         else
1120                 rv = net_close_connection(conn_handle->network_info_handle, profile_info->ProfileName);
1121
1122         if (rv == NET_ERR_ACCESS_DENIED)
1123                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1124         else if (rv != NET_ERR_NONE)
1125                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1126
1127         return CONNECTION_ERROR_NONE;
1128 }
1129
1130 int _connection_libnet_add_route(connection_handle_s *conn_handle,
1131                         const char *interface_name, const char *host_address)
1132 {
1133         int rv;
1134         char *endstr = NULL;
1135         int address_family = 0;
1136
1137         address_family = AF_INET;
1138
1139         endstr = strrchr(host_address, '.');
1140         if (endstr == NULL ||
1141                         strcmp(endstr, ".0") == 0 ||
1142                         strncmp(host_address, "0.", 2) == 0 ||
1143                         strstr(host_address, "255") != NULL) {
1144                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1145                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1146         }
1147
1148         rv = net_add_route(conn_handle->network_info_handle,
1149                                 host_address, interface_name, address_family);
1150         if (rv == NET_ERR_ACCESS_DENIED) {
1151                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1152                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1153         } else if (rv != NET_ERR_NONE)
1154                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1155
1156         return CONNECTION_ERROR_NONE;
1157 }
1158
1159 int _connection_libnet_remove_route(connection_handle_s *conn_handle,
1160                         const char *interface_name, const char *host_address)
1161 {
1162         int rv;
1163         char *endstr = strrchr(host_address, '.');
1164         int address_family = 0;
1165
1166         address_family = AF_INET;
1167
1168         endstr = strrchr(host_address, '.');
1169         if (endstr == NULL ||
1170                 strcmp(endstr, ".0") == 0 ||
1171                 strncmp(host_address, "0.", 2) == 0 ||
1172                 strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1173                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1174                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1175         }
1176
1177         rv = net_remove_route(conn_handle->network_info_handle,
1178                                 host_address, interface_name, address_family);
1179         if (rv == NET_ERR_ACCESS_DENIED) {
1180                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1181                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1182         } else if (rv != NET_ERR_NONE)
1183                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1184
1185         return CONNECTION_ERROR_NONE;
1186 }
1187
1188 int _connection_libnet_add_route_ipv6(connection_handle_s *conn_handle,
1189                         const char *interface_name, const char *host_address, const char *gateway)
1190 {
1191         int rv;
1192         int address_family = 0;
1193
1194         address_family = AF_INET6;
1195
1196         if (strncmp(host_address, "fe80:", 5) == 0 ||
1197                 strncmp(host_address, "ff00:", 5) == 0 ||
1198                 strncmp(host_address, "::", 2) == 0) {
1199                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1200                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1201         }
1202
1203         rv = net_add_route_ipv6(conn_handle->network_info_handle,
1204                                 host_address, interface_name, address_family, gateway);
1205         if (rv == NET_ERR_ACCESS_DENIED) {
1206                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1207                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1208         } else if (rv != NET_ERR_NONE)
1209                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1210
1211         return CONNECTION_ERROR_NONE;
1212 }
1213
1214 int _connection_libnet_remove_route_ipv6(connection_handle_s *conn_handle,
1215                         const char *interface_name, const char *host_address, const char *gateway)
1216 {
1217         int rv;
1218         int address_family = 0;
1219
1220         address_family = AF_INET6;
1221
1222         if (strncmp(host_address, "fe80:", 5) == 0 ||
1223                 strncmp(host_address, "ff00:", 5) == 0 ||
1224                 strncmp(host_address, "::", 2) == 0) {
1225                 CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1226                 return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1227         }
1228
1229         rv = net_remove_route_ipv6(conn_handle->network_info_handle,
1230                                 host_address, interface_name, address_family, gateway);
1231         if (rv == NET_ERR_ACCESS_DENIED) {
1232                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1233                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1234         } else if (rv != NET_ERR_NONE)
1235                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1236
1237         return CONNECTION_ERROR_NONE;
1238 }
1239
1240 int _connection_libnet_add_route_entry(connection_handle_s *conn_handle,
1241                 connection_address_family_e address_family, const char *interface_name,
1242                 const char *host_address, const char *gateway)
1243 {
1244         int rv;
1245         char *endstr = NULL;
1246         int address_family_type = 0;
1247
1248         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1249                 address_family_type = AF_INET;
1250         else
1251                 address_family_type = AF_INET6;
1252
1253         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1254
1255                 endstr = strrchr(host_address, '.');
1256                 if (endstr == NULL ||
1257                                 strcmp(endstr, ".0") == 0 ||
1258                                 strncmp(host_address, "0.", 2) == 0 ||
1259                                 strstr(host_address, "255") != NULL) {
1260                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1261                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1262                 }
1263
1264                 rv = net_add_route_entry(conn_handle->network_info_handle,
1265                                 host_address, interface_name, address_family_type, gateway);
1266                 if (rv == NET_ERR_ACCESS_DENIED) {
1267                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1268                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1269                 } else if (rv != NET_ERR_NONE)
1270                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1271
1272         } else {
1273
1274                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1275                         strncmp(host_address, "ff00:", 5) == 0 ||
1276                         strncmp(host_address, "::", 2) == 0) {
1277                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1278                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1279                 }
1280
1281                 rv = net_add_route_ipv6(conn_handle->network_info_handle,
1282                                 host_address, interface_name, address_family_type, gateway);
1283                 if (rv == NET_ERR_ACCESS_DENIED) {
1284                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1285                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1286                 } else if (rv != NET_ERR_NONE)
1287                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1288         }
1289
1290         return CONNECTION_ERROR_NONE;
1291 }
1292
1293 int _connection_libnet_remove_route_entry(connection_handle_s *conn_handle,
1294                 connection_address_family_e address_family, const char *interface_name,
1295                 const char *host_address, const char *gateway)
1296 {
1297         int rv;
1298         char *endstr = strrchr(host_address, '.');
1299         int address_family_type = 0;
1300
1301         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4)
1302                 address_family_type = AF_INET;
1303         else
1304                 address_family_type = AF_INET6;
1305
1306         if (address_family == CONNECTION_ADDRESS_FAMILY_IPV4) {
1307                 endstr = strrchr(host_address, '.');
1308                 if (endstr == NULL ||
1309                         strcmp(endstr, ".0") == 0 ||
1310                         strncmp(host_address, "0.", 2) == 0 ||
1311                         strstr(host_address, ".0.") != NULL || strstr(host_address, "255") != NULL) {
1312                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed"); //LCOV_EXCL_LINE
1313                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1314                 }
1315
1316                 rv = net_remove_route_entry(conn_handle->network_info_handle, host_address,
1317                                         interface_name, address_family_type, gateway);
1318                 if (rv == NET_ERR_ACCESS_DENIED) {
1319                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1320                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1321                 } else if (rv != NET_ERR_NONE)
1322                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1323
1324         } else {
1325
1326                 if (strncmp(host_address, "fe80:", 5) == 0 ||
1327                         strncmp(host_address, "ff00:", 5) == 0 ||
1328                         strncmp(host_address, "::", 2) == 0) {
1329                         CONNECTION_LOG(CONNECTION_ERROR, "Invalid IP address Passed\n"); //LCOV_EXCL_LINE
1330                         return CONNECTION_ERROR_INVALID_PARAMETER; //LCOV_EXCL_LINE
1331                 }
1332
1333                 rv = net_remove_route_ipv6(conn_handle->network_info_handle, host_address,
1334                                         interface_name, address_family_type, gateway);
1335                 if (rv == NET_ERR_ACCESS_DENIED) {
1336                         CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1337                         return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1338                 } else if (rv != NET_ERR_NONE)
1339                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1340         }
1341
1342         return CONNECTION_ERROR_NONE;
1343 }
1344
1345 void _connection_libnet_add_to_profile_list(connection_profile_h profile)
1346 {
1347         prof_handle_list = g_slist_append(prof_handle_list, profile);
1348 }
1349
1350 void _connection_libnet_remove_from_profile_list(connection_profile_h profile)
1351 {
1352         prof_handle_list = g_slist_remove(prof_handle_list, profile);
1353         g_free(profile);
1354 }
1355
1356 bool _connection_libnet_add_to_profile_cb_list(connection_profile_h profile,
1357                 connection_profile_state_changed_cb callback, void *user_data)
1358 {
1359         net_profile_info_t *profile_info = profile;
1360         char *profile_name = g_strdup(profile_info->ProfileName);
1361
1362         struct _profile_cb_s *profile_cb_info = g_try_malloc0(sizeof(struct _profile_cb_s));
1363         if (profile_cb_info == NULL) {
1364                 g_free(profile_name); //LCOV_EXCL_LINE
1365                 return false; //LCOV_EXCL_LINE
1366         }
1367
1368         profile_cb_info->callback = callback;
1369         profile_cb_info->user_data = user_data;
1370         profile_cb_info->state = _profile_convert_to_cp_state(profile_info->ProfileState);
1371
1372         g_hash_table_replace(profile_cb_table, profile_name, profile_cb_info);
1373
1374         return true;
1375 }
1376
1377 bool _connection_libnet_remove_from_profile_cb_list(connection_profile_h profile)
1378 {
1379         net_profile_info_t *profile_info = profile;
1380
1381         if (g_hash_table_remove(profile_cb_table, profile_info->ProfileName) == TRUE)
1382                 return true;
1383
1384         return false; //LCOV_EXCL_LINE
1385 }
1386
1387 int _connection_libnet_set_statistics(connection_handle_s *conn_handle,
1388                         net_device_t device_type, net_statistics_type_e statistics_type)
1389 {
1390         int rv;
1391         rv = net_set_statistics(conn_handle->network_info_handle,
1392                                 device_type, statistics_type);
1393         if (rv == NET_ERR_ACCESS_DENIED) {
1394                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1395                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1396         } else if (rv != NET_ERR_NONE)
1397                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1398
1399         return CONNECTION_ERROR_NONE;
1400 }
1401
1402 int _connection_libnet_get_statistics(connection_handle_s *conn_handle,
1403                         net_statistics_type_e statistics_type, unsigned long long *size)
1404 {
1405         int rv;
1406         rv = net_get_statistics(conn_handle->network_info_handle,
1407                                 NET_DEVICE_WIFI, statistics_type, size);
1408         if (rv == NET_ERR_ACCESS_DENIED) {
1409                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1410                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1411         } else if (rv != NET_ERR_NONE)
1412                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1413
1414         return CONNECTION_ERROR_NONE;
1415 }
1416
1417 int _connection_libnet_set_cellular_subscriber_id(connection_profile_h profile,
1418                 connection_cellular_subscriber_id_e sim_id)
1419 {
1420         char *modem_path = NULL;
1421         net_profile_info_t *profile_info = (net_profile_info_t *)profile;
1422
1423         if (net_get_cellular_modem_object_path(&modem_path, sim_id) != NET_ERR_NONE) {
1424                 CONNECTION_LOG(CONNECTION_ERROR, "Failed to get subscriber[%d]", sim_id); //LCOV_EXCL_LINE
1425                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1426         }
1427
1428         if (!modem_path) {
1429                 CONNECTION_LOG(CONNECTION_ERROR, "NULL modem object path"); //LCOV_EXCL_LINE
1430                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1431         }
1432
1433         g_strlcpy(profile_info->ProfileInfo.Pdp.PSModemPath, modem_path,
1434                                 NET_PROFILE_NAME_LEN_MAX);
1435         g_free(modem_path);
1436
1437         return CONNECTION_ERROR_NONE;
1438 }
1439
1440 int _connection_libnet_check_get_privilege(void)
1441 {
1442         int rv;
1443
1444         rv = net_check_get_privilege();
1445         if (rv == NET_ERR_ACCESS_DENIED) {
1446                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1447                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1448         } else if (rv != NET_ERR_NONE)
1449                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1450
1451         return CONNECTION_ERROR_NONE;
1452 }
1453
1454 int _connection_libnet_check_profile_privilege(void)
1455 {
1456         int rv;
1457
1458         rv = net_check_profile_privilege();
1459         if (rv == NET_ERR_ACCESS_DENIED) {
1460                 CONNECTION_LOG(CONNECTION_ERROR, "Access denied"); //LCOV_EXCL_LINE
1461                 return CONNECTION_ERROR_PERMISSION_DENIED; //LCOV_EXCL_LINE
1462         } else if (rv != NET_ERR_NONE)
1463                 return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1464
1465         return CONNECTION_ERROR_NONE;
1466 }
1467
1468 bool __libnet_check_feature_supported(const char *key, connection_supported_feature_e feature)
1469 {
1470         if (!connection_is_feature_checked[feature]) {
1471                 if (system_info_get_platform_bool(key, &connection_feature_supported[feature]) < 0) {
1472                         CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature getting from System Info"); //LCOV_EXCL_LINE
1473                         set_last_result(CONNECTION_ERROR_OPERATION_FAILED); //LCOV_EXCL_LINE
1474                         return CONNECTION_ERROR_OPERATION_FAILED; //LCOV_EXCL_LINE
1475                 }
1476                 connection_is_feature_checked[feature] = true;
1477         }
1478         return connection_feature_supported[feature];
1479 }
1480
1481 int _connection_check_feature_supported(const char *feature_name, ...)
1482 {
1483         va_list list;
1484         const char *key;
1485         bool value = false;
1486         bool feature_supported = false;
1487
1488         va_start(list, feature_name);
1489         key = feature_name;
1490         while (1) {
1491                 if (strcmp(key, TELEPHONY_FEATURE) == 0)
1492                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TELEPHONY);
1493                 if (strcmp(key, WIFI_FEATURE) == 0)
1494                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_WIFI);
1495                 if (strcmp(key, TETHERING_BLUETOOTH_FEATURE) == 0)
1496                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_TETHERING_BLUETOOTH);
1497                 if (strcmp(key, ETHERNET_FEATURE) == 0)
1498                         value = __libnet_check_feature_supported(key, CONNECTION_SUPPORTED_FEATURE_ETHERNET);
1499
1500                 feature_supported |= value;
1501                 key = va_arg(list, const char *);
1502                 if (!key) break;
1503         }
1504         if (!feature_supported) {
1505                 CONNECTION_LOG(CONNECTION_ERROR, "Error - Feature is not supported");
1506                 set_last_result(CONNECTION_ERROR_NOT_SUPPORTED);
1507                 va_end(list);
1508                 return CONNECTION_ERROR_NOT_SUPPORTED;
1509         }
1510
1511         va_end(list);
1512         set_last_result(CONNECTION_ERROR_NONE);
1513         return CONNECTION_ERROR_NONE;
1514 }
1515
1516 int _connection_libnet_start_tcpdump(connection_handle_s *conn_handle)
1517 {
1518         connection_error_e result = CONNECTION_ERROR_NONE;
1519         net_err_t ret = NET_ERR_NONE;
1520
1521         ret = net_start_tcpdump(conn_handle->network_info_handle);
1522         result = __libnet_convert_to_cp_error_type(ret);
1523
1524         return result;
1525 }
1526
1527 int _connection_libnet_stop_tcpdump(connection_handle_s *conn_handle)
1528 {
1529         connection_error_e result = CONNECTION_ERROR_NONE;
1530         net_err_t ret = NET_ERR_NONE;
1531
1532         ret = net_stop_tcpdump(conn_handle->network_info_handle);
1533         result = __libnet_convert_to_cp_error_type(ret);
1534
1535         return result;
1536 }
1537
1538 int _connection_libnet_get_tcpdump_state(connection_handle_s *conn_handle,
1539                         gboolean *tcpdump_state)
1540 {
1541         connection_error_e result = CONNECTION_ERROR_NONE;
1542         net_err_t ret = NET_ERR_NONE;
1543
1544         ret = net_get_tcpdump_state(conn_handle->network_info_handle, tcpdump_state);
1545         result = __libnet_convert_to_cp_error_type(ret);
1546
1547         return result;
1548 }
1549
1550 void _connection_lock(void)
1551 {
1552         pthread_mutex_lock(&g_conn_thread_mutex);
1553 }
1554
1555 void _connection_unlock(void)
1556 {
1557         pthread_mutex_unlock(&g_conn_thread_mutex);
1558 }