/** @file wlan_exp_ip_udp_socket_t.c * @brief Mango wlan_exp IP/UDP Library (Socket) * * @copyright Copyright 2014-2019, Mango Communications. All rights reserved. * Distributed under the Mango Reference Design license (https://mangocomm.com/802.11/license) */ /***************************** Include Files *********************************/ #include "wlan_mac_high_sw_config.h" #if WLAN_SW_CONFIG_ENABLE_WLAN_EXP // Xilinx / Standard library includes #include "xparameters.h" #include "xstatus.h" #include "xil_io.h" #include "stdlib.h" #include "stdio.h" #include "string.h" // Mango wlan_exp IP/UDP Library includes #include "wlan_exp_ip_udp.h" #include "wlan_exp_ip_udp_socket.h" #include "wlan_exp_ip_udp_arp.h" #include "wlan_high_types.h" /*********************** Global Variable Definitions *************************/ wlan_exp_ip_udp_socket_t ETH_sockets[WLAN_EXP_IP_UDP_NUM_SOCKETS]; /*************************** Function Prototypes *****************************/ int _socket_check(int socket_index); wlan_exp_ip_udp_socket_t* _socket_get_l(int socket_index); wlan_exp_ip_udp_socket_t* _socket_alloc_l(); /******************************** Functions **********************************/ /*****************************************************************************/ /** * Initialize the Socket structures * * @param None * * @return None * ******************************************************************************/ void socket_init() { u32 i; // Initialize all the sockets for (i = 0; i < WLAN_EXP_IP_UDP_NUM_SOCKETS; i++) { ETH_sockets[i].index = i; ETH_sockets[i].state = SOCKET_CLOSED; } } /*****************************************************************************/ /** * Allocate a socket from the library * * @param domain - Communications domain in which a socket is to be created * - AF_INET - Inter-network: UDP, TCP, etc. (only supported value) * @param type - Type of socket to be created * - SOCK_DGRAM - Socket datagram (connectionless) (UDP) (only supported value) * @param protocol - Particular protocol to be used with the socket * - 0 - Use default protocol appropriate for the requested socket type (only supported value) * * @return int - Socket Index * - WLAN_EXP_IP_UDP_FAILURE if there was an error * * @note Only UDP sockets are supported: socket_alloc(AF_INET, SOCK_DGRAM, 0); * *****************************************************************************/ int socket_alloc(int domain, int type, int protocol) { wlan_exp_ip_udp_socket_t* socket = NULL; // Check this is an appropriate socket if ((domain == AF_INET) && (type == SOCK_DGRAM) && (protocol == 0)) { // Allocate the socket from the library socket = _socket_alloc_l(); if (socket != NULL) { // Record values in the socket socket->sin_family = domain; // Return the index of the socket return socket->index; } } else { // !!! TBD !!! - Print error message } return WLAN_FAILURE; } /*****************************************************************************/ /** * Bind the socket to an Ethernet device * * @param socket_index - Index of the socket * @param port - Port to bind * * @return int - Status * - WLAN_EXP_IP_UDP_SUCCESS if socket is bound * - WLAN_EXP_IP_UDP_FAILURE if there was an error * *****************************************************************************/ int socket_bind_eth(int socket_index, u16 port) { wlan_exp_ip_udp_socket_t* socket; u8 ip_addr[IP_ADDR_LEN]; // Ethernet device IP address eth_get_ip_addr(ip_addr); // Get the socket from the socket index socket = _socket_get_l(socket_index); if (socket != NULL) { // Populate the socket socket->state = SOCKET_OPEN; socket->sin_port = port; // This is a recent change. We store the IP address little endian. It must be // endian swapped in order to be used in any outgoing transmissions. Previous // code was inconsistent -- swapping some things (like IP address) and not others // (like port). memcpy(socket->sin_addr, ip_addr, IP_ADDR_LEN); } else { // !!! TBD !!! - Print error message return WLAN_FAILURE; } return WLAN_SUCCESS; } sockaddr_in_t socket_get(int socket_index){ sockaddr_in_t sockaddr_in; bzero(&sockaddr_in, sizeof(sockaddr_in_t)); wlan_exp_ip_udp_socket_t* socket = _socket_get_l(socket_index); if(socket == NULL) return sockaddr_in; sockaddr_in.sin_family = AF_INET; memcpy(sockaddr_in.sin_addr.s_addr, socket->sin_addr, IP_ADDR_LEN); sockaddr_in.sin_port = socket->sin_port; return sockaddr_in; } /*****************************************************************************/ /** * Close a socket * * @param socket_index - Index of socket to send the message on * @param to - Pointer to socket address structure to send the data * @param buffers - Array of wlan_exp_ip_udp_buffer describing data to send * @param num_buffers - Number of wlan_exp_ip_udp_buffer in array * * @return int - Socket Index * WLAN_EXP_IP_UDP_FAILURE if there was an error * *****************************************************************************/ void socket_close(int socket_index) { wlan_exp_ip_udp_socket_t * socket = NULL; // Get the socket from the socket index socket = _socket_get_l(socket_index); if (socket != NULL) { // Mark the socket as CLOSED socket->state = SOCKET_CLOSED; } else { xil_printf("Error, unable to to close socket %d\n", socket_index); } } /*****************************************************************************/ /** * Find the socket_index by Ethernet device & Port * * @param port - Port of the socket * * @return int - Socket Index * WLAN_EXP_IP_UDP_FAILURE if there was an error * *****************************************************************************/ int socket_find_index_by_port(u16 port) { u32 i; int socket_index = SOCKET_INVALID_SOCKET; // Search through socket pool for (i = 0; i < WLAN_EXP_IP_UDP_NUM_SOCKETS; i++) { // Check socket parameters if ((ETH_sockets[i].state == SOCKET_OPEN) && (ETH_sockets[i].sin_port == port ) ) { socket_index = i; break; } } return socket_index; } /**********************************************************************************************************************/ /** * @brief Internal Methods * **********************************************************************************************************************/ /******************************************************************************/ /** * Allocate a socket from the global pool * * @param None * * @return wlan_exp_ip_udp_socket_t * - Pointer to the socket * NULL if not able to get the socket * *****************************************************************************/ wlan_exp_ip_udp_socket_t* _socket_alloc_l() { u32 i; int socket_index = SOCKET_INVALID_SOCKET; wlan_exp_ip_udp_socket_t* socket = NULL; // Search through socket pool for a closed socket for (i = 0; i < WLAN_EXP_IP_UDP_NUM_SOCKETS; i++) { if (ETH_sockets[i].state == SOCKET_CLOSED) { socket_index = i; break; } } if (socket_index != SOCKET_INVALID_SOCKET) { // Get the socket from the global structure socket = &(ETH_sockets[socket_index]); // Set the socket state to "ALLOCATED" socket->state = SOCKET_ALLOCATED; } else { // !!! TBD !!! - Print error message } return socket; } /******************************************************************************/ /** * Get a pointer to the socket from the socket index * * @param socket_index - Index of the socket * * @return wlan_exp_ip_udp_socket_t * - Pointer to the socket * NULL if not able to get the socket * *****************************************************************************/ wlan_exp_ip_udp_socket_t* _socket_get_l(int socket_index) { wlan_exp_ip_udp_socket_t* socket = NULL; // Check the socket index if (_socket_check(socket_index) == WLAN_SUCCESS) { // Get the socket from the global structure socket = &(ETH_sockets[socket_index]); // Check the socket status; if it is closed, then return NULL if (socket->state == SOCKET_CLOSED) { // !!! TBD !!! - Print error message socket = NULL; } } return socket; } /*****************************************************************************/ /** * Check the socket index * * @param socket_index - Index of the socket * * @return int - Status of the command: * WLAN_SUCCESS - Command completed successfully * WLAN_FAILURE - There was an error in the command * *****************************************************************************/ int _socket_check(int socket_index) { // Check that the socket_index is valid if ((socket_index < 0) || (socket_index > WLAN_EXP_IP_UDP_NUM_SOCKETS)) { // !!! TBD !!! - Print error message return WLAN_FAILURE; } return WLAN_SUCCESS; } #endif // #if WLAN_SW_CONFIG_ENABLE_WLAN_EXP