1.将A27新UI文件夹重命名为CANUI 2.A272O新版本发布

This commit is contained in:
2025-03-26 18:43:18 +08:00
parent 497f8eb1e1
commit 5bc7ee438c
13399 changed files with 58500 additions and 59183 deletions

View File

@ -0,0 +1,23 @@
This directory contains generic network interface device drivers that
do not contain any hardware or architecture specific code. The files
are:
ethernet.c
Shared code for Ethernet based interfaces.
lowpan6.c
A 6LoWPAN implementation as a netif.
lowpan6_ble.c
A 6LoWPAN over Bluetooth Low Energy (BLE) implementation as netif,
according to RFC-7668.
slipif.c
A generic implementation of the SLIP (Serial Line IP)
protocol. It requires a sio (serial I/O) module to work.
ppp/ Point-to-Point Protocol stack
The lwIP PPP support is based from pppd (http://ppp.samba.org) with
huge changes to match code size and memory requirements for embedded
devices. Please read /doc/ppp.txt and ppp/PPPD_FOLLOWUP for a detailed
explanation.

View File

@ -0,0 +1,68 @@
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* All rights reserved.
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* This file is part of the lwIP TCP/IP stack.
*
* Author: Adam Dunkels <adam@sics.se>
*
*/
#include "lwip/opt.h"
#include "lwip/netif.h"
#include "lwip/ip_addr.h"
#include "lwip/tcpip.h"
#include "netif/tapif.h"
#include "default_netif.h"
static struct netif netif;
#if LWIP_IPV4
#define NETIF_ADDRS ipaddr, netmask, gw,
void init_default_netif(const ip4_addr_t *ipaddr, const ip4_addr_t *netmask, const ip4_addr_t *gw)
#else
#define NETIF_ADDRS
void init_default_netif(void)
#endif
{
#if NO_SYS
netif_add(&netif, NETIF_ADDRS NULL, tapif_init, netif_input);
#else
netif_add(&netif, NETIF_ADDRS NULL, tapif_init, tcpip_input);
#endif
netif_set_default(&netif);
}
void
default_netif_poll(void)
{
tapif_poll(&netif);
}
void
default_netif_shutdown(void)
{
}

View File

@ -0,0 +1,803 @@
#include <stdio.h>
#include <stdint.h>
#include <lwip/opt.h>
#include <lwip/sockets.h>
#include <lwip/inet_chksum.h>
#include <netif/etharp.h>
//#include <netif/ethernetif.h>
#include <lwip/ip.h>
#include <lwip/init.h>
#if (LWIP_VERSION) < 0x02000000U
#error "not support old LWIP"
#endif
#if !LWIP_IPV4
#error "must enable IPV4"
#endif
#if (LWIP_VERSION) >= 0x02000000U
#include <lwip/prot/dhcp.h>
#endif
/* DHCP server option */
/* allocated client ip range */
#ifndef DHCPD_CLIENT_IP_MIN
#define DHCPD_CLIENT_IP_MIN 20
#endif
#ifndef DHCPD_CLIENT_IP_MAX
#define DHCPD_CLIENT_IP_MAX 25
#endif
/* the DHCP server address */
#ifndef DHCPD_SERVER_IP
#define DHCPD_SERVER_IP "192.168.13.1"
#endif
#define DHCP_DEBUG_PRINTF
#ifdef DHCP_DEBUG_PRINTF
#define DEBUG_PRINTF printf("[DHCP] "); printf
#else
#define DEBUG_PRINTF(...)
#endif /* DHCP_DEBUG_PRINTF */
/* we need some routines in the DHCP of lwIP */
#undef LWIP_DHCP
#define LWIP_DHCP 1
#include <lwip/dhcp.h>
/** Mac address length */
#define DHCP_MAX_HLEN 6
/** dhcp default live time */
#define DHCP_DEFAULT_LIVE_TIME 0x80510100
/** Minimum length for request before packet is parsed */
#define DHCP_MIN_REQUEST_LEN 44
#define LWIP_NETIF_LOCK(...)
#define LWIP_NETIF_UNLOCK(...)
#ifndef DHCP_SERVER_PORT
#define DHCP_SERVER_PORT 67
#endif
/**
* The dhcp client node struct.
*/
struct dhcp_client_node
{
struct dhcp_client_node *next;
u8_t chaddr[DHCP_MAX_HLEN];
ip4_addr_t ipaddr;
u32_t lease_end;
};
/**
* The dhcp server struct.
*/
struct dhcp_server
{
struct dhcp_server *next;
struct netif *netif;
struct udp_pcb *pcb;
struct dhcp_client_node *node_list;
ip4_addr_t start;
ip4_addr_t end;
ip4_addr_t current;
};
static u8_t *dhcp_server_option_find(u8_t *buf, u16_t len, u8_t option);
/**
* The dhcp server struct list.
*/
static struct dhcp_server *lw_dhcp_server;
/**
* Find a dhcp client node by mac address
*
* @param dhcpserver The dhcp server
* @param chaddr Mac address
* @param hlen Mac address length
* @return dhcp client node
*/
static struct dhcp_client_node *
dhcp_client_find_by_mac(struct dhcp_server *dhcpserver, const u8_t *chaddr, u8_t hlen)
{
struct dhcp_client_node *node;
for (node = dhcpserver->node_list; node != NULL; node = node->next)
{
if (memcmp(node->chaddr, chaddr, hlen) == 0)
{
return node;
}
}
return NULL;
}
/**
* Find a dhcp client node by ip address
*
* @param dhcpserver The dhcp server
* @param chaddr Mac address
* @param hlen Mac address length
* @return dhcp client node
*/
static struct dhcp_client_node *
dhcp_client_find_by_ip(struct dhcp_server *dhcpserver, const ip4_addr_t *ip)
{
struct dhcp_client_node *node;
for (node = dhcpserver->node_list; node != NULL; node = node->next)
{
if (ip4_addr_cmp(&node->ipaddr, ip))
{
return node;
}
}
return NULL;
}
/**
* Find a dhcp client node by ip address
*
* @param dhcpserver The dhcp server
* @param chaddr Mac address
* @param hlen Mac address length
* @return dhcp client node
*/
static struct dhcp_client_node *
dhcp_client_find(struct dhcp_server *dhcpserver, struct dhcp_msg *msg,
u8_t *opt_buf, u16_t len)
{
u8_t *opt;
//u32_t ipaddr;
struct dhcp_client_node *node;
node = dhcp_client_find_by_mac(dhcpserver, msg->chaddr, msg->hlen);
if (node != NULL)
{
return node;
}
opt = dhcp_server_option_find(opt_buf, len, DHCP_OPTION_REQUESTED_IP);
if (opt != NULL)
{
node = dhcp_client_find_by_ip(dhcpserver, (ip4_addr_t *)(&opt[2]));
if (node != NULL)
{
return node;
}
}
return NULL;
}
/**
* Find a dhcp client node by ip address
*
* @param dhcpserver The dhcp server
* @param chaddr Mac address
* @param hlen Mac address length
* @return dhcp client node
*/
static struct dhcp_client_node *
dhcp_client_alloc(struct dhcp_server *dhcpserver, struct dhcp_msg *msg,
u8_t *opt_buf, u16_t len)
{
u8_t *opt;
u32_t ipaddr;
struct dhcp_client_node *node;
int retry_count = 0;
node = dhcp_client_find_by_mac(dhcpserver, msg->chaddr, msg->hlen);
if (node != NULL)
{
return node;
}
opt = dhcp_server_option_find(opt_buf, len, DHCP_OPTION_REQUESTED_IP);
if (opt != NULL)
{
node = dhcp_client_find_by_ip(dhcpserver, (ip4_addr_t *)(&opt[2]));
if (node != NULL)
{
return node;
}
}
dhcp_alloc_again:
node = dhcp_client_find_by_ip(dhcpserver, &dhcpserver->current);
if (node != NULL)
{
ipaddr = (ntohl(dhcpserver->current.addr) + 1);
if (ipaddr > ntohl(dhcpserver->end.addr))
{
ipaddr = ntohl(dhcpserver->start.addr);
}
dhcpserver->current.addr = htonl(ipaddr);
if (retry_count++ < 10) {
printf("%s:%d\n", __func__, __LINE__);
goto dhcp_alloc_again;
} else {
ipaddr = (ntohl(dhcpserver->current.addr) - 1);
dhcpserver->current.addr = htonl(ipaddr);
printf("%s:%d\n", __func__, __LINE__);
}
}
node = (struct dhcp_client_node *)mem_malloc(sizeof(struct dhcp_client_node));
if (node == NULL)
{
return NULL;
}
SMEMCPY(node->chaddr, msg->chaddr, msg->hlen);
node->ipaddr = dhcpserver->current;
node->next = dhcpserver->node_list;
dhcpserver->node_list = node;
return node;
}
/**
* find option from buffer.
*
* @param buf The buffer to find option
* @param len The buffer length
* @param option Which option to find
* @return dhcp option buffer
*/
static u8_t *
dhcp_server_option_find(u8_t *buf, u16_t len, u8_t option)
{
u8_t *end = buf + len;
while ((buf < end) && (*buf != DHCP_OPTION_END))
{
if (*buf == option)
{
return buf;
}
buf += (buf[1] + 2);
}
return NULL;
}
/**
* If an incoming DHCP message is in response to us, then trigger the state machine
*/
static void
dhcp_server_recv(void *arg, struct udp_pcb *pcb, struct pbuf *p, const ip_addr_t *recv_addr, u16_t port)
{
struct dhcp_server *dhcp_server = (struct dhcp_server *)arg;
struct dhcp_msg *msg;
struct pbuf *q;
u8_t *opt_buf;
u8_t *opt;
struct dhcp_client_node *node;
u8_t msg_type;
u16_t length;
ip_addr_t addr = *recv_addr;
u32_t tmp;
printf ("[%s:%d] %c%c recv %d\r\n", __FUNCTION__, __LINE__, dhcp_server->netif->name[0], dhcp_server->netif->name[1], p->tot_len);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("[%s:%d] %c%c recv %d\n", __FUNCTION__, __LINE__, dhcp_server->netif->name[0], dhcp_server->netif->name[1], p->tot_len));
/* prevent warnings about unused arguments */
LWIP_UNUSED_ARG(pcb);
LWIP_UNUSED_ARG(addr);
LWIP_UNUSED_ARG(port);
if (p->len < DHCP_MIN_REQUEST_LEN)
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("DHCP request message or pbuf too short\n"));
pbuf_free(p);
return;
}
q = pbuf_alloc(PBUF_TRANSPORT, 1024, PBUF_RAM);
if (q == NULL)
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloc dhcp_msg failed!\n"));
pbuf_free(p);
return;
}
if (q->tot_len < p->tot_len)
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("pbuf_alloc dhcp_msg too small %d:%d\n", q->tot_len, p->tot_len));
pbuf_free(p);
return;
}
pbuf_copy(q, p);
pbuf_free(p);
msg = (struct dhcp_msg *)q->payload;
if (msg->op != DHCP_BOOTREQUEST)
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("not a DHCP request message, but type %"U16_F"\n", (u16_t)msg->op));
goto free_pbuf_and_return;
}
if (msg->cookie != PP_HTONL(DHCP_MAGIC_COOKIE))
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING, ("bad DHCP_MAGIC_COOKIE!\n"));
goto free_pbuf_and_return;
}
if (msg->hlen > DHCP_MAX_HLEN)
{
goto free_pbuf_and_return;
}
opt_buf = (u8_t *)msg + DHCP_OPTIONS_OFS;
length = q->tot_len - DHCP_OPTIONS_OFS;
printf("q->tot_len:%d p->len:%d\r\n", q->tot_len, p->len);
opt = dhcp_server_option_find(opt_buf, length, DHCP_OPTION_MESSAGE_TYPE);
if (opt)
{
msg_type = *(opt + 2);
if (msg_type == DHCP_DISCOVER)
{
node = dhcp_client_alloc(dhcp_server, msg, opt_buf, length);
if (node == NULL)
{
goto free_pbuf_and_return;
}
node->lease_end = DHCP_DEFAULT_LIVE_TIME;
/* create dhcp offer and send */
msg->op = DHCP_BOOTREPLY;
msg->hops = 0;
msg->secs = 0;
SMEMCPY(&msg->siaddr, &(dhcp_server->netif->ip_addr), 4);
msg->sname[0] = '\0';
msg->file[0] = '\0';
msg->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
SMEMCPY(&msg->yiaddr, &node->ipaddr, 4);
opt_buf = (u8_t *)msg + DHCP_OPTIONS_OFS;
/* add msg type */
*opt_buf++ = DHCP_OPTION_MESSAGE_TYPE;
*opt_buf++ = 1;
*opt_buf++ = DHCP_OFFER;
/* add server id */
*opt_buf++ = DHCP_OPTION_SERVER_ID;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &(dhcp_server->netif->ip_addr), 4);
opt_buf += 4;
/* add_lease_time */
*opt_buf++ = DHCP_OPTION_LEASE_TIME;
*opt_buf++ = 4;
tmp = PP_HTONL(DHCP_DEFAULT_LIVE_TIME);
SMEMCPY(opt_buf, &tmp, 4);
opt_buf += 4;
/* add config */
*opt_buf++ = DHCP_OPTION_SUBNET_MASK;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &ip_2_ip4(&dhcp_server->netif->netmask)->addr, 4);
opt_buf += 4;
//*opt_buf++ = DHCP_OPTION_DNS_SERVER;
//*opt_buf++ = 4;
#ifdef DHCP_DNS_SERVER_IP
{
//ip_addr_t dns_addr;
//ipaddr_aton(DHCP_DNS_SERVER_IP, &dns_addr);
//SMEMCPY(opt_buf, &ip_2_ip4(&dns_addr)->addr, 4);
}
#else
/* default use gatewary dns server */
//SMEMCPY(opt_buf, &(dhcp_server->netif->ip_addr), 4);
#endif /* DHCP_DNS_SERVER_IP */
//opt_buf += 4;
*opt_buf++ = DHCP_OPTION_ROUTER;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &ip_2_ip4(&dhcp_server->netif->ip_addr)->addr, 4);
opt_buf += 4;
/* add option end */
*opt_buf++ = DHCP_OPTION_END;
length = (u32_t)opt_buf - (u32_t)msg;
if (length < q->tot_len)
{
pbuf_realloc(q, length);
}
ip_2_ip4(&addr)->addr = INADDR_BROADCAST;
udp_sendto_if(pcb, q, &addr, port, dhcp_server->netif);
}
else
{
if (1)
{
if (msg_type == DHCP_REQUEST)
{
node = dhcp_client_find(dhcp_server, msg, opt_buf, length);
if (node != NULL)
{
/* Send ack */
node->lease_end = DHCP_DEFAULT_LIVE_TIME;
/* create dhcp offer and send */
msg->op = DHCP_BOOTREPLY;
msg->hops = 0;
msg->secs = 0;
SMEMCPY(&msg->siaddr, &(dhcp_server->netif->ip_addr), 4);
msg->sname[0] = '\0';
msg->file[0] = '\0';
msg->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
SMEMCPY(&msg->yiaddr, &node->ipaddr, 4);
opt_buf = (u8_t *)msg + DHCP_OPTIONS_OFS;
/* add msg type */
*opt_buf++ = DHCP_OPTION_MESSAGE_TYPE;
*opt_buf++ = 1;
*opt_buf++ = DHCP_ACK;
/* add server id */
*opt_buf++ = DHCP_OPTION_SERVER_ID;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &(dhcp_server->netif->ip_addr), 4);
opt_buf += 4;
/* add_lease_time */
*opt_buf++ = DHCP_OPTION_LEASE_TIME;
*opt_buf++ = 4;
tmp = PP_HTONL(DHCP_DEFAULT_LIVE_TIME);
SMEMCPY(opt_buf, &tmp, 4);
opt_buf += 4;
/* add config */
*opt_buf++ = DHCP_OPTION_SUBNET_MASK;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &ip_2_ip4(&dhcp_server->netif->netmask)->addr, 4);
opt_buf += 4;
//*opt_buf++ = DHCP_OPTION_DNS_SERVER;
//*opt_buf++ = 4;
#ifdef DHCP_DNS_SERVER_IP
{
//ip_addr_t dns_addr;
//ipaddr_aton(DHCP_DNS_SERVER_IP, &dns_addr);
//SMEMCPY(opt_buf, &ip_2_ip4(&dns_addr)->addr, 4);
}
#else
/* default use gatewary dns server */
//SMEMCPY(opt_buf, &(dhcp_server->netif->ip_addr), 4);
#endif /* DHCP_DNS_SERVER_IP */
//opt_buf += 4;
*opt_buf++ = DHCP_OPTION_ROUTER;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &ip_2_ip4(&dhcp_server->netif->ip_addr)->addr, 4);
opt_buf += 4;
/* add option end */
*opt_buf++ = DHCP_OPTION_END;
length = (u32_t)opt_buf - (u32_t)msg;
if (length < q->tot_len)
{
pbuf_realloc(q, length);
}
ip_2_ip4(&addr)->addr = INADDR_BROADCAST;
udp_sendto_if(pcb, q, &addr, port, dhcp_server->netif);
}
else
{
/* Send no ack */
/* create dhcp offer and send */
msg->op = DHCP_BOOTREPLY;
msg->hops = 0;
msg->secs = 0;
SMEMCPY(&msg->siaddr, &(dhcp_server->netif->ip_addr), 4);
msg->sname[0] = '\0';
msg->file[0] = '\0';
msg->cookie = PP_HTONL(DHCP_MAGIC_COOKIE);
memset(&msg->yiaddr, 0, 4);
opt_buf = (u8_t *)msg + DHCP_OPTIONS_OFS;
/* add msg type */
*opt_buf++ = DHCP_OPTION_MESSAGE_TYPE;
*opt_buf++ = 1;
*opt_buf++ = DHCP_NAK;
/* add server id */
*opt_buf++ = DHCP_OPTION_SERVER_ID;
*opt_buf++ = 4;
SMEMCPY(opt_buf, &(dhcp_server->netif->ip_addr), 4);
opt_buf += 4;
/* add option end */
*opt_buf++ = DHCP_OPTION_END;
length = (u32_t)opt_buf - (u32_t)msg;
if (length < q->tot_len)
{
pbuf_realloc(q, length);
}
ip_2_ip4(&addr)->addr = INADDR_BROADCAST;
udp_sendto_if(pcb, q, &addr, port, dhcp_server->netif);
}
}
else if (msg_type == DHCP_RELEASE)
{
struct dhcp_client_node *node_prev = NULL;
for (node = dhcp_server->node_list; node != NULL; node = node->next)
{
if (memcmp(node->chaddr, msg->chaddr, msg->hlen) == 0)
{
if (node == dhcp_server->node_list)
{
dhcp_server->node_list = node->next;
}
else
{
node_prev->next = node->next;
}
break;
}
node_prev = node;
node = node->next;
}
if (node != NULL)
{
mem_free(node);
}
}
else if (msg_type == DHCP_DECLINE)
{
;
}
else if (msg_type == DHCP_INFORM)
{
;
}
}
}
}
free_pbuf_and_return:
pbuf_free(q);
}
/**
* start dhcp server for a netif
*
* @param netif The netif which use dhcp server
* @param start The Start IP address
* @param end The netif which use dhcp server
* @return lwIP error code
* - ERR_OK - No error
* - ERR_MEM - Out of memory
*/
err_t
dhcp_server_start(struct netif *netif, ip4_addr_t *start, ip4_addr_t *end)
{
struct dhcp_server *dhcp_server;
/* If this netif alreday use the dhcp server. */
for (dhcp_server = lw_dhcp_server; dhcp_server != NULL; dhcp_server = dhcp_server->next)
{
if (dhcp_server->netif == netif)
{
dhcp_server->start = *start;
dhcp_server->end = *end;
dhcp_server->current = *start;
return ERR_OK;
}
}
dhcp_server = NULL;
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_server_start(): starting new DHCP server\n"));
dhcp_server = (struct dhcp_server *)mem_malloc(sizeof(struct dhcp_server));
if (dhcp_server == NULL)
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_server_start(): could not allocate dhcp\n"));
return ERR_MEM;
}
/* clear data structure */
memset(dhcp_server, 0, sizeof(struct dhcp_server));
/* store this dhcp server to list */
dhcp_server->next = lw_dhcp_server;
lw_dhcp_server = dhcp_server;
dhcp_server->netif = netif;
dhcp_server->node_list = NULL;
dhcp_server->start = *start;
dhcp_server->end = *end;
dhcp_server->current = *start;
/* allocate UDP PCB */
dhcp_server->pcb = udp_new();
if (dhcp_server->pcb == NULL)
{
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_server_start(): could not obtain pcb\n"));
return ERR_MEM;
}
ip_set_option(dhcp_server->pcb, SOF_BROADCAST);
/* set up local and remote port for the pcb */
udp_bind(dhcp_server->pcb, IP_ADDR_ANY, DHCP_SERVER_PORT);
//udp_connect(dhcp_server->pcb, IP_ADDR_ANY, DHCP_CLIENT_PORT);
/* set up the recv callback and argument */
udp_recv(dhcp_server->pcb, dhcp_server_recv, dhcp_server);
LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_TRACE, ("dhcp_server_start(): starting DHCP server\n"));
return ERR_OK;
}
extern void set_if(const char *netif_name, const char *ip_addr, const char *gw_addr, const char *nm_addr);
void dhcpd_start(const char *netif_name)
{
struct netif *netif = netif_list;
err_t res;
DEBUG_PRINTF("%s: %s\r\n", __FUNCTION__, netif_name);
LWIP_NETIF_LOCK();
if (strlen(netif_name) > sizeof(netif->name))
{
DEBUG_PRINTF("network interface name too long!\r\n");
goto _exit;
}
while (netif != NULL)
{
if (strncmp(netif_name, netif->name, sizeof(netif->name)) == 0)
break;
netif = netif->next;
if (netif == NULL)
{
DEBUG_PRINTF("network interface: %s not found!\r\n", netif_name);
break;
}
}
if (netif == NULL)
{
goto _exit;
}
if (1)
{
dhcp_stop(netif);
//set_if(netif_name, DHCPD_SERVER_IP, "0.0.0.0", "255.255.255.0");
netif_set_up(netif);
}
{
char str_tmp[4 * 4 + 4] = DHCPD_SERVER_IP;
char *p = str_tmp;
ip4_addr_t ip_start, ip_end;
p = strchr(str_tmp, '.');
if (p)
{
p = strchr(p + 1, '.');
if (p)
{
p = strchr(p + 1, '.');
}
}
if (!p)
{
DEBUG_PRINTF("DHCPD_SERVER_IP: %s error!\r\n", str_tmp);
goto _exit;
}
p = p + 1; /* move to xxx.xxx.xxx.^ */
sprintf(p, "%d", DHCPD_CLIENT_IP_MIN);
ip4addr_aton(str_tmp, &ip_start);
DEBUG_PRINTF("ip_start: [%s]\r\n", str_tmp);
sprintf(p, "%d", DHCPD_CLIENT_IP_MAX);
ip4addr_aton(str_tmp, &ip_end);
DEBUG_PRINTF("ip_start: [%s]\r\n", str_tmp);
res = dhcp_server_start(netif, &ip_start, &ip_end);
if (res != 0)
{
DEBUG_PRINTF("dhcp_server_start res: %d.\r\n", res);
}
}
_exit:
LWIP_NETIF_UNLOCK();
return;
}
void dhcpd_stop(const char *netif_name)
{
struct dhcp_server *dhcp_server, *server_node;
struct netif *netif = netif_list;
struct dhcp_client_node *node, *next;
DEBUG_PRINTF("%s: %s\r\n", __FUNCTION__, netif_name);
LWIP_NETIF_LOCK();
if (strlen(netif_name) > sizeof(netif->name))
{
DEBUG_PRINTF("network interface name too long!\r\n");
goto _exit;
}
while (netif != NULL)
{
if (strncmp(netif_name, netif->name, sizeof(netif->name)) == 0)
break;
netif = netif->next;
if (netif == NULL)
{
DEBUG_PRINTF("network interface: %s not found!\r\n", netif_name);
break;
}
}
if (netif == NULL)
{
goto _exit;
}
/* If this netif alreday use the dhcp server. */
for (dhcp_server = lw_dhcp_server; dhcp_server != NULL; dhcp_server = dhcp_server->next)
{
if (dhcp_server->netif == netif)
{
break;
}
}
if (dhcp_server == NULL)
{
goto _exit;
}
/* remove dhcp server */
if (dhcp_server == lw_dhcp_server)
{
lw_dhcp_server = lw_dhcp_server->next;
}
else
{
server_node = lw_dhcp_server;
while (server_node->next && server_node->next != dhcp_server)
{
server_node = server_node->next;
}
if (server_node->next != NULL)
{
server_node->next = server_node->next->next;
}
}
udp_disconnect(dhcp_server->pcb);
udp_remove(dhcp_server->pcb);
/* remove all client node */
for (node = dhcp_server->node_list; node != NULL; node = next)
{
next = node->next;
mem_free(node);
}
mem_free(dhcp_server);
//set_if(netif_name, "0.0.0.0", "0.0.0.0", "0.0.0.0");
_exit:
LWIP_NETIF_UNLOCK();
}

