efl_net_session and efl_net_control for ConnMan

These are objects to allow control of networking devices
(efl_net_control) as well as an application to request for
connectivity (efl_net_session).

They are loosely based on ConnMan.org, which we already use in
Enlightenment Window Manager via DBus access with Eldbus. However they
do not map 1:1 as the goal was to expose a viable subset of controls
but in a simple and general way, thus nome strings were converted to
enums, some arrays of strings were converted to bitwise flags, some
names were made more general, such as "service" was turned into
"access point" so it doesn't generate confusion with other "network
services" (ie: http server), or "favorite" that was renamed to
"remembered". Some behavior are slightly different (yet able to be
implemented on top), such as "Service.MoveBefore" and "MoveAfter" were
converted to a numeric "priority", calculated from service's list
index, changing the priority will reoder the list and thus generate
the MoveBefore and MoveAfter DBus commands.

ConnMan was chosen not only because we already use it, but because its
DBus API is sane and simple, with the server doing almost all that we
need. This is visible in the efl_net_session, which is completely done
in the server and do not require any extra work on our side -- aside
from talking DBus and converting to Eo, which is a major work :-D

   NOTE: ConnMan doesn't use FreeDesktop.Org DBus interfaces such as
         Properties and ObjectManager, thus we cannot use
         eldbus_model_object.

There are two examples added:

 - efl_net_session_example: monitors the connection available for an
   application and try to connect. You need a connman compiled with
   session_policy_local and a configuration file explained in
   https://github.com/aldebaran/connman/blob/master/doc/session-policy-format.txt
   to get a connection if nothing is connected. Otherwise it will just
   monitor the connectivity state.

 - efl_net_control_example: monitors, plays the agent and configure
   the network details. It can enable/disable technologies, connect to
   access points (services) and configure them. It's quite extensive
   as allows testing all of ConnMan's DBus API except P2P (Peers).
This commit is contained in:
Gustavo Sverzut Barbieri 2016-09-15 21:43:19 -03:00
parent f1b1d1354a
commit 0e0cac8577
4 changed files with 1633 additions and 2 deletions

2
ecore/.gitignore vendored
View File

