コード例 #1
0
ファイル: main.c プロジェクト: PeterKietzmann/Demos
void *beaconing(void *arg)
{
    (void) arg;
    xtimer_t status_timer;
    msg_t msg;
    msg_t update_msg;
    kernel_pid_t mypid = thread_getpid();

    /* initialize message queue */
    msg_init_queue(_beac_msg_q, Q_SZ);

    /* start periodic timer */
    update_msg.type = MSG_UPDATE_EVENT;
    xtimer_set_msg(&status_timer, UPDATE_INTERVAL, &update_msg, mypid);

    while(1) {
        msg_receive(&msg);

        switch (msg.type) {
            case MSG_UPDATE_EVENT:
                xtimer_set_msg(&status_timer, UPDATE_INTERVAL, &update_msg, mypid);
                send_update(initial_pos, p_buf);
                break;
            default:
                break;
        }
    }

    /* never reached */
    return NULL;
}
コード例 #2
0
/* start sending beacons */
void beaconing_start(void)
{
    uint8_t remaining_beacons = DOW_BEACONING_COUNT;
    bool end_beaconing = false;

    /* register for RX */
    gnrc_netreg_entry_t _ne;
    _ne.target.pid = sched_active_pid;
    _ne.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
    gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &_ne);
    /* schedule beacon */
    msg_t beacon_msg;
    beacon_msg.type = DOW_MSG_BEACON;
    xtimer_t beacon_timer;
    beacon_timer.target = beacon_timer.long_target = 0;
    /* let's delay the first beacon by DOW_BEACONING_WAIT */
    uint32_t tmp = DOW_BEACONING_PERIOD + DOW_BEACONING_WAIT;
    xtimer_set_msg(&beacon_timer, tmp, &beacon_msg, sched_active_pid);
    tmp -= DOW_BEACONING_WAIT;
    uint32_t start = xtimer_now().ticks32;
    while (1) {
        msg_t m;
        msg_receive(&m);
        switch (m.type) {
            case DOW_MSG_BEACON:
                LOG_DEBUG("beaconing: ready to send next beacon\n");
                beaconing_send();
                tmp = DOW_BEACONING_PERIOD;
                /* check if we need to do further beaconing */
                if (--remaining_beacons > 0) {
                    xtimer_set_msg(&beacon_timer, tmp, &beacon_msg, sched_active_pid);
                }
                else {
                    beacon_msg.type = DOW_MSG_BEACON_END;
                    tmp = 2 * DOW_BEACONING_WAIT - (xtimer_now().ticks32 - start);
                    LOG_INFO("beaconing: end beaconing period in %" PRIu32 \
                              " seconds\n", (tmp / US_PER_SEC));

                    xtimer_set_msg(&beacon_timer, tmp, &beacon_msg, sched_active_pid);
                }
                break;
            case DOW_MSG_BEACON_END:
                LOG_INFO("beaconing: end beaconing\n");
                end_beaconing = true;
                break;
            case GNRC_NETAPI_MSG_TYPE_RCV:
                LOG_DEBUG("beaconing: received packet, assume that it is a beacon\n");
                _handle_beacon((gnrc_pktsnip_t *)m.content.ptr);
                break;
            default:
                LOG_WARNING("beaconing: didn't expect message type %X\n", m.type);
                break;
        }
        if (end_beaconing) {
            break;
        }
    }
    gnrc_netreg_unregister(GNRC_NETTYPE_UNDEF, &_ne);
}
コード例 #3
0
ファイル: gnrc_rpl.c プロジェクト: aabadie/RIOT
kernel_pid_t gnrc_rpl_init(kernel_pid_t if_pid)
{
    /* check if RPL was initialized before */
    if (gnrc_rpl_pid == KERNEL_PID_UNDEF) {
        _instance_id = 0;
        /* start the event loop */
        gnrc_rpl_pid = thread_create(_stack, sizeof(_stack), GNRC_RPL_PRIO,
                                     THREAD_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.target.pid = gnrc_rpl_pid;
        /* register interest in all ICMPv6 packets */
        gnrc_netreg_register(GNRC_NETTYPE_ICMPV6, &_me_reg);

        gnrc_rpl_of_manager_init();
        xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid);

#ifdef MODULE_NETSTATS_RPL
        memset(&gnrc_rpl_netstats, 0, sizeof(gnrc_rpl_netstats));
#endif
    }

    /* register all_RPL_nodes multicast address */
    gnrc_ipv6_netif_add_addr(if_pid, &ipv6_addr_all_rpl_nodes, IPV6_ADDR_BIT_LEN, 0);

    gnrc_rpl_send_DIS(NULL, (ipv6_addr_t *) &ipv6_addr_all_rpl_nodes);
    return gnrc_rpl_pid;
}
コード例 #4
0
ファイル: gnrc_ndp_internal.c プロジェクト: khhhh/RIOT
/**
 * @brief   Sends @ref GNRC_NETAPI_MSG_TYPE_SND delayed.
 *
 * @param[in] t         Timer for the delay.
 * @param[in] msg       Msg for the timer.
 * @param[in] interval  Delay interval.
 * @param[in] pkt       Packet to send delayed.
 */
