diff --git a/ChangeLog.txt b/ChangeLog.txt
index 89a5ea318..e52589cc8 100644
--- a/ChangeLog.txt
+++ b/ChangeLog.txt
@@ -1906,7 +1906,7 @@
 	  Kivilinna (2017-04-03).
 	* NSH: Fix some warnings about integer/pointer casts of different sizes
 	  (probably only effects 64-bit simulation) (2017-04-03).
-	* examples/nettest: Trying to adapt to use for testing 6loWPAN
+	* examples/nettest: Trying to adapt to use for testing 6LoWPAN
 	  (2017-04-03).
 	* examples/nettest:  If doing loopback, but not using the official
 	  loopback device, then use the server should use the configured client
@@ -1925,10 +1925,10 @@
 	  default is +x. No printing of a trace of script commands as they are
 	  executed.  From David Sidrane (2017-04-05).
 	* Print expanded variables if -x.  From David Sidrane (2017-04-05).
-	* examples/udpblaster:  Several fixes to work with 6loWPAN (2017-04-06).
+	* examples/udpblaster:  Several fixes to work with 6LoWPAN (2017-04-06).
 	* examples/udpblaster:  Add logic to bind the local UDP socket to a
 	  well-known address (2017-04-06).
-	* 6loWPAN:  Add network IOCTL support to set the node address
+	* 6LoWPAN:  Add network IOCTL support to set the node address
 	  (2017-04-06).
 	* examples/ostest: Add tests for pthread_rwlock.  Adding tests to be
 	  used to verify the pthread_rwlock lock works.  From Mark Schulte
@@ -1937,9 +1937,9 @@
 	  unconditionally (2017-04-07).
 	* examples/ostest: pthread rwlock additional tests and bugfixes.  From
 	  Mark Schulte (2017-04-07).
-	* netutils: Add a helper function to convert a string to a 6loWPAN node
+	* netutils: Add a helper function to convert a string to a 6LoWPAN node
 	  address (2017-04-08).
-	* NSH library: Extend ifconfig to support 6loWPAN.  Adapt to some
+	* NSH library: Extend ifconfig to support 6LoWPAN.  Adapt to some
 	  changes in configuration variable usage (2017-04-08).
 	* NSH set command:  Eliminate useless argc check of SCRIPTS are enabled
 	  but ENVIRONMENT is disabled (2017-04-09).
@@ -1995,7 +1995,7 @@
 	  eth0 for network device name (2017-05-02).
 	* wireless/wext:  Add drivers_wext from the WPA supplicant; Integrate
 	  into NSH.  From Simon Piriou (2017-05-02).
-	* 6loWPAN: Replace some Rime address naming with more consistent
+	* 6LoWPAN: Replace some Rime address naming with more consistent
 	  short/exended address terminology (2017-05-04).
 	* wireless/ieee802154:  Removes libradio to coincide with removal of
 	  ioctl with radio. Moves all functionality from libradio to libmac.
diff --git a/examples/smart/smart_main.c b/examples/smart/smart_main.c
index 0504ec976..56df54d73 100644
--- a/examples/smart/smart_main.c
+++ b/examples/smart/smart_main.c
@@ -55,7 +55,8 @@
 #include <nuttx/mtd/mtd.h>
 #include <nuttx/fs/smart.h>
 #include <nuttx/fs/ioctl.h>
-#include <nuttx/fs/mksmartfs.h>
+
+#include "fsutils/mksmartfs.h"
 
 /****************************************************************************
  * Pre-processor Definitions
@@ -821,7 +822,7 @@ int smart_main(int argc, char *argv[])
   /* Initialize to provide SMART on an MTD interface */
 
   MTD_IOCTL(mtd, MTDIOC_BULKERASE, 0);
-  ret = smart_initialize(1, mtd);
+  ret = smart_initialize(1, mtd, "SmartTest");
   if (ret < 0)
     {
       printf("ERROR: SMART initialization failed: %d\n", -ret);
@@ -831,7 +832,11 @@ int smart_main(int argc, char *argv[])
 
   /* Create a SMARTFS filesystem */
 
-  (void)mksmartfs("/dev/smart1");
+#ifdef CONFIG_SMARTFS_MULTI_ROOT_DIRS
+  (void)mksmartfs("/dev/smart1", 1024, 1);
+#else
+  (void)mksmartfs("/dev/smart1", 1024);
+#endif
 
   /* Mount the file system */
 
diff --git a/examples/udp/Kconfig b/examples/udp/Kconfig
index 7ca5bc70f..392ab6f73 100644
--- a/examples/udp/Kconfig
+++ b/examples/udp/Kconfig
@@ -12,9 +12,79 @@ config EXAMPLES_UDP
 
 if EXAMPLES_UDP
 
-config EXAMPLES_UDP_SERVER
-	bool "Target is the server"
+config EXAMPLES_UDP_SERVER1
+	bool "Target1 is the server"
 	default n
+	---help---
+		By default Target1 is the client and the host PC is the server
+
+config EXAMPLES_UDP_PROGNAME1
+	string "Target1 program name"
+	default "udpserver" if EXAMPLES_UDP_SERVER1
+	default "udpclient" if !EXAMPLES_UDP_SERVER1
+	depends on BUILD_KERNEL
+	---help---
+		This is the name of the Target1 program that will be use when the
+		NSH ELF program is installed.
+
+config EXAMPLES_UDP_PRIORITY1
+	int "Target1 task priority"
+	default 100
+
+config EXAMPLES_UDP_STACKSIZE1
+	int "Target1 stack size"
+	default 2048
+
+config EXAMPLES_UDP_TARGET2
+	bool "Second endpoint is a target"
+	default n
+	---help---
+		By default, the host PC is configured as the second endpoint of the
+		UDP test.  If this option is selected, then the second endpoint
+		will be built into the FLASH image as well.  This means that you
+		can use two target boards to run the test with not host PC
+		involvement.
+
+if EXAMPLES_UDP_TARGET2
+
+config EXAMPLES_UDP_PROGNAME2
+	string "Target2 program name"
+	default "udpserver" if !EXAMPLES_UDP_SERVER2
+	default "udpclient" if EXAMPLES_UDP_SERVER2
+	depends on BUILD_KERNEL
+	---help---
+		This is the name of the Target2 program that will be use when the
+		NSH ELF program is installed.
+
+config EXAMPLES_UDP_PRIORITY2
+	int "Target2 task priority"
+	default 100
+
+config EXAMPLES_UDP_STACKSIZE2
+	int "Target2 stack size"
+	default 2048
+
+endif # EXAMPLES_UDP_TARGET2
+
+config EXAMPLES_UDP_DEVNAME
+	string "Network device"
+	default "eth0"
+
+config EXAMPLES_UDP_NETINIT
+	bool "Initialize network"
+	default n if NSH_NETINIT
+	default y if !NSH_NETINIT
+	---help---
+		Selecting this option will enable logic in the example to perform
+		some basic initialization of the network.  You would probably only
+		want to do this if the example is running stand-alone.  If the
+		example is running as an NSH command, then the network as already
+		been initialized.
+
+		This basic initialization currently only supports basic
+		initialization of Ethernet network devices.  For other exotic
+		network devices this initialization should be suppressed.  Such
+		devices will require other, external initialization.
 
 choice
 	prompt "IP Domain"
@@ -35,6 +105,8 @@ if EXAMPLES_UDP_IPv4
 
 comment "IPv4 addresses"
 
+if EXAMPLES_UDP_NETINIT
+
 config EXAMPLES_UDP_IPADDR
 	hex "Target IP address"
 	default 0x0a000002
@@ -47,16 +119,17 @@ config EXAMPLES_UDP_NETMASK
 	hex "Network mask"
 	default 0xffffff00
 
+endif # !EXAMPLES_UDP_NETINIT
+
 config EXAMPLES_UDP_SERVERIP
 	hex "Server IP address"
-	default 0x0a000001 if !EXAMPLES_UDP_SERVER
-	default 0x0a000002 if EXAMPLES_UDP_SERVER
-
+	default 0x0a000001 if !EXAMPLES_UDP_SERVER1
+	default 0x0a000002 if EXAMPLES_UDP_SERVER1
 
 endif # EXAMPLES_UDP_IPv4
 
 if EXAMPLES_UDP_IPv6
-if !NET_ICMPv6_AUTOCONF
+if !NET_ICMPv6_AUTOCONF && EXAMPLES_UDP_NETINIT
 
 comment "Target IPv6 address"
 
@@ -306,7 +379,7 @@ config EXAMPLES_UDP_IPv6NETMASK_8
 
 endif # NET_ICMPv6_AUTOCONF
 
-comment "Server IPv6 address"
+comment "Default Server IPv6 address"
 
 config EXAMPLES_UDP_SERVERIPv6ADDR_1
 	hex "[0]"
@@ -422,8 +495,8 @@ config EXAMPLES_UDP_SERVERIPv6ADDR_7
 
 config EXAMPLES_UDP_SERVERIPv6ADDR_8
 	hex "[7]"
-	default 0x0001 if !EXAMPLES_UDP_SERVER
-	default 0x0002 if EXAMPLES_UDP_SERVER
+	default 0x0001 if !EXAMPLES_UDP_SERVER1
+	default 0x0002 if EXAMPLES_UDP_SERVER1
 	range 0x0 0xffff
 	---help---
 		IP address of the server.  If the target is the server, then
@@ -438,4 +511,13 @@ config EXAMPLES_UDP_SERVERIPv6ADDR_8
 		This is the last of the 8-values.
 
 endif # EXAMPLES_UDP_IPv6
+
+config EXAMPLES_SERVER_PORTNO
+	int "Server port number"
+	default 5471
+
+config EXAMPLES_CLIENT_PORTNO
+	int "Client port number"
+	default 5472
+
 endif # EXAMPLES_UDP
diff --git a/examples/udp/Makefile b/examples/udp/Makefile
index 3603ee0c3..0627426e6 100644
--- a/examples/udp/Makefile
+++ b/examples/udp/Makefile
@@ -39,25 +39,94 @@ include $(APPDIR)/Make.defs
 
 # UDP Test
 
-TARG_ASRCS =
-
-TARG_CSRCS =
-ifeq ($(CONFIG_EXAMPLES_UDP_SERVER),y)
-TARG_CSRCS += udp-server.c
-else
-TARG_CSRCS += udp-client.c
+TARGCMN_CSRCS = udp_cmdline.c
+ifeq ($(CONFIG_EXAMPLES_UDP_NETINIT),y)
+TARGCMN_CSRCS += target_netinit.c
 endif
-TARG_MAINSRC = target.c
+TARGCMN_COBJS = $(TARGCMN_CSRCS:.c=$(OBJEXT))
 
-TARG_AOBJS = $(TARG_ASRCS:.S=$(OBJEXT))
-TARG_COBJS = $(TARG_CSRCS:.c=$(OBJEXT))
-TARG_MAINOBJ = $(TARG_MAINSRC:.c=$(OBJEXT))
+# Target 1
 
-TARG_SRCS = $(TARG_ASRCS) $(TARG_CSRCS) $(TARG_MAINSRC)
-TARG_OBJS = $(TARG_AOBJS) $(TARG_COBJS)
+TARG1_CRCS =
+ifeq ($(CONFIG_EXAMPLES_UDP_SERVER1),y)
+TARG1_CRCS += udp_server.c
+else
+TARG1_CRCS += udp_client.c
+endif
+TARG1_MAINSRC = target1.c
+
+TARG1_COBJS = $(TARG1_CRCS:.c=$(OBJEXT))
+TARG1_MAINOBJ = $(TARG1_MAINSRC:.c=$(OBJEXT))
+
+ifeq ($(CONFIG_EXAMPLES_UDP_SERVER1),y)
+CONFIG_EXAMPLES_UDP_PROGNAME1 ?= udpserver
+APPNAME1 = udpserver
+else
+CONFIG_EXAMPLES_UDP_PROGNAME1 ?= udpclient
+APPNAME1 = udpclient
+endif
+CONFIG_EXAMPLES_UDP_PRIORITY1 ?= 100
+CONFIG_EXAMPLES_UDP_STACKSIZE1 ?= 2048
+
+PROGNAME1 = $(CONFIG_EXAMPLES_UDP_PROGNAME1)
+PRIORITY1 = $(CONFIG_EXAMPLES_UDP_PRIORITY1)
+STACKSIZE1 = $(CONFIG_EXAMPLES_UDP_STACKSIZE1)
+
+# Target 2
+
+ifeq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
+
+TARG2_CRCS =
+ifeq ($(CONFIG_EXAMPLES_UDP_SERVER1),y)
+TARG2_CRCS += udp_client.c
+else
+TARG2_CRCS += udp_server.c
+endif
+TARG2_MAINSRC = target2.c
+
+TARG2_COBJS = $(TARG2_CRCS:.c=$(OBJEXT))
+TARG2_MAINOBJ = $(TARG2_MAINSRC:.c=$(OBJEXT))
+
+ifeq ($(CONFIG_EXAMPLES_UDP_SERVER1),y)
+CONFIG_EXAMPLES_UDP_PROGNAME2 ?= udpclient
+APPNAME2 = udpclient
+else
+CONFIG_EXAMPLES_UDP_PROGNAME2 ?= udpserver
+APPNAME2 = udpserver
+endif
+CONFIG_EXAMPLES_UDP_PRIORITY2 ?= 100
+CONFIG_EXAMPLES_UDP_STACKSIZE2 ?= 2048
+
+PROGNAME2 = $(CONFIG_EXAMPLES_UDP_PROGNAME2)
+PRIORITY2 = $(CONFIG_EXAMPLES_UDP_PRIORITY2)
+STACKSIZE2 = $(CONFIG_EXAMPLES_UDP_STACKSIZE2)
+
+endif
+
+TARG_SRCS = $(TARG1_CRCS) $(TARG1_MAINSRC) $(TARG2_CRCS) $(TARG2_MAINSRC) $(TARGCMN_CSRCS)
+TARG_OBJS = $(TARG1_COBJS) $(TARG2_COBJS) $(TARGCMN_COBJS)
 
 ifneq ($(CONFIG_BUILD_KERNEL),y)
-  TARG_OBJS += $(TARG_MAINOBJ)
+  TARG_OBJS += $(TARG1_MAINOBJ) $(TARG2_MAINOBJ)
+endif
+
+# Host
+
+ifneq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
+
+HOSTCFLAGS += -DEXAMPLES_UDP_HOST=1
+HOSTOBJSEXT ?= o1
+
+HOST_SRCS = host.c udp_cmdline.c
+ifeq ($(CONFIG_EXAMPLES_UDP_SERVER1),y)
+HOST_SRCS += udp_client.c
+else
+HOST_SRCS += udp_server.c
+endif
+
+HOST_OBJS = $(HOST_SRCS:.c=.$(HOSTOBJSEXT))
+HOST_BIN = host$(EXEEXT)
+
 endif
 
 ifeq ($(CONFIG_WINDOWS_NATIVE),y)
@@ -70,27 +139,19 @@ else
 endif
 endif
 
-HOSTCFLAGS += -DEXAMPLES_UDP_HOST=1
-
-HOST_SRCS = host.c
-ifeq ($(CONFIG_EXAMPLES_UDP_SERVER),y)
-HOST_SRCS += udp-client.c
+ifeq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
+MAINNAME1 = udp1_main
+MAINNAME2 = udp2_main
 else
-HOST_SRCS += udp-server.c
+MAINNAME1 = udp_main
 endif
 
-HOST_OBJS = $(HOST_SRCS:.c=.o)
-HOST_BIN = host
-
 ifeq ($(WINTOOL),y)
   INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}"
 else
   INSTALL_DIR = $(BIN_DIR)
 endif
 
-CONFIG_XYZ_PROGNAME ?= udp$(EXEEXT)
-PROGNAME = $(CONFIG_XYZ_PROGNAME)
-
 ROOTDEPPATH = --dep-path .
 
 # Common build
@@ -98,45 +159,61 @@ ROOTDEPPATH = --dep-path .
 VPATH =
 
 all: .built
-.PHONY: clean depend distclean
+.PHONY: clean depend distclean preconfig
 
-$(TARG_AOBJS): %$(OBJEXT): %.S
-	$(call ASSEMBLE, $<, $@)
-
-$(TARG_COBJS) $(TARG_MAINOBJ): %$(OBJEXT): %.c
+$(TARG1_COBJS) $(TARG1_MAINOBJ)$(TARG2_COBJS) $(TARG2_MAINOBJ) $(TARGCMN_COBJS): %$(OBJEXT): %.c
 	$(call COMPILE, $<, $@)
 
 $(TARG_BIN): $(TARG_OBJS) $(HOST_BIN)
 	$(call ARCHIVE, $@, $(TARG_OBJS))
 
-$(HOST_OBJS): %.o: %.c
+ifneq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
+$(HOST_OBJS): %.$(HOSTOBJSEXT): %.c
 	@echo "CC:  $<"
 	$(Q) $(HOSTCC) -c $(HOSTCFLAGS) $< -o $@
+endif
 
 config.h: $(TOPDIR)/include/nuttx/config.h
 	@echo "CP:  $<"
 	$(Q) cp $< $@
 
+ifneq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
 $(HOST_BIN): config.h $(HOST_OBJS)
 	$(Q) $(HOSTCC) $(HOSTLDFLAGS) $(HOST_OBJS) -o $@
+endif
 
 .built: config.h $(TARG_BIN) $(HOST_BIN)
 	$(Q) touch .built
 
 ifeq ($(CONFIG_BUILD_KERNEL),y)
-$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(TARG_MAINOBJ)
-	@echo "LD: $(PROGNAME)"
-	$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(TARG_MAINOBJ) $(LDLIBS)
-	$(Q) $(NM) -u  $(INSTALL_DIR)$(DELIM)$(PROGNAME)
+$(BIN_DIR)$(DELIM)$(PROGNAME1): $(OBJS) $(TARG1_MAINOBJ)
+	@echo "LD: $(PROGNAME1)"
+	$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME1) $(ARCHCRT0OBJ) $(TARG1_MAINOBJ) $(LDLIBS)
+	$(Q) $(NM) -u  $(INSTALL_DIR)$(DELIM)$(PROGNAME1)
 
-install: $(BIN_DIR)$(DELIM)$(PROGNAME)
+install: $(BIN_DIR)$(DELIM)$(PROGNAME1)
 
 else
 install:
 
 endif
 
+ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat: $(DEPCONFIG) Makefile
+	$(call REGISTER,$(APPNAME1),$(PRIORITY1),$(STACKSIZE1),$(MAINNAME1))
+
+ifeq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
+$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat: $(DEPCONFIG) Makefile
+	$(call REGISTER,$(APPNAME2),$(PRIORITY2),$(STACKSIZE2),$(MAINNAME2))
+
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat \
+	$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME2)_main.bdat
+else
+context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME1)_main.bdat
+endif
+else
 context:
+endif
 
 .depend: Makefile config.h $(TARG_SRCS)
 	@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(TARG_SRCS) >Make.dep
@@ -146,8 +223,11 @@ depend: .depend
 
 clean:
 	$(call DELFILE, .built)
-	$(call DELFILE, $(TARG_BIN))
+	#$(call DELFILE, $(TARG_BIN))
+ifneq ($(CONFIG_EXAMPLES_UDP_TARGET2),y)
 	$(call DELFILE, $(HOST_BIN))
+	$(call DELFILE, *.$(HOSTOBJSEXT))
+endif
 	$(call DELFILE, *.dSYM)
 	$(call DELFILE, config.h)
 	$(call CLEAN)
@@ -156,7 +236,6 @@ distclean: clean
 	$(call DELFILE, Make.dep)
 	$(call DELFILE, .depend)
 
--include Make.dep
-
-.PHONY: preconfig
 preconfig:
+
+-include Make.dep
diff --git a/examples/udp/host.c b/examples/udp/host.c
index 6ea487712..f51410913 100644
--- a/examples/udp/host.c
+++ b/examples/udp/host.c
@@ -38,7 +38,7 @@
  ****************************************************************************/
 
 #include "config.h"
-#include "udp-internal.h"
+#include "udp.h"
 
 /****************************************************************************
  * Private Data
@@ -54,7 +54,13 @@
 
 int main(int argc, char **argv, char **envp)
 {
-#ifdef CONFIG_EXAMPLES_UDP_SERVER
+  /* Parse any command line options */
+
+  parse_cmdline(argc, argv);
+
+  /* Run the server or client, depending upon how target1 was configured */
+
+#ifdef CONFIG_EXAMPLES_UDP_SERVER1
   send_client();
 #else
   recv_server();
diff --git a/examples/udp/udp-internal.h b/examples/udp/target1.c
similarity index 74%
rename from examples/udp/udp-internal.h
rename to examples/udp/target1.c
index 8bd6fbe58..f64c7e098 100644
--- a/examples/udp/udp-internal.h
+++ b/examples/udp/target1.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * examples/udp/udp-internal.h
+ * examples/udp/target1.c
  *
- *   Copyright (C) 2007, 2008, 2015 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007, 2011, 2015, 2017 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -33,49 +33,46 @@
  *
  ****************************************************************************/
 
-#ifndef __EXAMPLES_UDP_INTERNAL_H
-#define __EXAMPLES_UDP_INTERNAL_H
-
 /****************************************************************************
  * Included Files
  ****************************************************************************/
 
-#ifdef EXAMPLES_UDP_HOST
-#else
-# include <debug.h>
-#endif
-
-#include <arpa/inet.h>
+#include "config.h"
+#include "udp.h"
 
 /****************************************************************************
- * Pre-processor Definitions
+ * Public Functions
  ****************************************************************************/
 
-#ifdef EXAMPLES_UDP_HOST
-   /* HTONS/L macros are unique to uIP */
-
-#  define HTONS(a)       htons(a)
-#  define HTONL(a)       htonl(a)
-#endif
-
-#ifdef CONFIG_EXAMPLES_UDP_IPv6
-#  define AF_INETX AF_INET6
-#  define PF_INETX PF_INET6
-#else
-#  define AF_INETX AF_INET
-#  define PF_INETX PF_INET
-#endif
-
-#define PORTNO     5471
-
-#define ASCIISIZE  (0x7f - 0x20)
-#define SENDSIZE   (ASCIISIZE+1)
-
 /****************************************************************************
- * Public Function Prototypes
+ * udp1_main
  ****************************************************************************/
 
-extern void send_client(void);
-extern void recv_server(void);
+#if defined(CONFIG_BUILD_KERNEL)
+int main(int argc, FAR char *argv[])
+#elif defined(CONFIG_EXAMPLES_UDP_TARGET2)
+int udp1_main(int argc, char *argv[])
+#else
+int udp_main(int argc, char *argv[])
+#endif
+{
+  /* Parse any command line options */
 
-#endif /* __EXAMPLES_UDP_INTERNAL_H */
+  parse_cmdline(argc, argv);
+
+#ifdef CONFIG_EXAMPLES_UDP_NETINIT
+  /* Initialize the network */
+
+  (void)target_netinit();
+#endif
+
+  /* Run the server or client, depending upon how we are configured */
+
+#ifdef CONFIG_EXAMPLES_UDP_SERVER1
+  recv_server();
+#else
+  send_client();
+#endif
+
+  return 0;
+}
diff --git a/netutils/netlib/netlib_setnodeaddr.c b/examples/udp/target2.c
similarity index 60%
rename from netutils/netlib/netlib_setnodeaddr.c
rename to examples/udp/target2.c
index e88ca727b..84332504b 100644
--- a/netutils/netlib/netlib_setnodeaddr.c
+++ b/examples/udp/target2.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * netutils/netlib/netlib_setnodeaddr.c
+ * examples/udp/target2.c
  *
  *   Copyright (C) 2017 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
@@ -37,73 +37,40 @@
  * Included Files
  ****************************************************************************/
 
-#include <nuttx/config.h>
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <stdint.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-
-#include <netinet/in.h>
-#include <net/if.h>
-
-#include <nuttx/net/sixlowpan.h>
-
-#include "netutils/netlib.h"
-
-#if defined(CONFIG_NET_6LOWPAN) && CONFIG_NSOCKET_DESCRIPTORS > 0
+#include "config.h"
+#include "udp.h"
 
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: netlib_setnodeaddr
- *
- * Description:
- *   Set the 6loWPAN IEEE802.15.4 MAC network driver node address
- *
- * Parameters:
- *   ifname   The name of the interface to use
- *   nodeaddr Node address to set, size must be NET_6LOWPAN_ADDRSIZE
- *
- * Return:
- *   0 on success; -1 on failure
- *
+ * udp2_main
  ****************************************************************************/
 
