Example #1
0
void ng_sixlowpan_frag_send(kernel_pid_t pid, ng_pktsnip_t *pkt,
                            size_t payload_len, size_t datagram_size)
{
    ng_sixlowpan_netif_t *iface = ng_sixlowpan_netif_get(pid);
    uint16_t offset = 0, res;

#if defined(DEVELHELP) && defined(ENABLE_DEBUG)
    if (iface == NULL) {
        DEBUG("6lo frag: iface == NULL, expect segmentation fault.\n");
        ng_pktbuf_release(pkt);
        return;
    }
#endif

    if ((res = _send_1st_fragment(iface, pkt, payload_len, datagram_size)) == 0) {
        /* error sending first fragment */
        DEBUG("6lo frag: error sending 1st fragment\n");
        ng_pktbuf_release(pkt);
        return;
    }

    offset += res;

    while (offset < datagram_size) {
        if ((res = _send_nth_fragment(iface, pkt, payload_len, datagram_size,
                                      offset)) == 0) {
            /* error sending subsequent fragment */
            DEBUG("6lo frag: error sending subsequent fragment (offset = %" PRIu16
                  ")\n", offset);
            ng_pktbuf_release(pkt);
            return;
        }

        offset += res;
    }

    /* remove original packet from packet buffer */
    ng_pktbuf_release(pkt);
    _tag++;
}
Example #2
0
static void _send(ng_pktsnip_t *pkt)
{
    ng_netif_hdr_t *hdr;
    ng_pktsnip_t *ipv6, *sixlowpan;
    ng_sixlowpan_netif_t *iface;
    /* cppcheck: datagram_size will be read by frag */
    /* cppcheck-suppress unreadVariable */
    size_t payload_len, datagram_size;
    uint16_t max_frag_size;
    /* cppcheck: disp is needed in other build paths on this level already */
    /* cppcheck-suppress variableScope */
    uint8_t *disp;

    if ((pkt == NULL) || (pkt->size < sizeof(ng_netif_hdr_t))) {
        DEBUG("6lo: Sending packet has no netif header\n");
        ng_pktbuf_release(pkt);
        return;
    }

    hdr = pkt->data;
    ipv6 = pkt->next;

    if ((ipv6 == NULL) || (ipv6->type != NG_NETTYPE_IPV6)) {
        DEBUG("6lo: Sending packet has no IPv6 header\n");
        ng_pktbuf_release(pkt);
        return;
    }

    /* payload length and datagram size are different in that the payload
     * length is the length of the IPv6 datagram + 6LoWPAN dispatches,
     * while the datagram size is the size of only the IPv6 datagram */
    payload_len = ng_pkt_len(ipv6);
    /* cppcheck: datagram_size will be read by ng_sixlowpan_frag implementation */
    /* cppcheck-suppress unreadVariable */
    datagram_size = (uint16_t)payload_len;

    /* use sixlowpan packet snip as temporary one */
    sixlowpan = ng_pktbuf_start_write(pkt);

    if (sixlowpan == NULL) {
        DEBUG("6lo: no space left in packet buffer\n");
        ng_pktbuf_release(pkt);
        return;
    }

    pkt = sixlowpan;
    iface = ng_sixlowpan_netif_get(hdr->if_pid);

    if (iface == NULL) {
        if (ng_netapi_get(hdr->if_pid, NETCONF_OPT_MAX_PACKET_SIZE,
                          0, &max_frag_size, sizeof(max_frag_size)) < 0) {
            /* if error we assume it works */
            DEBUG("6lo: can not get max packet size from interface %"
                  PRIkernel_pid "\n", hdr->if_pid);
            max_frag_size = UINT16_MAX;
        }

        ng_sixlowpan_netif_add(hdr->if_pid, max_frag_size);
        iface = ng_sixlowpan_netif_get(hdr->if_pid);
    }
    else {
        max_frag_size = iface->max_frag_size;
    }

#ifdef MODULE_NG_SIXLOWPAN_IPHC
    if (iface->iphc_enabled) {
        if (!ng_sixlowpan_iphc_encode(pkt)) {
            DEBUG("6lo: error on IPHC encoding\n");
            ng_pktbuf_release(pkt);
            return;
        }
    }
    else {
        DEBUG("6lo: Send uncompressed\n");

        sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t),
                                  NG_NETTYPE_SIXLOWPAN);

        if (sixlowpan == NULL) {
            DEBUG("6lo: no space left in packet buffer\n");
            ng_pktbuf_release(pkt);
            return;
        }

        sixlowpan->next = ipv6;
        pkt->next = sixlowpan;
        disp = sixlowpan->data;
        disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
        payload_len++;
    }
