⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ipp.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 5 页
字号:
/*
 * Copyright (c) 2007 Matus Harvan
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * The name of the author may not be used to endorse or promote
 *       products derived from this software without specific prior
 *       written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Parts of the 6lowpan implementation design were inspired Andrew
 * Christian's port of Adam Dunkel's uIP to TinyOS 1.x. This work is
 * distributed under the following copyrights:
 *
 * Copyright (c) 2001-2003, Adam Dunkels.
 * All rights reserved. 
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions 
 * are met: 
 * 1. Redistributions of source code must retain the above copyright 
 *    notice, this list of conditions and the following disclaimer. 
 * 2. Redistributions in binary form must reproduce the above copyright 
 *    notice, this list of conditions and the following disclaimer in the 
 *    documentation and/or other materials provided with the distribution. 
 * 3. The name of the author may not be used to endorse or promote
 *    products derived from this software without specific prior
 *    written permission.  
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 *
 * Copyright (c) 2005, Hewlett-Packard Company
 * All rights reserved
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:

 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 *       copyright notice, this list of conditions and the following
 *       disclaimer in the documentation and/or other materials provided
 *       with the distribution.
 *     * Neither the name of the Hewlett-Packard Company nor the names of its
 *       contributors may be used to endorse or promote products derived
 *       from this software without specific prior written permission.

 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * The actual implementaion of the 6lowpan/IPv6 stack lives in this file.
 */

#include "IP.h"
#include "IP_internal.h"
#include "message.h"
#ifdef ENABLE_PRINTF_DEBUG
#include "printf.h"
#endif /* ENABLE_PRINTF_DEBUG */

module IPP {
    provides {
	interface SplitControl as IPControl;
	interface IP;
	interface UDPClient[uint8_t i];
    }
    uses {
	interface Timer<TMilli> as Timer;
	interface Pool<lowpan_pkt_t> as SendPktPool;
	interface Pool<app_data_t> as AppDataPool;
	interface Pool<frag_info_t> as FragInfoPool;

	interface SplitControl as MessageControl;
	interface Receive;
	interface AMSend;
	interface Packet;
	interface AMPacket;

#ifdef ENABLE_PRINTF_DEBUG
	interface PrintfFlush;
	interface SplitControl as PrintfControl;
#endif /* ENABLE_PRINTF_DEBUG */

	interface Leds;
    }
}
 
