OSStatus platform_mcu_powersave_init(void) { #ifndef MICO_DISABLE_MCU_POWERSAVE #error Not working currently, uncomment MICO_DISABLE_MCU_POWERSAVE in platform_config.h /* Initialise all pins to be input pull-up to save power */ ioport_enable_port( IOPORT_PIOA, 0xffffffffU ); ioport_set_port_mode( IOPORT_PIOA, 0xffffffffU, IOPORT_MODE_PULLUP ); ioport_set_port_dir( IOPORT_PIOA, 0xffffffffU, IOPORT_DIR_INPUT ); ioport_enable_port( IOPORT_PIOB, 0xffffffffU ); ioport_set_port_mode( IOPORT_PIOB, 0xffffffffU, IOPORT_MODE_PULLUP ); ioport_set_port_dir( IOPORT_PIOB, 0xffffffffU, IOPORT_DIR_INPUT ); NVIC_DisableIRQ( RTT_IRQn ); NVIC_ClearPendingIRQ( RTT_IRQn ); NVIC_EnableIRQ( RTT_IRQn ); pmc_set_fast_startup_input( PMC_FSMR_RTTAL ); rtt_init( RTT, RTT_CLOCK_PRESCALER ); rtt_write_alarm_time( RTT, 64000 ); #endif /* MICO_DISABLE_MCU_POWERSAVE */ return kNoErr; }
ssize_t dg_send_recv(int fd, const void *outbuff, size_t outbytes, void *inbuff, size_t inbytes, const SA *destaddr, socklen_t destlen) { ssize_t n; struct iovec iovsend[2], iovrecv[2]; if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flags = 1; } sendhdr.seq++; msgsend.msg_name = destaddr; msgsend.msg_namelen = destlen; msgsend.msg_iov = iovsend; msgsend.msg_iovlen = 2; iovsend[0].iov_base = &sendhdr; iovsend[0].iov_len = sizeof(struct hdr); iovsend[1].iov_base = outbuff; iovsend[1].iov_len = outbytes; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; Signal(SIGALRM, sig_alrm); rtt_newpack(&rttinfo); /* initialize for this packet */ sendagain: sendhdr.ts = rtt_ts(&rttinfo); Sendmsg(fd, &msgsend, 0); alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */ if (sigsetjmp(jmpbuf, 1) != 0) { if (rtt_timeout(&rttinfo) < 0) { err_msg("dg_send_recv: no response from server, giving up"); rtt_init = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; return -1; } goto sendagain; } do { n = Recvmsg(fd, &msgrecv, 0); } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq); alarm(0); /* stop SIGALRM timer. */ /* calculate & store new RTT estimator value. */ rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); return (n - sizeof(struct hdr)); /* return size of received datagram. */ }
/* rtt_main tests for rtt*/ int rtt_main(){ struct sigaction sa = {0}; struct itimerval timer; int err; suseconds_t op1 = 1, op2 = 6; suseconds_t res = op1 - op2; printf("suseconds_t calc: %ld\n", res); printf("sizeof(suseconds_t): %ld\n", sizeof(suseconds_t)); /* Install timer_handler as the signal handler for SIGVTALRM. */ sa.sa_handler = &timer_handler; sigaction (SIGALRM, &sa, NULL); /* Configure the timer to expire after 250 msec... */ timer.it_value.tv_sec = 0; timer.it_value.tv_usec = 750000; /* ... and every never after that. */ timer.it_interval = (struct timeval){0, 750000}; rtt_init(&rttinfo); setitimer(ITIMER_REAL, &timer, NULL); /* Do busy work. */ while (1){ err = sleep(5); printf("secs left to sleep %d\n", err); } return 0; }
int infra_rtt_update(struct infra_cache* infra, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* nm, size_t nmlen, int qtype, int roundtrip, int orig_rtt, time_t timenow) { struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, nm, nmlen, 1); struct infra_data* data; int needtoinsert = 0; int rto = 1; if(!e) { if(!(e = new_entry(infra, addr, addrlen, nm, nmlen, timenow))) return 0; needtoinsert = 1; } else if(((struct infra_data*)e->data)->ttl < timenow) { data_entry_init(infra, e, timenow); } /* have an entry, update the rtt */ data = (struct infra_data*)e->data; if(roundtrip == -1) { rtt_lost(&data->rtt, orig_rtt); if(qtype == LDNS_RR_TYPE_A) { if(data->timeout_A < TIMEOUT_COUNT_MAX) data->timeout_A++; } else if(qtype == LDNS_RR_TYPE_AAAA) { if(data->timeout_AAAA < TIMEOUT_COUNT_MAX) data->timeout_AAAA++; } else { if(data->timeout_other < TIMEOUT_COUNT_MAX) data->timeout_other++; } } else { /* if we got a reply, but the old timeout was above server * selection height, delete the timeout so the server is * fully available again */ if(rtt_unclamped(&data->rtt) >= USEFUL_SERVER_TOP_TIMEOUT) rtt_init(&data->rtt); rtt_update(&data->rtt, roundtrip); data->probedelay = 0; if(qtype == LDNS_RR_TYPE_A) data->timeout_A = 0; else if(qtype == LDNS_RR_TYPE_AAAA) data->timeout_AAAA = 0; else data->timeout_other = 0; } if(data->rtt.rto > 0) rto = data->rtt.rto; if(needtoinsert) slabhash_insert(infra->hosts, e->hash, e, e->data, NULL); else { lock_rw_unlock(&e->lock); } return rto; }
struct hdr cli_recv(int fd, void *inbuff, size_t inbytes) { ssize_t n; struct iovec iovrecv[2]; struct rtt_info rttinfo; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; rttinfo.rtt_rto = CLI_TIMEOUT; //8 sec time out if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } Signal(SIGALRM, sig_alrm); rtt_newpack(&rttinfo); /* initialize for this packet */ alarm(rtt_start(&rttinfo)/1000); /* calc timeout value & start timer */ //#ifdef RTT_DEBUG rtt_debug(&rttinfo); //#endif if (sigsetjmp(jmpbuf, 1) != 0) { err_msg("cli_recv: no response from server, giving up"); rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; err_sys("[ERROR]: Timeout"); return recvhdr; } n = Recvmsg(fd, &msgrecv, 0); if (n < sizeof(struct hdr)){ err_sys("[ERROR]: Received packet incomplete"); } printf("Length: %d\n", (int)n); //printf("BUFFER: %s\n", (char *)iovrecv[1].iov_base); printf("SEQ NUM: %u\n", recvhdr.seq); printf("IS FIN: %u\n", recvhdr.fin); alarm(0); /* stop SIGALRM timer */ return(recvhdr); /* return size of received datagram */ }
void board_init(void) { /* initialize the boards LEDs, this is done first for debugging purposes */ leds_init(); /* Initialize power control pins */ power_pins_init(); /* Turn on Vperiph for peripherals */ gpio_set(MULLE_POWER_VPERIPH); /* Turn on AVDD for reading voltages */ gpio_set(MULLE_POWER_AVDD); LED_RED_ON; /* Initialize RTC oscillator as early as possible since we are using it as a * base clock for the FLL. * It takes a while to stabilize the oscillator, therefore we do this as * soon as possible during boot in order to let it stabilize while other * stuff is initializing. */ /* If the clock is not stable then the UART will have the wrong baud rate * for debug prints as well */ rtt_init(); /* Set up clocks */ set_safe_clock_dividers(); set_fll_source(); kinetis_mcg_set_mode(KINETIS_MCG_FEE); /* At this point we need to wait for 1 ms until the clock is stable. * Since the clock is not yet stable we can only guess how long we must * wait. I have tried to make this as short as possible but still being able * to read the initialization messages written on the UART. * (If the clock is not stable all UART output is garbled until it has * stabilized) */ for (int i = 0; i < 100000; ++i) { asm volatile("nop\n"); } /* Update SystemCoreClock global var */ SystemCoreClockUpdate(); /* initialize the CPU */ cpu_init(); }
/** * \brief RTT configuration function. * * Configures the RTT to generate a one second tick, which triggers * the RTT alarms interrupt. */ static void gpbr_test_configure_rtt(void) { uint32_t ul_previous_time; /* Configure RTT for a 1 second tick interrupt */ rtt_init(RTT, 32768); ul_previous_time = rtt_read_timer_value(RTT); while (ul_previous_time == rtt_read_timer_value(RTT)); /* Enable RTT alarms interrupt to return from backup mode */ NVIC_DisableIRQ(RTT_IRQn); NVIC_ClearPendingIRQ(RTT_IRQn); NVIC_SetPriority(RTT_IRQn, 0); NVIC_EnableIRQ(RTT_IRQn); rtt_enable_interrupt(RTT, RTT_MR_ALMIEN); }
static void _lwmac_init(gnrc_netif_t *netif) { netdev_t *dev; dev = netif->dev; dev->event_callback = _lwmac_event_cb; /* RTT is used for scheduling wakeup */ rtt_init(); /* Store pid globally, so that IRQ can use it to send msg */ lwmac_pid = netif->pid; /* Enable RX- and TX-started interrupts */ netopt_enable_t enable = NETOPT_ENABLE; dev->driver->set(dev, NETOPT_RX_START_IRQ, &enable, sizeof(enable)); dev->driver->set(dev, NETOPT_TX_START_IRQ, &enable, sizeof(enable)); dev->driver->set(dev, NETOPT_TX_END_IRQ, &enable, sizeof(enable)); uint16_t src_len = IEEE802154_LONG_ADDRESS_LEN; dev->driver->set(dev, NETOPT_SRC_LEN, &src_len, sizeof(src_len)); /* Get own address from netdev */ netif->l2addr_len = dev->driver->get(dev, NETOPT_ADDRESS_LONG, &netif->l2addr, IEEE802154_LONG_ADDRESS_LEN); /* Initialize broadcast sequence number. This at least differs from board * to board */ netif->mac.tx.bcast_seqnr = netif->l2addr[0]; /* Reset all timeouts just to be sure */ gnrc_lwmac_reset_timeouts(netif); /* Start duty cycling */ lwmac_set_state(netif, GNRC_LWMAC_START); #if (GNRC_LWMAC_ENABLE_DUTYCYLE_RECORD == 1) /* Start duty cycle recording */ netif->mac.lwmac.system_start_time_ticks = rtt_get_counter(); netif->mac.lwmac.last_radio_on_time_ticks = netif->mac.lwmac.system_start_time_ticks; netif->mac.lwmac.awake_duration_sum_ticks = 0; netif->mac.lwmac.lwmac_info |= GNRC_LWMAC_RADIO_IS_ON; #endif }
/** init the data elements */ static void data_entry_init(struct infra_cache* infra, struct lruhash_entry* e, time_t timenow) { struct infra_data* data = (struct infra_data*)e->data; data->ttl = timenow + infra->host_ttl; rtt_init(&data->rtt); data->edns_version = 0; data->edns_lame_known = 0; data->probedelay = 0; data->isdnsseclame = 0; data->rec_lame = 0; data->lame_type_A = 0; data->lame_other = 0; data->timeout_A = 0; data->timeout_AAAA = 0; data->timeout_other = 0; }
/** * \brief RTT configuration function. * * Configure the RTT to generate a one second tick, which triggers the RTTINC * interrupt. */ static void configure_rtt(void) { uint32_t ul_previous_time; /* Configure RTT for a 1 second tick interrupt */ #if SAM4N || SAM4S || SAM4E || SAM4C || SAM4CP || SAM4CM rtt_sel_source(RTT, false); #endif rtt_init(RTT, 32768); ul_previous_time = rtt_read_timer_value(RTT); while (ul_previous_time == rtt_read_timer_value(RTT)); /* Enable RTT interrupt */ NVIC_DisableIRQ(RTT_IRQn); NVIC_ClearPendingIRQ(RTT_IRQn); NVIC_SetPriority(RTT_IRQn, 0); NVIC_EnableIRQ(RTT_IRQn); rtt_enable_interrupt(RTT, RTT_MR_RTTINCIEN); }
int sendFileContents(int sockfd,int totalblocks, int windowsize){ //printf("%d\n", totalblocks); int first_unacknowledged_pos = 0; int pos_sent = -1; int prev_ack = 0; struct dgram recv_packet; int dups = 0; int recv_ack = -1; int retransmit = 0; int rtt_measured_packet = 0; uint32_t ts; int starttimer = 1; int hasBeenRtransmitted = 0; int slow_start = 1; Signal(SIGALRM, sig_alrm); if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } while(1){ retransmitpack: if(retransmit){ printf("RETRANSMIT PACKET: %d\n", first_unacknowledged_pos); hasBeenRtransmitted = 1; slow_start = 1; Sendto(sockfd, (void *)&fileContent[first_unacknowledged_pos], sizeof(struct dgram), 0, NULL, NULL); retransmit = 0; } if (sigsetjmp(jmpbuf, 1) != 0) { //rtt_debug(&rttinfo); if (rtt_timeout(&rttinfo) < 0) { err_msg("no response from client, giving up"); rttinit = 0; errno = ETIMEDOUT; return(-1); } retransmit = 1; goto retransmitpack; } int sent_packets = 0; while( (0 < slow_start) && (pos_sent < totalblocks-1) && (pos_sent + 1 < first_unacknowledged_pos + windowsize)){ if(starttimer){ rtt_newpack(&rttinfo); alarm(rtt_start(&rttinfo)); ts = rtt_ts(&rttinfo); starttimer = 0; rtt_measured_packet = fileContent[pos_sent+1].seqNum; hasBeenRtransmitted = 0; } Sendto(sockfd, (void *)&fileContent[pos_sent+1], sizeof(struct dgram), 0, NULL, NULL); printf("SEND PACKET: %d\n", pos_sent+1); pos_sent++; slow_start--; } if(Recvfrom(sockfd, &recv_packet, sizeof(struct dgram), 0, NULL, NULL) < 0){ err_msg("Receive error from client"); return -1; } else{ //rtt_debug(&rttinfo); windowsize = recv_packet.windowsize; if(recv_packet.ack == recv_ack){ dups++; } else { dups = 0; } recv_ack = recv_packet.ack; printf("RECEIVED ACK: %d\n", recv_ack); if(dups == 0){ alarm(0); if(!hasBeenRtransmitted && recv_ack > rtt_measured_packet) rtt_stop(&rttinfo, rtt_ts(&rttinfo) - ts); starttimer = 1; slow_start += 2*(recv_ack - prev_ack); } prev_ack = recv_ack; first_unacknowledged_pos = recv_packet.ack; retransmit = 0; if(dups >= MAXDUPS){ // retransmit first unack pos retransmit = 1; goto retransmitpack; } } if( first_unacknowledged_pos > 0 && fileContent[first_unacknowledged_pos-1].eof){ printf("SUCCESS: SENT ENTIRE FILE\n"); break; } } return totalblocks; }
int main(void) { enum sleepmgr_mode current_sleep_mode = SLEEPMGR_ACTIVE; /* * Initialize the synchronous clock system to the default configuration * set in conf_clock.h. * \note All non-essential peripheral clocks are initially disabled. */ sysclk_init(); /* * Initialize the resources used by this example to the default * configuration set in conf_board.h */ board_init(); /* * Turn the activity status LED on to inform the user that the device * is active. */ ioport_set_pin_level(LED_ACTIVITY_STATUS_PIN, LED_STATUS_ON); rtt_init(RTT, 32768); /* Enable RTT interrupt */ NVIC_DisableIRQ(RTT_IRQn); NVIC_ClearPendingIRQ(RTT_IRQn); NVIC_SetPriority(RTT_IRQn, 0); NVIC_EnableIRQ(RTT_IRQn); rtt_enable_interrupt(RTT, RTT_MR_ALMIEN); /* Set wakeup source to rtt_alarm */ pmc_set_fast_startup_input(PMC_FSMR_RTTAL); #if (!SAMG) supc_set_wakeup_mode(SUPC, SUPC_WUMR_RTTEN_ENABLE); #endif /* Initialize the sleep manager, lock initial mode. */ sleepmgr_init(); sleepmgr_lock_mode(current_sleep_mode); while (1) { rtt_write_alarm_time(RTT, rtt_read_timer_value(RTT) + SLEEP_TIME); /* * Turn the activity status LED off to inform the user that the * device is in a sleep mode. */ ioport_set_pin_level(LED_ACTIVITY_STATUS_PIN, LED_STATUS_OFF); /* * Go to sleep in the deepest allowed sleep mode (i.e. no * deeper than the currently locked sleep mode). */ sleepmgr_enter_sleep(); /* * Turn the activity status LED on to inform the user that the * device is active. */ ioport_set_pin_level(LED_ACTIVITY_STATUS_PIN, LED_STATUS_ON); /* Unlock the current sleep mode. */ sleepmgr_unlock_mode(current_sleep_mode); /* Add a 3s delay. */ delay_s(ACTIVE_TIME); /* Lock the next sleep mode. */ ++current_sleep_mode; if ((current_sleep_mode >= SLEEPMGR_NR_OF_MODES)) { current_sleep_mode = SLEEPMGR_ACTIVE; } sleepmgr_lock_mode(current_sleep_mode); } }
void mydg_echo( int sockfd, SA *servaddr, socklen_t servlen, SA *cliaddr , socklen_t clilen, char *filename ) { int n, persist_timer_flag=0; char mesg[MAXLINE]; socklen_t len, slen, slen1; int connfd; struct sockaddr_in ss, ss1; char IPServer[20], IPClient[20]; FILE *ifp; ssize_t bytes; char sendline[MAXLINE], recvline[MAXLINE + 1]; const int on=1; int onlength; onlength = sizeof( on ); printf( "\n******************* CHILD SERVER INITIATED *********************\n" ); //printf( "Creating Datagram...\n" ); if( ( connfd = socket( AF_INET, SOCK_DGRAM, 0 ) ) == NULL ) { printf( "socket error\n" ); exit(1); } getsockopt( sockfd, SOL_SOCKET, SO_DONTROUTE, &on, &onlength ) ; setsockopt( connfd, SOL_SOCKET, SO_DONTROUTE, &on, sizeof( on ) ); printf("Setting connection socket to SO_DONTROUTE..\n", on ); /* Bind to IPServer and EPHEMERAL PORT and return EPHEMERAL PORT */ bind( connfd, (SA *) servaddr, sizeof( struct sockaddr_in ) ); slen = sizeof( ss ); if( getsockname( connfd, (SA *)&ss, &slen ) < 0 ) { printf( "sockname error\n" ); exit(1); } printf("BOUND SOCKET ADDRESSES : %s\n", inet_ntop( AF_INET, &(ss.sin_addr), IPServer, MAXLINE )); printf( "SERVER PORT: %d\n", ntohl(ss.sin_port) ); /* Connect to IPClient */ if( connect( connfd, cliaddr, clilen ) < 0 ) { printf( "Error in connecting to server..\n" ); exit(1); } slen1 = sizeof( ss1 ); if( getpeername( connfd, (SA *)&ss1, &slen1 ) < 0 ) { printf( "peername error\n" ); exit(1); } inet_ntop( AF_INET, &(ss1.sin_addr), IPClient, MAXLINE ); printf( "DESTINATION ADDRESS : %s\n",IPClient ); printf( "DESTINATION PORT : %d\n", ss1.sin_port); sprintf( mesg, "%d\n", ss.sin_port ); printf("Sending the Ephemeral port number to client : %s..\n", mesg ); if( sendto( sockfd, mesg, sizeof( mesg ), 0, cliaddr, clilen) < 0 ) { printf("ERROR IN SENDTO : %d ",errno); exit(0); } printf( "Reading from the newly connected socket..\n" ); n = read( connfd, mesg, MAXLINE ); printf("Received data : %s\n",mesg ); if( n > 0 && strcmp( mesg, "ACK\n" ) == 0 ) { printf("ACK recieved..\n"); printf("Closing the listening socket on parent..\n"); close( sockfd ); } printf( "Reading file..\n" ); ifp = fopen( filename, "r" ); swnd1 = malloc( sender_window_size*sizeof(send_buffer) ); int i; for( i = 0 ; i<sender_window_size; i++) { swnd1[i].data[0] = '\0'; } int buffer_position, send_counter = 0, t, previous_na; memset( sendline, '\0', sizeof( sendline ) ); printf("Sending file to the client..\n"); int j, sender_usable_window, ack_recieved, closing_child=0 ; recv_advertisement = INT_MAX; ssthresh=recv_window_size; printf("\nSSTHRESH initiated to: %d\n",ssthresh); while(1) { if( cwnd > ( nt - na ) ) sender_usable_window = cwnd - ( nt - na ) ; else sender_usable_window = 0 ; printf("\nCongestion window : \nSender usable window : %d\nReciever window advertisement : %d\n", cwnd, sender_usable_window, recv_advertisement ); if(sender_usable_window==0) { printf( "\n*********************BUFFER FULL*************************\n"); } /* Check for if recv_adv == 0 i.e. no more packets to be sent. */ j = MIN( sender_usable_window , recv_advertisement ); if( (j == 0) || (send_counter == recv_advertisement) ) { while(1) { if( recv_advertisement == 0 && persist_timer_flag == 0 ) { persist_timer_flag = 1; //signal(SIGALRM, sig_alrm); //rtt_newpack( &rttinfo ); printf("************** PERSIST TIMER **************\n"); printf("Sending Probe packet..\n"); dg_retransmit( connfd, -1 ); } // previous_na = na; ack_recieved = dg_recieve_ack( connfd ); if( persist_timer_flag == 1 ) { if( recv_advertisement > 0) { persist_timer_flag = 0; struct itimerval value, ovalue, pvalue; value.it_interval.tv_sec = 0; /* Zero seconds */ value.it_interval.tv_usec = 0; /* Two hundred milliseconds */ value.it_value.tv_sec = 0; /* Zero seconds */ value.it_value.tv_usec = 0; /* Five hundred milliseconds */ setitimer( ITIMER_REAL, &value, &ovalue ); //alarm(0); break; } } if( dup_ack == 3 && persist_timer_flag == 0 ) { /* DUP ACK's case */ //dup_ack = 0; ssthresh = MIN( cwnd, recv_advertisement ); ssthresh = ( MAX( ssthresh, 2 ) )/2; printf("\n****************** 3 DUPLICATE ACK'S REC'VED ******************\n"); printf("Retransmitting the packet %d.. \n", ack_recieved); printf("Setting ssthresh to half of current window size : '%d'.. \n", ssthresh ); dg_retransmit( connfd, ack_recieved ); } if( ack_recieved == nt && persist_timer_flag == 0 ) { /* All Acks have been recieved.. */ printf("All ACK's have been recieved for buffer..\n"); struct itimerval value, ovalue, pvalue; value.it_interval.tv_sec = 0; /* Zero seconds */ value.it_interval.tv_usec = 0; /* Two hundred milliseconds */ value.it_value.tv_sec = 0; /* Zero seconds */ value.it_value.tv_usec = 0; /* Five hundred milliseconds */ setitimer( ITIMER_REAL, &value, &ovalue ); send_counter = 0; break; } } if( slowstart == 0 ) { cwnd += 1; } } else if( fread( sendline, 1, PACKET_SIZE, ifp ) != NULL ) { printf("********************************* SENDING DATA ************************************\n"); printf("DATA being sent : '%s'\n", sendline ); printf("Size : %d\n", strlen(sendline) ); printf("***********************************************************************************\n"); printf("Starting RTT timer..\n"); if( rttinit == 0 ) { rtt_init( &rttinfo ); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } if( send_counter == 0 ) { struct itimerval value, ovalue, pvalue; signal(SIGALRM, sig_alrm); rtt_newpack( &rttinfo ); /* initialize for this packet and sets retransmission counter to 0*/ value=rtt_start(&rttinfo); setitimer( ITIMER_REAL, &value, &ovalue ); } buffer_position = dg_send( connfd, sendline, strlen( sendline ) ); if ( sigsetjmp( jmpbuf, 1 ) != 0 ) { if ( rtt_timeout( &rttinfo ) < 0 && persist_timer_flag == 1 ) { err_msg( "Error : no response from client, giving up" ); rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; return(-1); } goto sendagain; } send_counter++; status_report(); printf("Buffer position : %d\n", buffer_position ); memset( sendline, '\0', sizeof( sendline ) ); } else { /* the last packets */ while( na != nt || (closing_child == 1) ) { ack_recieved = dg_recieve_ack( connfd ); if( dup_ack == 3 ) { /* DUP ACK's case */ ssthresh = MIN( cwnd, recv_advertisement ); ssthresh = ( MAX( ssthresh, 2 ) )/2; printf("****************** 3 DUPLICATE ACK'S REC'VED ******************\n"); printf("Retransmitting the packet %d.. \n", ack_recieved); printf("Setting ssthresh to half of current window size : '%d'.. \n", ssthresh ); dg_retransmit( connfd, ack_recieved ); } status_report(); } printf("**************** SERVER CHILD SHUTDOWN PROCEDURE INTITIATED *****************\n"); printf("\nCOMPLETED SENDING ALL PACKETS TO CLIENT..\n"); printf("SENDING A FIN..\n"); dg_retransmit(connfd,-3); //FIN PACKET dg_recieve_ack( connfd ); dg_retransmit(connfd,-4); //final ACK closing_child = 1; printf("\nSHUTTING DOWN CHILD SERVER IN 2MSL seconds (ASSUMED AS 10 SECONDS)..\n"); struct itimerval value, ovalue, pvalue; value.it_interval.tv_sec = 0; /* Zero seconds */ value.it_interval.tv_usec = 0; /* Two hundred milliseconds */ value.it_value.tv_sec = 10; /* Zero seconds */ value.it_value.tv_usec = 0; /* Five hundred milliseconds */ setitimer( ITIMER_REAL, &value, &ovalue ); } continue; sendagain : if( closing_child == 1 ) { printf("CLOSING THE CHILD PROCESS ON THE SERVER..\n"); exit(0); break; // TERMINATE SAFELY } if( recv_advertisement == 0 ) { dg_retransmit( connfd, -1 ); } else { printf("******************RTT TIMEOUT EXPERIENCED******************..\n"); printf("Retransmitting the packet %d.. )\n", na); dg_retransmit( connfd, na ); } ssthresh = MIN( cwnd, recv_advertisement ); ssthresh = ( MAX( ssthresh, 2 ) )/2; cwnd = 1; slowstart = 1; printf("\n\nSetting ssthresh to half of current window size : '%d'.. \n", ssthresh ); } }
void board_init(void) { int status; /* initialize the boards LEDs */ gpio_init(LED0_PIN, GPIO_OUT); gpio_init(LED1_PIN, GPIO_OUT); gpio_init(LED2_PIN, GPIO_OUT); /* Initialize power control pins */ power_pins_init(); /* Turn on Vperiph for peripherals */ /* * By turning on Vperiph first, and before waiting for the clocks to * stabilize, we will have used enough time to have let the FRAM start up * properly when we want to access it later without having to add any extra * delays. */ gpio_set(MULLE_POWER_VPERIPH); /* Turn on AVDD for reading voltages */ gpio_set(MULLE_POWER_AVDD); /* Initialize RTC oscillator as early as possible since we are using it as a * base clock for the FLL. * It takes a while to stabilize the oscillator, therefore we do this as * soon as possible during boot in order to let it stabilize while other * stuff is initializing. */ /* If the clock is not stable then the UART will have the wrong baud rate * for debug prints as well */ rtt_init(); /* Set up clocks */ set_safe_clock_dividers(); set_fll_source(); kinetis_mcg_set_mode(KINETIS_MCG_FEE); /* At this point we need to wait for 1 ms until the clock is stable. * Since the clock is not yet stable we can only guess how long we must * wait. I have tried to make this as short as possible but still being able * to read the initialization messages written on the UART. * (If the clock is not stable all UART output is garbled until it has * stabilized) */ for (int i = 0; i < 100000; ++i) { __asm__ volatile("nop\n"); } /* Update SystemCoreClock global var */ SystemCoreClockUpdate(); /* initialize the CPU */ cpu_init(); /* NVRAM requires xtimer for timing */ xtimer_init(); /* Initialize NVRAM */ status = mulle_nvram_init(); if (status == 0) { /* Increment boot counter */ increase_boot_count(); } }
void child(int index, struct sockaddr_in* ptr_connaddr, struct datagram* ptr_conn_gram) { struct datagram recv_gram; struct datagram send_gram; struct datagram* sendbuf; uint32_t* sendtv; char *tmp; int sockfd; int nready; int i; fd_set rset, allset; int maxfdp1 = 0; struct sockaddr_in servaddr, cliaddr; int local = 0; int on = 1; int len; //int filepos = -1; int filesize = 0; int servsockclosed = 0; int recv_seq; int last_ack; int last_ack_times; int recv_ack; int send_seq; int send_flag; int seq = 2568; int newport = 0; int recv_lock = 0; int eof = 0; int send_exist = 0; int buf_to_send = 0; int ssth = 0; float congestion_size = 1; int max_size = 0; uint32_t ts; FILE* file; char* payload; char* filename; struct rtt_info rttinfo; rtt_init(&rttinfo); for (i=0;i<count;i++) { if (i != index) { Close(sockfds[i]); continue; } } // todo: file not exist // todo: pipeline payload = get_payload_ptr(ptr_conn_gram); recv_windowsize = *(int*)payload; filename = payload+sizeof(int); printf("Client [%s:%d] request %s\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port), filename); file = fopen(filename, "r"); if (!file) { printf("File not exist: %s\n", filename); Close(sockfd); return; } fseek(file, 0, SEEK_END); filesize = ftell(file); fseek(file, 0, SEEK_SET); local = is_local(addrs[index], ptr_connaddr, 0); sockfd = Socket(AF_INET, SOCK_DGRAM, 0); Setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = ((struct sockaddr_in*)addrs[index]->ifi_addr)->sin_addr.s_addr; servaddr.sin_port = 0; Bind(sockfd, (SA *) &servaddr, sizeof(servaddr)); len = sizeof(servaddr); getsockname(sockfd, (SA *) &servaddr, &len); if (local == 0) { printf("Client [%s:%d] is not LOCAL\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port)); } else if (local == 1) { printf("Client [%s:%d] is LOCAL\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port)); } else if (local == 2) { printf("Client [%s:%d] is LOOPBACK\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port)); } if (local) Setsockopt(sockfd, SOL_SOCKET, SO_DONTROUTE, &on, sizeof(on)); //Connect(sockfd, (SA*)ptr_connaddr, sizeof(struct sockaddr_in)); // init // todo: fail sendbuf = (struct datagram*)malloc(windowsize*sizeof(struct datagram)); memset(sendbuf, 0, windowsize*sizeof(struct datagram)); sendtv = (uint32_t*)malloc(windowsize*sizeof(uint32_t)); memset(sendtv, 0, windowsize*sizeof(uint32_t)); send_exist = 0; last_ack = 0; last_ack_times = 0; newport = (int)ntohs(servaddr.sin_port); printf("New port for client [%s:%d] is %d\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port), newport); get_header(ptr_conn_gram, 0, &recv_seq, 0, &ts); make_datagram(&sendbuf[0], SYN | ACK, seq, recv_seq+1, ts, (char*)&newport, sizeof(newport)); sendtv[0] = rtt_ts(&rttinfo) + rtt_start(&rttinfo); send_to(sockfd, &sendbuf[0], ptr_connaddr, sizeof(struct sockaddr_in)); send_exist++; FD_ZERO(&allset); FD_ZERO(&rset); FD_SET(sockfd, &allset); maxfdp1 = sockfd+1; for(;;) { rset = allset; // handle timeout // todo: rtt, recv_lock ts = rtt_start(&rttinfo); struct timeval tv; tv.tv_sec = ts/1000; tv.tv_usec = (ts % 1000)*1000; nready = select(maxfdp1, &rset, NULL, NULL, &tv); if (nready < 0) { if (errno == EINTR) continue; /* back to for() */ else err_sys("select error"); } else if (nready == 0) { // timeout if (recv_lock) { ts = rtt_ts(&rttinfo); make_datagram(&send_gram, ACK, 0, 0, ts, NULL, 0); send_to(sockfd, &send_gram, ptr_connaddr, sizeof(*ptr_connaddr)); continue; } // resend for (i=0;i<windowsize;i++) { if (0 == sendtv[i]) continue; ts = rtt_ts(&rttinfo); if (ts >= sendtv[i]) { set_ts(&sendbuf[i], ts); send_to(sockfd, &sendbuf[i], ptr_connaddr, sizeof(*ptr_connaddr)); sendtv[i] = ts + rtt_start(&rttinfo); } } if (rtt_timeout(&rttinfo) < 0) { if (!servsockclosed) { Close(sockfds[index]); servsockclosed = 1; } Close(sockfd); fclose(file); printf("Too many timeouts for Client [%s:%d]\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port)); return; } ssth = (int)congestion_size/2; if (ssth < 1) ssth = 1; congestion_size = 1; printf("Timeout slow start\n"); continue; } if (FD_ISSET(sockfd, &rset)) { len = sizeof(cliaddr); recv_from(sockfd, &recv_gram, &cliaddr, &len); get_header(&recv_gram, 0, 0, &recv_ack, &ts); rtt_stop(&rttinfo, rtt_ts(&rttinfo)-ts); payload = get_payload_ptr(&recv_gram); recv_lock = (*(int*)payload == 0)?1:0; if (!servsockclosed) { Close(sockfds[index]); servsockclosed = 1; } for (i=0;i<windowsize;i++) { get_header(&sendbuf[i], &send_flag, &send_seq, 0, 0); if (!send_flag) continue; if (send_seq < recv_ack) { set_flag(&sendbuf[i], 0); sendtv[i] = 0; send_exist--; } } if ((recv_ack > seq) && eof) { Close(sockfd); fclose(file); printf("Client [%s:%d] end\n", inet_ntoa(ptr_connaddr->sin_addr), ntohs(ptr_connaddr->sin_port)); return; } if (last_ack == recv_ack) { last_ack_times++; } else { last_ack = recv_ack; last_ack_times=1; } if (last_ack_times >= 3) { last_ack = 0; for (i=0;i<windowsize;i++) { get_header(&sendbuf[i], &send_flag, &send_seq, 0, 0); if (!send_flag) continue; if (send_seq == recv_ack) break; } ts = rtt_ts(&rttinfo); set_ts(&sendbuf[i], ts); send_to(sockfd, &sendbuf[i], ptr_connaddr, sizeof(*ptr_connaddr)); // todo: congestion printf("Fast recvory\n"); congestion_size = ssth; if (congestion_size <= 0) congestion_size = 1; continue; } // todo: congestion max_size = windowsize; if (recv_windowsize < max_size) max_size = recv_windowsize; if (congestion_size < ssth) { congestion_size++; if (congestion_size >= ssth) { printf("Reach slow start threshold\n"); } } else { congestion_size += (max_size > 0)? 1.0/max_size:1.0; } if (congestion_size < max_size) max_size = (int)congestion_size; if (eof || recv_lock) { buf_to_send = 0; } else if (send_exist < max_size) { buf_to_send = max_size - send_exist; } else if (send_exist >= max_size) { buf_to_send = 0; } //printf("buf_to_send %d\n", buf_to_send); for (;buf_to_send > 0;buf_to_send--) { for (i=0;i<windowsize;i++) { get_header(&sendbuf[i], &send_flag, &send_seq, 0, 0); if (!send_flag) break; } seq++; ts = rtt_ts(&rttinfo); make_datagram(&sendbuf[i], DAT, seq, 0, ts, NULL, 0); payload = get_payload_ptr(&sendbuf[i]); //len = fread(payload+4, BUFFER_SIZE-HEADER_SIZE-4, 1, file); len = fread(payload+4, 1, BUFFER_SIZE-HEADER_SIZE-4, file); *(int*)payload = len; //printf("f %d %s\n", len, payload+4); if (ftell(file) >= filesize) { eof = 1; set_fin_flag(&sendbuf[i]); } sendtv[i] = ts + rtt_start(&rttinfo); send_to(sockfd, &sendbuf[i], ptr_connaddr, sizeof(*ptr_connaddr)); send_exist++; if (eof) break; } } } }
static unsigned long wait_mode_power_down_hook( unsigned long delay_ms ) { bool jtag_enabled = ( ( CoreDebug ->DHCSR & CoreDebug_DEMCR_TRCENA_Msk ) != 0 ) ? true : false; bool jtag_delay_elapsed = ( mico_get_time() > JTAG_DEBUG_SLEEP_DELAY_MS ) ? true : false; uint32_t elapsed_cycles = 0; /* Criteria to enter WAIT mode * 1. Clock needed counter is 0 and no JTAG debugging * 2. Clock needed counter is 0, in JTAG debugging session, and MiCO system tick has progressed over 3 seconds. * This is to give OpenOCD enough time to poke the JTAG tap before the CPU enters WAIT mode. */ if ( ( samg5x_clock_needed_counter == 0 ) && ( ( jtag_enabled == false ) || ( ( jtag_enabled == true ) && ( jtag_delay_elapsed == true ) ) ) ) { uint32_t total_sleep_cycles; uint32_t total_delay_cycles; /* Start real-time timer */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); /* Start atomic operation */ DISABLE_INTERRUPTS; /* Ensure deep sleep bit is enabled, otherwise system doesn't go into deep sleep */ SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; /* Disable SysTick */ SysTick->CTRL &= ( ~( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ) ); /* End atomic operation */ ENABLE_INTERRUPTS; /* Expected total time CPU executing in this function (including WAIT mode time) */ total_sleep_cycles = MS_TO_CYCLES( delay_ms ); /* Total cycles in WAIT mode loop */ total_delay_cycles = ( total_sleep_cycles / RTT_MAX_CYCLES + 1 ) * RC_OSC_DELAY_CYCLES + WAIT_MODE_ENTER_DELAY_CYCLES + WAIT_MODE_EXIT_DELAY_CYCLES; if ( total_sleep_cycles > total_delay_cycles ) { /* Adjust total sleep cycle to exclude exit delay */ total_sleep_cycles -= WAIT_MODE_EXIT_DELAY_CYCLES; /* Prepare platform specific settings before entering powersave */ // platform_enter_powersave(); ///* Prepare WLAN bus before entering powersave */ //platform_bus_enter_powersave(); /* Disable brownout detector */ supc_disable_brownout_detector( SUPC ); /* Backup system I/0 functions and set all to GPIO to save power */ system_io_backup_value = matrix_get_system_io(); matrix_set_system_io( 0x0CF0 ); /* Switch Master Clock to Main Clock (internal fast RC oscillator) */ pmc_switch_mck_to_mainck( PMC_PCK_PRES_CLK_1 ); /* Switch on internal fast RC oscillator, switch Main Clock source to internal fast RC oscillator and disables external fast crystal */ pmc_switch_mainck_to_fastrc( CKGR_MOR_MOSCRCF_8_MHz ); /* Disable external fast crystal */ pmc_osc_disable_xtal( 0 ); /* Disable PLLA */ pmc_disable_pllack( ); /* This above process introduces certain delay. Add delay to the elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); while ( wake_up_interrupt_triggered == false && elapsed_cycles < total_sleep_cycles ) { uint32_t current_sleep_cycles = total_sleep_cycles - elapsed_cycles; /* Start real-time timer and alarm */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); rtt_write_alarm_time( RTT, ( current_sleep_cycles > RTT_MAX_CYCLES ) ? RTT_MAX_CYCLES - RC_OSC_DELAY_CYCLES : current_sleep_cycles - RC_OSC_DELAY_CYCLES ); __asm("wfi"); /* Enter WAIT mode */ //pmc_enable_waitmode(); /* Clear wake-up status */ rtt_get_status( RTT ); /* Add sleep time to the elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); } /* Re-enable real-time timer to time clock reinitialisation delay */ rtt_init( RTT, RTT_CLOCK_PRESCALER ); /* Reinit fast clock. This takes ~19ms, but the timing has been compensated */ init_clocks(); /* Disable unused clock to save power */ pmc_osc_disable_fastrc(); /* Restore system I/O pins */ matrix_set_system_io( system_io_backup_value ); /* Restore WLAN bus */ //platform_bus_exit_powersave(); // /* Restore platform-specific settings */ // platform_exit_powersave(); /* Add clock reinitialisation delay to elapsed cycles */ elapsed_cycles += rtt_read_timer_value( RTT ); /* Disable RTT to save power */ RTT->RTT_MR = (uint32_t)( 1 << 20 ); } } /* Start atomic operation */ DISABLE_INTERRUPTS; /* Switch SysTick back on */ SysTick->CTRL |= ( SysTick_CTRL_TICKINT_Msk | SysTick_CTRL_ENABLE_Msk ); /* Clear flag indicating interrupt triggered by wake up pin */ wake_up_interrupt_triggered = false; /* End atomic operation */ ENABLE_INTERRUPTS; /* Return total time in milliseconds */ return CYCLES_TO_MS( elapsed_cycles ); }
static int su_serv_send_recv_act(su_serv_t *psvr, SA *destaddr, socklen_t destlen, const void *outbuff, int outbytes, void *inbuff, int inbytes, int retransmit) { int n; struct iovec iovsend[2]= {{0}}; struct msghdr msgsend = {0}; /* assumed init to 0 */ suhdr_t *r, sendhdr = {0}; /* protocol header */ int ret, waitsec; struct list *node = 0; frames_t *packet = 0; pthread_mutex_lock(&psvr->mutex); pthread_mutex_lock(&psvr->lock); if (retransmit == 0) { psvr->seq++; psvr->retransmission = 1; } else { if (psvr->retransmission == 0) { pthread_mutex_unlock(&psvr->mutex); pthread_mutex_unlock(&psvr->lock); errno = ETIMEDOUT; return -1; } psvr->retransmission --; } if (psvr->rttinit == 0) { rtt_init(&psvr->rttinfo, psvr->retry); /* first time we're called */ psvr->rttinit = 1; } sendhdr.act = SU_SYN; sendhdr.type = SU_RELIABLE; sendhdr.sid = psvr->sid; sendhdr.seq = psvr->seq; msgsend.msg_name = (void*)destaddr; msgsend.msg_namelen = destlen; msgsend.msg_iov = iovsend; msgsend.msg_iovlen = 2; iovsend[0].iov_base = (void*)&sendhdr; iovsend[0].iov_len = sizeof(suhdr_t); iovsend[1].iov_base = (void*)outbuff; iovsend[1].iov_len = outbytes; struct timespec abstime = {0}; suhdr_t *precvhdr; rtt_newpack(&psvr->rttinfo); /* initialize for this packet */ psvr->ackwaitnum ++; sendagain: sendhdr.ts = rtt_ts(&psvr->rttinfo); if (sendmsg(psvr->fd, &msgsend, 0) < 0) { ERR_RET("sendmsg error"); goto error_ret; } waitsec = rtt_start(&psvr->rttinfo); /* calc timeout value & start timer */ #ifdef SU_DEBUG_RTT fprintf(stderr, ColorRed "send seq %4d: " ColorEnd, sendhdr.seq); rtt_debug(&psvr->rttinfo); #endif /* set timed wait time-point */ maketimeout_seconds(&abstime, waitsec); #ifdef SU_DEBUG_TIMEVERBOSE struct timeval now; gettimeofday(&now, 0); log_msg( ColorBlue "pthread_cond_timedwait : %u.%u time expire" ColorEnd, abstime.tv_sec, abstime.tv_nsec); log_msg( ColorBlue "pthread_cond_timedwait : %d.%d now time" ColorEnd, now.tv_sec, now.tv_usec*1000); #endif timedwaitagain: ret = pthread_cond_timedwait(&psvr->ackcond, &psvr->lock, &abstime); if (ret == 0) { #ifdef SU_DEBUG_TIMEVERBOSE struct timeval now; gettimeofday(&now, 0); log_msg(ColorBlue "pthread_cond_timedwait : %d.%d ack cond interrupt" ColorEnd, now.tv_sec, now.tv_usec*1000); #endif node = psvr->ackrecvls.next; for (; node != &psvr->ackrecvls; node = node->next) { packet = container_of(node, frames_t, node); r = &packet->recvhdr; if (su_cmp_ack_SU_RELIABLE(&sendhdr, r)) { break; } } if ( node == &psvr->ackrecvls ) { /* Be careful of the lock, locked -> timedwait -> unlock */ #ifdef SU_DEBUG_LIST log_msg("serv %x no found seq %d ack, timed wait again", psvr, sendhdr.seq); #endif goto timedwaitagain; } /* Find response packet node */ list_remove(&packet->node); n = packet->len; precvhdr = &packet->recvhdr; #if defined SU_DEBUG_PEER_RECV || defined SU_DEBUG_LIST log_msg("serv %x finded ack " ColorRed "%p" ColorEnd " seq %d datagram len %d", psvr, packet, r->seq, packet->len); #endif #ifdef SU_DEBUG_RTT fprintf(stderr, ColorRed "recv seq %4d \n" ColorEnd, precvhdr->seq); #endif // SU_RELIABLE received response, copy to user buffer memcpy(inbuff, packet->data, n > inbytes ? inbytes : n); } else if (ret == EINTR) { log_msg("pthread_cond_timedwait system EINTR"); goto timedwaitagain; } else if (ret == ETIMEDOUT) { #ifdef SU_DEBUG_TIMEVERBOSE struct timeval now; gettimeofday(&now, 0); log_msg(ColorBlue "pthread_cond_timedwait : %u.%u ETIMEOUT have expired" ColorEnd, now.tv_sec, now.tv_usec*1000); #endif if (rtt_timeout(&psvr->rttinfo) < 0) { #ifdef SU_DEBUG_RTT err_msg(ColorYel "no response from server, giving up" ColorEnd); #endif psvr->rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; goto error_ret; } #ifdef SU_DEBUG_RTT err_msg(ColorRed " seq %4d timeout, retransmitting %d" ColorEnd, sendhdr.seq, ++retransmit); #endif goto sendagain; } else { errno = ret; ERR_RET(" su_serv_send_recv_act unknown error[%d]", ret); goto error_ret; } /* calculate & store new RTT estimator values */ rtt_stop(&psvr->rttinfo, rtt_ts(&psvr->rttinfo) - precvhdr->ts); if (--psvr->ackwaitnum == 0) { su_serv_list_empty(psvr, &psvr->ackrecvls); } pthread_mutex_unlock(&psvr->mutex); pthread_mutex_unlock(&psvr->lock); #ifdef SU_DEBUG_LIST log_msg("serv %x free node " ColorRed "%p"ColorEnd" seq %d", psvr, packet, sendhdr.seq); #endif free(packet); return(n); /* return size of received datagram */ error_ret: if (--psvr->ackwaitnum == 0) { su_serv_list_empty(psvr, &psvr->ackrecvls); } pthread_mutex_unlock(&psvr->mutex); pthread_mutex_unlock(&psvr->lock); return(-1); }
void rtc_init(void) { rtt_init(); }
int main(int argc, char **argv) { int n,sockfd, on=1,i,j,maxfdp,optval=1; char recvline[LINE_MAX], in_packet[PACKET_LEN]; client_config_t config; int num_ifi = 0; pthread_t tid; thread_arg* arg; bool done = FALSE, is_probe = FALSE, is_error = FALSE; unsigned int ack_seq, seq, timestamp; unsigned short curr_win; circ_buffer_t rcv_buffer; ifi_t *ifi_array[IFI_MAX]; read_client_config("client.in", &config); print_client_config(&config); num_ifi = get_ifi(ifi_array); print_ifi(ifi_array, num_ifi); srand(config.seed); init_circular_buffer(&rcv_buffer, config.window_size); rtt_init(&rttinfo); if (connection_setup(&sockfd, ifi_array, num_ifi, &rcv_buffer, &config) < 0) err_sys("[Error] Connection Setup Error, Terminating..\n"); /* TODO: Recv ACK and connect to the new port */ arg = (thread_arg*)calloc(1, sizeof(thread_arg)); arg->rcv_buf = &rcv_buffer; arg->config = &config; arg->sockfd = sockfd; Pthread_create(&tid, NULL, &consumer_thread, arg); /* Below is the Producer Logic which reads from the socket and fills * up the receive Buffer. */ while (!done) { if ((n = read(sockfd, in_packet, PACKET_LEN)) < 0) { if (errno == EINTR) continue; else err_sys("[Error] Unknown Read Error"); } packet_info_t *pkt_info = get_packet_info(in_packet, n); if (!IS_DATA(pkt_info) && !(is_probe = IS_PROBE(pkt_info)) && !(is_error = IS_ERR(pkt_info))) { free_pkt_info(pkt_info); continue; } if (consume_random_packet(pkt_info, config.prob_loss, TRUE)) { free_pkt_info(pkt_info); continue; } if(IS_EOF(pkt_info) || is_error) done = TRUE; Pthread_mutex_lock(&buf_mutex); /* Special Handling for Probes & Errors, send an ACK, don't store in buffer */ if(!is_probe && !is_error) { write_to_buffer(&rcv_buffer , pkt_info); } /* Save off these values as we are releasing the lock below */ curr_win = window_size(&rcv_buffer); ack_seq = NEXT_ACK(&rcv_buffer); seq = pkt_info->seq; timestamp = pkt_info->timestamp; Pthread_mutex_unlock(&buf_mutex); if(is_probe) printf("[Info] Persist Timer Response [Ack:%u] [Window Size:%hu]\n", ack_seq, curr_win); else printf("[Info] Received [Seq: %u] Responding with [Ack:%u] [Window Size:%hu]\n", seq, ack_seq, curr_win); send_ack(sockfd, curr_win, seq, ack_seq, timestamp, config.prob_loss); } pthread_exit(NULL); }
ssize_t dg_send_recv(int fd, const void *outbuff, size_t outbytes, void *inbuff, size_t inbytes, const SA *destaddr, socklen_t destlen) { ssize_t n; struct iovec iovsend[2], iovrecv[2]; fd_set rset; int nsel, maxfdp1; struct timeval tv; if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } sendhdr.seq++; msgsend.msg_name = destaddr; msgsend.msg_namelen = destlen; msgsend.msg_iov = iovsend; msgsend.msg_iovlen = 2; iovsend[0].iov_base = &sendhdr; iovsend[0].iov_len = sizeof(struct hdr); iovsend[1].iov_base = outbuff; iovsend[1].iov_len = outbytes; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; rtt_newpack(&rttinfo); /* initialize for this packet */ sendagain: #ifdef RTT_DEBUG fprintf(stderr, "send %4d: ", sendhdr.seq); #endif sendhdr.ts = rtt_ts(&rttinfo); Sendmsg(fd, &msgsend, 0); alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */ #ifdef RTT_DEBUG rtt_debug(&rttinfo); #endif tv.tv_sec = rtt_start(&rttinfo); tv.tv_usec = 0; maxfdp1 = fd + 1; again: FD_ZERO(&rset); FD_SET(fd, &rset); nsel = select(maxfdp1, &rset, NULL, NULL, &tv); if ((nsel == -1) || (errno == EINTR)) goto again; else if (nsel == -1) err_msg("select error"); else if (nsel == 0) { if (rtt_timeout(&rttinfo) < 0) { err_msg("dg_send_recv: no response from server, giving up"); rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; return(-1); } #ifdef RTT_DEBUG err_msg("dg_send_recv: timeout, retransmitting"); #endif goto sendagain; } if (FD_ISSET(fd, &rset)) { do { n = Recvmsg(fd, &msgrecv, 0); #ifdef RTT_DEBUG fprintf(stderr, "recv %4d\n", recvhdr.seq); #endif } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq); } /* 4calculate & store new RTT estimator values */ rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); return(n - sizeof(struct hdr)); /* return size of received datagram */ }
ssize_t dg_send_recv(int fd, const void *outbuff, size_t outbytes, void *inbuff, size_t inbytes, const SA *destaddr, socklen_t destlen) { ssize_t n; struct iovec iovsend[2], iovrecv[2]; if (rttinit == 0) { rtt_init(&rttinfo); /* first time we're called */ rttinit = 1; rtt_d_flag = 1; } sendhdr.seq++; msgsend.msg_name = destaddr; msgsend.msg_namelen = destlen; msgsend.msg_iov = iovsend; msgsend.msg_iovlen = 2; iovsend[0].iov_base = &sendhdr; iovsend[0].iov_len = sizeof(struct hdr); iovsend[1].iov_base = outbuff; iovsend[1].iov_len = outbytes; msgrecv.msg_name = NULL; msgrecv.msg_namelen = 0; msgrecv.msg_iov = iovrecv; msgrecv.msg_iovlen = 2; iovrecv[0].iov_base = &recvhdr; iovrecv[0].iov_len = sizeof(struct hdr); iovrecv[1].iov_base = inbuff; iovrecv[1].iov_len = inbytes; /* end dgsendrecv1 */ /* include dgsendrecv2 */ if (signal(SIGALRM, sig_alrm) == SIG_ERR) { perror("signal error"); exit(1); } rtt_newpack(&rttinfo); /* initialize for this packet */ sendagain: #ifdef RTT_DEBUG fprintf(stderr, "send %4d: ", sendhdr.seq); #endif sendhdr.ts = rtt_ts(&rttinfo); int nbytes = 0; /* must first figure out what return value should be */ int i; for (i = 0; i < msgsend.msg_iovlen; i++) nbytes += msgsend.msg_iov[i].iov_len; if (sendmsg(fd, &msgsend, 0) != nbytes) { perror("sendmsg error"); exit(1); } alarm(rtt_start(&rttinfo)); /* calc timeout value & start timer */ #ifdef RTT_DEBUG rtt_debug(&rttinfo); #endif if (sigsetjmp(jmpbuf, 1) != 0) { if (rtt_timeout(&rttinfo) < 0) { fprintf(stderr, "dg_send_recv: no response from server, giving up\n"); rttinit = 0; /* reinit in case we're called again */ errno = ETIMEDOUT; return(-1); } #ifdef RTT_DEBUG fprintf(stderr, "dg_send_recv: timeout, retransmitting\n"); #endif goto sendagain; } do { if ((n = recvmsg(fd, &msgrecv, 0)) < 0) { perror("recvmsg error"); exit(1); } #ifdef RTT_DEBUG fprintf(stderr, "recv %4d\n", recvhdr.seq); #endif } while (n < sizeof(struct hdr) || recvhdr.seq != sendhdr.seq); alarm(0); /* stop SIGALRM timer */ /* 4calculate & store new RTT estimator values */ rtt_stop(&rttinfo, rtt_ts(&rttinfo) - recvhdr.ts); return(n - sizeof(struct hdr)); /* return size of received datagram */ }
ssize_t jxclient_sendrecv(struct jxclient* cli, const struct sockaddr* servaddr, jxsocklen_t addrlen, mflag_t mflag) { char outbuf[MAX_MSG_LEN]; ssize_t recvbytes; jxsocklen_t sendlen; struct jxmsg_header* bufheader = NULL; if (s_rttinit == 0) { rtt_init(&s_rttinfo); s_rttinit = 1; #ifdef _DEBUG rtt_d_flag = 1; #endif } if (s_mutex_inited == 0) { s_sendrecv_init(); } bufheader = (struct jxmsg_header*)outbuf; bufheader->mflag = mflag; bufheader->header.seq = ++s_sendhdr.seq; rtt_newpack(&s_rttinfo); sendlen = sizeof(bufheader->addr); jxsock_getsockname(cli->hsock_sendrecv, &bufheader->addr, &sendlen); bufheader->addrlen = (uint8_t)sendlen; bufheader->numbytes = htonl(cli->len_senddata); if (jxmemcpy( outbuf + sizeof(struct jxmsg_header), sizeof(outbuf) - sizeof(struct jxmsg_header), cli->sendbuf, cli->len_senddata) != 0) { return 1; } s_recv_stat = RECV_RESEND; while (RECV_RESEND == s_recv_stat) { bufheader->header.ts = s_sendhdr.ts = rtt_ts(&s_rttinfo); if (SOCKET_ERROR == sendto( cli->hsock_sendrecv, outbuf, sizeof(struct jxmsg_header) + cli->len_senddata, 0, servaddr, (jxsocklen_t)addrlen)) { fprintf(stderr, "%s sendto() fail, error code: %d.\n", cli->prompt, jxsock_get_last_error()); return -2; } if (!JX_MFLAG_WAIT_RECV(mflag)) { return 0; } s_reset_recvtimer(); if ((recvbytes = s_recvmsg(cli->hsock_sendrecv, cli->recvbuf, sizeof(cli->recvbuf))) == -3) { return -3; } } if (s_recv_stat == RECV_TIMEOUT) { s_rttinit = 0; return -1; } rtt_stop(&s_rttinfo, rtt_ts(&s_rttinfo) - ((struct jxmsg_header*)cli->recvbuf)->header.ts); jxmsg_copyaddr((struct jxmsg_header*)cli->recvbuf, servaddr, addrlen); return recvbytes - sizeof(struct jxmsg_header); }