2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
22 #include <glib-object.h>
23 #include <sys/socket.h>
24 #include <netinet/in.h>
25 #include <arpa/inet.h>
29 #include "tethering.h"
31 #define INPUT_BUF_LEN 32
32 #define DISABLE_REASON_TEXT_LEN 64
33 #define COMMON_STR_BUF_LEN 32
36 tethering_enabled_cb enabled_cb;
37 tethering_disabled_cb disabled_cb;
38 tethering_connection_state_changed_cb changed_cb;
41 static GMainLoop *mainloop = NULL;
43 static bool __is_err(tethering_error_e ret)
48 case TETHERING_ERROR_INVALID_PARAMETER:
49 err_msg = "Wrong parameter is used";
52 case TETHERING_ERROR_OUT_OF_MEMORY:
53 err_msg = "Memory is not enough";
56 case TETHERING_ERROR_NONE:
59 case TETHERING_ERROR_NOT_ENABLED:
60 err_msg = "Tethering is not enabled";
63 case TETHERING_ERROR_OPERATION_FAILED:
64 err_msg = "Operation is failed";
67 case TETHERING_ERROR_RESOURCE_BUSY:
68 err_msg = "Resource is busy";
72 err_msg = "This should not be happened";
76 g_print("%s\n", err_msg);
81 static const char *__convert_tethering_type_to_str(const tethering_type_e type)
83 static char str_buf[COMMON_STR_BUF_LEN] = {0, };
86 case TETHERING_TYPE_USB:
87 g_strlcpy(str_buf, "USB", sizeof(str_buf));
90 case TETHERING_TYPE_WIFI:
91 g_strlcpy(str_buf, "Wi-Fi", sizeof(str_buf));
94 case TETHERING_TYPE_BT:
95 g_strlcpy(str_buf, "Bluetooth", sizeof(str_buf));
99 g_strlcpy(str_buf, "Unknown", sizeof(str_buf));
106 static const char *__convert_disabled_code_to_str(const tethering_disabled_cause_e code)
108 static char str_buf[DISABLE_REASON_TEXT_LEN] = {0, };
111 case TETHERING_DISABLED_BY_USB_DISCONNECTION:
112 strncpy(str_buf, "disabled due to usb disconnection", sizeof(str_buf));
115 case TETHERING_DISABLED_BY_FLIGHT_MODE:
116 strncpy(str_buf, "disabled due to flight mode on", sizeof(str_buf));
119 case TETHERING_DISABLED_BY_LOW_BATTERY:
120 strncpy(str_buf, "disabled due to low battery", sizeof(str_buf));
123 case TETHERING_DISABLED_BY_NETWORK_CLOSE:
124 strncpy(str_buf, "disabled due to pdp network close", sizeof(str_buf));
127 case TETHERING_DISABLED_BY_TIMEOUT:
128 strncpy(str_buf, "disabled due to timeout", sizeof(str_buf));
131 case TETHERING_DISABLED_BY_MDM_ON:
132 strncpy(str_buf, "disabled due to mdm on", sizeof(str_buf));
135 case TETHERING_DISABLED_BY_OTHERS:
136 strncpy(str_buf, "disabled by other apps", sizeof(str_buf));
139 case TETHERING_DISABLED_BY_REQUEST:
140 strncpy(str_buf, "disabled by my request", sizeof(str_buf));
143 case TETHERING_DISABLED_BY_WIFI_ON:
144 strncpy(str_buf, "disabled by Wi-Fi station on", sizeof(str_buf));
147 case TETHERING_DISABLED_BY_BT_OFF:
148 strncpy(str_buf, "disabled by bluetooth off", sizeof(str_buf));
152 strncpy(str_buf, "disabled by unknown reason", sizeof(str_buf));
159 static void __register_cbs(tethering_h th, __tethering_cbs *cbs, void *user_data)
161 tethering_error_e ret = TETHERING_ERROR_NONE;
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");
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");
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");
184 static void __deregister_cbs(tethering_h th)
186 tethering_error_e ret = TETHERING_ERROR_NONE;
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");
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");
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");
206 /* Tethering callbacks */
207 static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
209 if (error != TETHERING_ERROR_NONE) {
214 g_print("## %s tethering is not enabled. error code[0x%X]\n",
215 __convert_tethering_type_to_str(type),
221 g_print("## %s tethering is enabled successfully\n",
222 __convert_tethering_type_to_str(type));
224 g_print("## %s tethering is enabled by other app\n",
225 __convert_tethering_type_to_str(type));
230 static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
232 if (error != TETHERING_ERROR_NONE) {
233 if (code != TETHERING_DISABLED_BY_REQUEST) {
237 g_print("## %s tethering is not disabled. error code[0x%X]\n",
238 __convert_tethering_type_to_str(type), error);
242 g_print("## %s tethering is %s\n",
243 __convert_tethering_type_to_str(type),
244 __convert_disabled_code_to_str(code));
249 static void __connection_state_changed_cb(tethering_client_h client, bool open, void *data)
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;
257 tethering_client_clone(&clone, client);
259 g_print("tetheirng_client_clone is failed\n");
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);
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);
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);
286 tethering_client_destroy(clone);
291 static void __data_usage_cb(tethering_error_e result, unsigned long long received_data,
292 unsigned long long sent_data, void *user_data)
294 g_print("__data_usage_cb\n");
296 if (result != TETHERING_ERROR_NONE) {
297 g_print("tethering_get_data_usage is failed. error[0x%X]\n", result);
301 g_print("## Received data : %llu bytes\n", received_data);
302 g_print("## Sent data : %llu bytes\n", sent_data);
307 static bool __clients_foreach_cb(tethering_client_h client, void *data)
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;
315 /* Clone internal information */
316 if (tethering_client_clone(&clone, client) != TETHERING_ERROR_NONE) {
317 g_print("tethering_client_clone is failed\n");
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");
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");
330 if (tethering_client_get_mac_address(clone, &mac_address) != TETHERING_ERROR_NONE) {
331 g_print("tethering_client_get_mac_address is failed\n");
334 if (tethering_client_get_name(clone, &hostname) != TETHERING_ERROR_NONE) {
335 g_print("tethering_client_get_hostname is failed\n");
337 /* End of getting information */
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);
345 /* Destroy cloned objects */
353 tethering_client_destroy(clone);
355 /* Continue iteration */
358 /* End of tethering callbacks */
360 static void __enable_tethering(tethering_h th, tethering_type_e type)
365 tethering_error_e error = TETHERING_ERROR_NONE;
367 error = tethering_enable(th, type);
373 static void __disable_tethering(tethering_h th, tethering_type_e type)
378 tethering_error_e error = TETHERING_ERROR_NONE;
380 error = tethering_disable(th, type);
386 static void __print_interface_info(tethering_h th, tethering_type_e type)
388 char *interface = NULL;
389 char *mac_address = NULL;
390 char *ip_address = NULL;
391 char *gateway_address = NULL;
392 char *subnet_mask = NULL;
394 if (tethering_is_enabled(th, type) == FALSE) {
395 g_print("%s tethering is not enabled\n",
396 __convert_tethering_type_to_str(type));
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,
404 tethering_get_gateway_address(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
406 tethering_get_subnet_mask(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
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);
422 free(gateway_address);
429 static void __print_wifi_tethering_setting(tethering_h th)
432 char *passphrase = NULL;
433 bool visibility = false;
434 tethering_wifi_security_type_e security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
436 int error = TETHERING_ERROR_NONE;
438 error = tethering_wifi_get_ssid(th, &ssid);
439 if (error != TETHERING_ERROR_NONE)
442 g_print("\n\t** WiFi tethering SSID : %s\n", ssid);
444 error = tethering_wifi_get_passphrase(th, &passphrase);
445 if (error != TETHERING_ERROR_NONE)
448 g_print("\t** WiFi tethering passphrase : %s\n", passphrase);
450 error = tethering_wifi_get_ssid_visibility(th, &visibility);
451 if (error != TETHERING_ERROR_NONE)
454 g_print("\t** WiFi tethering ssid visibility : %s\n",
455 visibility ? "visible" : "invisible");
457 error = tethering_wifi_get_security_type(th, &security_type);
458 if (error != TETHERING_ERROR_NONE)
461 g_print("\t** WiFi tethering security_type : %s\n",
463 TETHERING_WIFI_SECURITY_TYPE_NONE ?
464 "open" : "wpa2-psk");
474 void print_menu(void)
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> ");
489 gboolean input(GIOChannel *channel, GIOCondition condition, gpointer data)
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, };
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");
507 g_io_channel_read_chars(channel, buf, INPUT_BUF_LEN, &read, &err);
509 g_print("g_io_channel_read is failed : %s\n", err->message);
519 param = strrchr(buf, ' ');
522 if (!strcmp(cmd, "quit")) {
523 g_main_loop_quit(mainloop);
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",
543 if (!strcmp(cmd, "get") && !strcmp(param, "wifi_setting")) {
544 __print_wifi_tethering_setting(th);
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",
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",
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",
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;
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",
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);
607 int main(int argc, char *argv[])
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};
616 /* Create tethering handle */
617 ret = tethering_create(&th);
618 if (__is_err(ret) == true)
622 __register_cbs(th, &cbs, NULL);
624 stdin_channel = g_io_channel_unix_new(0);
625 if (stdin_channel == NULL)
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);
632 g_io_add_watch(stdin_channel, G_IO_IN, input, (gpointer)th);
636 mainloop = g_main_loop_new (NULL, 0);
638 g_main_loop_run(mainloop);
639 g_main_loop_unref(mainloop);
642 __deregister_cbs(th);
644 /* Destroy tethering handle */
645 ret = tethering_destroy(th);