Example #1
0
static void test_fib_15_get_lifetime(void)
{
    timex_t lifetime, now;
    kernel_pid_t iface_id = 1;
    char addr_dst[] = "Test address151";
    char addr_nxt[] = "Test address152";
    size_t add_buf_size = 16;
    uint32_t addr_dst_flags = 0x77777777;
    uint32_t addr_nxt_flags = 0x77777777;

    TEST_ASSERT_EQUAL_INT(0, fib_add_entry(iface_id, (uint8_t *)addr_dst, add_buf_size - 1,
                          addr_dst_flags, (uint8_t *)addr_nxt, add_buf_size - 1,
                          addr_nxt_flags, 1000));

    TEST_ASSERT_EQUAL_INT(0, fib_devel_get_lifetime(&lifetime, (uint8_t *)addr_dst, add_buf_size - 1));

    /* assuming some ms passed during these operations... */
    vtimer_now(&now);
    timex_t cmp_lifetime = timex_add(now, timex_set(0, 900000));
    timex_t cmp_max_lifetime = timex_add(now, timex_set(1,1));
    TEST_ASSERT_EQUAL_INT(1, timex_cmp(lifetime, cmp_lifetime));
    /* make sure lifetime hasn't grown magically either */
    TEST_ASSERT_EQUAL_INT(-1, timex_cmp(lifetime, cmp_max_lifetime));

    fib_deinit();
}
Example #2
0
static void test_timex_sub(void)
{
    timex_t time;
    time = timex_sub(timex_set(100, 100), timex_set(40, 10));
    TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(60, 90)));
    time = timex_sub(timex_set(100, 100), timex_set(40, 200));
    TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(59, 999900)));
}
Example #3
0
static void test_timex_add(void)
{
    timex_t time;
    time = timex_add(timex_set(100, 100), timex_set(40, 10));
    TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(140, 110)));
    time = timex_add(timex_set(100, 700000), timex_set(40, 800000));
    TEST_ASSERT_EQUAL_INT(0, timex_cmp(time, timex_set(141, 500000)));
}
Example #4
0
File: ping.c Project: AnonMall/RIOT
static void calc_rtt(void)
{
    timex_t rtt = timex_sub(end, start);
    rtt_sum = timex_add(rtt_sum, rtt);

    l2_ping_stats.last_rtt = rtt;
    l2_ping_stats.avg_rtt = timex_from_uint64(timex_uint64(rtt_sum) / l2_ping_stats.pong_count);
    if (timex_cmp(rtt, l2_ping_stats.max_rtt) > 0) {
        l2_ping_stats.max_rtt = rtt;
    }
    if (timex_cmp(rtt, l2_ping_stats.min_rtt) < 0) {
        l2_ping_stats.min_rtt = rtt;
    }
}
Example #5
0
/*
 * Check if entry at index i is stale and clear the struct it fills if it is
 */
static void _reset_entry_if_stale(uint8_t i)
{
    vtimer_now(&now);

    if (timex_cmp(rreq_table[i].timestamp, null_time) == 0) {
        return;
    }
    timex_t expiration_time = timex_add(rreq_table[i].timestamp, _max_idletime);
    if (timex_cmp(expiration_time, now) < 0) {
        /* timestamp+expiration time is in the past: this entry is stale */
        DEBUG("\treset rreq table entry %s\n",
              netaddr_to_string(&nbuf, &rreq_table[i].origNode));
        memset(&rreq_table[i], 0, sizeof(rreq_table[i]));
    }
}
Example #6
0
/*
 * Check if entry at index i is stale as described in Section 6.3.
 * and clear the struct it fills if it is
 */
