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

📄 ipp.nc

📁 tinyos-2.x.rar
💻 NC
📖 第 1 页 / 共 5 页
字号:
	return FALSE;
}

uint8_t cmp_ipv6_addr(const ip6_addr_t *addr1, const ip6_addr_t *addr2)
{
    return memcmp(addr1, addr2, sizeof(ip6_addr_t));
}

uint8_t ipv6_addr_is_for_me(const ip6_addr_t *addr)
{
    //TODO: loopback addr (::1)
    //TODO: interface-local addr FF01::1
    if (cmp_ipv6_addr(addr, &global_addr) == 0 ||
	cmp_ipv6_addr(addr, &linklocal_addr) == 0 ||
	ipv6_addr_is_linklocal_allnodes(addr) ||
	(ipv6_addr_is_solicited_node_multicast_prefix(addr)
	 && (((addr->addr[13] == global_addr.addr[13])
	      && (addr->addr[14] == global_addr.addr[14])
	      && (addr->addr[15] == global_addr.addr[15])
	      ) ||
	     ((addr->addr[13] == linklocal_addr.addr[13])
		  && (addr->addr[14] == linklocal_addr.addr[14])
	      && (addr->addr[15] == linklocal_addr.addr[15])
	      )
	     )
	 )
	)
	return 1;
    else
	return 0;
}

/* determine the right src_addr given a dst_addr */
ip6_addr_t * determine_src_ipv6_addr(const ip6_addr_t *dst_addr)
{
    if (ipv6_addr_is_linklocal(dst_addr)) {
	return &linklocal_addr;
    } else {
	return &global_addr;
    }
}

uint8_t cmp_hw_addr(const hw_addr_t *addr1, const hw_addr_t *addr2)
{
    // for short addresses compare only the first two bytes
    if (addr1->type == HW_ADDR_SHORT && addr2->type == HW_ADDR_SHORT) {
	return memcmp(addr1->addr_short, addr2->addr_short, 2);
    } else {
	return memcmp(addr1, addr2, sizeof(hw_addr_t));
    }
}

uint8_t hw_addr_is_broadcat(const hw_addr_t *hw_addr)
{
    if (hw_addr->type == HW_ADDR_SHORT
	&& hw_addr->addr_short[0] == 0xFF
	&& hw_addr->addr_short[1] == 0xFF)
	return 1;
    // TODO: long address
    else return 0;
}

uint8_t hw_addr_is_for_me(const hw_addr_t *addr)
{
    am_addr_t am_addr = call AMPacket.address();
    if (hw_addr_is_broadcat(addr) ||
	(addr->addr_short[0] == (uint8_t) am_addr
	 && addr->addr_short[1] == (uint8_t) (am_addr >> 8))
	)
	return 1;
    else
	return 0;
}
/*---------------------------------------------------------------------------*/

void increment_g_dgram_tag()
{
    uint16_t tmp = ntohs(g_dgram_tag);
    if (tmp == 0xFFFF)
	tmp = 0;
    else
	tmp++;
    g_dgram_tag = htons(tmp);
}

void lowpan_pkt_clear(lowpan_pkt_t *pkt)
{
    memset(pkt, 0, sizeof(*pkt));
    pkt->header_begin = pkt->header + sizeof(pkt->header);
}

/*
void frag_buf_clear(frag_buf_t *frag_buf)
{
    memset(frag_buf, 0, sizeof(*frag_buf));
    frag_buf->buf_begin = frag_buf->buf;
}
*/

