Hello,
I'm proposing changes related to the attached discussion, on retrieval of stored
services information, in two RFC proposals:
RFC (1): Add a method GetKnownServices to the Manager that has similar behavior of
GetServices but the source is not the active services list but the services stored in
STORAGEDIR.
RFC (2): Deletion of stored service: as far as I understood, provisioned services (the one
with a .config file) cannot be deleted with Remove method of Service, but after testing of
the WiFi technology I saw that it is not possible to remove
(STORAGEDIR)/service_folder/settings even if there is no .config file, with the Remove
method of a Service. This will lead to an increasing storage unless manually file deletion
is done. The RFC then is to change the _connman_service_remove function to actually
delete folders and files, when possible, meaning I would preserve current conditions to
return false in _connman_service_remove and moreover the .config files in (STORAGEDIR)
won't be touched.
This email is to start with the RFC (1) modifications and see if my ideas are approved,
because I made some assumptions that I hope are not a misunderstanding:
a) currently from Service component, using Storage component it is possible to access
only information stored in (STORAGEDIR)/service_folder/settings and not
(STORAGEDIR)/files.config. The latter is only accessed by Config component
b) the user can create a .config file in STORAGEDIR containing the information of
connection (including passphrase for WiFi) of the services he already knows, so connman
can connect (or autoconnect) to them without interaction. If a connection is made to these
services with success, then a corresponding folder with a settings file will be created in
(STORAGEDIR)/, that will reflects the .config file. Until a connection is done, only the
.config file will exists. For services that don't have a .config file, after the user
succeeds to connect to them the (STORAGEDIR)/service_folder/settings will be created.
Basing on the above assumption, mainly for (a) which would require further modifications,
the GetKnownServices only retrieves the services that have
(STORAGEDIR)/service_folder/settings; it will not read the content of the .config files.
For our personal usage this is not a limitation because we won't have .config files,
moreover the Remove method won't be able to remove them, but I'm open to change if
you have suggestions.
Here's my proposal for RFC (1):
client/commands.c | 13 ++++++++++++
doc/connmanctl.1.in | 11 ++++++++++
doc/manager-api.txt | 18 ++++++++++++++++
src/connman.h | 1 +
src/manager.c | 23 +++++++++++++++++++++
src/service.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/manager-api.c | 33 ++++++++++++++++++++++++++++++
7 files changed, 158 insertions(+)
diff --git a/client/commands.c b/client/commands.c
index db24d16..313174a 100644
--- a/client/commands.c
+++ b/client/commands.c
@@ -348,6 +348,17 @@ static int object_properties(DBusMessageIter *iter,
return 0;
}
+static int cmd_known_services(char *args[], int num, struct connman_option *options)
+{
+ if (num > 1)
+ return -E2BIG;
+
+ return __connmanctl_dbus_method_call(connection,
+ CONNMAN_SERVICE, CONNMAN_PATH,
+ "net.connman.Manager",
"GetKnownServices",
+ services_list, NULL, NULL, NULL);
+}
+
static int cmd_services(char *args[], int num, struct connman_option *options)
{
char *service_name = NULL;
@@ -2549,6 +2560,8 @@ static const struct {
lookup_tether },
{ "services", "[<service>]",
service_options, cmd_services,
"Display services", lookup_service_arg },
+ { "known-services", NULL, NULL, cmd_known_services,
+ "Display known services", NULL },
{ "peers", "[peer]", NULL,
cmd_peers,
"Display peers", lookup_peer_arg },
{ "scan", "<technology>", NULL,
cmd_scan,
diff --git a/doc/connmanctl.1.in b/doc/connmanctl.1.in
index 0f891bd..fe7359c 100644
--- a/doc/connmanctl.1.in
+++ b/doc/connmanctl.1.in
@@ -12,6 +12,7 @@ SYNOPSIS
.BI tether \ technology\ \fRon|off\ |
.BI tether\fR\ wifi\ on|off\ ssid\ passphrase\fR\ |
.BR services \ [\fIservice\fR]\ |
+.BR known-services\fR\ |
.BI peers \ peer\fR\ |
.BI scan \ technology\fR\ |
.RI \fBconnect \ service | peer \ |
@@ -103,6 +104,16 @@ Only the service path (e.g. wifi_6834534139723_managed_none)
is accepted as a parameter.
.PP
.TP
+.B known-services
+Returns a sorted list of tuples with service object path and dictionary of service
+properties, for the known services having their own directory in STORAGEDIR; it
+does not read .config files in root STORAGEDIR. With this principle, it will return
+only services that have been connected at least one time.
+This list will not contain sensitive information like passphrases etc.
+The object path can be used as string to retrieve main properties concatenated
+(for WiFi it includes SSID an security of the AP).
+.PP
+.TP
.BI scan \ technology
Scans for new services on the given technology.
.PP
diff --git a/doc/manager-api.txt b/doc/manager-api.txt
index 31e137c..509eac9 100644
--- a/doc/manager-api.txt
+++ b/doc/manager-api.txt
@@ -45,6 +45,24 @@ Methods dict GetProperties()
and dictionary of peer properties
Possible Errors:
[service].Error.InvalidArguments
+
+ array{object,dict} GetKnownServices() [experimental]
+
+ Returns a sorted list of tuples with
service
+ object path and dictionary of service
properties,
+ for the known services having their own
directory in
+ STORAGEDIR; it does not read .config files
in root STORAGEDIR.
+ With this principle, it will return only
services that
+ have been connected at least one time.
+
+ This list will not contain sensitive
information
+ like passphrases etc.
+
+ The object path can be used as string to
retrieve main
+ properties concatenated (for WiFi it
includes SSID an
+ security of the AP).
+
+ Possible Errors:
[service].Error.InvalidArguments
object ConnectProvider(dict provider) [deprecated]
diff --git a/src/connman.h b/src/connman.h
index 447bdd7..041b191 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -654,6 +654,7 @@ int __connman_service_init(void);
void __connman_service_cleanup(void);
int __connman_service_load_modifiable(struct connman_service *service);
+void __connman_known_service_list_struct(DBusMessageIter *iter);
void __connman_service_list_struct(DBusMessageIter *iter);
int __connman_service_compare(const struct connman_service *a,
diff --git a/src/manager.c b/src/manager.c
index d15ce20..1f59644 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -175,6 +175,11 @@ static struct connman_notifier technology_notifier = {
.idle_state = idle_state,
};
+static void append_known_service_structs(DBusMessageIter *iter, void *user_data)
+{
+ __connman_known_service_list_struct(iter);
+}
+
static void append_service_structs(DBusMessageIter *iter, void *user_data)
{
__connman_service_list_struct(iter);
@@ -195,6 +200,21 @@ static DBusMessage *get_services(DBusConnection *conn,
return reply;
}
+static DBusMessage *get_known_services(DBusConnection *conn,
+ DBusMessage
*msg, void *data)
+{
+ DBusMessage *reply;
+
+ reply = dbus_message_new_method_return(msg);
+ if (!reply)
+ return NULL;
+
+ __connman_dbus_append_objpath_dict_array(reply,
+ append_known_service_structs, NULL);
+
+ return reply;
+}
+
static void append_peer_structs(DBusMessageIter *iter, void *user_data)
{
__connman_peer_list_struct(iter);
@@ -513,6 +533,9 @@ static const GDBusMethodTable manager_methods[] = {
{ GDBUS_DEPRECATED_METHOD("RemoveProvider",
GDBUS_ARGS({ "provider",
"o" }), NULL,
remove_provider) },
+ { GDBUS_METHOD("GetKnownServices",
+ NULL, GDBUS_ARGS({
"knownServices", "a(oa{sv})" }),
+ get_known_services) },
{ GDBUS_METHOD("GetServices",
NULL, GDBUS_ARGS({ "services",
"a(oa{sv})" }),
get_services) },
diff --git a/src/service.c b/src/service.c
index a93aebf..e18caa0 100644
--- a/src/service.c
+++ b/src/service.c
@@ -2431,6 +2431,65 @@ static void append_struct(gpointer value, gpointer user_data)
append_struct_service(iter, append_dict_properties, service);
}
+void __connman_known_service_list_struct(DBusMessageIter *iter)
+{
+ gchar **services = NULL;
+ gchar **serviceIDParts = NULL;
+ int i = 0;
+ struct connman_service *service = NULL;
+
+ DBG("listing known services");
+
+ services = connman_storage_get_services();
+ if (services == NULL)
+ return;
+
+ for (i = 0; i < g_strv_length(services); i++)
+ {
+ service = connman_service_create();
+ if (service == NULL)
+ {
+ connman_error("connman_service_create()
allocation failed");
+ return ;
+ }
+ service->identifier = g_strdup(services[i]);
+ serviceIDParts = g_strsplit(services[i], "_",
-1);
+ if(serviceIDParts != NULL)
+ {
+ service->type =
__connman_service_string2type(serviceIDParts[0]);
+ service->path =
g_strdup_printf("%s/service/%s", CONNMAN_PATH, service->identifier);
+ if(service->type ==
CONNMAN_SERVICE_TYPE_WIFI)
+ service->security =
__connman_service_string2security(serviceIDParts[g_strv_length(serviceIDParts)-1]);
+
+ if(service->path != NULL)
+ {
+
if(find_service(service->path) != NULL)
+
service->state = (find_service(service->path))->state;
+ if(service->type ==
CONNMAN_SERVICE_TYPE_ETHERNET && find_service(service->path) != NULL)
+
service->name = (find_service(service->path))->name;
+
+ if (0 !=
service_load(service))
+ {
+
connman_error("service_load() returned error");
+
g_free(service);
+
g_strfreev(serviceIDParts);
+
g_strfreev(services);
+ return;
+ }
+
+ append_struct_service(iter,
append_dict_properties, service);
+ }
+
+ g_strfreev(serviceIDParts);
+ }
+ g_free(service);
+
+ }
+
+ g_strfreev(services);
+}
+
+
void __connman_service_list_struct(DBusMessageIter *iter)
{
g_list_foreach(service_list, append_struct, iter);
diff --git a/tools/manager-api.c b/tools/manager-api.c
index e082962..9e97f70 100644
--- a/tools/manager-api.c
+++ b/tools/manager-api.c
@@ -64,6 +64,39 @@ static DBusMessage *set_property(DBusConnection *connection,
return reply;
}
+DBusMessage *manager_get_known_services(DBusConnection *connection)
+{
+ DBusMessage *message, *reply;
+ DBusError error;
+
+ message = dbus_message_new_method_call(CONNMAN_SERVICE,
+
CONNMAN_MANAGER_PATH,
+
CONNMAN_MANAGER_INTERFACE,
+
"GetKnownServices");
+
+ if (!message)
+ return NULL;
+
+ dbus_error_init(&error);
+
+ reply = dbus_connection_send_with_reply_and_block(connection,
+
message, -1, &error);
+ if (!reply) {
+ if (dbus_error_is_set(&error)) {
+ LOG("%s", error.message);
+ dbus_error_free(&error);
+ } else {
+ LOG("Failed to get known
services");
+ }
+ dbus_message_unref(message);
+ return NULL;
+ }
+
+ dbus_message_unref(message);
+
+ return reply;
+}
+
DBusMessage *manager_get_services(DBusConnection *connection)
{
DBusMessage *message, *reply;
--
1.9.1
Regards,
Marco
________________________________
VISITA IL NOSTRO NUOVO SITO WEB! - VISIT OUR NEW WEB SITE!
www.magnetimarelli.com
Confidential Notice: This message - including its attachments - may contain proprietary,
confidential and/or legally protected information and is intended solely for the use of
the designated addressee(s) above. If you are not the intended recipient be aware that any
downloading, copying, disclosure, distribution or use of the contents of the above
information is strictly prohibited.
If you have received this communication by mistake, please forward the message back to the
sender at the email address above, delete the message from all mailboxes and any other
electronic storage medium and destroy all copies.
Disclaimer Notice: Internet communications cannot be guaranteed to be safe or error-free.
Therefore we do not assure that this message is complete or accurate and we do not accept
liability for any errors or omissions in the contents of this message.