static inline void _send_delayed(xtimer_t *t, msg_t *msg, uint32_t interval, gnrc_pktsnip_t *pkt)
{
    xtimer_remove(t);
    msg->type = GNRC_NETAPI_MSG_TYPE_SND;
    msg->content.ptr = (char *) pkt;
    xtimer_set_msg(t, interval, msg, gnrc_ipv6_pid);
}
コード例 #5
0
ファイル: main.c プロジェクト: OlegHahm/miniature-dangerzone
int main(void)
{
    gnrc_netreg_entry_t ne;

    uint8_t cpuid[CPUID_LEN];
    cpuid_get(cpuid);
    conn_test_id = djb2_hash(cpuid, CPUID_LEN);
    random_init(conn_test_id);

    ne.pid = thread_create(_stack, sizeof(_stack), THREAD_PRIORITY_MAIN - 1,
                             THREAD_CREATE_STACKTEST, _listener, NULL,
                             "listener");

    ne.demux_ctx = GNRC_NETREG_DEMUX_CTX_ALL;
    gnrc_netreg_register(GNRC_NETTYPE_UNDEF, &ne);

    puts("Connectivity Test program!");
    printf("MY ID: %08lX\n", (unsigned long) conn_test_id);
    unsigned res = CONN_TEST_CHAN;
    if (gnrc_netapi_set(CONN_TEST_NETIF, NETOPT_CHANNEL, 0, (uint16_t *)&res, sizeof(uint16_t)) < 0) {
        puts("main: error setting channel");
    }

    unsigned int addr_len = 8;
    if (gnrc_netapi_set(CONN_TEST_NETIF, NETOPT_SRC_LEN, 0, (uint16_t *)&addr_len, sizeof(uint16_t)) < 0) {
        printf("main: error setting addressing mode\n");
    }
    xtimer_set_msg(&ct_timer, (SEC_IN_USEC * 3) + (random_uint32() & 0x001FFFFF), &ct_m, ne.pid);

    char line_buf[SHELL_DEFAULT_BUFSIZE];
    shell_run(shell_commands, line_buf, SHELL_DEFAULT_BUFSIZE);
    return 0;
}
コード例 #6
0
/* 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;

    xtimer_remove(&abr->ltimer);
    abr->ltimer_msg.type = GNRC_SIXLOWPAN_ND_MSG_ABR_TIMEOUT;
    abr->ltimer_msg.content.ptr = (char *) abr;
    xtimer_set_msg(&abr->ltimer, (uint32_t) timex_uint64(t), &abr->ltimer_msg, gnrc_ipv6_pid);
}
コード例 #7
0
ファイル: gnrc_ndp_host.c プロジェクト: deepfryed/RIOT
static inline void _reschedule_rtr_sol(gnrc_ipv6_netif_t *iface, uint32_t delay)
{
    xtimer_remove(&iface->rtr_sol_timer);
    iface->rtr_sol_msg.type = GNRC_NDP_MSG_RTR_SOL_RETRANS;
    iface->rtr_sol_msg.content.ptr = iface;
    xtimer_set_msg(&iface->rtr_sol_timer, delay, &iface->rtr_sol_msg, gnrc_ipv6_pid);
}
コード例 #8
0
ファイル: gnrc_rpl.c プロジェクト: hexanoid/polymcu
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();
        xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid);
    }

    /* 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;
}
コード例 #9
0
ファイル: gnrc_sixlowpan_nd.c プロジェクト: khhhh/RIOT
static inline void _rtr_sol_reschedule(gnrc_ipv6_netif_t *iface, uint32_t sec_delay)
{
    xtimer_remove(&iface->rtr_sol_timer);
    iface->rtr_sol_msg.type = GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL;
    iface->rtr_sol_msg.content.ptr = (char *) iface;
    xtimer_set_msg(&iface->rtr_sol_timer, sec_delay * SEC_IN_USEC, &iface->rtr_sol_msg,
                   gnrc_ipv6_pid);
}
コード例 #10
0
ファイル: gnrc_tcp_fsm.c プロジェクト: A-Paul/RIOT
/**
 * @brief Restarts timewait timer.
 *
 * @param[in,out] tcb   TCB holding the timer struct to reset.
 *
 * @return   Zero on success.
 */
