From d3b9394bee987c2d7db6d955d0bc7f8eb1faa829 Mon Sep 17 00:00:00 2001 From: Ali Moallem Date: Wed, 16 Jun 2021 22:55:17 +0430 Subject: [PATCH 1/2] Increased the number of DNS addresses from DHCP server, Added receiving NTP addresses and TimeZone from DHCP server, Added Taking Hostname from user --- Internet/DHCP/dhcp.c | 687 ++++++++++++++++++++++++------------------- Internet/DHCP/dhcp.h | 25 +- 2 files changed, 407 insertions(+), 305 deletions(-) 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 From a0aac0998f51808544f604232ac5674f67bc31e4 Mon Sep 17 00:00:00 2001 From: Mohammad Sayadi Date: Mon, 19 Jul 2021 10:53:01 +0430 Subject: [PATCH 2/2] Added network client-like interface and some features. Added TCP Client. Added UDP Client. Added related TCP and UDP methods. Improved speed of transmit functions in compare of normal functions. Added useful datatypes. Added useful macros. --- NetworkInterface/NetworkInterface.c | 1074 +++++++++++++++++++++++++++ NetworkInterface/NetworkInterface.h | 235 ++++++ 2 files changed, 1309 insertions(+) create mode 100644 NetworkInterface/NetworkInterface.c create mode 100644 NetworkInterface/NetworkInterface.h 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 */