Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
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. */
}
Ejemplo n.º 3
0
/* 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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
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 */
}
Ejemplo n.º 6
0
Archivo: board.c Proyecto: patkan/RIOT
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();
}
Ejemplo n.º 7
0
/**
 * \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);
}
Ejemplo n.º 8
0
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
}
Ejemplo n.º 9
0
/** 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;
}
Ejemplo n.º 10
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);
}
Ejemplo n.º 11
0
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;	
}
Ejemplo n.º 12
0
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);
	}
}
Ejemplo n.º 13
0
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 );
				
	}	
}
Ejemplo n.º 14
0
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();
    }
}
Ejemplo n.º 15
0
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;
            }
        }
    }
}
Ejemplo n.º 16
0
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 );
}
Ejemplo n.º 17
0
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);
}
Ejemplo n.º 18
0
void rtc_init(void)
{
    rtt_init();
}
Ejemplo n.º 19
0
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);
}
Ejemplo n.º 20
0
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 */ 
} 
Ejemplo n.º 21
0
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 */
}
Ejemplo n.º 22
0
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);
}