Commit 5722b4f2 authored by Slava Monich's avatar Slava Monich

[usb-moded] Connman tethering support

Contributes to JB#15005
parent fc160385
......@@ -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);
}
......@@ -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)
......
......@@ -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
......@@ -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 */
......
......@@ -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);
......@@ -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);
......
......@@ -411,6 +411,100 @@ end:
}
#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
*/
......
......@@ -20,7 +20,8 @@
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"
......@@ -28,3 +29,9 @@ 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_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment