uint8_t rpl_init(int if_id) { mutex_init(&rpl_send_mutex); mutex_init(&rpl_recv_mutex); rpl_instances_init(); /* initialize routing table */ rpl_clear_routing_table(); init_trickle(); rpl_process_pid = thread_create(rpl_process_buf, RPL_PROCESS_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, rpl_process, "rpl_process"); /* INSERT NEW OBJECTIVE FUNCTIONS HERE */ objective_functions[0] = rpl_get_of0(); objective_functions[1] = rpl_get_of_mrhof(); sixlowpan_lowpan_init_interface(if_id); /* need link local prefix to query _our_ corresponding address */ ipv6_addr_t ll_address; ipv6_addr_set_link_local_prefix(&ll_address); ipv6_net_if_get_best_src_addr(&my_address, &ll_address); ipv6_register_rpl_handler(rpl_process_pid); /* initialize ETX-calculation if needed */ if (RPL_DEFAULT_OCP == 1) { DEBUG("%s, %d: INIT ETX BEACONING\n", __FILE__, __LINE__); etx_init_beaconing(&my_address); } return SIXLOWERROR_SUCCESS; }
/* obligatory for each mode. normally not modified */ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header) { uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); ipv6_send_buf->version_trafficclass = IPV6_VER; ipv6_send_buf->trafficclass_flowlabel = 0; ipv6_send_buf->flowlabel = 0; ipv6_send_buf->nextheader = next_header; ipv6_send_buf->hoplimit = MULTIHOP_HOPLIMIT; ipv6_send_buf->length = HTONS(p_len); memcpy(&(ipv6_send_buf->destaddr), destination, 16); ipv6_net_if_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); icmp_send_buf->checksum = icmpv6_csum(ipv6_send_buf, icmp_send_buf); /* The packet was "assembled" in rpl_%mode%.c. Therefore rpl_send_buf was used. * Therefore memcpy is not needed because the payload is at the * right memory location already. */ if (p_ptr != payload) { memcpy(p_ptr, payload, p_len); } ipv6_send_packet(ipv6_send_buf, NULL); }
int ipv6_send_packet(ipv6_hdr_t *packet) { uint16_t length = IPV6_HDR_LEN + NTOHS(packet->length); ndp_neighbor_cache_t *nce; ipv6_net_if_get_best_src_addr(&packet->srcaddr, &packet->destaddr); if (!ipv6_addr_is_multicast(&packet->destaddr) && ndp_addr_is_on_link(&packet->destaddr)) { nce = ndp_get_ll_address(&packet->destaddr); if (nce == NULL || sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr, nce->lladdr_len, (uint8_t *)packet, length) < 0) { /* XXX: this is wrong, but until ND does not work correctly, * this is the only way (aka the old way)*/ uint16_t raddr = NTOHS(packet->destaddr.uint16[7]); sixlowpan_lowpan_sendto(0, &raddr, 2, (uint8_t *)packet, length); /* return -1; */ } return length; } else { /* see if dest should be routed to a different next hop */ if (ipv6_addr_is_multicast(&packet->destaddr)) { /* if_id will be ignored */ uint16_t addr = 0xffff; return sixlowpan_lowpan_sendto(0, &addr, 2, (uint8_t *)packet, length); } if (ip_get_next_hop == NULL) { return -1; } ipv6_addr_t *dest = ip_get_next_hop(&packet->destaddr); if (dest == NULL) { return -1; } nce = ndp_get_ll_address(&packet->destaddr); if (nce == NULL || sixlowpan_lowpan_sendto(nce->if_id, &nce->lladdr, nce->lladdr_len, (uint8_t *)packet, length) < 0) { /* XXX: this is wrong, but until ND does not work correctly, * this is the only way (aka the old way)*/ uint16_t raddr = NTOHS(packet->destaddr.uint16[7]); sixlowpan_lowpan_sendto(0, &raddr, 2, (uint8_t *)packet, length); /* return -1; */ } return length; } }
/* obligatory for each mode. normally not modified */ void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header) { uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); DEBUGF("Trying to send to destination: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, destination)); ipv6_send_buf->version_trafficclass = IPV6_VER; ipv6_send_buf->trafficclass_flowlabel = 0; ipv6_send_buf->flowlabel = 0; ipv6_send_buf->nextheader = next_header; ipv6_send_buf->hoplimit = MULTIHOP_HOPLIMIT; ipv6_send_buf->length = HTONS(p_len); memcpy(&(ipv6_send_buf->destaddr), destination, 16); ipv6_net_if_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); icmp_send_buf->checksum = icmpv6_csum(ipv6_send_buf, icmp_send_buf); /* The packet was "assembled" in rpl_%mode%.c. Therefore rpl_send_buf was used. * Therefore memcpy is not needed because the payload is at the * right memory location already. */ if (p_ptr != payload) { memcpy(p_ptr, payload, p_len); } if (ipv6_addr_is_multicast(&ipv6_send_buf->destaddr)) { ipv6_send_packet(ipv6_send_buf, NULL); } else { /* find appropriate next hop before sending */ ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr); DEBUGF("Trying to send to destination: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, next_hop)); if (next_hop == NULL) { if (i_am_root) { DEBUGF("[Error] destination unknown: %s\n", ipv6_addr_to_str(addr_str_mode, IPV6_MAX_ADDR_STR_LEN, &ipv6_send_buf->destaddr)); return; } else { next_hop = rpl_get_my_preferred_parent(); if (next_hop == NULL) { DEBUGF("[Error] no preferred parent, dropping package\n"); return; } } } DEBUGF("Sending done (for RPL)\n"); ipv6_send_packet(ipv6_send_buf, NULL); } }
void rpl_send(ipv6_addr_t *destination, uint8_t *payload, uint16_t p_len, uint8_t next_header) { uint8_t *p_ptr; ipv6_send_buf = get_rpl_send_ipv6_buf(); p_ptr = get_rpl_send_payload_buf(ipv6_ext_hdr_len); uint16_t packet_length = 0; ipv6_send_buf->version_trafficclass = IPV6_VER; ipv6_send_buf->trafficclass_flowlabel = 0; ipv6_send_buf->flowlabel = 0; ipv6_send_buf->nextheader = next_header; ipv6_send_buf->hoplimit = MULTIHOP_HOPLIMIT; ipv6_send_buf->length = HTONS(p_len); memcpy(&(ipv6_send_buf->destaddr), destination, 16); ipv6_net_if_get_best_src_addr(&(ipv6_send_buf->srcaddr), &(ipv6_send_buf->destaddr)); icmp_send_buf = get_rpl_send_icmpv6_buf(ipv6_ext_hdr_len); icmp_send_buf->checksum = icmpv6_csum(ipv6_send_buf, icmp_send_buf); /* The packet was "assembled" in rpl.c. Therefore rpl_send_buf was used. * Therefore memcpy is not needed because the payload is at the * right memory location already. */ if (p_ptr != payload) { memcpy(p_ptr, payload, p_len); } packet_length = IPV6_HDR_LEN + p_len; if (ipv6_addr_is_multicast(&ipv6_send_buf->destaddr)) { ipv6_send_packet(ipv6_send_buf); } else { /* find appropriate next hop before sending */ ipv6_addr_t *next_hop = rpl_get_next_hop(&ipv6_send_buf->destaddr); if (next_hop == NULL) { if (i_am_root) { DEBUG("%s, %d: [Error] destination unknown\n", __FILE__, __LINE__); return; } else { next_hop = rpl_get_my_preferred_parent(); if (next_hop == NULL) { DEBUG("%s, %d: [Error] no preferred parent, dropping package\n", __FILE__, __LINE__); return; } } } ipv6_send_packet(ipv6_send_buf); } }
static void *etx_radio(void *arg) { (void) arg; msg_t m; radio_packet_t *p; ieee802154_frame_t frame; msg_init_queue(msg_que, ETX_RCV_QUEUE_SIZE); ipv6_addr_t ll_address; ipv6_addr_t candidate_addr; ipv6_addr_set_link_local_prefix(&ll_address); ipv6_net_if_get_best_src_addr(&candidate_addr, &ll_address); while (1) { msg_receive(&m); if (m.type == PKT_PENDING) { p = (radio_packet_t *) m.content.ptr; ieee802154_frame_read(p->data, &frame, p->length); if (frame.payload[0] == ETX_PKT_OPTVAL) { //copy to receive buffer memcpy(etx_rec_buf, &frame.payload[0], frame.payload_len); //create IPv6 address from radio packet //we can do the cast here since rpl nodes can only have addr //up to 8 bits candidate_addr.uint8[ETX_IPV6_LAST_BYTE] = (uint8_t) p->src; //handle the beacon mutex_lock(&etx_mutex); etx_handle_beacon(&candidate_addr); mutex_unlock(&etx_mutex); } p->processing--; } else if (m.type == ENOBUFFER) { DEBUGF("Transceiver buffer full\n"); } else { //packet is not for me, whatever } } return NULL; }
uint8_t rpl_init(int if_id) { rpl_instances_init(); /* initialize routing table */ rpl_clear_routing_table(); if (RPL_DEFAULT_MOP == RPL_STORING_MODE_NO_MC) { rpl_max_routing_entries = RPL_MAX_ROUTING_ENTRIES_STORING; rpl_clear_routing_table(); } else { rpl_max_routing_entries = RPL_MAX_ROUTING_ENTRIES_NON_STORING; rpl_clear_routing_table(); } if (rpl_routing_table == NULL) { DEBUGF("Routing table init failed!\n"); return SIXLOWERROR_NULLPTR; } else { DEBUGF("Routing table init finished!\n"); } init_trickle(); rpl_process_pid = thread_create(rpl_process_buf, RPL_PROCESS_STACKSIZE, PRIORITY_MAIN - 1, CREATE_STACKTEST, rpl_process, NULL, "rpl_process"); sixlowpan_lowpan_init_interface(if_id); /* need link local prefix to query _our_ corresponding address */ ipv6_addr_t ll_address; ipv6_addr_set_link_local_prefix(&ll_address); ipv6_net_if_get_best_src_addr(&my_address, &ll_address); ipv6_register_rpl_handler(rpl_process_pid); ipv6_iface_set_srh_indicator(rpl_is_root); ipv6_iface_set_routing_provider(rpl_get_next_hop); DEBUGF("All addresses set!\n"); /* initialize objective function manager */ rpl_of_manager_init(&my_address); rpl_init_mode(&my_address); return SIXLOWERROR_SUCCESS; }
int32_t udp_sendto(int s, const void *buf, uint32_t len, int flags, sockaddr6_t *to, uint32_t tolen) { (void) flags; (void) tolen; if (udp_socket_compliancy(s) && (socket_base_get_socket(s)->socket_values.foreign_address.sin6_port == 0)) { uint8_t send_buffer[BUFFER_SIZE]; ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer)); udp_hdr_t *current_udp_packet = ((udp_hdr_t *)(&send_buffer[IPV6_HDR_LEN])); uint8_t *payload = &send_buffer[IPV6_HDR_LEN + UDP_HDR_LEN]; memcpy(&(temp_ipv6_header->destaddr), &to->sin6_addr, 16); ipv6_net_if_get_best_src_addr(&(temp_ipv6_header->srcaddr), &(temp_ipv6_header->destaddr)); current_udp_packet->src_port = socket_base_get_free_source_port(IPPROTO_UDP); current_udp_packet->dst_port = to->sin6_port; current_udp_packet->checksum = 0; memcpy(payload, buf, len); current_udp_packet->length = HTONS(UDP_HDR_LEN + len); temp_ipv6_header->length = UDP_HDR_LEN + len; current_udp_packet->checksum = ~ipv6_csum(temp_ipv6_header, (uint8_t *) current_udp_packet, UDP_HDR_LEN + len, IPPROTO_UDP); return ipv6_sendto(&to->sin6_addr, IPPROTO_UDP, (uint8_t *)(current_udp_packet), NTOHS(current_udp_packet->length), NULL); } else { return -1; } }