3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
23 #include <net_connection.h>
25 #include "mobileap_softap.h"
26 #include "mobileap_common.h"
27 #include "mobileap_network.h"
28 #include "mobileap_wifi.h"
29 #include "mobileap_bluetooth.h"
30 #include "mobileap_usb.h"
31 #include "mobileap_iptables.h"
37 } tethering_cellular_service_type_e;
40 connection_profile_h handle;
41 tethering_cellular_service_type_e svc_type;
42 } tethering_cellular_profile_s;
44 #define MH_PORT_FORWARD_CONF_FILEPATH "/tmp/mobileap_agent_port_forward_info"
45 #define MH_MAX_PORT_FORWARD_RULE_LEN 64 /* interface(10) protocol(10) ip(15):port(5) ip(15):port(5) */
46 #define MH_MAX_NO_OF_PORT_FORWARD_RULE 64
49 char *input_interface;
52 unsigned short org_dest_port;
54 unsigned short new_dest_port;
55 } port_forward_info_s;
57 static TetheringObject *obj = NULL;
58 static connection_h connection = NULL;
59 static tethering_cellular_profile_s c_prof = {NULL, __NO_SERVICE};
60 static guint net_timeout_id;
61 static connection_profile_h tethered_prof = NULL;
62 static GSList *port_forward_info = NULL;
65 static gboolean __try_to_open_tethering_profile(gpointer user_data);
67 static mobile_ap_error_code_e __get_conn_error(int conn_error)
69 mobile_ap_error_code_e err = MOBILE_AP_ERROR_NONE;
72 case CONNECTION_ERROR_NONE:
73 err = MOBILE_AP_ERROR_NONE;
76 case CONNECTION_ERROR_OUT_OF_MEMORY:
77 err = MOBILE_AP_ERROR_RESOURCE;
80 case CONNECTION_ERROR_INVALID_OPERATION:
81 err = MOBILE_AP_ERROR_INTERNAL;
84 case CONNECTION_ERROR_INVALID_PARAMETER:
85 err = MOBILE_AP_ERROR_INVALID_PARAM;
88 case CONNECTION_ERROR_ALREADY_EXISTS:
89 err = MOBILE_AP_ERROR_ALREADY_ENABLED;
92 case CONNECTION_ERROR_PERMISSION_DENIED:
93 err = MOBILE_AP_ERROR_PERMISSION_DENIED;
96 case CONNECTION_ERROR_DHCP_FAILED:
97 err = MOBILE_AP_ERROR_DHCP;
100 case CONNECTION_ERROR_NOW_IN_PROGRESS:
101 err = MOBILE_AP_ERROR_IN_PROGRESS;
105 ERR("Not defined error : %d\n", conn_error);
106 err = MOBILE_AP_ERROR_INTERNAL;
113 static gboolean __is_valid_ipv4_addr(const char *ip)
119 char tmp_ip[16] = {0, };
126 if (len > 15 /* 255.255.255.255 */ || len < 7 /* 0.0.0.0 */)
128 g_strlcpy(tmp_ip, ip, sizeof(tmp_ip));
130 for (i = 0; i <= len; i++) {
131 if (tmp_ip[i] == '.') {
138 if (addr < 0 || addr > 255)
141 } else if (tmp_ip[i] == '\0') {
145 if (addr < 0 || addr > 255)
148 } else if (tmp_ip[i] < '0' || tmp_ip[i] > '9')
158 static void __clear_port_forward_info(void)
162 port_forward_info_s *pf;
164 for (l = port_forward_info; l; ) {
165 pf = (port_forward_info_s *)l->data;
167 g_free(pf->new_dest_ip);
168 g_free(pf->org_dest_ip);
170 g_free(pf->input_interface);
176 port_forward_info = g_slist_delete_link(port_forward_info, temp_l);
182 static gboolean __read_port_forward_info(const char *conf_file)
184 if (conf_file == NULL) {
185 ERR("Invalid parameter\n");
192 char buf[MH_MAX_PORT_FORWARD_RULE_LEN];
193 port_forward_info_s *pf;
196 __clear_port_forward_info();
198 fp = fopen(conf_file, "r");
200 ERR("fopen is failed : %s\n", strerror(errno));
204 while (fgets(buf, sizeof(buf), fp)) {
207 char *saveptr1 = NULL;
208 char *saveptr2 = NULL;
210 char *input_interface;
215 if (no_of_rule++ >= MH_MAX_NO_OF_PORT_FORWARD_RULE) {
216 DBG("There are too many rules\n");
220 /* "Input interface" "Protocol" "Original destination IP:Port" "New destination IP:Port" */
221 /* pdp0 udp 10.90.50.38:23 192.168.43.10:23 */
223 input_interface = strtok_r(buf, " ", &saveptr1);
224 if (input_interface == NULL) {
225 SERR("Invalid rule : %s\n", buf);
229 proto = strtok_r(NULL, " ", &saveptr1);
231 SERR("Invalid rule : %s\n", buf);
235 for (i = 0; i < sizeof(dest_ip) / sizeof(char *); i++) {
236 token = strtok_r(NULL, " ", &saveptr1);
238 SERR("Invalid rule : %s\n", buf);
242 dest_ip[i] = strtok_r(token, ":", &saveptr2);
243 if (dest_ip[i] == NULL ||
244 !__is_valid_ipv4_addr(dest_ip[i])) {
245 SERR("Invalid rule : %s\n", buf);
249 dest_port[i] = strtok_r(NULL, ":", &saveptr2);
250 if (dest_port[i] == NULL) {
251 SERR("Invalid rule : %s\n", buf);
256 if (i < sizeof(dest_ip) / sizeof(char *))
259 pf = (port_forward_info_s *)malloc(sizeof(port_forward_info_s));
263 pf->input_interface = g_strdup(input_interface);
264 pf->proto = g_strdup(proto);
265 pf->org_dest_ip = g_strdup(dest_ip[0]);
266 pf->org_dest_port = (unsigned short)atoi(dest_port[0]);
267 pf->new_dest_ip = g_strdup(dest_ip[1]);
268 pf->new_dest_port = (unsigned short)atoi(dest_port[1]);
269 port_forward_info = g_slist_append(port_forward_info, pf);
271 SDBG("Port forward rule #%d : %s %s %s:%d %s:%d\n", no_of_rule,
272 pf->input_interface, pf->proto,
273 pf->org_dest_ip, pf->org_dest_port,
274 pf->new_dest_ip, pf->new_dest_port);
282 static gboolean __is_valid_port_forward_info(port_forward_info_s *pf)
287 if (!pf->input_interface || !pf->proto ||
288 !pf->org_dest_ip || !pf->new_dest_ip)
291 if (!strlen(pf->input_interface) || !strlen(pf->proto) ||
292 !strlen(pf->org_dest_ip) || !strlen(pf->new_dest_ip))
298 static void __print_cellular_profile(void)
302 char *home_url = NULL;
303 bool roaming = false;
304 connection_cellular_service_type_e service_type;
306 if (c_prof.handle == NULL)
309 ret = connection_profile_get_cellular_service_type(c_prof.handle, &service_type);
310 if (ret != CONNECTION_ERROR_NONE)
311 ERR("connection API fail: 0x%X\n", ret);
313 SDBG("Service type: %d\n", service_type);
315 ret = connection_profile_get_cellular_apn(c_prof.handle, &apn);
316 if (ret != CONNECTION_ERROR_NONE)
317 ERR("connection API fail: 0x%X\n", ret);
319 SDBG("APN: %s\n", apn);
323 ret = connection_profile_get_cellular_home_url(c_prof.handle, &home_url);
324 if (ret != CONNECTION_ERROR_NONE)
325 ERR("connection API fail: 0x%X\n", ret);
327 SDBG("Home url: %s\n", home_url);
331 ret = connection_profile_is_cellular_roaming(c_prof.handle, &roaming);
332 if (ret != CONNECTION_ERROR_NONE)
333 ERR("connection API fail: 0x%X\n", ret);
335 SDBG("Roaming: %d\n", roaming);
338 static void __handle_open_network_error(void)
340 int ret = MOBILE_AP_ERROR_NONE;
342 if (_mobileap_is_disabled()) {
346 ret = _disable_wifi_tethering(obj);
347 DBG("_disable_wifi_tethering returns %d\n", ret);
349 ret = _disable_bt_tethering(obj);
350 DBG("_disable_bt_tethering returns %d\n", ret);
352 ret = _disable_usb_tethering(obj);
353 DBG("_disable_usb_tethering returns %d\n", ret);
355 _emit_mobileap_dbus_signal(obj, E_SIGNAL_NET_CLOSED, NULL);
360 static gboolean __is_equal_profile(connection_profile_h a, connection_profile_h b)
366 ret = connection_profile_get_id(a, &a_id);
367 if (ret != CONNECTION_ERROR_NONE || a_id == NULL) {
368 ERR("connection_profile_get_id is failed [0x%X]\n", ret);
372 ret = connection_profile_get_id(b, &b_id);
373 if (ret != CONNECTION_ERROR_NONE || b_id == NULL) {
374 ERR("connection_profile_get_id is failed [0x%X]\n", ret);
379 ret = g_strcmp0(a_id, b_id);
383 return (ret == 0) ? TRUE : FALSE;
386 static gboolean __is_connected_profile(connection_profile_h profile)
388 if (profile == NULL) {
389 ERR("profile is NULL\n");
394 connection_profile_state_e pstat = CONNECTION_PROFILE_STATE_DISCONNECTED;
396 ret = connection_profile_get_state(profile, &pstat);
397 if (ret != CONNECTION_ERROR_NONE) {
398 ERR("connection_profile_get_state is failed: 0x%X\n", ret);
402 if (pstat != CONNECTION_PROFILE_STATE_CONNECTED) {
406 DBG("Profile is connected\n");
410 static void __connection_type_changed_cb(connection_type_e type, void *user_data)
412 DBG("Changed connection type is [%s]\n",
413 type == CONNECTION_TYPE_DISCONNECTED ? "DISCONNECTED" :
414 type == CONNECTION_TYPE_WIFI ? "Wi-Fi" :
415 type == CONNECTION_TYPE_CELLULAR ? "Cellular" :
416 type == CONNECTION_TYPE_ETHERNET ? "Ethernet" :
419 if (_mobileap_is_disabled()) {
420 DBG("Tethering is disabled\n");
424 if (_open_network() != MOBILE_AP_ERROR_NONE) {
425 ERR("_open_network() is failed\n");
426 __handle_open_network_error();
432 void __cellular_state_changed_cb(keynode_t *node, void *user_data)
435 ERR("Invalid parameter\n");
439 if (vconf_keynode_get_type(node) != VCONF_TYPE_INT) {
440 ERR("Invalid vconf key type\n");
446 connection_type_e net_type;
448 cellular_state = vconf_keynode_get_int(node);
449 SDBG("key = %s, value = %d(int)\n",
450 vconf_keynode_get_name(node), cellular_state);
452 if (_mobileap_is_disabled())
455 if (cellular_state != VCONFKEY_NETWORK_CELLULAR_ON)
458 ret = connection_get_type(connection, &net_type);
459 if (ret != CONNECTION_ERROR_NONE) {
460 ERR("connection_get_type is failed [0x%X]\n", ret);
464 if (net_type != CONNECTION_TYPE_DISCONNECTED &&
465 net_type != CONNECTION_TYPE_CELLULAR)
471 DBG("VCONFKEY_NETWORK_CELLULAR_ON\n");
472 if (_open_network() != MOBILE_AP_ERROR_NONE) {
473 ERR("_open_network() is failed\n");
474 __handle_open_network_error();
480 static void __profile_state_changed_cb(connection_profile_state_e state, void *user_data)
482 if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
483 ERR("There is no proper profile\n");
487 DBG("Tethering cellular profile is %s\n",
488 state == CONNECTION_PROFILE_STATE_DISCONNECTED ? "Disconnected" :
489 state == CONNECTION_PROFILE_STATE_ASSOCIATION ? "Associated" :
490 state == CONNECTION_PROFILE_STATE_CONFIGURATION ? "Configured" :
491 state == CONNECTION_PROFILE_STATE_CONNECTED ? "Connected" :
497 connection_profile_refresh(c_prof.handle);
499 if (_mobileap_is_disabled())
502 if (c_prof.svc_type != __TETHERING_ONLY)
506 if (!__is_equal_profile(tethered_prof, c_prof.handle))
508 connection_profile_refresh(tethered_prof);
511 if (state != CONNECTION_PROFILE_STATE_DISCONNECTED)
514 DBG("Cellular profile is disconnected\n");
517 ret = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state);
519 ERR("vconf_get_int is failed : %d\n", ret);
520 if (vconf_ignore_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
521 __cellular_state_changed_cb) < 0) {
522 ERR("vconf_ignore_key_changed is failed\n");
527 if (cellular_state != VCONFKEY_NETWORK_CELLULAR_ON)
530 if (_open_network() != MOBILE_AP_ERROR_NONE) {
531 ERR("_open_network() is failed\n");
532 __handle_open_network_error();
539 static void __update_tethering_cellular_profile(void)
542 connection_profile_h profile;
543 tethering_cellular_service_type_e svc_type;
545 ret = connection_get_default_cellular_service_profile(connection,
546 CONNECTION_CELLULAR_SERVICE_TYPE_TETHERING, &profile);
547 if (ret == CONNECTION_ERROR_NONE) {
548 svc_type = __TETHERING_ONLY;
551 DBG("There is no tethering profile\n");
553 ret = connection_get_default_cellular_service_profile(connection,
554 CONNECTION_CELLULAR_SERVICE_TYPE_INTERNET, &profile);
555 if (ret == CONNECTION_ERROR_NONE) {
556 svc_type = __INTERNET;
559 ERR("Getting default connection for internet is failed\n");
560 /* To-Do : Need to consider prepaid internet profile */
563 connection_profile_unset_state_changed_cb(c_prof.handle);
564 connection_profile_destroy(c_prof.handle);
565 c_prof.handle = NULL;
566 c_prof.svc_type = __NO_SERVICE;
571 if (c_prof.handle == NULL ||
572 !__is_equal_profile(c_prof.handle, profile)) {
574 DBG("Tethering cellular profile is updated\n");
575 connection_profile_unset_state_changed_cb(c_prof.handle);
576 connection_profile_destroy(c_prof.handle);
579 c_prof.handle = profile;
580 c_prof.svc_type = svc_type;
581 connection_profile_set_state_changed_cb(c_prof.handle,
582 __profile_state_changed_cb, NULL);
584 connection_profile_destroy(profile);
585 connection_profile_refresh(c_prof.handle);
591 static void __profile_closed_cb(connection_error_e result, void *user_data)
593 connection_profile_refresh(c_prof.handle);
595 if (result != CONNECTION_ERROR_NONE) {
596 ERR("Unable to close profile [0x%X]", result);
598 DBG("Tethering profile is closed");
604 static gboolean __close_tethering_profile(void)
606 if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
607 ERR("There is no proper cellular profile\n");
612 connection_profile_state_e state;
616 if (net_timeout_id) {
617 g_source_remove(net_timeout_id);
621 if (c_prof.svc_type == __INTERNET) {
622 __profile_closed_cb(CONNECTION_ERROR_NONE, NULL);
626 ret = connection_profile_get_state(c_prof.handle, &state);
627 if (ret != CONNECTION_ERROR_NONE) {
628 ERR("connection_profile_get_state is failed [0x%X]\n", ret);
632 if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
633 DBG("Already disconnected profile\n");
637 ret = connection_close_profile(connection, c_prof.handle,
638 __profile_closed_cb, NULL);
639 if (ret != CONNECTION_ERROR_NONE) {
640 ERR("Connection close Failed!!\n");
648 static void __profile_opened_cb(connection_error_e result, void *user_data)
650 if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
651 ERR("There is no proper profile\n");
656 connection_type_e net_type;
660 connection_profile_refresh(c_prof.handle);
662 if (_mobileap_is_disabled()) {
663 __close_tethering_profile();
667 if (result == CONNECTION_ERROR_OPERATION_ABORTED) {
668 DBG("connection_open_profile is cancelled\n");
672 /* Check opened and retry context */
673 ret = connection_get_type(connection, &net_type);
674 if (ret != CONNECTION_ERROR_NONE) {
675 ERR("connection_get_type is failed\n");
676 __close_tethering_profile();
680 if (net_type != CONNECTION_TYPE_DISCONNECTED &&
681 net_type != CONNECTION_TYPE_CELLULAR) {
682 DBG("Connection type is changed\n");
683 __close_tethering_profile();
688 connection_profile_refresh(tethered_prof);
693 if (result != CONNECTION_ERROR_ALREADY_EXISTS &&
694 result != CONNECTION_ERROR_NONE) {
695 DBG("Retry to open profile [0x%X]\n", result);
696 if (net_timeout_id) {
697 g_source_remove(net_timeout_id);
700 net_timeout_id = g_timeout_add(TETHERING_NET_OPEN_RETRY_INTERVAL,
701 __try_to_open_tethering_profile,
706 DBG("Tethering profile is opened");
708 __print_cellular_profile();
710 connection_profile_clone(&tethered_prof, c_prof.handle);
712 _add_default_router();
713 _add_port_forward_rule();
720 static gboolean __open_tethering_profile(void)
722 if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
723 ERR("There is no proper cellular profile\n");
731 if (c_prof.svc_type == __INTERNET) {
735 if (__is_connected_profile(c_prof.handle)) {
736 DBG("Already connected profile\n");
740 ret = connection_open_profile(connection, c_prof.handle,
741 __profile_opened_cb, NULL);
742 if (ret != CONNECTION_ERROR_NONE) {
743 ERR("Unable to open profile [0x%X]", ret);
751 static gboolean __try_to_open_tethering_profile(gpointer user_data)
755 if (_mobileap_is_disabled()) {
756 DBG("Tethering is disabled\n");
761 if (__open_tethering_profile() == FALSE)
768 gboolean _is_trying_network_operation(void)
776 gboolean _get_network_interface_name(char **if_name)
778 if (if_name == NULL) {
779 ERR("if_name is NULL\n");
783 if (tethered_prof == NULL) {
789 connection_profile_refresh(tethered_prof);
791 ret = connection_profile_get_network_interface_name(tethered_prof, if_name);
792 if (ret != CONNECTION_ERROR_NONE) {
793 ERR("connection_profile_get_network_interface_name is failed : 0x%X\n", ret);
797 if (strlen(*if_name) == 0) {
798 ERR("if_name is zero length\n");
806 gboolean _get_network_gateway_address(char **ip)
813 if (tethered_prof == NULL) {
819 connection_profile_refresh(tethered_prof);
821 ret = connection_profile_get_gateway_address(tethered_prof,
822 CONNECTION_ADDRESS_FAMILY_IPV4, ip);
823 if (ret != CONNECTION_ERROR_NONE) {
824 ERR("connection_profile_get_ip_address is failed : 0x%X\n", ret);
831 gboolean _set_masquerade(void)
833 char *if_name = NULL;
835 if (_get_network_interface_name(&if_name) == FALSE) {
836 ERR("_get_network_interface_name is failed\n");
839 SDBG("Network interface : %s\n", if_name);
841 _mh_core_enable_masquerade(if_name);
847 gboolean _unset_masquerade(void)
849 if (tethered_prof == NULL) {
850 DBG("There is nothing to unset masquerading\n");
854 char *if_name = NULL;
856 if (_get_network_interface_name(&if_name) == FALSE) {
857 ERR("_get_network_interface_name is failed\n");
860 SDBG("Network interface : %s\n", if_name);
862 _mh_core_disable_masquerade(if_name);
868 gboolean _add_default_router(void)
870 if (tethered_prof == NULL) {
871 DBG("There is no network\n");
875 char cmd[MAX_BUF_SIZE] = {0, };
877 char *interface = NULL;
879 if (_get_network_gateway_address(&ip) == FALSE) {
883 if (_get_network_interface_name(&interface) == FALSE) {
888 snprintf(cmd, sizeof(cmd), "%s route replace "DEFAULT_ROUTER,
889 IP_CMD, ip, interface, TETHERING_ROUTING_TABLE);
893 if (_execute_command(cmd)) {
894 ERR("%s is failed\n", cmd);
901 gboolean _del_default_router(void)
903 if (tethered_prof == NULL) {
904 DBG("There is no network\n");
908 char cmd[MAX_BUF_SIZE] = {0, };
910 char *interface = NULL;
912 if (_get_network_gateway_address(&ip) == FALSE) {
916 if (_get_network_interface_name(&interface) == FALSE) {
921 snprintf(cmd, sizeof(cmd), "%s route del "DEFAULT_ROUTER,
922 IP_CMD, ip, interface, TETHERING_ROUTING_TABLE);
926 if (_execute_command(cmd)) {
927 ERR("%s is failed\n", cmd);
934 void _add_port_forward_rule(void)
939 port_forward_info_s *pf;
941 if (access(MH_PORT_FORWARD_CONF_FILEPATH, F_OK) < 0) {
945 if (__read_port_forward_info(MH_PORT_FORWARD_CONF_FILEPATH) == FALSE) {
946 ERR("__read_port_forward_info() is failed\n");
950 _iptables_create_chain(TABLE_NAT, TETH_NAT_PRE);
951 _iptables_add_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_PRE,
954 for (l = port_forward_info; l; l = g_slist_next(l)) {
955 pf = (port_forward_info_s *)l->data;
957 if (__is_valid_port_forward_info(pf) == FALSE)
960 _iptables_add_rule(PORT_FW_RULE, TABLE_NAT, TETH_NAT_PRE,
961 pf->input_interface, pf->proto, pf->org_dest_ip,
962 pf->new_dest_ip, (int)pf->org_dest_port, (int)pf->new_dest_port);
968 void _del_port_forward_rule(void)
972 port_forward_info_s *pf;
976 if (port_forward_info == NULL) {
977 DBG("port forwarding rules were not applied, no need to deleted\n");
981 for(l = port_forward_info; l;) {
982 pf = (port_forward_info_s *)l->data;
984 g_free(pf->new_dest_ip);
985 g_free(pf->org_dest_ip);
987 g_free(pf->input_interface);
993 port_forward_info = g_slist_delete_link(port_forward_info,
997 _iptables_delete_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_PRE,
999 _iptables_flush_rules(TABLE_NAT, TETH_NAT_PRE);
1000 _iptables_delete_chain(TABLE_NAT, TETH_NAT_PRE);
1005 int _open_network(void)
1012 connection_type_e net_type;
1014 ret = connection_get_type(connection, &net_type);
1015 if (ret != CONNECTION_ERROR_NONE) {
1016 ERR("connection_get_type is failed\n");
1017 con_ret = __get_conn_error(ret);
1021 if (vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state) < 0) {
1022 ERR("vconf_get_int is failed\n");
1023 return MOBILE_AP_ERROR_INTERNAL;
1026 DBG("Connection type : %d, Cellular State : %d\n",
1027 net_type, cellular_state);
1029 if (tethered_prof) {
1030 if (net_type == CONNECTION_TYPE_CELLULAR) {
1031 __update_tethering_cellular_profile();
1032 if (__is_equal_profile(tethered_prof, c_prof.handle)) {
1033 DBG("Cellular profile is already configured\n");
1034 return MOBILE_AP_ERROR_NONE;
1038 DBG("There is already tethered profile\n");
1042 if (net_type == CONNECTION_TYPE_DISCONNECTED &&
1043 cellular_state != VCONFKEY_NETWORK_CELLULAR_ON) {
1044 DBG("There is no network\n");
1045 /* Callback will handle this once Network type is changed */
1046 return MOBILE_AP_ERROR_NONE;
1050 case CONNECTION_TYPE_DISCONNECTED:
1051 case CONNECTION_TYPE_CELLULAR:
1052 __update_tethering_cellular_profile();
1053 if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
1054 DBG("There is no proper cellular profile for tethering\n");
1055 return MOBILE_AP_ERROR_NONE;
1057 __print_cellular_profile();
1059 if (!__is_connected_profile(c_prof.handle)) {
1060 if (c_prof.svc_type != __TETHERING_ONLY) {
1061 return MOBILE_AP_ERROR_NONE;
1064 if (net_timeout_id) {
1065 g_source_remove(net_timeout_id);
1068 net_timeout_id = g_timeout_add(TETHERING_NET_OPEN_RETRY_INTERVAL,
1069 __try_to_open_tethering_profile, NULL);
1071 return MOBILE_AP_ERROR_NONE;
1073 connection_profile_clone(&tethered_prof, c_prof.handle);
1076 case CONNECTION_TYPE_WIFI:
1077 case CONNECTION_TYPE_ETHERNET:
1078 case CONNECTION_TYPE_BT:
1079 ret = connection_get_current_profile(connection, &tethered_prof);
1080 if (ret != CONNECTION_ERROR_NONE) {
1081 ERR("connection_get_current_profile is failed [0x%X]\n", ret);
1082 con_ret = __get_conn_error(ret);
1088 ERR("Unknown connection type : %d\n", net_type);
1089 return MOBILE_AP_ERROR_INTERNAL;
1093 _add_default_router();
1094 _add_port_forward_rule();
1098 return MOBILE_AP_ERROR_NONE;
1101 void _close_network(void)
1103 if (tethered_prof == NULL) {
1104 DBG("There is no tethered profile\n");
1110 _del_port_forward_rule();
1111 _del_default_router();
1112 _unset_masquerade();
1114 connection_profile_destroy(tethered_prof);
1115 tethered_prof = NULL;
1116 __close_tethering_profile();
1122 gboolean _init_network(void *user_data)
1124 if (user_data == NULL) {
1125 ERR("Invalid parameter\n");
1131 obj = (TetheringObject *)user_data;
1133 ret = connection_create(&connection);
1134 if (ret != CONNECTION_ERROR_NONE) {
1135 ERR("connection_create is failed : 0x%X\n", ret);
1139 ret = connection_set_type_changed_cb(connection,
1140 __connection_type_changed_cb, user_data);
1141 if (ret != CONNECTION_ERROR_NONE) {
1142 ERR("connection_set_type_changed cb is failed : 0x%X\n", ret);
1146 ret = vconf_notify_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
1147 __cellular_state_changed_cb, NULL);
1149 ERR("vconf_notify_key_changed is failed : %d\n", ret);
1150 connection_unset_type_changed_cb(connection);
1154 __update_tethering_cellular_profile();
1160 connection_destroy(connection);
1167 gboolean _deinit_network(void)
1171 if (connection == NULL) {
1172 ERR("Connection handle is not initialized\n");
1176 if (c_prof.handle) {
1177 vconf_ignore_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
1178 __cellular_state_changed_cb);
1179 connection_profile_unset_state_changed_cb(c_prof.handle);
1180 connection_profile_destroy(c_prof.handle);
1181 c_prof.handle = NULL;
1182 c_prof.svc_type = __NO_SERVICE;
1185 ret = connection_unset_type_changed_cb(connection);
1186 if (ret != CONNECTION_ERROR_NONE) {
1187 ERR("connection_unset_type_changed_cb is failed : %d\n", ret);
1190 connection_destroy(connection);