Beispiel #1
0
/* control_loop() is the main STCP loop; it repeatedly waits for one of the
 * following to happen:
 *   - incoming data from the peer
 *   - new data from the application (via mywrite())
 *   - the socket to be closed (via myclose())
 *   - a timeout
 */
 static void control_loop(mysocket_t sd, context_t *ctx)
 {
    assert(ctx);
    assert(!ctx->done);
    while (!ctx->done)
    {
        unsigned int event;
        
        event = stcp_wait_for_event(sd, ANY_EVENT, NULL);

        /* check whether it was the network, app, or a close request */
        
        if (event & NETWORK_DATA) {
            /* there was network data received */
            //our_dprintf("got network data\n");
            handle_cstate_est_recv(sd, ctx);
        } 
        if (event & APP_DATA) {
            /* the application has requested that data be sent */
            /* see stcp_app_recv() */
            handle_cstate_est_send(sd, ctx);
        } 
        if (event & APP_CLOSE_REQUESTED) {
            /* the application has requested that the conn be closed */
            //our_dprintf("close received \n");
            send_syn_ack_fin(sd, ctx, SEND_FIN, 0, 0);
            ctx->connection_state = CSTATE_FIN_WAIT_1;

            close_tcp_conn(sd, ctx);
        } 

    }
}
Beispiel #2
0
bool gsm_pwr_off( )
{
	u16 result_temp;

	//close connect... AT^SISC=0
	if( !close_tcp_conn( ) )  {
		debug_gsm("Close connection error\r\n");
	}

	//Check link status... AT^SISI?
	result_temp = check_tcp_status( );
	debug_gsm("AT^SISI return %d\r\n",result_temp);

	if ( result_temp != 2 ) { //error, force shutdown
		close_tcp_conn( );
		OSTimeDlyHMSM(0, 0, 1, 0);
	}

	//shutdown module ... AT^SMSO
	if( !shutdown_mg323( ) )  {
		debug_gsm("shutdown error\r\n");
		OSTimeDlyHMSM(0, 0, 1, 0);
		shutdown_mg323( );
	}
	else {
		debug_gsm("shutdown CMD ok.\r\n");
	}

	OSTimeDlyHMSM(0, 0, 1, 0);//不能太长,否则会自动重开机

	GSM_PM_OFF;

	my_icar.mg323.try_online_cnt = 1;
	my_icar.mg323.gprs_count = 0 ;
	my_icar.mg323.gprs_ready = false;
	my_icar.mg323.tcp_online = false ;
	my_icar.mg323.power_on = false;
	memset(my_icar.mg323.ip_local, 0x0, IP_LEN-1);

	prompt("Turn off GSM power.\r\n");
	return true ;
}
Beispiel #3
0
bool gprs_disconnect(  )
{

	prompt("!!! Close GPRS connection !!!\t");
	//close connect... AT^SISC=0
	if( close_tcp_conn( ) )  {
		prompt("ok.\r\n");
	}
	else {
		prompt("failure.\r\n");
	}

	my_icar.mg323.tcp_online = false ;
	my_icar.mg323.try_online_cnt = 1 ;

	return true ;
}
Beispiel #4
0
/* initialise the transport layer, and start the main loop, handling
 * any data from the peer or the application.  this function should not
 * return until the connection is closed.
 */
 void transport_init(mysocket_t sd, bool_t is_active)
 {
    context_t *ctx;
    int res;
    ctx = (context_t *) calloc(1, sizeof(context_t));
    assert(ctx);

    generate_initial_seq_num(ctx);
    ctx->connection_state = CSTATE_CLOSED;
    
    ctx->send_wind = (uint8_t *) malloc(MAX_WINDOW_SIZE);
    memset(ctx->send_wind, 0, MAX_WINDOW_SIZE);

    ctx->recv_wind = (uint8_t *) malloc(MAX_WINDOW_SIZE);
    memset(ctx->recv_wind, 0, MAX_WINDOW_SIZE);
    res = open_tcp_conn(sd, ctx, is_active);

    /* XXX: you should send a SYN packet here if is_active, or wait for one
     * to arrive if !is_active.  after the handshake completes, unblock the
     * application with stcp_unblock_application(sd).  you may also use
     * this to communicate an error condition back to the application, e.g.
     * if connection fails; to do so, just set errno appropriately (e.g. to
     * ECONNREFUSED, etc.) before calling the function.
     */

    stcp_unblock_application(sd);


    if (ctx->connection_state == CSTATE_ESTABLISHED){
        control_loop(sd, ctx);
    } else if (ctx->connection_state == CSTATE_FIN_WAIT_1){
        close_tcp_conn(sd, ctx);
    } else if (ctx->connection_state == CSTATE_CLOSED) {
        ;
    }else {
        our_dprintf("bad state in transport init");
        assert(0);
    }

    /* do any cleanup here */
    free(ctx->send_wind);
    free(ctx->recv_wind);
    free(ctx);
}
Beispiel #5
0
int handle_cstate_syn_rcvd(mysocket_t sd, context_t * ctx) {

    int ret = 0;
    unsigned int event;

    our_dprintf("in CSTATE_SYN_RCVD\n");
    event = stcp_wait_for_event(sd, NETWORK_DATA | APP_CLOSE_REQUESTED | TIMEOUT, NULL);

    /* check whether it was the network, app, or a close request */
    if (event & NETWORK_DATA) {
        /* there was network data received */

        size_t recd;
        recd = stcp_network_recv(sd, ctx->recv_wind, MAX_WINDOW_SIZE);
        if (recd == 0) {
            our_dprintf("bad network recv\n");
            return -1;
        }

        struct tcphdr * tcp_packet  = (struct tcphdr *) ctx->recv_wind;

        if (tcp_packet->th_flags & TH_ACK){
            /* ack received */
            if (ntohl(tcp_packet->th_ack) < ctx->sent_last_byte_acked || ntohl(tcp_packet->th_ack) > ctx->sent_last_byte_written+1){
                our_dprintf("bad ack, expected %u, received %u. returning \n", ctx->sent_last_byte_sent+1, tcp_packet->th_ack);
                return -1;
            }
            ctx->sent_last_byte_acked = ntohl(tcp_packet->th_ack);
            ctx->recd_adv_window = ntohs(tcp_packet->th_win);
            //our_dprintf("*** got ack %u, got adv window %u\n", ctx->sent_last_byte_acked, ctx->recd_adv_window);
            ctx->connection_state = CSTATE_ESTABLISHED;
        }
    } 

    if (event & APP_CLOSE_REQUESTED) {
        /* the application has requested that the conn be closed */

        ctx->connection_state = CSTATE_FIN_WAIT_1;
        close_tcp_conn(sd, ctx);
    } 
    return ret;
}
Beispiel #6
0
int handle_cstate_est_recv(mysocket_t sd, context_t * ctx){

    our_dprintf("* IN EST REC\n");
    size_t len =  sizeof(struct tcphdr) + STCP_MSS;
    uint8_t buff[len];
    uint32_t data_len, data_index;
    size_t delta, recv_len, recv_packet_len;
    recv_len = stcp_network_recv(sd, buff, len);
    struct tcphdr * tcp_packet  = (struct tcphdr *) buff;
    size_t hdr_size = tcp_packet->th_off * 4;
    recv_packet_len = recv_len - 4 * tcp_packet->th_off;

    /* check if any data was ack'd */
    if (tcp_packet->th_flags & TH_ACK) {
        if (ntohl(tcp_packet->th_ack) < ctx->sent_last_byte_acked || ntohl(tcp_packet->th_ack) > ctx->sent_last_byte_written+1){
            our_dprintf("bad ack, expected %u, received %u. returning \n", ctx->sent_last_byte_sent+1, tcp_packet->th_ack);
            return -1;
        }
        ctx->sent_last_byte_acked = ntohl(tcp_packet->th_ack);
        //our_dprintf("****got an ack: %u\n", tcp_packet->th_ack);
    }
    /* check to see if the seq number is appropriate */
    if (ntohl(tcp_packet->th_seq) != ctx->recd_next_byte_expected){
        //our_dprintf("unexpected seq. rec seq : %u, expected : %u\n", tcp_packet->th_seq, ctx->recd_next_byte_expected);

        /* if part of the data is below the seq window */
        if ((ntohl(tcp_packet->th_seq) < ctx->recd_next_byte_expected) && 
            (ntohl(tcp_packet->th_seq) + recv_packet_len > ctx->recd_next_byte_expected)){
            //our_dprintf("some data salvageable\n");
            /* some of the data should be salvaged */
            data_len = ntohl(tcp_packet->th_seq) + recv_packet_len - ctx->recd_next_byte_expected;
            data_index = recv_packet_len - data_len;
        } else if (0) {
            /* placeholder for if data overflows upper bound of sliding window */

        } else {
            //our_dprintf("bad packet\n");
            return 0;
        }
    } else {
        data_len = recv_packet_len;
        data_index = 0;
    }
    uint8_t * data = buff + hdr_size; 
    uint32_t wind_index = ((ctx->recd_last_byte_recd + 1) - ctx->initial_recd_seq_num) % MAX_WINDOW_SIZE;  
    //our_dprintf("window index %u, data len %u\n", wind_index, data_len); 
    //our_dprintf("received data: %s\n", data);
    if (wind_index + data_len > MAX_WINDOW_SIZE){
        /* we're wrapping the buffer */
        delta = MAX_WINDOW_SIZE - wind_index;
        //our_dprintf("wrapping recv buff \n");
        /*copy data to ctx->buffer and send it to app */ 
        memcpy(ctx->recv_wind + wind_index, data + data_index, delta); 
        stcp_app_send( sd, ctx->recv_wind + wind_index, delta);

        memcpy(ctx->recv_wind, data + delta + data_index, data_len - delta);
        stcp_app_send( sd, ctx->recv_wind, data_len - delta);
        
    } else {
        /* we're not wrapping the buffer */
        //our_dprintf("don't need to wrap, data len %d\n", data_len);
        /*copy data to ctx->buffer and send it to app */
        memcpy(ctx->recv_wind + wind_index, data + data_index, data_len);
        stcp_app_send( sd, ctx->recv_wind + wind_index, data_len);
    }

    ctx->recd_last_byte_recd += data_len;
    ctx->recd_next_byte_expected += data_len;
    ctx->recd_last_byte_read += data_len;

    if (data_len > 0 ) {
        //our_dprintf("acking %u bytes\n", data_len);
        send_syn_ack_fin(sd, ctx, SEND_ACK, 0, ctx->recd_next_byte_expected);
    } else {
        //our_dprintf("** flags %u\n", tcp_packet->th_flags);
    }
    

    if (tcp_packet->th_flags & TH_FIN) {
        stcp_fin_received(sd);
        if (data_len == 0){
            ctx->recd_last_byte_recd++;
            ctx->recd_next_byte_expected++;
            ctx->recd_last_byte_read++;
        }
        send_syn_ack_fin(sd, ctx, SEND_ACK, 0, ctx->recd_next_byte_expected);
        ctx->connection_state = CSTATE_CLOSE_WAIT;
        close_tcp_conn(sd, ctx);
    }
    return 0;
}