-int netlib_setnodeaddr(FAR const char *ifname, FAR const uint8_t *nodeaddr)
+#if defined(CONFIG_BUILD_KERNEL)
+int main(int argc, FAR char *argv[])
+#else
+int udp2_main(int argc, char *argv[])
+#endif
 {
-  int ret = ERROR;
+  /* Parse any command line options */
 
-  if (ifname && nodeaddr)
-    {
-      /* Get a socket (only so that we get access to the INET subsystem) */
+  parse_cmdline(argc, argv);
 
-      int sockfd = socket(PF_INET6, NETLIB_SOCK_IOCTL, 0);
-      if (sockfd >= 0)
-        {
-          struct ifreq req;
+#ifdef CONFIG_EXAMPLES_UDP_NETINIT
+  /* Initialize the network */
 
-          /* Put the driver name into the request */
+  (void)target_netinit();
+#endif
 
-          strncpy(req.ifr_name, ifname, IFNAMSIZ);
+  /* Run the server or client, depending upon how target1 was configured */
 
-          /* Put the new MAC address into the request */
+#ifdef CONFIG_EXAMPLES_UDP_SERVER1
+  send_client();
+#else
+  recv_server();
+#endif
 
-          req.ifr_hwaddr.sa_family = AF_INET6;
-          memcpy(&req.ifr_hwaddr.sa_data, nodeaddr, NET_6LOWPAN_ADDRSIZE);
-
-          /* Perform the ioctl to set the node address */
-
-          ret = ioctl(sockfd, SIOCSIFHWADDR, (unsigned long)&req);
-          close(sockfd);
-        }
-    }
-
-  return ret;
+  return 0;
 }
-
-#endif /* CONFIG_NET_6LOWPAN && CONFIG_NSOCKET_DESCRIPTORS */
diff --git a/examples/udp/target.c b/examples/udp/target_netinit.c
similarity index 72%
rename from examples/udp/target.c
rename to examples/udp/target_netinit.c
index 0074cb999..d66a6d3ca 100644
--- a/examples/udp/target.c
+++ b/examples/udp/target_netinit.c
@@ -1,7 +1,7 @@
 /****************************************************************************
- * examples/udp/target.c
+ * examples/udp/target_netinit.c
  *
- *   Copyright (C) 2007, 2011, 2015 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2007, 2011, 2015, 2017 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
@@ -39,6 +39,7 @@
 
 #include "config.h"
 
+#include <stdbool.h>
 #include <stdio.h>
 #include <debug.h>
 
@@ -47,12 +48,20 @@
 
 #include "netutils/netlib.h"
 
-#include "udp-internal.h"
+#include "udp.h"
+
+#ifdef CONFIG_EXAMPLES_UDP_NETINIT
 
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
 
+#ifdef CONFIG_EXAMPLES_UDP_DEVNAME
+#  define DEVNAME CONFIG_EXAMPLES_UDP_DEVNAME
+#else
+#  define DEVNAME "eth0"
+#endif
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
@@ -101,76 +110,75 @@ static const uint16_t g_ipv6_netmask[8] =
 };
 #endif /* CONFIG_EXAMPLES_UDP_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF */
 
+static bool g_initialized;
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * udp_main
+ * target_netinit
  ****************************************************************************/
 
-#ifdef CONFIG_BUILD_KERNEL
-int main(int argc, FAR char *argv[])
-#else
-int udp_main(int argc, char *argv[])
-#endif
+int target_netinit(void)
 {
+  if (!g_initialized)
+    {
 #ifdef CONFIG_EXAMPLES_UDP_IPv6
 #ifdef CONFIG_NET_ICMPv6_AUTOCONF
-  /* Perform ICMPv6 auto-configuration */
+      /* Perform ICMPv6 auto-configuration */
 
-  netlib_icmpv6_autoconfiguration("eth0");
+      netlib_icmpv6_autoconfiguration(DEVNAME);
 
 #else /* CONFIG_NET_ICMPv6_AUTOCONF */
 
-  /* Set up our fixed host address */
+      /* Set up our fixed host address */
 
-  netlib_set_ipv6addr("eth0",
-                      (FAR const struct in6_addr *)g_ipv6_hostaddr);
+      netlib_set_ipv6addr(DEVNAME,
+                          (FAR const struct in6_addr *)g_ipv6_hostaddr);
 
-  /* Set up the default router address */
+      /* Set up the default router address */
 
-  netlib_set_dripv6addr("eth0",
-                        (FAR const struct in6_addr *)g_ipv6_draddr);
+      netlib_set_dripv6addr(DEVNAME,
+                            (FAR const struct in6_addr *)g_ipv6_draddr);
 
-  /* Setup the subnet mask */
+      /* Setup the subnet mask */
 
-  netlib_set_ipv6netmask("eth0",
-                        (FAR const struct in6_addr *)g_ipv6_netmask);
+      netlib_set_ipv6netmask(DEVNAME,
+                            (FAR const struct in6_addr *)g_ipv6_netmask);
 
 #endif /* CONFIG_NET_ICMPv6_AUTOCONF */
 #else /* CONFIG_EXAMPLES_UDP_IPv6 */
 
-  struct in_addr addr;
+      struct in_addr addr;
 
-  /* Set up our host address */
+      /* Set up our host address */
 
-  addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_IPADDR);
-  netlib_set_ipv4addr("eth0", &addr);
+      addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_IPADDR);
+      netlib_set_ipv4addr(DEVNAME, &addr);
 
-  /* Set up the default router address */
+      /* Set up the default router address */
 
-  addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_DRIPADDR);
-  netlib_set_dripv4addr("eth0", &addr);
+      addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_DRIPADDR);
+      netlib_set_dripv4addr(DEVNAME, &addr);
 
-  /* Setup the subnet mask */
+      /* Setup the subnet mask */
 
-  addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_NETMASK);
-  netlib_set_ipv4netmask("eth0", &addr);
+      addr.s_addr = HTONL(CONFIG_EXAMPLES_UDP_NETMASK);
+      netlib_set_ipv4netmask(DEVNAME, &addr);
 
 #endif /* CONFIG_EXAMPLES_UDP_IPv6 */
 
-  /* New versions of netlib_set_ipvXaddr will not bring the network up,
-   * So ensure the network is really up at this point.
-   */
+      /* New versions of netlib_set_ipvXaddr will not bring the network up,
+       * So ensure the network is really up at this point.
+       */
 
-  netlib_ifup("eth0");
-
-#ifdef CONFIG_EXAMPLES_UDP_SERVER
-  recv_server();
-#else
-  send_client();
-#endif
+      netlib_ifup(DEVNAME);
+      g_initialized = true;
+    }
 
   return 0;
 }
+
+#endif /* CONFIG_EXAMPLES_UDP_NETINIT */
+
diff --git a/examples/udp/udp.h b/examples/udp/udp.h
new file mode 100644
index 000000000..9316240be
--- /dev/null
+++ b/examples/udp/udp.h
@@ -0,0 +1,119 @@
+/****************************************************************************
+ * examples/udp/udp.h
+ *
+ *   Copyright (C) 2007, 2008, 2015, 2017 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __EXAMPLES_UDP_UDP_H
+#define __EXAMPLES_UDP_UDP_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#ifdef EXAMPLES_UDP_HOST
+#else
+# include <debug.h>
+#endif
+
+#include <arpa/inet.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#ifdef EXAMPLES_UDP_HOST
+   /* HTONS/L macros are unique to uIP-based networks */
+
+#  ifdef CONFIG_ENDIAN_BIG
+#    define HTONS(ns) (ns)
+#    define HTONL(nl) (nl)
+#  else
+#    define HTONS(ns) \
+       (unsigned short) \
+         (((((unsigned short)(ns)) & 0x00ff) << 8) | \
+         ((((unsigned short)(ns)) >> 8) & 0x00ff))
+#      define HTONL(nl) \
+       (unsigned long) \
+         (((((unsigned long)(nl)) & 0x000000ffUL) << 24) | \
+         ((((unsigned long)(nl)) & 0x0000ff00UL) <<  8) | \
+         ((((unsigned long)(nl)) & 0x00ff0000UL) >>  8) | \
+         ((((unsigned long)(nl)) & 0xff000000UL) >> 24))
+#  endif
+
+#  define NTOHS(hs) HTONS(hs)
+#  define NTOHL(hl) HTONL(hl)
+#  define FAR
+#endif
+
+#ifdef CONFIG_EXAMPLES_UDP_IPv6
+#  define AF_INETX AF_INET6
+#  define PF_INETX PF_INET6
+#else
+#  define AF_INETX AF_INET
+#  define PF_INETX PF_INET
+#endif
+
+#ifndef CONFIG_EXAMPLES_SERVER_PORTNO
+#  define CONFIG_EXAMPLES_SERVER_PORTNO 5471
+#endif
+
+#ifndef CONFIG_EXAMPLES_CLIENT_PORTNO
+#  define CONFIG_EXAMPLES_CLIENT_PORTNO 5472
+#endif
+
+#define ASCIISIZE  (0x7f - 0x20)
+#define SENDSIZE   (ASCIISIZE+1)
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef CONFIG_EXAMPLES_UDP_IPv6
+uint16_t g_server_ipv6[8];
+#else
+uint32_t g_server_ipv4;
+#endif
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+#ifdef CONFIG_EXAMPLES_UDP_NETINIT
+int target_netinit(void);
+#endif
+
+void parse_cmdline(int argc, char **argv);
+void send_client(void);
+void recv_server(void);
+
+#endif /* __EXAMPLES_UDP_UDP_H */
diff --git a/examples/udp/udp-client.c b/examples/udp/udp_client.c
similarity index 72%
rename from examples/udp/udp-client.c
rename to examples/udp/udp_client.c
index 416a2b4ea..18368c1a3 100644
--- a/examples/udp/udp-client.c
+++ b/examples/udp/udp_client.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * examples/udp/udp-client.c
+ * examples/udp/udp_client.c
  *
  *   Copyright (C) 2007, 2015 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
@@ -51,12 +51,65 @@
 #include <arpa/inet.h>
 #include <netinet/in.h>
 
-#include "udp-internal.h"
+#include "udp.h"
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
+static int create_socket(void)
+{
+  socklen_t addrlen;
+  int sockfd;
+
+#ifdef CONFIG_EXAMPLES_UDP_IPv4
+  struct sockaddr_in addr;
+
+  /* Create a new IPv4 UDP socket */
+
+  sockfd = socket(AF_INET, SOCK_DGRAM, 0);
+  if (sockfd < 0)
+    {
+      printf("client ERROR: client socket failure %d\n", errno);
+      return -1;
+    }
+
+  /* Bind the UDP socket to a IPv4 port */
+
+  addr.sin_family      = AF_INET;
+  addr.sin_port        = HTONS(CONFIG_EXAMPLES_CLIENT_PORTNO);
+  addr.sin_addr.s_addr = HTONL(INADDR_ANY);
+  addrlen              = sizeof(struct sockaddr_in);
+
+#else
+  struct sockaddr_in6 addr;
+
+  /* Create a new IPv6 UDP socket */
+
+  sockfd = socket(AF_INET6, SOCK_DGRAM, 0);
+  if (sockfd < 0)
+    {
+      printf("client ERROR: client socket failure %d\n", errno);
+      return -1;
+    }
+
+  /* Bind the UDP socket to a IPv6 port */
+
+  addr.sin6_family     = AF_INET6;
+  addr.sin6_port       = HTONS(CONFIG_EXAMPLES_CLIENT_PORTNO);
+  memset(addr.sin6_addr.s6_addr, 0, sizeof(struct in6_addr));
+  addrlen              = sizeof(struct sockaddr_in6);
+#endif
+
+  if (bind(sockfd, (FAR struct sockaddr *)&addr, addrlen) < 0)
+    {
+      printf("client ERROR: Bind failure: %d\n", errno);
+      return -1;
+    }
+
+  return sockfd;
+}
+
 static inline void fill_buffer(unsigned char *buf, int offset)
 {
   int ch;
@@ -92,10 +145,10 @@ void send_client(void)
 
   /* Create a new UDP socket */
 
-  sockfd = socket(PF_INETX, SOCK_DGRAM, 0);
+  sockfd = create_socket();
   if (sockfd < 0)
     {
-      printf("client socket failure %d\n", errno);
+      printf("client ERROR: create_socket failed %d\n");
       exit(1);
     }
 
@@ -111,23 +164,13 @@ void send_client(void)
 
 #ifdef CONFIG_EXAMPLES_UDP_IPv6
       server.sin6_family            = AF_INET6;
-      server.sin6_port              = HTONS(PORTNO);
-
-      server.sin6_addr.s6_addr16[0] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_1);
-      server.sin6_addr.s6_addr16[1] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_2);
-      server.sin6_addr.s6_addr16[2] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_3);
-      server.sin6_addr.s6_addr16[3] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_4);
-      server.sin6_addr.s6_addr16[4] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_5);
-      server.sin6_addr.s6_addr16[5] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_6);
-      server.sin6_addr.s6_addr16[6] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_7);
-      server.sin6_addr.s6_addr16[7] = HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_8);
-
+      server.sin6_port              = HTONS(CONFIG_EXAMPLES_SERVER_PORTNO);
+      memcpy(server.sin6_addr.s6_addr16, g_server_ipv6, 8 * sizeof(uint16_t));
       addrlen                       = sizeof(struct sockaddr_in6);
 #else
       server.sin_family             = AF_INET;
-      server.sin_port               = HTONS(PORTNO);
-      server.sin_addr.s_addr        = HTONL(CONFIG_EXAMPLES_UDP_SERVERIP);
-
+      server.sin_port               = HTONS(CONFIG_EXAMPLES_SERVER_PORTNO);
+      server.sin_addr.s_addr        = (in_addr_t)g_server_ipv4;
       addrlen                       = sizeof(struct sockaddr_in);
 #endif
 
diff --git a/examples/udp/udp_cmdline.c b/examples/udp/udp_cmdline.c
new file mode 100644
index 000000000..8eb93f8d8
--- /dev/null
+++ b/examples/udp/udp_cmdline.c
@@ -0,0 +1,118 @@
+/****************************************************************************
+ * examples/udp/udp_cmdline.c
+ *
+ *   Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ *   Author: Gregory Nutt <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <arpa/inet.h>
+
+#include "udp.h"
+
+/****************************************************************************
+ * Public Data
+ ****************************************************************************/
+
+#ifdef CONFIG_EXAMPLES_UDP_IPv6
+uint16_t g_server_ipv6[8] =
+{
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_1),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_2),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_3),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_4),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_5),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_6),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_7),
+  HTONS(CONFIG_EXAMPLES_UDP_SERVERIPv6ADDR_8)
+};
+#else
+uint32_t g_server_ipv4 = HTONL(CONFIG_EXAMPLES_UDP_SERVERIP);
+#endif
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * show_usage
+ ****************************************************************************/
+
+static void show_usage(FAR const char *progname)
+{
+  fprintf(stderr, "USAGE: %s [<server-addr>]\n", progname);
+  exit(1);
+}
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * parse_cmdline
+ ****************************************************************************/
+
+void parse_cmdline(int argc, char **argv)
+{
+  /* Currently only a single command line option is supported:  The server
+   * IP address.
+   */
+
+  if (argc == 2)
+    {
+      int ret;
+
+      /* Convert the <server-addr> argument into a binary address */
+
+#ifdef CONFIG_EXAMPLES_UDP_IPv6
+      ret = inet_pton(AF_INET6, argv[1], g_server_ipv6);
+#else
+      ret = inet_pton(AF_INET, argv[1], &g_server_ipv4);
+#endif
+      if (ret < 0)
+        {
+          fprintf(stderr, "ERROR: <server-addr> is invalid\n");
+          show_usage(argv[0]);
+        }
+    }
+  else if (argc != 1)
+    {
+      fprintf(stderr, "ERROR: Too many arguments\n");
+      show_usage(argv[0]);
+    }
+}
diff --git a/examples/udp/udp-server.c b/examples/udp/udp_server.c
similarity index 97%
rename from examples/udp/udp-server.c
rename to examples/udp/udp_server.c
index c9f16d571..03233d68b 100644
--- a/examples/udp/udp-server.c
+++ b/examples/udp/udp_server.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * examples/udp/udp-server.c
+ * examples/udp/udp_server.c
  *
  *   Copyright (C) 2007, 2009, 2012, 2015 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
@@ -50,7 +50,7 @@
 
 #include <arpa/inet.h>
 
-#include "udp-internal.h"
+#include "udp.h"
 
 /****************************************************************************
  * Private Functions
@@ -124,13 +124,13 @@ void recv_server(void)
 
 #ifdef CONFIG_EXAMPLES_UDP_IPv6
   server.sin6_family     = AF_INET6;
-  server.sin6_port       = HTONS(PORTNO);
+  server.sin6_port       = HTONS(CONFIG_EXAMPLES_SERVER_PORTNO);
   memset(&server.sin6_addr, 0, sizeof(struct in6_addr));
 
   addrlen                = sizeof(struct sockaddr_in6);
 #else
   server.sin_family      = AF_INET;
-  server.sin_port        = HTONS(PORTNO);
+  server.sin_port        = HTONS(CONFIG_EXAMPLES_SERVER_PORTNO);
   server.sin_addr.s_addr = HTONL(INADDR_ANY);
 
   addrlen                = sizeof(struct sockaddr_in);
diff --git a/include/netutils/netlib.h b/include/netutils/netlib.h
index 46225819c..07a97b5bc 100644
--- a/include/netutils/netlib.h
+++ b/include/netutils/netlib.h
@@ -115,12 +115,11 @@ int netlib_getmacaddr(FAR const char *ifname, FAR uint8_t *macaddr);
 #endif
 
 #ifdef CONFIG_NET_6LOWPAN
-/* Get IEEE802.15.4 MAC driver node address */
+/* Set IEEE 802.15.4 extended address. */
 
-int netlib_getpanid(FAR const char *ifname, FAR uint16_t *panid);
-int netlib_setnodeaddr(FAR const char *ifname, FAR const uint8_t *nodeaddr);
-int netlib_setpanid(FAR const char *ifname, uint16_t panid);
-bool netlib_nodeaddrconv(FAR const char *hwstr, FAR uint8_t *hw);
+int netlib_seteaddr(FAR const char *ifname, FAR const uint8_t *eaddr);
+int netlib_getpanid(FAR const char *ifname, FAR uint8_t *panid);
+bool netlib_eaddrconv(FAR const char *hwstr, FAR uint8_t *hw);
 #endif
 
 /* IP address support */
diff --git a/include/wireless/ieee802154.h b/include/wireless/ieee802154.h
index 60ab3df65..7822a4e5c 100644
--- a/include/wireless/ieee802154.h
+++ b/include/wireless/ieee802154.h
@@ -2,7 +2,10 @@
  * apps/include/wireless/ieee802154.h
  *
  *   Copyright(C) 2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright(C) 2017 Verge Inc. All rights reserved.
+ *
  *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -65,6 +68,7 @@ int ieee802154_get_req(int fd, FAR struct ieee802154_get_req_s *req);
 int ieee802154_gts_req(int fd, FAR struct ieee802154_gts_req_s *req);
 int ieee802154_orphan_resp(int fd,
       FAR struct ieee802154_orphan_resp_s *resp);
+int ieee802154_reset_req(int fd, FAR struct ieee802154_reset_req_s *req);
 int ieee802154_rxenable_req(int fd,
       FAR struct ieee802154_rxenable_req_s *req);
 int ieee802154_scan_req(int fd, FAR struct ieee802154_scan_req_s *req);
@@ -85,11 +89,11 @@ int ieee802154_calibrate_req(int fd,
 int ieee802154_setchan(int fd, uint8_t chan);
 int ieee802154_getchan(int fd, FAR uint8_t *chan);
 
-int ieee802154_setpanid(int fd, uint16_t panid);
-int ieee802154_getpanid(int fd, FAR uint16_t *panid);
+int ieee802154_setpanid(int fd, FAR const uint8_t *panid);
+int ieee802154_getpanid(int fd, FAR uint8_t *panid);
 
-int ieee802154_setsaddr(int fd, uint16_t saddr);
-int ieee802154_getsaddr(int fd, FAR uint16_t *saddr);
+int ieee802154_setsaddr(int fd, FAR const uint8_t *saddr);
+int ieee802154_getsaddr(int fd, FAR uint8_t *saddr);
 
 int ieee802154_seteaddr(int fd, FAR const uint8_t *eaddr);
 int ieee802154_geteaddr(int fd, FAR uint8_t *eaddr);
@@ -106,6 +110,8 @@ int ieee802154_gettxpwr(int fd, FAR int32_t *txpwr);
 int ieee802154_setcca(int fd, FAR struct ieee802154_cca_s *cca);
 int ieee802154_getcca(int fd, FAR struct ieee802154_cca_s *cca);
 
+int ieee802154_getdevmode(int fd, FAR enum ieee802154_devmode_e *devmode);
+
 #ifdef CONFIG_NET_6LOWPAN
 /* Netork driver IOCTL helpers */
 
@@ -151,13 +157,15 @@ int sixlowpan_calibrate_req(int sock, FAR const char *ifname,
 int sixlowpan_setchan(int sock, FAR const char *ifname, uint8_t chan);
 int sixlowpan_getchan(int sock, FAR const char *ifname, FAR uint8_t *chan);
 
-int sixlowpan_setpanid(int sock, FAR const char *ifname, uint16_t panid);
+int sixlowpan_setpanid(int sock, FAR const char *ifname,
+      FAR const uint8_t *panid);
 int sixlowpan_getpanid(int sock, FAR const char *ifname,
-      FAR uint16_t *panid);
+      FAR uint8_t *panid);
 
-int sixlowpan_setsaddr(int sock, FAR const char *ifname, uint16_t saddr);
+int sixlowpan_setsaddr(int sock, FAR const char *ifname,
+      FAR const uint8_t *saddr);
 int sixlowpan_getsaddr(int sock, FAR const char *ifname,
-      FAR uint16_t *saddr);
+      FAR uint8_t *saddr);
 
 int sixlowpan_seteaddr(int sock, FAR const char *ifname,
       FAR const uint8_t *eaddr);
diff --git a/netutils/netlib/Makefile b/netutils/netlib/Makefile
index a2233036e..0828ae46a 100644
--- a/netutils/netlib/Makefile
+++ b/netutils/netlib/Makefile
@@ -80,15 +80,14 @@ ifeq ($(CONFIG_NETDEV_WIRELESS_IOCTL),y)
 CSRCS += netlib_getessid.c netlib_setessid.c
 endif
 
-# MAC address support(Ethernet and 6loWPAN only)
+# MAC address support(Ethernet and 6LoWPAN only)
 
 ifeq ($(CONFIG_NET_ETHERNET),y)
 CSRCS += netlib_setmacaddr.c netlib_getmacaddr.c
 endif
 
 ifeq ($(CONFIG_NET_6LOWPAN),y)
-CSRCS += netlib_getpanid.c netlib_setnodeaddr.c netlib_setpanid.c
-CSRCS += netlib_nodeaddrconv.c
+CSRCS += netlib_seteaddr.c netlib_getpanid.c netlib_eaddrconv.c
 endif
 
 # IGMP support
diff --git a/netutils/netlib/netlib_nodeaddrconv.c b/netutils/netlib/netlib_eaddrconv.c
similarity index 91%
rename from netutils/netlib/netlib_nodeaddrconv.c
rename to netutils/netlib/netlib_eaddrconv.c
index 4cb6760e4..a618e9818 100644
--- a/netutils/netlib/netlib_nodeaddrconv.c
+++ b/netutils/netlib/netlib_eaddrconv.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * netutils/netlib/netlib_nodeaddrconv.c
+ * netutils/netlib/netlib_eaddrconv.c
  *
  *   Copyright (C) 2017 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
@@ -50,26 +50,26 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: netlib_nodeaddrconv
+ * Name: netlib_eaddrconv
  ****************************************************************************/
 
