示例#1
0
文件: fnet_ping.c 项目: rschuck/K64f
/************************************************************************
* NAME: fnet_ping_state_machine
*
* DESCRIPTION: PING service state machine.
************************************************************************/
static void fnet_ping_state_machine(void *fnet_ping_if_p)
{
    fnet_int32_t            received;    
    fnet_icmp_echo_header_t *hdr;
    fnet_ping_if_t          *ping_if = (fnet_ping_if_t *)fnet_ping_if_p;
    struct sockaddr         addr;
    fnet_size_t             addr_len = sizeof(addr);

    switch(ping_if->state)
    {
        /*===================================*/ 
        case FNET_PING_STATE_SENDING_REQUEST:
            /* Build message.*/
            hdr = (fnet_icmp_echo_header_t *)&fnet_ping_if.buffer[0];

            /* Fill ICMP Echo request header.*/
            fnet_memset_zero(hdr, sizeof(*hdr));
            hdr->header.type = (fnet_uint8_t)((fnet_ping_if.family == AF_INET) ? FNET_ICMP_ECHO: FNET_ICMP6_TYPE_ECHO_REQ);
            hdr->identifier = FNET_CFG_PING_IDENTIFIER;
            fnet_ping_if.sequence_number++;
            hdr->sequence_number = fnet_htons(fnet_ping_if.sequence_number);
            
            /* Fill payload data by pattern.*/
            fnet_memset(&fnet_ping_if.buffer[sizeof(*hdr)], ping_if->pattern, ping_if->packet_size);
                
            /* Checksum.*/
#if FNET_CFG_IP4
            if(ping_if->family == AF_INET)
            {
                hdr->header.checksum = fnet_checksum_buf(&fnet_ping_if.buffer[0], (sizeof(*hdr) + ping_if->packet_size));
            }
            else
#endif  
#if FNET_CFG_IP6
            if(ping_if->family == AF_INET6)
            {
                const fnet_ip6_addr_t   *src_ip = fnet_ip6_select_src_addr(FNET_NULL, (fnet_ip6_addr_t *)ping_if->target_addr.sa_data); /*TBD  Check result.*/

                hdr->header.checksum = fnet_checksum_pseudo_buf(&fnet_ping_if.buffer[0], 
                                                                (fnet_uint16_t)(sizeof(*hdr) + ping_if->packet_size), 
                                                                FNET_HTONS((fnet_uint16_t)IPPROTO_ICMPV6), 
                                                                (const fnet_uint8_t *)src_ip,
                                                                ping_if->target_addr.sa_data, 
                                                                sizeof(fnet_ip6_addr_t));
            }
            else
#endif 
            {}
            
            /* Send request.*/    
            fnet_socket_sendto(fnet_ping_if.socket_foreign, (fnet_uint8_t*)(&fnet_ping_if.buffer[0]), (sizeof(*hdr) + ping_if->packet_size), 0u,  &ping_if->target_addr, sizeof(ping_if->target_addr));
            ping_if->packet_count--;
           
            fnet_ping_if.send_time = fnet_timer_ticks();        
            
            ping_if->state = FNET_PING_STATE_WAITING_REPLY;
            break;
        /*===================================*/    
        case  FNET_PING_STATE_WAITING_REPLY:
            /* Receive data */
            
            received = fnet_socket_recvfrom(ping_if->socket_foreign, (fnet_uint8_t*)(&ping_if->buffer[0]), FNET_PING_BUFFER_SIZE, 0u, &addr, &addr_len );
            
            if(received > 0 )
            {
                fnet_uint16_t  checksum = 0u;
                
                hdr = (fnet_icmp_echo_header_t *)(ping_if->buffer);
                
                
                /* Check checksum.*/
#if FNET_CFG_IP4
                if(ping_if->family == AF_INET)
                {
                    checksum = fnet_checksum_buf(&fnet_ping_if.buffer[0], (fnet_size_t)received);
                }
                else
#endif  
#if 0 /* #if FNET_CFG_IP6  */ /* TBD case to receive from multicast address ff02::1*/
                if(ping_if->family == AF_INET6)
                {
                     checksum = fnet_checksum_pseudo_buf(&fnet_ping_if.buffer[0], 
                                                                (fnet_uint16_t)(received), 
                                                                IPPROTO_ICMPV6, 
                                                                ping_if->local_addr.sa_data,
                                                                ping_if->target_addr.sa_data, 
                                                                sizeof(fnet_ip6_addr_t));
                }
                else    
#endif                               
                {}
 
                /* Check header.*/
                if( checksum
                    ||(hdr->header.type != ((addr.sa_family == AF_INET) ? FNET_ICMP_ECHOREPLY: FNET_ICMP6_TYPE_ECHO_REPLY))
                    ||(hdr->identifier != FNET_CFG_PING_IDENTIFIER)
                    ||(hdr->sequence_number != fnet_htons(ping_if->sequence_number)) )
                {
                    goto NO_DATA;
                }     
                
                /* Call handler.*/
                if(ping_if->handler)   
                {
                    ping_if->handler(FNET_ERR_OK, ping_if->packet_count, &addr, ping_if->handler_cookie);
                }
                    
                if(ping_if->packet_count)
                {
                    ping_if->state = FNET_PING_STATE_WAITING_TIMEOUT;
                }
                else
                {
                    fnet_ping_release();              
                }
            }
            else if(received == FNET_ERR)
            {
                /* Call handler.*/
                if(ping_if->handler)
                {
                    fnet_error_t    sock_err ;
                    fnet_size_t     option_len;
                    
                    /* Get socket error.*/
                    option_len = sizeof(sock_err); 
                    fnet_socket_getopt(ping_if->socket_foreign, SOL_SOCKET, SO_ERROR, (fnet_uint8_t*)&sock_err, &option_len);
                                 
                    ping_if->handler(sock_err, ping_if->packet_count, FNET_NULL, ping_if->handler_cookie);
                }
               
                if(ping_if->packet_count)
                {
                    ping_if->state = FNET_PING_STATE_WAITING_TIMEOUT;
                }
                else
                {
                    fnet_ping_release();    
                }
            }
            else /* No data. Check timeout */
            {
NO_DATA:            
                if(fnet_timer_get_interval(fnet_ping_if.send_time, fnet_timer_ticks()) > fnet_ping_if.timeout_clk)
                {
                    /* Call handler.*/
                    if(ping_if->handler)   
                    {
                        ping_if->handler(FNET_ERR_TIMEDOUT, ping_if->packet_count, FNET_NULL, ping_if->handler_cookie);
                    }
                        
                    if(ping_if->packet_count)
                    {
                        ping_if->state = FNET_PING_STATE_SENDING_REQUEST;
                    }
                    else
                    {
                        fnet_ping_release();    
                    }
                }
            }
            break;
        /*===================================*/             
        case FNET_PING_STATE_WAITING_TIMEOUT:
            if(fnet_timer_get_interval(fnet_ping_if.send_time, fnet_timer_ticks()) > fnet_ping_if.timeout_clk)
            {
                ping_if->state = FNET_PING_STATE_SENDING_REQUEST;
            }
            break;

        default:
            break;  /* do nothing, avoid compiler warning "enumeration value not handled in switch" */
    }
}
示例#2
0
文件: startup.c 项目: 8bitgeek/fnet
void
common_startup(void)
{
    /* Declare a counter we'll use in all of the copy loops */
    uint32 n;
    
    /* Addresses for VECTOR_TABLE and VECTOR_RAM come from the linker file */  
    extern uint32 __vector_table[];

    /* Copy the vector table to RAM */
    if ((uint32 *)FNET_CFG_CPU_VECTOR_TABLE != __vector_table)
    {
        uint32 *vector_ram = (uint32 *)FNET_CFG_CPU_VECTOR_TABLE;
			
        for (n = 0; n < 0x410; n++)
        {
            *vector_ram++= __vector_table[n];					
        }				
    }
	
    /* Point the VTOR to the new copy of the vector table */
    write_vtor((uint32)FNET_CFG_CPU_VECTOR_TABLE);

#if FNET_CFG_COMP_CW
    {
    	RomInfo *ptr_tmp = __S_romp;
    	StaticInitializer s, *p;
    	
    	/* Zero bss section*/
    	fnet_memset(__START_BSS, 0, (__END_BSS - __START_BSS));
        
        /* Copying sections from ROM to RAM.*/
        if((uint32)ptr_tmp)
		{
			int	index;
	
			/*
			 *	Go through the entire table, copying sections from ROM to RAM.
			 */
			for (index = 0;
				 __S_romp[index].Source != 0 ||
				 __S_romp[index].Target != 0 ||
				 __S_romp[index].Size != 0;
				 ++index)
			{
				copy_rom_section( __S_romp[index].Target,
									__S_romp[index].Source,
									__S_romp[index].Size );
			} 	
		}
     	
        /*	See if the static initializer table exists	*/
        if (__sinit__)
        {
        	/*	call all static initializers in the table	*/
        	for (p = __sinit__; p && (s = *p) != 0; p++)
        		s();
        }
    }    
#endif /* FNET_CFG_COMP_CW */
    
#if FNET_CFG_COMP_IAR
    {
		/* Get the addresses for the .data section (initialized data section) */
		uint8* data_ram = __section_begin(".data");
		uint8* data_rom = __section_begin(".data_init");
		uint8* data_rom_end = __section_end(".data_init");
		
		/* Copy initialized data from ROM to RAM */
		n = data_rom_end - data_rom;
		while (n--)
		  *data_ram++ = *data_rom++;
	 
	 
		/* Get the addresses for the .bss section (zero-initialized data) */
		uint8* bss_start = __section_begin(".bss");
		uint8* bss_end = __section_end(".bss");
		
		/* Clear the zero-initialized data section */
		n = bss_end - bss_start;
		while(n--)
		  *bss_start++ = 0;    
		
		/* Get addresses for any code sections that need to be copied from ROM to RAM.
		 * The IAR tools have a predefined keyword that can be used to mark individual
		 * functions for execution from RAM. Add "__ramfunc" before the return type in
		 * the function prototype for any routines you need to execute from RAM instead 
		 * of ROM. ex: __ramfunc void foo(void);
		 */
		uint8* code_relocate_ram = __section_begin("CodeRelocateRam");
		uint8* code_relocate = __section_begin("CodeRelocate");
		uint8* code_relocate_end = __section_end("CodeRelocate");
		
		/* Copy functions from ROM to RAM */
		n = code_relocate_end - code_relocate;
		while (n--)
		  *code_relocate_ram++ = *code_relocate++;
    }
#endif /*FNET_CFG_COMP_IAR*/    
}