static int _restart_timewait_timer(gnrc_tcp_tcb_t *tcb)
{
    xtimer_remove(&tcb->tim_tout);
    tcb->msg_tout.type = MSG_TYPE_TIMEWAIT;
    tcb->msg_tout.content.ptr = (void *)tcb;
    xtimer_set_msg(&tcb->tim_tout, 2 * GNRC_TCP_MSL, &tcb->msg_tout, gnrc_tcp_pid);
    return 0;
}
コード例 #11
0
ファイル: gnrc_sixlowpan_nd.c プロジェクト: khhhh/RIOT
void gnrc_sixlowpan_nd_rtr_sol_reschedule(gnrc_ipv6_nc_t *nce, uint32_t sec_delay)
{
    assert(nce != NULL);
    assert(sec_delay != 0U);
    gnrc_ipv6_netif_t *iface = gnrc_ipv6_netif_get(nce->iface);
    xtimer_remove(&iface->rtr_sol_timer);
    iface->rtr_sol_msg.type = GNRC_SIXLOWPAN_ND_MSG_MC_RTR_SOL;
    iface->rtr_sol_msg.content.ptr = (char *) iface;
    xtimer_set_msg(&iface->rtr_sol_timer, sec_delay * SEC_IN_USEC, &iface->rtr_sol_msg,
                   gnrc_ipv6_pid);
}
コード例 #12
0
ファイル: gnrc_rpl.c プロジェクト: aabadie/RIOT
void _update_lifetime(void)
{
    uint32_t now = xtimer_now();
    uint16_t now_sec = now / SEC_IN_USEC;

    gnrc_rpl_parent_t *parent;
    gnrc_rpl_instance_t *inst;

    for (uint8_t i = 0; i < GNRC_RPL_PARENTS_NUMOF; ++i) {
        parent = &gnrc_rpl_parents[i];
        if (parent->state != 0) {
            if ((int32_t)(parent->lifetime - now_sec) <= 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 ((int32_t)(parent->lifetime - now_sec) <= (GNRC_RPL_LIFETIME_UPDATE_STEP * 2)) {
                gnrc_rpl_send_DIS(parent->dodag->instance, &parent->addr);
            }
        }
    }

    for (int i = 0; i < GNRC_RPL_INSTANCES_NUMOF; ++i) {
        inst = &gnrc_rpl_instances[i];
        if (inst->state != 0) {
            if ((inst->cleanup > 0) && (inst->dodag.parents == NULL) &&
                (inst->dodag.my_rank == GNRC_RPL_INFINITE_RANK)) {
                inst->cleanup -= GNRC_RPL_LIFETIME_UPDATE_STEP;
                if (inst->cleanup <= 0) {
                    /* no parents - delete this instance and DODAG */
                    gnrc_rpl_instance_remove(inst);
                    continue;
                }
            }

            if (inst->dodag.dao_time > GNRC_RPL_LIFETIME_UPDATE_STEP) {
                inst->dodag.dao_time -= GNRC_RPL_LIFETIME_UPDATE_STEP;
            }
            else {
                _dao_handle_send(&inst->dodag);
            }
        }
    }

#ifdef MODULE_GNRC_RPL_P2P
    gnrc_rpl_p2p_update();
#endif

    xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid);
}
コード例 #13
0
ファイル: timeout.c プロジェクト: A-Paul/RIOT
void gnrc_gomach_set_timeout(gnrc_netif_t *netif,
                             gnrc_gomach_timeout_type_t type,
                             uint32_t offset)
{
    assert(netif);

    gnrc_gomach_timeout_t *timeout;
    if ((timeout = _gomach_acquire_timeout(netif, type))) {
        timeout->expired = false;
        timeout->msg.type = GNRC_GOMACH_EVENT_TIMEOUT_TYPE;
        timeout->msg.content.ptr = (void *) timeout;
        xtimer_set_msg(&(timeout->timer), offset,
                       &(timeout->msg), netif->pid);
    }
    else {
        DEBUG("[GoMacH]: Cannot set timeout, too many concurrent timeouts\n");
    }
}
コード例 #14
0
ファイル: main.c プロジェクト: JMR-b/RIOT
int main(void)
{
    msg_t m, tmsg;
    xtimer_t t;
    int64_t offset = -1000;
    tmsg.type = 44;

    for (int i = 0; i < 10; i++) {
        xtimer_set_msg(&t, SEC_IN_USEC + offset, &tmsg, sched_active_pid);
        if (xtimer_msg_receive_timeout(&m, SEC_IN_USEC) < 0) {
            puts("Timeout!");
        }
        else {
            printf("Message received: %" PRIu16 "\n", m.type);
        }
        offset = (offset < 0) ? 1000 : -1000;
    }
    return 0;
}
コード例 #15
0
ファイル: gnrc_ndp.c プロジェクト: Otmane123/RIOT
/* 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->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
                (ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) {
                if ((nc_entry = gnrc_ipv6_nc_add(iface, ipaddr, l2addr,
                                                 (uint16_t)l2addr_len,
                                                 GNRC_IPV6_NC_STATE_STALE |
                                                 GNRC_IPV6_NC_TYPE_TENTATIVE)) != NULL) {
                    xtimer_set_msg(&nc_entry->type_timeout,
                                   (GNRC_SIXLOWPAN_ND_TENTATIVE_NCE_LIFETIME * SEC_IN_USEC),
                                   &nc_entry->type_timeout_msg,
                                   gnrc_ipv6_pid);
                }
                return;
            }
#endif
            gnrc_ipv6_nc_add(iface, ipaddr, l2addr, (uint16_t)l2addr_len,
                             GNRC_IPV6_NC_STATE_STALE);
        }
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
        /* unreachable set in gnrc_ndp_retrans_nbr_sol() will just be staled */
        else if (gnrc_ipv6_nc_get_state(nc_entry) == GNRC_IPV6_NC_STATE_UNREACHABLE) {
            gnrc_ndp_internal_set_state(nc_entry, GNRC_IPV6_NC_STATE_STALE);
        }
