mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2025-01-18 12:52:44 +01:00
gnrc_sixlowpan_frag: adapt for #8511
This refactors the `gnrc_sixlowpan_frag` module for the API proposed in #8511. The `ctx` for `gnrc_sixlowpan_frag_send()` is required to be a `gnrc_sixlowpan_msg_frag_t` object, so IPHC can later on use it to provide the *original* datagram size (otherwise, we would need to adapt the API just for that, which seems to me as convoluted as this proposal). I also provide an expose function with a future possibility to provide more than just one `gnrc_sixlowpan_msg_frag_t` object later on (plus having cleaner module separation in general).
This commit is contained in:
parent
d49e0d2f79
commit
a2eb3c7f15
@ -74,26 +74,45 @@ typedef struct {
|
||||
*/
|
||||
typedef struct {
|
||||
gnrc_pktsnip_t *pkt; /**< Pointer to the IPv6 packet to be fragmented */
|
||||
size_t datagram_size; /**< Length of just the IPv6 packet to be fragmented */
|
||||
size_t datagram_size; /**< Length of just the (uncompressed) IPv6 packet to be fragmented */
|
||||
uint16_t offset; /**< Offset of the Nth fragment from the beginning of the
|
||||
* payload datagram */
|
||||
kernel_pid_t pid; /**< PID of the interface */
|
||||
} gnrc_sixlowpan_msg_frag_t;
|
||||
|
||||
/**
|
||||
* @brief Sends a packet fragmented.
|
||||
* @brief Allocates a @ref gnrc_sixlowpan_msg_frag_t object
|
||||
*
|
||||
* @param[in] fragment_msg Message containing status of the 6LoWPAN
|
||||
* fragmentation progress
|
||||
* @return A @ref gnrc_sixlowpan_msg_frag_t if available
|
||||
* @return NULL, otherwise
|
||||
*/
|
||||
void gnrc_sixlowpan_frag_send(gnrc_sixlowpan_msg_frag_t *fragment_msg);
|
||||
gnrc_sixlowpan_msg_frag_t *gnrc_sixlowpan_msg_frag_get(void);
|
||||
|
||||
/**
|
||||
* @brief Handles a packet containing a fragment header.
|
||||
* @brief Sends a packet fragmented
|
||||
*
|
||||
* @param[in] pkt The packet to handle.
|
||||
* @pre `ctx != NULL`
|
||||
* @pre gnrc_sixlowpan_msg_frag_t::pkt of @p ctx is equal to @p pkt or
|
||||
* `pkt == NULL`.
|
||||
*
|
||||
* @param[in] pkt A packet. May be NULL.
|
||||
* @param[in] ctx Message containing status of the 6LoWPAN fragmentation
|
||||
* progress. Expected to be of type
|
||||
* @ref gnrc_sixlowpan_msg_frag_t, with
|
||||
* gnrc_sixlowpan_msg_frag_t set to @p pkt. Must not be
|
||||
* NULL.
|
||||
* @param[in] page Current 6Lo dispatch parsing page.
|
||||
*/
|
||||
void gnrc_sixlowpan_frag_handle_pkt(gnrc_pktsnip_t *pkt);
|
||||
void gnrc_sixlowpan_frag_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page);
|
||||
|
||||
/**
|
||||
* @brief Handles a packet containing a fragment header
|
||||
*
|
||||
* @param[in] pkt The packet to handle
|
||||
* @param[in] ctx Context for the packet. May be NULL.
|
||||
* @param[in] page Current 6Lo dispatch parsing page.
|
||||
*/
|
||||
void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -31,6 +31,10 @@
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
static gnrc_sixlowpan_msg_frag_t _fragment_msg = {
|
||||
NULL, 0, 0, KERNEL_PID_UNDEF
|
||||
};
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
/* For PRIu16 etc. */
|
||||
#include <inttypes.h>
|
||||
@ -209,8 +213,15 @@ static uint16_t _send_nth_fragment(gnrc_netif_t *iface, gnrc_pktsnip_t *pkt,
|
||||
return local_offset;
|
||||
}
|
||||
|
||||
void gnrc_sixlowpan_frag_send(gnrc_sixlowpan_msg_frag_t *fragment_msg)
|
||||
gnrc_sixlowpan_msg_frag_t *gnrc_sixlowpan_msg_frag_get(void)
|
||||
{
|
||||
return (_fragment_msg.pkt == NULL) ? &_fragment_msg : NULL;
|
||||
}
|
||||
|
||||
void gnrc_sixlowpan_frag_send(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
|
||||
{
|
||||
assert(ctx != NULL);
|
||||
gnrc_sixlowpan_msg_frag_t *fragment_msg = ctx;
|
||||
gnrc_netif_t *iface = gnrc_netif_get_by_pid(fragment_msg->pid);
|
||||
uint16_t res;
|
||||
/* payload_len: actual size of the packet vs
|
||||
@ -218,6 +229,9 @@ void gnrc_sixlowpan_frag_send(gnrc_sixlowpan_msg_frag_t *fragment_msg)
|
||||
size_t payload_len = gnrc_pkt_len(fragment_msg->pkt->next);
|
||||
msg_t msg;
|
||||
|
||||
assert((fragment_msg->pkt == pkt) || (pkt == NULL));
|
||||
(void)page;
|
||||
(void)pkt;
|
||||
#if defined(DEVELHELP) && ENABLE_DEBUG
|
||||
if (iface == NULL) {
|
||||
DEBUG("6lo frag: iface == NULL, expect segmentation fault.\n");
|
||||
@ -275,13 +289,15 @@ void gnrc_sixlowpan_frag_send(gnrc_sixlowpan_msg_frag_t *fragment_msg)
|
||||
}
|
||||
}
|
||||
|
||||
void gnrc_sixlowpan_frag_handle_pkt(gnrc_pktsnip_t *pkt)
|
||||
void gnrc_sixlowpan_frag_recv(gnrc_pktsnip_t *pkt, void *ctx, unsigned page)
|
||||
{
|
||||
gnrc_netif_hdr_t *hdr = pkt->next->data;
|
||||
sixlowpan_frag_t *frag = pkt->data;
|
||||
uint16_t offset = 0;
|
||||
size_t frag_size;
|
||||
|
||||
(void)ctx;
|
||||
(void)page;
|
||||
switch (frag->disp_size.u8[0] & SIXLOWPAN_FRAG_DISP_MASK) {
|
||||
case SIXLOWPAN_FRAG_1_DISP:
|
||||
frag_size = (pkt->size - sizeof(sixlowpan_frag_t));
|
||||
|
@ -34,10 +34,6 @@
|
||||
|
||||
static kernel_pid_t _pid = KERNEL_PID_UNDEF;
|
||||
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
|
||||
static gnrc_sixlowpan_msg_frag_t fragment_msg = {NULL, 0, 0, KERNEL_PID_UNDEF};
|
||||
#endif
|
||||
|
||||
#if ENABLE_DEBUG
|
||||
static char _stack[GNRC_SIXLOWPAN_STACK_SIZE + THREAD_EXTRA_STACKSIZE_PRINTF];
|
||||
#else
|
||||
@ -164,7 +160,7 @@ static void _receive(gnrc_pktsnip_t *pkt)
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
|
||||
else if (sixlowpan_frag_is((sixlowpan_frag_t *)dispatch)) {
|
||||
DEBUG("6lo: received 6LoWPAN fragment\n");
|
||||
gnrc_sixlowpan_frag_handle_pkt(pkt);
|
||||
gnrc_sixlowpan_frag_recv(pkt, NULL, 0);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@ -305,27 +301,24 @@ static void _send(gnrc_pktsnip_t *pkt)
|
||||
return;
|
||||
}
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
|
||||
else if (fragment_msg.pkt != NULL) {
|
||||
DEBUG("6lo: Fragmentation already ongoing. Dropping packet\n");
|
||||
gnrc_pktbuf_release(pkt2);
|
||||
return;
|
||||
}
|
||||
else if (datagram_size <= SIXLOWPAN_FRAG_MAX_LEN) {
|
||||
DEBUG("6lo: Send fragmented (%u > %" PRIu8 ")\n",
|
||||
(unsigned int)datagram_size, iface->sixlo.max_frag_size);
|
||||
msg_t msg;
|
||||
gnrc_sixlowpan_msg_frag_t *fragment_msg;
|
||||
|
||||
fragment_msg.pid = hdr->if_pid;
|
||||
fragment_msg.pkt = pkt2;
|
||||
fragment_msg.datagram_size = datagram_size;
|
||||
fragment_msg = gnrc_sixlowpan_msg_frag_get();
|
||||
if (fragment_msg == NULL) {
|
||||
DEBUG("6lo: Not enough resources to fragment packet. Dropping packet\n");
|
||||
gnrc_pktbuf_release(pkt2);
|
||||
return;
|
||||
}
|
||||
fragment_msg->pid = hdr->if_pid;
|
||||
fragment_msg->pkt = pkt2;
|
||||
fragment_msg->datagram_size = datagram_size;
|
||||
/* Sending the first fragment has an offset==0 */
|
||||
fragment_msg.offset = 0;
|
||||
fragment_msg->offset = 0;
|
||||
|
||||
/* set the outgoing message's fields */
|
||||
msg.type = GNRC_SIXLOWPAN_MSG_FRAG_SND;
|
||||
msg.content.ptr = &fragment_msg;
|
||||
/* send message to self */
|
||||
msg_send_to_self(&msg);
|
||||
gnrc_sixlowpan_frag_send(pkt2, fragment_msg, 0);
|
||||
}
|
||||
else {
|
||||
DEBUG("6lo: packet too big (%u > %" PRIu16 ")\n",
|
||||
@ -380,7 +373,7 @@ static void *_event_loop(void *args)
|
||||
#ifdef MODULE_GNRC_SIXLOWPAN_FRAG
|
||||
case GNRC_SIXLOWPAN_MSG_FRAG_SND:
|
||||
DEBUG("6lo: send fragmented event received\n");
|
||||
gnrc_sixlowpan_frag_send(msg.content.ptr);
|
||||
gnrc_sixlowpan_frag_send(NULL, msg.content.ptr, 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user