On 10/27/2011 07:42 PM, Alexander Smirnov wrote: > This patch adds support for compression/decompression of UDP header > of ipv6 datagram.
Could you please try to prepare a separate patch, containing a split of lowpan_header_create and lowpan_process_data functions into pieces, where each part will consume exactly one header. Then resubmit this one as based on the split up patch. > > Derived from Contiki OS > > Signed-off-by: Alexander Smirnov<alex.bluesman.smir...@gmail.com> > --- > net/ieee802154/6lowpan.c | 101 > +++++++++++++++++++++++++++++++++++++++++++-- > net/ieee802154/6lowpan.h | 5 ++ > 2 files changed, 101 insertions(+), 5 deletions(-) > > diff --git a/net/ieee802154/6lowpan.c b/net/ieee802154/6lowpan.c > index 1ee6d1c..9f3e270 100644 > --- a/net/ieee802154/6lowpan.c > +++ b/net/ieee802154/6lowpan.c > @@ -367,8 +367,6 @@ static int lowpan_header_create(struct sk_buff *skb, > if (hdr->nexthdr == UIP_PROTO_UDP) > iphc0 |= LOWPAN_IPHC_NH_C; > > -/* TODO: next header compression */ > - > if ((iphc0& LOWPAN_IPHC_NH_C) == 0) { > *hc06_ptr = hdr->nexthdr; > hc06_ptr += 1; > @@ -456,8 +454,53 @@ static int lowpan_header_create(struct sk_buff *skb, > } > } > > - /* TODO: UDP header compression */ > - /* TODO: Next Header compression */ > + /* UDP header compression */ > + if (hdr->nexthdr == UIP_PROTO_UDP) { > + struct udphdr *uh = udp_hdr(skb); > + > + pr_debug("(%s): UDP header compression\n", __func__); > + > + if (((uh->source& LOWPAN_NHC_UDP_4BIT_MASK) == > + LOWPAN_NHC_UDP_4BIT_PORT)&& > + ((uh->dest& LOWPAN_NHC_UDP_4BIT_MASK) == > + LOWPAN_NHC_UDP_4BIT_PORT)) { > + pr_debug("(%s): both ports compression to 4 bits\n", > + __func__); > + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_11; > + *(hc06_ptr + 1) = /* subtraction is faster */ > + (u8)((uh->dest - LOWPAN_NHC_UDP_4BIT_PORT) + > + ((uh->source& LOWPAN_NHC_UDP_4BIT_PORT)<< 4)); > + hc06_ptr += 2; > + } else if ((uh->dest& LOWPAN_NHC_UDP_8BIT_MASK) == > + LOWPAN_NHC_UDP_8BIT_PORT) { > + pr_debug("(%s): remove 8 bits of dest\n", __func__); > + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_01; > + memcpy(hc06_ptr + 1,&uh->source, 2); > + *(hc06_ptr + 3) = > + (u8)(uh->dest - LOWPAN_NHC_UDP_8BIT_PORT); > + hc06_ptr += 4; > + } else if ((uh->source& LOWPAN_NHC_UDP_8BIT_MASK) == > + LOWPAN_NHC_UDP_8BIT_PORT) { > + pr_debug("(%s): remove 8 bits of source\n", __func__); > + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_10; > + memcpy(hc06_ptr + 1,&uh->dest, 2); > + *(hc06_ptr + 3) = > + (u8)(uh->source - LOWPAN_NHC_UDP_8BIT_PORT); > + hc06_ptr += 4; > + } else { > + pr_debug("(%s): can't compress header\n", __func__); > + *hc06_ptr = LOWPAN_NHC_UDP_CS_P_00; > + memcpy(hc06_ptr + 1,&uh->source, 2); > + memcpy(hc06_ptr + 3,&uh->dest, 2); > + hc06_ptr += 5; > + } > + > + /* checksum is always inline */ > + memcpy(hc06_ptr,&uh->check, 2); > + hc06_ptr += 2; > + } > + > + /* TODO: other NH types support? */ > > head[0] = iphc0; > head[1] = iphc1; > @@ -799,7 +842,55 @@ lowpan_process_data(struct sk_buff *skb) > goto drop; > } > > - /* TODO: UDP header parse */ > + /* UDP data uncompression */ > + if (iphc0& LOWPAN_IPHC_NH_C) { > + tmp = lowpan_fetch_skb_u8(skb); > + > + if ((tmp& LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) { > + struct udphdr *uh = udp_hdr(skb); > + > + pr_debug("(%s): UDP header uncompression\n", __func__); > + switch (tmp& LOWPAN_NHC_UDP_CS_P_11) { > + case LOWPAN_NHC_UDP_CS_P_00: > + memcpy(&uh->source,&skb->data[0], 2); > + memcpy(&uh->dest,&skb->data[2], 2); > + skb_pull(skb, 4); > + break; > + case LOWPAN_NHC_UDP_CS_P_01: > + memcpy(&uh->source,&skb->data[0], 2); > + uh->dest = > + skb->data[2] + LOWPAN_NHC_UDP_8BIT_PORT; > + skb_pull(skb, 3); > + break; > + case LOWPAN_NHC_UDP_CS_P_10: > + uh->source = skb->data[0] + > LOWPAN_NHC_UDP_8BIT_PORT; > + memcpy(&uh->dest,&skb->data[1], 2); > + skb_pull(skb, 3); > + break; > + case LOWPAN_NHC_UDP_CS_P_11: > + uh->source = > + LOWPAN_NHC_UDP_4BIT_PORT + (skb->data[0]>> > 4); > + uh->dest = > + LOWPAN_NHC_UDP_4BIT_PORT + (skb->data[0]& > 0x0f); > + skb_pull(skb, 1); > + break; > + default: > + pr_debug("(%s) ERROR: unknown UDP format\n", > __func__); > + goto drop; > + } > + > + pr_debug("(%s): uncompressed UDP ports: src = %d, dst = > %d\n", > + __func__, uh->source, uh->dest); > + > + /* copy checksum */ > + memcpy(&uh->check,&skb->data[0], 2); > + skb_pull(skb, 2); > + } else { > + pr_debug("(%s): ERROR: unsupported NH format\n", > + __func__); > + goto drop; > + } > + } > > /* Not fragmented package */ > hdr.payload_len = htons(skb->len); > diff --git a/net/ieee802154/6lowpan.h b/net/ieee802154/6lowpan.h > index eeb5446..31e0d5e 100644 > --- a/net/ieee802154/6lowpan.h > +++ b/net/ieee802154/6lowpan.h > @@ -219,6 +219,11 @@ > #define LOWPAN_NHC_UDP_CHECKSUMC 0x04 > #define LOWPAN_NHC_UDP_CHECKSUMI 0x00 > > +#define LOWPAN_NHC_UDP_4BIT_PORT 0xF0B0 > +#define LOWPAN_NHC_UDP_4BIT_MASK 0xFFF0 > +#define LOWPAN_NHC_UDP_8BIT_PORT 0xF000 > +#define LOWPAN_NHC_UDP_8BIT_MASK 0xFF00 > + > /* values for port compression, _with checksum_ ie bit 5 set to 0 */ > #define LOWPAN_NHC_UDP_CS_P_00 0xF0 /* all inline */ > #define LOWPAN_NHC_UDP_CS_P_01 0xF1 /* source 16bit inline, -- With best wishes Dmitry ------------------------------------------------------------------------------ RSA® Conference 2012 Save $700 by Nov 18 Register now http://p.sf.net/sfu/rsa-sfdev2dev1 _______________________________________________ Linux-zigbee-devel mailing list Linux-zigbee-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/linux-zigbee-devel