1 /*
2 * Copyright (c) 2022 Talkweb Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "app_ethernet.h"
17
18 #define DO_PHY_STATUS_CALLBACK(func, val) \
19 { \
20 do { \
21 if (func != NULL) { \
22 func(val); \
23 } \
24 } while (0); \
25 }
26
27 static EthLinkInfo gEthLinkInfo = {
28 .useStaticIp = 0,
29 .useStaticMac = 0};
30
get_ethernet_link_info(EthLinkInfo * info)31 void get_ethernet_link_info(EthLinkInfo *info)
32 {
33 if (info == NULL) {
34 ETH_DEBUG("get eth info fail, param is null.\r\n");
35 return;
36 }
37 memcpy(info, &gEthLinkInfo, sizeof(gEthLinkInfo));
38 }
39
set_ethernet_link_info(EthLinkInfo * info)40 void set_ethernet_link_info(EthLinkInfo *info)
41 {
42 if (info == NULL) {
43 ETH_DEBUG("set eth info fail, param is null.\r\n");
44 return;
45 }
46 memcpy(&gEthLinkInfo, info, sizeof(gEthLinkInfo));
47 }
48
ethernet_staticIP_config(void)49 static void ethernet_staticIP_config(void)
50 {
51 ETH_DEBUG("use static IP:\r\n");
52 ETH_DEBUG("ip........................%d.%d.%d.%d\r\n", gEthLinkInfo.ipaddr.u8_addr[0],gEthLinkInfo.ipaddr.u8_addr[1], gEthLinkInfo.ipaddr.u8_addr[2], gEthLinkInfo.ipaddr.u8_addr[3]);
53 ETH_DEBUG("netmask...................%d.%d.%d.%d\r\n", gEthLinkInfo.netmask.u8_addr[0], gEthLinkInfo.netmask.u8_addr[1], gEthLinkInfo.netmask.u8_addr[2], gEthLinkInfo.netmask.u8_addr[3]);
54 ETH_DEBUG("gw........................%d.%d.%d.%d\r\n", gEthLinkInfo.gw.u8_addr[0], gEthLinkInfo.gw.u8_addr[1], gEthLinkInfo.gw.u8_addr[2], gEthLinkInfo.gw.u8_addr[3]);
55 }
56
ethernet_dhcpReslut_get(void)57 static void ethernet_dhcpReslut_get(void)
58 {
59 ETH_DEBUG("ip........................%u.%u.%u.%u\r\n", (gNetif.ip_addr.addr >> 0) & 0XFF, (gNetif.ip_addr.addr >> 8) & 0XFF, (gNetif.ip_addr.addr >> 16) & 0XFF, (gNetif.ip_addr.addr >> 24) & 0XFF);
60 ETH_DEBUG("netmask...................%u.%u.%u.%u\r\n", (gNetif.netmask.addr >> 0) & 0XFF, (gNetif.netmask.addr >> 8) & 0XFF, (gNetif.netmask.addr >> 16) & 0XFF, (gNetif.netmask.addr >> 24) & 0XFF);
61 ETH_DEBUG("gw........................%u.%u.%u.%u\r\n", (gNetif.gw.addr >> 0) & 0XFF, (gNetif.gw.addr >> 8) & 0XFF, (gNetif.gw.addr >> 16) & 0XFF, (gNetif.gw.addr >> 24) & 0XFF);
62 gEthLinkInfo.ipaddr.u32_addr = gNetif.ip_addr;
63 gEthLinkInfo.netmask.u32_addr = gNetif.netmask;
64 gEthLinkInfo.gw.u32_addr = gNetif.gw;
65 }
66
user_dhcp_wait(void)67 static void user_dhcp_wait(void)
68 {
69 dhcp_start(&gNetif);
70 ETH_DEBUG("dhcp start...\r\n");
71
72 unsigned int timeout = DHCP_TIMEOUT_S;
73 gNetif.ip_addr.addr = 0;
74 do {
75 osDelay(1000);
76 if (--timeout <= 0) {
77 break;
78 }
79 } while (gNetif.ip_addr.addr == 0);
80
81 if (gNetif.ip_addr.addr != 0) {
82 ETH_DEBUG("dhcp success:\r\n");
83 ethernet_dhcpReslut_get();
84 } else {
85 dhcp_stop(&gNetif);
86 ETH_DEBUG("dhcp fail!\r\n");
87 ethernet_staticIP_config();
88 netif_set_addr(&gNetif, &gEthLinkInfo.ipaddr.u32_addr, &gEthLinkInfo.netmask.u32_addr, &gEthLinkInfo.gw.u32_addr);
89 }
90 }
91
ethernet_thread_task(void * param)92 static void ethernet_thread_task(void *param)
93 {
94 ETH_DEBUG("start ethernet config task...\r\n");
95 tcpip_init(NULL, NULL);
96
97 if (gEthLinkInfo.useStaticIp == 1) {
98 ethernet_staticIP_config();
99 }
100
101 netif_add(&gNetif, &gEthLinkInfo.ipaddr.u32_addr, &gEthLinkInfo.netmask.u32_addr, &gEthLinkInfo.gw.u32_addr, NULL, ðernetif_init, ðernet_input);
102
103 while ((gNetif.flags & NETIF_FLAG_LINK_UP) != NETIF_FLAG_LINK_UP) {
104 ETH_DEBUG("Please check the network port!\r\n");
105 ethernetif_init(&gNetif);
106 osDelay(2000);
107 }
108 netif_set_default(&gNetif);
109
110 if (netif_is_link_up(&gNetif)) {
111 netif_set_up(&gNetif);
112 } else {
113 netif_set_down(&gNetif);
114 }
115
116 if (gEthLinkInfo.useStaticIp == 0) {
117 user_dhcp_wait();
118 }
119
120 unsigned int regval = 0;
121 unsigned char status = 0;
122 eth_state_callBack callback = (eth_state_callBack)param;
123
124 for (;;) {
125 /* get phy link status */
126 HAL_ETH_ReadPHYRegister(&gEthHandle, PHY_BSR, ®val);
127 if (status != (regval & PHY_LINKED_STATUS)) {
128 status = regval & PHY_LINKED_STATUS;
129 if (status == 0) {
130 netif_set_down(&gNetif);
131 DO_PHY_STATUS_CALLBACK(callback, STATE_UPDATE_LINK_DOWN);
132 } else {
133 netif_set_up(&gNetif);
134 DO_PHY_STATUS_CALLBACK(callback, STATE_UPDATE_LINK_UP);
135 }
136 }
137 osDelay(1000);
138 }
139 }
140
ethernet_enable(eth_state_callBack callback)141 void ethernet_enable(eth_state_callBack callback)
142 {
143 osThreadAttr_t attr = {.name = "ethernet_thread_task", .attr_bits = 0U, .cb_mem = NULL, .stack_mem = NULL, .stack_size = 4096, .priority = ETH_THREAD_PRIORITY};
144 if (osThreadNew((osThreadFunc_t)ethernet_thread_task, (void *)callback, &attr) == NULL) {
145 ETH_DEBUG("Create ethernet_thread_task failed!\r\n");
146 }
147 }
148