Add API : tethering_wifi_set_ssid()
[platform/core/api/tethering.git] / src / tethering.c
1 /*
2 * Copyright (c) 2011 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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <sys/ioctl.h>
21 #include <sys/socket.h>
22 #include <netinet/in.h>
23 #include <net/if.h>
24 #include <arpa/inet.h>
25 #include <unistd.h>
26
27 #include <vconf.h>
28
29 #include "tethering-client-stub.h"
30 #include "marshal.h"
31 #include "tethering_private.h"
32
33 static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
34 static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
35 static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
36 static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
37 static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
38 static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
39 static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
40 static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data);
41 static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data);
42 static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data);
43 static void __handle_security_type_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
44 static void __handle_ssid_visibility_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
45 static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
46
47 static __tethering_sig_t sigs[] = {
48         {SIGNAL_NAME_NET_CLOSED, __handle_net_closed},
49         {SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on},
50         {SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off},
51         {SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on},
52         {SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off},
53         {SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on},
54         {SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off},
55         {SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout},
56         {SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode},
57         {SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode},
58         {SIGNAL_NAME_SECURITY_TYPE_CHANGED, __handle_security_type_changed},
59         {SIGNAL_NAME_SSID_VISIBILITY_CHANGED, __handle_ssid_visibility_changed},
60         {SIGNAL_NAME_PASSPHRASE_CHANGED, __handle_passphrase_changed},
61         {"", NULL}};
62
63 static bool __any_tethering_is_enabled(tethering_h tethering)
64 {
65         if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) ||
66                         tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) ||
67                         tethering_is_enabled(tethering, TETHERING_TYPE_BT))
68                 return true;
69
70         return false;
71 }
72
73 static tethering_error_e __get_error(int agent_error)
74 {
75         tethering_error_e err = TETHERING_ERROR_NONE;
76
77         switch (agent_error) {
78         case MOBILE_AP_ERROR_NONE:
79                 err = TETHERING_ERROR_NONE;
80                 break;
81
82         case MOBILE_AP_ERROR_RESOURCE:
83                 err = TETHERING_ERROR_OUT_OF_MEMORY;
84                 break;
85
86         case MOBILE_AP_ERROR_INTERNAL:
87                 err = TETHERING_ERROR_OPERATION_FAILED;
88                 break;
89
90         case MOBILE_AP_ERROR_INVALID_PARAM:
91                 err = TETHERING_ERROR_INVALID_PARAMETER;
92                 break;
93
94         case MOBILE_AP_ERROR_ALREADY_ENABLED:
95                 err = TETHERING_ERROR_OPERATION_FAILED;
96                 break;
97
98         case MOBILE_AP_ERROR_NOT_ENABLED:
99                 err = TETHERING_ERROR_NOT_ENABLED;
100                 break;
101
102         case MOBILE_AP_ERROR_NET_OPEN:
103                 err = TETHERING_ERROR_OPERATION_FAILED;
104                 break;
105
106         case MOBILE_AP_ERROR_NET_CLOSE:
107                 err = TETHERING_ERROR_OPERATION_FAILED;
108                 break;
109
110         case MOBILE_AP_ERROR_DHCP:
111                 err = TETHERING_ERROR_OPERATION_FAILED;
112                 break;
113
114         case MOBILE_AP_ERROR_IN_PROGRESS:
115                 err = TETHERING_ERROR_OPERATION_FAILED;
116                 break;
117
118         case MOBILE_AP_ERROR_NOT_PERMITTED:
119                 err = TETHERING_ERROR_OPERATION_FAILED;
120                 break;
121
122         default:
123                 ERR("Not defined error : %d\n", agent_error);
124                 err = TETHERING_ERROR_OPERATION_FAILED;
125                 break;
126         }
127
128         return err;
129 }
130
131 static void __handle_dhcp(DBusGProxy *proxy, const char *member,
132                 guint interface, const char *ip, const char *mac,
133                 const char *name, gpointer user_data)
134 {
135         DBG("+\n");
136
137         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
138
139         __tethering_h *th = (__tethering_h *)user_data;
140         bool opened = false;
141         tethering_type_e type = 0;
142         tethering_connection_state_changed_cb ccb = NULL;
143         __tethering_client_h client = {0, };
144         void *data = NULL;
145
146         if (!g_strcmp0(member, "DhcpConnected")) {
147                 opened = true;
148         } else if (!g_strcmp0(member, "DhcpLeaseDeleted")) {
149                 opened = false;
150         } else {
151                 ERR("Unknown event [%s]\n", member);
152                 return;
153         }
154
155         if (interface == MOBILE_AP_TYPE_USB)
156                 type = TETHERING_TYPE_USB;
157         else if (interface == MOBILE_AP_TYPE_WIFI)
158                 type = TETHERING_TYPE_WIFI;
159         else if (interface == MOBILE_AP_TYPE_BT)
160                 type = TETHERING_TYPE_BT;
161         else {
162                 ERR("Not supported tethering type [%d]\n", interface);
163                 return;
164         }
165
166         ccb = th->changed_cb[type];
167         if (ccb == NULL)
168                 return;
169         data = th->changed_user_data[type];
170
171         client.interface = type;
172         g_strlcpy(client.ip, ip, sizeof(client.ip));
173         g_strlcpy(client.mac, mac, sizeof(client.mac));
174         g_strlcpy(client.hostname, name, sizeof(client.hostname));
175
176         ccb((tethering_client_h)&client, opened, data);
177
178         return;
179 }
180
181 static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
182 {
183         DBG("+\n");
184
185         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
186
187         __tethering_h *th = (__tethering_h *)user_data;
188         tethering_type_e type = 0;
189         tethering_disabled_cb dcb = NULL;
190         void *data = NULL;
191         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE;
192
193         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
194                 dcb = th->disabled_cb[type];
195                 if (dcb == NULL)
196                         continue;
197                 data = th->disabled_user_data[type];
198
199                 dcb(TETHERING_ERROR_NONE, type, code, data);
200         }
201
202         return;
203 }
204
205 static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
206 {
207         DBG("+\n");
208
209         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
210
211         __tethering_h *th = (__tethering_h *)user_data;
212         tethering_type_e type = TETHERING_TYPE_WIFI;
213         bool is_requested = false;
214         tethering_enabled_cb ecb = NULL;
215         void *data = NULL;
216
217         ecb = th->enabled_cb[type];
218         if (ecb == NULL)
219                 return;
220         data = th->enabled_user_data[type];
221
222         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
223 }
224
225 static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
226 {
227         DBG("+\n");
228
229         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
230
231         __tethering_h *th = (__tethering_h *)user_data;
232         tethering_type_e type = TETHERING_TYPE_WIFI;
233         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
234         tethering_disabled_cb dcb = NULL;
235         void *data = NULL;
236
237         dcb = th->disabled_cb[type];
238         if (dcb == NULL)
239                 return;
240         data = th->disabled_user_data[type];
241
242         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
243                 code = TETHERING_DISABLED_BY_WIFI_ON;
244         else if (!g_strcmp0(value_name, SIGNAL_MSG_TIMEOUT))
245                 code = TETHERING_DISABLED_BY_TIMEOUT;
246
247         dcb(TETHERING_ERROR_NONE, type, code, data);
248
249         return;
250 }
251
252 static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
253 {
254         DBG("+\n");
255
256         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
257
258         __tethering_h *th = (__tethering_h *)user_data;
259         tethering_type_e type = TETHERING_TYPE_USB;
260         bool is_requested = false;
261         tethering_enabled_cb ecb = NULL;
262         void *data = NULL;
263
264         ecb = th->enabled_cb[type];
265         if (ecb == NULL)
266                 return;
267         data = th->enabled_user_data[type];
268
269         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
270 }
271
272 static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
273 {
274         DBG("+\n");
275
276         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
277
278         __tethering_h *th = (__tethering_h *)user_data;
279         tethering_type_e type = TETHERING_TYPE_USB;
280         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
281         tethering_disabled_cb dcb = NULL;
282         void *data = NULL;
283
284         dcb = th->disabled_cb[type];
285         if (dcb == NULL)
286                 return;
287         data = th->disabled_user_data[type];
288
289         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
290                 code = TETHERING_DISABLED_BY_USB_DISCONNECTION;
291
292         dcb(TETHERING_ERROR_NONE, type, code, data);
293
294         return;
295 }
296
297 static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
298 {
299         DBG("+\n");
300
301         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
302
303         __tethering_h *th = (__tethering_h *)user_data;
304         tethering_type_e type = TETHERING_TYPE_BT;
305         bool is_requested = false;
306         tethering_enabled_cb ecb = NULL;
307         void *data = NULL;
308
309         ecb = th->enabled_cb[type];
310         if (ecb == NULL)
311                 return;
312         data = th->enabled_user_data[type];
313
314         ecb(TETHERING_ERROR_NONE, type, is_requested, data);
315 }
316
317 static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
318 {
319         DBG("+\n");
320
321         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
322
323         __tethering_h *th = (__tethering_h *)user_data;
324         tethering_type_e type = TETHERING_TYPE_BT;
325         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
326         tethering_disabled_cb dcb = NULL;
327         void *data = NULL;
328
329         dcb = th->disabled_cb[type];
330         if (dcb == NULL)
331                 return;
332         data = th->disabled_user_data[type];
333
334         if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
335                 code = TETHERING_DISABLED_BY_BT_OFF;
336         else if (!g_strcmp0(value_name, SIGNAL_MSG_TIMEOUT))
337                 code = TETHERING_DISABLED_BY_TIMEOUT;
338
339         dcb(TETHERING_ERROR_NONE, type, code, data);
340
341         return;
342 }
343
344 static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data)
345 {
346         DBG("+\n");
347
348         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
349
350         __tethering_h *th = (__tethering_h *)user_data;
351         tethering_type_e type = 0;
352         tethering_disabled_cb dcb = NULL;
353         void *data = NULL;
354         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT;
355
356         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
357                 dcb = th->disabled_cb[type];
358                 if (dcb == NULL)
359                         continue;
360                 data = th->disabled_user_data[type];
361
362                 dcb(TETHERING_ERROR_NONE, type, code, data);
363         }
364 }
365
366 static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
367 {
368         DBG("+\n");
369
370         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
371
372         __tethering_h *th = (__tethering_h *)user_data;
373         tethering_type_e type = 0;
374         tethering_disabled_cb dcb = NULL;
375         void *data = NULL;
376         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY;
377
378         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
379                 dcb = th->disabled_cb[type];
380                 if (dcb == NULL)
381                         continue;
382                 data = th->disabled_user_data[type];
383
384                 dcb(TETHERING_ERROR_NONE, type, code, data);
385         }
386 }
387
388 static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
389 {
390         DBG("+\n");
391
392         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
393
394         __tethering_h *th = (__tethering_h *)user_data;
395         tethering_type_e type = 0;
396         tethering_disabled_cb dcb = NULL;
397         void *data = NULL;
398         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE;
399
400         for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
401                 dcb = th->disabled_cb[type];
402                 if (dcb == NULL)
403                         continue;
404                 data = th->disabled_user_data[type];
405
406                 dcb(TETHERING_ERROR_NONE, type, code, data);
407         }
408 }
409
410 static void __handle_security_type_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
411 {
412         DBG("+\n");
413
414         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
415
416         __tethering_h *th = (__tethering_h *)user_data;
417         tethering_wifi_security_type_changed_cb scb = NULL;
418         void *data = NULL;
419         tethering_wifi_security_type_e security_type;
420
421         scb = th->security_type_changed_cb;
422         if (scb == NULL)
423                 return;
424
425         data = th->security_type_user_data;
426         if (g_strcmp0(value_name, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
427                 security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
428         else if (g_strcmp0(value_name, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
429                 security_type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
430         else {
431                 ERR("Unknown security type : %s\n", value_name);
432                 return;
433         }
434
435         scb(security_type, data);
436
437         return;
438 }
439
440 static void __handle_ssid_visibility_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
441 {
442         DBG("+\n");
443
444         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
445
446         __tethering_h *th = (__tethering_h *)user_data;
447         tethering_wifi_ssid_visibility_changed_cb scb = NULL;
448         void *data = NULL;
449         bool visible = false;
450
451         scb = th->ssid_visibility_changed_cb;
452         if (scb == NULL)
453                 return;
454
455         data = th->ssid_visibility_user_data;
456         if (g_strcmp0(value_name, SIGNAL_MSG_SSID_VISIBLE) == 0)
457                 visible = true;
458
459         scb(visible, data);
460
461         return;
462 }
463
464 static void __handle_passphrase_changed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
465 {
466         DBG("+\n");
467
468         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
469
470         __tethering_h *th = (__tethering_h *)user_data;
471         tethering_wifi_passphrase_changed_cb pcb = NULL;
472         void *data = NULL;
473
474         pcb = th->passphrase_changed_cb;
475         if (pcb == NULL)
476                 return;
477
478         data = th->passphrase_user_data;
479
480         pcb(data);
481
482         return;
483 }
484
485 static void __cfm_cb(DBusGProxy *remoteobj, guint event, guint info,
486                 GError *g_error, gpointer user_data)
487 {
488         DBG("+\n");
489
490         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
491
492         tethering_h tethering = (tethering_h)user_data;
493         __tethering_h *th = (__tethering_h *)tethering;
494         DBusGProxy *proxy = th->client_bus_proxy;
495
496         tethering_type_e type = 0;
497         tethering_error_e error = __get_error(info);
498         bool is_requested = true;
499         tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST;
500
501         tethering_enabled_cb ecb = NULL;
502         tethering_disabled_cb dcb = NULL;
503         void *data = NULL;
504
505         if (g_error) {
506                 ERR("DBus error [%s]\n", g_error->message);
507                 g_error_free(g_error);
508                 return;
509         }
510
511         DBG("cfm event : %d info : %d\n", event, info);
512         switch (event) {
513         case MOBILE_AP_ENABLE_WIFI_TETHERING_CFM:
514                 type = TETHERING_TYPE_WIFI;
515                 ecb = th->enabled_cb[type];
516                 data = th->enabled_user_data[type];
517                 if (ecb)
518                         ecb(error, type, is_requested, data);
519                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
520                                 G_CALLBACK(__handle_wifi_tether_on),
521                                 (gpointer)tethering, NULL);
522                 break;
523
524         case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM:
525                 type = TETHERING_TYPE_WIFI;
526                 dcb = th->disabled_cb[type];
527                 data = th->disabled_user_data[type];
528                 if (dcb)
529                         dcb(error, type, code, data);
530                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
531                                 G_CALLBACK(__handle_wifi_tether_off),
532                                 (gpointer)tethering, NULL);
533                 break;
534
535         case MOBILE_AP_ENABLE_BT_TETHERING_CFM:
536                 type = TETHERING_TYPE_BT;
537                 ecb = th->enabled_cb[type];
538                 data = th->enabled_user_data[type];
539                 if (ecb)
540                         ecb(error, type, is_requested, data);
541                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
542                                 G_CALLBACK(__handle_bt_tether_on),
543                                 (gpointer)tethering, NULL);
544                 break;
545
546         case MOBILE_AP_DISABLE_BT_TETHERING_CFM:
547                 type = TETHERING_TYPE_BT;
548                 dcb = th->disabled_cb[type];
549                 data = th->disabled_user_data[type];
550                 if (dcb)
551                         dcb(error, type, code, data);
552                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
553                                 G_CALLBACK(__handle_bt_tether_off),
554                                 (gpointer)tethering, NULL);
555                 break;
556
557         case MOBILE_AP_ENABLE_USB_TETHERING_CFM:
558                 type = TETHERING_TYPE_USB;
559                 ecb = th->enabled_cb[type];
560                 data = th->enabled_user_data[type];
561                 if (ecb)
562                         ecb(error, type, is_requested, data);
563                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
564                                 G_CALLBACK(__handle_usb_tether_on),
565                                 (gpointer)tethering, NULL);
566                 break;
567
568         case MOBILE_AP_DISABLE_USB_TETHERING_CFM:
569                 type = TETHERING_TYPE_USB;
570                 dcb = th->disabled_cb[type];
571                 data = th->disabled_user_data[type];
572                 if (dcb)
573                         dcb(error, type, code, data);
574                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
575                                 G_CALLBACK(__handle_usb_tether_off),
576                                 (gpointer)tethering, NULL);
577                 break;
578
579         case MOBILE_AP_DISABLE_CFM:
580                 for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
581                         dcb = th->disabled_cb[type];
582                         if (dcb == NULL)
583                                 continue;
584                         data = th->disabled_user_data[type];
585
586                         dcb(error, type, code, data);
587                 }
588
589                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
590                                 G_CALLBACK(__handle_usb_tether_off),
591                                 (gpointer)tethering, NULL);
592                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
593                                 G_CALLBACK(__handle_wifi_tether_off),
594                                 (gpointer)tethering, NULL);
595                 dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
596                                 G_CALLBACK(__handle_bt_tether_off),
597                                 (gpointer)tethering, NULL);
598                 break;
599
600         default:
601                 ERR("Invalid event\n");
602                 return;
603         }
604
605         return;
606 }
607
608 static void __get_data_usage_cb(DBusGProxy *remoteobj, guint event,
609                 guint64 tx_bytes, guint64 rx_bytes,
610                 GError *error, gpointer user_data)
611 {
612         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
613
614         __tethering_h *th = (__tethering_h *)user_data;
615
616         if (th->data_usage_cb == NULL) {
617                 ERR("There is no data_usage_cb\n");
618                 return;
619         }
620
621         if (error || event != MOBILE_AP_GET_DATA_PACKET_USAGE_CFM) {
622                 if (error)  {
623                         ERR("DBus fail [%s]\n", error->message);
624                         g_error_free(error);
625                 }
626
627                 th->data_usage_cb(TETHERING_ERROR_OPERATION_FAILED,
628                                 0LL, 0LL, th->data_usage_user_data);
629
630                 th->data_usage_cb = NULL;
631                 th->data_usage_user_data = NULL;
632
633                 return;
634         }
635
636         th->data_usage_cb(TETHERING_ERROR_NONE,
637                         rx_bytes, tx_bytes, th->data_usage_user_data);
638
639         th->data_usage_cb = NULL;
640         th->data_usage_user_data = NULL;
641
642         return;
643 }
644
645 static void __connect_signals(tethering_h tethering)
646 {
647         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
648
649         __tethering_h *th = (__tethering_h *)tethering;
650         DBusGProxy *proxy = th->client_bus_proxy;
651         int i = 0;
652
653         for (i = 0; sigs[i].cb != NULL; i++) {
654                 dbus_g_proxy_add_signal(proxy, sigs[i].name,
655                                 G_TYPE_STRING, G_TYPE_INVALID);
656                 dbus_g_proxy_connect_signal(proxy, sigs[i].name,
657                                 G_CALLBACK(sigs[i].cb), (gpointer)tethering, NULL);
658         }
659
660         dbus_g_object_register_marshaller(marshal_VOID__STRING_UINT_STRING_STRING_STRING,
661                         G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
662                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
663         dbus_g_proxy_add_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
664                         G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
665                         G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
666         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
667                         G_CALLBACK(__handle_dhcp), (gpointer)tethering, NULL);
668
669         return;
670 }
671
672 static void __disconnect_signals(tethering_h tethering)
673 {
674         _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
675
676         __tethering_h *th = (__tethering_h *)tethering;
677         DBusGProxy *proxy = th->client_bus_proxy;
678
679         int i = 0;
680
681         for (i = 0; sigs[i].cb != NULL; i++) {
682                 dbus_g_proxy_disconnect_signal(proxy, sigs[i].name,
683                                 G_CALLBACK(sigs[i].cb), (gpointer)tethering);
684         }
685
686         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
687                         G_CALLBACK(__handle_dhcp), (gpointer)tethering);
688
689         return;
690 }
691
692 static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len)
693 {
694         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
695
696         switch (type) {
697         case TETHERING_TYPE_USB:
698                 g_strlcpy(buf, TETHERING_USB_IF, len);
699                 break;
700
701         case TETHERING_TYPE_WIFI:
702                 g_strlcpy(buf, TETHERING_WIFI_IF, len);
703                 break;
704
705         case TETHERING_TYPE_BT:
706                 g_strlcpy(buf, TETHERING_BT_IF, len);
707                 break;
708
709         default:
710                 ERR("Not supported type : %d\n", type);
711                 return false;
712         }
713
714         return true;
715 }
716
717 static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int len)
718 {
719         _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
720
721         switch (type) {
722         case TETHERING_TYPE_USB:
723                 g_strlcpy(buf, TETHERING_USB_GATEWAY, len);
724                 break;
725
726         case TETHERING_TYPE_WIFI:
727                 g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len);
728                 break;
729
730         case TETHERING_TYPE_BT:
731                 g_strlcpy(buf, TETHERING_BT_GATEWAY, len);
732                 break;
733
734         default:
735                 ERR("Not supported type : %d\n", type);
736                 return false;
737         }
738
739         return true;
740 }
741
742 static void __deinit_cb(DBusGProxy *remoteobj,
743                 GError *error, gpointer user_data)
744 {
745         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
746
747         if (error) {
748                 ERR("DBus fail [%s]\n", error->message);
749                 g_error_free(error);
750         }
751
752         return;
753 }
754
755 static void __wifi_set_security_type_cb(DBusGProxy *remoteobj,
756                 GError *error, gpointer user_data)
757 {
758         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
759
760         tethering_h tethering = (tethering_h)user_data;
761         __tethering_h *th = (__tethering_h *)tethering;
762         DBusGProxy *proxy = th->client_bus_proxy;
763
764         if (error) {
765                 ERR("DBus fail [%s]\n", error->message);
766                 g_error_free(error);
767         }
768
769         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED,
770                         G_CALLBACK(__handle_security_type_changed),
771                         (gpointer)tethering, NULL);
772
773         return;
774 }
775
776 static void __wifi_set_ssid_visibility_cb(DBusGProxy *remoteobj,
777                 GError *error, gpointer user_data)
778 {
779         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
780
781         tethering_h tethering = (tethering_h)user_data;
782         __tethering_h *th = (__tethering_h *)tethering;
783         DBusGProxy *proxy = th->client_bus_proxy;
784
785         if (error) {
786                 ERR("DBus fail [%s]\n", error->message);
787                 g_error_free(error);
788         }
789
790         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
791                         G_CALLBACK(__handle_ssid_visibility_changed),
792                         (gpointer)tethering, NULL);
793
794         return;
795 }
796
797 static void __wifi_set_passphrase_cb(DBusGProxy *remoteobj,
798                 GError *error, gpointer user_data)
799 {
800         _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
801
802         tethering_h tethering = (tethering_h)user_data;
803         __tethering_h *th = (__tethering_h *)tethering;
804         DBusGProxy *proxy = th->client_bus_proxy;
805
806         if (error) {
807                 ERR("DBus fail [%s]\n", error->message);
808                 g_error_free(error);
809         }
810
811         dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED,
812                         G_CALLBACK(__handle_passphrase_changed),
813                         (gpointer)tethering, NULL);
814
815         return;
816 }
817
818 /**
819  * @brief  Creates the handle of tethering.
820  * @remarks  The @a tethering must be released tethering_destroy() by you.
821  * @param[out]  tethering  A handle of a new mobile ap handle on success
822  * @return  0 on success, otherwise a negative error value.
823  * @retval  #TETHERING_ERROR_NONE  Successful
824  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
825  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
826  * @see  tethering_destroy()
827  */
828 API int tethering_create(tethering_h *tethering)
829 {
830         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
831                         "parameter(tethering) is NULL\n");
832
833         __tethering_h *th = NULL;
834         GError *error = NULL;
835
836         th = (__tethering_h *)malloc(sizeof(__tethering_h));
837         _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
838                         "malloc is failed\n");
839         memset(th, 0x00, sizeof(__tethering_h));
840
841 #if !GLIB_CHECK_VERSION(2,35,0)
842         g_type_init();
843 #endif
844         th->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
845         if (error) {
846                 ERR("Couldn't connect to the System bus[%s]", error->message);
847                 g_error_free(error);
848                 free(th);
849                 return TETHERING_ERROR_OPERATION_FAILED;
850         }
851
852         th->client_bus_proxy = dbus_g_proxy_new_for_name(th->client_bus,
853                         TETHERING_SERVICE_NAME,
854                         TETHERING_SERVICE_OBJECT_PATH,
855                         TETHERING_SERVICE_INTERFACE);
856         if (!th->client_bus_proxy) {
857                 ERR("Couldn't create the proxy object");
858                 dbus_g_connection_unref(th->client_bus);
859                 free(th);
860                 return TETHERING_ERROR_OPERATION_FAILED;
861         }
862
863         __connect_signals((tethering_h)th);
864
865         *tethering = (tethering_h)th;
866         DBG("Tethering Handle : 0x%X\n", th);
867
868         return TETHERING_ERROR_NONE;
869 }
870
871 /**
872  * @brief  Destroys the handle of tethering.
873  * @param[in]  tethering  The handle of tethering
874  * @return  0 on success, otherwise a negative error value.
875  * @retval  #TETHERING_ERROR_NONE  Successful
876  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
877  * @see  tethering_create()
878  */
879 API int tethering_destroy(tethering_h tethering)
880 {
881         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
882                         "parameter(tethering) is NULL\n");
883
884         __tethering_h *th = (__tethering_h *)tethering;
885
886         DBG("Tethering Handle : 0x%X\n", th);
887         __disconnect_signals(tethering);
888
889         org_tizen_tethering_deinit_async(th->client_bus_proxy, __deinit_cb,
890                         (gpointer)tethering);
891
892         if (th->ssid)
893                 free(th->ssid);
894         g_object_unref(th->client_bus_proxy);
895         dbus_g_connection_unref(th->client_bus);
896         memset(th, 0x00, sizeof(__tethering_h));
897         free(th);
898
899         return TETHERING_ERROR_NONE;
900 }
901
902 /**
903  * @brief Enables the tethering, asynchronously.
904  * @param[in]  tethering  The handle of tethering
905  * @param[in]  type  The type of tethering
906  * @return 0 on success, otherwise negative error value.
907  * @retval  #TETHERING_ERROR_NONE  Successful
908  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
909  * @post tethering_enabled_cb() will be invoked.
910  * @see  tethering_is_enabled()
911  * @see  tethering_disable()
912  */
913 API int tethering_enable(tethering_h tethering, tethering_type_e type)
914 {
915         DBG("+\n");
916
917         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
918                         "parameter(tethering) is NULL\n");
919
920         __tethering_h *th = (__tethering_h *)tethering;
921         DBusGProxy *proxy = th->client_bus_proxy;
922
923         switch (type) {
924         case TETHERING_TYPE_USB:
925                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
926                                 G_CALLBACK(__handle_usb_tether_on),
927                                 (gpointer)tethering);
928                 org_tizen_tethering_enable_usb_tethering_async(proxy,
929                                 __cfm_cb, (gpointer)tethering);
930                 break;
931
932         case TETHERING_TYPE_WIFI:
933                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
934                                 G_CALLBACK(__handle_wifi_tether_on),
935                                 (gpointer)tethering);
936                 org_tizen_tethering_enable_wifi_tethering_async(proxy,
937                                 th->ssid ? th->ssid : "", "", false,
938                                 __cfm_cb, (gpointer)tethering);
939                 break;
940
941         case TETHERING_TYPE_BT:
942                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
943                                 G_CALLBACK(__handle_bt_tether_on),
944                                 (gpointer)tethering);
945                 org_tizen_tethering_enable_bt_tethering_async(proxy,
946                                 __cfm_cb, (gpointer)tethering);
947
948                 break;
949
950         case TETHERING_TYPE_ALL:
951                 /* TETHERING_TYPE_USB */
952                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
953                                 G_CALLBACK(__handle_usb_tether_on),
954                                 (gpointer)tethering);
955                 org_tizen_tethering_enable_usb_tethering_async(proxy,
956                                 __cfm_cb, (gpointer)tethering);
957
958                 /* TETHERING_TYPE_WIFI */
959                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
960                                 G_CALLBACK(__handle_wifi_tether_on),
961                                 (gpointer)tethering);
962                 org_tizen_tethering_enable_wifi_tethering_async(proxy,
963                                 th->ssid ? th->ssid : "", "", false,
964                                 __cfm_cb, (gpointer)tethering);
965
966                 /* TETHERING_TYPE_BT */
967                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
968                                 G_CALLBACK(__handle_bt_tether_on),
969                                 (gpointer)tethering);
970                 org_tizen_tethering_enable_bt_tethering_async(proxy,
971                                 __cfm_cb, (gpointer)tethering);
972                 break;
973
974         default:
975                 ERR("Unknown type : %d\n", type);
976                 return TETHERING_ERROR_INVALID_PARAMETER;
977         }
978
979         return TETHERING_ERROR_NONE;
980 }
981
982 /**
983  * @brief Disables the tethering, asynchronously.
984  * @param[in]  tethering  The handle of tethering
985  * @param[in]  type  The type of tethering
986  * @return 0 on success, otherwise negative error value.
987  * @retval  #TETHERING_ERROR_NONE  Successful
988  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
989  * @post tethering_disabled_cb() will be invoked.
990  * @see  tethering_is_enabled()
991  * @see  tethering_enable()
992  */
993 API int tethering_disable(tethering_h tethering, tethering_type_e type)
994 {
995         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
996                         "parameter(tethering) is NULL\n");
997
998         __tethering_h *th = (__tethering_h *)tethering;
999         DBusGProxy *proxy = th->client_bus_proxy;
1000
1001         switch (type) {
1002         case TETHERING_TYPE_USB:
1003                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
1004                                 G_CALLBACK(__handle_usb_tether_off),
1005                                 (gpointer)tethering);
1006                 org_tizen_tethering_disable_usb_tethering_async(proxy,
1007                                 __cfm_cb, (gpointer)tethering);
1008                 break;
1009
1010         case TETHERING_TYPE_WIFI:
1011                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
1012                                 G_CALLBACK(__handle_wifi_tether_off),
1013                                 (gpointer)tethering);
1014                 org_tizen_tethering_disable_wifi_tethering_async(proxy,
1015                                 __cfm_cb, (gpointer)tethering);
1016                 break;
1017         case TETHERING_TYPE_BT:
1018                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
1019                                 G_CALLBACK(__handle_bt_tether_off),
1020                                 (gpointer)tethering);
1021                 org_tizen_tethering_disable_bt_tethering_async(proxy,
1022                                 __cfm_cb, (gpointer)tethering);
1023                 break;
1024
1025         case TETHERING_TYPE_ALL:
1026                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
1027                                 G_CALLBACK(__handle_usb_tether_off),
1028                                 (gpointer)tethering);
1029                 org_tizen_tethering_disable_usb_tethering_async(proxy,
1030                                 __cfm_cb, (gpointer)tethering);
1031
1032                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
1033                                 G_CALLBACK(__handle_wifi_tether_off),
1034                                 (gpointer)tethering);
1035                 org_tizen_tethering_disable_wifi_tethering_async(proxy,
1036                                 __cfm_cb, (gpointer)tethering);
1037
1038                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
1039                                 G_CALLBACK(__handle_bt_tether_off),
1040                                 (gpointer)tethering);
1041                 org_tizen_tethering_disable_bt_tethering_async(proxy,
1042                                 __cfm_cb, (gpointer)tethering);
1043                 break;
1044
1045         default :
1046                 ERR("Not supported tethering type [%d]\n", type);
1047                 return TETHERING_ERROR_INVALID_PARAMETER;
1048                 break;
1049         }
1050
1051         return TETHERING_ERROR_NONE;
1052 }
1053
1054 /**
1055  * @brief  Checks whetehr the tethering is enabled or not.
1056  * @param[in]  tethering  The handle of tethering
1057  * @param[in]  type  The type of tethering
1058  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1059  */
1060 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1061 {
1062         int is_on = 0;
1063         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1064
1065         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) {
1066                 return FALSE;
1067         }
1068
1069         switch (type) {
1070         case TETHERING_TYPE_USB:
1071                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1072                 break;
1073
1074         case TETHERING_TYPE_WIFI:
1075                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1076                 break;
1077
1078         case TETHERING_TYPE_BT:
1079                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1080                 break;
1081
1082         default:
1083                 ERR("Not supported type : %d\n", type);
1084                 break;
1085         }
1086
1087         return is_on & vconf_type ? true : false;
1088 }
1089
1090 /**
1091  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
1092  * @remarks @a mac_address must be released with free() by you.
1093  * @param[in]  tethering  The handle of tethering
1094  * @param[in]  type  The type of tethering
1095  * @param[out]  mac_address  The MAC address
1096  * @return  0 on success, otherwise a negative error value.
1097  * @retval  #TETHERING_ERROR_NONE  Successful
1098  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1099  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1100  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1101  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1102  * @pre  tethering must be enabled.
1103  * @see  tethering_is_enabled()
1104  * @see  tethering_enable()
1105  */
1106 API int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
1107 {
1108         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1109                         "parameter(tethering) is NULL\n");
1110         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1111                         "parameter(mac_address) is NULL\n");
1112         _retvm_if(tethering_is_enabled(tethering, type) == false,
1113                         TETHERING_ERROR_NOT_ENABLED,
1114                         "tethering type[%d] is not enabled\n", type);
1115
1116         struct ifreq ifr;
1117         int s = 0;
1118         char *macbuf = NULL;
1119
1120         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1121                         TETHERING_ERROR_OPERATION_FAILED,
1122                         "getting interface name is failed\n");
1123
1124         s = socket(AF_INET, SOCK_DGRAM, 0);
1125         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1126                         "getting socket is failed\n");
1127         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
1128                 ERR("getting mac is failed\n");
1129                 close(s);
1130                 return TETHERING_ERROR_OPERATION_FAILED;
1131         }
1132         close(s);
1133
1134         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
1135         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1136                         "Not enough memory\n");
1137         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
1138                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
1139                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
1140                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
1141                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
1142                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
1143                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
1144
1145         *mac_address = macbuf;
1146
1147         return TETHERING_ERROR_NONE;
1148 }
1149
1150 /**
1151  * @brief Gets the name of network interface. For example, usb0.
1152  * @remarks @a interface_name must be released with free() by you.
1153  * @param[in]  tethering  The handle of tethering
1154  * @param[in]  type  The type of tethering
1155  * @param[out]  interface_name  The name of network interface
1156  * @return 0 on success, otherwise negative error value.
1157  * @retval  #TETHERING_ERROR_NONE  Successful
1158  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1159  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1160  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1161  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1162  * @pre  tethering must be enabled.
1163  * @see  tethering_is_enabled()
1164  * @see  tethering_enable()
1165  */
1166 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
1167 {
1168         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1169                         "parameter(tethering) is NULL\n");
1170         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1171                         "parameter(interface_name) is NULL\n");
1172         _retvm_if(tethering_is_enabled(tethering, type) == false,
1173                         TETHERING_ERROR_NOT_ENABLED,
1174                         "tethering type[%d] is not enabled\n", type);
1175
1176         char intf[TETHERING_STR_INFO_LEN] = {0, };
1177
1178         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
1179                         TETHERING_ERROR_OPERATION_FAILED,
1180                         "getting interface name is failed\n");
1181         *interface_name = strdup(intf);
1182         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1183                         "Not enough memory\n");
1184
1185         return TETHERING_ERROR_NONE;
1186 }
1187
1188 /**
1189  * @brief Gets the local IP address.
1190  * @remarks @a ip_address must be released with free() by you.
1191  * @param[in]  tethering  The handle of tethering
1192  * @param[in]  type  The type of tethering
1193  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1194  * @param[out]  ip_address  The local IP address
1195  * @return 0 on success, otherwise negative error value.
1196  * @retval  #TETHERING_ERROR_NONE  Successful
1197  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1198  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1199  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1200  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1201  * @pre  tethering must be enabled.
1202  * @see  tethering_is_enabled()
1203  * @see  tethering_enable()
1204  */
1205 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
1206 {
1207         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1208                         "parameter(tethering) is NULL\n");
1209         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1210                         "parameter(ip_address) is NULL\n");
1211         _retvm_if(tethering_is_enabled(tethering, type) == false,
1212                         TETHERING_ERROR_NOT_ENABLED,
1213                         "tethering type[%d] is not enabled\n", type);
1214
1215         struct ifreq ifr;
1216         int s = 0;
1217         char *ipbuf = NULL;
1218
1219         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1220                         TETHERING_ERROR_OPERATION_FAILED,
1221                         "getting interface name is failed\n");
1222
1223         s = socket(AF_INET, SOCK_DGRAM, 0);
1224         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1225                         "getting socket is failed\n");
1226         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
1227                 ERR("ioctl is failed\n");
1228                 close(s);
1229                 return TETHERING_ERROR_OPERATION_FAILED;
1230         }
1231         close(s);
1232
1233         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
1234         *ip_address = strdup(ipbuf);
1235         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1236                         "Not enough memory\n");
1237
1238         return TETHERING_ERROR_NONE;
1239 }
1240
1241 /**
1242  * @brief Gets the Gateway address.
1243  * @remarks @a gateway_address must be released with free() by you.
1244  * @param[in]  tethering  The handle of tethering
1245  * @param[in]  type  The type of tethering
1246  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1247  * @param[out]  gateway_address  The local IP address
1248  * @return 0 on success, otherwise negative error value.
1249  * @retval  #TETHERING_ERROR_NONE  Successful
1250  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1251  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1252  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1253  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1254  * @pre  tethering must be enabled.
1255  * @see  tethering_is_enabled()
1256  * @see  tethering_enable()
1257  */
1258 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
1259 {
1260         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1261                         "parameter(tethering) is NULL\n");
1262         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1263                         "parameter(gateway_address) is NULL\n");
1264         _retvm_if(tethering_is_enabled(tethering, type) == false,
1265                         TETHERING_ERROR_NOT_ENABLED,
1266                         "tethering type[%d] is not enabled\n", type);
1267
1268         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
1269
1270         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
1271                         TETHERING_ERROR_OPERATION_FAILED,
1272                         "getting gateway address is failed\n");
1273
1274         *gateway_address = strdup(gateway_buf);
1275
1276         return TETHERING_ERROR_NONE;
1277 }
1278
1279 /**
1280  * @brief Gets the Subnet Mask.
1281  * @remarks @a subnet_mask must be released with free() by you.
1282  * @param[in]  tethering  The handle of tethering
1283  * @param[in]  type  The type of tethering
1284  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1285  * @param[out]  subnet_mask  The local IP address
1286  * @return 0 on success, otherwise negative error value.
1287  * @retval  #TETHERING_ERROR_NONE  Successful
1288  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1289  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1290  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1291  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1292  * @pre  tethering must be enabled.
1293  * @see  tethering_is_enabled()
1294  * @see  tethering_enable()
1295  */
1296 API int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
1297 {
1298         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1299                         "parameter(tethering) is NULL\n");
1300         _retvm_if(tethering_is_enabled(tethering, type) == false,
1301                         TETHERING_ERROR_NOT_ENABLED,
1302                         "tethering is not enabled\n");
1303         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1304                         "parameter(subnet_mask) is NULL\n");
1305
1306         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
1307         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1308                         "Not enough memory\n");
1309
1310         return TETHERING_ERROR_NONE;
1311 }
1312
1313 /**
1314  * @brief Gets the data usage.
1315  * @param[in]  tethering  The handle of tethering
1316  * @param[out]  usage  The data usage
1317  * @return 0 on success, otherwise negative error value.
1318  * @retval  #TETHERING_ERROR_NONE  Successful
1319  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1320  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1321  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1322  * @pre  tethering must be enabled.
1323  * @see  tethering_is_enabled()
1324  * @see  tethering_enable()
1325  */
1326 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
1327 {
1328         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1329                         "parameter(tethering) is NULL\n");
1330         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1331                         "parameter(callback) is NULL\n");
1332         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1333                         TETHERING_ERROR_NOT_ENABLED,
1334                         "tethering is not enabled\n");
1335
1336         __tethering_h *th = (__tethering_h *)tethering;
1337         DBusGProxy *proxy = th->client_bus_proxy;
1338
1339         th->data_usage_cb = callback;
1340         th->data_usage_user_data = user_data;
1341
1342         org_tizen_tethering_get_data_packet_usage_async(proxy,
1343                         __get_data_usage_cb, (gpointer)th);
1344
1345         return TETHERING_ERROR_NONE;
1346 }
1347
1348 /**
1349  * @brief Gets the client which is connected by USB tethering.
1350  * @param[in]  tethering  The handle of tethering
1351  * @param[in]  type  The type of tethering
1352  * @param[in]  callback  The callback function to invoke
1353  * @param[in]  user_data  The user data to be passed to the callback function
1354  * @retval  #TETHERING_ERROR_NONE  Successful
1355  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1356  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1357  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1358  * @pre  tethering must be enabled.
1359  * @see  tethering_is_enabled()
1360  * @see  tethering_enable()
1361  */
1362 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
1363 {
1364         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1365                         "parameter(tethering) is NULL\n");
1366         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1367                         "parameter(callback) is NULL\n");
1368         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1369                         TETHERING_ERROR_NOT_ENABLED,
1370                         "tethering is not enabled\n");
1371
1372         __tethering_h *th = (__tethering_h *)tethering;
1373         __tethering_client_h client = {0, };
1374
1375         guint event = 0;
1376         GPtrArray *array = NULL;
1377         GValue value = {0, {{0}}};
1378         GError *error = NULL;
1379         int i = 0;
1380         int no_of_client = 0;
1381         guint interface = 0;
1382         gchar *ip = NULL;
1383         gchar *mac = NULL;
1384         gchar *hostname = NULL;
1385
1386         org_tizen_tethering_get_station_info(th->client_bus_proxy, &event,
1387                         &array, &error);
1388         if (error != NULL) {
1389                 ERR("DBus fail : %s\n", error->message);
1390                 g_error_free(error);
1391                 return TETHERING_ERROR_OPERATION_FAILED;
1392         }
1393
1394         g_value_init(&value, DBUS_STRUCT_STATIONS);
1395         no_of_client = array->len;
1396         for (i = 0; i < no_of_client; i++) {
1397                 g_value_set_boxed(&value, g_ptr_array_index(array, i));
1398
1399                 dbus_g_type_struct_get(&value, 0, &interface, 1, &ip,
1400                                 2, &mac, 3, &hostname, G_MAXUINT);
1401
1402                 if (interface == MOBILE_AP_TYPE_USB)
1403                         client.interface = TETHERING_TYPE_USB;
1404                 else if (interface == MOBILE_AP_TYPE_WIFI)
1405                         client.interface = TETHERING_TYPE_WIFI;
1406                 else if (interface == MOBILE_AP_TYPE_BT)
1407                         client.interface = TETHERING_TYPE_BT;
1408
1409                 if (client.interface != type && TETHERING_TYPE_ALL != type)
1410                         continue;
1411
1412                 g_strlcpy(client.ip, ip, sizeof(client.ip));
1413                 g_strlcpy(client.mac, mac, sizeof(client.mac));
1414                 g_strlcpy(client.hostname, hostname, sizeof(client.hostname));
1415
1416                 if (callback((tethering_client_h)&client, user_data) == false) {
1417                         DBG("iteration is stopped\n");
1418                         return TETHERING_ERROR_NONE;
1419                 }
1420         }
1421
1422         if (array->len > 0)
1423                 g_ptr_array_free(array, TRUE);
1424
1425         return TETHERING_ERROR_NONE;
1426 }
1427
1428 /**
1429  * @brief Registers the callback function called when tethering is enabled.
1430  * @param[in]  tethering  The handle of tethering
1431  * @param[in]  type  The type of tethering
1432  * @param[in]  callback  The callback function to invoke
1433  * @param[in]  user_data  The user data to be passed to the callback function
1434  * @retval  #TETHERING_ERROR_NONE  Successful
1435  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1436  * @see  tethering_unset_enabled_cb()
1437  */
1438 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
1439 {
1440         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1441                         "parameter(tethering) is NULL\n");
1442         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1443                         "parameter(callback) is NULL\n");
1444
1445         __tethering_h *th = (__tethering_h *)tethering;
1446         tethering_type_e ti;
1447
1448         if (type != TETHERING_TYPE_ALL) {
1449                 th->enabled_cb[type] = callback;
1450                 th->enabled_user_data[type] = user_data;
1451
1452                 return TETHERING_ERROR_NONE;
1453         }
1454
1455         /* TETHERING_TYPE_ALL */
1456         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1457                 th->enabled_cb[ti] = callback;
1458                 th->enabled_user_data[ti] = user_data;
1459         }
1460
1461         return TETHERING_ERROR_NONE;
1462 }
1463
1464 /**
1465  * @brief Unregisters the callback function called when tethering is disabled.
1466  * @param[in]  tethering  The handle of tethering
1467  * @param[in]  type  The type of tethering
1468  * @retval  #TETHERING_ERROR_NONE  Successful
1469  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1470  * @see  tethering_set_enabled_cb()
1471  */
1472 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
1473 {
1474         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1475                         "parameter(tethering) is NULL\n");
1476
1477         __tethering_h *th = (__tethering_h *)tethering;
1478         tethering_type_e ti;
1479
1480         if (type != TETHERING_TYPE_ALL) {
1481                 th->enabled_cb[type] = NULL;
1482                 th->enabled_user_data[type] = NULL;
1483
1484                 return TETHERING_ERROR_NONE;
1485         }
1486
1487         /* TETHERING_TYPE_ALL */
1488         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1489                 th->enabled_cb[ti] = NULL;
1490                 th->enabled_user_data[ti] = NULL;
1491         }
1492
1493         return TETHERING_ERROR_NONE;
1494 }
1495
1496 /**
1497  * @brief Registers the callback function called when tethering is disabled.
1498  * @param[in]  tethering  The handle of tethering
1499  * @param[in]  type  The type of tethering
1500  * @param[in]  callback  The callback function to invoke
1501  * @param[in]  user_data  The user data to be passed to the callback function
1502  * @retval  #TETHERING_ERROR_NONE  Successful
1503  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1504  * @see  tethering_unset_disabled_cb()
1505  */
1506 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
1507 {
1508         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1509                         "parameter(tethering) is NULL\n");
1510         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1511                         "parameter(callback) is NULL\n");
1512
1513         __tethering_h *th = (__tethering_h *)tethering;
1514         tethering_type_e ti;
1515
1516         if (type != TETHERING_TYPE_ALL) {
1517                 th->disabled_cb[type] = callback;
1518                 th->disabled_user_data[type] = user_data;
1519
1520                 return TETHERING_ERROR_NONE;
1521         }
1522
1523         /* TETHERING_TYPE_ALL */
1524         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1525                 th->disabled_cb[ti] = callback;
1526                 th->disabled_user_data[ti] = user_data;
1527         }
1528
1529         return TETHERING_ERROR_NONE;
1530 }
1531
1532 /**
1533  * @brief Unregisters the callback function called when tethering is disabled.
1534  * @param[in]  tethering  The handle of tethering
1535  * @param[in]  type  The type of tethering
1536  * @retval  #TETHERING_ERROR_NONE  Successful
1537  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1538  * @see  tethering_set_disabled_cb()
1539  */
1540 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
1541 {
1542         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1543                         "parameter(tethering) is NULL\n");
1544
1545         __tethering_h *th = (__tethering_h *)tethering;
1546         tethering_type_e ti;
1547
1548         if (type != TETHERING_TYPE_ALL) {
1549                 th->disabled_cb[type] = NULL;
1550                 th->disabled_user_data[type] = NULL;
1551
1552                 return TETHERING_ERROR_NONE;
1553         }
1554
1555         /* TETHERING_TYPE_ALL */
1556         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1557                 th->disabled_cb[ti] = NULL;
1558                 th->disabled_user_data[ti] = NULL;
1559         }
1560
1561         return TETHERING_ERROR_NONE;
1562 }
1563
1564 /**
1565  * @brief Registers the callback function called when the state of connection is changed.
1566  * @param[in]  tethering  The handle of tethering
1567  * @param[in]  type  The type of tethering
1568  * @param[in]  callback  The callback function to invoke
1569  * @param[in]  user_data  The user data to be passed to the callback function
1570  * @retval  #TETHERING_ERROR_NONE  Successful
1571  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1572  * @see  tethering_unset_connection_state_changed_cb_cb()
1573  */
1574 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
1575 {
1576         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1577                         "parameter(tethering) is NULL\n");
1578         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1579                         "parameter(callback) is NULL\n");
1580
1581         __tethering_h *th = (__tethering_h *)tethering;
1582         tethering_type_e ti;
1583
1584         if (type != TETHERING_TYPE_ALL) {
1585                 th->changed_cb[type] = callback;
1586                 th->changed_user_data[type] = user_data;
1587
1588                 return TETHERING_ERROR_NONE;
1589         }
1590
1591         /* TETHERING_TYPE_ALL */
1592         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1593                 th->changed_cb[ti] = callback;
1594                 th->changed_user_data[ti] = user_data;
1595         }
1596
1597         return TETHERING_ERROR_NONE;
1598 }
1599
1600 /**
1601  * @brief Unregisters the callback function called when the state of connection is changed.
1602  * @param[in]  tethering  The handle of tethering
1603  * @param[in]  type  The type of tethering
1604  * @retval  #TETHERING_ERROR_NONE  Successful
1605  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1606  * @see  tethering_set_connection_state_changed_cb()
1607  */
1608 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
1609 {
1610         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1611                         "parameter(tethering) is NULL\n");
1612
1613         __tethering_h *th = (__tethering_h *)tethering;
1614         tethering_type_e ti;
1615
1616         if (type != TETHERING_TYPE_ALL) {
1617                 th->changed_cb[type] = NULL;
1618                 th->changed_user_data[type] = NULL;
1619
1620                 return TETHERING_ERROR_NONE;
1621         }
1622
1623         /* TETHERING_TYPE_ALL */
1624         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1625                 th->changed_cb[ti] = NULL;
1626                 th->changed_user_data[ti] = NULL;
1627         }
1628
1629         return TETHERING_ERROR_NONE;
1630 }
1631
1632 /**
1633  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
1634  * @param[in]  tethering  The handle of tethering
1635  * @param[in]  callback  The callback function to invoke
1636  * @param[in]  user_data  The user data to be passed to the callback function
1637  * @retval  #TETHERING_ERROR_NONE  Successful
1638  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1639  * @see  tethering_wifi_unset_security_type_changed_cb()
1640  */
1641 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
1642 {
1643         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1644                         "parameter(tethering) is NULL\n");
1645         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1646                         "parameter(callback) is NULL\n");
1647
1648         __tethering_h *th = (__tethering_h *)tethering;
1649
1650         th->security_type_changed_cb = callback;
1651         th->security_type_user_data = user_data;
1652
1653         return TETHERING_ERROR_NONE;
1654
1655 }
1656
1657 /**
1658  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
1659  * @param[in]  tethering  The handle of tethering
1660  * @param[in]  type  The type of tethering
1661  * @retval  #TETHERING_ERROR_NONE  Successful
1662  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1663  * @see  tethering_wifi_set_security_type_changed_cb()
1664  */
1665 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
1666 {
1667         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1668                         "parameter(tethering) is NULL\n");
1669
1670         __tethering_h *th = (__tethering_h *)tethering;
1671
1672         th->security_type_changed_cb = NULL;
1673         th->security_type_user_data = NULL;
1674
1675         return TETHERING_ERROR_NONE;
1676 }
1677
1678 /**
1679  * @brief Registers the callback function called when the visibility of SSID is changed.
1680  * @param[in]  tethering  The handle of tethering
1681  * @param[in]  callback  The callback function to invoke
1682  * @param[in]  user_data  The user data to be passed to the callback function
1683  * @retval  #TETHERING_ERROR_NONE  Successful
1684  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1685  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
1686  */
1687 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
1688 {
1689         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1690                         "parameter(tethering) is NULL\n");
1691         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1692                         "parameter(callback) is NULL\n");
1693
1694         __tethering_h *th = (__tethering_h *)tethering;
1695
1696         th->ssid_visibility_changed_cb = callback;
1697         th->ssid_visibility_user_data = user_data;
1698
1699         return TETHERING_ERROR_NONE;
1700 }
1701
1702 /**
1703  * @brief Unregisters the callback function called when the visibility of SSID is changed.
1704  * @param[in]  tethering  The handle of tethering
1705  * @retval  #TETHERING_ERROR_NONE  Successful
1706  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1707  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
1708  */
1709 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
1710 {
1711         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1712                         "parameter(tethering) is NULL\n");
1713
1714         __tethering_h *th = (__tethering_h *)tethering;
1715
1716         th->ssid_visibility_changed_cb = NULL;
1717         th->ssid_visibility_user_data = NULL;
1718
1719         return TETHERING_ERROR_NONE;
1720 }
1721
1722 /**
1723  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
1724  * @param[in]  tethering  The handle of tethering
1725  * @param[in]  callback  The callback function to invoke
1726  * @param[in]  user_data  The user data to be passed to the callback function
1727  * @retval  #TETHERING_ERROR_NONE  Successful
1728  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1729  * @see  tethering_wifi_unset_passphrase_changed_cb()
1730  */
1731 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
1732 {
1733         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1734                         "parameter(tethering) is NULL\n");
1735         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1736                         "parameter(callback) is NULL\n");
1737
1738         __tethering_h *th = (__tethering_h *)tethering;
1739
1740         th->passphrase_changed_cb = callback;
1741         th->passphrase_user_data = user_data;
1742
1743         return TETHERING_ERROR_NONE;
1744 }
1745
1746 /**
1747  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
1748  * @param[in]  tethering  The handle of tethering
1749  * @retval  #TETHERING_ERROR_NONE  Successful
1750  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1751  * @see  tethering_wifi_set_passphrase_changed_cb()
1752  */
1753 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
1754 {
1755         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1756                         "parameter(tethering) is NULL\n");
1757
1758         __tethering_h *th = (__tethering_h *)tethering;
1759
1760         th->passphrase_changed_cb = NULL;
1761         th->passphrase_user_data = NULL;
1762
1763         return TETHERING_ERROR_NONE;
1764 }
1765
1766 /**
1767  * @brief Sets the security type of Wi-Fi tethering.
1768  * @remarks This change is applied next time Wi-Fi tethering is enabled
1769  * @param[in]  tethering  The handle of tethering
1770  * @param[in]  type  The security type
1771  * @return 0 on success, otherwise negative error value.
1772  * @retval  #TETHERING_ERROR_NONE  Successful
1773  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1774  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1775  * @see  tethering_wifi_get_security_type()
1776  */
1777 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
1778 {
1779         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1780                         "parameter(tethering) is NULL\n");
1781         DBG("+\n");
1782
1783         __tethering_h *th = (__tethering_h *)tethering;
1784         DBusGProxy *proxy = th->client_bus_proxy;
1785         char *type_str = NULL;
1786
1787         if (type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
1788                 type_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
1789         } else if (type == TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) {
1790                 type_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
1791         } else {
1792                 ERR("Unsupported type\n");
1793                 return TETHERING_ERROR_INVALID_PARAMETER;
1794         }
1795
1796         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED,
1797                         G_CALLBACK(__handle_security_type_changed),
1798                         (gpointer)tethering);
1799
1800         org_tizen_tethering_set_wifi_tethering_security_type_async(proxy, type_str,
1801                         __wifi_set_security_type_cb, (gpointer)tethering);
1802
1803         DBG("-\n");
1804         return TETHERING_ERROR_NONE;
1805 }
1806
1807 /**
1808  * @brief Gets the security type of Wi-Fi tethering.
1809  * @param[in]  tethering  The handle of tethering
1810  * @param[out]  type  The security type
1811  * @return 0 on success, otherwise negative error value.
1812  * @retval  #TETHERING_ERROR_NONE  Successful
1813  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1814  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1815  * @see  tethering_wifi_set_security_type()
1816  */
1817 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
1818 {
1819         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1820                         "parameter(tethering) is NULL\n");
1821         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1822                         "parameter(type) is NULL\n");
1823         DBG("+\n");
1824
1825         __tethering_h *th = (__tethering_h *)tethering;
1826         DBusGProxy *proxy = th->client_bus_proxy;
1827         GError *error = NULL;
1828         char *type_str = NULL;
1829
1830         org_tizen_tethering_get_wifi_tethering_security_type(proxy, &type_str, &error);
1831         if (error != NULL) {
1832                 ERR("DBus fail : %s\n", error->message);
1833                 g_error_free(error);
1834                 return TETHERING_ERROR_OPERATION_FAILED;
1835         }
1836
1837         if (type_str == NULL)
1838                 return TETHERING_ERROR_OPERATION_FAILED;
1839
1840         DBG("security type : %s\n", type_str);
1841         if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
1842                 *type = TETHERING_WIFI_SECURITY_TYPE_NONE;
1843         else if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
1844                 *type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1845         else {
1846                 ERR("Unknown security type : %s\n", type_str);
1847                 g_free(type_str);
1848                 return TETHERING_ERROR_OPERATION_FAILED;
1849         }
1850
1851         g_free(type_str);
1852
1853         DBG("-\n");
1854         return TETHERING_ERROR_NONE;
1855 }
1856
1857 /**
1858  * @brief Sets the SSID (service set identifier).
1859  * @details If SSID is not set, Device name is used as SSID
1860  * @remarks This change is applied next time Wi-Fi tethering is enabled with same @a tethering handle
1861  * @param[in]  tethering  The handle of tethering
1862  * @param[out]  ssid  The SSID
1863  * @return 0 on success, otherwise negative error value.
1864  * @retval  #TETHERING_ERROR_NONE  Successful
1865  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1866  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1867  */
1868 int tethering_wifi_set_ssid(tethering_h tethering, const char *ssid)
1869 {
1870         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1871                         "parameter(tethering) is NULL\n");
1872         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1873                         "parameter(ssid) is NULL\n");
1874
1875         __tethering_h *th = (__tethering_h *)tethering;
1876         char *p_ssid;
1877         int ssid_len;
1878
1879         ssid_len = strlen(ssid);
1880         if (ssid_len > TETHERING_WIFI_SSID_MAX_LEN) {
1881                 ERR("parameter(ssid) is too long");
1882                 return TETHERING_ERROR_INVALID_PARAMETER;
1883         }
1884
1885         p_ssid = strdup(ssid);
1886         _retvm_if(p_ssid == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1887                         "strdup is failed\n");
1888
1889         if (th->ssid)
1890                 free(th->ssid);
1891         th->ssid = p_ssid;
1892
1893         return TETHERING_ERROR_NONE;
1894 }
1895
1896 /**
1897  * @brief Gets the SSID (service set identifier).
1898  * @remarks @a ssid must be released with free() by you.
1899  * @param[in]  tethering  The handle of tethering
1900  * @param[out]  ssid  The SSID
1901  * @return 0 on success, otherwise negative error value.
1902  * @retval  #TETHERING_ERROR_NONE  Successful
1903  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1904  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1905  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1906  */
1907 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
1908 {
1909         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1910                         "parameter(tethering) is NULL\n");
1911         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1912                         "parameter(ssid) is NULL\n");
1913         DBG("+\n");
1914
1915         __tethering_h *th = (__tethering_h *)tethering;
1916         DBusGProxy *proxy = th->client_bus_proxy;
1917         GError *error = NULL;
1918         char *ssid_buf = NULL;
1919
1920         if (tethering_is_enabled(NULL, TETHERING_TYPE_WIFI) == false &&
1921                         th->ssid != NULL) {
1922                 DBG("Private SSID is set : %s\n", th->ssid);
1923                 *ssid = strdup(th->ssid);
1924                 if (*ssid == NULL) {
1925                         ERR("Memory allocation failed\n");
1926                         return TETHERING_ERROR_OUT_OF_MEMORY;
1927                 }
1928                 DBG("-\n");
1929                 return TETHERING_ERROR_NONE;
1930         }
1931
1932         org_tizen_tethering_get_wifi_tethering_ssid(proxy, &ssid_buf, &error);
1933         if (error != NULL) {
1934                 ERR("dbus fail : %s\n", error->message);
1935                 g_error_free(error);
1936                 return TETHERING_ERROR_OPERATION_FAILED;
1937         }
1938
1939         if (ssid_buf == NULL)
1940                 return TETHERING_ERROR_OPERATION_FAILED;
1941
1942         *ssid = strdup(ssid_buf);
1943         if (*ssid == NULL) {
1944                 ERR("Memory allocation failed\n");
1945                 return TETHERING_ERROR_OUT_OF_MEMORY;
1946         }
1947
1948         g_free(ssid_buf);
1949
1950         DBG("-\n");
1951         return TETHERING_ERROR_NONE;
1952 }
1953
1954 /**
1955  * @brief Sets the visibility of SSID(service set identifier).
1956  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
1957  * @remarks This change is applied next time Wi-Fi tethering is enabled
1958  * @param[in]  tethering  The handle of tethering
1959  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
1960  * @return 0 on success, otherwise negative error value.
1961  * @retval  #TETHERING_ERROR_NONE  Successful
1962  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1963  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1964  * @see  tethering_wifi_get_ssid_visibility()
1965  */
1966 API int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
1967 {
1968         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1969                         "parameter(tethering) is NULL\n");
1970         DBG("+\n");
1971
1972         __tethering_h *th = (__tethering_h *)tethering;
1973         DBusGProxy *proxy = th->client_bus_proxy;
1974         int hide_mode = 0;
1975
1976         if (visible)
1977                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_OFF;
1978         else
1979                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_ON;
1980
1981         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
1982                         G_CALLBACK(__handle_ssid_visibility_changed),
1983                         (gpointer)tethering);
1984
1985         org_tizen_tethering_set_wifi_tethering_hide_mode_async(proxy, hide_mode,
1986                         __wifi_set_ssid_visibility_cb, (gpointer)tethering);
1987
1988         DBG("-\n");
1989         return TETHERING_ERROR_NONE;
1990 }
1991
1992 /**
1993  * @brief Gets the visibility of SSID(service set identifier).
1994  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
1995  * @param[in]  tethering  The handle of tethering
1996  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
1997  * @return 0 on success, otherwise negative error value.
1998  * @retval  #TETHERING_ERROR_NONE  Successful
1999  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2000  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2001  * @see  tethering_wifi_set_ssid_visibility()
2002  */
2003 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
2004 {
2005         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2006                         "parameter(tethering) is NULL\n");
2007         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2008                         "parameter(visible) is NULL\n");
2009         DBG("+\n");
2010
2011         __tethering_h *th = (__tethering_h *)tethering;
2012         DBusGProxy *proxy = th->client_bus_proxy;
2013         GError *error = NULL;
2014         int hide_mode = 0;
2015
2016         org_tizen_tethering_get_wifi_tethering_hide_mode(proxy, &hide_mode, &error);
2017         if (error != NULL) {
2018                 ERR("dbus fail : %s\n", error->message);
2019                 g_error_free(error);
2020                 return TETHERING_ERROR_OPERATION_FAILED;
2021         }
2022         DBG("hide mode : %d\n", hide_mode);
2023
2024         if (hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF)
2025                 *visible = true;
2026         else
2027                 *visible = false;
2028
2029         DBG("-\n");
2030         return TETHERING_ERROR_NONE;
2031 }
2032
2033 /**
2034  * @brief Sets the passphrase.
2035  * @remarks This change is applied next time Wi-Fi tethering is enabled
2036  * @param[in]  tethering  The handle of tethering
2037  * @param[in]  passphrase  The passphrase
2038  * @return 0 on success, otherwise negative error value.
2039  * @retval  #TETHERING_ERROR_NONE  Successful
2040  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2041  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2042  * @see  tethering_wifi_get_passphrase()
2043  */
2044 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
2045 {
2046         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2047                         "parameter(tethering) is NULL\n");
2048         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2049                         "parameter(passphrase) is NULL\n");
2050         DBG("+\n");
2051
2052         __tethering_h *th = (__tethering_h *)tethering;
2053         DBusGProxy *proxy = th->client_bus_proxy;
2054         int passphrase_len;
2055
2056         passphrase_len = strlen(passphrase);
2057         if (passphrase_len < TETHERING_WIFI_KEY_MIN_LEN ||
2058                         passphrase_len > TETHERING_WIFI_KEY_MAX_LEN) {
2059                 ERR("parameter(passphrase) is too short or long\n");
2060                 return TETHERING_ERROR_INVALID_PARAMETER;
2061         }
2062
2063         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED,
2064                         G_CALLBACK(__handle_passphrase_changed),
2065                         (gpointer)tethering);
2066
2067         org_tizen_tethering_set_wifi_tethering_passphrase_async(proxy,
2068                         passphrase, passphrase_len,
2069                         __wifi_set_passphrase_cb, (gpointer)tethering);
2070
2071         DBG("-\n");
2072         return TETHERING_ERROR_NONE;
2073 }
2074
2075 /**
2076  * @brief Gets the passphrase.
2077  * @remarks @a passphrase must be released with free() by you.
2078  * @param[in]  tethering  The handle of tethering
2079  * @param[out]  passphrase  The passphrase
2080  * @return 0 on success, otherwise negative error value.
2081  * @retval  #TETHERING_ERROR_NONE  Successful
2082  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2083  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2084  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2085  * @see  tethering_wifi_set_passphrase()
2086  */
2087 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
2088 {
2089         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2090                         "parameter(tethering) is NULL\n");
2091         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2092                         "parameter(passphrase) is NULL\n");
2093         DBG("+\n");
2094
2095         __tethering_h *th = (__tethering_h *)tethering;
2096         DBusGProxy *proxy = th->client_bus_proxy;
2097         GError *error = NULL;
2098         char *passphrase_buf = NULL;
2099         unsigned int len = 0;
2100
2101         org_tizen_tethering_get_wifi_tethering_passphrase(proxy,
2102                         &passphrase_buf, &len, &error);
2103         if (error != NULL) {
2104                 ERR("dbus fail : %s\n", error->message);
2105                 g_error_free(error);
2106                 return TETHERING_ERROR_OPERATION_FAILED;
2107         }
2108
2109         if (passphrase_buf == NULL)
2110                 return TETHERING_ERROR_OPERATION_FAILED;
2111
2112         *passphrase = strdup(passphrase_buf);
2113         if (*passphrase == NULL) {
2114                 ERR("Memory allocation failed\n");
2115                 return TETHERING_ERROR_OUT_OF_MEMORY;
2116         }
2117
2118         g_free(passphrase_buf);
2119
2120         DBG("-\n");
2121         return TETHERING_ERROR_NONE;
2122 }