/*---------------------------------------------------------------------------*/ static void handle_incoming_rrep(void) { struct uaodv_msg_rrep *rm = (struct uaodv_msg_rrep *)uip_appdata; struct uaodv_rt_entry *rt; /* Useless HELLO message? */ if(uip_ipaddr_cmp(&BUF->destipaddr, &uip_broadcast_addr)) { #ifdef AODV_RESPOND_TO_HELLOS uint32_t net_seqno; #ifdef CC2420_RADIO int ret = cc2420_check_remote(uip_udp_sender()->u16[1]); if(ret == REMOTE_YES) { print_debug("HELLO drop is remote\n"); return; } else if (ret == REMOTE_NO) { /* Is neigbour, accept it. */ } else if(cc2420_last_rssi < RSSI_THRESHOLD) { print_debug("HELLO drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation); return; } #endif /* Sometimes it helps to send a non-requested RREP in response! */ net_seqno = uip_htonl(my_hseqno); send_rrep(&uip_hostaddr, &BUF->srcipaddr, &BUF->srcipaddr, &net_seqno, 0); #endif return; } print_debug("RREP %d.%d.%d.%d -> %d.%d.%d.%d" " dest=%d.%d.%d.%d seq=%lu hops=%u orig=%d.%d.%d.%d\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno), rm->hop_count, uip_ipaddr_to_quad(&rm->orig_addr)); rt = uaodv_rt_lookup(&rm->dest_addr); /* New forward route? */ if(rt == NULL || (SCMP32(uip_ntohl(rm->dest_seqno), rt->hseqno) > 0)) { print_debug("Inserting3\n"); rt = uaodv_rt_add(&rm->dest_addr, uip_udp_sender(), rm->hop_count, &rm->dest_seqno); #ifdef CC2420_RADIO /* This link is ok since he is unicasting back to us! */ cc2420_recv_ok(uip_udp_sender()); print_debug("RREP recv ok %d %d\n", cc2420_last_rssi, cc2420_last_correlation); #endif } else { print_debug("Not inserting\n"); } /* Forward RREP towards originator? */ if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) { print_debug("ROUTE FOUND\n"); if(rm->flags & UAODV_RREP_ACK) { struct uaodv_msg_rrep_ack *ack = (void *)uip_appdata; ack->type = UAODV_RREP_ACK_TYPE; ack->reserved = 0; sendto(uip_udp_sender(), ack, sizeof(*ack)); } } else { rt = uaodv_rt_lookup(&rm->orig_addr); if(rt == NULL) { print_debug("RREP received, but no route back to originator... :-( \n"); return; } if(rm->flags & UAODV_RREP_ACK) { print_debug("RREP with ACK request (ignored)!\n"); /* Don't want any RREP-ACKs in return! */ rm->flags &= ~UAODV_RREP_ACK; } rm->hop_count++; print_debug("Fwd RREP to %d.%d.%d.%d\n", uip_ipaddr_to_quad(&rt->nexthop)); sendto(&rt->nexthop, rm, sizeof(struct uaodv_msg_rrep)); } }
/*---------------------------------------------------------------------------*/ static void handle_incoming_rreq(void) { struct uaodv_msg_rreq *rm = (struct uaodv_msg_rreq *)uip_appdata; uip_ipaddr_t dest_addr, orig_addr; struct uaodv_rt_entry *rt, *fw = NULL; print_debug("RREQ %d.%d.%d.%d -> %d.%d.%d.%d ttl=%u" " orig=%d.%d.%d.%d seq=%lu hops=%u dest=%d.%d.%d.%d seq=%lu\n", uip_ipaddr_to_quad(&BUF->srcipaddr), uip_ipaddr_to_quad(&BUF->destipaddr), BUF->ttl, uip_ipaddr_to_quad(&rm->orig_addr), uip_ntohl(rm->orig_seqno), rm->hop_count, uip_ipaddr_to_quad(&rm->dest_addr), uip_ntohl(rm->dest_seqno)); if(uip_ipaddr_cmp(&rm->orig_addr, &uip_hostaddr)) { return; /* RREQ looped back! */ } #ifdef CC2420_RADIO { int ret = cc2420_check_remote(uip_udp_sender()->u16[1]); if(ret == REMOTE_YES) { print_debug("RREQ drop is remote\n"); return; } else if (ret == REMOTE_NO) { /* Is neigbour, accept it. */ } else if(cc2420_last_rssi < RSSI_THRESHOLD) { print_debug("RREQ drop %d %d\n", cc2420_last_rssi, cc2420_last_correlation); return; } } #endif #ifdef AODV_BAD_HOP_EXTENSION if(uip_len > (sizeof(*rm) + 2)) { struct uaodv_bad_hop_ext *ext = (void *)(uip_appdata + sizeof(*rm)); uint8_t *end = uip_appdata + uip_len; for(; (uint8_t *)ext < end; ext = (void *)((uint8_t *)ext + ext->length + 2)) { uint8_t *eend = (uint8_t *)ext + ext->length; if(eend > end) eend = end; if(ext->type == RREQ_BAD_HOP_EXT) { uip_ipaddr_t *a; for(a = ext->addrs; (uint8_t *)a < eend; a++) { if(uip_ipaddr_cmp(a, &uip_hostaddr)) { print_debug("BAD_HOP drop\n"); return; } } } } } #endif /* AODV_BAD_HOP_EXTENSION */ /* New reverse route? */ rt = uaodv_rt_lookup(&rm->orig_addr); if(rt == NULL || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) > 0) /* New route. */ || (SCMP32(uip_ntohl(rm->orig_seqno), rt->hseqno) == 0 && rm->hop_count < rt->hop_count)) { /* Better route. */ print_debug("Inserting1\n"); rt = uaodv_rt_add(&rm->orig_addr, uip_udp_sender(), rm->hop_count, &rm->orig_seqno); } /* Check if it is for our address or a fresh route. */ if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr) || rm->flags & UAODV_RREQ_DESTONLY) { fw = NULL; } else { fw = uaodv_rt_lookup(&rm->dest_addr); if(!(rm->flags & UAODV_RREQ_UNKSEQNO) && fw != NULL && SCMP32(fw->hseqno, uip_ntohl(rm->dest_seqno)) <= 0) { fw = NULL; } } if (fw != NULL) { uint32_t net_seqno; print_debug("RREQ for known route\n"); uip_ipaddr_copy(&dest_addr, &rm->dest_addr); uip_ipaddr_copy(&orig_addr, &rm->orig_addr); net_seqno = uip_htonl(fw->hseqno); send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, fw->hop_count + 1); } else if(uip_ipaddr_cmp(&rm->dest_addr, &uip_hostaddr)) { uint32_t net_seqno; print_debug("RREQ for our address\n"); uip_ipaddr_copy(&dest_addr, &rm->dest_addr); uip_ipaddr_copy(&orig_addr, &rm->orig_addr); my_hseqno++; if(!(rm->flags & UAODV_RREQ_UNKSEQNO) && SCMP32(my_hseqno, uip_ntohl(rm->dest_seqno)) < 0) { print_debug("New my_hseqno %lu\n", my_hseqno); /* We have rebooted. */ my_hseqno = uip_ntohl(rm->dest_seqno) + 1; } net_seqno = uip_htonl(my_hseqno); send_rrep(&dest_addr, &rt->nexthop, &orig_addr, &net_seqno, 0); } else if(BUF->ttl > 1) { int len; /* Have we seen this RREQ before? */ if(fwc_lookup(&rm->orig_addr, &rm->rreq_id)) { print_debug("RREQ cached, not fwd\n"); return; } fwc_add(&rm->orig_addr, &rm->rreq_id); print_debug("RREQ fwd\n"); rm->hop_count++; bcastconn->ttl = BUF->ttl - 1; len = sizeof(struct uaodv_msg_rreq); len += add_rreq_extensions(rm + 1); uip_udp_packet_send(bcastconn, rm, len); } }
/*---------------------------------------------------------------------------*/ void uip_nd6_ra_output(uip_ipaddr_t * dest) { UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0; UIP_IP_BUF->flow = 0; UIP_IP_BUF->proto = UIP_PROTO_ICMP6; UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; if(dest == NULL) { uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); } else { /* For sollicited RA */ uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest); } uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); UIP_ICMP_BUF->type = ICMP6_RA; UIP_ICMP_BUF->icode = 0; UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit; UIP_ND6_RA_BUF->flags_reserved = (UIP_ND6_M_FLAG << 7) | (UIP_ND6_O_FLAG << 6); UIP_ND6_RA_BUF->router_lifetime = uip_htons(UIP_ND6_ROUTER_LIFETIME); //UIP_ND6_RA_BUF->reachable_time = uip_htonl(uip_ds6_if.reachable_time); //UIP_ND6_RA_BUF->retrans_timer = uip_htonl(uip_ds6_if.retrans_timer); UIP_ND6_RA_BUF->reachable_time = 0; UIP_ND6_RA_BUF->retrans_timer = 0; uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN; nd6_opt_offset = UIP_ND6_RA_LEN; #if !UIP_CONF_ROUTER /* Prefix list */ for(prefix = uip_ds6_prefix_list; prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) { if((prefix->isused) && (prefix->advertise)) { UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO; UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8; UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length; UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved; UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime); UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime); UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0; uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr)); nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN; uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN; } } #endif /* !UIP_CONF_ROUTER */ /* Source link-layer option */ create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO); uip_len += UIP_ND6_OPT_LLAO_LEN; nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN; /* MTU */ UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU; UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3; UIP_ND6_OPT_MTU_BUF->reserved = 0; //UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(uip_ds6_if.link_mtu); UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(1500); uip_len += UIP_ND6_OPT_MTU_LEN; nd6_opt_offset += UIP_ND6_OPT_MTU_LEN; UIP_IP_BUF->len[0] = ((uip_len - UIP_IPH_LEN) >> 8); UIP_IP_BUF->len[1] = ((uip_len - UIP_IPH_LEN) & 0xff); /*ICMP checksum */ UIP_ICMP_BUF->icmpchksum = 0; UIP_ICMP_BUF->icmpchksum = ~uip_icmp6chksum(); UIP_STAT(++uip_stat.nd6.sent); PRINTF("Sending RA to"); PRINT6ADDR(&UIP_IP_BUF->destipaddr); PRINTF("from"); PRINT6ADDR(&UIP_IP_BUF->srcipaddr); PRINTF("\n"); return; }
/*---------------------------------------------------------------------------*/ void uip_nd6_ra_output(uip_ipaddr_t * dest) { UIP_IP_BUF->vtc = 0x60; UIP_IP_BUF->tcflow = 0; UIP_IP_BUF->flow = 0; UIP_IP_BUF->proto = UIP_PROTO_ICMP6; UIP_IP_BUF->ttl = UIP_ND6_HOP_LIMIT; if(dest == NULL) { uip_create_linklocal_allnodes_mcast(&UIP_IP_BUF->destipaddr); } else { /* For sollicited RA */ uip_ipaddr_copy(&UIP_IP_BUF->destipaddr, dest); } uip_ds6_select_src(&UIP_IP_BUF->srcipaddr, &UIP_IP_BUF->destipaddr); UIP_ICMP_BUF->type = ICMP6_RA; UIP_ICMP_BUF->icode = 0; UIP_ND6_RA_BUF->cur_ttl = uip_ds6_if.cur_hop_limit; UIP_ND6_RA_BUF->flags_reserved = (UIP_ND6_M_FLAG << 7) | (UIP_ND6_O_FLAG << 6); UIP_ND6_RA_BUF->router_lifetime = uip_htons(UIP_ND6_ROUTER_LIFETIME); //UIP_ND6_RA_BUF->reachable_time = uip_htonl(uip_ds6_if.reachable_time); //UIP_ND6_RA_BUF->retrans_timer = uip_htonl(uip_ds6_if.retrans_timer); UIP_ND6_RA_BUF->reachable_time = 0; UIP_ND6_RA_BUF->retrans_timer = 0; uip_len = UIP_IPH_LEN + UIP_ICMPH_LEN + UIP_ND6_RA_LEN; nd6_opt_offset = UIP_ND6_RA_LEN; /* Prefix list */ for(prefix = uip_ds6_prefix_list; prefix < uip_ds6_prefix_list + UIP_DS6_PREFIX_NB; prefix++) { if((prefix->isused) && (prefix->advertise)) { UIP_ND6_OPT_PREFIX_BUF->type = UIP_ND6_OPT_PREFIX_INFO; UIP_ND6_OPT_PREFIX_BUF->len = UIP_ND6_OPT_PREFIX_INFO_LEN / 8; UIP_ND6_OPT_PREFIX_BUF->preflen = prefix->length; UIP_ND6_OPT_PREFIX_BUF->flagsreserved1 = prefix->l_a_reserved; UIP_ND6_OPT_PREFIX_BUF->validlt = uip_htonl(prefix->vlifetime); UIP_ND6_OPT_PREFIX_BUF->preferredlt = uip_htonl(prefix->plifetime); UIP_ND6_OPT_PREFIX_BUF->reserved2 = 0; uip_ipaddr_copy(&(UIP_ND6_OPT_PREFIX_BUF->prefix), &(prefix->ipaddr)); nd6_opt_offset += UIP_ND6_OPT_PREFIX_INFO_LEN; uip_len += UIP_ND6_OPT_PREFIX_INFO_LEN; } } /* Source link-layer option */ create_llao((uint8_t *)UIP_ND6_OPT_HDR_BUF, UIP_ND6_OPT_SLLAO); uip_len += UIP_ND6_OPT_LLAO_LEN; nd6_opt_offset += UIP_ND6_OPT_LLAO_LEN; /* MTU */ UIP_ND6_OPT_MTU_BUF->type = UIP_ND6_OPT_MTU; UIP_ND6_OPT_MTU_BUF->len = UIP_ND6_OPT_MTU_LEN >> 3; UIP_ND6_OPT_MTU_BUF->reserved = 0; //UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(uip_ds6_if.link_mtu); UIP_ND6_OPT_MTU_BUF->mtu = uip_htonl(1500); uip_len += UIP_ND6_OPT_MTU_LEN; nd6_opt_offset += UIP_ND6_OPT_MTU_LEN; #if UIP_CONF_DS6_ROUTE_INFORMATION for(rtinfo = uip_ds6_route_info_list; rtinfo < uip_ds6_route_info_list + UIP_DS6_ROUTE_INFO_NB; rtinfo++) { if((rtinfo->isused)) { UIP_ND6_OPT_ROUTE_BUF->type = UIP_ND6_OPT_ROUTE_INFO; UIP_ND6_OPT_ROUTE_BUF->len =(rtinfo->length >> 6) + 1 ; UIP_ND6_OPT_ROUTE_BUF->preflen = rtinfo->length; UIP_ND6_OPT_ROUTE_BUF->flagsreserved = rtinfo->flags; UIP_ND6_OPT_ROUTE_BUF->rlifetime = uip_htonl(rtinfo->lifetime); uip_ipaddr_copy(&(UIP_ND6_OPT_ROUTE_BUF->prefix), &(rtinfo->ipaddr)); nd6_opt_offset += ((rtinfo->length >> 6) + 1)<<3; uip_len += ((rtinfo->length >> 6) + 1)<<3; } }
/*---------------------------------------------------------------------------*/ static uint8_t process_request() { uint8_t len; uint8_t count; /* How many did we pack? */ uint8_t i; uint8_t left; uint8_t entry_size; left = VIZTOOL_MAX_PAYLOAD_LEN - 1; len = 2; /* start filling the buffer from position [2] */ count = 0; if(buf[0] == REQUEST_TYPE_ND) { /* Neighbors */ PRINTF("Neighbors\n"); for(i = buf[1]; i < UIP_DS6_NBR_NB; i++) { if(uip_ds6_nbr_cache[i].isused) { entry_size = sizeof(i) + sizeof(uip_ipaddr_t) + sizeof(uip_lladdr_t) + sizeof(uip_ds6_nbr_cache[i].state); PRINTF("%02u: ", i); PRINT6ADDR(&uip_ds6_nbr_cache[i].ipaddr); PRINTF(" - "); PRINTLLADDR(&uip_ds6_nbr_cache[i].lladdr); PRINTF(" - %u\n", uip_ds6_nbr_cache[i].state); memcpy(buf + len, &i, sizeof(i)); len += sizeof(i); memcpy(buf + len, &uip_ds6_nbr_cache[i].ipaddr, sizeof(uip_ipaddr_t)); len += sizeof(uip_ipaddr_t); memcpy(buf + len, &uip_ds6_nbr_cache[i].lladdr, sizeof(uip_lladdr_t)); len += sizeof(uip_lladdr_t); memcpy(buf + len, &uip_ds6_nbr_cache[i].state, sizeof(uip_ds6_nbr_cache[i].state)); len += sizeof(uip_ds6_nbr_cache[i].state); count++; left -= entry_size; if(left < entry_size) { break; } } } } else if(buf[0] == REQUEST_TYPE_RT) { uint32_t flip = 0; PRINTF("Routing table\n"); for(i = buf[1]; i < UIP_DS6_ROUTE_NB; i++) { if(uip_ds6_routing_table[i].isused) { entry_size = sizeof(i) + sizeof(uip_ds6_routing_table[i].ipaddr) + sizeof(uip_ds6_routing_table[i].length) + sizeof(uip_ds6_routing_table[i].metric) + sizeof(uip_ds6_routing_table[i].nexthop) + sizeof(uip_ds6_routing_table[i].state.lifetime) + sizeof(uip_ds6_routing_table[i].state.learned_from); memcpy(buf + len, &i, sizeof(i)); len += sizeof(i); memcpy(buf + len, &uip_ds6_routing_table[i].ipaddr, sizeof(uip_ds6_routing_table[i].ipaddr)); len += sizeof(uip_ds6_routing_table[i].ipaddr); memcpy(buf + len, &uip_ds6_routing_table[i].length, sizeof(uip_ds6_routing_table[i].length)); len += sizeof(uip_ds6_routing_table[i].length); memcpy(buf + len, &uip_ds6_routing_table[i].metric, sizeof(uip_ds6_routing_table[i].metric)); len += sizeof(uip_ds6_routing_table[i].metric); memcpy(buf + len, &uip_ds6_routing_table[i].nexthop, sizeof(uip_ds6_routing_table[i].nexthop)); len += sizeof(uip_ds6_routing_table[i].nexthop); PRINT6ADDR(&uip_ds6_routing_table[i].ipaddr); PRINTF(" - %02x", uip_ds6_routing_table[i].length); PRINTF(" - %02x", uip_ds6_routing_table[i].metric); PRINTF(" - "); PRINT6ADDR(&uip_ds6_routing_table[i].nexthop); flip = uip_htonl(uip_ds6_routing_table[i].state.lifetime); memcpy(buf + len, &flip, sizeof(flip)); len += sizeof(flip); PRINTF(" - %08lx", uip_ds6_routing_table[i].state.lifetime); memcpy(buf + len, &uip_ds6_routing_table[i].state.learned_from, sizeof(uip_ds6_routing_table[i].state.learned_from)); len += sizeof(uip_ds6_routing_table[i].state.learned_from); PRINTF(" - %02x [%u]\n", uip_ds6_routing_table[i].state.learned_from, entry_size); count++; left -= entry_size; if(left < entry_size) { break; } } } } else if (buf[0] == REQUEST_TYPE_DRT) { uint32_t flip = 0; PRINTF("Default Routes\n"); for(i = buf[1]; i < UIP_DS6_DEFRT_NB; i++) { if(uip_ds6_defrt_list[i].isused) { entry_size = sizeof(i) + sizeof(uip_ds6_defrt_list[i].ipaddr) + sizeof(uip_ds6_defrt_list[i].isinfinite); memcpy(buf + len, &i, sizeof(i)); len += sizeof(i); memcpy(buf + len, &uip_ds6_defrt_list[i].ipaddr, sizeof(uip_ds6_defrt_list[i].ipaddr)); len += sizeof(uip_ds6_defrt_list[i].ipaddr); memcpy(buf + len, &uip_ds6_defrt_list[i].isinfinite, sizeof(uip_ds6_defrt_list[i].isinfinite)); len += sizeof(uip_ds6_defrt_list[i].isinfinite); PRINT6ADDR(&uip_ds6_defrt_list[i].ipaddr); PRINTF(" - %u\n", uip_ds6_defrt_list[i].isinfinite); count++; left -= entry_size; if(left < entry_size) { break; } } } } else if (buf[0] == REQUEST_TYPE_ADDR) { PRINTF("Unicast Addresses\n"); for(i = buf[1]; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { entry_size = sizeof(i) + sizeof(uip_ds6_if.addr_list[i].ipaddr); memcpy(buf + len, &i, sizeof(i)); len += sizeof(i); memcpy(buf + len, &uip_ds6_if.addr_list[i].ipaddr, sizeof(uip_ds6_if.addr_list[i].ipaddr)); len += sizeof(uip_ds6_if.addr_list[i].ipaddr); PRINT6ADDR(&uip_ds6_if.addr_list[i].ipaddr); PRINTF("\n"); count++; left -= entry_size; if(left < entry_size) { break; } } } } else if (buf[0] == REQUEST_TYPE_TOTALS) { memset(&buf[2], 0, 4); for(i = 0; i < UIP_DS6_ADDR_NB; i++) { if(uip_ds6_if.addr_list[i].isused) { buf[2]++; } } for(i = 0; i < UIP_DS6_NBR_NB; i++) { if(uip_ds6_nbr_cache[i].isused) { buf[3]++; } } for(i = 0; i < UIP_DS6_ROUTE_NB; i++) { if(uip_ds6_routing_table[i].isused) { buf[4]++; } } for(i = 0; i < UIP_DS6_DEFRT_NB; i++) { if(uip_ds6_defrt_list[i].isused) { buf[5]++; } } len += 4; count = 4; } else { return 0; } buf[1] = count; return len; }
void device_handler(void* request, void* response, uint8_t *buffer, uint16_t preferred_size, int32_t *offset) { const char *uri_path = NULL; uint8_t uri_len = REST.get_url(request, &uri_path); if (uri_len == 1) { if (*offset >= LEN_D_CORE) { coap_set_status_code(response, BAD_OPTION_4_02); coap_set_payload(response, "BlockOutOfScope", 15); return; } flash_getVar(buffer, RES_D_CORE + *offset, preferred_size); if (LEN_D_CORE - *offset < preferred_size) { preferred_size = LEN_D_CORE - *offset; *offset = -1; } else { *offset += preferred_size; } REST.set_header_content_type(response, APPLICATION_LINK_FORMAT); REST.set_response_payload(response, buffer, preferred_size); return; } //************************************************************************* //* DEVICE NAME * //************************************************************************* if (uri_path[2] == 'n' && uri_path[3] == 'a') { flash_getVar(buffer, RES_NAME, LEN_NAME); REST.set_header_content_type(response, TEXT_PLAIN); REST.set_response_payload(response, buffer, strlen(buffer)); } //************************************************************************* //* DEVICE MODEL * //************************************************************************* if (uri_path[2] == 'm') { flash_getVar(buffer, RES_MODEL, LEN_MODEL); REST.set_header_content_type(response, TEXT_PLAIN); REST.set_response_payload(response, buffer, strlen(buffer)); return; } //************************************************************************* //* DEVICE IDENTIFIER * //************************************************************************* if (uri_path[2] == 'u') { leds_on(LEDS_GREEN); send_hello = 0; flash_getVar(buffer, RES_UUID, LEN_UUID); REST.set_header_content_type(response, APPLICATION_OCTET_STREAM); REST.set_response_payload(response, buffer, LEN_UUID); } //************************************************************************* //* DEVICE TIME * //************************************************************************* if (uri_path[2] == 't') { uint32_t time = uip_htonl(clock_seconds()); memcpy(buffer, &time, 4); REST.set_header_content_type(response, APPLICATION_OCTET_STREAM); REST.set_response_payload(response, buffer, 4); } //************************************************************************* //* DEVICE PSK * //************************************************************************* if (uri_path[2] == 'p') { getPSK(buffer); REST.set_header_content_type(response, APPLICATION_OCTET_STREAM); REST.set_response_payload(response, buffer, LEN_PSK); } //************************************************************************* //* DEVICE DEFAULT ROUTE * //************************************************************************* if (uri_path[2] == 'r') { uip_ipaddr_t *addr = uip_ds6_defrt_choose(); memcpy(buffer, addr, 16); REST.set_header_content_type(response, APPLICATION_OCTET_STREAM); REST.set_response_payload(response, buffer, 16); } //************************************************************************* //* DEVICE NEIGHBOURS * //************************************************************************* if (uri_path[2] == 'n' && uri_path[3] == 'b') { uint32_t o = *offset / 16; uint32_t bfr_ptr = 0; uint32_t i; uip_ds6_nbr_t *nbr = nbr_table_head(ds6_neighbors); for (i = 0; i < (o+2); i++) { if (i >= o) { memcpy(buffer + bfr_ptr, &nbr->ipaddr, 16); bfr_ptr += 16; } nbr = nbr_table_next(ds6_neighbors, nbr); if (nbr == NULL) { if (bfr_ptr == 0) { coap_set_status_code(response, BAD_OPTION_4_02); coap_set_payload(response, "BlockOutOfScope", 15); return; } break; } } if (nbr == NULL) { *offset = -1; } else { *offset += bfr_ptr; } REST.set_header_content_type(response, APPLICATION_OCTET_STREAM); REST.set_response_payload(response, buffer, bfr_ptr); } }