tizen 2.3 release
[framework/connectivity/mobileap-agent.git] / src / mobileap_network.c
1 /*
2  * mobileap-agent
3  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18 #include <stdio.h>
19 #include <unistd.h>
20 #include <stdlib.h>
21 #include <glib.h>
22 #include <string.h>
23 #include <net_connection.h>
24
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"
32
33 typedef enum {
34         __NO_SERVICE,
35         __INTERNET,
36         __TETHERING_ONLY
37 } tethering_cellular_service_type_e;
38
39 typedef struct {
40         connection_profile_h handle;
41         tethering_cellular_service_type_e svc_type;
42 } tethering_cellular_profile_s;
43
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
47
48 typedef struct {
49         char *input_interface;
50         char *proto;
51         char *org_dest_ip;
52         unsigned short org_dest_port;
53         char *new_dest_ip;
54         unsigned short new_dest_port;
55 } port_forward_info_s;
56
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;
63
64
65 static gboolean __try_to_open_tethering_profile(gpointer user_data);
66
67 static mobile_ap_error_code_e __get_conn_error(int conn_error)
68 {
69         mobile_ap_error_code_e err = MOBILE_AP_ERROR_NONE;
70
71         switch (conn_error) {
72         case CONNECTION_ERROR_NONE:
73                 err = MOBILE_AP_ERROR_NONE;
74                 break;
75
76         case CONNECTION_ERROR_OUT_OF_MEMORY:
77                 err = MOBILE_AP_ERROR_RESOURCE;
78                 break;
79
80         case CONNECTION_ERROR_INVALID_OPERATION:
81                 err = MOBILE_AP_ERROR_INTERNAL;
82                 break;
83
84         case CONNECTION_ERROR_INVALID_PARAMETER:
85                 err = MOBILE_AP_ERROR_INVALID_PARAM;
86                 break;
87
88         case CONNECTION_ERROR_ALREADY_EXISTS:
89                 err = MOBILE_AP_ERROR_ALREADY_ENABLED;
90                 break;
91
92         case CONNECTION_ERROR_PERMISSION_DENIED:
93                 err = MOBILE_AP_ERROR_PERMISSION_DENIED;
94                 break;
95
96         case CONNECTION_ERROR_DHCP_FAILED:
97                 err = MOBILE_AP_ERROR_DHCP;
98                 break;
99
100         case CONNECTION_ERROR_NOW_IN_PROGRESS:
101                 err = MOBILE_AP_ERROR_IN_PROGRESS;
102                 break;
103
104         default:
105                 ERR("Not defined error : %d\n", conn_error);
106                 err = MOBILE_AP_ERROR_INTERNAL;
107                 break;
108         }
109
110         return err;
111 }
112
113 static gboolean __is_valid_ipv4_addr(const char *ip)
114 {
115         int i;
116         int len;
117         int dot_count = 0;
118         int addr;
119         char tmp_ip[16] = {0, };
120         char *p = tmp_ip;
121
122         if (ip == NULL)
123                 return FALSE;
124
125         len = strlen(ip);
126         if (len > 15 /* 255.255.255.255 */ || len < 7 /* 0.0.0.0 */)
127                 return FALSE;
128         g_strlcpy(tmp_ip, ip, sizeof(tmp_ip));
129
130         for (i = 0; i <= len; i++) {
131                 if (tmp_ip[i] == '.') {
132                         if (++dot_count > 3)
133                                 return FALSE;
134                         if (&tmp_ip[i] == p)
135                                 return FALSE;
136                         tmp_ip[i] = '\0';
137                         addr = atoi(p);
138                         if (addr < 0 || addr > 255)
139                                 return FALSE;
140                         p = &tmp_ip[i + 1];
141                 } else if (tmp_ip[i] == '\0') {
142                         if (&tmp_ip[i] == p)
143                                 return FALSE;
144                         addr = atoi(p);
145                         if (addr < 0 || addr > 255)
146                                 return FALSE;
147                         break;
148                 } else if (tmp_ip[i] < '0' || tmp_ip[i] > '9')
149                         return FALSE;
150         }
151
152         if (dot_count != 3)
153                 return FALSE;
154
155         return TRUE;
156 }
157
158 static void __clear_port_forward_info(void)
159 {
160         GSList *l;
161         GSList *temp_l;
162         port_forward_info_s *pf;
163
164         for (l = port_forward_info; l; ) {
165                 pf = (port_forward_info_s *)l->data;
166                 if (pf) {
167                         g_free(pf->new_dest_ip);
168                         g_free(pf->org_dest_ip);
169                         g_free(pf->proto);
170                         g_free(pf->input_interface);
171                         g_free(pf);
172                 }
173
174                 temp_l = l;
175                 l = g_slist_next(l);
176                 port_forward_info = g_slist_delete_link(port_forward_info, temp_l);
177         }
178
179         return;
180 }
181
182 static gboolean __read_port_forward_info(const char *conf_file)
183 {
184         if (conf_file == NULL) {
185                 ERR("Invalid parameter\n");
186                 return FALSE;
187         }
188
189         DBG("+\n");
190
191         FILE *fp;
192         char buf[MH_MAX_PORT_FORWARD_RULE_LEN];
193         port_forward_info_s *pf;
194         int no_of_rule = 0;
195
196         __clear_port_forward_info();
197
198         fp = fopen(conf_file, "r");
199         if (fp == NULL) {
200                 ERR("fopen is failed : %s\n", strerror(errno));
201                 return FALSE;
202         }
203
204         while (fgets(buf, sizeof(buf), fp)) {
205                 int i;
206                 char *token;
207                 char *saveptr1 = NULL;
208                 char *saveptr2 = NULL;
209
210                 char *input_interface;
211                 char *proto;
212                 char *dest_ip[2];
213                 char *dest_port[2];
214
215                 if (no_of_rule++ >= MH_MAX_NO_OF_PORT_FORWARD_RULE) {
216                         DBG("There are too many rules\n");
217                         break;
218                 }
219
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 */
222
223                 input_interface = strtok_r(buf, " ", &saveptr1);
224                 if (input_interface == NULL) {
225                         SERR("Invalid rule : %s\n", buf);
226                         continue;
227                 }
228
229                 proto = strtok_r(NULL, " ", &saveptr1);
230                 if (proto == NULL) {
231                         SERR("Invalid rule : %s\n", buf);
232                         continue;
233                 }
234
235                 for (i = 0; i < sizeof(dest_ip) / sizeof(char *); i++) {
236                         token = strtok_r(NULL, " ", &saveptr1);
237                         if (token == NULL) {
238                                 SERR("Invalid rule : %s\n", buf);
239                                 break;
240                         }
241
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);
246                                 break;
247                         }
248
249                         dest_port[i] = strtok_r(NULL, ":", &saveptr2);
250                         if (dest_port[i] == NULL) {
251                                 SERR("Invalid rule : %s\n", buf);
252                                 break;
253                         }
254                 }
255
256                 if (i < sizeof(dest_ip) / sizeof(char *))
257                         continue;
258
259                 pf = (port_forward_info_s *)malloc(sizeof(port_forward_info_s));
260                 if (pf == NULL)
261                         break;
262
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);
270
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);
275         }
276
277         fclose(fp);
278
279         return TRUE;
280 }
281
282 static gboolean __is_valid_port_forward_info(port_forward_info_s *pf)
283 {
284         if (pf == NULL)
285                 return FALSE;
286
287         if (!pf->input_interface || !pf->proto ||
288                         !pf->org_dest_ip || !pf->new_dest_ip)
289                 return FALSE;
290
291         if (!strlen(pf->input_interface) || !strlen(pf->proto) ||
292                         !strlen(pf->org_dest_ip) || !strlen(pf->new_dest_ip))
293                 return FALSE;
294
295         return TRUE;
296 }
297
298 static void __print_cellular_profile(void)
299 {
300         int ret = 0;
301         char *apn = NULL;
302         char *home_url = NULL;
303         bool roaming = false;
304         connection_cellular_service_type_e service_type;
305
306         if (c_prof.handle == NULL)
307                 return;
308
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);
312         else
313                 SDBG("Service type: %d\n", service_type);
314
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);
318         else {
319                 SDBG("APN: %s\n", apn);
320                 g_free(apn);
321         }
322
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);
326         else {
327                 SDBG("Home url: %s\n", home_url);
328                 g_free(home_url);
329         }
330
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);
334         else
335                 SDBG("Roaming: %d\n", roaming);
336 }
337
338 static void __handle_open_network_error(void)
339 {
340         int ret = MOBILE_AP_ERROR_NONE;
341
342         if (_mobileap_is_disabled()) {
343                 return;
344         }
345
346         ret = _disable_wifi_tethering(obj);
347         DBG("_disable_wifi_tethering returns %d\n", ret);
348
349         ret = _disable_bt_tethering(obj);
350         DBG("_disable_bt_tethering returns %d\n", ret);
351
352         ret = _disable_usb_tethering(obj);
353         DBG("_disable_usb_tethering returns %d\n", ret);
354
355         _emit_mobileap_dbus_signal(obj, E_SIGNAL_NET_CLOSED, NULL);
356
357         return;
358 }
359
360 static gboolean __is_equal_profile(connection_profile_h a, connection_profile_h b)
361 {
362         char *a_id = NULL;
363         char *b_id = NULL;
364         int ret;
365
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);
369                 return FALSE;
370         }
371
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);
375                 g_free(a_id);
376                 return FALSE;
377         }
378
379         ret = g_strcmp0(a_id, b_id);
380         g_free(a_id);
381         g_free(b_id);
382
383         return (ret == 0) ? TRUE : FALSE;
384 }
385
386 static gboolean __is_connected_profile(connection_profile_h profile)
387 {
388         if (profile == NULL) {
389                 ERR("profile is NULL\n");
390                 return FALSE;
391         }
392
393         int ret;
394         connection_profile_state_e pstat = CONNECTION_PROFILE_STATE_DISCONNECTED;
395
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);
399                 return FALSE;
400         }
401
402         if (pstat != CONNECTION_PROFILE_STATE_CONNECTED) {
403                 return FALSE;
404         }
405
406         DBG("Profile is connected\n");
407         return TRUE;
408 }
409
410 static void __connection_type_changed_cb(connection_type_e type, void *user_data)
411 {
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" :
417                         "Unknown");
418
419         if (_mobileap_is_disabled()) {
420                 DBG("Tethering is disabled\n");
421                 return;
422         }
423
424         if (_open_network() != MOBILE_AP_ERROR_NONE) {
425                 ERR("_open_network() is failed\n");
426                 __handle_open_network_error();
427         }
428
429         return;
430 }
431
432 void __cellular_state_changed_cb(keynode_t *node, void *user_data)
433 {
434         if (node == NULL) {
435                 ERR("Invalid parameter\n");
436                 return;
437         }
438
439         if (vconf_keynode_get_type(node) != VCONF_TYPE_INT) {
440                 ERR("Invalid vconf key type\n");
441                 return;
442         }
443
444         int ret;
445         int cellular_state;
446         connection_type_e net_type;
447
448         cellular_state = vconf_keynode_get_int(node);
449         SDBG("key = %s, value = %d(int)\n",
450                         vconf_keynode_get_name(node), cellular_state);
451
452         if (_mobileap_is_disabled())
453                 return;
454
455         if (cellular_state != VCONFKEY_NETWORK_CELLULAR_ON)
456                 return;
457
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);
461                 return;
462         }
463
464         if (net_type != CONNECTION_TYPE_DISCONNECTED &&
465                         net_type != CONNECTION_TYPE_CELLULAR)
466                 return;
467
468         if (tethered_prof)
469                 return;
470
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();
475         }
476
477         return;
478 }
479
480 static void __profile_state_changed_cb(connection_profile_state_e state, void *user_data)
481 {
482         if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
483                 ERR("There is no proper profile\n");
484                 return;
485         }
486
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" :
492                         "Unknown");
493
494         int ret;
495         int cellular_state;
496
497         connection_profile_refresh(c_prof.handle);
498
499         if (_mobileap_is_disabled())
500                 return;
501
502         if (c_prof.svc_type != __TETHERING_ONLY)
503                 return;
504
505         if (tethered_prof) {
506                 if (!__is_equal_profile(tethered_prof, c_prof.handle))
507                         return;
508                 connection_profile_refresh(tethered_prof);
509         }
510
511         if (state != CONNECTION_PROFILE_STATE_DISCONNECTED)
512                 return;
513
514         DBG("Cellular profile is disconnected\n");
515         _close_network();
516
517         ret = vconf_get_int(VCONFKEY_NETWORK_CELLULAR_STATE, &cellular_state);
518         if (ret < 0) {
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");
523                 }
524                 return;
525         }
526
527         if (cellular_state != VCONFKEY_NETWORK_CELLULAR_ON)
528                 return;
529
530         if (_open_network() != MOBILE_AP_ERROR_NONE) {
531                 ERR("_open_network() is failed\n");
532                 __handle_open_network_error();
533         }
534
535         DBG("-\n");
536         return;
537 }
538
539 static void __update_tethering_cellular_profile(void)
540 {
541         int ret;
542         connection_profile_h profile;
543         tethering_cellular_service_type_e svc_type;
544
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;
549                 goto DONE;
550         }
551         DBG("There is no tethering profile\n");
552
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;
557                 goto DONE;
558         }
559         ERR("Getting default connection for internet is failed\n");
560         /* To-Do : Need to consider prepaid internet profile */
561
562         if (c_prof.handle) {
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;
567         }
568         return;
569
570 DONE:
571         if (c_prof.handle == NULL ||
572                         !__is_equal_profile(c_prof.handle, profile)) {
573                 if (c_prof.handle) {
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);
577                 }
578
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);
583         } else {
584                 connection_profile_destroy(profile);
585                 connection_profile_refresh(c_prof.handle);
586         }
587
588         return;
589 }
590
591 static void __profile_closed_cb(connection_error_e result, void *user_data)
592 {
593         connection_profile_refresh(c_prof.handle);
594
595         if (result != CONNECTION_ERROR_NONE) {
596                 ERR("Unable to close profile [0x%X]", result);
597         } else {
598                 DBG("Tethering profile is closed");
599         }
600
601         return;
602 }
603
604 static gboolean __close_tethering_profile(void)
605 {
606         if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
607                 ERR("There is no proper cellular profile\n");
608                 return FALSE;
609         }
610
611         int ret;
612         connection_profile_state_e state;
613
614         DBG("+\n");
615
616         if (net_timeout_id) {
617                 g_source_remove(net_timeout_id);
618                 net_timeout_id = 0;
619         }
620
621         if (c_prof.svc_type == __INTERNET) {
622                 __profile_closed_cb(CONNECTION_ERROR_NONE, NULL);
623                 return TRUE;
624         }
625
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);
629                 return FALSE;
630         }
631
632         if (state == CONNECTION_PROFILE_STATE_DISCONNECTED) {
633                 DBG("Already disconnected profile\n");
634                 return TRUE;
635         }
636
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");
641                 return FALSE;
642         }
643
644         DBG("-\n");
645         return TRUE;
646 }
647
648 static void __profile_opened_cb(connection_error_e result, void *user_data)
649 {
650         if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
651                 ERR("There is no proper profile\n");
652                 return;
653         }
654
655         int ret;
656         connection_type_e net_type;
657
658         DBG("+\n");
659
660         connection_profile_refresh(c_prof.handle);
661
662         if (_mobileap_is_disabled()) {
663                 __close_tethering_profile();
664                 return;
665         }
666
667         if (result == CONNECTION_ERROR_OPERATION_ABORTED) {
668                 DBG("connection_open_profile is cancelled\n");
669                 return;
670         }
671
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();
677                 return;
678         }
679
680         if (net_type != CONNECTION_TYPE_DISCONNECTED &&
681                         net_type != CONNECTION_TYPE_CELLULAR) {
682                 DBG("Connection type is changed\n");
683                 __close_tethering_profile();
684                 return;
685         }
686
687         if (tethered_prof) {
688                 connection_profile_refresh(tethered_prof);
689                 return;
690         }
691         /* End of check */
692
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);
698                         net_timeout_id = 0;
699                 }
700                 net_timeout_id = g_timeout_add(TETHERING_NET_OPEN_RETRY_INTERVAL,
701                                 __try_to_open_tethering_profile,
702                                 NULL);
703                 return;
704         }
705
706         DBG("Tethering profile is opened");
707
708         __print_cellular_profile();
709
710         connection_profile_clone(&tethered_prof, c_prof.handle);
711         _set_masquerade();
712         _add_default_router();
713         _add_port_forward_rule();
714
715         DBG("-\n");
716
717         return;
718 }
719
720 static gboolean __open_tethering_profile(void)
721 {
722         if (c_prof.handle == NULL || c_prof.svc_type == __NO_SERVICE) {
723                 ERR("There is no proper cellular profile\n");
724                 return FALSE;
725         }
726
727         int ret;
728
729         DBG("+\n");
730
731         if (c_prof.svc_type == __INTERNET) {
732                 return TRUE;
733         }
734
735         if (__is_connected_profile(c_prof.handle)) {
736                 DBG("Already connected profile\n");
737                 return TRUE;
738         }
739
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);
744                 return FALSE;
745         }
746
747         DBG("-\n");
748         return TRUE;
749 }
750
751 static gboolean __try_to_open_tethering_profile(gpointer user_data)
752 {
753         DBG("+\n");
754
755         if (_mobileap_is_disabled()) {
756                 DBG("Tethering is disabled\n");
757                 net_timeout_id = 0;
758                 return FALSE;
759         }
760
761         if (__open_tethering_profile() == FALSE)
762                 return TRUE;
763
764         net_timeout_id = 0;
765         return FALSE;
766 }
767
768 gboolean _is_trying_network_operation(void)
769 {
770         if (net_timeout_id)
771                 return TRUE;
772
773         return FALSE;
774 }
775
776 gboolean _get_network_interface_name(char **if_name)
777 {
778         if (if_name == NULL) {
779                 ERR("if_name is NULL\n");
780                 return FALSE;
781         }
782
783         if (tethered_prof == NULL) {
784                 return FALSE;
785         }
786
787         int ret = 0;
788
789         connection_profile_refresh(tethered_prof);
790
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);
794                 return FALSE;
795         }
796
797         if (strlen(*if_name) == 0) {
798                 ERR("if_name is zero length\n");
799                 free(*if_name);
800                 return FALSE;
801         }
802
803         return TRUE;
804 }
805
806 gboolean _get_network_gateway_address(char **ip)
807 {
808         if (ip == NULL) {
809                 ERR("ip is NULL\n");
810                 return FALSE;
811         }
812
813         if (tethered_prof == NULL) {
814                 return FALSE;
815         }
816
817         int ret = 0;
818
819         connection_profile_refresh(tethered_prof);
820
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);
825                 return FALSE;
826         }
827
828         return TRUE;
829 }
830
831 gboolean _set_masquerade(void)
832 {
833         char *if_name = NULL;
834
835         if (_get_network_interface_name(&if_name) == FALSE) {
836                 ERR("_get_network_interface_name is failed\n");
837                 return FALSE;
838         }
839         SDBG("Network interface : %s\n", if_name);
840
841         _mh_core_enable_masquerade(if_name);
842         free(if_name);
843
844         return TRUE;
845 }
846
847 gboolean _unset_masquerade(void)
848 {
849         if (tethered_prof == NULL) {
850                 DBG("There is nothing to unset masquerading\n");
851                 return TRUE;
852         }
853
854         char *if_name = NULL;
855
856         if (_get_network_interface_name(&if_name) == FALSE) {
857                 ERR("_get_network_interface_name is failed\n");
858                 return FALSE;
859         }
860         SDBG("Network interface : %s\n", if_name);
861
862         _mh_core_disable_masquerade(if_name);
863         free(if_name);
864
865         return TRUE;
866 }
867
868 gboolean _add_default_router(void)
869 {
870         if (tethered_prof == NULL) {
871                 DBG("There is no network\n");
872                 return TRUE;
873         }
874
875         char cmd[MAX_BUF_SIZE] = {0, };
876         char *ip = NULL;
877         char *interface = NULL;
878
879         if (_get_network_gateway_address(&ip) == FALSE) {
880                 return FALSE;
881         }
882
883         if (_get_network_interface_name(&interface) == FALSE) {
884                 free(ip);
885                 return FALSE;
886         }
887
888         snprintf(cmd, sizeof(cmd), "%s route replace "DEFAULT_ROUTER,
889                         IP_CMD, ip, interface, TETHERING_ROUTING_TABLE);
890         free(interface);
891         free(ip);
892
893         if (_execute_command(cmd)) {
894                 ERR("%s is failed\n", cmd);
895                 return FALSE;
896         }
897
898         return TRUE;
899 }
900
901 gboolean _del_default_router(void)
902 {
903         if (tethered_prof == NULL) {
904                 DBG("There is no network\n");
905                 return TRUE;
906         }
907
908         char cmd[MAX_BUF_SIZE] = {0, };
909         char *ip = NULL;
910         char *interface = NULL;
911
912         if (_get_network_gateway_address(&ip) == FALSE) {
913                 return FALSE;
914         }
915
916         if (_get_network_interface_name(&interface) == FALSE) {
917                 free(ip);
918                 return FALSE;
919         }
920
921         snprintf(cmd, sizeof(cmd), "%s route del "DEFAULT_ROUTER,
922                         IP_CMD, ip, interface, TETHERING_ROUTING_TABLE);
923         free(interface);
924         free(ip);
925
926         if (_execute_command(cmd)) {
927                 ERR("%s is failed\n", cmd);
928                 return FALSE;
929         }
930
931         return TRUE;
932 }
933
934 void _add_port_forward_rule(void)
935 {
936         DBG("+\n");
937
938         GSList *l;
939         port_forward_info_s *pf;
940
941         if (access(MH_PORT_FORWARD_CONF_FILEPATH, F_OK) < 0) {
942                 return;
943         }
944
945         if (__read_port_forward_info(MH_PORT_FORWARD_CONF_FILEPATH) == FALSE) {
946                 ERR("__read_port_forward_info() is failed\n");
947                 return;
948         }
949
950         _iptables_create_chain(TABLE_NAT, TETH_NAT_PRE);
951         _iptables_add_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_PRE,
952                 TETH_NAT_PRE);
953
954         for (l = port_forward_info; l; l = g_slist_next(l)) {
955                 pf = (port_forward_info_s *)l->data;
956
957                 if (__is_valid_port_forward_info(pf) == FALSE)
958                         continue;
959
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);
963         }
964
965         return;
966 }
967
968 void _del_port_forward_rule(void)
969 {
970         GSList *l;
971         GSList *temp_l;
972         port_forward_info_s *pf;
973
974         DBG("+\n");
975
976         if (port_forward_info == NULL) {
977                 DBG("port forwarding rules were not applied, no need to deleted\n");
978                 return;
979         }
980
981         for(l = port_forward_info; l;) {
982                 pf = (port_forward_info_s *)l->data;
983                 if (pf) {
984                         g_free(pf->new_dest_ip);
985                         g_free(pf->org_dest_ip);
986                         g_free(pf->proto);
987                         g_free(pf->input_interface);
988                         g_free(pf);
989                 }
990
991                 temp_l = l;
992                 l = g_slist_next(l);
993                 port_forward_info = g_slist_delete_link(port_forward_info,
994                                         temp_l);
995         }
996
997         _iptables_delete_rule(PKT_REDIRECTION_RULE, TABLE_NAT, CHAIN_PRE,
998                 TETH_NAT_PRE);
999         _iptables_flush_rules(TABLE_NAT, TETH_NAT_PRE);
1000         _iptables_delete_chain(TABLE_NAT, TETH_NAT_PRE);
1001
1002         return;
1003 }
1004
1005 int _open_network(void)
1006 {
1007         DBG("+\n");
1008
1009         int ret;
1010         int con_ret;
1011         int cellular_state;
1012         connection_type_e net_type;
1013
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);
1018                 return con_ret;
1019         }
1020
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;
1024         }
1025
1026         DBG("Connection type : %d, Cellular State : %d\n",
1027                         net_type, cellular_state);
1028
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;
1035                         }
1036                 }
1037
1038                 DBG("There is already tethered profile\n");
1039                 _close_network();
1040         }
1041
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;
1047         }
1048
1049         switch (net_type) {
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;
1056                 }
1057                 __print_cellular_profile();
1058
1059                 if (!__is_connected_profile(c_prof.handle)) {
1060                         if (c_prof.svc_type != __TETHERING_ONLY) {
1061                                 return MOBILE_AP_ERROR_NONE;
1062                         }
1063
1064                         if (net_timeout_id) {
1065                                 g_source_remove(net_timeout_id);
1066                                 net_timeout_id = 0;
1067                         }
1068                         net_timeout_id = g_timeout_add(TETHERING_NET_OPEN_RETRY_INTERVAL,
1069                                         __try_to_open_tethering_profile, NULL);
1070
1071                         return MOBILE_AP_ERROR_NONE;
1072                 }
1073                 connection_profile_clone(&tethered_prof, c_prof.handle);
1074                 break;
1075
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);
1083                         return con_ret;
1084                 }
1085                 break;
1086
1087         default:
1088                 ERR("Unknown connection type : %d\n", net_type);
1089                 return MOBILE_AP_ERROR_INTERNAL;
1090         }
1091
1092         _set_masquerade();
1093         _add_default_router();
1094         _add_port_forward_rule();
1095
1096         DBG("-\n");
1097
1098         return MOBILE_AP_ERROR_NONE;
1099 }
1100
1101 void _close_network(void)
1102 {
1103         if (tethered_prof == NULL) {
1104                 DBG("There is no tethered profile\n");
1105                 return;
1106         }
1107
1108         DBG("+\n");
1109
1110         _del_port_forward_rule();
1111         _del_default_router();
1112         _unset_masquerade();
1113
1114         connection_profile_destroy(tethered_prof);
1115         tethered_prof = NULL;
1116         __close_tethering_profile();
1117
1118         DBG("-\n");
1119         return;
1120 }
1121
1122 gboolean _init_network(void *user_data)
1123 {
1124         if (user_data == NULL) {
1125                 ERR("Invalid parameter\n");
1126                 return FALSE;
1127         }
1128
1129         int ret;
1130
1131         obj = (TetheringObject *)user_data;
1132
1133         ret = connection_create(&connection);
1134         if (ret != CONNECTION_ERROR_NONE) {
1135                 ERR("connection_create is failed : 0x%X\n", ret);
1136                 goto FAIL;
1137         }
1138
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);
1143                 goto FAIL;
1144         }
1145
1146         ret = vconf_notify_key_changed(VCONFKEY_NETWORK_CELLULAR_STATE,
1147                         __cellular_state_changed_cb, NULL);
1148         if (ret < 0) {
1149                 ERR("vconf_notify_key_changed is failed : %d\n", ret);
1150                 connection_unset_type_changed_cb(connection);
1151                 goto FAIL;
1152         }
1153
1154         __update_tethering_cellular_profile();
1155
1156         return TRUE;
1157
1158 FAIL:
1159         if (connection) {
1160                 connection_destroy(connection);
1161                 connection = NULL;
1162         }
1163
1164         return FALSE;
1165 }
1166
1167 gboolean _deinit_network(void)
1168 {
1169         int ret;
1170
1171         if (connection == NULL) {
1172                 ERR("Connection handle is not initialized\n");
1173                 return TRUE;
1174         }
1175
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;
1183         }
1184
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);
1188         }
1189
1190         connection_destroy(connection);
1191         connection = NULL;
1192         obj = NULL;
1193
1194         return TRUE;
1195 }