#endif
        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);
        }
    }
}
コード例 #16
0
ファイル: timeout.c プロジェクト: jthacker/RIOT
void gnrc_lwmac_set_timeout(gnrc_netif_t *netif,
                            gnrc_lwmac_timeout_type_t type,
                            uint32_t offset)
{
    assert(netif);

    gnrc_lwmac_timeout_t *timeout;
    if ((timeout = _lwmac_acquire_timeout(netif, type))) {
        DEBUG("[LWMAC] Set timeout %s in %" PRIu32 " us\n",
              lwmac_timeout_names[type], offset);
        timeout->expired = false;
        timeout->msg.type = GNRC_LWMAC_EVENT_TIMEOUT_TYPE;
        timeout->msg.content.ptr = (void *) timeout;
        xtimer_set_msg(&(timeout->timer), offset,
                       &(timeout->msg), netif->pid);
    }
    else {
        DEBUG("[LWMAC] Cannot set timeout %s, too many concurrent timeouts\n",
              lwmac_timeout_names[type]);
    }
}
コード例 #17
0
ファイル: gnrc_ndp_router.c プロジェクト: JelmerT/RIOT
static void _send_rtr_adv(gnrc_ipv6_netif_t *iface, ipv6_addr_t *dst)
{
    bool fin;
    uint32_t interval;

    mutex_lock(&iface->mutex);
    fin = (iface->adv_ltime == 0);
    assert((iface->min_adv_int != 0) && (iface->max_adv_int != 0));
    interval = genrand_uint32_range(iface->min_adv_int, iface->max_adv_int);
    if (!fin && !((iface->flags | GNRC_IPV6_NETIF_FLAGS_ROUTER) &&
                  (iface->flags | GNRC_IPV6_NETIF_FLAGS_RTR_ADV))) {
        DEBUG("ndp rtr: interface %" PRIkernel_pid " is not an advertising interface\n",
              iface->pid);
        return;
    }
    if (iface->rtr_adv_count > 1) { /* regard for off-by-one error */
        iface->rtr_adv_count--;
        if (!fin && (interval > GNRC_NDP_MAX_INIT_RTR_ADV_INT)) {
            interval = GNRC_NDP_MAX_INIT_RTR_ADV_INT;
        }
    }
    if (!fin || (iface->rtr_adv_count > 1)) {   /* regard for off-by-one-error */
        /* reset timer for next router advertisement */
        xtimer_remove(&iface->rtr_adv_timer);
        iface->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_RETRANS;
        iface->rtr_adv_msg.content.ptr = (char *) iface;
        xtimer_set_msg(&iface->rtr_adv_timer, interval * SEC_IN_USEC, &iface->rtr_adv_msg,
                       gnrc_ipv6_pid);
    }
    mutex_unlock(&iface->mutex);
    for (int i = 0; i < GNRC_IPV6_NETIF_ADDR_NUMOF; i++) {
        ipv6_addr_t *src = &iface->addrs[i].addr;

        if (!ipv6_addr_is_unspecified(src) && ipv6_addr_is_link_local(src) &&
            !gnrc_ipv6_netif_addr_is_non_unicast(src)) {
            /* send one for every link local address (ideally there is only one) */
            gnrc_ndp_internal_send_rtr_adv(iface->pid, src, dst, fin);
        }
    }
}
コード例 #18
0
ファイル: main.c プロジェクト: OlegHahm/miniature-dangerzone
static void *_listener(void *unused)
{
    msg_init_queue(_listener_mq, 8);
    msg_t msg;
    while (1) {
        msg_receive(&msg);
        gnrc_pktsnip_t *snip = NULL;

        switch (msg.type) {
            case GNRC_NETAPI_MSG_TYPE_RCV:
                {
                gnrc_pktsnip_t *pkt = (gnrc_pktsnip_t *)msg.content.ptr;
                snip = pkt;
                while (snip != NULL) {
                    if (snip->type == GNRC_NETTYPE_NETIF) {
                        //gnrc_netif_hdr_print(snip->data);
                    }
                    else if (snip->type == GNRC_NETTYPE_UNDEF) {
                        printf("ID: %08lX\n",
                               (unsigned long) ((conn_test_payload_t*)snip->data)->id);
                    }
                    snip = snip->next;
                }
                gnrc_pktbuf_release(pkt);
                break;
                }
            case CONN_TEST_SEND:
                _send(0, NULL);
                xtimer_set_msg(&ct_timer, (SEC_IN_USEC * 3) + (random_uint32()
                                                               & 0x001FFFFF),
                               &ct_m, sched_active_pid);
                break;
            default:
                puts("UNEXPECTED MESSAGE TYPE!");
        }
    }

    return NULL;
}
コード例 #19
0
ファイル: gnrc_rpl.c プロジェクト: hexanoid/polymcu
void _update_lifetime(void)
{
    uint64_t now = xtimer_now64();
    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 ((int64_t)(parent->lifetime - now) <= (int64_t) (GNRC_RPL_LIFETIME_UPDATE_STEP
                * SEC_IN_USEC)) {
                gnrc_rpl_dodag_t *dodag = parent->dodag;
                gnrc_rpl_parent_remove(parent);
                gnrc_rpl_parent_update(dodag, NULL);
                continue;
            }
            else if ((int64_t)(parent->lifetime - now) <=
                     (int64_t) (GNRC_RPL_LIFETIME_UPDATE_STEP * SEC_IN_USEC * 2)) {
                gnrc_rpl_send_DIS(parent->dodag, &parent->addr);
            }
        }
    }
    xtimer_set_msg(&_lt_timer, _lt_time, &_lt_msg, gnrc_rpl_pid);
}
コード例 #20
0
ファイル: gnrc_sixlowpan_nd.c プロジェクト: khhhh/RIOT
uint8_t gnrc_sixlowpan_nd_opt_ar_handle(kernel_pid_t iface, ipv6_hdr_t *ipv6,
                                        uint8_t icmpv6_type, ipv6_addr_t *addr,
                                        sixlowpan_nd_opt_ar_t *ar_opt,
                                        uint8_t *sl2a, size_t sl2a_len)
{
    eui64_t eui64;
    gnrc_ipv6_netif_t *ipv6_iface;
    gnrc_ipv6_nc_t *nc_entry;
    uint8_t status = 0;
    (void)sl2a;
    (void)sl2a_len;
    if (ar_opt->len != SIXLOWPAN_ND_OPT_AR_LEN) {
        /* discard silently: see https://tools.ietf.org/html/rfc6775#section-5.5.2 */
        return 0;
    }
    if (gnrc_netapi_get(iface, NETOPT_ADDRESS_LONG, 0, &eui64,
                        sizeof(eui64)) < 0) {
        /* discard silently: see https://tools.ietf.org/html/rfc6775#section-5.5.2 */
        return 0;
    }
    ipv6_iface = gnrc_ipv6_netif_get(iface);
    nc_entry = gnrc_ipv6_nc_get(iface, addr);
    switch (icmpv6_type) {
        case ICMPV6_NBR_ADV:
            if (!(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN)) {
                DEBUG("6lo nd: interface not a 6LoWPAN interface\n");
                return 0;
            }
            if (eui64.uint64.u64 != ar_opt->eui64.uint64.u64) {
                /* discard silently: see https://tools.ietf.org/html/rfc6775#section-5.5.2 */
                return 0;
            }
            /* we expect the sender to be already in neighbor cache, if not we
             * ignore it */
            if (nc_entry == NULL) {
                DEBUG("6lo nd: sending router not in neighbor cache\n");
                return 0;
            }
            switch (ar_opt->status) {
                case SIXLOWPAN_ND_STATUS_SUCCESS:
                    DEBUG("6lo nd: address registration successful\n");
                    mutex_lock(&ipv6_iface->mutex);
                    /* reschedule 1 minute before lifetime expires */
                    gnrc_ndp_internal_reset_nbr_sol_timer(nc_entry, SEC_IN_USEC * 60 *
                                                          (uint32_t)(byteorder_ntohs(ar_opt->ltime)
                                                          -1),
                                                          GNRC_NDP_MSG_NBR_SOL_RETRANS,
                                                          gnrc_ipv6_pid);
                    mutex_unlock(&ipv6_iface->mutex);
                    break;
                case SIXLOWPAN_ND_STATUS_DUP:
                    DEBUG("6lo nd: address registration determined duplicated\n");
                    /* TODO: handle DAD failed case */
                    gnrc_ipv6_netif_remove_addr(iface, &ipv6->dst);
                    /* address should not be used anymore */
                    break;
                case SIXLOWPAN_ND_STATUS_NC_FULL:
                    DEBUG("6lo nd: neighbor cache on router is full\n");
                    gnrc_ipv6_nc_remove(iface, &ipv6->src);
                    /* try to find another router */
                    gnrc_sixlowpan_nd_init(ipv6_iface);
                    break;
                default:
                    DEBUG("6lo nd: unknown status for registration received\n");
                    break;
            }
            break;
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
        case ICMPV6_NBR_SOL:
            if (!(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
                !(ipv6_iface->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER)) {
                DEBUG("6lo nd: interface not a 6LoWPAN or forwarding interface\n");
                return 0;
            }
            if ((ar_opt->status != 0) ||
                ipv6_addr_is_unspecified(&ipv6->src)) {
                /* discard silently */
                return 0;
            }
            /* TODO multihop DAD */
            if ((nc_entry != NULL) &&
                ((gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_REGISTERED) ||
                 (gnrc_ipv6_nc_get_type(nc_entry) == GNRC_IPV6_NC_TYPE_TENTATIVE)) &&
                ((nc_entry->eui64.uint64.u64 != 0) &&
                 (ar_opt->eui64.uint64.u64 != nc_entry->eui64.uint64.u64))) {
                /* there is already another node with this address */
                DEBUG("6lo nd: duplicate address detected\n");
                status = SIXLOWPAN_ND_STATUS_DUP;
            }
            else if ((nc_entry != NULL) && (ar_opt->ltime.u16 == 0)) {
                gnrc_ipv6_nc_remove(iface, &ipv6->src);
                /* TODO, notify routing protocol */
            }
            else if (ar_opt->ltime.u16 != 0) {
                /* TODO: multihop DAD behavior */
                uint16_t reg_ltime;
                if (nc_entry == NULL) {
                    if ((nc_entry = gnrc_ipv6_nc_add(iface, &ipv6->src, sl2a, sl2a_len,
                                                     GNRC_IPV6_NC_STATE_STALE)) == NULL) {
                        DEBUG("6lo nd: neighbor cache is full\n");
                        return SIXLOWPAN_ND_STATUS_NC_FULL;
                    }
                    nc_entry->eui64 = ar_opt->eui64;
                }
                nc_entry->flags &= ~GNRC_IPV6_NC_TYPE_MASK;
                nc_entry->flags |= GNRC_IPV6_NC_TYPE_REGISTERED;
                reg_ltime = byteorder_ntohs(ar_opt->ltime);
                /* TODO: notify routing protocol */
                xtimer_set_msg(&nc_entry->type_timeout, (reg_ltime * 60 * SEC_IN_USEC),
                               &nc_entry->type_timeout_msg, gnrc_ipv6_pid);
            }
            break;
#endif
        default:
            break;
    }

    return status;
}
コード例 #21
0
ファイル: gnrc_tftp.c プロジェクト: LucaZulberti/RIOT
tftp_state _tftp_send(gnrc_pktsnip_t *buf, tftp_context_t *ctxt, size_t len)
{
    network_uint16_t src_port, dst_port;
    gnrc_pktsnip_t *udp, *ip;

    assert(len <= TFTP_DEFAULT_DATA_SIZE);

    /* down-size the packet to it's used size */
    if (len > TFTP_DEFAULT_DATA_SIZE) {
        DEBUG("tftp: can't reallocate to bigger packet, buffer overflowed\n");
        gnrc_pktbuf_release(buf);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "buffer overflowed");
        }

        return TS_FAILED;
    }
    else if (gnrc_pktbuf_realloc_data(buf, len) != 0) {
        assert(false);

        DEBUG("tftp: failed to reallocate data snippet\n");
        gnrc_pktbuf_release(buf);

        /* inform the user that we can't reallocate */
        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no reallocate");
        }

        return TS_FAILED;
    }

    /* allocate UDP header, set source port := destination port */
    src_port.u16 = ctxt->src_port;
    dst_port.u16 = ctxt->dst_port;
    udp = gnrc_udp_hdr_build(buf, src_port.u16, dst_port.u16);
    if (udp == NULL) {
        DEBUG("tftp: error unable to allocate UDP header\n");
        gnrc_pktbuf_release(buf);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no udp allocate");
        }

        return TS_FAILED;
    }

    /* allocate IPv6 header */
    ip = gnrc_ipv6_hdr_build(udp, NULL, &(ctxt->peer));
    if (ip == NULL) {
        DEBUG("tftp: error unable to allocate IPv6 header\n");
        gnrc_pktbuf_release(udp);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no ip allocate");
        }

        return TS_FAILED;
    }

    /* send packet */
    if (gnrc_netapi_dispatch_send(GNRC_NETTYPE_UDP, GNRC_NETREG_DEMUX_CTX_ALL,
                                  ip) == 0) {
        /* if send failed inform the user */
        DEBUG("tftp: error unable to locate UDP thread\n");
        gnrc_pktbuf_release(ip);

        if (ctxt->stop_cb) {
            ctxt->stop_cb(TFTP_INTERN_ERROR, "no dispatch send");
        }

        return TS_FAILED;
    }

    /* only set timeout if enabled for this block */
    if (ctxt->block_timeout) {
        ctxt->timer_msg.type = TFTP_TIMEOUT_MSG;
        xtimer_set_msg(&(ctxt->timer), ctxt->block_timeout, &(ctxt->timer_msg), thread_getpid());
        DEBUG("tftp: set timeout %" PRIu32 " ms\n", ctxt->block_timeout / MS_IN_USEC);
    }

    return TS_BUSY;
}
コード例 #22
0
ファイル: gnrc_ndp_internal.c プロジェクト: khhhh/RIOT
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_PI_LEN)) {
        DEBUG("ndp: invalid PI option received\n");
        return false;
    }
    if (icmpv6_type != ICMPV6_RTR_ADV || ipv6_addr_is_link_local(&pi_opt->prefix)) {
        /* else discard silently */
        return true;
    }
