diff --git a/configure.ac b/configure.ac index 49942d0..676a90a 100644 --- a/configure.ac +++ b/configure.ac @@ -86,7 +86,7 @@ AC_ARG_ENABLE([udev], AS_HELP_STRING([--enable-udev], [Enable udev interface @<: esac],[udev=true CFLAGS="-DUDEV -ludev $CFLAGS" ]) AM_CONDITIONAL([UDEV], [test x$udev = xtrue]) -AC_ARG_ENABLE([upstart], AS_HELP_STRING([--enable-upstart], [Enable upstart interface for appsync @<:@default=true@:>@]), +AC_ARG_ENABLE([upstart], AS_HELP_STRING([--enable-upstart], [Enable upstart interface for appsync @<:@default=false@:>@]), [case "${enableval}" in yes) upstart=true ; CFLAGS="-DUPSTART $CFLAGS" ;; no) upstart=false ;; @@ -94,6 +94,14 @@ AC_ARG_ENABLE([upstart], AS_HELP_STRING([--enable-upstart], [Enable upstart inte esac],[upstart=false]) AM_CONDITIONAL([UPSTART], [test x$upstart = xtrue]) +AC_ARG_ENABLE([connman], AS_HELP_STRING([--enable-connman], [Enable connman support for usb tethering @<:@default=false@:>@]), + [case "${enableval}" in + yes) connman=true ; CFLAGS="-DCONNMAN $CFLAGS" ;; + no) connman=false ;; + *) AC_MSG_ERROR([bad value ${enableval} for --enable-connman]) ;; + esac],[connman=false]) +AM_CONDITIONAL([CONNMAN], [test x$connman = xtrue]) + #TODO: Figure out how to check for this depending on the gconf flag # gconf-2.0 >= 2.16.0 PKG_CHECK_MODULES([USB_MODED], [ diff --git a/dbus-send-test.txt b/dbus-send-test.txt index 2baf468..6d768b7 100644 --- a/dbus-send-test.txt +++ b/dbus-send-test.txt @@ -9,5 +9,5 @@ aegis-exec -a usb-moded::USBControl #connman mess dbus-send --system --type=method_call --print-reply --dest=net.connman / net.connman.Manager.GetProperties -dbus-send --system --type=method_call --print-reply --dest=net.connman / net.connman.Manager.GetService /* get all network connections */ +dbus-send --system --type=method_call --print-reply --dest=net.connman / net.connman.Manager.GetServices /* get all network connections */ dbus-send --system --type=method_call --print-reply --dest=net.connman /service_path/from/previous/command/ net.connman.Service.GetProperties diff --git a/src/usb_moded-modesetting.c b/src/usb_moded-modesetting.c index 980ad82..e25385a 100644 --- a/src/usb_moded-modesetting.c +++ b/src/usb_moded-modesetting.c @@ -350,6 +350,11 @@ int set_dynamic_mode(void) return set_mass_storage_mode(); } + /* Needs to be called before application synching so + that the dhcp server has the right config */ + if(data->nat) + usb_network_set_up_dhcpd(data); + #ifdef APP_SYNC if(data->appsync) if(activate_sync(data->mode_name)) /* returns 1 on error */ diff --git a/src/usb_moded-network.c b/src/usb_moded-network.c index d51a5e5..c235403 100644 --- a/src/usb_moded-network.c +++ b/src/usb_moded-network.c @@ -43,6 +43,12 @@ #endif const char default_interface[] = "usb0"; +typedef struct ipforward_data +{ + char *dns1; + char *dns2; + char *interface; +}ipforward_data; static char* get_interface(struct mode_list_elem *data) { @@ -93,6 +99,130 @@ static void set_usb_ip_forward(struct mode_list_elem *data) free((char *)nat_interface); } +/** + * Read dns settings from /etc/resolv.conf + */ +static int resolv_conf_dns(ipforward_data *ipforward) +{ + /* TODO: implement */ + return(0); +} + +#ifdef CONNMAN +/** + * Connman message handling + */ +static const char * connman_parse_manager_reply(DBusMessage *reply) +{ + DBusMessageIter iter, subiter; + int type; + char *service; + + log_debug("trying to get connman services\n"); + dbus_message_iter_init(reply, &iter); + type = dbus_message_iter_get_arg_type(&iter); + while(type != DBUS_TYPE_INVALID) + { + if(type == DBUS_TYPE_ARRAY) + { + dbus_message_iter_recurse(&iter, &subiter); + type = dbus_message_iter_get_arg_type(&subiter); + iter = subiter; + if(type == DBUS_TYPE_STRUCT) + { + dbus_message_iter_recurse(&iter, &subiter); + type = dbus_message_iter_get_arg_type(&subiter); + iter = subiter; + if(type == DBUS_TYPE_OBJECT_PATH) + { + dbus_message_iter_get_basic(&iter, &service); + log_debug("service = %s\n", service); + if(strstr(service, "cellular")) + return(service); + break; + } + } + } + dbus_message_iter_next (&iter); + type = dbus_message_iter_get_arg_type(&iter); + } + return(0); +} + +/** + * Turn on cellular connection if it is not on + */ +static int connman_set_cellular_online(DBusConnection *dbus_conn_connman, const char *service) +{ + DBusMessage *msg = NULL; + DBusError error; + int ret = 0; + + dbus_error_init(&error); + + if ((msg = dbus_message_new_method_call("net.connman", service, "net.connman.Service", "connect")) != NULL) + { + /* we don't care for the reply, which is empty anyway if all goes well */ + ret = !dbus_connection_send(dbus_conn_connman, msg, NULL); + /* make sure the message is sent before cleaning up and closing the connection */ + dbus_connection_flush(dbus_conn_connman); + dbus_message_unref(msg); + } + + return(ret); + +} + +static int connman_get_connection_data(struct ipforward_data *ipforward) +{ + DBusConnection *dbus_conn_connman = NULL; + DBusMessage *msg = NULL, *reply = NULL; + DBusError error; + const char *service = NULL; + + dbus_error_init(&error); + + if( (dbus_conn_connman = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) == 0 ) + { + log_err("Could not connect to dbus for connman\n"); + } + + /* get list of services so we can find out which one is the cellular */ + if ((msg = dbus_message_new_method_call("net.connman", "/", "net.connman.Manager", "GetServices")) != NULL) + { + if ((reply = dbus_connection_send_with_reply_and_block(dbus_conn_connman, msg, -1, NULL)) != NULL) + { + service = connman_parse_manager_reply(reply); + dbus_message_unref(reply); + } + dbus_message_unref(msg); + } + dbus_connection_unref(dbus_conn_connman); + dbus_error_free(&error); + free((char *)service); + return(0); +} +#endif /* CONNMAN */ + +/** + * Write out /etc/udhcpd.conf conf so the config is available when it gets started + * NOTE: This will be called before network is brought up! + */ +int usb_network_set_up_dhcpd(struct mode_list_elem *data) +{ + struct ipforward_data *ipforward; + + ipforward = malloc(sizeof(struct ipforward_data)); +#ifdef CONNMAN + connman_get_connection_data(ipforward); +#else + resolv_conf_dns(ipforward); +#endif /*CONNMAN */ + + free(ipforward); + return(0); +} + /** * Activate the network interface * @@ -125,8 +255,7 @@ int usb_network_up(struct mode_list_elem *data) dbus_message_unref(msg); } dbus_connection_unref(dbus_conn_connman); - - log_debug("connman state = %d\n", ret); + dbus_error_free(&error); return(ret); #else diff --git a/src/usb_moded-network.h b/src/usb_moded-network.h index c241c38..d88d313 100644 --- a/src/usb_moded-network.h +++ b/src/usb_moded-network.h @@ -27,3 +27,4 @@ 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);