Navigation Menu

Skip to content

Commit

Permalink
Merge pull request #28 from monich/tethering
Browse files Browse the repository at this point in the history
[tethering] Connman tethering support
  • Loading branch information
philippedeswert committed Apr 16, 2015
2 parents fc16038 + 059905e commit e0378c4
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 2 deletions.
13 changes: 13 additions & 0 deletions config/dyn-modes/connection_sharing-android-connman.ini
@@ -0,0 +1,13 @@
[mode]
name = connection_sharing
module = none

[options]
sysfs_path = /sys/class/android_usb/android0/functions
sysfs_value = rndis
sysfs_reset_value = none
softconnect_path = /sys/class/android_usb/android0/enable
softconnect = 1
softconnect_disconnect = 0
idProduct = 0A02
connman_tethering = /net/connman/technology/gadget
17 changes: 17 additions & 0 deletions rpm/usb-moded.spec
Expand Up @@ -235,6 +235,19 @@ system bus.
This package contains configuration to enable sharing the cellular data
connection over the USB with the android gadget driver.

%package connection-sharing-android-connman-config
Summary: USB mode controller - USB/cellular data connection sharing config
Group: Config

%description connection-sharing-android-connman-config
Usb_moded is a daemon to control the USB states. For this
it loads unloads the relevant usb gadget modules, keeps track
of the filesystem(s) and notifies about changes on the DBUS
system bus.

This package contains configuration to enable sharing the cellular data
connection over the USB with the connman gadget driver.

%package mass-storage-android-config
Summary: USB mode controller - mass-storage config with android gadget
Group: Config
Expand Down Expand Up @@ -420,6 +433,10 @@ systemctl daemon-reload || :
%{_sysconfdir}/usb-moded/dyn-modes/connection_sharing.ini
%{_sysconfdir}/usb-moded/run/udhcpd-connection-sharing.ini

%files connection-sharing-android-connman-config
%defattr(-,root,root,-)
%{_sysconfdir}/usb-moded/dyn-modes/connection_sharing-android-connman.ini

%files mass-storage-android-config
%defattr(-,root,root,-)
%{_sysconfdir}/usb-moded/dyn-modes/mass_storage_android.ini
Expand Down
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
8 changes: 7 additions & 1 deletion 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,7 +80,10 @@ 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;

/* diag is used to select a secondary configuration location for diagnostic purposes */
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 e0378c4

Please sign in to comment.