#ifdef MODULE_GNRC_SIXLOWPAN_ND
    if ((gnrc_ipv6_netif_get(iface)->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) &&
        (pi_opt->flags & NDP_OPT_PI_FLAGS_L)) {
        /* ignore: see https://tools.ietf.org/html/rfc6775#section-5.4 */
        return true;
    }
#endif
    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)) {
        ipv6_addr_t pref_addr;

        if ((gnrc_netapi_get(iface, NETOPT_IPV6_IID, 0, &pref_addr.u64[1],
                             sizeof(eui64_t)) < 0)) {
            DEBUG("ndp: could not get IID from interface %d\n", iface);
            return false;
        }
        ipv6_addr_init_prefix(&pref_addr, &pi_opt->prefix, pi_opt->prefix_len);
        prefix = gnrc_ipv6_netif_add_addr(iface, &pref_addr,
                                          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;
        }
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
        gnrc_sixlowpan_nd_router_set_rtr_adv(gnrc_ipv6_netif_get(iface), true);
#endif
    }
    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);
    if (netif_addr->valid != UINT32_MAX) {
        xtimer_set_msg(&netif_addr->valid_timeout,
                       (byteorder_ntohl(pi_opt->valid_ltime) * SEC_IN_USEC),
                       &netif_addr->valid_timeout_msg, thread_getpid());
    }
    /* 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;
}
コード例 #23
0
ファイル: gnrc_ndp.c プロジェクト: Otmane123/RIOT
void gnrc_ndp_rtr_adv_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt, ipv6_hdr_t *ipv6,
                             ndp_rtr_adv_t *rtr_adv, size_t icmpv6_size)
{
    uint8_t *buf = (uint8_t *)(rtr_adv + 1);
    gnrc_ipv6_nc_t *nc_entry = NULL;
    gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface);
    uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX];
#ifdef MODULE_GNRC_SIXLOWPAN_ND
    uint32_t next_rtr_sol = 0;
#endif
    int sicmpv6_size = (int)icmpv6_size, l2src_len = 0;
    uint16_t opt_offset = 0;

    if (!ipv6_addr_is_link_local(&ipv6->src) ||
        ipv6_addr_is_multicast(&ipv6->src) ||
        (ipv6->hl != 255) || (rtr_adv->code != 0) ||
        (icmpv6_size < sizeof(ndp_rtr_adv_t))) {
        DEBUG("ndp: router advertisement was invalid\n");
        /* ipv6 releases */
        return;
    }
    /* get source from default router list */
    nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src);
    if (nc_entry == NULL) { /* not in default router list */
        /* create default router list entry */
        nc_entry = gnrc_ipv6_nc_add(iface, &ipv6->src, NULL, 0,
                                    GNRC_IPV6_NC_IS_ROUTER);
        if (nc_entry == NULL) {
            DEBUG("ndp: error on default router list entry creation\n");
            return;
        }
    }
    else if ((nc_entry->flags & GNRC_IPV6_NC_IS_ROUTER) && (byteorder_ntohs(rtr_adv->ltime) == 0)) {
        nc_entry->flags &= ~GNRC_IPV6_NC_IS_ROUTER;
    }
    else {
        nc_entry->flags |= GNRC_IPV6_NC_IS_ROUTER;
    }
    /* set router life timer */
    if (rtr_adv->ltime.u16 != 0) {
        uint16_t ltime = byteorder_ntohs(rtr_adv->ltime);
#ifdef MODULE_GNRC_SIXLOWPAN_ND
        next_rtr_sol = ltime;
#endif
        xtimer_set_msg(&nc_entry->rtr_timeout, (ltime * SEC_IN_USEC),
                       &nc_entry->rtr_timeout_msg, thread_getpid());
    }
    /* set current hop limit from message if available */
    if (rtr_adv->cur_hl != 0) {
        if_entry->cur_hl = rtr_adv->cur_hl;
    }
    /* set flags from message */
    if_entry->flags &= ~GNRC_IPV6_NETIF_FLAGS_RTR_ADV_MASK;
    if_entry->flags |= (rtr_adv->flags << GNRC_IPV6_NETIF_FLAGS_RTR_ADV_POS) &
                       GNRC_IPV6_NETIF_FLAGS_RTR_ADV_MASK;
    /* set reachable time from message if it is not the same as the random base
     * value */
    if ((rtr_adv->reach_time.u32 != 0) &&
        (if_entry->reach_time_base != byteorder_ntohl(rtr_adv->reach_time))) {
        _set_reach_time(if_entry, byteorder_ntohl(rtr_adv->reach_time));
    }
    /* set retransmission timer from message */
    if (rtr_adv->retrans_timer.u32 != 0) {
        if_entry->retrans_timer = timex_set(0, byteorder_ntohl(rtr_adv->retrans_timer));
        timex_normalize(&if_entry->retrans_timer);
    }
    mutex_unlock(&if_entry->mutex);
    sicmpv6_size -= sizeof(ndp_rtr_adv_t);
    /* parse options */
    while (sicmpv6_size > 0) {
        ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset);
        switch (opt->type) {
            case NDP_OPT_SL2A:
                if ((l2src_len = gnrc_ndp_internal_sl2a_opt_handle(pkt, ipv6, rtr_adv->type, opt,
                                                                   l2src)) < 0) {
                    /* -ENOTSUP can not happen */
                    /* invalid source link-layer address option */
                    return;
                }
                break;
            case NDP_OPT_MTU:
                if (!gnrc_ndp_internal_mtu_opt_handle(iface, rtr_adv->type, (ndp_opt_mtu_t *)opt)) {
                    /* invalid MTU option */
                    return;
                }
                break;
            case NDP_OPT_PI:
                if (!gnrc_ndp_internal_pi_opt_handle(iface, rtr_adv->type, (ndp_opt_pi_t *)opt)) {
                    /* invalid prefix information option */
                    return;
                }
#ifdef MODULE_GNRC_SIXLOWPAN_ND
                uint32_t valid_ltime = byteorder_ntohl(((ndp_opt_pi_t *)opt)->valid_ltime);
                if ((valid_ltime != 0) && (valid_ltime < next_rtr_sol)) {
                    next_rtr_sol = valid_ltime;
                }
#endif
                break;
#ifdef MODULE_GNRC_SIXLOWPAN_ND
            case NDP_OPT_6CTX:
                if (!gnrc_sixlowpan_nd_opt_6ctx_handle(rtr_adv->type,
                                                       (sixlowpan_nd_opt_6ctx_t *)opt)) {
                    /* invalid 6LoWPAN context option */
                    return;
                }
                uint16_t ltime = byteorder_ntohs(((sixlowpan_nd_opt_6ctx_t *)opt)->ltime);
                if ((ltime != 0) && (ltime < (next_rtr_sol / 60))) {
                    next_rtr_sol = ltime * 60;
                }

                break;
#endif
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
            case NDP_OPT_ABR:
                gnrc_sixlowpan_nd_opt_abr_handle(iface, rtr_adv, icmpv6_size,
                                                 (sixlowpan_nd_opt_abr_t *)opt);
                break;
#endif
        }

        opt_offset += (opt->len * 8);
        sicmpv6_size -= (opt->len * 8);

