diff --git a/include/nuttx/wireless/ieee802154/ieee802154_mac.h b/include/nuttx/wireless/ieee802154/ieee802154_mac.h index f91fbbceae..93bd2ca76f 100644 --- a/include/nuttx/wireless/ieee802154/ieee802154_mac.h +++ b/include/nuttx/wireless/ieee802154/ieee802154_mac.h @@ -524,7 +524,7 @@ struct ieee802154_frame_meta_s uint8_t msdu_handle; /* Handle assoc. with MSDU */ /* Number of bytes contained in the MAC Service Data Unit (MSDU) - * to be transmitted by the MAC sublayer enitity + * to be transmitted by the MAC sublayer entity * Note: This could be a uint8_t but if anyone ever wants to use * non-standard frame lengths, they may want a length larger than * a uint8_t. diff --git a/net/sixlowpan/sixlowpan_framelist.c b/net/sixlowpan/sixlowpan_framelist.c index 048944d674..9d5756ed8b 100644 --- a/net/sixlowpan/sixlowpan_framelist.c +++ b/net/sixlowpan/sixlowpan_framelist.c @@ -218,7 +218,6 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, struct sixlowpan_addr_s bcastmac; uint16_t pktlen; uint16_t paysize; - uint16_t dest_panid; #ifdef CONFIG_NET_6LOWPAN_FRAG uint16_t outlen = 0; #endif @@ -238,6 +237,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, /* Set stream mode for all TCP packets, except FIN packets. */ +#if 0 /* Currently the frame type is always data */ if (destip->proto == IP_PROTO_TCP) { FAR const struct tcp_hdr_s *tcp = @@ -253,6 +253,7 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, g_packet_meta.type = FRAME_ATTR_TYPE_STREAM_END; } } +#endif /* The destination address will be tagged to each outbound packet. If the * argument destmac is NULL, we are sending a broadcast packet. @@ -312,14 +313,14 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, * PAN IDs are the same. */ - dest_panid = 0xffff; - (void)sixlowpan_src_panid(ieee, &dest_panid); + g_packet_meta.dpanid = 0xffff; + (void)sixlowpan_src_panid(ieee, &g_packet_meta.dpanid); /* Based on the collected attributes and addresses, construct the MAC meta * data structure that we need to interface with the IEEE802.15.4 MAC. */ - ret = sixlowpan_meta_data(dest_panid, &meta); + ret = sixlowpan_meta_data(ieee, &meta, 0); if (ret < 0) { nerr("ERROR: sixlowpan_meta_data() failed: %d\n", ret); @@ -528,14 +529,42 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, } /* Submit all of the fragments to the MAC. We send all frames back- - * to-back like this to eliminate any possible condition where some + * to-back like this to minimize any possible condition where some * frame which is not a fragment from this sequence from intervening. */ - ret = sixlowpan_frame_submit(ieee, &meta, qhead); - if (ret < 0) + paysize = 0; + for (iob = qhead; iob != NULL; iob = qhead) { - nerr("ERROR: sixlowpan_frame_submit() failed: %d\n", ret); + uint16_t newsize; + + /* Remove the IOB from the list */ + + qhead = iob->io_flink; + iob->io_flink = NULL; + + /* Re-construct the MAC meta data structure using the correct + * payload size for this frame (if it is different than the + * payload size of the previous frame). + */ + + newsize = iob->io_len - iob->io_offset; + if (newsize != paysize) + { + ret = sixlowpan_meta_data(ieee, &meta, newsize); + if (ret < 0) + { + nerr("ERROR: sixlowpan_meta_data() failed: %d\n", ret); + } + + paysize = newsize; + } + + ret = sixlowpan_frame_submit(ieee, &meta, iob); + if (ret < 0) + { + nerr("ERROR: sixlowpan_frame_submit() failed: %d\n", ret); + } } /* Update the datagram TAG value */ @@ -565,6 +594,16 @@ int sixlowpan_queue_frames(FAR struct ieee802154_driver_s *ieee, sixlowpan_dumpbuffer("Outgoing frame", (FAR const uint8_t *)iob->io_data, iob->io_len); + /* Re-construct the MAC meta data structure using the correct payload + * size for this frame. + */ + + ret = sixlowpan_meta_data(ieee, &meta, iob->io_len - iob->io_offset); + if (ret < 0) + { + nerr("ERROR: sixlowpan_meta_data() failed: %d\n", ret); + } + /* Submit the frame to the MAC */ ret = sixlowpan_frame_submit(ieee, &meta, iob); diff --git a/net/sixlowpan/sixlowpan_framer.c b/net/sixlowpan/sixlowpan_framer.c index f5c5c25966..b750156d36 100644 --- a/net/sixlowpan/sixlowpan_framer.c +++ b/net/sixlowpan/sixlowpan_framer.c @@ -147,9 +147,9 @@ static inline bool sixlowpan_eaddrnull(FAR uint8_t *eaddr) * data structure that we need to interface with the IEEE802.15.4 MAC. * * Input Parameters: - * dest_panid - PAN ID of the destination. May be 0xffff if the destination - * is not associated. - * meta - Location to return the corresponding meta data. + * ieee - IEEE 802.15.4 MAC driver state reference. + * meta - Location to return the corresponding meta data. + * paylen - The size of the data payload to be sent. * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -159,105 +159,97 @@ static inline bool sixlowpan_eaddrnull(FAR uint8_t *eaddr) * ****************************************************************************/ -int sixlowpan_meta_data(uint16_t dest_panid, - FAR struct ieee802154_frame_meta_s *meta) +int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee, + FAR struct ieee802154_frame_meta_s *meta, + uint16_t paylen) { -#if 0 /* To be provided */ - /* Set up the frame parameters */ - - uint16_t src_panid; bool rcvrnull; - /* Initialize all prameters to all zero */ + /* Initialize all settings to all zero */ memset(meta, 0, sizeof(struct ieee802154_frame_meta_s)); - /* Build the FCF (Only non-zero elements need to be initialized). */ + /* Source address mode */ - meta->fcf.frame_type = FRAME802154_DATAFRAME; - meta->fcf.frame_pending = g_packet_meta.pending; + meta->src_addr_mode = g_packet_meta.sextended != 0? + IEEE802154_ADDRMODE_EXTENDED : + IEEE802154_ADDRMODE_SHORT; - /* If the output address is NULL in the MAC header buf, then it is - * broadcast on the 802.15.4 network. - */ + /* Check for a broadcast destination address (all zero) */ if (g_packet_meta.dextended != 0) { + /* Extended destination address mode */ + rcvrnull = sixlowpan_eaddrnull(g_packet_meta.dest.eaddr.u8); } else { + /* Short destination address mode */ + rcvrnull = sixlowpan_saddrnull(g_packet_meta.dest.saddr.u8); } if (rcvrnull) { - meta->fcf.ack_required = g_packet_meta.macack; + meta->msdu_flags.ack_tx = TRUE; } - /* Insert IEEE 802.15.4 (2003) version bit. */ + /* Destination address */ - meta->fcf.frame_version = FRAME802154_IEEE802154_2003; - - /* Complete the addressing fields. */ - /* Get the source PAN ID from the IEEE802.15.4 radio driver */ - - src_panid = 0xffff; - (void)sixlowpan_src_panid(ieee, &src_panid); - - /* Set the source and destination PAN ID. */ - - meta->src_pid = src_panid; - meta->dest_pid = dest_panid; - - /* If the output address is NULL in the MAC header buf, then it is - * broadcast on the 802.15.4 network. + /* If the output address is NULL, then it is broadcast on the 802.15.4 + * network. */ if (rcvrnull) { /* Broadcast requires short address mode. */ - meta->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - meta->dest_addr[0] = 0xff; - meta->dest_addr[1] = 0xff; + meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT; + meta->dest_addr.saddr = 0; } else if (g_packet_meta.dextended != 0) { - meta->fcf.dest_addr_mode = FRAME802154_LONGADDRMODE; - sixlowpan_eaddrcopy((struct sixlowpan_addr_s *)&meta->dest_addr, - g_packet_meta.dest.eaddr.u8); + /* Extended destination address mode */ + + meta->dest_addr.mode = IEEE802154_ADDRMODE_EXTENDED; + sixlowpan_eaddrcopy(&meta->dest_addr.eaddr, g_packet_meta.dest.eaddr.u8); } else { - meta->fcf.dest_addr_mode = FRAME802154_SHORTADDRMODE; - sixlowpan_saddrcopy((struct sixlowpan_addr_s *)&meta->dest_addr, - g_packet_meta.dest.saddr.u8); + /* Short destination address mode */ + + meta->dest_addr.mode = IEEE802154_ADDRMODE_SHORT; + sixlowpan_saddrcopy(&meta->dest_addr.saddr, g_packet_meta.dest.saddr.u8); } -#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR - DEBUGASSERT(g_packet_meta.sextended != 0); - meta->fcf.src_addr_mode = FRAME802154_LONGADDRMODE; - sixlowpan_eaddrcopy((struct sixlowpan_addr_s *)&meta->src_addr, - g_packet_meta.source.eaddr.u8); -#else - DEBUGASSERT(g_packet_meta.sextended == 0); - meta->fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; - sixlowpan_saddrcopy((struct sixlowpan_addr_s *)&meta->src_addr, - g_packet_meta.source.saddr.u8); + meta->dest_addr.panid = g_packet_meta.dpanid; + + /* Handle associated with MSDU. Will increment once per packet, not + * necesarily per frame: The MSDU handler will be used for each fragment + * of a disassembled packet. + */ + + meta->msdu_handle = ieee->i_msdu_handle++; + + /* Number of bytes contained in the MAC Service Data Unit (MSDU) */ + + meta->msdu_length = paylen; + + /* MSDU flags that may be non-zero */ + + +#ifdef CONFIG_IEEE802154_SECURITY +# warning CONFIG_IEEE802154_SECURITY not yet supported" +#endif + +#ifdef CONFIG_IEEE802154_UWB +# warning CONFIG_IEEE802154_UWB not yet supported" #endif - /* Use short soruce address mode if so configured */ + /* Ranging left zero */ -#ifdef CONFIG_NET_6LOWPAN_EXTENDEDADDR - meta->fcf.src_addr_mode = FRAME802154_LONGADDRMODE; -#else - meta->fcf.src_addr_mode = FRAME802154_SHORTADDRMODE; -#endif -#endif /* 0 */ - -#warning Missing logic - return -ENOSYS; + return OK; } /**************************************************************************** diff --git a/net/sixlowpan/sixlowpan_internal.h b/net/sixlowpan/sixlowpan_internal.h index 7e3f45332a..1e38d46b65 100644 --- a/net/sixlowpan/sixlowpan_internal.h +++ b/net/sixlowpan/sixlowpan_internal.h @@ -80,7 +80,7 @@ #define sixlowpan_saddrcopy(dest,src) \ sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_SADDRSIZE) -#define sixlowpan_aeddrcopy(dest,src) \ +#define sixlowpan_eaddrcopy(dest,src) \ sixlowpan_anyaddrcopy(dest,src,NET_6LOWPAN_EADDRSIZE) #define sixlowpan_addrcopy(dest,src) \ @@ -100,14 +100,6 @@ #define sixlowpan_addrcmp(addr1,addr2) \ sixlowpan_anyaddrcmp(addr1,addr2,NET_6LOWPAN_ADDRSIZE) -/* Frame meta data definitions */ - -#define FRAME_ATTR_TYPE_DATA 0 -#define FRAME_ATTR_TYPE_ACK 1 -#define FRAME_ATTR_TYPE_STREAM 2 -#define FRAME_ATTR_TYPE_STREAM_END 3 -#define FRAME_ATTR_TYPE_TIMESTAMP 4 - /* General helper macros ****************************************************/ #define GETINT16(ptr,index) \ @@ -171,12 +163,10 @@ struct ipv6icmp_hdr_s struct packet_metadata_s { - uint8_t type : 3; /* See FRAME_ATTR_TYPE_* definitons */ - uint8_t pending : 1; /* Pending attribute */ - uint8_t macack : 1; /* MAC ACK */ uint8_t sextended : 1; /* Extended source address */ uint8_t dextended : 1; /* Extended destination address */ uint8_t xmits; /* Max MAC transmisstion */ + uint16_t dpanid; /* Destination PAN ID */ union sixlowpan_anyaddr_u source; /* Source IEEE 802.15.4 address */ union sixlowpan_anyaddr_u dest; /* Destination IEEE 802.15.4 address */ }; @@ -271,9 +261,9 @@ int sixlowpan_send(FAR struct net_driver_s *dev, * data structure that we need to interface with the IEEE802.15.4 MAC. * * Input Parameters: - * dest_panid - PAN ID of the destination. May be 0xffff if the destination - * is not associated. - * meta - Location to return the corresponding meta data. + * ieee - IEEE 802.15.4 MAC driver state reference. + * meta - Location to return the corresponding meta data. + * paylen - The size of the data payload to be sent. * * Returned Value: * Ok is returned on success; Othewise a negated errno value is returned. @@ -283,8 +273,9 @@ int sixlowpan_send(FAR struct net_driver_s *dev, * ****************************************************************************/ -int sixlowpan_meta_data(uint16_t dest_panid, - FAR struct ieee802154_frame_meta_s *meta); +int sixlowpan_meta_data(FAR struct ieee802154_driver_s *ieee, + FAR struct ieee802154_frame_meta_s *meta, + uint16_t paylen); /**************************************************************************** * Name: sixlowpan_frame_hdrlen