View File

@ -0,0 +1,321 @@
/**
* @file
* Ethernet common functions
*
* @defgroup ethernet Ethernet
* @ingroup callbackstyle_api
*/
/*
* Copyright (c) 2001-2003 Swedish Institute of Computer Science.
* Copyright (c) 2003-2004 Leon Woestenberg <leon.woestenberg@axon.tv>
* Copyright (c) 2003-2004 Axon Digital Design B.V., The Netherlands.
* All rights reserved.
*
* 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. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
*
* This file is part of the lwIP TCP/IP stack.
*
*/
#include "lwip/opt.h"
#if LWIP_ARP || LWIP_ETHERNET
#include "netif/ethernet.h"
#include "lwip/def.h"
#include "lwip/stats.h"
#include "lwip/etharp.h"
#include "lwip/ip.h"
#include "lwip/snmp.h"
#include <string.h>
#include "netif/ppp/ppp_opts.h"
#if PPPOE_SUPPORT
#include "netif/ppp/pppoe.h"
#endif /* PPPOE_SUPPORT */
#ifdef LWIP_HOOK_FILENAME
#include LWIP_HOOK_FILENAME
#endif
const struct eth_addr ethbroadcast = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff}};
const struct eth_addr ethzero = {{0, 0, 0, 0, 0, 0}};
/**
* @ingroup lwip_nosys
* Process received ethernet frames. Using this function instead of directly
* calling ip_input and passing ARP frames through etharp in ethernetif_input,
* the ARP cache is protected from concurrent access.\n
* Don't call directly, pass to netif_add() and call netif->input().
*
* @param p the received packet, p->payload pointing to the ethernet header
* @param netif the network interface on which the packet was received
*
* @see LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
* @see ETHARP_SUPPORT_VLAN
* @see LWIP_HOOK_VLAN_CHECK
*/
err_t
ethernet_input(struct pbuf *p, struct netif *netif)
{
struct eth_hdr *ethhdr;
u16_t type;
#if LWIP_ARP || ETHARP_SUPPORT_VLAN || LWIP_IPV6
u16_t next_hdr_offset = SIZEOF_ETH_HDR;
#endif /* LWIP_ARP || ETHARP_SUPPORT_VLAN */
LWIP_ASSERT_CORE_LOCKED();
if (p->len <= SIZEOF_ETH_HDR) {
/* a packet with only an ethernet header (or less) is not valid for us */
ETHARP_STATS_INC(etharp.proterr);
ETHARP_STATS_INC(etharp.drop);
MIB2_STATS_NETIF_INC(netif, ifinerrors);
goto free_and_return;
}
if (p->if_idx == NETIF_NO_INDEX) {
p->if_idx = netif_get_index(netif);
}
/* points to packet payload, which starts with an Ethernet header */
ethhdr = (struct eth_hdr *)p->payload;
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("ethernet_input: dest:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", src:%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F":%"X8_F", type:%"X16_F"\n",
(unsigned char)ethhdr->dest.addr[0], (unsigned char)ethhdr->dest.addr[1], (unsigned char)ethhdr->dest.addr[2],
(unsigned char)ethhdr->dest.addr[3], (unsigned char)ethhdr->dest.addr[4], (unsigned char)ethhdr->dest.addr[5],
(unsigned char)ethhdr->src.addr[0], (unsigned char)ethhdr->src.addr[1], (unsigned char)ethhdr->src.addr[2],
(unsigned char)ethhdr->src.addr[3], (unsigned char)ethhdr->src.addr[4], (unsigned char)ethhdr->src.addr[5],
lwip_htons(ethhdr->type)));
type = ethhdr->type;
#if ETHARP_SUPPORT_VLAN
if (type == PP_HTONS(ETHTYPE_VLAN)) {
struct eth_vlan_hdr *vlan = (struct eth_vlan_hdr *)(((char *)ethhdr) + SIZEOF_ETH_HDR);
next_hdr_offset = SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR;
if (p->len <= SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) {
/* a packet with only an ethernet/vlan header (or less) is not valid for us */
ETHARP_STATS_INC(etharp.proterr);
ETHARP_STATS_INC(etharp.drop);
MIB2_STATS_NETIF_INC(netif, ifinerrors);
goto free_and_return;
}
#if defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) /* if not, allow all VLANs */
#ifdef LWIP_HOOK_VLAN_CHECK
if (!LWIP_HOOK_VLAN_CHECK(netif, ethhdr, vlan)) {
#elif defined(ETHARP_VLAN_CHECK_FN)
if (!ETHARP_VLAN_CHECK_FN(ethhdr, vlan)) {
#elif defined(ETHARP_VLAN_CHECK)
if (VLAN_ID(vlan) != ETHARP_VLAN_CHECK) {
#endif
/* silently ignore this packet: not for our VLAN */
pbuf_free(p);
return ERR_OK;
}
#endif /* defined(LWIP_HOOK_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK) || defined(ETHARP_VLAN_CHECK_FN) */
type = vlan->tpid;
}
#endif /* ETHARP_SUPPORT_VLAN */
#if LWIP_ARP_FILTER_NETIF
netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, lwip_htons(type));
#endif /* LWIP_ARP_FILTER_NETIF*/
if (ethhdr->dest.addr[0] & 1) {
/* this might be a multicast or broadcast packet */
if (ethhdr->dest.addr[0] == LL_IP4_MULTICAST_ADDR_0) {
#if LWIP_IPV4
if ((ethhdr->dest.addr[1] == LL_IP4_MULTICAST_ADDR_1) &&
(ethhdr->dest.addr[2] == LL_IP4_MULTICAST_ADDR_2)) {
/* mark the pbuf as link-layer multicast */
p->flags |= PBUF_FLAG_LLMCAST;
}
#endif /* LWIP_IPV4 */
}
#if LWIP_IPV6
else if ((ethhdr->dest.addr[0] == LL_IP6_MULTICAST_ADDR_0) &&
(ethhdr->dest.addr[1] == LL_IP6_MULTICAST_ADDR_1)) {
/* mark the pbuf as link-layer multicast */
p->flags |= PBUF_FLAG_LLMCAST;
}
#endif /* LWIP_IPV6 */
else if (eth_addr_cmp(&ethhdr->dest, &ethbroadcast)) {
/* mark the pbuf as link-layer broadcast */
p->flags |= PBUF_FLAG_LLBCAST;
}
}
switch (type) {
#if LWIP_IPV4 && LWIP_ARP
/* IP packet? */
case PP_HTONS(ETHTYPE_IP):
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
goto free_and_return;
}
/* skip Ethernet header (min. size checked above) */
if (pbuf_remove_header(p, next_hdr_offset)) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("ethernet_input: IPv4 packet dropped, too short (%"U16_F"/%"U16_F")\n",
p->tot_len, next_hdr_offset));
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
goto free_and_return;
} else {
/* pass to IP layer */
ip4_input(p, netif);
}
break;
case PP_HTONS(ETHTYPE_ARP):
if (!(netif->flags & NETIF_FLAG_ETHARP)) {
goto free_and_return;
}
/* skip Ethernet header (min. size checked above) */
if (pbuf_remove_header(p, next_hdr_offset)) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("ethernet_input: ARP response packet dropped, too short (%"U16_F"/%"U16_F")\n",
p->tot_len, next_hdr_offset));
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE, ("Can't move over header in packet"));
ETHARP_STATS_INC(etharp.lenerr);
ETHARP_STATS_INC(etharp.drop);
goto free_and_return;
} else {
/* pass p to ARP module */
etharp_input(p, netif);
}
break;
#endif /* LWIP_IPV4 && LWIP_ARP */
#if PPPOE_SUPPORT
case PP_HTONS(ETHTYPE_PPPOEDISC): /* PPP Over Ethernet Discovery Stage */
pppoe_disc_input(netif, p);
break;
case PP_HTONS(ETHTYPE_PPPOE): /* PPP Over Ethernet Session Stage */
pppoe_data_input(netif, p);
break;
#endif /* PPPOE_SUPPORT */
#if LWIP_IPV6
case PP_HTONS(ETHTYPE_IPV6): /* IPv6 */
/* skip Ethernet header */
if ((p->len < next_hdr_offset) || pbuf_remove_header(p, next_hdr_offset)) {
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_WARNING,
("ethernet_input: IPv6 packet dropped, too short (%"U16_F"/%"U16_F")\n",
p->tot_len, next_hdr_offset));
goto free_and_return;
} else {
/* pass to IPv6 layer */
ip6_input(p, netif);
}
break;
#endif /* LWIP_IPV6 */
default:
#ifdef LWIP_HOOK_UNKNOWN_ETH_PROTOCOL
if (LWIP_HOOK_UNKNOWN_ETH_PROTOCOL(p, netif) == ERR_OK) {
break;
}
#endif
ETHARP_STATS_INC(etharp.proterr);
ETHARP_STATS_INC(etharp.drop);
MIB2_STATS_NETIF_INC(netif, ifinunknownprotos);
goto free_and_return;
}
/* This means the pbuf is freed or consumed,
so the caller doesn't have to free it again */
return ERR_OK;
free_and_return:
pbuf_free(p);
return ERR_OK;
}
/**
* @ingroup ethernet
* Send an ethernet packet on the network using netif->linkoutput().
* The ethernet header is filled in before sending.
*
* @see LWIP_HOOK_VLAN_SET
*
* @param netif the lwIP network interface on which to send the packet
* @param p the packet to send. pbuf layer must be @ref PBUF_LINK.
* @param src the source MAC address to be copied into the ethernet header
* @param dst the destination MAC address to be copied into the ethernet header
* @param eth_type ethernet type (@ref lwip_ieee_eth_type)
* @return ERR_OK if the packet was sent, any other err_t on failure
*/
err_t
ethernet_output(struct netif * netif, struct pbuf * p,
const struct eth_addr * src, const struct eth_addr * dst,
u16_t eth_type) {
struct eth_hdr *ethhdr;
u16_t eth_type_be = lwip_htons(eth_type);
#if ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET)
s32_t vlan_prio_vid = LWIP_HOOK_VLAN_SET(netif, p, src, dst, eth_type);
if (vlan_prio_vid >= 0) {
struct eth_vlan_hdr *vlanhdr;
LWIP_ASSERT("prio_vid must be <= 0xFFFF", vlan_prio_vid <= 0xFFFF);
if (pbuf_add_header(p, SIZEOF_ETH_HDR + SIZEOF_VLAN_HDR) != 0) {
goto pbuf_header_failed;
}
vlanhdr = (struct eth_vlan_hdr *)(((u8_t *)p->payload) + SIZEOF_ETH_HDR);
vlanhdr->tpid = eth_type_be;
vlanhdr->prio_vid = lwip_htons((u16_t)vlan_prio_vid);
eth_type_be = PP_HTONS(ETHTYPE_VLAN);
} else
#endif /* ETHARP_SUPPORT_VLAN && defined(LWIP_HOOK_VLAN_SET) */
{
if (pbuf_add_header(p, SIZEOF_ETH_HDR) != 0) {
goto pbuf_header_failed;
}
}
LWIP_ASSERT_CORE_LOCKED();
ethhdr = (struct eth_hdr *)p->payload;
ethhdr->type = eth_type_be;
SMEMCPY(&ethhdr->dest, dst, ETH_HWADDR_LEN);
SMEMCPY(&ethhdr->src, src, ETH_HWADDR_LEN);
LWIP_ASSERT("netif->hwaddr_len must be 6 for ethernet_output!",
(netif->hwaddr_len == ETH_HWADDR_LEN));
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE,
("ethernet_output: sending packet %p\n", (void *)p));
/* send the packet */
return netif->linkoutput(netif, p);
pbuf_header_failed:
LWIP_DEBUGF(ETHARP_DEBUG | LWIP_DBG_TRACE | LWIP_DBG_LEVEL_SERIOUS,
("ethernet_output: could not allocate room for header.\n"));
LINK_STATS_INC(link.lenerr);
return ERR_BUF;
}
#endif /* LWIP_ARP || LWIP_ETHERNET */

