diff --git a/configs/b-l475e-iot01a/README.txt b/configs/b-l475e-iot01a/README.txt index 5df8c8887f9..92f20454751 100644 --- a/configs/b-l475e-iot01a/README.txt +++ b/configs/b-l475e-iot01a/README.txt @@ -369,9 +369,10 @@ Configuration sub-directories 2017-08-01: Testing began. The Spirit1 no configurations with no errors, but there are no tests yet in place to exercise it. - 2017-08-02: The nettest, udp, telnet test programs were added. - + 2017-08-05: Successfully exchanging packets, but there there are + issues with address filtering, CRC calculation, and data integrity + (like bad UDP checksums). Lot's more to be done! Test Matrix: The following configurations have been tested: diff --git a/drivers/wireless/spirit/drivers/Kconfig b/drivers/wireless/spirit/drivers/Kconfig index fa0eac2f136..58301996d70 100644 --- a/drivers/wireless/spirit/drivers/Kconfig +++ b/drivers/wireless/spirit/drivers/Kconfig @@ -69,4 +69,10 @@ config SPIRIT_BROADCAST ---help--- Enables address filtering for the broadcast addess 0xff. +config SPIRIT_CRCDISABLE + bool "Disable CRC" + default n + ---help--- + Disables CRC calculation and filtering. Default is enabled. + endif # SPIRIT_NETDEV diff --git a/drivers/wireless/spirit/drivers/spirit_netdev.c b/drivers/wireless/spirit/drivers/spirit_netdev.c index d9fd740e480..67f89ef22b0 100644 --- a/drivers/wireless/spirit/drivers/spirit_netdev.c +++ b/drivers/wireless/spirit/drivers/spirit_netdev.c @@ -110,36 +110,38 @@ * transfer the packet length. */ +#if CONFIG_SPIRIT_PKTLEN < 2 +# define PKT_LENGTH_WIDTH 1 /* 0 - 1 */ #if CONFIG_SPIRIT_PKTLEN < 4 -# define PKT_LENGTH_WIDTH (2 - 1) +# define PKT_LENGTH_WIDTH 2 /* 2 - 3 */ #elif CONFIG_SPIRIT_PKTLEN < 8 -# define PKT_LENGTH_WIDTH (3 - 1) +# define PKT_LENGTH_WIDTH 3 /* 4 - 7 */ #elif CONFIG_SPIRIT_PKTLEN < 16 -# define PKT_LENGTH_WIDTH (4 - 1) +# define PKT_LENGTH_WIDTH 4 /* 8 - 15 */ #elif CONFIG_SPIRIT_PKTLEN < 32 -# define PKT_LENGTH_WIDTH (5 - 1) +# define PKT_LENGTH_WIDTH 5 /* 16 - 31 */ #elif CONFIG_SPIRIT_PKTLEN < 64 -# define PKT_LENGTH_WIDTH (6 - 1) +# define PKT_LENGTH_WIDTH 6 /* 32 - 63 */ #elif CONFIG_SPIRIT_PKTLEN < 128 -# define PKT_LENGTH_WIDTH (7 - 1) +# define PKT_LENGTH_WIDTH 7 /* 63 - 127 */ #elif CONFIG_SPIRIT_PKTLEN < 256 -# define PKT_LENGTH_WIDTH (8 - 1) +# define PKT_LENGTH_WIDTH 8 /* 128 - 255 */ #elif CONFIG_SPIRIT_PKTLEN < 512 -# define PKT_LENGTH_WIDTH (9 - 1) +# define PKT_LENGTH_WIDTH 9 /* 256 - 255 */ #elif CONFIG_SPIRIT_PKTLEN < 1024 -# define PKT_LENGTH_WIDTH (10 - 1) +# define PKT_LENGTH_WIDTH 10 /* 512 - 1023 */ #elif CONFIG_SPIRIT_PKTLEN < 2048 -# define PKT_LENGTH_WIDTH (11 - 1) +# define PKT_LENGTH_WIDTH 11 /* 1024 - 2047 */ #elif CONFIG_SPIRIT_PKTLEN < 4096 -# define PKT_LENGTH_WIDTH (12 - 1) +# define PKT_LENGTH_WIDTH 12 /* 2048 - 4095 */ #elif CONFIG_SPIRIT_PKTLEN < 8192 -# define PKT_LENGTH_WIDTH (13 - 1) +# define PKT_LENGTH_WIDTH 13 /* 4096 - 8191 */ #elif CONFIG_SPIRIT_PKTLEN < 16384 -# define PKT_LENGTH_WIDTH (14 - 1) +# define PKT_LENGTH_WIDTH 14 /* 8192 - 16383 */ #elif CONFIG_SPIRIT_PKTLEN < 32768 -# define PKT_LENGTH_WIDTH (15 - 1) +# define PKT_LENGTH_WIDTH 15 /* 16384 - 32767 */ #elif CONFIG_SPIRIT_PKTLEN < 65536 -# define PKT_LENGTH_WIDTH (16 - 1) +# define PKT_LENGTH_WIDTH 16 /* 32768 - 65535 */ #else # error Invalid CONFIG_SPIRIT_PKTLEN #endif @@ -274,32 +276,41 @@ int spirit_hw_initialize(FAR struct spirit_driver_s *dev, static const struct radio_init_s g_radio_init = { - SPIRIT_BASE_FREQUENCY, /* base_frequency */ - SPIRIT_CHANNEL_SPACE, /* chspace */ - SPIRIT_XTAL_OFFSET_PPM, /* foffset */ - SPIRIT_CHANNEL_NUMBER, /* chnum */ - SPIRIT_MODULATION_SELECT, /* modselect */ - SPIRIT_DATARATE, /* datarate */ - SPIRIT_FREQ_DEVIATION, /* freqdev */ - SPIRIT_BANDWIDTH /* bandwidth */ + SPIRIT_BASE_FREQUENCY, /* base_frequency selected in board.h */ + SPIRIT_CHANNEL_SPACE, /* chspace selected in board.h */ + SPIRIT_XTAL_OFFSET_PPM, /* foffset selected in board.h */ + SPIRIT_CHANNEL_NUMBER, /* chnum selected in board.h */ + SPIRIT_MODULATION_SELECT, /* modselect selected in board.h */ + SPIRIT_DATARATE, /* datarate selected in board.h */ + SPIRIT_FREQ_DEVIATION, /* freqdev selected in board.h */ + SPIRIT_BANDWIDTH /* bandwidth selected in board.h */ }; /* Spirit PktBasic initialization */ static const struct pktbasic_init_s g_pktbasic_init = { - SPIRIT_SYNC_WORD, /* syncwords */ - SPIRIT_PREAMBLE_LENGTH, /* premblen */ - SPIRIT_SYNC_LENGTH, /* synclen */ - PKT_LENGTH_VAR, /* fixvarlen, variable packet length */ - PKT_LENGTH_WIDTH, /* pktlenwidth from CONFIG_SPIRIT_PKTLEN */ - SPIRIT_CRC_MODE, /* crcmode */ - SPIRIT_CONTROL_LENGTH, /* ctrllen */ - S_ENABLE, /* txdestaddr, need to send address */ - SPIRIT_EN_FEC, /* fec */ - SPIRIT_EN_WHITENING /* datawhite */ + SPIRIT_SYNC_WORD, /* syncword selected in board.h */ + SPIRIT_PREAMBLE_LENGTH, /* premblen selected in board.h*/ + SPIRIT_SYNC_LENGTH, /* synclen selected in board.h */ + PKT_LENGTH_VAR, /* fixvarlen variable packet length */ + PKT_LENGTH_WIDTH, /* pktlenwidth from CONFIG_SPIRIT_PKTLEN */ +#ifdef CONFIG_SPIRIT_CRCDISABLE + PKT_NO_CRC, /* crcmode none */ +#else + SPIRIT_CRC_MODE, /* crcmode selected in board.h */ +#endif + SPIRIT_CONTROL_LENGTH, /* ctrllen selected in board.h */ + S_ENABLE, /* txdestaddr need to send address */ + SPIRIT_EN_FEC, /* fec selected in board.h */ + SPIRIT_EN_WHITENING /* datawhite selected in board.h */ }; +/* GPIO Configuration. + * + * REVISIT: Assumes interrupt is on GPIO3. Might need to be configurable. + */ + static const struct spirit_gpio_init_s g_gpioinit = { SPIRIT_GPIO_3, /* gpiopin */ @@ -307,43 +318,45 @@ static const struct spirit_gpio_init_s g_gpioinit = SPIRIT_GPIO_DIG_OUT_IRQ /* gpioio */ }; +/* CSMA initialization */ + static const struct spirit_csma_init_s g_csma_init = { - 1, /* BU counter seed */ - S_ENABLE, /* enable persistent mode */ - TBIT_TIME_64, /* Tcca time */ - TCCA_TIME_3, /* Lcca length */ - 3, /* max nr of backoffs (<8) */ - 8 /* BU prescaler */ + 1, /* BU counter seed */ + S_ENABLE, /* enable persistent mode */ + TBIT_TIME_64, /* Tcca time */ + TCCA_TIME_3, /* Lcca length */ + 3, /* max nr of backoffs (<8) */ + 8 /* BU prescaler */ }; #ifdef CONFIG_SPIRIT_PROMISICUOUS static struct pktbasic_addr_s g_addrinit = { - S_DISABLE, /* Disable filtering on node address */ - SPIRIT_NODE_ADDR, /* Node address (Temporary, until assigned) */ - S_DISABLE, /* Disable filtering on multicast address */ - 0xee, /* Multicast address */ - S_DISABLE, /* Disable filtering on broadcast address */ - 0xff /* Broadcast address */ + S_DISABLE, /* Disable filtering on node address */ + SPIRIT_NODE_ADDR, /* Node address (Temporary, until assigned) */ + S_DISABLE, /* Disable filtering on multicast address */ + SPIRIT_MCAST_ADDRESS, /* Multicast address */ + S_DISABLE, /* Disable filtering on broadcast address */ + SPIRIT_BCAST_ADDRESS /* Broadcast address */ }; #else static struct pktbasic_addr_s g_addrinit = { - S_ENABLE, /* Enable filtering on node address */ - SPIRIT_NODE_ADDR, /* Node address (Temporary, until assigned) */ + S_ENABLE, /* Enable filtering on node address */ + SPIRIT_NODE_ADDR, /* Node address (Temporary, until assigned) */ #ifdef CONFIG_SPIRIT_MULTICAST - S_ENABLE, /* Enable filtering on multicast address */ + S_ENABLE, /* Enable filtering on multicast address */ #else - S_DISABLE, /* Disable filtering on multicast address */ + S_DISABLE, /* Disable filtering on multicast address */ #endif - 0xee, /* Multicast address */ + SPIRIT_MCAST_ADDRESS, /* Multicast address */ #ifdef CONFIG_SPIRIT_BROADCAST - S_ENABLE, /* Enable filtering on broadcast address */ + S_ENABLE, /* Enable filtering on broadcast address */ #else - S_DISABLE, /* Disable filtering on broadcast address */ + S_DISABLE, /* Disable filtering on broadcast address */ #endif - 0xff /* Broadcast address */ + SPIRIT_BCAST_ADDRESS /* Broadcast address */ }; #endif @@ -1922,9 +1935,22 @@ static int spirit_properties(FAR struct sixlowpan_driver_s *netdev, FAR struct sixlowpan_properties_s *properties) { DEBUGASSERT(netdev != NULL && properties != NULL); + memset(properties, 0, sizeof(struct sixlowpan_properties_s)); + + /* General */ properties->sp_addrlen = 1; /* Length of an address */ properties->sp_pktlen = CONFIG_SPIRIT_PKTLEN; /* Fixed packet length */ + + /* Multicast address */ + + properties->sp_mcast.nv_addrlen = 1; + properties->sp_mcast.nv_addr[0] = SPIRIT_MCAST_ADDRESS; + + /* Broadcast address */ + + properties->sp_bcast.nv_addrlen = 1; + properties->sp_bcast.nv_addr[0] = SPIRIT_BCAST_ADDRESS; return OK; } diff --git a/include/nuttx/net/sixlowpan.h b/include/nuttx/net/sixlowpan.h index 30f70d76d7b..655771e80d2 100644 --- a/include/nuttx/net/sixlowpan.h +++ b/include/nuttx/net/sixlowpan.h @@ -355,6 +355,8 @@ struct sixlowpan_properties_s { uint8_t sp_addrlen; /* Length of an address */ uint8_t sp_pktlen; /* Fixed packet/frame size (up to 255) */ + struct netdev_varaddr_s sp_mcast; /* Multicast address */ + struct netdev_varaddr_s sp_bcast; /* Broadcast address */ }; /* The device structure for radio network device differs from the standard diff --git a/include/nuttx/wireless/pktradio.h b/include/nuttx/wireless/pktradio.h index 26fa35a6e53..3587c6b91bb 100644 --- a/include/nuttx/wireless/pktradio.h +++ b/include/nuttx/wireless/pktradio.h @@ -44,6 +44,7 @@ ****************************************************************************/ #include +#include #include #ifdef CONFIG_WIRELESS_PKTRADIO @@ -92,14 +93,18 @@ ****************************************************************************/ /* This describes an address used by the packet radio. There is no standard - * size for such an address. Hence, it is represented simply as a arry of + * size for such an address. Hence, it is represented simply as a array of * bytes. + * + * NOTE: This MUST be the same as the struct netdev_varaddr_s as defined in + * netdev.h. It is duplicated here for no particularly good reason other + * than to maintain a clean PktRadio namespace. */ struct pktradio_addr_s { uint8_t pa_addrlen; /* Length of the following address */ - uint8_t pa_addr[CONFIG_PKTRADIO_ADDRLEN]; + uint8_t pa_addr[RADIO_MAX_ADDRLEN]; }; /* Different packet radios may have different properties. If there are @@ -116,6 +121,8 @@ struct pktradio_properties_s { uint8_t pp_addrlen; /* Length of an address */ uint8_t pp_pktlen; /* Fixed packet/frame size (up to 255) */ + struct pktradio_addr_s pp_mcast; /* Multicast address */ + struct pktradio_addr_s pp_bcast; /* Broadcast address */ }; /* This is the structure passed with all packet radio IOCTL commands. diff --git a/include/nuttx/wireless/spirit.h b/include/nuttx/wireless/spirit.h index a6741ac308c..8e48c2e0a8d 100644 --- a/include/nuttx/wireless/spirit.h +++ b/include/nuttx/wireless/spirit.h @@ -46,6 +46,15 @@ #include +/**************************************************************************** + * Preprocessor Definitions + ****************************************************************************/ + +/* Special multicast and broadcast addresses */ + +#define SPIRIT_MCAST_ADDRESS 0xee +#define SPIRIT_BCAST_ADDRESS 0xff + /**************************************************************************** * Public Types ****************************************************************************/ diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 430f1e6a2ff..b8a1ebf19b4 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -326,7 +326,10 @@ static int sixlowpan_pktradio_metadata(FAR struct sixlowpan_driver_s *radio, radio->r_dev.d_mac.sixlowpan.nv_addr, radio->r_dev.d_mac.sixlowpan.nv_addrlen); - /* Set the destination address */ + /* Set the destination address. + * REVISIT: Do wee need to check for multicast or broadcast addresses + * here? + */ pktmeta->pm_dest.pa_addrlen = destmac->nv_addrlen; memcpy(pktmeta->pm_dest.pa_addr, destmac->nv_addr, destmac->nv_addrlen); diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c index 4c681a4e8cc..961ed493ab6 100644 --- a/net/sixlowpan/sixlowpan_framer.c +++ b/net/sixlowpan/sixlowpan_framer.c @@ -198,9 +198,9 @@ int sixlowpan_meta_data(FAR struct sixlowpan_driver_s *radio, { /* Broadcast requires short address mode. */ - meta->destaddr.mode = IEEE802154_ADDRMODE_SHORT; - meta->destaddr.saddr[0] = 0; - meta->destaddr.saddr[1] = 0; + meta->destaddr.mode = IEEE802154_ADDRMODE_SHORT; + meta->destaddr.saddr[0] = 0xff; + meta->destaddr.saddr[1] = 0xff; } else if (pktmeta->dextended != 0) { diff --git a/wireless/ieee802154/mac802154_loopback.c b/wireless/ieee802154/mac802154_loopback.c index edb73d389d3..5d9a8292cc9 100644 --- a/wireless/ieee802154/mac802154_loopback.c +++ b/wireless/ieee802154/mac802154_loopback.c @@ -909,9 +909,32 @@ static int lo_properties(FAR struct sixlowpan_driver_s *netdev, FAR struct sixlowpan_properties_s *properties) { DEBUGASSERT(netdev != NULL && properties != NULL); + memset(properties, 0, sizeof(struct sixlowpan_properties_s)); + + /* General */ properties->sp_addrlen = NET_6LOWPAN_ADDRSIZE; /* Length of an address */ properties->sp_pktlen = CONFIG_NET_6LOWPAN_FRAMELEN; /* Fixed frame length */ + + /* Multicast address (uses broadcast address) + * + * Multicast address should really determined by the first 3 bits + * (RFC 4944): + * + * 0xxxxxxx xxxxxxxx: Unicast address + * 100xxxxx xxxxxxxx: Multicast address + * 101xxxxx xxxxxxxx: Reserved + * 110xxxxx xxxxxxxx: Reserved + * 111xxxxx xxxxxxxx: Reserved + */ + + properties->sp_mcast.nv_addrlen = NET_6LOWPAN_SADDRSIZE; + memset(properties->sp_mcast.nv_addr, 0xff, RADIO_MAX_ADDRLEN); + + /* Broadcast address */ + + properties->sp_bcast.nv_addrlen = NET_6LOWPAN_SADDRSIZE; + memset(properties->sp_mcast.nv_addr, 0xff, RADIO_MAX_ADDRLEN); return OK; } diff --git a/wireless/ieee802154/mac802154_netdev.c b/wireless/ieee802154/mac802154_netdev.c index 5678b0460ad..16ae302a146 100644 --- a/wireless/ieee802154/mac802154_netdev.c +++ b/wireless/ieee802154/mac802154_netdev.c @@ -973,9 +973,32 @@ static int macnet_properties(FAR struct sixlowpan_driver_s *netdev, FAR struct sixlowpan_properties_s *properties) { DEBUGASSERT(netdev != NULL && properties != NULL); + memset(properties, 0, sizeof(struct sixlowpan_properties_s)); + + /* General */ properties->sp_addrlen = NET_6LOWPAN_ADDRSIZE; /* Length of an address */ properties->sp_pktlen = CONFIG_NET_6LOWPAN_FRAMELEN; /* Fixed frame length */ + + /* Multicast address (uses broadcast address) + * + * Multicast address should really determined by the first 3 bits + * (RFC 4944): + * + * 0xxxxxxx xxxxxxxx: Unicast address + * 100xxxxx xxxxxxxx: Multicast address + * 101xxxxx xxxxxxxx: Reserved + * 110xxxxx xxxxxxxx: Reserved + * 111xxxxx xxxxxxxx: Reserved + */ + + properties->sp_mcast.nv_addrlen = NET_6LOWPAN_SADDRSIZE; + memset(properties->sp_mcast.nv_addr, 0xff, RADIO_MAX_ADDRLEN); + + /* Broadcast address */ + + properties->sp_bcast.nv_addrlen = NET_6LOWPAN_SADDRSIZE; + memset(properties->sp_mcast.nv_addr, 0xff, RADIO_MAX_ADDRLEN); return OK; } diff --git a/wireless/pktradio/pktradio_loopback.c b/wireless/pktradio/pktradio_loopback.c index b04a26640dc..039a32002e9 100644 --- a/wireless/pktradio/pktradio_loopback.c +++ b/wireless/pktradio/pktradio_loopback.c @@ -751,7 +751,7 @@ static int lo_ioctl(FAR struct net_driver_s *dev, int cmd, FAR struct sixlowpan_properties_s *props = (FAR struct sixlowpan_properties_s *)&cmddata->pifr_props; - ret = spirit_properties(radio, props); + ret = lo_properties(radio, props); } break; @@ -932,9 +932,22 @@ static int lo_properties(FAR struct sixlowpan_driver_s *netdev, FAR struct sixlowpan_properties_s *properties) { DEBUGASSERT(netdev != NULL && properties != NULL); + memset(properties, 0, sizeof(struct sixlowpan_properties_s)); + + /* General */ properties->sp_addrlen = CONFIG_PKTRADIO_ADDRLEN; /* Length of an address */ properties->sp_pktlen = CONFIG_NET_6LOWPAN_FRAMELEN; /* Fixed frame length */ + + /* Multicast address */ + + properties->sp_mcast.nv_addrlen = CONFIG_PKTRADIO_ADDRLEN; + memset(properties->sp_mcast.nv_addr, 0xee, RADIO_MAX_ADDRLEN); + + /* Broadcast address */ + + properties->sp_bcast.nv_addrlen = CONFIG_PKTRADIO_ADDRLEN; + memset(properties->sp_mcast.nv_addr, 0xff, RADIO_MAX_ADDRLEN); return OK; }