Source code upload
[platform/core/api/tethering.git] / test / tethering_test.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 <unistd.h>
21 #include <glib.h>
22 #include <glib-object.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
26
27 #include <vconf.h>
28
29 #include "tethering.h"
30
31 #define INPUT_BUF_LEN           32
32 #define DISABLE_REASON_TEXT_LEN 64
33 #define COMMON_STR_BUF_LEN      32
34
35 typedef struct {
36         tethering_enabled_cb enabled_cb;
37         tethering_disabled_cb disabled_cb;
38         tethering_connection_state_changed_cb changed_cb;
39 } __tethering_cbs;
40
41 static GMainLoop *mainloop = NULL;
42
43 static bool __is_err(tethering_error_e ret)
44 {
45         char *err_msg = NULL;
46
47         switch (ret) {
48         case TETHERING_ERROR_INVALID_PARAMETER:
49                 err_msg = "Wrong parameter is used";
50                 break;
51
52         case TETHERING_ERROR_OUT_OF_MEMORY:
53                 err_msg = "Memory is not enough";
54                 break;
55
56         case TETHERING_ERROR_NONE:
57                 return false;
58
59         case TETHERING_ERROR_NOT_ENABLED:
60                 err_msg = "Tethering is not enabled";
61                 break;
62
63         case TETHERING_ERROR_OPERATION_FAILED:
64                 err_msg = "Operation is failed";
65                 break;
66
67         case TETHERING_ERROR_RESOURCE_BUSY:
68                 err_msg = "Resource is busy";
69                 break;
70
71         default:
72                 err_msg = "This should not be happened";
73                 break;
74         }
75
76         g_print("%s\n", err_msg);
77
78         return true;
79 }
80
81 static const char *__convert_tethering_type_to_str(const tethering_type_e type)
82 {
83         static char str_buf[COMMON_STR_BUF_LEN] = {0, };
84
85         switch (type) {
86         case TETHERING_TYPE_USB:
87                 g_strlcpy(str_buf, "USB", sizeof(str_buf));
88                 break;
89
90         case TETHERING_TYPE_WIFI:
91                 g_strlcpy(str_buf, "Wi-Fi", sizeof(str_buf));
92                 break;
93
94         case TETHERING_TYPE_BT:
95                 g_strlcpy(str_buf, "Bluetooth", sizeof(str_buf));
96                 break;
97
98         default:
99                 g_strlcpy(str_buf, "Unknown", sizeof(str_buf));
100                 break;
101         }
102
103         return str_buf;
104 }
105
106 static const char *__convert_disabled_code_to_str(const tethering_disabled_cause_e code)
107 {
108         static char str_buf[DISABLE_REASON_TEXT_LEN] = {0, };
109
110         switch (code) {
111         case TETHERING_DISABLED_BY_USB_DISCONNECTION:
112                 strncpy(str_buf, "disabled due to usb disconnection", sizeof(str_buf));
113                 break;
114
115         case TETHERING_DISABLED_BY_FLIGHT_MODE:
116                 strncpy(str_buf, "disabled due to flight mode on", sizeof(str_buf));
117                 break;
118
119         case TETHERING_DISABLED_BY_LOW_BATTERY:
120                 strncpy(str_buf, "disabled due to low battery", sizeof(str_buf));
121                 break;
122
123         case TETHERING_DISABLED_BY_NETWORK_CLOSE:
124                 strncpy(str_buf, "disabled due to pdp network close", sizeof(str_buf));
125                 break;
126
127         case TETHERING_DISABLED_BY_TIMEOUT:
128                 strncpy(str_buf, "disabled due to timeout", sizeof(str_buf));
129                 break;
130
131         case TETHERING_DISABLED_BY_MDM_ON:
132                 strncpy(str_buf, "disabled due to mdm on", sizeof(str_buf));
133                 break;
134
135         case TETHERING_DISABLED_BY_OTHERS:
136                 strncpy(str_buf, "disabled by other apps", sizeof(str_buf));
137                 break;
138
139         case TETHERING_DISABLED_BY_REQUEST:
140                 strncpy(str_buf, "disabled by my request", sizeof(str_buf));
141                 break;
142
143         case TETHERING_DISABLED_BY_WIFI_ON:
144                 strncpy(str_buf, "disabled by Wi-Fi station on", sizeof(str_buf));
145                 break;
146
147         case TETHERING_DISABLED_BY_BT_OFF:
148                 strncpy(str_buf, "disabled by bluetooth off", sizeof(str_buf));
149                 break;
150
151         default:
152                 strncpy(str_buf, "disabled by unknown reason", sizeof(str_buf));
153                 break;
154         }
155
156         return str_buf;
157 }
158
159 static void __register_cbs(tethering_h th, __tethering_cbs *cbs, void *user_data)
160 {
161         tethering_error_e ret = TETHERING_ERROR_NONE;
162
163         ret = tethering_set_enabled_cb(th, TETHERING_TYPE_ALL,
164                         cbs->enabled_cb, user_data);
165         if (__is_err(ret) == true) {
166                 g_print("tethering_set_enabled_cb is failed\n");
167         }
168
169         ret = tethering_set_disabled_cb(th, TETHERING_TYPE_ALL,
170                         cbs->disabled_cb, user_data);
171         if (__is_err(ret) == true) {
172                 g_print("tethering_set_disabled_cb is failed\n");
173         }
174
175         ret = tethering_set_connection_state_changed_cb(th, TETHERING_TYPE_ALL,
176                         cbs->changed_cb, user_data);
177         if (__is_err(ret) == true) {
178                 g_print("tethering_set_connection_state_changed_cb is failed\n");
179         }
180
181         return;
182 }
183
184 static void __deregister_cbs(tethering_h th)
185 {
186         tethering_error_e ret = TETHERING_ERROR_NONE;
187
188         ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_ALL);
189         if (__is_err(ret) == true) {
190                 g_print("tethering_unset_enabled_cb is failed\n");
191         }
192
193         ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_ALL);
194         if (__is_err(ret) == true) {
195                 g_print("tethering_unset_disabled_cb is failed\n");
196         }
197
198         ret = tethering_unset_connection_state_changed_cb(th, TETHERING_TYPE_ALL);
199         if (__is_err(ret) == true) {
200                 g_print("tethering_unset_connection_state_changed_cb is failed\n");
201         }
202
203         return;
204 }
205
206 /* Tethering callbacks */
207 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
208 {
209         if (error != TETHERING_ERROR_NONE) {
210                 if (!is_requested) {
211                         return;
212                 }
213
214                 g_print("## %s tethering is not enabled. error code[0x%X]\n",
215                                 __convert_tethering_type_to_str(type),
216                                 error);
217                 return;
218         }
219
220         if (is_requested)
221                 g_print("## %s tethering is enabled successfully\n",
222                                 __convert_tethering_type_to_str(type));
223         else
224                 g_print("## %s tethering is enabled by other app\n",
225                                 __convert_tethering_type_to_str(type));
226
227         return;
228 }
229
230 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
231 {
232         if (error != TETHERING_ERROR_NONE) {
233                 if (code != TETHERING_DISABLED_BY_REQUEST) {
234                         return;
235                 }
236
237                 g_print("## %s tethering is not disabled. error code[0x%X]\n",
238                                 __convert_tethering_type_to_str(type), error);
239                 return;
240         }
241
242         g_print("## %s tethering is %s\n",
243                         __convert_tethering_type_to_str(type),
244                         __convert_disabled_code_to_str(code));
245
246         return;
247 }
248
249 static void __connection_state_changed_cb(tethering_client_h client, bool open, void *data)
250 {
251         tethering_client_h clone = NULL;
252         tethering_type_e type;
253         char *ip_address = NULL;
254         char *mac_address = NULL;
255         char *hostname = NULL;
256
257         tethering_client_clone(&clone, client);
258         if (clone == NULL) {
259                 g_print("tetheirng_client_clone is failed\n");
260                 return;
261         }
262
263         tethering_client_get_tethering_type(clone, &type);
264         tethering_client_get_ip_address(clone,
265                         TETHERING_ADDRESS_FAMILY_IPV4, &ip_address);
266         tethering_client_get_mac_address(clone, &mac_address);
267         tethering_client_get_name(clone, &hostname);
268
269         if (open) {
270                 g_print("## New station Type [%s], IP [%s], MAC [%s], hostname [%s]\n",
271                                 __convert_tethering_type_to_str(type),
272                                 ip_address, mac_address, hostname);
273         } else {
274                 g_print("## Disconnected station Type [%s], IP [%s], MAC [%s], hostname [%s]\n",
275                                 __convert_tethering_type_to_str(type),
276                                 ip_address, mac_address, hostname);
277         }
278
279         if (ip_address)
280                 free(ip_address);
281         if (mac_address)
282                 free(mac_address);
283         if (hostname)
284                 free(hostname);
285
286         tethering_client_destroy(clone);
287
288         return;
289 }
290
291 static void __data_usage_cb(tethering_error_e result, unsigned long long received_data,
292                 unsigned long long sent_data, void *user_data)
293 {
294         g_print("__data_usage_cb\n");
295
296         if (result != TETHERING_ERROR_NONE) {
297                 g_print("tethering_get_data_usage is failed. error[0x%X]\n", result);
298                 return;
299         }
300
301         g_print("## Received data : %llu bytes\n", received_data);
302         g_print("## Sent data : %llu bytes\n", sent_data);
303
304         return;
305 }
306
307 static bool __clients_foreach_cb(tethering_client_h client, void *data)
308 {
309         tethering_client_h clone = NULL;
310         tethering_type_e type;
311         char *ip_address = NULL;
312         char *mac_address = NULL;
313         char *hostname = NULL;
314
315         /* Clone internal information */
316         if (tethering_client_clone(&clone, client) != TETHERING_ERROR_NONE) {
317                 g_print("tethering_client_clone is failed\n");
318                 return false;
319         }
320
321         /* Get information */
322         if (tethering_client_get_tethering_type(clone, &type) != TETHERING_ERROR_NONE) {
323                 g_print("tethering_client_get_type is failed\n");
324         }
325
326         if (tethering_client_get_ip_address(clone, TETHERING_ADDRESS_FAMILY_IPV4, &ip_address) != TETHERING_ERROR_NONE) {
327                 g_print("tethering_client_get_ip_address is failed\n");
328         }
329
330         if (tethering_client_get_mac_address(clone, &mac_address) != TETHERING_ERROR_NONE) {
331                 g_print("tethering_client_get_mac_address is failed\n");
332         }
333
334         if (tethering_client_get_name(clone, &hostname) != TETHERING_ERROR_NONE) {
335                 g_print("tethering_client_get_hostname is failed\n");
336         }
337         /* End of getting information */
338
339         g_print("\n< Client Info. >\n");
340         g_print("\tType %s\n", __convert_tethering_type_to_str(type));
341         g_print("\tIP Address %s\n", ip_address);
342         g_print("\tMAC Address : %s\n", mac_address);
343         g_print("\tHostname : %s\n", hostname);
344
345         /* Destroy cloned objects */
346         if (ip_address)
347                 free(ip_address);
348         if (mac_address)
349                 free(mac_address);
350         if (hostname)
351                 free(hostname);
352
353         tethering_client_destroy(clone);
354
355         /* Continue iteration */
356         return true;
357 }
358 /* End of tethering callbacks */
359
360 static void __enable_tethering(tethering_h th, tethering_type_e type)
361 {
362         if (th == NULL)
363                 return;
364
365         tethering_error_e error = TETHERING_ERROR_NONE;
366
367         error = tethering_enable(th, type);
368         __is_err(error);
369
370         return;
371 }
372
373 static void __disable_tethering(tethering_h th, tethering_type_e type)
374 {
375         if (th == NULL)
376                 return;
377
378         tethering_error_e error = TETHERING_ERROR_NONE;
379
380         error = tethering_disable(th, type);
381         __is_err(error);
382
383         return;
384 }
385
386 static void __print_interface_info(tethering_h th, tethering_type_e type)
387 {
388         char *interface = NULL;
389         char *mac_address = NULL;
390         char *ip_address = NULL;
391         char *gateway_address = NULL;
392         char *subnet_mask = NULL;
393
394         if (tethering_is_enabled(th, type) == FALSE) {
395                 g_print("%s tethering is not enabled\n",
396                                 __convert_tethering_type_to_str(type));
397                 return;
398         }
399
400         tethering_get_network_interface_name(th, type, &interface);
401         tethering_get_mac_address(th, type, &mac_address);
402         tethering_get_ip_address(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
403                         &ip_address);
404         tethering_get_gateway_address(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
405                         &gateway_address);
406         tethering_get_subnet_mask(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
407                         &subnet_mask);
408
409         g_print("interface name : %s\n", interface);
410         g_print("mac address : %s\n", mac_address);
411         g_print("ip address : %s\n", ip_address);
412         g_print("gateway address: %s\n", gateway_address);
413         g_print("subnet mask : %s\n", subnet_mask);
414
415         if (interface)
416                 free(interface);
417         if (mac_address)
418                 free(mac_address);
419         if (ip_address)
420                 free(ip_address);
421         if (gateway_address)
422                 free(gateway_address);
423         if (subnet_mask)
424                 free(subnet_mask);
425
426         return;
427 }
428
429 static void __print_wifi_tethering_setting(tethering_h th)
430 {
431         char *ssid = NULL;
432         char *passphrase = NULL;
433         bool visibility = false;
434         tethering_wifi_security_type_e security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
435
436         int error = TETHERING_ERROR_NONE;
437
438         error = tethering_wifi_get_ssid(th, &ssid);
439         if (error != TETHERING_ERROR_NONE)
440                 __is_err(error);
441         else
442                 g_print("\n\t** WiFi tethering SSID : %s\n", ssid);
443
444         error = tethering_wifi_get_passphrase(th, &passphrase);
445         if (error != TETHERING_ERROR_NONE)
446                 __is_err(error);
447         else
448                 g_print("\t** WiFi tethering passphrase : %s\n", passphrase);
449
450         error = tethering_wifi_get_ssid_visibility(th, &visibility);
451         if (error != TETHERING_ERROR_NONE)
452                 __is_err(error);
453         else
454                 g_print("\t** WiFi tethering ssid visibility : %s\n",
455                                 visibility ? "visible" : "invisible");
456
457         error = tethering_wifi_get_security_type(th, &security_type);
458         if (error != TETHERING_ERROR_NONE)
459                 __is_err(error);
460         else
461                 g_print("\t** WiFi tethering security_type : %s\n",
462                                 security_type ==
463                                 TETHERING_WIFI_SECURITY_TYPE_NONE ?
464                                 "open" : "wpa2-psk");
465
466         if (ssid)
467                 free(ssid);
468         if (passphrase)
469                 free(passphrase);
470
471         return;
472 }
473
474 void print_menu(void)
475 {
476         g_print("\nTo get client information, enter 'clients [USB | WIFI | BT | ALL]'");
477         g_print("\nTo get interface information, enter 'info [USB | WIFI | BT]'");
478         g_print("\nTo get data usage, enter 'get data_usage'");
479         g_print("\nTo enable tethering, enter 'enable [USB | WIFI | BT | ALL]'");
480         g_print("\nTo disable tethering, enter 'disable [USB | WIFI | BT | ALL]'");
481         g_print("\nTo get Wi-Fi tethering setting, enter 'get wifi_setting'");
482         g_print("\nTo set Wi-Fi tethering setting, enter '[set_security_type | set_visibility] [0 | 1]'");
483         g_print("\nTo set Wi-Fi tethering passphrase, enter 'set_passphrase [passphrase]'");
484         g_print("\nTo quit, enter 'quit'\n> ");
485
486         return;
487 }
488
489 gboolean input(GIOChannel *channel, GIOCondition condition, gpointer data)
490 {
491         tethering_h th = (tethering_h)data;
492         tethering_type_e type = 0;
493         tethering_error_e error = 0;
494         gchar buf[INPUT_BUF_LEN] = {0, };
495         gchar *cmd = NULL;
496         gchar *param = NULL;
497         gsize read = 0;
498
499 #if !GLIB_CHECK_VERSION(2, 31, 0)
500         if (g_io_channel_read(channel, buf, INPUT_BUF_LEN, &read) != G_IO_ERROR_NONE) {
501                 g_print("g_io_channel_read is failed\n");
502                 return FALSE;
503         }
504 #else
505         GError *err = NULL;
506
507         g_io_channel_read_chars(channel, buf, INPUT_BUF_LEN, &read, &err);
508         if (err != NULL) {
509                 g_print("g_io_channel_read is failed : %s\n", err->message);
510                 g_error_free(err);
511                 return FALSE;
512         }
513 #endif
514
515         buf[read] = '\0';
516         g_strstrip(buf);
517
518         cmd = buf;
519         param = strrchr(buf, ' ');
520
521         /* No parameter */
522         if (!strcmp(cmd, "quit")) {
523                 g_main_loop_quit(mainloop);
524                 return TRUE;
525         }
526
527         if (param == NULL) {
528                 print_menu();
529                 return TRUE;
530         }
531         *param = '\0';
532         param++;
533
534         /* One parameter except type */
535         if (!strcmp(cmd, "get") && !strcmp(param, "data_usage")) {
536                 error = tethering_get_data_usage(th, __data_usage_cb, NULL);
537                 if (error != TETHERING_ERROR_NONE)
538                         g_print("tethering_get_data_usage is failed [0x%X]\n",
539                                         error);
540                 goto DONE;
541         }
542
543         if (!strcmp(cmd, "get") && !strcmp(param, "wifi_setting")) {
544                 __print_wifi_tethering_setting(th);
545                 goto DONE;
546         }
547
548         if (!strcmp(cmd, "set_visibility")) {
549                 error = tethering_wifi_set_ssid_visibility(th, atoi(param));
550                 if (error != TETHERING_ERROR_NONE)
551                         g_print("tethering_wifi_set_ssid_visibility is failed [0x%X]\n",
552                                         error);
553                 goto DONE;
554         }
555
556         if (!strcmp(cmd, "set_security_type")) {
557                 error = tethering_wifi_set_security_type(th, atoi(param));
558                 if (error != TETHERING_ERROR_NONE)
559                         g_print("tethering_wifi_set_security_type is failed [0x%X]\n",
560                                         error);
561                 goto DONE;
562         }
563
564         /* This should be removed */
565         if (!strcmp(cmd, "set_passphrase")) {
566                 error = tethering_wifi_set_passphrase(th, param);
567                 if (error != TETHERING_ERROR_NONE)
568                         g_print("tethering_wifi_set_passphrase is failed [0x%X]\n",
569                                         error);
570                 goto DONE;
571         }
572
573         /* One parameter(type) */
574         if (!strcmp(param, "USB"))
575                 type = TETHERING_TYPE_USB;
576         else if (!strcmp(param, "WIFI"))
577                 type = TETHERING_TYPE_WIFI;
578         else if (!strcmp(param, "BT"))
579                 type = TETHERING_TYPE_BT;
580         else if (!strcmp(param, "ALL"))
581                 type = TETHERING_TYPE_ALL;
582         else {
583                 goto DONE;
584         }
585
586         if (!strcmp(cmd, "clients")) {
587                 error = tethering_foreach_connected_clients(th, type,
588                                 __clients_foreach_cb, NULL);
589                 if (error != TETHERING_ERROR_NONE)
590                         g_print("tethering_get_data_usage is failed [0x%X]\n",
591                                         error);
592         } else if (!strcmp(cmd, "info")) {
593                 __print_interface_info(th, type);
594         } else if (!strcmp(cmd, "enable")) {
595                 __enable_tethering(th, type);
596         } else if (!strcmp(cmd, "disable")) {
597                 __disable_tethering(th, type);
598         } else {
599                 goto DONE;
600         }
601
602 DONE:
603         print_menu();
604         return TRUE;
605 }
606
607 int main(int argc, char *argv[])
608 {
609         tethering_h th = NULL;
610         GIOChannel *stdin_channel = NULL;
611         tethering_error_e ret = TETHERING_ERROR_NONE;
612         __tethering_cbs cbs = {__enabled_cb, __disabled_cb, __connection_state_changed_cb};
613
614         g_type_init();
615
616         /* Create tethering handle */
617         ret = tethering_create(&th);
618         if (__is_err(ret) == true)
619                 return 0;
620
621         /* Register cbs */
622         __register_cbs(th, &cbs, NULL);
623
624         stdin_channel = g_io_channel_unix_new(0);
625         if (stdin_channel == NULL)
626                 return 0;
627
628         g_io_channel_set_encoding(stdin_channel, NULL, NULL);
629         g_io_channel_set_flags(stdin_channel,
630                         G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK, NULL);
631
632         g_io_add_watch(stdin_channel, G_IO_IN, input, (gpointer)th);
633
634         print_menu();
635
636         mainloop = g_main_loop_new (NULL, 0);
637
638         g_main_loop_run(mainloop);
639         g_main_loop_unref(mainloop);
640
641         /* Deregister cbs */
642         __deregister_cbs(th);
643
644         /* Destroy tethering handle */
645         ret = tethering_destroy(th);
646         __is_err(ret);
647
648         return 0;
649 }
650