static void _reset_entry_if_stale(uint8_t i)
{
    vtimer_now(&now);
    timex_t lastUsed, expirationTime;

    if (timex_cmp(routing_table[i].expirationTime, null_time) == 0) {
        return;
    }

    int state = routing_table[i].state;
    lastUsed = routing_table[i].lastUsed;
    expirationTime = routing_table[i].expirationTime;

    /* an Active route is considered to remain Active as long as it is used at least once
     * during every ACTIVE_INTERVAL. When a route is no longer Active, it becomes an Idle route. */

    /* if the node is younger than the active interval, don't bother */
    if (timex_cmp(now, active_interval) < 0) {
        return;
    }

    if ((state == ROUTE_STATE_ACTIVE) &&
        (timex_cmp(timex_sub(now, active_interval), lastUsed) == 1)) {
        DEBUG("\t[routing] route towards %s Idle\n",
              netaddr_to_string(&nbuf, &routing_table[i].addr));
        routing_table[i].state = ROUTE_STATE_IDLE;
        routing_table[i].lastUsed = now; /* mark the time entry was set to Idle */
    }

    /* After an Idle route remains Idle for MAX_IDLETIME, it becomes an Invalid route. */

    /* if the node is younger than the expiration time, don't bother */
    if (timex_cmp(now, expirationTime) < 0) {
        return;
    }

    /* If Current_Time > Route.ExpirationTime, set Route.State := Invalid. */
    if ((state == ROUTE_STATE_IDLE) &&
        (timex_cmp(now, expirationTime) > 0)) {
        DEBUG("\t[routing] route towards %s became Invalid\n",
              netaddr_to_string(&nbuf, &routing_table[i].addr));
        routing_table[i].state = ROUTE_STATE_INVALID;
        routing_table[i].lastUsed = now; /* mark the time entry was set to Invalid */
    }

    /* If (Current_Time - Route.LastUsed) > (ACTIVE_INTERVAL + MAX_IDLETIME),
     * and if (Route.Timed == FALSE), set Route.State := Invalid. */
    if ((timex_cmp(timex_sub(now, lastUsed), timex_add(active_interval, max_idletime)) > 0) &&
        (state != ROUTE_STATE_TIMED)) {
        routing_table[i].state = ROUTE_STATE_INVALID;
    }

    /* After that time, old sequence number information is considered no longer
     * valid and the Invalid route MUST BE expunged */
    if (timex_cmp(timex_sub(now, lastUsed), max_seqnum_lifetime) >= 0) {
        DEBUG("\t[routing] Expunged routing table entry for %s at %i\n",
              netaddr_to_string(&nbuf, &routing_table[i].addr), i);
        memset(&routing_table[i], 0, sizeof(routing_table[i]));
    }
}
Example #7
0
cv_status condition_variable::wait_until(unique_lock<mutex>& lock,
                                         const time_point& timeout_time) {
  xtimer_t timer;
  // todo: use function to wait for absolute timepoint once available
  timex_t before;
  xtimer_now_timex(&before);
  auto diff = timex_sub(timeout_time.native_handle(), before);
  xtimer_set_wakeup(&timer, timex_uint64(diff), sched_active_pid);
  wait(lock);
  timex_t after;
  xtimer_now_timex(&after);
  xtimer_remove(&timer);
  auto cmp = timex_cmp(after, timeout_time.native_handle());
  return cmp < 1 ? cv_status::no_timeout : cv_status::timeout;
}
Example #8
0
void cc1100_phy_init(void)
{
    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 = timex_set(CC1100_WATCHDOG_PERIOD, 0);

        if (timex_cmp(cc1100_watch_dog_period, timex_set(0, 0)) != 0) {
            vtimer_set_msg(&cc1100_watch_dog, cc1100_watch_dog_period, cc1100_event_handler_pid, NULL);
        }
    }
}
Example #9
0
File: fib.c Project: JiapengLi/RIOT
/**
 * @brief returns pointer to the entry for the given destination address
 *
 * @param[in] dst                  the destination address
 * @param[in] dst_size             the destination address size
 * @param[out] entry_arr           the array to scribe the found match
 * @param[in, out] entry_arr_size  the number of entries provided by entry_arr (should be always 1)
 *                                 this value is overwritten with the actual found number
 *
 * @return 0 if we found a next-hop prefix
 *         1 if we found the exact address next-hop
 *         -EHOSTUNREACH if no fitting next-hop is available
 */