#if ENABLE_DEBUG
        if (sicmpv6_size < 0) {
            DEBUG("ndp: Option parsing out of sync.\n");
        }
#endif
    }
#if ENABLE_DEBUG && defined(MODULE_GNRC_SIXLOWPAN_ND)
    if ((if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) && (l2src_len <= 0)) {
        DEBUG("ndp: Router advertisement did not contain any source address information\n");
    }
#endif
    _stale_nc(iface, &ipv6->src, l2src, l2src_len);
    /* stop multicast router solicitation retransmission timer */
    xtimer_remove(&if_entry->rtr_sol_timer);
#ifdef MODULE_GNRC_SIXLOWPAN_ND
    if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
        /* 3/4 of the time should be "well before" enough the respective timeout
         * not to run out; see https://tools.ietf.org/html/rfc6775#section-5.4.3 */
        next_rtr_sol *= 3;
        next_rtr_sol = (next_rtr_sol > 4) ? (next_rtr_sol >> 2) : 1;
        /* according to https://tools.ietf.org/html/rfc6775#section-5.3:
         * "In all cases, the RS retransmissions are terminated when an RA is
         *  received."
         *  Hence, reset router solicitation counter and reset timer. */
        if_entry->rtr_sol_count = 0;
        gnrc_sixlowpan_nd_rtr_sol_reschedule(nc_entry, next_rtr_sol);
        gnrc_ndp_internal_send_nbr_sol(nc_entry->iface, NULL, &nc_entry->ipv6_addr,
                                       &nc_entry->ipv6_addr);
        if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) {
            gnrc_ipv6_netif_set_rtr_adv(if_entry, true);
        }
    }
