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; }
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; }
/** * @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); } }
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; }
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; }
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; }
/** * @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); }
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; }
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; }
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"); }
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"); }
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"); } }
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; }
/** * @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 }
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 = ¤t_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, ¤t_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(¤t_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(¤t_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(¤t_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(¤t_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; }
timex_t vtimer_now() { timex_t t = timex_set(seconds, hwtimer_now()-longterm_tick_start); return t; }