All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH wpan-tools v2 0/8] iwpan: Scan support
@ 2023-01-06 11:18 Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 1/8] iwpan: Synchronize nl802154.h with the latest kernel Miquel Raynal
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

Hello,

This series follows the work done in the Linux kernel stack [1]: now
that the core knows about the different netlink commands and attributes
in order to support scanning requests, we can sync the userspace tools
to use them.

As part of these additions, a few cleanup patches are introducing the
series, including a first sync with a recent change in nl802154.h.

[1] https://lore.kernel.org/linux-wpan/ec93100f-8c55-2f54-d3d5-63f31c2602f4@datenfreihafen.org/T/#t

Cheers,
Miquèl

Changes in v2:
* Adapted to the latest kernel changes.
* Added a real "monitor" command in place of the scan done command.
* Renamed iwpan event into iwpan monitor.
* Dropped an unused function.
* Changed the behavior of the scan monitor call.
* Added SIGINT support to send an abort.
* Avoided a race in the scan command by using pthread when starting to
  monitor, before triggering the scan operation.
* Dropped beaconing support for this first version.

David Girault (4):
  iwpan: Export iwpan_debug
  iwpan: Remove duplicated SECTION
  iwpan: Add scan support
  iwpan: Add events support

Miquel Raynal (3):
  iwpan: Synchronize nl802154.h with the latest kernel
  iwpan: Fix a comment
  iwpan: Synchronize nl802154.h with the latest scan changes

Romuald Despres (1):
  iwpan: Fix the channels printing

 src/Makefile.am |   2 +
 src/event.c     | 230 ++++++++++++++++++++
 src/info.c      |   2 +-
 src/iwpan.c     |   2 +-
 src/iwpan.h     |  10 +-
 src/nl802154.h  | 107 +++++++++-
 src/scan.c      | 548 ++++++++++++++++++++++++++++++++++++++++++++++++
 7 files changed, 888 insertions(+), 13 deletions(-)
 create mode 100644 src/event.c
 create mode 100644 src/scan.c

-- 
2.34.1


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 1/8] iwpan: Synchronize nl802154.h with the latest kernel
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 2/8] iwpan: Fix the channels printing Miquel Raynal
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

The low-level security commands are now listed inconditionnally, so
let's reflect this change in the header so that the addition of further
commands is made at the right location.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/nl802154.h | 6 ++----
 1 file changed, 2 insertions(+), 4 deletions(-)

diff --git a/src/nl802154.h b/src/nl802154.h
index ddcee12..eb8ad48 100644
--- a/src/nl802154.h
+++ b/src/nl802154.h
@@ -56,9 +56,6 @@ enum nl802154_commands {
 
 	NL802154_CMD_SET_WPAN_PHY_NETNS,
 
-	/* add new commands above here */
-
-#ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
 	NL802154_CMD_SET_SEC_PARAMS,
 	NL802154_CMD_GET_SEC_KEY,		/* can dump */
 	NL802154_CMD_NEW_SEC_KEY,
@@ -72,7 +69,8 @@ enum nl802154_commands {
 	NL802154_CMD_GET_SEC_LEVEL,		/* can dump */
 	NL802154_CMD_NEW_SEC_LEVEL,
 	NL802154_CMD_DEL_SEC_LEVEL,
-#endif /* CONFIG_IEEE802154_NL802154_EXPERIMENTAL */
+
+	/* add new commands above here */
 
 	/* used to define NL802154_CMD_MAX below */
 	__NL802154_CMD_AFTER_LAST,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 2/8] iwpan: Fix the channels printing
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 1/8] iwpan: Synchronize nl802154.h with the latest kernel Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 3/8] iwpan: Export iwpan_debug Miquel Raynal
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Romuald Despres,
	Miquel Raynal

From: Romuald Despres <Romuald.Despres@qorvo.com>

The presence of a channel capability is checked against the tb_msg
netlink attributes array which is the root one, while here we are
looking for channel capabilities, themselves being nested and parsed
into tb_caps. Use tb_caps instead of tb_msg here otherwise we are
accessing a random index in the upper attributes list.

Signed-off-by: Romuald Despres <Romuald.Despres@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/info.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/info.c b/src/info.c
index f85690c..8ed5e4f 100644
--- a/src/info.c
+++ b/src/info.c
@@ -342,7 +342,7 @@ static int print_phy_handler(struct nl_msg *msg, void *arg)
 			printf("\b \n");
 		}
 
-		if (tb_msg[NL802154_CAP_ATTR_CHANNELS]) {
+		if (tb_caps[NL802154_CAP_ATTR_CHANNELS]) {
 			int counter = 0;
 			int rem_pages;
 			struct nlattr *nl_pages;
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 3/8] iwpan: Export iwpan_debug
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 1/8] iwpan: Synchronize nl802154.h with the latest kernel Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 2/8] iwpan: Fix the channels printing Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 4/8] iwpan: Fix a comment Miquel Raynal
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

From: David Girault <david.girault@qorvo.com>

This debug flag will be used later on in different files.

Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/iwpan.c | 2 +-
 src/iwpan.h | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/src/iwpan.c b/src/iwpan.c
index fb7bef1..3cf5fe2 100644
--- a/src/iwpan.c
+++ b/src/iwpan.c
@@ -21,7 +21,7 @@
 
 /* TODO libnl 1.x compatibility code */
 
