void lwip_netif_status_callback(struct netif *netif)
{
if(((netif->flags & NETIF_FLAG_UP) != 0) && (0 != netif->ip_addr.addr)) {
/* initilaize the tcp server: telnet 8000 */
hello_gigadevice_init();
/* initilaize the tcp client: echo 10260 */
tcp_client_init();
/* initilaize the udp: echo 1025 */
udp_echo_init();
}
}
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
IP4_ADDR(&gd_ipaddr, BORAD_IP_ADDR0, BORAD_IP_ADDR1, BORAD_IP_ADDR2, BORAD_IP_ADDR3);
IP4_ADDR(&gd_netmask, BORAD_NETMASK_ADDR0, BORAD_NETMASK_ADDR1, BORAD_NETMASK_ADDR2, BORAD_NETMASK_ADDR3);
IP4_ADDR(&gd_gw, BORAD_GW_ADDR0, BORAD_GW_ADDR1, BORAD_GW_ADDR2, BORAD_GW_ADDR3);
#endif /* USE_DHCP */
/* add a new network interface */
netif_add(&g_mynetif, &gd_ipaddr, &gd_netmask, &gd_gw, NULL, ðernetif_init, &tcpip_input);
/* set a default network interface */
netif_set_default(&g_mynetif);
/* set a callback when interface is up/down */
netif_set_status_callback(&g_mynetif, lwip_netif_status_callback);
/* set the flag of netif as NETIF_FLAG_LINK_UP */
netif_set_link_up(&g_mynetif);
/* bring an interface up and set the flag of netif as NETIF_FLAG_UP */
netif_set_up(&g_mynetif);
}
void
netif_set_status_callback(struct netif *netif, netif_status_callback_fn status_callback)
{
LWIP_ASSERT_CORE_LOCKED();
if (netif) {
netif->status_callback = status_callback;
}
}
有三处调用了NETIF_STATUS_CALLBACK(n),分别是netif_do_set_ipaddr()、netif_set_up(struct netif *netif)、netif_set_down(struct netif *netif)
lwip_stack_init()调用了netif_add(),netif_add()调用了netif_set_addr(),netif_set_addr(netif, ipaddr, netmask, gw)调用了netif_do_set_ipaddr()
static int
netif_do_set_ipaddr(struct netif *netif, const ip4_addr_t *ipaddr, ip_addr_t *old_addr)
{
LWIP_ASSERT("invalid pointer", ipaddr != NULL);
LWIP_ASSERT("invalid pointer", old_addr != NULL);
/* address is actually being changed? */
if (ip4_addr_cmp(ipaddr, netif_ip4_addr(netif)) == 0) {
ip_addr_t new_addr;
*ip_2_ip4(&new_addr) = *ipaddr;
IP_SET_TYPE_VAL(new_addr, IPADDR_TYPE_V4);
ip_addr_copy(*old_addr, *netif_ip_addr4(netif));
LWIP_DEBUGF(NETIF_DEBUG | LWIP_DBG_STATE, ("netif_set_ipaddr: netif address being changed\n"));
netif_do_ip_addr_changed(old_addr, &new_addr);
mib2_remove_ip4(netif);
mib2_remove_route_ip4(0, netif);
/* set new IP address to netif */
ip4_addr_set(ip_2_ip4(&netif->ip_addr), ipaddr);
IP_SET_TYPE_VAL(netif->ip_addr, IPADDR_TYPE_V4);
mib2_add_ip4(netif);
mib2_add_route_ip4(0, netif);
netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4);
NETIF_STATUS_CALLBACK(netif);
return 1; /* address changed */
}
return 0; /* address unchanged */
}
/**
* @ingroup netif
* Bring an interface up, available for processing
* traffic.
*/
void
netif_set_up(struct netif *netif)
{
LWIP_ASSERT_CORE_LOCKED();
LWIP_ERROR("netif_set_up: invalid netif", netif != NULL, return);
if (!(netif->flags & NETIF_FLAG_UP)) {
netif_set_flags(netif, NETIF_FLAG_UP);
MIB2_COPY_SYSUPTIME_TO(&netif->ts);
NETIF_STATUS_CALLBACK(netif); //实际调用lwip_netif_status_callback()
#if LWIP_NETIF_EXT_STATUS_CALLBACK
{
netif_ext_callback_args_t args;
args.status_changed.state = 1;
netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args);
}
#endif
netif_issue_reports(netif, NETIF_REPORT_TYPE_IPV4 | NETIF_REPORT_TYPE_IPV6);
#if LWIP_IPV6
nd6_restart_netif(netif);
#endif /* LWIP_IPV6 */
}
}
/**
* @ingroup netif
* Bring an interface down, disabling any traffic processing.
*/
void
netif_set_down(struct netif *netif)
{
LWIP_ASSERT_CORE_LOCKED();
LWIP_ERROR("netif_set_down: invalid netif", netif != NULL, return);
if (netif->flags & NETIF_FLAG_UP) {
#if LWIP_NETIF_EXT_STATUS_CALLBACK
{
netif_ext_callback_args_t args;
args.status_changed.state = 0;
netif_invoke_ext_callback(netif, LWIP_NSC_STATUS_CHANGED, &args);
}
#endif
netif_clear_flags(netif, NETIF_FLAG_UP);
MIB2_COPY_SYSUPTIME_TO(&netif->ts);
#if LWIP_IPV4 && LWIP_ARP
if (netif->flags & NETIF_FLAG_ETHARP) {
etharp_cleanup_netif(netif);
}
#endif /* LWIP_IPV4 && LWIP_ARP */
#if LWIP_IPV6
nd6_cleanup_netif(netif);
#endif /* LWIP_IPV6 */
NETIF_STATUS_CALLBACK(netif);
}
}
//
/* add a new network interface */
netif_add(&g_mynetif, &gd_ipaddr, &gd_netmask, &gd_gw, NULL, ðernetif_init, &tcpip_input);
/**
* @ingroup netif
* Add a network interface to the list of lwIP netifs.
*
* @param netif a pre-allocated netif structure
* @param ipaddr IP address for the new netif
* @param netmask network mask for the new netif
* @param gw default gateway IP address for the new netif
* @param state opaque data passed to the new netif
* @param init callback function that initializes the interface
* @param input callback function that is called to pass
* ingress packets up in the protocol layer stack.\n
* It is recommended to use a function that passes the input directly
* to the stack (netif_input(), NO_SYS=1 mode) or via sending a
* message to TCPIP thread (tcpip_input(), NO_SYS=0 mode).\n
* These functions use netif flags NETIF_FLAG_ETHARP and NETIF_FLAG_ETHERNET
* to decide whether to forward to ethernet_input() or ip_input().
* In other words, the functions only work when the netif
* driver is implemented correctly!\n
* Most members of struct netif should be be initialized by the
* netif init function = netif driver (init parameter of this function).\n
* IPv6: Don't forget to call netif_create_ip6_linklocal_address() after
* setting the MAC address in struct netif.hwaddr
* (IPv6 requires a link-local address).
*
* @return netif, or NULL if failed.
*/
struct netif *
netif_add(struct netif *netif,
#if LWIP_IPV4
const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw,
#endif /* LWIP_IPV4 */
void *state, netif_init_fn init, netif_input_fn input)
{
#if LWIP_IPV6
s8_t i;
#endif
LWIP_ASSERT_CORE_LOCKED();
#if LWIP_SINGLE_NETIF
if (netif_default != NULL) {
LWIP_ASSERT("single netif already set", 0);
return NULL;
}
#endif
LWIP_ERROR("netif_add: invalid netif", netif != NULL, return NULL);
LWIP_ERROR("netif_add: No init function given", init != NULL, return NULL);
#if LWIP_IPV4
if (ipaddr == NULL) {
ipaddr = ip_2_ip4(IP4_ADDR_ANY);
}
if (netmask == NULL) {
netmask = ip_2_ip4(IP4_ADDR_ANY);
}
if (gw == NULL) {
gw = ip_2_ip4(IP4_ADDR_ANY);
}
/* reset new interface configuration state */
ip_addr_set_zero_ip4(&netif->ip_addr);
ip_addr_set_zero_ip4(&netif->netmask);
ip_addr_set_zero_ip4(&netif->gw);
netif->output = netif_null_output_ip4;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
for (i = 0; i < LWIP_IPV6_NUM_ADDRESSES; i++) {
ip_addr_set_zero_ip6(&netif->ip6_addr[i]);
netif->ip6_addr_state[i] = IP6_ADDR_INVALID;
#if LWIP_IPV6_ADDRESS_LIFETIMES
netif->ip6_addr_valid_life[i] = IP6_ADDR_LIFE_STATIC;
netif->ip6_addr_pref_life[i] = IP6_ADDR_LIFE_STATIC;
#endif /* LWIP_IPV6_ADDRESS_LIFETIMES */
}
netif->output_ip6 = netif_null_output_ip6;
#endif /* LWIP_IPV6 */
NETIF_SET_CHECKSUM_CTRL(netif, NETIF_CHECKSUM_ENABLE_ALL);
netif->mtu = 0;
netif->flags = 0;
#ifdef netif_get_client_data
memset(netif->client_data, 0, sizeof(netif->client_data));
#endif /* LWIP_NUM_NETIF_CLIENT_DATA */
#if LWIP_IPV6
#if LWIP_IPV6_AUTOCONFIG
/* IPv6 address autoconfiguration not enabled by default */
netif->ip6_autoconfig_enabled = 0;
#endif /* LWIP_IPV6_AUTOCONFIG */
nd6_restart_netif(netif);
#endif /* LWIP_IPV6 */
#if LWIP_NETIF_STATUS_CALLBACK
netif->status_callback = NULL;
#endif /* LWIP_NETIF_STATUS_CALLBACK */
#if LWIP_NETIF_LINK_CALLBACK
netif->link_callback = NULL;
#endif /* LWIP_NETIF_LINK_CALLBACK */
#if LWIP_IGMP
netif->igmp_mac_filter = NULL;
#endif /* LWIP_IGMP */
#if LWIP_IPV6 && LWIP_IPV6_MLD
netif->mld_mac_filter = NULL;
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
#if ENABLE_LOOPBACK
netif->loop_first = NULL;
netif->loop_last = NULL;
#endif /* ENABLE_LOOPBACK */
/* remember netif specific state information data */
netif->state = state; //NULL
netif->num = netif_num;
netif->input = input; //tcpip_input
NETIF_RESET_HINTS(netif);
#if ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS
netif->loop_cnt_current = 0;
#endif /* ENABLE_LOOPBACK && LWIP_LOOPBACK_MAX_PBUFS */
#if LWIP_IPV4
netif_set_addr(netif, ipaddr, netmask, gw);
#endif /* LWIP_IPV4 */
/* call user specified initialization function for netif */
if (init(netif) != ERR_OK) { //ethernetif_init
return NULL;
}
#if LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES
/* Initialize the MTU for IPv6 to the one set by the netif driver.
This can be updated later by RA. */
netif->mtu6 = netif->mtu;
#endif /* LWIP_IPV6 && LWIP_ND6_ALLOW_RA_UPDATES */
#if !LWIP_SINGLE_NETIF
/* Assign a unique netif number in the range [0..254], so that (num+1) can
serve as an interface index that fits in a u8_t.
We assume that the new netif has not yet been added to the list here.
This algorithm is O(n^2), but that should be OK for lwIP.
*/
{
struct netif *netif2;
int num_netifs;
do {
if (netif->num == 255) {
netif->num = 0;
}
num_netifs = 0;
for (netif2 = netif_list; netif2 != NULL; netif2 = netif2->next) {
LWIP_ASSERT("netif already added", netif2 != netif);
num_netifs++;
LWIP_ASSERT("too many netifs, max. supported number is 255", num_netifs <= 255);
if (netif2->num == netif->num) {
netif->num++;
break;
}
}
} while (netif2 != NULL);
}
if (netif->num == 254) {
netif_num = 0;
} else {
netif_num = (u8_t)(netif->num + 1);
}
/* add this netif to the list */
netif->next = netif_list;
netif_list = netif;
#endif /* "LWIP_SINGLE_NETIF */
mib2_netif_added(netif);
#if LWIP_IGMP
/* start IGMP processing */
if (netif->flags & NETIF_FLAG_IGMP) {
igmp_start(netif);
}
#endif /* LWIP_IGMP */
LWIP_DEBUGF(NETIF_DEBUG, ("netif: added interface %c%c IP",
netif->name[0], netif->name[1]));
#if LWIP_IPV4
LWIP_DEBUGF(NETIF_DEBUG, (" addr "));
ip4_addr_debug_print(NETIF_DEBUG, ipaddr);
LWIP_DEBUGF(NETIF_DEBUG, (" netmask "));
ip4_addr_debug_print(NETIF_DEBUG, netmask);
LWIP_DEBUGF(NETIF_DEBUG, (" gw "));
ip4_addr_debug_print(NETIF_DEBUG, gw);
#endif /* LWIP_IPV4 */
LWIP_DEBUGF(NETIF_DEBUG, ("\n"));
netif_invoke_ext_callback(netif, LWIP_NSC_NETIF_ADDED, NULL);
return netif;
}