-bool netlib_nodeaddrconv(FAR const char *hwstr, FAR uint8_t *hw)
+bool netlib_eaddrconv(FAR const char *hwstr, FAR uint8_t *hw)
 {
   unsigned char tmp;
   unsigned char i;
   unsigned char j;
   char ch;
 
-  /* Form xx:xx or xx:xx:xx:xx:xx:xx:xx:xx for extended Rime address */
+  /* Extended Address Form:  xx:xx:xx:xx:xx:xx:xx:xx */
 
-  if (strlen(hwstr) != 3 * NET_6LOWPAN_ADDRSIZE - 1)
+  if (strlen(hwstr) != 3 * 8 - 1)
     {
       return false;
     }
 
   tmp = 0;
 
-  for (i = 0; i < NET_6LOWPAN_ADDRSIZE; ++i)
+  for (i = 0; i < 8; ++i)
     {
       j = 0;
       do
diff --git a/netutils/netlib/netlib_getpanid.c b/netutils/netlib/netlib_getpanid.c
index 30f2d0ed7..98e2b4508 100644
--- a/netutils/netlib/netlib_getpanid.c
+++ b/netutils/netlib/netlib_getpanid.c
@@ -70,7 +70,7 @@
  *
  ****************************************************************************/
 
-int netlib_getpanid(FAR const char *ifname, FAR uint16_t *panid)
+int netlib_getpanid(FAR const char *ifname, FAR uint8_t *panid)
 {
   int ret = ERROR;
 
diff --git a/netutils/netlib/netlib_setpanid.c b/netutils/netlib/netlib_seteaddr.c
similarity index 91%
rename from netutils/netlib/netlib_setpanid.c
rename to netutils/netlib/netlib_seteaddr.c
index a99d6eee2..251653b22 100644
--- a/netutils/netlib/netlib_setpanid.c
+++ b/netutils/netlib/netlib_seteaddr.c
@@ -1,5 +1,5 @@
 /****************************************************************************
- * netutils/netlib/netlib_setpanid.c
+ * netutils/netlib/netlib_seteaddr.c
  *
  *   Copyright (C) 2017 Gregory Nutt. All rights reserved.
  *   Author: Gregory Nutt <gnutt@nuttx.org>
@@ -56,21 +56,21 @@
  ****************************************************************************/
 
 /****************************************************************************
- * Name: netlib_setpanid
+ * Name: netlib_seteaddr
  *
  * Description:
- *   Join the specified PAN ID
+ *   Set the IEEE802.15.4 extended MAC address
  *
  * Parameters:
  *   ifname The name of the interface to use
- *   panid  The PAN ID to join
+ *   eaddr  The new extended address
  *
  * Return:
  *   0 on success; -1 on failure.  errno will be set on failure.
  *
  ****************************************************************************/
 
-int netlib_setpanid(FAR const char *ifname, uint16_t panid)
+int netlib_seteaddr(FAR const char *ifname, FAR const uint8_t *eaddr)
 {
   int ret = ERROR;
 
@@ -83,7 +83,7 @@ int netlib_setpanid(FAR const char *ifname, uint16_t panid)
         {
           /* Use the helper provided in libmac */
 
-          ret = sixlowpan_setpanid(sockfd, ifname, panid);
+          ret = sixlowpan_seteaddr(sockfd, ifname, eaddr);
           close(sockfd);
         }
     }
diff --git a/nshlib/Kconfig b/nshlib/Kconfig
index 3337e2995..cabfd52b2 100644
--- a/nshlib/Kconfig
+++ b/nshlib/Kconfig
@@ -1129,7 +1129,10 @@ config NSH_NETINIT_DEBUG
 		or CONFIG_DEBUG_INFO are not selected.  This allows for focused, unit-
 		level debug of the NSH network initialization logic.
 
+# No IP address if 6LOWPAN selected; but Ethernet has precedence.
+
 menu "IP Address Configuration"
+	depends on NET_ETHERNET || !NET_6LOWPAN
 
 config NSH_DHCPC
 	bool "Use DHCP to get IP address"
@@ -1426,7 +1429,7 @@ config NSH_IPv6NETMASK_8
 		individually.  This is the eighth of the 8-values.  The default for
 		all eight values is fe00::0.
 
-endif #NET_IPv6 && !NET_ICMPv6_AUTOCONF
+endif # NET_IPv6 && !NET_ICMPv6_AUTOCONF
 endmenu # IP Address Configuration
 
 config NSH_DNS
@@ -1472,8 +1475,9 @@ endchoice # MAC address selection
 
 config NSH_MACADDR
 	hex "Fixed MAC address"
-	default 0x00e0deadbeef
-	depends on NSH_SWMAC
+	default 0x00e0deadbeef if NET_ETHERNET
+	default 0x00fade00deadbeef if !NET_ETHERNET && NET_6LOWPAN
+	depends on NSH_SWMAC && (NET_ETHERNET || NET_6LOWPAN)
 	---help---
 		If the hardware has no built-in MAC address and if the NSH_SWMAC
 		option is selected, then the fixed, software-assigned MAC address
@@ -1481,14 +1485,6 @@ config NSH_MACADDR
 
 endif # NSH_NOMAC
 
-config NSH_PANID
-	hex "6loWPAN PAN ID"
-	default 0xface
-	depends on NET_6LOWPAN
-	range 0x0000 0xffff
-	---help---
-		Select the PAN ID to join upon initialization.
-
 menu "WAPI Configuration"
 	depends on NET && WIRELESS_WAPI
 
diff --git a/nshlib/nsh_netcmds.c b/nshlib/nsh_netcmds.c
index d80ef1a10..f57a71a73 100644
--- a/nshlib/nsh_netcmds.c
+++ b/nshlib/nsh_netcmds.c
@@ -762,7 +762,7 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
   uint8_t mac[IFHWADDRLEN];
 #endif
 #ifdef CONFIG_NET_6LOWPAN
-  uint8_t nodeaddr[NET_6LOWPAN_ADDRSIZE];
+  uint8_t eaddr[8];
 #endif
 #if defined(CONFIG_NSH_DHCPC)
   FAR void *handle;
@@ -862,7 +862,7 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 #ifdef CONFIG_NET_ETHERNET
                       badarg = !netlib_ethaddrconv(hw, mac);
 #else
-                      badarg = !netlib_nodeaddrconv(hw, nodeaddr);
+                      badarg = !netlib_eaddrconv(hw, eaddr);
 #endif
                     }
                   else
@@ -906,7 +906,7 @@ int cmd_ifconfig(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv)
 #ifdef CONFIG_NET_ETHERNET
       netlib_setmacaddr(intf, mac);
 #else
-      netlib_setnodeaddr(intf, nodeaddr);
+      netlib_seteaddr(intf, eaddr);
 #endif
     }
 #endif
diff --git a/nshlib/nsh_netinit.c b/nshlib/nsh_netinit.c
index d030bf7d4..2670f084e 100644
--- a/nshlib/nsh_netinit.c
+++ b/nshlib/nsh_netinit.c
@@ -88,20 +88,50 @@
  * Pre-processor Definitions
  ****************************************************************************/
 
-/* Only Ethernet and 6loWPAN have MAC layer addresses */
+/* Pick one and at most one supported link layer so that all decisions are
+ * made consistently.
+ *
+ * NOTE: Ethernet should always be selected with IEEE 802.11
+ */
+
+#if defined(CONFIG_NET_ETHERNET)
+#  undef CONFIG_NET_6LOWPAN
+#  undef CONFIG_NET_SLIP
+#  undef CONFIG_NET_TUN
+#  undef CONFIG_NET_LOCAL
+#  undef CONFIG_NET_USRSOCK
+#  undef CONFIG_NET_LOOPBACK
+#elif defined(CONFIG_NET_6LOWPAN)
+#  undef CONFIG_NET_SLIP
+#  undef CONFIG_NET_TUN
+#  undef CONFIG_NET_LOCAL
+#  undef CONFIG_NET_USRSOCK
+#  undef CONFIG_NET_LOOPBACK
+#elif defined(CONFIG_NET_SLIP)
+#  undef CONFIG_NET_TUN
+#  undef CONFIG_NET_LOCAL
+#  undef CONFIG_NET_USRSOCK
+#  undef CONFIG_NET_LOOPBACK
+#elif defined(CONFIG_NET_TUN)
+#  undef CONFIG_NET_LOCAL
+#  undef CONFIG_NET_USRSOCK
+#  undef CONFIG_NET_LOOPBACK
+#elif defined(CONFIG_NET_LOCAL)
+#  undef CONFIG_NET_USRSOCK
+#  undef CONFIG_NET_LOOPBACK
+#elif defined(CONFIG_NET_USRSOCK)
+#  undef CONFIG_NET_LOOPBACK
+#endif
+
+/* Only Ethernet and 6LoWPAN have MAC layer addresses */
 
 #undef HAVE_MAC
 #if defined(CONFIG_NET_ETHERNET) || defined(CONFIG_NET_6LOWPAN)
 #  define HAVE_MAC 1
-#  if defined(CONFIG_NET_6LOWPAN)
-#    if !defined(CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED) && CONFIG_NSH_MACADDR > 0xffff
-#      error Invalid 6loWPAN node address for SIZE == 2
-#    elif defined(CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED) && CONFIG_NSH_MACADDR > 0xffffffffffffffffull
-#      error Invalid 6loWPAN node address for SIZE == 8
-#    endif
-#  endif
 #endif
 
+/* Provide a default DNS address */
+
 #if defined(CONFIG_NSH_DRIPADDR) && !defined(CONFIG_NSH_DNSIPADDR)
 #  define CONFIG_NSH_DNSIPADDR CONFIG_NSH_DRIPADDR
 #endif
@@ -185,7 +215,8 @@
 static sem_t g_notify_sem;
 #endif
 
-#if defined(CONFIG_NET_IPv6) && !defined(CONFIG_NET_ICMPv6_AUTOCONF)
+#if defined(CONFIG_NET_IPv6) && !defined(CONFIG_NET_ICMPv6_AUTOCONF) && \
+   !defined(CONFIG_NET_6LOWPAN)
 /* Host IPv6 address */
 
 static const uint16_t g_ipv6_hostaddr[8] =
@@ -227,45 +258,32 @@ static const uint16_t g_ipv6_netmask[8] =
   HTONS(CONFIG_NSH_IPv6NETMASK_7),
   HTONS(CONFIG_NSH_IPv6NETMASK_8),
 };
-#endif /* CONFIG_NET_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF */
+#endif /* CONFIG_NET_IPv6 && !CONFIG_NET_ICMPv6_AUTOCONF && !CONFIG_NET_6LOWPAN */
 
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Name: nsh_netinit_configure
+ * Name: nsh_set_macaddr
  *
  * Description:
- *   Initialize the network per the selected NuttX configuration
+ *   Set the hardware MAC address if the hardware is not capable of doing
+ *   that for itself.
  *
  ****************************************************************************/
 
-static void nsh_netinit_configure(void)
+#if defined(NSH_HAVE_NETDEV) && defined(CONFIG_NSH_NOMAC) && defined(HAVE_MAC)
+static void nsh_set_macaddr(void)
 {
-#ifdef NSH_HAVE_NETDEV
-#ifdef CONFIG_NET_IPv4
-  struct in_addr addr;
-#endif
-
-#if defined(CONFIG_NSH_DHCPC) && !defined(CONFIG_NSH_NETLOCAL)
-  FAR void *handle;
-#endif
-
-#if (((defined(CONFIG_NSH_DHCPC) && !defined(CONFIG_NSH_NETLOCAL)) || \
-     defined(CONFIG_NSH_NOMAC)) && defined(HAVE_MAC))
 #if defined(CONFIG_NET_ETHERNET)
   uint8_t mac[IFHWADDRLEN];
 #elif defined(CONFIG_NET_6LOWPAN)
-  uint8_t nodeaddr[NET_6LOWPAN_ADDRSIZE];
+  uint8_t eaddr[8];
 #endif
-#endif
-
-  ninfo("Entry\n");
 
   /* Many embedded network interfaces must have a software assigned MAC */
 
-#if defined(CONFIG_NSH_NOMAC) && defined(HAVE_MAC)
 #if defined(CONFIG_NET_ETHERNET)
   /* Use the configured, fixed MAC address */
 
@@ -281,33 +299,44 @@ static void nsh_netinit_configure(void)
   netlib_setmacaddr(NET_DEVNAME, mac);
 
 #elif defined(CONFIG_NET_6LOWPAN)
-  /* Use the configured, fixed MAC address */
+  /* Use the configured, fixed extended address */
 
-#ifdef CONFIG_NET_6LOWPAN_RIMEADDR_EXTENDED
-  nodeaddr[0] = (CONFIG_NSH_MACADDR >> (8 * 7)) & 0xff;
-  nodeaddr[1] = (CONFIG_NSH_MACADDR >> (8 * 6)) & 0xff;
-  nodeaddr[2] = (CONFIG_NSH_MACADDR >> (8 * 5)) & 0xff;
-  nodeaddr[3] = (CONFIG_NSH_MACADDR >> (8 * 4)) & 0xff;
-  nodeaddr[4] = (CONFIG_NSH_MACADDR >> (8 * 3)) & 0xff;
-  nodeaddr[5] = (CONFIG_NSH_MACADDR >> (8 * 2)) & 0xff;
-  nodeaddr[6] = (CONFIG_NSH_MACADDR >> (8 * 1)) & 0xff;
-  nodeaddr[7] = (CONFIG_NSH_MACADDR >> (8 * 0)) & 0xff;
+  eaddr[0] = (CONFIG_NSH_MACADDR >> (8 * 7)) & 0xff;
+  eaddr[1] = (CONFIG_NSH_MACADDR >> (8 * 6)) & 0xff;
+  eaddr[2] = (CONFIG_NSH_MACADDR >> (8 * 5)) & 0xff;
+  eaddr[3] = (CONFIG_NSH_MACADDR >> (8 * 4)) & 0xff;
+  eaddr[4] = (CONFIG_NSH_MACADDR >> (8 * 3)) & 0xff;
+  eaddr[5] = (CONFIG_NSH_MACADDR >> (8 * 2)) & 0xff;
+  eaddr[6] = (CONFIG_NSH_MACADDR >> (8 * 1)) & 0xff;
+  eaddr[7] = (CONFIG_NSH_MACADDR >> (8 * 0)) & 0xff;
+
+  /* Set the 6LoWPAN extended address */
+
+  (void)netlib_seteaddr(NET_DEVNAME, eaddr);
+
+#endif /* CONFIG_NET_ETHERNET */
+}
 #else
-  nodeaddr[0] = (CONFIG_NSH_MACADDR >> (8 * 1)) & 0xff;
-  nodeaddr[1] = (CONFIG_NSH_MACADDR >> (8 * 0)) & 0xff;
+#  define nsh_set_macaddr()
 #endif
 
-  /* Set the 6loWPAN node address */
-
-  (void)netlib_setnodeaddr(NET_DEVNAME, nodeaddr);
-
-  /* Set the 6loWPAN PAN ID */
-
-  (void)netlib_setpanid(NET_DEVNAME, CONFIG_NSH_PANID);
-#endif /* CONFIG_NET_ETHERNET */
-#endif /* CONFIG_NSH_NOMAC && HAVE_MAC */
+/****************************************************************************
+ * Name: nsh_set_ipaddrs
+ *
+ * Description:
+ *   Setup IP addresses.
+ *
+ *   For 6LoWPAN, the IP address derives from the MAC address.  Setting it
+ *   to any user provided value is asking for trouble.
+ *
+ ****************************************************************************/
 
+#if defined(NSH_HAVE_NETDEV) && !defined(CONFIG_NET_6LOWPAN)
+static void nsh_set_ipaddrs(void)
+{
 #ifdef CONFIG_NET_IPv4
+  struct in_addr addr;
+
   /* Set up our host address */
 
 #ifndef CONFIG_NSH_DHCPC
@@ -358,13 +387,30 @@ static void nsh_netinit_configure(void)
   addr.s_addr = HTONL(CONFIG_NSH_DNSIPADDR);
   netlib_set_ipv4dnsaddr(&addr);
 #endif
+}
+#else
+#  define nsh_set_ipaddrs()
+#endif
 
-  /* That completes the 'local' initialization of the network device. */
+/****************************************************************************
+ * Name: nsh_net_bringup()
+ *
+ * Description:
+ *   Bring up the configured network
+ *
+ ****************************************************************************/
+
+#if defined(NSH_HAVE_NETDEV) && !defined(CONFIG_NSH_NETLOCAL)
+static void nsh_net_bringup(void)
+{
+#ifdef CONFIG_NSH_DHCPC
+  uint8_t mac[IFHWADDRLEN];
+  FAR void *handle;
+#endif
 
-#ifndef CONFIG_NSH_NETLOCAL
   /* Bring the network up. */
 
-  netlib_ifup("eth0");
+  netlib_ifup(NET_DEVNAME);
 
 #ifdef CONFIG_WIRELESS_WAPI
   /* Associate the wlan with an access point. */
@@ -415,10 +461,38 @@ static void nsh_netinit_configure(void)
 
   ntpc_start();
 #endif
-#endif /* CONFIG_NSH_NETLOCAL */
-#endif /* NSH_HAVE_NETDEV */
+}
+#else
+#  define nsh_net_bringup()
+#endif
 
-  ninfo("Exit\n");
+/****************************************************************************
+ * Name: nsh_netinit_configure
+ *
+ * Description:
+ *   Initialize the network per the selected NuttX configuration
+ *
+ ****************************************************************************/
+
+static void nsh_netinit_configure(void)
+{
+#ifdef NSH_HAVE_NETDEV
+  /* Many embedded network interfaces must have a software assigned MAC */
+
+  nsh_set_macaddr();
+
+  /* Set up IP addresses */
+
+  nsh_set_ipaddrs();
+
+  /* That completes the 'local' initialization of the network device. */
+
+#ifndef CONFIG_NSH_NETLOCAL
+  /* Bring the network up. */
+
+  nsh_net_bringup();
+#endif
+#endif /* NSH_HAVE_NETDEV */
 }
 
 /****************************************************************************
diff --git a/nshlib/nsh_usbconsole.c b/nshlib/nsh_usbconsole.c
index e766ead9b..84f04f039 100644
--- a/nshlib/nsh_usbconsole.c
+++ b/nshlib/nsh_usbconsole.c
@@ -52,7 +52,7 @@
 #  include <nuttx/usb/cdcacm.h>
 #endif
 
-#ifdef CONFIG_CDCACM
+#ifdef CONFIG_PL2303
 #  include <nuttx/usb/pl2303.h>
 #endif
 
diff --git a/platform/mikroe-stm32f4/mikroe_configdata.c b/platform/mikroe-stm32f4/mikroe_configdata.c
index cb58ae11b..a6b50cf68 100644
--- a/platform/mikroe-stm32f4/mikroe_configdata.c
+++ b/platform/mikroe-stm32f4/mikroe_configdata.c
@@ -52,26 +52,6 @@
 
 #ifdef CONFIG_PLATFORM_CONFIGDATA
 
-/************************************************************************************
- * Pre-processor Definitions
- ************************************************************************************/
-
-/************************************************************************************
- * Private Types
- ************************************************************************************/
-
-/************************************************************************************
- * Private Function Prototypes
- ************************************************************************************/
-
-/****************************************************************************
- * Private Data
- ****************************************************************************/
-
-/************************************************************************************
- * Private Functions
- ************************************************************************************/
-
 /************************************************************************************
  * Public Functions
  ************************************************************************************/