implementation { 
    /* global variables */
  enum {
    COUNT_UDP_CLIENT = uniqueCount("UDPClient"),
    COUNT_UDP_CONNS  = COUNT_UDP_CLIENT
  };
    
    ip6_addr_t global_addr;       
    ip6_addr_t linklocal_addr;       

    uint16_t g_dgram_tag = 0;
    uint16_t uip_len, uip_slen;
    uint8_t  uip_flags;     /* The uip_flags variable is used for
			     communication between the TCP/IP stack
			     and the application program. */

    message_t g_msg; // AM for sending
    lowpan_pkt_t rx_pkt; // packet used for receiving
    //struct lowpan_pkt send_pkt[SEND_PKTS]; // packets to be sent
    lowpan_pkt_t *send_queue; // packets to be sent - queue

    frag_buf_t frag_bufs[FRAG_BUFS]; // fragment reassembly buffers

    struct udp_conn udp_conns[COUNT_UDP_CONNS];
    static uint16_t lastport;       /* Keeps track of the last port used for
				       a new connection. */
    static int g_send_pending = 0;

    // Pre-declare
    // clear all fields, set app_data = NULL
    void lowpan_pkt_clear(lowpan_pkt_t *pkt);
    int ip6_addr_cmp(const ip6_addr_t *a, const ip6_addr_t *b);

    static void dump_serial_packet(const unsigned char *packet, const int len);
/*---------------------------------------------------------------------------*/
/* from http://www.nabble.com/memcpy-assumes-16-bit-alignment--t712619.html */
void * 
my_memcpy(void *dst0, const void *src0, size_t len) 
{ 
        char *dst = (char *)dst0; 
        const char *src = (const char *)src0; 
        void *ret = dst0; 

        for (; len > 0; len--) 
                *dst++ = *src++; 

        return ret; 
}

/*
 * Use this function for copying/setting/memset() 16-bit values
 * on the MSP430 !!!
 *
 * The mspgcc compiler geenrates broken code when doing memset with 16
 * bit values, i.e. things go wrong if they are not aligned at 16-bit
 * boundaries. See
 * http://www.nabble.com/msp430-gcc-generating-unaligned-access.-t2261862.html
 * and page 25 in http://www.eecs.harvard.edu/~konrad/projects/motetrack/mspgcc-manual-20031127.pdf for details.
 */
/* use when DST may be UNALIGNED */
inline void set_16t(void *dst, uint16_t val)
{
    *((uint8_t*)dst) = *((uint8_t*)&val);
    *(((uint8_t*)dst)+1) = *(((uint8_t*)&val)+1);
    //memcpy((uint8_t*)dst, (uint8_t*)&val, sizeof(uint8_t));
    //memcpy(((uint8_t*)dst)+1, ((uint8_t*)&val)+1, sizeof(uint8_t));
}

/* use when SRC may be UNALIGNED */
inline uint16_t get_16t(void *val)
{
    uint16_t tmp;
    *((uint8_t*)&tmp) = *((uint8_t*)val);
    *(((uint8_t*)&tmp)+1) = *(((uint8_t*)val)+1);
    //memcpy((uint8_t*)&tmp, (uint8_t*)val, sizeof(uint8_t));
    //memcpy(((uint8_t*)&tmp)+1, ((uint8_t*)val)+1, sizeof(uint8_t));
    return tmp;
}

  inline uint16_t htons( uint16_t val )
  {
    // The MSB is little-endian; network order is big
    return ((val & 0xff) << 8) | ((val & 0xff00) >> 8);
  }

  inline uint16_t ntohs( uint16_t val )
  {
    // The MSB is little-endian; network order is big
    return ((val & 0xff) << 8) | ((val & 0xff00) >> 8);
  }

  inline void htonl( uint32_t val, uint8_t *dest )
  {
    dest[0] = (val & 0xff000000) >> 24;
    dest[1] = (val & 0x00ff0000) >> 16;
    dest[2] = (val & 0x0000ff00) >> 8;
    dest[3] = (val & 0x000000ff);
  }

  inline uint32_t ntohl( uint8_t *src )
  {
    return (((uint32_t) src[0]) << 24) | (((uint32_t) src[1]) << 16) |
      (((uint32_t) src[2]) << 8) | (((uint32_t) src[3]));
  }

    /*
  inline void uip_pack_ipaddr( ip6_addr_t *addr, uint8_t *new_addr) 
  {
      memcpy(addr, new_addr, sizeof(addr));
  }

  // Unpack the IP address into an array of octet
  inline void uip_unpack_ipaddr( uint8_t *in, uint8_t *out )
  {
      memcpy(out, in, sizeof(ip6_addr_t));
  }
    */
/*---------------------------------------------------------------------------*/
    
    /* This should be optimized for aligned and unaligned case */
    static uint16_t ip_chksum(const uint8_t *buf, uint16_t len,
			      uint16_t acc)
    {
	uint16_t v;
	
	for (; len > 1; len -= 2) {
	    v = (((uint16_t) buf[1]) << 8) | ((uint16_t) buf[0]);
	    
	    if ( (acc += v) < v ) acc++;
	    buf += 2;
    }
	
	// add an odd byte (note we pad with 0)
	if (len) {
	    v = (uint16_t) buf[0];
	    if ( (acc += v) < v ) acc++;
	}
	
	return acc;
    }
    
    /* 
     * IPv6 checksum of the pseudo-header (RFC 2460, Sec 8.1)
     * src_addr and dst_addr are in nerwork byte order
     * len is in host byte order (will internally be converted)
     */
    static uint16_t ipv6_chksum(const ip6_addr_t* src_addr,
				const ip6_addr_t* dst_addr,
				const uint8_t next_header,
				const uint16_t upper_layer_len,
				uint16_t acc)
    {
	uint16_t tmp;
	
	/* source address */
	acc =  ip_chksum((const uint8_t *) src_addr, sizeof(*src_addr), acc);

	/* destination address */
	acc =  ip_chksum((const uint8_t *) dst_addr, sizeof(*dst_addr), acc);

	/* upper-layer packet length */
	tmp = htons(upper_layer_len);
	acc = ip_chksum((const uint8_t *) &tmp, sizeof(tmp), acc);

	/* next header */
	tmp = htons(next_header);
	acc = ip_chksum((const uint8_t *) &tmp, sizeof(tmp), acc);
	
	return acc;
    }

    /* same as above, but including the uppel-layer buffer */
    static uint16_t ipv6_chksum_data(const ip6_addr_t* src_addr,
				     const ip6_addr_t* dst_addr, 
				     const uint8_t next_header,
				     const uint8_t *data, uint16_t data_len,
				     uint16_t acc)
    {
	/* upper-layer payload */
	acc = ip_chksum(data, data_len, acc);
	
	return ipv6_chksum(src_addr, dst_addr, next_header, data_len, acc);
    }
/*---------------------------------------------------------------------------*/
    bool ipv6_addr_is_zero(const ip6_addr_t *addr)
    {
	int i;
	for (i=0;i<16;i++) {
	    if (addr->addr[i]) {
		return FALSE;
	    }
	}
	return TRUE;
    }

    bool ipv6_addr_is_linklocal_unicast(const ip6_addr_t *addr)
    {
	if (   addr->addr[0] == 0xFE
	    && addr->addr[1] == 0x80
	    && addr->addr[2] == 0
	    && addr->addr[3] == 0
	    && addr->addr[4] == 0
	    && addr->addr[5] == 0
	    && addr->addr[6] == 0
	    && addr->addr[7] == 0
	    )
	    return TRUE;
	else
	    return FALSE;
    }
    
//TODO: prepend pan_id once we have a proper 802.15.4 stack
void ipv6_iface_id_from_am_addr(am_addr_t am_addr, uint8_t *host_part)
{
    memset(host_part, 0, 6);
    host_part[4] = 0xFF;
    host_part[5] = 0xFE;
    host_part += 6;
    set_16t(host_part, htons(am_addr));
}

void ipv6_iface_id_from_hw_addr(hw_addr_t *hw_addr, uint8_t *host_part)
{
    if (hw_addr->type == HW_ADDR_SHORT) {
	memset(host_part, 0, 6);
	host_part[4] = 0xFF;
	host_part[5] = 0xFE;
	host_part[7] = hw_addr->addr_short[0];
	host_part[8] = hw_addr->addr_short[1];
	//ipv6_iface_id_from_am_addr(hw_addr->addr_short, host_part);
    } else {
	//TODO
    }
}
    
bool ipv6_addr_is_linklocal_multicast(const ip6_addr_t *addr)
{
    if (addr->addr[0] == 0xFF
	&& addr->addr[1] == 0x02)
	return TRUE;
    else
	return FALSE;
}

bool ipv6_addr_is_linklocal(const ip6_addr_t *addr)
{
    return (ipv6_addr_is_linklocal_unicast(addr)
	    || ipv6_addr_is_linklocal_multicast(addr));
}

bool ipv6_addr_is_linklocal_allnodes(const ip6_addr_t *addr)
{
    //TODO: interface-local addr FF01::1
    if (   addr->addr[0] == 0xFF
	   && addr->addr[1] == 0x02
	   && addr->addr[2] == 0
	   && addr->addr[3] == 0
	   && addr->addr[4] == 0
	   && addr->addr[5] == 0
	   && addr->addr[6] == 0
	   && addr->addr[7] == 0
	   && addr->addr[8] == 0
	   && addr->addr[9] == 0
	   && addr->addr[10] == 0
	   && addr->addr[11] == 0
	   && addr->addr[12] == 0
	   && addr->addr[13] == 0
	   && addr->addr[14] == 0
	    && addr->addr[15] == 0x01
	   )
	return TRUE;
    else
	return FALSE;
}

bool ipv6_addr_is_solicited_node_multicast_prefix(const ip6_addr_t *addr)
{
//       Solicited-Node Address:  FF02:0:0:0:0:1:FFXX:XXXX

//    Solicited-Node multicast address are computed as a function of a
//    node's unicast and anycast addresses.  A Solicited-Node multicast
//    address is formed by taking the low-order 24 bits of an address
//    (unicast or anycast) and appending those bits to the prefix
//    FF02:0:0:0:0:1:FF00::/104 resulting in a multicast address in the
//    range

//          FF02:0:0:0:0:1:FF00:0000

//    to

//          FF02:0:0:0:0:1:FFFF:FFFF

    if (   addr->addr[0] == 0xFF
	   && addr->addr[1] == 0x02
	   && addr->addr[2] == 0
	   && addr->addr[3] == 0
	   && addr->addr[4] == 0
	   && addr->addr[5] == 0
	   && addr->addr[6] == 0
	   && addr->addr[7] == 0
	   && addr->addr[8] == 0
	   && addr->addr[9] == 0
	   && addr->addr[10] == 0
	   && addr->addr[11] == 0x01
	   && addr->addr[12] == 0xFF
	   )
	return TRUE;
    else

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -