Ejemplo n.º 1
0
int main(void)
{
    hwtimer_init();

    struct bloom_t *bloom = bloom_new(1 << 12, 8, fnv_hash, sax_hash, sdbm_hash,
            djb2_hash, kr_hash, dek_hash, rotating_hash, one_at_a_time_hash);

    printf("Testing Bloom filter.\n\n");
    printf("m: %" PRIu32 " k: %" PRIu32 "\n\n", (uint32_t) bloom->m,
            (uint32_t) bloom->k);

    genrand_init(myseed);

    unsigned long t1 = hwtimer_now();
    for (int i = 0; i < lenB; i++) {
        buf_fill(buf, BUF_SIZE);
        buf[0] = MAGIC_B;
        bloom_add(bloom,
                  (uint8_t *) buf,
                  BUF_SIZE * sizeof(uint32_t)/ sizeof(uint8_t));
    }
    unsigned long t2 = hwtimer_now();
    printf("adding %d elements took %" PRIu32 "ms\n", lenB,
            (uint32_t) HWTIMER_TICKS_TO_US(t2-t1) / 1000);

    int in = 0;
    int not_in = 0;

    unsigned long t3 = hwtimer_now();
    for (int i = 0; i < lenA; i++) {
        buf_fill(buf, BUF_SIZE);
        buf[0] = MAGIC_A;

        if (bloom_check(bloom,
                        (uint8_t *) buf,
                        BUF_SIZE * sizeof(uint32_t) / sizeof(uint8_t))) {
            in++;
        } else {
            not_in++;
        }
    }
    unsigned long t4 = hwtimer_now();
    printf("checking %d elements took %" PRIu32 "ms\n", lenA,
            (uint32_t) HWTIMER_TICKS_TO_US(t4-t3) / 1000);

    printf("\n");
    printf("%d elements probably in the filter.\n", in);
    printf("%d elements not in the filter.\n", not_in);
    double false_positive_rate = (double) in / (double) lenA;
    printf("%f false positive rate.\n", false_positive_rate);

    bloom_del(bloom);
    printf("\nAll done!\n");
    return 0;
}
Ejemplo n.º 2
0
void print_packet(radio_packet_t *p)
#endif
{
    volatile uint8_t i, j, k;

    if (p) {
        printf("len 0x%02x lqi 0x%02x rx_time 0x%08lx", p->length, p->lqi, hwtimer_now());

        for (j = 0, k = 0; j <= ((p->length) / PER_ROW); j++) {
            printf("\n\r");

            for (i = 0; i < PER_ROW; i++, k++) {
                if (k >= p->length) {
                    printf("\n\r");
                    return;
                }

#if MODULE_AT86RF231 || MODULE_CC2420 || MODULE_MC1322X
                printf("%02x ", p->frame.payload[j * PER_ROW + i]);
#else
                printf("%02x ", p->data[j * PER_ROW + i]);
#endif
            }
        }
    }

    printf("\n\r");
    return;
}
Ejemplo n.º 3
0
/**
 * @brief Prints a list of running threads including stack usage to stdout.
 */