-static int iwpan_debug = 0;
+int iwpan_debug = 0;
 
 static int nl802154_init(struct nl802154_state *state)
 {
diff --git a/src/iwpan.h b/src/iwpan.h
index 48c4f03..860dd37 100644
--- a/src/iwpan.h
+++ b/src/iwpan.h
@@ -120,4 +120,6 @@ DECLARE_SECTION(get);
 
 const char *iftype_name(enum nl802154_iftype iftype);
 
+extern int iwpan_debug;
+
 #endif /* __IWPAN_H */
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 4/8] iwpan: Fix a comment
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
                   ` (2 preceding siblings ...)
  2023-01-06 11:18 ` [PATCH wpan-tools v2 3/8] iwpan: Export iwpan_debug Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 5/8] iwpan: Remove duplicated SECTION Miquel Raynal
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

There are a couple of words missing, add them to clarify the comment.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/iwpan.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/iwpan.h b/src/iwpan.h
index 860dd37..9d265c6 100644
--- a/src/iwpan.h
+++ b/src/iwpan.h
@@ -43,7 +43,7 @@ struct cmd {
 	const enum command_identify_by idby;
 	/* The handler should return a negative error code,
 	 * zero on success, 1 if the arguments were wrong
-	 * and the usage message should and 2 otherwise.
+	 * and the usage message should be displayed, 2 otherwise.
 	 */
 	int (*handler)(struct nl802154_state *state,
 		       struct nl_cb *cb,
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 5/8] iwpan: Remove duplicated SECTION
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
                   ` (3 preceding siblings ...)
  2023-01-06 11:18 ` [PATCH wpan-tools v2 4/8] iwpan: Fix a comment Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 6/8] iwpan: Synchronize nl802154.h with the latest scan changes Miquel Raynal
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

From: David Girault <david.girault@qorvo.com>

This section has been duplicated, drop one.

Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/iwpan.h | 6 ------
 1 file changed, 6 deletions(-)

diff --git a/src/iwpan.h b/src/iwpan.h
index 9d265c6..406940a 100644
--- a/src/iwpan.h
+++ b/src/iwpan.h
@@ -90,12 +90,6 @@ struct cmd {
 		.handler = (_handler),					\
 		.help = (_help),					\
 	 }
-#define SECTION(_name)							\
-	struct cmd __section ## _ ## _name				\
-	__attribute__((used)) __attribute__((section("__cmd"))) = {	\
-		.name = (#_name),					\
-		.hidden = 1,						\
-	}
 
 #define SECTION(_name)							\
 	struct cmd __section ## _ ## _name				\
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 6/8] iwpan: Synchronize nl802154.h with the latest scan changes
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
                   ` (4 preceding siblings ...)
  2023-01-06 11:18 ` [PATCH wpan-tools v2 5/8] iwpan: Remove duplicated SECTION Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 7/8] iwpan: Add scan support Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 8/8] iwpan: Add events support Miquel Raynal
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

The content of this file has evolved, reflect the changes accepted in the
mainline Linux kernel here with the additional scan definitions.

Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/nl802154.h | 101 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)

