Exemplo n.º 1
0
/** Author: Xiaoman Xu
 *	Server side data link layer
 *	receives frames and 
 * 	reassembles it into a packet
 *	and forward to to server netword layer
 **/
int datalink_recv(unsigned short sock, packet_t* packet, FILE* &outlog)
{
	int frame_num = 0;
	size_t recv_at = 0;
	int recv_size = 0;
	frame_t frame, ack_frame;;
    bool valid, repeat = false; 

	size_t packet_size = sizeof(packet_t);

	//while still more to receive
	while(recv_at < packet_size)
	{
		uint16_t frame_expected;
		frame_expected = ack_frame_send_seq;
        valid = false;

        //if the data frame received is not valid,
        //keep receiving
        while (!valid) {
            if((recv_size = physical_recv(sock, & frame)) != sizeof(frame_t))
            {
                DieWithError("Server DataLink: Physical layer receive different size %d than expected", recv_size);
            }

            //if the data frame seq num is the frame expected, 
            //then copy the data from the payload
            if(frame.sequence_num == frame_expected)
            {
            	
            	repeat = false;
            	memcpy(((char*)packet) + recv_at, frame.payload, frame.length);
            	
            }

            //selse the data frame is repeated.
            else
            {
            	repeat = true;
            }
            // check whether the data frame is valid
            valid = frame.check == get_hash(&frame);
            if(!valid)
            	fprintf(outlog, "Server data link layer: data frame %d of packet %d received in error (frame %d)\n",
            		frame_num, packet_sent, frame_expected);
        }

        //open the log file if not already
        if(outlog == NULL)
        {
        	char logname [20];
        	sprintf(logname, "server_%c.log", packet->filename[0]);
        	outlog = fopen(logname, "w");
        }
		ack_frame.type = FRAME_ACK;
		ack_frame.length = 0;
		ack_frame.sequence_num = ack_frame_send_seq;
	    ack_frame.check = get_hash(&ack_frame);
	    //send the ACK frame to client
		if(!repeat)
		{
			frame_num ++;
			fprintf(outlog, "Server Data Link: data frame %d of packet %d received.(frame %d)\n",
        		frame_num, packet_sent, frame_expected);
			recv_at += frame.length;
			flip_frame(&ack_frame);
			ack_frame_send_seq++;

		}
		else
		{
			fprintf(outlog, "Server data link: data frame %d of packet %d repeated!(frame %d)\n",
				frame_num, packet_sent, frame_expected);
		}
		
		datalink_send_ACK(sock, &ack_frame);
		fprintf(outlog, "Server data link layer: ACK frame %d of packet %d sent.(frame %d)\n",
			frame_num, packet_sent, frame_expected);

		if(frame.is_end&&repeat)
		{
			return 0;
		}	
	}
	packet_sent++;
    
	return sizeof(packet_t);
}
Exemplo n.º 2
0
//Author: Xiaoman Xu
int datalink_send(unsigned short sock, packet_t *packet, FILE* outfile)
{
	frame_t frame, ack_frame;
	uint8_t len = (uint8_t)FRAME_SIZE;
	unsigned int readpos = 0;
	int transmit_time = 0;
	size_t packet_size = sizeof(packet_t);

	//While still more to send in a packet, split the packet into
	//frames to transmit along physcial layer
	while(transmit_time < (int)packet_size/FRAME_SIZE + 1)
	{
		uint16_t frame_expected;
		frame_expected = frame_send_seq;
		frame.type = FRAME_DATA;
		frame.is_end = (transmit_time == (packet_size/FRAME_SIZE));
		
		//Want to make sure get the right length
		if(frame.is_end)
		{
			len = packet_size % FRAME_SIZE;	
		}
		
		memcpy(frame.payload, ((char*) packet) + readpos, len);
		
		frame.length = len;
		frame.sequence_num = frame_expected;
		
		//checksum
        frame.check = get_hash(&frame);

        //set a timer
        fd_set rfds; 
		struct timeval tv; 
		int retval;
		FD_ZERO(&rfds); 
		FD_SET(sock,&rfds);
		tv.tv_sec=0;
		tv.tv_usec=50000;

        if(frame_expected == frame_sent)
        {
        	//if the frame_expected is the frame already sent, record the same frame retransmitted
        	fprintf(outfile, "Client Data Link: frame %d of packet %d retransmited.\t(frame %d)\n",
        		transmit_time + 1, packet_sent, frame_expected);
        	num_of_retransmission++;
        }
        else
        {
        	//do error simulation 
        	flip_frame(&frame);
        	fprintf(outfile, "Client Data Link: frame %d of packet %d sent.\t(frame %d)\n",
        		transmit_time + 1, packet_sent, frame_expected);
        	
        } 
        
        //send along physcial layer;
		physical_send(sock, &frame);
		num_of_frame_sent ++;
		frame_sent = frame_send_seq;
		bool valid = false;
		
		//while not valid, keep receiving
		while (!valid)
		{
			int frame_ack = 1;
			//start the timer;
			retval = select(sock+1, &rfds,0, 0, &tv);
			if(retval == 0)
			{
				fprintf(outfile, "Client Data Link: time out after frame %d of packet %d sent.\t(frame %d)\n",
        		transmit_time + 1, packet_sent, frame_expected);
				break;
			}
			else if(retval < 0)
			{
				DieWithError("Fail to set timer");
			}
			else{
				FD_ISSET(0, &rfds);
			}
			
			frame_ack = datalink_recvACK(sock, &ack_frame);
			fprintf(outfile, "Client Data Link: ACK frame %d of packet %d received.\t(ACK frame %d)\n",
        		transmit_time + 1, packet_sent, ack_frame.sequence_num);
			
			//check whether the frame received is valid.
			valid = ack_frame.check == get_hash(&ack_frame);
			if(!valid)
			{
				fprintf(outfile, "Client Data Link: ACK frame %d of packet %d received in error.(ACK frame %d)\n",
        		transmit_time + 1, packet_sent, ack_frame.sequence_num);
        		num_of_errorACK ++;
			}
			else
			{
				num_of_goodACK ++;
			}

			if(!frame_ack)
				valid = false;
        	//log_debug("ack_frame %d is valid? %d", frame.sequence_num, valid);
        }
        //if the frame acked succesfully, ready to send the next one
        if(valid)
        {
        	
			readpos += len;
			frame_send_seq++;
			transmit_time++;
        }

        if(packet->last_photo && packet ->is_end && frame.is_end)
        {
        	fprintf(outfile, "\nTotal frame sent: %d\nTotal retransmission: %d\nTotal goodACK: %d\nTotal badACK: %d\n\n",
        	 num_of_frame_sent, num_of_retransmission, num_of_goodACK, num_of_errorACK);
        }

	}

	//record the packet sent number
	packet_sent++;
	return packet_size;
}
Exemplo n.º 3
0
/***********************************************************************
* plugin main ppu thread
***********************************************************************/
static void vsh_menu_thread(uint64_t arg)
{
    #ifdef DEBUG
    dbg_init();
    dbg_printf("programstart:\n");
    #endif

    uint16_t oldpad = 0, curpad = 0;
    CellPadData pdata;

    // wait for XMB, feedback
    sys_timer_sleep(13);

    //vshtask_notify("sprx running...");

    play_rco_sound("system_plugin", "snd_trophy");

    #ifdef HAVE_STARFIELD
    init_once(/* stars */);
    #endif

    // custom bg_color init
    a = GET_A(bg_color_menu[1]);
    r = GET_R(bg_color_menu[1]);
    g = GET_G(bg_color_menu[1]);
    b = GET_B(bg_color_menu[1]);

    while(1)
    {
        // if VSH Menu is running, we get pad data over our MyPadGetData()
        // else, we use the vsh pad_data struct
        if(menu_running)
            MyPadGetData(0, &pdata);
        else
            VSHPadGetData(&pdata);

        // if pad_data and we are in XMB(vshmain_EB757101() == 0)
        if((pdata.len > 0)
        && (vshmain_EB757101() == 0)
        )
        {
            curpad = (pdata.button[2] | (pdata.button[3] << 8));

            if((curpad & PAD_SELECT) && (curpad != oldpad))
            {
                switch(menu_running)
                {
                    // VSH Menu not running, start VSH Menu
                    case 0:
                      // main view and start on first entry 
                      view = line = 0;

                      //
                      pause_RSX_rendering();

                      // create VSH Menu heap memory from memory container 1("app")
                      create_heap(64);       // 64 MB

                      // initialize VSH Menu graphic (init drawing context, alloc buffers, blah, blah, blah...)
                      init_graphic();

                      // stop vsh pad
                      start_stop_vsh_pad(0);

                      // set menu_running
                      menu_running = 1;

                      break;

                    // VSH Menu is running, stop VSH Menu
                    case 1:
                      stop_VSH_Menu();

                      // restart vsh pad
                      start_stop_vsh_pad(1);

                      break;
                }

                oldpad = 0;
                sys_timer_usleep(300000);
            }


          // VSH Menu is running, draw menu / check pad
          if(menu_running)
          {
                #ifdef DEBUG
                dbg_printf("%p\n", pdata);
                #endif

                draw_frame(&pdata);

                flip_frame();

                if(curpad != oldpad)
                {

                    if(curpad & PAD_UP)
                    {
                        if(line <= 0){
                            line = 0;
                        }else{
                            line--;
                            play_rco_sound("system_plugin", "snd_cursor");
                        }
                    }

                    if(curpad & PAD_DOWN)
                    {
                        if(line >= max_menu[view]-1){
                            line = max_menu[view]-1;
                        }else{
                            line++;
                            play_rco_sound("system_plugin", "snd_cursor");
                        }
                    }

                    if(curpad & PAD_LEFT
                    || curpad & PAD_RIGHT) do_leftright_action(curpad);

                    if(curpad & PAD_CROSS) do_menu_action();

                }

                // ...

                sys_timer_usleep(30);

            } // end VSH Menu is running

            oldpad = curpad;
        }else{
            oldpad = 0;
        }
    }

    #ifdef DEBUG
    dbg_fini();
    #endif
    sys_ppu_thread_exit(0);
}