📄 ipp.nc
字号:
printf("off: %d\n", dgram_offset);#endif /* ENABLE_PRINTF_DEBUG */ /* printf("off: %d, f_b[%d] %d\n", dgram_offset, 0, frag_bufs[0].frag_timeout); */ frag = find_fragment(&rx_pkt.hw_src_addr, &rx_pkt.hw_dst_addr, dgram_size, dgram_tag); /* if (frag) { printf("frag found\n"); } else { printf("frag NOT found\n"); } */ if (frag) { /* fragment reassembly buffer found */ /* check for overlap */ //TODO: ENABLE THIS PART !!!// for (p = frag->frag_list; p; p=p->next) {// if (dgram_offset == p->offset){// if (len == p->len) {// /* same offset, same len => discard this duplicate */// goto discard_packet;// } else {// /* same offset, but different len */// goto frag_overlap;// }// } else if (dgram_offset > p->offset// && dgram_offset < p->offset + p->len/8// ) {// /* offset inside another frag*/// goto frag_overlap;// }// } /* no overlap found */ //printf("frag found: %d\n", frag->frag_timeout); goto frag_reassemble; } else { /* fragment reassembly buffer not found - set up a new one */ // no match found -- need a new frag_buf_t for (i = 0; i< FRAG_BUFS; i++) { if (frag_bufs[i].frag_timeout == FRAG_FREE && call AppDataPool.empty() == FALSE) { frag = &frag_bufs[i]; set_16t(&frag->dgram_tag, get_16t(&frag_hdr->dgram_tag)); set_16t(&frag->dgram_size, dgram_size); memcpy(&frag->hw_src_addr, &rx_pkt.hw_src_addr, sizeof(frag->hw_src_addr)); memcpy(&frag->hw_dst_addr, &rx_pkt.hw_dst_addr, sizeof(frag->hw_dst_addr)); frag->frag_timeout = FRAG_TIMEOUT; frag->buf = (uint8_t *) call AppDataPool.get(); frag->frag_list = NULL; /* printf("new frag_buf[%d] %d\n", i, frag_bufs[i].frag_timeout); printf("frag pool size: %d\n", call FragInfoPool.size()); call PrintfFlush.flush(); */ goto frag_reassemble; } } // no free slot for reassembling fragments#ifdef ENABLE_PRINTF_DEBUG printf("no free slot - discarding frag\n"); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ goto discard_packet; } frag_overlap: /* overlap - discard previous frags * and restart fragment reassembly */ free_frag_list(frag->frag_list); frag->frag_list = NULL; frag->frag_timeout = FRAG_TIMEOUT; goto frag_reassemble; frag_reassemble: /* printf("tag: 0x%04X, size: %d, off: %d, t: %d\n", get_16t(&frag->dgram_tag), ntohs(get_16t(&frag->dgram_size)), dgram_offset, frag->frag_timeout); //printf("f_b[%d] %d\n", 0, frag_bufs[0].frag_timeout); if (dgram_offset > 0) { call PrintfFlush.flush(); } */ /* copy buf data */ //if (dgram_offset*8 + len <= sizeof(frag->buf)) { if (dgram_offset*8 + len <= FRAG_BUF_SIZE) { memcpy(frag->buf + (dgram_offset*8), buf, len); } else { call Leds.led0Toggle(); } /* update frag_info */ p = call FragInfoPool.get(); if (!p) { //out of memory - fragment reassembly failing //TODO call Leds.led0Toggle();#ifdef ENABLE_PRINTF_DEBUG printf("FAILED to alloc frag_info_t\n"); call PrintfFlush.flush();#endif /* ENABLE_PRINTF_DEBUG */ } else { p->offset = dgram_offset; p->len = len; /* insert frag_info into the orderer list */ if (frag->frag_list) { for(q = &(frag->frag_list); (*q)->next; q=&((*q)->next)) { if (p->offset > (*q)->offset) { break; } } p->next = *q; *q = p; } else { p->next = frag->frag_list; frag->frag_list = p; } }#ifdef ENABLE_PRINTF_DEBUG if (dgram_offset > 20) { printf("frag_list:\n"); //ntohs(get_16t(&frag->dgram_tag)), //ntohs(get_16t(&frag->dgram_size))); for (p=frag->frag_list;p;p=p->next) { printf("off: %d, len: %d\n", p->offset, p->len); } call PrintfFlush.flush(); }#endif /* ENABLE_PRINTF_DEBUG */ /* check if this is not the last fragment */ if (!dgram_offset) { /* the first fragment cannot be the last one */ last_frag = 0; } else { last_frag=1; dgram_offset = ntohs(dgram_size)/8; for(p=frag->frag_list; p && dgram_offset; p=p->next) { //debug("dgram_offset: %d, p->offset: %d, p->len: %d\n", // dgram_offset, p->offset, p->len); if (p->offset + p->len/8 != dgram_offset) { //debug("offset mismatch - not the last fragment\n"); last_frag = 0; break; } dgram_offset = p->offset; } } if (last_frag) { call Leds.led1Toggle(); /* prepare the complete packet to be passed up*/ lowpan_pkt_clear(&rx_pkt); rx_pkt.app_data = frag->buf; rx_pkt.app_data_dealloc = APP_DATA_DEALLOC_TRUE; rx_pkt.header_begin = frag->buf; rx_pkt.header_len = ntohs(dgram_size); //debug("dumping reassembled datagram...\n"); //dump_serial_packet(pkt->buf_begin, pkt->len); /* pass up the packet */ layer3_input(rx_pkt.header_begin, rx_pkt.header_len); /* deallocate all fragment info */ free_frag_list(frag->frag_list); frag->frag_list = NULL; frag->frag_timeout = FRAG_FREE; if (rx_pkt.app_data_dealloc == APP_DATA_DEALLOC_TRUE && rx_pkt.app_data) { /* deallocate the frag_buf */ call AppDataPool.put((app_data_t *) rx_pkt.app_data); } } else { /* packet not yet complete */ return; } dispatch = buf; } else { /* no fragmentation */ /* pass up the complete packet */ lowpan_pkt_clear(&rx_pkt); rx_pkt.header_begin = buf; rx_pkt.header_len = len; layer3_input(buf, len); } discard_packet: // deallocate pkt // update stats}/* Receive an AM from the lower layer */event TRUSTEDBLOCK message_t* Receive.receive(message_t* msg, void* payload, uint8_t len){ am_addr_t am_addr; //call Leds.led0Toggle(); /* 802.15.4 source address */ rx_pkt.hw_src_addr.type = HW_ADDR_SHORT; am_addr = call AMPacket.source(msg); memcpy(&rx_pkt.hw_src_addr.addr_short, &am_addr, sizeof(am_addr_t)); /* 802.15.4 destination address */ rx_pkt.hw_dst_addr.type = HW_ADDR_SHORT; am_addr = call AMPacket.destination(msg); memcpy(&rx_pkt.hw_dst_addr.addr_short, &am_addr, sizeof(am_addr_t)); lowpan_input(payload, len); return msg;}/****************************************** * Interface StdControl ******************************************/ command error_t IPControl.start() {#ifdef ENABLE_PRINTF_DEBUG call PrintfControl.start();#endif /* ENABLE_PRINTF_DEBUG */ ip_init(); linklocal_addr.addr[0] = 0xfe; linklocal_addr.addr[1] = 0x80; ipv6_iface_id_from_am_addr(call AMPacket.address(), &(linklocal_addr.addr[8])); //set_16t((uint16_t *)&(linklocal_addr.addr[14]), am_addr); call MessageControl.start(); return SUCCESS;}event void MessageControl.startDone(error_t err) { if (err == SUCCESS) { signal IPControl.startDone(err); call Timer.startPeriodic(1024); /* fire every second */ } else { call MessageControl.start(); }}command error_t IPControl.stop(){ call MessageControl.stop(); call Timer.stop(); #ifdef ENABLE_PRINTF_DEBUG call PrintfControl.stop();#endif /* ENABLE_PRINTF_DEBUG */ return SUCCESS;}event void MessageControl.stopDone(error_t err) { signal IPControl.stopDone(err);}/****************************************** * IP Interface ******************************************/command void IP.getAddress(ip6_addr_t *addr){ addr = &global_addr; //uip_unpack_ipaddr( uip_global_addr, addr->addr );}command void IP.setAddress(const ip6_addr_t *addr){ memcpy(&global_addr, addr, sizeof(*addr)); //uip_pack_ipaddr(uip_global_addr,octet1,octet2,octet3,octet4);}command void IP.setAddressAutoconf(const ip6_addr_t *addr){ memcpy(&global_addr, addr, sizeof(*addr)); ipv6_iface_id_from_am_addr(call AMPacket.address(), &(global_addr.addr[8])); //set_16t((uint16_t *)&(global_addr.addr[14]), am_addr);}/***************************** * UDP functions *****************************/command error_t UDPClient.listen[uint8_t num](uint16_t port){ if (port) { memset(&udp_conns[num].ripaddr, 0, sizeof(udp_conns[num].ripaddr)); set_16t(&udp_conns[num].lport, htons(port)); } else { set_16t(&udp_conns[num].lport, 0); } return SUCCESS;}command error_tUDPClient.connect[uint8_t num](const ip6_addr_t *addr, const uint16_t port){ struct udp_conn *conn = &udp_conns[num]; if (addr && port) { memcpy(&conn->ripaddr, addr, sizeof(conn->ripaddr)); set_16t(&conn->rport, htons(port)); } else { memset(&conn->ripaddr, 0 , sizeof(conn->ripaddr)); set_16t(&conn->rport, 0); } return SUCCESS;}command error_tUDPClient.sendTo[uint8_t num](const ip6_addr_t *addr, uint16_t port, const uint8_t *buf, uint16_t len){ if (udp_conns[num].lport == 0) { set_16t(&udp_conns[num].lport, htons(udp_assign_port())); } return udp_compressed_output(buf, len, NULL, addr, udp_conns[num].lport, htons(port), num+1);}command error_t UDPClient.send[uint8_t num]( const uint8_t *buf, uint16_t len ){ if (udp_conns[num].rport == 0 || ipv6_addr_is_zero(&udp_conns[num].ripaddr)) return FAIL; return call UDPClient.sendTo[num](&(udp_conns[num].ripaddr), udp_conns[num].rport, buf, len);}default event voidUDPClient.sendDone[uint8_t num](error_t result, void* buf){}default event voidUDPClient.receive[uint8_t num](const ip6_addr_t *addr, uint16_t port, uint8_t *buf, uint16_t len){}/****************************************** * Printf Timer ******************************************/#ifdef ENABLE_PRINTF_DEBUGevent void PrintfFlush.flushDone(error_t error) {}event void PrintfControl.startDone(error_t error) {}event void PrintfControl.stopDone(error_t error) {}static void dump_serial_packet(const unsigned char *packet, const int len){ int i; printf("len: %d\n", len); //call PrintfFlush.flush(); if (!packet) { printf("packet is NULL"); } else { for (i = 0; i < len; i++) printf("%02x ", packet[i]); } printf("\n"); //call PrintfFlush.flush();}#endif /* ENABLE_PRINTF_DEBUG */#ifndef ENABLE_PRINTF_DEBUGstatic void dump_serial_packet(const unsigned char *packet, const int len){}#endif /* ENABLE_PRINTF_DEBUG *//****************************************** * Interface Timer ******************************************/event void Timer.fired() { int i=0; /* heartbeat led */ //call Leds.led0Toggle(); /* discard timed-out and not yet assembled fragmented packet */ for (i=0;i<FRAG_BUFS; i++) { if (frag_bufs[i].frag_timeout != FRAG_FREE) { if (frag_bufs[i].frag_timeout > 0) { frag_bufs[i].frag_timeout--; } else { /* fragment reassembly timed out */ frag_bufs[i].frag_timeout = FRAG_FREE; free_frag_list(frag_bufs[i].frag_list); if (frag_bufs[i].buf) { call AppDataPool.put((app_data_t *) frag_bufs[i].buf); } //call Leds.led0Toggle(); } } } //TODO: check for timed-out ND request and resend/give up and mark as such //TODO: check outgoing pkts queue and schedule ND or sending /* counter++; if (locked) { return; } else { //Packet.clear(&test_packet); uint8_t* data=(uint8_t*) call Packet.getPayload(&test_packet,NULL); if (call Packet.maxPayloadLength() < 1) { return; } data[0] = counter; call AMPacket.setSource(&test_packet, 0x14); if (call AMSend.send(3, &test_packet, 1) == SUCCESS) { // if (call AMSend.send(AM_BROADCAST_ADDR, &test_packet, sizeof(test_serial_msg_t)) == SUCCESS) { locked = TRUE; } } */}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -