Fix API's description
[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         g_type_init();
842         th->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
843         if (error) {
844                 ERR("Couldn't connect to the System bus[%s]", error->message);
845                 g_error_free(error);
846                 free(th);
847                 return TETHERING_ERROR_OPERATION_FAILED;
848         }
849
850         th->client_bus_proxy = dbus_g_proxy_new_for_name(th->client_bus,
851                         TETHERING_SERVICE_NAME,
852                         TETHERING_SERVICE_OBJECT_PATH,
853                         TETHERING_SERVICE_INTERFACE);
854         if (!th->client_bus_proxy) {
855                 ERR("Couldn't create the proxy object");
856                 dbus_g_connection_unref(th->client_bus);
857                 free(th);
858                 return TETHERING_ERROR_OPERATION_FAILED;
859         }
860
861         __connect_signals((tethering_h)th);
862
863         *tethering = (tethering_h)th;
864         DBG("Tethering Handle : 0x%X\n", th);
865
866         return TETHERING_ERROR_NONE;
867 }
868
869 /**
870  * @brief  Destroys the handle of tethering.
871  * @param[in]  tethering  The handle of tethering
872  * @return  0 on success, otherwise a negative error value.
873  * @retval  #TETHERING_ERROR_NONE  Successful
874  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
875  * @see  tethering_create()
876  */
877 API int tethering_destroy(tethering_h tethering)
878 {
879         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
880                         "parameter(tethering) is NULL\n");
881
882         __tethering_h *th = (__tethering_h *)tethering;
883
884         DBG("Tethering Handle : 0x%X\n", th);
885         __disconnect_signals(tethering);
886
887         org_tizen_tethering_deinit_async(th->client_bus_proxy, __deinit_cb,
888                         (gpointer)tethering);
889
890         g_object_unref(th->client_bus_proxy);
891         dbus_g_connection_unref(th->client_bus);
892         memset(th, 0x00, sizeof(__tethering_h));
893         free(th);
894
895         return TETHERING_ERROR_NONE;
896 }
897
898 /**
899  * @brief Enables the tethering, asynchronously.
900  * @param[in]  tethering  The handle of tethering
901  * @param[in]  type  The type of tethering
902  * @return 0 on success, otherwise negative error value.
903  * @retval  #TETHERING_ERROR_NONE  Successful
904  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
905  * @post tethering_enabled_cb() will be invoked.
906  * @see  tethering_is_enabled()
907  * @see  tethering_disable()
908  */
909 int tethering_enable(tethering_h tethering, tethering_type_e type)
910 {
911         DBG("+\n");
912
913         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
914                         "parameter(tethering) is NULL\n");
915
916         __tethering_h *th = (__tethering_h *)tethering;
917         DBusGProxy *proxy = th->client_bus_proxy;
918
919         switch (type) {
920         case TETHERING_TYPE_USB:
921                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
922                                 G_CALLBACK(__handle_usb_tether_on),
923                                 (gpointer)tethering);
924                 org_tizen_tethering_enable_usb_tethering_async(proxy,
925                                 __cfm_cb, (gpointer)tethering);
926                 break;
927
928         case TETHERING_TYPE_WIFI:
929                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
930                                 G_CALLBACK(__handle_wifi_tether_on),
931                                 (gpointer)tethering);
932                 org_tizen_tethering_enable_wifi_tethering_async(proxy, "", "", false,
933                                 __cfm_cb, (gpointer)tethering);
934                 break;
935
936         case TETHERING_TYPE_BT:
937                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
938                                 G_CALLBACK(__handle_bt_tether_on),
939                                 (gpointer)tethering);
940                 org_tizen_tethering_enable_bt_tethering_async(proxy,
941                                 __cfm_cb, (gpointer)tethering);
942
943                 break;
944
945         case TETHERING_TYPE_ALL:
946                 /* TETHERING_TYPE_USB */
947                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
948                                 G_CALLBACK(__handle_usb_tether_on),
949                                 (gpointer)tethering);
950                 org_tizen_tethering_enable_usb_tethering_async(proxy,
951                                 __cfm_cb, (gpointer)tethering);
952
953                 /* TETHERING_TYPE_WIFI */
954                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
955                                 G_CALLBACK(__handle_wifi_tether_on),
956                                 (gpointer)tethering);
957                 org_tizen_tethering_enable_wifi_tethering_async(proxy, "", "", false,
958                                 __cfm_cb, (gpointer)tethering);
959
960                 /* TETHERING_TYPE_BT */
961                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
962                                 G_CALLBACK(__handle_bt_tether_on),
963                                 (gpointer)tethering);
964                 org_tizen_tethering_enable_bt_tethering_async(proxy,
965                                 __cfm_cb, (gpointer)tethering);
966                 break;
967
968         default:
969                 ERR("Unknown type : %d\n", type);
970                 return TETHERING_ERROR_INVALID_PARAMETER;
971         }
972
973         return TETHERING_ERROR_NONE;
974 }
975
976 /**
977  * @brief Disables the tethering, asynchronously.
978  * @param[in]  tethering  The handle of tethering
979  * @param[in]  type  The type of tethering
980  * @return 0 on success, otherwise negative error value.
981  * @retval  #TETHERING_ERROR_NONE  Successful
982  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
983  * @post tethering_disabled_cb() will be invoked.
984  * @see  tethering_is_enabled()
985  * @see  tethering_enable()
986  */
987 API int tethering_disable(tethering_h tethering, tethering_type_e type)
988 {
989         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
990                         "parameter(tethering) is NULL\n");
991
992         __tethering_h *th = (__tethering_h *)tethering;
993         DBusGProxy *proxy = th->client_bus_proxy;
994
995         switch (type) {
996         case TETHERING_TYPE_USB:
997                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
998                                 G_CALLBACK(__handle_usb_tether_off),
999                                 (gpointer)tethering);
1000                 org_tizen_tethering_disable_usb_tethering_async(proxy,
1001                                 __cfm_cb, (gpointer)tethering);
1002                 break;
1003
1004         case TETHERING_TYPE_WIFI:
1005                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
1006                                 G_CALLBACK(__handle_wifi_tether_off),
1007                                 (gpointer)tethering);
1008                 org_tizen_tethering_disable_wifi_tethering_async(proxy,
1009                                 __cfm_cb, (gpointer)tethering);
1010                 break;
1011         case TETHERING_TYPE_BT:
1012                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
1013                                 G_CALLBACK(__handle_bt_tether_off),
1014                                 (gpointer)tethering);
1015                 org_tizen_tethering_disable_bt_tethering_async(proxy,
1016                                 __cfm_cb, (gpointer)tethering);
1017                 break;
1018
1019         case TETHERING_TYPE_ALL:
1020                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
1021                                 G_CALLBACK(__handle_usb_tether_off),
1022                                 (gpointer)tethering);
1023                 org_tizen_tethering_disable_usb_tethering_async(proxy,
1024                                 __cfm_cb, (gpointer)tethering);
1025
1026                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
1027                                 G_CALLBACK(__handle_wifi_tether_off),
1028                                 (gpointer)tethering);
1029                 org_tizen_tethering_disable_wifi_tethering_async(proxy,
1030                                 __cfm_cb, (gpointer)tethering);
1031
1032                 dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
1033                                 G_CALLBACK(__handle_bt_tether_off),
1034                                 (gpointer)tethering);
1035                 org_tizen_tethering_disable_bt_tethering_async(proxy,
1036                                 __cfm_cb, (gpointer)tethering);
1037                 break;
1038
1039         default :
1040                 ERR("Not supported tethering type [%d]\n", type);
1041                 return TETHERING_ERROR_INVALID_PARAMETER;
1042                 break;
1043         }
1044
1045         return TETHERING_ERROR_NONE;
1046 }
1047
1048 /**
1049  * @brief  Checks whetehr the tethering is enabled or not.
1050  * @param[in]  tethering  The handle of tethering
1051  * @param[in]  type  The type of tethering
1052  * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
1053  */
1054 API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
1055 {
1056         int is_on = 0;
1057         int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
1058
1059         if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) {
1060                 return FALSE;
1061         }
1062
1063         switch (type) {
1064         case TETHERING_TYPE_USB:
1065                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
1066                 break;
1067
1068         case TETHERING_TYPE_WIFI:
1069                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
1070                 break;
1071
1072         case TETHERING_TYPE_BT:
1073                 vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
1074                 break;
1075
1076         default:
1077                 ERR("Not supported type : %d\n", type);
1078                 break;
1079         }
1080
1081         return is_on & vconf_type ? true : false;
1082 }
1083
1084 /**
1085  * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
1086  * @remarks @a mac_address must be released with free() by you.
1087  * @param[in]  tethering  The handle of tethering
1088  * @param[in]  type  The type of tethering
1089  * @param[out]  mac_address  The MAC address
1090  * @return  0 on success, otherwise a negative error value.
1091  * @retval  #TETHERING_ERROR_NONE  Successful
1092  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1093  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1094  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1095  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1096  * @pre  tethering must be enabled.
1097  * @see  tethering_is_enabled()
1098  * @see  tethering_enable()
1099  */
1100 int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
1101 {
1102         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1103                         "parameter(tethering) is NULL\n");
1104         _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1105                         "parameter(mac_address) is NULL\n");
1106         _retvm_if(tethering_is_enabled(tethering, type) == false,
1107                         TETHERING_ERROR_NOT_ENABLED,
1108                         "tethering type[%d] is not enabled\n", type);
1109
1110         struct ifreq ifr;
1111         int s = 0;
1112         char *macbuf = NULL;
1113
1114         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1115                         TETHERING_ERROR_OPERATION_FAILED,
1116                         "getting interface name is failed\n");
1117
1118         s = socket(AF_INET, SOCK_DGRAM, 0);
1119         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1120                         "getting socket is failed\n");
1121         if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
1122                 ERR("getting mac is failed\n");
1123                 close(s);
1124                 return TETHERING_ERROR_OPERATION_FAILED;
1125         }
1126         close(s);
1127
1128         macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
1129         _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1130                         "Not enough memory\n");
1131         snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
1132                         (unsigned char)ifr.ifr_hwaddr.sa_data[0],
1133                         (unsigned char)ifr.ifr_hwaddr.sa_data[1],
1134                         (unsigned char)ifr.ifr_hwaddr.sa_data[2],
1135                         (unsigned char)ifr.ifr_hwaddr.sa_data[3],
1136                         (unsigned char)ifr.ifr_hwaddr.sa_data[4],
1137                         (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
1138
1139         *mac_address = macbuf;
1140
1141         return TETHERING_ERROR_NONE;
1142 }
1143
1144 /**
1145  * @brief Gets the name of network interface. For example, usb0.
1146  * @remarks @a interface_name must be released with free() by you.
1147  * @param[in]  tethering  The handle of tethering
1148  * @param[in]  type  The type of tethering
1149  * @param[out]  interface_name  The name of network interface
1150  * @return 0 on success, otherwise negative error value.
1151  * @retval  #TETHERING_ERROR_NONE  Successful
1152  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1153  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1154  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1155  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1156  * @pre  tethering must be enabled.
1157  * @see  tethering_is_enabled()
1158  * @see  tethering_enable()
1159  */
1160 API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
1161 {
1162         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1163                         "parameter(tethering) is NULL\n");
1164         _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1165                         "parameter(interface_name) is NULL\n");
1166         _retvm_if(tethering_is_enabled(tethering, type) == false,
1167                         TETHERING_ERROR_NOT_ENABLED,
1168                         "tethering type[%d] is not enabled\n", type);
1169
1170         char intf[TETHERING_STR_INFO_LEN] = {0, };
1171
1172         _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
1173                         TETHERING_ERROR_OPERATION_FAILED,
1174                         "getting interface name is failed\n");
1175         *interface_name = strdup(intf);
1176         _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1177                         "Not enough memory\n");
1178
1179         return TETHERING_ERROR_NONE;
1180 }
1181
1182 /**
1183  * @brief Gets the local IP address.
1184  * @remarks @a ip_address must be released with free() by you.
1185  * @param[in]  tethering  The handle of tethering
1186  * @param[in]  type  The type of tethering
1187  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1188  * @param[out]  ip_address  The local IP address
1189  * @return 0 on success, otherwise negative error value.
1190  * @retval  #TETHERING_ERROR_NONE  Successful
1191  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1192  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1193  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1194  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1195  * @pre  tethering must be enabled.
1196  * @see  tethering_is_enabled()
1197  * @see  tethering_enable()
1198  */
1199 API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
1200 {
1201         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1202                         "parameter(tethering) is NULL\n");
1203         _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1204                         "parameter(ip_address) is NULL\n");
1205         _retvm_if(tethering_is_enabled(tethering, type) == false,
1206                         TETHERING_ERROR_NOT_ENABLED,
1207                         "tethering type[%d] is not enabled\n", type);
1208
1209         struct ifreq ifr;
1210         int s = 0;
1211         char *ipbuf = NULL;
1212
1213         _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
1214                         TETHERING_ERROR_OPERATION_FAILED,
1215                         "getting interface name is failed\n");
1216
1217         s = socket(AF_INET, SOCK_DGRAM, 0);
1218         _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
1219                         "getting socket is failed\n");
1220         if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
1221                 ERR("ioctl is failed\n");
1222                 close(s);
1223                 return TETHERING_ERROR_OPERATION_FAILED;
1224         }
1225         close(s);
1226
1227         ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
1228         *ip_address = strdup(ipbuf);
1229         _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1230                         "Not enough memory\n");
1231
1232         return TETHERING_ERROR_NONE;
1233 }
1234
1235 /**
1236  * @brief Gets the Gateway address.
1237  * @remarks @a gateway_address must be released with free() by you.
1238  * @param[in]  tethering  The handle of tethering
1239  * @param[in]  type  The type of tethering
1240  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1241  * @param[out]  gateway_address  The local IP address
1242  * @return 0 on success, otherwise negative error value.
1243  * @retval  #TETHERING_ERROR_NONE  Successful
1244  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1245  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1246  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1247  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1248  * @pre  tethering must be enabled.
1249  * @see  tethering_is_enabled()
1250  * @see  tethering_enable()
1251  */
1252 API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
1253 {
1254         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1255                         "parameter(tethering) is NULL\n");
1256         _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1257                         "parameter(gateway_address) is NULL\n");
1258         _retvm_if(tethering_is_enabled(tethering, type) == false,
1259                         TETHERING_ERROR_NOT_ENABLED,
1260                         "tethering type[%d] is not enabled\n", type);
1261
1262         char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
1263
1264         _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
1265                         TETHERING_ERROR_OPERATION_FAILED,
1266                         "getting gateway address is failed\n");
1267
1268         *gateway_address = strdup(gateway_buf);
1269
1270         return TETHERING_ERROR_NONE;
1271 }
1272
1273 /**
1274  * @brief Gets the Subnet Mask.
1275  * @remarks @a subnet_mask must be released with free() by you.
1276  * @param[in]  tethering  The handle of tethering
1277  * @param[in]  type  The type of tethering
1278  * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
1279  * @param[out]  subnet_mask  The local IP address
1280  * @return 0 on success, otherwise negative error value.
1281  * @retval  #TETHERING_ERROR_NONE  Successful
1282  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1283  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1284  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1285  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1286  * @pre  tethering must be enabled.
1287  * @see  tethering_is_enabled()
1288  * @see  tethering_enable()
1289  */
1290 int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
1291 {
1292         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1293                         "parameter(tethering) is NULL\n");
1294         _retvm_if(tethering_is_enabled(tethering, type) == false,
1295                         TETHERING_ERROR_NOT_ENABLED,
1296                         "tethering is not enabled\n");
1297         _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1298                         "parameter(subnet_mask) is NULL\n");
1299
1300         *subnet_mask = strdup(TETHERING_SUBNET_MASK);
1301         _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
1302                         "Not enough memory\n");
1303
1304         return TETHERING_ERROR_NONE;
1305 }
1306
1307 /**
1308  * @brief Gets the data usage.
1309  * @param[in]  tethering  The handle of tethering
1310  * @param[out]  usage  The data usage
1311  * @return 0 on success, otherwise negative error value.
1312  * @retval  #TETHERING_ERROR_NONE  Successful
1313  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1314  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1315  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1316  * @pre  tethering must be enabled.
1317  * @see  tethering_is_enabled()
1318  * @see  tethering_enable()
1319  */
1320 API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
1321 {
1322         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1323                         "parameter(tethering) is NULL\n");
1324         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1325                         "parameter(callback) is NULL\n");
1326         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1327                         TETHERING_ERROR_NOT_ENABLED,
1328                         "tethering is not enabled\n");
1329
1330         __tethering_h *th = (__tethering_h *)tethering;
1331         DBusGProxy *proxy = th->client_bus_proxy;
1332
1333         th->data_usage_cb = callback;
1334         th->data_usage_user_data = user_data;
1335
1336         org_tizen_tethering_get_data_packet_usage_async(proxy,
1337                         __get_data_usage_cb, (gpointer)th);
1338
1339         return TETHERING_ERROR_NONE;
1340 }
1341
1342 /**
1343  * @brief Gets the client which is connected by USB tethering.
1344  * @param[in]  tethering  The handle of tethering
1345  * @param[in]  type  The type of tethering
1346  * @param[in]  callback  The callback function to invoke
1347  * @param[in]  user_data  The user data to be passed to the callback function
1348  * @retval  #TETHERING_ERROR_NONE  Successful
1349  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1350  * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
1351  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1352  * @pre  tethering must be enabled.
1353  * @see  tethering_is_enabled()
1354  * @see  tethering_enable()
1355  */
1356 API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
1357 {
1358         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1359                         "parameter(tethering) is NULL\n");
1360         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1361                         "parameter(callback) is NULL\n");
1362         _retvm_if(__any_tethering_is_enabled(tethering) == false,
1363                         TETHERING_ERROR_NOT_ENABLED,
1364                         "tethering is not enabled\n");
1365
1366         __tethering_h *th = (__tethering_h *)tethering;
1367         __tethering_client_h client = {0, };
1368
1369         guint event = 0;
1370         GPtrArray *array = NULL;
1371         GValue value = {0, {{0}}};
1372         GError *error = NULL;
1373         int i = 0;
1374         int no_of_client = 0;
1375         guint interface = 0;
1376         gchar *ip = NULL;
1377         gchar *mac = NULL;
1378         gchar *hostname = NULL;
1379
1380         org_tizen_tethering_get_station_info(th->client_bus_proxy, &event,
1381                         &array, &error);
1382         if (error != NULL) {
1383                 ERR("DBus fail : %s\n", error->message);
1384                 g_error_free(error);
1385                 return TETHERING_ERROR_OPERATION_FAILED;
1386         }
1387
1388         g_value_init(&value, DBUS_STRUCT_STATIONS);
1389         no_of_client = array->len;
1390         for (i = 0; i < no_of_client; i++) {
1391                 g_value_set_boxed(&value, g_ptr_array_index(array, i));
1392
1393                 dbus_g_type_struct_get(&value, 0, &interface, 1, &ip,
1394                                 2, &mac, 3, &hostname, G_MAXUINT);
1395
1396                 if (interface == MOBILE_AP_TYPE_USB)
1397                         client.interface = TETHERING_TYPE_USB;
1398                 else if (interface == MOBILE_AP_TYPE_WIFI)
1399                         client.interface = TETHERING_TYPE_WIFI;
1400                 else if (interface == MOBILE_AP_TYPE_BT)
1401                         client.interface = TETHERING_TYPE_BT;
1402
1403                 if (client.interface != type && TETHERING_TYPE_ALL != type)
1404                         continue;
1405
1406                 g_strlcpy(client.ip, ip, sizeof(client.ip));
1407                 g_strlcpy(client.mac, mac, sizeof(client.mac));
1408                 g_strlcpy(client.hostname, hostname, sizeof(client.hostname));
1409
1410                 if (callback((tethering_client_h)&client, user_data) == false) {
1411                         DBG("iteration is stopped\n");
1412                         return TETHERING_ERROR_NONE;
1413                 }
1414         }
1415
1416         if (array->len > 0)
1417                 g_ptr_array_free(array, TRUE);
1418
1419         return TETHERING_ERROR_NONE;
1420 }
1421
1422 /**
1423  * @brief Registers the callback function called when tethering is enabled.
1424  * @param[in]  tethering  The handle of tethering
1425  * @param[in]  type  The type of tethering
1426  * @param[in]  callback  The callback function to invoke
1427  * @param[in]  user_data  The user data to be passed to the callback function
1428  * @retval  #TETHERING_ERROR_NONE  Successful
1429  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1430  * @see  tethering_unset_enabled_cb()
1431  */
1432 API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
1433 {
1434         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1435                         "parameter(tethering) is NULL\n");
1436         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1437                         "parameter(callback) is NULL\n");
1438
1439         __tethering_h *th = (__tethering_h *)tethering;
1440         tethering_type_e ti;
1441
1442         if (type != TETHERING_TYPE_ALL) {
1443                 th->enabled_cb[type] = callback;
1444                 th->enabled_user_data[type] = user_data;
1445
1446                 return TETHERING_ERROR_NONE;
1447         }
1448
1449         /* TETHERING_TYPE_ALL */
1450         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1451                 th->enabled_cb[ti] = callback;
1452                 th->enabled_user_data[ti] = user_data;
1453         }
1454
1455         return TETHERING_ERROR_NONE;
1456 }
1457
1458 /**
1459  * @brief Unregisters the callback function called when tethering is disabled.
1460  * @param[in]  tethering  The handle of tethering
1461  * @param[in]  type  The type of tethering
1462  * @retval  #TETHERING_ERROR_NONE  Successful
1463  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1464  * @see  tethering_set_enabled_cb()
1465  */
1466 API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
1467 {
1468         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1469                         "parameter(tethering) is NULL\n");
1470
1471         __tethering_h *th = (__tethering_h *)tethering;
1472         tethering_type_e ti;
1473
1474         if (type != TETHERING_TYPE_ALL) {
1475                 th->enabled_cb[type] = NULL;
1476                 th->enabled_user_data[type] = NULL;
1477
1478                 return TETHERING_ERROR_NONE;
1479         }
1480
1481         /* TETHERING_TYPE_ALL */
1482         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1483                 th->enabled_cb[ti] = NULL;
1484                 th->enabled_user_data[ti] = NULL;
1485         }
1486
1487         return TETHERING_ERROR_NONE;
1488 }
1489
1490 /**
1491  * @brief Registers the callback function called when tethering is disabled.
1492  * @param[in]  tethering  The handle of tethering
1493  * @param[in]  type  The type of tethering
1494  * @param[in]  callback  The callback function to invoke
1495  * @param[in]  user_data  The user data to be passed to the callback function
1496  * @retval  #TETHERING_ERROR_NONE  Successful
1497  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1498  * @see  tethering_unset_disabled_cb()
1499  */
1500 API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
1501 {
1502         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1503                         "parameter(tethering) is NULL\n");
1504         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1505                         "parameter(callback) is NULL\n");
1506
1507         __tethering_h *th = (__tethering_h *)tethering;
1508         tethering_type_e ti;
1509
1510         if (type != TETHERING_TYPE_ALL) {
1511                 th->disabled_cb[type] = callback;
1512                 th->disabled_user_data[type] = user_data;
1513
1514                 return TETHERING_ERROR_NONE;
1515         }
1516
1517         /* TETHERING_TYPE_ALL */
1518         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1519                 th->disabled_cb[ti] = callback;
1520                 th->disabled_user_data[ti] = user_data;
1521         }
1522
1523         return TETHERING_ERROR_NONE;
1524 }
1525
1526 /**
1527  * @brief Unregisters the callback function called when tethering is disabled.
1528  * @param[in]  tethering  The handle of tethering
1529  * @param[in]  type  The type of tethering
1530  * @retval  #TETHERING_ERROR_NONE  Successful
1531  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1532  * @see  tethering_set_disabled_cb()
1533  */
1534 API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
1535 {
1536         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1537                         "parameter(tethering) is NULL\n");
1538
1539         __tethering_h *th = (__tethering_h *)tethering;
1540         tethering_type_e ti;
1541
1542         if (type != TETHERING_TYPE_ALL) {
1543                 th->disabled_cb[type] = NULL;
1544                 th->disabled_user_data[type] = NULL;
1545
1546                 return TETHERING_ERROR_NONE;
1547         }
1548
1549         /* TETHERING_TYPE_ALL */
1550         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1551                 th->disabled_cb[ti] = NULL;
1552                 th->disabled_user_data[ti] = NULL;
1553         }
1554
1555         return TETHERING_ERROR_NONE;
1556 }
1557
1558 /**
1559  * @brief Registers the callback function called when the state of connection is changed.
1560  * @param[in]  tethering  The handle of tethering
1561  * @param[in]  type  The type of tethering
1562  * @param[in]  callback  The callback function to invoke
1563  * @param[in]  user_data  The user data to be passed to the callback function
1564  * @retval  #TETHERING_ERROR_NONE  Successful
1565  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1566  * @see  tethering_unset_connection_state_changed_cb_cb()
1567  */
1568 API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
1569 {
1570         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1571                         "parameter(tethering) is NULL\n");
1572         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1573                         "parameter(callback) is NULL\n");
1574
1575         __tethering_h *th = (__tethering_h *)tethering;
1576         tethering_type_e ti;
1577
1578         if (type != TETHERING_TYPE_ALL) {
1579                 th->changed_cb[type] = callback;
1580                 th->changed_user_data[type] = user_data;
1581
1582                 return TETHERING_ERROR_NONE;
1583         }
1584
1585         /* TETHERING_TYPE_ALL */
1586         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1587                 th->changed_cb[ti] = callback;
1588                 th->changed_user_data[ti] = user_data;
1589         }
1590
1591         return TETHERING_ERROR_NONE;
1592 }
1593
1594 /**
1595  * @brief Unregisters the callback function called when the state of connection is changed.
1596  * @param[in]  tethering  The handle of tethering
1597  * @param[in]  type  The type of tethering
1598  * @retval  #TETHERING_ERROR_NONE  Successful
1599  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1600  * @see  tethering_set_connection_state_changed_cb()
1601  */
1602 API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
1603 {
1604         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1605                         "parameter(tethering) is NULL\n");
1606
1607         __tethering_h *th = (__tethering_h *)tethering;
1608         tethering_type_e ti;
1609
1610         if (type != TETHERING_TYPE_ALL) {
1611                 th->changed_cb[type] = NULL;
1612                 th->changed_user_data[type] = NULL;
1613
1614                 return TETHERING_ERROR_NONE;
1615         }
1616
1617         /* TETHERING_TYPE_ALL */
1618         for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
1619                 th->changed_cb[ti] = NULL;
1620                 th->changed_user_data[ti] = NULL;
1621         }
1622
1623         return TETHERING_ERROR_NONE;
1624 }
1625
1626 /**
1627  * @brief Registers the callback function called when the security type of Wi-Fi tethering is changed.
1628  * @param[in]  tethering  The handle of tethering
1629  * @param[in]  callback  The callback function to invoke
1630  * @param[in]  user_data  The user data to be passed to the callback function
1631  * @retval  #TETHERING_ERROR_NONE  Successful
1632  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1633  * @see  tethering_wifi_unset_security_type_changed_cb()
1634  */
1635 API int tethering_wifi_set_security_type_changed_cb(tethering_h tethering, tethering_wifi_security_type_changed_cb callback, void *user_data)
1636 {
1637         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1638                         "parameter(tethering) is NULL\n");
1639         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1640                         "parameter(callback) is NULL\n");
1641
1642         __tethering_h *th = (__tethering_h *)tethering;
1643
1644         th->security_type_changed_cb = callback;
1645         th->security_type_user_data = user_data;
1646
1647         return TETHERING_ERROR_NONE;
1648
1649 }
1650
1651 /**
1652  * @brief Unregisters the callback function called when the security type of Wi-Fi tethering is changed.
1653  * @param[in]  tethering  The handle of tethering
1654  * @param[in]  type  The type of tethering
1655  * @retval  #TETHERING_ERROR_NONE  Successful
1656  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1657  * @see  tethering_wifi_set_security_type_changed_cb()
1658  */
1659 API int tethering_wifi_unset_security_type_changed_cb(tethering_h tethering)
1660 {
1661         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1662                         "parameter(tethering) is NULL\n");
1663
1664         __tethering_h *th = (__tethering_h *)tethering;
1665
1666         th->security_type_changed_cb = NULL;
1667         th->security_type_user_data = NULL;
1668
1669         return TETHERING_ERROR_NONE;
1670 }
1671
1672 /**
1673  * @brief Registers the callback function called when the visibility of SSID is changed.
1674  * @param[in]  tethering  The handle of tethering
1675  * @param[in]  callback  The callback function to invoke
1676  * @param[in]  user_data  The user data to be passed to the callback function
1677  * @retval  #TETHERING_ERROR_NONE  Successful
1678  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1679  * @see  tethering_wifi_unset_ssid_visibility_changed_cb_cb()
1680  */
1681 API int tethering_wifi_set_ssid_visibility_changed_cb(tethering_h tethering, tethering_wifi_ssid_visibility_changed_cb callback, void *user_data)
1682 {
1683         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1684                         "parameter(tethering) is NULL\n");
1685         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1686                         "parameter(callback) is NULL\n");
1687
1688         __tethering_h *th = (__tethering_h *)tethering;
1689
1690         th->ssid_visibility_changed_cb = callback;
1691         th->ssid_visibility_user_data = user_data;
1692
1693         return TETHERING_ERROR_NONE;
1694 }
1695
1696 /**
1697  * @brief Unregisters the callback function called when the visibility of SSID is changed.
1698  * @param[in]  tethering  The handle of tethering
1699  * @retval  #TETHERING_ERROR_NONE  Successful
1700  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1701  * @see  tethering_wifi_set_ssid_visibility_changed_cb()
1702  */
1703 API int tethering_wifi_unset_ssid_visibility_changed_cb(tethering_h tethering)
1704 {
1705         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1706                         "parameter(tethering) is NULL\n");
1707
1708         __tethering_h *th = (__tethering_h *)tethering;
1709
1710         th->ssid_visibility_changed_cb = NULL;
1711         th->ssid_visibility_user_data = NULL;
1712
1713         return TETHERING_ERROR_NONE;
1714 }
1715
1716 /**
1717  * @brief Registers the callback function called when the passphrase of Wi-Fi tethering is changed.
1718  * @param[in]  tethering  The handle of tethering
1719  * @param[in]  callback  The callback function to invoke
1720  * @param[in]  user_data  The user data to be passed to the callback function
1721  * @retval  #TETHERING_ERROR_NONE  Successful
1722  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1723  * @see  tethering_wifi_unset_passphrase_changed_cb()
1724  */
1725 API int tethering_wifi_set_passphrase_changed_cb(tethering_h tethering, tethering_wifi_passphrase_changed_cb callback, void *user_data)
1726 {
1727         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1728                         "parameter(tethering) is NULL\n");
1729         _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1730                         "parameter(callback) is NULL\n");
1731
1732         __tethering_h *th = (__tethering_h *)tethering;
1733
1734         th->passphrase_changed_cb = callback;
1735         th->passphrase_user_data = user_data;
1736
1737         return TETHERING_ERROR_NONE;
1738 }
1739
1740 /**
1741  * @brief Unregisters the callback function called when the passphrase of Wi-Fi tethering is changed.
1742  * @param[in]  tethering  The handle of tethering
1743  * @retval  #TETHERING_ERROR_NONE  Successful
1744  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1745  * @see  tethering_wifi_set_passphrase_changed_cb()
1746  */
1747 API int tethering_wifi_unset_passphrase_changed_cb(tethering_h tethering)
1748 {
1749         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1750                         "parameter(tethering) is NULL\n");
1751
1752         __tethering_h *th = (__tethering_h *)tethering;
1753
1754         th->passphrase_changed_cb = NULL;
1755         th->passphrase_user_data = NULL;
1756
1757         return TETHERING_ERROR_NONE;
1758 }
1759
1760 /**
1761  * @brief Sets the security type of Wi-Fi tethering.
1762  * @remarks This change is applied next time Wi-Fi tethering is enabled
1763  * @param[in]  tethering  The handle of tethering
1764  * @param[in]  type  The security type
1765  * @return 0 on success, otherwise negative error value.
1766  * @retval  #TETHERING_ERROR_NONE  Successful
1767  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1768  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1769  * @see  tethering_wifi_get_security_type()
1770  */
1771 API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
1772 {
1773         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1774                         "parameter(tethering) is NULL\n");
1775         DBG("+\n");
1776
1777         __tethering_h *th = (__tethering_h *)tethering;
1778         DBusGProxy *proxy = th->client_bus_proxy;
1779         char *type_str = NULL;
1780
1781         if (type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
1782                 type_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
1783         } else if (type == TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) {
1784                 type_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
1785         } else {
1786                 ERR("Unsupported type\n");
1787                 return TETHERING_ERROR_INVALID_PARAMETER;
1788         }
1789
1790         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SECURITY_TYPE_CHANGED,
1791                         G_CALLBACK(__handle_security_type_changed),
1792                         (gpointer)tethering);
1793
1794         org_tizen_tethering_set_wifi_tethering_security_type_async(proxy, type_str,
1795                         __wifi_set_security_type_cb, (gpointer)tethering);
1796
1797         DBG("-\n");
1798         return TETHERING_ERROR_NONE;
1799 }
1800
1801 /**
1802  * @brief Gets the security type of Wi-Fi tethering.
1803  * @param[in]  tethering  The handle of tethering
1804  * @param[out]  type  The security type
1805  * @return 0 on success, otherwise negative error value.
1806  * @retval  #TETHERING_ERROR_NONE  Successful
1807  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1808  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1809  * @see  tethering_wifi_set_security_type()
1810  */
1811 API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
1812 {
1813         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1814                         "parameter(tethering) is NULL\n");
1815         _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1816                         "parameter(type) is NULL\n");
1817         DBG("+\n");
1818
1819         __tethering_h *th = (__tethering_h *)tethering;
1820         DBusGProxy *proxy = th->client_bus_proxy;
1821         GError *error = NULL;
1822         char *type_str = NULL;
1823
1824         org_tizen_tethering_get_wifi_tethering_security_type(proxy, &type_str, &error);
1825         if (error != NULL) {
1826                 ERR("DBus fail : %s\n", error->message);
1827                 g_error_free(error);
1828                 return TETHERING_ERROR_OPERATION_FAILED;
1829         }
1830
1831         if (type_str == NULL)
1832                 return TETHERING_ERROR_OPERATION_FAILED;
1833
1834         DBG("security type : %s\n", type_str);
1835         if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
1836                 *type = TETHERING_WIFI_SECURITY_TYPE_NONE;
1837         else if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
1838                 *type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
1839         else {
1840                 ERR("Unknown security type : %s\n", type_str);
1841                 g_free(type_str);
1842                 return TETHERING_ERROR_OPERATION_FAILED;
1843         }
1844
1845         g_free(type_str);
1846
1847         DBG("-\n");
1848         return TETHERING_ERROR_NONE;
1849 }
1850
1851 /**
1852  * @brief Gets the SSID (service set identifier).
1853  * @remarks @a ssid must be released with free() by you.
1854  * @param[in]  tethering  The handle of tethering
1855  * @param[out]  ssid  The SSID
1856  * @return 0 on success, otherwise negative error value.
1857  * @retval  #TETHERING_ERROR_NONE  Successful
1858  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1859  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
1860  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1861  */
1862 API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
1863 {
1864         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1865                         "parameter(tethering) is NULL\n");
1866         _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1867                         "parameter(ssid) is NULL\n");
1868         DBG("+\n");
1869
1870         __tethering_h *th = (__tethering_h *)tethering;
1871         DBusGProxy *proxy = th->client_bus_proxy;
1872         GError *error = NULL;
1873         char *ssid_buf = NULL;
1874
1875         org_tizen_tethering_get_wifi_tethering_ssid(proxy, &ssid_buf, &error);
1876         if (error != NULL) {
1877                 ERR("dbus fail : %s\n", error->message);
1878                 g_error_free(error);
1879                 return TETHERING_ERROR_OPERATION_FAILED;
1880         }
1881
1882         if (ssid_buf == NULL)
1883                 return TETHERING_ERROR_OPERATION_FAILED;
1884
1885         *ssid = strdup(ssid_buf);
1886         if (*ssid == NULL) {
1887                 ERR("Memory allocation failed\n");
1888                 return TETHERING_ERROR_OUT_OF_MEMORY;
1889         }
1890
1891         g_free(ssid_buf);
1892
1893         DBG("-\n");
1894         return TETHERING_ERROR_NONE;
1895 }
1896
1897 /**
1898  * @brief Sets the visibility of SSID(service set identifier).
1899  * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
1900  * @remarks This change is applied next time Wi-Fi tethering is enabled
1901  * @param[in]  tethering  The handle of tethering
1902  * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
1903  * @return 0 on success, otherwise negative error value.
1904  * @retval  #TETHERING_ERROR_NONE  Successful
1905  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1906  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1907  * @see  tethering_wifi_get_ssid_visibility()
1908  */
1909 int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
1910 {
1911         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1912                         "parameter(tethering) is NULL\n");
1913         DBG("+\n");
1914
1915         __tethering_h *th = (__tethering_h *)tethering;
1916         DBusGProxy *proxy = th->client_bus_proxy;
1917         int hide_mode = 0;
1918
1919         if (visible)
1920                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_OFF;
1921         else
1922                 hide_mode = VCONFKEY_MOBILE_AP_HIDE_ON;
1923
1924         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_SSID_VISIBILITY_CHANGED,
1925                         G_CALLBACK(__handle_ssid_visibility_changed),
1926                         (gpointer)tethering);
1927
1928         org_tizen_tethering_set_wifi_tethering_hide_mode_async(proxy, hide_mode,
1929                         __wifi_set_ssid_visibility_cb, (gpointer)tethering);
1930
1931         DBG("-\n");
1932         return TETHERING_ERROR_NONE;
1933 }
1934
1935 /**
1936  * @brief Gets the visibility of SSID(service set identifier).
1937  * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
1938  * @param[in]  tethering  The handle of tethering
1939  * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
1940  * @return 0 on success, otherwise negative error value.
1941  * @retval  #TETHERING_ERROR_NONE  Successful
1942  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1943  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1944  * @see  tethering_wifi_set_ssid_visibility()
1945  */
1946 API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
1947 {
1948         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1949                         "parameter(tethering) is NULL\n");
1950         _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1951                         "parameter(visible) is NULL\n");
1952         DBG("+\n");
1953
1954         __tethering_h *th = (__tethering_h *)tethering;
1955         DBusGProxy *proxy = th->client_bus_proxy;
1956         GError *error = NULL;
1957         int hide_mode = 0;
1958
1959         org_tizen_tethering_get_wifi_tethering_hide_mode(proxy, &hide_mode, &error);
1960         if (error != NULL) {
1961                 ERR("dbus fail : %s\n", error->message);
1962                 g_error_free(error);
1963                 return TETHERING_ERROR_OPERATION_FAILED;
1964         }
1965         DBG("hide mode : %d\n", hide_mode);
1966
1967         if (hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF)
1968                 *visible = true;
1969         else
1970                 *visible = false;
1971
1972         DBG("-\n");
1973         return TETHERING_ERROR_NONE;
1974 }
1975
1976 /**
1977  * @brief Sets the passphrase.
1978  * @remarks This change is applied next time Wi-Fi tethering is enabled
1979  * @param[in]  tethering  The handle of tethering
1980  * @param[in]  passphrase  The passphrase
1981  * @return 0 on success, otherwise negative error value.
1982  * @retval  #TETHERING_ERROR_NONE  Successful
1983  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
1984  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
1985  * @see  tethering_wifi_get_passphrase()
1986  */
1987 API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
1988 {
1989         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1990                         "parameter(tethering) is NULL\n");
1991         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
1992                         "parameter(passphrase) is NULL\n");
1993         DBG("+\n");
1994
1995         __tethering_h *th = (__tethering_h *)tethering;
1996         DBusGProxy *proxy = th->client_bus_proxy;
1997
1998         dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_PASSPHRASE_CHANGED,
1999                         G_CALLBACK(__handle_passphrase_changed),
2000                         (gpointer)tethering);
2001
2002         org_tizen_tethering_set_wifi_tethering_passphrase_async(proxy,
2003                         passphrase, strlen(passphrase),
2004                         __wifi_set_passphrase_cb, (gpointer)tethering);
2005
2006         DBG("-\n");
2007         return TETHERING_ERROR_NONE;
2008 }
2009
2010 /**
2011  * @brief Gets the passphrase.
2012  * @remarks @a passphrase must be released with free() by you.
2013  * @param[in]  tethering  The handle of tethering
2014  * @param[out]  passphrase  The passphrase
2015  * @return 0 on success, otherwise negative error value.
2016  * @retval  #TETHERING_ERROR_NONE  Successful
2017  * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
2018  * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
2019  * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
2020  * @see  tethering_wifi_set_passphrase()
2021  */
2022 API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
2023 {
2024         _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2025                         "parameter(tethering) is NULL\n");
2026         _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
2027                         "parameter(passphrase) is NULL\n");
2028         DBG("+\n");
2029
2030         __tethering_h *th = (__tethering_h *)tethering;
2031         DBusGProxy *proxy = th->client_bus_proxy;
2032         GError *error = NULL;
2033         char *passphrase_buf = NULL;
2034         unsigned int len = 0;
2035
2036         org_tizen_tethering_get_wifi_tethering_passphrase(proxy,
2037                         &passphrase_buf, &len, &error);
2038         if (error != NULL) {
2039                 ERR("dbus fail : %s\n", error->message);
2040                 g_error_free(error);
2041                 return TETHERING_ERROR_OPERATION_FAILED;
2042         }
2043
2044         if (passphrase_buf == NULL)
2045                 return TETHERING_ERROR_OPERATION_FAILED;
2046
2047         *passphrase = strdup(passphrase_buf);
2048         if (*passphrase == NULL) {
2049                 ERR("Memory allocation failed\n");
2050                 return TETHERING_ERROR_OUT_OF_MEMORY;
2051         }
2052
2053         g_free(passphrase_buf);
2054
2055         DBG("-\n");
2056         return TETHERING_ERROR_NONE;
2057 }