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