Lines Matching +full:4 +full:- +full:byte

4 …* 6LowPAN output for IPv6. Uses ND tables for link-layer addressing. Fragments packets to 6LowPAN …
6 * This implementation aims to conform to IEEE 802.15.4(-2015), RFC 4944 and RFC 6282.
75 * (IEEE 802.15.4 limits to 127 bytes)
87 /** This struct keeps track of per-netif state */
97 /** local PAN ID for IEEE 802.15.4 header */
99 /** Sequence Number for IEEE 802.15.4 transmission */
104 #define LOWPAN6_MAX_PAYLOAD (127 - 2)
121 /* IEEE 802.15.4 specific functions: */
123 /** Write the IEEE 802.15.4 header that encapsulates the 6LoWPAN frame.
143 if (dst->addr_len == 2) { in lowpan6_write_iee802154_header()
146 LWIP_ASSERT("invalid dst address length", dst->addr_len == 8); in lowpan6_write_iee802154_header()
149 if (src->addr_len == 2) { in lowpan6_write_iee802154_header()
152 LWIP_ASSERT("invalid src address length", src->addr_len == 8); in lowpan6_write_iee802154_header()
155 hdr->frame_control = fc; in lowpan6_write_iee802154_header()
156 hdr->sequence_number = lowpan6_data.tx_frame_seq_num++; in lowpan6_write_iee802154_header()
157 hdr->destination_pan_id = lowpan6_data.ieee_802154_pan_id; /* pan id */ in lowpan6_write_iee802154_header()
161 i = dst->addr_len; in lowpan6_write_iee802154_header()
163 while (i-- > 0) { in lowpan6_write_iee802154_header()
164 buffer[ieee_header_len++] = dst->addr[i]; in lowpan6_write_iee802154_header()
167 i = src->addr_len; in lowpan6_write_iee802154_header()
169 while (i-- > 0) { in lowpan6_write_iee802154_header()
170 buffer[ieee_header_len++] = src->addr[i]; in lowpan6_write_iee802154_header()
175 /** Parse the IEEE 802.15.4 header from a pbuf.
180 * @param p input pbuf, p->payload pointing at the IEEE 802.15.4 header
194 /* Parse IEEE 802.15.4 header */ in lowpan6_parse_iee802154_header()
195 puc = (u8_t *)p->payload; in lowpan6_parse_iee802154_header()
210 dest->addr_len = 8; in lowpan6_parse_iee802154_header()
213 dest->addr[i] = puc[datagram_offset + 7 - i]; in lowpan6_parse_iee802154_header()
218 dest->addr_len = 2; in lowpan6_parse_iee802154_header()
220 dest->addr[0] = puc[datagram_offset + 1]; in lowpan6_parse_iee802154_header()
221 dest->addr[1] = puc[datagram_offset]; in lowpan6_parse_iee802154_header()
236 src->addr_len = 8; in lowpan6_parse_iee802154_header()
239 src->addr[i] = puc[datagram_offset + 7 - i]; in lowpan6_parse_iee802154_header()
244 src->addr_len = 2; in lowpan6_parse_iee802154_header()
245 src->addr[0] = puc[datagram_offset + 1]; in lowpan6_parse_iee802154_header()
246 src->addr[1] = puc[datagram_offset]; in lowpan6_parse_iee802154_header()
260 /** Calculate the 16-bit CRC as required by IEEE 802.15.4 */
290 if (lrh->reass) { in free_reass_datagram()
291 pbuf_free(lrh->reass); in free_reass_datagram()
293 if (lrh->frags) { in free_reass_datagram()
294 pbuf_free(lrh->frags); in free_reass_datagram()
306 lowpan6_data.reass_list = lowpan6_data.reass_list->next_packet; in dequeue_datagram()
310 prev->next_packet = lrh->next_packet; in dequeue_datagram()
317 * - Remove incomplete/old packets
326 lrh_next = lrh->next_packet; in lowpan6_tmr()
327 if ((--lrh->timer) == 0) { in lowpan6_tmr()
338 * Encapsulates data into IEEE 802.15.4 frames.
339 * Fragments an IPv6 datagram into 6LowPAN units, which fit into IEEE 802.15.4 frames.
355 LWIP_ASSERT("lowpan6_frag: netif->linkoutput not set", netif->linkoutput != NULL); in lowpan6_frag()
363 LWIP_ASSERT("this needs a pbuf in one piece", p_frag->len == p_frag->tot_len); in lowpan6_frag()
365 /* Write IEEE 802.15.4 header. */ in lowpan6_frag()
366 buffer = (u8_t *)p_frag->payload; in lowpan6_frag()
368 LWIP_ASSERT("ieee_header_len < p_frag->len", ieee_header_len < p_frag->len); in lowpan6_frag()
372 /* do the header compression (this does NOT copy any non-compressed data) */ in lowpan6_frag()
373 err = lowpan6_compress_headers(netif, (u8_t *)p->payload, p->len, in lowpan6_frag()
374 &buffer[ieee_header_len], p_frag->len - ieee_header_len, &lowpan6_header_len, in lowpan6_frag()
384 /* Send uncompressed IPv6 header with appropriate dispatch byte. */ in lowpan6_frag()
390 remaining_len = p->tot_len; in lowpan6_frag()
400 max_data_len = LOWPAN6_MAX_PAYLOAD - ieee_header_len - lowpan6_header_len; in lowpan6_frag()
404 memmove(&buffer[ieee_header_len + 4], &buffer[ieee_header_len], lowpan6_header_len); in lowpan6_frag()
407 buffer[ieee_header_len] = 0xc0 | (((p->tot_len + hidden_header_len) >> 8) & 0x7); in lowpan6_frag()
408 buffer[ieee_header_len + 1] = (p->tot_len + hidden_header_len) & 0xff; in lowpan6_frag()
415 data_len = (max_data_len - 4) & 0xf8; in lowpan6_frag()
418 …pbuf_copy_partial(p, buffer + ieee_header_len + lowpan6_header_len + 4, frag_len - lowpan6_header_… in lowpan6_frag()
419 remaining_len -= frag_len - lowpan6_header_len; in lowpan6_frag()
421 datagram_offset = frag_len - lowpan6_header_len + hidden_header_len; in lowpan6_frag()
425 p_frag->len = p_frag->tot_len = ieee_header_len + 4 + frag_len + 2; /* add 2 bytes for crc*/ in lowpan6_frag()
428 crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2); in lowpan6_frag()
429 pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2); in lowpan6_frag()
432 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); in lowpan6_frag()
434 err = netif->linkoutput(netif, p_frag); in lowpan6_frag()
439 hdr->sequence_number = lowpan6_data.tx_frame_seq_num++; in lowpan6_frag()
444 …buffer[ieee_header_len + 4] = (u8_t)(datagram_offset >> 3); /* datagram offset in FRAGN header (da… in lowpan6_frag()
446 frag_len = (127 - ieee_header_len - 5 - 2) & 0xf8; in lowpan6_frag()
451 pbuf_copy_partial(p, buffer + ieee_header_len + 5, frag_len, p->tot_len - remaining_len); in lowpan6_frag()
452 remaining_len -= frag_len; in lowpan6_frag()
456 p_frag->len = p_frag->tot_len = frag_len + 5 + ieee_header_len + 2; in lowpan6_frag()
459 crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2); in lowpan6_frag()
460 pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2); in lowpan6_frag()
463 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); in lowpan6_frag()
465 err = netif->linkoutput(netif, p_frag); in lowpan6_frag()
476 p_frag->len = p_frag->tot_len = frag_len + lowpan6_header_len + ieee_header_len + 2; in lowpan6_frag()
477 LWIP_ASSERT("", p_frag->len <= 127); in lowpan6_frag()
480 crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->payload, p_frag->len - 2); in lowpan6_frag()
481 pbuf_take_at(p_frag, &crc, 2, p_frag->len - 2); in lowpan6_frag()
484 MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p_frag->tot_len); in lowpan6_frag()
486 err = netif->linkoutput(netif, p_frag); in lowpan6_frag()
533 /* Create IEEE 802.15.4 address from netif address */
537 addr->addr_len = 8; in lowpan6_hwaddr_to_addr()
538 if (netif->hwaddr_len == 8) { in lowpan6_hwaddr_to_addr()
539 LWIP_ERROR("NETIF_MAX_HWADDR_LEN >= 8 required", sizeof(netif->hwaddr) >= 8, return ERR_VAL;); in lowpan6_hwaddr_to_addr()
540 SMEMCPY(addr->addr, netif->hwaddr, 8); in lowpan6_hwaddr_to_addr()
541 } else if (netif->hwaddr_len == 6) { in lowpan6_hwaddr_to_addr()
542 /* Copy from MAC-48 */ in lowpan6_hwaddr_to_addr()
543 SMEMCPY(addr->addr, netif->hwaddr, 3); in lowpan6_hwaddr_to_addr()
544 addr->addr[3] = addr->addr[4] = 0xff; in lowpan6_hwaddr_to_addr()
545 SMEMCPY(&addr->addr[5], &netif->hwaddr[3], 3); in lowpan6_hwaddr_to_addr()
555 * Resolve and fill-in IEEE 802.15.4 address header for outgoing IPv6 packet.
578 ip6_hdr = (struct ip6_hdr *)q->payload; in lowpan6_output()
579 ip6_addr_copy_from_packed(ip6_src, ip6_hdr->src); in lowpan6_output()
608 * is also compressable to 2-bytes, assume we can infer dest as a short address too. */ in lowpan6_output()
610 dest.addr[0] = ((u8_t *)q->payload)[38]; in lowpan6_output()
611 dest.addr[1] = ((u8_t *)q->payload)[39]; in lowpan6_output()
612 if ((src.addr_len == 2) && (ip6_addr_netcmp_zoneless(&ip6_hdr->src, &ip6_hdr->dest)) && in lowpan6_output()
659 MIB2_STATS_NETIF_ADD(netif, ifinoctets, p->tot_len); in lowpan6_input()
661 if (p->len != p->tot_len) { in lowpan6_input()
671 puc = (u8_t *)p->payload; in lowpan6_input()
683 lrh_next = lrh->next_packet; in lowpan6_input()
684 if ((lrh->sender_addr.addr_len == src.addr_len) && in lowpan6_input()
685 (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0)) { in lowpan6_input()
687 if ((datagram_tag == lrh->datagram_tag) && (datagram_size == lrh->datagram_size)) { in lowpan6_input()
705 pbuf_remove_header(p, 4); /* hide frag1 dispatch */ in lowpan6_input()
712 lrh->sender_addr.addr_len = src.addr_len; in lowpan6_input()
714 lrh->sender_addr.addr[i] = src.addr[i]; in lowpan6_input()
716 lrh->datagram_size = datagram_size; in lowpan6_input()
717 lrh->datagram_tag = datagram_tag; in lowpan6_input()
718 lrh->frags = NULL; in lowpan6_input()
719 if (*(u8_t *)p->payload == 0x41) { in lowpan6_input()
720 /* This is a complete IPv6 packet, just skip dispatch byte. */ in lowpan6_input()
721 pbuf_remove_header(p, 1); /* hide dispatch byte. */ in lowpan6_input()
722 lrh->reass = p; in lowpan6_input()
723 } else if ((*(u8_t *)p->payload & 0xe0 ) == 0x60) { in lowpan6_input()
724 lrh->reass = lowpan6_decompress(p, datagram_size, LWIP_6LOWPAN_CONTEXTS(netif), &src, &dest); in lowpan6_input()
725 if (lrh->reass == NULL) { in lowpan6_input()
732 lrh->next_packet = lowpan6_data.reass_list; in lowpan6_input()
733 lrh->timer = 2; in lowpan6_input()
741 datagram_offset = (u16_t)puc[4] << 3; in lowpan6_input()
742 pbuf_remove_header(p, 4); /* hide frag1 dispatch but keep datagram offset for reassembly */ in lowpan6_input()
744 for (lrh = lowpan6_data.reass_list; lrh != NULL; lrh_prev = lrh, lrh = lrh->next_packet) { in lowpan6_input()
745 if ((lrh->sender_addr.addr_len == src.addr_len) && in lowpan6_input()
746 (memcmp(lrh->sender_addr.addr, src.addr, src.addr_len) == 0) && in lowpan6_input()
747 (datagram_tag == lrh->datagram_tag) && in lowpan6_input()
748 (datagram_size == lrh->datagram_size)) { in lowpan6_input()
758 LWIP_ASSERT("p->next == NULL", p->next == NULL); in lowpan6_input()
759 if (lrh->reass != NULL) { in lowpan6_input()
761 if (datagram_offset < lrh->reass->len) { in lowpan6_input()
768 if (lrh->frags == NULL) { in lowpan6_input()
770 lrh->frags = p; in lowpan6_input()
774 u16_t new_frag_len = p->len - 1; /* p->len includes datagram_offset byte */ in lowpan6_input()
775 for (q = lrh->frags, last = NULL; q != NULL; last = q, q = q->next) { in lowpan6_input()
776 u16_t q_datagram_offset = ((u8_t *)q->payload)[0] << 3; in lowpan6_input()
777 u16_t q_frag_len = q->len - 1; in lowpan6_input()
801 lrh->frags = p; in lowpan6_input()
803 last->next = p; in lowpan6_input()
804 p->next = q; in lowpan6_input()
808 if (lrh->reass) { in lowpan6_input()
809 u16_t offset = lrh->reass->len; in lowpan6_input()
811 for (q = lrh->frags; q != NULL; q = q->next) { in lowpan6_input()
812 u16_t q_datagram_offset = ((u8_t *)q->payload)[0] << 3; in lowpan6_input()
817 offset += q->len - 1; in lowpan6_input()
821 u16_t datagram_left = datagram_size - lrh->reass->len; in lowpan6_input()
822 for (q = lrh->frags; q != NULL; q = q->next) { in lowpan6_input()
823 /* hide datagram_offset byte now */ in lowpan6_input()
825 q->tot_len = datagram_left; in lowpan6_input()
826 datagram_left -= q->len; in lowpan6_input()
829 q = lrh->reass; in lowpan6_input()
830 q->tot_len = datagram_size; in lowpan6_input()
831 q->next = lrh->frags; in lowpan6_input()
832 lrh->frags = NULL; in lowpan6_input()
833 lrh->reass = NULL; in lowpan6_input()
846 /* This is a complete IPv6 packet, just skip dispatch byte. */ in lowpan6_input()
847 pbuf_remove_header(p, 1); /* hide dispatch byte. */ in lowpan6_input()
877 netif->name[0] = 'L'; in lowpan6_if_init()
878 netif->name[1] = '6'; in lowpan6_if_init()
879 netif->output_ip6 = lowpan6_output; in lowpan6_if_init()
884 netif->mtu = 1280; in lowpan6_if_init()
887 netif->flags = NETIF_FLAG_BROADCAST /* | NETIF_FLAG_LOWPAN6 */; in lowpan6_if_init()
909 * @param p the received packet, p->payload pointing to the
910 * IEEE 802.15.4 header.