static int fib_find_entry(uint8_t *dst, size_t dst_size,
                          fib_entry_t **entry_arr, size_t *entry_arr_size)
{
    timex_t now;
    vtimer_now(&now);

    size_t count = 0;
    size_t prefix_size = 0;
    size_t match_size = dst_size;
    int ret = -EHOSTUNREACH;

    for (size_t i = 0; i < FIB_MAX_FIB_TABLE_ENTRIES; ++i) {

        /* autoinvalidate if the entry lifetime is not set to not expire */
        if ((fib_table[i].lifetime.seconds != FIB_LIFETIME_NO_EXPIRE)
            || (fib_table[i].lifetime.microseconds != FIB_LIFETIME_NO_EXPIRE)) {

            /* check if the lifetime expired */
            if (timex_cmp(now, fib_table[i].lifetime) > -1) {
                /* remove this entry if its lifetime expired */
                fib_table[i].lifetime.seconds = 0;
                fib_table[i].lifetime.microseconds = 0;

                if (fib_table[i].global != NULL) {
                    universal_address_rem(fib_table[i].global);
                    fib_table[i].global = NULL;
                }

                if (fib_table[i].next_hop != NULL) {
                    universal_address_rem(fib_table[i].next_hop);
                    fib_table[i].next_hop = NULL;
                }
            }
        }

        if ((prefix_size < dst_size) &&
            (fib_table[i].global != NULL) &&
            (universal_address_compare(fib_table[i].global, dst, &match_size) == 0)) {

            /* If we found an exact match */
            if (match_size == dst_size) {
                entry_arr[0] = &(fib_table[i]);
                *entry_arr_size = 1;
                /* we will not find a better one so we return */
                return 1;
            }
            else {
                /* we try to find the most fitting prefix */
                if (match_size > prefix_size) {
                    entry_arr[0] = &(fib_table[i]);
                    /* we could find a better one so we move on */
                    ret = 0;
                }
            }

            prefix_size = match_size;
            match_size = dst_size;
            count = 1;
        }
    }

    *entry_arr_size = count;
    return ret;
}
Example #10
0
/*---------------------------------------------------------------------------*/
int cc1100_send_csmaca(radio_address_t address, protocol_t protocol, int priority, char *payload, radio_packet_length_t payload_len)
{
    uint16_t min_window_size;
    uint16_t max_window_size;
    uint16_t difs;
    uint16_t slottime;

    switch(priority) {
        case PRIORITY_ALARM:
            min_window_size = PRIO_ALARM_MIN_WINDOW_SIZE;
            max_window_size = PRIO_ALARM_MAX_WINDOW_SIZE;
            difs = PRIO_ALARM_DIFS;
            slottime = PRIO_ALARM_SLOTTIME;
            break;

        case PRIORITY_WARNING:
            min_window_size = PRIO_WARN_MIN_WINDOW_SIZE;
            max_window_size = PRIO_WARN_MAX_WINDOW_SIZE;
            difs = PRIO_WARN_DIFS;
            slottime = PRIO_WARN_SLOTTIME;
            break;

        default:
            min_window_size = PRIO_DATA_MIN_WINDOW_SIZE;
            max_window_size = PRIO_DATA_MAX_WINDOW_SIZE;
            difs = PRIO_DATA_DIFS;
            slottime = PRIO_DATA_SLOTTIME;
    }

    /* Calculate collisions per second */
    if (collision_state == COLLISION_STATE_INITIAL) {
        vtimer_now(&collision_measurement_start);
        collision_count = 0;
        collisions_per_sec = 0;
        collision_state = COLLISION_STATE_MEASURE;
    }
    else if (collision_state == COLLISION_STATE_MEASURE) {
        timex_t now;
        vtimer_now(&now);
        timex_t timespan = timex_sub(now, collision_measurement_start);

        if (timex_cmp(timespan, timex_set(1, 0)) > 0) {
            collisions_per_sec = (collision_count * 1000000) / (double) timex_uint64(timespan);

            if (collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) {
                timex_t now;
                vtimer_now(&now);
                collision_measurement_start = now;
                collision_state = COLLISION_STATE_KEEP;
            }
            else if (collisions_per_sec > 2.2) {
                timex_t now;
                vtimer_now(&now);
                collision_measurement_start = now;
                collision_state = COLLISION_STATE_KEEP;
            }
            else {
                collision_state = COLLISION_STATE_INITIAL;
            }
        }
    }
    else if (collision_state == COLLISION_STATE_KEEP) {
        timex_t now;
        vtimer_now(&now);
        timex_t timespan = timex_sub(now, collision_measurement_start);

        if (timex_cmp(timespan, timex_set(5, 0)) > 0) {
            collision_state = COLLISION_STATE_INITIAL;
        }
    }

    /* Adjust initial window size according to collision rate */
    if (collisions_per_sec > 0.5 && collisions_per_sec <= 2.2) {
        min_window_size *= 2;
    }
    else if (collisions_per_sec > 2.2) {
        min_window_size *= 4;
    }

    uint16_t windowSize = min_window_size;      /* Start with window size of PRIO_XXX_MIN_WINDOW_SIZE */
    uint16_t backoff = 0;                       /* Backoff between 1 and windowSize */
    uint32_t total;                             /* Holds the total wait time before send try */
    uint32_t cs_timeout;                        /* Current carrier sense timeout value */

    if (protocol == 0) {
        return RADIO_INVALID_PARAM;             /* Not allowed, protocol id must be greater zero */
    }

    cc1100_phy_mutex_lock();                    /* Lock radio for exclusive access */

    /* Get carrier sense timeout based on overall error rate till now */
    send_csmaca_calls++;
    int fail_percentage = (send_csmaca_calls_cs_timeout * 100) / send_csmaca_calls;

    if (fail_percentage == 0) {
        fail_percentage = 1;
    }

    cs_timeout = CARRIER_SENSE_TIMEOUT / fail_percentage;

    if (cs_timeout < CARRIER_SENSE_TIMEOUT_MIN) {
        cs_timeout = CARRIER_SENSE_TIMEOUT_MIN;
    }

    cc1100_cs_init();                           /* Initialize carrier sensing */

window:

    if (backoff != 0) {
        goto cycle;    /* If backoff was 0 */
    }

    windowSize *= 2;                        /* ...double the current window size */

    if (windowSize > max_window_size) {
        windowSize = max_window_size;       /* This is the maximum size allowed */
    }

    backoff = rand() % windowSize;          /* ...and choose new backoff */

    backoff += (uint16_t) 1;
cycle:
    cs_timeout_flag = 0;                    /* Carrier sense timeout flag */
    cs_hwtimer_id = hwtimer_set(cs_timeout, /* Set hwtimer to set CS timeout flag */
                                cs_timeout_cb, NULL);

    while (cc1100_cs_read()) {          /* Wait until air is free */
        if (cs_timeout_flag) {
            send_csmaca_calls_cs_timeout++;
#ifndef CSMACA_MAC_AGGRESSIVE_MODE
            cc1100_phy_mutex_unlock();
            cc1100_go_after_tx();           /* Go from RX to default mode */
            return RADIO_CS_TIMEOUT;        /* Return immediately */
#endif
#ifdef CSMACA_MAC_AGGRESSIVE_MODE
            goto send;                      /* Send anyway */
#endif
        }
    }

    hwtimer_remove(cs_hwtimer_id);          /* Remove hwtimer */
    cc1100_cs_write_cca(1);                 /* Air is free now */
    cc1100_cs_set_enabled(true);

    if (cc1100_cs_read()) {
        goto window;    /* GDO0 triggers on rising edge, so */
    }

    /* test once after interrupt is enabled */
    if (backoff > 0) {
        backoff--;    /* Decrement backoff counter */
    }

    total = slottime;                       /* Calculate total wait time */
    total *= (uint32_t)backoff;             /* Slot vector set */
    total += difs;                          /* ...and standard DIFS wait time */
    cs_timeout_flag = 0;                    /* Carrier sense timeout flag */
    cs_hwtimer_id = hwtimer_set(total,      /* Set hwtimer to set CS timeout flag */
                                cs_timeout_cb, NULL);

    while (!cs_timeout_flag
          || !cc1100_cs_read_cca()) {   /* Wait until timeout is finished */
        if (cc1100_cs_read_cca() == 0) {    /* Is the air still free? */
            hwtimer_remove(cs_hwtimer_id);
            goto window;                    /* No. Go back to new wait period. */
        }
    }

    cc1100_cs_set_enabled(false);
#ifdef CSMACA_MAC_AGGRESSIVE_MODE
send:
#endif
    int res = cc1100_send(address, protocol, priority, payload, payload_len);

    if (res < 0) {
        collision_count++;
    }

    return res;
}