View File

@ -0,0 +1,199 @@
#include <stdio.h>
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/ethip6.h"
#include "lwip/etharp.h"
#include "ethernet.h"
#define DUMP_LWIP_NCM_TX_DATA 0
#define DUMP_LWIP_NCM_RX_DATA 0
/* Define those to better describe your network interface. */
#define IFNAME0 'n'
#define IFNAME1 'c'
struct ethernetif {
struct eth_addr *ethaddr;
};
void ncm_net_set_intf(void* intf);
void gether_send_ext(void * const pxDescriptor);
int g_ncm_register(const char *name);
int ncm_get_mac_address(char mac[6]);
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void
ncm_low_level_init(struct netif *netif)
{
struct ethernetif *ethernetif = netif->state;
//int ret = -1;
char mac[6] = {0xdc, 0x0d, 0x30, 0xa2, 0x70, 0xcd};
/*ret = ncm_get_mac_address(mac);
if (ret < 0) {
printf("get wlan mac failed\r\n");
}*/
printf("%s:%d str_mac: %02x:%02x:%02x:%02x:%02x:%02x \r\n", __func__, __LINE__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
(void)ethernetif;
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = mac[0];
netif->hwaddr[1] = mac[1];
netif->hwaddr[2] = mac[2];
netif->hwaddr[3] = mac[3];
netif->hwaddr[4] = mac[4];
netif->hwaddr[5] = mac[5];
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
#if LWIP_IPV6 && LWIP_IPV6_MLD
/*
* For hardware/netifs that implement MAC filtering.
* All-nodes link-local is handled by default, so we must let the hardware know
* to allow multicast packets in.
* Should set mld_mac_filter previously. */
if (netif->mld_mac_filter != NULL) {
ip6_addr_t ip6_allnodes_ll;
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
}
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
/* Do whatever else is needed to initialize interface. */
}
static err_t
ncm_low_level_output(struct netif *netif, struct pbuf *p)
{
struct ethernetif *ethernetif = netif->state;
struct pbuf *q;
(void)ethernetif;
#if ETH_PAD_SIZE
pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */
#endif
for (q = p; q != NULL; q = q->next) {
pbuf_ref(q);
gether_send_ext((void*)q);
#if DUMP_LWIP_NCM_RX_DATA
if (1) {
int i;
char *tmpbuf = q->payload;
printf("[lwip] [send]-->");
for (i = 0; i < q->len; i++) {
printf("%02x ", tmpbuf[i]);
}printf("\r\n");
}
#endif
}
//signal that packet should be sent();
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
if (((u8_t *)p->payload)[0] & 1) {
/* broadcast or multicast packet*/
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
} else {
/* unicast packet */
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
}
/* increase ifoutdiscards or ifouterrors on error */
#if ETH_PAD_SIZE
pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
void ncm_ethernetif_input(void *h, struct pbuf* p)
{
struct netif *netif = (struct netif *)h;
//printf("netif->input:%p\r\n", netif->input);
#if DUMP_LWIP_NCM_RX_DATA
if (1) {
int i;
char *tmpbuf = p->payload;
printf("[lwip] [recv]-->");
for (i = 0; i < p->len; i++) {
printf("%02x ", tmpbuf[i]);
}printf("\r\n");
}
#endif
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
/* the pbuf will be free in upper layer, eg: ethernet_input */
}
err_t
ncm_ethernetif_init(struct netif *netif)
{
struct ethernetif *ethernetif;
LWIP_ASSERT("netif != NULL", (netif != NULL));
ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
return ERR_MEM;
}
#if LWIP_NETIF_HOSTNAME
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
#if LWIP_IPV4
netif->output = etharp_output;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = ncm_low_level_output;
g_ncm_register("ncm");
ethernetif->ethaddr = (struct eth_addr *) & (netif->hwaddr[0]);
ncm_low_level_init(netif);
ncm_net_set_intf((void*)netif);
return ERR_OK;
}

View File

@ -0,0 +1,322 @@
#include <stdio.h>
#include "lwip/opt.h"
#include "lwip/def.h"
#include "lwip/mem.h"
#include "lwip/pbuf.h"
#include "lwip/stats.h"
#include "lwip/snmp.h"
#include "lwip/ethip6.h"
#include "lwip/etharp.h"
#include "ethernet.h"
#include "wifi_constants.h"
#include "net_stack_intf.h"
#include "wifi_conf.h"
#define DUMP_LWIP_TX_DATA 0
#define DUMP_LWIP_RX_DATA 1
/* Define those to better describe your network interface. */
#define IFNAME0 'w'
#define IFNAME1 'i'
struct ethernetif {
struct eth_addr *ethaddr;
};
void print_hex(unsigned char *data, int len, const char* tag)
{
unsigned long i, j, l;
unsigned char tmp_str[140];
unsigned char tmp_str1[10];
//return;
for (i = 0; i < len; i += 16) {
int n ;
tmp_str[0] = '\0';
n = i ;
for (j = 0; j < 4; j++) {
l = n % 16;
if (l >= 10)
tmp_str[3 - j] = (unsigned char)('A' + l - 10);
else
tmp_str[3 - j] = (unsigned char)(l + '0');
n >>= 4 ;
}
tmp_str[4] = '\0';
strcat((char *) tmp_str, ": ");
/*
Output the hex bytes
*/
for (j = i; j < (i + 16); j ++) {
int m ;
if (j < len) {
m = ((unsigned int)((unsigned char) * (data + j))) / 16 ;
if (m >= 10)
tmp_str1[0] = 'A' + (unsigned char) m - 10;
else
tmp_str1[0] = (unsigned char) m + '0';
m = ((unsigned int)((unsigned char) * (data + j))) % 16 ;
if (m >= 10)
tmp_str1[1] = 'A' + (unsigned char) m - 10;
else
tmp_str1[1] = (unsigned char) m + '0';
tmp_str1[2] = '\0';
strcat((char *) tmp_str, (char *) tmp_str1);
strcat((char *) tmp_str, " ");
} else {
strcat((char *) tmp_str, " ");
}
}
strcat((char *) tmp_str, " ");
l = strlen((char *) tmp_str);
/* Output the ASCII bytes */
for (j = i; j < (i + 16); j++) {
if (j < len) {
char c = * (data + j);
if (c < ' ' || c > 'z') {
c = '.';
}
tmp_str[l ++] = c;
} else {
tmp_str[l ++] = ' ';
}
}
tmp_str[l ++] = '\r';
tmp_str[l ++] = '\n';
tmp_str[l ++] = '\0';
#ifdef __ANDROID__
if (tag)
__android_log_print(ANDROID_LOG_VERBOSE, tag, "%s", (const char *) tmp_str);
else
LOGV("%s", (const char *) tmp_str); //add (const char*)
#else
printf("%s", (const char *) tmp_str);
#endif
}
}
void rltk_wlan_set_intf(void* intf);
/**
* In this function, the hardware should be initialized.
* Called from ethernetif_init().
*
* @param netif the already initialized lwip network interface structure
* for this ethernetif
*/
static void
wlan_low_level_init(struct netif *netif)
{
struct ethernetif *ethernetif = netif->state;
int ret = -1;
char mac[6] = {0xdc, 0x0d, 0x30, 0xa2, 0x70, 0xcd};
char str_mac[32] = {0};
ret = wifi_get_mac_address(str_mac);
if (ret < 0) {
printf("get wlan mac failed\r\n");
} else {
sscanf(str_mac, "%02x:%02x:%02x:%02x:%02x:%02x", (uint32_t *)&mac[0], (uint32_t *)&mac[1], (uint32_t *)&mac[2],
(uint32_t *)&mac[3], (uint32_t *)&mac[4], (uint32_t *)&mac[5]);
}
printf("%s:%d str_mac: %02x:%02x:%02x:%02x:%02x:%02x \r\n", __func__, __LINE__, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
(void)ethernetif;
/* set MAC hardware address length */
netif->hwaddr_len = ETHARP_HWADDR_LEN;
/* set MAC hardware address */
netif->hwaddr[0] = mac[0];
netif->hwaddr[1] = mac[1];
netif->hwaddr[2] = mac[2];
netif->hwaddr[3] = mac[3];
netif->hwaddr[4] = mac[4];
netif->hwaddr[5] = mac[5];
/* maximum transfer unit */
netif->mtu = 1500;
/* device capabilities */
/* don't set NETIF_FLAG_ETHARP if this device is not an ethernet one */
netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_IGMP;
#if LWIP_IPV6 && LWIP_IPV6_MLD
/*
* For hardware/netifs that implement MAC filtering.
* All-nodes link-local is handled by default, so we must let the hardware know
* to allow multicast packets in.
* Should set mld_mac_filter previously. */
if (netif->mld_mac_filter != NULL) {
ip6_addr_t ip6_allnodes_ll;
ip6_addr_set_allnodes_linklocal(&ip6_allnodes_ll);
netif->mld_mac_filter(netif, &ip6_allnodes_ll, NETIF_ADD_MAC_FILTER);
}
#endif /* LWIP_IPV6 && LWIP_IPV6_MLD */
/* Do whatever else is needed to initialize interface. */
}
static err_t
wlan_low_level_output(struct netif *netif, struct pbuf *p)
{
struct ethernetif *ethernetif = netif->state;
struct pbuf *q;
(void)ethernetif;
if (!(netif->flags & NETIF_FLAG_UP)) {
printf("wlan is not up\r\n");
return ERR_IF;
}
#if ETH_PAD_SIZE
pbuf_remove_header(p, ETH_PAD_SIZE); /* drop the padding word */
#endif
for (q = p; q != NULL; q = q->next) {
struct eth_drv_sg sg_list = {0};
sg_list.buf = (unsigned int)q->payload;
sg_list.len = (unsigned int)q->len;
rltk_wlan_send(0, &sg_list, 1, q->len);
#if DUMP_LWIP_TX_DATA
if (1) {
int i;
char *tmpbuf = q->payload;
printf("[lwip] [send]-->");
for (i = 0; i < q->tot_len; i++) {
printf("%02x ", tmpbuf[i]);
}printf("\r\n");
}
#endif
}
//signal that packet should be sent();
MIB2_STATS_NETIF_ADD(netif, ifoutoctets, p->tot_len);
if (((u8_t *)p->payload)[0] & 1) {
/* broadcast or multicast packet*/
MIB2_STATS_NETIF_INC(netif, ifoutnucastpkts);
} else {
/* unicast packet */
MIB2_STATS_NETIF_INC(netif, ifoutucastpkts);
}
/* increase ifoutdiscards or ifouterrors on error */
#if ETH_PAD_SIZE
pbuf_add_header(p, ETH_PAD_SIZE); /* reclaim the padding word */
#endif
LINK_STATS_INC(link.xmit);
return ERR_OK;
}
void wlan_ethernetif_input(void *h, size_t len)
{
struct netif *netif = (struct netif *)h;
struct pbuf *p;
int ret = -1;
if (NULL == netif) {
printf("wlan is not ready\r\n");
return;
}
if (!(netif->flags & NETIF_FLAG_UP)) {
printf("wlan is not up\r\n");
return;
}
/* acquire new pbuf, type: PBUF_REF */
p = pbuf_alloc(PBUF_RAW, len, PBUF_POOL);
if (p == NULL) {
printf("wlan_ethernetif_input malloc failed\r\n");
return;
}
struct eth_drv_sg sg_list = {0};
sg_list.buf = (unsigned int)p->payload;
sg_list.len = (unsigned int)len;
ret = rltk_wlan_recv(0, &sg_list, 1);
if (ret == 0) {
printf("no rcv data\r\n");
pbuf_free(p);
return;
}//printf("netif->input:%p\r\n", netif->input);
#if DUMP_LWIP_RX_DATA
if (0) {
int i;
char *tmpbuf = p->payload;
printf("[lwip] [recv]-->");
for (i = 0; i < len; i++) {
printf("%02x ", tmpbuf[i]);
}printf("\r\n");
} else {
if (len > 100) {
//printf("recv len:%d\r\n", len);
//print_hex(p->payload, len, NULL);
}
}
#endif
/* full packet send to tcpip_thread to process */
if (netif->input(p, netif) != ERR_OK) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_input: IP input error\n"));
pbuf_free(p);
}
/* the pbuf will be free in upper layer, eg: ethernet_input */
}
err_t
wlan_ethernetif_init(struct netif *netif)
{
struct ethernetif *ethernetif;
LWIP_ASSERT("netif != NULL", (netif != NULL));
ethernetif = mem_malloc(sizeof(struct ethernetif));
if (ethernetif == NULL) {
LWIP_DEBUGF(NETIF_DEBUG, ("ethernetif_init: out of memory\n"));
return ERR_MEM;
}
#if LWIP_NETIF_HOSTNAME
netif->hostname = "lwip";
#endif /* LWIP_NETIF_HOSTNAME */
//MIB2_INIT_NETIF(netif, snmp_ifType_ethernet_csmacd, LINK_SPEED_OF_YOUR_NETIF_IN_BPS);
netif->state = ethernetif;
netif->name[0] = IFNAME0;
netif->name[1] = IFNAME1;
#if LWIP_IPV4
netif->output = etharp_output;
#endif /* LWIP_IPV4 */
#if LWIP_IPV6
netif->output_ip6 = ethip6_output;
#endif /* LWIP_IPV6 */
netif->linkoutput = wlan_low_level_output;
ethernetif->ethaddr = (struct eth_addr *) & (netif->hwaddr[0]);
wlan_low_level_init(netif);
rltk_wlan_set_intf((void*)netif);
return ERR_OK;
}