allow configuring IPv4 services.
authorbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 31 Dec 2009 07:10:48 +0000 (07:10 +0000)
committerbarbieri <barbieri@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Thu, 31 Dec 2009 07:10:48 +0000 (07:10 +0000)
ConnMan fails to notify these properties changed, so they'll get out
of sync. This should be solved in upstream/connman in future.

git-svn-id: svn+ssh://svn.enlightenment.org/var/svn/e/trunk/e_dbus@44828 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/bin/e_dbus_connman_test.c
src/lib/connman/E_Connman.h
src/lib/connman/e_connman_element.c
src/lib/connman/e_connman_service.c

index adfe961..6f65729 100644 (file)
@@ -5,6 +5,22 @@
 #include <errno.h>
 
 static void
+_method_success_check(void *data, DBusMessage *msg, DBusError *error)
+{
+   const char *name = data;
+
+   if ((!error) || (!dbus_error_is_set(error)))
+     {
+       printf("SUCCESS: method %s() finished successfully.\n", name);
+       return;
+     }
+
+   printf("FAILURE: method %s() finished with error: %s %s\n",
+         name, error->name, error->message);
+   dbus_error_free(error);
+}
+
+static void
 _elements_print(E_Connman_Element **elements, unsigned int count)
 {
    unsigned int i;
@@ -1997,6 +2013,67 @@ _on_cmd_service_get_ipv4_configuration_netmask(char *cmd, char *args)
 }
 
 static int
