Example #1
0
void handle_established(socket_internal_t *current_socket)
{
    msg_t send;
    double current_timeout = current_socket->socket_values.tcp_control.rto;

    if (current_timeout < SECOND) {
        current_timeout = SECOND;
    }

    uint8_t i;

    if ((current_socket->socket_values.tcp_control.send_nxt >
         current_socket->socket_values.tcp_control.send_una) &&
        (thread_getstatus(current_socket->send_pid) == STATUS_RECEIVE_BLOCKED)) {
        for (i = 0; i < current_socket->socket_values.tcp_control.no_of_retries;
             i++) {
            current_timeout *= 2;
        }

        timex_t now;
        vtimer_now(&now);

        if (current_timeout > TCP_ACK_MAX_TIMEOUT) {
            net_msg_send(&send, current_socket->send_pid, 0, TCP_TIMEOUT);
        }
        else if (timex_uint64(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time)) >
                 current_timeout) {
            current_socket->socket_values.tcp_control.no_of_retries++;
            net_msg_send(&send, current_socket->send_pid, 0, TCP_RETRY);
        }
    }
}
Example #2
0
void vtimer_gettimeofday(struct timeval *tp) {
    timex_t now;
    vtimer_now(&now);

    tp->tv_sec = now.seconds;
    tp->tv_usec = now.microseconds;
}
Example #3
0
File: ip.c Project: ajf58/RIOT
uint32_t get_remaining_time(timex_t *t)
{
    timex_t now;
    vtimer_now(&now);

    return (timex_sub(*t, now).seconds);
}
Example #4
0
void handle_synchro_timeout(socket_internal_t *current_socket)
{
    msg_t send;

    if (thread_getstatus(current_socket->recv_pid) == STATUS_RECEIVE_BLOCKED) {
        timex_t now;
        vtimer_now(&now);

        if ((current_socket->socket_values.tcp_control.no_of_retries == 0) &&
            (timex_uint64(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time)) > TCP_SYN_INITIAL_TIMEOUT)) {
            current_socket->socket_values.tcp_control.no_of_retries++;
            net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
        }
        else if ((current_socket->socket_values.tcp_control.no_of_retries > 0) &&
                 (timex_uint64(timex_sub(now, current_socket->socket_values.tcp_control.last_packet_time)) >
                  (current_socket->socket_values.tcp_control.no_of_retries *
                   TCP_SYN_TIMEOUT + TCP_SYN_INITIAL_TIMEOUT))) {
            current_socket->socket_values.tcp_control.no_of_retries++;

            if (current_socket->socket_values.tcp_control.no_of_retries >
                TCP_MAX_SYN_RETRIES) {
                net_msg_send(&send, current_socket->recv_pid, 0, TCP_TIMEOUT);
            }
            else {
                net_msg_send(&send, current_socket->recv_pid, 0, TCP_RETRY);
            }
        }
    }
}
Example #5
0
int _l2_ping_probe_handler(int argc, char **argv)
{
    size_t payload_strlen;
    uint16_t count = 5;
    timex_t start, end, period;

    if (transceiver_pid == KERNEL_PID_UNDEF) {
        puts("Transceiver not initialized");
        return 1;
    }
    if (argc < 2) {
        printf("Usage:\t%s <ADDR> [COUNT] [MSG]\n", argv[0]);
        return 1;
    }

    char l2_payload[L2_PING_PAYLOAD_SIZE];
    if (argc > 3) {
        payload_strlen = strlen(argv[3]);
        if (payload_strlen > L2_PING_PAYLOAD_SIZE) {
            printf("[l2_ping] Your input is too long and will be truncated to \"%.*s\".\n", L2_PING_PAYLOAD_SIZE, argv[3]);
            payload_strlen = L2_PING_PAYLOAD_SIZE;
        }
        memset(l2_payload, 0, L2_PING_PAYLOAD_SIZE);
        strncpy(l2_payload, argv[3], payload_strlen);
    }
    else {
        payload_strlen = 0;
    }

    if (argc > 2) {
        count = atoi(argv[2]);
    }

    printf("[l2_ping] Send %" PRIu16 " probes to %" PRIu16 " with interval %u  and payload %s\n",
            count, atoi(argv[1]), L2_PING_DEFAULT_INTERVAL, (argc > 3) ? l2_payload : "NULL");
    vtimer_now(&start);
    l2_ping((radio_address_t) atoi(argv[1]), count, L2_PING_DEFAULT_INTERVAL,
            l2_payload, payload_strlen, 1);
    vtimer_now(&end);
    period = timex_sub(end, start);

    printf("  --- ping statistics for host %" PRIu16 " ---\n", l2_ping_stats.dst);
    printf("  %" PRIu16 " packets transmitted in %" PRIu32 ".%06" PRIu32 "s\n", l2_ping_stats.ping_count,
            period.seconds, period.microseconds);

    return 0;
}
Example #6
0
void calc_rtt(void)
{
    timex_t end;
    vtimer_now(&end);
    timex_t result = vtimer_sub(end, start);

    rtt = result.seconds + (float)result.microseconds / 100000;
}
Example #7
0
File: ip.c Project: A-L-E-X/RIOT
void set_remaining_time(timex_t *t, uint32_t time)
{
    timex_t tmp = {time, 0};

    timex_t now;
    vtimer_now(&now);
    *t = timex_add(now, tmp);
}
Example #8
0
void vtimer_get_localtime(struct tm *localt)
{
    timex_t now;
    vtimer_now(&now);

    memset(localt, 0, sizeof(struct tm));
    localt->tm_sec = now.seconds % 60;
    localt->tm_min = (now.seconds / 60) % 60;
    localt->tm_hour = (now.seconds / 60 / 60) % 24;
}
Example #9
0
void vtimer_get_localtime(struct tm *localt)
{
    timex_t now;
    vtimer_now(&now);

    localt->tm_sec = now.seconds % 60;
    localt->tm_min = (now.seconds / 60) % 60;
    localt->tm_hour = (now.seconds / 60 / 60) % 24;

    // TODO: fill the other fields
}
Example #10
0
void print_tcp_cb(tcp_cb_t *cb)
{
    timex_t now;
    vtimer_now(&now);
    printf("Send_ISS: %" PRIu32 "\nSend_UNA: %" PRIu32 "\nSend_NXT: %" PRIu32 "\nSend_WND: %u\n",
           cb->send_iss, cb->send_una, cb->send_nxt, cb->send_wnd);
    printf("Rcv_IRS: %" PRIu32 "\nRcv_NXT: %" PRIu32 "\nRcv_WND: %u\n",
           cb->rcv_irs, cb->rcv_nxt, cb->rcv_wnd);
    printf("Time difference: %" PRIu32 ", No_of_retries: %u, State: %u\n\n",
           timex_sub(now, cb->last_packet_time).microseconds, cb->no_of_retries, cb->state);
}
Example #11
0
bool rreqtable_is_redundant(struct aodvv2_packet_data *packet_data)
{
    struct aodvv2_rreq_entry *comparable_rreq;
    timex_t now;
    bool result;

    mutex_lock(&rreqt_mutex);
    comparable_rreq = _get_comparable_rreq(packet_data);

    /* if there is no comparable rreq stored, add one and return false */
    if (comparable_rreq == NULL) {
        _add_rreq(packet_data);
        result = false;
    }
    else {
        int seqnum_comparison = seqnum_cmp(packet_data->origNode.seqnum, comparable_rreq->seqnum);

        /*
         * If two RREQs have the same
         * metric type and OrigNode and Targnode addresses, the information from
         * the one with the older Sequence Number is not needed in the table
         */
        if (seqnum_comparison == -1) {
            result = true;
        }

        if (seqnum_comparison == 1) {
            /* Update RREQ table entry with new seqnum value */
            comparable_rreq->seqnum = packet_data->origNode.seqnum;
        }

        /*
         * in case they have the same Sequence Number, the one with the greater
         * Metric value is not needed
         */
        if (seqnum_comparison == 0) {
            if (comparable_rreq->metric <= packet_data->origNode.metric) {
                result = true;
            }
            /* Update RREQ table entry with new metric value */
            comparable_rreq->metric = packet_data->origNode.metric;
        }

        /* Since we've changed RREQ info, update the timestamp */
        vtimer_now(&now);
        comparable_rreq->timestamp = now;
        result = true;
    }

    mutex_unlock(&rreqt_mutex);
    return result;
}
Example #12
0
File: ping.c Project: AnonMall/RIOT
/* internal functions */
static void *l2_pkt_handler(void *unused)
{
    (void) unused;

    msg_t m;
    radio_packet_t *p;
    l2_ping_payload_t *pp;

    msg_init_queue(msg_q, sizeof(msg_q));

    while (1) {
        msg_receive(&m);

        if (m.type == PKT_PENDING) {
            vtimer_now(&end);
            p = (radio_packet_t *) m.content.ptr;
            pp = (l2_ping_payload_t *) p->data;

            if ((pp->type & L2_PAYLOAD_TYPE) == L2_PAYLOAD_PING) {
                DEBUGF("INFO: received l2_ping_packet number %d from %d with payload(%d) %.*s.\n",
                        pp->seq, p->src, pp->payload_len, pp->payload_len, pp->payload);
                switch (pp->type & L2_PING_TYPE) {
                    case L2_PING:
                        ping_handler(p->src, pp->seq);
                        break;
                    case L2_PONG:
                        pong_handler();
                        break;
                    case L2_PROBE:
                        probe_handler(p->src);
                        break;
                    default:
                        DEBUGF("ERROR: Unknown L2 PING type\n");
                }
            }
            else {
                DEBUGF("WARN: no L2 ping packet, type is %02X\n", pp->type);
            }

            p->processing--;
        }
        else if (m.type == ENOBUFFER) {
            DEBUGF("ERROR: Transceiver buffer full\n");
        }
        else {
            DEBUGF("ERROR: Unknown messagereceived\n");
        }
    }

    return NULL;
}
Example #13
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 #14
0
static void riot_ccn_pit_test(int argc, char **argv)
{
    (void) argc; /* the function takes no arguments */
    (void) argv;

    char name[] = "/riot/test";

    char *prefix[CCNL_MAX_NAME_COMP];
    char *cp = strtok(name, "/");
    int i = 0;

    while (i < (CCNL_MAX_NAME_COMP - 1) && cp) {
        prefix[i++] = cp;
        cp = strtok(NULL, "/");
    }

    //prefix[i] = 0; //segment to request
    prefix[i + 1] = 0;

    msg_t m;
    riot_ccnl_msg_t rmsg;
    char segment_string[16]; //max=999\0
    timex_t now;

    int segment;

    for (segment = 0; segment < 200; segment++) {
        memset(segment_string, 0, 16);
        snprintf(segment_string, 16, "%d", segment);
        prefix[i] = segment_string;
        unsigned int interest_nonce = genrand_uint32();
        int interest_len = mkInterest(prefix, &interest_nonce, (unsigned char *) small_buf);

        rmsg.payload = &small_buf;
        rmsg.size = interest_len;
        m.content.ptr = (char *) &rmsg;
        m.type = CCNL_RIOT_MSG;

        msg_send(&m, relay_pid);

        if ((segment % 50) == 0) {
            vtimer_now(&now);
            printf("done: %d - %ld.%ld\n", segment, now.tv_sec, now.tv_usec);
        }
    }

    printf("done: tried to send %d interests\n", segment);
}
Example #15
0
void def_rtr_lst_add(ipv6_addr_t *ipaddr, uint32_t rtr_ltime)
{
    if (def_rtr_count == DEF_RTR_LST_SIZE) {
        DEBUG("ERROR: default router list full\n");
    }
    else {
        memcpy(&(def_rtr_lst[def_rtr_count].addr), ipaddr, 16);
        timex_t rltime = {rtr_ltime, 0};
        timex_t now;
        vtimer_now(&now);

        def_rtr_lst[def_rtr_count].inval_time = timex_add(now, rltime);

        def_rtr_count++;
    }
}
Example #16
0
int pthread_cond_timedwait(struct pthread_cond_t *cond, struct mutex_t *mutex, const struct timespec *abstime)
{
    timex_t now, then, reltime;

    vtimer_now(&now);
    then.seconds = abstime->tv_sec;
    then.microseconds = abstime->tv_nsec / 1000u;
    reltime = timex_sub(then, now);

    vtimer_t timer;
    vtimer_set_wakeup(&timer, reltime, sched_active_thread->pid);
    int result = pthread_cond_wait(cond, mutex);
    vtimer_remove(&timer);

    return result;
}
Example #17
0
File: destiny.c Project: Poopi/RIOT
int destiny_init_transport_layer(void)
{
    printf("Initializing transport layer packages. Size of socket_type: %u\n",
           sizeof(socket_internal_t));
    /* SOCKETS */
    memset(sockets, 0, MAX_SOCKETS * sizeof(socket_internal_t));

    /* UDP */
    int udp_thread_pid = thread_create(udp_stack_buffer, UDP_STACK_SIZE,
                                       PRIORITY_MAIN, CREATE_STACKTEST,
                                       udp_packet_handler, "udp_packet_handler");

    if (udp_thread_pid < 0) {
        return -1;
    }

    ipv6_register_next_header_handler(IPV6_PROTO_NUM_UDP, udp_thread_pid);

    /* TCP */
    timex_t now;
    vtimer_now(&now);
    srand(now.microseconds);
#ifdef TCP_HC
    printf("TCP_HC enabled!\n");
    global_context_counter = rand();
#endif
    global_sequence_counter = rand();

    int tcp_thread_pid = thread_create(tcp_stack_buffer, TCP_STACK_SIZE,
                                       PRIORITY_MAIN, CREATE_STACKTEST,
                                       tcp_packet_handler, "tcp_packet_handler");

    if (udp_thread_pid < 0) {
        return -1;
    }

    ipv6_register_next_header_handler(IPV6_PROTO_NUM_TCP, tcp_thread_pid);

    if (thread_create(tcp_timer_stack, TCP_TIMER_STACKSIZE, PRIORITY_MAIN + 1,
                      CREATE_STACKTEST, tcp_general_timer, "tcp_general_timer") < 0) {
        return -1;
    }

    return 0;
}
Example #18
0
void ping(radio_address_t addr, uint8_t channr)
{
    cc1100_set_packet_handler(protocol_id, pong_handler);
    cc1100_set_channel(channr);
    cc1100_set_address(r_address);

    while(1) {
        vtimer_now(&start);
        int trans_ok = cc1100_send_csmaca(addr,
                                          protocol_id, 2, pipa->payload, sizeof(pipa->payload));

        if(trans_ok < 0) {
            print_failed();
        }

        hwtimer_wait(500000);
    }
}
Example #19
0
static int vtimer_set(vtimer_t *timer)
{
    DEBUG("vtimer_set(): New timer. Offset: %" PRIu32 " %" PRIu32 "\n", timer->absolute.seconds, timer->absolute.microseconds);

    timex_t now;
    vtimer_now(&now);
    timer->absolute = timex_add(now, timer->absolute);
    normalize_to_tick(&(timer->absolute));

    DEBUG("vtimer_set(): Absolute: %" PRIu32 " %" PRIu32 "\n", timer->absolute.seconds, timer->absolute.microseconds);
    DEBUG("vtimer_set(): NOW: %" PRIu32 " %" PRIu32 "\n", now.seconds, now.microseconds);

    int result = 0;

    if (timer->absolute.seconds == 0) {
        if (timer->absolute.microseconds > 10) {
            timer->absolute.microseconds -= 10;
        }
    }

    unsigned state = disableIRQ();
    if (timer->absolute.seconds != longterm_tick_timer.absolute.seconds) {
        /* we're long-term */
        DEBUG("vtimer_set(): setting long_term\n");
        result = set_longterm(timer);
    }
    else {
        DEBUG("vtimer_set(): setting short_term\n");

        if (set_shortterm(timer)) {
            /* delay update of next shortterm timer if we
            * are called from within vtimer_callback. */

            if (!in_callback) {
                result = update_shortterm();
            }
        }
    }
    restoreIRQ(state);

    return result;
}
Example #20
0
File: fib.c Project: JiapengLi/RIOT
void fib_print_routes(void)
{
    mutex_lock(&mtx_access);
    printf("%-32s %-6s %-32s %-6s %-16s Interface\n"
           , "Destination", "Flags", "Next Hop", "Flags", "Expires");

    timex_t now;
    vtimer_now(&now);

    for (size_t i = 0; i < FIB_MAX_FIB_TABLE_ENTRIES; ++i) {
        if (fib_table[i].lifetime.seconds != 0 || fib_table[i].lifetime.microseconds != 0) {
            fib_print_adress(fib_table[i].global);
            printf(" 0x%04x ", fib_table[i].global_flags);
            fib_print_adress(fib_table[i].next_hop);
            printf(" 0x%04x ", fib_table[i].next_hop_flags);

            if ((fib_table[i].lifetime.seconds != FIB_LIFETIME_NO_EXPIRE)
                || (fib_table[i].lifetime.microseconds != FIB_LIFETIME_NO_EXPIRE)) {

                timex_t tm = timex_sub(fib_table[i].lifetime, now);

                /* we must interpret the values as signed */
                if ((int32_t)tm.seconds < 0
                    || (tm.seconds == 0 && (int32_t)tm.microseconds < 0)) {
                    printf("%-16s ", "EXPIRED");
                }
                else {
                    printf("%"PRIu32".%05"PRIu32, tm.seconds, tm.microseconds);
                }
            }
            else {
                printf("%-16s ", "NEVER");
            }

            printf("%d\n", (int)fib_table[i].iface_id);
        }
    }

    mutex_unlock(&mtx_access);
}
Example #21
0
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);
}
Example #22
0
static bool contains_seq_entry(uint8_t src, uint8_t id)
{
    int i;
    uint32_t cmp;
    timex_t now_timex;
    vtimer_now(&now_timex);

    for (i = 0; i < MAX_SEQ_BUFFER_SIZE; i++) {
        if ((seq_buffer[i].source == src) && (seq_buffer[i].identification == id)) {
            /* Check if time stamp is OK */
            cmp = (radio_mode == CC1100_MODE_WOR) ? cc1100_wor_config.rx_interval : 16000; /* constant RX ~16ms */

            if ((timex_uint64(now_timex) - seq_buffer[i].m_ticks < cmp)) {
                return true;
            }
            else {
                seq_buffer[i].source = 0; /* Reset */
            }
        }
    }

    return false;
}
Example #23
0
File: rtc.c Project: lab11/opo
void rtc_set_unixtime(time_t btime) {
    base_unixtime = btime;
    base_time = vtimer_now();
}
Example #24
0
File: ip.c Project: A-L-E-X/RIOT
int ipv6_net_if_add_addr(int if_id, const ipv6_addr_t *addr,
                         ndp_addr_state_t state, uint32_t val_ltime,
                         uint32_t pref_ltime, uint8_t is_anycast)
{
    ipv6_net_if_addr_t *addr_entry;
    ipv6_net_if_hit_t hit;

    if (ipv6_addr_is_unspecified(addr) == 128) {
        DEBUG("ERROR: unspecified address (::) can't be assigned to interface.\n");
        return 0;
    }

    if (ipv6_addr_is_multicast(addr) && is_anycast) {
        DEBUG("ERROR: anycast addresses must not be multicast addresses "
              "(i.e. start with ff::/2)\n");
        return 0;
    }

    if (ipv6_net_if_addr_match(&hit, addr)) {
        return 1;
    }

    if (ipv6_net_if_addr_buffer_count < IPV6_NET_IF_ADDR_BUFFER_LEN) {
        timex_t valtime = {val_ltime, 0};
        timex_t preftime = {pref_ltime, 0};
        timex_t now;

        vtimer_now(&now);

        ipv6_addr_t *addr_data = &ipv6_addr_buffer[ipv6_net_if_addr_buffer_count];
        memcpy(addr_data, addr, sizeof(ipv6_addr_t));

        addr_entry = &ipv6_net_if_addr_buffer[ipv6_net_if_addr_buffer_count];
        addr_entry->addr_data = addr_data;
        addr_entry->addr_len = 128;

        if (is_anycast) {
            addr_entry->addr_protocol = NET_IF_L3P_IPV6_ANYCAST;
        }
        else if (ipv6_addr_is_multicast(addr_data)) {
            addr_entry->addr_protocol = NET_IF_L3P_IPV6_MULTICAST;
        }
        else {
            addr_entry->addr_protocol = NET_IF_L3P_IPV6_UNICAST;
        }

        addr_entry->ndp_state = state;
        addr_entry->valid_lifetime = timex_add(now, valtime);
        addr_entry->preferred_lifetime = timex_add(now, preftime);
        addr_entry->is_anycast = is_anycast;

        ipv6_net_if_addr_buffer_count++;

        net_if_add_address(if_id, (net_if_addr_t *)addr_entry);

        /* Register to Solicited-Node multicast address according to RFC 4291 */
        if (is_anycast || !ipv6_addr_is_multicast(addr)) {
            ipv6_addr_t sol_node_mcast_addr;
            ipv6_addr_set_solicited_node_addr(&sol_node_mcast_addr, addr);

            if (ipv6_net_if_addr_match(&hit, &sol_node_mcast_addr) == NULL) {
                ipv6_net_if_add_addr(if_id, &sol_node_mcast_addr, state,
                                     val_ltime, pref_ltime, 0);
            }
        }

        return 1;
    }

    return 0;
}
Example #25
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;
}
Example #26
0
/**
 * This callback is called every time the _rreq_consumer finishes reading a
 * packet.
 * @param cont
 * @param dropped indicates whether the packet has been dropped previously by
 *                another callback
 */
