68#if LWIP_6LOWPAN_802154_HW_CRC
69#define LWIP_6LOWPAN_DO_CALC_CRC(buf, len) 0
71#define LWIP_6LOWPAN_DO_CALC_CRC(buf, len) LWIP_6LOWPAN_CALC_CRC(buf, len)
77struct lowpan6_reass_helper {
78 struct lowpan6_reass_helper *next_packet;
82 struct lowpan6_link_addr sender_addr;
88struct lowpan6_ieee802154_data {
90 struct lowpan6_reass_helper *reass_list;
91#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
96 u16_t tx_datagram_tag;
98 u16_t ieee_802154_pan_id;
100 u8_t tx_frame_seq_num;
104#define LOWPAN6_MAX_PAYLOAD (127 - 2)
107static struct lowpan6_ieee802154_data lowpan6_data;
109#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
110#define LWIP_6LOWPAN_CONTEXTS(netif) lowpan6_data.lowpan6_context
112#define LWIP_6LOWPAN_CONTEXTS(netif) NULL
115static const struct lowpan6_link_addr ieee_802154_broadcast = {2, {0xff, 0xff}};
117#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
118static struct lowpan6_link_addr short_mac_addr = {2, {0, 0}};
131 const struct lowpan6_link_addr *
dst)
133 u8_t ieee_header_len;
140 if (
dst != &ieee_802154_broadcast) {
143 if (
dst->addr_len == 2) {
149 if (
src->addr_len == 2) {
155 hdr->frame_control =
fc;
156 hdr->sequence_number = lowpan6_data.tx_frame_seq_num++;
157 hdr->destination_pan_id = lowpan6_data.ieee_802154_pan_id;
172 return ieee_header_len;
186lowpan6_parse_iee802154_header(
struct pbuf *
p,
struct lowpan6_link_addr *
src,
187 struct lowpan6_link_addr *
dest)
191 u16_t frame_control, addr_mode;
192 u16_t datagram_offset;
195 puc = (
u8_t *)
p->payload;
196 frame_control = puc[0] | (puc[1] << 8);
206 datagram_offset += 2;
212 for (
i = 0;
i < 8;
i++) {
213 dest->addr[
i] = puc[datagram_offset + 7 -
i];
215 datagram_offset += 8;
220 dest->addr[0] = puc[datagram_offset + 1];
221 dest->addr[1] = puc[datagram_offset];
222 datagram_offset += 2;
230 datagram_offset += 2;
238 for (
i = 0;
i < 8;
i++) {
239 src->addr[
i] = puc[datagram_offset + 7 -
i];
241 datagram_offset += 8;
245 src->addr[0] = puc[datagram_offset + 1];
246 src->addr[1] = puc[datagram_offset];
247 datagram_offset += 2;
264#define CCITT_POLY_16 0x8408U
270 for (
i = 0;
i <
len;
i++) {
272 for (
b = 0
U;
b < 8U;
b++) {
273 if (((
data ^ crc) & 1) != 0) {
274 crc = (
u16_t)((crc >> 1) ^ CCITT_POLY_16);
276 crc = (
u16_t)(crc >> 1);
288free_reass_datagram(
struct lowpan6_reass_helper *lrh)
303dequeue_datagram(
struct lowpan6_reass_helper *lrh,
struct lowpan6_reass_helper *prev)
305 if (lowpan6_data.reass_list == lrh) {
306 lowpan6_data.reass_list = lowpan6_data.reass_list->next_packet;
310 prev->next_packet = lrh->next_packet;
322 struct lowpan6_reass_helper *lrh, *lrh_next, *lrh_prev =
NULL;
324 lrh = lowpan6_data.reass_list;
325 while (lrh !=
NULL) {
326 lrh_next = lrh->next_packet;
327 if ((--lrh->timer) == 0) {
328 dequeue_datagram(lrh, lrh_prev);
329 free_reass_datagram(lrh);
343lowpan6_frag(
struct netif *
netif,
struct pbuf *
p,
const struct lowpan6_link_addr *
src,
const struct lowpan6_link_addr *
dst)
346 u16_t frag_len, remaining_len, max_data_len;
348 u8_t ieee_header_len;
349 u8_t lowpan6_header_len;
350 u8_t hidden_header_len;
352 u16_t datagram_offset;
359 if (p_frag ==
NULL) {
368 LWIP_ASSERT(
"ieee_header_len < p_frag->len", ieee_header_len < p_frag->
len);
374 &
buffer[ieee_header_len], p_frag->
len - ieee_header_len, &lowpan6_header_len,
375 &hidden_header_len, LWIP_6LOWPAN_CONTEXTS(
netif),
src,
dst);
385 lowpan6_header_len = 1;
386 hidden_header_len = 0;
387 buffer[ieee_header_len] = 0x41;
391 remaining_len =
p->tot_len;
393 if (remaining_len > 0x7FF) {
401 max_data_len = LOWPAN6_MAX_PAYLOAD - ieee_header_len - lowpan6_header_len;
402 if (remaining_len > max_data_len) {
408 buffer[ieee_header_len] = 0xc0 | (((
p->tot_len + hidden_header_len) >> 8) & 0x7);
409 buffer[ieee_header_len + 1] = (
p->tot_len + hidden_header_len) & 0xff;
411 lowpan6_data.tx_datagram_tag++;
412 buffer[ieee_header_len + 2] = (lowpan6_data.tx_datagram_tag >> 8) & 0xff;
413 buffer[ieee_header_len + 3] = lowpan6_data.tx_datagram_tag & 0xff;
416 data_len = (max_data_len - 4) & 0xf8;
417 frag_len = data_len + lowpan6_header_len;
420 remaining_len -= frag_len - lowpan6_header_len;
422 datagram_offset = frag_len - lowpan6_header_len + hidden_header_len;
423 LWIP_ASSERT(
"datagram offset must be a multiple of 8", (datagram_offset & 7) == 0);
426 p_frag->
len = p_frag->
tot_len = ieee_header_len + 4 + frag_len + 2;
429 crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->
payload, p_frag->
len - 2);
437 while ((remaining_len > 0) && (
err ==
ERR_OK)) {
440 hdr->sequence_number = lowpan6_data.tx_frame_seq_num++;
442 buffer[ieee_header_len] |= 0x20;
444 LWIP_ASSERT(
"datagram offset must be a multiple of 8", (datagram_offset & 7) == 0);
445 buffer[ieee_header_len + 4] = (
u8_t)(datagram_offset >> 3);
447 frag_len = (127 - ieee_header_len - 5 - 2) & 0xf8;
448 if (frag_len > remaining_len) {
449 frag_len = remaining_len;
453 remaining_len -= frag_len;
454 datagram_offset += frag_len;
457 p_frag->
len = p_frag->
tot_len = frag_len + 5 + ieee_header_len + 2;
460 crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->
payload, p_frag->
len - 2);
470 frag_len = remaining_len;
477 p_frag->
len = p_frag->
tot_len = frag_len + lowpan6_header_len + ieee_header_len + 2;
481 crc = LWIP_6LOWPAN_DO_CALC_CRC(p_frag->
payload, p_frag->
len - 2);
502#if LWIP_6LOWPAN_NUM_CONTEXTS > 0
509 ip6_addr_set(&lowpan6_data.lowpan6_context[
idx],
context);
519#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
525lowpan6_set_short_addr(
u8_t addr_high,
u8_t addr_low)
527 short_mac_addr.addr[0] = addr_high;
528 short_mac_addr.addr[1] = addr_low;
536lowpan6_hwaddr_to_addr(
struct netif *
netif,
struct lowpan6_link_addr *
addr)
545 addr->addr[3] =
addr->addr[4] = 0xff;
567lowpan6_output(
struct netif *
netif,
struct pbuf *
q,
const ip6_addr_t *ip6addr)
571 struct lowpan6_link_addr
src,
dest;
572#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
577#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
582 if (lowpan6_get_address_mode(&
ip6_src, &short_mac_addr) == 3) {
584 src.addr[0] = short_mac_addr.addr[0];
585 src.addr[1] = short_mac_addr.addr[1];
597 if (ip6_addr_ismulticast(ip6addr)) {
600 return lowpan6_frag(
netif,
q, &
src, &ieee_802154_broadcast);
606#if LWIP_6LOWPAN_INFER_SHORT_ADDRESS
607 if (
src.addr_len == 2) {
613 if ((
src.addr_len == 2) && (ip6_addr_net_zoneless_eq(&
ip6_hdr->src, &
ip6_hdr->dest)) &&
614 (lowpan6_get_address_mode(ip6addr, &
dest) == 3)) {
651 struct lowpan6_link_addr
src,
dest;
652 u16_t datagram_size = 0;
653 u16_t datagram_offset, datagram_tag;
654 struct lowpan6_reass_helper *lrh, *lrh_next, *lrh_prev =
NULL;
662 if (
p->len !=
p->tot_len) {
664 goto lowpan6_input_discard;
668 goto lowpan6_input_discard;
672 puc = (
u8_t *)
p->payload;
675 if ((
b & 0xf8) == 0xc0) {
677 datagram_size = ((
u16_t)(puc[0] & 0x07) << 8) | (
u16_t)puc[1];
678 datagram_tag = ((
u16_t)puc[2] << 8) | (
u16_t)puc[3];
681 lrh = lowpan6_data.reass_list;
682 while (lrh !=
NULL) {
684 lrh_next = lrh->next_packet;
685 if ((lrh->sender_addr.addr_len ==
src.addr_len) &&
686 (
memcmp(lrh->sender_addr.addr,
src.addr,
src.addr_len) == 0)) {
688 if ((datagram_tag == lrh->datagram_tag) && (datagram_size == lrh->datagram_size)) {
690 goto lowpan6_input_discard;
697 dequeue_datagram(lrh, lrh_prev);
698 free_reass_datagram(lrh);
708 lrh = (
struct lowpan6_reass_helper *)
mem_malloc(
sizeof(
struct lowpan6_reass_helper));
710 goto lowpan6_input_discard;
713 lrh->sender_addr.addr_len =
src.addr_len;
714 for (
i = 0;
i <
src.addr_len;
i++) {
715 lrh->sender_addr.addr[
i] =
src.addr[
i];
717 lrh->datagram_size = datagram_size;
718 lrh->datagram_tag = datagram_tag;
720 if (*(
u8_t *)
p->payload == 0x41) {
724 }
else if ((*(
u8_t *)
p->payload & 0xe0 ) == 0x60) {
725 lrh->reass = lowpan6_decompress(
p, datagram_size, LWIP_6LOWPAN_CONTEXTS(
netif), &
src, &
dest);
726 if (lrh->reass ==
NULL) {
729 goto lowpan6_input_discard;
733 lrh->next_packet = lowpan6_data.reass_list;
735 lowpan6_data.reass_list = lrh;
738 }
else if ((
b & 0xf8) == 0xe0) {
740 datagram_size = ((
u16_t)(puc[0] & 0x07) << 8) | (
u16_t)puc[1];
741 datagram_tag = ((
u16_t)puc[2] << 8) | (
u16_t)puc[3];
742 datagram_offset = (
u16_t)puc[4] << 3;
745 for (lrh = lowpan6_data.reass_list; lrh !=
NULL; lrh_prev = lrh, lrh = lrh->next_packet) {
746 if ((lrh->sender_addr.addr_len ==
src.addr_len) &&
747 (
memcmp(lrh->sender_addr.addr,
src.addr,
src.addr_len) == 0) &&
748 (datagram_tag == lrh->datagram_tag) &&
749 (datagram_size == lrh->datagram_size)) {
755 goto lowpan6_input_discard;
760 if (lrh->reass !=
NULL) {
762 if (datagram_offset < lrh->reass->len) {
764 dequeue_datagram(lrh, lrh_prev);
765 free_reass_datagram(lrh);
766 goto lowpan6_input_discard;
769 if (lrh->frags ==
NULL) {
775 u16_t new_frag_len =
p->len - 1;
777 u16_t q_datagram_offset = ((
u8_t *)
q->payload)[0] << 3;
778 u16_t q_frag_len =
q->len - 1;
779 if (datagram_offset < q_datagram_offset) {
780 if (datagram_offset + new_frag_len > q_datagram_offset) {
782 dequeue_datagram(lrh, lrh_prev);
783 free_reass_datagram(lrh);
784 goto lowpan6_input_discard;
788 }
else if (datagram_offset == q_datagram_offset) {
789 if (q_frag_len != new_frag_len) {
791 dequeue_datagram(lrh, lrh_prev);
792 free_reass_datagram(lrh);
793 goto lowpan6_input_discard;
813 u16_t q_datagram_offset = ((
u8_t *)
q->payload)[0] << 3;
814 if (q_datagram_offset !=
offset) {
820 if (
offset == datagram_size) {
822 u16_t datagram_left = datagram_size - lrh->reass->len;
826 q->tot_len = datagram_left;
827 datagram_left -=
q->len;
829 LWIP_ASSERT(
"datagram_left == 0", datagram_left == 0);
831 q->tot_len = datagram_size;
832 q->next = lrh->frags;
835 dequeue_datagram(lrh, lrh_prev);
840 return ip6_input(
q,
netif);
849 }
else if ((
b & 0xe0 ) == 0x60) {
851 p = lowpan6_decompress(
p, datagram_size, LWIP_6LOWPAN_CONTEXTS(
netif), &
src, &
dest);
857 goto lowpan6_input_discard;
863 return ip6_input(
p,
netif);
865lowpan6_input_discard:
880 netif->output_ip6 = lowpan6_output;
898lowpan6_set_pan_id(
u16_t pan_id)
900 lowpan6_data.ieee_802154_pan_id = pan_id;
915tcpip_6lowpan_input(
struct pbuf *
p,
struct netif *inp)
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
#define mem_free(ptr, bsize)
void * mem_malloc(mem_size_t size_in)
#define LWIP_DEBUGF(debug, message)
#define LWIP_ERROR(message, expression, handler)
#define LWIP_ASSERT(message, assertion)
#define MIB2_STATS_NETIF_ADD(n, x, val)
#define MIB2_STATS_NETIF_INC(n, x)
#define MIB2_INIT_NETIF(netif, type, speed)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLdouble GLdouble GLdouble GLdouble q
GLboolean GLboolean GLboolean b
GLenum GLuint GLenum GLsizei const GLchar * buf
GLenum const GLvoid * addr
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
#define LWIP_UNUSED_ARG(x)
#define SMEMCPY(dst, src, len)
#define NETIF_FLAG_BROADCAST
struct pbuf * pbuf_alloc(pbuf_layer layer, u16_t length, pbuf_type type)
u8_t pbuf_free(struct pbuf *p)
u16_t pbuf_copy_partial(const struct pbuf *buf, void *dataptr, u16_t len, u16_t offset)
err_t pbuf_take_at(struct pbuf *buf, const void *dataptr, u16_t len, u16_t offset)
#define IEEE_802154_FC_SRC_ADDR_MODE_SHORT
#define IEEE_802154_FC_FRAME_VERSION_GET(x)
#define IEEE_802154_FC_SRC_ADDR_MODE_MASK
#define IEEE_802154_FC_FT_DATA
#define IEEE_802154_FC_SRC_ADDR_MODE_EXT
#define IEEE_802154_FC_DST_ADDR_MODE_EXT
#define IEEE_802154_FC_ACK_REQ
#define IEEE_802154_FC_DST_ADDR_MODE_SHORT
#define IEEE_802154_FC_PANID_COMPR
#define IEEE_802154_FC_SEQNO_SUPPR
#define IEEE_802154_FC_DST_ADDR_MODE_MASK
#define LWIP_6LOWPAN_NUM_CONTEXTS
#define LWIP_LOWPAN6_DEBUG
#define memmove(s1, s2, n)
u8_t pbuf_remove_header(struct pbuf *p, size_t header_size_decrement)
#define IP6_MIN_MTU_LENGTH
u8_t hwaddr[NETIF_MAX_HWADDR_LEN]
netif_linkoutput_fn linkoutput
err_t tcpip_inpkt(struct pbuf *p, struct netif *inp, netif_input_fn input_fn)