diff --git a/src/nl802154.h b/src/nl802154.h
index eb8ad48..648fc93 100644
--- a/src/nl802154.h
+++ b/src/nl802154.h
@@ -70,6 +70,11 @@ enum nl802154_commands {
 	NL802154_CMD_NEW_SEC_LEVEL,
 	NL802154_CMD_DEL_SEC_LEVEL,
 
+	NL802154_CMD_SCAN_EVENT,
+	NL802154_CMD_TRIGGER_SCAN,
+	NL802154_CMD_ABORT_SCAN,
+	NL802154_CMD_SCAN_DONE,
+
 	/* add new commands above here */
 
 	/* used to define NL802154_CMD_MAX below */
@@ -129,6 +134,15 @@ enum nl802154_attrs {
 	NL802154_ATTR_PID,
 	NL802154_ATTR_NETNS_FD,
 
+	NL802154_ATTR_COORDINATOR,
+	NL802154_ATTR_SCAN_TYPE,
+	NL802154_ATTR_SCAN_FLAGS,
+	NL802154_ATTR_SCAN_CHANNELS,
+	NL802154_ATTR_SCAN_PREAMBLE_CODES,
+	NL802154_ATTR_SCAN_MEAN_PRF,
+	NL802154_ATTR_SCAN_DURATION,
+	NL802154_ATTR_SCAN_DONE_REASON,
+
 	/* add attributes here, update the policy in nl802154.c */
 
 #ifdef CONFIG_IEEE802154_NL802154_EXPERIMENTAL
@@ -215,6 +229,93 @@ enum nl802154_wpan_phy_capability_attr {
 	NL802154_CAP_ATTR_MAX = __NL802154_CAP_ATTR_AFTER_LAST - 1
 };
 
+/**
+ * enum nl802154_scan_types - Scan types
+ *
+ * @__NL802154_SCAN_INVALID: scan type number 0 is reserved
+ * @NL802154_SCAN_ED: An ED scan allows a device to obtain a measure of the peak
+ *	energy in each requested channel
+ * @NL802154_SCAN_ACTIVE: Locate any coordinator transmitting Beacon frames using
+ *	a Beacon Request command
+ * @NL802154_SCAN_PASSIVE: Locate any coordinator transmitting Beacon frames
+ * @NL802154_SCAN_ORPHAN: Relocate coordinator following a loss of synchronisation
+ * @NL802154_SCAN_ENHANCED_ACTIVE: Same as Active using Enhanced Beacon Request
+ *	command instead of Beacon Request command
+ * @NL802154_SCAN_RIT_PASSIVE: Passive scan for RIT Data Request command frames
+ *	instead of Beacon frames
+ * @NL802154_SCAN_ATTR_MAX: Maximum SCAN attribute number
+ */
+enum nl802154_scan_types {
+	__NL802154_SCAN_INVALID,
+	NL802154_SCAN_ED,
+	NL802154_SCAN_ACTIVE,
+	NL802154_SCAN_PASSIVE,
+	NL802154_SCAN_ORPHAN,
+	NL802154_SCAN_ENHANCED_ACTIVE,
+	NL802154_SCAN_RIT_PASSIVE,
+
+	/* keep last */
+	NL802154_SCAN_ATTR_MAX,
+};
+
+/**
+ * enum nl802154_scan_done_reasons - End of scan reasons
+ *
+ * @__NL802154_SCAN_DONE_REASON_INVALID: scan done reason number 0 is reserved.
+ * @NL802154_SCAN_DONE_REASON_FINISHED: The scan just finished naturally after
+ *      going through all the requested and possible (complex) channels.
+ * @NL802154_SCAN_DONE_REASON_ABORTED: The scan was aborted upon user request.
+ *      a Beacon Request command
+ * @NL802154_SCAN_DONE_REASON_MAX: Maximum scan done reason attribute number.
+ */
+enum nl802154_scan_done_reasons {
+        __NL802154_SCAN_DONE_REASON_INVALID,
+        NL802154_SCAN_DONE_REASON_FINISHED,
+        NL802154_SCAN_DONE_REASON_ABORTED,
+
+        /* keep last */
+        NL802154_SCAN_DONE_REASON_MAX,
+};
+
+/**
+ * enum nl802154_coord - Netlink attributes for a coordinator
+ *
+ * @__NL802154_COORD_INVALID: invalid
+ * @NL802154_COORD_PANID: PANID of the coordinator (2 bytes)
+ * @NL802154_COORD_ADDR: Coordinator address, (8 bytes or 2 bytes)
+ * @NL802154_COORD_CHANNEL: channel number, related to @NL802154_COORD_PAGE (u8)
+ * @NL802154_COORD_PAGE: channel page, related to @NL802154_COORD_CHANNEL (u8)
+ * @NL802154_COORD_PREAMBLE_CODE: Preamble code used when the beacon was received,
+ *     this is PHY dependent and optional (u8)
+ * @NL802154_COORD_MEAN_PRF: Mean PRF used when the beacon was received,
+ *     this is PHY dependent and optional (u8)
+ * @NL802154_COORD_SUPERFRAME_SPEC: superframe specification of the PAN (u16)
+ * @NL802154_COORD_LINK_QUALITY: signal quality of beacon in unspecified units,
+ *	scaled to 0..255 (u8)
+ * @NL802154_COORD_GTS_PERMIT: set to true if GTS is permitted on this PAN
+ * @NL802154_COORD_PAYLOAD_DATA: binary data containing the raw data from the
+ *	frame payload, (only if beacon or probe response had data)
+ * @NL802154_COORD_PAD: attribute used for padding for 64-bit alignment
+ * @NL802154_COORD_MAX: highest coordinator attribute
+ */
+enum nl802154_coord {
+	__NL802154_COORD_INVALID,
+	NL802154_COORD_PANID,
+	NL802154_COORD_ADDR,
+	NL802154_COORD_CHANNEL,
+	NL802154_COORD_PAGE,
+	NL802154_COORD_PREAMBLE_CODE,
+	NL802154_COORD_MEAN_PRF,
+	NL802154_COORD_SUPERFRAME_SPEC,
+	NL802154_COORD_LINK_QUALITY,
+	NL802154_COORD_GTS_PERMIT,
+	NL802154_COORD_PAYLOAD_DATA,
+	NL802154_COORD_PAD,
+
+	/* keep last */
+	NL802154_COORD_MAX,
+};
+
 /**
  * enum nl802154_cca_modes - cca modes
  *
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 7/8] iwpan: Add scan support
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
                   ` (5 preceding siblings ...)
  2023-01-06 11:18 ` [PATCH wpan-tools v2 6/8] iwpan: Synchronize nl802154.h with the latest scan changes Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  2023-01-06 11:18 ` [PATCH wpan-tools v2 8/8] iwpan: Add events support Miquel Raynal
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

From: David Girault <david.girault@qorvo.com>

Bring support for different scanning operations, such as starting or
aborting a scan operation with a given configuration, and dumping the
discovered coordinators.

Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/Makefile.am |   1 +
 src/scan.c      | 548 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 549 insertions(+)
 create mode 100644 src/scan.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 2d54576..18b3569 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -9,6 +9,7 @@ iwpan_SOURCES = \
 	interface.c \
 	phy.c \
 	mac.c \
+	scan.c \
 	nl_extras.h \
 	nl802154.h
 
diff --git a/src/scan.c b/src/scan.c
new file mode 100644
index 0000000..63a5e24
--- /dev/null
+++ b/src/scan.c
@@ -0,0 +1,548 @@
+#include <errno.h>
+#include <inttypes.h>
+#include <net/if.h>
+#include <signal.h>
+#include <string.h>
+#include <stdbool.h>
+#include <unistd.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl802154.h"
+#include "nl_extras.h"
+#include "iwpan.h"
+
+static char scantypebuf[100];
+
+static const char *scantype_name(enum nl802154_scan_types scantype)
+{
+	switch (scantype) {
+	case NL802154_SCAN_ED:
+		return "ed";
+	case NL802154_SCAN_ACTIVE:
+		return "active";
+	case NL802154_SCAN_PASSIVE:
+		return "passive";
+	case NL802154_SCAN_ENHANCED_ACTIVE:
+		return "enhanced";
+	case NL802154_SCAN_RIT_PASSIVE:
+		return "rit";
+	default:
+		sprintf(scantypebuf, "Invalid scantype (%d)", scantype);
+		return scantypebuf;
+	}
+}
+
+/* for help */
+#define SCAN_TYPES "Valid scanning types are: ed, active, passive, enhanced, rit."
+
+/* return 0 if ok, internal error otherwise */
+static int get_scan_type(int *argc, char ***argv, enum nl802154_scan_types *type)
+{
+	char *tpstr;
+
+	if (*argc < 2)
+		return 1;
+
+	if (strcmp((*argv)[0], "type"))
+		return 1;
+
+	tpstr = (*argv)[1];
+	*argc -= 2;
+	*argv += 2;
+
+	if (strcmp(tpstr, "ed") == 0) {
+		*type = NL802154_SCAN_ED;
+		return 0;
+	} else if (strcmp(tpstr, "active") == 0) {
+		*type = NL802154_SCAN_ACTIVE;
+		return 0;
+	} else if (strcmp(tpstr, "passive") == 0) {
+		*type = NL802154_SCAN_PASSIVE;
+		return 0;
+	} else if (strcmp(tpstr, "enhanced") == 0) {
+		*type = NL802154_SCAN_ENHANCED_ACTIVE;
+		return 0;
+	} else if (strcmp(tpstr, "rit") == 0) {
+		*type = NL802154_SCAN_RIT_PASSIVE;
+		return 0;
+	}
+
+	fprintf(stderr, "invalid interface type %s\n", tpstr);
+	return 2;
+}
+
+static int get_option_value(int *argc, char ***argv, const char *marker, unsigned long *result, bool *valid)
+{
+	unsigned long value;
+	char *tpstr, *end;
+
+	*valid = false;
+
+	if (*argc < 2)
+		return 0;
+
+	if (strcmp((*argv)[0], marker))
+		return 0;
+
+	tpstr = (*argv)[1];
+	*argc -= 2;
+	*argv += 2;
+
+	value = strtoul(tpstr, &end, 0);
+	if (*end != '\0')
+		return 1;
+
+	*result = value;
+	*valid = true;
+
+	return 0;
+}
+
+static int scan_trigger_handler(struct nl802154_state *state,
+				struct nl_cb *cb,
+				struct nl_msg *msg,
+				int argc, char **argv,
+				enum id_input id)
+{
+	enum nl802154_scan_types type;
+	unsigned long page, channels, duration;
+	int tpset;
+	bool valid_page, valid_channels, valid_duration;
+
+	if (argc < 2)
+		return 1;
+
+	tpset = get_scan_type(&argc, &argv, &type);
+	if (tpset)
+		return tpset;
+
+	tpset = get_option_value(&argc, &argv, "page", &page, &valid_page);
+	if (tpset)
+		return tpset;
+	if (valid_page && page > UINT8_MAX)
+		return 1;
+
+	tpset = get_option_value(&argc, &argv, "channels", &channels, &valid_channels);
+	if (tpset)
+		return tpset;
+	if (valid_channels && channels > UINT32_MAX)
+		return 1;
+
+	tpset = get_option_value(&argc, &argv, "duration", &duration, &valid_duration);
+	if (tpset)
+		return tpset;
+	if (valid_duration && duration > UINT8_MAX)
+		return 1;
+
+	if (argc)
+		return 1;
+
+	/* Mandatory argument */
+	NLA_PUT_U8(msg, NL802154_ATTR_SCAN_TYPE, type);
+	/* Optional arguments */
+	if (valid_duration)
+		NLA_PUT_U8(msg, NL802154_ATTR_SCAN_DURATION, duration);
+	if (valid_page)
+		NLA_PUT_U8(msg, NL802154_ATTR_PAGE, page);
+	if (valid_channels)
+		NLA_PUT_U32(msg, NL802154_ATTR_SCAN_CHANNELS, channels);
+
+	/* TODO: support IES parameters for active scans */
+
+	return 0;
+
+nla_put_failure:
+	return -ENOBUFS;
+}
+
+static int scan_abort_handler(struct nl802154_state *state,
+			      struct nl_cb *cb,
+			      struct nl_msg *msg,
+			      int argc, char **argv,
+			      enum id_input id)
+{
+	return 0;
+}
+
+struct ieee802154_addr {
+	uint16_t pan_id;
+	uint8_t addr_len;
+	union {
+		uint16_t short_addr;
+		uint64_t extended_addr;
+	};
+	struct ieee802154_addr *next;
+};
+
+static struct ieee802154_addr *known_coord_list;
+
+static bool coord_addrs_are_equal(struct ieee802154_addr *a,
+				  struct ieee802154_addr *b)
+{
+	if (a->pan_id != b->pan_id)
+		return false;
+
+	if (a->addr_len != b->addr_len)
+		return false;
+
+	if (a->addr_len == 2 && a->short_addr == b->short_addr)
+		return true;
+	else if (a->extended_addr == b->extended_addr)
+		return true;
+
+	return false;
+}
+
+static bool coord_is_known(struct ieee802154_addr *addr)
+{
+	struct ieee802154_addr *item = known_coord_list;
+
+	while (item) {
+		if (coord_addrs_are_equal(addr, item))
+			return true;
+
+		item = item->next;
+	}
+
+	return false;
+}
+
+static void record_coord(struct ieee802154_addr *addr)
+{
+	struct ieee802154_addr *item;
+
+	if (!known_coord_list) {
+		known_coord_list = addr;
+		return;
+	}
+
+	item = known_coord_list;
+	if (!item->next) {
+		item->next = addr;
+		return;
+	}
+
+	do {
+		item = item->next;
+	} while (item->next);
+
+	item->next = addr;
+}
+
+static void flush_coords(void)
+{
+	struct ieee802154_addr *item, *next;
+
+	if (!known_coord_list)
+		return;
+
+	item = known_coord_list;
+	do {
+		next = item->next;
+		free(item);
+		item = next;
+	} while (item);
+}
+
+static struct ieee802154_addr *parse_new_coordinator(struct nlattr *nestedcoord)
+{
+	struct nlattr *pan[NL802154_COORD_MAX + 1];
+	static struct nla_policy pan_policy[NL802154_COORD_MAX + 1] = {
+		[NL802154_COORD_PANID] = { .type = NLA_U16, },
+		[NL802154_COORD_ADDR] = { .minlen = 2, .maxlen = 8, }, /* 2 or 8 */
+		[NL802154_COORD_CHANNEL] = { .type = NLA_U8, },
+		[NL802154_COORD_PAGE] = { .type = NLA_U8, },
+		[NL802154_COORD_PREAMBLE_CODE] = { .type = NLA_U8, },
+		[NL802154_COORD_MEAN_PRF] = { .type = NLA_U8, },
+		[NL802154_COORD_SUPERFRAME_SPEC] = { .type = NLA_U16, },
+		[NL802154_COORD_LINK_QUALITY] = { .type = NLA_U8, },
+		[NL802154_COORD_GTS_PERMIT] = { .type = NLA_FLAG, },
+	};
+	struct ieee802154_addr *addr;
+	struct nlattr *coord;
+	char dev[20];
+	int ret;
+
+	ret = nla_parse_nested(pan, NL802154_COORD_MAX, nestedcoord, pan_policy);
+	if (ret < 0) {
+		fprintf(stderr, "failed to parse nested attributes! (ret = %d)\n",
+			ret);
+		return NULL;
+	}
+	if (!pan[NL802154_COORD_PANID] || !pan[NL802154_COORD_ADDR])
+		return NULL;
+
+	addr = malloc(sizeof(*addr));
+	if (!addr)
+		return NULL;
+
+	addr->pan_id = nla_get_u16(pan[NL802154_COORD_PANID]);
+	coord = pan[NL802154_COORD_ADDR];
+	addr->addr_len = nla_len(coord);
+	if (addr->addr_len == 2)
+		addr->short_addr = nla_get_u16(coord);
+	else
+		addr->extended_addr = nla_get_u64(coord);
+
+	return addr;
+}
+
+static int print_new_coordinator(struct nlattr *nestedcoord,
+				 struct nlattr *ifattr)
+{
+	struct nlattr *pan[NL802154_COORD_MAX + 1];
+	static struct nla_policy pan_policy[NL802154_COORD_MAX + 1] = {
+		[NL802154_COORD_PANID] = { .type = NLA_U16, },
+		[NL802154_COORD_ADDR] = { .minlen = 2, .maxlen = 8, }, /* 2 or 8 */
+		[NL802154_COORD_CHANNEL] = { .type = NLA_U8, },
+		[NL802154_COORD_PAGE] = { .type = NLA_U8, },
+		[NL802154_COORD_PREAMBLE_CODE] = { .type = NLA_U8, },
+		[NL802154_COORD_MEAN_PRF] = { .type = NLA_U8, },
+		[NL802154_COORD_SUPERFRAME_SPEC] = { .type = NLA_U16, },
+		[NL802154_COORD_LINK_QUALITY] = { .type = NLA_U8, },
+		[NL802154_COORD_GTS_PERMIT] = { .type = NLA_FLAG, },
+	};
+	char dev[20];
+	int ret;
+
+	ret = nla_parse_nested(pan, NL802154_COORD_MAX, nestedcoord, pan_policy);
+	if (ret < 0) {
+		fprintf(stderr, "failed to parse nested attributes! (ret = %d)\n",
+			ret);
+		return NL_SKIP;
+	}
+	if (!pan[NL802154_COORD_PANID])
+		return NL_SKIP;
+
+	printf("PAN 0x%04x", le16toh(nla_get_u16(pan[NL802154_COORD_PANID])));
+	if (ifattr) {
+		if_indextoname(nla_get_u32(ifattr), dev);
+		printf(" (on %s)", dev);
+	}
+	printf("\n");
+	if (pan[NL802154_COORD_ADDR]) {
+		struct nlattr *coord = pan[NL802154_COORD_ADDR];
+		if (nla_len(coord) == 2) {
+			uint16_t addr = nla_get_u16(coord);
+			printf("\tcoordinator 0x%04x\n", le16toh(addr));
+		} else {
+			uint64_t addr = nla_get_u64(coord);
+			printf("\tcoordinator 0x%016" PRIx64 "\n", le64toh(addr));
+		}
+	}
+	if (pan[NL802154_COORD_PAGE]) {
+		printf("\tpage %u\n", nla_get_u8(pan[NL802154_COORD_PAGE]));
+	}
+	if (pan[NL802154_COORD_CHANNEL]) {
+		printf("\tchannel %u\n", nla_get_u8(pan[NL802154_COORD_CHANNEL]));
+	}
+	if (pan[NL802154_COORD_SUPERFRAME_SPEC]) {
+		printf("\tsuperframe spec. 0x%x\n", nla_get_u16(
+				pan[NL802154_COORD_SUPERFRAME_SPEC]));
+	}
+	if (pan[NL802154_COORD_LINK_QUALITY]) {
+		printf("\tLQI %x\n", nla_get_u8(
+				pan[NL802154_COORD_LINK_QUALITY]));
+	}
+	if (pan[NL802154_COORD_GTS_PERMIT]) {
+		printf("\tGTS permitted\n");
+	}
+
+	/* TODO: Beacon IES display/decoding */
+
+	return NL_OK;
+}
+
+static int parse_and_print_new_coordinator(struct nlattr *nestedcoord,
+					   struct nlattr *ifattr)
+{
+	struct ieee802154_addr *addr;
+
+	addr = parse_new_coordinator(nestedcoord);
+	if (!addr)
+		return NL_SKIP;
+
+	if (coord_is_known(addr)) {
+		free(addr);
+	} else {
+		record_coord(addr);
+		print_new_coordinator(nestedcoord, ifattr);
+	}
+
+	return NL_OK;
+}
+
+static int parse_and_print_scan_event(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct nlattr *tb[NL802154_ATTR_MAX + 1];
+	struct nlattr *nestedcoord;
+
+	nla_parse(tb, NL802154_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+	nestedcoord = tb[NL802154_ATTR_COORDINATOR];
+	if (!nestedcoord) {
+		fprintf(stderr, "coordinator info missing!\n");
+		return NL_SKIP;
+	}
+
+	return parse_and_print_new_coordinator(nestedcoord, tb[NL802154_ATTR_IFINDEX]);
+}
+
+struct scan_done {
+	volatile int done;
+	int devidx;
+};
+
+static int scan_message_handler(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct scan_done *sd = (struct scan_done *)arg;
+
+	if (gnlh->cmd == NL802154_CMD_SCAN_EVENT)
+		return parse_and_print_scan_event(msg, arg);
+
+	if (gnlh->cmd != NL802154_CMD_SCAN_DONE &&
+	    gnlh->cmd != NL802154_CMD_ABORT_SCAN)
+		return 0;
+
+	if (sd->devidx != -1) {
+		struct nlattr *tb[NL802154_ATTR_MAX + 1];
+		nla_parse(tb, NL802154_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+			genlmsg_attrlen(gnlh, 0), NULL);
+		if (!tb[NL802154_ATTR_IFINDEX] ||
+		    nla_get_u32(tb[NL802154_ATTR_IFINDEX]) != sd->devidx)
+			return 0;
+	}
+
+	sd->done = 1;
+	return 0;
+}
+
+static int no_seq_check(struct nl_msg *msg, void *arg)
+{
+	return NL_OK;
+}
+
+struct abort_info {
+	char *cmd[3];
+	struct nl802154_state *state;
+	enum id_input id;
+	struct scan_done *sd;
+};
+
+static struct abort_info abort_info = {
+	.cmd = { NULL, "scan", "abort" },
+};
+
+static void scan_sigint_handler(int signo)
+{
+	/* dev <iface> scan abort */
+	handle_cmd(abort_info.state, abort_info.id, 3, abort_info.cmd);
+	abort_info.sd->done = 1;
+	nl_socket_set_nonblocking(abort_info.state->nl_sock);
+}
+
+static int scan_handler(struct nl802154_state *state, struct nl_cb *cb,
+			struct nl_msg *msg, int argc, char **argv,
+			enum id_input id)
+{
+	struct scan_done sd;
+	int ret, group;
+
+	/* Abort scan upon SIGINT */
+	abort_info.cmd[0] = argv[0];
+	abort_info.state = state;
+	abort_info.id = id;
+	abort_info.sd = &sd;
+	signal(SIGINT, scan_sigint_handler);
+
+	/* Create netlink message to trigger the scan */
+	msg = nlmsg_alloc();
+	if (!msg) {
+		fprintf(stderr, "failed to allocate netlink message\n");
+		return 2;
+	}
+
+	cb = nl_cb_alloc(iwpan_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
+	if (!cb) {
+		fprintf(stderr, "failed to allocate netlink callbacks\n");
+		ret = 2;
+		goto free_msg;
+	}
+
+	genlmsg_put(msg, 0, 0, state->nl802154_id, 0, 0,
+		    NL802154_CMD_TRIGGER_SCAN, 0);
+
+	sd.devidx = if_nametoindex(*argv);
+	if (sd.devidx == 0)
+		sd.devidx = -1;
+
+	NLA_PUT_U32(msg, NL802154_ATTR_IFINDEX, sd.devidx);
+
+	/* Skip "<iface> scan" */
+	argc -= 2;
+	argv += 2;
+
+	/* Parse the "trigger" command */
+	ret = scan_trigger_handler(state, cb, msg, argc, argv, id);
+	if (ret)
+		goto nla_put_failure;
+
+	/* Configure socket to receive messages in Scan multicast group */
+	group = genl_ctrl_resolve_grp(state->nl_sock, "nl802154", "scan");
+	if (group < 0) {
+		ret = group;
+		goto nla_put_failure;
+	}
+
+	ret = nl_socket_add_membership(state->nl_sock, group);
+	if (ret)
+		goto nla_put_failure;
+
+	/* Install scan message handler */
+	nl_socket_set_cb(state->nl_sock, cb);
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, scan_message_handler, &sd);
+
+	/* No sequence checking for multicast messages */
+	nl_socket_disable_seq_check(state->nl_sock);
+
+	/* Trigger the scan */
+	ret = nl_send_auto_complete(state->nl_sock, msg);
+	if (ret < 0)
+		goto nla_put_failure;
+
+	ret = 0;
+
+	/* Receive messages */
+	sd.done = 0;
+	do {
+		nl_recvmsgs(state->nl_sock, cb);
+	} while (!sd.done);
+
+	flush_coords();
+
+nla_put_failure:
+	nl_cb_put(cb);
+free_msg:
+	nlmsg_free(msg);
+
+	return ret;
+}
+TOPLEVEL(scan, "type <type> [page <page>] [channels <bitfield>] [duration <duration-order>]",
+	0, 0, CIB_NETDEV, scan_handler,
+	"Scan on this virtual interface with the given configuration.\n"
+	SCAN_TYPES);
+COMMAND(scan, abort, NULL, NL802154_CMD_ABORT_SCAN, 0, CIB_NETDEV, scan_abort_handler,
+	"Abort ongoing scanning on this virtual interface");
+COMMAND(scan, trigger,
+	"type <type> [page <page>] [channels <bitfield>] [duration <duration-order>]",
+	NL802154_CMD_TRIGGER_SCAN, 0, CIB_NETDEV, scan_trigger_handler,
+	"Launch scanning on this virtual interface with the given configuration.\n"
+	SCAN_TYPES);
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH wpan-tools v2 8/8] iwpan: Add events support
  2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
                   ` (6 preceding siblings ...)
  2023-01-06 11:18 ` [PATCH wpan-tools v2 7/8] iwpan: Add scan support Miquel Raynal
@ 2023-01-06 11:18 ` Miquel Raynal
  7 siblings, 0 replies; 9+ messages in thread
From: Miquel Raynal @ 2023-01-06 11:18 UTC (permalink / raw)
  To: Alexander Aring, Stefan Schmidt, linux-wpan
  Cc: David Girault, Romuald Despres, Frederic Blain, Nicolas Schodet,
	Guilhem Imberton, Thomas Petazzoni, Miquel Raynal

From: David Girault <david.girault@qorvo.com>

Add the possibility to listen to the scan multicast netlink family in
order to print all the events happening in the 802.15.4 stack, like the
discovery of a new coordinator or an end of scan.

Signed-off-by: David Girault <david.girault@qorvo.com>
Signed-off-by: Miquel Raynal <miquel.raynal@bootlin.com>
---
 src/Makefile.am |   1 +
 src/event.c     | 230 ++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 231 insertions(+)
 create mode 100644 src/event.c

diff --git a/src/Makefile.am b/src/Makefile.am
index 18b3569..7933daf 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -10,6 +10,7 @@ iwpan_SOURCES = \
 	phy.c \
 	mac.c \
 	scan.c \
+	event.c \
 	nl_extras.h \
 	nl802154.h
 
diff --git a/src/event.c b/src/event.c
new file mode 100644
index 0000000..5ec597d
--- /dev/null
+++ b/src/event.c
@@ -0,0 +1,230 @@
+#include <net/if.h>
+#include <errno.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <inttypes.h>
+
+#include <netlink/genl/genl.h>
+#include <netlink/genl/family.h>
+#include <netlink/genl/ctrl.h>
+#include <netlink/msg.h>
+#include <netlink/attr.h>
+
+#include "nl802154.h"
+#include "nl_extras.h"
+#include "iwpan.h"
+
+struct print_event_args {
+	struct timeval ts; /* internal */
+	bool have_ts; /* must be set false */
+	bool frame, time, reltime;
+};
+
+static int print_event(struct nl_msg *msg, void *arg)
+{
+	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
+	struct nlattr *tb[NL802154_ATTR_MAX + 1], *nst, *nestedcoord;
+	struct nlattr *pan[NL802154_COORD_MAX + 1];
+	struct print_event_args *args = arg;
+	char ifname[100];
+	static struct nla_policy pan_policy[NL802154_COORD_MAX + 1] = {
+		[NL802154_COORD_PANID] = { .type = NLA_U16, },
+		[NL802154_COORD_ADDR] = { .minlen = 2, .maxlen = 8, }, /* 2 or 8 */
+	};
+	uint8_t reg_type;
+	uint32_t wpan_phy_idx = 0;
+	int rem_nst;
+	uint16_t status;
+	int ret;
+
+	if (args->time || args->reltime) {
+		unsigned long long usecs, previous;
+
+		previous = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec;
+		gettimeofday(&args->ts, NULL);
+		usecs = 1000000ULL * args->ts.tv_sec + args->ts.tv_usec;
+		if (args->reltime) {
+			if (!args->have_ts) {
+				usecs = 0;
+				args->have_ts = true;
+			} else
+				usecs -= previous;
+		}
+		printf("%llu.%06llu: ", usecs/1000000, usecs % 1000000);
+	}
+
+	nla_parse(tb, NL802154_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
+		  genlmsg_attrlen(gnlh, 0), NULL);
+
+	if (tb[NL802154_ATTR_IFINDEX] && tb[NL802154_ATTR_WPAN_PHY]) {
+		if_indextoname(nla_get_u32(tb[NL802154_ATTR_IFINDEX]), ifname);
+		printf("%s (phy #%d): ", ifname, nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]));
+	} else if (tb[NL802154_ATTR_WPAN_DEV] && tb[NL802154_ATTR_WPAN_PHY]) {
+		printf("wdev 0x%llx (phy #%d): ",
+			(unsigned long long)nla_get_u64(tb[NL802154_ATTR_WPAN_DEV]),
+			nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]));
+	} else if (tb[NL802154_ATTR_IFINDEX]) {
+		if_indextoname(nla_get_u32(tb[NL802154_ATTR_IFINDEX]), ifname);
+		printf("%s: ", ifname);
+	} else if (tb[NL802154_ATTR_WPAN_DEV]) {
+		printf("wdev 0x%llx: ", (unsigned long long)nla_get_u64(tb[NL802154_ATTR_WPAN_DEV]));
+	} else if (tb[NL802154_ATTR_WPAN_PHY]) {
+		printf("phy #%d: ", nla_get_u32(tb[NL802154_ATTR_WPAN_PHY]));
+	}
+
+	switch (gnlh->cmd) {
+	case NL802154_CMD_NEW_WPAN_PHY:
+		printf("renamed to %s\n", nla_get_string(tb[NL802154_ATTR_WPAN_PHY_NAME]));
+		break;
+	case NL802154_CMD_DEL_WPAN_PHY:
+		printf("delete wpan_phy\n");
+		break;
+	case NL802154_CMD_TRIGGER_SCAN:
+		printf("scan started\n");
+		break;
+	case NL802154_CMD_SCAN_DONE:
+		if (tb[NL802154_ATTR_SCAN_DONE_REASON])
+			status = nla_get_u8(tb[NL802154_ATTR_SCAN_DONE_REASON]);
+		if (status == NL802154_SCAN_DONE_REASON_ABORTED)
+			printf("scan aborted\n");
+		else
+			printf("scan finished\n");
+		break;
+	case NL802154_CMD_ABORT_SCAN:
+		printf("scan aborted\n");
+		break;
+	case NL802154_CMD_SCAN_EVENT:
+		nestedcoord = tb[NL802154_ATTR_COORDINATOR];
+		if (!nestedcoord)
+			break;
+		ret = nla_parse_nested(pan, NL802154_COORD_MAX, nestedcoord, pan_policy);
+		if (ret < 0)
+			break;
+		if (!pan[NL802154_COORD_PANID])
+			break;
+		printf("beacon received: PAN 0x%04x",
+		       le16toh(nla_get_u16(pan[NL802154_COORD_PANID])));
+		if (pan[NL802154_COORD_ADDR]) {
+			struct nlattr *coord = pan[NL802154_COORD_ADDR];
+			if (nla_len(coord) == 2) {
+				uint16_t addr = nla_get_u16(coord);
+				printf(", addr 0x%04x\n", le16toh(addr));
+			} else {
+				uint64_t addr = nla_get_u64(coord);
+				printf(", addr 0x%016" PRIx64 "\n", le64toh(addr));
+			}
+		}
+		break;
+	default:
+		printf("unknown event %d\n", gnlh->cmd);
+		break;
+	}
+	fflush(stdout);
+	return NL_SKIP;
+}
+
+static int __prepare_listen_events(struct nl802154_state *state)
+{
+	int mcid, ret;
+
+	/* Configuration multicast group */
+	mcid = genl_ctrl_resolve_grp(state->nl_sock, NL802154_GENL_NAME,
+				     "config");
+	if (mcid < 0)
+		return mcid;
+	ret = nl_socket_add_membership(state->nl_sock, mcid);
+	if (ret)
+		return ret;
+
+	/* Scan multicast group */
+	mcid = genl_ctrl_resolve_grp(state->nl_sock, NL802154_GENL_NAME,
+				     "scan");
+	if (mcid >= 0) {
+		ret = nl_socket_add_membership(state->nl_sock, mcid);
+		if (ret)
+			return ret;
+	}
+
+	/* MLME multicast group */
+	mcid = genl_ctrl_resolve_grp(state->nl_sock, NL802154_GENL_NAME,
+				     "mlme");
+	if (mcid >= 0) {
+		ret = nl_socket_add_membership(state->nl_sock, mcid);
+		if (ret)
+			return ret;
+	}
+
+	return 0;
+}
+
+static int __do_listen_events(struct nl802154_state *state,
+			      struct print_event_args *args)
+{
+	struct nl_cb *cb = nl_cb_alloc(iwpan_debug ? NL_CB_DEBUG : NL_CB_DEFAULT);
+	if (!cb) {
+		fprintf(stderr, "failed to allocate netlink callbacks\n");
+		return -ENOMEM;
+	}
+	nl_socket_set_cb(state->nl_sock, cb);
+	/* No sequence checking for multicast messages */
+	nl_socket_disable_seq_check(state->nl_sock);
+	/* Install print_event message handler */
+	nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, print_event, args);
+
+	/* Loop waiting until interrupted by signal */
+	while (1) {
+		int ret = nl_recvmsgs(state->nl_sock, cb);
+		if (ret) {
+			fprintf(stderr, "nl_recvmsgs return error %d\n", ret);
+			break;
+		}
+	}
+	/* Free allocated nl_cb structure */
+	nl_cb_put(cb);
+	return 0;
+}
+
+static int print_events(struct nl802154_state *state,
+			struct nl_cb *cb,
+			struct nl_msg *msg,
+			int argc, char **argv,
+			enum id_input id)
+{
+	struct print_event_args args;
+	int ret;
+
+	memset(&args, 0, sizeof(args));
+
+	argc--;
+	argv++;
+
+	while (argc > 0) {
+		if (strcmp(argv[0], "-f") == 0)
+			args.frame = true;
+		else if (strcmp(argv[0], "-t") == 0)
+			args.time = true;
+		else if (strcmp(argv[0], "-r") == 0)
+			args.reltime = true;
+		else
+			return 1;
+		argc--;
+		argv++;
+	}
+	if (args.time && args.reltime)
+		return 1;
+	if (argc)
+		return 1;
+
+	/* Prepare reception of all multicast messages */
+	ret = __prepare_listen_events(state);
+	if (ret)
+		return ret;
+
+	/* Read message loop */
+	return __do_listen_events(state, &args);
+}
+TOPLEVEL(monitor, "[-t|-r] [-f]", 0, 0, CIB_NONE, print_events,
+	"Monitor events from the kernel.\n"
+	"-t - print timestamp\n"
+	"-r - print relative timestamp\n"
+	"-f - print full frame for auth/assoc etc.");
-- 
2.34.1


^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2023-01-06 11:18 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-01-06 11:18 [PATCH wpan-tools v2 0/8] iwpan: Scan support Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 1/8] iwpan: Synchronize nl802154.h with the latest kernel Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 2/8] iwpan: Fix the channels printing Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 3/8] iwpan: Export iwpan_debug Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 4/8] iwpan: Fix a comment Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 5/8] iwpan: Remove duplicated SECTION Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 6/8] iwpan: Synchronize nl802154.h with the latest scan changes Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 7/8] iwpan: Add scan support Miquel Raynal
2023-01-06 11:18 ` [PATCH wpan-tools v2 8/8] iwpan: Add events support Miquel Raynal

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.