Skip to content

Commit

Permalink
[usb-moded] Connman tethering support
Browse files Browse the repository at this point in the history
Contributes to JB#15005
  • Loading branch information
monich committed Apr 15, 2015
1 parent fc16038 commit 5722b4f
Show file tree
Hide file tree
Showing 5 changed files with 124 additions and 1 deletion.
6 changes: 6 additions & 0 deletions src/usb_moded-dyn-config.c
Expand Up @@ -51,6 +51,9 @@ void list_item_free(mode_list_elem *list_item)
free(list_item->android_extra_sysfs_path2);
free(list_item->android_extra_sysfs_value2);
free(list_item->idProduct);
#ifdef CONNMAN
free(list_item->connman_tethering);
#endif
free(list_item);
}

Expand Down Expand Up @@ -146,6 +149,9 @@ static struct mode_list_elem *read_mode_file(const gchar *filename)
list_item->idProduct = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_IDPRODUCT, NULL);
list_item->nat = g_key_file_get_integer(settingsfile, MODE_OPTIONS_ENTRY, MODE_HAS_NAT, NULL);
list_item->dhcp_server = g_key_file_get_integer(settingsfile, MODE_OPTIONS_ENTRY, MODE_HAS_DHCP_SERVER, NULL);
#ifdef CONNMAN
list_item->connman_tethering = g_key_file_get_string(settingsfile, MODE_OPTIONS_ENTRY, MODE_CONNMAN_TETHERING, NULL);
#endif

g_key_file_free(settingsfile);
if(list_item->mode_name == NULL || list_item->mode_module == NULL)
Expand Down
6 changes: 6 additions & 0 deletions src/usb_moded-dyn-config.h
Expand Up @@ -51,6 +51,9 @@ android engineers prefered to have sysfs entries... go figure... */
#define MODE_IDPRODUCT "idProduct"
#define MODE_HAS_NAT "nat"
#define MODE_HAS_DHCP_SERVER "dhcp_server"
#ifdef CONNMAN
#define MODE_CONNMAN_TETHERING "connman_tethering"
#endif

/**
* Struct keeping all the data needed for the definition of a dynamic mode
Expand All @@ -77,6 +80,9 @@ typedef struct mode_list_elem
char *idProduct; /* product id to assign to a specific profile */
int nat; /* If NAT should be set up in this mode or not */
int dhcp_server; /* if a DHCP server needs to be configured and started or not */
#ifdef CONNMAN
char* connman_tethering; /* connman's tethering technology path */
#endif
/*@} */
}mode_list_elem;

Expand Down
10 changes: 10 additions & 0 deletions src/usb_moded-modesetting.c
Expand Up @@ -449,6 +449,11 @@ int set_dynamic_mode(void)
if(data->appsync && !ret)
activate_sync_post(data->mode_name);

#ifdef CONNMAN
if(data->connman_tethering)
connman_set_tethering(data->connman_tethering, TRUE);
#endif

if(ret)
usb_moded_send_error_signal(MODE_SETTING_FAILED);
return(ret);
Expand All @@ -471,6 +476,11 @@ void unset_dynamic_mode(void)
return;
}

#ifdef CONNMAN
if(data->connman_tethering)
connman_set_tethering(data->connman_tethering, FALSE);
#endif

if(data->network)
{
usb_network_down(data);
Expand Down
94 changes: 94 additions & 0 deletions src/usb_moded-network.c
Expand Up @@ -411,6 +411,100 @@ static int write_udhcpd_conf(struct ipforward_data *ipforward, struct mode_list_
}

#ifdef CONNMAN

#define CONNMAN_SERVICE "net.connman"
#define CONNMAN_TECH_INTERFACE "net.connman.Technology"
#define CONNMAN_ERROR_INTERFACE CONNMAN_SERVICE ".Error"
#define CONNMAN_ERROR_ALREADY_ENABLED CONNMAN_ERROR_INTERFACE ".AlreadyEnabled"
#define CONNMAN_ERROR_ALREADY_DISABLED CONNMAN_ERROR_INTERFACE ".AlreadyDisabled"

/*
* Configures tethering for the specified connman technology.
*/
static gboolean connman_try_set_tethering(DBusConnection *connection, const char *path, gboolean on)
{
gboolean ok = FALSE;
DBusMessage *message = dbus_message_new_method_call(CONNMAN_SERVICE, path, CONNMAN_TECH_INTERFACE, "SetProperty");
if (message)
{
DBusMessage *reply;
DBusMessageIter iter;
DBusMessageIter iter2;
DBusError error;

const char* key = "Tethering";
dbus_bool_t value = (on != FALSE);

dbus_message_iter_init_append(message, &iter);
dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key);
dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, DBUS_TYPE_BOOLEAN_AS_STRING, &iter2);
dbus_message_iter_append_basic(&iter2, DBUS_TYPE_BOOLEAN, &value);
dbus_message_iter_close_container(&iter, &iter2);

dbus_error_init(&error);
reply = dbus_connection_send_with_reply_and_block(connection, message, DBUS_TIMEOUT_USE_DEFAULT, &error);
dbus_message_unref(message);
if (reply)
{
log_debug("%s tethering %s", path, on ? "on" : "off");
dbus_message_unref(reply);
ok = TRUE;
}
else
{
if ((on && !g_strcmp0(error.name, CONNMAN_ERROR_ALREADY_ENABLED)) ||
(!on && (!g_strcmp0(error.name, CONNMAN_ERROR_ALREADY_DISABLED) ||
!g_strcmp0(error.name, DBUS_ERROR_UNKNOWN_OBJECT))))
{
ok = TRUE;
}
else
{
log_err("%s\n", error.message);
}
dbus_error_free(&error);
}
}
return ok;
}

gboolean connman_set_tethering(const char *path, gboolean on)
{
gboolean ok = FALSE;
DBusError error;
DBusConnection *connection;

dbus_error_init(&error);
connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
if (connection)
{
int i;
for (i=0; i<10; i++)
{
if (i>0)
{
struct timespec tv;
tv.tv_sec = 0;
tv.tv_nsec = 200000000;
nanosleep(&tv, NULL);
}
if (connman_try_set_tethering(connection, path, on))
{
ok = TRUE;
break;
}
}
dbus_connection_unref(connection);
}
else
{
log_err("%s\n", error.message);
dbus_error_free (&error);
}

return ok;
}

/**
* Connman message handling
*/
Expand Down
9 changes: 8 additions & 1 deletion src/usb_moded-network.h
Expand Up @@ -20,11 +20,18 @@
usb-moded_network : (De)activates network depending on the network setting system.
*/

/*============================================================================= */
#ifndef USB_MODED_NETWORK_H_
#define USB_MODED_NETWORK_H_

#include "usb_moded-dyn-config.h"

int usb_network_up(struct mode_list_elem *data);
int usb_network_down(struct mode_list_elem *data);
int usb_network_update(void);
int usb_network_set_up_dhcpd(struct mode_list_elem *data);

#ifdef CONNMAN
gboolean connman_set_tethering(const char *path, gboolean on);
#endif

#endif /* USB_MODED_NETWORK_H_ */

0 comments on commit 5722b4f

Please sign in to comment.