summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntti Seppälä <a.seppala@gmail.com>2015-08-08 07:44:38 +0000
committerFelix Fietkau <nbd@openwrt.org>2015-08-13 08:56:33 +0200
commit8a97586e9445a60e355dea13aa87885ab3dcb277 (patch)
tree6cea5a7483469cd9b32fd593251cabf3a805bf5e
parent4dc4ca968008f4bdf614e8e9941e9935114d54be (diff)
uqmi: Add get-current-settings command-line switch
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.seppala@gmail.com> Tested-by: Matti Laakso <malaakso@elisanet.fi>
-rw-r--r--commands-wds.c123
-rw-r--r--commands-wds.h4
2 files changed, 126 insertions, 1 deletions
diff --git a/commands-wds.c b/commands-wds.c
index fdf9003..fabb5f4 100644
--- a/commands-wds.c
+++ b/commands-wds.c
@@ -20,6 +20,7 @@
*/
#include <stdlib.h>
+#include <arpa/inet.h>
#include "qmi-message.h"
@@ -198,3 +199,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" \