void trickle_interval(trickle_t *trickle) { trickle->I = trickle->I * 2; DEBUG("TRICKLE new Interval %" PRIu32 "\n", trickle->I); if (trickle->I == 0) { DEBUGF("[WARNING] Interval was 0\n"); if (trickle->Imax == 0) { DEBUGF("[WARNING] Imax == 0\n"); } trickle->I = (trickle->Imin << trickle->Imax); } if (trickle->I > (trickle->Imin << trickle->Imax)) { trickle->I = (trickle->Imin << trickle->Imax); } trickle->c = 0; trickle->t = (trickle->I / 2) + (rand() % ((trickle->I / 2) + 1)); vtimer_remove(&trickle->msg_callback_timer); trickle->msg_callback_time = timex_set(0, trickle->t * 1000); vtimer_set_msg(&trickle->msg_callback_timer, trickle->msg_callback_time, trickle->pid, trickle->callback_msg_type, trickle); vtimer_remove(&trickle->msg_interval_timer); trickle->msg_interval_time = timex_set(0, trickle->I * 1000); vtimer_set_msg(&trickle->msg_interval_timer, trickle->msg_interval_time, trickle->pid, trickle->interval_msg_type, trickle); }
void ng_ndp_retrans_nbr_sol(ng_ipv6_nc_t *nc_entry) { if ((ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) || (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_PROBE)) { if (nc_entry->probes_remaining > 1) { ng_ipv6_addr_t dst; DEBUG("ndp: Retransmit neighbor solicitation for %s\n", ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); /* retransmit neighbor solicatation */ if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_INCOMPLETE) { ng_ipv6_addr_set_solicited_nodes(&dst, &nc_entry->ipv6_addr); } else { dst.u64[0] = nc_entry->ipv6_addr.u64[0]; dst.u64[1] = nc_entry->ipv6_addr.u64[1]; } nc_entry->probes_remaining--; if (nc_entry->iface == KERNEL_PID_UNDEF) { timex_t t = { 0, NG_NDP_RETRANS_TIMER }; kernel_pid_t ifs[NG_NETIF_NUMOF]; size_t ifnum = ng_netif_get(ifs); for (size_t i = 0; i < ifnum; i++) { _send_nbr_sol(ifs[i], &nc_entry->ipv6_addr, &dst); } vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); } else { ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(nc_entry->iface); _send_nbr_sol(nc_entry->iface, &nc_entry->ipv6_addr, &dst); mutex_lock(&ipv6_iface->mutex); vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, ipv6_iface->retrans_timer, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); mutex_unlock(&ipv6_iface->mutex); } } else if (nc_entry->probes_remaining <= 1) { DEBUG("ndp: Remove nc entry %s for interface %" PRIkernel_pid "\n", ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str)), nc_entry->iface); #ifdef MODULE_FIB fib_remove_entry((uint8_t *) & (nc_entry->ipv6_addr), sizeof(ng_ipv6_addr_t)); #endif ng_ipv6_nc_remove(nc_entry->iface, &nc_entry->ipv6_addr); } } }
void icn_initInterest(uint16_t seq) { if (WANT_CONTENT) { uint32_t tmp1; uint16_t tmp2; tmp1 = _getSmallestMissing(); LOG_DEBUG("Smallest missing is %lu\n", tmp1); tmp2 = seq; if ((tmp1 < NUMBER_OF_CHUNKS) && (tmp1 >= 0)) { LOG_INFO("Scheduling retransmission for %lu\n", tmp1); vtimer_remove(&retry_vt); vtimer_set_msg(&retry_vt, retry_interval, thread_getpid(), ICN_RESEND_INTEREST, &tmp1); } if (bf_isset(received_chunks, seq)) { LOG_INFO("Already received a chunk for %u, not sending again\n", seq); return; } #if FLOW_CONTROL if (seq > (receive_counter + FLOW_THR)) { LOG_INFO("Flow control, seq is %u, receive counter is %u\n", seq, receive_counter); return; } #endif /* create packet */ ng_pktsnip_t *pkt; icn_pkt_t icn_pkt; icn_pkt.type = ICN_INTEREST; icn_pkt.seq = seq; memcpy(icn_pkt.payload, interest, strlen(interest) + 1); pkt = ng_pktbuf_add(NULL, &icn_pkt, sizeof(icn_pkt_t), NG_NETTYPE_UNDEF); // send interest packet if (tmp2 < NUMBER_OF_CHUNKS) { LOG_INFO("Sending Interest for %u to %s\n", seq, ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), CONTENT_STORE->uint8, ADDR_LEN_64B)); icn_send(CONTENT_STORE, pkt); } if (tmp2 < NUMBER_OF_CHUNKS) { tmp2++; #if TIMED_SENDING vtimer_remove(&periodic_vt); vtimer_set_msg(&periodic_vt, interval, thread_getpid(), ICN_SEND_INTEREST, &tmp2); #else icn_initInterest(tmp2); #endif } } else { LOG_DEBUG("nothing to do\n"); } }
static int set_timeout(vtimer_t *timeout, long useconds, void *args) { timex_t interval; interval.seconds = useconds / 1000000; interval.microseconds = (useconds % 1000000) * 1000; return vtimer_set_msg(timeout, interval, sending_slot_pid, args); }
gnrc_ipv6_nc_t *gnrc_ipv6_nc_still_reachable(const ipv6_addr_t *ipv6_addr) { gnrc_ipv6_nc_t *entry = gnrc_ipv6_nc_get(KERNEL_PID_UNDEF, ipv6_addr); if (entry == NULL) { DEBUG("ipv6_nc: No entry found for %s\n", ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); return NULL; } if ((gnrc_ipv6_nc_get_state(entry) != GNRC_IPV6_NC_STATE_INCOMPLETE) && (gnrc_ipv6_nc_get_state(entry) != GNRC_IPV6_NC_STATE_UNMANAGED)) { #if defined(MODULE_GNRC_IPV6_NETIF) && defined(MODULE_VTIMER) && defined(MODULE_GNRC_IPV6) gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(entry->iface); timex_t t = iface->reach_time; vtimer_remove(&entry->nbr_sol_timer); vtimer_set_msg(&entry->nbr_sol_timer, t, gnrc_ipv6_pid, GNRC_NDP_MSG_NC_STATE_TIMEOUT, entry); #endif DEBUG("ipv6_nc: Marking entry %s as reachable\n", ipv6_addr_to_str(addr_str, ipv6_addr, sizeof(addr_str))); entry->flags &= ~(GNRC_IPV6_NC_STATE_MASK >> GNRC_IPV6_NC_STATE_POS); entry->flags |= (GNRC_IPV6_NC_STATE_REACHABLE >> GNRC_IPV6_NC_STATE_POS); }
/* sets an entry to stale if its l2addr differs from the given one or creates it stale if it * does not exist */ static void _stale_nc(kernel_pid_t iface, ipv6_addr_t *ipaddr, uint8_t *l2addr, int l2addr_len) { if (l2addr_len != -ENOTSUP) { gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, ipaddr); if (nc_entry == NULL) { #ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER /* tentative type see https://tools.ietf.org/html/rfc6775#section-6.3 */ gnrc_ipv6_netif_t *ipv6_iface = gnrc_ipv6_netif_get(iface); if ((ipv6_iface == NULL) || (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) { timex_t t = { GNRC_SIXLOWPAN_ND_TENTATIVE_NCE_LIFETIME, 0 }; gnrc_ipv6_nc_add(iface, ipaddr, l2addr, (uint16_t)l2addr_len, GNRC_IPV6_NC_STATE_STALE | GNRC_IPV6_NC_TYPE_TENTATIVE); vtimer_remove(&nc_entry->type_timeout); vtimer_set_msg(&nc_entry->type_timeout, t, gnrc_ipv6_pid, GNRC_SIXLOWPAN_ND_MSG_AR_TIMEOUT, nc_entry); return; } #endif gnrc_ipv6_nc_add(iface, ipaddr, l2addr, (uint16_t)l2addr_len, GNRC_IPV6_NC_STATE_STALE); } else if (((uint16_t)l2addr_len != nc_entry->l2_addr_len) || (memcmp(l2addr, nc_entry->l2_addr, l2addr_len) != 0)) { /* if entry exists but l2 address differs: set */ nc_entry->l2_addr_len = (uint16_t)l2addr_len; memcpy(nc_entry->l2_addr, l2addr, l2addr_len); gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE); } } }
kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid) { /* check if RPL was initialized before */ if (gnrc_rpl_pid == KERNEL_PID_UNDEF) { /* start the event loop */ gnrc_rpl_pid = thread_create(_stack, sizeof(_stack), GNRC_RPL_PRIO, CREATE_STACKTEST, _event_loop, NULL, "RPL"); if (gnrc_rpl_pid == KERNEL_PID_UNDEF) { DEBUG("RPL: could not start the event loop\n"); return KERNEL_PID_UNDEF; } _me_reg.demux_ctx = ICMPV6_RPL_CTRL; _me_reg.pid = gnrc_rpl_pid; /* register interest in all ICMPv6 packets */ gnrc_netreg_register(GNRC_NETTYPE_ICMPV6, &_me_reg); gnrc_rpl_of_manager_init(); _lt_time = timex_set(GNRC_RPL_LIFETIME_UPDATE_STEP, 0); vtimer_set_msg(&_lt_timer, _lt_time, gnrc_rpl_pid, GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE, NULL); } /* register all_RPL_nodes multicast address */ ipv6_addr_t all_RPL_nodes = GNRC_RPL_ALL_NODES_ADDR; gnrc_ipv6_netif_add_addr(if_pid, &all_RPL_nodes, IPV6_ADDR_BIT_LEN, 0); gnrc_rpl_send_DIS(NULL, &all_RPL_nodes); return gnrc_rpl_pid; }
static int set_timeout(vtimer_t *timeout, timex_t val, void *args) { vtimer_remove(timeout); timex_normalize(&val); return vtimer_set_msg(timeout, val, sending_slot_pid, args); }
void _rpl_update_routing_table(void) { rpl_dodag_t *my_dodag, *end; rpl_routing_entry_t *rt = rpl_get_routing_table(); for (unsigned int i = 0; i < rpl_max_routing_entries; i++) { if (rt[i].used) { if (rt[i].lifetime <= 1) { memset(&rt[i], 0, sizeof(rt[i])); } else { rt[i].lifetime = rt[i].lifetime - RPL_LIFETIME_STEP; } } } for (my_dodag = rpl_dodags, end = my_dodag + RPL_MAX_DODAGS; my_dodag < end; my_dodag++) { if ((my_dodag->used) && (my_dodag->my_preferred_parent != NULL)) { if (my_dodag->my_preferred_parent->lifetime <= 1) { DEBUGF("parent lifetime timeout\n"); rpl_parent_update(my_dodag, NULL); } else { my_dodag->my_preferred_parent->lifetime = my_dodag->my_preferred_parent->lifetime - RPL_LIFETIME_STEP; } } } vtimer_remove(&rt_timer); vtimer_set_msg(&rt_timer, rt_time, rpl_process_pid, RPL_MSG_TYPE_ROUTING_ENTRY_UPDATE, NULL); }
/** * Function executed by NHDP thread receiving messages in an endless loop */ static void *_nhdp_runner(void *arg) { nhdp_if_entry_t *if_entry; msg_t msg_rcvd, msg_queue[NHDP_MSG_QUEUE_SIZE]; (void)arg; msg_init_queue(msg_queue, NHDP_MSG_QUEUE_SIZE); while (1) { msg_receive(&msg_rcvd); switch (msg_rcvd.type) { case MSG_TIMER: mutex_lock(&send_rcv_mutex); if_entry = (nhdp_if_entry_t *) msg_rcvd.content.ptr; nhdp_writer_send_hello(if_entry); /* TODO: Add jitter */ /* Schedule next sending */ vtimer_set_msg(&if_entry->if_timer, if_entry->hello_interval, thread_getpid(), MSG_TIMER, (void *) if_entry); mutex_unlock(&send_rcv_mutex); break; default: break; } } return 0; }
void gnrc_rpl_delay_dao(gnrc_rpl_dodag_t *dodag) { dodag->dao_time = timex_set(GNRC_RPL_DEFAULT_DAO_DELAY, 0); dodag->dao_counter = 0; dodag->dao_ack_received = false; vtimer_remove(&dodag->dao_timer); vtimer_set_msg(&dodag->dao_timer, dodag->dao_time, gnrc_rpl_pid, GNRC_RPL_MSG_TYPE_DAO_HANDLE, dodag); }
void gnrc_rpl_long_delay_dao(gnrc_rpl_dodag_t *dodag) { dodag->dao_time = timex_set(GNRC_RPL_REGULAR_DAO_INTERVAL, 0); dodag->dao_counter = 0; dodag->dao_ack_received = false; vtimer_remove(&dodag->dao_timer); vtimer_set_msg(&dodag->dao_timer, dodag->dao_time, gnrc_rpl_pid, GNRC_RPL_MSG_TYPE_DAO_HANDLE, dodag); }
void gnrc_sixlowpan_nd_rtr_sol_reschedule(gnrc_ipv6_nc_t *nce, uint32_t sec_delay) { assert(nce != NULL); assert(sec_delay != 0U); vtimer_remove(&nce->rtr_sol_timer); vtimer_set_msg(&nce->rtr_sol_timer, timex_set(sec_delay, 0), gnrc_ipv6_pid, GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL, nce); }
/* router-only functions from net/gnrc/sixlowpan/nd.h */ void gnrc_sixlowpan_nd_opt_abr_handle(kernel_pid_t iface, ndp_rtr_adv_t *rtr_adv, int sicmpv6_size, sixlowpan_nd_opt_abr_t *abr_opt) { uint16_t opt_offset = 0; uint8_t *buf = (uint8_t *)(rtr_adv + 1); gnrc_sixlowpan_nd_router_abr_t *abr; timex_t t = { 0, 0 }; if (_is_me(&abr_opt->braddr)) { return; } /* validity and version was checked in previously called * gnrc_sixlowpan_nd_router_abr_older() */ abr = _get_abr(&abr_opt->braddr); if (abr == NULL) { return; } abr->ltime = byteorder_ntohs(abr_opt->ltime); if (abr->ltime == 0) { abr->ltime = GNRC_SIXLOWPAN_ND_BORDER_ROUTER_DEFAULT_LTIME; return; } sicmpv6_size -= sizeof(ndp_rtr_adv_t); while (sicmpv6_size > 0) { ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset); switch (opt->type) { case NDP_OPT_PI: _add_prefix(iface, abr, (ndp_opt_pi_t *)opt); case NDP_OPT_6CTX: _add_ctx(abr, (sixlowpan_nd_opt_6ctx_t *)opt); default: break; } opt_offset += (opt->len * 8); sicmpv6_size -= (opt->len * 8); } abr->version = (uint32_t)byteorder_ntohs(abr_opt->vlow); abr->version |= ((uint32_t)byteorder_ntohs(abr_opt->vhigh)) << 16; abr->addr.u64[0] = abr_opt->braddr.u64[0]; abr->addr.u64[1] = abr_opt->braddr.u64[1]; memset(abr->ctxs, 0, sizeof(abr->ctxs)); abr->prfs = NULL; t.seconds = abr->ltime * 60; vtimer_set_msg(&abr->ltimer, t, gnrc_ipv6_pid, GNRC_SIXLOWPAN_ND_MSG_ABR_TIMEOUT, abr); }
/* This function is used for regular update of the routes. * The Timer can be overwritten, as the normal delay_dao function gets called */ void long_delay_dao(rpl_dodag_t *dodag) { dodag->dao_time = timex_set(REGULAR_DAO_INTERVAL, 0); dodag->dao_counter = 0; dodag->ack_received = false; vtimer_remove(&dodag->dao_timer); vtimer_set_msg(&dodag->dao_timer, dodag->dao_time, rpl_process_pid, RPL_MSG_TYPE_DAO_HANDLE, dodag); }
void rpl_delay_dao(rpl_dodag_t *dodag) { dodag->dao_time = timex_set(DEFAULT_DAO_DELAY, 0); dodag->dao_counter = 0; dodag->ack_received = false; vtimer_remove(&dodag->dao_timer); vtimer_set_msg(&dodag->dao_timer, dodag->dao_time, rpl_process_pid, RPL_MSG_TYPE_DAO_HANDLE, dodag); }
void gnrc_sixlowpan_nd_wakeup(void) { gnrc_ipv6_nc_t *router = gnrc_ipv6_nc_get_next_router(NULL); while (router) { timex_t t = { 0, GNRC_NDP_RETRANS_TIMER }; vtimer_remove(&router->rtr_sol_timer); gnrc_sixlowpan_nd_uc_rtr_sol(router); gnrc_ndp_internal_send_nbr_sol(router->iface, &router->ipv6_addr, &router->ipv6_addr); vtimer_remove(&router->nbr_sol_timer); vtimer_set_msg(&router->nbr_sol_timer, t, gnrc_ipv6_pid, GNRC_NDP_MSG_NBR_SOL_RETRANS, router); } }
static void _set_state(ng_ipv6_nc_t *nc_entry, uint8_t state) { ng_ipv6_netif_t *ipv6_iface; timex_t t = { NG_NDP_FIRST_PROBE_DELAY, 0 }; nc_entry->flags &= ~NG_IPV6_NC_STATE_MASK; nc_entry->flags |= state; switch (state) { case NG_IPV6_NC_STATE_REACHABLE: ipv6_iface = ng_ipv6_netif_get(nc_entry->iface); t = ipv6_iface->reach_time; /* we intentionally fall through here to set the desired timeout t */ case NG_IPV6_NC_STATE_DELAY: vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid, NG_NDP_MSG_NC_STATE_TIMEOUT, nc_entry); break; case NG_IPV6_NC_STATE_PROBE: ipv6_iface = ng_ipv6_netif_get(nc_entry->iface); nc_entry->probes_remaining = NG_NDP_MAX_UC_NBR_SOL_NUMOF; _send_nbr_sol(nc_entry->iface, &nc_entry->ipv6_addr, &nc_entry->ipv6_addr); mutex_lock(&ipv6_iface->mutex); vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, ipv6_iface->retrans_timer, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); mutex_unlock(&ipv6_iface->mutex); break; default: break; } }
void _dao_handle_send(gnrc_rpl_dodag_t *dodag) { if ((dodag->dao_ack_received == false) && (dodag->dao_counter < GNRC_RPL_DAO_SEND_RETRIES)) { dodag->dao_counter++; gnrc_rpl_send_DAO(dodag, NULL, dodag->default_lifetime); dodag->dao_time = timex_set(GNRC_RPL_DEFAULT_WAIT_FOR_DAO_ACK, 0); vtimer_remove(&dodag->dao_timer); vtimer_set_msg(&dodag->dao_timer, dodag->dao_time, gnrc_rpl_pid, GNRC_RPL_MSG_TYPE_DAO_HANDLE, dodag); } else if (dodag->dao_ack_received == false) { gnrc_rpl_long_delay_dao(dodag); } }
void _dao_handle_send(rpl_dodag_t *dodag) { if ((dodag->ack_received == false) && (dodag->dao_counter < DAO_SEND_RETRIES)) { dodag->dao_counter++; rpl_send_DAO(dodag, NULL, 0, true, 0); dodag->dao_time = timex_set(DEFAULT_WAIT_FOR_DAO_ACK, 0); vtimer_remove(&dodag->dao_timer); vtimer_set_msg(&dodag->dao_timer, dodag->dao_time, rpl_process_pid, RPL_MSG_TYPE_DAO_HANDLE, dodag); } else if (dodag->ack_received == false) { long_delay_dao(dodag); } }
bool gnrc_ndp_internal_pi_opt_handle(kernel_pid_t iface, uint8_t icmpv6_type, ndp_opt_pi_t *pi_opt) { ipv6_addr_t *prefix; gnrc_ipv6_netif_addr_t *netif_addr; if ((pi_opt->len != NDP_OPT_MTU_LEN)) { DEBUG("ndp: invalid MTU option received\n"); return false; } if (icmpv6_type != ICMPV6_RTR_ADV || ipv6_addr_is_link_local(&pi_opt->prefix)) { /* else discard silently */ return true; } prefix = gnrc_ipv6_netif_find_addr(iface, &pi_opt->prefix); if (((prefix == NULL) || (gnrc_ipv6_netif_addr_get(prefix)->prefix_len != pi_opt->prefix_len)) && (pi_opt->valid_ltime.u32 != 0)) { prefix = gnrc_ipv6_netif_add_addr(iface, &pi_opt->prefix, pi_opt->prefix_len, pi_opt->flags & NDP_OPT_PI_FLAGS_MASK); if (prefix == NULL) { DEBUG("ndp: could not add prefix to interface %d\n", iface); return false; } } netif_addr = gnrc_ipv6_netif_addr_get(prefix); if (pi_opt->valid_ltime.u32 == 0) { if (prefix != NULL) { gnrc_ipv6_netif_remove_addr(iface, &netif_addr->addr); } return true; } netif_addr->valid = byteorder_ntohl(pi_opt->valid_ltime); netif_addr->preferred = byteorder_ntohl(pi_opt->pref_ltime); vtimer_remove(&netif_addr->valid_timeout); if (netif_addr->valid != UINT32_MAX) { vtimer_set_msg(&netif_addr->valid_timeout, timex_set(byteorder_ntohl(pi_opt->valid_ltime), 0), thread_getpid(), GNRC_NDP_MSG_ADDR_TIMEOUT, &netif_addr->addr); } /* TODO: preferred lifetime for address auto configuration */ /* on-link flag MUST stay set if it was */ netif_addr->flags &= ~NDP_OPT_PI_FLAGS_A; netif_addr->flags |= (pi_opt->flags & NDP_OPT_PI_FLAGS_MASK); return true; }
int vtimer_msg_receive_timeout(msg_t *m, timex_t timeout) { msg_t timeout_message; timeout_message.type = MSG_TIMER; timeout_message.content.ptr = (char *) &timeout_message; vtimer_t t; vtimer_set_msg(&t, timeout, sched_active_pid, MSG_TIMER, &timeout_message); msg_receive(m); if (m->type == MSG_TIMER && m->content.ptr == (char *) &timeout_message) { /* we hit the timeout */ return -1; } else { vtimer_remove(&t); return 1; } }
void icn_initBackground(void) { /* create packet */ ng_pktsnip_t *pkt; icn_pkt_t icn_pkt; icn_pkt.type = ICN_BACKGROUND; icn_pkt.seq = 0; memcpy(icn_pkt.payload, content, strlen(content) + 1); pkt = ng_pktbuf_add(NULL, &icn_pkt, sizeof(icn_pkt_t), NG_NETTYPE_UNDEF); LOG_DEBUG("make some noise\n"); // send interest packet icn_send(CONTENT_STORE, pkt); vtimer_remove(&bg_vt); vtimer_set_msg(&bg_vt, background_interval, thread_getpid(), ICN_SEND_BACKGROUND, NULL); }
uint8_t rpl_init(int if_id, ipv6_addr_t *address) { rpl_if_id = if_id; /* initialize routing table */ #if RPL_MAX_ROUTING_ENTRIES != 0 rpl_max_routing_entries = RPL_MAX_ROUTING_ENTRIES; #endif rpl_process_pid = thread_create(rpl_process_buf, sizeof(rpl_process_buf), THREAD_PRIORITY_MAIN - 1, CREATE_STACKTEST, rpl_process, NULL, "rpl_process"); sixlowpan_lowpan_init_interface(if_id); ipv6_register_rpl_handler(rpl_process_pid); if (address) { my_address = *address; ipv6_net_if_add_addr(if_id, &my_address, NDP_ADDR_STATE_PREFERRED, 0, 0, 0); } /* add all-RPL-nodes address */ ipv6_addr_t all_rpl_nodes; ipv6_addr_set_all_rpl_nodes_addr(&all_rpl_nodes); ipv6_net_if_add_addr(if_id, &all_rpl_nodes, NDP_ADDR_STATE_ANY, 0, 0, 0); #if (RPL_DEFAULT_MOP == RPL_MOP_NON_STORING_MODE) ipv6_iface_set_srh_indicator(rpl_is_root); #endif ipv6_iface_set_routing_provider(rpl_get_next_hop); DEBUGF("All addresses set!\n"); /* initialize objective function manager */ rpl_of_manager_init(&my_address); rt_time = timex_set(RPL_LIFETIME_STEP, 0); vtimer_set_msg(&rt_timer, rt_time, rpl_process_pid, RPL_MSG_TYPE_ROUTING_ENTRY_UPDATE, NULL); return SIXLOWERROR_SUCCESS; }
void cc1100_phy_init() { int i; rx_buffer_head = 0; rx_buffer_tail = 0; rx_buffer_size = 0; /* Initialize RX-Buffer (clear content) */ for (i = 0; i < RX_BUFF_SIZE; i++) { rx_buffer->packet.length = 0; } /* Initialize handler table & packet monitor */ packet_monitor = NULL; pm_init_table((pm_table_t *)&handler_table, MAX_PACKET_HANDLERS, handlers); /* Clear sequence number buffer */ memset(seq_buffer, 0, sizeof(seq_buffer_entry_t) * MAX_SEQ_BUFFER_SIZE); /* Initialize mutex */ cc1100_mutex_pid = -1; mutex_init(&cc1100_mutex); /* Allocate event numbers and start cc1100 event process */ cc1100_event_handler_pid = thread_create(event_handler_stack, sizeof(event_handler_stack), PRIORITY_CC1100, CREATE_STACKTEST, cc1100_event_handler_function, cc1100_event_handler_name); /* Active watchdog for the first time */ if (radio_mode == CC1100_MODE_CONSTANT_RX) { cc1100_watch_dog_period.microseconds = CC1100_WATCHDOG_PERIOD; if (cc1100_watch_dog_period.microseconds != 0) { timex_t temp = timex_set(0, 5000000L); vtimer_set_msg(&cc1100_watch_dog, temp, cc1100_event_handler_pid, NULL); } } }
void _update_lifetime(void) { timex_t now; vtimer_now(&now); gnrc_rpl_parent_t *parent; for (uint8_t i = 0; i < GNRC_RPL_PARENTS_NUMOF; ++i) { parent = &gnrc_rpl_parents[i]; if (parent->state != 0) { if ((signed)(parent->lifetime.seconds - now.seconds) <= GNRC_RPL_LIFETIME_UPDATE_STEP) { gnrc_rpl_dodag_t *dodag = parent->dodag; gnrc_rpl_parent_remove(parent); gnrc_rpl_parent_update(dodag, NULL); continue; } else if (((signed)(parent->lifetime.seconds - now.seconds) <= GNRC_RPL_LIFETIME_UPDATE_STEP * 2)) { gnrc_rpl_send_DIS(parent->dodag, &parent->addr); } } } vtimer_remove(&_lt_timer); vtimer_set_msg(&_lt_timer, _lt_time, gnrc_rpl_pid, GNRC_RPL_MSG_TYPE_LIFETIME_UPDATE, NULL); }
static void _set_state(ng_ipv6_nc_t *nc_entry, uint8_t state) { ng_ipv6_netif_t *ipv6_iface; timex_t t = { NG_NDP_FIRST_PROBE_DELAY, 0 }; nc_entry->flags &= ~NG_IPV6_NC_STATE_MASK; nc_entry->flags |= state; DEBUG("ndp: set %s state to ", ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); switch (state) { case NG_IPV6_NC_STATE_REACHABLE: ipv6_iface = ng_ipv6_netif_get(nc_entry->iface); DEBUG("REACHABLE (reachable time = %" PRIu32 ".%06" PRIu32 ")\n", ipv6_iface->reach_time.seconds, ipv6_iface->reach_time.microseconds); t = ipv6_iface->reach_time; /* we intentionally fall through here to set the desired timeout t */ case NG_IPV6_NC_STATE_DELAY: #if ENABLE_DEBUG if (state == NG_IPV6_NC_STATE_DELAY) { DEBUG("DELAY (probe with unicast NS in %u seconds)\n", NG_NDP_FIRST_PROBE_DELAY); } #endif vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid, NG_NDP_MSG_NC_STATE_TIMEOUT, nc_entry); break; case NG_IPV6_NC_STATE_PROBE: ipv6_iface = ng_ipv6_netif_get(nc_entry->iface); nc_entry->probes_remaining = NG_NDP_MAX_UC_NBR_SOL_NUMOF; DEBUG("PROBE (probe with %" PRIu8 " unicast NS every %" PRIu32 ".%06" PRIu32 " seconds)\n", nc_entry->probes_remaining, ipv6_iface->retrans_timer.seconds, ipv6_iface->retrans_timer.microseconds); _send_nbr_sol(nc_entry->iface, &nc_entry->ipv6_addr, &nc_entry->ipv6_addr); mutex_lock(&ipv6_iface->mutex); vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, ipv6_iface->retrans_timer, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); mutex_unlock(&ipv6_iface->mutex); break; #ifdef ENABLE_DEBUG case NG_IPV6_NC_STATE_STALE: DEBUG("STALE (go into DELAY on next packet)\n"); break; #endif default: DEBUG("errorneous or unknown\n"); break; } }
/* special netapi helper */ static inline void _send_delayed(vtimer_t *t, timex_t interval, ng_pktsnip_t *pkt) { vtimer_remove(t); vtimer_set_msg(t, interval, ng_ipv6_pid, NG_NETAPI_MSG_TYPE_SND, pkt); }
kernel_pid_t ng_ndp_next_hop_l2addr(uint8_t *l2addr, uint8_t *l2addr_len, kernel_pid_t iface, ng_ipv6_addr_t *dst, ng_pktsnip_t *pkt) { ng_ipv6_addr_t *next_hop_ip = NULL, *prefix = NULL; #ifdef MODULE_NG_IPV6_EXT_RH next_hop_ip = ng_ipv6_ext_rh_next_hop(hdr); #endif #ifdef MODULE_FIB size_t next_hop_size = sizeof(ng_ipv6_addr_t); uint32_t next_hop_flags = 0; ng_ipv6_addr_t next_hop_actual; /* FIB copies address into this variable */ if ((next_hop_ip == NULL) && (fib_get_next_hop(&iface, next_hop_actual.u8, &next_hop_size, &next_hop_flags, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0) >= 0) && (next_hop_size == sizeof(ng_ipv6_addr_t))) { next_hop_ip = &next_hop_actual; } #endif if (next_hop_ip == NULL) { /* no route to host */ if (iface == KERNEL_PID_UNDEF) { /* ng_ipv6_netif_t doubles as prefix list */ iface = ng_ipv6_netif_find_by_prefix(&prefix, dst); } else { /* ng_ipv6_netif_t doubles as prefix list */ prefix = ng_ipv6_netif_match_prefix(iface, dst); } if ((prefix != NULL) && /* prefix is on-link */ (ng_ipv6_netif_addr_get(prefix)->flags & NG_IPV6_NETIF_ADDR_FLAGS_NDP_ON_LINK)) { next_hop_ip = dst; #ifdef MODULE_FIB /* We don't care if FIB is full, this is just for efficiency * for later sends */ fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0, (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0, FIB_LIFETIME_NO_EXPIRE); #endif } } if (next_hop_ip == NULL) { next_hop_ip = _default_router(); #ifdef MODULE_FIB /* We don't care if FIB is full, this is just for efficiency for later * sends */ fib_add_entry(iface, (uint8_t *)dst, sizeof(ng_ipv6_addr_t), 0, (uint8_t *)next_hop_ip, sizeof(ng_ipv6_addr_t), 0, FIB_LIFETIME_NO_EXPIRE); #endif } if (next_hop_ip != NULL) { ng_ipv6_nc_t *nc_entry = ng_ipv6_nc_get(iface, next_hop_ip); if ((nc_entry != NULL) && ng_ipv6_nc_is_reachable(nc_entry)) { DEBUG("ndp: found reachable neighbor (%s => ", ng_ipv6_addr_to_str(addr_str, &nc_entry->ipv6_addr, sizeof(addr_str))); DEBUG("%s)\n", ng_netif_addr_to_str(addr_str, sizeof(addr_str), nc_entry->l2_addr, nc_entry->l2_addr_len)); if (ng_ipv6_nc_get_state(nc_entry) == NG_IPV6_NC_STATE_STALE) { _set_state(nc_entry, NG_IPV6_NC_STATE_DELAY); } memcpy(l2addr, nc_entry->l2_addr, nc_entry->l2_addr_len); *l2addr_len = nc_entry->l2_addr_len; /* TODO: unreachability check */ return nc_entry->iface; } else if (nc_entry == NULL) { ng_pktqueue_t *pkt_node; ng_ipv6_addr_t dst_sol; nc_entry = ng_ipv6_nc_add(iface, next_hop_ip, NULL, 0, NG_IPV6_NC_STATE_INCOMPLETE << NG_IPV6_NC_STATE_POS); if (nc_entry == NULL) { DEBUG("ndp: could not create neighbor cache entry\n"); return KERNEL_PID_UNDEF; } pkt_node = _alloc_pkt_node(pkt); if (pkt_node == NULL) { DEBUG("ndp: could not add packet to packet queue\n"); } else { /* prevent packet from being released by IPv6 */ ng_pktbuf_hold(pkt_node->pkt, 1); ng_pktqueue_add(&nc_entry->pkts, pkt_node); } /* address resolution */ ng_ipv6_addr_set_solicited_nodes(&dst_sol, next_hop_ip); if (iface == KERNEL_PID_UNDEF) { timex_t t = { 0, NG_NDP_RETRANS_TIMER }; kernel_pid_t ifs[NG_NETIF_NUMOF]; size_t ifnum = ng_netif_get(ifs); for (size_t i = 0; i < ifnum; i++) { _send_nbr_sol(ifs[i], next_hop_ip, &dst_sol); } vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, t, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); } else { ng_ipv6_netif_t *ipv6_iface = ng_ipv6_netif_get(iface); _send_nbr_sol(iface, next_hop_ip, &dst_sol); mutex_lock(&ipv6_iface->mutex); vtimer_remove(&nc_entry->nbr_sol_timer); vtimer_set_msg(&nc_entry->nbr_sol_timer, ipv6_iface->retrans_timer, ng_ipv6_pid, NG_NDP_MSG_NBR_SOL_RETRANS, nc_entry); mutex_unlock(&ipv6_iface->mutex); } } } return KERNEL_PID_UNDEF; }
static inline void _rtr_sol_reschedule(gnrc_ipv6_netif_t *iface, uint32_t sec_delay) { vtimer_remove(&iface->rtr_sol_timer); vtimer_set_msg(&iface->rtr_sol_timer, timex_set(sec_delay, 0), gnrc_ipv6_pid, GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL, iface); }