/************************************************************************ * 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" */ } }
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*/ }