void thread_print_all(void)
{
    extern unsigned long hwtimer_now(void);
    const char queued_name[] = {'_', 'Q'};
    int i;
    int overall_stacksz = 0;

    printf("\tpid | %-21s| %-9sQ | pri | stack ( used) location   | runtime | switches \n", "name", "state");
    for( i = 0; i < MAXTHREADS; i++ ) {
        tcb_t* p = (tcb_t*)sched_threads[i];

        if( p != NULL ) {
            int state = p->status;                                          // copy state
            int statebit = number_of_highest_bit(state >> 1);               // get state index
            const char* sname = state_names[statebit];                      // get state name
            const char* queued = queued_name + (state & BIT0);              // get queued flag
            int stacksz = p->stack_size;                                    // get max used stack
            double runtime = 0/0.0;
            int switches = -1;
#if SCHEDSTATISTICS
            runtime =  pidlist[i].runtime / (double) hwtimer_now() * 100;
            switches = pidlist[i].schedules;
#endif
            overall_stacksz += stacksz;
            stacksz -= thread_measure_stack_usage(p->stack_start);
            printf("\t%3u | %-21s| %-8s %.1s | %3i | %5i (%5i) %p | %6.3f%% | %8i\n",
                    p->pid, p->name, sname, queued, p->priority, p->stack_size, stacksz, p->stack_start, runtime, switches);
        }
    }
Ejemplo n.º 4
0
int main(void)
{
    shell_t shell;
    kernel_pid_t mac = basic_mac_init(mac_stack, BASIC_MAC_CONTROL_STACKSIZE,
                                      PRIORITY_MAIN - 1, CREATE_STACKTEST,
                                      "basic_mac_default", NETDEV_DEFAULT);
    sixlowpan = sixlowpan_init(mac, sixlowpan_stack, SIXLOWPAN_CONTROL_STACKSIZE,
                               PRIORITY_MAIN - 1, CREATE_STACKTEST,
                               "basic_mac_default");

    genrand_init(hwtimer_now());
    data_value = (uint8_t)(genrand_uint32() % 256);

    netapi_set_option(sixlowpan, NETAPI_CONF_SRC_LEN, &src_len, sizeof(size_t));
    netapi_get_option(sixlowpan, NETAPI_CONF_ADDRESS, &src, sizeof(uint16_t));

    (void) posix_open(uart0_handler_pid, 0);

    (void) puts("Welcome to RIOT!");

    shell_init(&shell, shell_command, UART0_BUFSIZE, uart0_readc, uart0_putc);

    shell_run(&shell);
    return 0;
}
Ejemplo n.º 5
0
void vtimer_now(timex_t *out)
{
    uint32_t us = HWTIMER_TICKS_TO_US(hwtimer_now()) - longterm_tick_start;
    static const uint32_t us_per_s = 1000ul * 1000ul;

    out->seconds = longterm_tick_timer.absolute.seconds + us / us_per_s;
    out->microseconds = us % us_per_s;
}
Ejemplo n.º 6
0
void vtimer_now(timex_t *out)
{
    uint32_t us = HWTIMER_TICKS_TO_US(hwtimer_now() - longterm_tick_start);
    uint32_t us_per_s = 1000ul * 1000ul;

    out->seconds = seconds + us / us_per_s;
    out->microseconds = us % us_per_s;
}
Ejemplo n.º 7
0
/**
 * @brief   Make a raw dump of the given packet contents
 */
void dump_pkt(ng_pktsnip_t *pkt)
{
    ng_pktsnip_t *snip = pkt;

    printf("rftest-rx --- len 0x%02x lqi 0x%02x rx_time 0x%08lx\n\n",
           ng_pkt_len(pkt), 0, hwtimer_now());

    while (snip) {
        for (size_t i = 0; i < snip->size; i++) {
            printf("0x%02x ", ((uint8_t *)(snip->data))[i]);
        }
        snip = snip->next;
    }
    puts("\n");

    ng_pktbuf_release(pkt);
}
Ejemplo n.º 8
0
static int update_shortterm(void)
{
    if (shortterm_priority_queue_root.first == NULL) {
        /* there is no vtimer to schedule, queue is empty */
        DEBUG("update_shortterm: shortterm_priority_queue_root.next == NULL - dont know what to do here\n");
        return 0;
    }
    if (hwtimer_id != -1) {
        /* there is a running hwtimer for us */
        if (hwtimer_next_absolute != shortterm_priority_queue_root.first->priority) {
            /* the next timer in the vtimer queue is not the next hwtimer */
            /* we have to remove the running hwtimer (and schedule a new one) */
            hwtimer_remove(hwtimer_id);
        }
        else {
            /* the next vtimer is the next hwtimer, nothing to do */
            return 0;
        }
    }

    /* short term part of the next vtimer */
    hwtimer_next_absolute = shortterm_priority_queue_root.first->priority;

    uint32_t next = hwtimer_next_absolute;

    /* current short term time */
    uint32_t now = HWTIMER_TICKS_TO_US(hwtimer_now());

    /* make sure the longterm_tick_timer does not get truncated */
    if (node_get_timer(shortterm_priority_queue_root.first)->action != vtimer_callback_tick) {
        /* the next vtimer to schedule is the long term tick */
        /* it has a shortterm offset of longterm_tick_start */
        next += longterm_tick_start;
    }

    if((next -  HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now) > MICROSECONDS_PER_TICK ) {
        DEBUG("truncating next (next -  HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now): %lu\n", (next -  HWTIMER_TICKS_TO_US(VTIMER_THRESHOLD) - now));
        next = now +  HWTIMER_TICKS_TO_US(VTIMER_BACKOFF);
    }

    DEBUG("update_shortterm: Set hwtimer to %" PRIu32 " (now=%lu)\n", next, HWTIMER_TICKS_TO_US(hwtimer_now()));
    hwtimer_id = hwtimer_set_absolute(HWTIMER_TICKS(next), vtimer_callback, NULL);

    return 0;
}
Ejemplo n.º 9
0
static int update_shortterm() {
    if (hwtimer_id != -1) {
        if (hwtimer_next_absolute != shortterm_queue_root.next->priority) {
            hwtimer_remove(hwtimer_id);
        } else {
            return 0;
        }
    }

    hwtimer_next_absolute = shortterm_queue_root.next->priority;

    unsigned int next = hwtimer_next_absolute + longterm_tick_start;
    unsigned int now = hwtimer_now();

    if((next - VTIMER_THRESHOLD - now) > MICROSECONDS_PER_TICK ) {
        next = now + VTIMER_BACKOFF;
    }
    
    hwtimer_id = hwtimer_set_absolute(next, vtimer_callback, NULL);

    DEBUG("update_shortterm: Set hwtimer to %lu (now=%lu)\n", hwtimer_next_absolute + longterm_tick_start, hwtimer_now());
    return 0;
}
Ejemplo n.º 10
0
void sched_run() {
    sched_context_switch_request = 0;

    tcb_t *my_active_thread = (tcb_t*)active_thread;

    if (my_active_thread) {
        if( my_active_thread->status ==  STATUS_RUNNING) {
            my_active_thread->status =  STATUS_PENDING;
        }

#ifdef SCHED_TEST_STACK
        if (*((unsigned int*)my_active_thread->stack_start) != (unsigned int) my_active_thread->stack_start) {
            printf("scheduler(): stack overflow detected, task=%s pid=%u\n", my_active_thread->name, my_active_thread->pid);
        }
#endif

    }

#if SCHEDSTATISTICS
    extern unsigned long hwtimer_now(void);
    unsigned int time = hwtimer_now();
    if (my_active_thread && (pidlist[my_active_thread->pid].laststart)) {
        pidlist[my_active_thread->pid].runtime += time - pidlist[my_active_thread->pid].laststart;
    }
#endif

    DEBUG("\nscheduler: previous task: %s\n", ( my_active_thread == NULL) ? "none" : my_active_thread->name );

    if (num_tasks == 0) {
        DEBUG("scheduler: no tasks left.\n");
        while(! num_tasks);
        DEBUG("scheduler: new task created.\n");
    }

    my_active_thread = NULL;
    while(! my_active_thread) {

        //        for (int i = 0; i < SCHED_PRIO_LEVELS; i++) { /* TODO: introduce bitfield cache */
        //            if (runqueues[i]) {
        int nextrq = number_of_lowest_bit(runqueue_bitcache);
        clist_node_t next = *(runqueues[nextrq]);
        DEBUG("scheduler: first in queue: %s\n", ((tcb_t*)next.data)->name);
        clist_advance(&(runqueues[nextrq]));
        my_active_thread = (tcb_t*)next.data;
        thread_pid = (volatile int) my_active_thread->pid;
#if SCHEDSTATISTICS
        pidlist[my_active_thread->pid].laststart = time;
        pidlist[my_active_thread->pid].schedules ++;
#endif
        //                break;
        //            }
        //        }
        if (active_thread->pid != last_pid) {
            last_pid = active_thread->pid;
        }
    }

    DEBUG("scheduler: next task: %s\n", my_active_thread->name);

    if (my_active_thread != active_thread) {
        if (active_thread != NULL) { //TODO: necessary?
            if (active_thread->status ==  STATUS_RUNNING) {
                active_thread->status =  STATUS_PENDING ;
            }
        }
        sched_set_status((tcb_t*)my_active_thread,  STATUS_RUNNING);
    }

    active_thread = (volatile tcb_t*) my_active_thread;

    DEBUG("scheduler: done.\n");
}
Ejemplo n.º 11
0
void sched_run()
{
    sched_context_switch_request = 0;

    tcb_t *my_active_thread = (tcb_t *)active_thread;

    if (my_active_thread) {
        if (my_active_thread->status == STATUS_RUNNING) {
            my_active_thread->status = STATUS_PENDING;
        }

#ifdef SCHED_TEST_STACK

        if (*((unsigned int *)my_active_thread->stack_start) != (unsigned int) my_active_thread->stack_start) {
            printf("scheduler(): stack overflow detected, task=%s pid=%u\n", my_active_thread->name, my_active_thread->pid);
        }

#endif

    }

#ifdef SCHEDSTATISTICS
    unsigned long time = hwtimer_now();

    if (my_active_thread && (pidlist[my_active_thread->pid].laststart)) {
        pidlist[my_active_thread->pid].runtime_ticks += time - pidlist[my_active_thread->pid].laststart;
    }

#endif

    DEBUG("\nscheduler: previous task: %s\n", (my_active_thread == NULL) ? "none" : my_active_thread->name);

    if (num_tasks == 0) {
        DEBUG("scheduler: no tasks left.\n");

        while (!num_tasks) {
            /* loop until a new task arrives */
            ;
        }

        DEBUG("scheduler: new task created.\n");
    }

    my_active_thread = NULL;

    while (!my_active_thread) {
        int nextrq = number_of_lowest_bit(runqueue_bitcache);
        clist_node_t next = *(runqueues[nextrq]);
        DEBUG("scheduler: first in queue: %s\n", ((tcb_t *)next.data)->name);
        clist_advance(&(runqueues[nextrq]));
        my_active_thread = (tcb_t *)next.data;
        thread_pid = (volatile int) my_active_thread->pid;
#if SCHEDSTATISTICS
        pidlist[my_active_thread->pid].laststart = time;
        pidlist[my_active_thread->pid].schedules++;
        if ((sched_cb) && (my_active_thread->pid != last_pid)) {
            sched_cb(hwtimer_now(), my_active_thread->pid);
            last_pid = my_active_thread->pid;
        }
#endif
#ifdef MODULE_NSS

        if (active_thread && active_thread->pid != last_pid) {
            last_pid = active_thread->pid;
        }

#endif
    }

    DEBUG("scheduler: next task: %s\n", my_active_thread->name);

    if (my_active_thread != active_thread) {
        if (active_thread != NULL) {  /* TODO: necessary? */
            if (active_thread->status ==  STATUS_RUNNING) {
                active_thread->status =  STATUS_PENDING ;
            }
        }

        sched_set_status((tcb_t *)my_active_thread,  STATUS_RUNNING);
    }

    active_thread = (volatile tcb_t *) my_active_thread;

    DEBUG("scheduler: done.\n");
}
Ejemplo n.º 12
0
Archivo: tap.c Proyecto: 4120976/RIOT
void _native_handle_tap_input(void)
{
    int nread;
    union eth_frame frame;
    radio_packet_t p;

    DEBUG("_native_handle_tap_input\n");

    /* TODO: check whether this is an input or an output event
       TODO: refactor this into general io-signal multiplexer */

    nread = real_read(_native_tap_fd, &frame, sizeof(union eth_frame));
    DEBUG("_native_handle_tap_input - read %d bytes\n", nread);
    if (nread > 0) {
        if (ntohs(frame.field.header.ether_type) == NATIVE_ETH_PROTO) {
            nread = nread - ETHER_HDR_LEN;
            if ((nread - 1) <= 0) {
                DEBUG("_native_handle_tap_input: no payload\n");
            }
            else {
                unsigned long t = hwtimer_now();
                p.processing = 0;
                p.src = ntohs(frame.field.payload.nn_header.src);
                p.dst = ntohs(frame.field.payload.nn_header.dst);
                p.rssi = 0;
                p.lqi = 0;
                p.toa.seconds = HWTIMER_TICKS_TO_US(t)/1000000;
                p.toa.microseconds = HWTIMER_TICKS_TO_US(t)%1000000;
                /* XXX: check overflow */
                p.length = ntohs(frame.field.payload.nn_header.length);
                p.data = frame.field.payload.data;
                if (p.length > (nread - sizeof(struct nativenet_header))) {
                    warnx("_native_handle_tap_input: packet with malicious length field received, discarding");
                }
                else {
                    DEBUG("_native_handle_tap_input: received packet of length %" PRIu16 " for %" PRIu16 " from %" PRIu16 "\n", p.length, p.dst, p.src);
                    _nativenet_handle_packet(&p);
                }
            }
        }
        else {
            DEBUG("ignoring non-native frame\n");
        }

        /* work around lost signals */
        fd_set rfds;
        struct timeval t;
        memset(&t, 0, sizeof(t));
        FD_ZERO(&rfds);
        FD_SET(_native_tap_fd, &rfds);

        _native_in_syscall++; // no switching here
        if (select(_native_tap_fd +1, &rfds, NULL, NULL, &t) == 1) {
            int sig = SIGIO;
            extern int _sig_pipefd[2];
            extern ssize_t (*real_write)(int fd, const void *buf, size_t count);
            real_write(_sig_pipefd[1], &sig, sizeof(int));
            _native_sigpend++;
            DEBUG("_native_handle_tap_input: sigpend++\n");
        }
        else {
            DEBUG("_native_handle_tap_input: no more pending tap data\n");
#ifdef __MACH__
            kill(sigio_child_pid, SIGCONT);
#endif
        }
        _native_in_syscall--;
    }
    else if (nread == -1) {
        if ((errno == EAGAIN ) || (errno == EWOULDBLOCK)) {
            //warn("read");
        }
        else {
            err(EXIT_FAILURE, "_native_handle_tap_input: read");
        }
    }
    else {
        errx(EXIT_FAILURE, "internal error _native_handle_tap_input");
    }
}
Ejemplo n.º 13
0
static bool send_burst(cc1100_packet_layer0_t *packet, uint8_t retries, uint8_t rtc)
{
    int i;
    radio_state = RADIO_SEND_BURST;
    rflags.LL_ACK = false;

    for (i = 1; i <= cc1100_burst_count; i++) {
        /*
         * Number of bytes to send is:
         * length of phy payload (packet->length)
         * + size of length field (1 byte)
         */
        extern unsigned long hwtimer_now(void);
        timer_tick_t t = hwtimer_now() + RTIMER_TICKS(T_PACKET_INTERVAL);
        cc1100_send_raw((uint8_t *)packet, packet->length + 1);	/* RX -> TX (9.6 us) */

        cc1100_statistic.raw_packets_out++;

        /* Delay until predefined "send" interval has passed */
        timer_tick_t now = hwtimer_now();

        if (t > now) {
            hwtimer_wait(t - now);
        }

        /**
         * After sending the packet the CC1100 goes automatically
         * into RX mode (21.5 us) (listening for an ACK).
         * Do not interrupt burst if send to broadcast address (a node may
         * have the broadcast address at startup and would stop the burst
         * by sending an ACK).
         */
        if (rflags.LL_ACK && packet->address != CC1100_BROADCAST_ADDRESS) {
            cc1100_statistic.raw_packets_out_acked += i;
            break;
        }
    }

    /* No link level ACK -> do retry if retry counter greater zero
     * Note: Event broadcast packets can be sent repeatedly if in
     *       constant RX mode. In WOR mode it is not necessary, so
     *       set retry count to zero.*/
    if (!rflags.LL_ACK && retries > 0) {
        return send_burst(packet, retries - 1, rtc + 1);
    }

    /* Store number of transmission retries */
    rflags.RETC = rtc;
    rflags.RPS = rtc * cc1100_burst_count + i;

    if (i > cc1100_burst_count) {
        rflags.RPS--;
    }

    rflags.TX = false;

    /* Go to mode after TX (CONST_RX -> RX, WOR -> WOR) */
    cc1100_go_after_tx();

    /* Burst from any other node is definitely over */
    last_seq_num = 0;

    if (packet->address != CC1100_BROADCAST_ADDRESS && !rflags.LL_ACK) {
        return false;
    }

    return true;
}
Ejemplo n.º 14
0
Archivo: ps.c Proyecto: A-L-E-X/RIOT
/**
 * @brief Prints a list of running threads including stack usage to stdout.
 */
void thread_print_all(void)
{
    const char queued_name[] = {'_', 'Q'};
#ifdef DEVELHELP
    int overall_stacksz = 0, overall_used = 0;
#endif

    printf("\tpid | %-21s| %-9sQ | pri | "
#ifdef DEVELHELP
           "stack ( used) "
#endif
           "location"
#if SCHEDSTATISTICS
           "  | runtime | switches"
#endif
           "\n"
           , "name", "state");

    for (kernel_pid_t i = KERNEL_PID_FIRST; i <= KERNEL_PID_LAST; i++) {
        tcb_t *p = (tcb_t *)sched_threads[i];

        if (p != NULL) {
            int state = p->status;                                                 /* copy state */
            const char *sname = state_names[state];                                /* get state name */
            const char *queued = &queued_name[(int)(state >= STATUS_ON_RUNQUEUE)]; /* get queued flag */
#ifdef DEVELHELP
            int stacksz = p->stack_size;                                           /* get stack size */
            overall_stacksz += stacksz;
            stacksz -= thread_measure_stack_free(p->stack_start);
            overall_used += stacksz;
#endif
#if SCHEDSTATISTICS
            double runtime_ticks =  sched_pidlist[i].runtime_ticks / (double) hwtimer_now() * 100;
            int switches = sched_pidlist[i].schedules;
#endif
            printf("\t%3u | %-21s| %-8s %.1s | %3i | "
#ifdef DEVELHELP
                   "%5i (%5i) "
#endif
                   "%p"
#if SCHEDSTATISTICS
                   " | %6.3f%% |  %8d"
#endif
                   "\n",
                   p->pid, p->name, sname, queued, p->priority,
#ifdef DEVELHELP
                   p->stack_size, stacksz,
#endif
                   p->stack_start
#if SCHEDSTATISTICS
                   , runtime_ticks, switches
#endif
                  );
        }
    }

#ifdef DEVELHELP
    printf("\t%5s %-21s|%13s%6s %5i (%5i)\n", "|", "SUM", "|", "|",
           overall_stacksz, overall_used);
#endif
}
Ejemplo n.º 15
0
int32_t destiny_socket_send(int s, const void *buf, uint32_t len, int flags)
{
    /* Variables */
    msg_t recv_msg;
    int32_t sent_bytes = 0, total_sent_bytes = 0;
    socket_internal_t *current_int_tcp_socket;
    socket_t *current_tcp_socket;
    uint8_t send_buffer[BUFFER_SIZE];
    memset(send_buffer, 0, 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 and is TCP socket */
    if (!is_tcp_socket(s)) {
        return -1;
    }

    current_int_tcp_socket = get_socket(s);
    current_tcp_socket = &current_int_tcp_socket->socket_values;

    /* Check for ESTABLISHED STATE */
    if (current_tcp_socket->tcp_control.state != ESTABLISHED) {
        return -1;
    }

    /* Add thread PID */
    current_int_tcp_socket->send_pid = thread_getpid();

    recv_msg.type = UNDEFINED;

    while (1) {
        current_tcp_socket->tcp_control.no_of_retries = 0;

#ifdef TCP_HC
        current_tcp_socket->tcp_control.tcp_context.hc_type = COMPRESSED_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) - 1);
#endif

        while (recv_msg.type != TCP_ACK) {
            /* Add packet data */
            if (current_tcp_socket->tcp_control.send_wnd >
                current_tcp_socket->tcp_control.mss) {
                /* Window size > Maximum Segment Size */
                if ((len - total_sent_bytes) > current_tcp_socket->tcp_control.mss) {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], buf,
                           current_tcp_socket->tcp_control.mss);
                    sent_bytes = current_tcp_socket->tcp_control.mss;
                    total_sent_bytes += sent_bytes;
                }
                else {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN],
                           buf + total_sent_bytes, len - total_sent_bytes);
                    sent_bytes = len - total_sent_bytes;
                    total_sent_bytes = len;
                }
            }
            else {
                /* Window size <= Maximum Segment Size */
                if ((len - total_sent_bytes) > current_tcp_socket->tcp_control.send_wnd) {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN], buf,
                           current_tcp_socket->tcp_control.send_wnd);
                    sent_bytes = current_tcp_socket->tcp_control.send_wnd;
                    total_sent_bytes += sent_bytes;
                }
                else {
                    memcpy(&send_buffer[IPV6_HDR_LEN + TCP_HDR_LEN],
                           buf + total_sent_bytes, len - total_sent_bytes);
                    sent_bytes = len - total_sent_bytes;
                    total_sent_bytes = len;
                }
            }

            current_tcp_socket->tcp_control.send_nxt += sent_bytes;
            current_tcp_socket->tcp_control.send_wnd -= sent_bytes;

            if (send_tcp(current_int_tcp_socket, current_tcp_packet,
                         temp_ipv6_header, 0, sent_bytes) != 1) {
                /* Error while sending tcp data */
                current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
                current_tcp_socket->tcp_control.send_wnd += sent_bytes;
#ifdef TCP_HC
                memcpy(&current_tcp_socket->tcp_control.tcp_context,
                       &saved_tcp_context, sizeof(tcp_hc_context_t));
                current_tcp_socket->tcp_control.tcp_context.hc_type =
                    COMPRESSED_HEADER;
#endif
                printf("Error while sending, returning to application thread!\n");
                return -1;
            }

            /* Remember current time */
            current_tcp_socket->tcp_control.last_packet_time.microseconds =
                hwtimer_now();
            net_msg_receive(&recv_msg);

            switch (recv_msg.type) {
                case TCP_ACK: {
                    if (current_tcp_socket->tcp_control.no_of_retries == 0) {
                        calculate_rto(&current_tcp_socket->tcp_control,
                                      hwtimer_now());
                    }

                    tcp_hdr_t *tcp_header = ((tcp_hdr_t *)(recv_msg.content.ptr));

                    if ((current_tcp_socket->tcp_control.send_nxt ==
                         tcp_header->ack_nr) && (total_sent_bytes == len)) {
                        current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_wnd = tcp_header->window;
                        /* Got ACK for every sent byte */
#ifdef TCP_HC
                        current_tcp_socket->tcp_control.tcp_context.hc_type =
                            COMPRESSED_HEADER;
#endif
                        return sent_bytes;
                    }
                    else if ((current_tcp_socket->tcp_control.send_nxt ==
                              tcp_header->ack_nr) && (total_sent_bytes != len)) {
                        current_tcp_socket->tcp_control.send_una = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_nxt = tcp_header->ack_nr;
                        current_tcp_socket->tcp_control.send_wnd = tcp_header->window;
                        /* Got ACK for every sent byte */
#ifdef TCP_HC
                        current_tcp_socket->tcp_control.tcp_context.hc_type =
                            COMPRESSED_HEADER;
#endif
                        break;
                    }

                    /* else {
                     *     TODO: If window size > MSS, ACK was valid only for
                     *     a few segments, handle retransmit of missing
                     *     segments
                     *	break;
                     * } */
                    break;
                }

                case TCP_RETRY: {
                    current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
                    current_tcp_socket->tcp_control.send_wnd += sent_bytes;
                    total_sent_bytes -= sent_bytes;
#ifdef TCP_HC
                    memcpy(&current_tcp_socket->tcp_control.tcp_context,
                           $&saved_tcp_context, sizeof(tcp_hc_context_t));
                    current_tcp_socket->tcp_control.tcp_context.hc_type =
                        MOSTLY_COMPRESSED_HEADER;
#endif
                    break;
                }

                case TCP_TIMEOUT: {
                    current_tcp_socket->tcp_control.send_nxt -= sent_bytes;
                    current_tcp_socket->tcp_control.send_wnd += sent_bytes;
#ifdef TCP_HC
                    memcpy(&current_tcp_socket->tcp_control.tcp_context,
                           &saved_tcp_context, sizeof(tcp_hc_context_t));
                    current_tcp_socket->tcp_control.tcp_context.hc_type =
                        COMPRESSED_HEADER;
#endif
                    return -1;
                    break;
                }
            }
        }
    }

    return sent_bytes;
}
Ejemplo n.º 16
0
timex_t vtimer_now() {
    timex_t t = timex_set(seconds, hwtimer_now()-longterm_tick_start);
    return t;
}