+_on_cmd_service_ipv4_configure_dhcp(char *cmd, char *args)
+{
+   char *path;
+   E_Connman_Element *e;
+
+   if (!args)
+     {
+       fputs("ERROR: missing the service path\n", stderr);
+       return 1;
+     }
+   path = args;
+   _tok(args);
+
+   e = e_connman_service_get(path);
+   if (e_connman_service_ipv4_configure_dhcp
+       (e, _method_success_check, "service_ipv4_configure_dhcp"))
+     printf(":::Service %s IPv4 Configuration set to DHCP\n", path);
+   else
+     fputs("ERROR: can't set service ipv4_configuration dhcp\n", stderr);
+   return 1;
+}
+
+static int
+_on_cmd_service_ipv4_configure_manual(char *cmd, char *args)
+{
+   char *path, *next_args, *address, *netmask = NULL;
+   E_Connman_Element *e;
+
+   if (!args)
+     {
+       fputs("ERROR: missing the service path\n", stderr);
+       return 1;
+     }
+   path = args;
+   next_args = _tok(args);
+   if (!next_args)
+     {
+       fputs("ERROR: missing the service address\n", stderr);
+       return 1;
+     }
+
+   address = next_args;
+   next_args = _tok(next_args);
+   if (next_args)
+     {
+       netmask = next_args;
+       _tok(next_args);
+     }
+
+   e = e_connman_service_get(path);
+   if (e_connman_service_ipv4_configure_manual
+       (e, address, netmask,
+       _method_success_check, "service_ipv4_configure_manual"))
+     printf(":::Service %s IPv4 Configuration set to Manual (%s/%s)\n",
+           path, address, netmask);
+   else
+     fputs("ERROR: can't set service ipv4_configuration manual\n", stderr);
+   return 1;
+}
+
+static int
 _on_cmd_service_get_ethernet_method(char *cmd, char *args)
 {
    const char *ethernet_method, *path;
@@ -2182,6 +2259,8 @@ _on_input(void *data, Ecore_Fd_Handler *fd_handler)
      {"service_get_ipv4_configuration_address", _on_cmd_service_get_ipv4_configuration_address},
      {"service_get_ipv4_configuration_gateway", _on_cmd_service_get_ipv4_configuration_gateway},
      {"service_get_ipv4_configuration_netmask", _on_cmd_service_get_ipv4_configuration_netmask},
+     {"service_ipv4_configure_dhcp", _on_cmd_service_ipv4_configure_dhcp},
+     {"service_ipv4_configure_manual", _on_cmd_service_ipv4_configure_manual},
      {"service_get_ethernet_method", _on_cmd_service_get_ethernet_method},
      {"service_get_ethernet_address", _on_cmd_service_get_ethernet_address},
      {"service_get_ethernet_mtu", _on_cmd_service_get_ethernet_mtu},
index c3dbd76..ce182c7 100644 (file)
@@ -202,10 +202,11 @@ extern "C" {
 
   EAPI bool e_connman_service_ethernet_netmask_get(const E_Connman_Element *service, const char **netmask) EINA_ARG_NONNULL(1, 2) EINA_PURE EINA_WARN_UNUSED_RESULT;
 
-  // TODO: ipv4_configuration_method_set
-  // TODO: ipv4_configuration_address_set
-  // TODO: ipv4_configuration_netmask_set
-  // TODO: ipv4_configuration_gateway_set
+  /* Methods to configure IPv4 service */
+  EAPI bool e_connman_service_ipv4_configure_dhcp(E_Connman_Element *service, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1) EINA_WARN_UNUSED_RESULT;
+  EAPI bool e_connman_service_ipv4_configure_manual(E_Connman_Element *service, const char *address, const char *netmask, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
+
+
   // TODO: ethernet_speed_get (not in connman yet)
   // TODO: ethernet_duplex_get (not in connman yet)
 
@@ -234,6 +235,7 @@ extern "C" {
 
   EAPI bool e_connman_element_property_set(E_Connman_Element *element, const char *prop, int type, const void *value) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
   EAPI bool e_connman_element_property_set_full(E_Connman_Element *element, const char *prop, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2) EINA_WARN_UNUSED_RESULT;
+  EAPI bool e_connman_element_property_dict_set_full(E_Connman_Element *element, const char *prop, const char *key, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data) EINA_ARG_NONNULL(1, 2, 3) EINA_WARN_UNUSED_RESULT;
 
   EAPI void e_connman_element_properties_list(const E_Connman_Element *element, bool (*cb)(void *data, const E_Connman_Element *element, const char *name, int type, const void *value), const void *data) EINA_ARG_NONNULL(1, 2);
 
index a962053..19a5ffa 100644 (file)
@@ -482,6 +482,8 @@ _e_connman_element_objects_array_register(E_Connman_Array *array, const char *na
    unsigned int i;
    void *item;
 
+   if (!array)
+     return;
    if (array->type != DBUS_TYPE_OBJECT_PATH)
      return;
    EINA_ARRAY_ITER_NEXT(array->array, i, item, iterator)
@@ -1294,6 +1296,83 @@ e_connman_element_properties_sync(E_Connman_Element *element)
 }
 
 /**
+ * Call method SetProperty(prop, {key: value}) at the given element on server.
+ *
+ * This is a server call, not local, so it may fail and in that case
+ * no property is updated locally. If the value was set the event
+ * E_CONNMAN_EVENT_ELEMENT_UPDATED will be added to main loop.
+ *
+ * @param element to call method on server.
+ * @param prop property name.
+ * @param key dict key name.
+ * @param type DBus type to use for value.
+ * @param value pointer to value, just like regular DBus, see
+ *        dbus_message_iter_append_basic().
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_element_property_dict_set_full(E_Connman_Element *element, const char *prop, const char *key, int type, const void *value, E_DBus_Method_Return_Cb cb, const void *data)
+{
+   const char name[] = "SetProperty";
+   DBusMessage *msg;
+   DBusMessageIter itr, variant, dict, entry;
+   char typestr[32];
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(element, 0);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(prop, 0);
+
+   msg = dbus_message_new_method_call
+     (e_connman_system_bus_name_get(), element->path, element->interface, name);
+
+   if (!msg)
+     return 0;
+
+   dbus_message_iter_init_append(msg, &itr);
+   dbus_message_iter_append_basic(&itr, DBUS_TYPE_STRING, &prop);
+
+   if ((size_t)snprintf(typestr, sizeof(typestr),
+                       (DBUS_TYPE_ARRAY_AS_STRING
+                        DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+                        DBUS_TYPE_STRING_AS_STRING
+                        "%c"
+                        DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
+                       type) >= sizeof(typestr))
+     {
+       ERR("sizeof(typestr) is too small!");
+       return 0;
+     }
+
+   dbus_message_iter_open_container(&itr, DBUS_TYPE_VARIANT, typestr, &variant);
+
+   snprintf(typestr, sizeof(typestr),
+           (DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+            DBUS_TYPE_STRING_AS_STRING
+            "%c"
+            DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
+           type);
+
+   dbus_message_iter_open_container(&variant, DBUS_TYPE_ARRAY, typestr, &dict);
+   dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+
+   dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
+
+   if ((type == DBUS_TYPE_STRING) || (type == DBUS_TYPE_OBJECT_PATH))
+     dbus_message_iter_append_basic(&entry, type, &value);
+   else
+     dbus_message_iter_append_basic(&entry, type, value);
+
+   dbus_message_iter_close_container(&dict, &entry);
+   dbus_message_iter_close_container(&variant, &dict);
+   dbus_message_iter_close_container(&itr, &variant);
+
+   return e_connman_element_message_send
+     (element, name, NULL, msg, &element->_pending.property_set, cb, data);
+}
+
+/**
  * Call method SetProperty(prop, value) at the given element on server.
  *
  * This is a server call, not local, so it may fail and in that case
index b30e58b..df114ca 100644 (file)
@@ -1039,6 +1039,102 @@ e_connman_service_ipv4_configuration_netmask_get(const E_Connman_Element *servic
 }
 
 /**
+ * Set IPv4 to connect automatically using DHCP.
+ *
+ * @param service path to set.
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_service_ipv4_configure_dhcp(E_Connman_Element *service, E_DBus_Method_Return_Cb cb, const void *data)
+{
+   const char method[] = "dhcp";
+   EINA_SAFETY_ON_NULL_RETURN_VAL(service, 0);
+   return e_connman_element_property_dict_set_full
+     (service, e_connman_prop_ipv4_configuration, e_connman_prop_method,
+      DBUS_TYPE_STRING, method, cb, data);
+}
+
+/**
+ * Set IPv4 to connect using manually set parameters.
+ *
+ * @param service path to set.
+ * @param address IPv4 address.
+ * @param netmask IPv4 netmask, or @c NULL for "/32"
+ * @param cb function to call when server replies or some error happens.
+ * @param data data to give to cb when it is called.
+ *
+ * @return 1 on success, 0 otherwise.
+ */
+bool
+e_connman_service_ipv4_configure_manual(E_Connman_Element *service, const char *address, const char *netmask, E_DBus_Method_Return_Cb cb, const void *data)
+{
+   const char name[] = "SetProperty";
+   const char *method = "manual"; /* not method[] as gcc screws it with dbus */
+   DBusMessage *msg;
+   DBusMessageIter itr, variant, dict, entry;
+
+   EINA_SAFETY_ON_NULL_RETURN_VAL(service, 0);
+   EINA_SAFETY_ON_NULL_RETURN_VAL(address, 0);
+
+   msg = dbus_message_new_method_call
+     (e_connman_system_bus_name_get(), service->path, service->interface, name);
+
+   if (!msg)
+     return 0;
+
+   dbus_message_iter_init_append(msg, &itr);
+   dbus_message_iter_append_basic
+     (&itr, DBUS_TYPE_STRING, &e_connman_prop_ipv4_configuration);
+
+   dbus_message_iter_open_container
+     (&itr, DBUS_TYPE_VARIANT,
+      (DBUS_TYPE_ARRAY_AS_STRING
+       DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+       DBUS_TYPE_STRING_AS_STRING
+       DBUS_TYPE_STRING_AS_STRING
+       DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
+      &variant);
+   dbus_message_iter_open_container
+     (&variant, DBUS_TYPE_ARRAY,
+      (DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
+       DBUS_TYPE_STRING_AS_STRING
+       DBUS_TYPE_STRING_AS_STRING
+       DBUS_DICT_ENTRY_END_CHAR_AS_STRING),
+      &dict);
+
+   dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+   dbus_message_iter_append_basic
+     (&entry, DBUS_TYPE_STRING, &e_connman_prop_method);
+   dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &method);
+   dbus_message_iter_close_container(&dict, &entry);
+
+   dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+   dbus_message_iter_append_basic
+     (&entry, DBUS_TYPE_STRING, &e_connman_prop_address);
+   dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &address);
+   dbus_message_iter_close_container(&dict, &entry);
+
+   if (netmask)
+     {
+       dbus_message_iter_open_container
+         (&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry);
+       dbus_message_iter_append_basic
+         (&entry, DBUS_TYPE_STRING, &e_connman_prop_netmask);
+       dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &netmask);
+       dbus_message_iter_close_container(&dict, &entry);
+     }
+
+   dbus_message_iter_close_container(&variant, &dict);
+   dbus_message_iter_close_container(&itr, &variant);
+
+   return e_connman_element_message_send
+     (service, name, NULL, msg, &service->_pending.property_set, cb, data);
+}
+
+/**
  * Get property "Ethernet.Method" value.
  *
  * If this property isn't found then 0 is returned.