Adding --get-current-settings switch which can be used to query 
ip-settings among some other useful data obtained from remote end when 
connected.

This is mainly useful with modems which do not provide a dhcp server for 
nameserver or ip-information (especially in ipv6 networks).

Signed-off-by: Antti Seppälä <a.sepp...@gmail.com>
Tested-by: Matti Laakso <malaa...@elisanet.fi>
---
 commands-wds.c | 124 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 commands-wds.h |   4 +-
 2 files changed, 126 insertions(+), 2 deletions(-)

diff --git a/commands-wds.c b/commands-wds.c
index fdf9003..19b3b40 100644
--- a/commands-wds.c
+++ b/commands-wds.c
@@ -20,6 +20,7 @@
  */
 
 #include <stdlib.h>
+#include <arpa/inet.h>
 
 #include "qmi-message.h"
 
@@ -185,7 +186,6 @@ cmd_wds_set_ip_family_prepare(struct qmi_dev *qmi, struct 
qmi_request *req, stru
                { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED },
        };
        int i;
-
        for (i = 0; i < ARRAY_SIZE(modes); i++) {
                if (strcasecmp(modes[i].name, arg) != 0)
                        continue;
@@ -198,3 +198,125 @@ cmd_wds_set_ip_family_prepare(struct qmi_dev *qmi, struct 
qmi_request *req, stru
        uqmi_add_error("Invalid value (valid: ipv4, ipv6, unspecified)");
        return QMI_CMD_EXIT;
 }
+
+static void wds_to_ipv4(const char *name, const uint32_t addr)
+{
+       struct in_addr ip_addr;
+       char buf[INET_ADDRSTRLEN];
+
+       ip_addr.s_addr = htonl(addr);
+       blobmsg_add_string(&status, name, inet_ntop(AF_INET, &ip_addr, buf, 
sizeof(buf)));
+}
+
+static void wds_to_ipv6(const char *name, const uint16_t *addr)
+{
+       int i;
+       struct in6_addr ip_addr;
+       char buf[INET6_ADDRSTRLEN];
+
+       for (i = 0; i < ARRAY_SIZE(ip_addr.s6_addr16); i++) {
+               ip_addr.s6_addr16[i] = htons(addr[i]);
+       }
+
+       blobmsg_add_string(&status, name, inet_ntop(AF_INET6, &ip_addr, buf, 
sizeof(buf)));
+}
+
+static void
+cmd_wds_get_current_settings_cb(struct qmi_dev *qmi, struct qmi_request *req, 
struct qmi_msg *msg)
+{
+       void *v4, *v6, *d, *t;
+       struct qmi_wds_get_current_settings_response res;
+       const char *pdptypes[] = {
+               [QMI_WDS_PDP_TYPE_IPV4] = "ipv4",
+               [QMI_WDS_PDP_TYPE_PPP] = "ppp",
+               [QMI_WDS_PDP_TYPE_IPV6] = "ipv6",
+               [QMI_WDS_PDP_TYPE_IPV4_OR_IPV6] = "ipv4-or-ipv6",
+       };
+       const struct ip_modes {
+               const char *name;
+               const QmiWdsIpFamily mode;
+       } modes[] = {
+               { "ipv4", QMI_WDS_IP_FAMILY_IPV4 },
+               { "ipv6", QMI_WDS_IP_FAMILY_IPV6 },
+               { "unspecified", QMI_WDS_IP_FAMILY_UNSPECIFIED },
+       };
+       int i;
+
+       qmi_parse_wds_get_current_settings_response(msg, &res);
+
+       t = blobmsg_open_table(&status, NULL);
+
+       if (res.set.pdp_type && res.data.pdp_type < ARRAY_SIZE(pdptypes))
+               blobmsg_add_string(&status, "pdp-type", 
pdptypes[res.data.pdp_type]);
+
+       if (res.set.ip_family) {
+               for (i = 0; i < ARRAY_SIZE(modes); i++) {
+                       if (modes[i].mode != res.data.ip_family)
+                               continue;
+                       blobmsg_add_string(&status, "ip-family", modes[i].name);
+                       break;
+               }
+       }
+
+       if (res.set.mtu)
+               blobmsg_add_u32(&status, "mtu", res.data.mtu);
+
+       /* IPV4 */
+       v4 = blobmsg_open_table(&status, "ipv4");
+
+       if (res.set.ipv4_address)
+               wds_to_ipv4("ip", res.data.ipv4_address);
+       if (res.set.primary_ipv4_dns_address)
+               wds_to_ipv4("dns1", res.data.primary_ipv4_dns_address);
+       if (res.set.secondary_ipv4_dns_address)
+               wds_to_ipv4("dns2", res.data.secondary_ipv4_dns_address);
+       if (res.set.ipv4_gateway_address)
+               wds_to_ipv4("gateway", res.data.ipv4_gateway_address);
+       if (res.set.ipv4_gateway_subnet_mask)
+               wds_to_ipv4("subnet", res.data.ipv4_gateway_subnet_mask);
+       blobmsg_close_table(&status, v4);
+
+       /* IPV6 */
+       v6 = blobmsg_open_table(&status, "ipv6");
+
+       if (res.set.ipv6_address) {
+               wds_to_ipv6("ip", res.data.ipv6_address.address);
+               blobmsg_add_u32(&status, "ip-prefix-length", 
res.data.ipv6_address.prefix_length);
+       }
+       if (res.set.ipv6_gateway_address) {
+               wds_to_ipv6("gateway", res.data.ipv6_gateway_address.address);
+               blobmsg_add_u32(&status, "gw-prefix-length", 
res.data.ipv6_gateway_address.prefix_length);
+       }
+       if (res.set.ipv6_primary_dns_address)
+               wds_to_ipv6("dns1", res.data.ipv6_primary_dns_address);
+       if (res.set.ipv6_secondary_dns_address)
+               wds_to_ipv6("dns2", res.data.ipv6_secondary_dns_address);
+
+       blobmsg_close_table(&status, v6);
+
+       d = blobmsg_open_table(&status, "domain-names");
+       for (i = 0; i < res.data.domain_name_list_n; i++) {
+               blobmsg_add_string(&status, NULL, res.data.domain_name_list[i]);
+       }
+       blobmsg_close_table(&status, d);
+
+       blobmsg_close_table(&status, t);
+}
+
+static enum qmi_cmd_result
+cmd_wds_get_current_settings_prepare(struct qmi_dev *qmi, struct qmi_request 
*req, struct qmi_msg *msg, char *arg)
+{
+       struct qmi_wds_get_current_settings_request gcs_req;
+       memset(&gcs_req, '\0', sizeof(struct 
qmi_wds_get_current_settings_request));
+       qmi_set(&gcs_req, requested_settings,
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_PDP_TYPE |
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DNS_ADDRESS |
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GRANTED_QOS |
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_ADDRESS |
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_GATEWAY_INFO |
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_MTU |
+               
QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_DOMAIN_NAME_LIST |
+               QMI_WDS_GET_CURRENT_SETTINGS_REQUESTED_SETTINGS_IP_FAMILY);
+       qmi_set_wds_get_current_settings_request(msg, &gcs_req);
+       return QMI_CMD_REQUEST;
+}
diff --git a/commands-wds.h b/commands-wds.h
index 8ddfb1e..8cb7289 100644
--- a/commands-wds.h
+++ b/commands-wds.h
@@ -29,7 +29,8 @@
        __uqmi_command(wds_stop_network, stop-network, required, 
QMI_SERVICE_WDS), \
        __uqmi_command(wds_get_packet_service_status, get-data-status, no, 
QMI_SERVICE_WDS), \
        __uqmi_command(wds_set_autoconnect_setting, set-autoconnect, required, 
QMI_SERVICE_WDS), \
-       __uqmi_command(wds_reset, reset-wds, no, QMI_SERVICE_WDS) \
+       __uqmi_command(wds_reset, reset-wds, no, QMI_SERVICE_WDS), \
+       __uqmi_command(wds_get_current_settings, get-current-settings, no, 
QMI_SERVICE_WDS) \
 
 
 #define wds_helptext \
@@ -43,4 +44,5 @@
                "    --autoconnect:                  Disable automatic 
connect/reconnect\n" \
                "  --get-data-status:                Get current data access 
status\n" \
                "  --set-autoconnect <val>:          Get current data access 
status (disabled, enabled, paused)\n" \
+               "  --get-current-settings:           Get current connection 
settings\n" \
 
-- 
2.1.4
_______________________________________________
openwrt-devel mailing list
openwrt-devel@lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel

Reply via email to