forked from xuos/xiuos
319 lines
8.9 KiB
C
319 lines
8.9 KiB
C
/*
|
|
* Copyright (c) 2006-2022, RT-Thread Development Team
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*
|
|
* Change Logs:
|
|
* Date Author Notes
|
|
* 2019-03-18 ChenYong First version
|
|
*/
|
|
|
|
/**
|
|
* @file netdev_manipulate.c
|
|
* @brief register net dev function
|
|
* @version 3.0
|
|
* @author AIIT XUOS Lab
|
|
* @date 2023-08-07
|
|
*/
|
|
|
|
/*************************************************
|
|
File name: netdev_manipulate.c
|
|
Description: register net dev function
|
|
Others: take RT-Thread v4.0.2/components/driver/serial/serial.c for references
|
|
https://github.com/RT-Thread/rt-thread/tree/v4.0.2
|
|
History:
|
|
1. Date: 2023-08-07
|
|
Author: AIIT XUOS Lab
|
|
Modification:
|
|
1. support net dev set-ip, set-netmask, set-gw, set-addr-callback, set-status-callback, set-up and set-down
|
|
*************************************************/
|
|
|
|
#include <netdev.h>
|
|
#include <string.h>
|
|
#include <xs_isr.h>
|
|
#include <xs_kdbg.h>
|
|
|
|
inline int netdev_check_set_addr_condition(struct netdev* netdev)
|
|
{
|
|
if (NULL == netdev->ops || NULL == netdev->ops->set_addr_info) {
|
|
SYS_KDEBUG_LOG(NETDEV_DEBUG, ("The network interface device(%s) not support to set IP address.\n", netdev->name));
|
|
return -ERROR;
|
|
}
|
|
|
|
// check whether dhcp enabled
|
|
if (netdev_is_dhcp_enabled(netdev)) {
|
|
SYS_KDEBUG_LOG(NETDEV_DEBUG, ("The network interface device(%s) DHCP capability is enable, not support set IP address.\n", netdev->name));
|
|
return -ERROR;
|
|
}
|
|
|
|
return EOK;
|
|
}
|
|
|
|
/**
|
|
* This function will set network interface device IP address.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
* @param ip_addr the new IP address
|
|
*
|
|
* @return 0: set IP address successfully
|
|
* -1: set IP address failed
|
|
*/
|
|
int netdev_set_ipaddr(struct netdev* netdev, const ip_addr_t* ipaddr)
|
|
{
|
|
CHECK(netdev);
|
|
CHECK(ipaddr);
|
|
|
|
if (EOK != netdev_check_set_addr_condition(netdev)) {
|
|
return -ERROR;
|
|
}
|
|
|
|
return netdev->ops->set_addr_info(netdev, (ip_addr_t*)ipaddr, NULL, NULL);
|
|
}
|
|
|
|
/**
|
|
* This function will set network interface device netmask address.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
* @param netmask the new netmask address
|
|
*
|
|
* @return 0: set netmask address successfully
|
|
* -1: set netmask address failed
|
|
*/
|
|
int netdev_set_netmask(struct netdev* netdev, const ip_addr_t* netmask)
|
|
{
|
|
CHECK(netdev);
|
|
CHECK(netmask);
|
|
|
|
if (EOK != netdev_check_set_addr_condition(netdev)) {
|
|
return -ERROR;
|
|
}
|
|
|
|
return netdev->ops->set_addr_info(netdev, NULL, (ip_addr_t*)netmask, NULL);
|
|
}
|
|
|
|
/**
|
|
* This function will set network interface device gateway address.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
* @param gw the new gateway address
|
|
*
|
|
* @return 0: set gateway address successfully
|
|
* -1: set gateway address failed
|
|
*/
|
|
int netdev_set_gw(struct netdev* netdev, const ip_addr_t* gw)
|
|
{
|
|
CHECK(netdev);
|
|
CHECK(gw);
|
|
|
|
if (EOK != netdev_check_set_addr_condition(netdev)) {
|
|
return -ERROR;
|
|
}
|
|
|
|
/* execute network interface device set gateway address operations */
|
|
return netdev->ops->set_addr_info(netdev, NULL, NULL, (ip_addr_t*)gw);
|
|
}
|
|
|
|
/**
|
|
* This function will set network interface device DNS server address.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
* @param dns_num the number of the DNS server
|
|
* @param dns_server the new DNS server address
|
|
*
|
|
* @return 0: set netmask address successfully
|
|
* -1: set netmask address failed
|
|
*/
|
|
int netdev_set_dns_server(struct netdev* netdev, uint8_t dns_num, const ip_addr_t* dns_server)
|
|
{
|
|
CHECK(netdev);
|
|
CHECK(dns_server);
|
|
|
|
// check dns server number
|
|
if (dns_num >= NETDEV_DNS_SERVERS_NUM) {
|
|
SYS_KDEBUG_LOG(NETDEV_DEBUG, ("The number of DNS servers(%d) set exceeds the maximum number(%d).\n", dns_num + 1, NETDEV_DNS_SERVERS_NUM));
|
|
return -ERROR;
|
|
}
|
|
|
|
// check dns set function existence
|
|
if (NULL == netdev->ops || NULL == netdev->ops->set_dns_server) {
|
|
SYS_KDEBUG_LOG(NETDEV_DEBUG, ("The network interface device(%s) not support to set DNS server address.\n", netdev->name));
|
|
return -ERROR;
|
|
}
|
|
|
|
return netdev->ops->set_dns_server(netdev, dns_num, (ip_addr_t*)dns_server);
|
|
}
|
|
|
|
/**
|
|
* This function will set callback to be called when the network interface device status has been changed.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
* @param status_callback the callback be called when the status has been changed.
|
|
*/
|
|
void netdev_set_status_callback(struct netdev* netdev, netdev_callback_fn status_callback)
|
|
{
|
|
CHECK(netdev);
|
|
CHECK(status_callback);
|
|
|
|
netdev->status_callback = status_callback;
|
|
}
|
|
|
|
/**
|
|
* This function will set callback to be called when the network interface device address has been changed.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
* @param addr_callback the callback be called when the address has been changed.
|
|
*/
|
|
void netdev_set_addr_callback(struct netdev* netdev, netdev_callback_fn addr_callback)
|
|
{
|
|
CHECK(netdev);
|
|
CHECK(addr_callback);
|
|
|
|
netdev->addr_callback = addr_callback;
|
|
}
|
|
|
|
/**
|
|
* This function will enable network interface device .
|
|
*
|
|
* @param netdev the network interface device to change
|
|
*
|
|
* @return 0: set status successfully
|
|
* -1: set status failed
|
|
*/
|
|
int netdev_set_up(struct netdev* netdev)
|
|
{
|
|
CHECK(netdev);
|
|
|
|
if (!netdev->ops || !netdev->ops->set_up) {
|
|
SYS_KDEBUG_LOG(NETDEV_DEBUG, ("The network interface device(%s) not support to set status.\n", netdev->name));
|
|
return -ERROR;
|
|
}
|
|
|
|
/* network interface device status flags check */
|
|
if (netdev_is_up(netdev)) {
|
|
return EOK;
|
|
}
|
|
|
|
/* execute enable network interface device operations by network interface device driver */
|
|
return netdev->ops->set_up(netdev);
|
|
}
|
|
|
|
/**
|
|
* This function will disable network interface device.
|
|
*
|
|
* @param netdev the network interface device to change
|
|
*
|
|
* @return 0: set status successfully
|
|
* -1: set sttaus failed
|
|
*/
|
|
int netdev_set_down(struct netdev* netdev)
|
|
{
|
|
CHECK(netdev);
|
|
|
|
if (!netdev->ops || !netdev->ops->set_down) {
|
|
SYS_KDEBUG_LOG(NETDEV_DEBUG, ("The network interface device(%s) not support to set status.\n", netdev->name));
|
|
return -ERROR;
|
|
}
|
|
|
|
/* network interface device status flags check */
|
|
if (!netdev_is_up(netdev)) {
|
|
return EOK;
|
|
}
|
|
|
|
/* execute disable network interface device operations by network interface driver */
|
|
return netdev->ops->set_down(netdev);
|
|
}
|
|
|
|
/**
|
|
* This function will get the first network interface device
|
|
* with the flags in network interface device list.
|
|
*
|
|
* @param flags the network interface device flags
|
|
*
|
|
* @return != NULL: network interface device object
|
|
* NULL: get failed
|
|
*/
|
|
struct netdev* netdev_get_first_by_flags(uint16_t flags)
|
|
{
|
|
if (NETDEV_LISTHEAD == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
// get netdev from list
|
|
x_base lock = DISABLE_INTERRUPT();
|
|
struct netdev* current_dev = NETDEV_LISTHEAD;
|
|
SINGLE_LINKLIST_FOR_EACH_ENTRY(current_dev, &(NETDEV_LISTHEAD->list), list)
|
|
{
|
|
if (NULL != current_dev && 0 != (current_dev->flags & flags)) {
|
|
ENABLE_INTERRUPT(lock);
|
|
return current_dev;
|
|
}
|
|
}
|
|
ENABLE_INTERRUPT(lock);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* This function will get the first network interface device
|
|
* in network interface device list by IP address.
|
|
*
|
|
* @param ip_addr the network interface device IP address
|
|
*
|
|
* @return != NULL: network interface device object
|
|
* NULL: get failed
|
|
*/
|
|
struct netdev* netdev_get_by_ipaddr(ip_addr_t* ip_addr)
|
|
{
|
|
if (NETDEV_LISTHEAD == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
// get netdev from list
|
|
x_base lock = DISABLE_INTERRUPT();
|
|
struct netdev* current_dev = NETDEV_LISTHEAD;
|
|
SINGLE_LINKLIST_FOR_EACH_ENTRY(current_dev, &(NETDEV_LISTHEAD->list), list)
|
|
{
|
|
if (NULL != current_dev && ip_addr_cmp(&(current_dev->ip_addr), ip_addr)) {
|
|
ENABLE_INTERRUPT(lock);
|
|
return current_dev;
|
|
}
|
|
}
|
|
ENABLE_INTERRUPT(lock);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
/**
|
|
* This function will get network interface device
|
|
* in network interface device list by netdev name.
|
|
*
|
|
* @param name the network interface device name
|
|
*
|
|
* @return != NULL: network interface device object
|
|
* NULL: get failed
|
|
*/
|
|
struct netdev* netdev_get_by_name(const char* name)
|
|
{
|
|
if (NETDEV_LISTHEAD == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
// get netdev from list
|
|
x_base lock = DISABLE_INTERRUPT();
|
|
struct netdev* current_dev = NETDEV_LISTHEAD;
|
|
SINGLE_LINKLIST_FOR_EACH_ENTRY(current_dev, &(NETDEV_LISTHEAD->list), list)
|
|
{
|
|
if (NULL == current_dev) {
|
|
continue;
|
|
}
|
|
uint32_t name_len = strlen(current_dev->name);
|
|
if (NULL != current_dev && (strncmp(current_dev->name, name, strlen(current_dev->name) < NAME_NUM_MAX ? strlen(current_dev->name) : NAME_NUM_MAX) == 0)) {
|
|
ENABLE_INTERRUPT(lock);
|
|
return current_dev;
|
|
}
|
|
}
|
|
ENABLE_INTERRUPT(lock);
|
|
|
|
return NULL;
|
|
}
|