コード例 #24
0
ファイル: gnrc_ndp.c プロジェクト: Otmane123/RIOT
void gnrc_ndp_rtr_sol_handle(kernel_pid_t iface, gnrc_pktsnip_t *pkt,
                             ipv6_hdr_t *ipv6, ndp_rtr_sol_t *rtr_sol,
                             size_t icmpv6_size)
{
    gnrc_ipv6_netif_t *if_entry = gnrc_ipv6_netif_get(iface);

    if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_ROUTER) {
        int sicmpv6_size = (int)icmpv6_size, l2src_len = 0;
        uint8_t l2src[GNRC_IPV6_NC_L2_ADDR_MAX];
        uint16_t opt_offset = 0;
        uint8_t *buf = (uint8_t *)(rtr_sol + 1);
        /* check validity */
        if ((ipv6->hl != 255) || (rtr_sol->code != 0) ||
            (icmpv6_size < sizeof(ndp_rtr_sol_t))) {
            DEBUG("ndp: router solicitation was invalid\n");
            return;
        }
        sicmpv6_size -= sizeof(ndp_rtr_sol_t);
        while (sicmpv6_size > 0) {
            ndp_opt_t *opt = (ndp_opt_t *)(buf + opt_offset);

            switch (opt->type) {
                case NDP_OPT_SL2A:
                    if ((l2src_len = gnrc_ndp_internal_sl2a_opt_handle(pkt, ipv6, rtr_sol->type, opt,
                                                                       l2src)) < 0) {
                        /* -ENOTSUP can not happen */
                        /* invalid source link-layer address option */
                        return;
                    }
                    break;

                default:
                    /* silently discard all other options */
                    break;
            }

            opt_offset += (opt->len * 8);
            sicmpv6_size -= (opt->len * 8);

#if ENABLE_DEBUG
            if (sicmpv6_size < 0) {
                DEBUG("ndp: Option parsing out of sync.\n");
            }
#endif
        }
        _stale_nc(iface, &ipv6->src, l2src, l2src_len);
        /* send delayed */
        if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_RTR_ADV) {
            uint32_t delay;
            uint32_t ms = GNRC_NDP_MAX_RTR_ADV_DELAY;
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
            if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
                ms = GNRC_SIXLOWPAN_ND_MAX_RTR_ADV_DELAY;
            }
