wireless/ieee802154: i8sak adds sniffing functionality back in

This commit is contained in:
Anthony Merlino 2017-05-08 16:25:09 -04:00
parent a6ef54cf0c
commit 84dc6ddcd7
2 changed files with 154 additions and 36 deletions

View File

@ -20,5 +20,13 @@ config IEEE802154_I8SAK_PROGNAME
This is the name of the program that will be use when the NSH ELF This is the name of the program that will be use when the NSH ELF
program is installed. program is installed.
config IEEE802154_I8SAK_PRIORITY
int "i8sak task priority"
default 100
config IEEE802154_I8SAK_STACKSIZE
int "i8sak stack size"
default 2048
endif endif

View File

@ -73,7 +73,8 @@
* Private Function Prototypes * Private Function Prototypes
****************************************************************************/ ****************************************************************************/
static int tx(int fd, FAR const char *str, int verbose); static int tx(FAR const char *devname, FAR const char *str, int verbose);
static int start_sniffer_daemon(FAR const char *devname);
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -81,6 +82,9 @@ static int tx(int fd, FAR const char *str, int verbose);
uint8_t g_handle = 0; uint8_t g_handle = 0;
uint8_t g_txframe[IEEE802154_MAX_MAC_PAYLOAD_SIZE]; uint8_t g_txframe[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
static int sniffer_daemon(int argc, FAR char *argv[]);
bool g_sniffer_daemon_started = false;
/**************************************************************************** /****************************************************************************
* Public Data * Public Data
@ -90,6 +94,112 @@ uint8_t g_txframe[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
* Private Functions * Private Functions
****************************************************************************/ ****************************************************************************/
/****************************************************************************
* Name : start_sniff
*
* Description :
* Starts a thread to run the sniffer in the background
****************************************************************************/
static int start_sniffer_daemon(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 EXIT_SUCCESS;
}
sniffer_argv[0] = devname;
sniffer_argv[1] = NULL;
ret = task_create("sniffer_daemon", CONFIG_IEEE802154_I8SAK_PRIORITY,
CONFIG_IEEE802154_I8SAK_STACKSIZE, sniffer_daemon,
(FAR char * const *)sniffer_argv);
if (ret < 0)
{
int errcode = errno;
printf("i8sak: ERROR: Failed to start sniffer_daemon: %d\n",
errcode);
return EXIT_FAILURE;
}
g_sniffer_daemon_started = true;
printf("i8sak: sniffer_daemon started\n");
return OK;
}
/****************************************************************************
* Name : sniffer_daemon
*
* Description :
* Sniff for frames (Promiscuous mode)
****************************************************************************/
static int 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");
/* 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)
{
printf("sniffer_daemon: read failed: %d\n", errno);
goto errout;
}
printf("Frame Received:\n");
for (i = 0; i < rx.length; i++)
{
printf("%02X", rx.payload[i]);
}
printf("\n");
fflush(stdout);
}
errout:
/* Turn receiver off when idle */
ret = ieee802154_setrxonidle(fd, false);
/* Disable promiscuous mode */
ret = ieee802154_setpromisc(fd, false);
printf("sniffer_daemon: closing");
close(fd);
g_sniffer_daemon_started = false;
return OK;
}
/**************************************************************************** /****************************************************************************
* Name : tx * Name : tx
* *
@ -97,12 +207,22 @@ uint8_t g_txframe[IEEE802154_MAX_MAC_PAYLOAD_SIZE];
* Transmit a data frame. * Transmit a data frame.
****************************************************************************/ ****************************************************************************/
static int tx(int fd, FAR const char *str, int verbose) static int tx(FAR const char *devname, FAR const char *str, int verbose)
{ {
struct mac802154dev_txframe_s tx; struct mac802154dev_txframe_s tx;
int ret, str_len; int ret, str_len, fd;
int i = 0; int i = 0;
/* Open device */
fd = open(devname, O_RDWR);
if (fd < 0)
{
printf("cannot open %s, errno=%d\n", devname, errno);
ret = errno;
return ret;
}
/* Set an application defined handle */ /* Set an application defined handle */
tx.meta.msdu_handle = g_handle++; tx.meta.msdu_handle = g_handle++;
@ -116,6 +236,8 @@ static int tx(int fd, FAR const char *str, int verbose)
tx.meta.ranging = IEEE802154_NON_RANGING; tx.meta.ranging = IEEE802154_NON_RANGING;
tx.meta.src_addr_mode = IEEE802154_ADDRMODE_EXTENDED; tx.meta.src_addr_mode = IEEE802154_ADDRMODE_EXTENDED;
tx.meta.dest_addr.mode = IEEE802154_ADDRMODE_SHORT;
tx.meta.dest_addr.saddr = 0xFADE;
str_len = strlen(str); str_len = strlen(str);
@ -128,7 +250,7 @@ static int tx(int fd, FAR const char *str, int verbose)
if ((str_len & 1) || (tx.length > IEEE802154_MAX_MAC_PAYLOAD_SIZE)) if ((str_len & 1) || (tx.length > IEEE802154_MAX_MAC_PAYLOAD_SIZE))
{ {
goto data_error; goto error;
} }
/* Decode hex packet */ /* Decode hex packet */
@ -144,7 +266,7 @@ static int tx(int fd, FAR const char *str, int verbose)
} }
else else
{ {
goto data_error; goto error;
} }
} }
@ -173,11 +295,13 @@ static int tx(int fd, FAR const char *str, int verbose)
printf(" write: errno=%d\n",errno); printf(" write: errno=%d\n",errno);
} }
return ret; close(fd);
return ret;
data_error: error:
printf("data error\n"); printf("data error\n");
return ERROR;; close(fd);
return ERROR;
} }
/**************************************************************************** /****************************************************************************
@ -190,7 +314,8 @@ data_error:
int usage(void) int usage(void)
{ {
printf("i8 <device> <op> [<args>]\n" printf("i8 <devname> <op> [<args>]\n"
" sniffer Listen for packets\n"
" tx <hexpacket> Transmit a data frame\n" " tx <hexpacket> Transmit a data frame\n"
); );
@ -207,48 +332,33 @@ int main(int argc, FAR char *argv[])
int i8_main(int argc, char *argv[]) int i8_main(int argc, char *argv[])
#endif #endif
{ {
unsigned long arg = 0; FAR const char *devname;
int fd; FAR const char *cmdname;
int ret = OK; int ret = OK;
if (argc < 3) if (argc < 3)
{ {
printf("ERROR: Missing argument\n");
return usage(); return usage();
} }
if (argc >= 4) devname = argv[1];
{ cmdname = argv[2];
arg = atol(argv[3]);
}
/* Open device */
fd = open(argv[1], O_RDWR);
if (fd < 0)
{
printf("cannot open %s, errno=%d\n", argv[1], errno);
ret = errno;
goto exit;
}
/* Get mode */ /* Get mode */
if (!strcmp(argv[2], "tx")) if (!strcmp(cmdname, "tx"))
{ {
ret = tx(fd, argv[3], TRUE); ret = tx(devname, argv[3], TRUE);
if (ret < 0)
{
goto error;
} }
else if(!strcmp(argv[2], "sniffer"))
{
ret = start_sniffer_daemon(devname);
} }
else else
{ {
usage:
ret = usage(); ret = usage();
} }
error:
close(fd);
exit:
return ret; return ret;
} }