W5500协议层之DHCP功能
头文件
# ifndef STM32_VET6_W5500_DHCP_H
# define STM32_VET6_W5500_DHCP_H
# include "socket.h"
# define DEVICE_ID "w5500"
# define IP_CONFLICT_STR "CHECK_IP_CONFLICT"
# define DHCP_FLAGSBROADCAST 0x8000
# define DHCP_SERVER_PORT 67
# define DHCP_CLIENT_PORT 68
# define DHCP_BOOTREQUEST 1
# define DHCP_BOOTREPLY 2
# define DHCP_DISCOVER 1
# define DHCP_OFFER 2
# define DHCP_REQUEST 3
# define DHCP_DECLINE 4
# define DHCP_ACK 5
# define DHCP_NAK 6
# define DHCP_RELEASE 7
# define DHCP_INFORM 8
# define DHCP_HTYPE10MB 1
# define DHCP_HTYPE100MB 2
# define DHCP_HLENETHERNET 6
# define DHCP_HOPS 0
# define DHCP_SECS 0
# define MAGIC_COOKIE 0x63825363
# define DEFAULT_XID 0x12345678
# define MAX_DHCP_OPT 16
enum {
STATE_DHCP_READY = 0 ,
STATE_DHCP_DISCOVER,
STATE_DHCP_REQUEST,
STATE_DHCP_LEASED,
STATE_DHCP_REREQUEST,
STATE_DHCP_RELEASE,
} ;
enum {
padOption = 0 ,
subnetMask = 1 ,
timerOffset = 2 ,
routersOnSubnet = 3 ,
timeServer = 4 ,
nameServer = 5 ,
dns = 6 ,
logServer = 7 ,
cookieServer = 8 ,
lprServer = 9 ,
impressServer = 10 ,
resourceLocationServer = 11 ,
hostName = 12 ,
bootFileSize = 13 ,
meritDumpFile = 14 ,
domainName = 15 ,
swapServer = 16 ,
rootPath = 17 ,
extentionsPath = 18 ,
IPforwarding = 19 ,
nonLocalSourceRouting = 20 ,
policyFilter = 21 ,
maxDgramReasmSize = 22 ,
defaultIPTTL = 23 ,
pathMTUagingTimeout = 24 ,
pathMTUplateauTable = 25 ,
ifMTU = 26 ,
allSubnetsLocal = 27 ,
broadcastAddr = 28 ,
performMaskDiscovery = 29 ,
maskSupplier = 30 ,
performRouterDiscovery = 31 ,
routerSolicitationAddr = 32 ,
staticRoute = 33 ,
trailerEncapsulation = 34 ,
arpCacheTimeout = 35 ,
ethernetEncapsulation = 36 ,
tcpDefaultTTL = 37 ,
tcpKeepaliveInterval = 38 ,
tcpKeepaliveGarbage = 39 ,
nisDomainName = 40 ,
nisServers = 41 ,
ntpServers = 42 ,
vendorSpecificInfo = 43 ,
netBIOSnameServer = 44 ,
netBIOSdgramDistServer = 45 ,
netBIOSnodeType = 46 ,
netBIOSscope = 47 ,
xFontServer = 48 ,
xDisplayManager = 49 ,
dhcpRequestedIPaddr = 50 ,
dhcpIPaddrLeaseTime = 51 ,
dhcpOptionOverload = 52 ,
dhcpMessageType = 53 ,
dhcpServerIdentifier = 54 ,
dhcpParamRequest = 55 ,
dhcpMsg = 56 ,
dhcpMaxMsgSize = 57 ,
dhcpT1value = 58 ,
dhcpT2value = 59 ,
dhcpClassIdentifier = 60 ,
dhcpClientIdentifier = 61 ,
endOption = 255
} ;
typedef struct _RIP_MSG {
uint8_t op;
uint8_t htype;
uint8_t hlen;
uint8_t hops;
uint32_t xid;
uint16_t secs;
uint16_t flags;
uint8_t ciaddr[ 4 ] ;
uint8_t yiaddr[ 4 ] ;
uint8_t siaddr[ 4 ] ;
uint8_t giaddr[ 4 ] ;
uint8_t chaddr[ 16 ] ;
uint8_t sname[ 64 ] ;
uint8_t file[ 128 ] ;
uint8_t OPT[ 312 ] ;
} RIP_MSG;
void dhcp_init ( ) ;
void dhcp_config_registry ( module_w5500_t * conf) ;
bool do_dhcp ( SOCKET s, uint32_t timeout_cnt) ;
# endif
源文件
# include "w5500_dhcp.h"
# define DBG_ENABLE
# define DBG_SECTION_NAME "dhcp"
# define DBG_LEVEL DBG_INFO
# include "sys_dbg.h"
uint8_t EXTERN_DHCPBUF[ 1024 ] ;
RIP_MSG * pRIPMSG = ( RIP_MSG * ) EXTERN_DHCPBUF;
uint32_t DHCP_XID = DEFAULT_XID;
uint8_t OLD_SIP[ 4 ] ;
uint8_t DHCP_SIP[ 4 ] = { 0 } ;
uint8_t DHCP_REAL_SIP[ 4 ] = { 0 } ;
static module_w5500_t * w5500_ptr;
uint32_t dhcp_lease_time;
void send_DHCP_DISCOVER ( SOCKET s) ;
void send_DHCP_REQUEST ( SOCKET s, uint8_t pkt_type) ;
void send_DHCP_RELEASE_DECLINE ( SOCKET s, char msgtype) ;
uint8_t parseDHCPMSG ( SOCKET s, uint16_t length) ;
uint8_t check_leasedIP ( SOCKET s) ;
uint8_t * SRC_MAC_ADDR = NULL ;
uint8_t * GET_SIP = NULL ;
uint8_t * GET_GW_IP = NULL ;
uint8_t * GET_SN_MASK = NULL ;
uint8_t GET_DNS_IP[ 4 ] = { 0 } ;
void dhcp_config_registry ( module_w5500_t * conf) {
w5500_ptr = conf;
GET_SIP = conf-> net_conf. ip;
GET_SN_MASK = conf-> net_conf. sub;
SRC_MAC_ADDR = conf-> net_conf. mac;
GET_GW_IP = conf-> net_conf. gw;
}
void dhcp_init ( ) {
w5500_ptr-> driver. rst_low ( ) ;
w5500_ptr-> driver. delay ( 3 ) ;
w5500_ptr-> driver. rst_high ( ) ;
w5500_ptr-> driver. delay ( 1600 ) ;
w5500_chip_init ( ) ;
w5500_writes ( MAC_ADDR, w5500_ptr-> net_conf. mac, 6 ) ;
for ( uint8_t i = 0 ; i < w5500_ptr-> base_conf. socket_num; i++ ) {
w5500_write ( Sn_TXMEM_SIZE ( i) , w5500_ptr-> base_conf. tx_size[ i] ) ;
w5500_write ( Sn_RXMEM_SIZE ( i) , w5500_ptr-> base_conf. rx_size[ i] ) ;
}
}
uint16_t wait_DHCP_Response ( SOCKET s, uint32_t timeout_cnt) {
uint16_t len;
uint8_t type = 0 ;
for ( int i = 0 ; i < timeout_cnt; ++ i) {
len = w5500_socket_rx_size_read ( s) ;
if ( len > 0 ) {
type = parseDHCPMSG ( s, len) ;
break ;
}
}
return type;
}
bool do_dhcp ( SOCKET s, uint32_t timeout_cnt) {
uint16_t type;
if ( udp_client_init ( s, DHCP_CLIENT_PORT) ) {
send_DHCP_DISCOVER ( s) ;
type = wait_DHCP_Response ( s, timeout_cnt) ;
if ( type == DHCP_OFFER) {
send_DHCP_REQUEST ( s, STATE_DHCP_REQUEST) ;
type = wait_DHCP_Response ( s, timeout_cnt) ;
if ( type == DHCP_ACK) {
LOG_D ( "dhcp_lease_time is %d" , dhcp_lease_time) ;
if ( check_leasedIP ( s) ) {
memcpy ( OLD_SIP, GET_SIP, 4 ) ;
DHCP_XID++ ;
send_DHCP_REQUEST ( s, STATE_DHCP_LEASED) ;
type = wait_DHCP_Response ( s, timeout_cnt) ;
if ( type != DHCP_ACK && type != 0 ) {
LOG_W ( "release dhcp connect error:%d" , type) ;
}
LOG_D ( "config ip start" ) ;
w5500_writes ( SUB_ADDR, w5500_ptr-> net_conf. sub, 4 ) ;
w5500_writes ( GAR_ADDR, w5500_ptr-> net_conf. gw, 4 ) ;
w5500_writes ( SIPR_ADDR, w5500_ptr-> net_conf. ip, 4 ) ;
LOG_I ( "<DHCP GET IP OK>" ) ;
LOG_I ( "IP:%d.%d.%d.%d" , w5500_ptr-> net_conf. ip[ 0 ] , w5500_ptr-> net_conf. ip[ 1 ] ,
w5500_ptr-> net_conf. ip[ 2 ] , w5500_ptr-> net_conf. ip[ 3 ] ) ;
return true;
} else {
LOG_W ( "state : DHCP_RET_CONFLICT" ) ;
}
} else if ( type == DHCP_NAK) {
LOG_W ( "send_DHCP_REQUEST is DHCP_NAK " ) ;
}
}
}
return false;
}
uint8_t check_leasedIP ( SOCKET s) {
LOG_D ( "<Check the IP Conflict %d.%d.%d.%d: " , GET_SIP[ 0 ] , GET_SIP[ 1 ] , GET_SIP[ 2 ] , GET_SIP[ 3 ] ) ;
if ( sendto ( s, ( uint8_t * ) IP_CONFLICT_STR, strlen ( IP_CONFLICT_STR) , GET_SIP, 5000 ) ) {
send_DHCP_RELEASE_DECLINE ( s, 1 ) ;
return 0 ;
}
return 1 ;
}
uint8_t parseDHCPMSG ( SOCKET s, uint16_t length) {
uint8_t svr_addr[ 6 ] ;
uint16_t svr_port;
uint16_t len;
uint8_t * p;
uint8_t * e;
uint8_t type;
uint8_t opt_len = 0 ;
len = recvfrom ( s, ( uint8_t * ) pRIPMSG, length, svr_addr, & svr_port) ;
LOG_D ( "DHCP_SIP:%u.%u.%u.%u" , DHCP_SIP[ 0 ] , DHCP_SIP[ 1 ] , DHCP_SIP[ 2 ] , DHCP_SIP[ 3 ] ) ;
LOG_D ( "DHCP_RIP:%u.%u.%u.%u" , DHCP_REAL_SIP[ 0 ] , DHCP_REAL_SIP[ 1 ] , DHCP_REAL_SIP[ 2 ] , DHCP_REAL_SIP[ 3 ] ) ;
LOG_D ( "svr_addr:%u.%u.%u.%u" , svr_addr[ 0 ] , svr_addr[ 1 ] , svr_addr[ 2 ] , svr_addr[ 3 ] ) ;
if ( pRIPMSG-> op != DHCP_BOOTREPLY || svr_port != DHCP_SERVER_PORT) {
LOG_D ( "DHCP : NO DHCP MSG" ) ;
return 0 ;
}
if ( memcmp ( pRIPMSG-> chaddr, SRC_MAC_ADDR, 6 ) != 0 || pRIPMSG-> xid != htonl ( DHCP_XID) ) {
LOG_W ( "No My DHCP Message. This message is ignored." ) ;
LOG_W ( "\tSRC_MAC_ADDR(%02X.%02X.%02X.%02X.%02X.%02X)" ,
SRC_MAC_ADDR[ 0 ] , SRC_MAC_ADDR[ 1 ] , SRC_MAC_ADDR[ 2 ] ,
SRC_MAC_ADDR[ 3 ] , SRC_MAC_ADDR[ 4 ] , SRC_MAC_ADDR[ 5 ] ) ;
LOG_W ( ", pRIPMSG->chaddr(%02X.%02X.%02X." , ( char ) pRIPMSG-> chaddr[ 0 ] , ( char ) pRIPMSG-> chaddr[ 1 ] ,
( char ) pRIPMSG-> chaddr[ 2 ] ) ;
LOG_W ( "%02X.%02X.%02X)" , pRIPMSG-> chaddr[ 3 ] , pRIPMSG-> chaddr[ 4 ] , pRIPMSG-> chaddr[ 5 ] ) ;
LOG_W ( "\tpRIPMSG->xid(%08X), DHCP_XID(%08X)" , pRIPMSG-> xid, ( DHCP_XID) ) ;
LOG_W ( "\tpRIMPMSG->yiaddr:%d.%d.%d.%d" , pRIPMSG-> yiaddr[ 0 ] , pRIPMSG-> yiaddr[ 1 ] , pRIPMSG-> yiaddr[ 2 ] ,
pRIPMSG-> yiaddr[ 3 ] ) ;
return 0 ;
}
if ( * ( ( uint32_t * ) DHCP_SIP) != 0x00000000 ) {
if ( * ( ( uint32_t * ) DHCP_REAL_SIP) != * ( ( uint32_t * ) svr_addr) &&
* ( ( uint32_t * ) DHCP_SIP) != * ( ( uint32_t * ) svr_addr) ) {
LOG_D ( "Another DHCP sever send a response message. This is ignored." ) ;
LOG_D ( "\tIP:%u.%u.%u.%u" , svr_addr[ 0 ] , svr_addr[ 1 ] , svr_addr[ 2 ] , svr_addr[ 3 ] ) ;
return 0 ;
}
}
memcpy ( GET_SIP, pRIPMSG-> yiaddr, 4 ) ;
LOG_D ( "DHCP MSG received" ) ;
LOG_D ( "yiaddr : %u.%u.%u.%u" , GET_SIP[ 0 ] , GET_SIP[ 1 ] , GET_SIP[ 2 ] , GET_SIP[ 3 ] ) ;
type = 0 ;
p = ( uint8_t * ) ( & pRIPMSG-> op) ;
p = p + 240 ;
e = p + ( len - 240 ) ;
LOG_D ( "p : %08X e : %08X len : %d" , ( uint32_t ) p, ( uint32_t ) e, len) ;
while ( p < e) {
switch ( * p++ ) {
case endOption:
return type;
case padOption:
break ;
case dhcpMessageType:
opt_len = * p++ ;
type = * p;
LOG_D ( "dhcpMessageType : %02X" , type) ;
break ;
case subnetMask:
opt_len = * p++ ;
memcpy ( GET_SN_MASK, p, 4 ) ;
break ;
case routersOnSubnet:
opt_len = * p++ ;
memcpy ( GET_GW_IP, p, 4 ) ;
break ;
case dns:
opt_len = * p++ ;
memcpy ( GET_DNS_IP, p, 4 ) ;
break ;
case dhcpIPaddrLeaseTime:
opt_len = * p++ ;
dhcp_lease_time = ntohl ( * ( ( uint32_t * ) p) ) ;
break ;
case dhcpServerIdentifier:
opt_len = * p++ ;
if ( * ( ( uint32_t * ) DHCP_SIP) == 0 ||
* ( ( uint32_t * ) DHCP_REAL_SIP) == * ( ( uint32_t * ) svr_addr) ||
* ( ( uint32_t * ) DHCP_SIP) == * ( ( uint32_t * ) svr_addr) ) {
memcpy ( DHCP_SIP, p, 4 ) ;
memcpy ( DHCP_REAL_SIP, svr_addr, 4 ) ;
LOG_D ( "My dhcpServerIdentifier : %u.%u.%u.%u" ,
DHCP_SIP[ 0 ] , DHCP_SIP[ 1 ] , DHCP_SIP[ 2 ] , DHCP_SIP[ 3 ] ) ;
LOG_D ( "My DHCP server real IP address :%u.%u.%u.%u" ,
DHCP_REAL_SIP[ 0 ] , DHCP_REAL_SIP[ 1 ] , DHCP_REAL_SIP[ 2 ] , DHCP_REAL_SIP[ 3 ] ) ;
} else {
LOG_D ( "Another dhcpServerIdentifier : MY(%u.%u.%u.%u) Another(%u.%u.%u.%u)" ,
DHCP_SIP[ 0 ] , DHCP_SIP[ 1 ] , DHCP_SIP[ 2 ] , DHCP_SIP[ 3 ] ,
svr_addr[ 0 ] , svr_addr[ 1 ] , svr_addr[ 2 ] , svr_addr[ 3 ] ) ;
}
break ;
default :
opt_len = * p++ ;
break ;
}
p += opt_len;
}
return 0 ;
}
void send_DHCP_DISCOVER ( SOCKET s) {
uint8_t ip[ 4 ] = { 255 , 255 , 255 , 255 } ;
uint16_t i = 0 ;
uint8_t host_name[ 12 ] ;
memset ( ( void * ) pRIPMSG, 0 , sizeof ( RIP_MSG) ) ;
pRIPMSG-> op = DHCP_BOOTREQUEST;
pRIPMSG-> htype = DHCP_HTYPE10MB;
pRIPMSG-> hlen = DHCP_HLENETHERNET;
pRIPMSG-> hops = DHCP_HOPS;
pRIPMSG-> xid = htonl ( DHCP_XID) ;
pRIPMSG-> secs = htons ( DHCP_SECS) ;
pRIPMSG-> flags = htons ( DHCP_FLAGSBROADCAST) ;
memcpy ( pRIPMSG-> chaddr, SRC_MAC_ADDR, 6 ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 24 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 16 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 8 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( MAGIC_COOKIE & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = dhcpMessageType;
pRIPMSG-> OPT[ i++ ] = 0x01 ;
pRIPMSG-> OPT[ i++ ] = DHCP_DISCOVER;
pRIPMSG-> OPT[ i++ ] = dhcpClientIdentifier;
pRIPMSG-> OPT[ i++ ] = 0x07 ;
pRIPMSG-> OPT[ i++ ] = 0x01 ;
memcpy ( pRIPMSG-> OPT + i, SRC_MAC_ADDR, 6 ) ;
i += 6 ;
pRIPMSG-> OPT[ i++ ] = hostName;
sprintf ( ( char * ) host_name, "%.4s-%02X%02X%02X" , DEVICE_ID,
SRC_MAC_ADDR[ 3 ] , SRC_MAC_ADDR[ 4 ] , SRC_MAC_ADDR[ 5 ] ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) strlen ( ( char * ) host_name) ;
strcpy ( ( char * ) ( & ( pRIPMSG-> OPT[ i] ) ) , ( char * ) host_name) ;
i += ( uint16_t ) strlen ( ( char * ) host_name) ;
pRIPMSG-> OPT[ i++ ] = dhcpParamRequest;
pRIPMSG-> OPT[ i++ ] = 0x06 ;
pRIPMSG-> OPT[ i++ ] = subnetMask;
pRIPMSG-> OPT[ i++ ] = routersOnSubnet;
pRIPMSG-> OPT[ i++ ] = dns;
pRIPMSG-> OPT[ i++ ] = domainName;
pRIPMSG-> OPT[ i++ ] = dhcpT1value;
pRIPMSG-> OPT[ i++ ] = dhcpT2value;
pRIPMSG-> OPT[ i++ ] = endOption;
sendto ( s, ( uint8_t * ) pRIPMSG, sizeof ( RIP_MSG) , ip, DHCP_SERVER_PORT) ;
LOG_D ( "sent DHCP_DISCOVER" ) ;
}
void send_DHCP_REQUEST ( SOCKET s, uint8_t pkt_type) {
uint8_t ip[ 4 ] , host_name[ 12 ] ;
uint16_t i = 0 ;
memset ( ( void * ) pRIPMSG, 0 , sizeof ( RIP_MSG) ) ;
pRIPMSG-> op = DHCP_BOOTREQUEST;
pRIPMSG-> htype = DHCP_HTYPE10MB;
pRIPMSG-> hlen = DHCP_HLENETHERNET;
pRIPMSG-> hops = DHCP_HOPS;
pRIPMSG-> xid = htonl ( DHCP_XID) ;
pRIPMSG-> secs = htons ( DHCP_SECS) ;
if ( pkt_type < STATE_DHCP_LEASED)
pRIPMSG-> flags = htons ( DHCP_FLAGSBROADCAST) ;
else {
pRIPMSG-> flags = 0 ;
memcpy ( pRIPMSG-> ciaddr, GET_SIP, 4 ) ;
}
memcpy ( pRIPMSG-> chaddr, SRC_MAC_ADDR, 6 ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 24 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 16 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 8 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( MAGIC_COOKIE & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = dhcpMessageType;
pRIPMSG-> OPT[ i++ ] = 0x01 ;
pRIPMSG-> OPT[ i++ ] = DHCP_REQUEST;
pRIPMSG-> OPT[ i++ ] = dhcpClientIdentifier;
pRIPMSG-> OPT[ i++ ] = 0x07 ;
pRIPMSG-> OPT[ i++ ] = 0x01 ;
memcpy ( pRIPMSG-> OPT + i, SRC_MAC_ADDR, 6 ) ;
i += 6 ;
if ( pkt_type < STATE_DHCP_LEASED) {
pRIPMSG-> OPT[ i++ ] = dhcpRequestedIPaddr;
pRIPMSG-> OPT[ i++ ] = 0x04 ;
memcpy ( pRIPMSG-> OPT + i, GET_SIP, 4 ) ;
i += 4 ;
pRIPMSG-> OPT[ i++ ] = dhcpServerIdentifier;
pRIPMSG-> OPT[ i++ ] = 0x04 ;
memcpy ( pRIPMSG-> OPT + i, DHCP_SIP, 4 ) ;
i += 4 ;
}
pRIPMSG-> OPT[ i++ ] = hostName;
sprintf ( ( char * ) host_name, ( char * ) "%.4s-%02X%02X%02X" , DEVICE_ID, SRC_MAC_ADDR[ 3 ] , SRC_MAC_ADDR[ 4 ] ,
SRC_MAC_ADDR[ 5 ] ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) strlen ( ( char * ) host_name) ;
strcpy ( ( char * ) & ( pRIPMSG-> OPT[ i] ) , ( char * ) host_name) ;
i += strlen ( ( char * ) host_name) ;
pRIPMSG-> OPT[ i++ ] = dhcpParamRequest;
pRIPMSG-> OPT[ i++ ] = 0x08 ;
pRIPMSG-> OPT[ i++ ] = subnetMask;
pRIPMSG-> OPT[ i++ ] = routersOnSubnet;
pRIPMSG-> OPT[ i++ ] = dns;
pRIPMSG-> OPT[ i++ ] = domainName;
pRIPMSG-> OPT[ i++ ] = dhcpT1value;
pRIPMSG-> OPT[ i++ ] = dhcpT2value;
pRIPMSG-> OPT[ i++ ] = performRouterDiscovery;
pRIPMSG-> OPT[ i++ ] = staticRoute;
pRIPMSG-> OPT[ i++ ] = endOption;
if ( pkt_type < STATE_DHCP_LEASED)
memset ( ip, 0xFF , 4 ) ;
else
memcpy ( ip, DHCP_SIP, 4 ) ;
sendto ( s, ( uint8_t * ) pRIPMSG, sizeof ( RIP_MSG) , ip, DHCP_SERVER_PORT) ;
LOG_D ( "sent DHCP_REQUEST" ) ;
}
void send_DHCP_RELEASE_DECLINE ( SOCKET s, char msgtype) {
uint16_t i = 0 ;
uint8_t ip[ 4 ] ;
memset ( ( void * ) pRIPMSG, 0 , sizeof ( RIP_MSG) ) ;
pRIPMSG-> op = DHCP_BOOTREQUEST;
pRIPMSG-> htype = DHCP_HTYPE10MB;
pRIPMSG-> hlen = DHCP_HLENETHERNET;
pRIPMSG-> hops = DHCP_HOPS;
pRIPMSG-> xid = htonl ( DHCP_XID) ;
pRIPMSG-> secs = htons ( DHCP_SECS) ;
pRIPMSG-> flags = 0 ;
memcpy ( pRIPMSG-> chaddr, SRC_MAC_ADDR, 6 ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 24 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 16 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( ( MAGIC_COOKIE >> 8 ) & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = ( uint8_t ) ( MAGIC_COOKIE & 0xFF ) ;
pRIPMSG-> OPT[ i++ ] = dhcpMessageType;
pRIPMSG-> OPT[ i++ ] = 0x01 ;
pRIPMSG-> OPT[ i++ ] = ( ( ! msgtype) ? DHCP_RELEASE : DHCP_DECLINE) ;
pRIPMSG-> OPT[ i++ ] = dhcpClientIdentifier;
pRIPMSG-> OPT[ i++ ] = 0x07 ;
pRIPMSG-> OPT[ i++ ] = 0x01 ;
memcpy ( pRIPMSG-> OPT + i, SRC_MAC_ADDR, 6 ) ;
i += 6 ;
pRIPMSG-> OPT[ i++ ] = dhcpServerIdentifier;
pRIPMSG-> OPT[ i++ ] = 0x04 ;
pRIPMSG-> OPT[ i++ ] = DHCP_SIP[ 0 ] ;
pRIPMSG-> OPT[ i++ ] = DHCP_SIP[ 1 ] ;
pRIPMSG-> OPT[ i++ ] = DHCP_SIP[ 2 ] ;
pRIPMSG-> OPT[ i++ ] = DHCP_SIP[ 3 ] ;
if ( msgtype) {
pRIPMSG-> OPT[ i++ ] = dhcpRequestedIPaddr;
pRIPMSG-> OPT[ i++ ] = 0x04 ;
pRIPMSG-> OPT[ i++ ] = GET_SIP[ 0 ] ;
pRIPMSG-> OPT[ i++ ] = GET_SIP[ 1 ] ;
pRIPMSG-> OPT[ i++ ] = GET_SIP[ 2 ] ;
pRIPMSG-> OPT[ i++ ] = GET_SIP[ 3 ] ;
LOG_D ( "sent DHCP_DECLINE\r\n" ) ;
} else {
LOG_D ( "sent DHCP_RELEASE" ) ;
}
pRIPMSG-> OPT[ i++ ] = endOption;
if ( msgtype)
memset ( ip, 0xFF , 4 ) ;
else
memcpy ( ip, DHCP_SIP, 4 ) ;
sendto ( s, ( uint8_t * ) pRIPMSG, sizeof ( RIP_MSG) , ip, DHCP_SERVER_PORT) ;
}
测试
# include "app_conf.h"
# include "w5500_config.h"
# if APP_CONFIG_W5500_DHCP
# define DBG_ENABLE
# define DBG_SECTION_NAME "w5500"
# define DBG_LEVEL W5500_DBG_LEVEL
# include "sys_dbg.h"
# include "w5500_dhcp.h"
# define W5500_CS stm_port_define ( B, 12 )
# define W5500_RST stm_port_define ( B, 10 )
static SPI_HandleTypeDef * w5500_spi = NULL ;
static void send_and_rec_bytes ( uint8_t * in_dat, uint8_t * out_data, uint16_t len) {
if ( in_dat == NULL && out_data == NULL ) return ;
uint8_t * p_tx = in_dat;
uint8_t * p_rx = out_data;
if ( p_rx == NULL ) {
HAL_SPI_Transmit ( w5500_spi, p_tx, len, 10 ) ;
} else {
if ( p_tx == NULL ) {
p_tx = p_rx;
}
HAL_SPI_TransmitReceive ( w5500_spi, p_tx, p_rx, len, 10 ) ;
}
}
static void W5500_RST_HIGH ( void ) { stm_pin_high ( GPIOB, GPIO_PIN_10) ; }
static void W5500_RST_LOW ( void ) { stm_pin_low ( GPIOB, GPIO_PIN_10) ; }
static void W5500_CS_LOW ( void ) { stm_pin_low ( GPIOB, GPIO_PIN_12) ; }
static void W5500_CS_HIGH ( void ) { stm_pin_high ( GPIOB, GPIO_PIN_12) ; }
static void W5500_Driver_MspInit ( void ) {
stm32_pin_mode ( W5500_CS, pin_mode_output) ;
stm32_pin_mode ( W5500_RST, pin_mode_output) ;
stm_pin_low ( W5500_RST) ;
stm_pin_low ( W5500_CS) ;
bsp_SpiHandleInit ( w5500_spi, SPI_BAUDRATEPRESCALER_4, spi_mode_0) ;
}
module_w5500_t w5500_conf = {
. base_conf= {
. socket_num = 4 ,
. rx_size= { 4 , 4 , 4 , 4 } ,
. tx_size= { 4 , 4 , 4 , 4 } ,
} ,
. net_conf= {
} ,
. driver= {
. cs_high = W5500_CS_HIGH,
. cs_low = W5500_CS_LOW,
. rst_high= W5500_RST_HIGH,
. rst_low= W5500_RST_LOW,
. delay = HAL_Delay,
. send_and_rec_bytes = send_and_rec_bytes
} ,
. api = {
. msp_init= W5500_Driver_MspInit,
}
} ;
static void w5500_pre_init ( void ) {
w5500_spi = conv_spi_handle_ptr ( handle_get_by_id ( spi2_id) ) ;
module_w5500_init ( & w5500_conf) ;
uint32_t uid0 = HAL_GetUIDw0 ( ) ;
uint32_t uid1 = HAL_GetUIDw1 ( ) ;
uint32_t uid2 = HAL_GetUIDw2 ( ) ;
uint8_t mac[ 6 ] = { 0 , uid0 >> 8 , uid1, uid1 >> 8 , uid2, uid2 >> 8 } ;
memcpy ( w5500_conf. net_conf. mac, mac, sizeof ( mac) ) ;
dhcp_config_registry ( & w5500_conf) ;
w5500_conf. net_conf_init = dhcp_init;
}
static void w5500_init ( void ) {
w5500_conf. api. msp_init ( ) ;
}
static void w5500_after_init ( void ) {
w5500_conf. net_conf_init ( ) ;
printf ( "w5500 invoke after\r\n" ) ;
uint16_t try_cnt = 0 ;
while ( ! do_dhcp ( 0 , 0x1000 ) ) {
if ( try_cnt > 20 ) {
LOG_D ( "try timeout" ) ;
break ;
}
try_cnt++ ;
}
}
app_init_export ( w5500_net_conf, w5500_pre_init, w5500_init, w5500_after_init) ;
# endif
结果