static enum rfc5444_result _cb_rreq_end_callback(
    struct rfc5444_reader_tlvblock_context *cont, bool dropped)
{
    (void) cont;

    struct aodvv2_routing_entry_t *rt_entry;
    timex_t now;

    /* Check if packet contains the required information */
    if (dropped) {
        DEBUG("\t Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if ((packet_data.origNode.addr._type == AF_UNSPEC) || !packet_data.origNode.seqnum) {
        DEBUG("\tERROR: missing OrigNode Address or SeqNum. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if (packet_data.targNode.addr._type == AF_UNSPEC) {
        DEBUG("\tERROR: missing TargNode Address. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if (packet_data.hoplimit == 0) {
        DEBUG("\tERROR: Hoplimit is 0. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if ((_get_max_metric(packet_data.metricType) - _get_link_cost(packet_data.metricType))
        <= packet_data.origNode.metric) {
        DEBUG("\tMetric Limit reached. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }

    /*
      The incoming RREQ MUST be checked against previously received
      information from the RREQ Table Section 7.6.  If the information
      in the incoming RteMsg is redundant, then then no further action
      is taken.
    */
    if (rreqtable_is_redundant(&packet_data)) {
        DEBUG("\tPacket is redundant. Dropping Packet. %i\n", RFC5444_DROP_PACKET);
        return RFC5444_DROP_PACKET;
    }

    /* Update the cost of the route, since the packet has successfully traversed
     * one more hop. */
    packet_data.origNode.metric = _get_route_cost(packet_data.metricType,
                                                  packet_data.origNode.metric);
    vtimer_now(&now);
    packet_data.timestamp = now;

    /* for every relevant
     * address (RteMsg.Addr) in the RteMsg, HandlingRtr searches its route
     * table to see if there is a route table entry with the same MetricType
     * of the RteMsg, matching RteMsg.Addr.
     */

    rt_entry = routingtable_get_entry(&packet_data.origNode.addr, packet_data.metricType);

    if (!rt_entry || (rt_entry->metricType != packet_data.metricType)) {
        /* CAUTION SUPER HACKY FIX FIXME ASAP
        problem: sometimes we get broadcasted RREQs from 2 hop neighbors and then
        AODVv2 gets super confused when they're not in the routing table and starts a
        Route discovery to find them and all hell breaks loose. let's see if we can fix
        this (horribly).

        (another fix would be to stop bouncing the RREP back to the sender and asking
        the routing table for the next hop (or just send towards TargNode and let the
        network stack figure out the rest?))
        TODO evaluate that
        */

        ipv6_addr_t sender_tmp;
        netaddr_to_ipv6_addr_t(&packet_data.sender, &sender_tmp);
        ndp_neighbor_cache_t *ndp_nc_entry = ndp_neighbor_cache_search(&sender_tmp);

        if (ndp_nc_entry == NULL) {
            DEBUG("OH NOES! No bidirectional link to sender. Dropping packet.\n");
            return RFC5444_DROP_PACKET;
        }
        /* HACKY FIX ENDS HERE */

        VDEBUG("\tCreating new Routing Table entry...\n");

        struct aodvv2_routing_entry_t *tmp_rt_entry = (struct aodvv2_routing_entry_t *)
                                                       malloc(sizeof(struct aodvv2_routing_entry_t));
        memset(tmp_rt_entry, 0, sizeof(*tmp_rt_entry));

        routingtable_fill_routing_entry_t_rreq(&packet_data, tmp_rt_entry);
        routingtable_add_entry(tmp_rt_entry);

        /* add entry to FIB */
        fib_add_entry(aodvv2_if_id, tmp_rt_entry->addr._addr, sizeof(ipv6_addr_t), 0,
                      tmp_rt_entry->nextHopAddr._addr, sizeof(ipv6_addr_t), 0, aodvv2_validity_t);

        free(tmp_rt_entry);
    }
    else {
        if (!routingtable_offers_improvement(rt_entry, &packet_data.origNode)) {
            DEBUG("\tPacket offers no improvement over known route. Dropping Packet.\n");
            return RFC5444_DROP_PACKET;
        }
        /* The incoming routing information is better than existing routing
         * table information and SHOULD be used to improve the route table. */
        VDEBUG("\tUpdating Routing Table entry...\n");
        routingtable_fill_routing_entry_t_rreq(&packet_data, rt_entry);

        /* update the FIB */
        fib_update_entry(rt_entry->addr._addr, sizeof(ipv6_addr_t), rt_entry->nextHopAddr._addr,
                         sizeof(ipv6_addr_t), 0, aodvv2_validity_t);
    }

    /*
     * If TargNode is a client of the router receiving the RREQ, then the
     * router generates a RREP message as specified in Section 7.4, and
     * subsequently processing for the RREQ is complete.  Otherwise,
     * processing continues as follows.
     */
    if (clienttable_is_client(&packet_data.targNode.addr)) {
        AODV_DEBUG("TargNode is in client list, sending RREP\n");

        /* make sure to start with a clean metric value */
        packet_data.targNode.metric = 0;
        aodv_send_rrep(&packet_data, &packet_data.sender);
    }
    else {
        AODV_DEBUG("I am not TargNode, forwarding RREQ\n");
        aodv_send_rreq(&packet_data);
    }
    return RFC5444_OKAY;
}
Example #27
0
int destiny_socket_connect(int socket, sockaddr6_t *addr, uint32_t addrlen)
{
    /* Variables */
    ipv6_addr_t src_addr;
    socket_internal_t *current_int_tcp_socket;
    socket_t *current_tcp_socket;
    msg_t msg_from_server;
    uint8_t send_buffer[BUFFER_SIZE];
    ipv6_hdr_t *temp_ipv6_header = ((ipv6_hdr_t *)(&send_buffer));
    tcp_hdr_t *current_tcp_packet = ((tcp_hdr_t *)(&send_buffer[IPV6_HDR_LEN]));

    /* Check if socket exists */
    current_int_tcp_socket = get_socket(socket);

    if (current_int_tcp_socket == NULL) {
        return -1;
    }

    current_tcp_socket = &current_int_tcp_socket->socket_values;

    current_int_tcp_socket->recv_pid = thread_getpid();

    /* Local address information */
    ipv6_iface_get_best_src_addr(&src_addr, &addr->sin6_addr);
    set_socket_address(&current_tcp_socket->local_address, PF_INET6,
                       HTONS(get_free_source_port(IPPROTO_TCP)), 0, &src_addr);

    /* Foreign address information */
    set_socket_address(&current_tcp_socket->foreign_address, addr->sin6_family,
                       addr->sin6_port, addr->sin6_flowinfo, &addr->sin6_addr);

    /* Fill lcoal TCP socket information */
    srand(addr->sin6_port);

    current_tcp_socket->tcp_control.rcv_irs	= 0;
    mutex_lock(&global_sequence_clunter_mutex);
    current_tcp_socket->tcp_control.send_iss = global_sequence_counter;
    mutex_unlock(&global_sequence_clunter_mutex);
    current_tcp_socket->tcp_control.state = SYN_SENT;

#ifdef TCP_HC
    /* Choosing random number Context ID */
    mutex_lock(&global_context_counter_mutex);
    current_tcp_socket->tcp_control.tcp_context.context_id = global_context_counter;
    mutex_unlock(&global_context_counter_mutex);

    current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;

    /* Remember TCP Context for possible TCP_RETRY */
    tcp_hc_context_t saved_tcp_context;
    memcpy(&saved_tcp_context, &current_tcp_socket->tcp_control.tcp_context,
           sizeof(tcp_hc_context_t));
#endif

    set_tcp_cb(&current_tcp_socket->tcp_control, 0, DESTINY_SOCKET_STATIC_WINDOW,
               current_tcp_socket->tcp_control.send_iss,
               current_tcp_socket->tcp_control.send_iss, 0);

    /* Remember current time */
    timex_t now;
    vtimer_now(&now);
    current_tcp_socket->tcp_control.last_packet_time = now;
    current_tcp_socket->tcp_control.no_of_retries = 0;

    msg_from_server.type = TCP_RETRY;

    while (msg_from_server.type == TCP_RETRY) {
        /* Send packet */
        send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header,
                 TCP_SYN, 0);

        /* wait for SYN ACK or RETRY */
        msg_receive(&msg_from_server);

        if (msg_from_server.type == TCP_TIMEOUT) {
#ifdef TCP_HC
            /* We did not send anything successful so restore last context */
            memcpy(&current_tcp_socket->tcp_control.tcp_context,
                   &saved_tcp_context, sizeof(tcp_hc_context_t));
#endif
            return -1;
        }

#ifdef TCP_HC
        else if (msg_from_server.type == TCP_RETRY) {
            /* We retry sending a packet so set everything to last values again */
            memcpy(&current_tcp_socket->tcp_control.tcp_context,
                   &saved_tcp_context, sizeof(tcp_hc_context_t));
        }

#endif
    }

    /* Read packet content */
    tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(msg_from_server.content.ptr));

    /* Check for consistency */
    if (tcp_header->ack_nr != current_tcp_socket->tcp_control.send_nxt + 1) {
        printf("TCP packets not consistent!\n");
    }

    /* Got SYN ACK from Server */
    /* Refresh foreign TCP socket information */
    if ((tcp_header->dataOffset_reserved * 4 > TCP_HDR_LEN) &&
        (*(((uint8_t *)tcp_header) + TCP_HDR_LEN) == TCP_MSS_OPTION)) {
        current_tcp_socket->tcp_control.mss =
            *((uint16_t *)(((uint8_t *)tcp_header) + TCP_HDR_LEN + 2));
    }
    else {
        current_tcp_socket->tcp_control.mss = DESTINY_SOCKET_STATIC_MSS;
    }

    current_tcp_socket->tcp_control.rcv_irs = tcp_header->seq_nr;
    set_tcp_cb(&current_tcp_socket->tcp_control, tcp_header->seq_nr + 1,
               current_tcp_socket->tcp_control.rcv_wnd,
               current_tcp_socket->tcp_control.send_una,
               current_tcp_socket->tcp_control.send_una,
               tcp_header->window);
    current_tcp_socket->tcp_control.send_una++;
    current_tcp_socket->tcp_control.send_nxt++;

    msg_from_server.type = UNDEFINED;

    /* Remember current time */
    vtimer_now(&now);
    current_tcp_socket->tcp_control.last_packet_time = now;
    current_tcp_socket->tcp_control.no_of_retries = 0;

#ifdef TCP_HC
    current_tcp_socket->tcp_control.tcp_context.hc_type = FULL_HEADER;
    /* Remember TCP Context for possible TCP_RETRY */
    memcpy(&saved_tcp_context, &current_tcp_socket->tcp_control.tcp_context,
           sizeof(tcp_hc_context_t));
#endif

    while (msg_from_server.type != TCP_RETRY) {
        /* Send packet */
        send_tcp(current_int_tcp_socket, current_tcp_packet, temp_ipv6_header,
                 TCP_ACK, 0);

        msg_receive(&msg_from_server);
#ifdef TCP_HC

        if (msg_from_server.type == TCP_SYN_ACK) {
            /* TCP_SYN_ACK from server arrived again, copy old context and
             * send TCP_ACK again */
            memcpy(&current_tcp_socket->tcp_control.tcp_context,
                   &saved_tcp_context, sizeof(tcp_hc_context_t));
        }
        else if (msg_from_server.type == TCP_RETRY) {
            /* We waited for RTT, no TCP_SYN_ACK received, so we assume the
             * TCP_ACK packet arrived safely */
        }

#endif
    }

    current_tcp_socket->tcp_control.state = ESTABLISHED;

    current_int_tcp_socket->recv_pid = 255;

    destiny_socket_print_sockets();
    return 0;
}
Example #28
0
/**
 * This callback is called every time the _rreq_consumer finishes reading a
 * packet.
 * @param cont
 * @param dropped indicates wehther the packet has been dropped previously by
 *                another callback
 */
static enum rfc5444_result _cb_rrep_end_callback(
    struct rfc5444_reader_tlvblock_context *cont, bool dropped)
{
    (void) cont;

    VDEBUG("%s()\n", __func__);

    struct aodvv2_routing_entry_t *rt_entry;
#if ENABLE_DEBUG
    struct netaddr_str nbuf;
#endif
    timex_t now;

    /* Check if packet contains the required information */
    if (dropped) {
        DEBUG("\t Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if ((packet_data.origNode.addr._type == AF_UNSPEC)
        || !packet_data.origNode.seqnum) {
        DEBUG("\tERROR: missing OrigNode Address or SeqNum. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if ((packet_data.targNode.addr._type == AF_UNSPEC)
        || !packet_data.targNode.seqnum) {
        DEBUG("\tERROR: missing TargNode Address or SeqNum. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }
    if ((_get_max_metric(packet_data.metricType) - _get_link_cost(packet_data.metricType))
        <= packet_data.targNode.metric) {
        DEBUG("\tMetric Limit reached. Dropping packet.\n");
        return RFC5444_DROP_PACKET;
    }

    /* Update the cost of the route, since the packet has successfully traversed
     * one more hop. */
    packet_data.targNode.metric = _get_route_cost(packet_data.metricType,
                                                  packet_data.targNode.metric);
    vtimer_now(&now);
    packet_data.timestamp = now;

    /* for every relevant address (RteMsg.Addr) in the RteMsg, HandlingRtr
    searches its route table to see if there is a route table entry with the
    same MetricType of the RteMsg, matching RteMsg.Addr. */

    rt_entry = routingtable_get_entry(&packet_data.targNode.addr, packet_data.metricType);

    if (!rt_entry || (rt_entry->metricType != packet_data.metricType)) {
        /* CAUTION SUPER HACKY FIX FIXME ASAP
        problem: sometimes we get broadcasted RREQs from 2 hop neighbors and then
        AODVv2 gets super confused when they're not in the routing table and starts a
        Route discovery to find them and all hell breaks loose. let's see if we can fix
        this (horribly).

        (another fix would be to stop bouncing the RREP back to the sender and asking
        the routing table for the next hop (or just send towards TargNode and let the network stack figure out the rest?))
        TODO evaluate that
        */

        ipv6_addr_t sender_tmp;
        netaddr_to_ipv6_addr_t(&packet_data.sender, &sender_tmp);
        ndp_neighbor_cache_t *ndp_nc_entry = ndp_neighbor_cache_search(&sender_tmp);

        if (ndp_nc_entry == NULL) {
            DEBUG("OH NOES! No bidirectional link to sender. Dropping packet.\n");
            return RFC5444_DROP_PACKET;
        }
        /* HACKY FIX ENDS HERE */
        VDEBUG("\tCreating new Routing Table entry...\n");

        struct aodvv2_routing_entry_t *tmp_rt_entry = (struct aodvv2_routing_entry_t *)
                                                       malloc(sizeof(struct aodvv2_routing_entry_t));
        memset(tmp_rt_entry, 0, sizeof(*tmp_rt_entry));

        routingtable_fill_routing_entry_t_rrep(&packet_data, tmp_rt_entry);
        routingtable_add_entry(tmp_rt_entry);

        /* add entry to FIB */
        fib_add_entry(aodvv2_if_id, tmp_rt_entry->addr._addr, sizeof(ipv6_addr_t), 0,
                      tmp_rt_entry->nextHopAddr._addr, sizeof(ipv6_addr_t), 0, aodvv2_validity_t);

        free(tmp_rt_entry);
    }
    else {
        if (!routingtable_offers_improvement(rt_entry, &packet_data.targNode)) {
            DEBUG("\tPacket offers no improvement over known route. Dropping Packet.\n");
            return RFC5444_DROP_PACKET;
        }
        /* The incoming routing information is better than existing routing
         * table information and SHOULD be used to improve the route table. */
        VDEBUG("\tUpdating Routing Table entry...\n");
        routingtable_fill_routing_entry_t_rrep(&packet_data, rt_entry);

        /* update the FIB */
        fib_update_entry(rt_entry->addr._addr, sizeof(ipv6_addr_t), rt_entry->nextHopAddr._addr,
                         sizeof(ipv6_addr_t), 0, aodvv2_validity_t);
    }

    /* If HandlingRtr is RREQ_Gen then the RREP satisfies RREQ_Gen's
    earlier RREQ, and RREP processing is completed.  Any packets
    buffered for OrigNode should be transmitted. */
    if (clienttable_is_client(&packet_data.origNode.addr)) {
#if ENABLE_DEBUG
        static struct netaddr_str nbuf2;
#endif

        DEBUG("\t{%" PRIu32 ":%" PRIu32 "} %s:  This is my RREP (SeqNum: %d). We are done here, thanks %s!\n",
              now.seconds, now.microseconds, netaddr_to_string(&nbuf, &packet_data.origNode.addr),
              packet_data.origNode.seqnum, netaddr_to_string(&nbuf2, &packet_data.targNode.addr));
    }

    else {
        /* If HandlingRtr is not RREQ_Gen then the outgoing RREP is sent to the
         * Route.NextHopAddress for the RREP.AddrBlk[OrigNodeNdx]. */
        AODV_DEBUG("Not my RREP, passing it on to the next hop\n");
        aodv_send_rrep(&packet_data,
                       routingtable_get_next_hop(&packet_data.origNode.addr,packet_data.metricType));
    }
    return RFC5444_OKAY;
}
Example #29
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 #30
0
File: fib.c Project: JiapengLi/RIOT
/**
 * @brief convert given ms to a point in time from now on in the future
 * @param[in]  ms     the milliseconds to be converted
 * @param[out] timex  the converted point in time
 */
static void fib_ms_to_timex(uint32_t ms, timex_t *timex)
{
    vtimer_now(timex);
    timex->seconds += ms / 1000;
    timex->microseconds += (ms - timex->seconds * 1000) * 1000;
}