frag_buf_t * find_fragment(hw_addr_t *hw_src_addr, hw_addr_t *hw_dst_addr,
			   uint16_t dgram_size, uint16_t dgram_tag)
{
    int i;
    for (i = 0; i< FRAG_BUFS; i++) {
	//printf("find_frag\n");
	if (frag_bufs[i].frag_timeout != FRAG_FREE) {
	    //printf("find: [%d] %d\n", i, frag_bufs[i].frag_timeout);
	    /*
	  printf("find: tag: 0x%04X, size: %d\n",
		 get_16t(&frag_bufs[i].dgram_tag),
		 ntohs(get_16t(&frag_bufs[i].dgram_size)));
	    */
	    if (   get_16t(&(frag_bufs[i].dgram_tag)) == dgram_tag
		&& get_16t(&(frag_bufs[i].dgram_size)) == dgram_size
		&& cmp_hw_addr(&frag_bufs[i].hw_src_addr, hw_src_addr) == 0
		&& cmp_hw_addr(&frag_bufs[i].hw_dst_addr, hw_dst_addr) == 0
		) {
		return &(frag_bufs[i]);
	    }
	} else {
	    //printf("find: [%d] FREE\n", i);
	}
    }
    return NULL;
}

void free_frag_list(frag_info_t *p)
{
    frag_info_t *q;
    while (p) {
	q = p->next;
	call FragInfoPool.put(p);
	p = q;
    }
}
/*---------------------------------------------------------------------------*/
  
    void ip_init()
    {
	//int i;
	lastport = 1024;
	memset(udp_conns, 0, sizeof(udp_conns));
	//memset(&global_addr, 0, sizeof(global_addr));
	memset(&linklocal_addr, 0, sizeof(linklocal_addr));
	memset(frag_bufs, 0, sizeof(frag_bufs));
	/*
	for(i=0;i<FAG_BUFS,i++) {
	    frag_buf_clear(frag_bufs[i]);
	}
	*/
    }

    uint16_t udp_assign_port()
    {
	int c;
	
	/* Find an unused local port. */
    again:
	++lastport;
	
	if (lastport >= 32000) {
	    lastport = 4096;
	}
	
	for (c = 0; c < COUNT_UDP_CONNS; ++c) {
	    if (udp_conns[c].lport == lastport) {
		goto again;
	    }
	}
	
	return lastport;
    }    

