From 954ce7c35f36bb669a3ba76a35a3e6d14de24b5b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 7 Sep 2012 18:03:54 -0500 Subject: core: implement GetIP4ConfigEx Allows returning the IP method, prefix, and gateway along with other information. --- .../org.freedesktop.ModemManager.Modem.xml | 19 ++++ plugins/mm-modem-hso.c | 7 +- src/mm-modem.c | 107 +++++++++++++++++++++ 3 files changed, 132 insertions(+), 1 deletion(-) diff --git a/introspection/org.freedesktop.ModemManager.Modem.xml b/introspection/org.freedesktop.ModemManager.Modem.xml index e246881f8..bd78a5664 100644 --- a/introspection/org.freedesktop.ModemManager.Modem.xml +++ b/introspection/org.freedesktop.ModemManager.Modem.xml @@ -50,6 +50,25 @@ + + + Request the IPv4 configuration from the device. Supported for all + modes (DHCP, static, PPP) and should be used in preference to + GetIP4Config. + + + + + IP configuration method to be used. + + + Dictionary of IPv4 configuration details, including "address", + "prefix", "gateway", "dns1", "dns2", etc. All IP addresses given + as strings; "prefix" given as a unsigned integer value. Most values + are only relevant for the MM_MODEM_IP_METHOD_STATIC IPMethod. + + + Get the card information (manufacturer, modem, version). diff --git a/plugins/mm-modem-hso.c b/plugins/mm-modem-hso.c index 39a83fee7..74c470847 100644 --- a/plugins/mm-modem-hso.c +++ b/plugins/mm-modem-hso.c @@ -548,8 +548,13 @@ get_ip4_config_done (MMAtSerialPort *port, break; } } else if (i == 1) { /* IP address */ - if (inet_pton (AF_INET, *iter, &tmp) > 0) + if (inet_pton (AF_INET, *iter, &tmp) > 0) { mm_callback_info_set_data (info, "ip4-address", GUINT_TO_POINTER (tmp), NULL); + mm_callback_info_set_data (info, "ip4-netmask", GUINT_TO_POINTER (0xFFFFFF), NULL); + } + } else if (i == 2) { /* Gateway */ + if (inet_pton (AF_INET, *iter, &tmp) > 0) + mm_callback_info_set_data (info, "ip4-gateway", GUINT_TO_POINTER (tmp), NULL); } else if (i == 3) { /* DNS 1 */ if (inet_pton (AF_INET, *iter, &tmp) > 0) g_array_append_val (dns_array, tmp); diff --git a/src/mm-modem.c b/src/mm-modem.c index 341bb7843..69c40ed7b 100644 --- a/src/mm-modem.c +++ b/src/mm-modem.c @@ -17,16 +17,20 @@ #include #include #include +#include + #include "mm-modem.h" #include "mm-log.h" #include "mm-errors.h" #include "mm-callback-info.h" #include "mm-marshal.h" +#include "mm-utils.h" static void impl_modem_enable (MMModem *modem, gboolean enable, DBusGMethodInvocation *context); static void impl_modem_connect (MMModem *modem, const char *number, DBusGMethodInvocation *context); static void impl_modem_disconnect (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_get_ip4_config (MMModem *modem, DBusGMethodInvocation *context); +static void impl_modem_get_ip4_config_ex (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_get_info (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_reset (MMModem *modem, DBusGMethodInvocation *context); static void impl_modem_factory_reset (MMModem *modem, const char *code, DBusGMethodInvocation *context); @@ -340,6 +344,109 @@ impl_modem_get_ip4_config (MMModem *modem, mm_modem_get_ip4_config (modem, get_ip4_done, context); } +static guint32 +_ip4_netmask_to_prefix (guint32 netmask) +{ + guchar *p, *end; + guint32 prefix = 0; + + p = (guchar *) &netmask; + end = p + sizeof (guint32); + + while ((*p == 0xFF) && p < end) { + prefix += 8; + p++; + } + + if (p < end) { + guchar v = *p; + + while (v) { + prefix++; + v <<= 1; + } + } + + return prefix; +} + +static void +get_ip4_ex_done (MMModem *modem, + guint32 address, + guint32 netmask, + guint32 gateway, + GArray *dns, + GError *error, + gpointer user_data) +{ + DBusGMethodInvocation *context = (DBusGMethodInvocation *) user_data; + GHashTable *props; + MMModemIpMethod method = MM_MODEM_IP_METHOD_PPP; + char buf[INET_ADDRSTRLEN + 1]; + guint32 num; + + if (error) { + dbus_g_method_return_error (context, error); + return; + } + + props = value_hash_new (); + g_object_get (G_OBJECT (modem), MM_MODEM_IP_METHOD, &method, NULL); + value_hash_add_uint (props, "method", method); + + if (method == MM_MODEM_IP_METHOD_STATIC) { + g_assert (address); + g_assert (netmask); + + if (address) { + if (inet_ntop (AF_INET, (void *) &address, buf, sizeof (buf) - 1)) + value_hash_add_string (props, "address", buf); + else + mm_warn ("Failed to convert IP address 0x%04X", address); + } + + if (netmask) + value_hash_add_uint (props, "prefix", _ip4_netmask_to_prefix (netmask)); + + if (gateway) { + if (inet_ntop (AF_INET, (void *) &gateway, buf, sizeof (buf) - 1)) + value_hash_add_string (props, "gateway", buf); + else + mm_warn ("Failed to convert IP gateway 0x%04X", gateway); + } + + if (dns->len >= 1) { + num = g_array_index (dns, guint32, 0); + if (num) { + if (inet_ntop (AF_INET, (void *) &num, buf, sizeof (buf) - 1)) + value_hash_add_string (props, "dns1", buf); + else + mm_warn ("Failed to convert IP DNS1 0x%04X", num); + } + } + + if (dns->len >= 2) { + num = g_array_index (dns, guint32, 1); + if (num) { + if (inet_ntop (AF_INET, (void *) &num, buf, sizeof (buf) - 1)) + value_hash_add_string (props, "dns2", buf); + else + mm_warn ("Failed to convert IP DNS2 0x%04X", num); + } + } + } + + dbus_g_method_return (context, props); + g_hash_table_unref (props); +} + +static void +impl_modem_get_ip4_config_ex (MMModem *modem, + DBusGMethodInvocation *context) +{ + mm_modem_get_ip4_config (modem, get_ip4_ex_done, context); +} + void mm_modem_disconnect (MMModem *self, MMModemStateReason reason, -- cgit v1.2.1