0
mirror of https://github.com/Indemsys/Frequency_Inverter.git synced 2026-05-05 13:17:53 +00:00
Files
2022-01-04 12:22:53 +02:00

1877 lines
53 KiB
C

/**HEADER********************************************************************
*
* Copyright (c) 2008 Freescale Semiconductor;
* All Rights Reserved
*
***************************************************************************
*
* THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*
**************************************************************************
*
* $FileName: ipcfg.c$
* $Version : 3.8.36.0$
* $Date : Sep-19-2012$
*
* Comments:
*
* High level IP config functions and task.
*
*END************************************************************************/
#include <mqx.h>
#include <bsp.h>
#include <enet.h>
#include <rtcs.h>
#include <dns.h>
#include "rtcs_prv.h"
#include "tcpip.h"
#include "ip_prv.h"
#include "ipcfg.h"
#include "ipcfg_prv.h"
#ifdef BSP_ENET_DEVICE_COUNT
#if (BSP_ENET_DEVICE_COUNT > 0)
#if (RTCSCFG_IPCFG_ENABLE_DHCP || RTCSCFG_IPCFG_ENABLE_BOOT) && (! RTCSCFG_ENABLE_UDP)
#error "Please set RTCSCFG_ENABLE_UDP to 1 to enable DHCP or BOOT and recompile RTCS again!"
#endif
/* hidden global data */
static uchar ipcfg_empty_string[] = "";
static const char ipcfg_task_name[] = IPCFG_TASK_NAME;
static boolean ipcfg_task_run = FALSE;
IPCFG_CONTEXT ipcfg_data[IPCFG_DEVICE_COUNT] = {0};
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ipcfg_get_device_number()
* Returned Value : device number or -1
* Comments : Returns corresponding device number for given interface.
*
*END*-----------------------------------------------------------------*/
uint_32 ipcfg_get_device_number
(
_rtcs_if_handle ihandle
)
{
_mqx_int i;
for (i = 0; i < IPCFG_DEVICE_COUNT; i++) {
if (ipcfg_data[i].ihandle == ihandle)
break;
}
return (i < IPCFG_DEVICE_COUNT) ? i : -1;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ipcfg_add_interface()
* Returned Value : device number or -1
* Comments : Add new interface and returns corresponding device number.
*
*END*-----------------------------------------------------------------*/
uint_32 ipcfg_add_interface
(
uint_32 dev_num,
_rtcs_if_handle ihandle
)
{
_mqx_int i = IPCFG_DEVICE_COUNT;
if (dev_num != (uint_32)-1) {
if (dev_num < IPCFG_DEVICE_COUNT && ipcfg_data[dev_num].ihandle == NULL) {
ipcfg_data[dev_num].ihandle = ihandle;
i = dev_num;
}
}
else {
for (i = 0; i < IPCFG_DEVICE_COUNT; i++) {
if (ipcfg_data[i].ihandle == NULL) {
ipcfg_data[i].ihandle = ihandle;
break;
}
}
}
return (i < IPCFG_DEVICE_COUNT) ? i : -1;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ipcfg_del_interface()
* Returned Value : ipcfg error code.
* Comments : Delete interface defined by device number.
*
*END*-----------------------------------------------------------------*/
uint_32 ipcfg_del_interface (uint_32 dev_num)
{
if (dev_num < IPCFG_DEVICE_COUNT)
{
ipcfg_data[dev_num].actual_state = IPCFG_STATE_INIT;
ipcfg_data[dev_num].ihandle = NULL;
return IPCFG_OK;
}
else
return RTCSERR_IPCFG_DEVICE_NUMBER;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ipcfg_get_ihandle()
* Returned Value : interface handle or NULL
* Comments : Returns interface handle for given device number.
*
*END*-----------------------------------------------------------------*/
_rtcs_if_handle ipcfg_get_ihandle
(
uint_32 device
)
{
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].ihandle;
}
return NULL;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ipcfg_get_mac()
* Returned Value : TRUE and mac address if successful, FALSE otherwise
* Comments : Returns ethernet mac address for given device number.
*
*END*-----------------------------------------------------------------*/
boolean ipcfg_get_mac
(
uint_32 device,
_enet_address mac
)
{
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
{
ENET_get_address (((IP_IF_PTR)(ipcfg_data[device].ihandle))->HANDLE, mac);
return TRUE;
}
else
{
ENET_get_mac_address (device, 0, mac);
return TRUE;
}
}
return FALSE;
}
/*FUNCTION*-------------------------------------------------------------
*
* Function Name : ipcfg_get_state_string()
* Returned Value : state name string or NULL
* Comments : Returns const char_ptr to name of given state.
*
*END*-----------------------------------------------------------------*/
const char * ipcfg_get_state_string (IPCFG_STATE state)
{
static const char_ptr ipcfg_states[] =
{
"INIT", //"init",
"UNBOUND", //"unbound",
"BUSY", //"busy",
"MANUAL", //"staticip",
"DHCPNOAUTO", //"dhcpnoauto",
"AUTOIP", //"autoip",
"DHCP", //"dhcp",
"BOOT" //"boot"
};
if (state < sizeof (ipcfg_states))
{
return ipcfg_states[state];
}
return NULL;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_state()
* Returned Value : actual ipcfg state
* Comments : Returns ipcfg state enum element.
*
*END--------------------------------------------------------------------*/
IPCFG_STATE ipcfg_get_state
(
uint_32 device
)
{
IPCFG_STATE state = IPCFG_STATE_INIT;
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
{
if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return IPCFG_STATE_BUSY;
state = ipcfg_data[device].actual_state;
_lwsem_post (&(ipcfg_data[device].request_semaphore));
}
}
return state;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_last_state()
* Returned Value : last ipcfg state
* Comments : Returns ipcfg state enum element.
*
*END--------------------------------------------------------------------*/
IPCFG_STATE ipcfg_get_desired_state
(
uint_32 device
)
{
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].desired_state;
}
return IPCFG_STATE_INIT;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_link_active()
* Returned Value : TRUE if link active, FALSE otherwise
* Comments : Returns actual link state.
*
*END--------------------------------------------------------------------*/
boolean ipcfg_get_link_active
(
uint_32 device
)
{
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
return ENET_link_status (((IP_IF_PTR)(ipcfg_data[device].ihandle))->HANDLE);
}
return FALSE;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_phy_registers()
* Returned Value : TRUE if link active, FALSE otherwise
* Comments : Returns actual link state.
*
*END--------------------------------------------------------------------*/
boolean ipcfg_phy_registers
(
uint_32 device,
uint_32 num_regs,
uint_32_ptr regs_ptr
)
{
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
return ENET_phy_registers(((IP_IF_PTR)(ipcfg_data[device].ihandle))->HANDLE, num_regs,regs_ptr);
}
return FALSE;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_dns_ip()
* Returned Value : dns IP address
* Comments : Returns N-th DNS ip address from DNS list for given N.
*
*END--------------------------------------------------------------------*/
_ip_address ipcfg_get_dns_ip
(
uint_32 device,
uint_32 n
)
{
uint_32 result = 0;
#if RTCSCFG_IPCFG_ENABLE_DNS
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
{
#if RTCSCFG_ENABLE_LWDNS
if (n == 0) result = LWDNS_server_ipaddr;
#else
DNS_SLIST_STRUCT _PTR_ temp_ptr;
for (temp_ptr = DNS_First_Local_server; (temp_ptr != NULL) && (n != 0); temp_ptr = temp_ptr->NEXT) n--;
if (temp_ptr != NULL)
{
result = temp_ptr->IPADDR;
}
#endif
}
}
#endif
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_add_dns_ip()
* Returned Value : TRUE if successful, FALSE otherwise
* Comments : Adds/updates DNS ip address info inside DNS list and
* starts the DNS machine, if not running already.
*
*END--------------------------------------------------------------------*/
boolean ipcfg_add_dns_ip
(
uint_32 device,
_ip_address address
)
{
boolean result = FALSE;
#if RTCSCFG_IPCFG_ENABLE_DNS
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
{
#if RTCSCFG_ENABLE_LWDNS
LWDNS_server_ipaddr = address;
result = TRUE;
#else
DNS_CONTROL_STRUCT _PTR_ control_ptr = RTCS_getcfg(DNS);
DNS_SLIST_STRUCT slist_entry;
if (control_ptr == NULL)
{
DNS_init();
}
DNS_init_slist_entry (&slist_entry);
slist_entry.IPADDR = address;
if (DNS_add_slist_entry (&slist_entry) == DNS_OK)
{
result = TRUE;
}
#endif
}
}
#endif
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_del_dns_ip()
* Returned Value : TRUE if successful, FALSE otherwise
* Comments : Removes given address from DNS list, if exists.
*
*END--------------------------------------------------------------------*/
boolean ipcfg_del_dns_ip
(
uint_32 device,
_ip_address address
)
{
boolean result = FALSE;
#if RTCSCFG_IPCFG_ENABLE_DNS
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
{
#if RTCSCFG_ENABLE_LWDNS
if (LWDNS_server_ipaddr == address)
{
LWDNS_server_ipaddr = 0;
result = TRUE;
}
#else
DNS_remove_slist_entry (address);
result = TRUE;
#endif
}
}
#endif
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_ip()
* Returned Value : TRUE and IP, mask and gateway, if successful
* Comments : Returns actual ip information from DHCP response, if any.
*
*END--------------------------------------------------------------------*/
boolean ipcfg_get_ip
(
uint_32 device,
IPCFG_IP_ADDRESS_DATA_PTR data
)
{
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
{
*data = ipcfg_data[device].actual_ip_data;
return TRUE;
}
}
return FALSE;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_tftp_serveraddress()
* Returned Value : _ip_address
* Comments : Returns TFTP serveraddress, if any.
*
*END--------------------------------------------------------------------*/
_ip_address ipcfg_get_tftp_serveraddress
(
uint_32 device
)
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].tftp_serveraddress;
}
#endif
return 0;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_tftp_servername()
* Returned Value : pointer to string servername
* Comments : Returns TFTP servername, if any.
*
*END--------------------------------------------------------------------*/
uchar_ptr ipcfg_get_tftp_servername
(
uint_32 device
)
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].tftp_servername;
}
#endif
return ipcfg_empty_string;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_get_boot_filename()
* Returned Value : pointer to string filename
* Comments : Returns boot filename, if any.
*
*END--------------------------------------------------------------------*/
uchar_ptr ipcfg_get_boot_filename
(
uint_32 device
)
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
if (device < IPCFG_DEVICE_COUNT)
{
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT) return ipcfg_data[device].boot_filename;
}
#endif
return ipcfg_empty_string;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_unbind_internal_actual()
* Returned Value : ipcfg error code
* Comments : Actual unbind process.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_unbind_internal_actual
(
uint_32 device
)
{
if (ipcfg_data[device].actual_ip_data.ip != 0)
{
if ((ipcfg_data[device].actual_state == IPCFG_STATE_DHCP_IP) || (ipcfg_data[device].actual_state == IPCFG_STATE_DHCPAUTO_IP))
{
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
DHCPCLNT_release (ipcfg_data[device].ihandle);
#endif
}
else if ((ipcfg_data[device].actual_state == IPCFG_STATE_STATIC_IP) || (ipcfg_data[device].actual_state == IPCFG_STATE_AUTO_IP) || (ipcfg_data[device].actual_state == IPCFG_STATE_BOOT))
{
RTCS_if_unbind (ipcfg_data[device].ihandle, ipcfg_data[device].actual_ip_data.ip);
}
}
#if RTCSCFG_ENABLE_GATEWAYS
if (ipcfg_data[device].actual_ip_data.gateway != 0)
{
RTCS_gate_remove (ipcfg_data[device].actual_ip_data.gateway, INADDR_ANY, INADDR_ANY);
}
#endif
#if RTCSCFG_IPCFG_ENABLE_DNS
if (ipcfg_data[device].dns != 0)
{
ipcfg_del_dns_ip (device, ipcfg_data[device].dns);
}
ipcfg_data[device].dns = 0;
#endif
ipcfg_data[device].actual_ip_data.ip = 0;
ipcfg_data[device].actual_ip_data.mask = 0;
ipcfg_data[device].actual_ip_data.gateway = 0;
#if RTCSCFG_IPCFG_ENABLE_BOOT
ipcfg_data[device].tftp_serveraddress = 0;
ipcfg_data[device].tftp_servername[0] = ipcfg_empty_string[0];
ipcfg_data[device].boot_filename[0] = ipcfg_empty_string[0];
#endif
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
ipcfg_data[device].dhcp_retries = 0;
#endif
ipcfg_data[device].actual_state = IPCFG_STATE_UNBOUND;
return IPCFG_OK;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_unbind_internal()
* Returned Value : ipcfg error code
* Comments : Control semaphore unprotected unbind.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_unbind_internal
(
uint_32 device
)
{
uint_32 result;
if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
result = ipcfg_unbind_internal_actual (device);
_lwsem_post (&(ipcfg_data[device].request_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_unbind()
* Returned Value : ipcfg error code
* Comments : Releases any ip information associated with given device.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_unbind
(
uint_32 device
)
{
uint_32 result;
if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;
if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
result = ipcfg_unbind_internal (device);
if (result == IPCFG_OK)
{
ipcfg_data[device].desired_ip_data = ipcfg_data[device].actual_ip_data;
ipcfg_data[device].desired_state = ipcfg_data[device].actual_state;
}
_lwsem_post (&(ipcfg_data[device].control_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_staticip_internal()
* Returned Value : ipcfg error code
* Comments : Actual static bind process.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_bind_staticip_internal
(
uint_32 device,
IPCFG_IP_ADDRESS_DATA_PTR static_ip_data
)
{
uint_32 result;
if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
ipcfg_unbind_internal_actual (device);
if (static_ip_data == NULL)
{
static_ip_data = &(ipcfg_data[device].desired_ip_data);
}
result = RTCSERR_IPCFG_BIND;
if (RTCS_if_probe_and_bind (ipcfg_data[device].ihandle, static_ip_data->ip, static_ip_data->mask) == RTCS_OK)
{
ipcfg_data[device].desired_ip_data.ip = static_ip_data->ip;
ipcfg_data[device].desired_ip_data.mask = static_ip_data->mask;
ipcfg_data[device].desired_ip_data.gateway = static_ip_data->gateway;
ipcfg_data[device].actual_ip_data.ip = static_ip_data->ip;
ipcfg_data[device].actual_ip_data.mask = static_ip_data->mask;
#if RTCSCFG_ENABLE_GATEWAYS
if (static_ip_data->gateway != 0)
{
if (RTCS_gate_add (static_ip_data->gateway, INADDR_ANY, INADDR_ANY) == RTCS_OK)
{
ipcfg_data[device].actual_ip_data.gateway = static_ip_data->gateway;
}
}
#endif
ipcfg_data[device].desired_state = IPCFG_STATE_STATIC_IP;
ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
result = IPCFG_OK;
}
_lwsem_post (&(ipcfg_data[device].request_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_staticip()
* Returned Value : ipcfg error code
* Comments : Tries to bind given static ip for given device.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_bind_staticip
(
uint_32 device,
IPCFG_IP_ADDRESS_DATA_PTR static_ip_data
)
{
uint_32 result;
if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;
if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
result = ipcfg_bind_staticip_internal (device, static_ip_data);
_lwsem_post (&(ipcfg_data[device].control_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_autoip_internal_actual()
* Returned Value : ipcfg error code
* Comments : Actual auto bind process.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_bind_autoip_internal_actual
(
uint_32 device,
IPCFG_IP_ADDRESS_DATA_PTR auto_ip_data
)
{
uint_32 attempts;
uint_32 result;
ipcfg_unbind_internal_actual (device);
if (auto_ip_data == NULL)
{
auto_ip_data = &(ipcfg_data[device].desired_ip_data);
}
result = RTCSERR_IPCFG_BIND;
for (attempts = 0; attempts < IPCFG_MAX_AUTOIP_ATTEMPTS; attempts++)
{
if (RTCS_if_probe_and_bind (ipcfg_data[device].ihandle, auto_ip_data->ip, auto_ip_data->mask) == RTCS_OK)
{
ipcfg_data[device].desired_ip_data.ip = auto_ip_data->ip;
ipcfg_data[device].desired_ip_data.mask = auto_ip_data->mask;
ipcfg_data[device].desired_ip_data.gateway = auto_ip_data->gateway;
ipcfg_data[device].actual_ip_data.ip = auto_ip_data->ip;
ipcfg_data[device].actual_ip_data.mask = auto_ip_data->mask;
#if RTCSCFG_ENABLE_GATEWAYS
if (auto_ip_data->gateway != 0)
{
if (RTCS_gate_add (auto_ip_data->gateway, INADDR_ANY, INADDR_ANY) == RTCS_OK)
{
ipcfg_data[device].actual_ip_data.gateway = auto_ip_data->gateway;
}
}
#endif
ipcfg_data[device].desired_state = IPCFG_STATE_AUTO_IP;
ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
result = IPCFG_OK;
break;
}
do
{
auto_ip_data->ip = (auto_ip_data->ip & auto_ip_data->mask) | ((auto_ip_data->ip + 1) & (~ auto_ip_data->mask));
} while (auto_ip_data->ip & (~ auto_ip_data->mask) == 0);
}
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_autoip_internal()
* Returned Value : ipcfg error code
* Comments : Control semaphore unprotected auto bind.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_bind_autoip_internal
(
uint_32 device,
IPCFG_IP_ADDRESS_DATA_PTR auto_ip_data
)
{
uint_32 result;
if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
result = ipcfg_bind_autoip_internal_actual (device, auto_ip_data);
_lwsem_post (&(ipcfg_data[device].request_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_autoip()
* Returned Value : ipcfg error code
* Comments : Tries to bind given ip address data for given device and
* continues incrementing ip until bound or maximum tries reached.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_bind_autoip
(
uint_32 device,
IPCFG_IP_ADDRESS_DATA_PTR auto_ip_data
)
{
uint_32 result;
if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;
if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
result = ipcfg_bind_autoip_internal (device, auto_ip_data);
_lwsem_post (&(ipcfg_data[device].control_semaphore));
return result;
}
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_dhcp_choice_func()
* Returned Value : 0 == not acceptable
* Comments : This function is used to choose if a DHCPOFFER is
* acceptable. If it is, the Client will request the
* lease with the parameters given.
*
*END--------------------------------------------------------------------*/
static int_32 ipcfg_dhcp_choice_func
(
uchar_ptr buffer_ptr,
uint_32 buffer_size
)
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("DHCP choice func.\n");
#endif
return 1;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_dhcp_func()
* Returned Value : void
* Comments : This function is called when the DHCP interface is bound
* to inform the application that a network connection has
* been established. Can be used to trigger an event, etc..
*
*END--------------------------------------------------------------------*/
static void ipcfg_bind_dhcp_func
(
uchar_ptr buffer_ptr,
uint_32 buffer_size,
_rtcs_if_handle ihandle
)
{
uchar_ptr optptr;
uint_32 optlen;
DHCP_HEADER_PTR dhcp_ptr = (DHCP_HEADER_PTR)buffer_ptr;
uint_32 device = ipcfg_get_device_number (ihandle);
if (device >= IPCFG_DEVICE_COUNT)
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("DHCP bind func - wrong device number.\n");
#endif
return;
}
if ((buffer_ptr == NULL) || (buffer_size == 0))
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("DHCP bind func - lease not obtained.\n");
#endif
}
else
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("DHCP bind func - success.\n");
#endif
ipcfg_data[device].actual_ip_data.ip = ntohl (dhcp_ptr->YIADDR);
optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_MASK);
if (optptr)
{
optptr++;
optlen = ntohc (optptr);
optptr++;
if (optlen >= 4)
{
ipcfg_data[device].actual_ip_data.mask = ntohl (optptr);
}
}
#if RTCSCFG_ENABLE_GATEWAYS
optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_ROUTER);
if (optptr) {
optptr++;
optlen = ntohc (optptr);
optptr++;
if (optlen >= 4)
{
ipcfg_data[device].actual_ip_data.gateway = ntohl (optptr);
}
}
#endif
#if RTCSCFG_IPCFG_ENABLE_DNS
optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_DNSSERVER);
if (optptr)
{
optptr++;
optlen = ntohc (optptr);
optptr++;
if (optlen >= 4)
{
ipcfg_data[device].dns = ntohl (optptr);
}
}
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_TFTPSERVER);
if (optptr)
{
optptr++;
optlen = ntohc (optptr);
optptr++;
if (optlen >= RTCS_SNAME_LEN - 1) optlen = RTCS_SNAME_LEN - 2;
_mem_copy (optptr, ipcfg_data[device].tftp_servername, optlen);
ipcfg_data[device].tftp_servername[optlen + 1] = '\0';
}
else
{
_mem_copy (dhcp_ptr->SNAME, ipcfg_data[device].tftp_servername, RTCS_SNAME_LEN);
ipcfg_data[device].tftp_servername[RTCS_SNAME_LEN - 1] = '\0';
}
optptr = DHCPCLNT_find_option (buffer_ptr, buffer_size, DHCPOPT_BOOTFILENAME);
if (optptr)
{
optptr++;
optlen = ntohc (optptr);
optptr++;
if (optlen >= RTCS_BOOTFILE_LEN - 1) optlen = RTCS_BOOTFILE_LEN - 2;
_mem_copy (optptr, ipcfg_data[device].boot_filename, optlen);
ipcfg_data[device].boot_filename[optlen + 1] = '\0';
}
else
{
_mem_copy (dhcp_ptr->FILE, ipcfg_data[device].boot_filename, RTCS_BOOTFILE_LEN);
ipcfg_data[device].boot_filename[RTCS_BOOTFILE_LEN - 1] = '\0';
}
#endif
if (ipcfg_data[device].actual_state == IPCFG_STATE_UNBOUND)
ipcfg_data[device].actual_state = IPCFG_STATE_BUSY;
}
if (ipcfg_data[device].actual_state == IPCFG_STATE_BUSY)
_lwsem_post (&(ipcfg_data[device].dhcp_response_semaphore));
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_dhcp_nak_func()
* Returned Value : boolean
* Comments : This function is called when the DHCP interface is bound
* to inform the application that a network connection has
* been established. Can be used to trigger an event, etc..
*
*END--------------------------------------------------------------------*/
static boolean ipcfg_dhcp_nak_func
(
uchar_ptr buffer_ptr,
uint_32 buffer_size,
_rtcs_if_handle ihandle
)
{
uint_32 device = ipcfg_get_device_number (ihandle);
#if IPCFG_DEBUG_LEVEL >= 1
printf("DHCP nak func - ");
#endif
if (device >= IPCFG_DEVICE_COUNT)
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("wrong device number.\n");
#endif
return FALSE;
}
if (ipcfg_data[device].dhcp_retries++ < IPCFG_MAX_NAK_RETRIES)
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("retry %d.\n", ipcfg_data[device].dhcp_retries);
#endif
return TRUE;
}
else
{
#if IPCFG_DEBUG_LEVEL >= 1
printf ("abort.\n");
#endif
return FALSE;
}
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_dhcp_unbind_func()
* Returned Value : boolean
* Comments : This function is called when the DHCP lease terminates.
* It allows the application the flexibility to decide if
* it wishes to re-bind the interface again or terminate the
* DHCP client and permanently unbind.
*
*END--------------------------------------------------------------------*/
static boolean ipcfg_dhcp_unbind_func
(
_rtcs_if_handle ihandle
)
{
#if IPCFG_DEBUG_LEVEL >= 1
printf("DHCP unbind func.\n");
#endif
// remove gateway here
return( TRUE );
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_dhcp_fail_func()
* Returned Value : boolean
* Comments : This function is called when a DHCP failure is detected
* This is will invoked if the a NAK is recieved from the server
*
*END--------------------------------------------------------------------*/
static boolean ipcfg_dhcp_fail_func
(
_rtcs_if_handle ihandle
)
{
uint_32 device = ipcfg_get_device_number (ihandle);
#if IPCFG_DEBUG_LEVEL >= 1
printf("DHCP fail func.\n");
#endif
if (device < IPCFG_DEVICE_COUNT)
{
_lwsem_post(&(ipcfg_data[device].dhcp_response_semaphore));
}
return FALSE;
}
#endif
/*FUNCTION*-----------------------------------------------------------------
*
* Function Name : ipcfg_bind_dhcp_internal()
* Returned Value : ipcfg error code
* Comments : Actual DHCP start process.
*
*END------------------------------------------------------------------*/
static uint_32 ipcfg_bind_dhcp_internal
(
uint_32 device,
boolean try_auto_ip
)
{
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
DHCP_DATA_STRUCT options;
uchar_ptr optptr;
uchar DHCP_option_array[256];
uint_32 optlen = sizeof (DHCP_option_array);
uchar parm_options[] = {DHCPOPT_MASK, DHCPOPT_DNSSERVER, DHCPOPT_ROUTER, DHCPOPT_TFTPSERVER, DHCPOPT_BOOTFILENAME};
uint_32 error = 0;
uint_32 result = IPCFG_OK;
if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
ipcfg_unbind_internal_actual (device);
options.CHOICE_FUNC = ipcfg_dhcp_choice_func;
options.BIND_FUNC = ipcfg_bind_dhcp_func;
options.UNBIND_FUNC = ipcfg_dhcp_unbind_func;
options.FAILURE_FUNC = ipcfg_dhcp_fail_func;
options.NAK_FUNC = ipcfg_dhcp_nak_func;
optptr = DHCP_option_array;
DHCP_option_variable (&optptr, &optlen, DHCPOPT_PARAMLIST, parm_options, sizeof (parm_options));
error = RTCS_if_bind_DHCP (ipcfg_data[device].ihandle, &options, DHCP_option_array, optptr - DHCP_option_array);
if (error != RTCS_OK)
{
if (try_auto_ip)
{
_lwsem_post(&(ipcfg_data[device].dhcp_response_semaphore));
}
else
{
_lwsem_post (&(ipcfg_data[device].request_semaphore));
result = RTCSERR_IPCFG_BIND;
}
}
return result;
#else
return RTCSERR_IPCFG_BIND;
#endif
}
/*FUNCTION*-----------------------------------------------------------------
*
* Function Name : ipcfg_bind_dhcp()
* Returned Value : ipcfg error code
* Comments : Starts DHCP process for given device, locks it with semaphore.
*
*END------------------------------------------------------------------*/
uint_32 ipcfg_bind_dhcp
(
uint_32 device,
boolean try_auto_ip
)
{
uint_32 result;
if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;
if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
result = ipcfg_bind_dhcp_internal (device, try_auto_ip);
#else
result = RTCSERR_IPCFG_BIND;
#endif
_lwsem_post (&(ipcfg_data[device].control_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_poll_dhcp_internal()
* Returned Value : ipcfg error code
* Comments : Actual DHCP polling process.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_poll_dhcp_internal
(
uint_32 device,
boolean try_auto_ip,
IPCFG_IP_ADDRESS_DATA_PTR auto_ip_data
)
{
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
uint_32 result = RTCSERR_IPCFG_BUSY;
if (_lwsem_poll (&(ipcfg_data[device].dhcp_response_semaphore)))
{
if (ipcfg_data[device].actual_state == IPCFG_STATE_BUSY)
{
result = IPCFG_OK;
#if RTCSCFG_IPCFG_ENABLE_DNS
if (ipcfg_data[device].dns != 0)
{
if (! ipcfg_add_dns_ip (device, ipcfg_data[device].dns))
{
ipcfg_data[device].dns = 0;
}
}
#endif
#if RTCSCFG_ENABLE_GATEWAYS
if (ipcfg_data[device].actual_ip_data.gateway != 0)
{
if (RTCS_gate_add (ipcfg_data[device].actual_ip_data.gateway, INADDR_ANY, INADDR_ANY) != RTCS_OK)
{
ipcfg_data[device].actual_ip_data.gateway = 0;
}
}
#endif
if (auto_ip_data == NULL)
{
auto_ip_data = &(ipcfg_data[device].desired_ip_data);
}
ipcfg_data[device].desired_ip_data.ip = auto_ip_data->ip;
ipcfg_data[device].desired_ip_data.mask = auto_ip_data->mask;
ipcfg_data[device].desired_ip_data.gateway = auto_ip_data->gateway;
if (try_auto_ip)
{
ipcfg_data[device].desired_state = IPCFG_STATE_DHCPAUTO_IP;
}
else
{
ipcfg_data[device].desired_state = IPCFG_STATE_DHCP_IP;
}
ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
}
else
{
result = RTCSERR_IPCFG_BIND;
if (try_auto_ip)
{
result = ipcfg_bind_autoip_internal_actual (device, auto_ip_data);
if (result == IPCFG_OK)
{
ipcfg_data[device].desired_state = IPCFG_STATE_DHCPAUTO_IP;
ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
}
}
}
_lwsem_post (&(ipcfg_data[device].request_semaphore));
}
return result;
#else
return RTCSERR_IPCFG_BIND;
#endif
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_poll_dhcp()
* Returned Value : ipcfg error code
* Comments : Polls DHCP bind completion for given device, releases
* the device related semaphore lock.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_poll_dhcp
(
uint_32 device,
boolean try_auto_ip,
IPCFG_IP_ADDRESS_DATA_PTR auto_ip_data
)
{
uint_32 result;
if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;
if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return IPCFG_STATE_BUSY;
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
result = ipcfg_poll_dhcp_internal (device, try_auto_ip, auto_ip_data);
#else
result = RTCSERR_IPCFG_BIND;
#endif
_lwsem_post (&(ipcfg_data[device].control_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_boot_internal()
* Returned Value : ipcfg error code
* Comments : Control semaphore unprotected boot bind.
*
*END--------------------------------------------------------------------*/
static uint_32 ipcfg_bind_boot_internal
(
uint_32 device
)
{
#if RTCSCFG_IPCFG_ENABLE_BOOT
BOOTP_DATA_STRUCT boot_data;
#endif
uint_32 result = RTCSERR_IPCFG_BIND;
#if RTCSCFG_IPCFG_ENABLE_BOOT
if (! _lwsem_poll (&(ipcfg_data[device].request_semaphore))) return RTCSERR_IPCFG_BUSY;
ipcfg_unbind_internal_actual (device);
if (RTCS_if_bind_BOOTP (ipcfg_data[device].ihandle, &boot_data) == RTCS_OK)
{
#if RTCSCFG_BOOTP_RETURN_YIADDR
if (boot_data.YIADDR != 0)
{
ipcfg_data[device].actual_ip_data.ip = boot_data.YIADDR;
ipcfg_data[device].actual_ip_data.mask = 0;
ipcfg_data[device].actual_ip_data.gateway = 0;
}
#endif
if (boot_data.SADDR != 0)
{
ipcfg_data[device].tftp_serveraddress = boot_data.SADDR;
}
if (boot_data.SNAME[0] != '\0')
{
_mem_copy (boot_data.SNAME, ipcfg_data[device].tftp_servername, RTCS_SNAME_LEN);
ipcfg_data[device].tftp_servername[RTCS_SNAME_LEN - 1] = '\0';
}
if (boot_data.BOOTFILE[0] != '\0')
{
_mem_copy (boot_data.BOOTFILE, ipcfg_data[device].boot_filename, RTCS_BOOTFILE_LEN);
ipcfg_data[device].boot_filename[RTCS_BOOTFILE_LEN - 1] = '\0';
}
ipcfg_data[device].desired_state = IPCFG_STATE_BOOT;
ipcfg_data[device].actual_state = ipcfg_data[device].desired_state;
result = IPCFG_OK;
}
_lwsem_post (&(ipcfg_data[device].request_semaphore));
#endif
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_boot()
* Returned Value : ipcfg error code
* Comments : Tries to bind via boot protocol for given device.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_bind_boot
(
uint_32 device
)
{
uint_32 result;
if (device >= IPCFG_DEVICE_COUNT) return RTCSERR_IPCFG_DEVICE_NUMBER;
if (ipcfg_data[device].actual_state == IPCFG_STATE_INIT) return RTCSERR_IPCFG_INIT;
if (! _lwsem_poll (&(ipcfg_data[device].control_semaphore))) return RTCSERR_IPCFG_BUSY;
result = ipcfg_bind_boot_internal (device);
_lwsem_post (&(ipcfg_data[device].control_semaphore));
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_bind_dhcp_wait()
* Returned Value : ipcfg error code
* Comments : Tries to bind via dhcp (followed by auto ip) and waits for it.
*
*END----------------------------------------------------------------*/
uint_32 ipcfg_bind_dhcp_wait
(
uint_32 device,
boolean try_auto_ip,
IPCFG_IP_ADDRESS_DATA_PTR auto_ip_data
)
{
uint_32 result = IPCFG_OK;
do
{
if (result == RTCSERR_IPCFG_BUSY) _time_delay (200);
result = ipcfg_bind_dhcp (device, try_auto_ip);
} while (result == RTCSERR_IPCFG_BUSY);
if (result != IPCFG_OK) return result;
do
{
_time_delay (200);
result = ipcfg_poll_dhcp (device, try_auto_ip, auto_ip_data);
} while (result == RTCSERR_IPCFG_BUSY);
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_task_poll()
* Returned Value : TRUE if bind process finished (stable), FALSE otherwise (must call it again)
* Comments : One step of the ethernet link/bind monitoring task.
*
*END----------------------------------------------------------------*/
boolean ipcfg_task_poll (void)
{
IPCFG_STATE actual_state;
IPCFG_STATE desired_state;
uint_32 error;
uint_32 i;
boolean link;
boolean can_finish = TRUE;
// go through all ethernet devices
for (i = 0; i < IPCFG_DEVICE_COUNT; i++)
{
// check if current device interface is initialized
if (ipcfg_data[i].actual_state != IPCFG_STATE_INIT)
{
link = ipcfg_get_link_active (i);
// take control, outside binds are discarded for the moment, or skip this otherwise
if (_lwsem_poll (&(ipcfg_data[i].control_semaphore)))
{
// check link and bind status
actual_state = ipcfg_get_state (i);
desired_state = ipcfg_get_desired_state (i);
if ((link) && (actual_state != desired_state))
{
// link is up but bind is not finished
switch (desired_state)
{
case IPCFG_STATE_UNBOUND:
ipcfg_unbind_internal (i);
break;
case IPCFG_STATE_STATIC_IP:
ipcfg_bind_staticip_internal (i, NULL);
break;
case IPCFG_STATE_DHCP_IP:
error = ipcfg_bind_dhcp_internal (i, FALSE);
if ((error == IPCFG_OK) || (error == RTCSERR_IPCFG_BUSY))
{
ipcfg_poll_dhcp_internal (i, FALSE, NULL);
}
break;
case IPCFG_STATE_AUTO_IP:
ipcfg_bind_autoip_internal (i, NULL);
break;
case IPCFG_STATE_DHCPAUTO_IP:
error = ipcfg_bind_dhcp_internal (i, TRUE);
if ((error == IPCFG_OK) || (error == RTCSERR_IPCFG_BUSY))
{
ipcfg_poll_dhcp_internal (i, TRUE, NULL);
}
break;
case IPCFG_STATE_BOOT:
ipcfg_bind_boot_internal (i);
break;
default:
break;
}
}
else if ((! link) && (actual_state != IPCFG_STATE_UNBOUND))
{
// link is down, unbind any interface
ipcfg_unbind_internal (i);
}
// if busy, don't finish the task and check it next time
can_finish &= (actual_state != IPCFG_STATE_BUSY);
_lwsem_post (&(ipcfg_data[i].control_semaphore));
}
else
{
// interface was busy, don't finish the task and check it next time
actual_state = IPCFG_STATE_BUSY;
can_finish = FALSE;
}
#if IPCFG_DEBUG_LEVEL >= 2
printf ("Eth#:%d link:%s state:%s\n", i, link ? "on" : "off", ipcfg_get_state_string (actual_state));
#endif
}
}
return can_finish;
}
/*TASK*--------------------------------------------------------------
*
* Function Name : ipcfg_monitor_task()
* Returned Value : void
* Comments : All ethernet devices monitoring/binding task.
*
*END----------------------------------------------------------------*/
static void ipcfg_monitor_task
(
uint_32 check_period_ms
)
{
boolean can_finish;
#if IPCFG_DEBUG_LEVEL >= 2
printf ("IPCFG task created.\n");
#endif
while (TRUE)
{
can_finish = ipcfg_task_poll ();
if ((! ipcfg_task_run) && can_finish) break;
_time_delay (check_period_ms);
}
#if IPCFG_DEBUG_LEVEL >= 2
printf ("IPCFG task destroyed.\n");
#endif
_task_destroy (MQX_NULL_TASK_ID);
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_task_create()
* Returned Value : MQX error code
* Comments : Starts ipcfg task, if not started yet.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_task_create
(
uint_32 priority,
uint_32 task_period_ms
)
{
TASK_TEMPLATE_STRUCT task_templ;
_task_id tid;
uint_32 tec;
uint_32 result;
if (ipcfg_task_status ())
{
return MQX_DUPLICATE_TASK_TEMPLATE_INDEX;
}
ipcfg_task_run = TRUE;
tec = _task_get_error();
_mem_zero ((uchar_ptr)&task_templ, sizeof (task_templ));
task_templ.TASK_ADDRESS = ipcfg_monitor_task;
task_templ.TASK_STACKSIZE = IPCFG_TASK_STACK_SIZE;
task_templ.TASK_PRIORITY = priority;
task_templ.TASK_NAME = (char_ptr)ipcfg_task_name;
task_templ.CREATION_PARAMETER = task_period_ms;
tid = _task_create (0, 0, (uint_32)&task_templ);
if (tid == MQX_NULL_TASK_ID)
{
result = MQX_INVALID_TASK_ID;
}
else
{
result = MQX_OK;
}
_task_set_error(tec);
return result;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_task_destroy()
* Returned Value : void
* Comments : Sets flag to destroy ipcfg task, can wait for completion.
*
*END--------------------------------------------------------------------*/
void ipcfg_task_destroy
(
boolean wait_task_finish
)
{
_task_id tid;
uint_32 period;
ipcfg_task_run = FALSE;
if (! wait_task_finish) return;
do
{
tid = _task_get_id_from_name ((char_ptr)&ipcfg_task_name);
if (tid != MQX_NULL_TASK_ID)
{
period = _task_get_parameter_for (tid);
if ((period < 10 || period > 10000)) period = 1000;
_time_delay (period);
}
} while (tid != MQX_NULL_TASK_ID);
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_task_status()
* Returned Value : TRUE if running, FALSE otherwise
* Comments : Checks whether task is running.
*
*END--------------------------------------------------------------------*/
boolean ipcfg_task_status (void)
{
_task_id tid;
tid = _task_get_id_from_name ((char_ptr)&ipcfg_task_name);
if (tid != MQX_NULL_TASK_ID)
{
return TRUE;
}
return FALSE;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_init_device()
* Returned Value : error code
* Comments : Initializes given enet device and associated ip interface.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_init_device
(
uint_32 device,
_enet_address mac
)
{
_enet_handle ehandle;
_rtcs_if_handle ihandle;
uint_32 error = 0;
error = ENET_initialize (device, mac, 0, &ehandle);
if (error == RTCS_OK)
{
error = RTCS_if_add (ehandle, RTCS_IF_ENET, &ihandle);
if (error == RTCS_OK)
{
error = ipcfg_init_interface(device, ihandle);
if (error != RTCS_OK)
{
RTCS_if_remove (ihandle);
ENET_shutdown (ehandle);
#if IPCFG_DEBUG_LEVEL >= 2
printf ("IPCFG init error: %08x\n", error);
#endif
}
}
else
{
ENET_shutdown (ehandle);
#if IPCFG_DEBUG_LEVEL >= 2
printf ("Interface add error: %08x\n", error);
#endif
}
}
else if (error == ENETERR_INIT_DEVICE)
{
#if IPCFG_DEBUG_LEVEL >= 2
printf ("Device reinitialization... \n");
#endif
}
else
{
#if IPCFG_DEBUG_LEVEL >= 2
printf ("Device initialization error: %08x\n", error);
#endif
}
return error;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_release_device()
* Returned Value : error code
* Comments : Releases given enet device and associated ip interface.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_release_device(uint_32 device )
{
_enet_handle ehandle;
_rtcs_if_handle ihandle;
uint_32 error = 0;
if (device < IPCFG_DEVICE_COUNT)
{
ihandle = ipcfg_get_ihandle(device);
if(ihandle != NULL)
{
ehandle = RTCS_get_enet_handle(ihandle);
error = ipcfg_release_interface(device);
if (error == RTCS_OK)
{
error = RTCS_if_remove (ihandle);
if (error == RTCS_OK)
{
error = ENET_shutdown (ehandle);
}
}
return error;
}
else /* Not initialised by ipcfg_init_device().*/
return RTCSERR_IPCFG_NOT_INIT;
}
else
return RTCSERR_IPCFG_DEVICE_NUMBER;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_init_interface()
* Returned Value : ipcfg error code
* Comments : Initializes interface related internal structure - once.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_init_interface
(
uint_32 dev_num,
_rtcs_if_handle ihandle
)
{
_mqx_uint device;
if (ihandle == NULL) return RTCSERR_IPCFG_INIT;
device = ipcfg_add_interface(dev_num, ihandle);
if (device == (uint_32)-1)
return RTCSERR_IPCFG_INIT;
if (ipcfg_data[device].actual_state != IPCFG_STATE_INIT)
return RTCSERR_IPCFG_BUSY;
if (_lwsem_create (&ipcfg_data[device].control_semaphore, 1) != MQX_OK)
{
return RTCSERR_IPCFG_INIT;
}
if (_lwsem_create (&ipcfg_data[device].request_semaphore, 1) != MQX_OK)
{
_lwsem_destroy (&ipcfg_data[device].control_semaphore);
return RTCSERR_IPCFG_INIT;
}
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
if (_lwsem_create (&ipcfg_data[device].dhcp_response_semaphore, 0) != MQX_OK)
{
_lwsem_destroy (&ipcfg_data[device].control_semaphore);
_lwsem_destroy (&ipcfg_data[device].request_semaphore);
return RTCSERR_IPCFG_INIT;
}
ipcfg_data[device].dhcp_retries = 0;
#endif
ipcfg_data[device].ihandle = ihandle;
ipcfg_data[device].desired_ip_data.ip = 0;
ipcfg_data[device].desired_ip_data.mask = 0;
ipcfg_data[device].desired_ip_data.gateway = 0;
ipcfg_data[device].actual_ip_data.ip = 0;
ipcfg_data[device].actual_ip_data.mask = 0;
ipcfg_data[device].actual_ip_data.gateway = 0;
#if RTCSCFG_IPCFG_ENABLE_DNS
ipcfg_data[device].dns = 0;
#endif
#if RTCSCFG_IPCFG_ENABLE_BOOT
ipcfg_data[device].tftp_serveraddress = 0;
ipcfg_data[device].tftp_servername[0] = ipcfg_empty_string[0];
ipcfg_data[device].boot_filename[0] = ipcfg_empty_string[0];
#endif
ipcfg_data[device].desired_state = IPCFG_STATE_UNBOUND;
ipcfg_data[device].actual_state = IPCFG_STATE_UNBOUND;
return RTCS_OK;
}
/*FUNCTION*--------------------------------------------------------------
*
* Function Name : ipcfg_release_interface()
* Returned Value : ipcfg error code
* Comments : Releases interface related internal structure.
*
*END--------------------------------------------------------------------*/
uint_32 ipcfg_release_interface ( uint_32 dev_num)
{
if (dev_num < IPCFG_DEVICE_COUNT)
{
ipcfg_unbind (dev_num);
#if RTCSCFG_IPCFG_ENABLE_DHCP && RTCSCFG_ENABLE_IP4
_lwsem_destroy (&ipcfg_data[dev_num].dhcp_response_semaphore);
#endif
_lwsem_destroy (&ipcfg_data[dev_num].request_semaphore);
_lwsem_destroy (&ipcfg_data[dev_num].control_semaphore);
ipcfg_del_interface(dev_num);
return RTCS_OK;
}
else
return RTCSERR_IPCFG_DEVICE_NUMBER;
}
#endif /* (BSP_ENET_DEVICE_COUNT > 0) */
#endif /* BSP_ENET_DEVICE_COUNT */