Initial commit: CCU621_M firmware project with BLE debug link support.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,346 @@
|
||||
/*!
|
||||
\file netconf.c
|
||||
\brief network connection configuration
|
||||
|
||||
\version 2025-02-19, V2.1.0, demo for GD32H7xx
|
||||
*/
|
||||
|
||||
/*
|
||||
Copyright (c) 2024, GigaDevice Semiconductor Inc.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
3. Neither the name of the copyright holder nor the names of its contributors
|
||||
may be used to endorse or promote products derived from this software without
|
||||
specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS 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 THE COPYRIGHT HOLDER OR 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.
|
||||
*/
|
||||
|
||||
#include "lwip/mem.h"
|
||||
#include "lwip/memp.h"
|
||||
#include "lwip/dhcp.h"
|
||||
#include "lwip/dns.h"
|
||||
#include "ethernetif.h"
|
||||
#include "main.h"
|
||||
#include "netconf.h"
|
||||
#include "publicdata/publicdata.h"
|
||||
#include "lwip/tcpip.h"
|
||||
#include <stdio.h>
|
||||
#include "lwip/errno.h"
|
||||
#include "queue.h"
|
||||
|
||||
#define DHCP_TRIES_MAX_TIMES 3
|
||||
|
||||
int errno;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
DHCP_ADDR_NONE = 0,
|
||||
DHCP_ADDR_BEGIN,
|
||||
DHCP_ADDR_GOT,
|
||||
DHCP_ADDR_FAIL
|
||||
}dhcp_addr_status_enum;
|
||||
|
||||
#ifdef USE_DHCP
|
||||
dhcp_addr_status_enum dhcp_state = DHCP_ADDR_NONE;
|
||||
#endif /* USE_DHCP */
|
||||
|
||||
#ifdef USE_ENET0
|
||||
struct netif g_mynetif0;
|
||||
#endif /* USE_ENET0 */
|
||||
#ifdef USE_ENET1
|
||||
struct netif g_mynetif1;
|
||||
#endif /* USE_ENET1 */
|
||||
|
||||
ip_addr_t ip_address = {0};
|
||||
|
||||
static uint8_t netconf_is_all_value(const U8_T *buf, U8_T value)
|
||||
{
|
||||
return (uint8_t)((buf[0] == value) && (buf[1] == value) && (buf[2] == value) && (buf[3] == value));
|
||||
}
|
||||
|
||||
static uint8_t netconf_is_valid_host_ip(const U8_T *ip)
|
||||
{
|
||||
if (netconf_is_all_value(ip, 0x00U) || netconf_is_all_value(ip, 0xFFU)) {
|
||||
return 0U;
|
||||
}
|
||||
if ((ip[0] == 0U) || (ip[0] == 127U) || (ip[0] >= 224U)) {
|
||||
return 0U;
|
||||
}
|
||||
return 1U;
|
||||
}
|
||||
|
||||
static uint8_t netconf_is_valid_netmask(const U8_T *mask)
|
||||
{
|
||||
uint32_t m;
|
||||
uint8_t seen_zero = 0U;
|
||||
|
||||
if (netconf_is_all_value(mask, 0x00U) || netconf_is_all_value(mask, 0xFFU)) {
|
||||
return 0U;
|
||||
}
|
||||
|
||||
m = ((uint32_t)mask[0] << 24) | ((uint32_t)mask[1] << 16) | ((uint32_t)mask[2] << 8) | (uint32_t)mask[3];
|
||||
for (uint32_t bit = 0U; bit < 32U; bit++) {
|
||||
uint8_t cur = (uint8_t)((m >> (31U - bit)) & 0x1U);
|
||||
if (cur == 0U) {
|
||||
seen_zero = 1U;
|
||||
} else if (seen_zero != 0U) {
|
||||
return 0U;
|
||||
}
|
||||
}
|
||||
return 1U;
|
||||
}
|
||||
|
||||
static uint8_t netconf_is_same_subnet(const U8_T *ip, const U8_T *gw, const U8_T *mask)
|
||||
{
|
||||
uint32_t ip32 = ((uint32_t)ip[0] << 24) | ((uint32_t)ip[1] << 16) | ((uint32_t)ip[2] << 8) | (uint32_t)ip[3];
|
||||
uint32_t gw32 = ((uint32_t)gw[0] << 24) | ((uint32_t)gw[1] << 16) | ((uint32_t)gw[2] << 8) | (uint32_t)gw[3];
|
||||
uint32_t m32 = ((uint32_t)mask[0] << 24) | ((uint32_t)mask[1] << 16) | ((uint32_t)mask[2] << 8) | (uint32_t)mask[3];
|
||||
return (uint8_t)(((ip32 & m32) == (gw32 & m32)) ? 1U : 0U);
|
||||
}
|
||||
|
||||
static void netconf_get_static_ip_from_cfg(ip_addr_t *ip, ip_addr_t *mask, ip_addr_t *gw)
|
||||
{
|
||||
const U8_T *cfg_ip = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_eth_ip;
|
||||
const U8_T *cfg_mask = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_eth_mask;
|
||||
const U8_T *cfg_gw = g_t_share_data.t_sys_fix_cfg.s_net_cfg.u8_eth_gate;
|
||||
uint8_t use_cfg = 1U;
|
||||
|
||||
if (netconf_is_valid_host_ip(cfg_ip) == 0U) {
|
||||
use_cfg = 0U;
|
||||
}
|
||||
if (netconf_is_valid_host_ip(cfg_gw) == 0U) {
|
||||
use_cfg = 0U;
|
||||
}
|
||||
if (netconf_is_valid_netmask(cfg_mask) == 0U) {
|
||||
use_cfg = 0U;
|
||||
}
|
||||
if ((use_cfg != 0U) && (netconf_is_same_subnet(cfg_ip, cfg_gw, cfg_mask) == 0U)) {
|
||||
use_cfg = 0U;
|
||||
}
|
||||
|
||||
if (use_cfg != 0U) {
|
||||
IP4_ADDR(ip, cfg_ip[0], cfg_ip[1], cfg_ip[2], cfg_ip[3]);
|
||||
IP4_ADDR(mask, cfg_mask[0], cfg_mask[1], cfg_mask[2], cfg_mask[3]);
|
||||
IP4_ADDR(gw, cfg_gw[0], cfg_gw[1], cfg_gw[2], cfg_gw[3]);
|
||||
printf("[NETCONF] static ip from cfg: %u.%u.%u.%u, mask=%u.%u.%u.%u, gw=%u.%u.%u.%u\r\n",
|
||||
cfg_ip[0], cfg_ip[1], cfg_ip[2], cfg_ip[3],
|
||||
cfg_mask[0], cfg_mask[1], cfg_mask[2], cfg_mask[3],
|
||||
cfg_gw[0], cfg_gw[1], cfg_gw[2], cfg_gw[3]);
|
||||
} else {
|
||||
IP4_ADDR(ip, BOARD_IP_ADDR0, BOARD_IP_ADDR1, BOARD_IP_ADDR2, BOARD_IP_ADDR3);
|
||||
IP4_ADDR(mask, BOARD_NETMASK_ADDR0, BOARD_NETMASK_ADDR1, BOARD_NETMASK_ADDR2, BOARD_NETMASK_ADDR3);
|
||||
IP4_ADDR(gw, BOARD_GW_ADDR0, BOARD_GW_ADDR1, BOARD_GW_ADDR2, BOARD_GW_ADDR3);
|
||||
printf("[NETCONF] cfg ip invalid, fallback board ip: %u.%u.%u.%u\r\n",
|
||||
BOARD_IP_ADDR0, BOARD_IP_ADDR1, BOARD_IP_ADDR2, BOARD_IP_ADDR3);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief after the netif is fully configured, it will be called to initialize the function of telnet, client and udp
|
||||
\param[in] netif: the struct used for lwIP network interface
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lwip_netif_status_callback(struct netif *netif)
|
||||
{
|
||||
if(((netif->flags & NETIF_FLAG_UP) != 0) && (0 != netif->ip_addr.addr)) {
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief initializes the LwIP stack
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void lwip_stack_init(void)
|
||||
{
|
||||
ip_addr_t gd_ipaddr;
|
||||
ip_addr_t gd_netmask;
|
||||
ip_addr_t gd_gw;
|
||||
|
||||
/* create tcp_ip stack thread */
|
||||
tcpip_init(NULL, NULL);
|
||||
|
||||
/* IP address setting */
|
||||
#ifdef USE_DHCP
|
||||
gd_ipaddr.addr = 0;
|
||||
gd_netmask.addr = 0;
|
||||
gd_gw.addr = 0;
|
||||
#else
|
||||
netconf_get_static_ip_from_cfg(&gd_ipaddr, &gd_netmask, &gd_gw);
|
||||
#endif /* USE_DHCP */
|
||||
|
||||
#ifdef USE_ENET0
|
||||
/* add a new network interface */
|
||||
netif_add(&g_mynetif0, &gd_ipaddr, &gd_netmask, &gd_gw, NULL, ðernetif_init, &tcpip_input);
|
||||
|
||||
/* set a default network interface */
|
||||
netif_set_default(&g_mynetif0);
|
||||
|
||||
/* set a callback when interface is up/down */
|
||||
netif_set_status_callback(&g_mynetif0, lwip_netif_status_callback);
|
||||
|
||||
/* set the flag of netif as NETIF_FLAG_LINK_UP */
|
||||
netif_set_link_up(&g_mynetif0);
|
||||
|
||||
/* bring an interface up and set the flag of netif as NETIF_FLAG_UP */
|
||||
netif_set_up(&g_mynetif0);
|
||||
|
||||
#if LWIP_DNS
|
||||
/* 静态 IP 时无 DHCP 下发 DNS,需手动设置 */
|
||||
{
|
||||
ip_addr_t dns_server;
|
||||
IP_ADDR4(&dns_server, 114, 114, 114, 114);
|
||||
dns_setserver(0, &dns_server);
|
||||
}
|
||||
#endif /* LWIP_DNS */
|
||||
#endif /* USE_ENET0 */
|
||||
|
||||
#ifdef USE_ENET1
|
||||
/* add a new network interface */
|
||||
netif_add(&g_mynetif1, &gd_ipaddr, &gd_netmask, &gd_gw, NULL, ðernetif_init, &tcpip_input);
|
||||
|
||||
/* set a default network interface */
|
||||
netif_set_default(&g_mynetif1);
|
||||
|
||||
/* set a callback when interface is up/down */
|
||||
netif_set_status_callback(&g_mynetif1, lwip_netif_status_callback);
|
||||
|
||||
/* set the flag of netif as NETIF_FLAG_LINK_UP */
|
||||
netif_set_link_up(&g_mynetif1);
|
||||
|
||||
/* bring an interface up and set the flag of netif as NETIF_FLAG_UP */
|
||||
netif_set_up(&g_mynetif1);
|
||||
|
||||
#if LWIP_DNS
|
||||
{
|
||||
ip_addr_t dns_server;
|
||||
IP_ADDR4(&dns_server, 114, 114, 114, 114);
|
||||
dns_setserver(0, &dns_server);
|
||||
}
|
||||
#endif /* LWIP_DNS */
|
||||
#endif /* USE_ENET1 */
|
||||
}
|
||||
|
||||
#ifdef USE_DHCP
|
||||
/*!
|
||||
\brief dhcp_task
|
||||
\param[in] none
|
||||
\param[out] none
|
||||
\retval none
|
||||
*/
|
||||
void dhcp_task(void * pvParameters)
|
||||
{
|
||||
ip_addr_t gd_ipaddr;
|
||||
ip_addr_t gd_netmask;
|
||||
ip_addr_t gd_gw;
|
||||
|
||||
#ifdef USE_ENET0
|
||||
struct dhcp *dhcp_client0;
|
||||
#endif /* USE_ENET0 */
|
||||
#ifdef USE_ENET1
|
||||
struct dhcp *dhcp_client1;
|
||||
#endif /* USE_ENET1 */
|
||||
|
||||
for(;;){
|
||||
#ifdef USE_ENET0
|
||||
switch(dhcp_state){
|
||||
case DHCP_ADDR_NONE:
|
||||
dhcp_start(&g_mynetif0);
|
||||
/* IP address should be set to 0 every time we want to assign a new DHCP address*/
|
||||
ip_address.addr = 0;
|
||||
dhcp_state = DHCP_ADDR_BEGIN;
|
||||
break;
|
||||
|
||||
case DHCP_ADDR_BEGIN:
|
||||
/* got the IP address */
|
||||
ip_address.addr = g_mynetif0.ip_addr.addr;
|
||||
|
||||
if(0 != ip_address.addr){
|
||||
dhcp_state = DHCP_ADDR_GOT;
|
||||
printf("\r\nDHCP -- eval board ip address: %d.%d.%d.%d \r\n", ip4_addr1_16(&ip_address), \
|
||||
ip4_addr2_16(&ip_address), ip4_addr3_16(&ip_address), ip4_addr4_16(&ip_address));
|
||||
}else{
|
||||
/* DHCP timeout */
|
||||
dhcp_client0 = netif_dhcp_data(&g_mynetif0);
|
||||
if(dhcp_client0->tries > DHCP_TRIES_MAX_TIMES){
|
||||
dhcp_state = DHCP_ADDR_FAIL;
|
||||
/* stop DHCP */
|
||||
dhcp_stop(&g_mynetif0);
|
||||
|
||||
/* use static address as IP address */
|
||||
IP4_ADDR(&gd_ipaddr, BOARD_IP_ADDR0, BOARD_IP_ADDR1, BOARD_IP_ADDR2, BOARD_IP_ADDR3);
|
||||
IP4_ADDR(&gd_netmask, BOARD_NETMASK_ADDR0, BOARD_NETMASK_ADDR1, BOARD_NETMASK_ADDR2, BOARD_NETMASK_ADDR3);
|
||||
IP4_ADDR(&gd_gw, BOARD_GW_ADDR0, BOARD_GW_ADDR1, BOARD_GW_ADDR2, BOARD_GW_ADDR3);
|
||||
netif_set_addr(&g_mynetif0, &gd_ipaddr, &gd_netmask, &gd_gw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* USE_ENET0 */
|
||||
#ifdef USE_ENET1
|
||||
switch(dhcp_state){
|
||||
case DHCP_ADDR_NONE:
|
||||
dhcp_start(&g_mynetif1);
|
||||
/* IP address should be set to 0 every time we want to assign a new DHCP address*/
|
||||
ip_address.addr = 0;
|
||||
dhcp_state = DHCP_ADDR_BEGIN;
|
||||
break;
|
||||
|
||||
case DHCP_ADDR_BEGIN:
|
||||
/* got the IP address */
|
||||
ip_address.addr = g_mynetif1.ip_addr.addr;
|
||||
|
||||
if(0 != ip_address.addr){
|
||||
dhcp_state = DHCP_ADDR_GOT;
|
||||
printf("\r\nDHCP -- eval board ip address: %d.%d.%d.%d \r\n", ip4_addr1_16(&ip_address), \
|
||||
ip4_addr2_16(&ip_address), ip4_addr3_16(&ip_address), ip4_addr4_16(&ip_address));
|
||||
}else{
|
||||
/* DHCP timeout */
|
||||
dhcp_client1 = netif_dhcp_data(&g_mynetif1);
|
||||
if(dhcp_client1->tries > DHCP_TRIES_MAX_TIMES){
|
||||
dhcp_state = DHCP_ADDR_FAIL;
|
||||
/* stop DHCP */
|
||||
dhcp_stop(&g_mynetif1);
|
||||
|
||||
/* use static address as IP address */
|
||||
IP4_ADDR(&gd_ipaddr, BOARD_IP_ADDR0, BOARD_IP_ADDR1, BOARD_IP_ADDR2, BOARD_IP_ADDR3);
|
||||
IP4_ADDR(&gd_netmask, BOARD_NETMASK_ADDR0, BOARD_NETMASK_ADDR1, BOARD_NETMASK_ADDR2, BOARD_NETMASK_ADDR3);
|
||||
IP4_ADDR(&gd_gw, BOARD_GW_ADDR0, BOARD_GW_ADDR1, BOARD_GW_ADDR2, BOARD_GW_ADDR3);
|
||||
netif_set_addr(&g_mynetif1, &gd_ipaddr, &gd_netmask, &gd_gw);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
#endif /* USE_ENET1 */
|
||||
/* wait 250 ms */
|
||||
vTaskDelay(250);
|
||||
}
|
||||
}
|
||||
#endif /* USE_DHCP */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user