/* ========================= IPv6 - output ================================= */
task void sendTask()
{
    lowpan_pkt_t *pkt = send_queue;
    struct lowpan_frag_hdr *frag_hdr;
    uint8_t *payload;
    uint8_t frame_len;
    uint8_t len; /* length of the fragment just being sent
		  * excluding the 6lowpan optional headers */
    uint8_t remaining_len; /* how much more data can we fit 
			    * into this fragment */

    uint8_t *tmp_cpy_buf; /* simplifies memcpy */
    uint8_t tmp_cpy_len; /* simplifies memcpy */

    if (!pkt || g_send_pending) {
	return;
    }
    
    //len = pkt->header_len + pkt->app_data_len - pkt->dgram_offset*8;
    if (pkt->header_len + pkt->app_data_len <= LINK_DATA_MTU) {
	/* fragmentation not needed */
	frame_len = pkt->header_len + pkt->app_data_len;
	/* prepare the AM */
	call Packet.clear(&g_msg);
	call Packet.setPayloadLength(&g_msg, frame_len);
	payload = call Packet.getPayload(&g_msg, frame_len);
	// memset(payload, 0 , payload_len);
	// should check payload_len here
	
	/* copy header */
	if (pkt->header_begin && pkt->header_len)
	    memcpy(payload, pkt->header_begin, pkt->header_len);
	payload += pkt->header_len;

	/* copy app_data */
	if (pkt->app_data_begin && pkt->app_data_len)
	    memcpy(payload, pkt->app_data_begin, pkt->app_data_len);

    } else {
	/* do fragmentation */
	if (pkt->dgram_offset == 0) {
	    /* first fragment */
	    increment_g_dgram_tag();
	    set_16t(&pkt->dgram_size,
		    htons(pkt->header_len + pkt->app_data_len));
	    
	    /* align fragment length at an 8-byte multiple */
	    len = LINK_DATA_MTU - sizeof(struct lowpan_frag_hdr);
	    len -= len%8;
	    frame_len = len + sizeof(struct lowpan_frag_hdr);
	} else {
	    /* subsequent fragment */
	    if (pkt->header_len + pkt->app_data_len - pkt->dgram_offset*8
		<= LINK_DATA_MTU - sizeof(struct lowpan_frag_hdr)
		- sizeof(uint8_t)) {
		/* last fragment -- does not have to be aligned
		 * at an 8-byte multiple */
		len = pkt->header_len + pkt->app_data_len
		    - pkt->dgram_offset*8;
	    } else {
		/* align fragment length at an 8-byte multiple */
		len = LINK_DATA_MTU - sizeof(struct lowpan_frag_hdr)
		    - sizeof(uint8_t);
		len -= len%8;
	    }
	    frame_len = len + sizeof(struct lowpan_frag_hdr)
		+ sizeof(uint8_t);
	}
    
	/* prepare the AM */
	call Packet.clear(&g_msg);
	call Packet.setPayloadLength(&g_msg,frame_len);
	payload = call Packet.getPayload(&g_msg, frame_len);
	remaining_len = frame_len;
	if (remaining_len != frame_len) {
	    //TODO: report an error
#ifdef ENABLE_PRINTF_DEBUG
	    printf("payload length does not match requested length\n");
	    call PrintfFlush.flush();
#endif /* ENABLE_PRINTF_DEBUG */
	    return;
	}

	/* fill in the fragment header */
	frag_hdr = (struct lowpan_frag_hdr *) payload;
	set_16t(&frag_hdr->dgram_size, pkt->dgram_size);
	set_16t(&frag_hdr->dgram_tag, g_dgram_tag);
	payload += sizeof(struct lowpan_frag_hdr);
	remaining_len -= sizeof(struct lowpan_frag_hdr);
	
	if (pkt->dgram_offset == 0) {
	    /* first fragment */
	    frag_hdr->dispatch |= DISPATCH_FIRST_FRAG;
	} else {
	    /* subsequent fragment */
	    frag_hdr->dispatch |= DISPATCH_SUBSEQ_FRAG;
	    *payload = pkt->dgram_offset;
	    payload += sizeof(uint8_t);
	}

	/* copy header */
	if (pkt->header_begin
	    && pkt->header_len
	    && pkt->header_len > pkt->dgram_offset*8
	       /* don't copy the header if offset is beyond it*/
	    ) {
	    /* determine what has to be copied */
	    tmp_cpy_buf = pkt->header_begin + pkt->dgram_offset*8;
	    tmp_cpy_len = min(pkt->header_len - pkt->dgram_offset*8,
			  remaining_len);
	    /* copy it */
	    memcpy(payload, tmp_cpy_buf, tmp_cpy_len);
	    payload += tmp_cpy_len;
	    remaining_len -= tmp_cpy_len;
	}
	
	/* copy app_data */
	if (remaining_len
	    && pkt->app_data_begin
	    && pkt->app_data_len
	    ) {
	    /* determine what has to be copied */
	    if (pkt->dgram_offset*8 > pkt->header_len) {
		tmp_cpy_buf = pkt->app_data_begin
		              + pkt->dgram_offset*8 - pkt->header_len;
	    } else {
		/* header has been copied only now, offset not yet updated */
		tmp_cpy_buf = pkt->app_data_begin;
	    }
	    tmp_cpy_len = min(remaining_len,
			      pkt->app_data_len
			      - (pkt->dgram_offset*8 - pkt->header_len));
	    /* copy it */
	    memcpy(payload, tmp_cpy_buf, tmp_cpy_len);
	    payload += tmp_cpy_len;
	    remaining_len -= tmp_cpy_len;
	}
		
	/* update the offset - in 8-byte multiples */
	pkt->dgram_offset += len/8;
	if (len%8) {
	    /* last fragment with a special length */
	    pkt->dgram_offset++;
	}
    }

    /* send the AM */
    g_send_pending = 1;
    call AMSend.send(AM_BROADCAST_ADDR, &g_msg, frame_len);
    //call AMSend.send(0x12, &g_msg, frame_len);
}