#else
    DEBUG("6lo: Send uncompressed\n");

    sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t), NG_NETTYPE_SIXLOWPAN);

    if (sixlowpan == NULL) {
        DEBUG("6lo: no space left in packet buffer\n");
        ng_pktbuf_release(pkt);
        return;
    }

    sixlowpan->next = ipv6;
    pkt->next = sixlowpan;
    disp = sixlowpan->data;
    disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
    payload_len++;
#endif

    DEBUG("6lo: max_frag_size = %" PRIu16 " for interface %"
          PRIkernel_pid "\n", max_frag_size, hdr->if_pid);

    /* IP should not send anything here if it is not a 6LoWPAN interface,
     * so we don't need to check for NULL pointers */
    if (payload_len <= max_frag_size) {
        DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
              (void *)pkt, hdr->if_pid);
        ng_netapi_send(hdr->if_pid, pkt);

        return;
    }
#ifdef MODULE_NG_SIXLOWPAN_FRAG
    else {
        DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
              (unsigned int)payload_len, max_frag_size);
        ng_sixlowpan_frag_send(hdr->if_pid, pkt, payload_len, datagram_size);
    }
#else
    (void)datagram_size;
    DEBUG("6lo: packet too big (%u> %" PRIu16 ")\n",
          (unsigned int)payload_len, max_frag_size);
#endif
}
Example #3
0
void ng_sixlowpan_netif_remove(kernel_pid_t pid)
{
    ng_sixlowpan_netif_t *entry = ng_sixlowpan_netif_get(pid);

    entry->pid = KERNEL_PID_UNDEF;
}
Example #4
0
static void _send(ng_pktsnip_t *pkt)
{
    ng_netif_hdr_t *hdr;
    ng_pktsnip_t *pkt2;
    ng_sixlowpan_netif_t *iface;
    /* datagram_size: pure IPv6 packet without 6LoWPAN dispatches or compression */
    size_t datagram_size;

    if ((pkt == NULL) || (pkt->size < sizeof(ng_netif_hdr_t))) {
        DEBUG("6lo: Sending packet has no netif header\n");
        ng_pktbuf_release(pkt);
        return;
    }

    if ((pkt->next == NULL) || (pkt->next->type != NG_NETTYPE_IPV6)) {
        DEBUG("6lo: Sending packet has no IPv6 header\n");
        ng_pktbuf_release(pkt);
        return;
    }

    pkt2 = ng_pktbuf_start_write(pkt);

    if (pkt2 == NULL) {
        DEBUG("6lo: no space left in packet buffer\n");
        ng_pktbuf_release(pkt);
        return;
    }

    hdr = pkt2->data;
    iface = ng_sixlowpan_netif_get(hdr->if_pid);
    datagram_size = ng_pkt_len(pkt2->next);

    if (iface == NULL) {
        DEBUG("6lo: Can not get 6LoWPAN specific interface information.\n");
        ng_pktbuf_release(pkt);
        return;
    }

#ifdef MODULE_NG_SIXLOWPAN_IPHC
    if (iface->iphc_enabled) {
        if (!ng_sixlowpan_iphc_encode(pkt2)) {
            DEBUG("6lo: error on IPHC encoding\n");
            ng_pktbuf_release(pkt2);
            return;
        }
        /* IPHC dispatch does not count on dispatch length since it _shortens_
         * the datagram */
    }
    else {
        if (!_add_uncompr_disp(pkt2)) {
            /* adding uncompressed dispatch failed */
            DEBUG("6lo: no space left in packet buffer\n");
            ng_pktbuf_release(pkt2);
            return;
        }
    }
#else
    /* suppress clang-analyzer report about iface being not read */
    (void) iface;
    if (!_add_uncompr_disp(pkt2)) {
        /* adding uncompressed dispatch failed */
        DEBUG("6lo: no space left in packet buffer\n");
        ng_pktbuf_release(pkt2);
        return;
    }
#endif
    DEBUG("6lo: iface->max_frag_size = %" PRIu16 " for interface %"
          PRIkernel_pid "\n", iface->max_frag_size, hdr->if_pid);

    /* IP should not send anything here if it is not a 6LoWPAN interface,
     * so we don't need to check for NULL pointers */
    if (datagram_size <= iface->max_frag_size) {
        DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
              (void *)pkt2, hdr->if_pid);
        ng_netapi_send(hdr->if_pid, pkt2);

        return;
    }
#ifdef MODULE_NG_SIXLOWPAN_FRAG
    else {
        DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
              (unsigned int)datagram_size, iface->max_frag_size);
        ng_sixlowpan_frag_send(hdr->if_pid, pkt2, datagram_size);
    }
#else
    (void)datagram_size;
    DEBUG("6lo: packet too big (%u> %" PRIu16 ")\n",
          (unsigned int)datagram_size, iface->max_frag_size);
#endif
}