diff --git a/drivers/wireless/spirit/drivers/Kconfig b/drivers/wireless/spirit/drivers/Kconfig index 67c7726de3..a0b1892ed9 100644 --- a/drivers/wireless/spirit/drivers/Kconfig +++ b/drivers/wireless/spirit/drivers/Kconfig @@ -24,15 +24,15 @@ config SPIRIT_PKTLEN Fixed pkt sizes are used. This setting describes that fixed packet size. - "Sometimes Spirit1 seems to NOT deliver (correctly) the 'IRQ_RX_DATA_READY' - event for packets which have a length which is close to a multiple of - RX FIFO size. Furthermore, in these cases also the content delivery seems - to be compromised as well as the generation of RX/TX FIFO errors. - This can be avoided by reducing the maximum packet length to a value which - is lower than the RX FIFO size." - - Also, with a packet size of 96, I have seen CRC failures on the receiving - side. With a packet size of 94, CRC filtering behaves well. + This comment exists in the STMicro Spirit driver. I have not + experienced this myself, but this is something you should be aware + of: "Sometimes Spirit1 seems to NOT deliver (correctly) the + 'IRQ_RX_DATA_READY' event for packets which have a length which is + close to a multiple of RX FIFO size. Furthermore, in these cases + also the content delivery seems to be compromised as well as the + generation of RX/TX FIFO errors. This can be avoided by reducing + the maximum packet length to a value which is lower than the RX FIFO + size." config SPIRIT_FIFOS bool "FIFO Watermarks" @@ -48,12 +48,15 @@ config SPIRIT_FIFOS occurrences of RX FIFO errors if the packet size is less than but close to 96. - "Sometimes Spirit1 seems to NOT deliver (correctly) the 'IRQ_RX_DATA_READY' - event for packets which have a length which is close to a multiple of - RX FIFO size. Furthermore, in these cases also the content delivery seems - to be compromised as well as the generation of RX/TX FIFO errors. - This can be avoided by reducing the maximum packet length to a value which - is lower than the RX FIFO size." + This comment exists in the STMicro Spirit driver. I have not + experienced this myself, but this is something you should be aware + of: "Sometimes Spirit1 seems to NOT deliver (correctly) the + 'IRQ_RX_DATA_READY' event for packets which have a length which is + close to a multiple of RX FIFO size. Furthermore, in these cases + also the content delivery seems to be compromised as well as the + generation of RX/TX FIFO errors. This can be avoided by reducing + the maximum packet length to a value which is lower than the RX FIFO + size." From my reading, the only known work-around is to reduce the maximum packet size so that it is smaller than 96. Hence, this option is @@ -86,6 +89,13 @@ config SPIRIT_CRCDISABLE ---help--- Disables CRC calculation and filtering. Default is enabled. + Errata: "Using the STack packet format and no CRC field, the + reading from RX FIFO to the last received byte, is not possible. ..." + Workaround: "By configuring the packet handler with at least one byte + of CRC, the problem is solved. If the CRC is not required in the + application, configure one byte of CRC in the receiver only, to read + the payload correctly from RX FIFO." + config SPIRIT_HUBNODE hex "Address of hub node" default 0x34 diff --git a/net/inet/inet.h b/net/inet/inet.h index 4a4f97b833..947e99d733 100644 --- a/net/inet/inet.h +++ b/net/inet/inet.h @@ -92,8 +92,8 @@ EXTERN uint16_t g_ipid; #ifdef CONFIG_NET_IPv6 EXTERN const net_ipv6addr_t g_ipv6_allzeroaddr; /* An address of all zeroes */ -#if defined(CONFIG_NET_ICMPv6_AUTOCONF) || defined(CONFIG_NET_ICMPv6_ROUTER) EXTERN const net_ipv6addr_t g_ipv6_allnodes; /* All link local nodes */ +#if defined(CONFIG_NET_ICMPv6_AUTOCONF) || defined(CONFIG_NET_ICMPv6_ROUTER) EXTERN const net_ipv6addr_t g_ipv6_allrouters; /* All link local routers */ #ifdef CONFIG_NET_ICMPv6_AUTOCONF EXTERN const net_ipv6addr_t g_ipv6_llnetmask; /* Netmask for local link address */ diff --git a/net/sixlowpan/sixlowpan_utils.c b/net/sixlowpan/sixlowpan_utils.c index 5da752882d..bd9bb36722 100644 --- a/net/sixlowpan/sixlowpan_utils.c +++ b/net/sixlowpan/sixlowpan_utils.c @@ -53,10 +53,12 @@ #include #include +#include #include #include #include +#include "inet/inet.h" #include "sixlowpan/sixlowpan_internal.h" #ifdef CONFIG_NET_6LOWPAN @@ -233,9 +235,7 @@ int sixlowpan_destaddrfromip(FAR struct sixlowpan_driver_s *radio, * disturbing every interface in the network. */ - if (ipaddr[1] == 0 && ipaddr[2] == 0 && ipaddr[3] == 0 && - ipaddr[4] == 0 && ipaddr[5] == 0 && ipaddr[5] == 0 && - ipaddr[7] == HTONS(0x0001)) + if (net_ipv6addr_cmp(ipaddr, g_ipv6_allnodes)) { memcpy(destaddr, &properties.sp_bcast, sizeof(struct netdev_varaddr_s)); diff --git a/net/udp/udp_conn.c b/net/udp/udp_conn.c index 11913f8581..514d2ac059 100644 --- a/net/udp/udp_conn.c +++ b/net/udp/udp_conn.c @@ -277,6 +277,9 @@ static uint16_t udp_select_port(void) static inline FAR struct udp_conn_s * udp_ipv4_active(FAR struct net_driver_s *dev, FAR struct udp_hdr_s *udp) { +#ifdef CONFIG_NET_BROADCAST + static const inaddr_t bcast = INADDR_BROADCAST; +#endif FAR struct ipv4_hdr_s *ip = IPv4BUF; FAR struct udp_conn_s *conn; @@ -315,13 +318,26 @@ static inline FAR struct udp_conn_s * if (conn->lport != 0 && udp->destport == conn->lport && (conn->rport == 0 || udp->srcport == conn->rport) && + #ifdef CONFIG_NETDEV_MULTINIC + /* Local port accepts any address on this port or there + * is an exact match in destipaddr and the bound local + * address. This catches the receipt of a broadcast when + * the socket is bound to INADDR_ANY. + */ + (net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_ANY) || - net_ipv4addr_cmp(conn->u.ipv4.laddr, INADDR_BROADCAST) || net_ipv4addr_hdrcmp(ip->destipaddr, &conn->u.ipv4.laddr)) && #endif + /* If not connected to a remote address, or a broadcast address + * destipaddr was received, or there is an exact match between the + * srcipaddr and the bound IP address, then accept the packet. + */ + (net_ipv4addr_cmp(conn->u.ipv4.raddr, INADDR_ANY) || - net_ipv4addr_cmp(conn->u.ipv4.raddr, INADDR_BROADCAST) || +#ifdef CONFIG_NET_BROADCAST + net_ipv4addr_hdrcmp(ip->destipaddr, &bcast) || +#endif net_ipv4addr_hdrcmp(ip->srcipaddr, &conn->u.ipv4.raddr))) { /* Matching connection found.. return a reference to it */ @@ -370,7 +386,7 @@ static inline FAR struct udp_conn_s * * - If multiple network interfaces are supported, then the local * IP address is available and we will insist that the * destination IP matches the bound address. If a socket is bound to - * INADDRY_ANY (laddr), then it should receive all packets directed + * INADDR6_ANY (laddr), then it should receive all packets directed * to the port. REVISIT: Should also depend on SO_BROADCAST. * - Finally, if the connection is bound to a remote IP address, * the source IP address of the packet is checked. @@ -380,7 +396,8 @@ static inline FAR struct udp_conn_s * * * To send and receive multicast packets, the application should: * - * - Bind socket to INADDR6_ANY or to a specific + * - Bind socket to INADDR6_ANY (for the all-nodes multicast address) + * or to a specific * - setsockopt to SO_BROADCAST (for all-nodes address) * - call sendto with sendaddr.sin_addr.s_addr = * - call recvfrom. @@ -390,11 +407,27 @@ static inline FAR struct udp_conn_s * if (conn->lport != 0 && udp->destport == conn->lport && (conn->rport == 0 || udp->srcport == conn->rport) && + #ifdef CONFIG_NETDEV_MULTINIC + /* Local port accepts any address on this port or there + * is an exact match in destipaddr and the bound local + * address. This catches the cast of the all nodes multicast + * when the socket is bound to INADDR6_ANY. + */ + (net_ipv6addr_cmp(conn->u.ipv6.laddr, g_ipv6_allzeroaddr) || net_ipv6addr_hdrcmp(ip->destipaddr, conn->u.ipv6.laddr)) && #endif + /* If not connected to a remote address, or a all-nodes multicast + * destipaddr was received, or there is an exact match between the + * srcipaddr and the bound remote IP address, then accept the + * packet. + */ + (net_ipv6addr_cmp(conn->u.ipv6.raddr, g_ipv6_allzeroaddr) || +#ifdef CONFIG_NET_BROADCAST + net_ipv6addr_hdrcmp(ip->destipaddr, g_ipv6_allnodes) || +#endif net_ipv6addr_hdrcmp(ip->srcipaddr, conn->u.ipv6.raddr))) { /* Matching connection found.. return a reference to it */