diff --git a/Internet/DHCP/dhcp.c b/Internet/DHCP/dhcp.c index 87f4db9..99c7bd5 100644 --- a/Internet/DHCP/dhcp.c +++ b/Internet/DHCP/dhcp.c @@ -1,5 +1,11 @@ //***************************************************************************** // +// +// THIS FILE HAS BEEN MODIFIED FOR Mahda System. +// +// +//***************************************************************************** +// //! \file dhcp.c //! \brief DHCP APIs implement file. //! \details Processing DHCP protocol as DISCOVER, OFFER, REQUEST, ACK, NACK and DECLINE. @@ -11,7 +17,7 @@ //! <2012/12/20> V1.1.0 //! 1. Optimize code //! 2. Add reg_dhcp_cbfunc() -//! 3. Add DHCP_stop() +//! 3. Add DHCP_stop() //! 4. Integrate check_DHCP_state() & DHCP_run() to DHCP_run() //! 5. Don't care system endian //! 6. Add comments @@ -22,30 +28,30 @@ //! //! Copyright (c) 2013, WIZnet Co., LTD. //! All rights reserved. -//! -//! Redistribution and use in source and binary forms, with or without -//! modification, are permitted provided that the following conditions -//! are met: -//! -//! * Redistributions of source code must retain the above copyright -//! notice, this list of conditions and the following disclaimer. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions +//! are met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. //! * 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. -//! * Neither the name of the nor the names of its -//! contributors may be used to endorse or promote products derived -//! from this software without specific prior written permission. -//! +//! documentation and/or other materials provided with the distribution. +//! * Neither the name of the 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 +//! 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 OWNER OR CONTRIBUTORS BE -//! LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -//! CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +//! ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER 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 +//! 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. // //***************************************************************************** @@ -56,8 +62,8 @@ /* If you want to display debug & processing message, Define _DHCP_DEBUG_ in dhcp.h */ #ifdef _DHCP_DEBUG_ - #include -#endif +#include +#endif /* DHCP state machine. */ #define STATE_DHCP_INIT 0 ///< Initialize @@ -169,7 +175,7 @@ enum /* * @brief DHCP message format - */ + */ typedef struct { uint8_t op; ///< @ref DHCP_BOOTREQUEST or @ref DHCP_BOOTREPLY uint8_t htype; ///< @ref DHCP_HTYPE10MB or @ref DHCP_HTYPE100MB @@ -200,8 +206,12 @@ uint8_t OLD_allocated_ip[4] = {0, }; // Previous IP address uint8_t DHCP_allocated_ip[4] = {0, }; // IP address from DHCP uint8_t DHCP_allocated_gw[4] = {0, }; // Gateway address from DHCP uint8_t DHCP_allocated_sn[4] = {0, }; // Subnet mask from DHCP -uint8_t DHCP_allocated_dns[4] = {0, }; // DNS address from DHCP +uint8_t DHCP_allocated_dns[MAX_DNS_SERVER_ADDRESS][4] = {0, }; // DNS address from DHCP +uint8_t DHCP_allocated_ntp[MAX_DNS_SERVER_ADDRESS][4] = {0, }; // NTP address from DHCP +int32_t DHCP_allocated_to = 0; // Time offset from DHCP +uint8_t DHCP_allocated_dns_counter = 0; +uint8_t DHCP_allocated_ntp_counter = 0; int8_t dhcp_state = STATE_DHCP_INIT; // DHCP state int8_t dhcp_retry_count = 0; @@ -214,7 +224,7 @@ uint32_t DHCP_XID; // Any number RIP_MSG* pDHCPMSG; // Buffer pointer for DHCP processing -uint8_t HOST_NAME[] = DCHP_HOST_NAME; +uint8_t HOST_NAME[MAX_SIZE_OF_DCHP_HOST_NAME] = DEFAULT_DCHP_HOST_NAME; uint8_t DHCP_CHADDR[6]; // DHCP Client MAC address. @@ -256,19 +266,19 @@ int8_t parseDHCPCMSG(void); /* The default handler of ip assign first */ void default_ip_assign(void) { - setSIPR(DHCP_allocated_ip); - setSUBR(DHCP_allocated_sn); - setGAR (DHCP_allocated_gw); + setSIPR(DHCP_allocated_ip); + setSUBR(DHCP_allocated_sn); + setGAR (DHCP_allocated_gw); } /* The default handler of ip changed */ void default_ip_update(void) { /* WIZchip Software Reset */ - setMR(MR_RST); - getMR(); // for delay - default_ip_assign(); - setSHAR(DHCP_CHADDR); + setMR(MR_RST); + getMR(); // for delay + default_ip_assign(); + setSHAR(DHCP_CHADDR); } /* The default handler of ip changed */ @@ -356,7 +366,7 @@ void send_DHCP_DISCOVER(void) uint16_t i; uint8_t ip[4]; uint16_t k = 0; - + makeDHCPMSG(); DHCP_SIP[0]=0; DHCP_SIP[1]=0; @@ -368,12 +378,12 @@ void send_DHCP_DISCOVER(void) DHCP_REAL_SIP[3]=0; k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - + // Option Request Param pDHCPMSG->OPT[k++] = dhcpMessageType; pDHCPMSG->OPT[k++] = 0x01; pDHCPMSG->OPT[k++] = DHCP_DISCOVER; - + // Client identifier pDHCPMSG->OPT[k++] = dhcpClientIdentifier; pDHCPMSG->OPT[k++] = 0x07; @@ -384,18 +394,18 @@ void send_DHCP_DISCOVER(void) pDHCPMSG->OPT[k++] = DHCP_CHADDR[3]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - + // host name pDHCPMSG->OPT[k++] = hostName; pDHCPMSG->OPT[k++] = 0; // fill zero length of hostname for(i = 0 ; HOST_NAME[i] != 0; i++) - pDHCPMSG->OPT[k++] = HOST_NAME[i]; - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname pDHCPMSG->OPT[k++] = dhcpParamRequest; @@ -406,6 +416,8 @@ void send_DHCP_DISCOVER(void) pDHCPMSG->OPT[k++] = domainName; pDHCPMSG->OPT[k++] = dhcpT1value; pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = timerOffset; + pDHCPMSG->OPT[k++] = ntpServers; pDHCPMSG->OPT[k++] = endOption; for (i = k; i < OPT_SIZE; i++) pDHCPMSG->OPT[i] = 0; @@ -430,31 +442,31 @@ void send_DHCP_REQUEST(void) uint8_t ip[4]; uint16_t k = 0; - makeDHCPMSG(); + makeDHCPMSG(); if(dhcp_state == STATE_DHCP_LEASED || dhcp_state == STATE_DHCP_REREQUEST) { - *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); - *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); - pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; - pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; - pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; - pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; - ip[0] = DHCP_SIP[0]; - ip[1] = DHCP_SIP[1]; - ip[2] = DHCP_SIP[2]; - ip[3] = DHCP_SIP[3]; - } - else - { - ip[0] = 255; - ip[1] = 255; - ip[2] = 255; - ip[3] = 255; - } - - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); + *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); + pDHCPMSG->ciaddr[0] = DHCP_allocated_ip[0]; + pDHCPMSG->ciaddr[1] = DHCP_allocated_ip[1]; + pDHCPMSG->ciaddr[2] = DHCP_allocated_ip[2]; + pDHCPMSG->ciaddr[3] = DHCP_allocated_ip[3]; + ip[0] = DHCP_SIP[0]; + ip[1] = DHCP_SIP[1]; + ip[2] = DHCP_SIP[2]; + ip[3] = DHCP_SIP[3]; + } + else + { + ip[0] = 255; + ip[1] = 255; + ip[2] = 255; + ip[3] = 255; + } + + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + // Option Request Param. pDHCPMSG->OPT[k++] = dhcpMessageType; pDHCPMSG->OPT[k++] = 0x01; @@ -470,15 +482,15 @@ void send_DHCP_REQUEST(void) pDHCPMSG->OPT[k++] = DHCP_CHADDR[4]; pDHCPMSG->OPT[k++] = DHCP_CHADDR[5]; - if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) - { + if(ip[3] == 255) // if(dchp_state == STATE_DHCP_LEASED || dchp_state == DHCP_REREQUEST_STATE) + { pDHCPMSG->OPT[k++] = dhcpRequestedIPaddr; pDHCPMSG->OPT[k++] = 0x04; pDHCPMSG->OPT[k++] = DHCP_allocated_ip[0]; pDHCPMSG->OPT[k++] = DHCP_allocated_ip[1]; pDHCPMSG->OPT[k++] = DHCP_allocated_ip[2]; pDHCPMSG->OPT[k++] = DHCP_allocated_ip[3]; - + pDHCPMSG->OPT[k++] = dhcpServerIdentifier; pDHCPMSG->OPT[k++] = 0x04; pDHCPMSG->OPT[k++] = DHCP_SIP[0]; @@ -491,23 +503,25 @@ void send_DHCP_REQUEST(void) pDHCPMSG->OPT[k++] = hostName; pDHCPMSG->OPT[k++] = 0; // length of hostname for(i = 0 ; HOST_NAME[i] != 0; i++) - pDHCPMSG->OPT[k++] = HOST_NAME[i]; - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); - pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); + pDHCPMSG->OPT[k++] = HOST_NAME[i]; + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3] >> 4); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[3]); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4] >> 4); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[4]); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5] >> 4); + // pDHCPMSG->OPT[k++] = NibbleToHex(DHCP_CHADDR[5]); pDHCPMSG->OPT[k - (i+6+1)] = i+6; // length of hostname - + pDHCPMSG->OPT[k++] = dhcpParamRequest; - pDHCPMSG->OPT[k++] = 0x08; + pDHCPMSG->OPT[k++] = 0x08 + 0x02; pDHCPMSG->OPT[k++] = subnetMask; pDHCPMSG->OPT[k++] = routersOnSubnet; pDHCPMSG->OPT[k++] = dns; pDHCPMSG->OPT[k++] = domainName; pDHCPMSG->OPT[k++] = dhcpT1value; pDHCPMSG->OPT[k++] = dhcpT2value; + pDHCPMSG->OPT[k++] = timerOffset; + pDHCPMSG->OPT[k++] = ntpServers; pDHCPMSG->OPT[k++] = performRouterDiscovery; pDHCPMSG->OPT[k++] = staticRoute; pDHCPMSG->OPT[k++] = endOption; @@ -517,7 +531,7 @@ void send_DHCP_REQUEST(void) #ifdef _DHCP_DEBUG_ printf("> Send DHCP_REQUEST\r\n"); #endif - + sendto(DHCP_SOCKET, (uint8_t *)pDHCPMSG, RIP_MSG_SIZE, ip, DHCP_SERVER_PORT); } @@ -528,11 +542,11 @@ void send_DHCP_DECLINE(void) int i; uint8_t ip[4]; uint16_t k = 0; - + makeDHCPMSG(); - k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() - + k = 4; // because MAGIC_COOKIE already made by makeDHCPMSG() + *((uint8_t*)(&pDHCPMSG->flags)) = ((DHCP_FLAGSUNICAST & 0xFF00)>> 8); *((uint8_t*)(&pDHCPMSG->flags)+1) = (DHCP_FLAGSUNICAST & 0x00FF); @@ -593,37 +607,37 @@ int8_t parseDHCPMSG(void) uint8_t * e; uint8_t type = 0; uint8_t opt_len; - - if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) - { - len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); - #ifdef _DHCP_DEBUG_ - printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); - #endif - } - else return 0; + + if((len = getSn_RX_RSR(DHCP_SOCKET)) > 0) + { + len = recvfrom(DHCP_SOCKET, (uint8_t *)pDHCPMSG, len, svr_addr, &svr_port); +#ifdef _DHCP_DEBUG_ + printf("DHCP message : %d.%d.%d.%d(%d) %d received. \r\n",svr_addr[0],svr_addr[1],svr_addr[2], svr_addr[3],svr_port, len); +#endif + } + else return 0; if (svr_port == DHCP_SERVER_PORT) { - // compare mac address + // compare mac address if ( (pDHCPMSG->chaddr[0] != DHCP_CHADDR[0]) || (pDHCPMSG->chaddr[1] != DHCP_CHADDR[1]) || - (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || - (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) + (pDHCPMSG->chaddr[2] != DHCP_CHADDR[2]) || (pDHCPMSG->chaddr[3] != DHCP_CHADDR[3]) || + (pDHCPMSG->chaddr[4] != DHCP_CHADDR[4]) || (pDHCPMSG->chaddr[5] != DHCP_CHADDR[5]) ) { #ifdef _DHCP_DEBUG_ - printf("No My DHCP Message. This message is ignored.\r\n"); + printf("No My DHCP Message. This message is ignored.\r\n"); #endif - return 0; + return 0; } - //compare DHCP server ip address - if((DHCP_SIP[0]!=0) || (DHCP_SIP[1]!=0) || (DHCP_SIP[2]!=0) || (DHCP_SIP[3]!=0)){ + //compare DHCP server ip address + if((DHCP_SIP[0]!=0) || (DHCP_SIP[1]!=0) || (DHCP_SIP[2]!=0) || (DHCP_SIP[3]!=0)){ if( ((svr_addr[0]!=DHCP_SIP[0])|| (svr_addr[1]!=DHCP_SIP[1])|| (svr_addr[2]!=DHCP_SIP[2])|| (svr_addr[3]!=DHCP_SIP[3])) && ((svr_addr[0]!=DHCP_REAL_SIP[0])|| (svr_addr[1]!=DHCP_REAL_SIP[1])|| (svr_addr[2]!=DHCP_REAL_SIP[2])|| (svr_addr[3]!=DHCP_REAL_SIP[3])) ) - { + { #ifdef _DHCP_DEBUG_ - printf("Another DHCP sever send a response message. This is ignored.\r\n"); + printf("Another DHCP sever send a response message. This is ignored.\r\n"); #endif - return 0; - } - } + return 0; + } + } p = (uint8_t *)(&pDHCPMSG->op); p = p + 240; // 240 = sizeof(RIP_MSG) + MAGIC_COOKIE size in RIP_MSG.opt - sizeof(RIP_MSG.opt) e = p + (len - 240); @@ -632,71 +646,104 @@ int8_t parseDHCPMSG(void) switch ( *p ) { - case endOption : - p = e; // for break while(p < e) - break; - case padOption : - p++; - break; - case dhcpMessageType : - p++; - p++; - type = *p++; - break; - case subnetMask : - p++; - p++; - DHCP_allocated_sn[0] = *p++; - DHCP_allocated_sn[1] = *p++; - DHCP_allocated_sn[2] = *p++; - DHCP_allocated_sn[3] = *p++; - break; - case routersOnSubnet : - p++; - opt_len = *p++; - DHCP_allocated_gw[0] = *p++; - DHCP_allocated_gw[1] = *p++; - DHCP_allocated_gw[2] = *p++; - DHCP_allocated_gw[3] = *p++; - p = p + (opt_len - 4); - break; - case dns : - p++; - opt_len = *p++; - DHCP_allocated_dns[0] = *p++; - DHCP_allocated_dns[1] = *p++; - DHCP_allocated_dns[2] = *p++; - DHCP_allocated_dns[3] = *p++; - p = p + (opt_len - 4); - break; - case dhcpIPaddrLeaseTime : - p++; - opt_len = *p++; - dhcp_lease_time = *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - dhcp_lease_time = (dhcp_lease_time << 8) + *p++; - #ifdef _DHCP_DEBUG_ - dhcp_lease_time = 10; - #endif - break; - case dhcpServerIdentifier : - p++; - opt_len = *p++; - DHCP_SIP[0] = *p++; - DHCP_SIP[1] = *p++; - DHCP_SIP[2] = *p++; - DHCP_SIP[3] = *p++; - DHCP_REAL_SIP[0]=svr_addr[0]; - DHCP_REAL_SIP[1]=svr_addr[1]; - DHCP_REAL_SIP[2]=svr_addr[2]; - DHCP_REAL_SIP[3]=svr_addr[3]; - break; - default : - p++; - opt_len = *p++; - p += opt_len; - break; + case endOption : + p = e; // for break while(p < e) + break; + case padOption : + p++; + break; + case dhcpMessageType : + p++; + p++; + type = *p++; + break; + case subnetMask : + p++; + p++; + DHCP_allocated_sn[0] = *p++; + DHCP_allocated_sn[1] = *p++; + DHCP_allocated_sn[2] = *p++; + DHCP_allocated_sn[3] = *p++; + break; + case routersOnSubnet : + p++; + opt_len = *p++; + DHCP_allocated_gw[0] = *p++; + DHCP_allocated_gw[1] = *p++; + DHCP_allocated_gw[2] = *p++; + DHCP_allocated_gw[3] = *p++; + p = p + (opt_len - 4); + break; + case dns : + p++; + opt_len = *p++; + DHCP_allocated_dns_counter = opt_len / 4; + for (uint8_t CC = 0; CC < DHCP_allocated_dns_counter; CC++) { + if (CC < MAX_DNS_SERVER_ADDRESS) { + DHCP_allocated_dns[CC][0] = *p++; + DHCP_allocated_dns[CC][1] = *p++; + DHCP_allocated_dns[CC][2] = *p++; + DHCP_allocated_dns[CC][3] = *p++; + } + else + p += 4; + } + p = p + (opt_len - DHCP_allocated_dns_counter * 4); // It can be removed + break; + case dhcpIPaddrLeaseTime : + p++; + opt_len = *p++; + dhcp_lease_time = *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + dhcp_lease_time = (dhcp_lease_time << 8) + *p++; + // #ifdef _DHCP_DEBUG_ + // dhcp_lease_time = 10; + // #endif + break; + case dhcpServerIdentifier : + p++; + opt_len = *p++; + DHCP_SIP[0] = *p++; + DHCP_SIP[1] = *p++; + DHCP_SIP[2] = *p++; + DHCP_SIP[3] = *p++; + DHCP_REAL_SIP[0]=svr_addr[0]; + DHCP_REAL_SIP[1]=svr_addr[1]; + DHCP_REAL_SIP[2]=svr_addr[2]; + DHCP_REAL_SIP[3]=svr_addr[3]; + break; + case timerOffset: + p++; + opt_len = *p++; + DHCP_allocated_to = (*p++ << 24); + DHCP_allocated_to |= (*p++ << 16); + DHCP_allocated_to |= (*p++ << 8); + DHCP_allocated_to |= (*p++ << 0); + // printf("TO : %d\r\n",DHCP_allocated_to); + p = p + (opt_len - 4); + break; + case ntpServers: + p++; + opt_len = *p++; + DHCP_allocated_ntp_counter = opt_len / 4; + for (uint8_t CC = 0; CC < DHCP_allocated_ntp_counter; CC++) { + if (CC < MAX_NTP_SERVER_ADDRESS) { + DHCP_allocated_ntp[CC][0] = *p++; + DHCP_allocated_ntp[CC][1] = *p++; + DHCP_allocated_ntp[CC][2] = *p++; + DHCP_allocated_ntp[CC][3] = *p++; + } + else + p += 4; + } + p = p + (opt_len - DHCP_allocated_ntp_counter * 4); // It can be removed + break; + default: + p++; + opt_len = *p++; + p += opt_len; + break; } // switch } // while } // if @@ -711,123 +758,123 @@ uint8_t DHCP_run(void) if(dhcp_state == STATE_DHCP_STOP) return DHCP_STOPPED; if(getSn_SR(DHCP_SOCKET) != SOCK_UDP) - socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); + socket(DHCP_SOCKET, Sn_MR_UDP, DHCP_CLIENT_PORT, 0x00); ret = DHCP_RUNNING; type = parseDHCPMSG(); switch ( dhcp_state ) { - case STATE_DHCP_INIT : - DHCP_allocated_ip[0] = 0; - DHCP_allocated_ip[1] = 0; - DHCP_allocated_ip[2] = 0; - DHCP_allocated_ip[3] = 0; - send_DHCP_DISCOVER(); - dhcp_state = STATE_DHCP_DISCOVER; - break; - case STATE_DHCP_DISCOVER : - if (type == DHCP_OFFER){ + case STATE_DHCP_INIT : + DHCP_allocated_ip[0] = 0; + DHCP_allocated_ip[1] = 0; + DHCP_allocated_ip[2] = 0; + DHCP_allocated_ip[3] = 0; + send_DHCP_DISCOVER(); + dhcp_state = STATE_DHCP_DISCOVER; + break; + case STATE_DHCP_DISCOVER : + if (type == DHCP_OFFER){ #ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_OFFER\r\n"); + printf("> Receive DHCP_OFFER\r\n"); #endif - DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; - DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; - DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; - DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; - - send_DHCP_REQUEST(); - dhcp_state = STATE_DHCP_REQUEST; - } else ret = check_DHCP_timeout(); - break; + DHCP_allocated_ip[0] = pDHCPMSG->yiaddr[0]; + DHCP_allocated_ip[1] = pDHCPMSG->yiaddr[1]; + DHCP_allocated_ip[2] = pDHCPMSG->yiaddr[2]; + DHCP_allocated_ip[3] = pDHCPMSG->yiaddr[3]; + + send_DHCP_REQUEST(); + dhcp_state = STATE_DHCP_REQUEST; + } else ret = check_DHCP_timeout(); + break; - case STATE_DHCP_REQUEST : - if (type == DHCP_ACK) { + case STATE_DHCP_REQUEST : + if (type == DHCP_ACK) { #ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_ACK\r\n"); + printf("> Receive DHCP_ACK\r\n"); #endif - if (check_DHCP_leasedIP()) { - // Network info assignment from DHCP - dhcp_ip_assign(); - reset_DHCP_timeout(); - - dhcp_state = STATE_DHCP_LEASED; - } else { - // IP address conflict occurred - reset_DHCP_timeout(); - dhcp_ip_conflict(); - dhcp_state = STATE_DHCP_INIT; - } - } else if (type == DHCP_NAK) { + if (check_DHCP_leasedIP()) { + // Network info assignment from DHCP + dhcp_ip_assign(); + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_LEASED; + } else { + // IP address conflict occurred + reset_DHCP_timeout(); + dhcp_ip_conflict(); + dhcp_state = STATE_DHCP_INIT; + } + } else if (type == DHCP_NAK) { #ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_NACK\r\n"); + printf("> Receive DHCP_NACK\r\n"); #endif - reset_DHCP_timeout(); + reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_DISCOVER; - } else ret = check_DHCP_timeout(); + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); break; - case STATE_DHCP_LEASED : - ret = DHCP_IP_LEASED; - if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { - + case STATE_DHCP_LEASED : + ret = DHCP_IP_LEASED; + if ((dhcp_lease_time != INFINITE_LEASETIME) && ((dhcp_lease_time/2) < dhcp_tick_1s)) { + #ifdef _DHCP_DEBUG_ - printf("> Maintains the IP address \r\n"); + printf("> Maintains the IP address \r\n"); #endif - type = 0; - OLD_allocated_ip[0] = DHCP_allocated_ip[0]; - OLD_allocated_ip[1] = DHCP_allocated_ip[1]; - OLD_allocated_ip[2] = DHCP_allocated_ip[2]; - OLD_allocated_ip[3] = DHCP_allocated_ip[3]; - - DHCP_XID++; + type = 0; + OLD_allocated_ip[0] = DHCP_allocated_ip[0]; + OLD_allocated_ip[1] = DHCP_allocated_ip[1]; + OLD_allocated_ip[2] = DHCP_allocated_ip[2]; + OLD_allocated_ip[3] = DHCP_allocated_ip[3]; - send_DHCP_REQUEST(); + DHCP_XID++; - reset_DHCP_timeout(); + send_DHCP_REQUEST(); - dhcp_state = STATE_DHCP_REREQUEST; - } + reset_DHCP_timeout(); + + dhcp_state = STATE_DHCP_REREQUEST; + } break; - case STATE_DHCP_REREQUEST : - ret = DHCP_IP_LEASED; - if (type == DHCP_ACK) { - dhcp_retry_count = 0; - if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || - OLD_allocated_ip[1] != DHCP_allocated_ip[1] || - OLD_allocated_ip[2] != DHCP_allocated_ip[2] || - OLD_allocated_ip[3] != DHCP_allocated_ip[3]) - { - ret = DHCP_IP_CHANGED; - dhcp_ip_update(); - #ifdef _DHCP_DEBUG_ - printf(">IP changed.\r\n"); - #endif - - } - #ifdef _DHCP_DEBUG_ - else printf(">IP is continued.\r\n"); - #endif - reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_LEASED; - } else if (type == DHCP_NAK) { + case STATE_DHCP_REREQUEST : + ret = DHCP_IP_LEASED; + if (type == DHCP_ACK) { + dhcp_retry_count = 0; + if (OLD_allocated_ip[0] != DHCP_allocated_ip[0] || + OLD_allocated_ip[1] != DHCP_allocated_ip[1] || + OLD_allocated_ip[2] != DHCP_allocated_ip[2] || + OLD_allocated_ip[3] != DHCP_allocated_ip[3]) + { + ret = DHCP_IP_CHANGED; + dhcp_ip_update(); +#ifdef _DHCP_DEBUG_ + printf(">IP changed.\r\n"); +#endif + + } +#ifdef _DHCP_DEBUG_ + else printf(">IP is continued.\r\n"); +#endif + reset_DHCP_timeout(); + dhcp_state = STATE_DHCP_LEASED; + } else if (type == DHCP_NAK) { #ifdef _DHCP_DEBUG_ - printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); + printf("> Receive DHCP_NACK, Failed to maintain ip\r\n"); #endif - reset_DHCP_timeout(); + reset_DHCP_timeout(); - dhcp_state = STATE_DHCP_DISCOVER; - } else ret = check_DHCP_timeout(); - break; - default : - break; + dhcp_state = STATE_DHCP_DISCOVER; + } else ret = check_DHCP_timeout(); + break; + default : + break; } return ret; @@ -835,36 +882,36 @@ uint8_t DHCP_run(void) void DHCP_stop(void) { - close(DHCP_SOCKET); - dhcp_state = STATE_DHCP_STOP; + close(DHCP_SOCKET); + dhcp_state = STATE_DHCP_STOP; } uint8_t check_DHCP_timeout(void) { uint8_t ret = DHCP_RUNNING; - + if (dhcp_retry_count < MAX_DHCP_RETRY) { if (dhcp_tick_next < dhcp_tick_1s) { switch ( dhcp_state ) { - case STATE_DHCP_DISCOVER : -// printf("<> state : STATE_DHCP_DISCOVER\r\n"); - send_DHCP_DISCOVER(); + case STATE_DHCP_DISCOVER : + // printf("<> state : STATE_DHCP_DISCOVER\r\n"); + send_DHCP_DISCOVER(); break; - - case STATE_DHCP_REQUEST : -// printf("<> state : STATE_DHCP_REQUEST\r\n"); - send_DHCP_REQUEST(); + case STATE_DHCP_REQUEST : + // printf("<> state : STATE_DHCP_REQUEST\r\n"); + + send_DHCP_REQUEST(); break; - case STATE_DHCP_REREQUEST : -// printf("<> state : STATE_DHCP_REREQUEST\r\n"); - - send_DHCP_REQUEST(); + case STATE_DHCP_REREQUEST : + // printf("<> state : STATE_DHCP_REREQUEST\r\n"); + + send_DHCP_REQUEST(); break; - - default : + + default : break; } @@ -874,7 +921,7 @@ uint8_t check_DHCP_timeout(void) } } else { // timeout occurred - switch(dhcp_state) { + switch(dhcp_state) { case STATE_DHCP_DISCOVER: dhcp_state = STATE_DHCP_INIT; ret = DHCP_FAILED; @@ -925,23 +972,23 @@ int8_t check_DHCP_leasedIP(void) return 0; } -} +} -void DHCP_init(uint8_t s, uint8_t * buf) +void DHCP_init(uint8_t s, uint8_t * buf, const char *HostName) { - uint8_t zeroip[4] = {0,0,0,0}; - getSHAR(DHCP_CHADDR); - if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) - { - // assigning temporary mac address, you should be set SHAR before call this function. - DHCP_CHADDR[0] = 0x00; - DHCP_CHADDR[1] = 0x08; - DHCP_CHADDR[2] = 0xdc; - DHCP_CHADDR[3] = 0x00; - DHCP_CHADDR[4] = 0x00; - DHCP_CHADDR[5] = 0x00; - setSHAR(DHCP_CHADDR); - } + uint8_t zeroip[4] = {0,0,0,0}; + getSHAR(DHCP_CHADDR); + if((DHCP_CHADDR[0] | DHCP_CHADDR[1] | DHCP_CHADDR[2] | DHCP_CHADDR[3] | DHCP_CHADDR[4] | DHCP_CHADDR[5]) == 0x00) + { + // assigning temporary mac address, you should be set SHAR before call this function. + DHCP_CHADDR[0] = 0x00; + DHCP_CHADDR[1] = 0x08; + DHCP_CHADDR[2] = 0xdc; + DHCP_CHADDR[3] = 0x00; + DHCP_CHADDR[4] = 0x00; + DHCP_CHADDR[5] = 0x00; + setSHAR(DHCP_CHADDR); + } DHCP_SOCKET = s; // SOCK_DHCP pDHCPMSG = (RIP_MSG*)buf; @@ -958,8 +1005,17 @@ void DHCP_init(uint8_t s, uint8_t * buf) reset_DHCP_timeout(); dhcp_state = STATE_DHCP_INIT; -} + if (strlen(HostName) < MAX_SIZE_OF_DCHP_HOST_NAME) { + for (uint8_t ContrChar = 0; HostName[ContrChar] != 0; ContrChar++) { + HOST_NAME[ContrChar] = HostName[ContrChar]; + } + } +#ifdef _DHCP_DEBUG_ + else + printf("> Max Size of Hostname Reached! Uses default Hostname : %s\r\n", DEFAULT_DCHP_HOST_NAME); +#endif +} /* Reset the DHCP timeout count and retry count. */ void reset_DHCP_timeout(void) @@ -978,7 +1034,7 @@ void getIPfromDHCP(uint8_t* ip) { ip[0] = DHCP_allocated_ip[0]; ip[1] = DHCP_allocated_ip[1]; - ip[2] = DHCP_allocated_ip[2]; + ip[2] = DHCP_allocated_ip[2]; ip[3] = DHCP_allocated_ip[3]; } @@ -987,23 +1043,50 @@ void getGWfromDHCP(uint8_t* ip) ip[0] =DHCP_allocated_gw[0]; ip[1] =DHCP_allocated_gw[1]; ip[2] =DHCP_allocated_gw[2]; - ip[3] =DHCP_allocated_gw[3]; + ip[3] =DHCP_allocated_gw[3]; } void getSNfromDHCP(uint8_t* ip) { - ip[0] = DHCP_allocated_sn[0]; - ip[1] = DHCP_allocated_sn[1]; - ip[2] = DHCP_allocated_sn[2]; - ip[3] = DHCP_allocated_sn[3]; + ip[0] = DHCP_allocated_sn[0]; + ip[1] = DHCP_allocated_sn[1]; + ip[2] = DHCP_allocated_sn[2]; + ip[3] = DHCP_allocated_sn[3]; +} + +uint8_t getNTPfromDHCP(uint8_t* ip) +{ + if (!ip) + return DHCP_allocated_ntp_counter; + for (uint8_t CC = 0; CC < DHCP_allocated_ntp_counter; CC++) + { + ip[0 + 4 * CC] = DHCP_allocated_ntp[CC][0]; + ip[1 + 4 * CC] = DHCP_allocated_ntp[CC][1]; + ip[2 + 4 * CC] = DHCP_allocated_ntp[CC][2]; + ip[3 + 4 * CC] = DHCP_allocated_ntp[CC][3]; + // printf("NTP OUT : %d.%d.%d.%d\r\n",ip[0 + 4 * CC],ip[1 + 4 * CC],ip[2 + 4 * CC],ip[3 + 4 * CC]); + } + return DHCP_allocated_ntp_counter; } -void getDNSfromDHCP(uint8_t* ip) +void getTOfromDHCP(int32_t *to) { - ip[0] = DHCP_allocated_dns[0]; - ip[1] = DHCP_allocated_dns[1]; - ip[2] = DHCP_allocated_dns[2]; - ip[3] = DHCP_allocated_dns[3]; + *to = DHCP_allocated_to; +} + +uint8_t getDNSfromDHCP(uint8_t *ip) +{ + if (!ip) + return DHCP_allocated_dns_counter; + for (uint8_t CC = 0; CC < DHCP_allocated_dns_counter; CC++) + { + ip[0 + 4 * CC] = DHCP_allocated_dns[CC][0]; + ip[1 + 4 * CC] = DHCP_allocated_dns[CC][1]; + ip[2 + 4 * CC] = DHCP_allocated_dns[CC][2]; + ip[3 + 4 * CC] = DHCP_allocated_dns[CC][3]; + // printf("DNS OUT : %d.%d.%d.%d\r\n",ip[0 + 4 * CC],ip[1 + 4 * CC],ip[2 + 4 * CC],ip[3 + 4 * CC]); + } + return DHCP_allocated_dns_counter; } uint32_t getDHCPLeasetime(void) @@ -1013,11 +1096,11 @@ uint32_t getDHCPLeasetime(void) char NibbleToHex(uint8_t nibble) { - nibble &= 0x0F; - if (nibble <= 9) - return nibble + '0'; - else - return nibble + ('A'-0x0A); + nibble &= 0x0F; + if (nibble <= 9) + return nibble + '0'; + else + return nibble + ('A'-0x0A); } diff --git a/Internet/DHCP/dhcp.h b/Internet/DHCP/dhcp.h index 9a8d5e9..9837472 100644 --- a/Internet/DHCP/dhcp.h +++ b/Internet/DHCP/dhcp.h @@ -50,6 +50,9 @@ extern "C" { #endif +#include +#include +#include /* * @brief * @details If you want to display debug & processing message, Define _DHCP_DEBUG_ @@ -70,7 +73,11 @@ extern "C" { #define MAGIC_COOKIE 0x63825363 ///< You should not modify it number. -#define DCHP_HOST_NAME "WIZnet\0" +#define DEFAULT_DCHP_HOST_NAME "WIZnet\0" +#define MAX_SIZE_OF_DCHP_HOST_NAME 50 + +#define MAX_DNS_SERVER_ADDRESS 5 +#define MAX_NTP_SERVER_ADDRESS 5 /* * @brief return value of @ref DHCP_run() @@ -90,7 +97,7 @@ enum * @param s - socket number * @param buf - buffer for processing DHCP message */ -void DHCP_init(uint8_t s, uint8_t * buf); +void DHCP_init(uint8_t s, uint8_t * buf, const char * HostName); /* * @brief DHCP 1s Tick Timer handler @@ -142,11 +149,23 @@ void getGWfromDHCP(uint8_t* ip); * @param ip - Subnet mask to be returned */ void getSNfromDHCP(uint8_t* ip); +/* + * @brief Get NTP address + * @param ip - NTP address to be returned + * @retval Number Of NTP Servers + */ +uint8_t getNTPfromDHCP(uint8_t* ip); +/* + * @brief Get Time Offset address + * @param to - Time Offset to be returned + */ +void getTOfromDHCP(int32_t *to); /* * @brief Get DNS address * @param ip - DNS address to be returned + * @retval Number Of DNS Servers */ -void getDNSfromDHCP(uint8_t* ip); +uint8_t getDNSfromDHCP(uint8_t* ip); /* * @brief Get the leased time by DHCP sever diff --git a/NetworkInterface/NetworkInterface.c b/NetworkInterface/NetworkInterface.c new file mode 100644 index 0000000..e74dc51 --- /dev/null +++ b/NetworkInterface/NetworkInterface.c @@ -0,0 +1,1074 @@ +#include "NetworkInterface.h" + +#ifdef _NETWORK_INTERFACE_USE_FREERTOS + #define NetworkInterface_Delay osDelay +#else + #define NetworkInterface_Delay HAL_Delay +#endif + +// Private variables +uint16_t W5500_ReadWriteBuff_For_i; +// Private functions ---------------------------------------------------------------------------- +static char * socketErrorString(int32_t sockErrorCode) { + char * returnValue = NULL; + switch(sockErrorCode) { + case SOCK_OK : returnValue = "[SOCK_OK] => Result is OK about socket process."; break; + case SOCK_BUSY : returnValue = "[SOCK_ERROR] or [SOCK_BUSY] => Socket is busy on processing the operation. Valid only Non-block IO Mode."; break; + case SOCK_FATAL : returnValue = "[SOCK_FATAL] => Result is fatal error about socket process."; break; + case SOCKERR_SOCKNUM : returnValue = "[SOCKERR_SOCKNUM] => Invalid socket number."; break; + case SOCKERR_SOCKOPT : returnValue = "[SOCKERR_SOCKOPT] => Invalid socket option."; break; + case SOCKERR_SOCKINIT : returnValue = "[SOCKERR_SOCKINIT] => Socket is not initialized or SIPR is Zero IP address when Sn_MR_TCP."; break; + case SOCKERR_SOCKCLOSED: returnValue = "[SOCKERR_SOCKCLOSED] => Socket unexpectedly closed."; break; + case SOCKERR_SOCKMODE : returnValue = "[SOCKERR_SOCKMODE] => Invalid socket mode for socket operation."; break; + case SOCKERR_SOCKFLAG : returnValue = "[SOCKERR_SOCKFLAG] => Invalid socket flag."; break; + case SOCKERR_SOCKSTATUS: returnValue = "[SOCKERR_SOCKSTATUS] => Invalid socket status for socket operation."; break; + case SOCKERR_ARG : returnValue = "[SOCKERR_ARG] => Invalid argument."; break; + case SOCKERR_PORTZERO : returnValue = "[SOCKERR_PORTZERO] => Port number is zero."; break; + case SOCKERR_IPINVALID : returnValue = "[SOCKERR_IPINVALID] => Invalid IP address."; break; + case SOCKERR_TIMEOUT : returnValue = "[SOCKERR_TIMEOUT] => Timeout occurred."; break; + case SOCKERR_DATALEN : returnValue = "[SOCKERR_DATALEN] => Data length is zero or greater than buffer max size."; break; + case SOCKERR_BUFFER : returnValue = "[SOCKERR_BUFFER] => Socket buffer is not enough for data communication."; break; + case SOCKFATAL_PACKLEN : returnValue = "[SOCKFATAL_PACKLEN] => Invalid packet length. Fatal Error."; break; + default: returnValue = "[Not Defined Error Code]"; break; + } + return returnValue; +} + +// Low Level Implementation --------------------------------------------------------------------- +void W5500_ResetLow(void) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_GPIO_WritePin(DEFAULT_NETWORK_INTERFACE_RESET_GPIO_Port, DEFAULT_NETWORK_INTERFACE_RESET_Pin, GPIO_PIN_RESET); + #else + DEFAULT_NETWORK_INTERFACE_RESET_GPIO_Port->BSRR = (uint32_t)DEFAULT_NETWORK_INTERFACE_RESET_Pin << 16; + #endif +} +void W5500_ResetHigh(void) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_GPIO_WritePin(DEFAULT_NETWORK_INTERFACE_RESET_GPIO_Port, DEFAULT_NETWORK_INTERFACE_RESET_Pin, GPIO_PIN_SET); + #else + DEFAULT_NETWORK_INTERFACE_RESET_GPIO_Port->BSRR = (uint32_t)DEFAULT_NETWORK_INTERFACE_RESET_Pin; + #endif +} +void W5500_Select(void) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_GPIO_WritePin(DEFAULT_NETWORK_INTERFACE_CS_GPIO_Port, DEFAULT_NETWORK_INTERFACE_CS_Pin, GPIO_PIN_RESET); + #else + DEFAULT_NETWORK_INTERFACE_CS_GPIO_Port->BSRR = (uint32_t)DEFAULT_NETWORK_INTERFACE_CS_Pin << 16; + #endif +} +void W5500_Unselect(void) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_GPIO_WritePin(DEFAULT_NETWORK_INTERFACE_CS_GPIO_Port, DEFAULT_NETWORK_INTERFACE_CS_Pin, GPIO_PIN_SET); + #else + DEFAULT_NETWORK_INTERFACE_CS_GPIO_Port->BSRR = (uint32_t)DEFAULT_NETWORK_INTERFACE_CS_Pin; + #endif +} +void W5500_ReadBuff(uint8_t * buff, uint16_t len) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_SPI_Receive(&DEFAULT_HSPI_NETWORK_INTERFACE, buff, len, HAL_MAX_DELAY); + #else + MY_SPI_Receive(DEFAULT_SPI_NETWORK_INTERFACE, buff, len); + #endif +} +void W5500_WriteBuff(uint8_t * buff, uint16_t len) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_SPI_Transmit(&DEFAULT_HSPI_NETWORK_INTERFACE, buff, len, HAL_MAX_DELAY); + #else + MY_SPI_Transmit(DEFAULT_SPI_NETWORK_INTERFACE, buff, len); + #endif +} +uint8_t W5500_ReadByte(void) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + uint8_t receiveSpiData; + HAL_SPI_Receive(&DEFAULT_HSPI_NETWORK_INTERFACE, &receiveSpiData, 1, HAL_MAX_DELAY); + return receiveSpiData; + #else + return MY_SPI_ReceiveByte(DEFAULT_SPI_NETWORK_INTERFACE); + #endif +} +void W5500_WriteByte(uint8_t spiData) { + #ifdef _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + HAL_SPI_Transmit(&DEFAULT_HSPI_NETWORK_INTERFACE, &spiData, 1, HAL_MAX_DELAY); + #else + MY_SPI_TransmitByte(DEFAULT_SPI_NETWORK_INTERFACE, spiData); + #endif +} +// ---------------------------------------------------------------------------------------------- + +// Run Time Variables --------------------------------------------------------------------------- +#define WIZNET_SOCKET_IO_BLOCKING_MODE SF_IO_NONBLOCK + +#ifdef _NETWORK_INTERFACE_INCLUDE_DHCP +static uint8_t dhcp_buffer[2048]; // 1K should be enough, see https://forum.wiznet.io/t/topic/1612/2 +#endif +//static uint8_t dns_buffer[1024]; // 1K seems to be enough for this buffer as well + +static Type_IPAssignMode ipAssignMode = IPAssignMode_Static; + +volatile bool ip_assigned = false; +volatile uint32_t ctr = 10000; + +static uint16_t runTimeVariable_ReceivedDataSize; +static Type_IP4Address runTimeVariable_SenderIP; +static uint16_t runTimeVariable_SenderPort; + +static uint8_t runTimeVariable_SocketCounter2; + +static wiz_NetInfo net_info; +static int8_t networkInterfaceResult; +static bool w5500SocketIsBusy[_WIZCHIP_SOCK_NUM_] = { false, false, false, false, false, false, false, false }; +static void* usingNetworkClients[_WIZCHIP_SOCK_NUM_] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; +wiz_NetTimeout netTimeout = { 10 /* Rerty */, 10000 /* 100 * 100us = 10ms */}; +// ---------------------------------------------------------------------------------------------- + +// Callbacks ------------------------------------------------------------------------------------ +void Callback_IPAssigned(void) { + PROGRAM_LOG("Callback: IP assigned! Leased time:% d sec\r\n", getDHCPLeasetime()); + ip_assigned = true; +} + +void Callback_IPConflict(void) { + PROGRAM_LOG("Callback: IP conflict!\r\n"); +} +// ---------------------------------------------------------------------------------------------- + +// Static Functions ----------------------------------------------------------------------------- +static bool W5500SocketManager_ReserveFreeSocket(uint8_t* socketNumber) { + bool thisFunctionResult = false; + for(uint8_t getW5500FreeSockcetCounter = 0; getW5500FreeSockcetCounter < 8; getW5500FreeSockcetCounter++) { + if(w5500SocketIsBusy[getW5500FreeSockcetCounter] == false) { + *socketNumber = getW5500FreeSockcetCounter; + w5500SocketIsBusy[getW5500FreeSockcetCounter] = true; + thisFunctionResult = true; + break; + } + } + return thisFunctionResult; +} +static bool W5500SocketManager_ReserveSocket(uint8_t socketNumber) { + bool thisFunctionResult = false; + if(w5500SocketIsBusy[socketNumber] == false) { + w5500SocketIsBusy[socketNumber] = true; + thisFunctionResult = true; + } + return thisFunctionResult; +} +static void W5500SocketManager_ReleaseSocket(uint8_t socketNumber) { + w5500SocketIsBusy[socketNumber] = false; +} + +// Exported Functions --------------------------------------------------------------------------- +bool TransmitDataIndependentUdpTest(Type_IP4Address ipA4Address) { + bool thisFunctionResult = true; + uint8_t selectedSocket = 0; + networkInterfaceResult = socket(selectedSocket, Sn_MR_UDP, 3000, SF_IO_NONBLOCK); // Success : The socket number 'sn' passed as parameter + if(networkInterfaceResult == selectedSocket) { + PROGRAM_LOG("socket=<(%d)>%s\r\n", 0, "OK"); + char * testUdpData = "MohammadSayadi"; + networkInterfaceResult = sendto(selectedSocket, (uint8_t*)testUdpData, strlen(testUdpData), (void*)&ipA4Address, 65001); + if(networkInterfaceResult > SOCK_ERROR) { + PROGRAM_LOG("sendto=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + } + else { + PROGRAM_LOG("sendto=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + thisFunctionResult = false; + } + networkInterfaceResult = close(selectedSocket); + PROGRAM_LOG("close=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + } + else { + PROGRAM_LOG("socket=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + thisFunctionResult = false; + } + return thisFunctionResult; +} +bool TransmitDataIndependentTcpTest(Type_IP4Address ipA4Address) { + bool thisFunctionResult = true; + uint8_t selectedSocket = 0; + networkInterfaceResult = socket(selectedSocket, Sn_MR_TCP, 60001, 0); // Success : The socket number 'sn' passed as parameter + if(networkInterfaceResult == selectedSocket) { + PROGRAM_LOG("socket=<(%d)>%s\r\n", 0, "OK"); + networkInterfaceResult = connect(selectedSocket, (void*)&ipA4Address, 60001); + PROGRAM_LOG("connect=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + if(networkInterfaceResult == SOCK_OK) { + char * testUdpData = "MohammadSayadi"; + networkInterfaceResult = send(selectedSocket, (uint8_t*)testUdpData, strlen(testUdpData) - 1); + if(networkInterfaceResult > SOCK_ERROR) { + PROGRAM_LOG("send=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + } + else { + PROGRAM_LOG("send=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + thisFunctionResult = false; + } + + networkInterfaceResult = send(selectedSocket, (uint8_t*)testUdpData, strlen(testUdpData) - 1); + if(networkInterfaceResult > SOCK_ERROR) { + PROGRAM_LOG("send=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + } + else { + PROGRAM_LOG("send=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + thisFunctionResult = false; + } + + networkInterfaceResult = send(selectedSocket, (uint8_t*)testUdpData, strlen(testUdpData) - 1); + if(networkInterfaceResult > SOCK_ERROR) { + PROGRAM_LOG("send=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + } + else { + PROGRAM_LOG("send=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + thisFunctionResult = false; + } + + networkInterfaceResult = close(selectedSocket); + PROGRAM_LOG("close=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + } + else { + close(selectedSocket); + thisFunctionResult = false; + } + } + else { + PROGRAM_LOG("socket=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + thisFunctionResult = false; + } + return thisFunctionResult; +} +void NetworkInterface_Init1(void) { +// // All capable, Auto-negotiation enabled +// HAL_GPIO_WritePin(W5500_MODE0_GPIO_Port, W5500_MODE0_Pin, GPIO_PIN_SET); +// HAL_GPIO_WritePin(W5500_MODE1_GPIO_Port, W5500_MODE1_Pin, GPIO_PIN_SET); +// HAL_GPIO_WritePin(W5500_MODE2_GPIO_Port, W5500_MODE2_Pin, GPIO_PIN_SET); +// +// PROGRAM_LOG("Reset W5500\r\n"); +// W5500_ResetLow(); +// NetworkInterface_Delay(20); +// W5500_ResetHigh(); +// NetworkInterface_Delay(50); +// +// reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect); +// PROGRAM_LOG("reg_wizchip_cs_cbfunc\r\n"); +// reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte); +// PROGRAM_LOG("reg_wizchip_spi_cbfunc\r\n"); +// reg_wizchip_spiburst_cbfunc(W5500_ReadBuff, W5500_WriteBuff); +// PROGRAM_LOG("reg_wizchip_spiburst_cbfunc\r\n"); + +// uint8_t dummy[50]; +// memset(dummy, 0xFF, 50); +// W5500_WriteBuff(dummy, 50); +// W5500_Select(); +// NetworkInterface_Delay(50); +// W5500_Unselect(); +// +// wizchip_sw_reset(); +// +// uint8_t rx_tx_buff_sizes[] = {2, 2, 2, 2, 2, 2, 2, 2}; +// wizchip_init(rx_tx_buff_sizes, rx_tx_buff_sizes); +// PROGRAM_LOG("wizchip_init\r\n"); + +// PROGRAM_LOG("Calling DHCP_init()...\r\n"); +// wiz_NetInfo net_info = { +// .mac = { 0xEA, 0x11, 0x22, 0x33, 0x44, 0xEA }, +// .dhcp = NETINFO_DHCP +// }; +// // set MAC address before using DHCP +// setSHAR(net_info.mac); +// DHCP_init(APPLICATION_DHCP_SOCKET, dhcp_buffer); + +// PROGRAM_LOG("Registering DHCP callbacks...\r\n"); +// reg_dhcp_cbfunc( +// Callback_IPAssigned, +// Callback_IPAssigned, +// Callback_IPConflict +// ); + +// PROGRAM_LOG("Calling DHCP_run()...\r\n"); +// // actually should be called in a loop, e.g. by timer +// uint32_t ctr = 10000; +// while((!ip_assigned) && (ctr > 0)) { +// DHCP_run(); +// ctr--; +// NetworkInterface_Delay(100); +// } +// if(!ip_assigned) { +// PROGRAM_LOG("\r\nIP was not assigned :(\r\n"); +// return; +// } + +// getIPfromDHCP(net_info.ip); +// getGWfromDHCP(net_info.gw); +// getSNfromDHCP(net_info.sn); + +// uint8_t dns[4]; +// getDNSfromDHCP(dns); + +// PROGRAM_LOG("IP: %d.%d.%d.%d\r\nGW: %d.%d.%d.%d\r\nNet: %d.%d.%d.%d\r\nDNS: %d.%d.%d.%d\r\n", +// net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3], +// net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3], +// net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3], +// dns[0], dns[1], dns[2], dns[3] +// ); + +// PROGRAM_LOG("Calling wizchip_setnetinfo()...\r\n"); +// wizchip_setnetinfo(&net_info); + +// PROGRAM_LOG("Calling DNS_init()...\r\n"); +// DNS_init(DNS_SOCKET, dns_buffer); + +// uint8_t addr[4]; +// { +// char domain_name[] = "eax.me"; +// PROGRAM_LOG("Resolving domain name \"%s\"...\r\n", domain_name); +// int8_t res = DNS_run(dns, (uint8_t*)&domain_name, addr); +// if(res != 1) { +// PROGRAM_LOG("DNS_run() failed, res = %d", res); +// return; +// } +// PROGRAM_LOG("Result: %d.%d.%d.%d\r\n", addr[0], addr[1], addr[2], addr[3]); +// } + +// PROGRAM_LOG("Creating socket...\r\n"); +// uint8_t http_socket = HTTP_SOCKET; +// uint8_t code = socket(http_socket, Sn_MR_TCP, 10888, 0); +// if(code != http_socket) { +// PROGRAM_LOG("socket() failed, code = %d\r\n", code); +// return; +// } + +// PROGRAM_LOG("Socket created, connecting...\r\n"); +// code = connect(http_socket, addr, 80); +// if(code != SOCK_OK) { +// PROGRAM_LOG("connect() failed, code = %d\r\n", code); +// close(http_socket); +// return; +// } + +// PROGRAM_LOG("Connected, sending HTTP request...\r\n"); +// { +// char req[] = "GET / HTTP/1.0\r\nHost: eax.me\r\n\r\n"; +// uint16_t len = sizeof(req) - 1; +// uint8_t* buff = (uint8_t*)&req; +// while(len > 0) { +// PROGRAM_LOG("Sending %d bytes...\r\n", len); +// int32_t nbytes = send(http_socket, buff, len); +// if(nbytes <= 0) { +// PROGRAM_LOG("send() failed, %d returned\r\n", nbytes); +// close(http_socket); +// return; +// } +// PROGRAM_LOG("%d bytes sent!\r\n", nbytes); +// len -= nbytes; +// } +// } + +// PROGRAM_LOG("Request sent. Reading response...\r\n"); +// { +// char buff[32]; +// for(;;) { +// int32_t nbytes = recv(http_socket, (uint8_t*)&buff, sizeof(buff)-1); +// if(nbytes == SOCKERR_SOCKSTATUS) { +// PROGRAM_LOG("\r\nConnection closed.\r\n"); +// break; +// } + +// if(nbytes <= 0) { +// PROGRAM_LOG("\r\nrecv() failed, %d returned\r\n", nbytes); +// break; +// } + +// buff[nbytes] = '\0'; +// PROGRAM_LOG("%s", buff); +// } +// } + +// PROGRAM_LOG("Closing socket.\r\n"); +// close(http_socket); +} +bool NetworkInterface_Init(Type_IPAssignMode ipAssignMode, uint8_t* mac, Type_NetworkProperties* networkProperties) { + bool operationResult = false; + + // W5500_100BT_FullDuplex + HAL_GPIO_WritePin(W5500_MODE0_GPIO_Port, W5500_MODE0_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(W5500_MODE1_GPIO_Port, W5500_MODE1_Pin, GPIO_PIN_SET); + HAL_GPIO_WritePin(W5500_MODE2_GPIO_Port, W5500_MODE2_Pin, GPIO_PIN_SET); + + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Reset W5500\r\n"); + #endif + W5500_ResetLow(); + NetworkInterface_Delay(20); + W5500_ResetHigh(); + NetworkInterface_Delay(50); + + reg_wizchip_cs_cbfunc(W5500_Select, W5500_Unselect); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("reg_wizchip_cs_cbfunc\r\n"); + #endif + reg_wizchip_spi_cbfunc(W5500_ReadByte, W5500_WriteByte); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("reg_wizchip_spi_cbfunc\r\n"); + #endif + reg_wizchip_spiburst_cbfunc(W5500_ReadBuff, W5500_WriteBuff); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("reg_wizchip_spiburst_cbfunc\r\n"); + #endif + + uint8_t rx_tx_buff_sizes[] = {8, 2, 1, 1, 1, 1, 1, 1}; + networkInterfaceResult = wizchip_init(rx_tx_buff_sizes, rx_tx_buff_sizes); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("wizchip_init=<(%d)>%s\r\n", 0, "OK"); + #endif + + //wizphy_setphypmode(PHYCFGR_OPMDC_10F); + + wizchip_settimeout(&netTimeout); // Very Important + + switch(ipAssignMode) { + case IPAssignMode_Static: { + memcpy(net_info.mac, mac, 6); + Fill_IPAddressArrayFromStruct(net_info.ip, networkProperties->IPAddress); + Fill_IPAddressArrayFromStruct(net_info.sn, networkProperties->SubnetMask); + Fill_IPAddressArrayFromStruct(net_info.gw, networkProperties->DefaultGateway); + Fill_IPAddressArrayFromStruct(net_info.dns, networkProperties->DnsServer); + net_info.dhcp = NETINFO_STATIC; + + wizchip_setnetinfo(&net_info); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("wizchip_setnetinfo\r\n"); + #endif + + wiz_NetInfo rnet_info; + wizchip_getnetinfo(&rnet_info); + + if( + rnet_info.mac[0] == net_info.mac[0] && + rnet_info.mac[1] == net_info.mac[1] && + rnet_info.mac[2] == net_info.mac[2] && + rnet_info.mac[3] == net_info.mac[3] && + rnet_info.mac[4] == net_info.mac[4] && + rnet_info.mac[5] == net_info.mac[5] && + rnet_info.ip[0] == net_info.ip[0] && + rnet_info.ip[1] == net_info.ip[1] && + rnet_info.ip[2] == net_info.ip[2] && + rnet_info.ip[3] == net_info.ip[3] && + rnet_info.gw[0] == net_info.gw[0] && + rnet_info.gw[1] == net_info.gw[1] && + rnet_info.gw[2] == net_info.gw[2] && + rnet_info.gw[3] == net_info.gw[3] && + rnet_info.sn[0] == net_info.sn[0] && + rnet_info.sn[1] == net_info.sn[1] && + rnet_info.sn[2] == net_info.sn[2] && + rnet_info.sn[3] == net_info.sn[3] && + rnet_info.dns[0] == net_info.dns[0] && + rnet_info.dns[1] == net_info.dns[1] && + rnet_info.dns[2] == net_info.dns[2] && + rnet_info.dns[3] == net_info.dns[3] + ) { + operationResult = true; + } + + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("wizchip_getnetinfo\r\n"); + PROGRAM_LOG("MAC: %02X:%02X:%02X:%02X:%02X:%02X\r\n", rnet_info.mac[0], rnet_info.mac[1], rnet_info.mac[2], rnet_info.mac[3], rnet_info.mac[4], rnet_info.mac[5]); + PROGRAM_LOG("Ip: %d.%d.%d.%d\r\n", rnet_info.ip[0] , rnet_info.ip[1] , rnet_info.ip[2] , rnet_info.ip[3] ); + PROGRAM_LOG("Gateway: %d.%d.%d.%d\r\n", rnet_info.gw[0] , rnet_info.gw[1] , rnet_info.gw[2] , rnet_info.gw[3] ); + PROGRAM_LOG("Subnet Mask: %d.%d.%d.%d\r\n", rnet_info.sn[0] , rnet_info.sn[1] , rnet_info.sn[2] , rnet_info.sn[3] ); + PROGRAM_LOG("DNS: %d.%d.%d.%d\r\n", rnet_info.dns[0], rnet_info.dns[1], rnet_info.dns[2], rnet_info.dns[3]); + #endif + + break; + } // case IPAssignMode_Static + case IPAssignMode_Dhcp: { + #ifdef _NETWORK_INTERFACE_INCLUDE_DHCP + memcpy(net_info.mac, mac, 6); + Fill_IPAddressArray(net_info.ip, 0, 0, 0, 0); + Fill_IPAddressArray(net_info.sn, 0, 0, 0, 0); + Fill_IPAddressArray(net_info.gw, 0, 0, 0, 0); + Fill_IPAddressArray(net_info.dns, 0, 0, 0, 0); + net_info.dhcp = NETINFO_DHCP; + + wizchip_setnetinfo(&net_info); + PROGRAM_LOG("wizchip_setnetinfo(Init)\r\n"); + + PROGRAM_LOG("DHCP_time_handler timer routine init\r\n"); + if(xTimerIsTimerActive(Timer_DhcpHandle) == pdTRUE ) { + xTimerStop(Timer_DhcpHandle, (TickType_t)FREERTOS_MS_TO_TICK(2000)); + } + xTimerChangePeriod(Timer_DhcpHandle, FREERTOS_MS_TO_TICK(1000), (TickType_t)FREERTOS_MS_TO_TICK(2000)); + xTimerStart(Timer_DhcpHandle, (TickType_t)FREERTOS_MS_TO_TICK(2000)); + + W5500SocketManager_ReserveSocket(APPLICATION_DHCP_SOCKET); + DHCP_init(APPLICATION_DHCP_SOCKET, dhcp_buffer); + + PROGRAM_LOG("Registering DHCP callbacks...\r\n"); + reg_dhcp_cbfunc(Callback_IPAssigned, Callback_IPAssigned, Callback_IPConflict); + + PROGRAM_LOG("Calling DHCP_run()...\r\n"); + // actually should be called in a loop, e.g. by timer + volatile uint8_t dhcp_ret; + while((!ip_assigned) && (ctr > 0)) { +// while(dhcp_ret != DHCP_IP_ASSIGN && dhcp_ret != DHCP_IP_LEASED) { + dhcp_ret = DHCP_run(); + ctr--; + NetworkInterface_Delay(1); + } + if(!ip_assigned) { + PROGRAM_LOG("\r\nIP was not assigned :(\r\n"); + return; + } + + getIPfromDHCP(net_info.ip); + getGWfromDHCP(net_info.gw); + getSNfromDHCP(net_info.sn); + + uint8_t dns[4]; + getDNSfromDHCP(dns); + + PROGRAM_LOG("IP: %d.%d.%d.%d\r\nGW: %d.%d.%d.%d\r\nNet: %d.%d.%d.%d\r\nDNS: %d.%d.%d.%d\r\n", + net_info.ip[0], net_info.ip[1], net_info.ip[2], net_info.ip[3], + net_info.gw[0], net_info.gw[1], net_info.gw[2], net_info.gw[3], + net_info.sn[0], net_info.sn[1], net_info.sn[2], net_info.sn[3], + dns[0], dns[1], dns[2], dns[3] + ); + + wizchip_setnetinfo(&net_info); + PROGRAM_LOG("wizchip_setnetinfo(From Dhcp)\r\n"); + #endif /* _NETWORK_INTERFACE_INCLUDE_DHCP */ + break; + } // case IPAssignMode_Dhcp + } + return operationResult; +} +bool NetworkInterface_Udp_Open(Type_NetworkClient* udpClient, uint16_t localPort) { + bool thisFunctionResult; + uint8_t selectedSocket; + if(udpClient) { + if(W5500SocketManager_ReserveFreeSocket(&selectedSocket)) { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("socket number = %d\r\n", selectedSocket); + #endif + networkInterfaceResult = socket(selectedSocket, Sn_MR_UDP, localPort, SF_IO_NONBLOCK); // Success : The socket number 'sn' passed as parameter + if(networkInterfaceResult == selectedSocket) { + udpClient->SocketNumber = selectedSocket; + udpClient->LocalPort = localPort; + thisFunctionResult = true; + udpClient->LastStatus = NetworkStatus_Opened; + udpClient->ClientType = ClientType_Udp; + udpClient->IsDataReceived = false; + udpClient->ReceivedDataSize = false; + udpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + usingNetworkClients[selectedSocket] = udpClient; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("socket=<(%d)>%s\r\n", 0, "OK"); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("socket=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + } + else thisFunctionResult = false; + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Udp_Connect(Type_NetworkClient* udpClient, Type_IP4Address destinationIP, uint16_t destinationPort) { + bool thisFunctionResult = true; + if(udpClient) { + Fill_IP4AddressStructFromStruct(udpClient->RemoteIP, destinationIP); + udpClient->RemotePort = destinationPort; + uint8_t tmpip4[4]; + Fill_IPAddressArrayFromStruct(tmpip4, udpClient->RemoteIP); + setSn_DIPR(udpClient->SocketNumber, tmpip4); + setSn_DPORT(udpClient->SocketNumber, udpClient->RemotePort); + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Udp_Send(Type_NetworkClient* udpClient, void* data, uint16_t length) { + bool thisFunctionResult = true; + if(udpClient) { + networkInterfaceResult = sendto(udpClient->SocketNumber, data, length, (uint8_t*)&udpClient->RemoteIP, udpClient->RemotePort); + if(networkInterfaceResult > SOCK_ERROR) { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("send=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("send=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Udp_SendTo(Type_NetworkClient* udpClient, void* data, uint16_t length, Type_IP4Address destinationIP, uint16_t destinationPort) { + bool thisFunctionResult = true; + if(udpClient) { + networkInterfaceResult = sendto(udpClient->SocketNumber, data, length, (uint8_t*)&destinationIP, destinationPort); + if(networkInterfaceResult > SOCK_ERROR) { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("sendto=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("sendto=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +void NetworkInterface_Udp_Send2(Type_NetworkClient* udpClient, void* data, uint16_t length) { + uint32_t timeout_us = 500000; +// uint16_t freesize = 0; +// freesize = getSn_TxMAX(udpClient->SocketNumber); +// if (length > freesize) length = freesize; // check size not to exceed MAX size. +// while(timeout_ms) { +// freesize = getSn_TX_FSR(udpClient->SocketNumber); +// if(length <= freesize) break; +// else { +// timeout_ms--; +// NetworkInterface_Delay(1); +// } +// } + wiz_send_data(udpClient->SocketNumber, data, length); + setSn_CR(udpClient->SocketNumber, Sn_CR_SEND); + while(getSn_CR(udpClient->SocketNumber)) {} + while(timeout_us) { + if(getSn_IR(udpClient->SocketNumber) & Sn_IR_SENDOK) { + setSn_IR(udpClient->SocketNumber, Sn_IR_SENDOK); + break; + } + timeout_us--; + MicroDelay2_DelayUs(1); + } +} +bool NetworkInterface_Udp_Receive(Type_NetworkClient* udpClient, uint8_t* buffer, Type_IP4Address* senderIP, uint16_t* senderPort) { + if(udpClient) { + uint16_t receivedDataSize; + getsockopt(udpClient->SocketNumber, SO_RECVBUF, &receivedDataSize); + networkInterfaceResult = recvfrom(udpClient->SocketNumber, buffer, receivedDataSize, (uint8_t*)senderIP, senderPort); + if(networkInterfaceResult > 0) { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("recvfrom = %d bytes\r\n", networkInterfaceResult); + #endif + return true; + } + else { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("recvfrom=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + return false; + } + } + return false; +} +bool NetworkInterface_Udp_StartReceive(Type_NetworkClient* udpClient, uint8_t* receiveBuffer) { + if(udpClient && receiveBuffer) { + // Enabling interrupt (pin) + intr_kind int_mask = wizchip_getinterruptmask(); + int_mask |= (intr_kind)(IK_SOCK_0 << udpClient->SocketNumber); + wizchip_setinterruptmask(int_mask); + // Set Filter Param + udpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + udpClient->ReceiveBuffer = receiveBuffer; + return true; + } + return false; +} +bool NetworkInterface_Udp_StopReceive(Type_NetworkClient* udpClient) { + if(udpClient) { + // Disabaling interrupt (pin) + intr_kind int_mask = wizchip_getinterruptmask(); + int_mask &= ~((intr_kind)(IK_SOCK_0 << udpClient->SocketNumber)); + wizchip_setinterruptmask(int_mask); + // Set Filter Param + udpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + return true; + } + return false; +} +bool NetworkInterface_Udp_StartReceiveFrom(Type_NetworkClient* udpClient, uint8_t* receiveBuffer, Type_IP4Address senderIP, uint16_t senderPort) { + if(udpClient) { + // Enabling interrupt (pin) + intr_kind int_mask = wizchip_getinterruptmask(); + int_mask |= (intr_kind)(IK_SOCK_0 << udpClient->SocketNumber); + wizchip_setinterruptmask(int_mask); + // Set Filter Param + udpClient->ApplyReceiveDataFilterBasedOnIpAndPort = true; + Fill_IP4AddressStructFromStruct(udpClient->ReceiveFilterRemoteIP, senderIP); + udpClient->ReceiveFilterRemotePort = senderPort; + udpClient->ReceiveBuffer = receiveBuffer; + return true; + } + return false; +} +bool NetworkInterface_Udp_StopReceiveFrom(Type_NetworkClient* udpClient) { + if(udpClient) { + // Disabaling interrupt (pin) + intr_kind int_mask = wizchip_getinterruptmask(); + int_mask &= ~((intr_kind)(IK_SOCK_0 << udpClient->SocketNumber)); + wizchip_setinterruptmask(int_mask); + // Set Filter Param + udpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + return true; + } + return false; +} +uint16_t NetworkInterface_Udp_ReceiveDataAvailableInBuffer(Type_NetworkClient* udpClient) { /* return > 0 if any data available */ + if(udpClient) { + if(udpClient->IsDataReceived) { + return udpClient->ReceivedDataSize; + } + } + return 0; +} +uint8_t* NetworkInterface_Udp_GetReceivedData(Type_NetworkClient* udpClient) { + if(udpClient) { + if(udpClient->IsDataReceived) { + udpClient->IsDataReceived = false; + return udpClient->ReceiveBuffer; + } + return NULL; + } + return NULL; +} +bool NetworkInterface_Udp_Close(Type_NetworkClient* udpClient) { + bool thisFunctionResult = true; + if(udpClient) { + networkInterfaceResult = close(udpClient->SocketNumber); + W5500SocketManager_ReleaseSocket(udpClient->SocketNumber); + udpClient->LastStatus = NetworkStatus_Closed; + usingNetworkClients[udpClient->SocketNumber] = NULL; +// memset(&udpClient, 0, sizeof(Type_NetworkClient)); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("close=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Tcp_Open(Type_NetworkClient* tcpClient, uint16_t localPort) { + bool thisFunctionResult; + uint8_t selectedSocket; + if(tcpClient) { + if(W5500SocketManager_ReserveFreeSocket(&selectedSocket)) { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("socket number = %d\r\n", selectedSocket); + #endif + networkInterfaceResult = socket(selectedSocket, Sn_MR_TCP, localPort, WIZNET_SOCKET_IO_BLOCKING_MODE); // Success : The socket number 'sn' passed as parameter + if(networkInterfaceResult == selectedSocket) { + tcpClient->SocketNumber = selectedSocket; + tcpClient->LocalPort = localPort; + thisFunctionResult = true; + tcpClient->LastStatus = NetworkStatus_Opened; + tcpClient->ClientType = ClientType_Tcp; + tcpClient->IsDataReceived = false; + tcpClient->ReceivedDataSize = false; + tcpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + usingNetworkClients[selectedSocket] = tcpClient; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("socket=<(%d)>%s\r\n", 0, "OK"); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("socket=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + } + else thisFunctionResult = false; + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Tcp_Connect(Type_NetworkClient* tcpClient, Type_IP4Address destinationIP, uint16_t destinationPort, uint32_t timeout_ms) { + bool thisFunctionResult; + if(tcpClient) { + Fill_IP4AddressStructFromStruct(tcpClient->RemoteIP, destinationIP); + tcpClient->RemotePort = destinationPort; + networkInterfaceResult = connect(tcpClient->SocketNumber, (uint8_t*)&tcpClient->RemoteIP, tcpClient->RemotePort); + if(WIZNET_SOCKET_IO_BLOCKING_MODE == SF_IO_NONBLOCK && networkInterfaceResult == SOCK_BUSY) { + networkInterfaceResult = SOCK_OK; + } + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("connect=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + uint8_t connectionStatus = 255; + while(timeout_ms) { + getsockopt(tcpClient->SocketNumber, SO_STATUS, &connectionStatus); + if(connectionStatus == SOCK_ESTABLISHED) break; + NetworkInterface_Delay(1); + timeout_ms--; + } + if(connectionStatus == SOCK_ESTABLISHED) { + thisFunctionResult = true; + tcpClient->LastStatus = NetworkStatus_Connected; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Connected\r\n"); + #endif + } + else { + thisFunctionResult = false; + tcpClient->LastStatus = NetworkStatus_Disconnected; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Timeout Reached\r\n"); + #endif + } + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Tcp_Disconnect(Type_NetworkClient* tcpClient, uint32_t timeout_ms) { + bool thisFunctionResult; + if(tcpClient) { + networkInterfaceResult = disconnect(tcpClient->SocketNumber); + if(WIZNET_SOCKET_IO_BLOCKING_MODE == SF_IO_NONBLOCK && networkInterfaceResult == SOCK_BUSY) { + networkInterfaceResult = SOCK_OK; + } + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("disconnect=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + uint8_t connectionStatus = 255; + while(timeout_ms) { + getsockopt(tcpClient->SocketNumber, SO_STATUS, &connectionStatus); + if(connectionStatus != SOCK_ESTABLISHED) break; + timeout_ms--; + } + if(connectionStatus != SOCK_ESTABLISHED) { + thisFunctionResult = true; + tcpClient->LastStatus = NetworkStatus_Disconnected; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Disconnected\r\n"); + #endif + } + else { + thisFunctionResult = false; + tcpClient->LastStatus = NetworkStatus_Connected; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Timeout Reached\r\n"); + #endif + } + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +bool NetworkInterface_Tcp_Send(Type_NetworkClient* tcpClient, void* data, uint16_t length) { + bool thisFunctionResult; + if(tcpClient) { + networkInterfaceResult = send(tcpClient->SocketNumber, data, length); + if(networkInterfaceResult > SOCK_ERROR) { + thisFunctionResult = true; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("send=<(%d Bytes)>%s\r\n", networkInterfaceResult, "OK"); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("send=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +void NetworkInterface_Tcp_Send2(Type_NetworkClient* tcpClient, void* data, uint16_t length) { + uint32_t timeout_us = 500000; + wiz_send_data(tcpClient->SocketNumber, data, length); + setSn_CR(tcpClient->SocketNumber, Sn_CR_SEND); + while(getSn_CR(tcpClient->SocketNumber)) {} + while(timeout_us) { + if(getSn_IR(tcpClient->SocketNumber) & Sn_IR_SENDOK) { + setSn_IR(tcpClient->SocketNumber, Sn_IR_SENDOK); + break; + } + timeout_us--; + MicroDelay2_DelayUs(1); + } +} +bool NetworkInterface_Tcp_Receive(Type_NetworkClient* tcpClient, uint8_t* buffer, Type_IP4Address* senderIP, uint16_t* senderPort) { + if(tcpClient) { + uint16_t receivedDataSize; + getsockopt(tcpClient->SocketNumber, SO_RECVBUF, &receivedDataSize); + networkInterfaceResult = recv(tcpClient->SocketNumber, buffer, receivedDataSize); + if(networkInterfaceResult > 0) { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("recv = %d bytes\r\n", networkInterfaceResult); + #endif + return true; + } + else { + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("recv=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + return false; + } + } + return false; +} +bool NetworkInterface_Tcp_StartReceive(Type_NetworkClient* tcpClient, uint8_t* receiveBuffer) { + if(tcpClient && receiveBuffer) { + // Enabling interrupt (pin) + intr_kind int_mask = wizchip_getinterruptmask(); + int_mask |= (intr_kind)(IK_SOCK_0 << tcpClient->SocketNumber); + wizchip_setinterruptmask(int_mask); + // Set Filter Param + tcpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + tcpClient->ReceiveBuffer = receiveBuffer; + return true; + } + return false; +} +bool NetworkInterface_Tcp_StopReceive(Type_NetworkClient* tcpClient) { + if(tcpClient) { + // Disabaling interrupt (pin) + intr_kind int_mask = wizchip_getinterruptmask(); + int_mask &= ~((intr_kind)(IK_SOCK_0 << tcpClient->SocketNumber)); + wizchip_setinterruptmask(int_mask); + // Set Filter Param + tcpClient->ApplyReceiveDataFilterBasedOnIpAndPort = false; + return true; + } + return false; +} +uint16_t NetworkInterface_Tcp_ReceiveDataAvailableInBuffer(Type_NetworkClient* tcpClient) { /* return > 0 if any data available */ + if(tcpClient) { + if(tcpClient->IsDataReceived) { + return tcpClient->ReceivedDataSize; + } + } + return 0; +} +uint8_t* NetworkInterface_Tcp_GetReceivedData(Type_NetworkClient* tcpClient) { + if(tcpClient) { + if(tcpClient->IsDataReceived) { + tcpClient->IsDataReceived = false; + return tcpClient->ReceiveBuffer; + } + return NULL; + } + return NULL; +} +bool NetworkInterface_Tcp_Close(Type_NetworkClient* tcpClient) { + bool thisFunctionResult = true; + if(tcpClient) { + networkInterfaceResult = close(tcpClient->SocketNumber); + W5500SocketManager_ReleaseSocket(tcpClient->SocketNumber); + tcpClient->LastStatus = NetworkStatus_Closed; + usingNetworkClients[tcpClient->SocketNumber] = NULL; +// memset(&tcpClient, 0, sizeof(Type_NetworkClient)); + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("close=<(%d)>%s\r\n", networkInterfaceResult, socketErrorString(networkInterfaceResult)); + #endif + } + else { + thisFunctionResult = false; + #ifdef _NETWORK_INTERFACE_INTERNAL_DEBUG + PROGRAM_LOG("Invalid or NULL network client structure\r\n"); + #endif + } + return thisFunctionResult; +} +void NetworkInterface_ReceiveInterruptCallback(void) { + intr_kind wizchipInterrupts = wizchip_getinterrupt(); // Read last interrupts status + Type_NetworkClient* networkClient; + for(runTimeVariable_SocketCounter2 = 0; runTimeVariable_SocketCounter2 < _WIZCHIP_SOCK_NUM_; runTimeVariable_SocketCounter2++) { + if(((intr_kind)(IK_SOCK_0 << runTimeVariable_SocketCounter2)) & wizchipInterrupts) { + if(usingNetworkClients[runTimeVariable_SocketCounter2] && w5500SocketIsBusy[runTimeVariable_SocketCounter2]) { + networkClient = usingNetworkClients[runTimeVariable_SocketCounter2]; + if(networkClient->ReceiveBuffer) { + switch(networkClient->ClientType) { + case ClientType_Udp: { + if(networkClient->ApplyReceiveDataFilterBasedOnIpAndPort) { + getsockopt(networkClient->SocketNumber, SO_RECVBUF, &runTimeVariable_ReceivedDataSize); + networkInterfaceResult = recvfrom(networkClient->SocketNumber, networkClient->ReceiveBuffer, runTimeVariable_ReceivedDataSize, (uint8_t*)&runTimeVariable_SenderIP, &runTimeVariable_SenderPort); + if(IP4Address_Compare_StructVsStruct(runTimeVariable_SenderIP, networkClient->ReceiveFilterRemoteIP) && (runTimeVariable_SenderPort == networkClient->ReceiveFilterRemotePort)) { + Fill_IP4AddressStructFromStruct(networkClient->LastReceivedPacketRemoteIP, runTimeVariable_SenderIP); + networkClient->LastReceivedPacketRemotePort = runTimeVariable_SenderPort; + networkClient->ReceivedDataSize = runTimeVariable_ReceivedDataSize; + networkClient->IsDataReceived = true; + } + } // if(networkClient->ApplyReceiveDataFilterBasedOnIpAndPort) + else { + getsockopt(networkClient->SocketNumber, SO_RECVBUF, &runTimeVariable_ReceivedDataSize); + networkInterfaceResult = recvfrom(networkClient->SocketNumber, networkClient->ReceiveBuffer, runTimeVariable_ReceivedDataSize, (uint8_t*)&networkClient->LastReceivedPacketRemoteIP, &networkClient->LastReceivedPacketRemotePort); + networkClient->ReceivedDataSize = runTimeVariable_ReceivedDataSize; + networkClient->IsDataReceived = true; + } // else if(networkClient->ApplyReceiveDataFilterBasedOnIpAndPort) + break; + } // case ClientType_Udp + case ClientType_Tcp: { + getsockopt(networkClient->SocketNumber, SO_RECVBUF, &runTimeVariable_ReceivedDataSize); + networkInterfaceResult = recv(networkClient->SocketNumber, networkClient->ReceiveBuffer, runTimeVariable_ReceivedDataSize); + networkClient->ReceivedDataSize = runTimeVariable_ReceivedDataSize; + networkClient->IsDataReceived = true; + break; + } // case ClientType_Tcp + } // switch(networkClient->ClientType) + } // if(networkClient->ReceiveBuffer != NULL) + } // if(usingNetworkClients[socketCounter] && w5500SocketIsBusy[socketCounter]) + } // if(((intr_kind)(IK_SOCK_0 << socketCounter)) & wizchipInterrupts) + } // for(uint8_t socketCounter = 0; socketCounter < 8; socketCounter++) + wizchip_clrinterrupt(wizchipInterrupts); // Clear interrupts +} +#ifdef _NETWORK_INTERFACE_INCLUDE_DHCP +//void NetworkInterface_1Second_Routine(void) { +// if(ipAssignMode == IPAssignMode_Dhcp) DHCP_time_handler(); +//} +void Timer_Dhcp_Callback(void *argument) { + DHCP_time_handler(); +} +#endif diff --git a/NetworkInterface/NetworkInterface.h b/NetworkInterface/NetworkInterface.h new file mode 100644 index 0000000..3082a4d --- /dev/null +++ b/NetworkInterface/NetworkInterface.h @@ -0,0 +1,235 @@ +#ifndef __NETWORK_INTERFACE_H +#define __NETWORK_INTERFACE_H + +#include +#include +#include +#include + +#include "cmsis_os.h" +#include "timers.h" + +#include "main.h" + +#include "stm32f4xx_my_spi.h" + +#include "MicroDelay.h" + +#include "debug.h" + +#include "socket.h" +#include "dhcp.h" +#include "dns.h" + +#define _NETWORK_INTERFACE_USE_FREERTOS +//#define _NETWORK_INTERFACE_INTERNAL_DEBUG +//#define _NETWORK_INTERFACE_INCLUDE_DHCP +//#define _NETWORK_INTERFACE_USE_HAL_SPI_DRIVER + +#ifdef _NETWORK_INTERFACE_USE_FREERTOS + #include "cmsis_os.h" +#endif + +#define APPLICATION_DHCP_SOCKET 7 +#define APPLICATION_DNS_SOCKET 6 +#define APPLICATION_HTTP_SOCKET 5 +#define APPLICATION_DATA_SOCKET 0 + +// PMODE 2 1 0 +#define W5500_10BT_HalfDuplex // 0 0 0 +#define W5500_10BT_FullDuplex // 0 0 1 +#define W5500_100BT_HalfDuplex // 0 1 0 +#define W5500_100BT_FullDuplex // 0 1 1 +#define W5500_100BT_HalfDuplex_AutoNegotiation // 1 0 0 +#define W5500_NotUsed1 // 1 0 1 +#define W5500_NotUsed2 // 1 1 0 +#define W5500_AllCapable_AutoNegotiation // 1 1 1 + +#define DEFAULT_SPI_NETWORK_INTERFACE SPI2 +#define DEFAULT_HSPI_NETWORK_INTERFACE hspi2 +#define DEFAULT_NETWORK_INTERFACE_RESET_GPIO_Port W5500_RESET_GPIO_Port +#define DEFAULT_NETWORK_INTERFACE_RESET_Pin W5500_RESET_Pin +#define DEFAULT_NETWORK_INTERFACE_CS_GPIO_Port W5500_CS_GPIO_Port +#define DEFAULT_NETWORK_INTERFACE_CS_Pin W5500_CS_Pin + +extern SPI_HandleTypeDef hspi2; + +extern osTimerId_t Timer_DhcpHandle; + +//Exported Macros ------------------------------------------------------------------------------- +#define Fill_IP4AddressFromArray(_IP4AddressStruct,_IP4AddressArray) \ + _IP4AddressStruct.Part1 = _IP4AddressArray[0]; \ + _IP4AddressStruct.Part2 = _IP4AddressArray[1]; \ + _IP4AddressStruct.Part3 = _IP4AddressArray[2]; \ + _IP4AddressStruct.Part4 = _IP4AddressArray[3] + +#define Fill_IP4AddressStruct(_IP4AddressStruct,_ip1,_ip2,_ip3,_ip4) \ + _IP4AddressStruct.Part1 = _ip1; \ + _IP4AddressStruct.Part2 = _ip2; \ + _IP4AddressStruct.Part3 = _ip3; \ + _IP4AddressStruct.Part4 = _ip4 + +#define Fill_IP4AddressStructFromStruct(_IP4AddressStruct_Dst,_IP4AddressStruct_Src) \ + _IP4AddressStruct_Dst.Part1 = _IP4AddressStruct_Src.Part1; \ + _IP4AddressStruct_Dst.Part2 = _IP4AddressStruct_Src.Part2; \ + _IP4AddressStruct_Dst.Part3 = _IP4AddressStruct_Src.Part3; \ + _IP4AddressStruct_Dst.Part4 = _IP4AddressStruct_Src.Part4 + +#define FillInit_IP4Address(ip1,ip2,ip3,ip4) { ip1,ip2,ip3,ip4 } + +#define Fill_IPAddressArrayFromStruct(_IP4AddressArray,_IP4AddressStruct) \ + _IP4AddressArray[0] = _IP4AddressStruct.Part1; \ + _IP4AddressArray[1] = _IP4AddressStruct.Part2; \ + _IP4AddressArray[2] = _IP4AddressStruct.Part3; \ + _IP4AddressArray[3] = _IP4AddressStruct.Part4 + +#define Fill_IPAddressArray(_IP4AddressArray,_ip1,_ip2,_ip3,_ip4) \ + _IP4AddressArray[0] = _ip1; \ + _IP4AddressArray[1] = _ip2; \ + _IP4AddressArray[2] = _ip3; \ + _IP4AddressArray[3] = _ip4 + +#define Fill_IPAddress_Uint8ToUint32(ip8,ip32) \ + ip32 = ((uint32_t)ip8[0]) & 0x000000FF; \ + ip32 = (ip32 << 8) + ((uint32_t)ip8[1] & 0x000000FF); \ + ip32 = (ip32 << 8) + ((uint32_t)ip8[2] & 0x000000FF); \ + ip32 = (ip32 << 8) + ((uint32_t)ip8[3] & 0x000000FF) + +#define IP4Address_Compare_StructVsStruct(_IP4AddressStruct_1,_IP4AddressStruct_2) ((_IP4AddressStruct_1.Part1 == _IP4AddressStruct_2.Part1) ? (((_IP4AddressStruct_1.Part2 == _IP4AddressStruct_2.Part2) ? (((_IP4AddressStruct_1.Part3 == _IP4AddressStruct_2.Part3) ? (((_IP4AddressStruct_1.Part4 == _IP4AddressStruct_2.Part4) ? (1) : (0))) : (0))) : (0))) : (0)) + +#define Fill_MAC(_mac,_mac_p1,_mac_p2,_mac_p3,_mac_p4,_mac_p5,_mac_p6) \ + _mac[0] = _mac_p1; \ + _mac[1] = _mac_p2; \ + _mac[2] = _mac_p3; \ + _mac[3] = _mac_p4; \ + _mac[4] = _mac_p5; \ + _mac[5] = _mac_p6 + +// Data Types ----------------------------------------------------------------------------------- +typedef enum Enum_IPAssignMode { + IPAssignMode_Static, + IPAssignMode_Dhcp +} Type_IPAssignMode; + +typedef enum Enum_NetworkStatus { + NetworkStatus_Closed, + NetworkStatus_Opened, + NetworkStatus_Connected, + NetworkStatus_Disconnected +} Type_NetworkStatus; + +typedef enum Enum_ClientType { + ClientType_Udp, + ClientType_Tcp +} Type_ClientType; + +typedef struct Struct_IP4Address { + uint8_t Part1; + uint8_t Part2; + uint8_t Part3; + uint8_t Part4; +} Type_IP4Address; + +typedef struct Struct_NetworkProperties { + Type_IP4Address IPAddress; + Type_IP4Address SubnetMask; + Type_IP4Address DefaultGateway; + Type_IP4Address DnsServer; +} Type_NetworkProperties; + +typedef struct Struct_UdpClient { + Type_ClientType ClientType; + uint8_t SocketNumber; + Type_IP4Address RemoteIP; + uint16_t RemotePort; + uint16_t LocalPort; + Type_NetworkStatus LastStatus; + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + uint8_t * ReceiveBuffer; + uint16_t ReceivedDataSize; + bool IsDataReceived; /* Act as Flag */ + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + Type_IP4Address LastReceivedPacketRemoteIP; + uint16_t LastReceivedPacketRemotePort; + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + bool ApplyReceiveDataFilterBasedOnIpAndPort; + Type_IP4Address ReceiveFilterRemoteIP; + uint16_t ReceiveFilterRemotePort; +} Type_UdpClient; + +typedef struct Struct_TcpClient { + Type_ClientType ClientType; + uint8_t SocketNumber; + Type_IP4Address RemoteIP; + uint16_t RemotePort; + uint16_t LocalPort; + Type_NetworkStatus LastStatus; + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + uint8_t * ReceiveBuffer; + uint16_t ReceivedDataSize; + bool IsDataReceived; /* Act as Flag */ + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + Type_IP4Address LastReceivedPacketRemoteIP; + uint16_t LastReceivedPacketRemotePort; + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + bool ApplyReceiveDataFilterBasedOnIpAndPort; + Type_IP4Address ReceiveFilterRemoteIP; + uint16_t ReceiveFilterRemotePort; +} Type_TcpClient; + +typedef struct Struct_NetworkClient { + Type_ClientType ClientType; + uint8_t SocketNumber; + Type_IP4Address RemoteIP; + uint16_t RemotePort; + uint16_t LocalPort; + Type_NetworkStatus LastStatus; + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + uint8_t * ReceiveBuffer; + uint16_t ReceivedDataSize; + bool IsDataReceived; /* Act as Flag */ + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + Type_IP4Address LastReceivedPacketRemoteIP; + uint16_t LastReceivedPacketRemotePort; + // /\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/ + bool ApplyReceiveDataFilterBasedOnIpAndPort; + Type_IP4Address ReceiveFilterRemoteIP; + uint16_t ReceiveFilterRemotePort; +} Type_NetworkClient; +// Exported Functions --------------------------------------------------------------------------- +bool NetworkInterface_Init(Type_IPAssignMode ipAssignMode, uint8_t* mac, Type_NetworkProperties* networkProperties); +bool TransmitDataIndependentUdpTest(Type_IP4Address ipA4Address); +bool TransmitDataIndependentTcpTest(Type_IP4Address ipA4Address); + +bool NetworkInterface_Udp_Open(Type_NetworkClient* udpClient, uint16_t localPort); +bool NetworkInterface_Udp_Connect(Type_NetworkClient* udpClient, Type_IP4Address destinationIP, uint16_t destinationPort); +bool NetworkInterface_Udp_Send(Type_NetworkClient* udpClient, void* data, uint16_t length); // Normal Send +bool NetworkInterface_Udp_SendTo(Type_NetworkClient* udpClient, void* data, uint16_t length, Type_IP4Address destinationIP, uint16_t destinationPort); +void NetworkInterface_Udp_Send2(Type_NetworkClient* udpClient, void* data, uint16_t length); // Fast implementation +bool NetworkInterface_Udp_Receive(Type_NetworkClient* udpClient, uint8_t* buffer, Type_IP4Address* senderIP, uint16_t* senderPort); // Normal Receive +bool NetworkInterface_Udp_StartReceive(Type_NetworkClient* udpClient, uint8_t* receiveBuffer); // Start interrupt receiving in background +bool NetworkInterface_Udp_StopReceive(Type_NetworkClient* udpClient); // Stop interrupt receiving in background +bool NetworkInterface_Udp_StartReceiveFrom(Type_NetworkClient* udpClient, uint8_t* receiveBuffer, Type_IP4Address senderIP, uint16_t senderPort); // Start interrupt receiving from specific Ip and Port in background +bool NetworkInterface_Udp_StopReceiveFrom(Type_NetworkClient* udpClient); // Stop interrupt receiving from specific Ip and Port in background +uint16_t NetworkInterface_Udp_ReceiveDataAvailableInBuffer(Type_NetworkClient* udpClient); /* return > 0 if any data available */ +uint8_t* NetworkInterface_Udp_GetReceivedData(Type_NetworkClient* udpClient); +bool NetworkInterface_Udp_Close(Type_NetworkClient* udpClient); + +bool NetworkInterface_Tcp_Open(Type_NetworkClient* tcpClient, uint16_t localPort); +bool NetworkInterface_Tcp_Connect(Type_NetworkClient* tcpClient, Type_IP4Address destinationIP, uint16_t destinationPort, uint32_t timeout_ms); +bool NetworkInterface_Tcp_Disconnect(Type_NetworkClient* tcpClient, uint32_t timeout_ms); +bool NetworkInterface_Tcp_Send(Type_NetworkClient* tcpClient, void* data, uint16_t length); // Normal Send +void NetworkInterface_Tcp_Send2(Type_NetworkClient* tcpClient, void* data, uint16_t length); // Fast Implementation +bool NetworkInterface_Tcp_Receive(Type_NetworkClient* tcpClient, uint8_t* buffer, Type_IP4Address* senderIP, uint16_t* senderPort); // Normal Receive +bool NetworkInterface_Tcp_StartReceive(Type_NetworkClient* tcpClient, uint8_t* receiveBuffer); // Start interrupt receiving in background +bool NetworkInterface_Tcp_StopReceive(Type_NetworkClient* tcpClient); // Stop interrupt receiving in background +uint16_t NetworkInterface_Tcp_ReceiveDataAvailableInBuffer(Type_NetworkClient* tcpClient); /* return > 0 if any data available */ +uint8_t* NetworkInterface_Tcp_GetReceivedData(Type_NetworkClient* tcpClient); +bool NetworkInterface_Tcp_Close(Type_NetworkClient* tcpClient); + +void NetworkInterface_ReceiveInterruptCallback(void); + +#ifdef _NETWORK_INTERFACE_INCLUDE_DHCP +void NetworkInterface_1Second_Routine(void); +#endif +#endif /* __NETWORK_INTERFACE_H */