@@ -109,12 +89,12 @@ int platform_setconfig(enum config_data_e id, int instance,
                        FAR const uint8_t *configdata, size_t datalen)
 {
 #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_FS
-  FILE*   fd;
+  FILE *fd;
 #endif
 #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_PART
-  struct config_data_s  config;
-  int                   ret;
-  int                   fd;
+  struct config_data_s config;
+  int ret;
+  int fd;
 
   /* Try to open the /dev/config device file */
 
@@ -127,10 +107,10 @@ int platform_setconfig(enum config_data_e id, int instance,
 
   /* Setup structure for the SETCONFIG ioctl */
 
-  config.id = (enum config_data_e)id;
-  config.instance = instance;
+  config.id         = (enum config_data_e)id;
+  config.instance   = instance;
   config.configdata = (FAR uint8_t *) configdata;
-  config.len = datalen;
+  config.len        = datalen;
 
   ret = ioctl(fd, CFGDIOC_SETCONFIG, (unsigned long) &config);
   close(fd);
@@ -144,11 +124,13 @@ int platform_setconfig(enum config_data_e id, int instance,
 
 #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_FS
         /* Save config data in a file on the filesystem.  Try to open
-         * the file. */
+         * the file.
+         */
 
         if ((fd = fopen(CONFIG_MIKROE_STM32F4_CONFIGDATA_FILENAME, "w+")) == NULL)
           {
             /* Error opening the file */
+
             set_errno(ENOENT);
             return -1;
           }
@@ -167,7 +149,6 @@ int platform_setconfig(enum config_data_e id, int instance,
         return OK;
 
 #elif defined(CONFIG_MIKROE_STM32F4_CONFIGDATA_ROM)
-
         /* We are reading from a read-only system, so nothing to do. */
 
         return OK;
@@ -220,15 +201,17 @@ int platform_getconfig(enum config_data_e id, int instance,
                        FAR uint8_t *configdata, size_t datalen)
 {
 #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_FS
-  FILE*   fd;
+  FILE   *fd;
   size_t  bytes;
   enum    config_data_e saved_id;
   int     saved_instance;
 #elif defined(CONFIG_MIKROE_STM32F4_CONFIGDATA_ROM)
-  static const uint8_t touch_cal_data[] = {
+  static const uint8_t touch_cal_data[] =
+  {
       0x9a, 0x2f, 0x00, 0x00,
       0x40, 0xbc, 0x69, 0xfe, 0x70, 0x2e, 0x00,
-      0x00, 0xb8, 0x2d, 0xdb, 0xff };
+      0x00, 0xb8, 0x2d, 0xdb, 0xff
+  };
 #endif
 #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_PART
   struct config_data_s  config;
@@ -256,14 +239,14 @@ int platform_getconfig(enum config_data_e id, int instance,
   return ret;
 
 #else /* CONFIG_MIKROE_STM32F4_CONFIGDATA_PART */
-
   switch (id)
     {
       case CONFIGDATA_TSCALIBRATION:
 
 #ifdef CONFIG_MIKROE_STM32F4_CONFIGDATA_FS
         /* Load config data fram a file on the filesystem.  Try to open
-         * the file. */
+         * the file.
+         */
 
         if ((fd = fopen(CONFIG_MIKROE_STM32F4_CONFIGDATA_FILENAME, "r")) == NULL)
           {
@@ -294,12 +277,7 @@ int platform_getconfig(enum config_data_e id, int instance,
         fclose(fd);
         return OK;
 
-        /* Save config data in a file on the filesystem */
-
-        return OK;
-
 #elif defined(CONFIG_MIKROE_STM32F4_CONFIGDATA_ROM)
-
         memcpy(configdata, touch_cal_data, datalen);
         return OK;
 
@@ -318,3 +296,4 @@ int platform_getconfig(enum config_data_e id, int instance,
 }
 
 #endif /* CONFIG_PLATFORM_CONFIGDATA */
+
diff --git a/system/composite/composite_main.c b/system/composite/composite_main.c
index ab473124b..5a9bf25ea 100644
--- a/system/composite/composite_main.c
+++ b/system/composite/composite_main.c
@@ -726,7 +726,7 @@ void board_cdcuninitialize(FAR struct usbdevclass_driver_s *classdev)
  *   This is the main program that configures the USB mass storage device
  *   and exports the LUN(s).  If CONFIG_NSH_BUILTIN_APPS is defined
  *   in the NuttX configuration, then this program can be executed by
- *   entering the "msconn" command at the NSH console.
+ *   entering the "conn" command at the NSH console.
  *
  ****************************************************************************/
 
@@ -739,7 +739,7 @@ int conn_main(int argc, char *argv[])
   struct boardioc_usbdev_ctrl_s ctrl;
   int ret;
 
-  /* If this program is implemented as the NSH 'msconn' command, then we need to
+  /* If this program is implemented as the NSH 'conn' command, then we need to
    * do a little error checking to assure that we are not being called re-entrantly.
    */
 
diff --git a/wireless/ieee802154/i8sak/Kconfig b/wireless/ieee802154/i8sak/Kconfig
index 465d6f9c8..d74fddd74 100644
--- a/wireless/ieee802154/i8sak/Kconfig
+++ b/wireless/ieee802154/i8sak/Kconfig
@@ -9,6 +9,7 @@ config IEEE802154_I8SAK
 	select IEEE802154_MAC_DEV
 	select IEEE802154_LIBUTILS
 	select IEEE802154_LIBMAC
+	select IEEE802154_WPANLISTENER
 	---help---
 		Enable the IEEE 802.15.4 Swiss Army Knife
 
diff --git a/wireless/ieee802154/i8sak/Makefile b/wireless/ieee802154/i8sak/Makefile
index ce4b8bec4..530740af5 100644
--- a/wireless/ieee802154/i8sak/Makefile
+++ b/wireless/ieee802154/i8sak/Makefile
@@ -47,7 +47,8 @@ STACKSIZE = 4096
 # IEEE 802.15.4 SAK (Swiss Army Knife)
 
 ASRCS =
-CSRCS =
+CSRCS = i8sak_acceptassoc.c i8sak_assoc.c i8sak_blaster.c i8sak_poll.c
+CSRCS += i8sak_sniffer.c i8sak_startpan.c i8sak_tx.c wpanlistener.c
 MAINSRC = i8sak_main.c
 
 AOBJS = $(ASRCS:.S=$(OBJEXT))
diff --git a/wireless/ieee802154/i8sak/README.txt b/wireless/ieee802154/i8sak/README.txt
new file mode 100644
index 000000000..173d38c9e
--- /dev/null
+++ b/wireless/ieee802154/i8sak/README.txt
@@ -0,0 +1,153 @@
+IEEE 802.15.4 Swiss Army Knife (i8sak, or i8)
+============================================================
+
+Description
+===========
+The i8sak app is a useful CLI for testing various IEEE 802.15.4 functionality.
+It also serves as a starting place for learning how to interface with the
+NuttX IEEE 802.15.4 MAC layer.
+
+The i8sak CLI can be used to manipulate multiple MAC layer networks at once.
+IEEE 802.15.4 MAC character drivers show up in NuttX as /dev/ieeeN by default.
+When you invoke the first call to i8sak with a specified devname, it creates
+an i8sak instance and launches a deamon to handle processing work. The instance
+is considered sticky, so it is possible to run `i8 /dev/ieee0` at the beginning
+of a session and then can exclude the devname from all future calls. The number
+of i8sak instances supported is controllable through menuconfig.
+
+The i8sak app has many settings that can be configured. Most options are "sticky",
+meaning, if you set the endpoint short address once, any future operation using
+the endpoint short address can default to the previously used address. This is
+particularly useful to keep the command lengths down.
+
+How To Use
+==========
+The i8sak app has a series of CLI functions that can be invoked.  The default
+i8sak command is 'i8' to make things quick and easy to type.
+
+In my test setup I have 2 Clicker2-STM32 boards from MikroElektronika, with
+the BEE-click (MRF24J40) radios. Choose one device to be the PAN Coordinator.
+We'll refer to that as device A.
+
+On that device, run:
+```
+i8 /dev/ieee0 startpan
+```
+For now, this function assumes that we are operating a non-beacon enabled PAN,
+since, as of this writing, beacon-enabled networks are unfinished. Unless you
+have previously overriden address settings, the startpan command will also
+configure the devices address to be that of CONFIG_I8SAK_PANCOORD_XXX. It
+will then set the endpoint to be the CONFIG_I8SAK_DEV_XXX address.
+
+Next, on the same device, run:
+```
+i8 acceptassoc
+```
+Notice in the second command, we did not use the devname, again, that is "sticky"
+so unless we are switching back and forth between character drivers, we can
+just use it once.
+
+The acceptassoc command, without any arguments, informs the i8sak instance to
+accept all association requests. The acceptassoc command also allows you to only
+accept requests from a single device by specifying the extended address with option
+-e.
+
+For instance:
+```
+i8 acceptassoc -e DEADBEEF00FADE0B
+```
+
+But for this example, let's just use the command with no arguments.
+
+Now, the second device will act as an endpoint device. The i8sak instance defaults
+to being in endpoint mode. Let's refer to the second device as device B.
+
+On device B, run:
+```
+i8 /dev/ieee0 assoc
+```
+This command without any options defaults the endpoint address to the default
+PANCOORD address settings, and sends an association request to that device.
+
+If everything is setup correctly, device A should have log information saying
+that a device tried to associate and that it accepted the assocation.  On device
+B, the console should show that the association request was successful. With all
+default settings, device B should have been allocated a short address of 0x000B.
+
+If you are following along with a packet sniffer, you should see the following
+transactions:
+
+1) Association Request
+    Frame Type      - CMD
+    Sequence Number - 0
+    Dest. PAN ID    - 0xFADE
+    Dest. Address   - 0x000A
+    Src.  PAN ID    - 0xFFFE
+    Src.  Address   - 0xDEADBEEF00FADE0C
+    Command Type    - Association Request
+
+    1a) ACK
+        Frame Type      - ACK
+        Sequence Number - 0
+
+2) Data Request
+    Frame Type      - CMD
+    Sequence Number - 1
+    Dest. PAN ID    - 0xFADE
+    Dest. Address   - 0x000A
+    Src.  PAN ID    - 0xFFFE
+    Src.  Address   - 0xDEADBEEF00FADE0C
+    Command Type    - Data Request
+
+    2a) ACK
+        Frame Type      - ACK
+        Sequence Number - 1
+
+3) Association Response
+    Frame Type      - CMD
+    Sequence Number - 0
+    Dest. PAN ID    - 0xFADE
+    Dest. Address   - 0xDEADBEEF00FADE0C
+    Src.  Address   - 0xDEADBEEF00FADE0A
+    Command Type    - Association Response
+    Assigned SADDR  - 0x000C
+    Assoc Status    - Successful
+
+    3a) ACK
+        Frame Type      - ACK
+        Sequence Number - 0
+
+
+Device B has now successfully associated with device A. If you want to send data
+from device B to device A, run the following on device B:
+```
+i8 tx ABCDEF
+```
+This will immediately (not actually immediate, transaction is sent using CSMA)
+send the frame to device A with frame payload 0xABCDEF
+
+Sending data from device A to device B is different. In IEEE 802.15.4, frames
+must be extracted from the coordinator. To prepare the frame, run the following
+command on device A
+```
+i8 tx AB
+```
+Because the devmode is PAN Coordinator, the i8sak app knows to send the data
+as an indirect transaction.  If you were running the i8sak app on a device
+that is a coordinator, but not the PAN coordinator, you can force the i8sak app
+to send the transaction directly, rather than to the parent coordinator, by using
+the -d option.
+
+NOTE: Currently, the indirect transaction timeout is disabled.  This means frames
+must be extracted or space may run out. This is only for the testing phase as it
+is easier to debug when I am not fighting a timeout. Re-enabling the timeout may
+effect the behavior of the indirect transaction features in the i8sak app.
+
+To extract the data, run the following command on device B:
+```
+i8 poll
+```
+This command polls the endpoint (our device A PAN Coordinator in this case) to
+see if there is any data. In the console of device B you should see a Poll request
+status print out.
+
diff --git a/wireless/ieee802154/i8sak/i8sak.h b/wireless/ieee802154/i8sak/i8sak.h
new file mode 100644
index 000000000..c9508ce14
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak.h
@@ -0,0 +1,193 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak.h
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_EXAMPLES_WIRELESS_IEEE802154_I8SAK_H
+#define __APPS_EXAMPLES_WIRELESS_IEEE802154_I8SAK_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include "wpanlistener.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#if !defined(CONFIG_IEEE802154_I8SAK_PANCOORD_SADDR)
+#define CONFIG_IEEE802154_I8SAK_PANCOORD_SADDR 0x000A
+#endif
+#if !defined(CONFIG_IEEE802154_I8SAK_PANCOORD_EADDR)
+#define CONFIG_IEEE802154_I8SAK_PANCOORD_EADDR 0xDEADBEEF00FADE0A
+#endif
+
+#if !defined(CONFIG_IEEE802154_I8SAK_COORD_SADDR)
+#define CONFIG_IEEE802154_I8SAK_COORD_SADDR 0x000B
+#endif
+#if !defined(CONFIG_IEEE802154_I8SAK_COORD_EADDR)
+#define CONFIG_IEEE802154_I8SAK_COORD_EADDR 0xDEADBEEF00FADE0B
+#endif
+
+#if !defined(CONFIG_IEEE802154_I8SAK_DEV_SADDR)
+#define CONFIG_IEEE802154_I8SAK_DEV_SADDR 0x000C
+#endif
+#if !defined(CONFIG_IEEE802154_I8SAK_DEV_EADDR)
+#define CONFIG_IEEE802154_I8SAK_DEV_EADDR 0xDEADBEEF00FADE0C
+#endif
+
+#if !defined(CONFIG_IEEE802154_I8SAK_PANID)
+#define CONFIG_IEEE802154_I8SAK_PANID 0xFADE
+#endif
+
+#if !defined(CONFIG_IEEE802154_I8SAK_BLATER_PERIOD)
+#define CONFIG_IEEE802154_I8SAK_BLATER_PERIOD 1000
+#endif
+
+#if !defined(CONFIG_IEEE802154_I8SAK_CHNUM)
+#define CONFIG_IEEE802154_I8SAK_CHNUM 11
+#endif
+
+#if !defined(CONFIG_IEEE802154_I8SAK_CHPAGE)
+#define CONFIG_IEEE802154_I8SAK_CHPAGE 0
+#endif
+
+#define I8SAK_DAEMONNAME_FMT    "i8sak_%s"
+#define I8SAK_MAX_DEVNAME 12
+/* /dev/ is 5 characters */
+#define I8SAK_DAEMONNAME_FMTLEN (6 + (I8SAK_MAX_DEVNAME-5) + 1)
+
+
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+enum i8sak_cmd_e
+{
+  I8_CMD_NONE = 0x00,
+  I8_CMD_SNIFFER,
+  I8_CMD_STARTPAN,
+  I8_CMD_ACCEPTASSOC,
+  I8_CMD_ASSOC,
+  I8_CMD_TX,
+  I8_CMD_BLASTER,
+  I8_CMD_POLL,
+};
+
+struct i8sak_s
+{
+  /* Support singly linked list */
+
+  FAR struct i8sak_s *flink;
+
+  bool initialized      : 1;
+  bool daemon_started   : 1;
+  bool daemon_shutdown  : 1;
+  bool addrset          : 1;
+  bool blasterenabled   : 1;
+  bool verbose          : 1;
+  bool indirect         : 1;
+  bool acceptall        : 1;
+  bool assoc            : 1;
+
+  pid_t daemon_pid;
+  FAR char devname[I8SAK_MAX_DEVNAME];
+  struct wpanlistener_s wpanlistener;
+  int fd;
+
+  sem_t exclsem;   /* For synchronizing access to the signaling semaphore */
+  sem_t sigsem;    /* For signaling various tasks */
+  sem_t updatesem; /* For signaling the daemon that it's settings have changed */
+
+  uint8_t msdu_handle;
+
+  /* Settings */
+
+  uint8_t chnum;
+  uint8_t chpage;
+  struct ieee802154_addr_s addr;
+  struct ieee802154_addr_s ep;
+  uint8_t next_saddr[IEEE802154_SADDRSIZE];
+  uint8_t payload[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
+  uint16_t payload_len;
+  int blasterperiod;
+};
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+int i8sak_tx(FAR struct i8sak_s *i8sak, int fd);
+long i8sak_str2long(FAR const char *str);
+uint8_t i8sak_str2luint8(FAR const char *str);
+uint16_t i8sak_str2luint16(FAR const char *str);
+uint8_t i8sak_char2nibble(char ch);
+
+int i8sak_str2payload(FAR const char *str, FAR uint8_t *buf);
+void i8sak_str2eaddr(FAR const char *str, FAR uint8_t *eaddr);
+void i8sak_str2saddr(FAR const char *str, FAR uint8_t *saddr);
+void i8sak_str2panid(FAR const char *str, FAR uint8_t *panid);
+bool i8sak_str2bool(FAR const char *str);
+
+void i8sak_startpan_cmd    (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+void i8sak_acceptassoc_cmd (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+void i8sak_assoc_cmd       (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+void i8sak_tx_cmd          (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+void i8sak_poll_cmd        (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+void i8sak_sniffer_cmd     (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+void i8sak_blaster_cmd     (FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
+
+/****************************************************************************
+ * Inline Functions
+ ****************************************************************************/
+
+static inline void i8sak_cmd_error(FAR struct i8sak_s *i8sak)
+{
+  sem_post(&i8sak->exclsem);
+  exit(EXIT_FAILURE);
+}
+
+#endif /* __APPS_EXAMPLES_WIRELESS_IEEE802154_I8SAK_H */
diff --git a/wireless/ieee802154/i8sak/i8sak_acceptassoc.c b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c
new file mode 100644
index 000000000..c68caa466
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_acceptassoc.c
@@ -0,0 +1,163 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_acceptassoc.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void acceptassoc_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8_acceptassoc
+ *
+ * Description :
+ *   Start accepting association requests.
+ ****************************************************************************/
+
+void i8sak_acceptassoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  struct wpanlistener_eventfilter_s filter;
+  bool acceptall = true; /* start off assuming we are going to allow all connections */
+  int option;
+  int optcnt;
+
+  optcnt = 0;
+  while ((option = getopt(argc, argv, ":he:")) != ERROR)
+    {
+      optcnt++;
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Starts accepting association requests\n"
+                    "Usage: %s [-h|e <extended address>]\n"
+                    "    -h = this help menu\n"
+                    "    -e = only accept requests from eaddr\n"
+                    "Note: No option accepts all requests\n"
+                    , argv[0]);
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+          case 'e': /* Accept only this extended address */
+            i8sak_str2eaddr(optarg, &i8sak->ep.eaddr[0]);
+            acceptall = false;
+            break;
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+          case '?':
+            fprintf(stderr, "ERROR: invalid argument\n");
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+        }
+    }
+
+  if (!optcnt)
+    {
+      i8sak->acceptall = acceptall;
+      printf("i8sak: accepting all assoc requests\n");
+    }
+
+  /* Register new callback for receiving the association notifications */
+
+  memset(&filter, 0, sizeof(struct wpanlistener_eventfilter_s));
+  filter.indevents.assoc = true;
+
+  wpanlistener_add_eventreceiver(&i8sak->wpanlistener, acceptassoc_eventcb,
+                                 &filter, (FAR void *)i8sak, !i8sak->acceptall);
+}
+
+static void acceptassoc_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg)
+{
+  FAR struct i8sak_s *i8sak = (FAR struct i8sak_s *)arg;
+  struct ieee802154_assoc_resp_s assocresp;
+
+  printf("i8sak: a device is trying to associate\n");
+
+  /* Send a ASSOC.resp primtive to the MAC. Copy the association
+   * indication address into the association response primitive
+   */
+
+  IEEE802154_EADDRCOPY(assocresp.devaddr, notif->u.assocind.devaddr);
+
+  /* If the address matches our device, accept the association.
+   * Otherwise, reject the assocation.
+   */
+
+  if (IEEE802154_EADDRCMP(notif->u.assocind.devaddr, i8sak->ep.eaddr))
+    {
+      IEEE802154_SADDRCOPY(assocresp.assocsaddr, i8sak->next_saddr);
+      assocresp.status = IEEE802154_STATUS_SUCCESS;
+      printf("i8sak: accepting association request\n");
+    }
+  else
+    {
+      assocresp.status = IEEE802154_STATUS_DENIED;
+      printf("i8sak: rejecting association request\n");
+    }
+
+  ieee802154_assoc_resp(i8sak->fd, &assocresp);
+}
\ No newline at end of file
diff --git a/wireless/ieee802154/i8sak/i8sak_assoc.c b/wireless/ieee802154/i8sak/i8sak_assoc.c
new file mode 100644
index 000000000..da34816ab
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_assoc.c
@@ -0,0 +1,232 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_assoc.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void assoc_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8sak_assoc
+ *
+ * Description :
+ *   Request association with the Coordinator
+ ****************************************************************************/
+
+void i8sak_assoc_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  struct ieee802154_assoc_req_s assocreq;
+  struct wpanlistener_eventfilter_s filter;
+  int fd;
+  int option;
+  int optcnt;
+  int ret;
+
+  /* If the addresses has never been automatically or manually set before, set
+   * it assuming that we are the default device address and the endpoint is the
+   * default PAN Coordinator address.  This is actually the way the i8sak settings
+   * are configured, so just set the flag if it's not already set.
+   */
+
+  if (!i8sak->addrset)
+    {
+      i8sak->addrset = true;
+    }
+
+  optcnt = 0;
+  while ((option = getopt(argc, argv, ":hs:e:")) != ERROR)
+    {
+      optcnt++;
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Requests association with endpoint\n"
+                    "Usage: %s [-h]\n"
+                    "    -h = this help menu\n"
+                    , argv[0]);
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+
+          case 's':
+            /* Parse extended address and put it into the i8sak instance */
+
+            i8sak_str2saddr(optarg, i8sak->ep.saddr);
+            i8sak->ep.mode= IEEE802154_ADDRMODE_SHORT;
+            break;
+
+          case 'e':
+            /* Parse extended address and put it into the i8sak instance */
+
+            i8sak_str2eaddr(optarg, i8sak->ep.eaddr);
+            i8sak->ep.mode = IEEE802154_ADDRMODE_EXTENDED;
+            break;
+
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+
+          case '?':
+            fprintf(stderr, "ERROR: unknown argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+        }
+    }
+
+  /* If none of the option flags were used, and there is an argument included,
+   * assume it is the PAN ID
+   */
+
+  if (optcnt && argc == 2)
+    {
+      i8sak_str2panid(argv[1], i8sak->ep.panid);
+    }
+
+  fd = open(i8sak->devname, O_RDWR);
+  if (fd < 0)
+    {
+      printf("i8sak: cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak_cmd_error(i8sak);
+    }
+
+  if (argc < 2)
+    {
+      /* TODO: Perform a scan operation here, to determine addressing information
+       * of coordinator.
+       */
+
+      fprintf(stderr, "i8sak: scan not implemented. Using default values\n");
+    }
+
+  /* Register new callback for receiving the association notifications */
+
+  memset(&filter, 0, sizeof(struct wpanlistener_eventfilter_s));
+  filter.confevents.assoc = true;
+
+  wpanlistener_add_eventreceiver(&i8sak->wpanlistener, assoc_eventcb, &filter,
+                                 (FAR void *)i8sak, true);
+
+  printf("i8sak: issuing ASSOC. request\n");
+
+  assocreq.chnum = i8sak->chnum;
+  assocreq.chpage = i8sak->chpage;
+
+  memcpy(&assocreq.coordaddr, &i8sak->ep, sizeof(struct ieee802154_addr_s));
+
+  assocreq.capabilities.devtype = 0;
+  assocreq.capabilities.powersource = 1;
+  assocreq.capabilities.rxonidle = 1;
+  assocreq.capabilities.security = 0;
+  assocreq.capabilities.allocaddr = 1;
+
+  ieee802154_assoc_req(fd, &assocreq);
+
+  close(fd);
+
+  /* Wait here, the event listener will notify us if the correct event occurs */
+
+  i8sak->assoc = true;
+
+  ret = sem_wait(&i8sak->sigsem);
+  sem_post(&i8sak->exclsem);
+  if (ret != OK)
+    {
+      i8sak->assoc = false;
+      printf("i8sak: test cancelled\n");
+      i8sak_cmd_error(i8sak);
+    }
+}
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void assoc_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg)
+{
+  FAR struct i8sak_s *i8sak = (FAR struct i8sak_s *)arg;
+
+  if (notif->u.assocconf.status == IEEE802154_STATUS_SUCCESS)
+    {
+      printf("i8sak: ASSOC.request succeeded\n");
+    }
+  else
+    {
+      printf("i8sak: ASSOC.request failed: %s\n",
+             IEEE802154_STATUS_STRING[notif->u.assocconf.status]);
+    }
+
+  if (i8sak->assoc)
+    {
+      sem_post(&i8sak->sigsem);
+      i8sak->assoc = false;
+    }
+}
diff --git a/wireless/ieee802154/i8sak/i8sak_blaster.c b/wireless/ieee802154/i8sak/i8sak_blaster.c
new file mode 100644
index 000000000..432b99a2c
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_blaster.c
@@ -0,0 +1,150 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_blaster.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+ /****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static inline void i8sak_blaster_start (FAR struct i8sak_s *i8sak);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8sak_blaster
+ *
+ * Description :
+ *   Continuously transmit a packet
+ ****************************************************************************/
+
+void i8sak_blaster_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  int option;
+
+  if (argc < 2)
+    {
+      i8sak_blaster_start(i8sak);
+    }
+
+  while ((option = getopt(argc, argv, "hqp:f:")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Blasts frames\n"
+                    "Usage: %s [-h|q|f <hex-payload>|p <period_ms>]\n"
+                    "    -h = this help menu\n"
+                    "    -q = quit blasting\n"
+                    "    -f = set frame (and starts blaster)\n"
+                    "    -p = set period (and start blaster)\n"
+                    "Note: No option starts blaster with defaults\n"
+                    , argv[0]);
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+          case 'q': /* Quit blaster */
+            i8sak->blasterenabled = false;
+            break;
+
+          case 'p': /* Inline change blaster period */
+            i8sak->blasterperiod = atoi(optarg);
+            i8sak_blaster_start(i8sak);
+            break;
+
+          case 'f': /* Inline change blaster frame */
+            i8sak->payload_len = i8sak_str2payload(optarg, &i8sak->payload[0]);
+            i8sak_blaster_start(i8sak);
+            break;
+
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+            break;
+
+          case '?':
+            fprintf(stderr, "ERROR: unknown argument\n");
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+        }
+    }
+}
+
+static inline void i8sak_blaster_start (FAR struct i8sak_s *i8sak)
+{
+  if (!i8sak->blasterenabled)
+    {
+      i8sak->blasterenabled = true;
+
+      /* Signal the daemon to start running */
+
+      printf("starting blaster\n");
+      sem_post(&i8sak->updatesem);
+    }
+}
\ No newline at end of file
diff --git a/wireless/ieee802154/i8sak/i8sak_main.c b/wireless/ieee802154/i8sak/i8sak_main.c
index a4473314b..96586778f 100644
--- a/wireless/ieee802154/i8sak/i8sak_main.c
+++ b/wireless/ieee802154/i8sak/i8sak_main.c
@@ -4,7 +4,11 @@
  *
  *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
  *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
  *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
@@ -55,398 +59,169 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <strings.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <queue.h>
 #include <sys/ioctl.h>
 #include <nuttx/fs/ioctl.h>
 
+#include "i8sak.h"
+
 #include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
 #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
 #include "wireless/ieee802154.h"
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#if !defined(CONFIG_IEEE802154_I8SAK_NINSTANCES) || CONFIG_IEEE802154_I8SAK_NINSTANCES <= 0
+#  undef CONFIG_IEEE802154_I8SAK_NINSTANCES
+#  define CONFIG_IEEE802154_I8SAK_NINSTANCES 3
+#endif
+
 /****************************************************************************
  * Private Types
  ****************************************************************************/
 
-struct i8_command_s
+/* Describes one command */
+
+struct i8sak_command_s
 {
   FAR const char *name;
-  uint8_t noptions;
-  CODE void *handler;
+  CODE void (*handler)(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[]);
 };
 
-/* Generic form of a command handler */
-
-typedef void (*cmd0_t)(FAR const char *devname);
-typedef void (*cmd1_t)(FAR const char *devname, FAR const char *arg1);
-typedef void (*cmd2_t)(FAR const char *devname, FAR const char *arg1,
-                       FAR const char *arg2);
-typedef void (*cmd3_t)(FAR const char *devname, FAR const char *arg1,
-                       FAR const char *arg2, FAR const char *arg3);
-
-/****************************************************************************
- * Private Function Prototypes
- ****************************************************************************/
-
-static int i8_tx(int fd);
-static int i8_parse_payload(FAR const char *str);
-static pthread_addr_t i8_eventlistener(pthread_addr_t arg);
-
-static void i8_tx_cmd(FAR const char *devname, FAR const char *payload);
-static void i8_sniffer_cmd(FAR const char *devname);
-static void i8_blaster_cmd(FAR const char *devname, FAR const char *period_ms,
-                           FAR const char *payload);
-
-static int i8_sniffer_daemon(int argc, FAR char *argv[]);
-static int i8_blaster_daemon(int argc, FAR char *argv[]);
-
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-static const struct i8_command_s g_i8_commands[] =
+static const struct i8sak_command_s g_i8sak_commands[] =
 {
-  {"help",    0, (CODE void *)NULL},
-  {"tx",      1, (CODE void *)i8_tx_cmd},
-  {"sniffer", 0, (CODE void *)i8_sniffer_cmd},
-  {"blaster", 2, (CODE void *)i8_blaster_cmd},
+  {"help",        (CODE void *)NULL},
+  {"startpan",    (CODE void *)i8sak_startpan_cmd},
+  {"acceptassoc", (CODE void *)i8sak_acceptassoc_cmd},
+  {"assoc",       (CODE void *)i8sak_assoc_cmd},
+  {"tx",          (CODE void *)i8sak_tx_cmd},
+  {"poll",        (CODE void *)i8sak_poll_cmd},
+  {"sniffer",     (CODE void *)i8sak_sniffer_cmd},
+  {"blaster",     (CODE void *)i8sak_blaster_cmd},
 };
 
-#define NCOMMANDS (sizeof(g_i8_commands) / sizeof(struct i8_command_s))
+#define NCOMMANDS (sizeof(g_i8sak_commands) / sizeof(struct i8sak_command_s))
 
-uint8_t g_handle = 0;
-uint8_t g_txframe[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
-uint16_t g_txframe_len;
-
-int g_blaster_period = 0;
-
-bool g_sniffer_daemon_started = false;
-bool g_blaster_daemon_started = false;
-bool g_eventlistener_run = false;
+static sq_queue_t g_i8sak_free;
+static sq_queue_t g_i8sak_instances;
+static struct i8sak_s g_i8sak_pool[CONFIG_IEEE802154_I8SAK_NINSTANCES];
+static bool g_i8sak_initialized = false;
+static bool g_activei8sak_set = false;
+static FAR struct i8sak_s *g_activei8sak;
 
 /****************************************************************************
- * Public Data
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *devname);
+static int i8sak_daemon(int argc, FAR char *argv[]);
+static int i8sak_showusage(FAR const char *progname, int exitcode);
+static void i8sak_switch_instance(FAR char *devname);
+
+/****************************************************************************
+ * Public Functions
  ****************************************************************************/
 
 /****************************************************************************
- * Private Functions
- ****************************************************************************/
-
-/****************************************************************************
- * Name : i8_sniffer_cmd
- *
- * Description :
- *   Starts a thread to run the sniffer in the background
- ****************************************************************************/
-
-static void i8_sniffer_cmd(FAR const char *devname)
-{
-  int ret;
-  FAR const char *sniffer_argv[2];
-
-  printf("i8sak: Starting sniffer_daemon\n");
-
-  if (g_sniffer_daemon_started)
-    {
-      printf("i8sak: sniffer_daemon already running\n");
-      return;
-    }
-  
-  sniffer_argv[0] = devname;
-  sniffer_argv[1] = NULL;
-  
-  ret = task_create("sniffer_daemon", CONFIG_IEEE802154_I8SAK_PRIORITY,
-                    CONFIG_IEEE802154_I8SAK_STACKSIZE, i8_sniffer_daemon,
-                    (FAR char * const *)sniffer_argv);
-  if (ret < 0)
-    {
-      fprintf(stderr, "ERROR: Failed to start sniffer_daemon\n", errno);
-      return;
-    }
-
-  printf("i8sak: sniffer_daemon started\n");
-}
- 
-/****************************************************************************
- * Name : i8_sniffer_daemon
- *
- * Description :
- *   Sniff for frames (Promiscuous mode)
- ****************************************************************************/
-
-static int i8_sniffer_daemon(int argc, FAR char *argv[])
-{
-  int ret, fd, i;
-  struct mac802154dev_rxframe_s rx;
-
-  fd = open(argv[1], O_RDWR);
-  if (fd < 0)
-    {
-      printf("cannot open %s, errno=%d\n", argv[1], errno);
-      ret = errno;
-      return ret;
-    }
-
-  printf("Listening...\n"); 
-
-  g_sniffer_daemon_started = true;
-
-  /* We don't care about any events, so disable them */
-
-  ret = ieee802154_enableevents(fd, false);
-
-  /* Enable promiscuous mode */
-
-  ret = ieee802154_setpromisc(fd, true);
-
-  /* Make sure receiver is always on while idle */
-
-  ret = ieee802154_setrxonidle(fd, true);
-
-  while(1)
-    {
-      ret = read(fd, &rx, sizeof(struct mac802154dev_rxframe_s));
-      if (ret < 0)
-        {
-          fprintf(stderr, "ERROR: read failed: %d\n", errno);
-          goto done;
-        }
-
-      printf("Frame Received:\n");
-
-      for (i = 0; i < rx.length; i++)
-        {
-          printf("%02X", rx.payload[i]);
-        }
-
-      printf(" \n");
-
-      fflush(stdout);
-    }
-
-done:
-  /* Turn receiver off when idle */
-
-  ret = ieee802154_setrxonidle(fd, false);
-
-  /* Disable promiscuous mode */
-
-  ret = ieee802154_setpromisc(fd, false);
-
-  ret = ieee802154_enableevents(fd, true);
-
-  printf("sniffer_daemon: closing");
-  close(fd);
-  g_sniffer_daemon_started = false;
-  return OK;
-}
-
-/****************************************************************************
- * Name : i8_blaster_cmd
- *
- * Description :
- *   Starts a thread to send continuous packets at a fixed interval
- ****************************************************************************/
-
-static void i8_blaster_cmd(FAR const char *devname, FAR const char *period_ms,
-                           FAR const char *payload)
-{
-  int ret;
-  FAR const char *blaster_argv[2];
-
-  printf("i8sak: Starting blaster_daemon\n");
-
-  if (g_blaster_daemon_started)
-    {
-      printf("i8sak: blaster_daemon already running\n");
-      return;
-    }
-  
-  blaster_argv[0] = devname;
-  blaster_argv[1] = NULL;
-  
-  g_blaster_period = atoi(period_ms);
-
-  ret = i8_parse_payload(payload);
-  if (ret < 0)
-    {
-      fprintf(stderr, "ERROR:invalid hex payload\n", ret);
-      return;
-    }
-  
-  ret = task_create("blaster_daemon", CONFIG_IEEE802154_I8SAK_PRIORITY,
-                    CONFIG_IEEE802154_I8SAK_STACKSIZE, i8_blaster_daemon,
-                    (FAR char * const *)blaster_argv);
-  if (ret < 0)
-    {
-      fprintf(stderr, "ERROR: Failed to start blaster_daemon", errno);
-      return;
-    }
-
-  printf("i8sak: blaster_daemon started\n");
-}
-
-/****************************************************************************
- * Name : i8_blaster_daemon
- *
- * Description :
- *   Continuously transmit a packet
- ****************************************************************************/
-
-static int i8_blaster_daemon(int argc, FAR char *argv[])
-{
-  int ret, fd;
-  pthread_t eventthread;
-
-  fd = open(argv[1], O_RDWR);
-  if (fd < 0)
-    {
-      fprintf(stderr, "ERROR:cannot open %s, errno=%d\n", argv[1], errno);
-      ret = errno;
-      return ret;
-    }
-
-  printf("blaster_daemon: starting\n"); 
-  g_blaster_daemon_started = true;
-
-  /* Start a thread to handle any events that occur */
-
-  g_eventlistener_run = true;
-  ret = pthread_create(&eventthread, NULL, i8_eventlistener, (void *)&fd);
-  if (ret != 0)
-    {
-      printf("blaster_daemon: Failed to create eventlistener thread: %d\n", ret);
-      goto done;
-    }
-
-  while(1)
-    {
-      ret = i8_tx(fd);
-      if (ret < 0)
-        {
-          goto done;
-        }
-      ret = usleep(g_blaster_period*1000L);
-      if (ret < 0)
-        {
-          goto done;
-        }
-    }
-
-done:
-  /* Tell the eventthread to stop */
-
-  printf("blaster_daemon: closing\n");
-  g_eventlistener_run = false;
-  pthread_join(eventthread, NULL);
-  close(fd);
-  g_blaster_daemon_started = false;
-  return OK;
-}
-
-/****************************************************************************
- * Name : i8_tx_cmd
+ * Name : i8sak_tx
  *
  * Description :
  *   Transmit a data frame.
  ****************************************************************************/
 
-static void i8_tx_cmd(FAR const char *devname, FAR const char *str)
-{
-  int ret, fd;
-  int i = 0;
-
-  ret = i8_parse_payload(str);
-  if (ret < 0)
-    {
-      fprintf(stderr, "ERROR:invalid hex payload\n", ret);
-      return;
-    }
-
-  for (i = 0; i < g_txframe_len; i++)
-    {
-      printf("%02X", g_txframe[i]);
-    }
-
-  fflush(stdout);
-
-  /* Open device */
-
-  fd = open(devname, O_RDWR);
-  if (fd < 0)
-    {
-      fprintf(stderr, "ERROR:cannot open %s, errno=%d\n", devname, errno);
-      return;
-    }
-
-  ret = i8_tx(fd);
-  if (ret < 0)
-    {
-      fprintf(stderr, "ERROR:Failed to transmit packet.\n", ret);
-    }
-  
-  close(fd);
-}
-
-/****************************************************************************
- * Name : i8_eventlistener
- *
- * Description :
- *   Listen for events from the MAC layer
- ****************************************************************************/
-
-static pthread_addr_t i8_eventlistener(pthread_addr_t arg)
+int i8sak_tx(FAR struct i8sak_s *i8sak, int fd)
 {
+  struct mac802154dev_txframe_s tx;
   int ret;
-  struct ieee802154_notif_s notif;
-  int fd = *(int *)arg;
 
-  while (g_eventlistener_run)
+  /* Set an application defined handle */
+
+  tx.meta.msdu_handle = i8sak->msdu_handle++;
+
+  /* This is a normal transaction, no special handling */
+
+  tx.meta.msdu_flags.ack_tx = 0;
+  tx.meta.msdu_flags.gts_tx = 0;
+
+  tx.meta.msdu_flags.indirect_tx = i8sak->indirect;
+
+  if (i8sak->indirect)
     {
-      ret = ioctl(fd, MAC802154IOC_GET_EVENT, (unsigned long)((uintptr_t)&notif));
-      if (ret < 0)
+      if (i8sak->verbose)
         {
-          fprintf(stderr, "MAC802154IOC_GET_EVENTS failed: %d\n", ret);
+          printf("i8sak: queuing indirect transaction\n");
+          fflush(stdout);
         }
-      
-      switch (notif.notiftype)
+    }
+  else
+    {
+      if (i8sak->verbose)
         {
-          case IEEE802154_NOTIFY_CONF_DATA:
-            printf("Data Confirmation Status %d\n", notif.u.dataconf.status);
-            break;
-          default:
-            printf("Unhandled notification: %d\n", notif.notiftype);
-            break;
+          printf("i8sak: queuing CSMA transaction\n");
+          fflush(stdout);
         }
     }
 
-    return NULL;
+  tx.meta.ranging = IEEE802154_NON_RANGING;
+
+  tx.meta.srcaddr_mode = IEEE802154_ADDRMODE_SHORT;
+  memcpy(&tx.meta.destaddr, &i8sak->ep, sizeof(struct ieee802154_addr_s));
+
+  /* Each byte is represented by 2 chars */
+
+  tx.length = i8sak->payload_len;
+  tx.payload = &i8sak->payload[0];
+
+  ret = write(fd, &tx, sizeof(struct mac802154dev_txframe_s));
+  if (ret != OK)
+    {
+      printf(" write: errno=%d\n",errno);
+    }
+
+  return ret;
 }
 
 /****************************************************************************
- * Name : i8_parse_payload
+ * Name : i8sak_str2payload
  *
  * Description :
- *   Parse string to get payload
+ *   Parse string to get buffer of data. Buf is expected to be of size
+ *   IEEE802154_MAX_MAC_PAYLOAD_SIZE or larger.
+ *
+ * Returns:
+ *   Positive length value of frame payload
  ****************************************************************************/
 
-static int i8_parse_payload(FAR const char *str)
+int i8sak_str2payload(FAR const char *str, FAR uint8_t *buf)
 {
   int str_len;
+  int ret;
   int i = 0;
-  
+
   str_len = strlen(str);
 
   /* Each byte is represented by 2 chars */
 
-  g_txframe_len = str_len >> 1;
+  ret = str_len >> 1;
 
-  /* Check if the number of chars is a multiple of 2 and that the number of 
-   * bytes does not exceed the max MAC frame payload supported */
+  /* Check if the number of chars is a multiple of 2 and that the number of
+   * bytes does not exceed the max MAC frame payload supported.
+   */
 
-  if ((str_len & 1) || (g_txframe_len > IEEE802154_MAX_MAC_PAYLOAD_SIZE))
+  if ((str_len & 1) || (ret > IEEE802154_MAX_MAC_PAYLOAD_SIZE))
     {
-      return -EINVAL;
+      fprintf(stderr, "ERROR: Invalid payload\n");
+      exit(EXIT_FAILURE);
     }
 
   /* Decode hex packet */
@@ -456,85 +231,511 @@ static int i8_parse_payload(FAR const char *str)
       int dat;
       if (sscanf(str, "%2x", &dat) == 1)
         {
-          g_txframe[i++] = dat;
+          buf[i++] = dat;
           str += 2;
           str_len -= 2;
         }
       else
         {
-          return -EINVAL;
+          fprintf(stderr, "ERROR: Invalid payload\n");
+          exit(EXIT_FAILURE);
         }
     }
-  
-  return OK;
-}
 
-/****************************************************************************
- * Name : i8_tx
- *
- * Description :
- *   Transmit a data frame.
- ****************************************************************************/
-
-static int i8_tx(int fd)
-{
-  int ret;
-  struct mac802154dev_txframe_s tx;
-
-  /* Set an application defined handle */
-
-  tx.meta.msdu_handle = g_handle++;
-
-  /* This is a normal transaction, no special handling */
-
-  tx.meta.msdu_flags.ack_tx = 0;
-  tx.meta.msdu_flags.gts_tx = 0;
-  tx.meta.msdu_flags.indirect_tx = 0;
-
-  tx.meta.ranging = IEEE802154_NON_RANGING;
-
-  tx.meta.src_addrmode = IEEE802154_ADDRMODE_EXTENDED;
-  tx.meta.dest_addr.mode = IEEE802154_ADDRMODE_SHORT;
-  tx.meta.dest_addr.saddr = 0xFADE;
-
-  /* Each byte is represented by 2 chars */
-
-  tx.length = g_txframe_len;
-  tx.payload = &g_txframe[0];
-
-  ret = write(fd, &tx, sizeof(struct mac802154dev_txframe_s));
-  if (ret == OK)
-    {
-      printf(" Tx OK\n");
-    }
-  else
-    {
-      printf(" write: errno=%d\n",errno);
-    }
-  
   return ret;
 }
 
 /****************************************************************************
- * Public Functions
+ * Name: i8sak_str2long
+ *
+ * Description:
+ *   Convert a hex string to an integer value
+ *
  ****************************************************************************/
 
+long i8sak_str2long(FAR const char *str)
+{
+  FAR char *endptr;
+  long value;
+
+  value = strtol(str, &endptr, 0);
+  if (*endptr != '\0')
+    {
+      fprintf(stderr, "ERROR: Garbage after numeric argument\n");
+      exit(EXIT_FAILURE);
+    }
+
+  if (value > INT_MAX || value < INT_MIN)
+    {
+      fprintf(stderr, "ERROR: Integer value out of range\n");
+      return LONG_MAX;
+      exit(EXIT_FAILURE);
+    }
+
+  return value;
+}
+
 /****************************************************************************
- * Name: i8_showusage
+ * Name: i8sak_str2luint8
+ *
+ * Description:
+ *   Convert a string to an integer value
+ *
+ ****************************************************************************/
+
+uint8_t i8sak_str2luint8(FAR const char *str)
+{
+  long value = i8sak_str2long(str);
+  if (value < 0 || value > UINT8_MAX)
+    {
+      fprintf(stderr, "ERROR: 8-bit value out of range\n");
+      exit(EXIT_FAILURE);
+    }
+
+  return (uint8_t)value;
+}
+
+/****************************************************************************
+ * Name: i8sak_str2luint16
+ *
+ * Description:
+ *   Convert a string to an integer value
+ *
+ ****************************************************************************/
+
+uint16_t i8sak_str2luint16(FAR const char *str)
+{
+  long value = i8sak_str2long(str);
+  if (value < 0 || value > UINT16_MAX)
+    {
+      fprintf(stderr, "ERROR: 16-bit value out of range\n");
+      exit(EXIT_FAILURE);
+    }
+
+  return (uint16_t)value;
+}
+
+/****************************************************************************
+ * Name: i8sak_char2nibble
+ *
+ * Description:
+ *   Convert an hexadecimal character to a 4-bit nibble.
+ *
+ ****************************************************************************/
+
+uint8_t i8sak_char2nibble(char ch)
+{
+  if (ch >= '0' && ch <= '9')
+    {
+      return ch - '0';
+    }
+  else if (ch >= 'a' && ch <= 'f')
+    {
+      return ch - 'a' + 10;
+    }
+  else if (ch >= 'A' && ch <= 'F')
+    {
+      return ch - 'A' + 10;
+    }
+  else if (ch == '\0')
+    {
+      fprintf(stderr, "ERROR: Unexpected end hex\n");
+      exit(EXIT_FAILURE);
+    }
+  else
+    {
+      fprintf(stderr, "ERROR: Unexpected character in hex value: %02x\n", ch);
+      exit(EXIT_FAILURE);
+    }
+}
+
+/****************************************************************************
+ * Name: i8sak_str2eaddr
+ *
+ * Description:
+ *   Convert a string 8-byte EADDR array.
+ *
+ ****************************************************************************/
+
+void i8sak_str2eaddr(FAR const char *str, FAR uint8_t *eaddr)
+{
+  FAR const char *src = str;
+  uint8_t bvalue;
+  char ch;
+  int i;
+
+  for (i = 0; i < 8; i++)
+    {
+      ch = (char)*src++;
+      bvalue = i8sak_char2nibble(ch) << 4;
+
+      ch = (char)*src++;
+      bvalue |= i8sak_char2nibble(ch);
+
+      *eaddr++ = bvalue;
+
+      if (i < 7)
+        {
+          ch = (char)*src++;
+          if (ch != ':')
+            {
+              fprintf(stderr, "ERROR: Missing colon separator: %s\n", str);
+              fprintf(stderr, "       Expected xx:xx:xx:xx:xx:xx:xx:xx\n");
+              exit(EXIT_FAILURE);
+            }
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: i8sak_str2saddr
+ *
+ * Description:
+ *   Convert a string 2-byte SADDR array.
+ *
+ ****************************************************************************/
+
+void i8sak_str2saddr(FAR const char *str, FAR uint8_t *saddr)
+{
+  FAR const char *src = str;
+  uint8_t bvalue;
+  char ch;
+  int i;
+
+  for (i = 0; i < 2; i++)
+    {
+      ch = (char)*src++;
+      bvalue = i8sak_char2nibble(ch) << 4;
+
+      ch = (char)*src++;
+      bvalue |= i8sak_char2nibble(ch);
+
+      *saddr++ = bvalue;
+
+      if (i < 1)
+        {
+          ch = (char)*src++;
+          if (ch != ':')
+            {
+              fprintf(stderr, "ERROR: Missing colon separator: %s\n", str);
+              fprintf(stderr, "       Expected xx:xx\n");
+              exit(EXIT_FAILURE);
+            }
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: i8sak_str2panid
+ *
+ * Description:
+ *   Convert a string 2-byte PAN ID array.
+ *
+ ****************************************************************************/
+
+void i8sak_str2panid(FAR const char *str, FAR uint8_t *panid)
+{
+  FAR const char *src = str;
+  uint8_t bvalue;
+  char ch;
+  int i;
+
+  for (i = 0; i < 2; i++)
+    {
+      ch = (char)*src++;
+      bvalue = i8sak_char2nibble(ch) << 4;
+
+      ch = (char)*src++;
+      bvalue |= i8sak_char2nibble(ch);
+
+      *panid++ = bvalue;
+
+      if (i < 1)
+        {
+          ch = (char)*src++;
+          if (ch != ':')
+            {
+              fprintf(stderr, "ERROR: Missing colon separator: %s\n", str);
+              fprintf(stderr, "       Expected xx:xx\n");
+              exit(EXIT_FAILURE);
+            }
+        }
+    }
+}
+
+/****************************************************************************
+ * Name: i8sak_str2bool
+ *
+ * Description:
+ *   Convert a boolean name to a boolean value.
+ *
+ ****************************************************************************/
+
+bool i8sak_str2bool(FAR const char *str)
+{
+  if (strcasecmp(str, "true") == 0)
+    {
+      return true;
+    }
+  else if (strcasecmp(str, "false") == 0)
+    {
+      return false;
+    }
+  else
+    {
+      fprintf(stderr, "ERROR: Invalid boolean name: %s\n", str);
+      fprintf(stderr, "       Expected true or false\n");
+      exit(EXIT_FAILURE);
+    }
+}
+
+/****************************************************************************
+ * Private Functions
+ ****************************************************************************/
+
+static void i8sak_switch_instance(FAR char *devname)
+{
+  FAR struct i8sak_s *i8sak;
+
+  /* Search list of i8sak instances for one associated with the provided
+   * device.
+   */
+
+  i8sak = (FAR struct i8sak_s *)sq_peek(&g_i8sak_instances);
+
+  while (i8sak != NULL)
+    {
+      if (strcmp(devname, i8sak->devname) == 0)
+        {
+          break;
+        }
+
+      i8sak = (FAR struct i8sak_s *)sq_next((FAR sq_entry_t *)i8sak);
+    }
+
+  /* If there isn't a i8sak instance started for this device, allocate one */
+
+  if (i8sak == NULL)
+    {
+      i8sak = (FAR struct i8sak_s *)sq_remfirst(&g_i8sak_free);
+      if (i8sak == NULL)
+        {
+          fprintf(stderr, "ERROR: Failed to allocate i8sak instance\n");
+          exit(EXIT_FAILURE);
+        }
+
+      sq_addlast((FAR sq_entry_t *)i8sak, &g_i8sak_instances);
+    }
+
+  /* Update our "sticky" i8sak instance. Must come before call to setup so that
+   * the shared active global i8sak is correct.
+   */
+
+  g_activei8sak = i8sak;
+
+  if (!g_activei8sak_set)
+    {
+      g_activei8sak_set = true;
+    }
+
+  if (i8sak_setup(i8sak, devname) < 0)
+    {
+      exit(EXIT_FAILURE);
+    }
+}
+
+static int i8sak_setup(FAR struct i8sak_s *i8sak, FAR const char *devname)
+{
+  char daemonname[I8SAK_DAEMONNAME_FMTLEN];
+  int i;
+  int ret;
+  int fd;
+
+  if (i8sak->initialized)
+    {
+      return OK;
+    }
+
+  i8sak->daemon_started = false;
+  i8sak->daemon_shutdown = false;
+
+  i8sak->chnum = CONFIG_IEEE802154_I8SAK_CHNUM;
+  i8sak->chpage = CONFIG_IEEE802154_I8SAK_CHPAGE;
+
+  if (strlen(devname) > I8SAK_MAX_DEVNAME)
+    {
+      fprintf(stderr, "ERROR: devname too long\n");
+      return ERROR;
+    }
+
+  strcpy(&i8sak->devname[0], devname);
+
+  /* Initialze default extended address */
+
+  for (i = 0; i < IEEE802154_EADDRSIZE; i++)
+   {
+     i8sak->addr.eaddr[i] = (uint8_t)((CONFIG_IEEE802154_I8SAK_DEV_EADDR >> (i*8)) & 0xFF);
+   }
+
+  /* Initialize the default remote endpoint address */
+
+  i8sak->ep.mode = IEEE802154_ADDRMODE_SHORT;
+
+  for (i = 0; i < IEEE802154_EADDRSIZE; i++)
+   {
+     i8sak->ep.eaddr[i] = (uint8_t)((CONFIG_IEEE802154_I8SAK_PANCOORD_EADDR >> (i*8)) & 0xFF);
+   }
+
+  for (i = 0; i < IEEE802154_SADDRSIZE; i++)
+   {
+     i8sak->ep.saddr[i] = (uint8_t)((CONFIG_IEEE802154_I8SAK_PANCOORD_SADDR >> (i*8)) & 0xFF);
+   }
+
+  for (i = 0; i < IEEE802154_PANIDSIZE; i++)
+     {
+       i8sak->ep.panid[i] = (uint8_t)((CONFIG_IEEE802154_I8SAK_PANID >> (i*8)) & 0xFF);
+     }
+
+  /* Set the next association device to the default device address, so that
+   * the first device to request association gets that address.
+   */
+
+  for (i = 0; i < IEEE802154_SADDRSIZE; i++)
+   {
+     i8sak->next_saddr[i] = (uint8_t)((CONFIG_IEEE802154_I8SAK_DEV_SADDR >> (i*8)) & 0xFF);
+   }
+
+  fd = open(i8sak->devname, O_RDWR);
+  if (fd < 0)
+    {
+      printf("cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak_cmd_error(i8sak);
+    }
+
+  ieee802154_seteaddr(fd, i8sak->addr.eaddr);
+
+  close(fd);
+
+  i8sak->addrset = false;
+
+  i8sak->blasterperiod = CONFIG_IEEE802154_I8SAK_BLATER_PERIOD;
+
+  sem_init(&i8sak->exclsem, 0, 1);
+
+  sem_init(&i8sak->updatesem, 0, 0);
+  sem_setprotocol(&i8sak->updatesem, SEM_PRIO_NONE);
+
+  sem_init(&i8sak->sigsem, 0, 0);
+  sem_setprotocol(&i8sak->sigsem, SEM_PRIO_NONE);
+
+  /* Create strings for task based on device. i.e. i8_ieee0 */
+
+  snprintf(daemonname, I8SAK_DAEMONNAME_FMTLEN, I8SAK_DAEMONNAME_FMT, &devname[5]);
+
+  i8sak->daemon_pid = task_create(daemonname, CONFIG_IEEE802154_I8SAK_PRIORITY,
+                                  CONFIG_IEEE802154_I8SAK_STACKSIZE, i8sak_daemon,
+                                  NULL);
+  if (i8sak->daemon_pid < 0)
+    {
+      fprintf(stderr, "failed to start daemon\n");
+      return ERROR;
+    }
+
+  /* Use the signal semaphore to wait for daemon to start before returning */
+
+  ret = sem_wait(&i8sak->sigsem);
+  if (ret < 0)
+    {
+      fprintf(stderr, "i8sak:interrupted while daemon starting\n");
+      return ERROR;
+    }
+
+  i8sak->initialized = true;
+  return OK;
+}
+
+/****************************************************************************
+ * Name : i8sak_daemon
+ *
+ * Description :
+ *   Runs command in seperate task
+ ****************************************************************************/
+
+static int i8sak_daemon(int argc, FAR char *argv[])
+{
+  FAR struct i8sak_s *i8sak = g_activei8sak;
+  int ret;
+
+  fprintf(stderr, "i8sak: daemon started\n");
+  i8sak->daemon_started = true;
+
+  i8sak->fd = open(i8sak->devname, O_RDWR);
+  if (i8sak->fd < 0)
+    {
+      printf("cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak->daemon_started = false;
+      ret = errno;
+      return ret;
+    }
+
+  if (!i8sak->wpanlistener.is_setup)
+    {
+      wpanlistener_setup(&i8sak->wpanlistener, i8sak->fd);
+    }
+
+  wpanlistener_start(&i8sak->wpanlistener);
+
+  /* Signal the calling thread that the daemon is up and running */
+
+  sem_post(&i8sak->sigsem);
+
+  while (!i8sak->daemon_shutdown)
+    {
+      if (i8sak->blasterenabled)
+        {
+          usleep(i8sak->blasterperiod*1000);
+        }
+      else
+        {
+          ret = sem_wait(&i8sak->updatesem);
+          if (ret != OK)
+            {
+              break;
+            }
+        }
+
+      if (i8sak->blasterenabled)
+        {
+          i8sak_tx(i8sak, i8sak->fd);
+        }
+    }
+
+  wpanlistener_stop(&i8sak->wpanlistener);
+  i8sak->daemon_started = false;
+  close(i8sak->fd);
+  printf("i8sak: daemon closing\n");
+  return OK;
+}
+
+/****************************************************************************
+ * Name: i8sak_showusage
  *
  * Description:
  *   Show program usage.
  *
  ****************************************************************************/
 
-int i8_showusage(FAR const char *progname, int exitcode)
+static int i8sak_showusage(FAR const char *progname, int exitcode)
 {
-  fprintf(stderr, "Usage:\n", progname);
-  fprintf(stderr, "\t%s <op> <command> [OPTIONS]\n", progname);
-  fprintf(stderr, "\nWhere supported commands and [OPTIONS] appear below\n");
-  fprintf(stderr, "\t%s tx <devname> <hex payload>\n", progname);
-  fprintf(stderr, "\t%s sniffer <devname>\n", progname);
-  fprintf(stderr, "\t%s blaster <devname> <period (ms)> <hex payload>\n", progname);
+  fprintf(stderr, "Usage: %s\n"
+          "    startpan [-h]\n"
+          "    acceptassoc [-h|e <eaddr>]\n"
+          "    assoc [-h] [<panid>] \n"
+          "    tx [-h|d] <hex-payload>\n"
+          "    poll [-h]\n"
+          "    blaster [-h|q|f <hex payload>|p <period_ms>]\n"
+          "    sniffer [-h|q]\n"
+          , progname);
   exit(exitcode);
 }
 
@@ -548,90 +749,94 @@ int main(int argc, FAR char *argv[])
 int i8_main(int argc, char *argv[])
 #endif
 {
-  FAR const char *cmdname;
-  FAR const char *devname;
-  FAR const struct i8_command_s *i8cmd;
+  FAR const struct i8sak_command_s *i8sakcmd;
+  int argind;
+  int ret;
   int i;
 
-  if (argc < 2)
+  if (!g_i8sak_initialized)
     {
-      fprintf(stderr, "ERROR: Missing command\n");
-      i8_showusage(argv[0], EXIT_FAILURE);
+      sq_init(&g_i8sak_free);
+      sq_init(&g_i8sak_instances);
+      for (i = 0; i < CONFIG_IEEE802154_I8SAK_NINSTANCES; i++)
+        {
+          sq_addlast((FAR sq_entry_t *)&g_i8sak_pool[i], &g_i8sak_free);
+          g_i8sak_pool[i].initialized = false;
+        }
+
+      g_i8sak_initialized = true;
     }
 
-  if (argc < 3)
+  argind = 1;
+
+  /* Check if devname was included */
+
+  if (argc > 1)
     {
-      fprintf(stderr, "ERROR: Missing devname\n");
-      i8_showusage(argv[0], EXIT_FAILURE);
+      /* Check if argument starts with /dev/ */
+
+      if (strncmp(argv[argind], "/dev/", 5) == 0)
+        {
+          i8sak_switch_instance(argv[argind]);
+          argind++;
+
+          if (argc == 2)
+            {
+              /* Close silently to allow user to set devname without any
+               * other operation.
+               */
+
+              return EXIT_SUCCESS;
+            }
+        }
+
+      /* Argument must be command */
     }
 
-  cmdname = argv[1];
-  devname = argv[2];
+  /* If devname wasn't included, we need to check if our sticky feature has
+   * ever been set.
+   */
 
-  /* Find the command in the g_i8_command[] list */
+  else if (!g_activei8sak_set)
+    {
+      fprintf(stderr, "ERROR: Must include devname the first time you run\n");
+      i8sak_showusage(argv[0], EXIT_FAILURE);
+    }
 
-  i8cmd = NULL;
+  /* Find the command in the g_i8sak_command[] list */
+
+  i8sakcmd = NULL;
   for (i = 0; i < NCOMMANDS; i++)
     {
-      FAR const struct i8_command_s *cmd = &g_i8_commands[i];
-      if (strcmp(cmdname, cmd->name) == 0)
+      FAR const struct i8sak_command_s *cmd = &g_i8sak_commands[i];
+      if (strcmp(argv[argind], cmd->name) == 0)
         {
-          i8cmd = cmd;
+          i8sakcmd = cmd;
           break;
         }
     }
 
-  if (i8cmd == NULL)
+  if (i8sakcmd == NULL)
     {
-      fprintf(stderr, "ERROR: Unsupported command: %s\n", cmdname);
-      i8_showusage(argv[0], EXIT_FAILURE);
+      i8sak_showusage(argv[0], EXIT_FAILURE);
     }
 
-  if (i8cmd->noptions + 1 < argc)
+  /* Special case the help command which has no handler */
+
+  if (i8sakcmd->handler == NULL)
     {
-      fprintf(stderr, "ERROR: Garbage at end of command ignored\n");
-    }
-  else if (i8cmd->noptions + 1 > argc)
-    {
-      fprintf(stderr, "ERROR: Missing required command options: %s\n",
-              cmdname);
-      i8_showusage(argv[0], EXIT_FAILURE);
+      i8sak_showusage(argv[0], EXIT_SUCCESS);
     }
 
-  /* Special case the help command which has no arguments, no handler,
-   * and does not need a socket.
-   */
-
-  if (i8cmd->handler == NULL)
+  ret = sem_wait(&g_activei8sak->exclsem);
+  if (ret < 0)
     {
-      i8_showusage(argv[0], EXIT_SUCCESS);
+      fprintf(stderr, "ERROR: Failed to lock i8sak instance\n");
+      exit(EXIT_FAILURE);
     }
 
-  /* Dispatch the command handling */
+  i8sakcmd->handler(g_activei8sak, argc - argind, &argv[argind]);
 
-  switch (i8cmd->noptions)
-    {
-      case 0:
-        ((cmd0_t)i8cmd->handler)(devname);
-        break;
-
-      case 1:
-        ((cmd1_t)i8cmd->handler)(devname, argv[3]);
-        break;
-
-      case 2:
-        ((cmd2_t)i8cmd->handler)(devname, argv[3], argv[4]);
-        break;
-
-      case 3:
-        ((cmd3_t)i8cmd->handler)(devname, argv[3], argv[4], argv[5]);
-        break;
-
-      default:
-        fprintf(stderr, "ERROR: Too many arguments: %s\n",
-                cmdname);
-        i8_showusage(argv[0], EXIT_FAILURE);
-    }
-
-    return EXIT_SUCCESS;
+  sem_post(&g_activei8sak->exclsem);
+  return EXIT_SUCCESS;
 }
diff --git a/wireless/ieee802154/i8sak/i8sak_poll.c b/wireless/ieee802154/i8sak/i8sak_poll.c
new file mode 100644
index 000000000..7db6eaf48
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_poll.c
@@ -0,0 +1,176 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_poll.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+ /****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void poll_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8sak_poll_cmd
+ *
+ * Description :
+ *   Try and extract data from the coordinator
+ ****************************************************************************/
+
+void i8sak_poll_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  struct ieee802154_poll_req_s pollreq;
+  struct wpanlistener_eventfilter_s eventfilter;
+  int option;
+  int fd;
+  int ret;
+
+  ret = OK;
+  while ((option = getopt(argc, argv, ":h")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Polls coordinator for data\n"
+                    "Usage: %s [-h]\n"
+                    "    -h = this help menu\n"
+                    , argv[0]);
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+          case '?':
+            fprintf(stderr, "ERROR: unknown argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+        }
+    }
+
+  if (ret != OK)
+    {
+      i8sak_cmd_error(i8sak);
+    }
+
+  fd = open(i8sak->devname, O_RDWR);
+  if (fd < 0)
+    {
+      printf("cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak_cmd_error(i8sak);
+    }
+
+  /* Register new oneshot callback for receiving the association notifications */
+
+  memset(&eventfilter, 0, sizeof(struct wpanlistener_eventfilter_s));
+  eventfilter.confevents.poll = true;
+
+  wpanlistener_add_eventreceiver(&i8sak->wpanlistener, poll_eventcb,
+                                 &eventfilter, (FAR void *)i8sak, true);
+
+  printf("i8sak: Polling coordinator. PAN ID: %02X:%02X SADDR: %02X:%02X\n",
+         i8sak->ep.panid[0], i8sak->ep.panid[1],
+         i8sak->ep.saddr[0], i8sak->ep.saddr[1]);
+
+  pollreq.coordaddr.mode = IEEE802154_ADDRMODE_SHORT;
+  IEEE802154_SADDRCOPY(pollreq.coordaddr.saddr, i8sak->ep.saddr);
+  IEEE802154_PANIDCOPY(pollreq.coordaddr.panid, i8sak->ep.panid);
+
+  ieee802154_poll_req(fd, &pollreq);
+
+  close(fd);
+
+  /* Wait here, the event listener will notify us if the correct event occurs */
+
+  ret = sem_wait(&i8sak->sigsem);
+  if (ret != OK)
+    {
+      printf("i8sak: poll cancelled\n");
+      i8sak_cmd_error(i8sak);
+    }
+}
+
+/****************************************************************************
+ * Private Function
+ ****************************************************************************/
+
+static void poll_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg)
+{
+  FAR struct i8sak_s *i8sak = (FAR struct i8sak_s *)arg;
+
+  if (notif->u.pollconf.status == IEEE802154_STATUS_SUCCESS)
+    {
+      printf("i8sak: POLL.request succeeded\n");
+    }
+  else
+    {
+      printf("i8sak: POLL.request failed: %s\n",
+             IEEE802154_STATUS_STRING[notif->u.pollconf.status]);
+    }
+
+  sem_post(&i8sak->sigsem);
+}
diff --git a/wireless/ieee802154/i8sak/i8sak_sniffer.c b/wireless/ieee802154/i8sak/i8sak_sniffer.c
new file mode 100644
index 000000000..253ca8b4f
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_sniffer.c
@@ -0,0 +1,139 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_sniffer.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+ /****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8sak_sniffer_cmd
+ *
+ * Description :
+ *   Sniff for frames (Promiscuous mode)
+ ****************************************************************************/
+
+void i8sak_sniffer_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  int option;
+  int fd;
+  int ret;
+
+  ret = OK;
+  while ((option = getopt(argc, argv, "h")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Starts sniffer\n"
+                    "Usage: %s [-h]\n"
+                    "    -h = this help menu\n"
+                    , argv[0]);
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+          case '?':
+            fprintf(stderr, "ERROR: unknown argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+        }
+    }
+
+  if (ret != OK)
+    {
+      i8sak_cmd_error(i8sak);
+    }
+
+  fd = open(i8sak->devname, O_RDWR);
+  if (fd < 0)
+    {
+      printf("cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak_cmd_error(i8sak);
+    }
+
+  /* Enable promiscuous mode */
+
+  printf("i8sak: turning on promiscuous mode.\n");
+  ieee802154_setpromisc(fd, true);
+
+  /* Make sure receiver is always on while idle */
+
+  printf("i8sak: setting receiveonidle.\n");
+  ieee802154_setrxonidle(fd, true);
+
+  close(fd);
+
+  /* Don't need to register a callback or anything since the wpanlistener
+   * prints when it receives a frame. This may not be a good solution in
+   * the future.
+   */
+}
diff --git a/wireless/ieee802154/i8sak/i8sak_startpan.c b/wireless/ieee802154/i8sak/i8sak_startpan.c
new file mode 100644
index 000000000..409e83ea2
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_startpan.c
@@ -0,0 +1,196 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_startpan.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8sak_startpan_cmd
+ *
+ * Description :
+ *   Start PAN and accept association requests
+ ****************************************************************************/
+
+void i8sak_startpan_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  struct ieee802154_reset_req_s resetreq;
+  struct ieee802154_start_req_s startreq;
+  int option;
+  int fd;
+  int i;
+
+  while ((option = getopt(argc, argv, ":h")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Starts PAN as PAN Coordinator\n"
+                    "Usage: %s [-h]\n"
+                    "    -h = this help menu\n"
+                    , argv[0]);
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+          case '?':
+            fprintf(stderr, "ERROR: unknown argument\n");
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+        }
+    }
+
+  fd = open(i8sak->devname, O_RDWR);
+  if (fd < 0)
+    {
+      printf("cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak_cmd_error(i8sak);
+    }
+
+  /* Reset the MAC layer */
+
+  printf("\ni8sak: resetting MAC layer\n");
+  resetreq.rst_pibattr = true;
+  ieee802154_reset_req(fd, &resetreq);
+
+  /* Make sure receiver is always on */
+
+  ieee802154_setrxonidle(fd, true);
+
+  /* If the addresses has never been automatically or manually set before, set
+   * it assuming that we are the default PAN coordinator address and the
+   * endpoint is the default device address.
+   */
+
+  if (!i8sak->addrset)
+    {
+      /* Set our address to the default PAN Coordinator configuration */
+
+      i8sak->addr.mode = IEEE802154_ADDRMODE_SHORT;
+
+      for (i = 0; i < IEEE802154_EADDRSIZE; i++)
+      {
+        i8sak->addr.eaddr[i] =
+          (uint8_t)((CONFIG_IEEE802154_I8SAK_PANCOORD_EADDR >> (i*8)) & 0xFF);
+      }
+
+      for (i = 0; i < IEEE802154_SADDRSIZE; i++)
+      {
+        i8sak->addr.saddr[i] =
+          (uint8_t)((CONFIG_IEEE802154_I8SAK_PANCOORD_SADDR >> (i*8)) & 0xFF);
+      }
+
+      for (i = 0; i < IEEE802154_PANIDSIZE; i++)
+      {
+        i8sak->addr.panid[i] =
+          (uint8_t)((CONFIG_IEEE802154_I8SAK_PANID >> (i*8)) & 0xFF);
+      }
+
+      /* Set the endpoint address to the default endpoint device */
+
+      i8sak->ep.mode = IEEE802154_ADDRMODE_SHORT;
+
+      for (i = 0; i < IEEE802154_EADDRSIZE; i++)
+      {
+        i8sak->ep.eaddr[i] =
+          (uint8_t)((CONFIG_IEEE802154_I8SAK_DEV_EADDR >> (i*8)) & 0xFF);
+      }
+
+      for (i = 0; i < IEEE802154_SADDRSIZE; i++)
+      {
+        i8sak->ep.saddr[i] =
+          (uint8_t)((CONFIG_IEEE802154_I8SAK_DEV_SADDR >> (i*8)) & 0xFF);
+      }
+
+      for (i = 0; i < IEEE802154_PANIDSIZE; i++)
+      {
+        i8sak->ep.panid[i] =
+          (uint8_t)((CONFIG_IEEE802154_I8SAK_PANID >> (i*8)) & 0xFF);
+      }
+    }
+
+  /* Set EADDR and SADDR */
+
+  ieee802154_seteaddr(fd, i8sak->addr.eaddr);
+  ieee802154_setsaddr(fd, i8sak->addr.saddr);
+
+  /* Tell the MAC to start acting as a coordinator */
+
+  printf("i8sak: starting PAN\n");
+
+  IEEE802154_PANIDCOPY(startreq.panid, i8sak->addr.panid);
+  startreq.chnum = i8sak->chnum;
+  startreq.chpage = i8sak->chpage;
+  startreq.beaconorder = 15;
+  startreq.pancoord = true;
+  startreq.coordrealign = false;
+
+  ieee802154_start_req(fd, &startreq);
+
+  close(fd);
+}
\ No newline at end of file
diff --git a/wireless/ieee802154/i8sak/i8sak_tx.c b/wireless/ieee802154/i8sak/i8sak_tx.c
new file mode 100644
index 000000000..56fc83454
--- /dev/null
+++ b/wireless/ieee802154/i8sak/i8sak_tx.c
@@ -0,0 +1,238 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/i8sak_tx.c
+ * IEEE 802.15.4 Swiss Army Knife
+ *
+ *   Copyright (C) 2014-2015, 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2014-2015 Sebastien Lorquet. All rights reserved.
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *   Author: Gregory Nuttx <gnutt@nuttx.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+ /****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <nuttx/fs/ioctl.h>
+
+#include "i8sak.h"
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static void tx_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg);
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : i8_tx_cmd
+ *
+ * Description :
+ *   Transmit a data frame.
+ ****************************************************************************/
+
+void i8sak_tx_cmd(FAR struct i8sak_s *i8sak, int argc, FAR char *argv[])
+{
+  enum ieee802154_devmode_e devmode;
+  struct wpanlistener_eventfilter_s eventfilter;
+  bool sendasdev = false;
+  bool sendmax = false;
+  int argind;
+  int option;
+  int fd;
+  int ret;
+
+  ret = OK;
+  argind = 1;
+  while ((option = getopt(argc, argv, ":hdm")) != ERROR)
+    {
+      switch (option)
+        {
+          case 'h':
+            fprintf(stderr, "Transmits packet to endpoint\n"
+                    "Usage: %s [-h|d] [<hex-payload>]\n"
+                    "    -h = this help menu\n"
+                    "    -d = send as device instead of coord\n"
+                    "    -m = send the largest frame possible"
+                    , argv[0]);
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            return;
+
+          case 'd':
+            sendasdev = true;
+            argind++;
+            break;
+          
+          case 'm':
+            sendmax = true;
+            argind++;
+            break;
+
+          case ':':
+            fprintf(stderr, "ERROR: missing argument\n");
+
+            /* Must manually reset optind if we are going to exit early */
+
+            optind = -1;
+            i8sak_cmd_error(i8sak); /* This exits for us */
+
+          case '?':
+            fprintf(stderr, "ERROR: unknown argument\n");
+            ret = ERROR;
+            break;
+        }
+    }
+
+  if (ret != OK)
+    {
+      i8sak_cmd_error(i8sak);
+    }
+
+  if (argc == argind + 1)
+    {
+      i8sak->payload_len = i8sak_str2payload(argv[1], &i8sak->payload[0]);
+    }
+  
+  if (sendmax)
+    {
+      i8sak->payload_len = IEEE802154_MAX_SAFE_MAC_PAYLOAD_SIZE;
+    }
+
+  fd = open(i8sak->devname, O_RDWR);
+  if (fd < 0)
+    {
+      printf("i8sak: cannot open %s, errno=%d\n", i8sak->devname, errno);
+      i8sak_cmd_error(i8sak);
+    }
+
+  /* Check if transaction should be indirect or not */
+
+  ieee802154_getdevmode(fd, &devmode);
+
+  if (!sendasdev)
+    {
+      /* If we are acting as an endpoint, send as normal CSMA (non-indirect)
+       * If we are a coordinator or PAN coordinator, send as indirect.
+       */
+
+      if (devmode == IEEE802154_DEVMODE_ENDPOINT)
+        {
+          i8sak->indirect = false;
+        }
+      else
+        {
+          i8sak->indirect = true;
+        }
+    }
+  else
+    {
+      /* We cannot send a frame as direct if we are the PAN coordinator. Maybe
+       * this should be the hook for sending payload in beacon? But for now,
+       * let's just thow an error.
+       */
+
+      if (devmode == IEEE802154_DEVMODE_PANCOORD)
+        {
+          fprintf(stderr, "ERROR: invalid option\n");
+          close(fd);
+          i8sak_cmd_error(i8sak);
+        }
+
+      i8sak->indirect = false;
+    }
+
+  if (i8sak->indirect)
+    {
+      printf("i8sak: queuing indirect tx\n");
+    }
+
+  /* Register new oneshot callback for receiving the association notifications */
+
+  memset(&eventfilter, 0, sizeof(struct wpanlistener_eventfilter_s));
+  eventfilter.confevents.data = true;
+
+  wpanlistener_add_eventreceiver(&i8sak->wpanlistener, tx_eventcb,
+                                 &eventfilter, (FAR void *)i8sak, true);
+
+
+  ret = i8sak_tx(i8sak,fd);
+  if (ret < 0)
+    {
+      fprintf(stderr, "ERROR: Failed to transmit packet\n");
+      close(fd);
+      i8sak_cmd_error(i8sak);
+    }
+
+  close(fd);
+}
+
+static void tx_eventcb(FAR struct ieee802154_notif_s *notif, FAR void *arg)
+{
+  FAR struct i8sak_s *i8sak = (FAR struct i8sak_s *)arg;
+
+  if (notif->u.dataconf.status == IEEE802154_STATUS_SUCCESS)
+    {
+      if (i8sak->indirect)
+        {
+          printf("i8sak: tx frame extracted\n");
+        }
+      else
+        {
+          printf("i8sak: frame tx success\n");
+        }
+    }
+  else
+    {
+      printf("i8sak: frame failed to send: %s\n",
+             IEEE802154_STATUS_STRING[notif->u.dataconf.status]);
+    }
+
+  sem_post(&i8sak->sigsem);
+}
\ No newline at end of file
diff --git a/wireless/ieee802154/i8sak/wpanlistener.c b/wireless/ieee802154/i8sak/wpanlistener.c
new file mode 100644
index 000000000..4fdd344ba
--- /dev/null
+++ b/wireless/ieee802154/i8sak/wpanlistener.c
@@ -0,0 +1,836 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/wpanlistener.c
+ *
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#include "wpanlistener.h"
+
+/****************************************************************************
+ * Private Function Prototypes
+ ****************************************************************************/
+
+static pthread_addr_t wpanlistener_framethread(pthread_addr_t arg);
+static pthread_addr_t wpanlistener_eventthread(pthread_addr_t arg);
+
+/***************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wpanlistener_setup
+ *
+ * Description:
+ *   Initializes the internal struct
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct to initialize
+ *   fd     - file descriptor to access device
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_setup(FAR struct wpanlistener_s *handle, int fd)
+{
+  int i;
+
+  /* Initialize the frame receiver allocation pool */
+
+  sq_init(&handle->framereceivers);
+  sq_init(&handle->framereceivers_free);
+  for (i = 0; i < CONFIG_WPANLISTENER_NFRAMERECEIVERS; i++)
+    {
+      sq_addlast((FAR sq_entry_t *)&handle->framereceiver_pool[i], &handle->framereceivers_free);
+    }
+
+  /* Initialize the frame receiver allocation pool */
+
+  sq_init(&handle->eventreceivers);
+  sq_init(&handle->eventreceivers_free);
+  for (i = 0; i < CONFIG_WPANLISTENER_NEVENTRECEIVERS; i++)
+    {
+      sq_addlast((FAR sq_entry_t *)&handle->eventreceiver_pool[i], &handle->eventreceivers_free);
+    }
+
+  sem_init(&handle->exclsem, 0, 1);
+
+  handle->is_setup = true;
+  handle->fd = fd;
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wpanlistener_start
+ *
+ * Description:
+ *   Starts internal threads to listen for frames and events.
+ *
+ * Parameters:
+ *   handle  - handle to the wpan listener struct
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_start(FAR struct wpanlistener_s *handle)
+{
+  int ret;
+
+  handle->threadrun = true;
+
+  ret = pthread_create(&handle->frame_threadid, NULL, wpanlistener_framethread,
+                       (void *)handle);
+  if (ret != 0)
+    {
+      fprintf(stderr, "wpanlistener: failed to start frame thread: %d\n", ret);
+      return ret;
+    }
+
+  ret = pthread_create(&handle->event_threadid, NULL, wpanlistener_eventthread,
+                       (void *)handle);
+  if (ret != 0)
+    {
+      fprintf(stderr, "wpanlistener: failed to start event thread: %d\n", ret);
+      return ret;
+    }
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wpanlistener_stop
+ *
+ * Description:
+ *   Stops internal threads.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_stop(FAR struct wpanlistener_s *handle)
+{
+  return -ENOTTY;
+}
+
+/****************************************************************************
+ * Name: wpanlistener_add_framereceiver
+ *
+ * Description:
+ *   Add a frame receiver.  A frame receiver consists of filter settings for
+ *   determining which frames should be passed to the callback, and the corresponding
+ *   callback.
+ *
+ * Parameters:
+ *   handle   - handle to the wpan listener struct
+ *   callback - callback to be called on reception of frame matching filter
+ *                 settings
+ *   filter   - struct containing settings for filtering frames
+ *   arg      - user specified argument to send to the callback
+ *   oneshot  - whether the receiver is automatically unregistered after the
+ *              first notification
+ *
+ * Returned Value:
+ *   OK if successful; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_add_framereceiver(FAR struct wpanlistener_s *handle,
+                            wpanlistener_framecallback_t cb,
+                            FAR struct wpanlistener_framefilter_s *filter,
+                            FAR void * arg, bool oneshot)
+{
+  FAR struct wpanlistener_framereceiver_s *receiver;
+  int ret;
+
+  /* Get exclusive access to the struct */
+
+  ret = sem_wait(&handle->exclsem);
+  if (ret != OK)
+    {
+      fprintf(stderr, "wpanlistener: failed to add receiver: %d\n", ret);
+      return ret;
+    }
+
+  /* Allocate a receiver struct from the static pool */
+
+  receiver = (FAR struct wpanlistener_framereceiver_s *)sq_remfirst(
+                                                    &handle->framereceivers_free);
+  if (receiver == NULL)
+    {
+      fprintf(stderr, "wpanlistener: failed to add receiver: %d\n", ENOMEM);
+      sem_post(&handle->exclsem);
+      return -ENOMEM;
+    }
+
+  receiver->cb = cb;
+  memcpy(&receiver->filter, filter, sizeof(struct wpanlistener_framefilter_s));
+  receiver->arg = arg;
+  receiver->oneshot = oneshot;
+
+  /* Link the receiver into the list */
+
+  sq_addlast((FAR sq_entry_t *)receiver, &handle->framereceivers);
+
+  sem_post(&handle->exclsem);
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wpanlistener_add_eventreceiver
+ *
+ * Description:
+ *   Add an event receiver.  An event receiver consists of a callback and flags
+ *   for which events should be sent to the callback.
+ *
+ * Parameters:
+ *   handle   - handle to the wpan listener struct
+ *   cb       - callback to be called on reception of notification event from
+ *              MAC layer that matches one of the masked events
+ *   filter   - struct containing event mask bits to indicate whether event
+ *              type should trigger callback
+ *   arg      - user specified argument to send to the callback
+ *   oneshot  - whether the receiver is automatically unregistered after the
+ *              first notification
+ *
+ * Returned Value:
+ *   OK if successful; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_add_eventreceiver(FAR struct wpanlistener_s *handle,
+                            wpanlistener_eventcallback_t cb,
+                            FAR struct wpanlistener_eventfilter_s *filter,
+                            FAR void * arg, bool oneshot)
+{
+  FAR struct wpanlistener_eventreceiver_s *receiver;
+  int ret;
+
+  /* Get exclusive access to the struct */
+
+  ret = sem_wait(&handle->exclsem);
+  if (ret != OK)
+    {
+      fprintf(stderr, "wpanlistener: failed to add receiver: %d\n", ret);
+      return ret;
+    }
+
+  /* Allocate a receiver struct from the static pool */
+
+  receiver = (FAR struct wpanlistener_eventreceiver_s *)sq_remfirst(
+                                                    &handle->eventreceivers_free);
+  if (receiver == NULL)
+    {
+      fprintf(stderr, "wpanlistener: failed to add receiver: %d\n", ENOMEM);
+      sem_post(&handle->exclsem);
+      return -ENOMEM;
+    }
+
+  receiver->cb = cb;
+  memcpy(&receiver->filter, filter, sizeof(struct wpanlistener_eventfilter_s));
+  receiver->arg = arg;
+  receiver->oneshot = oneshot;
+
+  /* Link the receiver into the list */
+
+  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+  sem_post(&handle->exclsem);
+
+  return OK;
+}
+
+/****************************************************************************
+ * Name: wpanlistener_remove_framereceiver
+ *
+ * Description:
+ *   Removes a frame receiver.  Listener will no longer call callback. This
+ *   function finds the first frame receiver with the provided callback.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *   cb     - callback function to search for.
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_remove_framereceiver(FAR struct wpanlistener_s *handle,
+                                      wpanlistener_framecallback_t cb)
+{
+  FAR struct wpanlistener_framereceiver_s *receiver;
+  int ret;
+
+  /* Get exclusive access to the struct */
+
+  ret = sem_wait(&handle->exclsem);
+  if (ret != OK)
+    {
+      fprintf(stderr, "wpanlistener: failed to remove receiver: %d\n", ret);
+      return ret;
+    }
+
+  /* Search through frame receivers until either we match the callback, or
+   * there is no more receivers to check.
+   */
+
+  receiver = (FAR struct wpanlistener_framereceiver_s *)sq_peek(
+                &handle->framereceivers);
+
+  while (receiver != NULL)
+    {
+      /* Check if callback matches */
+
+      if (receiver->cb == cb)
+        {
+          /* Unlink the receiver from the list */
+
+          sq_rem((FAR sq_entry_t *)receiver, &handle->framereceivers);
+
+          /* Link the receiver back into the free list */
+
+          sq_addlast((FAR sq_entry_t *)receiver, &handle->framereceivers_free);
+
+          sem_post(&handle->exclsem);
+
+          return OK;
+        }
+
+      receiver = (FAR struct wpanlistener_framereceiver_s *)sq_next(
+                    (FAR sq_entry_t *)receiver);
+    }
+
+  sem_post(&handle->exclsem);
+  fprintf(stderr, "wpanlistener: failed to remove receiver");
+  return ERROR;
+}
+
+/****************************************************************************
+ * Name: wpanlistener_remove_eventreceiver
+ *
+ * Description:
+ *   Removes a event receiver.  Listener will no longer call callback. This
+ *   function finds the first event receiver with the provided callback.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *   cb     - callback function to search for.
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_remove_eventreceiver(FAR struct wpanlistener_s *handle,
+                                      wpanlistener_eventcallback_t cb)
+{
+  FAR struct wpanlistener_eventreceiver_s *receiver;
+  int ret;
+
+  /* Get exclusive access to the struct */
+
+  ret = sem_wait(&handle->exclsem);
+  if (ret != OK)
+    {
+      fprintf(stderr, "wpanlistener: failed to remove receiver: %d\n", ret);
+      return ret;
+    }
+
+  /* Search through frame receivers until either we match the callback, or
+   * there is no more receivers to check.
+   */
+
+  receiver = (FAR struct wpanlistener_eventreceiver_s *)sq_peek(
+                &handle->eventreceivers);
+
+  while (receiver != NULL)
+    {
+      /* Check if callback matches */
+
+      if (receiver->cb == cb)
+        {
+          /* Unlink the receiver from the list */
+
+          sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+          /* Link the receiver back into the free list */
+
+          sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+
+          sem_post(&handle->exclsem);
+
+          return OK;
+        }
+
+      receiver = (FAR struct wpanlistener_eventreceiver_s *)sq_next(
+                    (FAR sq_entry_t *)receiver);
+    }
+
+  sem_post(&handle->exclsem);
+  fprintf(stderr, "wpanlistener: failed to remove receiver");
+  return ERROR;
+}
+
+/****************************************************************************
+ * handleate Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name : wpanlistener_framethread
+ *
+ * Description :
+ *   Listen for frames received at the MAC layer
+ ****************************************************************************/
+
+static pthread_addr_t wpanlistener_framethread(pthread_addr_t arg)
+{
+  FAR struct wpanlistener_s *handle = (FAR struct wpanlistener_s *)arg;
+  FAR struct wpanlistener_framereceiver_s *receiver;
+  struct mac802154dev_rxframe_s frame;
+  int ret;
+  int i;
+
+  while (handle->threadrun)
+    {
+      ret = read(handle->fd, &frame, sizeof(struct mac802154dev_rxframe_s));
+      if (ret != OK)
+        {
+          return NULL;
+        }
+
+      /* Get exclusive access to the struct */
+
+      ret = sem_wait(&handle->exclsem);
+      if (ret != OK)
+        {
+          return NULL;
+        }
+
+      printf("Frame Received:\n");
+      for (i = 0; i < frame.length; i++)
+        {
+          printf("%02X", frame.payload[i]);
+        }
+
+      printf(" \n");
+      fflush(stdout);
+
+      /* Loop through frame receivers and call callbacks for those receivers
+       * whose filter matches this frame
+       */
+
+      receiver = (FAR struct wpanlistener_framereceiver_s *)sq_peek(
+                    &handle->framereceivers);
+
+      while (receiver != NULL)
+        {
+          /* TODO: When filtering options are figured out. Actually filter packets
+           * here. For now, all frames get passed to all receivers.
+           */
+
+          receiver->cb(&frame, receiver->arg);
+
+          receiver = (FAR struct wpanlistener_framereceiver_s *)sq_next(
+                        (FAR sq_entry_t *)receiver);
+
+          /* Check if the receiver was a one-shot receiver, then throw it out
+           * if it is
+           */
+
+          if (receiver->oneshot)
+            {
+              /* Unlink the receiver from the list */
+
+              sq_rem((FAR sq_entry_t *)receiver, &handle->framereceivers);
+
+              /* Link the receiver back into the free list */
+
+              sq_addlast((FAR sq_entry_t *)receiver, &handle->framereceivers_free);
+            }
+        }
+      sem_post(&handle->exclsem);
+    }
+
+  return NULL;
+}
+
+/****************************************************************************
+ * Name : wpanlistener_eventthread
+ *
+ * Description :
+ *   Listen for events from the MAC layer
+ ****************************************************************************/
+
+static pthread_addr_t wpanlistener_eventthread(pthread_addr_t arg)
+{
+  FAR struct wpanlistener_s *handle = (FAR struct wpanlistener_s *)arg;
+  FAR struct wpanlistener_eventreceiver_s *receiver;
+  struct ieee802154_notif_s notif;
+  int ret;
+
+  while (handle->threadrun)
+    {
+      ret = ioctl(handle->fd, MAC802154IOC_GET_EVENT, (unsigned long)((uintptr_t)&notif));
+      if (ret != OK)
+        {
+          return NULL;
+        }
+
+      /* Get exclusive access to the struct */
+
+      ret = sem_wait(&handle->exclsem);
+      if (ret != OK)
+        {
+          return NULL;
+        }
+
+      /* Loop through event receivers and call callbacks for those receivers
+       * listening for this event type.
+       */
+
+      receiver = (FAR struct wpanlistener_eventreceiver_s *)sq_peek(
+                    &handle->eventreceivers);
+
+      while (receiver != NULL)
+        {
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_DATA &&
+              receiver->filter.confevents.data)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_ASSOC &&
+              receiver->filter.confevents.assoc)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_DISASSOC &&
+              receiver->filter.confevents.disassoc)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_GTS &&
+              receiver->filter.confevents.gts)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_RESET &&
+              receiver->filter.confevents.reset)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_RXENABLE &&
+              receiver->filter.confevents.rxenable)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_SCAN &&
+              receiver->filter.confevents.scan)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_START &&
+              receiver->filter.confevents.start)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_CONF_POLL &&
+              receiver->filter.confevents.poll)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_ASSOC &&
+              receiver->filter.indevents.assoc)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_DISASSOC &&
+              receiver->filter.indevents.disassoc)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_BEACONNOTIFY &&
+              receiver->filter.indevents.beaconnotify)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_GTS &&
+              receiver->filter.indevents.gts)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_ORPHAN &&
+              receiver->filter.indevents.orphan)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_COMMSTATUS &&
+              receiver->filter.indevents.commstatus)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          if (notif.notiftype == IEEE802154_NOTIFY_IND_SYNCLOSS &&
+              receiver->filter.indevents.syncloss)
+            {
+              receiver->cb(&notif, receiver->arg);
+
+              if (receiver->oneshot)
+                {
+                  /* Unlink the receiver from the list */
+
+                  sq_rem((FAR sq_entry_t *)receiver, &handle->eventreceivers);
+
+                  /* Link the receiver back into the free list */
+
+                  sq_addlast((FAR sq_entry_t *)receiver, &handle->eventreceivers_free);
+                }
+            }
+
+          receiver = (FAR struct wpanlistener_eventreceiver_s *)sq_next(
+                        (FAR sq_entry_t *)receiver);
+        }
+      sem_post(&handle->exclsem);
+    }
+
+  return NULL;
+}
diff --git a/wireless/ieee802154/i8sak/wpanlistener.h b/wireless/ieee802154/i8sak/wpanlistener.h
new file mode 100644
index 000000000..5d1ee14aa
--- /dev/null
+++ b/wireless/ieee802154/i8sak/wpanlistener.h
@@ -0,0 +1,311 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/i8sak/wpanlistener.h
+ *
+ *   Copyright (C) 2017 Verge Inc. All rights reserved.
+ *   Author: Anthony Merlino <anthony@vergeaero.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+#ifndef __APPS_WIRELESS_IEEE802154_I8SAK_WPANLISTENER_H
+#define __APPS_WIRELESS_IEEE802154_I8SAK_WPANLISTENER_H
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+#include <semaphore.h>
+
+#include <nuttx/wireless/ieee802154/ieee802154_ioctl.h>
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+/* Configuration ************************************************************/
+
+#if !defined(CONFIG_WPANLISTENER_NFRAMERECEIVERS) || CONFIG_WPANLISTENER_NFRAMERECEIVERS <= 0
+#  undef CONFIG_WPANLISTENER_NFRAMERECEIVERS
+#  define CONFIG_WPANLISTENER_NFRAMERECEIVERS 3
+#endif
+
+#if !defined(CONFIG_WPANLISTENER_NEVENTRECEIVERS) || CONFIG_WPANLISTENER_NEVENTRECEIVERS <= 0
+#  undef CONFIG_WPANLISTENER_NEVENTRECEIVERS
+#  define CONFIG_WPANLISTENER_NEVENTRECEIVERS 3
+#endif
+
+/****************************************************************************
+ * Public Types
+ ****************************************************************************/
+
+typedef void (*wpanlistener_framecallback_t)
+               (FAR struct mac802154dev_rxframe_s *frame, FAR void *arg);
+
+typedef void (*wpanlistener_eventcallback_t) (FAR struct ieee802154_notif_s *notif,
+                                              FAR void *arg);
+
+struct wpanlistener_framefilter_s
+{
+  /* Frame filtering settings here */
+  bool acceptall;
+
+};
+
+struct wpanlistener_eventfilter_s
+{
+  struct
+  {
+    uint32_t assoc        : 1;
+    uint32_t disassoc     : 1;
+    uint32_t beaconnotify : 1;
+    uint32_t commstatus   : 1;
+    uint32_t gts          : 1;
+    uint32_t orphan       : 1;
+    uint32_t syncloss     : 1;
+  } indevents;
+
+  struct {
+    uint32_t data         : 1;
+    uint32_t assoc        : 1;
+    uint32_t disassoc     : 1;
+    uint32_t gts          : 1;
+    uint32_t commstatus   : 1;
+    uint32_t reset        : 1;
+    uint32_t rxenable     : 1;
+    uint32_t scan         : 1;
+    uint32_t start        : 1;
+    uint32_t poll         : 1;
+  } confevents;
+};
+
+struct wpanlistener_framereceiver_s
+{
+  FAR struct wpanlistener_framereceiver_s *flink;
+  wpanlistener_framecallback_t cb;
+  struct wpanlistener_framefilter_s filter;
+  FAR void *arg;
+  bool oneshot;
+};
+
+struct wpanlistener_eventreceiver_s
+{
+  FAR struct wpanlistener_eventreceiver_s *flink;
+  wpanlistener_eventcallback_t cb;
+  struct wpanlistener_eventfilter_s filter;
+  FAR void *arg;
+  bool oneshot;
+};
+
+struct wpanlistener_s
+{
+  sem_t exclsem;
+
+  int fd;
+
+  bool threadrun  : 1;
+  bool is_setup   : 1;
+  bool is_started : 1;
+
+  pthread_t frame_threadid;
+  pthread_t event_threadid;
+
+  sq_queue_t eventreceivers;
+  sq_queue_t framereceivers;
+
+  sq_queue_t eventreceivers_free;
+  sq_queue_t framereceivers_free;
+
+  struct wpanlistener_framereceiver_s
+            framereceiver_pool[CONFIG_WPANLISTENER_NFRAMERECEIVERS];
+
+  struct wpanlistener_eventreceiver_s
+            eventreceiver_pool[CONFIG_WPANLISTENER_NEVENTRECEIVERS];
+};
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: wpanlistener_setup
+ *
+ * Description:
+ *   Initializes the internal struct
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct to initialize
+ *   fd     - file descriptor to access device
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_setup(FAR struct wpanlistener_s *handle, int fd);
+
+/****************************************************************************
+ * Name: wpanlistener_start
+ *
+ * Description:
+ *   Starts internal threads to listen for frames and events.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_start(FAR struct wpanlistener_s *handle);
+
+/****************************************************************************
+ * Name: wpanlistener_stop
+ *
+ * Description:
+ *   Stops internal threads.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_stop(FAR struct wpanlistener_s *handle);
+
+/****************************************************************************
+ * Name: wpanlistener_add_framereceiver
+ *
+ * Description:
+ *   Add a frame receiver.  A frame receiver consists of filter settings for
+ *   determining which frames should be passed to the callback, and the corresponding
+ *   callback.
+ *
+ * Parameters:
+ *   handle   - handle to the wpan listener struct
+ *   callback - callback to be called on reception of frame matching filter
+ *                 settings
+ *   filter   - struct containing settings for filtering frames
+ *   arg      - user specified argument to send to the callback
+ *   oneshot  - whether the receiver is automatically unregistered after the
+ *              first notification
+ *
+ * Returned Value:
+ *   OK if successful; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_add_framereceiver(FAR struct wpanlistener_s *handle,
+                            wpanlistener_framecallback_t cb,
+                            FAR struct wpanlistener_framefilter_s *filter,
+                            FAR void * arg, bool oneshot);
+
+/****************************************************************************
+ * Name: wpanlistener_add_eventreceiver
+ *
+ * Description:
+ *   Add an event receiver.  An event receiver consists of a callback and flags
+ *   for which events should be sent to the callback.
+ *
+ * Parameters:
+ *   handle   - handle to the wpan listener struct
+ *   cb       - callback to be called on reception of notification event from
+ *              MAC layer that matches one of the masked events
+ *   filter   - struct containing event mask bits to indicate whether event
+ *              type should trigger callback
+ *   arg      - user specified argument to send to the callback
+ *   oneshot  - whether the receiver is automatically unregistered after the
+ *              first notification
+ *
+ * Returned Value:
+ *   OK if successful; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_add_eventreceiver(FAR struct wpanlistener_s *handle,
+                            wpanlistener_eventcallback_t cb,
+                            FAR struct wpanlistener_eventfilter_s *filter,
+                            FAR void * arg, bool oneshot);
+
+/****************************************************************************
+ * Name: wpanlistener_remove_framereceiver
+ *
+ * Description:
+ *   Removes a frame receiver.  Listener will no longer call callback. This
+ *   function finds the first frame receiver with the provided callback.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *   cb     - callback function to search for.
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_remove_framereceiver(FAR struct wpanlistener_s *handle,
+                                      wpanlistener_framecallback_t cb);
+
+/****************************************************************************
+ * Name: wpanlistener_remove_eventreceiver
+ *
+ * Description:
+ *   Removes a event receiver.  Listener will no longer call callback. This
+ *   function finds the first event receiver with the provided callback.
+ *
+ * Parameters:
+ *   handle - handle to the wpan listener struct
+ *   cb     - callback function to search for.
+ *
+ * Returned Value:
+ *   OK on success; a negated errno on failure
+ *
+ * Assumptions:
+ *
+ ****************************************************************************/
+
+int wpanlistener_remove_eventreceiver(FAR struct wpanlistener_s *handle,
+                                      wpanlistener_eventcallback_t cb);
+
+#endif /* __APPS_WIRELESS_IEEE802154_I8SAK_WPANLISTENER_H */
diff --git a/wireless/ieee802154/libmac/Makefile b/wireless/ieee802154/libmac/Makefile
index 290100d09..fe4022108 100644
--- a/wireless/ieee802154/libmac/Makefile
+++ b/wireless/ieee802154/libmac/Makefile
@@ -54,6 +54,7 @@ CSRCS += ieee802154_seteaddr.c ieee802154_geteaddr.c
 CSRCS += ieee802154_setpromisc.c ieee802154_getpromisc.c 
 CSRCS += ieee802154_setrxonidle.c ieee802154_getrxonidle.c 
 CSRCS += ieee802154_settxpwr.c ieee802154_gettxpwr.c 