event void AMSend.sendDone(message_t* msg, error_t error)
{
    uint16_t len;
    lowpan_pkt_t *pkt = send_queue;

    g_send_pending = 0;

    if (!send_queue) {
	// somethign really went wrong...
	return;
    }

    len = pkt->header_len + pkt->app_data_len;
    if (len <= LINK_DATA_MTU || pkt->dgram_offset*8 >= len){
	/* packet has been completely sent, we can move on to the next one */

	/* UDPClient.sendDone notification */
	if (send_queue->notify_num != LOWPAN_PKT_NO_NOTIFY) {
	    signal UDPClient.sendDone[send_queue->notify_num - 1]
		(SUCCESS, send_queue->app_data);
	}

	/* deallocation of app_data (fragment reassembly buffer) */
	if (send_queue->app_data_dealloc == APP_DATA_DEALLOC_TRUE
	    && send_queue->app_data) {
	    call AppDataPool.put((app_data_t*) send_queue->app_data);
	    send_queue->app_data = NULL;
	}
	
	pkt = send_queue->next;
	call SendPktPool.put(send_queue);
	send_queue = pkt;
    }
    if (send_queue) {
	post sendTask();
    }
}

void ipv6_output_uncompressed(lowpan_pkt_t *pkt, const uint8_t next_header)
{
    struct ip6_hdr *hdr;
    lowpan_pkt_t *p;

    pkt->header_begin -= sizeof(struct ip6_hdr);
    pkt->header_len += sizeof(struct ip6_hdr);
    hdr = (struct ip6_hdr *) pkt->header_begin;

    /* fill in the IPv6 header */
    hdr->vtc = IPV6_VERSION; /* IPv6 version */
    /* payload length */
    set_16t(&hdr->plen, htons(pkt->header_len + pkt->app_data_len
			      - sizeof(struct ip6_hdr)));
    
    hdr->nxt_hdr = next_header;
    hdr->hlim = IP_HOP_LIMIT; /* hop limit */
    
    memcpy(&hdr->src_addr, &pkt->ip_src_addr, sizeof(hdr->src_addr));
    memcpy(&hdr->dst_addr, &pkt->ip_dst_addr, sizeof(hdr->dst_addr));

    /* set 6lowpan dispatch value */
    pkt->header_begin -= sizeof(uint8_t);
    pkt->header_len += sizeof(uint8_t);
    *(pkt->header_begin) = DISPATCH_UNCOMPRESSED_IPV6;

    //TODO: check if neighbor is information available
    //  if yes
    //    fill in hw_addr
    //    append to send_queue
    //  else
    //    append to neighbor_queue
    //    request ND, add an entry into the neighbor table

    /* append pkt to send queue */
    if(!send_queue) {
	send_queue = pkt;
    } else {
	for(p=send_queue; p->next; p=p->next);
	p->next = pkt;
    }

    /* schedule sendTask */
    post sendTask();
}

/* determines length of the inline carried fields for the HC1 encoding
 * the return value is the number of bits, bot bytes !!!
 */
int get_hc1_length(uint8_t hc1_enc)
{
    int len = 0;
    /* Hop Limit always carried inline */
    len += 8;
    
    /* source IP address */
    if ((hc1_enc & HC1_SRC_PREFIX_MASK) == HC1_SRC_PREFIX_INLINE)
	len += 64;
     
    if ((hc1_enc & HC1_SRC_IFACEID_MASK) == HC1_SRC_IFACEID_INLINE)
	len += 64;

    /* destination IP address */
    if ((hc1_enc & HC1_DST_PREFIX_MASK) == HC1_DST_PREFIX_INLINE)
	len += 64;
     
    if ((hc1_enc & HC1_DST_IFACEID_MASK) == HC1_DST_IFACEID_INLINE)
	len += 64;

    /* Traffic Class and Flow Label */
    if ((hc1_enc & HC1_TCFL_MASK) == HC1_TCFL_INLINE)
	len += 24;

    /* Next Header */
    if ((hc1_enc & HC1_NEXTHDR_MASK) == HC1_NEXTHDR_INLINE)

⌨️ 快捷键说明

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