Also stick to coding style. use "strcmp ( , ) == 0" instead of (!strcmp( , ))
Signed-off-by: Ashok Nagarajan <[email protected]>
---
mesh.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/mesh.c b/mesh.c
index 3077abf..4fdad6a 100644
--- a/mesh.c
+++ b/mesh.c
@@ -232,19 +232,15 @@ static void print_all_mesh_param_descr(void)
static const struct mesh_param_descr *find_mesh_param(const char *name)
{
int i;
- const struct mesh_param_descr *mdescr = NULL;
/* Find out what mesh parameter we want to change. */
for (i = 0; i < ARRAY_SIZE(_mesh_param_descrs); i++) {
- if (!strcmp(_mesh_param_descrs[i].name, name))
+ if (strcmp(_mesh_param_descrs[i].name, name) == 0)
return _mesh_param_descrs + i;
}
- if (!mdescr) {
- print_all_mesh_param_descr();
- return NULL;
- }
- return mdescr;
+ print_all_mesh_param_descr();
+ return NULL;
}
/* Setter */
--
1.7.5.4
iw dev <devname> get mesh_stats [<stats>] gets statistics of the mesh network.
It will use the new %NL80211_CMD_GET_MESH_STATS command.
Signed-off-by: Ashok Nagarajan <[email protected]>
---
mesh.c | 117 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
util.c | 2 +
2 files changed, 119 insertions(+), 0 deletions(-)
diff --git a/mesh.c b/mesh.c
index 4fdad6a..32135ae 100644
--- a/mesh.c
+++ b/mesh.c
@@ -23,6 +23,14 @@ typedef struct _any_t {
} u;
} _any;
+/* describes a mesh stats */
+struct mesh_stats_descr {
+ const char *name;
+ enum nl80211_mesh_stats mesh_stats_num;
+ int (*nla_put_fn)(struct nl_msg*, int, _any*);
+ void (*nla_print_fn)(struct nlattr *);
+};
+
/* describes a mesh parameter */
struct mesh_param_descr {
const char *name;
@@ -150,6 +158,38 @@ static void _print_s32_in_dBm(struct nlattr *a)
printf("%d dBm", (int32_t) nla_get_u32(a));
}
+/* The current mesh stats */
+const static struct mesh_stats_descr _mesh_stats_descrs[] =
+{
+ {"mesh_fwded_mcast",
+ NL80211_MESH_STATS_FWDED_MCAST,
+ _my_nla_put_u32, _print_u32},
+ {"mesh_fwded_unicast",
+ NL80211_MESH_STATS_FWDED_UNICAST,
+ _my_nla_put_u32, _print_u32},
+ {"mesh_fwded_frames",
+ NL80211_MESH_STATS_FWDED_FRAMES,
+ _my_nla_put_u32, _print_u32},
+ {"mesh_dropped_frames_ttl",
+ NL80211_MESH_STATS_DROPPED_FRAMES_TTL,
+ _my_nla_put_u32, _print_u32},
+ {"mesh_dropped_frames_no_route",
+ NL80211_MESH_STATS_DROPPED_FRAMES_NO_ROUTE,
+ _my_nla_put_u32, _print_u32},
+ {"mesh_dropped_frames_congestion",
+ NL80211_MESH_STATS_DROPPED_FRAMES_CONGESTION,
+ _my_nla_put_u32, _print_u32},
+};
+
+static void print_all_mesh_stats_descr(void)
+{
+ int i;
+
+ printf("Possible mesh stats are:\n");
+
+ for (i = 0; i < ARRAY_SIZE(_mesh_stats_descrs); i++)
+ printf(" - %s\n", _mesh_stats_descrs[i].name);
+}
/* The current mesh parameters */
const static struct mesh_param_descr _mesh_param_descrs[] =
@@ -229,6 +269,19 @@ static void print_all_mesh_param_descr(void)
printf(" - %s\n", _mesh_param_descrs[i].name);
}
+static const struct mesh_stats_descr *find_mesh_stats(const char *name)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(_mesh_stats_descrs); i++) {
+ if (strcmp(_mesh_stats_descrs[i].name, name) == 0)
+ return _mesh_stats_descrs + i;
+ }
+
+ print_all_mesh_stats_descr();
+ return NULL;
+}
+
static const struct mesh_param_descr *find_mesh_param(const char *name)
{
int i;
@@ -351,6 +404,70 @@ static int print_mesh_param_handler(struct nl_msg *msg, void *arg)
return NL_SKIP;
}
+static int print_mesh_stats_handler(struct nl_msg *msg, void *arg)
+{
+ const struct mesh_stats_descr *mdescr = arg;
+ struct nlattr *attrs[NL80211_ATTR_MAX + 1];
+ struct nlattr *parent_attr;
+ struct nlattr *mesh_stats[NL80211_MESH_STATS_ATTR_MAX + 1];
+ struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+
+ /* locate NL80211_ATTR_MESH_STATS */
+ nla_parse(attrs, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+ genlmsg_attrlen(gnlh, 0), NULL);
+ parent_attr = attrs[NL80211_ATTR_MESH_STATS];
+ if (!parent_attr)
+ return -EINVAL;
+
+ if (nla_parse_nested(mesh_stats, NL80211_MESH_STATS_ATTR_MAX,
+ parent_attr, NULL))
+ return -EINVAL;
+
+ /* Print all mesh stats if no parameter is passed */
+ if (!mdescr) {
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(_mesh_stats_descrs); i++) {
+ mdescr = &_mesh_stats_descrs[i];
+ printf("%s = ", mdescr->name);
+ mdescr->nla_print_fn(mesh_stats[mdescr->mesh_stats_num]);
+ printf("\n");
+ }
+ return NL_SKIP;
+ }
+
+ /* Print the mesh stat requested */
+ mdescr->nla_print_fn(mesh_stats[mdescr->mesh_stats_num]);
+ printf("\n");
+ return NL_SKIP;
+}
+
+static int get_interface_meshstats(struct nl80211_state *state,
+ struct nl_cb *cb,
+ struct nl_msg *msg,
+ int argc, char **argv,
+ enum id_input id)
+{
+ const struct mesh_stats_descr *mdescr = NULL;
+
+ if (argc > 1)
+ return 1;
+
+ if (argc == 1) {
+ mdescr = find_mesh_stats(argv[0]);
+ if (!mdescr)
+ return 2;
+ }
+
+ nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM,
+ print_mesh_stats_handler, (void *)mdescr);
+ return 0;
+}
+
+COMMAND(get, mesh_stats, "[<stats>]",
+ NL80211_CMD_GET_MESH_STATS, 0, CIB_NETDEV, get_interface_meshstats,
+ "Retrieve mesh statistics (run command without any to see available ones).");
+
static int get_interface_meshparam(struct nl80211_state *state,
struct nl_cb *cb,
struct nl_msg *msg,
diff --git a/util.c b/util.c
index e40a2d5..6ceb9d4 100644
--- a/util.c
+++ b/util.c
@@ -236,6 +236,8 @@ static const char *commands[NL80211_CMD_MAX + 1] = {
[NL80211_CMD_UNEXPECTED_4ADDR_FRAME] = "unexpected_4addr_frame",
[NL80211_CMD_SET_NOACK_MAP] = "set_noack_map",
[NL80211_CMD_CH_SWITCH_NOTIFY] = "ch_switch_notify",
+ [NL80211_CMD_GET_MESH_STATS] = "get_mesh_stats",
+
};
static char cmdbuf[100];
--
1.7.5.4
On Tue, 2012-10-09 at 13:29 -0700, Ashok Nagarajan wrote:
> Also stick to coding style. use "strcmp ( , ) == 0" instead of (!strcmp( , ))
Applied, I'll take the 2nd patch after the u64 changes
johannes