+CSRCS += ieee802154_getdevmode.c 
 
 ifeq ($(CONFIG_NET_6LOWPAN),y) 
 # Add Get/Set Attribute helpers
diff --git a/wireless/ieee802154/libmac/ieee802154_assocresp.c b/wireless/ieee802154/libmac/ieee802154_assocresp.c
index c98c34274..a6fb90098 100644
--- a/wireless/ieee802154/libmac/ieee802154_assocresp.c
+++ b/wireless/ieee802154/libmac/ieee802154_assocresp.c
@@ -56,10 +56,9 @@
 
 int ieee802154_assoc_resp(int fd, FAR struct ieee802154_assoc_resp_s *resp)
 {
-  union ieee802154_macarg_u arg;
   int ret;
 
-  ret = ioctl(fd, MAC802154IOC_MLME_ASSOC_RESPONSE, (unsigned long)((uintptr_t)&arg));
+  ret = ioctl(fd, MAC802154IOC_MLME_ASSOC_RESPONSE, (unsigned long)((uintptr_t)resp));
   if (ret < 0)
     {
       ret = -errno;
@@ -67,6 +66,5 @@ int ieee802154_assoc_resp(int fd, FAR struct ieee802154_assoc_resp_s *resp)
       return ret;
     }
 
-  memcpy(resp, &arg.assocresp, sizeof(struct ieee802154_assoc_resp_s));
   return OK;
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_enableevents.c b/wireless/ieee802154/libmac/ieee802154_enableevents.c
index 9ce04725f..ea685610d 100644
--- a/wireless/ieee802154/libmac/ieee802154_enableevents.c
+++ b/wireless/ieee802154/libmac/ieee802154_enableevents.c
@@ -54,7 +54,7 @@
  * Public Functions
  ****************************************************************************/
 
-int ieee802154_enableevents(int fd, bool enable) 
+int ieee802154_enableevents(int fd, bool enable)
 {
   int ret;
 
diff --git a/wireless/ieee802154/libmac/ieee802154_getchan.c b/wireless/ieee802154/libmac/ieee802154_getchan.c
index 622fc9655..c988e373b 100644
--- a/wireless/ieee802154/libmac/ieee802154_getchan.c
+++ b/wireless/ieee802154/libmac/ieee802154_getchan.c
@@ -58,7 +58,7 @@ int ieee802154_getchan(int fd, FAR uint8_t *chan)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_PHY_CURRENT_CHANNEL;
+  req.attr = IEEE802154_ATTR_PHY_CURRENT_CHANNEL;
   ret = ieee802154_get_req(fd, &req);
 
   *chan = req.attrval.phy.channel;
diff --git a/wireless/ieee802154/libmac/ieee802154_getdevmode.c b/wireless/ieee802154/libmac/ieee802154_getdevmode.c
new file mode 100644
index 000000000..1f5e8a6f2
--- /dev/null
+++ b/wireless/ieee802154/libmac/ieee802154_getdevmode.c
@@ -0,0 +1,67 @@
+/****************************************************************************
+ * apps/wireless/ieee802154/libmac/ieee802154_getdevmode.c
+ *
+ *   Copyright (C) 2017 Gregory Nutt. All rights reserved.
+ *   Copyright (C) 2015 Sebastien Lorquet. All rights reserved.
+ *   Author: Sebastien Lorquet <sebastien@lorquet.fr>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ * 3. Neither the name NuttX nor the names of its contributors may be
+ *    used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <sys/ioctl.h>
+#include <stdint.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include <nuttx/wireless/ieee802154/ieee802154_mac.h>
+
+#include "wireless/ieee802154.h"
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+int ieee802154_getdevmode(int fd, FAR enum ieee802154_devmode_e *devmode)
+{
+  struct ieee802154_get_req_s req;
+  int ret;
+
+  req.attr = IEEE802154_ATTR_MAC_DEVMODE;
+  ret = ieee802154_get_req(fd, &req);
+
+  *devmode = req.attrval.mac.devmode;
+
+  return ret;
+}
diff --git a/wireless/ieee802154/libmac/ieee802154_geteaddr.c b/wireless/ieee802154/libmac/ieee802154_geteaddr.c
index 9ee011e1c..773c7ffe8 100644
--- a/wireless/ieee802154/libmac/ieee802154_geteaddr.c
+++ b/wireless/ieee802154/libmac/ieee802154_geteaddr.c
@@ -58,10 +58,10 @@ int ieee802154_geteaddr(int fd, FAR uint8_t *eaddr)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_EXTENDED_ADDR;
+  req.attr = IEEE802154_ATTR_MAC_EXTENDED_ADDR;
   ret = ieee802154_get_req(fd, &req);
 
-  memcpy(eaddr, &req.attrval.mac.eaddr[0], 8);
+  IEEE802154_EADDRCOPY(eaddr, req.attrval.mac.eaddr);
 
   return ret;
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_getpanid.c b/wireless/ieee802154/libmac/ieee802154_getpanid.c
index 7a7e2d01b..b214f3852 100644
--- a/wireless/ieee802154/libmac/ieee802154_getpanid.c
+++ b/wireless/ieee802154/libmac/ieee802154_getpanid.c
@@ -42,6 +42,7 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 
 #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
@@ -52,15 +53,14 @@
  * Public Functions
  ****************************************************************************/
 
-int ieee802154_getpanid(int fd, FAR uint16_t *panid)
+int ieee802154_getpanid(int fd, FAR uint8_t *panid)
 {
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PANID;
+  req.attr = IEEE802154_ATTR_MAC_PANID;
   ret = ieee802154_get_req(fd, &req);
 
-  *panid = req.attrval.mac.panid;
-
+  IEEE802154_PANIDCOPY(panid, req.attrval.mac.panid);
   return ret;
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_getpromisc.c b/wireless/ieee802154/libmac/ieee802154_getpromisc.c
index 34599c7f1..cfca87ad4 100644
--- a/wireless/ieee802154/libmac/ieee802154_getpromisc.c
+++ b/wireless/ieee802154/libmac/ieee802154_getpromisc.c
@@ -57,7 +57,7 @@ int ieee802154_getpromisc(int fd, FAR bool *promisc)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PROMISCUOUS_MODE;
+  req.attr = IEEE802154_ATTR_MAC_PROMISCUOUS_MODE;
   ret = ieee802154_get_req(fd, &req);
 
   *promisc = req.attrval.mac.promisc_mode;
diff --git a/wireless/ieee802154/libmac/ieee802154_getrxonidle.c b/wireless/ieee802154/libmac/ieee802154_getrxonidle.c
index 7b57d09e5..b00510735 100644
--- a/wireless/ieee802154/libmac/ieee802154_getrxonidle.c
+++ b/wireless/ieee802154/libmac/ieee802154_getrxonidle.c
@@ -58,7 +58,7 @@ int ieee802154_getrxonidle(int fd, FAR bool *rxonidle)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE;
+  req.attr = IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE;
   ret = ieee802154_get_req(fd, &req);
 
   *rxonidle = req.attrval.mac.rxonidle;
diff --git a/wireless/ieee802154/libmac/ieee802154_getsaddr.c b/wireless/ieee802154/libmac/ieee802154_getsaddr.c
index 71b297e91..cd20cc126 100644
--- a/wireless/ieee802154/libmac/ieee802154_getsaddr.c
+++ b/wireless/ieee802154/libmac/ieee802154_getsaddr.c
@@ -42,6 +42,7 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 
 #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
@@ -52,15 +53,14 @@
  * Public Functions
  ****************************************************************************/
 
-int ieee802154_getsaddr(int fd, FAR uint16_t *saddr)
+int ieee802154_getsaddr(int fd, FAR uint8_t *saddr)
 {
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_SHORT_ADDRESS;
+  req.attr = IEEE802154_ATTR_MAC_SHORT_ADDRESS;
   ret = ieee802154_get_req(fd, &req);
 
-  *saddr = req.attrval.mac.saddr;
-
+  IEEE802154_SADDRCOPY(saddr, req.attrval.mac.saddr);
   return ret;
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_gettxpwr.c b/wireless/ieee802154/libmac/ieee802154_gettxpwr.c
index 634b8dd14..bfa7e50b0 100644
--- a/wireless/ieee802154/libmac/ieee802154_gettxpwr.c
+++ b/wireless/ieee802154/libmac/ieee802154_gettxpwr.c
@@ -57,7 +57,7 @@ int ieee802154_gettxpwr(int fd, FAR int32_t *txpwr)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_PHY_TX_POWER;
+  req.attr = IEEE802154_ATTR_PHY_TX_POWER;
   ret = ieee802154_get_req(fd, &req);
 
   *txpwr = req.attrval.phy.txpwr;
diff --git a/wireless/ieee802154/libmac/ieee802154_setchan.c b/wireless/ieee802154/libmac/ieee802154_setchan.c
index a74eae895..bac4bc6f7 100644
--- a/wireless/ieee802154/libmac/ieee802154_setchan.c
+++ b/wireless/ieee802154/libmac/ieee802154_setchan.c
@@ -57,7 +57,7 @@ int ieee802154_setchan(int fd, uint8_t chan)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_PHY_CURRENT_CHANNEL;
+  req.attr = IEEE802154_ATTR_PHY_CURRENT_CHANNEL;
   req.attrval.phy.channel = chan;
 
   return ieee802154_set_req(fd, &req);
diff --git a/wireless/ieee802154/libmac/ieee802154_seteaddr.c b/wireless/ieee802154/libmac/ieee802154_seteaddr.c
index 75c589702..19494eafd 100644
--- a/wireless/ieee802154/libmac/ieee802154_seteaddr.c
+++ b/wireless/ieee802154/libmac/ieee802154_seteaddr.c
@@ -58,8 +58,8 @@ int ieee802154_seteaddr(int fd, FAR const uint8_t *eaddr)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_EXTENDED_ADDR;
-  memcpy(&req.attrval.mac.eaddr[0], eaddr, 8);
+  req.attr = IEEE802154_ATTR_MAC_EXTENDED_ADDR;
+  IEEE802154_EADDRCOPY(req.attrval.mac.eaddr, eaddr);
 
   return ieee802154_set_req(fd, &req);
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_setpanid.c b/wireless/ieee802154/libmac/ieee802154_setpanid.c
index 2a1d3983f..eb4b1f836 100644
--- a/wireless/ieee802154/libmac/ieee802154_setpanid.c
+++ b/wireless/ieee802154/libmac/ieee802154_setpanid.c
@@ -43,6 +43,7 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 
 #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
@@ -53,12 +54,12 @@
  * Public Functions
  ****************************************************************************/
 
-int ieee802154_setpanid(int fd, uint16_t panid)
+int ieee802154_setpanid(int fd, FAR const uint8_t *panid)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PANID;
-  req.attrval.mac.panid = panid;
+  req.attr = IEEE802154_ATTR_MAC_PANID;
+  IEEE802154_PANIDCOPY(req.attrval.mac.panid, panid);
 
   return ieee802154_set_req(fd, &req);
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_setpromisc.c b/wireless/ieee802154/libmac/ieee802154_setpromisc.c
index 833b5bd4f..cff645e89 100644
--- a/wireless/ieee802154/libmac/ieee802154_setpromisc.c
+++ b/wireless/ieee802154/libmac/ieee802154_setpromisc.c
@@ -58,7 +58,7 @@ int ieee802154_setpromisc(int fd, bool promisc)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PROMISCUOUS_MODE;
+  req.attr = IEEE802154_ATTR_MAC_PROMISCUOUS_MODE;
   req.attrval.mac.promisc_mode = promisc;
 
   return ieee802154_set_req(fd, &req);
diff --git a/wireless/ieee802154/libmac/ieee802154_setrxonidle.c b/wireless/ieee802154/libmac/ieee802154_setrxonidle.c
index bf5f019de..955eb4b8d 100644
--- a/wireless/ieee802154/libmac/ieee802154_setrxonidle.c
+++ b/wireless/ieee802154/libmac/ieee802154_setrxonidle.c
@@ -58,7 +58,7 @@ int ieee802154_setrxonidle(int fd, bool rxonidle)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE;
+  req.attr = IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE;
   req.attrval.mac.rxonidle = rxonidle;
 
   return ieee802154_set_req(fd, &req);
diff --git a/wireless/ieee802154/libmac/ieee802154_setsaddr.c b/wireless/ieee802154/libmac/ieee802154_setsaddr.c
index fe2559dbe..20f2fa544 100644
--- a/wireless/ieee802154/libmac/ieee802154_setsaddr.c
+++ b/wireless/ieee802154/libmac/ieee802154_setsaddr.c
@@ -43,6 +43,7 @@
 #include <sys/ioctl.h>
 #include <stdint.h>
 #include <stdio.h>
+#include <string.h>
 #include <errno.h>
 
 #include <nuttx/wireless/ieee802154/ieee802154_mac.h>
@@ -53,12 +54,12 @@
  * Public Functions
  ****************************************************************************/
 
-int ieee802154_setsaddr(int fd, uint16_t saddr)
+int ieee802154_setsaddr(int fd, FAR const uint8_t *saddr)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_SHORT_ADDRESS;
-  req.attrval.mac.saddr = saddr;
+  req.attr = IEEE802154_ATTR_MAC_SHORT_ADDRESS;
+  IEEE802154_SADDRCOPY(req.attrval.mac.saddr, saddr);
 
   return ieee802154_set_req(fd, &req);
 }
diff --git a/wireless/ieee802154/libmac/ieee802154_settxpwr.c b/wireless/ieee802154/libmac/ieee802154_settxpwr.c
index e66eb1650..ccd4c84e5 100644
--- a/wireless/ieee802154/libmac/ieee802154_settxpwr.c
+++ b/wireless/ieee802154/libmac/ieee802154_settxpwr.c
@@ -56,7 +56,7 @@ int ieee802154_settxpwr(int fd, int32_t txpwr)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_PHY_TX_POWER;
+  req.attr = IEEE802154_ATTR_PHY_TX_POWER;
   req.attrval.phy.txpwr = txpwr;
 
   return ieee802154_set_req(fd, &req);
diff --git a/wireless/ieee802154/libmac/sixlowpan_getchan.c b/wireless/ieee802154/libmac/sixlowpan_getchan.c
index 7d5b5b3dd..f445d421e 100644
--- a/wireless/ieee802154/libmac/sixlowpan_getchan.c
+++ b/wireless/ieee802154/libmac/sixlowpan_getchan.c
@@ -58,7 +58,7 @@ int sixlowpan_getchan(int sock, FAR const char *ifname, FAR uint8_t *chan)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_PHY_CURRENT_CHANNEL;
+  req.attr = IEEE802154_ATTR_PHY_CURRENT_CHANNEL;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
   *chan = req.attrval.phy.channel;
diff --git a/wireless/ieee802154/libmac/sixlowpan_geteaddr.c b/wireless/ieee802154/libmac/sixlowpan_geteaddr.c
index 0c62cc2dd..0344d43c6 100644
--- a/wireless/ieee802154/libmac/sixlowpan_geteaddr.c
+++ b/wireless/ieee802154/libmac/sixlowpan_geteaddr.c
@@ -58,10 +58,10 @@ int sixlowpan_geteaddr(int sock, FAR const char *ifname, FAR uint8_t *eaddr)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_EXTENDED_ADDR;
+  req.attr = IEEE802154_ATTR_MAC_EXTENDED_ADDR;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
-  memcpy(eaddr, &req.attrval.mac.eaddr[0], 8);
+  IEEE802154_EADDRCOPY(eaddr, req.attrval.mac.eaddr);
 
   return ret;
 }
diff --git a/wireless/ieee802154/libmac/sixlowpan_getpanid.c b/wireless/ieee802154/libmac/sixlowpan_getpanid.c
index 7b102ada1..0694e3f3e 100644
--- a/wireless/ieee802154/libmac/sixlowpan_getpanid.c
+++ b/wireless/ieee802154/libmac/sixlowpan_getpanid.c
@@ -53,15 +53,15 @@
  * Public Functions
  ****************************************************************************/
 
-int sixlowpan_getpanid(int sock, FAR const char *ifname, FAR uint16_t *panid)
+int sixlowpan_getpanid(int sock, FAR const char *ifname, FAR uint8_t *panid)
 {
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PANID;
+  req.attr = IEEE802154_ATTR_MAC_PANID;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
-  *panid = req.attrval.mac.panid;
+  IEEE802154_PANIDCOPY(panid, req.attrval.mac.panid);
 
   return ret;
 }
diff --git a/wireless/ieee802154/libmac/sixlowpan_getpromisc.c b/wireless/ieee802154/libmac/sixlowpan_getpromisc.c
index 00254a6ea..f4b25deb5 100644
--- a/wireless/ieee802154/libmac/sixlowpan_getpromisc.c
+++ b/wireless/ieee802154/libmac/sixlowpan_getpromisc.c
@@ -58,7 +58,7 @@ int sixlowpan_getpromisc(int sock, FAR const char *ifname, FAR bool *promisc)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PROMISCUOUS_MODE;
+  req.attr = IEEE802154_ATTR_MAC_PROMISCUOUS_MODE;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
   *promisc = req.attrval.mac.promisc_mode;
diff --git a/wireless/ieee802154/libmac/sixlowpan_getrxonidle.c b/wireless/ieee802154/libmac/sixlowpan_getrxonidle.c
index c75b2d2fd..a801e010b 100644
--- a/wireless/ieee802154/libmac/sixlowpan_getrxonidle.c
+++ b/wireless/ieee802154/libmac/sixlowpan_getrxonidle.c
@@ -58,7 +58,7 @@ int sixlowpan_getrxonidle(int sock, FAR const char *ifname, FAR bool *rxonidle)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE;
+  req.attr = IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
   *rxonidle = req.attrval.mac.rxonidle;
diff --git a/wireless/ieee802154/libmac/sixlowpan_getsaddr.c b/wireless/ieee802154/libmac/sixlowpan_getsaddr.c
index c9e62a880..ef221190c 100644
--- a/wireless/ieee802154/libmac/sixlowpan_getsaddr.c
+++ b/wireless/ieee802154/libmac/sixlowpan_getsaddr.c
@@ -53,15 +53,15 @@
  * Public Functions
  ****************************************************************************/
 
-int sixlowpan_getsaddr(int sock, FAR const char *ifname, FAR uint16_t *saddr)
+int sixlowpan_getsaddr(int sock, FAR const char *ifname, FAR uint8_t *saddr)
 {
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_MAC_SHORT_ADDRESS;
+  req.attr = IEEE802154_ATTR_MAC_SHORT_ADDRESS;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
-  *saddr = req.attrval.mac.saddr;
+  IEEE802154_SADDRCOPY(saddr, req.attrval.mac.saddr);
 
   return ret;
 }
diff --git a/wireless/ieee802154/libmac/sixlowpan_gettxpwr.c b/wireless/ieee802154/libmac/sixlowpan_gettxpwr.c
index e6dbdb607..2e1ec0da4 100644
--- a/wireless/ieee802154/libmac/sixlowpan_gettxpwr.c
+++ b/wireless/ieee802154/libmac/sixlowpan_gettxpwr.c
@@ -58,7 +58,7 @@ int sixlowpan_gettxpwr(int sock, FAR const char *ifname, FAR int32_t *txpwr)
   struct ieee802154_get_req_s req;
   int ret;
 
-  req.pib_attr = IEEE802154_PIB_PHY_TX_POWER;
+  req.attr = IEEE802154_ATTR_PHY_TX_POWER;
   ret = sixlowpan_get_req(sock, ifname, &req);
 
   *txpwr = req.attrval.phy.txpwr;
diff --git a/wireless/ieee802154/libmac/sixlowpan_setchan.c b/wireless/ieee802154/libmac/sixlowpan_setchan.c
index df3d834b5..c4e746b8c 100644
--- a/wireless/ieee802154/libmac/sixlowpan_setchan.c
+++ b/wireless/ieee802154/libmac/sixlowpan_setchan.c
@@ -57,7 +57,7 @@ int sixlowpan_setchan(int sock, FAR const char *ifname, uint8_t chan)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_PHY_CURRENT_CHANNEL;
+  req.attr = IEEE802154_ATTR_PHY_CURRENT_CHANNEL;
   req.attrval.phy.channel = chan;
 
   return sixlowpan_set_req(sock, ifname, &req);
diff --git a/wireless/ieee802154/libmac/sixlowpan_seteaddr.c b/wireless/ieee802154/libmac/sixlowpan_seteaddr.c
index e7034a971..9f3dcb46d 100644
--- a/wireless/ieee802154/libmac/sixlowpan_seteaddr.c
+++ b/wireless/ieee802154/libmac/sixlowpan_seteaddr.c
@@ -57,8 +57,8 @@ int sixlowpan_seteaddr(int sock, FAR const char *ifname, FAR const uint8_t *eadd
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_EXTENDED_ADDR;
-  memcpy(&req.attrval.mac.eaddr[0], eaddr, 8);
+  req.attr = IEEE802154_ATTR_MAC_EXTENDED_ADDR;
+  IEEE802154_EADDRCOPY(req.attrval.mac.eaddr, eaddr);
 
   return sixlowpan_set_req(sock, ifname, &req);
 }
diff --git a/wireless/ieee802154/libmac/sixlowpan_setpanid.c b/wireless/ieee802154/libmac/sixlowpan_setpanid.c
index fbe1186ec..559ae13e9 100644
--- a/wireless/ieee802154/libmac/sixlowpan_setpanid.c
+++ b/wireless/ieee802154/libmac/sixlowpan_setpanid.c
@@ -53,12 +53,12 @@
  * Public Functions
  ****************************************************************************/
 
-int sixlowpan_setpanid(int sock, FAR const char *ifname, uint16_t panid)
+int sixlowpan_setpanid(int sock, FAR const char *ifname, FAR const uint8_t *panid)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PANID;
-  req.attrval.mac.panid = panid;
+  req.attr = IEEE802154_ATTR_MAC_PANID;
+  IEEE802154_PANIDCOPY(req.attrval.mac.panid, panid);
 
   return sixlowpan_set_req(sock, ifname, &req);
 }
diff --git a/wireless/ieee802154/libmac/sixlowpan_setpromisc.c b/wireless/ieee802154/libmac/sixlowpan_setpromisc.c
index b0d4e7007..77121fc0a 100644
--- a/wireless/ieee802154/libmac/sixlowpan_setpromisc.c
+++ b/wireless/ieee802154/libmac/sixlowpan_setpromisc.c
@@ -58,7 +58,7 @@ int sixlowpan_setpromisc(int sock, FAR const char *ifname, bool promisc)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_PROMISCUOUS_MODE;
+  req.attr = IEEE802154_ATTR_MAC_PROMISCUOUS_MODE;
   req.attrval.mac.promisc_mode = promisc;
 
   return sixlowpan_set_req(sock, ifname, &req);
diff --git a/wireless/ieee802154/libmac/sixlowpan_setrxonidle.c b/wireless/ieee802154/libmac/sixlowpan_setrxonidle.c
index 81dd30765..53f9a1112 100644
--- a/wireless/ieee802154/libmac/sixlowpan_setrxonidle.c
+++ b/wireless/ieee802154/libmac/sixlowpan_setrxonidle.c
@@ -58,7 +58,7 @@ int sixlowpan_setrxonidle(int sock, FAR const char *ifname, bool rxonidle)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_RX_ON_WHEN_IDLE;
+  req.attr = IEEE802154_ATTR_MAC_RX_ON_WHEN_IDLE;
   req.attrval.mac.rxonidle = rxonidle;
 
   return sixlowpan_set_req(sock, ifname, &req);
diff --git a/wireless/ieee802154/libmac/sixlowpan_setsaddr.c b/wireless/ieee802154/libmac/sixlowpan_setsaddr.c
index 556777a3d..49c46f28b 100644
--- a/wireless/ieee802154/libmac/sixlowpan_setsaddr.c
+++ b/wireless/ieee802154/libmac/sixlowpan_setsaddr.c
@@ -53,12 +53,12 @@
  * Public Functions
  ****************************************************************************/
 
-int sixlowpan_setsaddr(int sock, FAR const char *ifname, uint16_t saddr)
+int sixlowpan_setsaddr(int sock, FAR const char *ifname, FAR const uint8_t *saddr)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_MAC_SHORT_ADDRESS;
-  req.attrval.mac.saddr = saddr;
+  req.attr = IEEE802154_ATTR_MAC_SHORT_ADDRESS;
+  IEEE802154_SADDRCOPY(req.attrval.mac.saddr, saddr);
 
   return sixlowpan_set_req(sock, ifname, &req);
 }