#endif
            delay = genrand_uint32_range(0, ms);
            xtimer_remove(&if_entry->rtr_adv_timer);
#ifdef MODULE_GNRC_SIXLOWPAN_ND_ROUTER
            /* in case of a 6LBR we have to check if the interface is actually
             * the 6lo interface */
            if (if_entry->flags & GNRC_IPV6_NETIF_FLAGS_SIXLOWPAN) {
                gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src);
                if (nc_entry != NULL) {
                    if_entry->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_SIXLOWPAN_DELAY;
                    if_entry->rtr_adv_msg.content.ptr = (char *) nc_entry;
                    xtimer_set_msg(&if_entry->rtr_adv_timer, delay, &if_entry->rtr_adv_msg,
                                   gnrc_ipv6_pid);
                }
            }
#elif defined(MODULE_GNRC_NDP_ROUTER) || defined(MODULE_GNRC_SIXLOWPAN_ND_BORDER_ROUTER)
            if (ipv6_addr_is_unspecified(&ipv6->src)) {
                /* either multicast, if source unspecified */
                if_entry->rtr_adv_msg.type = GNRC_NDP_MSG_RTR_ADV_RETRANS;
                if_entry->rtr_adv_msg.content.ptr = (char *) if_entry;
                xtimer_set_msg(&if_entry->rtr_adv_timer, delay, &if_entry->rtr_adv_msg,
                               gnrc_ipv6_pid);
            }
            else {
                /* or unicast, if source is known */
                /* XXX: can't just use GNRC_NETAPI_MSG_TYPE_SND, since the next retransmission
                 * must also be set. */
                gnrc_ipv6_nc_t *nc_entry = gnrc_ipv6_nc_get(iface, &ipv6->src);
                xtimer_set_msg(&nc_entry->rtr_adv_timer, delay, &nc_entry->rtr_adv_msg,
                               gnrc_ipv6_pid);
            }
#endif
        }
    }
    /* otherwise ignore silently */
}
コード例 #25
0
ファイル: gcoap.c プロジェクト: named-data-iot/RIOT
/* Event/Message loop for gcoap _pid thread. */
static void *_event_loop(void *arg)
{
    msg_t msg_rcvd;
    (void)arg;

    msg_init_queue(_msg_queue, GCOAP_MSG_QUEUE_SIZE);

    sock_udp_ep_t local;
    memset(&local, 0, sizeof(sock_udp_ep_t));
    local.family = AF_INET6;
    local.netif  = SOCK_ADDR_ANY_NETIF;
    local.port   = GCOAP_PORT;

    int res = sock_udp_create(&_sock, &local, NULL, 0);
    if (res < 0) {
        DEBUG("gcoap: cannot create sock: %d\n", res);
        return 0;
    }

    while(1) {
        res = msg_try_receive(&msg_rcvd);

        if (res > 0) {
            switch (msg_rcvd.type) {
            case GCOAP_MSG_TYPE_TIMEOUT: {
                gcoap_request_memo_t *memo = (gcoap_request_memo_t *)msg_rcvd.content.ptr;

                /* no retries remaining */
                if ((memo->send_limit == GCOAP_SEND_LIMIT_NON)
                        || (memo->send_limit == 0)) {
                    _expire_request(memo);
                }
                /* reduce retries remaining, double timeout and resend */
                else {
                    memo->send_limit--;
                    unsigned i        = COAP_MAX_RETRANSMIT - memo->send_limit;
                    uint32_t timeout  = ((uint32_t)COAP_ACK_TIMEOUT << i) * US_PER_SEC;
                    uint32_t variance = ((uint32_t)COAP_ACK_VARIANCE << i) * US_PER_SEC;
                    timeout = random_uint32_range(timeout, timeout + variance);

                    ssize_t bytes = sock_udp_send(&_sock, memo->msg.data.pdu_buf,
                                                  memo->msg.data.pdu_len,
                                                  &memo->remote_ep);
                    if (bytes > 0) {
                        xtimer_set_msg(&memo->response_timer, timeout,
                                       &memo->timeout_msg, _pid);
                    }
                    else {
                        DEBUG("gcoap: sock resend failed: %d\n", (int)bytes);
                        _expire_request(memo);
                    }
                }
                break;
            }
            default:
                break;
            }
        }

        _listen(&_sock);
    }

    return 0;
}