@ -61,3 +61,5 @@
/efl_net_socket_ssl_dialer_example
/efl_net_socket_ssl_server_example
/*.pem
/efl_net_session_example
/efl_net_control_example

View File

@ -88,7 +88,9 @@ efl_net_dialer_websocket_example \
efl_net_dialer_websocket_autobahntestee \
efl_net_dialer_udp_example \
efl_net_socket_ssl_dialer_example \
efl_net_socket_ssl_server_example
efl_net_socket_ssl_server_example \
efl_net_session_example \
efl_net_control_example
ECORE_COMMON_LDADD = \
@ -334,6 +336,12 @@ efl_net_socket_ssl_dialer_example_LDADD = $(ECORE_CON_COMMON_LDADD)
efl_net_socket_ssl_server_example_SOURCES = efl_net_socket_ssl_server_example.c
efl_net_socket_ssl_server_example_LDADD = $(ECORE_CON_COMMON_LDADD)
efl_net_session_example_SOURCES = efl_net_session_example.c
efl_net_session_example_LDADD = $(ECORE_CON_COMMON_LDADD)
efl_net_control_example_SOURCES = efl_net_control_example.c
efl_net_control_example_LDADD = $(ECORE_CON_COMMON_LDADD)
SRCS = \
ecore_animator_example.c \
ecore_buffer_example.c \
@ -391,7 +399,9 @@ efl_net_dialer_websocket_example.c \
efl_net_dialer_websocket_autobahntestee.c \
efl_net_dialer_udp_example.c \
efl_net_socket_ssl_dialer_example.c \
efl_net_socket_ssl_server_example.c
efl_net_socket_ssl_server_example.c \
efl_net_session_example.c \
efl_net_control_example.c
%.pem:
echo -e "US\nOR\nPortland\nXPTO Ltd\n\nlocalhost\nroot@localhost\n" | openssl req -new -x509 -days 30 -nodes -out $@ -keyout $@

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,181 @@
#define EFL_BETA_API_SUPPORT 1
#define EFL_EO_API_SUPPORT 1
#include <Ecore.h>
#include <Ecore_Con.h>
#include <Ecore_Getopt.h>
static int retval = EXIT_SUCCESS;
static const char *
_state_str(Efl_Net_Session_State state)
{
static const char *strs[] = {
[EFL_NET_SESSION_STATE_OFFLINE] = "offline",
[EFL_NET_SESSION_STATE_LOCAL] = "local",
[EFL_NET_SESSION_STATE_ONLINE] = "online",
};
if ((unsigned)state > sizeof(strs)/sizeof(strs[0])) return "???";
if (!strs[state]) return "???";
return strs[state];
}
static const char *
_technology_str(Efl_Net_Session_Technology tech)
{
static const char *strs[] = {
[EFL_NET_SESSION_TECHNOLOGY_UNKNOWN] = "none",
[EFL_NET_SESSION_TECHNOLOGY_ETHERNET] = "ethernet",
[EFL_NET_SESSION_TECHNOLOGY_WIFI] = "wifi",
[EFL_NET_SESSION_TECHNOLOGY_BLUETOOTH] = "bluetooth",
[EFL_NET_SESSION_TECHNOLOGY_CELLULAR] = "cellular",
[EFL_NET_SESSION_TECHNOLOGY_VPN] = "vpn",
[EFL_NET_SESSION_TECHNOLOGY_GADGET] = "gadget",
};
if ((unsigned)tech > sizeof(strs)/sizeof(strs[0])) return "???";
if (!strs[tech]) return "???";
return strs[tech];
}
static void
_changed(void *data EINA_UNUSED, const Efl_Event *event)
{
Eo *session = event->object;
const char *ip, *netmask, *gateway;
uint8_t prefix;
printf("INFO: session changed:\n"
"INFO: - name: '%s'\n"
"INFO: - state: %s\n"
"INFO: - technology: %s\n"
"INFO: - interface: '%s'\n",
efl_net_session_name_get(session),
_state_str(efl_net_session_state_get(session)),
_technology_str(efl_net_session_technology_get(session)),
efl_net_session_interface_get(session));
efl_net_session_ipv4_get(session, &ip, &netmask, &gateway);
if (ip)
{
printf("INFO: - IPv4: %s, gateway=%s, netmask=%s\n",
ip, gateway, netmask);
}
efl_net_session_ipv6_get(session, &ip, &prefix, &netmask, &gateway);
if (ip)
{
printf("INFO: - IPv6: %s/%hhu, gateway=%s, netmask=%s\n",
ip, prefix, gateway, netmask);
}
}
EFL_CALLBACKS_ARRAY_DEFINE(session_events_cbs,
{ EFL_NET_SESSION_EVENT_CHANGED, _changed });
static const Ecore_Getopt options = {
"efl_net_session_example", /* program name */
NULL, /* usage line */
"1", /* version */
"(C) 2016 Enlightenment Project", /* copyright */
"BSD 2-Clause", /* license */
/* long description, may be multiline and contain \n */
"Example of Efl_Net_Session to request or monitor a network session for an application.\n",
EINA_FALSE,
{
ECORE_GETOPT_STORE_TRUE('c', "connect", "Require a connection to the internet (See -o/--require-online)."),
ECORE_GETOPT_STORE_TRUE('o', "require-online", "When connecting (-c/--connect), require connection to the internet. Otherwise a local network connection is enough"),
ECORE_GETOPT_APPEND('t', "technology", "Bearer technologies to use when connecting (ethernet, wifi, bluetooth, cellular, vpn, gadget or all)", ECORE_GETOPT_TYPE_STR),
ECORE_GETOPT_VERSION('V', "version"),
ECORE_GETOPT_COPYRIGHT('C', "copyright"),
ECORE_GETOPT_LICENSE('L', "license"),
ECORE_GETOPT_HELP('h', "help"),
ECORE_GETOPT_SENTINEL
}
};
int
main(int argc, char **argv)
{
char *str;
Eina_List *techs = NULL;
Eina_Bool do_connect = EINA_FALSE;
Eina_Bool require_online = EINA_FALSE;
Eina_Bool quit_option = EINA_FALSE;
Efl_Net_Session_Technology technologies = EFL_NET_SESSION_TECHNOLOGY_ALL;
Ecore_Getopt_Value values[] = {
ECORE_GETOPT_VALUE_BOOL(do_connect),
ECORE_GETOPT_VALUE_BOOL(require_online),
ECORE_GETOPT_VALUE_LIST(techs),
/* standard block to provide version, copyright, license and help */
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -V/--version quits */
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -C/--copyright quits */
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -L/--license quits */
ECORE_GETOPT_VALUE_BOOL(quit_option), /* -h/--help quits */
ECORE_GETOPT_VALUE_NONE /* sentinel */
};
int args;
Eo *session;
ecore_init();
ecore_con_init();
args = ecore_getopt_parse(&options, values, argc, argv);
if (args < 0)
{
fputs("ERROR: Could not parse command line options.\n", stderr);
retval = EXIT_FAILURE;
goto end;
}
if (quit_option) goto end;
if (techs)
{
technologies = 0;
EINA_LIST_FREE(techs, str)
{
if (0) {}
#define MAP(X) else if (strcasecmp(str, #X) == 0) technologies |= EFL_NET_SESSION_TECHNOLOGY_ ## X
MAP(ETHERNET);
MAP(WIFI);
MAP(BLUETOOTH);
MAP(CELLULAR);
MAP(VPN);
MAP(GADGET);
#undef MAP
else fprintf(stderr, "WARNING: unknown technology '%s' ignored.\n", str);
free(str);
}
}
session = efl_add(EFL_NET_SESSION_CLASS, ecore_main_loop_get(),
efl_event_callback_array_add(efl_added, session_events_cbs(), NULL));
if (!session)
{
fputs("ERROR: Could not create Efl.Net.Session object.\n", stderr);
retval = EXIT_FAILURE;
goto end;
}
if (do_connect)
{
printf("INFO: requesting a %s connection.\n", require_online ? "online" : "local");
efl_net_session_connect(session, require_online, technologies);
}
printf("INFO: the session will active while this application runs. Use ^C (Control + C) to close it\n");
ecore_main_loop_begin();
efl_del(session);
end:
ecore_con_shutdown();
ecore_shutdown();
return retval;
}