diff --git a/wireless/ieee802154/libmac/sixlowpan_settxpwr.c b/wireless/ieee802154/libmac/sixlowpan_settxpwr.c
index 9c5a82cec..62e3685c8 100644
--- a/wireless/ieee802154/libmac/sixlowpan_settxpwr.c
+++ b/wireless/ieee802154/libmac/sixlowpan_settxpwr.c
@@ -57,7 +57,7 @@ int sixlowpan_settxpwr(int sock, FAR const char *ifname, int32_t txpwr)
 {
   struct ieee802154_set_req_s req;
 
-  req.pib_attr = IEEE802154_PIB_PHY_TX_POWER;
+  req.attr = IEEE802154_ATTR_PHY_TX_POWER;
   req.attrval.phy.txpwr = txpwr;
 
   return sixlowpan_set_req(sock, ifname, &req);
diff --git a/wireless/ieee802154/libutils/ieee802154_addrtostr.c b/wireless/ieee802154/libutils/ieee802154_addrtostr.c
index 42c9ed02a..818dd302e 100644
--- a/wireless/ieee802154/libutils/ieee802154_addrtostr.c
+++ b/wireless/ieee802154/libutils/ieee802154_addrtostr.c
@@ -48,9 +48,11 @@
  * Public Functions
  ****************************************************************************/
 
+
 int ieee802154_addrtostr(FAR char *buf, int len,
                          FAR struct ieee802154_addr_s *addr)
 {
+#if 0
 #ifndef CONFIG_BIG_ENDIAN
   uint16_t panid = ((addr->panid & 0xff) << 8) | ((addr->panid >> 8) & 0xff);
 #else
@@ -87,5 +89,7 @@ int ieee802154_addrtostr(FAR char *buf, int len,
       return snprintf(buf,len,"<INVAL>");
     }
 
+  return -1;
+#endif
   return -1;
 }
diff --git a/wireless/ieee802154/wpanlistener/Kconfig b/wireless/ieee802154/wpanlistener/Kconfig
new file mode 100644
index 000000000..a6b2dfea2
--- /dev/null
+++ b/wireless/ieee802154/wpanlistener/Kconfig
@@ -0,0 +1,25 @@
+#
+# For a description of the syntax of this configuration file,
+# see misc/tools/kconfig-language.txt.
+#
+
+config IEEE802154_WPANLISTENER
+	bool "WPAN Listener Module for receiving various IEEE 802.15.4 MAC events"
+	default n
+	select IEEE802154_MAC_DEV
+	select IEEE802154_LIBUTILS
+	select IEEE802154_LIBMAC
+	---help---
+		Enable the IEEE 802.15.4 WPAN Listener
+
+if IEEE802154_WPANLISTENER
+
+config WPANLISTENER_NFRAMERECEIVERS
+	int "Number of frame receivers"
+	default 3
+
+config WPANLISTENER_NEVENTRECEIVERS
+	int "Number of event receivers"
+	default 3
+
+endif
diff --git a/wireless/ieee802154/wpanlistener/Make.defs b/wireless/ieee802154/wpanlistener/Make.defs
new file mode 100644
index 000000000..f7ac51216
--- /dev/null
+++ b/wireless/ieee802154/wpanlistener/Make.defs
@@ -0,0 +1,39 @@
+############################################################################
+# apps/wireless/ieee802154/wpanlistener/Make.defs
+# Adds selected applications to apps/ build
+#
+#   Copyright (C) 2017 Verge Inc. All rights reserved.
+#   Author: Anthony Merlino <anthony@vergeaero.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+ifeq ($(CONFIG_IEEE802154_WPANLISTENER),y)
+CONFIGURED_APPS += wireless/ieee802154/wpanlistener
+endif
diff --git a/wireless/ieee802154/wpanlistener/Makefile b/wireless/ieee802154/wpanlistener/Makefile
new file mode 100644
index 000000000..5bba310dd
--- /dev/null
+++ b/wireless/ieee802154/wpanlistener/Makefile
@@ -0,0 +1,99 @@
+############################################################################
+# apps/wireless/ieee802154/wpanlistener/Makefile
+#
+#   Copyright (C) 2017 Gregory Nutt. All rights reserved.
+#   Copyright (C) 2017 Verge Inc. All rights reserved.
+#
+#   Author: Gregory Nutt <gnutt@nuttx.org>
+#   Author: Anthony Merlino <anthony@vergeaero.com>
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# 1. Redistributions of source code must retain the above copyright
+#    notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+#    notice, this list of conditions and the following disclaimer in
+#    the documentation and/or other materials provided with the
+#    distribution.
+# 3. Neither the name NuttX nor the names of its contributors may be
+#    used to endorse or promote products derived from this software
+#    without specific prior written permission.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+############################################################################
+
+-include $(TOPDIR)/.config
+-include $(TOPDIR)/Make.defs
+include $(APPDIR)/Make.defs
+
+ASRCS  =
+CSRCS  = wpanlistener.c
+
+AOBJS = $(ASRCS:.S=$(OBJEXT))
+COBJS = $(CSRCS:.c=$(OBJEXT))
+
+SRCS = $(ASRCS) $(CSRCS)
+OBJS = $(AOBJS) $(COBJS)
+
+ifeq ($(CONFIG_WINDOWS_NATIVE),y)
+  BIN = ..\..\..\libapps$(LIBEXT)
+else
+ifeq ($(WINTOOL),y)
+  BIN = ..\\..\\..\\libapps$(LIBEXT)
+else
+  BIN = ../../../libapps$(LIBEXT)
+endif
+endif
+
+ROOTDEPPATH = --dep-path .
+VPATH =
+
+# Build targets
+
+all: .built
+.PHONY: context .depend depend clean distclean
+
+$(AOBJS): %$(OBJEXT): %.S
+	$(call ASSEMBLE, $<, $@)
+
+$(COBJS): %$(OBJEXT): %.c
+	$(call COMPILE, $<, $@)
+
+.built: $(OBJS)
+	$(call ARCHIVE, $(BIN), $(OBJS))
+	@touch .built
+
+install:
+
+context:
+
+.depend: Makefile $(SRCS)
+	@$(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
+	@touch $@
+
+depend: .depend
+
+clean:
+	$(call DELFILE, .built)
+	$(call CLEAN)
+
+distclean: clean
+	$(call DELFILE, Make.dep)
+	$(call DELFILE, .depend)
+
+-include Make.dep
+
diff --git a/wireless/iwpan/src/iwpan.c b/wireless/iwpan/src/iwpan.c
index 769a1ec3f..9ac1b28e9 100644
--- a/wireless/iwpan/src/iwpan.c
+++ b/wireless/iwpan/src/iwpan.c
@@ -315,7 +315,7 @@ static bool iwpan_str2bool(FAR const char *str)
 
 static void iwpan_show_cmd(int sock, FAR const char *ifname)
 {
-  uint8_t eaddr[IEEE802154_EADDR_LEN] =
+  uint8_t eaddr[IEEE802154_EADDRSIZE] =
   {
     0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
   };
@@ -506,7 +506,7 @@ static void iwpan_devmode_cmd(int sock, FAR const char *ifname,
 static void iwpan_eaddr_cmd(int sock, FAR const char *ifname,
                             FAR const char *addrstr)
 {
-  uint8_t eaddr[IEEE802154_EADDR_LEN];
+  uint8_t eaddr[IEEE802154_EADDRSIZE];
   int ret;
 
   /* Convert input strings to values */
diff --git a/wireless/wapi/src/wapi.c b/wireless/wapi/src/wapi.c
index d96a0a6b5..b27a19f98 100644
--- a/wireless/wapi/src/wapi.c
+++ b/wireless/wapi/src/wapi.c
@@ -488,7 +488,7 @@ static void wapi_essid_cmd(int sock, FAR const char *ifname,
   /* Convert input strings to values */
 
   essid_flag = (enum wapi_essid_flag_e)wapi_str2ndx(flagstr, g_wapi_essid_flags, 2);
-  
+
   /* Set the ESSID */
 
   ret = wapi_set_essid(sock, ifname, essid, essid_flag);