summaryrefslogtreecommitdiff
path: root/FreeRTOS-Plus
diff options
context:
space:
mode:
Diffstat (limited to 'FreeRTOS-Plus')
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c2
-rw-r--r--FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/DemoTasks/SimpleMQTTExamples.c548
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSConfig.h210
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSIPConfig.h307
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/READ_ME_INSTRUCTIONS.url5
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj224
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj.filters308
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Packet32.h359
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/PacketData.h267
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Win32-Extensions.h114
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/arch.c336
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/bittypes.h137
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/ip6_misc.h163
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/netif.h52
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-bpf.h47
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-namedb.h42
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-stdinc.h93
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap.h45
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bluetooth.h48
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bpf.h934
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/namedb.h89
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/pcap.h407
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/sll.h129
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/usb.h90
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/vlan.h46
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/remote-ext.h444
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/wpcap.libbin19320 -> 0 bytes
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/atomic.h547
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.c526
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.h48
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config.h122
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config_common.h200
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_secure_sockets_config.h56
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/main.c364
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_demo.sln23
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/printf-stdarg.c667
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleTaskPoolExamples.c695
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleUDPClientAndServer.c355
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSConfig.h208
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSIPConfig.h307
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/READ_ME_INSTRUCTIONS.url6
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj210
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj.filters260
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Packet32.h359
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/PacketData.h267
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Win32-Extensions.h114
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/arch.c336
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/bittypes.h137
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/ip6_misc.h163
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/netif.h52
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-bpf.h47
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-namedb.h42
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-stdinc.h93
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap.h45
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bluetooth.h48
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bpf.h934
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/namedb.h89
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/pcap.h407
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/sll.h129
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/usb.h90
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/vlan.h46
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/remote-ext.h444
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/wpcap.libbin19320 -> 0 bytes
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.c526
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.h48
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config.h94
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config_common.h197
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/main.c210
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/printf-stdarg.c667
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/task_pool_demo.sln23
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOSConfig.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSIPConfig.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/arch.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/netif.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOSConfig.h2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c2
-rw-r--r--FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c2
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c1350
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c2042
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c3112
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c4674
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c7350
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c398
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c6780
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c3996
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c808
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt354
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url10
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h1138
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h282
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h174
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h274
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h674
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h1654
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h804
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h462
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h160
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h426
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h112
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h180
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h386
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h140
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h88
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c822
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c786
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt3
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h32
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h32
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h92
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h96
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h94
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h98
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_end.h66
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_start.h96
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h96
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h94
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h120
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h116
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c1274
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h1492
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c908
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h562
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c1888
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h2692
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h2698
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Common/phyHandling.c721
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c534
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c2136
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/ReadMe.txt4
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c662
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c896
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h328
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/README_DRIVER_DISCLAIMER.txt20
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c1251
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c354
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c236
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/NetworkInterface.c1193
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.c1835
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.h2214
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c2708
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt60
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f2xx_hal_eth.h6
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.c1833
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.h6
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f7xx_hal_eth.h6
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c1468
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h2262
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c350
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c1268
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c796
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt50
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c132
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.h23
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h288
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c1252
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c486
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h78
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c1170
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h92
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c124
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c328
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/include/phyHandling.h118
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c2544
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.c610
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.h67
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl_reg.h473
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c434
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c1240
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c1778
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c384
-rw-r--r--FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/readme.txt36
202 files changed, 37013 insertions, 65549 deletions
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c
index e973cef02..20fbe615c 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/File-Related-CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
index fd548844f..0ee1b6224 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/Sample-CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c
index ba3a43e6f..d61e017f8 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UARTCommandConsole.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c
index bac9b7a1a..27a948e2a 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_CLI_Demos/UDP-Related-CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c
index 157463544..b47c4dec1 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_FAT_SL_Demos/CreateExampleFiles/File-system-demo.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c
index a43264819..3df1c4458 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h
index 69dda2995..69698c6a6 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandInterpreter.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
index eb0d078ac..f8ea22e76 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/CLICommands/UDPCommandServer.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c
index cc1872876..e0f89d2e9 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h
index 3f1f6ef4f..e3c32fcd0 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/EchoClients/TwoEchoClients.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c
index b241fd369..b159373e5 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h
index 1a73f1cf1..939bff283 100644
--- a/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h
+++ b/FreeRTOS-Plus/Demo/Common/FreeRTOS_Plus_UDP_Demos/TraceMacros/Example1/DemoIPTrace.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/DemoTasks/SimpleMQTTExamples.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/DemoTasks/SimpleMQTTExamples.c
deleted file mode 100644
index 80a04169e..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/DemoTasks/SimpleMQTTExamples.c
+++ /dev/null
@@ -1,548 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/* Standard inclues. */
-#include <string.h>
-#include <stdio.h>
-
-/* Kernel includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-
-/* IoT SDK includes. */
-#include "iot_mqtt.h"
-#include "iot_taskpool.h"
-#include "platform/iot_network_freertos.h"
-
-/**
- * @brief The keep-alive interval used for this example.
- *
- * An MQTT ping request will be sent periodically at this interval.
- */
-#define mqttexampleKEEP_ALIVE_SECONDS ( 60 )
-
-/**
- * @brief The timeout for MQTT operations in this example.
- */
-#define mqttexampleMQTT_TIMEOUT_MS ( 50000 )
-
-/**
- * @brief The MQTT client identifier used in this example.
- */
-#define mqttexampleCLIENT_IDENTIFIER "mqttexampleclient"
-
-const char *pcClientIdentifiers[] = { "AAA" };//, "BBB", "CCC", "DDD", "EEE", "FFF", "GGG", "HHH", "III", "JJJ" };
-
-/**
- * @brief Details of the MQTT broker to connect to.
- *
- * @note This example does not use TLS and therefore won't work with AWS IoT.
- *
- */
-#define mqttexampleMQTT_BROKER_ENDPOINT "test.mosquitto.org"
-#define mqttexampleMQTT_BROKER_PORT 1883
-
-/**
- * @brief The topic to subscribe and publish to in the example.
- */
-#define mqttexampleTOPIC "example/topic"
-
-/**
- * @brief The MQTT message published in this example.
- */
-#define mqttexampleMESSAGE "Hello World!"
-
-/**
- * @brief Paramters to control the retry behaviour in case a QoS1 publish
- * message gets lost.
- *
- * Retry every minutes up to a maximum of 5 retries.
- */
-#define mqttexamplePUBLISH_RETRY_MS ( 1000 )
-#define mqttexamplePUBLISH_RETRY_LIMIT ( 5 )
-
-/**
- * @brief The bit which is set in the demo task's notification value from the
- * disconnect callback to inform the demo task about the MQTT disconnect.
- */
-#define mqttexampleDISCONNECTED_BIT ( 1UL << 0UL )
-
-/**
- * @brief The bit which is set in the demo task's notification value from the
- * publish callback to inform the demo task about the message received from the
- * MQTT broker.
- */
-#define mqttexampleMESSAGE_RECEIVED_BIT ( 1UL << 1UL )
-/*-----------------------------------------------------------*/
-
-/**
- * @brief Parameters used to create the system task pool.
- */
-static const IotTaskPoolInfo_t xTaskPoolParameters = {
- /* Minimum number of threads in a task pool.
- * Note the slimmed down version of the task
- * pool used by this library does not autoscale
- * the number of tasks in the pool so in this
- * case this sets the number of tasks in the
- * pool. */
- 2,
- /* Maximum number of threads in a task pool.
- * Note the slimmed down version of the task
- * pool used by this library does not autoscale
- * the number of tasks in the pool so in this
- * case this parameter is just ignored. */
- 2,
- /* Stack size for every task pool thread - in
- * bytes, hence multiplying by the number of bytes
- * in a word as configMINIMAL_STACK_SIZE is
- * specified in words. */
- configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ),
- /* Priority for every task pool thread. */
- tskIDLE_PRIORITY,
- };
-/*-----------------------------------------------------------*/
-
-/**
- * @brief The task used to demonstrate the MQTT API.
- *
- * @param[in] pvParameters Parmaters as passed at the time of task creation. Not
- * used in this example.
- */
-static void prvMQTTDemoTask( void *pvParameters );
-
-/**
- * @brief The callback invoked by the MQTT library when the MQTT connection gets
- * disconnected.
- *
- * @param[in] pvCallbackContext Callback context as provided at the time of
- * connect.
- * @param[in] pxCallbackParams Contains the reason why the MQTT connection was
- * disconnected.
- */
-static void prvExample_OnDisconnect( void * pvCallbackContext,
- IotMqttCallbackParam_t * pxCallbackParams );
-
-/**
- * @brief The callback invoked by the MQTT library when a message is received on
- * a subscribed topic from the MQTT broker.
- *
- * @param[in] pvCallbackContext Callback context as provided at the time of
- * subscribe.
- * @param[in] pxCallbackParams Contain the details about the received message -
- * topic on which the message was received, the received message.
- */
-static void prvExample_OnMessageReceived( void * pvCallbackContext,
- IotMqttCallbackParam_t * pxCallbackParams );
-
-/**
- * @brief Connects to the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT
- * and mqttexampleMQTT_BROKER_PORT.
- *
- * @note This example does not use TLS and therefore will not work with MQTT.
- */
-static void prvMQTTConnect( IotMqttConnection_t *xMQTTConnection, const char *pcClientID );
-
-/**
- * @brief Subscribes to pcTopicString.
- */
-static void prvMQTTSubscribe( IotMqttConnection_t xMQTTConnection, const char * const pcTopicString );
-
-/**
- * @brief Publishes a messages mqttexampleMESSAGE on mqttexampleTOPIC topic.
- */
-static void prvMQTTPublish( IotMqttConnection_t xMQTTConnection, const char * const pcTopicString );
-
-/**
- * @brief Unsubscribes from the mqttexampleTOPIC topic.
- */
-static void prvMQTTUnsubscribe( IotMqttConnection_t xMQTTConnection, const char * const pcTopicString );
-
-/**
- * @brief Disconnects from the MQTT broker gracefully by sending an MQTT
- * DISCONNECT message.
- */
-static void prvMQTTDisconnect( IotMqttConnection_t xMQTTConnection );
-/*-----------------------------------------------------------*/
-
-static void prvExample_OnDisconnect( void * pvCallbackContext,
- IotMqttCallbackParam_t * pxCallbackParams )
-{
-TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;
-
- /* Ensure that we initiated the disconnect. */
- configASSERT( pxCallbackParams->u.disconnectReason == IOT_MQTT_DISCONNECT_CALLED );
-
- /* Inform the demo task about the disconnect. */
- xTaskNotify( xDemoTaskHandle,
- mqttexampleDISCONNECTED_BIT,
- eSetBits /* Set the mqttexampleDISCONNECTED_BIT in the demo task's notification value. */
- );
-}
-/*-----------------------------------------------------------*/
-
-static void prvExample_OnMessageReceived( void * pvCallbackContext,
- IotMqttCallbackParam_t * pxCallbackParams )
-{
-TaskHandle_t xDemoTaskHandle = ( TaskHandle_t ) pvCallbackContext;
-
- /* Ensure that the message is received on the expected topic. */
-// configASSERT( pxCallbackParams->u.message.info.topicNameLength == strlen( mqttexampleTOPIC ) );
-// configASSERT( strncmp( pxCallbackParams->u.message.info.pTopicName,
-// mqttexampleTOPIC,
-// strlen( mqttexampleTOPIC ) ) == 0 );
-
- /* Ensure that the expected message is received. */
- configASSERT( pxCallbackParams->u.message.info.payloadLength == strlen( mqttexampleMESSAGE ) );
- configASSERT( strncmp( pxCallbackParams->u.message.info.pPayload,
- mqttexampleMESSAGE,
- strlen( mqttexampleMESSAGE ) ) == 0 );
-
- /* Ensure that the message QoS is as expected. */
- configASSERT( pxCallbackParams->u.message.info.qos == IOT_MQTT_QOS_1 );
-
- /* Although this print uses the constants rather than the data from the
- * message payload the asserts above have already checked the message
- * payload equals the constants, and it is more efficient not to have to
- * worry about lengths in the print. */
- configPRINTF( ( "Received %s on the topic %s\r\n", mqttexampleMESSAGE, mqttexampleTOPIC ) );
-
- /* Inform the demo task about the message received from the MQTT broker. */
- xTaskNotify( xDemoTaskHandle,
- mqttexampleMESSAGE_RECEIVED_BIT,
- eSetBits /* Set the mqttexampleMESSAGE_RECEIVED_BIT in the demo task's notification value. */
- );
-}
-/*-----------------------------------------------------------*/
-
-void vStartSimpleMQTTDemo( void )
-{
-uint32_t x;
-const uint32_t ulMax_x = sizeof( pcClientIdentifiers ) / sizeof( char * );
-
- /* This example uses a single application task, which in turn is used to
- * connect, subscribe, publish, unsubscribe and disconnect from the MQTT
- * broker. */
-for( x = 0; x < ulMax_x; x++ )
-{
- xTaskCreate( prvMQTTDemoTask, /* Function that implements the task. */
- "MQTTDemo", /* Text name for the task - only used for debugging. */
- configMINIMAL_STACK_SIZE, /* Size of stack (in words, not bytes) to allocate for the task. */
- ( void * ) x, /* Task parameter - not used in this case. */
- tskIDLE_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
- NULL ); /* Used to pass out a handle to the created task - not used in this case. */
-}
-}
-/*-----------------------------------------------------------*/
-
-static void prvMQTTDemoTask( void *pvParameters )
-{
-IotMqttError_t xResult;
-uint32_t ulNotificationValue = 0, ulPublishCount;
-uint32_t ulMaxPublishCount = 0UL;
-const TickType_t xNoDelay = ( TickType_t ) 1;
-IotMqttConnection_t xMQTTConnection = IOT_MQTT_CONNECTION_INITIALIZER;
-uint32_t ulTaskNumber = ( uint32_t ) pvParameters, x;
-char cTopicString[ sizeof( mqttexampleTOPIC ) + 5 ];//_RB_ Access by other tasks so must be persistant and will cause memory faults on memory protected systems.
-#pragma message ("Access by other tasks so must be persistant and will cause memory faults on memory protected systems.")
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- /* The MQTT library needs a task pool, so create the system task pool. */
- xResult = IotTaskPool_CreateSystemTaskPool( &( xTaskPoolParameters ) );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* MQTT library must be initialized before it can be used. This is just one
- * time initialization. */
- xResult = IotMqtt_Init();
- configASSERT( xResult == IOT_MQTT_SUCCESS );
-
- /* Create a topic string that is unique to the MQTT connection created by
- this task. */
- snprintf( cTopicString, sizeof( cTopicString ), "%s/%s", mqttexampleTOPIC, pcClientIdentifiers[ ulTaskNumber ] );
-
- for( ; ; )
- {
- /* Don't expect any notifications to be pending yet. */
- ulNotificationValue = ulTaskNotifyTake( pdTRUE, xNoDelay );
- configASSERT( ulNotificationValue == 0 );
-
-
- /****************************** Connect. ******************************/
-
- /* Establish a connection to the MQTT broker. This example connects to
- * the MQTT broker as specified in mqttexampleMQTT_BROKER_ENDPOINT and
- * mqttexampleMQTT_BROKER_PORT at the top of this file. Please change
- * it to the MQTT broker you want to connect to. Note that this example
- * does not use TLS and therefore will not work with AWS IoT. */
- prvMQTTConnect( &xMQTTConnection, pcClientIdentifiers[ ulTaskNumber ] );
- configPRINTF( ( "Connected to %s\r\n", mqttexampleMQTT_BROKER_ENDPOINT ) );
-
-
- /**************************** Subscribe. ******************************/
-
- /* The client is now connected to the broker. Subscribe to the topic
- * as specified in mqttexampleTOPIC at the top of this file. This
- * client will then publish to the same topic it subscribed to, so will
- * expect all the messages it sends to the broker to be sent back to it
- * from the broker. */
- prvMQTTSubscribe( xMQTTConnection, cTopicString );
- configPRINTF( ( "Subscribed to the topic %s\r\n", cTopicString ) );
-
-
- /*********************** Publish 5 messages. **************************/
-
- /* Publish a few messages while connected. */
- for( x = 0; x < ( ulTaskNumber + 1UL ); x++ )
- {
- ulMaxPublishCount = uxRand();
- }
-
- /* Cap ulMaxPublishCount but ensure it is not zero. */
- ulMaxPublishCount %= 10UL;
- ulMaxPublishCount++;
-
- for( ulPublishCount = 0; ulPublishCount < ulMaxPublishCount; ulPublishCount++ )
- {
- /* Publish a message on the mqttexampleTOPIC topic as specified at
- * the top of this file. */
- prvMQTTPublish( xMQTTConnection, cTopicString );
- configPRINTF( ( "Published %s on the topic %s\r\n", mqttexampleMESSAGE, cTopicString ) );
-
- /* Since we are subscribed to the same topic as we published on, we
- * will get the same message back from the MQTT broker. Wait for the
- * message to be received which is informed to us by the publish
- * callback (prvExample_OnMessageReceived) by setting the
- * mqttexampleMESSAGE_RECEIVED_BIT in this task's notification
- * value. Note that the bit is cleared in the task's notification
- * value to ensure that it is ready for next message. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- mqttexampleMESSAGE_RECEIVED_BIT, /* Clear bit on exit. */
- &( ulNotificationValue ), /* Obtain the notification value. */
- pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );
- configASSERT( ( ulNotificationValue & mqttexampleMESSAGE_RECEIVED_BIT ) == mqttexampleMESSAGE_RECEIVED_BIT );
- }
-
-
- /******************* Unsubscribe and Disconnect. **********************/
-
- /* Unsubscribe from the topic mqttexampleTOPIC and disconnect
- * gracefully. */
- prvMQTTUnsubscribe( xMQTTConnection, cTopicString );
- prvMQTTDisconnect( xMQTTConnection );
- configPRINTF( ( "Disconnected from %s\r\n\r\n", mqttexampleMQTT_BROKER_ENDPOINT ) );
-
- /* Wait for the disconnect operation to complete which is informed to us
- * by the disconnect callback (prvExample_OnDisconnect)by setting
- * the mqttexampleDISCONNECTED_BIT in this task's notification value.
- * Note that the bit is cleared in the task's notification value to
- * ensure that it is ready for the next run. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- mqttexampleDISCONNECTED_BIT, /* Clear bit on exit. */
- &( ulNotificationValue ), /* Obtain the notification value. */
- pdMS_TO_TICKS( mqttexampleMQTT_TIMEOUT_MS ) );
- configASSERT( ( ulNotificationValue & mqttexampleDISCONNECTED_BIT ) == mqttexampleDISCONNECTED_BIT );
-
- /* Wait for some time between two iterations to ensure that we do not
- * bombard the public test mosquitto broker. */
- configPRINTF( ( "prvMQTTDemoTask() completed an iteration without hitting an assert. Total free heap is %u\r\n\r\n", xPortGetFreeHeapSize() ) );
-// vTaskDelay( pdMS_TO_TICKS( 5000 ) );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvMQTTConnect( IotMqttConnection_t *xMQTTConnection, const char *pcClientID )
-{
-IotMqttError_t xResult;
-IotNetworkServerInfo_t xMQTTBrokerInfo;
-IotMqttNetworkInfo_t xNetworkInfo = IOT_MQTT_NETWORK_INFO_INITIALIZER;
-IotMqttConnectInfo_t xConnectInfo = IOT_MQTT_CONNECT_INFO_INITIALIZER;
-static char c[ 10 ];
-static int id = 0;
-
- /******************* Broker information setup. **********************/
-
- xMQTTBrokerInfo.pHostName = mqttexampleMQTT_BROKER_ENDPOINT;
- xMQTTBrokerInfo.port = mqttexampleMQTT_BROKER_PORT;
-
-
- /******************* Network information setup. **********************/
-
- /* No connection to the MQTT broker has been established yet and we want to
- * establish a new connection. */
- xNetworkInfo.createNetworkConnection = true;
- xNetworkInfo.u.setup.pNetworkServerInfo = &( xMQTTBrokerInfo );
-
- /* This example does not use TLS and therefore pNetworkCredentialInfo must
- * be set to NULL. */
- xNetworkInfo.u.setup.pNetworkCredentialInfo = NULL;
-
- /* Use FreeRTOS+TCP network. */
- xNetworkInfo.pNetworkInterface = IOT_NETWORK_INTERFACE_FREERTOS;
-
- /* Setup the callback which is called when the MQTT connection is
- * disconnected. The task handle is passed as the callback context which
- * is used by the callback to send a task notification to this task.*/
- xNetworkInfo.disconnectCallback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();
- xNetworkInfo.disconnectCallback.function = prvExample_OnDisconnect;
-
-
- /****************** MQTT Connection information setup. ********************/
-
- /* Set this flag to true if connecting to the AWS IoT MQTT broker. This
- * example does not use TLS and therefore won't work with AWS IoT. */
- xConnectInfo.awsIotMqttMode = false;
-
- /* Start with a clean session i.e. direct the MQTT broker to discard any
- * previous session data. Also, establishing a connection with clean session
- * will ensure that the broker does not store any data when this client
- * gets disconnected. */
- xConnectInfo.cleanSession = true;
-
- /* Since we are starting with a clean session, there are no previous
- * subscriptions to be restored. */
- xConnectInfo.pPreviousSubscriptions = NULL;
- xConnectInfo.previousSubscriptionCount = 0;
-
- /* We do not want to publish Last Will and Testament (LWT) message if the
- * client gets disconnected. */
- xConnectInfo.pWillInfo = NULL;
-
- /* Send an MQTT PING request every minute to keep the connection open if
- there is no other MQTT traffic. */
- xConnectInfo.keepAliveSeconds = mqttexampleKEEP_ALIVE_SECONDS;
-
- /* The client identifier is used to uniquely identify this MQTT client to
- * the MQTT broker. In a production device the identifier can be something
- * unique, such as a device serial number. */
- xConnectInfo.pClientIdentifier = pcClientID;
- xConnectInfo.clientIdentifierLength = ( uint16_t ) strlen( pcClientID );
-
- /* This example does not use any authentication and therefore username and
- * password fields are not used. */
- xConnectInfo.pUserName = NULL;
- xConnectInfo.userNameLength = 0;
- xConnectInfo.pPassword = NULL;
- xConnectInfo.passwordLength = 0;
-
- /* Establish the connection to the MQTT broker - It is a blocking call and
- will return only when connection is complete or a timeout occurs. */
- xResult = IotMqtt_Connect( &( xNetworkInfo ),
- &( xConnectInfo ),
- mqttexampleMQTT_TIMEOUT_MS,
- xMQTTConnection );
- configASSERT( xResult == IOT_MQTT_SUCCESS );
-}
-/*-----------------------------------------------------------*/
-
-static void prvMQTTSubscribe( IotMqttConnection_t xMQTTConnection, const char * const pcTopicString )
-{
-IotMqttError_t xResult;
-IotMqttSubscription_t xMQTTSubscription;
-
- /* Subscribe to the mqttexampleTOPIC topic filter. The task handle is passed
- * as the callback context which is used by the callback to send a task
- * notification to this task.*/
- xMQTTSubscription.qos = IOT_MQTT_QOS_1;
- xMQTTSubscription.pTopicFilter = pcTopicString;
- xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( pcTopicString );
- xMQTTSubscription.callback.pCallbackContext = ( void * ) xTaskGetCurrentTaskHandle();
- xMQTTSubscription.callback.function = prvExample_OnMessageReceived;
-
- /* Use the synchronous API to subscribe - It is a blocking call and only
- * returns when the subscribe operation is complete or a timeout occurs. */
- xResult = IotMqtt_TimedSubscribe( xMQTTConnection,
- &( xMQTTSubscription ),
- 1, /* We are subscribing to one topic filter. */
- 0, /* flags - currently ignored. */
- mqttexampleMQTT_TIMEOUT_MS );
- configASSERT( xResult == IOT_MQTT_SUCCESS );
-}
-/*-----------------------------------------------------------*/
-
-static void prvMQTTPublish( IotMqttConnection_t xMQTTConnection, const char * const pcTopicString )
-{
-IotMqttError_t xResult;
-IotMqttPublishInfo_t xMQTTPublishInfo;
-
- /* Publish a message with QoS1 on the mqttexampleTOPIC topic. Since we are
- * subscribed to the same topic, the MQTT broker will send the same message
- * back to us. It is verified in the publish callback. */
- xMQTTPublishInfo.qos = IOT_MQTT_QOS_1;
- xMQTTPublishInfo.retain = false;
- xMQTTPublishInfo.pTopicName = pcTopicString;
- xMQTTPublishInfo.topicNameLength = ( uint16_t ) strlen( pcTopicString );
- xMQTTPublishInfo.pPayload = mqttexampleMESSAGE;
- xMQTTPublishInfo.payloadLength = strlen( mqttexampleMESSAGE );
- xMQTTPublishInfo.retryMs = mqttexamplePUBLISH_RETRY_MS;
- xMQTTPublishInfo.retryLimit = mqttexamplePUBLISH_RETRY_LIMIT;
-
- /* Use the synchronous API to publish - It is a blocking call and only
- * returns when the publish operation is complete or a timeout occurs. */
- xResult = IotMqtt_TimedPublish( xMQTTConnection,
- &( xMQTTPublishInfo ),
- 0, /* flags - currently ignored. */
- mqttexampleMQTT_TIMEOUT_MS );
- configASSERT( xResult == IOT_MQTT_SUCCESS );
-}
-/*-----------------------------------------------------------*/
-
-static void prvMQTTUnsubscribe( IotMqttConnection_t xMQTTConnection, const char * const pcTopicString )
-{
-IotMqttError_t xResult;
-IotMqttSubscription_t xMQTTSubscription;
-
- /* Unsubscribe from the mqttexampleTOPIC topic filter. */
- xMQTTSubscription.pTopicFilter = pcTopicString;
- xMQTTSubscription.topicFilterLength = ( uint16_t ) strlen( pcTopicString );
- /* The following members of the IotMqttSubscription_t are ignored by the
- * unsubscribe operation. Just initialize them to avoid "use of uninitialized
- * variable" warnings. */
- xMQTTSubscription.qos = IOT_MQTT_QOS_1;
- xMQTTSubscription.callback.pCallbackContext = NULL;
- xMQTTSubscription.callback.function = NULL;
-
- /* Use the synchronous API to unsubscribe - It is a blocking call and only
- * returns when the unsubscribe operation is complete or a timeout occurs. */
- xResult = IotMqtt_TimedUnsubscribe( xMQTTConnection,
- &( xMQTTSubscription ),
- 1, /* We are unsubscribing from one topic filter. */
- 0, /* flags - currently ignored. */
- mqttexampleMQTT_TIMEOUT_MS );
- configASSERT( xResult == IOT_MQTT_SUCCESS );
-}
-/*-----------------------------------------------------------*/
-
-static void prvMQTTDisconnect( IotMqttConnection_t xMQTTConnection )
-{
- /* Send a MQTT DISCONNECT packet to the MQTT broker to do a graceful
- * disconnect. */
- IotMqtt_Disconnect( xMQTTConnection,
- 0 /* flags - 0 means a graceful disconnect by sending MQTT DISCONNECT. */
- );
-}
-/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSConfig.h
deleted file mode 100644
index 29b4aace0..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSConfig.h
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
- * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
- * http://www.freertos.org/a00110.html
- *
- * The bottom of this file contains some constants specific to running the UDP
- * stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than
- * the demo) are contained in FreeRTOSIPConfig.h.
- *----------------------------------------------------------*/
-#define configUSE_PREEMPTION 1
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
-#define configMAX_PRIORITIES ( 7 )
-#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
-#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */
-#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) )
-#define configMAX_TASK_NAME_LEN ( 15 )
-#define configUSE_TRACE_FACILITY 1
-#define configUSE_16_BIT_TICKS 0
-#define configIDLE_SHOULD_YIELD 1
-#define configUSE_CO_ROUTINES 0
-#define configUSE_MUTEXES 1
-#define configUSE_RECURSIVE_MUTEXES 1
-#define configQUEUE_REGISTRY_SIZE 0
-#define configUSE_APPLICATION_TASK_TAG 0
-#define configUSE_COUNTING_SEMAPHORES 1
-#define configUSE_ALTERNATIVE_API 0
-#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
-#define configENABLE_BACKWARD_COMPATIBILITY 1
-#define configSUPPORT_STATIC_ALLOCATION 1
-
-/* Hook function related definitions. */
-#define configUSE_TICK_HOOK 0
-#define configUSE_IDLE_HOOK 0
-#define configUSE_MALLOC_FAILED_HOOK 0
-#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */
-
-/* Software timer related definitions. */
-#define configUSE_TIMERS 1
-#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-#define configTIMER_QUEUE_LENGTH 5
-#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
-
-/* Event group related definitions. */
-#define configUSE_EVENT_GROUPS 1
-
-/* Run time stats gathering definitions. */
-#define configGENERATE_RUN_TIME_STATS 0
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
-
-/* Set the following definitions to 1 to include the API function, or zero
-to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 0
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_uxTaskGetStackHighWaterMark 1
-#define INCLUDE_xTaskGetSchedulerState 1
-#define INCLUDE_xTimerGetTimerTaskHandle 0
-#define INCLUDE_xTaskGetIdleTaskHandle 0
-#define INCLUDE_xQueueGetMutexHolder 1
-#define INCLUDE_eTaskGetState 1
-#define INCLUDE_xEventGroupSetBitsFromISR 1
-#define INCLUDE_xTimerPendFunctionCall 1
-#define INCLUDE_pcTaskGetTaskName 1
-
-/* This demo makes use of one or more example stats formatting functions. These
-format the raw data provided by the uxTaskGetSystemState() function in to human
-readable ASCII form. See the notes in the implementation of vTaskList() within
-FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS
-is set to 2 so the formatting functions are included without the stdio.h being
-included in tasks.c. That is because this project defines its own sprintf()
-functions. */
-#define configUSE_STATS_FORMATTING_FUNCTIONS 1
-
-/* Assert call defined for debug builds. */
-#ifdef _DEBUG
- extern void vAssertCalled( const char *pcFile, uint32_t ulLine );
- #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
-#endif /* _DEBUG */
-
-
-
-/* Application specific definitions follow. **********************************/
-
-/* Only used when running in the FreeRTOS Windows simulator. Defines the
-priority of the task used to simulate Ethernet interrupts. */
-#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 )
-
-/* This demo creates a virtual network connection by accessing the raw Ethernet
-or WiFi data to and from a real network connection. Many computers have more
-than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell
-the demo which real port should be used to create the virtual port. The ports
-available are displayed on the console when the application is executed. For
-example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4
-results in the wired network being used, while setting
-configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being
-used. */
-#define configNETWORK_INTERFACE_TO_USE 2L
-
-/* The address of an echo server is only left in this project as it doubles as
-the address to which logging is sent should UDP logging be enabled. */
-#define configECHO_SERVER_ADDR0 192
-#define configECHO_SERVER_ADDR1 168
-#define configECHO_SERVER_ADDR2 26
-#define configECHO_SERVER_ADDR3 100
-
-/* Default MAC address configuration. The demo creates a virtual network
-connection that uses this MAC address by accessing the raw Ethernet/WiFi data
-to and from a real network connection on the host PC. See the
-configNETWORK_INTERFACE_TO_USE definition above for information on how to
-configure the real network connection to use. */
-#define configMAC_ADDR0 0x00
-#define configMAC_ADDR1 0x11
-#define configMAC_ADDR2 0x11
-#define configMAC_ADDR3 0x11
-#define configMAC_ADDR4 0x11
-#define configMAC_ADDR5 0x41
-
-/* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or
-ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configIP_ADDR0 192
-#define configIP_ADDR1 168
-#define configIP_ADDR2 1
-#define configIP_ADDR3 51
-
-/* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to
-0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configGATEWAY_ADDR0 192
-#define configGATEWAY_ADDR1 168
-#define configGATEWAY_ADDR2 1
-#define configGATEWAY_ADDR3 1
-
-/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and
-208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set
-to 1 but a DNS server cannot be contacted.*/
-#define configDNS_SERVER_ADDR0 8
-#define configDNS_SERVER_ADDR1 8
-#define configDNS_SERVER_ADDR2 8
-#define configDNS_SERVER_ADDR3 8
-
-/* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or
-ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configNET_MASK0 255
-#define configNET_MASK1 255
-#define configNET_MASK2 255
-#define configNET_MASK3 0
-
-/* The UDP port to which print messages are sent. */
-#define configPRINT_PORT ( 15000 )
-
-#if( defined( _MSC_VER ) && ( _MSC_VER <= 1600 ) && !defined( snprintf ) )
- /* Map to Windows names. */
- #define snprintf _snprintf
- #define vsnprintf _vsnprintf
-#endif
-
-/* Visual studio does not have an implementation of strcasecmp(). */
-#define strcasecmp _stricmp
-#define strncasecmp _strnicmp
-#define strcmpi _strcmpi
-
-/* Prototype for the function used to print out. In this case it prints to the
-console before the network is connected then a UDP port after the network has
-connected. */
-extern void vLoggingPrintf( const char *pcFormatString, ... );
-#define configPRINTF( X ) vLoggingPrintf X
-
-#endif /* FREERTOS_CONFIG_H */
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSIPConfig.h
deleted file mode 100644
index 563f0cb09..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/FreeRTOSIPConfig.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-
-/*****************************************************************************
- *
- * See the following URL for configuration information.
- * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html
- *
- *****************************************************************************/
-
-#ifndef FREERTOS_IP_CONFIG_H
-#define FREERTOS_IP_CONFIG_H
-
-/* Prototype for the function used to print out. In this case it prints to the
-console before the network is connected then a UDP port after the network has
-connected. */
-extern void vLoggingPrintf( const char *pcFormatString, ... );
-
-/* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to
-1 then FreeRTOS_debug_printf should be defined to the function used to print
-out the debugging messages. */
-#define ipconfigHAS_DEBUG_PRINTF 0
-#if( ipconfigHAS_DEBUG_PRINTF == 1 )
- #define FreeRTOS_debug_printf(X) vLoggingPrintf X
-#endif
-
-/* Set to 1 to print out non debugging messages, for example the output of the
-FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1
-then FreeRTOS_printf should be set to the function used to print out the
-messages. */
-#define ipconfigHAS_PRINTF 1
-#if( ipconfigHAS_PRINTF == 1 )
- #define FreeRTOS_printf(X) vLoggingPrintf X
-#endif
-
-/* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing
-on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */
-#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
-
-/* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums)
-then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software
-stack repeating the checksum calculations. */
-#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
-
-/* Several API's will block until the result is known, or the action has been
-performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be
-set per socket, using setsockopt(). If not set, the times below will be
-used as defaults. */
-#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 )
-#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 )
-
-/* Include support for LLMNR: Link-local Multicast Name Resolution
-(non-Microsoft) */
-#define ipconfigUSE_LLMNR ( 0 )
-
-/* Include support for NBNS: NetBIOS Name Service (Microsoft) */
-#define ipconfigUSE_NBNS ( 0 )
-
-/* Include support for DNS caching. For TCP, having a small DNS cache is very
-useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low
-and also DNS may use small timeouts. If a DNS reply comes in after the DNS
-socket has been destroyed, the result will be stored into the cache. The next
-call to FreeRTOS_gethostbyname() will return immediately, without even creating
-a socket. */
-#define ipconfigUSE_DNS_CACHE ( 1 )
-#define ipconfigDNS_CACHE_NAME_LENGTH ( 32 )
-#define ipconfigDNS_CACHE_ENTRIES ( 4 )
-#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 )
-
-/* The IP stack executes it its own task (although any application task can make
-use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY
-sets the priority of the task that executes the IP stack. The priority is a
-standard FreeRTOS task priority so can take any value from 0 (the lowest
-priority) to (configMAX_PRIORITIES - 1) (the highest priority).
-configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in
-FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to
-the priority assigned to the task executing the IP stack relative to the
-priority assigned to tasks that use the IP stack. */
-#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
-
-/* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP
-task. This setting is less important when the FreeRTOS Win32 simulator is used
-as the Win32 simulator only stores a fixed amount of information on the task
-stack. FreeRTOS includes optional stack overflow detection, see:
-http://www.freertos.org/Stacks-and-stack-overflow-checking.html */
-#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 )
-
-/* ipconfigRAND32() is called by the IP stack to generate random numbers for
-things such as a DHCP transaction number or initial sequence number. Random
-number generation is performed via this macro to allow applications to use their
-own random number generation method. For example, it might be possible to
-generate a random number by sampling noise on an analogue input. */
-extern UBaseType_t uxRand();
-#define ipconfigRAND32() uxRand()
-
-/* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the
-network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK
-is not set to 1 then the network event hook will never be called. See
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml
-*/
-#define ipconfigUSE_NETWORK_EVENT_HOOK 1
-
-/* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but
-a network buffer cannot be obtained then the calling task is held in the Blocked
-state (so other tasks can continue to executed) until either a network buffer
-becomes available or the send block time expires. If the send block time expires
-then the send operation is aborted. The maximum allowable send block time is
-capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the
-maximum allowable send block time prevents prevents a deadlock occurring when
-all the network buffers are in use and the tasks that process (and subsequently
-free) the network buffers are themselves blocked waiting for a network buffer.
-ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in
-milliseconds can be converted to a time in ticks by dividing the time in
-milliseconds by portTICK_PERIOD_MS. */
-#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000 / portTICK_PERIOD_MS )
-
-/* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP
-address, netmask, DNS server address and gateway address from a DHCP server. If
-ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The
-stack will revert to using the static IP address even when ipconfigUSE_DHCP is
-set to 1 if a valid configuration cannot be obtained from a DHCP server for any
-reason. The static configuration used is that passed into the stack by the
-FreeRTOS_IPInit() function call. */
-#define ipconfigUSE_DHCP 0
-
-/* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at
-increasing time intervals until either a reply is received from a DHCP server
-and accepted, or the interval between transmissions reaches
-ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the
-static IP address passed as a parameter to FreeRTOS_IPInit() if the
-re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without
-a DHCP reply being received. */
-#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000 / portTICK_PERIOD_MS )
-
-/* The ARP cache is a table that maps IP addresses to MAC addresses. The IP
-stack can only send a UDP message to a remove IP address if it knowns the MAC
-address associated with the IP address, or the MAC address of the router used to
-contact the remote IP address. When a UDP message is received from a remote IP
-address the MAC address and IP address are added to the ARP cache. When a UDP
-message is sent to a remote IP address that does not already appear in the ARP
-cache then the UDP message is replaced by a ARP message that solicits the
-required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum
-number of entries that can exist in the ARP table at any one time. */
-#define ipconfigARP_CACHE_ENTRIES 6
-
-/* ARP requests that do not result in an ARP response will be re-transmitted a
-maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is
-aborted. */
-#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
-
-/* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP
-table being created or refreshed and the entry being removed because it is stale.
-New ARP requests are sent for ARP cache entries that are nearing their maximum
-age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is
-equal to 1500 seconds (or 25 minutes). */
-#define ipconfigMAX_ARP_AGE 150
-
-/* Implementing FreeRTOS_inet_addr() necessitates the use of string handling
-routines, which are relatively large. To save code space the full
-FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster
-alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr()
-takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter.
-FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets
-(for example, 192, 168, 0, 1) as its parameters. If
-ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and
-FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is
-not set to 1 then only FreeRTOS_indet_addr_quick() is available. */
-#define ipconfigINCLUDE_FULL_INET_ADDR 1
-
-/* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that
-are available to the IP stack. The total number of network buffers is limited
-to ensure the total amount of RAM that can be consumed by the IP stack is capped
-to a pre-determinable value. */
-#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60
-
-/* A FreeRTOS queue is used to send events from application tasks to the IP
-stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can
-be queued for processing at any one time. The event queue must be a minimum of
-5 greater than the total number of network buffers. */
-#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
-
-/* The address of a socket is the combination of its IP address and its port
-number. FreeRTOS_bind() is used to manually allocate a port number to a socket
-(to 'bind' the socket to a port), but manual binding is not normally necessary
-for client sockets (those sockets that initiate outgoing connections rather than
-wait for incoming connections on a known port number). If
-ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling
-FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP
-stack automatically binding the socket to a port number from the range
-socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If
-ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto()
-on a socket that has not yet been bound will result in the send operation being
-aborted. */
-#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
-
-/* Defines the Time To Live (TTL) values used in outgoing UDP packets. */
-#define ipconfigUDP_TIME_TO_LIVE 128
-#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */
-
-/* USE_TCP: Use TCP and all its features */
-#define ipconfigUSE_TCP ( 1 )
-
-/* USE_WIN: Let TCP use windowing mechanism. */
-#define ipconfigUSE_TCP_WIN ( 1 )
-
-/* The MTU is the maximum number of bytes the payload of a network frame can
-contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a
-lower value can save RAM, depending on the buffer management scheme used. If
-ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must
-be divisible by 8. */
-#define ipconfigNETWORK_MTU 1200
-
-/* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used
-through the FreeRTOS_gethostbyname() API function. */
-#define ipconfigUSE_DNS 1
-
-/* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will
-generate replies to incoming ICMP echo (ping) requests. */
-#define ipconfigREPLY_TO_INCOMING_PINGS 1
-
-/* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the
-FreeRTOS_SendPingRequest() API function is available. */
-#define ipconfigSUPPORT_OUTGOING_PINGS 0
-
-/* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select()
-(and associated) API function is available. */
-#define ipconfigSUPPORT_SELECT_FUNCTION 1
-
-/* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames
-that are not in Ethernet II format will be dropped. This option is included for
-potential future IP stack developments. */
-#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the
-responsibility of the Ethernet interface to filter out packets that are of no
-interest. If the Ethernet interface does not implement this functionality, then
-set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack
-perform the filtering instead (it is much less efficient for the stack to do it
-because the packet will already have been passed into the stack). If the
-Ethernet driver does all the necessary filtering in hardware then software
-filtering can be removed by using a value other than 1 or 0. */
-#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
-
-/* The windows simulator cannot really simulate MAC interrupts, and needs to
-block occasionally to allow other tasks to run. */
-#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS )
-
-/* Advanced only: in order to access 32-bit fields in the IP packets with
-32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits.
-This has to do with the contents of the IP-packets: all 32-bit fields are
-32-bit-aligned, plus 16-bit(!) */
-#define ipconfigPACKET_FILLER_SIZE 2
-
-/* Define the size of the pool of TCP window descriptors. On the average, each
-TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6
-outstanding packets (for Rx and Tx). When using up to 10 TP sockets
-simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */
-#define ipconfigTCP_WIN_SEG_COUNT 240
-
-/* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed
-maximum size. Define the size of Rx buffer for TCP sockets. */
-#define ipconfigTCP_RX_BUFFER_LENGTH ( 1000 )
-
-/* Define the size of Tx buffer for TCP sockets. */
-#define ipconfigTCP_TX_BUFFER_LENGTH ( 1000 )
-
-/* When using call-back handlers, the driver may check if the handler points to
-real program memory (RAM or flash) or just has a random non-zero value. */
-#define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL )
-
-/* Include support for TCP hang protection. All sockets in a connecting or
-disconnecting stage will timeout after a period of non-activity. */
-#define ipconfigTCP_HANG_PROTECTION ( 1 )
-#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 )
-
-/* Include support for TCP keep-alive messages. */
-#define ipconfigTCP_KEEP_ALIVE ( 1 )
-#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* in seconds */
-
-#define portINLINE __inline
-
-#endif /* FREERTOS_IP_CONFIG_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/READ_ME_INSTRUCTIONS.url b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/READ_ME_INSTRUCTIONS.url
deleted file mode 100644
index 8a5a8617e..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/READ_ME_INSTRUCTIONS.url
+++ /dev/null
@@ -1,5 +0,0 @@
-[{000214A0-0000-0000-C000-000000000046}]
-Prop3=19,11
-[InternetShortcut]
-IDList=
-URL=https://www.freertos.org/mqtt/
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj
deleted file mode 100644
index b92278318..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj
+++ /dev/null
@@ -1,224 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>
- <ProjectName>RTOSDemo</ProjectName>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseOfMfc>false</UseOfMfc>
- <CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v142</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseOfMfc>false</UseOfMfc>
- <CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v142</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Midl>
- <TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>
- <HeaderFileName>
- </HeaderFileName>
- </Midl>
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\..\Source\FreeRTOS-Plus-TCP\include;..\..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;.\DemoTasks\include;.\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private;..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include;..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include;..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\include;..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <MinimalRebuild>false</MinimalRebuild>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>
- <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
- <ObjectFileName>.\Debug/</ObjectFileName>
- <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
- <WarningLevel>Level4</WarningLevel>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <DisableLanguageExtensions>false</DisableLanguageExtensions>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <AdditionalOptions>/wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 /wd4200 %(AdditionalOptions)</AdditionalOptions>
- <BrowseInformation>true</BrowseInformation>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <ExceptionHandling>false</ExceptionHandling>
- <CompileAs>CompileAsC</CompileAs>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <Culture>0x0c09</Culture>
- </ResourceCompile>
- <Link>
- <OutputFile>.\Debug/RTOSDemo.exe</OutputFile>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>
- <SubSystem>Console</SubSystem>
- <TargetMachine>MachineX86</TargetMachine>
- <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>.\WinPCap</AdditionalLibraryDirectories>
- <Profile>false</Profile>
- <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- </Link>
- <Bscmake>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <OutputFile>.\Debug/WIN32.bsc</OutputFile>
- </Bscmake>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Midl>
- <TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>
- <HeaderFileName>
- </HeaderFileName>
- </Midl>
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>
- <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
- <ObjectFileName>.\Release/</ObjectFileName>
- <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
- <WarningLevel>Level3</WarningLevel>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\..\Source\include;..\..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <Culture>0x0c09</Culture>
- </ResourceCompile>
- <Link>
- <OutputFile>.\Release/RTOSDemo.exe</OutputFile>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>
- <SubSystem>Console</SubSystem>
- <TargetMachine>MachineX86</TargetMachine>
- <AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>
- <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- <Bscmake>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <OutputFile>.\Release/WIN32.bsc</OutputFile>
- </Bscmake>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\event_groups.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\list.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\queue.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\tasks.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\timers.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_clock_freertos.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_network_freertos.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_threads_freertos.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\logging\iot_logging.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\taskpool\iot_taskpool.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_api.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_network.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_operation.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_serialize.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_subscription.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_validate.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_ARP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DHCP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DNS.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_IP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Sockets.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Stream_Buffer.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_IP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_WIN.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
- <ClCompile Include="DemoTasks\SimpleMQTTExamples.c" />
- <ClCompile Include="demo_logging.c" />
- <ClCompile Include="main.c">
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\event_groups.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\FreeRTOS.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\portable.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\projdefs.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\queue.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\semphr.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\task.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\timers.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\portmacro.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\include\platform\iot_platform_types_freertos.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_clock.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_metrics.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_network.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_threads.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\types\iot_platform_types.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\iot_taskpool.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_error.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_logging.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_static_memory.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_taskpool_internal.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\types\iot_taskpool_types.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\include\iot_mqtt.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\include\types\iot_mqtt_types.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOSIPConfigDefaults.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_ARP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DHCP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DNS.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP_Private.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Sockets.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Stream_Buffer.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_IP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_WIN.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_UDP_IP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\IPTraceMacroDefaults.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkBufferManagement.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkInterface.h" />
- <ClInclude Include="FreeRTOSConfig.h" />
- <ClInclude Include="FreeRTOSIPConfig.h" />
- <ClInclude Include="iot_config.h" />
- <ClInclude Include="iot_config_common.h" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj.filters
deleted file mode 100644
index 98cdff0ad..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WIN32.vcxproj.filters
+++ /dev/null
@@ -1,308 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{38712199-cebf-4124-bf15-398f7c3419ea}</UniqueIdentifier>
- <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
- </Filter>
- <Filter Include="FreeRTOS">
- <UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS\Source">
- <UniqueIdentifier>{f32be356-4763-4cae-9020-974a2638cb08}</UniqueIdentifier>
- <Extensions>*.c</Extensions>
- </Filter>
- <Filter Include="FreeRTOS\Source\Portable">
- <UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+">
- <UniqueIdentifier>{e5ad4ec7-23dc-4295-8add-2acaee488f5a}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS\Source\include">
- <UniqueIdentifier>{d2dcd641-8d91-492b-852f-5563ffadaec6}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS+TCP">
- <UniqueIdentifier>{8672fa26-b119-481f-8b8d-086419c01a3e}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS+TCP\portable">
- <UniqueIdentifier>{4570be11-ec96-4b55-ac58-24b50ada980a}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS+TCP\include">
- <UniqueIdentifier>{5d93ed51-023a-41ad-9243-8d230165d34b}</UniqueIdentifier>
- </Filter>
- <Filter Include="DemoTasks">
- <UniqueIdentifier>{b71e974a-9f28-4815-972b-d930ba8a34d0}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries">
- <UniqueIdentifier>{60717407-397f-4ea5-8492-3314acdd25f0}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard">
- <UniqueIdentifier>{8a90222f-d723-4b4e-8e6e-c57afaf7fa92}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common">
- <UniqueIdentifier>{7c995f05-2a10-4771-ad77-18a755876e46}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\task_pool">
- <UniqueIdentifier>{e07288b6-a8e7-416a-947d-7f0260673dcc}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include">
- <UniqueIdentifier>{9a636cc3-ebc6-48c5-8c18-c72494686e81}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private">
- <UniqueIdentifier>{fe53a296-12ec-4819-bf2b-fd9dca2c6e96}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\types">
- <UniqueIdentifier>{29376c48-bc8b-4624-ad59-16807874c9f2}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions">
- <UniqueIdentifier>{91ef4008-de51-4b41-ba5e-bf24d8cda378}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform">
- <UniqueIdentifier>{ade43c6c-04c5-4897-abdb-91af2df04e5d}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos">
- <UniqueIdentifier>{08a4e35c-19ca-4b1e-af24-bac368c2bf7b}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include">
- <UniqueIdentifier>{1fc5fc25-c18b-45a2-bad3-0c07795db1e9}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\platform">
- <UniqueIdentifier>{f3a69e5b-1462-4e19-8651-274e86c252b0}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\types">
- <UniqueIdentifier>{9a849d9e-91e5-4035-ab4c-70a986c6aed1}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include">
- <UniqueIdentifier>{1e324500-91b4-4c76-b699-59ba75691760}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include\platform">
- <UniqueIdentifier>{bdcbc1ec-99b8-4c72-9075-49035c115488}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt">
- <UniqueIdentifier>{2d17d5e6-ed70-4e42-9693-f7a63baf4948}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src">
- <UniqueIdentifier>{7158b0be-01e7-42d1-8d3f-c75118a596a2}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\include">
- <UniqueIdentifier>{6ad56e6d-c330-4830-8f4b-c75b05dfa866}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\include\types">
- <UniqueIdentifier>{1d80b387-5a86-4744-a4cc-930033a52e4b}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\logging">
- <UniqueIdentifier>{1943ad1a-a367-4ef5-ab65-1313801e6327}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">
- <Filter>FreeRTOS\Source\Portable</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\timers.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\list.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\queue.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\tasks.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DHCP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DNS.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Sockets.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP\portable</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP\portable</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_ARP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_IP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_IP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_WIN.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\event_groups.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">
- <Filter>FreeRTOS\Source\Portable</Filter>
- </ClCompile>
- <ClCompile Include="main.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Stream_Buffer.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="demo_logging.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\taskpool\iot_taskpool.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\task_pool</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_api.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_operation.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_serialize.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\logging\iot_logging.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\logging</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_network.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_subscription.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\src\iot_mqtt_validate.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\src</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_clock_freertos.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_threads_freertos.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos</Filter>
- </ClCompile>
- <ClCompile Include="DemoTasks\SimpleMQTTExamples.c">
- <Filter>DemoTasks</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_network_freertos.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkInterface.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DNS.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Sockets.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_UDP_IP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\timers.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\event_groups.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\FreeRTOS.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\queue.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\semphr.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\task.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\portmacro.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP_Private.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkBufferManagement.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_ARP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DHCP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_IP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_WIN.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOSIPConfigDefaults.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\IPTraceMacroDefaults.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="FreeRTOSConfig.h" />
- <ClInclude Include="FreeRTOSIPConfig.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Stream_Buffer.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\portable.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\projdefs.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\iot_taskpool.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\types\iot_taskpool_types.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\types</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_error.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_logging.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_static_memory.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_taskpool_internal.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="iot_config.h" />
- <ClInclude Include="iot_config_common.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\types\iot_platform_types.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\types</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\include\iot_mqtt.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\mqtt\include\types\iot_mqtt_types.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\mqtt\include\types</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\include\platform\iot_platform_types_freertos.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include\platform</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_clock.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\platform</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_metrics.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\platform</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_network.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\platform</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\platform\iot_threads.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\platform</Filter>
- </ClInclude>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Packet32.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Packet32.h
deleted file mode 100644
index 1e0eacd77..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Packet32.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/** @ingroup packetapi
- * @{
- */
-
-/** @defgroup packet32h Packet.dll definitions and data structures
- * Packet32.h contains the data structures and the definitions used by packet.dll.
- * The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included
- * by the applications that use the functions of this library
- * @{
- */
-
-#ifndef __PACKET32
-#define __PACKET32
-
-#include <winsock2.h>
-
-#ifdef HAVE_AIRPCAP_API
-#include <airpcap.h>
-#else
-#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
-#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
-typedef struct _AirpcapHandle *PAirpcapHandle;
-#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */
-#endif /* HAVE_AIRPCAP_API */
-
-#ifdef HAVE_DAG_API
-#include <dagc.h>
-#endif /* HAVE_DAG_API */
-
-// Working modes
-#define PACKET_MODE_CAPT 0x0 ///< Capture mode
-#define PACKET_MODE_STAT 0x1 ///< Statistical mode
-#define PACKET_MODE_MON 0x2 ///< Monitoring mode
-#define PACKET_MODE_DUMP 0x10 ///< Dump mode
-#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode
-
-
-/// Alignment macro. Defines the alignment size.
-#define Packet_ALIGNMENT sizeof(int)
-/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT.
-#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))
-
-#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent
-
-// Loopback behaviour definitions
-#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver
-#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver
-
-/*!
- \brief Network type structure.
-
- This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed.
-*/
-typedef struct NetType
-{
- UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information)
- ULONGLONG LinkSpeed; ///< The speed of the network in bits per second
-}NetType;
-
-
-//some definitions stolen from libpcap
-
-#ifndef BPF_MAJOR_VERSION
-
-/*!
- \brief A BPF pseudo-assembly program.
-
- The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet.
-*/
-struct bpf_program
-{
- UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow.
- struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program.
-};
-
-/*!
- \brief A single BPF pseudo-instruction.
-
- bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver.
-*/
-struct bpf_insn
-{
- USHORT code; ///< Instruction type and addressing mode.
- UCHAR jt; ///< Jump if true
- UCHAR jf; ///< Jump if false
- int k; ///< Generic field used for various purposes.
-};
-
-/*!
- \brief Structure that contains a couple of statistics values on the current capture.
-
- It is used by packet.dll to return statistics about a capture session.
-*/
-struct bpf_stat
-{
- UINT bs_recv; ///< Number of packets that the driver received from the network adapter
- ///< from the beginning of the current capture. This value includes the packets
- ///< lost by the driver.
- UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture.
- ///< Basically, a packet is lost when the the buffer of the driver is full.
- ///< In this situation the packet cannot be stored and the driver rejects it.
- UINT ps_ifdrop; ///< drops by interface. XXX not yet supported
- UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and
- ///< thus reach the application.
-};
-
-/*!
- \brief Packet header.
-
- This structure defines the header associated with every packet delivered to the application.
-*/
-struct bpf_hdr
-{
- struct timeval bh_tstamp; ///< The timestamp associated with the captured packet.
- ///< It is stored in a TimeVal structure.
- UINT bh_caplen; ///< Length of captured portion. The captured portion <b>can be different</b>
- ///< from the original packet, because it is possible (with a proper filter)
- ///< to instruct the driver to capture only a portion of the packets.
- UINT bh_datalen; ///< Original length of packet
- USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases,
- ///< a padding could be added between the end of this structure and the packet
- ///< data for performance reasons. This filed can be used to retrieve the actual data
- ///< of the packet.
-};
-
-/*!
- \brief Dump packet header.
-
- This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets().
- It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a
- packet in a dump file. This makes straightforward sending WinPcap dump files to the network.
-*/
-struct dump_bpf_hdr{
- struct timeval ts; ///< Time stamp of the packet
- UINT caplen; ///< Length of captured portion. The captured portion can smaller than the
- ///< the original packet, because it is possible (with a proper filter) to
- ///< instruct the driver to capture only a portion of the packets.
- UINT len; ///< Length of the original packet (off wire).
-};
-
-
-#endif
-
-struct bpf_stat;
-
-#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices
-#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links
-#define NMAX_PACKET 65535
-
-/*!
- \brief Addresses of a network adapter.
-
- This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with
- an adapter.
-*/
-typedef struct npf_if_addr {
- struct sockaddr_storage IPAddress; ///< IP address.
- struct sockaddr_storage SubnetMask; ///< Netmask for that address.
- struct sockaddr_storage Broadcast; ///< Broadcast address.
-}npf_if_addr;
-
-
-#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API.
-#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API.
-#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
-#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
-
-
-typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
-typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
-
-#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter
-#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET
-#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card
-#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file
-#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones.
-#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card
-#define INFO_FLAG_NPFIM_DEVICE 32
-
-/*!
- \brief Describes an opened network adapter.
-
- This structure is the most important for the functioning of packet.dll, but the great part of its fields
- should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters
-*/
-typedef struct _ADAPTER {
- HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver.
- CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened.
- int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated
- ///< on the wire.
- HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter.
- ///< It can be passed to standard Win32 functions (like WaitForSingleObject
- ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some
- ///< data. It is particularly useful in GUI applications that need to wait
- ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy()
- ///< function can be used to define the minimum amount of data in the kernel buffer
- ///< that will cause the event to be signalled.
-
- UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and
- ///< ReadEvent will be signaled, also if no packets were captured
- CHAR Name[ADAPTER_NAME_LENGTH];
- PWAN_ADAPTER pWanAdapter;
- UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API.
-
-#ifdef HAVE_AIRPCAP_API
- PAirpcapHandle AirpcapAd;
-#endif // HAVE_AIRPCAP_API
-
-#ifdef HAVE_NPFIM_API
- void* NpfImHandle;
-#endif // HAVE_NPFIM_API
-
-#ifdef HAVE_DAG_API
- dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter
- PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card
- struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure
- unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry
- DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps).
-#endif // HAVE_DAG_API
-} ADAPTER, *LPADAPTER;
-
-/*!
- \brief Structure that contains a group of packets coming from the driver.
-
- This structure defines the header associated with every packet delivered to the application.
-*/
-typedef struct _PACKET {
- HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications.
- OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications.
- PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for
- ///< details about the organization of the data in this buffer
- UINT Length; ///< Length of the buffer
- DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data
- ///< received by the last call to PacketReceivePacket()
- BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications.
-} PACKET, *LPPACKET;
-
-/*!
- \brief Structure containing an OID request.
-
- It is used by the PacketRequest() function to send an OID to the interface card driver.
- It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address,
- the list of the multicast groups defined on it, and so on.
-*/
-struct _PACKET_OID_DATA {
- ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
- ///< for a complete list of valid codes.
- ULONG Length; ///< Length of the data field
- UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received
- ///< from the adapter.
-};
-typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @}
- */
-
-/*
-BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName,
- CHAR *Value,
- UINT *pValueLen,
- CHAR *DefaultVal);
-
-BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName,
- WCHAR *Value,
- UINT *pValueLen,
- WCHAR *DefaultVal);
-*/
-
-//---------------------------------------------------------------------------
-// EXPORTED FUNCTIONS
-//---------------------------------------------------------------------------
-
-PCHAR PacketGetVersion();
-PCHAR PacketGetDriverVersion();
-BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes);
-BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites);
-BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode);
-BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout);
-BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp);
-BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior);
-INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen);
-BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s);
-BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s);
-BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim);
-BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type);
-LPADAPTER PacketOpenAdapter(PCHAR AdapterName);
-BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync);
-INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync);
-LPPACKET PacketAllocatePacket(void);
-VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length);
-VOID PacketFreePacket(LPPACKET lpPacket);
-BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync);
-BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter);
-BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize);
-BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries);
-BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData);
-HANDLE PacketGetReadEvent(LPADAPTER AdapterObject);
-BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len);
-BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks);
-BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync);
-BOOL PacketStopDriver();
-VOID PacketCloseAdapter(LPADAPTER lpAdapter);
-BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength);
-BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags);
-PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject);
-
-//
-// Used by PacketStartOemEx
-//
-#define PACKET_START_OEM_NO_NETMON 0x00000001
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__PACKET32
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/PacketData.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/PacketData.h
deleted file mode 100644
index 8124db66d..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/PacketData.h
+++ /dev/null
@@ -1,267 +0,0 @@
-char pkt1[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x07, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02,
-0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04,
-0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 };
-
-char pkt2[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa6, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt3[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt4[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06,
-0x6d, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18,
-0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45,
-0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50,
-0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63,
-0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c,
-0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78,
-0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70,
-0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
-0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65,
-0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
-0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76,
-0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78,
-0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c,
-0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64,
-0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65,
-0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20,
-0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73,
-0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70,
-0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78,
-0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d,
-0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d,
-0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c,
-0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a,
-0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45,
-0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a,
-0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64,
-0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a,
-0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65,
-0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69,
-0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20,
-0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69,
-0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49,
-0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57,
-0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e,
-0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53,
-0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67,
-0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e,
-0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32,
-0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30,
-0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32,
-0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48,
-0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32,
-0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31,
-0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
-0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b,
-0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76,
-0x65, 0x0d, 0x0a, 0x0d, 0x0a };
-
-char pkt5[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa5, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt6[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt7[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06,
-0x6d, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18,
-0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45,
-0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50,
-0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63,
-0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c,
-0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78,
-0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70,
-0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
-0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65,
-0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
-0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76,
-0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78,
-0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c,
-0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64,
-0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65,
-0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20,
-0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73,
-0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70,
-0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78,
-0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d,
-0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d,
-0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c,
-0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a,
-0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45,
-0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a,
-0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64,
-0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a,
-0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65,
-0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69,
-0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20,
-0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69,
-0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49,
-0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57,
-0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e,
-0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53,
-0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67,
-0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e,
-0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32,
-0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30,
-0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32,
-0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48,
-0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32,
-0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31,
-0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
-0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b,
-0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76,
-0x65, 0x0d, 0x0a, 0x0d, 0x0a };
-
-char pkt8[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa4, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt9[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt10[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa3, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt11[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt12[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14,
-0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 };
-
-
-typedef struct
-{
- char *pcData;
- int iDataLen;
-} xPacketData;
-
-xPacketData xAllPackets[] =
-{
- { pkt1, sizeof( pkt1 ) },
-// { pkt2, sizeof( pkt2 ) },
- { pkt3, sizeof( pkt3 ) },
- { pkt4, sizeof( pkt4 ) },
-// { pkt5, sizeof( pkt5 ) },
- { pkt6, sizeof( pkt6 ) },
- { pkt7, sizeof( pkt7 ) },
- { pkt8, sizeof( pkt8 ) },
- { pkt9, sizeof( pkt9 ) },
- { pkt10, sizeof( pkt10 ) },
-// { pkt11, sizeof( pkt11 ) },
-// { pkt12, sizeof( pkt12 ) },
-// { pkt13, sizeof( pkt13 ) },
-// { pkt14, sizeof( pkt14 ) },
-// { pkt15, sizeof( pkt15 ) },
-// { pkt16, sizeof( pkt16 ) },
-};
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Win32-Extensions.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Win32-Extensions.h
deleted file mode 100644
index be71c85e9..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/Win32-Extensions.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef __WIN32_EXTENSIONS_H__
-#define __WIN32_EXTENSIONS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Definitions */
-
-/*!
- \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit().
-*/
-struct pcap_send_queue
-{
- u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field.
- u_int len; ///< Current size of the queue, in bytes.
- char *buffer; ///< Buffer containing the packets to be sent.
-};
-
-typedef struct pcap_send_queue pcap_send_queue;
-
-/*!
- \brief This typedef is a support for the pcap_get_airpcap_handle() function
-*/
-#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
-#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
-typedef struct _AirpcapHandle *PAirpcapHandle;
-#endif
-
-#define BPF_MEM_EX_IMM 0xc0
-#define BPF_MEM_EX_IND 0xe0
-
-/*used for ST*/
-#define BPF_MEM_EX 0xc0
-#define BPF_TME 0x08
-
-#define BPF_LOOKUP 0x90
-#define BPF_EXECUTE 0xa0
-#define BPF_INIT 0xb0
-#define BPF_VALIDATE 0xc0
-#define BPF_SET_ACTIVE 0xd0
-#define BPF_RESET 0xe0
-#define BPF_SET_MEMORY 0x80
-#define BPF_GET_REGISTER_VALUE 0x70
-#define BPF_SET_REGISTER_VALUE 0x60
-#define BPF_SET_WORKING 0x50
-#define BPF_SET_ACTIVE_READ 0x40
-#define BPF_SET_AUTODELETION 0x30
-#define BPF_SEPARATION 0xff
-
-/* Prototypes */
-pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);
-
-void pcap_sendqueue_destroy(pcap_send_queue* queue);
-
-int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);
-
-u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync);
-
-HANDLE pcap_getevent(pcap_t *p);
-
-struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size);
-
-int pcap_setuserbuffer(pcap_t *p, int size);
-
-int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks);
-
-int pcap_live_dump_ended(pcap_t *p, int sync);
-
-int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data);
-
-int pcap_start_oem(char* err_str, int flags);
-
-PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__WIN32_EXTENSIONS_H__
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/arch.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/arch.c
deleted file mode 100644
index d704da800..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/arch.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/* WinPCap includes. */
-#include "pcap.h"
-#include "remote-ext.h"
-
-/* uIP includes. */
-#include "net/uip.h"
-#include "net/uip_arp.h"
-#include "net/clock-arch.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-/*
- * Query the computer the simulation is being executed on to find the network
- * interfaces it has installed.
- */
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
-
-/*
- * Open the network interface. The number of the interface to be opened is set
- * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- */
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
-
-/*
- * Configure the capture filter to allow blocking reads, and to filter out
- * packets that are not of interest to this demo.
- */
-static void prvConfigureCaptureBehaviour( void );
-
-pcap_t *pxOpenedInterfaceHandle = NULL;
-LARGE_INTEGER freq, sys_start_time;
-
-#define archNUM_BUFFERS 5
-#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 )
-
-static void prvInterruptSimulator( void *pvParameters );
-
-static unsigned char ucEthernetBuffer[ archNUM_BUFFERS ][ UIP_CONF_BUFFER_SIZE ];
-static unsigned char *pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ];
-
-static long lLengthOfDataInBuffer[ archNUM_BUFFER_POINTERS ] = { 0 };
-static unsigned char ucNextBufferToFill = 0U, ucNextBufferToProcess = 0U;
-
-unsigned char *uip_buf = NULL;
-char cErrorBuffer[PCAP_ERRBUF_SIZE];
-
-void vNetifTx( void )
-{
- pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len );
- pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len );
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxNetifRx( void )
-{
-UBaseType_t xDataLen;
-unsigned char *pucTemp;
-
- /* Check there is really data available. */
- xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ];
- if( xDataLen != 0L )
- {
-
- /* The buffer pointed to by uip_buf is going to change. Remember which
- buffer uip_buf is currently pointing to. */
- pucTemp = uip_buf;
-
- /* Point uip_buf at the next buffer that contains data. */
- uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ];
-
- /* The buffer pointed to by
- pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by
- uip_buf, but the buffer uip_buf was pointing to on entry to this
- function is free. Set
- pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free
- buffer. */
- pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp;
- lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L;
-
- ucNextBufferToProcess++;
- if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS )
- {
- ucNextBufferToProcess = 0L;
- }
- }
-
- return xDataLen;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetifInit( void )
-{
-BaseType_t x;
-pcap_if_t *pxAllNetworkInterfaces;
-
- /* Allocate a free buffer to each buffer pointer. */
- for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ )
- {
- pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] );
- }
-
- /* Start with uip_buf pointing to a buffer that is not referenced from the
- pucEthernetBufferPointers[] array. */
- uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] );
-
- /* Query the computer the simulation is being executed on to find the
- network interfaces it has installed. */
- pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
-
- /* Open the network interface. The number of the interface to be opened is
- set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- Calling this function will set the pxOpenedInterfaceHandle variable. If,
- after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
- the interface could not be opened. */
- if( pxAllNetworkInterfaces != NULL )
- {
- prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
- }
-
-
- return x;
-}
-/*-----------------------------------------------------------*/
-
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
-{
-pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
-long lInterfaceNumber = 1;
-
- if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
- {
- printf( "\r\nCould not obtain a list of network interfaces\r\n%s\r\n", cErrorBuffer );
- pxAllNetworkInterfaces = NULL;
- }
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Print out the list of network interfaces. The first in the list
- is interface '1', not interface '0'. */
- for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
- {
- printf( "%d. %s", lInterfaceNumber, xInterface->name );
-
- if( xInterface->description != NULL )
- {
- printf( " (%s)\r\n", xInterface->description );
- }
- else
- {
- printf( " (No description available)\r\n") ;
- }
-
- lInterfaceNumber++;
- }
- }
-
- if( lInterfaceNumber == 1 )
- {
- /* The interface number was never incremented, so the above for() loop
- did not execute meaning no interfaces were found. */
- printf( " \r\nNo network interfaces were found.\r\n" );
- pxAllNetworkInterfaces = NULL;
- }
-
- printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" );
- printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE );
-
- if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) )
- {
- printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" );
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Free the device list, as no devices are going to be opened. */
- pcap_freealldevs( pxAllNetworkInterfaces );
- pxAllNetworkInterfaces = NULL;
- }
- }
-
- return pxAllNetworkInterfaces;
-}
-/*-----------------------------------------------------------*/
-
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
-{
-pcap_if_t *xInterface;
-long x;
-
- /* Walk the list of devices until the selected device is located. */
- xInterface = pxAllNetworkInterfaces;
- for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ )
- {
- xInterface = xInterface->next;
- }
-
- /* Open the selected interface. */
- pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */
- UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */
- PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and
- IP address is going to be "simulated", and
- not be the real MAC and IP address. This allows
- trafic to the simulated IP address to be routed
- to uIP, and trafic to the real IP address to be
- routed to the Windows TCP/IP stack. */
- 0xfffffffL, /* The read time out. This is going to block
- until data is available. */
- NULL, /* No authentication is required as this is
- not a remote capture session. */
- cErrorBuffer
- );
-
- if ( pxOpenedInterfaceHandle == NULL )
- {
- printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name );
- }
- else
- {
- /* Configure the capture filter to allow blocking reads, and to filter
- out packets that are not of interest to this demo. */
- prvConfigureCaptureBehaviour();
- }
-
- /* The device list is no longer required. */
- pcap_freealldevs( pxAllNetworkInterfaces );
-}
-/*-----------------------------------------------------------*/
-
-static void prvConfigureCaptureBehaviour( void )
-{
-struct bpf_program xFilterCode;
-const long lMinBytesToCopy = 10L, lBlocking = 0L;
-unsigned long ulNetMask;
-
- /* Unblock a read as soon as anything is received. */
- pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy );
-
- /* Allow blocking. */
- pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer );
-
- /* Set up a filter so only the packets of interest are passed to the uIP
- stack. cErrorBuffer is used for convenience to create the string. Don't
- confuse this with an error message. */
- sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
-
- ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
-
- if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
- {
- printf("\r\nThe packet filter string is invalid\r\n" );
- }
- else
- {
- if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
- {
- printf( "\r\nAn error occurred setting the packet filter.\r\n" );
- }
- }
-
- /* Create a task that simulates an interrupt in a real system. This will
- block waiting for packets, then send a message to the uIP task when data
- is available. */
- xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL );
-}
-/*-----------------------------------------------------------*/
-
-static void prvInterruptSimulator( void *pvParameters )
-{
-static struct pcap_pkthdr *pxHeader;
-const unsigned char *pucPacketData;
-extern QueueHandle_t xEMACEventQueue;
-const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;
-long lResult;
-
- /* Just to kill the compiler warning. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- /* Get the next packet. */
- lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData );
- if( lResult )
- {
- /* Is the next buffer into which data should be placed free? */
- if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L )
- {
- /* Copy the data from the captured packet into the buffer. */
- memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len );
-
- /* Note the amount of data that was copied. */
- lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len;
-
- /* Move onto the next buffer, wrapping around if necessary. */
- ucNextBufferToFill++;
- if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS )
- {
- ucNextBufferToFill = 0U;
- }
-
- /* Data was received and stored. Send a message to the uIP task
- to let it know. */
- xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY );
- }
- }
- }
-}
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/bittypes.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/bittypes.h
deleted file mode 100644
index f55fcecfd..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/bittypes.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project 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 PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef _BITTYPES_H
-#define _BITTYPES_H
-
-#ifndef HAVE_U_INT8_T
-
-#if SIZEOF_CHAR == 1
-typedef unsigned char u_int8_t;
-typedef signed char _int8_t;
-#elif SIZEOF_INT == 1
-typedef unsigned int u_int8_t;
-typedef signed int int8_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int8_t"
-#endif
-#define HAVE_U_INT8_T 1
-#define HAVE_INT8_T 1
-
-#endif /* HAVE_U_INT8_T */
-
-#ifndef HAVE_U_INT16_T
-
-#if SIZEOF_SHORT == 2
-typedef unsigned short u_int16_t;
-typedef signed short _int16_t;
-#elif SIZEOF_INT == 2
-typedef unsigned int u_int16_t;
-typedef signed int int16_t;
-#elif SIZEOF_CHAR == 2
-typedef unsigned char u_int16_t;
-typedef signed char int16_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int16_t"
-#endif
-#define HAVE_U_INT16_T 1
-#define HAVE_INT16_T 1
-
-#endif /* HAVE_U_INT16_T */
-
-#ifndef HAVE_U_INT32_T
-
-#if SIZEOF_INT == 4
-typedef unsigned int u_int32_t;
-typedef signed int _int32_t;
-#elif SIZEOF_LONG == 4
-typedef unsigned long u_int32_t;
-typedef signed long int32_t;
-#elif SIZEOF_SHORT == 4
-typedef unsigned short u_int32_t;
-typedef signed short int32_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int32_t"
-#endif
-#define HAVE_U_INT32_T 1
-#define HAVE_INT32_T 1
-
-#endif /* HAVE_U_INT32_T */
-
-#ifndef HAVE_U_INT64_T
-#if SIZEOF_LONG_LONG == 8
-typedef unsigned long long u_int64_t;
-typedef long long int64_t;
-#elif defined(_MSC_EXTENSIONS)
-typedef unsigned _int64 u_int64_t;
-typedef _int64 int64_t;
-#elif SIZEOF_INT == 8
-typedef unsigned int u_int64_t;
-#elif SIZEOF_LONG == 8
-typedef unsigned long u_int64_t;
-#elif SIZEOF_SHORT == 8
-typedef unsigned short u_int64_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int64_t"
-#endif
-
-#endif /* HAVE_U_INT64_T */
-
-#ifndef PRId64
-#ifdef _MSC_EXTENSIONS
-#define PRId64 "I64d"
-#else /* _MSC_EXTENSIONS */
-#define PRId64 "lld"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRId64 */
-
-#ifndef PRIo64
-#ifdef _MSC_EXTENSIONS
-#define PRIo64 "I64o"
-#else /* _MSC_EXTENSIONS */
-#define PRIo64 "llo"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRIo64 */
-
-#ifndef PRIx64
-#ifdef _MSC_EXTENSIONS
-#define PRIx64 "I64x"
-#else /* _MSC_EXTENSIONS */
-#define PRIx64 "llx"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRIx64 */
-
-#ifndef PRIu64
-#ifdef _MSC_EXTENSIONS
-#define PRIu64 "I64u"
-#else /* _MSC_EXTENSIONS */
-#define PRIu64 "llu"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRIu64 */
-
-#endif /* _BITTYPES_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/ip6_misc.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/ip6_misc.h
deleted file mode 100644
index 562fa6184..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/ip6_misc.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/Win32/Include/ip6_misc.h,v 1.5 2006-01-22 18:02:18 gianluca Exp $ (LBL)
- */
-
-/*
- * This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows
- */
-
-#include <winsock2.h>
-
-#include <ws2tcpip.h>
-
-#ifndef __MINGW32__
-#define IN_MULTICAST(a) IN_CLASSD(a)
-#endif
-
-#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000)
-
-#define IN_LOOPBACKNET 127
-
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
-/* IPv6 address */
-struct in6_addr
- {
- union
- {
- u_int8_t u6_addr8[16];
- u_int16_t u6_addr16[8];
- u_int32_t u6_addr32[4];
- } in6_u;
-#define s6_addr in6_u.u6_addr8
-#define s6_addr16 in6_u.u6_addr16
-#define s6_addr32 in6_u.u6_addr32
-#define s6_addr64 in6_u.u6_addr64
- };
-
-#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
-#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
-#endif /* __MINGW32__ */
-
-
-#if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF))
-typedef unsigned short sa_family_t;
-#endif
-
-
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
-
-#define __SOCKADDR_COMMON(sa_prefix) \
- sa_family_t sa_prefix##family
-
-/* Ditto, for IPv6. */
-struct sockaddr_in6
- {
- __SOCKADDR_COMMON (sin6_);
- u_int16_t sin6_port; /* Transport layer port # */
- u_int32_t sin6_flowinfo; /* IPv6 flow information */
- struct in6_addr sin6_addr; /* IPv6 address */
- };
-
-#define IN6_IS_ADDR_V4MAPPED(a) \
- ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
- (((u_int32_t *) (a))[2] == htonl (0xffff)))
-
-#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff)
-
-#define IN6_IS_ADDR_LINKLOCAL(a) \
- ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000))
-
-#define IN6_IS_ADDR_LOOPBACK(a) \
- (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
- ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
-#endif /* __MINGW32__ */
-
-#define ip6_vfc ip6_ctlun.ip6_un2_vfc
-#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
-#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
-#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
-#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
-#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
-
-#define nd_rd_type nd_rd_hdr.icmp6_type
-#define nd_rd_code nd_rd_hdr.icmp6_code
-#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
-#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
-
-/*
- * IPV6 extension headers
- */
-#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
-#define IPPROTO_IPV6 41 /* IPv6 header. */
-#define IPPROTO_ROUTING 43 /* IPv6 routing header */
-#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
-#define IPPROTO_ESP 50 /* encapsulating security payload */
-#define IPPROTO_AH 51 /* authentication header */
-#define IPPROTO_ICMPV6 58 /* ICMPv6 */
-#define IPPROTO_NONE 59 /* IPv6 no next header */
-#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
-#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */
-
-#define IPV6_RTHDR_TYPE_0 0
-
-/* Option types and related macros */
-#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
-#define IP6OPT_PADN 0x01 /* 00 0 00001 */
-#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
-#define IP6OPT_JUMBO_LEN 6
-#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */
-
-#define IP6OPT_RTALERT_LEN 4
-#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
-#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
-#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
-#define IP6OPT_MINLEN 2
-
-#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
-#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
-#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
-#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
-#define IP6OPT_EID 0x8a /* 10 0 01010 */
-
-#define IP6OPT_TYPE(o) ((o) & 0xC0)
-#define IP6OPT_TYPE_SKIP 0x00
-#define IP6OPT_TYPE_DISCARD 0x40
-#define IP6OPT_TYPE_FORCEICMP 0x80
-#define IP6OPT_TYPE_ICMP 0xC0
-
-#define IP6OPT_MUTABLE 0x20
-
-
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
-#ifndef EAI_ADDRFAMILY
-struct addrinfo {
- int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
- int ai_family; /* PF_xxx */
- int ai_socktype; /* SOCK_xxx */
- int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
- size_t ai_addrlen; /* length of ai_addr */
- char *ai_canonname; /* canonical name for hostname */
- struct sockaddr *ai_addr; /* binary address */
- struct addrinfo *ai_next; /* next structure in linked list */
-};
-#endif
-#endif /* __MINGW32__ */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/netif.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/netif.h
deleted file mode 100644
index 8fe539376..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/netif.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef NET_IF_H
-#define NET_IF_H
-
-/*
- * Send uip_len bytes from uip_buf to the network interface selected by the
- * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h).
- */
-void vNetifTx( void );
-
-/*
- * Receive bytes from the network interface selected by the
- * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). The
- * bytes are placed in uip_buf. The number of bytes copied into uip_buf is
- * returned.
- */
-UBaseType_t uxNetifRx( void );
-
-/*
- * Prepare a packet capture session. This will print out all the network
- * interfaces available, and the one actually used is set by the
- * configNETWORK_INTERFACE_TO_USE constant that is defined in
- * FreeRTOSConfig.h. */
-BaseType_t xNetifInit( void );
-
-#endif /* NET_IF_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-bpf.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-bpf.h
deleted file mode 100644
index 5fe129dbb..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-bpf.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.50 2007/04/01 21:43:55 guy Exp $ (LBL)
- */
-
-/*
- * For backwards compatibility.
- *
- * Note to OS vendors: do NOT get rid of this file! Some applications
- * might expect to be able to include <pcap-bpf.h>.
- */
-#include <pcap/bpf.h>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-namedb.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-namedb.h
deleted file mode 100644
index 80a2f0040..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-namedb.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1994, 1996
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006/10/04 18:13:32 guy Exp $ (LBL)
- */
-
-/*
- * For backwards compatibility.
- *
- * Note to OS vendors: do NOT get rid of this file! Some applications
- * might expect to be able to include <pcap-namedb.h>.
- */
-#include <pcap/namedb.h>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-stdinc.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-stdinc.h
deleted file mode 100644
index cbd62d169..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap-stdinc.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL)
- */
-
-#define SIZEOF_CHAR 1
-#define SIZEOF_SHORT 2
-#define SIZEOF_INT 4
-#ifndef _MSC_EXTENSIONS
-#define SIZEOF_LONG_LONG 8
-#endif
-
-/*
- * Avoids a compiler warning in case this was already defined
- * (someone defined _WINSOCKAPI_ when including 'windows.h', in order
- * to prevent it from including 'winsock.h')
- */
-#ifdef _WINSOCKAPI_
-#undef _WINSOCKAPI_
-#endif
-#include <winsock2.h>
-
-#include <fcntl.h>
-
-#include "bittypes.h"
-#include <time.h>
-#include <io.h>
-
-#ifndef __MINGW32__
-#include "IP6_misc.h"
-#endif
-
-#define caddr_t char*
-
-#if _MSC_VER < 1500
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define strdup _strdup
-#endif
-
-#define inline __inline
-
-#ifdef __MINGW32__
-#include <stdint.h>
-#else /*__MINGW32__*/
-/* MSVC compiler */
-#ifndef _UINTPTR_T_DEFINED
-#ifdef _WIN64
-typedef unsigned __int64 uintptr_t;
-#else
-typedef _W64 unsigned int uintptr_t;
-#endif
-#define _UINTPTR_T_DEFINED
-#endif
-
-#ifndef _INTPTR_T_DEFINED
-#ifdef _WIN64
-typedef __int64 intptr_t;
-#else
-typedef _W64 int intptr_t;
-#endif
-#define _INTPTR_T_DEFINED
-#endif
-
-#endif /*__MINGW32__*/
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap.h
deleted file mode 100644
index 935f9494c..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006/10/04 18:09:22 guy Exp $ (LBL)
- */
-
-/*
- * For backwards compatibility.
- *
- * Note to OS vendors: do NOT get rid of this file! Many applications
- * expect to be able to include <pcap.h>, and at least some of them
- * go through contortions in their configure scripts to try to detect
- * OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
- * leaving behind a <pcap.h> file.
- */
-#include <pcap/pcap.h>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bluetooth.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bluetooth.h
deleted file mode 100644
index 7bf65df03..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bluetooth.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2006 Paolo Abeni (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- * bluetooth data struct
- * By Paolo Abeni <paolo.abeni@email.it>
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $
- */
-
-#ifndef _PCAP_BLUETOOTH_STRUCTS_H__
-#define _PCAP_BLUETOOTH_STRUCTS_H__
-
-/*
- * Header prepended libpcap to each bluetooth h:4 frame.
- * fields are in network byte order
- */
-typedef struct _pcap_bluetooth_h4_header {
- u_int32_t direction; /* if first bit is set direction is incoming */
-} pcap_bluetooth_h4_header;
-
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bpf.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bpf.h
deleted file mode 100644
index 9f4ca33e3..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/bpf.h
+++ /dev/null
@@ -1,934 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)bpf.h 7.1 (Berkeley) 5/7/91
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.19.2.8 2008-09-22 20:16:01 guy Exp $ (LBL)
- */
-
-/*
- * This is libpcap's cut-down version of bpf.h; it includes only
- * the stuff needed for the code generator and the userland BPF
- * interpreter, and the libpcap APIs for setting filters, etc..
- *
- * "pcap-bpf.c" will include the native OS version, as it deals with
- * the OS's BPF implementation.
- *
- * XXX - should this all just be moved to "pcap.h"?
- */
-
-#ifndef BPF_MAJOR_VERSION
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* BSD style release date */
-#define BPF_RELEASE 199606
-
-#ifdef MSDOS /* must be 32-bit */
-typedef long bpf_int32;
-typedef unsigned long bpf_u_int32;
-#else
-typedef int bpf_int32;
-typedef u_int bpf_u_int32;
-#endif
-
-/*
- * Alignment macros. BPF_WORDALIGN rounds up to the next
- * even multiple of BPF_ALIGNMENT.
- */
-#ifndef __NetBSD__
-#define BPF_ALIGNMENT sizeof(bpf_int32)
-#else
-#define BPF_ALIGNMENT sizeof(long)
-#endif
-#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
-
-#define BPF_MAXBUFSIZE 0x8000
-#define BPF_MINBUFSIZE 32
-
-/*
- * Structure for "pcap_compile()", "pcap_setfilter()", etc..
- */
-struct bpf_program {
- u_int bf_len;
- struct bpf_insn *bf_insns;
-};
-
-/*
- * Struct return by BIOCVERSION. This represents the version number of
- * the filter language described by the instruction encodings below.
- * bpf understands a program iff kernel_major == filter_major &&
- * kernel_minor >= filter_minor, that is, if the value returned by the
- * running kernel has the same major number and a minor number equal
- * equal to or less than the filter being downloaded. Otherwise, the
- * results are undefined, meaning an error may be returned or packets
- * may be accepted haphazardly.
- * It has nothing to do with the source code version.
- */
-struct bpf_version {
- u_short bv_major;
- u_short bv_minor;
-};
-/* Current version number of filter architecture. */
-#define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
-
-/*
- * Data-link level type codes.
- *
- * Do *NOT* add new values to this list without asking
- * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run
- * the risk of using a value that's already being used for some other
- * purpose, and of having tools that read libpcap-format captures not
- * being able to handle captures with your new DLT_ value, with no hope
- * that they will ever be changed to do so (as that would destroy their
- * ability to read captures using that value for that other purpose).
- */
-
-/*
- * These are the types that are the same on all platforms, and that
- * have been defined by <net/bpf.h> for ages.
- */
-#define DLT_NULL 0 /* BSD loopback encapsulation */
-#define DLT_EN10MB 1 /* Ethernet (10Mb) */
-#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
-#define DLT_AX25 3 /* Amateur Radio AX.25 */
-#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
-#define DLT_CHAOS 5 /* Chaos */
-#define DLT_IEEE802 6 /* 802.5 Token Ring */
-#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
-#define DLT_SLIP 8 /* Serial Line IP */
-#define DLT_PPP 9 /* Point-to-point Protocol */
-#define DLT_FDDI 10 /* FDDI */
-
-/*
- * These are types that are different on some platforms, and that
- * have been defined by <net/bpf.h> for ages. We use #ifdefs to
- * detect the BSDs that define them differently from the traditional
- * libpcap <net/bpf.h>
- *
- * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
- * but I don't know what the right #define is for BSD/OS.
- */
-#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */
-
-#ifdef __OpenBSD__
-#define DLT_RAW 14 /* raw IP */
-#else
-#define DLT_RAW 12 /* raw IP */
-#endif
-
-/*
- * Given that the only OS that currently generates BSD/OS SLIP or PPP
- * is, well, BSD/OS, arguably everybody should have chosen its values
- * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they
- * didn't. So it goes.
- */
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#ifndef DLT_SLIP_BSDOS
-#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
-#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
-#endif
-#else
-#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
-#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
-#endif
-
-/*
- * 17 is used for DLT_OLD_PFLOG in OpenBSD;
- * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
- * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
- */
-
-#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
-
-/*
- * Apparently Redback uses this for its SmartEdge 400/800. I hope
- * nobody else decided to use it, too.
- */
-#define DLT_REDBACK_SMARTEDGE 32
-
-/*
- * These values are defined by NetBSD; other platforms should refrain from
- * using them for other purposes, so that NetBSD savefiles with link
- * types of 50 or 51 can be read as this type on all platforms.
- */
-#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
-#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
-
-/*
- * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses
- * a link-layer type of 99 for the tcpdump it supplies. The link-layer
- * header has 6 bytes of unknown data, something that appears to be an
- * Ethernet type, and 36 bytes that appear to be 0 in at least one capture
- * I've seen.
- */
-#define DLT_SYMANTEC_FIREWALL 99
-
-/*
- * Values between 100 and 103 are used in capture file headers as
- * link-layer types corresponding to DLT_ types that differ
- * between platforms; don't use those values for new DLT_ new types.
- */
-
-/*
- * This value was defined by libpcap 0.5; platforms that have defined
- * it with a different value should define it here with that value -
- * a link type of 104 in a save file will be mapped to DLT_C_HDLC,
- * whatever value that happens to be, so programs will correctly
- * handle files with that link type regardless of the value of
- * DLT_C_HDLC.
- *
- * The name DLT_C_HDLC was used by BSD/OS; we use that name for source
- * compatibility with programs written for BSD/OS.
- *
- * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
- * for source compatibility with programs written for libpcap 0.5.
- */
-#define DLT_C_HDLC 104 /* Cisco HDLC */
-#define DLT_CHDLC DLT_C_HDLC
-
-#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
-
-/*
- * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
- * except when it isn't. (I.e., sometimes it's just raw IP, and
- * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
- * so that we don't have to worry about the link-layer header.)
- */
-
-/*
- * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
- * with other values.
- * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
- * (DLCI, etc.).
- */
-#define DLT_FRELAY 107
-
-/*
- * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
- * that the AF_ type in the link-layer header is in network byte order.
- *
- * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so
- * we don't use 12 for it in OSes other than OpenBSD.
- */
-#ifdef __OpenBSD__
-#define DLT_LOOP 12
-#else
-#define DLT_LOOP 108
-#endif
-
-/*
- * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
- * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
- * than OpenBSD.
- */
-#ifdef __OpenBSD__
-#define DLT_ENC 13
-#else
-#define DLT_ENC 109
-#endif
-
-/*
- * Values between 110 and 112 are reserved for use in capture file headers
- * as link-layer types corresponding to DLT_ types that might differ
- * between platforms; don't use those values for new DLT_ types
- * other than the corresponding DLT_ types.
- */
-
-/*
- * This is for Linux cooked sockets.
- */
-#define DLT_LINUX_SLL 113
-
-/*
- * Apple LocalTalk hardware.
- */
-#define DLT_LTALK 114
-
-/*
- * Acorn Econet.
- */
-#define DLT_ECONET 115
-
-/*
- * Reserved for use with OpenBSD ipfilter.
- */
-#define DLT_IPFILTER 116
-
-/*
- * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
- * in SuSE 6.3, so we can't use 17 for it in capture-file headers.
- *
- * XXX: is there a conflict with DLT_PFSYNC 18 as well?
- */
-#ifdef __OpenBSD__
-#define DLT_OLD_PFLOG 17
-#define DLT_PFSYNC 18
-#endif
-#define DLT_PFLOG 117
-
-/*
- * Registered for Cisco-internal use.
- */
-#define DLT_CISCO_IOS 118
-
-/*
- * For 802.11 cards using the Prism II chips, with a link-layer
- * header including Prism monitor mode information plus an 802.11
- * header.
- */
-#define DLT_PRISM_HEADER 119
-
-/*
- * Reserved for Aironet 802.11 cards, with an Aironet link-layer header
- * (see Doug Ambrisko's FreeBSD patches).
- */
-#define DLT_AIRONET_HEADER 120
-
-/*
- * Reserved for Siemens HiPath HDLC.
- */
-#define DLT_HHDLC 121
-
-/*
- * This is for RFC 2625 IP-over-Fibre Channel.
- *
- * This is not for use with raw Fibre Channel, where the link-layer
- * header starts with a Fibre Channel frame header; it's for IP-over-FC,
- * where the link-layer header starts with an RFC 2625 Network_Header
- * field.
- */
-#define DLT_IP_OVER_FC 122
-
-/*
- * This is for Full Frontal ATM on Solaris with SunATM, with a
- * pseudo-header followed by an AALn PDU.
- *
- * There may be other forms of Full Frontal ATM on other OSes,
- * with different pseudo-headers.
- *
- * If ATM software returns a pseudo-header with VPI/VCI information
- * (and, ideally, packet type information, e.g. signalling, ILMI,
- * LANE, LLC-multiplexed traffic, etc.), it should not use
- * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
- * and the like don't have to infer the presence or absence of a
- * pseudo-header and the form of the pseudo-header.
- */
-#define DLT_SUNATM 123 /* Solaris+SunATM */
-
-/*
- * Reserved as per request from Kent Dahlgren <kent@praesum.com>
- * for private use.
- */
-#define DLT_RIO 124 /* RapidIO */
-#define DLT_PCI_EXP 125 /* PCI Express */
-#define DLT_AURORA 126 /* Xilinx Aurora link layer */
-
-/*
- * Header for 802.11 plus a number of bits of link-layer information
- * including radio information, used by some recent BSD drivers as
- * well as the madwifi Atheros driver for Linux.
- */
-#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */
-
-/*
- * Reserved for the TZSP encapsulation, as per request from
- * Chris Waters <chris.waters@networkchemistry.com>
- * TZSP is a generic encapsulation for any other link type,
- * which includes a means to include meta-information
- * with the packet, e.g. signal strength and channel
- * for 802.11 packets.
- */
-#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
-
-/*
- * BSD's ARCNET headers have the source host, destination host,
- * and type at the beginning of the packet; that's what's handed
- * up to userland via BPF.
- *
- * Linux's ARCNET headers, however, have a 2-byte offset field
- * between the host IDs and the type; that's what's handed up
- * to userland via PF_PACKET sockets.
- *
- * We therefore have to have separate DLT_ values for them.
- */
-#define DLT_ARCNET_LINUX 129 /* ARCNET */
-
-/*
- * Juniper-private data link types, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
- * for passing on chassis-internal metainformation such as
- * QOS profiles, etc..
- */
-#define DLT_JUNIPER_MLPPP 130
-#define DLT_JUNIPER_MLFR 131
-#define DLT_JUNIPER_ES 132
-#define DLT_JUNIPER_GGSN 133
-#define DLT_JUNIPER_MFR 134
-#define DLT_JUNIPER_ATM2 135
-#define DLT_JUNIPER_SERVICES 136
-#define DLT_JUNIPER_ATM1 137
-
-/*
- * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund
- * <dieter@apple.com>. The header that's presented is an Ethernet-like
- * header:
- *
- * #define FIREWIRE_EUI64_LEN 8
- * struct firewire_header {
- * u_char firewire_dhost[FIREWIRE_EUI64_LEN];
- * u_char firewire_shost[FIREWIRE_EUI64_LEN];
- * u_short firewire_type;
- * };
- *
- * with "firewire_type" being an Ethernet type value, rather than,
- * for example, raw GASP frames being handed up.
- */
-#define DLT_APPLE_IP_OVER_IEEE1394 138
-
-/*
- * Various SS7 encapsulations, as per a request from Jeff Morriss
- * <jeff.morriss[AT]ulticom.com> and subsequent discussions.
- */
-#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */
-#define DLT_MTP2 140 /* MTP2, without pseudo-header */
-#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */
-#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */
-
-/*
- * DOCSIS MAC frames.
- */
-#define DLT_DOCSIS 143
-
-/*
- * Linux-IrDA packets. Protocol defined at http://www.irda.org.
- * Those packets include IrLAP headers and above (IrLMP...), but
- * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy
- * framing can be handled by the hardware and depend on the bitrate.
- * This is exactly the format you would get capturing on a Linux-IrDA
- * interface (irdaX), but not on a raw serial port.
- * Note the capture is done in "Linux-cooked" mode, so each packet include
- * a fake packet header (struct sll_header). This is because IrDA packet
- * decoding is dependant on the direction of the packet (incomming or
- * outgoing).
- * When/if other platform implement IrDA capture, we may revisit the
- * issue and define a real DLT_IRDA...
- * Jean II
- */
-#define DLT_LINUX_IRDA 144
-
-/*
- * Reserved for IBM SP switch and IBM Next Federation switch.
- */
-#define DLT_IBM_SP 145
-#define DLT_IBM_SN 146
-
-/*
- * Reserved for private use. If you have some link-layer header type
- * that you want to use within your organization, with the capture files
- * using that link-layer header type not ever be sent outside your
- * organization, you can use these values.
- *
- * No libpcap release will use these for any purpose, nor will any
- * tcpdump release use them, either.
- *
- * Do *NOT* use these in capture files that you expect anybody not using
- * your private versions of capture-file-reading tools to read; in
- * particular, do *NOT* use them in products, otherwise you may find that
- * people won't be able to use tcpdump, or snort, or Ethereal, or... to
- * read capture files from your firewall/intrusion detection/traffic
- * monitoring/etc. appliance, or whatever product uses that DLT_ value,
- * and you may also find that the developers of those applications will
- * not accept patches to let them read those files.
- *
- * Also, do not use them if somebody might send you a capture using them
- * for *their* private type and tools using them for *your* private type
- * would have to read them.
- *
- * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value,
- * as per the comment above, and use the type you're given.
- */
-#define DLT_USER0 147
-#define DLT_USER1 148
-#define DLT_USER2 149
-#define DLT_USER3 150
-#define DLT_USER4 151
-#define DLT_USER5 152
-#define DLT_USER6 153
-#define DLT_USER7 154
-#define DLT_USER8 155
-#define DLT_USER9 156
-#define DLT_USER10 157
-#define DLT_USER11 158
-#define DLT_USER12 159
-#define DLT_USER13 160
-#define DLT_USER14 161
-#define DLT_USER15 162
-
-/*
- * For future use with 802.11 captures - defined by AbsoluteValue
- * Systems to store a number of bits of link-layer information
- * including radio information:
- *
- * http://www.shaftnet.org/~pizza/software/capturefrm.txt
- *
- * but it might be used by some non-AVS drivers now or in the
- * future.
- */
-#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
- * for passing on chassis-internal metainformation such as
- * QOS profiles, etc..
- */
-#define DLT_JUNIPER_MONITOR 164
-
-/*
- * Reserved for BACnet MS/TP.
- */
-#define DLT_BACNET_MS_TP 165
-
-/*
- * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
- *
- * This is used in some OSes to allow a kernel socket filter to distinguish
- * between incoming and outgoing packets, on a socket intended to
- * supply pppd with outgoing packets so it can do dial-on-demand and
- * hangup-on-lack-of-demand; incoming packets are filtered out so they
- * don't cause pppd to hold the connection up (you don't want random
- * input packets such as port scans, packets from old lost connections,
- * etc. to force the connection to stay up).
- *
- * The first byte of the PPP header (0xff03) is modified to accomodate
- * the direction - 0x00 = IN, 0x01 = OUT.
- */
-#define DLT_PPP_PPPD 166
-
-/*
- * Names for backwards compatibility with older versions of some PPP
- * software; new software should use DLT_PPP_PPPD.
- */
-#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD
-#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
- * for passing on chassis-internal metainformation such as
- * QOS profiles, cookies, etc..
- */
-#define DLT_JUNIPER_PPPOE 167
-#define DLT_JUNIPER_PPPOE_ATM 168
-
-#define DLT_GPRS_LLC 169 /* GPRS LLC */
-#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
-#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
-
-/*
- * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
- * monitoring equipment.
- */
-#define DLT_GCOM_T1E1 172
-#define DLT_GCOM_SERIAL 173
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_ is used
- * for internal communication to Physical Interface Cards (PIC)
- */
-#define DLT_JUNIPER_PIC_PEER 174
-
-/*
- * Link types requested by Gregor Maier <gregor@endace.com> of Endace
- * Measurement Systems. They add an ERF header (see
- * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
- * the link-layer header.
- */
-#define DLT_ERF_ETH 175 /* Ethernet */
-#define DLT_ERF_POS 176 /* Packet-over-SONET */
-
-/*
- * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
- * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
- * includes additional information before the LAPD header, so it's
- * not necessarily a generic LAPD header.
- */
-#define DLT_LINUX_LAPD 177
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ are used for prepending meta-information
- * like interface index, interface name
- * before standard Ethernet, PPP, Frelay & C-HDLC Frames
- */
-#define DLT_JUNIPER_ETHER 178
-#define DLT_JUNIPER_PPP 179
-#define DLT_JUNIPER_FRELAY 180
-#define DLT_JUNIPER_CHDLC 181
-
-/*
- * Multi Link Frame Relay (FRF.16)
- */
-#define DLT_MFR 182
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ is used for internal communication with a
- * voice Adapter Card (PIC)
- */
-#define DLT_JUNIPER_VP 183
-
-/*
- * Arinc 429 frames.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- * Every frame contains a 32bit A429 label.
- * More documentation on Arinc 429 can be found at
- * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
- */
-#define DLT_A429 184
-
-/*
- * Arinc 653 Interpartition Communication messages.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- * Please refer to the A653-1 standard for more information.
- */
-#define DLT_A653_ICM 185
-
-/*
- * USB packets, beginning with a USB setup header; requested by
- * Paolo Abeni <paolo.abeni@email.it>.
- */
-#define DLT_USB 186
-
-/*
- * Bluetooth HCI UART transport layer (part H:4); requested by
- * Paolo Abeni.
- */
-#define DLT_BLUETOOTH_HCI_H4 187
-
-/*
- * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
- * <cruz_petagay@bah.com>.
- */
-#define DLT_IEEE802_16_MAC_CPS 188
-
-/*
- * USB packets, beginning with a Linux USB header; requested by
- * Paolo Abeni <paolo.abeni@email.it>.
- */
-#define DLT_USB_LINUX 189
-
-/*
- * Controller Area Network (CAN) v. 2.0B packets.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- * Used to dump CAN packets coming from a CAN Vector board.
- * More documentation on the CAN v2.0B frames can be found at
- * http://www.can-cia.org/downloads/?269
- */
-#define DLT_CAN20B 190
-
-/*
- * IEEE 802.15.4, with address fields padded, as is done by Linux
- * drivers; requested by Juergen Schimmer.
- */
-#define DLT_IEEE802_15_4_LINUX 191
-
-/*
- * Per Packet Information encapsulated packets.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- */
-#define DLT_PPI 192
-
-/*
- * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
- * requested by Charles Clancy.
- */
-#define DLT_IEEE802_16_MAC_CPS_RADIO 193
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ is used for internal communication with a
- * integrated service module (ISM).
- */
-#define DLT_JUNIPER_ISM 194
-
-/*
- * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
- * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
- */
-#define DLT_IEEE802_15_4 195
-
-/*
- * Various link-layer types, with a pseudo-header, for SITA
- * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
- */
-#define DLT_SITA 196
-
-/*
- * Various link-layer types, with a pseudo-header, for Endace DAG cards;
- * encapsulates Endace ERF records. Requested by Stephen Donnelly
- * <stephen@endace.com>.
- */
-#define DLT_ERF 197
-
-/*
- * Special header prepended to Ethernet packets when capturing from a
- * u10 Networks board. Requested by Phil Mulholland
- * <phil@u10networks.com>.
- */
-#define DLT_RAIF1 198
-
-/*
- * IPMB packet for IPMI, beginning with the I2C slave address, followed
- * by the netFn and LUN, etc.. Requested by Chanthy Toeung
- * <chanthy.toeung@ca.kontron.com>.
- */
-#define DLT_IPMB 199
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ is used for capturing data on a secure tunnel interface.
- */
-#define DLT_JUNIPER_ST 200
-
-/*
- * Bluetooth HCI UART transport layer (part H:4), with pseudo-header
- * that includes direction information; requested by Paolo Abeni.
- */
-#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201
-
-/*
- * AX.25 packet with a 1-byte KISS header; see
- *
- * http://www.ax25.net/kiss.htm
- *
- * as per Richard Stearn <richard@rns-stearn.demon.co.uk>.
- */
-#define DLT_AX25_KISS 202
-
-/*
- * LAPD packets from an ISDN channel, starting with the address field,
- * with no pseudo-header.
- * Requested by Varuna De Silva <varunax@gmail.com>.
- */
-#define DLT_LAPD 203
-
-/*
- * Variants of various link-layer headers, with a one-byte direction
- * pseudo-header prepended - zero means "received by this host",
- * non-zero (any non-zero value) means "sent by this host" - as per
- * Will Barker <w.barker@zen.co.uk>.
- */
-#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */
-#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
-#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */
-#define DLT_LAPB_WITH_DIR 207 /* LAPB */
-
-/*
- * 208 is reserved for an as-yet-unspecified proprietary link-layer
- * type, as requested by Will Barker.
- */
-
-/*
- * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
- * <avn@pigeonpoint.com>.
- */
-#define DLT_IPMB_LINUX 209
-
-/*
- * FlexRay automotive bus - http://www.flexray.com/ - as requested
- * by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_FLEXRAY 210
-
-/*
- * Media Oriented Systems Transport (MOST) bus for multimedia
- * transport - http://www.mostcooperation.com/ - as requested
- * by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_MOST 211
-
-/*
- * Local Interconnect Network (LIN) bus for vehicle networks -
- * http://www.lin-subbus.org/ - as requested by Hannes Kaelber
- * <hannes.kaelber@x2e.de>.
- */
-#define DLT_LIN 212
-
-/*
- * X2E-private data link type used for serial line capture,
- * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_X2E_SERIAL 213
-
-/*
- * X2E-private data link type used for the Xoraya data logger
- * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_X2E_XORAYA 214
-
-/*
- * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
- * nothing), but with the PHY-level data for non-ASK PHYs (4 octets
- * of 0 as preamble, one octet of SFD, one octet of frame length+
- * reserved bit, and then the MAC-layer data, starting with the
- * frame control field).
- *
- * Requested by Max Filippov <jcmvbkbc@gmail.com>.
- */
-#define DLT_IEEE802_15_4_NONASK_PHY 215
-
-
-/*
- * DLT and savefile link type values are split into a class and
- * a member of that class. A class value of 0 indicates a regular
- * DLT_/LINKTYPE_ value.
- */
-#define DLT_CLASS(x) ((x) & 0x03ff0000)
-
-/*
- * NetBSD-specific generic "raw" link type. The class value indicates
- * that this is the generic raw type, and the lower 16 bits are the
- * address family we're dealing with. Those values are NetBSD-specific;
- * do not assume that they correspond to AF_ values for your operating
- * system.
- */
-#define DLT_CLASS_NETBSD_RAWAF 0x02240000
-#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af))
-#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff)
-#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF)
-
-
-/*
- * The instruction encodings.
- */
-/* instruction classes */
-#define BPF_CLASS(code) ((code) & 0x07)
-#define BPF_LD 0x00
-#define BPF_LDX 0x01
-#define BPF_ST 0x02
-#define BPF_STX 0x03
-#define BPF_ALU 0x04
-#define BPF_JMP 0x05
-#define BPF_RET 0x06
-#define BPF_MISC 0x07
-
-/* ld/ldx fields */
-#define BPF_SIZE(code) ((code) & 0x18)
-#define BPF_W 0x00
-#define BPF_H 0x08
-#define BPF_B 0x10
-#define BPF_MODE(code) ((code) & 0xe0)
-#define BPF_IMM 0x00
-#define BPF_ABS 0x20
-#define BPF_IND 0x40
-#define BPF_MEM 0x60
-#define BPF_LEN 0x80
-#define BPF_MSH 0xa0
-
-/* alu/jmp fields */
-#define BPF_OP(code) ((code) & 0xf0)
-#define BPF_ADD 0x00
-#define BPF_SUB 0x10
-#define BPF_MUL 0x20
-#define BPF_DIV 0x30
-#define BPF_OR 0x40
-#define BPF_AND 0x50
-#define BPF_LSH 0x60
-#define BPF_RSH 0x70
-#define BPF_NEG 0x80
-#define BPF_JA 0x00
-#define BPF_JEQ 0x10
-#define BPF_JGT 0x20
-#define BPF_JGE 0x30
-#define BPF_JSET 0x40
-#define BPF_SRC(code) ((code) & 0x08)
-#define BPF_K 0x00
-#define BPF_X 0x08
-
-/* ret - BPF_K and BPF_X also apply */
-#define BPF_RVAL(code) ((code) & 0x18)
-#define BPF_A 0x10
-
-/* misc */
-#define BPF_MISCOP(code) ((code) & 0xf8)
-#define BPF_TAX 0x00
-#define BPF_TXA 0x80
-
-/*
- * The instruction data structure.
- */
-struct bpf_insn {
- u_short code;
- u_char jt;
- u_char jf;
- bpf_u_int32 k;
-};
-
-/*
- * Macros for insn array initializers.
- */
-#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
-#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
-
-#if __STDC__ || defined(__cplusplus)
-extern int bpf_validate(const struct bpf_insn *, int);
-extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
-#else
-extern int bpf_validate();
-extern u_int bpf_filter();
-#endif
-
-/*
- * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
- */
-#define BPF_MEMWORDS 16
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/namedb.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/namedb.h
deleted file mode 100644
index 9002c7509..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/namedb.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 1994, 1996
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006/10/04 18:09:22 guy Exp $ (LBL)
- */
-
-#ifndef lib_pcap_namedb_h
-#define lib_pcap_namedb_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * As returned by the pcap_next_etherent()
- * XXX this stuff doesn't belong in this interface, but this
- * library already must do name to address translation, so
- * on systems that don't have support for /etc/ethers, we
- * export these hooks since they'll
- */
-struct pcap_etherent {
- u_char addr[6];
- char name[122];
-};
-#ifndef PCAP_ETHERS_FILE
-#define PCAP_ETHERS_FILE "/etc/ethers"
-#endif
-struct pcap_etherent *pcap_next_etherent(FILE *);
-u_char *pcap_ether_hostton(const char*);
-u_char *pcap_ether_aton(const char *);
-
-bpf_u_int32 **pcap_nametoaddr(const char *);
-#ifdef INET6
-struct addrinfo *pcap_nametoaddrinfo(const char *);
-#endif
-bpf_u_int32 pcap_nametonetaddr(const char *);
-
-int pcap_nametoport(const char *, int *, int *);
-int pcap_nametoportrange(const char *, int *, int *, int *);
-int pcap_nametoproto(const char *);
-int pcap_nametoeproto(const char *);
-int pcap_nametollc(const char *);
-/*
- * If a protocol is unknown, PROTO_UNDEF is returned.
- * Also, pcap_nametoport() returns the protocol along with the port number.
- * If there are ambiguous entried in /etc/services (i.e. domain
- * can be either tcp or udp) PROTO_UNDEF is returned.
- */
-#define PROTO_UNDEF -1
-
-/* XXX move these to pcap-int.h? */
-int __pcap_atodn(const char *, bpf_u_int32 *);
-int __pcap_atoin(const char *, bpf_u_int32 *);
-u_short __pcap_nametodnaddr(const char *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/pcap.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/pcap.h
deleted file mode 100644
index ad8fc40ac..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/pcap.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
-/*
- * Copyright (c) 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL)
- */
-
-#ifndef lib_pcap_pcap_h
-#define lib_pcap_pcap_h
-
-#if defined(WIN32)
- #include <pcap-stdinc.h>
-#elif defined(MSDOS)
- #include <sys/types.h>
- #include <sys/socket.h> /* u_int, u_char etc. */
-#else /* UN*X */
- #include <sys/types.h>
- #include <sys/time.h>
-#endif /* WIN32/MSDOS/UN*X */
-
-#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
-#include <pcap/bpf.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef HAVE_REMOTE
- // We have to define the SOCKET here, although it has been defined in sockutils.h
- // This is to avoid the distribution of the 'sockutils.h' file around
- // (for example in the WinPcap developer's pack)
- #ifndef SOCKET
- #ifdef WIN32
- #define SOCKET unsigned int
- #else
- #define SOCKET int
- #endif
- #endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PCAP_VERSION_MAJOR 2
-#define PCAP_VERSION_MINOR 4
-
-#define PCAP_ERRBUF_SIZE 256
-
-/*
- * Compatibility for systems that have a bpf.h that
- * predates the bpf typedefs for 64-bit support.
- */
-#if BPF_RELEASE - 0 < 199406
-typedef int bpf_int32;
-typedef u_int bpf_u_int32;
-#endif
-
-typedef struct pcap pcap_t;
-typedef struct pcap_dumper pcap_dumper_t;
-typedef struct pcap_if pcap_if_t;
-typedef struct pcap_addr pcap_addr_t;
-
-/*
- * The first record in the file contains saved values for some
- * of the flags used in the printout phases of tcpdump.
- * Many fields here are 32 bit ints so compilers won't insert unwanted
- * padding; these files need to be interchangeable across architectures.
- *
- * Do not change the layout of this structure, in any way (this includes
- * changes that only affect the length of fields in this structure).
- *
- * Also, do not change the interpretation of any of the members of this
- * structure, in any way (this includes using values other than
- * LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
- * field).
- *
- * Instead:
- *
- * introduce a new structure for the new format, if the layout
- * of the structure changed;
- *
- * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
- * a new magic number for your new capture file format, and, when
- * you get the new magic number, put it in "savefile.c";
- *
- * use that magic number for save files with the changed file
- * header;
- *
- * make the code in "savefile.c" capable of reading files with
- * the old file header as well as files with the new file header
- * (using the magic number to determine the header format).
- *
- * Then supply the changes as a patch at
- *
- * http://sourceforge.net/projects/libpcap/
- *
- * so that future versions of libpcap and programs that use it (such as
- * tcpdump) will be able to read your new capture file format.
- */
-struct pcap_file_header {
- bpf_u_int32 magic;
- u_short version_major;
- u_short version_minor;
- bpf_int32 thiszone; /* gmt to local correction */
- bpf_u_int32 sigfigs; /* accuracy of timestamps */
- bpf_u_int32 snaplen; /* max length saved portion of each pkt */
- bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
-};
-
-/*
- * Macros for the value returned by pcap_datalink_ext().
- *
- * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
- * gives the FCS length of packets in the capture.
- */
-#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
-#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
-#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
-
-typedef enum {
- PCAP_D_INOUT = 0,
- PCAP_D_IN,
- PCAP_D_OUT
-} pcap_direction_t;
-
-/*
- * Generic per-packet information, as supplied by libpcap.
- *
- * The time stamp can and should be a "struct timeval", regardless of
- * whether your system supports 32-bit tv_sec in "struct timeval",
- * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
- * and 64-bit applications. The on-disk format of savefiles uses 32-bit
- * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
- * and 64-bit versions of libpcap, even if they're on the same platform,
- * should supply the appropriate version of "struct timeval", even if
- * that's not what the underlying packet capture mechanism supplies.
- */
-struct pcap_pkthdr {
- struct timeval ts; /* time stamp */
- bpf_u_int32 caplen; /* length of portion present */
- bpf_u_int32 len; /* length this packet (off wire) */
-};
-
-/*
- * As returned by the pcap_stats()
- */
-struct pcap_stat {
- u_int ps_recv; /* number of packets received */
- u_int ps_drop; /* number of packets dropped */
- u_int ps_ifdrop; /* drops by interface XXX not yet supported */
-#ifdef HAVE_REMOTE
- u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */
- u_int ps_sent; /* number of packets sent by the server on the network */
- u_int ps_netdrop; /* number of packets lost on the network */
-#endif /* HAVE_REMOTE */
-};
-
-#ifdef MSDOS
-/*
- * As returned by the pcap_stats_ex()
- */
-struct pcap_stat_ex {
- u_long rx_packets; /* total packets received */
- u_long tx_packets; /* total packets transmitted */
- u_long rx_bytes; /* total bytes received */
- u_long tx_bytes; /* total bytes transmitted */
- u_long rx_errors; /* bad packets received */
- u_long tx_errors; /* packet transmit problems */
- u_long rx_dropped; /* no space in Rx buffers */
- u_long tx_dropped; /* no space available for Tx */
- u_long multicast; /* multicast packets received */
- u_long collisions;
-
- /* detailed rx_errors: */
- u_long rx_length_errors;
- u_long rx_over_errors; /* receiver ring buff overflow */
- u_long rx_crc_errors; /* recv'd pkt with crc error */
- u_long rx_frame_errors; /* recv'd frame alignment error */
- u_long rx_fifo_errors; /* recv'r fifo overrun */
- u_long rx_missed_errors; /* recv'r missed packet */
-
- /* detailed tx_errors */
- u_long tx_aborted_errors;
- u_long tx_carrier_errors;
- u_long tx_fifo_errors;
- u_long tx_heartbeat_errors;
- u_long tx_window_errors;
- };
-#endif
-
-/*
- * Item in a list of interfaces.
- */
-struct pcap_if {
- struct pcap_if *next;
- char *name; /* name to hand to "pcap_open_live()" */
- char *description; /* textual description of interface, or NULL */
- struct pcap_addr *addresses;
- bpf_u_int32 flags; /* PCAP_IF_ interface flags */
-};
-
-#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
-
-/*
- * Representation of an interface address.
- */
-struct pcap_addr {
- struct pcap_addr *next;
- struct sockaddr *addr; /* address */
- struct sockaddr *netmask; /* netmask for that address */
- struct sockaddr *broadaddr; /* broadcast address for that address */
- struct sockaddr *dstaddr; /* P2P destination address for that address */
-};
-
-typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-
-/*
- * Error codes for the pcap API.
- * These will all be negative, so you can check for the success or
- * failure of a call that returns these codes by checking for a
- * negative value.
- */
-#define PCAP_ERROR -1 /* generic error code */
-#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
-#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
-#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
-#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
-#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
-#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
-#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
-#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
-
-/*
- * Warning codes for the pcap API.
- * These will all be positive and non-zero, so they won't look like
- * errors.
- */
-#define PCAP_WARNING 1 /* generic warning code */
-#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
-
-char *pcap_lookupdev(char *);
-int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
-
-pcap_t *pcap_create(const char *, char *);
-int pcap_set_snaplen(pcap_t *, int);
-int pcap_set_promisc(pcap_t *, int);
-int pcap_can_set_rfmon(pcap_t *);
-int pcap_set_rfmon(pcap_t *, int);
-int pcap_set_timeout(pcap_t *, int);
-int pcap_set_buffer_size(pcap_t *, int);
-int pcap_activate(pcap_t *);
-
-pcap_t *pcap_open_live(const char *, int, int, int, char *);
-pcap_t *pcap_open_dead(int, int);
-pcap_t *pcap_open_offline(const char *, char *);
-#if defined(WIN32)
-pcap_t *pcap_hopen_offline(intptr_t, char *);
-#if !defined(LIBPCAP_EXPORTS)
-#define pcap_fopen_offline(f,b) \
- pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
-#else /*LIBPCAP_EXPORTS*/
-static pcap_t *pcap_fopen_offline(FILE *, char *);
-#endif
-#else /*WIN32*/
-pcap_t *pcap_fopen_offline(FILE *, char *);
-#endif /*WIN32*/
-
-void pcap_close(pcap_t *);
-int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
-int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
-const u_char*
- pcap_next(pcap_t *, struct pcap_pkthdr *);
-int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
-void pcap_breakloop(pcap_t *);
-int pcap_stats(pcap_t *, struct pcap_stat *);
-int pcap_setfilter(pcap_t *, struct bpf_program *);
-int pcap_setdirection(pcap_t *, pcap_direction_t);
-int pcap_getnonblock(pcap_t *, char *);
-int pcap_setnonblock(pcap_t *, int, char *);
-int pcap_inject(pcap_t *, const void *, size_t);
-int pcap_sendpacket(pcap_t *, const u_char *, int);
-const char *pcap_statustostr(int);
-const char *pcap_strerror(int);
-char *pcap_geterr(pcap_t *);
-void pcap_perror(pcap_t *, char *);
-int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
- bpf_u_int32);
-int pcap_compile_nopcap(int, int, struct bpf_program *,
- const char *, int, bpf_u_int32);
-void pcap_freecode(struct bpf_program *);
-int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
- const u_char *);
-int pcap_datalink(pcap_t *);
-int pcap_datalink_ext(pcap_t *);
-int pcap_list_datalinks(pcap_t *, int **);
-int pcap_set_datalink(pcap_t *, int);
-void pcap_free_datalinks(int *);
-int pcap_datalink_name_to_val(const char *);
-const char *pcap_datalink_val_to_name(int);
-const char *pcap_datalink_val_to_description(int);
-int pcap_snapshot(pcap_t *);
-int pcap_is_swapped(pcap_t *);
-int pcap_major_version(pcap_t *);
-int pcap_minor_version(pcap_t *);
-
-/* XXX */
-FILE *pcap_file(pcap_t *);
-int pcap_fileno(pcap_t *);
-
-pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
-pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
-FILE *pcap_dump_file(pcap_dumper_t *);
-long pcap_dump_ftell(pcap_dumper_t *);
-int pcap_dump_flush(pcap_dumper_t *);
-void pcap_dump_close(pcap_dumper_t *);
-void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
-
-int pcap_findalldevs(pcap_if_t **, char *);
-void pcap_freealldevs(pcap_if_t *);
-
-const char *pcap_lib_version(void);
-
-/* XXX this guy lives in the bpf tree */
-u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
-int bpf_validate(const struct bpf_insn *f, int len);
-char *bpf_image(const struct bpf_insn *, int);
-void bpf_dump(const struct bpf_program *, int);
-
-#if defined(WIN32)
-
-/*
- * Win32 definitions
- */
-
-int pcap_setbuff(pcap_t *p, int dim);
-int pcap_setmode(pcap_t *p, int mode);
-int pcap_setmintocopy(pcap_t *p, int size);
-
-#ifdef WPCAP
-/* Include file with the wpcap-specific extensions */
-#include <Win32-Extensions.h>
-#endif /* WPCAP */
-
-#define MODE_CAPT 0
-#define MODE_STAT 1
-#define MODE_MON 2
-
-#elif defined(MSDOS)
-
-/*
- * MS-DOS definitions
- */
-
-int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
-void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
-u_long pcap_mac_packets (void);
-
-#else /* UN*X */
-
-/*
- * UN*X definitions
- */
-
-int pcap_get_selectable_fd(pcap_t *);
-
-#endif /* WIN32/MSDOS/UN*X */
-
-#ifdef HAVE_REMOTE
-/* Includes most of the public stuff that is needed for the remote capture */
-#include <remote-ext.h>
-#endif /* HAVE_REMOTE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/sll.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/sll.h
deleted file mode 100644
index e9d5452af..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/sll.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.2.2.1 2008-05-30 01:36:06 guy Exp $ (LBL)
- */
-
-/*
- * For captures on Linux cooked sockets, we construct a fake header
- * that includes:
- *
- * a 2-byte "packet type" which is one of:
- *
- * LINUX_SLL_HOST packet was sent to us
- * LINUX_SLL_BROADCAST packet was broadcast
- * LINUX_SLL_MULTICAST packet was multicast
- * LINUX_SLL_OTHERHOST packet was sent to somebody else
- * LINUX_SLL_OUTGOING packet was sent *by* us;
- *
- * a 2-byte Ethernet protocol field;
- *
- * a 2-byte link-layer type;
- *
- * a 2-byte link-layer address length;
- *
- * an 8-byte source link-layer address, whose actual length is
- * specified by the previous value.
- *
- * All fields except for the link-layer address are in network byte order.
- *
- * DO NOT change the layout of this structure, or change any of the
- * LINUX_SLL_ values below. If you must change the link-layer header
- * for a "cooked" Linux capture, introduce a new DLT_ type (ask
- * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
- * a value that collides with a value already being used), and use the
- * new header in captures of that type, so that programs that can
- * handle DLT_LINUX_SLL captures will continue to handle them correctly
- * without any change, and so that capture files with different headers
- * can be told apart and programs that read them can dissect the
- * packets in them.
- */
-
-#ifndef lib_pcap_sll_h
-#define lib_pcap_sll_h
-
-/*
- * A DLT_LINUX_SLL fake link-layer header.
- */
-#define SLL_HDR_LEN 16 /* total header length */
-#define SLL_ADDRLEN 8 /* length of address field */
-
-struct sll_header {
- u_int16_t sll_pkttype; /* packet type */
- u_int16_t sll_hatype; /* link-layer address type */
- u_int16_t sll_halen; /* link-layer address length */
- u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
- u_int16_t sll_protocol; /* protocol */
-};
-
-/*
- * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
- * PACKET_ values on Linux, but are defined here so that they're
- * available even on systems other than Linux, and so that they
- * don't change even if the PACKET_ values change.
- */
-#define LINUX_SLL_HOST 0
-#define LINUX_SLL_BROADCAST 1
-#define LINUX_SLL_MULTICAST 2
-#define LINUX_SLL_OTHERHOST 3
-#define LINUX_SLL_OUTGOING 4
-
-/*
- * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
- * ETH_P_ values on Linux, but are defined here so that they're
- * available even on systems other than Linux. We assume, for now,
- * that the ETH_P_ values won't change in Linux; if they do, then:
- *
- * if we don't translate them in "pcap-linux.c", capture files
- * won't necessarily be readable if captured on a system that
- * defines ETH_P_ values that don't match these values;
- *
- * if we do translate them in "pcap-linux.c", that makes life
- * unpleasant for the BPF code generator, as the values you test
- * for in the kernel aren't the values that you test for when
- * reading a capture file, so the fixup code run on BPF programs
- * handed to the kernel ends up having to do more work.
- *
- * Add other values here as necessary, for handling packet types that
- * might show up on non-Ethernet, non-802.x networks. (Not all the ones
- * in the Linux "if_ether.h" will, I suspect, actually show up in
- * captures.)
- */
-#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
-#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/usb.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/usb.h
deleted file mode 100644
index adcd19c05..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/usb.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2006 Paolo Abeni (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Basic USB data struct
- * By Paolo Abeni <paolo.abeni@email.it>
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $
- */
-
-#ifndef _PCAP_USB_STRUCTS_H__
-#define _PCAP_USB_STRUCTS_H__
-
-/*
- * possible transfer mode
- */
-#define URB_TRANSFER_IN 0x80
-#define URB_ISOCHRONOUS 0x0
-#define URB_INTERRUPT 0x1
-#define URB_CONTROL 0x2
-#define URB_BULK 0x3
-
-/*
- * possible event type
- */
-#define URB_SUBMIT 'S'
-#define URB_COMPLETE 'C'
-#define URB_ERROR 'E'
-
-/*
- * USB setup header as defined in USB specification.
- * Appears at the front of each packet in DLT_USB captures.
- */
-typedef struct _usb_setup {
- u_int8_t bmRequestType;
- u_int8_t bRequest;
- u_int16_t wValue;
- u_int16_t wIndex;
- u_int16_t wLength;
-} pcap_usb_setup;
-
-
-/*
- * Header prepended by linux kernel to each event.
- * Appears at the front of each packet in DLT_USB_LINUX captures.
- */
-typedef struct _usb_header {
- u_int64_t id;
- u_int8_t event_type;
- u_int8_t transfer_type;
- u_int8_t endpoint_number;
- u_int8_t device_address;
- u_int16_t bus_id;
- char setup_flag;/*if !=0 the urb setup header is not present*/
- char data_flag; /*if !=0 no urb data is present*/
- int64_t ts_sec;
- int32_t ts_usec;
- int32_t status;
- u_int32_t urb_len;
- u_int32_t data_len; /* amount of urb data really present in this event*/
- pcap_usb_setup setup;
-} pcap_usb_header;
-
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/vlan.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/vlan.h
deleted file mode 100644
index b0cb7949b..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/pcap/vlan.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/vlan.h,v 1.1.2.2 2008-08-06 07:45:59 guy Exp $
- */
-
-#ifndef lib_pcap_vlan_h
-#define lib_pcap_vlan_h
-
-struct vlan_tag {
- u_int16_t vlan_tpid; /* ETH_P_8021Q */
- u_int16_t vlan_tci; /* VLAN TCI */
-};
-
-#define VLAN_TAG_LEN 4
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/remote-ext.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/remote-ext.h
deleted file mode 100644
index 9f54d6974..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/remote-ext.h
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (c) 2002 - 2003
- * NetGroup, Politecnico di Torino (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef __REMOTE_EXT_H__
-#define __REMOTE_EXT_H__
-
-
-#ifndef HAVE_REMOTE
-#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h
-#endif
-
-// Definition for Microsoft Visual Studio
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- \file remote-ext.h
-
- The goal of this file it to include most of the new definitions that should be
- placed into the pcap.h file.
-
- It includes all new definitions (structures and functions like pcap_open().
- Some of the functions are not really a remote feature, but, right now,
- they are placed here.
-*/
-
-
-
-// All this stuff is public
-/*! \addtogroup remote_struct
- \{
-*/
-
-
-
-
-/*!
- \brief Defines the maximum buffer size in which address, port, interface names are kept.
-
- In case the adapter name or such is larger than this value, it is truncated.
- This is not used by the user; however it must be aware that an hostname / interface
- name longer than this value will be truncated.
-*/
-#define PCAP_BUF_SIZE 1024
-
-
-/*! \addtogroup remote_source_ID
- \{
-*/
-
-
-/*!
- \brief Internal representation of the type of source in use (file,
- remote/local interface).
-
- This indicates a file, i.e. the user want to open a capture from a local file.
-*/
-#define PCAP_SRC_FILE 2
-/*!
- \brief Internal representation of the type of source in use (file,
- remote/local interface).
-
- This indicates a local interface, i.e. the user want to open a capture from
- a local interface. This does not involve the RPCAP protocol.
-*/
-#define PCAP_SRC_IFLOCAL 3
-/*!
- \brief Internal representation of the type of source in use (file,
- remote/local interface).
-
- This indicates a remote interface, i.e. the user want to open a capture from
- an interface on a remote host. This does involve the RPCAP protocol.
-*/
-#define PCAP_SRC_IFREMOTE 4
-
-/*!
- \}
-*/
-
-
-
-/*! \addtogroup remote_source_string
-
- The formats allowed by the pcap_open() are the following:
- - file://path_and_filename [opens a local file]
- - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
- - rpcap://host/devicename [opens the selected device available on a remote host]
- - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
- - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
- - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
-
- The formats allowed by the pcap_findalldevs_ex() are the following:
- - file://folder/ [lists all the files in the given folder]
- - rpcap:// [lists all local adapters]
- - rpcap://host:port/ [lists the devices available on a remote host]
-
- Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since
- IPv6 is fully supported, these are the allowed formats:
-
- - host (literal): e.g. host.foo.bar
- - host (numeric IPv4): e.g. 10.11.12.13
- - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13]
- - host (numeric IPv6): e.g. [1:2:3::4]
- - port: can be either numeric (e.g. '80') or literal (e.g. 'http')
-
- Here you find some allowed examples:
- - rpcap://host.foo.bar/devicename [everything literal, no port number]
- - rpcap://host.foo.bar:1234/devicename [everything literal, with port number]
- - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number]
- - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number]
- - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number]
- - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number]
- - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number]
- - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number]
-
- \{
-*/
-
-
-/*!
- \brief String that will be used to determine the type of source in use (file,
- remote/local interface).
-
- This string will be prepended to the interface name in order to create a string
- that contains all the information required to open the source.
-
- This string indicates that the user wants to open a capture from a local file.
-*/
-#define PCAP_SRC_FILE_STRING "file://"
-/*!
- \brief String that will be used to determine the type of source in use (file,
- remote/local interface).
-
- This string will be prepended to the interface name in order to create a string
- that contains all the information required to open the source.
-
- This string indicates that the user wants to open a capture from a network interface.
- This string does not necessarily involve the use of the RPCAP protocol. If the
- interface required resides on the local host, the RPCAP protocol is not involved
- and the local functions are used.
-*/
-#define PCAP_SRC_IF_STRING "rpcap://"
-
-/*!
- \}
-*/
-
-
-
-
-
-/*!
- \addtogroup remote_open_flags
- \{
-*/
-
-/*!
- \brief Defines if the adapter has to go in promiscuous mode.
-
- It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise.
- Note that even if this parameter is false, the interface could well be in promiscuous
- mode for some other reason (for example because another capture process with
- promiscuous mode enabled is currently using that interface).
- On on Linux systems with 2.2 or later kernels (that have the "any" device), this
- flag does not work on the "any" device; if an argument of "any" is supplied,
- the 'promisc' flag is ignored.
-*/
-#define PCAP_OPENFLAG_PROMISCUOUS 1
-
-/*!
- \brief Defines if the data trasfer (in case of a remote
- capture) has to be done with UDP protocol.
-
- If it is '1' if you want a UDP data connection, '0' if you want
- a TCP data connection; control connection is always TCP-based.
- A UDP connection is much lighter, but it does not guarantee that all
- the captured packets arrive to the client workstation. Moreover,
- it could be harmful in case of network congestion.
- This flag is meaningless if the source is not a remote interface.
- In that case, it is simply ignored.
-*/
-#define PCAP_OPENFLAG_DATATX_UDP 2
-
-
-/*!
- \brief Defines if the remote probe will capture its own generated traffic.
-
- In case the remote probe uses the same interface to capture traffic and to send
- data back to the caller, the captured traffic includes the RPCAP traffic as well.
- If this flag is turned on, the RPCAP traffic is excluded from the capture, so that
- the trace returned back to the collector is does not include this traffic.
-*/
-#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
-
-/*!
- \brief Defines if the local adapter will capture its own generated traffic.
-
- This flag tells the underlying capture driver to drop the packets that were sent by itself.
- This is usefult when building applications like bridges, that should ignore the traffic
- they just sent.
-*/
-#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
-
-/*!
- \brief This flag configures the adapter for maximum responsiveness.
-
- In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before
- copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage,
- i.e. better performance, which is good for applications like sniffers. If the user sets the
- PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application
- is ready to receive them. This is suggested for real time applications (like, for example, a bridge)
- that need the best responsiveness.*/
-#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
-
-/*!
- \}
-*/
-
-
-/*!
- \addtogroup remote_samp_methods
- \{
-*/
-
-/*!
- \brief No sampling has to be done on the current capture.
-
- In this case, no sampling algorithms are applied to the current capture.
-*/
-#define PCAP_SAMP_NOSAMP 0
-
-/*!
- \brief It defines that only 1 out of N packets must be returned to the user.
-
- In this case, the 'value' field of the 'pcap_samp' structure indicates the
- number of packets (minus 1) that must be discarded before one packet got accepted.
- In other words, if 'value = 10', the first packet is returned to the caller, while
- the following 9 are discarded.
-*/
-#define PCAP_SAMP_1_EVERY_N 1
-
-/*!
- \brief It defines that we have to return 1 packet every N milliseconds.
-
- In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting
- time' in milliseconds before one packet got accepted.
- In other words, if 'value = 10', the first packet is returned to the caller; the next
- returned one will be the first packet that arrives when 10ms have elapsed.
-*/
-#define PCAP_SAMP_FIRST_AFTER_N_MS 2
-
-/*!
- \}
-*/
-
-
-/*!
- \addtogroup remote_auth_methods
- \{
-*/
-
-/*!
- \brief It defines the NULL authentication.
-
- This value has to be used within the 'type' member of the pcap_rmtauth structure.
- The 'NULL' authentication has to be equal to 'zero', so that old applications
- can just put every field of struct pcap_rmtauth to zero, and it does work.
-*/
-#define RPCAP_RMTAUTH_NULL 0
-/*!
- \brief It defines the username/password authentication.
-
- With this type of authentication, the RPCAP protocol will use the username/
- password provided to authenticate the user on the remote machine. If the
- authentication is successful (and the user has the right to open network devices)
- the RPCAP connection will continue; otherwise it will be dropped.
-
- This value has to be used within the 'type' member of the pcap_rmtauth structure.
-*/
-#define RPCAP_RMTAUTH_PWD 1
-
-/*!
- \}
-*/
-
-
-
-
-/*!
-
- \brief This structure keeps the information needed to autheticate
- the user on a remote machine.
-
- The remote machine can either grant or refuse the access according
- to the information provided.
- In case the NULL authentication is required, both 'username' and
- 'password' can be NULL pointers.
-
- This structure is meaningless if the source is not a remote interface;
- in that case, the functions which requires such a structure can accept
- a NULL pointer as well.
-*/
-struct pcap_rmtauth
-{
- /*!
- \brief Type of the authentication required.
-
- In order to provide maximum flexibility, we can support different types
- of authentication based on the value of this 'type' variable. The currently
- supported authentication methods are defined into the
- \link remote_auth_methods Remote Authentication Methods Section\endlink.
-
- */
- int type;
- /*!
- \brief Zero-terminated string containing the username that has to be
- used on the remote machine for authentication.
-
- This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
- and it can be NULL.
- */
- char *username;
- /*!
- \brief Zero-terminated string containing the password that has to be
- used on the remote machine for authentication.
-
- This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
- and it can be NULL.
- */
- char *password;
-};
-
-
-/*!
- \brief This structure defines the information related to sampling.
-
- In case the sampling is requested, the capturing device should read
- only a subset of the packets coming from the source. The returned packets depend
- on the sampling parameters.
-
- \warning The sampling process is applied <strong>after</strong> the filtering process.
- In other words, packets are filtered first, then the sampling process selects a
- subset of the 'filtered' packets and it returns them to the caller.
-*/
-struct pcap_samp
-{
- /*!
- Method used for sampling. Currently, the supported methods are listed in the
- \link remote_samp_methods Sampling Methods Section\endlink.
- */
- int method;
-
- /*!
- This value depends on the sampling method defined. For its meaning, please check
- at the \link remote_samp_methods Sampling Methods Section\endlink.
- */
- int value;
-};
-
-
-
-
-//! Maximum lenght of an host name (needed for the RPCAP active mode)
-#define RPCAP_HOSTLIST_SIZE 1024
-
-
-/*!
- \}
-*/ // end of public documentation
-
-
-// Exported functions
-
-
-
-/** \name New WinPcap functions
-
- This section lists the new functions that are able to help considerably in writing
- WinPcap programs because of their easiness of use.
- */
-//\{
-pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
-int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf);
-int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf);
-int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
-struct pcap_samp *pcap_setsampling(pcap_t *p);
-
-//\}
-// End of new winpcap functions
-
-
-
-/** \name Remote Capture functions
- */
-//\{
-SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf);
-int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf);
-int pcap_remoteact_close(const char *host, char *errbuf);
-void pcap_remoteact_cleanup();
-//\}
-// End of remote capture functions
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/wpcap.lib b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/wpcap.lib
deleted file mode 100644
index f832e0445..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/WinPCap/wpcap.lib
+++ /dev/null
Binary files differ
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/atomic.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/atomic.h
deleted file mode 100644
index d44593d8f..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/atomic.h
+++ /dev/null
@@ -1,547 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.0
- * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/**
- * @file atomic.h
- * @brief FreeRTOS atomic operation support.
- *
- * Two implementations of atomic are given in this header file:
- * 1. Disabling interrupt globally.
- * 2. ISA native atomic support.
- * The former is available to all ports (compiler-architecture combination),
- * while the latter is only available to ports compiling with GCC (version at
- * least 4.7.0), which also have ISA atomic support.
- *
- * User can select which implementation to use by:
- * setting/clearing configUSE_ATOMIC_INSTRUCTION in FreeRTOSConfig.h.
- * Define AND set configUSE_ATOMIC_INSTRUCTION to 1 for ISA native atomic support.
- * Undefine OR clear configUSE_ATOMIC_INSTRUCTION for disabling global interrupt
- * implementation.
- *
- * @see GCC Built-in Functions for Memory Model Aware Atomic Operations
- * https://gcc.gnu.org/onlinedocs/gcc/_005f_005fatomic-Builtins.html
- */
-
-#ifndef ATOMIC_H
-#define ATOMIC_H
-
-#ifndef INC_FREERTOS_H
- #error "include FreeRTOS.h must appear in source files before include atomic.h"
-#endif
-
-/* Standard includes. */
-#include <stdint.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- /* Needed for __atomic_compare_exchange() weak=false. */
- #include <stdbool.h>
-
- /* This branch is for GCC compiler and GCC compiler only. */
- #ifndef portFORCE_INLINE
- #define portFORCE_INLINE inline __attribute__((always_inline))
- #endif
-
-#else
-
- /* Port specific definitions -- entering/exiting critical section.
- * Refer template -- ./lib/FreeRTOS/portable/Compiler/Arch/portmacro.h
- *
- * Every call to ATOMIC_EXIT_CRITICAL() must be closely paired with
- * ATOMIC_ENTER_CRITICAL().
- */
- #if defined( portSET_INTERRUPT_MASK_FROM_ISR )
-
- /* Nested interrupt scheme is supported in this port. */
- #define ATOMIC_ENTER_CRITICAL() \
- UBaseType_t uxCriticalSectionType = portSET_INTERRUPT_MASK_FROM_ISR()
-
- #define ATOMIC_EXIT_CRITICAL() \
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxCriticalSectionType )
-
- #else
-
- /* Nested interrupt scheme is NOT supported in this port. */
- #define ATOMIC_ENTER_CRITICAL() portENTER_CRITICAL()
- #define ATOMIC_EXIT_CRITICAL() portEXIT_CRITICAL()
-
- #endif /* portSET_INTERRUPT_MASK_FROM_ISR() */
-
- /* Port specific definition -- "always inline".
- * Inline is compiler specific, and may not always get inlined depending on your optimization level.
- * Also, inline is considerred as performance optimization for atomic.
- * Thus, if portFORCE_INLINE is not provided by portmacro.h, instead of resulting error,
- * simply define it.
- */
- #ifndef portFORCE_INLINE
- #define portFORCE_INLINE
- #endif
-
-#endif /* configUSE_GCC_BUILTIN_ATOMICS */
-
-#define ATOMIC_COMPARE_AND_SWAP_SUCCESS 0x1U /**< Compare and swap succeeded, swapped. */
-#define ATOMIC_COMPARE_AND_SWAP_FAILURE 0x0U /**< Compare and swap failed, did not swap. */
-
-/*----------------------------- Swap && CAS ------------------------------*/
-
-/**
- * Atomic compare-and-swap
- *
- * @brief Performs an atomic compare-and-swap operation on the specified values.
- *
- * @param[in, out] pDestination Pointer to memory location from where value is
- * to be loaded and checked.
- * @param[in] ulExchange If condition meets, write this value to memory.
- * @param[in] ulComparand Swap condition.
- *
- * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
- *
- * @note This function only swaps *pDestination with ulExchange, if previous
- * *pDestination value equals ulComparand.
- */
-static portFORCE_INLINE uint32_t Atomic_CompareAndSwap_u32(
- uint32_t volatile * pDestination,
- uint32_t ulExchange,
- uint32_t ulComparand )
-{
-
- uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
-
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- if ( __atomic_compare_exchange( pDestination,
- &ulComparand,
- &ulExchange,
- false,
- __ATOMIC_SEQ_CST,
- __ATOMIC_SEQ_CST ) )
- {
- ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
- }
-
-#else
-
- ATOMIC_ENTER_CRITICAL();
-
- if ( *pDestination == ulComparand )
- {
- *pDestination = ulExchange;
- ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
- }
-
- ATOMIC_EXIT_CRITICAL();
-
-#endif
-
- return ulReturnValue;
-
-}
-
-/**
- * Atomic swap (pointers)
- *
- * @brief Atomically sets the address pointed to by *ppDestination to the value
- * of *pExchange.
- *
- * @param[in, out] ppDestination Pointer to memory location from where a pointer
- * value is to be loaded and written back to.
- * @param[in] pExchange Pointer value to be written to *ppDestination.
- *
- * @return The initial value of *ppDestination.
- */
-static portFORCE_INLINE void * Atomic_SwapPointers_p32(
- void * volatile * ppDestination,
- void * pExchange )
-{
- void * pReturnValue;
-
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- __atomic_exchange( ppDestination, &pExchange, &pReturnValue, __ATOMIC_SEQ_CST );
-
-#else
-
- ATOMIC_ENTER_CRITICAL();
-
- pReturnValue = *ppDestination;
-
- *ppDestination = pExchange;
-
- ATOMIC_EXIT_CRITICAL();
-
-#endif
-
- return pReturnValue;
-}
-
-/**
- * Atomic compare-and-swap (pointers)
- *
- * @brief Performs an atomic compare-and-swap operation on the specified pointer
- * values.
- *
- * @param[in, out] ppDestination Pointer to memory location from where a pointer
- * value is to be loaded and checked.
- * @param[in] pExchange If condition meets, write this value to memory.
- * @param[in] pComparand Swap condition.
- *
- * @return Unsigned integer of value 1 or 0. 1 for swapped, 0 for not swapped.
- *
- * @note This function only swaps *ppDestination with pExchange, if previous
- * *ppDestination value equals pComparand.
- */
-static portFORCE_INLINE uint32_t Atomic_CompareAndSwapPointers_p32(
- void * volatile * ppDestination,
- void * pExchange, void * pComparand )
-{
- uint32_t ulReturnValue = ATOMIC_COMPARE_AND_SWAP_FAILURE;
-
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
- if ( __atomic_compare_exchange( ppDestination,
- &pComparand,
- &pExchange,
- false,
- __ATOMIC_SEQ_CST,
- __ATOMIC_SEQ_CST ) )
- {
- ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
- }
-
-#else
-
- ATOMIC_ENTER_CRITICAL();
-
- if ( *ppDestination == pComparand )
- {
- *ppDestination = pExchange;
- ulReturnValue = ATOMIC_COMPARE_AND_SWAP_SUCCESS;
- }
-
- ATOMIC_EXIT_CRITICAL();
-
-#endif
-
- return ulReturnValue;
-}
-
-
-/*----------------------------- Arithmetic ------------------------------*/
-
-/**
- * Atomic add
- *
- * @brief Atomically adds count to the value of the specified pointer points to.
- *
- * @param[in,out] pAddend Pointer to memory location from where value is to be
- * loaded and written back to.
- * @param[in] ulCount Value to be added to *pAddend.
- *
- * @return previous *pAddend value.
- */
-static portFORCE_INLINE uint32_t Atomic_Add_u32(
- uint32_t volatile * pAddend,
- uint32_t ulCount )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_add(pAddend, ulCount, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pAddend;
-
- *pAddend += ulCount;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/**
- * Atomic subtract
- *
- * @brief Atomically subtracts count from the value of the specified pointer
- * pointers to.
- *
- * @param[in,out] pAddend Pointer to memory location from where value is to be
- * loaded and written back to.
- * @param[in] ulCount Value to be subtract from *pAddend.
- *
- * @return previous *pAddend value.
- */
-static portFORCE_INLINE uint32_t Atomic_Subtract_u32(
- uint32_t volatile * pAddend,
- uint32_t ulCount )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_sub(pAddend, ulCount, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pAddend;
-
- *pAddend -= ulCount;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/**
- * Atomic increment
- *
- * @brief Atomically increments the value of the specified pointer points to.
- *
- * @param[in,out] pAddend Pointer to memory location from where value is to be
- * loaded and written back to.
- *
- * @return *pAddend value before increment.
- */
-static portFORCE_INLINE uint32_t Atomic_Increment_u32( uint32_t volatile * pAddend )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_add(pAddend, 1, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pAddend;
-
- *pAddend += 1;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/**
- * Atomic decrement
- *
- * @brief Atomically decrements the value of the specified pointer points to
- *
- * @param[in,out] pAddend Pointer to memory location from where value is to be
- * loaded and written back to.
- *
- * @return *pAddend value before decrement.
- */
-static portFORCE_INLINE uint32_t Atomic_Decrement_u32( uint32_t volatile * pAddend )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_sub(pAddend, 1, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pAddend;
-
- *pAddend -= 1;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/*----------------------------- Bitwise Logical ------------------------------*/
-
-/**
- * Atomic OR
- *
- * @brief Performs an atomic OR operation on the specified values.
- *
- * @param [in, out] pDestination Pointer to memory location from where value is
- * to be loaded and written back to.
- * @param [in] ulValue Value to be ORed with *pDestination.
- *
- * @return The original value of *pDestination.
- */
-static portFORCE_INLINE uint32_t Atomic_OR_u32(
- uint32_t volatile * pDestination,
- uint32_t ulValue )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_or(pDestination, ulValue, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pDestination;
-
- *pDestination |= ulValue;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/**
- * Atomic AND
- *
- * @brief Performs an atomic AND operation on the specified values.
- *
- * @param [in, out] pDestination Pointer to memory location from where value is
- * to be loaded and written back to.
- * @param [in] ulValue Value to be ANDed with *pDestination.
- *
- * @return The original value of *pDestination.
- */
-static portFORCE_INLINE uint32_t Atomic_AND_u32(
- uint32_t volatile * pDestination,
- uint32_t ulValue )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_and(pDestination, ulValue, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pDestination;
-
- *pDestination &= ulValue;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/**
- * Atomic NAND
- *
- * @brief Performs an atomic NAND operation on the specified values.
- *
- * @param [in, out] pDestination Pointer to memory location from where value is
- * to be loaded and written back to.
- * @param [in] ulValue Value to be NANDed with *pDestination.
- *
- * @return The original value of *pDestination.
- */
-static portFORCE_INLINE uint32_t Atomic_NAND_u32(
- uint32_t volatile * pDestination,
- uint32_t ulValue )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_nand(pDestination, ulValue, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pDestination;
-
- *pDestination = ~(ulCurrent & ulValue);
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-/**
- * Atomic XOR
- *
- * @brief Performs an atomic XOR operation on the specified values.
- *
- * @param [in, out] pDestination Pointer to memory location from where value is
- * to be loaded and written back to.
- * @param [in] ulValue Value to be XORed with *pDestination.
- *
- * @return The original value of *pDestination.
- */
-static portFORCE_INLINE uint32_t Atomic_XOR_u32(
- uint32_t volatile * pDestination,
- uint32_t ulValue )
-{
-#if defined ( configUSE_GCC_BUILTIN_ATOMICS ) && ( configUSE_GCC_BUILTIN_ATOMICS == 1 )
-
- return __atomic_fetch_xor(pDestination, ulValue, __ATOMIC_SEQ_CST);
-
-#else
-
- uint32_t ulCurrent;
-
- ATOMIC_ENTER_CRITICAL();
-
- ulCurrent = *pDestination;
-
- *pDestination ^= ulValue;
-
- ATOMIC_EXIT_CRITICAL();
-
- return ulCurrent;
-
-#endif
-}
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* ATOMIC_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.c
deleted file mode 100644
index d6a1d2577..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/*
- * Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and
- * disk file without making any Win32 system calls themselves.
- *
- * Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as
- * FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a
- * disk file are sent via a stream buffer to a Win32 thread which then performs
- * the actual output.
- */
-
-/* Standard includes. */
-#include <stdio.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <io.h>
-#include <ctype.h>
-
-/* FreeRTOS includes. */
-#include <FreeRTOS.h>
-#include "task.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_Stream_Buffer.h"
-
-/* Demo includes. */
-#include "demo_logging.h"
-
-/*-----------------------------------------------------------*/
-
-/* The maximum size to which the log file may grow, before being renamed
-to .ful. */
-#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul )
-
-/* Dimensions the arrays into which print messages are created. */
-#define dlMAX_PRINT_STRING_LENGTH 255
-
-/* The size of the stream buffer used to pass messages from FreeRTOS tasks to
-the Win32 thread that is responsible for making any Win32 system calls that are
-necessary for the selected logging method. */
-#define dlLOGGING_STREAM_BUFFER_SIZE 32768
-
-/* A block time of zero simply means don't block. */
-#define dlDONT_BLOCK 0
-
-/*-----------------------------------------------------------*/
-
-/*
- * Called from vLoggingInit() to start a new disk log file.
- */
-static void prvFileLoggingInit( void );
-
-/*
- * Attempt to write a message to the file.
- */
-static void prvLogToFile( const char *pcMessage, size_t xLength );
-
-/*
- * Simply close the logging file, if it is open.
- */
-static void prvFileClose( void );
-
-/*
- * Before the scheduler is started this function is called directly. After the
- * scheduler has started it is called from the Windows thread dedicated to
- * outputting log messages. Only the windows thread actually performs the
- * writing so as not to disrupt the simulation by making Windows system calls
- * from FreeRTOS tasks.
- */
-static void prvLoggingFlushBuffer( void );
-
-/*
- * The windows thread that performs the actual writing of messages that require
- * Win32 system calls. Only the windows thread can make system calls so as not
- * to disrupt the simulation by making Windows calls from FreeRTOS tasks.
- */
-static DWORD WINAPI prvWin32LoggingThread( void *pvParam );
-
-/*
- * Creates the socket to which UDP messages are sent. This function is not
- * called directly to prevent the print socket being created from within the IP
- * task - which could result in a deadlock. Instead the function call is
- * deferred to run in the RTOS daemon task - hence it prototype.
- */
-static void prvCreatePrintSocket( void *pvParameter1, uint32_t ulParameter2 );
-
-/*-----------------------------------------------------------*/
-
-/* Windows event used to wake the Win32 thread which performs any logging that
-needs Win32 system calls. */
-static void *pvLoggingThreadEvent = NULL;
-
-/* Stores the selected logging targets passed in as parameters to the
-vLoggingInit() function. */
-BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE;
-
-/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32
-thread that is responsible for making Win32 calls (when stdout or a disk log is
-used). */
-static StreamBuffer_t *xLogStreamBuffer = NULL;
-
-/* Handle to the file used for logging. This is left open while there are
-messages waiting to be logged, then closed again in between logs. */
-static FILE *pxLoggingFileHandle = NULL;
-
-/* When true prints are performed directly. After start up xDirectPrint is set
-to pdFALSE - at which time prints that require Win32 system calls are done by
-the Win32 thread responsible for logging. */
-BaseType_t xDirectPrint = pdTRUE;
-
-/* File names for the in use and complete (full) log files. */
-static const char *pcLogFileName = "RTOSDemo.log";
-static const char *pcFullLogFileName = "RTOSDemo.ful";
-
-/* Keep the current file size in a variable, as an optimisation. */
-static size_t ulSizeOfLoggingFile = 0ul;
-
-/* The UDP socket and address on/to which print messages are sent. */
-Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET;
-struct freertos_sockaddr xPrintUDPAddress;
-
-/*-----------------------------------------------------------*/
-
-void vLoggingInit( BaseType_t xLogToStdout, BaseType_t xLogToFile, BaseType_t xLogToUDP, uint32_t ulRemoteIPAddress, uint16_t usRemotePort )
-{
- /* Can only be called before the scheduler has started. */
- configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED );
-
- #if( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) )
- {
- HANDLE Win32Thread;
-
- /* Record which output methods are to be used. */
- xStdoutLoggingUsed = xLogToStdout;
- xDiskFileLoggingUsed = xLogToFile;
- xUDPLoggingUsed = xLogToUDP;
-
- /* If a disk file is used then initialise it now. */
- if( xDiskFileLoggingUsed != pdFALSE )
- {
- prvFileLoggingInit();
- }
-
- /* If UDP logging is used then store the address to which the log data
- will be sent - but don't create the socket yet because the network is
- not initialised. */
- if( xUDPLoggingUsed != pdFALSE )
- {
- /* Set the address to which the print messages are sent. */
- xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort );
- xPrintUDPAddress.sin_addr = ulRemoteIPAddress;
- }
-
- /* If a disk file or stdout are to be used then Win32 system calls will
- have to be made. Such system calls cannot be made from FreeRTOS tasks
- so create a stream buffer to pass the messages to a Win32 thread, then
- create the thread itself, along with a Win32 event that can be used to
- unblock the thread. */
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) )
- {
- /* Create the buffer. */
- xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 );
- configASSERT( xLogStreamBuffer );
- memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) );
- xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1;
-
- /* Create the Windows event. */
- pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" );
-
- /* Create the thread itself. */
- Win32Thread = CreateThread(
- NULL, /* Pointer to thread security attributes. */
- 0, /* Initial thread stack size, in bytes. */
- prvWin32LoggingThread, /* Pointer to thread function. */
- NULL, /* Argument for new thread. */
- 0, /* Creation flags. */
- NULL );
-
- /* Use the cores that are not used by the FreeRTOS tasks. */
- SetThreadAffinityMask( Win32Thread, ~0x01u );
- SetThreadPriorityBoost( Win32Thread, TRUE );
- SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE );
- }
- }
- #else
- {
- /* FreeRTOSIPConfig is set such that no print messages will be output.
- Avoid compiler warnings about unused parameters. */
- ( void ) xLogToStdout;
- ( void ) xLogToFile;
- ( void ) xLogToUDP;
- ( void ) usRemotePort;
- ( void ) ulRemoteIPAddress;
- }
- #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) */
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreatePrintSocket( void *pvParameter1, uint32_t ulParameter2 )
-{
-static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 );
-Socket_t xSocket;
-
- /* The function prototype is that of a deferred function, but the parameters
- are not actually used. */
- ( void ) pvParameter1;
- ( void ) ulParameter2;
-
- xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
-
- if( xSocket != FREERTOS_INVALID_SOCKET )
- {
- /* FreeRTOS+TCP decides which port to bind to. */
- FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
- FreeRTOS_bind( xSocket, NULL, 0 );
-
- /* Now the socket is bound it can be assigned to the print socket. */
- xPrintSocket = xSocket;
- }
-}
-/*-----------------------------------------------------------*/
-
-void vLoggingPrintf( const char *pcFormat, ... )
-{
-char cPrintString[ dlMAX_PRINT_STRING_LENGTH ];
-char cOutputString[ dlMAX_PRINT_STRING_LENGTH ];
-char *pcSource, *pcTarget, *pcBegin;
-size_t xLength, xLength2, rc;
-static BaseType_t xMessageNumber = 0;
-va_list args;
-uint32_t ulIPAddress;
-const char *pcTaskName;
-const char *pcNoTask = "None";
-int iOriginalPriority;
-HANDLE xCurrentTask;
-
-
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) )
- {
- /* There are a variable number of parameters. */
- va_start( args, pcFormat );
-
- /* Additional info to place at the start of the log. */
- if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
- {
- pcTaskName = pcTaskGetName( NULL );
- }
- else
- {
- pcTaskName = pcNoTask;
- }
-
- if( strcmp( pcFormat, "\n" ) != 0 )
- {
- xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%lu %lu [%s] ",
- xMessageNumber++,
- ( unsigned long ) xTaskGetTickCount(),
- pcTaskName );
- }
- else
- {
- xLength = 0;
- memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH );
- }
-
- xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args );
-
- if( xLength2 < 0 )
- {
- /* Clean up. */
- xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength;
- cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0';
- }
-
- xLength += xLength2;
- va_end( args );
-
- /* For ease of viewing, copy the string into another buffer, converting
- IP addresses to dot notation on the way. */
- pcSource = cPrintString;
- pcTarget = cOutputString;
-
- while( ( *pcSource ) != '\0' )
- {
- *pcTarget = *pcSource;
- pcTarget++;
- pcSource++;
-
- /* Look forward for an IP address denoted by 'ip'. */
- if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) )
- {
- *pcTarget = *pcSource;
- pcTarget++;
- *pcTarget = '\0';
- pcBegin = pcTarget - 8;
-
- while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) )
- {
- pcTarget--;
- }
-
- sscanf( pcTarget, "%8X", &ulIPAddress );
- rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu",
- ( unsigned long ) ( ulIPAddress >> 24UL ),
- ( unsigned long ) ( (ulIPAddress >> 16UL) & 0xffUL ),
- ( unsigned long ) ( (ulIPAddress >> 8UL) & 0xffUL ),
- ( unsigned long ) ( ulIPAddress & 0xffUL ) );
- pcTarget += rc;
- pcSource += 3; /* skip "<n>ip" */
- }
- }
-
- /* How far through the buffer was written? */
- xLength = ( BaseType_t ) ( pcTarget - cOutputString );
-
- /* If the message is to be logged to a UDP port then it can be sent directly
- because it only uses FreeRTOS function (not Win32 functions). */
- if( xUDPLoggingUsed != pdFALSE )
- {
- if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) )
- {
- /* Create and bind the socket to which print messages are sent. The
- xTimerPendFunctionCall() function is used even though this is
- not an interrupt because this function is called from the IP task
- and the IP task cannot itself wait for a socket to bind. The
- parameters to prvCreatePrintSocket() are not required so set to
- NULL or 0. */
- xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK );
- }
-
- if( xPrintSocket != FREERTOS_INVALID_SOCKET )
- {
- FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) );
-
- /* Just because the UDP data logger I'm using is dumb. */
- FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) );
- }
- }
-
- /* If logging is also to go to either stdout or a disk file then it cannot
- be output here - so instead write the message to the stream buffer and wake
- the Win32 thread which will read it from the stream buffer and perform the
- actual output. */
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) )
- {
- configASSERT( xLogStreamBuffer );
-
- /* How much space is in the buffer? */
- xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer );
-
- /* There must be enough space to write both the string and the length of
- the string. */
- if( xLength2 >= ( xLength + sizeof( xLength ) ) )
- {
- /* First write in the length of the data, then write in the data
- itself. Raising the thread priority is used as a critical section
- as there are potentially multiple writers. The stream buffer is
- only thread safe when there is a single writer (likewise for
- reading from the buffer). */
- xCurrentTask = GetCurrentThread();
- iOriginalPriority = GetThreadPriority( xCurrentTask );
- SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
- uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) );
- uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength );
- SetThreadPriority( GetCurrentThread(), iOriginalPriority );
- }
-
- /* xDirectPrint is initialised to pdTRUE, and while it remains true the
- logging output function is called directly. When the system is running
- the output function cannot be called directly because it would get
- called from both FreeRTOS tasks and Win32 threads - so instead wake the
- Win32 thread responsible for the actual output. */
- if( xDirectPrint != pdFALSE )
- {
- /* While starting up, the thread which calls prvWin32LoggingThread()
- is not running yet and xDirectPrint will be pdTRUE. */
- prvLoggingFlushBuffer();
- }
- else if( pvLoggingThreadEvent != NULL )
- {
- /* While running, wake up prvWin32LoggingThread() to send the
- logging data. */
- SetEvent( pvLoggingThreadEvent );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvLoggingFlushBuffer( void )
-{
-size_t xLength;
-char cPrintString[ dlMAX_PRINT_STRING_LENGTH ];
-
- /* Is there more than the length value stored in the circular buffer
- used to pass data from the FreeRTOS simulator into this Win32 thread? */
- while( uxStreamBufferGetSize( xLogStreamBuffer ) > sizeof( xLength ) )
- {
- memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH );
- uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
- uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE );
-
- /* Write the message to standard out if requested to do so when
- vLoggingInit() was called, or if the network is not yet up. */
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
- {
- /* Write the message to stdout. */
- printf( "%s", cPrintString ); /*_RB_ Replace with _write(). */
- }
-
- /* Write the message to a file if requested to do so when
- vLoggingInit() was called. */
- if( xDiskFileLoggingUsed != pdFALSE )
- {
- prvLogToFile( cPrintString, xLength );
- }
- }
-
- prvFileClose();
-}
-/*-----------------------------------------------------------*/
-
-static DWORD WINAPI prvWin32LoggingThread( void *pvParameter )
-{
-const DWORD xMaxWait = 1000;
-
- ( void ) pvParameter;
-
- /* From now on, prvLoggingFlushBuffer() will only be called from this
- Windows thread */
- xDirectPrint = pdFALSE;
-
- for( ;; )
- {
- /* Wait to be told there are message waiting to be logged. */
- WaitForSingleObject( pvLoggingThreadEvent, xMaxWait );
-
- /* Write out all waiting messages. */
- prvLoggingFlushBuffer();
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvFileLoggingInit( void )
-{
-FILE *pxHandle = fopen( pcLogFileName, "a" );
-
- if( pxHandle != NULL )
- {
- fseek( pxHandle, SEEK_END, 0ul );
- ulSizeOfLoggingFile = ftell( pxHandle );
- fclose( pxHandle );
- }
- else
- {
- ulSizeOfLoggingFile = 0ul;
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvFileClose( void )
-{
- if( pxLoggingFileHandle != NULL )
- {
- fclose( pxLoggingFileHandle );
- pxLoggingFileHandle = NULL;
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvLogToFile( const char *pcMessage, size_t xLength )
-{
- if( pxLoggingFileHandle == NULL )
- {
- pxLoggingFileHandle = fopen( pcLogFileName, "a" );
- }
-
- if( pxLoggingFileHandle != NULL )
- {
- fwrite( pcMessage, 1, xLength, pxLoggingFileHandle );
- ulSizeOfLoggingFile += xLength;
-
- /* If the file has grown to its maximum permissible size then close and
- rename it - then start with a new file. */
- if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE )
- {
- prvFileClose();
- if( _access( pcFullLogFileName, 00 ) == 0 )
- {
- remove( pcFullLogFileName );
- }
- rename( pcLogFileName, pcFullLogFileName );
- ulSizeOfLoggingFile = 0;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.h
deleted file mode 100644
index 62ae46a52..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/demo_logging.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef DEMO_LOGGING_H
-#define DEMO_LOGGING_H
-
-/*
- * Initialise a logging system that can be used from FreeRTOS tasks and Win32
- * threads. Do not call printf() directly while the scheduler is running.
- *
- * Set xLogToStdout, xLogToFile and xLogToUDP to either pdTRUE or pdFALSE to
- * lot to stdout, a disk file and a UDP port respectively.
- *
- * If xLogToUDP is pdTRUE then ulRemoteIPAddress and usRemotePort must be set
- * to the IP address and port number to which UDP log messages will be sent.
- */
-void vLoggingInit( BaseType_t xLogToStdout,
- BaseType_t xLogToFile,
- BaseType_t xLogToUDP,
- uint32_t ulRemoteIPAddress,
- uint16_t usRemotePort );
-
-#endif /* DEMO_LOGGING_H */
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config.h
deleted file mode 100644
index 8a06baac5..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config.h
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* This file contains configuration settings for the demos. */
-
-#ifndef IOT_CONFIG_H_
-#define IOT_CONFIG_H_
-
-
-/**
- * @brief The number of recyclable jobs for the task pool to cache.
- *
- * Caching dynamically allocated jobs (recyclable jobs) helps the application
- * to limit the number of allocations at runtime. Caching recyclable jobs may
- * help making the application more responsive and predictable, by removing a
- * potential for memory allocation failures, but it may also have negative
- * repercussions on the amount of memory available at any given time. It is up
- * to the application developer to strike the correct balance among these
- * competing needs. The task pool will cache a job when the application calls
- * IotTaskPool_RecycleJob on a job which was created using
- * IotTaskPool_CreateRecyclableJob API. Any recycled jobs in excess of
- * IOT_TASKPOOL_JOBS_RECYCLE_LIMIT will be destroyed and its memory will be
- * released.
- *
- * Default value (if undefined): 8
- */
-#define IOT_TASKPOOL_JOBS_RECYCLE_LIMIT 8
-
-/**
- * @brief Enable/Disable asserts for the task pool library.
- *
- * Set this to 1 to perform sanity checks when using the task pool library.
- * Asserts are useful for debugging, but should be disabled in production code.
- * If this is set to 1, IotTaskPool_Assert can be defined to set the assertion
- * function; otherwise, the standard library's assert function will be used.
- *
- * Possible values: 0 (asserts disabled) or 1 (asserts enabled)
- * Recommended values: 1 when debugging; 0 in production code.
- * Default value (if undefined): 0
- */
-#define IOT_TASKPOOL_ENABLE_ASSERTS 1
-
-/**
- * @brief The numer of worker tasks in the task pool.
- *
- * The full IoT Task Pool Library has many use cases, including Linux
- * development. Typical FreeRTOS use cases do not require the full
- * functionality so an optimized implementation is provided specifically for use
- * with FreeRTOS. The optimized version has a fixed number of tasks in the
- * task pool, each of which uses statically allocated memory to ensure creation
- * of the task pool is guaranteed (it does not run out of heap space).
- */
-#define IOT_TASKPOOL_NUMBER_OF_WORKERS 3
-
-/*
- * @brief Set the log level of the task pool library.
- *
- * Log messages from the task pool library at or below this setting will be
- * printed.
- *
- * Possible values: One of the Log levels.
- * Default value (if undefined): IOT_LOG_LEVEL_GLOBAL; if that is undefined,
- * then IOT_LOG_NONE.
- */
-#define IOT_LOG_LEVEL_TASKPOOL IOT_LOG_WARN
-
-
-/**
- * @brief The stack size (in bytes) for each worker task in the task pool.
- *
- * The minimal version of the of task pool library only supports one task pool
- * and the configuration of each worker task fixed at the compile time.
- */
-#define IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES 2048
-
-/**
- * @brief The amount of time the MQTT library waits for responses (PINGRESPs or
- * PUBACKs) from the MQTT broker.
- */
-#define IOT_MQTT_RESPONSE_WAIT_MS ( 10000 )
-
-/**
- * @brief Enable/Disable anonymous metrics collection when using AWS IoT.
- *
- * This demo does not use TLS and so does not work with AWS IoT. Therefore,
- * the metric collection must be disabled.
- */
-#define AWS_IOT_MQTT_ENABLE_METRICS 0
-
-/**
- * @brief Set the log level of the MQTT library.
- *
- * Log messages from the MQTT library at or below this setting will be printed.
- *
- * Possible values: One of the Log levels.
- * Default value (if undefined): IOT_LOG_LEVEL_GLOBAL; if that is undefined,
- * then IOT_LOG_NONE.
- */
-#define IOT_LOG_LEVEL_MQTT IOT_LOG_WARN
-
-/* Include the common configuration file for FreeRTOS. */
-#include "iot_config_common.h"
-
-#endif /* ifndef IOT_CONFIG_H_ */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config_common.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config_common.h
deleted file mode 100644
index 8d39bac4f..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_config_common.h
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
- * Amazon FreeRTOS V201906.00 Major
- * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* This file contains default configuration settings for the demos on FreeRTOS. */
-
-#ifndef IOT_CONFIG_COMMON_H_
-#define IOT_CONFIG_COMMON_H_
-
-/* FreeRTOS include. */
-#include "FreeRTOS.h" //_RB_Makes common config file FreeRTOS specific
-
-/* Use platform types on FreeRTOS. */
-#include "platform/iot_platform_types_freertos.h" //_RB_Makes common config file FreeRTOS specific
-
-/* SDK version. */
-#define IOT_SDK_VERSION "4.0.0"
-
-/* This config file is for the demos; disable any test code. */
-#define IOT_BUILD_TESTS ( 0 )
-
-/* Logging puts function. */
-#define IotLogging_Puts( str ) configPRINTF( ( "%s\r\n", str ) )
-
-/* Enable asserts in libraries by default. */
-#ifndef IOT_METRICS_ENABLE_ASSERTS
- #define IOT_METRICS_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_CONTAINERS_ENABLE_ASSERTS
- #define IOT_CONTAINERS_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_TASKPOOL_ENABLE_ASSERTS
- #define IOT_TASKPOOL_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_MQTT_ENABLE_ASSERTS
- #define IOT_MQTT_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef AWS_IOT_SHADOW_ENABLE_ASSERTS
- #define AWS_IOT_SHADOW_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef AWS_IOT_DEFENDER_ENABLE_ASSERTS
- #define AWS_IOT_DEFENDER_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_BLE_ENABLE_ASSERTS
- #define IOT_BLE_ENABLE_ASSERTS ( 1 )
-#endif
-
-/* Assert functions. */
-#define IotMetrics_Assert( expression ) configASSERT( expression )
-#define IotContainers_Assert( expression ) configASSERT( expression )
-#define IotTaskPool_Assert( expression ) configASSERT( expression )
-#define IotMqtt_Assert( expression ) configASSERT( expression )
-#define AwsIotShadow_Assert( expression ) configASSERT( expression )
-#define AwsIotDefender_Assert( expression ) configASSERT( expression )
-#define IotBle_Assert( expression ) configASSERT( expression )
-
-/* Control the usage of dynamic memory allocation. */
-#ifndef IOT_STATIC_MEMORY_ONLY
- #define IOT_STATIC_MEMORY_ONLY ( 0 )
-#endif
-
-/* Memory allocation configuration. Note that these functions will not be affected
- * by IOT_STATIC_MEMORY_ONLY. */
-#define IotNetwork_Malloc pvPortMalloc
-#define IotNetwork_Free vPortFree
-#define IotThreads_Malloc pvPortMalloc
-#define IotThreads_Free vPortFree
-#define IotLogging_Malloc pvPortMalloc
-#define IotLogging_Free vPortFree
-#define IotBle_Malloc pvPortMalloc
-#define IotBle_Free vPortFree
-/* #define IotLogging_StaticBufferSize */
-
-/* Memory allocation function configuration for the MQTT and Defender library.
- * These libraries will be affected by IOT_STATIC_MEMORY_ONLY. */
-#if IOT_STATIC_MEMORY_ONLY == 0
- #define IotMetrics_MallocTcpConnection pvPortMalloc
- #define IotMetrics_FreeTcpConnection vPortFree
- #define IotMetrics_MallocIpAddress pvPortMalloc
- #define IotMetrics_FreeIpAddress vPortFree
-
- #define IotTaskPool_MallocTaskPool pvPortMalloc
- #define IotTaskPool_FreeTaskPool vPortFree
- #define IotTaskPool_MallocJob pvPortMalloc
- #define IotTaskPool_FreeJob vPortFree
- #define IotTaskPool_MallocTimerEvent pvPortMalloc
- #define IotTaskPool_FreeTimerEvent vPortFree
-
- #define IotMqtt_MallocConnection pvPortMalloc
- #define IotMqtt_FreeConnection vPortFree
- #define IotMqtt_MallocMessage pvPortMalloc
- #define IotMqtt_FreeMessage vPortFree
- #define IotMqtt_MallocOperation pvPortMalloc
- #define IotMqtt_FreeOperation vPortFree
- #define IotMqtt_MallocSubscription pvPortMalloc
- #define IotMqtt_FreeSubscription vPortFree
-
- #define IotSerializer_MallocCborEncoder pvPortMalloc
- #define IotSerializer_FreeCborEncoder vPortFree
- #define IotSerializer_MallocCborParser pvPortMalloc
- #define IotSerializer_FreeCborParser vPortFree
- #define IotSerializer_MallocCborValue pvPortMalloc
- #define IotSerializer_FreeCborValue vPortFree
- #define IotSerializer_MallocDecoderObject pvPortMalloc
- #define IotSerializer_FreeDecoderObject vPortFree
-
- #define AwsIotShadow_MallocOperation pvPortMalloc
- #define AwsIotShadow_FreeOperation vPortFree
- #define AwsIotShadow_MallocString pvPortMalloc
- #define AwsIotShadow_FreeString vPortFree
- #define AwsIotShadow_MallocSubscription pvPortMalloc
- #define AwsIotShadow_FreeSubscription vPortFree
-
- #define AwsIotDefender_MallocReport pvPortMalloc
- #define AwsIotDefender_FreeReport vPortFree
- #define AwsIotDefender_MallocTopic pvPortMalloc
- #define AwsIotDefender_FreeTopic vPortFree
-#endif /* if IOT_STATIC_MEMORY_ONLY == 0 */
-
-/* Default platform thread stack size and priority. */
-#ifndef IOT_THREAD_DEFAULT_STACK_SIZE
- #define IOT_THREAD_DEFAULT_STACK_SIZE 2048
-#endif
-#ifndef IOT_THREAD_DEFAULT_PRIORITY
- #define IOT_THREAD_DEFAULT_PRIORITY tskIDLE_PRIORITY
-#endif
-
-/* Platform network configuration. */
-#ifndef IOT_NETWORK_RECEIVE_TASK_PRIORITY
- #define IOT_NETWORK_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
-#endif
-#ifndef IOT_NETWORK_RECEIVE_TASK_STACK_SIZE
- #define IOT_NETWORK_RECEIVE_TASK_STACK_SIZE IOT_THREAD_DEFAULT_STACK_SIZE
-#endif
-
-/* Platform and SDK name for AWS IoT MQTT metrics. Only used when
- * AWS_IOT_MQTT_ENABLE_METRICS is 1. */
-#define IOT_SDK_NAME "AmazonFreeRTOS"
-#ifdef configPLATFORM_NAME
- #define IOT_PLATFORM_NAME configPLATFORM_NAME
-#else
- #define IOT_PLATFORM_NAME "Unknown"
-#endif
-
-/* Cloud endpoint to which the device connects to. */
-#define IOT_CLOUD_ENDPOINT clientcredentialMQTT_BROKER_ENDPOINT
-
-/**
- * @brief Unique identifier used to recognize a device by the cloud.
- * This could be SHA-256 of the device certificate.
- */
-extern const char *getDeviceIdentifier( void );
-#define IOT_DEVICE_IDENTIFIER getDeviceIdentifier()
-
-/**
- * @brief Metrics emitted by the device.
- */
-extern const char *getDeviceMetrics( void );
-#define AWS_IOT_METRICS_USERNAME getDeviceMetrics()
-
-/**
- * @brief Length of the metrics emitted by device.
- */
-extern uint16_t getDeviceMetricsLength( void );
-#define AWS_IOT_METRICS_USERNAME_LENGTH getDeviceMetricsLength()
-
-/* Define the data type of metrics connection id as same as Socket_t in aws_secure_socket.h */
-#define IotMetricsConnectionId_t void *
-
-/* Configuration for defender demo: set format to CBOR. */
-#define AWS_IOT_DEFENDER_FORMAT AWS_IOT_DEFENDER_FORMAT_CBOR
-
-/* Configuration for defender demo: use long tag for readable output. Please use short tag for the real application. */
-#define AWS_IOT_DEFENDER_USE_LONG_TAG ( 1 )
-
-/* Demo runner configuration. */
-//_RB_#include "aws_demo_config.h"
-
-#endif /* ifndef IOT_CONFIG_COMMON_H_ */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_secure_sockets_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_secure_sockets_config.h
deleted file mode 100644
index 6442e8de2..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/iot_secure_sockets_config.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/*
- * Amazon FreeRTOS V1.4.7
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/**
- * @file aws_secure_sockets_config.h
- * @brief Secure sockets configuration options.
- */
-
-#ifndef _AWS_SECURE_SOCKETS_CONFIG_H_
-#define _AWS_SECURE_SOCKETS_CONFIG_H_
-
-/**
- * @brief Byte order of the target MCU.
- *
- * Valid values are pdLITTLE_ENDIAN and pdBIG_ENDIAN.
- */
-#define socketsconfigBYTE_ORDER pdLITTLE_ENDIAN
-
-/**
- * @brief Default socket send timeout.
- */
-#define socketsconfigDEFAULT_SEND_TIMEOUT ( 10000 )
-
-/**
- * @brief Default socket receive timeout.
- */
-#define socketsconfigDEFAULT_RECV_TIMEOUT ( 10000 )
-
-/**
- * @brief Enable metrics of secure socket.
- */
-#define AWS_IOT_SECURE_SOCKETS_METRICS_ENABLED ( 0 )
-
-#endif /* _AWS_SECURE_SOCKETS_CONFIG_H_ */ \ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/main.c
deleted file mode 100644
index f2f8eb5a2..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/main.c
+++ /dev/null
@@ -1,364 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
- /***
- * See https://www.FreeRTOS.org/mqtt/index.html for configuration and usage instructions.
- ***/
-
-/* Standard includes. */
-#include <stdio.h>
-#include <time.h>
-
-/* Visual studio intrinsics used so the __debugbreak() function is available
-should an assert get hit. */
-#include <intrin.h>
-
-/* FreeRTOS includes. */
-#include <FreeRTOS.h>
-#include "task.h"
-
-/* TCP/IP stack includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-
-/* Demo app includes. */
-#include "demo_logging.h"
-
-/*
- * Prototypes for the demos that can be started from this project. Note the
- * MQTT demo is not actually started until the network is already, which is
- * indicated by vApplicationIPNetworkEventHook() executing - hence
- * prvStartSimpleMQTTDemo() is called from inside vApplicationIPNetworkEventHook().
- */
-extern void vStartSimpleMQTTDemo( void );
-
-/*
- * Just seeds the simple pseudo random number generator.
- *
- * !!! NOTE !!!
- * This is not a secure method of generating random numbers and production
- * devices should use a true random number generator (TRNG).
- */
-static void prvSRand( UBaseType_t ulSeed );
-
-/*
- * Miscellaneous initialisation including preparing the logging and seeding the
- * random number generator.
- */
-static void prvMiscInitialisation( void );
-
-/* The default IP and MAC address used by the demo. The address configuration
-defined here will be used if ipconfigUSE_DHCP is 0, or if ipconfigUSE_DHCP is
-1 but a DHCP server could not be contacted. See the online documentation for
-more information. */
-static const uint8_t ucIPAddress[ 4 ] = { configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 };
-static const uint8_t ucNetMask[ 4 ] = { configNET_MASK0, configNET_MASK1, configNET_MASK2, configNET_MASK3 };
-static const uint8_t ucGatewayAddress[ 4 ] = { configGATEWAY_ADDR0, configGATEWAY_ADDR1, configGATEWAY_ADDR2, configGATEWAY_ADDR3 };
-static const uint8_t ucDNSServerAddress[ 4 ] = { configDNS_SERVER_ADDR0, configDNS_SERVER_ADDR1, configDNS_SERVER_ADDR2, configDNS_SERVER_ADDR3 };
-
-/* Set the following constant to pdTRUE to log using the method indicated by the
-name of the constant, or pdFALSE to not log using the method indicated by the
-name of the constant. Options include to standard out (xLogToStdout), to a disk
-file (xLogToFile), and to a UDP port (xLogToUDP). If xLogToUDP is set to pdTRUE
-then UDP messages are sent to the IP address configured as the echo server
-address (see the configECHO_SERVER_ADDR0 definitions in FreeRTOSConfig.h) and
-the port number set by configPRINT_PORT in FreeRTOSConfig.h. */
-const BaseType_t xLogToStdout = pdTRUE, xLogToFile = pdFALSE, xLogToUDP = pdFALSE;
-
-/* Default MAC address configuration. The demo creates a virtual network
-connection that uses this MAC address by accessing the raw Ethernet data
-to and from a real network connection on the host PC. See the
-configNETWORK_INTERFACE_TO_USE definition for information on how to configure
-the real network connection to use. */
-const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
-
-/* Use by the pseudo random number generator. */
-static UBaseType_t ulNextRand;
-/*-----------------------------------------------------------*/
-
-int main( void )
-{
- /***
- * See https://www.FreeRTOS.org/mqtt/index.html for configuration and usage instructions.
- ***/
-
- /* Miscellaneous initialisation including preparing the logging and seeding
- the random number generator. */
- prvMiscInitialisation();
-
- /* Initialise the network interface.
-
- ***NOTE*** Tasks that use the network are created in the network event hook
- when the network is connected and ready for use (see the implementation of
- vApplicationIPNetworkEventHook() below). The address values passed in here
- are used if ipconfigUSE_DHCP is set to 0, or if ipconfigUSE_DHCP is set to 1
- but a DHCP server cannot be contacted. */
- FreeRTOS_IPInit( ucIPAddress, ucNetMask, ucGatewayAddress, ucDNSServerAddress, ucMACAddress );
-
- /* Start the RTOS scheduler. */
- vTaskStartScheduler();
-
- /* If all is well, the scheduler will now be running, and the following
- line will never be reached. If the following line does execute, then
- there was insufficient FreeRTOS heap memory available for the idle and/or
- timer tasks to be created. See the memory management section on the
- FreeRTOS web site for more details (this is standard text that is not not
- really applicable to the Win32 simulator port). */
- for( ;; )
- {
- __debugbreak();
- }
-}
-/*-----------------------------------------------------------*/
-
-/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect
-events are only received if implemented in the MAC driver. */
-void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
-{
-uint32_t ulIPAddress, ulNetMask, ulGatewayAddress, ulDNSServerAddress;
-char cBuffer[ 16 ];
-static BaseType_t xTasksAlreadyCreated = pdFALSE;
-
- /* If the network has just come up...*/
- if( eNetworkEvent == eNetworkUp )
- {
- /* Create the tasks that use the IP stack if they have not already been
- created. */
- if( xTasksAlreadyCreated == pdFALSE )
- {
- /* Demos that use the nextwork are created after the nextwork is
- up. */
- vStartSimpleMQTTDemo();
- xTasksAlreadyCreated = pdTRUE;
- }
-
- /* Print out the network configuration, which may have come from a DHCP
- server. */
- FreeRTOS_GetAddressConfiguration( &ulIPAddress, &ulNetMask, &ulGatewayAddress, &ulDNSServerAddress );
- FreeRTOS_inet_ntoa( ulIPAddress, cBuffer );
- FreeRTOS_printf( ( "\r\n\r\nIP Address: %s\r\n", cBuffer ) );/*_RB_ Should use IoT libraries logging. */
-
- FreeRTOS_inet_ntoa( ulNetMask, cBuffer );
- FreeRTOS_printf( ( "Subnet Mask: %s\r\n", cBuffer ) );
-
- FreeRTOS_inet_ntoa( ulGatewayAddress, cBuffer );
- FreeRTOS_printf( ( "Gateway Address: %s\r\n", cBuffer ) );
-
- FreeRTOS_inet_ntoa( ulDNSServerAddress, cBuffer );
- FreeRTOS_printf( ( "DNS Server Address: %s\r\n\r\n\r\n", cBuffer ) );
- }
-}
-/*-----------------------------------------------------------*/
-
-void vAssertCalled( const char *pcFile, uint32_t ulLine )
-{
- volatile uint32_t ulBlockVariable = 0UL;
- volatile char *pcFileName = ( volatile char * ) pcFile;
- volatile uint32_t ulLineNumber = ulLine;
-
- ( void ) pcFileName;
- ( void ) ulLineNumber;
-
- printf( "vAssertCalled( %s, %u\n", pcFile, ulLine );
-
- /* Setting ulBlockVariable to a non-zero value in the debugger will allow
- this function to be exited. */
- taskDISABLE_INTERRUPTS();
- {
- while( ulBlockVariable == 0UL )
- {
- __debugbreak();
- }
- }
- taskENABLE_INTERRUPTS();
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxRand( void )
-{
-const uint32_t ulMultiplier = 0x015a4e35UL, ulIncrement = 1UL;
-
- /*
- * Utility function to generate a pseudo random number.
- *
- * !!!NOTE!!!
- * This is not a secure method of generating a random number. Production
- * devices should use a True Random Number Generator (TRNG).
- */
- ulNextRand = ( ulMultiplier * ulNextRand ) + ulIncrement;
- return( ( int ) ( ulNextRand >> 16UL ) & 0x7fffUL );
-}
-/*-----------------------------------------------------------*/
-
-static void prvSRand( UBaseType_t ulSeed )
-{
- /* Utility function to seed the pseudo random number generator. */
- ulNextRand = ulSeed;
-}
-/*-----------------------------------------------------------*/
-
-static void prvMiscInitialisation( void )
-{
-time_t xTimeNow;
-uint32_t ulLoggingIPAddress;
-
- ulLoggingIPAddress = FreeRTOS_inet_addr_quick( configECHO_SERVER_ADDR0, configECHO_SERVER_ADDR1, configECHO_SERVER_ADDR2, configECHO_SERVER_ADDR3 );
- vLoggingInit( xLogToStdout, xLogToFile, xLogToUDP, ulLoggingIPAddress, configPRINT_PORT );
-
- /*
- * Seed random number generator.
- *
- * !!!NOTE!!!
- * This is not a secure method of generating a random number. Production
- * devices should use a True Random Number Generator (TRNG).
- */
- time( &xTimeNow );
- FreeRTOS_debug_printf( ( "Seed for randomiser: %lu\n", xTimeNow ) );
- prvSRand( ( uint32_t ) xTimeNow );
- FreeRTOS_debug_printf( ( "Random numbers: %08X %08X %08X %08X\n", ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32(), ipconfigRAND32() ) );
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) || ( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
-
- const char *pcApplicationHostnameHook( void )
- {
- /* Assign the name "FreeRTOS" to this network node. This function will
- be called during the DHCP: the machine will be registered with an IP
- address plus this name. */
- return mainHOST_NAME;
- }
-
-#endif
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 )
-
- BaseType_t xApplicationDNSQueryHook( const char *pcName )
- {
- BaseType_t xReturn;
-
- /* Determine if a name lookup is for this node. Two names are given
- to this node: that returned by pcApplicationHostnameHook() and that set
- by mainDEVICE_NICK_NAME. */
- if( _stricmp( pcName, pcApplicationHostnameHook() ) == 0 )
- {
- xReturn = pdPASS;
- }
- else if( _stricmp( pcName, mainDEVICE_NICK_NAME ) == 0 )
- {
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- return xReturn;
- }
-
-#endif
-/*-----------------------------------------------------------*/
-
-/*
- * Callback that provides the inputs necessary to generate a randomized TCP
- * Initial Sequence Number per RFC 6528. THIS IS ONLY A DUMMY IMPLEMENTATION
- * THAT RETURNS A PSEUDO RANDOM NUMBER SO IS NOT INTENDED FOR USE IN PRODUCTION
- * SYSTEMS.
- */
-extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
- uint16_t usSourcePort,
- uint32_t ulDestinationAddress,
- uint16_t usDestinationPort )
-{
- ( void ) ulSourceAddress;
- ( void ) usSourcePort;
- ( void ) ulDestinationAddress;
- ( void ) usDestinationPort;
-
- return uxRand();
-}
-/*-----------------------------------------------------------*/
-
-/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
-implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
-used by the Idle task. */
-void vApplicationGetIdleTaskMemory( StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer, uint32_t* pulIdleTaskStackSize )
-{
- /* If the buffers to be provided to the Idle task are declared inside this
- function then they must be declared static - otherwise they will be allocated on
- the stack and so not exists after this function exits. */
- static StaticTask_t xIdleTaskTCB;
- static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
-
- /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
- state will be stored. */
- *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
-
- /* Pass out the array that will be used as the Idle task's stack. */
- *ppxIdleTaskStackBuffer = uxIdleTaskStack;
-
- /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
- Note that, as the array is necessarily of type StackType_t,
- configMINIMAL_STACK_SIZE is specified in words, not bytes. */
- *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
-}
-/*-----------------------------------------------------------*/
-
-/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
-application must provide an implementation of vApplicationGetTimerTaskMemory()
-to provide the memory that is used by the Timer service task. */
-void vApplicationGetTimerTaskMemory( StaticTask_t** ppxTimerTaskTCBBuffer, StackType_t** ppxTimerTaskStackBuffer, uint32_t* pulTimerTaskStackSize )
-{
- /* If the buffers to be provided to the Timer task are declared inside this
- function then they must be declared static - otherwise they will be allocated on
- the stack and so not exists after this function exits. */
- static StaticTask_t xTimerTaskTCB;
- static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
-
- /* Pass out a pointer to the StaticTask_t structure in which the Timer
- task's state will be stored. */
- *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
-
- /* Pass out the array that will be used as the Timer task's stack. */
- *ppxTimerTaskStackBuffer = uxTimerTaskStack;
-
- /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
- Note that, as the array is necessarily of type StackType_t,
- configMINIMAL_STACK_SIZE is specified in words, not bytes. */
- *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
-}
-/*-----------------------------------------------------------*/
-
-
-
-
-
-
-
-
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_demo.sln b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_demo.sln
deleted file mode 100644
index b362f36c5..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_demo.sln
+++ /dev/null
@@ -1,23 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"
-EndProject
-Global
- GlobalSection(TestCaseManagementSettings) = postSolution
- CategoryFile = FreeRTOS_Plus_TCP_Minimal.vsmdi
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/printf-stdarg.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/printf-stdarg.c
deleted file mode 100644
index 5505535c1..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/mqtt/printf-stdarg.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- Copyright 2001, 2002 Georges Menie (www.menie.org)
- stdarg version contributed by Christian Ettinger
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- Changes for the FreeRTOS ports:
-
- - The dot in "%-8.8s"
- - The specifiers 'l' (long) and 'L' (long long)
- - The specifier 'u' for unsigned
- - Dot notation for IP addresses:
- sprintf("IP = %xip\n", 0xC0A80164);
- will produce "IP = 192.168.1.100\n"
-*/
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "FreeRTOS.h"
-
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-
-/*
- * Return 1 for readable, 2 for writeable, 3 for both.
- * Function must be provided by the application.
- */
-extern BaseType_t xApplicationMemoryPermissions( uint32_t aAddress );
-
-extern void vOutputChar( const char cChar, const TickType_t xTicksToWait );
-static const TickType_t xTicksToWait = pdMS_TO_TICKS( 20 );
-
-struct xPrintFlags
-{
- int base;
- int width;
- int printLimit;
- unsigned
- pad : 8,
- letBase : 8,
- isSigned : 1,
- isNumber : 1,
- long32 : 1,
- long64 : 1;
-};
-
-struct SStringBuf
-{
- char *str;
- const char *orgStr;
- const char *nulPos;
- int curLen;
- struct xPrintFlags flags;
-};
-
-static void strbuf_init( struct SStringBuf *apStr, char *apBuf, const char *apMaxStr )
-{
- apStr->str = apBuf;
- apStr->orgStr = apBuf;
- apStr->nulPos = apMaxStr-1;
- apStr->curLen = 0;
-
- memset( &apStr->flags, '\0', sizeof( apStr->flags ) );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t strbuf_printchar( struct SStringBuf *apStr, int c )
-{
- if( apStr->str == NULL )
- {
- vOutputChar( ( char ) c, xTicksToWait );
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str < apStr->nulPos )
- {
- *( apStr->str++ ) = c;
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str == apStr->nulPos )
- {
- *( apStr->str++ ) = '\0';
- }
- return pdFALSE;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE BaseType_t strbuf_printchar_inline( struct SStringBuf *apStr, int c )
-{
- if( apStr->str == NULL )
- {
- vOutputChar( ( char ) c, xTicksToWait );
- if( c == 0 )
- {
- return pdFALSE;
- }
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str < apStr->nulPos )
- {
- *(apStr->str++) = c;
- if( c == 0 )
- {
- return pdFALSE;
- }
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str == apStr->nulPos )
- {
- *( apStr->str++ ) = '\0';
- }
- return pdFALSE;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE int i2hex( int aCh )
-{
-int iResult;
-
- if( aCh < 10 )
- {
- iResult = '0' + aCh;
- }
- else
- {
- iResult = 'A' + aCh - 10;
- }
-
- return iResult;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prints(struct SStringBuf *apBuf, const char *apString )
-{
- register int padchar = ' ';
- int i,len;
-
- if( xApplicationMemoryPermissions( ( uint32_t )apString ) == 0 )
- {
- /* The user has probably made a mistake with the parameter
- for '%s', the memory is not readbale. */
- apString = "INV_MEM";
- }
-
- if( apBuf->flags.width > 0 )
- {
- register int len = 0;
- register const char *ptr;
- for( ptr = apString; *ptr; ++ptr )
- {
- ++len;
- }
-
- if( len >= apBuf->flags.width )
- {
- apBuf->flags.width = 0;
- }
- else
- {
- apBuf->flags.width -= len;
- }
-
- if( apBuf->flags.pad & PAD_ZERO )
- {
- padchar = '0';
- }
- }
- if( ( apBuf->flags.pad & PAD_RIGHT ) == 0 )
- {
- for( ; apBuf->flags.width > 0; --apBuf->flags.width )
- {
- if( strbuf_printchar( apBuf, padchar ) == 0 )
- {
- return pdFALSE;
- }
- }
- }
- if( ( apBuf->flags.isNumber == pdTRUE ) && ( apBuf->flags.pad == pdTRUE ) )
- {
- /* The string to print represents an integer number.
- * In this case, printLimit is the min number of digits to print
- * If the length of the number to print is less than the min nb of i
- * digits to display, we add 0 before printing the number
- */
- len = strlen( apString );
-
- if( len < apBuf->flags.printLimit )
- {
- i = apBuf->flags.printLimit - len;
- for( ; i; i-- )
- {
- if( strbuf_printchar( apBuf, '0' ) == 0 )
- {
- return pdFALSE;
- }
- }
- }
- }
- /* The string to print is not the result of a number conversion to ascii.
- * For a string, printLimit is the max number of characters to display
- */
- for( ; apBuf->flags.printLimit && *apString ; ++apString, --apBuf->flags.printLimit )
- {
- if( !strbuf_printchar( apBuf, *apString ) )
- {
- return pdFALSE;
- }
- }
-
- for( ; apBuf->flags.width > 0; --apBuf->flags.width )
- {
- if( !strbuf_printchar( apBuf, padchar ) )
- {
- return pdFALSE;
- }
- }
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-/* the following should be enough for 32 bit int */
-#define PRINT_BUF_LEN 12 /* to print 4294967296 */
-
-#if SPRINTF_LONG_LONG
-#warning 64-bit libraries will be included as well
-static BaseType_t printll( struct SStringBuf *apBuf, long long i )
-{
- char print_buf[ 2 * PRINT_BUF_LEN ];
- register char *s;
- register int t, neg = 0;
- register unsigned long long u = i;
- lldiv_t lldiv_result;
-
-/* typedef struct
- * {
- * long long int quot; // quotient
- * long long int rem; // remainder
- * } lldiv_t;
- */
-
- apBuf->flags.isNumber = pdTRUE; /* Parameter for prints */
- if( i == 0LL )
- {
- print_buf[ 0 ] = '0';
- print_buf[ 1 ] = '\0';
- return prints( apBuf, print_buf );
- }
-
- if( ( apBuf->flags.isSigned == pdTRUE ) && ( apBuf->flags.base == 10 ) && ( i < 0LL ) )
- {
- neg = 1;
- u = -i;
- }
-
- s = print_buf + sizeof( print_buf ) - 1;
-
- *s = '\0';
- /* 18446744073709551616 */
- while( u != 0 )
- {
- lldiv_result = lldiv( u, ( unsigned long long ) apBuf->flags.base );
- t = lldiv_result.rem;
- if( t >= 10 )
- {
- t += apBuf->flags.letBase - '0' - 10;
- }
- *( --s ) = t + '0';
- u = lldiv_result.quot;
- }
-
- if( neg != 0 )
- {
- if( ( apBuf->flags.width != 0 ) && ( apBuf->flags.pad & PAD_ZERO ) )
- {
- if( !strbuf_printchar( apBuf, '-' ) )
- {
- return pdFALSE;
- }
- --apBuf->flags.width;
- }
- else
- {
- *( --s ) = '-';
- }
- }
-
- return prints( apBuf, s );
-}
-#endif /* SPRINTF_LONG_LONG */
-/*-----------------------------------------------------------*/
-
-static BaseType_t printi( struct SStringBuf *apBuf, int i )
-{
- char print_buf[ PRINT_BUF_LEN ];
- register char *s;
- register int t, neg = 0;
- register unsigned int u = i;
- register unsigned base = apBuf->flags.base;
-
- apBuf->flags.isNumber = pdTRUE; /* Parameter for prints */
-
- if( i == 0 )
- {
- print_buf[ 0 ] = '0';
- print_buf[ 1 ] = '\0';
- return prints( apBuf, print_buf );
- }
-
- if( ( apBuf->flags.isSigned == pdTRUE ) && ( base == 10 ) && ( i < 0 ) )
- {
- neg = 1;
- u = -i;
- }
-
- s = print_buf + sizeof( print_buf ) - 1;
-
- *s = '\0';
- switch( base )
- {
- case 16:
- while( u != 0 )
- {
- t = u & 0xF;
- if( t >= 10 )
- {
- t += apBuf->flags.letBase - '0' - 10;
- }
- *( --s ) = t + '0';
- u >>= 4;
- }
- break;
-
- case 8:
- case 10:
- /* GCC compiles very efficient */
- while( u )
- {
- t = u % base;
- *( --s ) = t + '0';
- u /= base;
- }
- break;
-/*
- // The generic case, not yet in use
- default:
- while( u )
- {
- t = u % base;
- if( t >= 10)
- {
- t += apBuf->flags.letBase - '0' - 10;
- }
- *( --s ) = t + '0';
- u /= base;
- }
- break;
-*/
- }
-
- if( neg != 0 )
- {
- if( apBuf->flags.width && (apBuf->flags.pad & PAD_ZERO ) )
- {
- if( strbuf_printchar( apBuf, '-' ) == 0 )
- {
- return pdFALSE;
- }
- --apBuf->flags.width;
- }
- else
- {
- *( --s ) = '-';
- }
- }
-
- return prints( apBuf, s );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t printIp(struct SStringBuf *apBuf, unsigned i )
-{
- char print_buf[16];
-
- sprintf( print_buf, "%u.%u.%u.%u",
- i >> 24,
- ( i >> 16 ) & 0xff,
- ( i >> 8 ) & 0xff,
- i & 0xff );
- apBuf->flags.isNumber = pdTRUE; /* Parameter for prints */
- prints( apBuf, print_buf );
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static void tiny_print( struct SStringBuf *apBuf, const char *format, va_list args )
-{
- char scr[2];
-
- for( ; ; )
- {
- int ch = *( format++ );
-
- if( ch != '%' )
- {
- do
- {
- /* Put the most like flow in a small loop */
- if( strbuf_printchar_inline( apBuf, ch ) == 0 )
- {
- return;
- }
- ch = *( format++ );
- } while( ch != '%' );
- }
- ch = *( format++ );
- /* Now ch has character after '%', format pointing to next */
-
- if( ch == '\0' )
- {
- break;
- }
- if( ch == '%' )
- {
- if( strbuf_printchar( apBuf, ch ) == 0 )
- {
- return;
- }
- continue;
- }
- memset( &apBuf->flags, '\0', sizeof( apBuf->flags ) );
-
- if( ch == '-' )
- {
- ch = *( format++ );
- apBuf->flags.pad = PAD_RIGHT;
- }
- while( ch == '0' )
- {
- ch = *( format++ );
- apBuf->flags.pad |= PAD_ZERO;
- }
- if( ch == '*' )
- {
- ch = *( format++ );
- apBuf->flags.width = va_arg( args, int );
- }
- else
- {
- while( ch >= '0' && ch <= '9' )
- {
- apBuf->flags.width *= 10;
- apBuf->flags.width += ch - '0';
- ch = *( format++ );
- }
- }
- if( ch == '.' )
- {
- ch = *( format++ );
- if( ch == '*' )
- {
- apBuf->flags.printLimit = va_arg( args, int );
- ch = *( format++ );
- }
- else
- {
- while( ch >= '0' && ch <= '9' )
- {
- apBuf->flags.printLimit *= 10;
- apBuf->flags.printLimit += ch - '0';
- ch = *( format++ );
- }
- }
- }
- if( apBuf->flags.printLimit == 0 )
- {
- apBuf->flags.printLimit--; /* -1: make it unlimited */
- }
- if( ch == 's' )
- {
- register char *s = ( char * )va_arg( args, int );
- if( prints( apBuf, s ? s : "(null)" ) == 0 )
- {
- break;
- }
- continue;
- }
- if( ch == 'c' )
- {
- /* char are converted to int then pushed on the stack */
- scr[0] = ( char ) va_arg( args, int );
-
- if( strbuf_printchar( apBuf, scr[0] ) == 0 )
- {
- return;
- }
-
- continue;
- }
- if( ch == 'l' )
- {
- ch = *( format++ );
- apBuf->flags.long32 = 1;
- /* Makes not difference as u32 == long */
- }
- if( ch == 'L' )
- {
- ch = *( format++ );
- apBuf->flags.long64 = 1;
- /* Does make a difference */
- }
- apBuf->flags.base = 10;
- apBuf->flags.letBase = 'a';
-
- if( ch == 'd' || ch == 'u' )
- {
- apBuf->flags.isSigned = ( ch == 'd' );
-#if SPRINTF_LONG_LONG
- if( apBuf->flags.long64 != pdFALSE )
- {
- if( printll( apBuf, va_arg( args, long long ) ) == 0 )
- {
- break;
- }
- } else
-#endif /* SPRINTF_LONG_LONG */
- if( printi( apBuf, va_arg( args, int ) ) == 0 )
- {
- break;
- }
- continue;
- }
-
- apBuf->flags.base = 16; /* From here all hexadecimal */
-
- if( ch == 'x' && format[0] == 'i' && format[1] == 'p' )
- {
- format += 2; /* eat the "xi" of "xip" */
- /* Will use base 10 again */
- if( printIp( apBuf, va_arg( args, int ) ) == 0 )
- {
- break;
- }
- continue;
- }
- if( ch == 'x' || ch == 'X' || ch == 'p' || ch == 'o' )
- {
- if( ch == 'X' )
- {
- apBuf->flags.letBase = 'A';
- }
- else if( ch == 'o' )
- {
- apBuf->flags.base = 8;
- }
-#if SPRINTF_LONG_LONG
- if( apBuf->flags.long64 != pdFALSE )
- {
- if( printll( apBuf, va_arg( args, long long ) ) == 0 )
- {
- break;
- }
- } else
-#endif /* SPRINTF_LONG_LONG */
- if( printi( apBuf, va_arg( args, int ) ) == 0 )
- {
- break;
- }
- continue;
- }
- }
- strbuf_printchar( apBuf, '\0' );
-}
-/*-----------------------------------------------------------*/
-
-int vsnprintf( char *apBuf, size_t aMaxLen, const char *apFmt, va_list args )
-{
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char* )apBuf + aMaxLen );
- tiny_print( &strBuf, apFmt, args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-int snprintf( char *apBuf, size_t aMaxLen, const char *apFmt, ... )
-{
- va_list args;
-
- va_start( args, apFmt );
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char* )apBuf + aMaxLen );
- tiny_print( &strBuf, apFmt, args );
- va_end( args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-int sprintf( char *apBuf, const char *apFmt, ... )
-{
- va_list args;
-
- va_start( args, apFmt );
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char * )apBuf + 1024 );
- tiny_print( &strBuf, apFmt, args );
- va_end( args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-int vsprintf( char *apBuf, const char *apFmt, va_list args )
-{
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char* ) apBuf + 1024 );
- tiny_print( &strBuf, apFmt, args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-const char *mkSize (unsigned long long aSize, char *apBuf, int aLen)
-{
-static char retString[33];
-size_t gb, mb, kb, sb;
-
- if (apBuf == NULL) {
- apBuf = retString;
- aLen = sizeof( retString );
- }
- gb = aSize / (1024*1024*1024);
- aSize -= gb * (1024*1024*1024);
- mb = aSize / (1024*1024);
- aSize -= mb * (1024*1024);
- kb = aSize / (1024);
- aSize -= kb * (1024);
- sb = aSize;
- if( gb )
- {
- snprintf (apBuf, aLen, "%u.%02u GB", ( unsigned ) gb, ( unsigned ) ( ( 100 * mb ) / 1024ul ) );
- }
- else if( mb )
- {
- snprintf (apBuf, aLen, "%u.%02u MB", ( unsigned ) mb, ( unsigned ) ( ( 100 * kb) / 1024ul ) );
- }
- else if( kb != 0ul )
- {
- snprintf (apBuf, aLen, "%u.%02u KB", ( unsigned ) kb, ( unsigned ) ( ( 100 * sb) / 1024ul ) );
- }
- else
- {
- snprintf (apBuf, aLen, "%u bytes", ( unsigned ) sb);
- }
- return apBuf;
-}
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleTaskPoolExamples.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleTaskPoolExamples.c
deleted file mode 100644
index fb2eaca26..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleTaskPoolExamples.c
+++ /dev/null
@@ -1,695 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-
-/* Kernel includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-
-/* Standard includes. */
-#include <stdio.h>
-
-/* IoT SDK includes. */
-#include "iot_taskpool.h"
-
-/* The priority at which that tasks in the task pool (the worker tasks) get
-created. */
-#define tpTASK_POOL_WORKER_PRIORITY 1
-
-/*
- * Prototypes for the functions that demonstrate the task pool API.
- * See the implementation of the prvTaskPoolDemoTask() function within this file
- * for a description of the individual functions. A configASSERT() is hit if
- * any of the demos encounter any unexpected behaviour.
- */
-static void prvExample_BasicSingleJob( void );
-static void prvExample_DeferredJobAndCancellingJobs( void );
-static void prvExample_BasicRecyclableJob( void );
-static void prvExample_ReuseRecyclableJobFromLowPriorityTask( void );
-static void prvExample_ReuseRecyclableJobFromHighPriorityTask( void );
-
-/*
- * Prototypes of the callback functions used in the examples. The callback
- * simply sends a signal (in the form of a direct task notification) to the
- * prvTaskPoolDemoTask() task to let the task know that the callback execute.
- * The handle of the prvTaskPoolDemoTask() task is not accessed directly, but
- * instead passed into the task pool job as the job's context.
- */
-static void prvSimpleTaskNotifyCallback( IotTaskPool_t pTaskPool, IotTaskPoolJob_t pJob, void *pUserContext );
-
-/*
- * The task used to demonstrate the task pool API. This task just loops through
- * each demo in turn.
- */
-static void prvTaskPoolDemoTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* Parameters used to create the system task pool - see TBD for more information
- * as the task pool used in this example is a slimmed down version of the full
- * library - the slimmed down version being intended specifically for FreeRTOS
- * kernel use cases. */
-static const IotTaskPoolInfo_t xTaskPoolParameters = {
- /* Minimum number of threads in a task pool.
- * Note the slimmed down version of the task
- * pool used by this library does not autoscale
- * the number of tasks in the pool so in this
- * case this sets the number of tasks in the
- * pool. */
- 2,
- /* Maximum number of threads in a task pool.
- * Note the slimmed down version of the task
- * pool used by this library does not autoscale
- * the number of tasks in the pool so in this
- * case this parameter is just ignored. */
- 2,
- /* Stack size for every task pool thread - in
- * bytes, hence multiplying by the number of bytes
- * in a word as configMINIMAL_STACK_SIZE is
- * specified in words. */
- configMINIMAL_STACK_SIZE * sizeof( portSTACK_TYPE ),
- /* Priority for every task pool thread. */
- tpTASK_POOL_WORKER_PRIORITY,
- };
-
-/*-----------------------------------------------------------*/
-
-void vStartSimpleTaskPoolDemo( void )
-{
- /* This example uses a single application task, which in turn is used to
- * create and send jobs to task pool tasks. */
- xTaskCreate( prvTaskPoolDemoTask, /* Function that implements the task. */
- "PoolDemo", /* Text name for the task - only used for debugging. */
- configMINIMAL_STACK_SIZE, /* Size of stack (in words, not bytes) to allocate for the task. */
- NULL, /* Task parameter - not used in this case. */
- tskIDLE_PRIORITY, /* Task priority, must be between 0 and configMAX_PRIORITIES - 1. */
- NULL ); /* Used to pass out a handle to the created task - not used in this case. */
-}
-/*-----------------------------------------------------------*/
-
-static void prvTaskPoolDemoTask( void *pvParameters )
-{
-IotTaskPoolError_t xResult;
-uint32_t ulLoops = 0;
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- /* The task pool must be created before it can be used. The system task
- * pool is the task pool managed by the task pool library itself - the storage
- * used by the task pool is provided by the library. */
- xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Attempting to create the task pool again should then appear to succeed
- * (in case it is initialised by more than one library), but have no effect. */
- xResult = IotTaskPool_CreateSystemTaskPool( &xTaskPoolParameters );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- for( ;; )
- {
- /* Demonstrate the most basic use case where a non persistent job is
- * created and scheduled to run immediately. The task pool worker tasks
- * (in which the job callback function executes) have a priority above the
- * priority of this task so the job's callback executes as soon as it is
- * scheduled. */
- prvExample_BasicSingleJob();
-
- /* Demonstrate a job being scheduled to run at some time in the
- * future, and how a job scheduled to run in the future can be cancelled
- * if it has not yet started executing. */
- prvExample_DeferredJobAndCancellingJobs();
-
- /* Demonstrate the most basic use of a recyclable job. This is similar
- * to prvExample_BasicSingleJob() but using a recyclable job. Creating a
- * recyclable job will re-use a previously created and now spare job from
- * the task pool's job cache if one is available, or otherwise dynamically
- * create a new job if a spare job is not available in the cache but space
- * remains in the cache. */
- prvExample_BasicRecyclableJob();
-
- /* Demonstrate a recyclable job being created, used, and then re-used.
- * In this the task pool worker tasks (in which the job callback
- * functions execute) have a priority above the priority of this task so
- * the job's callback functions execute as soon as they are scheduled. */
- prvExample_ReuseRecyclableJobFromLowPriorityTask();
-
- /* Again demonstrate a recyclable job being created, used, and then
- * re-usedbut this time the priority of the task pool worker tasks (in
- * which the job callback functions execute) are lower than the priority
- * of this task so the job's callback functions don't execute until this
- * task enters the blocked state. */
- prvExample_ReuseRecyclableJobFromHighPriorityTask();
-
- ulLoops++;
- if( ( ulLoops % 10UL ) == 0 )
- {
- configPRINTF( ( "prvTaskPoolDemoTask() performed %u iterations without hitting an assert.\r\n", ulLoops ) );
- fflush( stdout );
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvSimpleTaskNotifyCallback( IotTaskPool_t pTaskPool, IotTaskPoolJob_t pJob, void *pUserContext )
-{
-/* The jobs context is the handle of the task to which a notification should
- * be sent. */
-TaskHandle_t xTaskToNotify = ( TaskHandle_t ) pUserContext;
-
- /* Remove warnings about unused parameters. */
- ( void ) pTaskPool;
- ( void ) pJob;
-
- /* Notify the task that created this job. */
- xTaskNotifyGive( xTaskToNotify );
-}
-/*-----------------------------------------------------------*/
-
-static void prvExample_BasicSingleJob( void )
-{
-IotTaskPoolJobStorage_t xJobStorage;
-IotTaskPoolJob_t xJob;
-IotTaskPoolError_t xResult;
-uint32_t ulReturn;
-const uint32_t ulNoFlags = 0UL;
-const TickType_t xNoDelay = ( TickType_t ) 0;
-size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
-IotTaskPoolJobStatus_t xJobStatus;
-
- /* Don't expect any notifications to be pending yet. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* Create and schedule a job using the handle of this task as the job's
- * context and the function that sends a notification to the task handle as
- * the job's callback function. This is not a recyclable job so the storage
- * required to hold information about the job is provided by this task - in
- * this case the storage is on the stack of this task so no memory is allocated
- * dynamically but the stack frame must remain in scope for the lifetime of
- * the job. */
- xResult = IotTaskPool_CreateJob( prvSimpleTaskNotifyCallback, /* Callback function. */
- ( void * ) xTaskGetCurrentTaskHandle(), /* Job context. */
- &xJobStorage,
- &xJob );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The job has been created but not scheduled so is now ready. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
-
- /* This is not a persistent (recyclable) job and its storage is on the
- * stack of this function, so the amount of heap space available should not
- * have changed since entering this function. */
- configASSERT( xFreeHeapBeforeCreatingJob == xPortGetFreeHeapSize() );
-
- /* In the full task pool implementation the first parameter is used to
- * pass the handle of the task pool to schedule. The lean task pool
- * implementation used in this demo only supports a single task pool, which
- * is created internally within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_Schedule( NULL, xJob, ulNoFlags );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Look for the notification coming from the job's callback function. The
- * priority of the task pool worker task that executes the callback is higher
- * than the priority of this task so a block time is not needed - the task pool
- * worker task preempts this task and sends the notification (from the job's
- * callback) as soon as the job is scheduled. */
- ulReturn = ulTaskNotifyTake( pdTRUE, xNoDelay );
- configASSERT( ulReturn );
-
- /* The job's callback has executed so the job has now completed. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
-}
-/*-----------------------------------------------------------*/
-
-static void prvExample_DeferredJobAndCancellingJobs( void )
-{
-IotTaskPoolJobStorage_t xJobStorage;
-IotTaskPoolJob_t xJob;
-IotTaskPoolError_t xResult;
-uint32_t ulReturn;
-const uint32_t ulShortDelay_ms = 100UL;
-const TickType_t xNoDelay = ( TickType_t ) 0, xAllowableMargin = ( TickType_t ) 5; /* Large margin for Windows port, which is not real time. */
-TickType_t xTimeBefore, xElapsedTime, xShortDelay_ticks;
-size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
-IotTaskPoolJobStatus_t xJobStatus;
-
- /* Don't expect any notifications to be pending yet. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* Create a job using the handle of this task as the job's context and the
- * function that sends a notification to the task handle as the job's callback
- * function. The job is created using storage allocated on the stack of this
- * function - so no memory is allocated. */
- xResult = IotTaskPool_CreateJob( prvSimpleTaskNotifyCallback, /* Callback function. */
- ( void * ) xTaskGetCurrentTaskHandle(), /* Job context. */
- &xJobStorage,
- &xJob );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The job has been created but not scheduled so is now ready. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
-
- /* This is not a persistent (recyclable) job and its storage is on the
- * stack of this function, so the amount of heap space available should not
- * have changed since entering this function. */
- configASSERT( xFreeHeapBeforeCreatingJob == xPortGetFreeHeapSize() );
-
- /* Schedule the job to run its callback in ulShortDelay_ms milliseconds time.
- * In the full task pool implementation the first parameter is used to pass the
- * handle of the task pool to schedule. The lean task pool implementation used
- * in this demo only supports a single task pool, which is created internally
- * within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_ScheduleDeferred( NULL, xJob, ulShortDelay_ms );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The scheduled job should not have executed yet, so don't expect any
- * notifications and expect the job's status to be 'deferred'. */
- ulReturn = ulTaskNotifyTake( pdTRUE, xNoDelay );
- configASSERT( ulReturn == 0 );
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_DEFERRED );
-
- /* As the job has not yet been executed it can be cancelled. */
- xResult = IotTaskPool_TryCancel( NULL, xJob, &xJobStatus );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_CANCELED );
-
- /* Schedule the job again, and this time wait until its callback is
- * executed (the callback function sends a notification to this task) to see
- * that it executes at the right time. */
- xTimeBefore = xTaskGetTickCount();
- xResult = IotTaskPool_ScheduleDeferred( NULL, xJob, ulShortDelay_ms );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Wait twice the deferred execution time to ensure the callback is executed
- * before the call below times out. */
- ulReturn = ulTaskNotifyTake( pdTRUE, pdMS_TO_TICKS( ulShortDelay_ms * 2UL ) );
- xElapsedTime = xTaskGetTickCount() - xTimeBefore;
-
- /* A single notification should have been received... */
- configASSERT( ulReturn == 1 );
-
- /* ...and the time since scheduling the job should be greater than or
- * equal to the deferred execution time - which is converted to ticks for
- * comparison. */
- xShortDelay_ticks = pdMS_TO_TICKS( ulShortDelay_ms );
- configASSERT( ( xElapsedTime >= xShortDelay_ticks ) && ( xElapsedTime < ( xShortDelay_ticks + xAllowableMargin ) ) );
-}
-/*-----------------------------------------------------------*/
-
-static void prvExample_BasicRecyclableJob( void )
-{
-IotTaskPoolJob_t xJob;
-IotTaskPoolError_t xResult;
-uint32_t ulReturn;
-const uint32_t ulNoFlags = 0UL;
-const TickType_t xNoDelay = ( TickType_t ) 0;
-size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize();
-
- /* Don't expect any notifications to be pending yet. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* Create and schedule a job using the handle of this task as the job's
- * context and the function that sends a notification to the task handle as
- * the job's callback function. The job is created as a recyclable job and in
- * this case the memory used to hold the job status is allocated inside the
- * create function. As the job is persistent it can be used multiple times,
- * as demonstrated in other examples within this demo. In the full task pool
- * implementation the first parameter is used to pass the handle of the task
- * pool this recyclable job is to be associated with. In the lean
- * implementation of the task pool used by this demo there is only one task
- * pool (the system task pool created within the task pool library) so the
- * first parameter is NULL. */
- xResult = IotTaskPool_CreateRecyclableJob( NULL,
- prvSimpleTaskNotifyCallback,
- (void * ) xTaskGetCurrentTaskHandle(),
- &xJob );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* This recyclable job is persistent, and in this case created dynamically,
- * so expect there to be less heap space than when entering the function. */
- configASSERT( xPortGetFreeHeapSize() < xFreeHeapBeforeCreatingJob );
-
- /* In the full task pool implementation the first parameter is used to
- * pass the handle of the task pool to schedule. The lean task pool
- * implementation used in this demo only supports a single task pool, which
- * is created internally within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_Schedule( NULL, xJob, ulNoFlags );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Look for the notification coming from the job's callback function. The
- * priority of the task pool worker task that executes the callback is higher
- * than the priority of this task so a block time is not needed - the task pool
- * worker task preempts this task and sends the notification (from the job's
- * callback) as soon as the job is scheduled. */
- ulReturn = ulTaskNotifyTake( pdTRUE, xNoDelay );
- configASSERT( ulReturn );
-
- /* Clean up recyclable job. In the full implementation of the task pool
- * the first parameter is used to pass a handle to the task pool the job is
- * associated with. In the lean implementation of the task pool used by this
- * demo there is only one task pool (the system task pool created in the
- * task pool library itself) so the first parameter is NULL. */
- IotTaskPool_DestroyRecyclableJob( NULL, xJob );
-
- /* Once the job has been deleted the memory used to hold the job is
- * returned, so the available heap should be exactly as when entering this
- * function. */
- configASSERT( xPortGetFreeHeapSize() == xFreeHeapBeforeCreatingJob );
-}
-/*-----------------------------------------------------------*/
-
-static void prvExample_ReuseRecyclableJobFromLowPriorityTask( void )
-{
-IotTaskPoolError_t xResult;
-uint32_t ulNotificationValue;
-const uint32_t ulNoFlags = 0UL;
-const TickType_t xNoDelay = ( TickType_t ) 0;
-IotTaskPoolJob_t xJob, xJobRecycled;
-size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize(), xFreeHeapAfterCreatingJob = 0;
-IotTaskPoolJobStatus_t xJobStatus;
-
- /* Don't expect any notifications to be pending yet. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* Create a recycleable job using the handle of this task as the job's
- * context and the function that sends a notification to the task handle as
- * the job's callback function. In the full task pool implementation the
- * first parameter is used to pass the handle of the task pool this
- * recyclable job is to be associated with. In the lean implementation of
- * the task pool used by this demo there is only one task pool (the system
- * task pool created within the task pool library) so the first parameter is
- * NULL. */
- xResult = IotTaskPool_CreateRecyclableJob( NULL,
- prvSimpleTaskNotifyCallback,
- (void * ) xTaskGetCurrentTaskHandle(),
- &( xJob ) );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The job is created as a recyclable job and in this case the memory to
- * store the job information is allocated within the create function as at
- * this time there are no recyclable jobs in the task pool jobs cache. So
- * expect there to be less heap space than when entering the function. */
- xFreeHeapAfterCreatingJob = xPortGetFreeHeapSize();
- configASSERT( xFreeHeapAfterCreatingJob < xFreeHeapBeforeCreatingJob );
-
- /* The job has been created but not scheduled so is now ready. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
-
- /* In the full task pool implementation the first parameter is used to
- * pass the handle of the task pool to schedule. The lean task pool
- * implementation used in this demo only supports a single task pool, which
- * is created internally within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_Schedule( NULL, xJob, ulNoFlags );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The priority of the task pool task(s) is higher than the priority
- * of this task, so the job's callback function should have already
- * executed, sending a notification to this task, and incrementing this
- * task's notification value. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xNoDelay ); /* No block time, return immediately. */
- configASSERT( ulNotificationValue == 1 );
-
- /* The job's callback has executed so the job is now completed. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
-
- /* Return the job to the task pool's job cache. */
- IotTaskPool_RecycleJob( NULL, xJob );
-
- /* Create a recycleable job again using the handle of this task as the job's
- * context and the function that sends a notification to the task handle as
- * the job's callback function. In the full task pool implementation the
- * first parameter is used to pass the handle of the task pool this
- * recyclable job is to be associated with. In the lean implementation of
- * the task pool used by this demo there is only one task pool (the system
- * task pool created within the task pool library) so the first parameter is
- * NULL. */
- xResult = IotTaskPool_CreateRecyclableJob( NULL,
- prvSimpleTaskNotifyCallback,
- (void * ) xTaskGetCurrentTaskHandle(),
- &( xJobRecycled ) );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Since this time the task pool's job cache had a recycleable job, it must
- * have been re-used. Thefore expect the free heap space to be same as after
- * the creation of first job */
- configASSERT( xPortGetFreeHeapSize() == xFreeHeapAfterCreatingJob );
-
- /* Expect the task pool to re-use the job in its cache as opposed to
- * allocating a new one. */
- configASSERT( xJobRecycled == xJob );
-
- /* In the full task pool implementation the first parameter is used to
- * pass the handle of the task pool to schedule. The lean task pool
- * implementation used in this demo only supports a single task pool, which
- * is created internally within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_Schedule( NULL, xJobRecycled, ulNoFlags );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The priority of the task pool task(s) is higher than the priority
- * of this task, so the job's callback function should have already
- * executed, sending a notification to this task, and incrementing this
- * task's notification value. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xNoDelay ); /* No block time, return immediately. */
- configASSERT( ulNotificationValue == 2 );
-
- /* The job's callback has executed so the job is now completed. */
- IotTaskPool_GetStatus( NULL, xJobRecycled, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
-
- /* Clean up the recyclable job. In the full implementation of the task
- * pool the first parameter is used to pass a handle to the task pool the job
- * is associated with. In the lean implementation of the task pool used by
- * this demo there is only one task pool (the system task pool created in the
- * task pool library itself) so the first parameter is NULL. */
- xResult = IotTaskPool_DestroyRecyclableJob( NULL, xJobRecycled );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Clear all the notification value bits ready for the next example. */
- xTaskNotifyWait( portMAX_DELAY, /* Clear all bits on entry - portMAX_DELAY is used as it is a portable way of having all bits set. */
- 0UL, /* Don't clear any bits on exit. */
- NULL, /* Don't need the notification value this time. */
- xNoDelay ); /* No block time, return immediately. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* Once the job has been deleted the memory used to hold the job is
- * returned, so the available heap should be exactly as when entering this
- * function. */
- configASSERT( xPortGetFreeHeapSize() == xFreeHeapBeforeCreatingJob );
-}
-/*-----------------------------------------------------------*/
-
-static void prvExample_ReuseRecyclableJobFromHighPriorityTask( void )
-{
-IotTaskPoolError_t xResult;
-uint32_t ulNotificationValue;
-const uint32_t ulNoFlags = 0UL;
-const TickType_t xNoDelay = ( TickType_t ) 0;
-TickType_t xShortDelay = pdMS_TO_TICKS( 150 );
-IotTaskPoolJob_t xJob, xJobRecycled;
-size_t xFreeHeapBeforeCreatingJob = xPortGetFreeHeapSize(), xFreeHeapAfterCreatingJob = 0;
-IotTaskPoolJobStatus_t xJobStatus;
-
- /* Don't expect any notifications to be pending yet. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* prvExample_ReuseRecyclableJobFromLowPriorityTask() executes in a task
- * that has a lower [task] priority than the task pool's worker tasks.
- * Therefore a task pool worker preempts the task that calls
- * prvExample_ReuseRecyclableJobFromHighPriorityTask() as soon as the job is
- * scheduled. prvExample_ReuseRecyclableJobFromHighPriorityTask() reverses the
- * priorities - prvExample_ReuseRecyclableJobFromHighPriorityTask() raises its
- * priority to above the task pool's worker tasks, so the worker tasks do not
- * execute until the calling task enters the blocked state. First raise the
- * priority - passing NULL means raise the priority of the calling task. */
- vTaskPrioritySet( NULL, tpTASK_POOL_WORKER_PRIORITY + 1 );
-
- /* Create a recycleable job using the handle of this task as the job's
- * context and the function that sends a notification to the task handle as
- * the job's callback function. In the full task pool implementation the
- * first parameter is used to pass the handle of the task pool this
- * recyclable job is to be associated with. In the lean implementation of
- * the task pool used by this demo there is only one task pool (the system
- * task pool created within the task pool library) so the first parameter is
- * NULL. */
- xResult = IotTaskPool_CreateRecyclableJob( NULL,
- prvSimpleTaskNotifyCallback,
- (void * ) xTaskGetCurrentTaskHandle(),
- &( xJob ) );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The job is created as a recyclable job and in this case the memory to
- * store the job information is allocated within the create function as at
- * this time there are no recyclable jobs in the task pool jobs cache. So
- * expect there to be less heap space than when entering the function. */
- xFreeHeapAfterCreatingJob = xPortGetFreeHeapSize();
- configASSERT( xFreeHeapAfterCreatingJob < xFreeHeapBeforeCreatingJob );
-
- /* The job has been created but not scheduled so is now ready. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_READY );
-
- /* In the full task pool implementation the first parameter is used to
- * pass the handle of the task pool to schedule. The lean task pool
- * implementation used in this demo only supports a single task pool, which
- * is created internally within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_Schedule( NULL, xJob, ulNoFlags );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The priority of the task pool task(s) is lower than the priority
- * of this task, so the job's callback function should not have executed
- * yet, so don't expect the notification value for this task to have
- * changed. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xNoDelay ); /* No block time, return immediately. */
- configASSERT( ulNotificationValue == 0 );
-
- /* When this task blocks to wait for a notification, a worker thread will be
- * able to execute - but as soon as its callback function sends a
- * notification to this task, this task will preempt it (because it has a
- * higher priority). So this task expects to receive one notification. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xShortDelay ); /* Short delay to allow a task pool worker to execute. */
- configASSERT( ulNotificationValue == 1 );
-
- /* Since the scheduled job has now executed, so waiting for another
- * notification should timeout without the notification value changing. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xShortDelay ); /* Short delay to allow a task pool worker to execute. */
- configASSERT( ulNotificationValue == 1 );
-
- /* The job's callback has executed so the job is now completed. */
- IotTaskPool_GetStatus( NULL, xJob, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
-
- /* Return the job to the task pool's job cache. */
- IotTaskPool_RecycleJob( NULL, xJob );
-
- /* Create a recycleable job again using the handle of this task as the job's
- * context and the function that sends a notification to the task handle as
- * the job's callback function. In the full task pool implementation the
- * first parameter is used to pass the handle of the task pool this
- * recyclable job is to be associated with. In the lean implementation of
- * the task pool used by this demo there is only one task pool (the system
- * task pool created within the task pool library) so the first parameter is
- * NULL. */
- xResult = IotTaskPool_CreateRecyclableJob( NULL,
- prvSimpleTaskNotifyCallback,
- (void * ) xTaskGetCurrentTaskHandle(),
- &( xJobRecycled ) );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Since this time the task pool's job cache had a recycleable job, it must
- * have been re-used. Thefore expect the free heap space to be same as after
- * the creation of first job */
- configASSERT( xPortGetFreeHeapSize() == xFreeHeapAfterCreatingJob );
-
- /* Expect the task pool to re-use the job in its cache as opposed to
- * allocating a new one. */
- configASSERT( xJobRecycled == xJob );
-
- /* In the full task pool implementation the first parameter is used to
- * pass the handle of the task pool to schedule. The lean task pool
- * implementation used in this demo only supports a single task pool, which
- * is created internally within the library, so the first parameter is NULL. */
- xResult = IotTaskPool_Schedule( NULL, xJobRecycled, ulNoFlags );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* The priority of the task pool task(s) is lower than the priority
- * of this task, so the job's callback function should not have executed
- * yet, so don't expect the notification value for this task to have
- * changed. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xNoDelay ); /* No block time, return immediately. */
- configASSERT( ulNotificationValue == 1 );
-
- /* When this task blocks to wait for a notification, a worker thread will be
- * able to execute - but as soon as its callback function sends a
- * notification to this task, this task will preempt it (because it has a
- * higher priority). So this task expects to receive one notification. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xShortDelay ); /* Short delay to allow a task pool worker to execute. */
- configASSERT( ulNotificationValue == 2 );
-
- /* Since the scheduled job has now executed, so waiting for another
- * notification should timeout without the notification value changing. */
- xTaskNotifyWait( 0UL, /* Don't clear any bits on entry. */
- 0UL, /* Don't clear any bits on exit. */
- &ulNotificationValue, /* Obtain the notification value. */
- xShortDelay ); /* Short delay to allow a task pool worker to execute. */
- configASSERT( ulNotificationValue == 2 );
-
- /* The job's callback has executed so the job is now completed. */
- IotTaskPool_GetStatus( NULL, xJobRecycled, &xJobStatus );
- configASSERT( xJobStatus == IOT_TASKPOOL_STATUS_COMPLETED );
-
- /* Clean up the recyclable job. In the full implementation of the task
- * pool the first parameter is used to pass a handle to the task pool the job
- * is associated with. In the lean implementation of the task pool used by
- * this demo there is only one task pool (the system task pool created in the
- * task pool library itself) so the first parameter is NULL. */
- xResult = IotTaskPool_DestroyRecyclableJob( NULL, xJobRecycled );
- configASSERT( xResult == IOT_TASKPOOL_SUCCESS );
-
- /* Reset this task's priority. */
- vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
-
- /* Clear all the notification value bits ready for the next example. */
- xTaskNotifyWait( portMAX_DELAY, /* Clear all bits on entry - portMAX_DELAY is used as it is a portable way of having all bits set. */
- 0UL, /* Don't clear any bits on exit. */
- NULL, /* Don't need the notification value this time. */
- xNoDelay ); /* No block time, return immediately. */
- configASSERT( ulTaskNotifyTake( pdTRUE, xNoDelay ) == 0 );
-
- /* Once the job has been deleted the memory used to hold the job is
- * returned, so the available heap should be exactly as when entering this
- * function. */
- configASSERT( xPortGetFreeHeapSize() == xFreeHeapBeforeCreatingJob );
-}
-/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleUDPClientAndServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleUDPClientAndServer.c
deleted file mode 100644
index 54143c367..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/DemoTasks/SimpleUDPClientAndServer.c
+++ /dev/null
@@ -1,355 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/*
- * Creates two transmitting tasks and two receiving tasks. The transmitting
- * tasks send values that are received by the receiving tasks. One set of tasks
- * uses the standard API. The other set of tasks uses the zero copy API.
- *
- * See the following web page for essential demo usage and configuration
- * details:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/examples_FreeRTOS_simulator.html
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-
-#define simpTINY_DELAY ( ( TickType_t ) 2 )
-
-/*
- * Uses a socket to send data without using the zero copy option.
- * prvSimpleServerTask() will receive the data.
- */
-static void prvSimpleClientTask( void *pvParameters );
-
-/*
- * Uses a socket to receive the data sent by the prvSimpleClientTask() task.
- * Does not use the zero copy option.
- */
-static void prvSimpleServerTask( void *pvParameters );
-
-/*
- * Uses a socket to send data using the zero copy option.
- * prvSimpleZeroCopyServerTask() will receive the data.
- */
-static void prvSimpleZeroCopyUDPClientTask( void *pvParameters );
-
-/*
- * Uses a socket to receive the data sent by the prvSimpleZeroCopyUDPClientTask()
- * task. Uses the zero copy option.
- */
-static void prvSimpleZeroCopyServerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-void vStartSimpleUDPClientServerTasks( uint16_t usStackSize, uint32_t ulPort, UBaseType_t uxPriority )
-{
- /* Create the client and server tasks that do not use the zero copy
- interface. */
- xTaskCreate( prvSimpleClientTask, "SimpCpyClnt", usStackSize, ( void * ) ulPort, uxPriority, NULL );
- xTaskCreate( prvSimpleServerTask, "SimpCpySrv", usStackSize, ( void * ) ulPort, uxPriority + 1, NULL );
-
- /* Create the client and server tasks that do use the zero copy interface. */
- xTaskCreate( prvSimpleZeroCopyUDPClientTask, "SimpZCpyClnt", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority, NULL );
- xTaskCreate( prvSimpleZeroCopyServerTask, "SimpZCpySrv", usStackSize, ( void * ) ( ulPort + 1 ), uxPriority + 1, NULL );
-}
-/*-----------------------------------------------------------*/
-
-static void prvSimpleClientTask( void *pvParameters )
-{
-Socket_t xClientSocket;
-struct freertos_sockaddr xDestinationAddress;
-uint8_t cString[ 65 ];
-BaseType_t lReturned;
-uint32_t ulCount = 0UL, ulIPAddress;
-const uint32_t ulLoopsPerSocket = 10UL;
-const TickType_t x150ms = 150UL / portTICK_PERIOD_MS;
-
- /* Remove compiler warning about unused parameters. */
- ( void ) pvParameters;
-
- /* It is assumed that this task is not created until the network is up,
- so the IP address can be obtained immediately. store the IP address being
- used in ulIPAddress. This is done so the socket can send to a different
- port on the same IP address. */
- FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL );
-
- /* This test sends to itself, so data sent from here is received by a server
- socket on the same IP address. Setup the freertos_sockaddr structure with
- this nodes IP address, and the port number being sent to. The strange
- casting is to try and remove compiler warnings on 32 bit machines. */
- xDestinationAddress.sin_addr = ulIPAddress;
- xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
- xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port );
-
- for( ;; )
- {
- /* Create the socket. */
- xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET );
-
- /* The count is used to differentiate between different messages sent to
- the server, and to break out of the do while loop below. */
- ulCount = 0UL;
-
- do
- {
- /* Create the string that is sent to the server. */
- sprintf( ( char * ) cString, "Server received (not zero copy): Message number %lu\r\n", ulCount );
-
- /* Send the string to the socket. ulFlags is set to 0, so the zero
- copy option is not selected. That means the data from cString[] is
- copied into a network buffer inside FreeRTOS_sendto(), and cString[]
- can be reused as soon as FreeRTOS_sendto() has returned. */
- lReturned = FreeRTOS_sendto( xClientSocket, ( void * ) cString, strlen( ( const char * ) cString ), 0, &xDestinationAddress, sizeof( xDestinationAddress ) );
-
- ulCount++;
-
- } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) );
-
- FreeRTOS_closesocket( xClientSocket );
-
- /* A short delay to prevent the messages printed by the server task
- scrolling off the screen too quickly, and to prevent reduce the network
- loading. */
- vTaskDelay( x150ms );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvSimpleServerTask( void *pvParameters )
-{
-int32_t lBytes;
-uint8_t cReceivedString[ 60 ];
-struct freertos_sockaddr xClient, xBindAddress;
-uint32_t xClientLength = sizeof( xClient );
-Socket_t xListeningSocket;
-
- /* Just to prevent compiler warnings. */
- ( void ) pvParameters;
-
- /* Attempt to open the socket. */
- xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );
-
- /* This test receives data sent from a different port on the same IP
- address. Configure the freertos_sockaddr structure with the address being
- bound to. The strange casting is to try and remove compiler warnings on 32
- bit machines. Note that this task is only created after the network is up,
- so the IP address is valid here. */
- xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
- xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );
-
- /* Bind the socket to the port that the client task will send to. */
- FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );
-
- for( ;; )
- {
- /* Zero out the receive array so there is NULL at the end of the string
- when it is printed out. */
- memset( cReceivedString, 0x00, sizeof( cReceivedString ) );
-
- /* Receive data on the socket. ulFlags is zero, so the zero copy option
- is not set and the received data is copied into the buffer pointed to by
- cReceivedString. By default the block time is portMAX_DELAY.
- xClientLength is not actually used by FreeRTOS_recvfrom(), but is set
- appropriately in case future versions do use it. */
- lBytes = FreeRTOS_recvfrom( xListeningSocket, cReceivedString, sizeof( cReceivedString ), 0, &xClient, &xClientLength );
-
- /* Error check. */
- configASSERT( lBytes == ( BaseType_t ) strlen( ( const char * ) cReceivedString ) );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvSimpleZeroCopyUDPClientTask( void *pvParameters )
-{
-Socket_t xClientSocket;
-uint8_t *pucUDPPayloadBuffer;
-struct freertos_sockaddr xDestinationAddress;
-BaseType_t lReturned;
-uint32_t ulCount = 0UL, ulIPAddress;
-const uint32_t ulLoopsPerSocket = 10UL;
-const char *pcStringToSend = "Server received (using zero copy): Message number ";
-const TickType_t x150ms = 150UL / portTICK_PERIOD_MS;
-/* 15 is added to ensure the number, \r\n and terminating zero fit. */
-const size_t xStringLength = strlen( pcStringToSend ) + 15;
-
- /* Remove compiler warning about unused parameters. */
- ( void ) pvParameters;
-
- /* It is assumed that this task is not created until the network is up,
- so the IP address can be obtained immediately. store the IP address being
- used in ulIPAddress. This is done so the socket can send to a different
- port on the same IP address. */
- FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL );
-
- /* This test sends to itself, so data sent from here is received by a server
- socket on the same IP address. Setup the freertos_sockaddr structure with
- this nodes IP address, and the port number being sent to. The strange
- casting is to try and remove compiler warnings on 32 bit machines. */
- xDestinationAddress.sin_addr = ulIPAddress;
- xDestinationAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
- xDestinationAddress.sin_port = FreeRTOS_htons( xDestinationAddress.sin_port );
-
- for( ;; )
- {
- /* Create the socket. */
- xClientSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- configASSERT( xClientSocket != FREERTOS_INVALID_SOCKET );
-
- /* The count is used to differentiate between different messages sent to
- the server, and to break out of the do while loop below. */
- ulCount = 0UL;
-
- do
- {
- /* This task is going to send using the zero copy interface. The
- data being sent is therefore written directly into a buffer that is
- passed into, rather than copied into, the FreeRTOS_sendto()
- function.
-
- First obtain a buffer of adequate length from the IP stack into which
- the string will be written. Although a max delay is used, the actual
- delay will be capped to ipconfigMAX_SEND_BLOCK_TIME_TICKS, hence
- the do while loop is used to ensure a buffer is obtained. */
- do
- {
- } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xStringLength, portMAX_DELAY ) ) == NULL );
-
- /* A buffer was successfully obtained. Create the string that is
- sent to the server. First the string is filled with zeros as this will
- effectively be the null terminator when the string is received at the other
- end. Note that the string is being written directly into the buffer
- obtained from the IP stack above. */
- memset( ( void * ) pucUDPPayloadBuffer, 0x00, xStringLength );
- sprintf( ( char * ) pucUDPPayloadBuffer, "%s%lu\r\n", pcStringToSend, ulCount );
-
- /* Pass the buffer into the send function. ulFlags has the
- FREERTOS_ZERO_COPY bit set so the IP stack will take control of the
- buffer rather than copy data out of the buffer. */
- lReturned = FreeRTOS_sendto( xClientSocket, /* The socket being sent to. */
- ( void * ) pucUDPPayloadBuffer, /* A pointer to the the data being sent. */
- strlen( ( const char * ) pucUDPPayloadBuffer ) + 1, /* The length of the data being sent - including the string's null terminator. */
- FREERTOS_ZERO_COPY, /* ulFlags with the FREERTOS_ZERO_COPY bit set. */
- &xDestinationAddress, /* Where the data is being sent. */
- sizeof( xDestinationAddress ) );
-
- if( lReturned == 0 )
- {
- /* The send operation failed, so this task is still responsible
- for the buffer obtained from the IP stack. To ensure the buffer
- is not lost it must either be used again, or, as in this case,
- returned to the IP stack using FreeRTOS_ReleaseUDPPayloadBuffer().
- pucUDPPayloadBuffer can be safely re-used after this call. */
- FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
- }
- else
- {
- /* The send was successful so the IP stack is now managing the
- buffer pointed to by pucUDPPayloadBuffer, and the IP stack will
- return the buffer once it has been sent. pucUDPPayloadBuffer can
- be safely re-used. */
- }
-
- ulCount++;
-
- } while( ( lReturned != FREERTOS_SOCKET_ERROR ) && ( ulCount < ulLoopsPerSocket ) );
-
- FreeRTOS_closesocket( xClientSocket );
-
- /* A short delay to prevent the messages scrolling off the screen too
- quickly. */
- vTaskDelay( x150ms );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvSimpleZeroCopyServerTask( void *pvParameters )
-{
-int32_t lBytes;
-uint8_t *pucUDPPayloadBuffer;
-struct freertos_sockaddr xClient, xBindAddress;
-uint32_t xClientLength = sizeof( xClient ), ulIPAddress;
-Socket_t xListeningSocket;
-
- /* Just to prevent compiler warnings. */
- ( void ) pvParameters;
-
- /* Attempt to open the socket. */
- xListeningSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- configASSERT( xListeningSocket != FREERTOS_INVALID_SOCKET );
-
- /* This test receives data sent from a different port on the same IP address.
- Obtain the nodes IP address. Configure the freertos_sockaddr structure with
- the address being bound to. The strange casting is to try and remove
- compiler warnings on 32 bit machines. Note that this task is only created
- after the network is up, so the IP address is valid here. */
- FreeRTOS_GetAddressConfiguration( &ulIPAddress, NULL, NULL, NULL );
- xBindAddress.sin_addr = ulIPAddress;
- xBindAddress.sin_port = ( uint16_t ) ( ( uint32_t ) pvParameters ) & 0xffffUL;
- xBindAddress.sin_port = FreeRTOS_htons( xBindAddress.sin_port );
-
- /* Bind the socket to the port that the client task will send to. */
- FreeRTOS_bind( xListeningSocket, &xBindAddress, sizeof( xBindAddress ) );
-
- for( ;; )
- {
- /* Receive data on the socket. ulFlags has the zero copy bit set
- (FREERTOS_ZERO_COPY) indicating to the stack that a reference to the
- received data should be passed out to this task using the second
- parameter to the FreeRTOS_recvfrom() call. When this is done the
- IP stack is no longer responsible for releasing the buffer, and
- the task *must* return the buffer to the stack when it is no longer
- needed. By default the block time is portMAX_DELAY. */
- lBytes = FreeRTOS_recvfrom( xListeningSocket, ( void * ) &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xClient, &xClientLength );
-
- /* Print the received characters. */
- if( lBytes > 0 )
- {
- /* It is expected to receive one more byte than the string length as
- the NULL terminator is also transmitted. */
- configASSERT( lBytes == ( ( BaseType_t ) strlen( ( const char * ) pucUDPPayloadBuffer ) + 1 ) );
- }
-
- if( lBytes >= 0 )
- {
- /* The buffer *must* be freed once it is no longer needed. */
- FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );
- }
- }
-}
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSConfig.h
deleted file mode 100644
index 3b63eb063..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSConfig.h
+++ /dev/null
@@ -1,208 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef FREERTOS_CONFIG_H
-#define FREERTOS_CONFIG_H
-
-/*-----------------------------------------------------------
- * Application specific definitions.
- *
- * These definitions should be adjusted for your particular hardware and
- * application requirements.
- *
- * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE
- * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE.
- * http://www.freertos.org/a00110.html
- *
- * The bottom of this file contains some constants specific to running the UDP
- * stack in this demo. Constants specific to FreeRTOS+TCP itself (rather than
- * the demo) are contained in FreeRTOSIPConfig.h.
- *----------------------------------------------------------*/
-#define configUSE_PREEMPTION 1
-#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1
-#define configMAX_PRIORITIES ( 7 )
-#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */
-#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 60 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the Win32 thread. */
-#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 2048U * 1024U ) )
-#define configMAX_TASK_NAME_LEN ( 15 )
-#define configUSE_TRACE_FACILITY 1
-#define configUSE_16_BIT_TICKS 0
-#define configIDLE_SHOULD_YIELD 1
-#define configUSE_CO_ROUTINES 0
-#define configUSE_MUTEXES 1
-#define configUSE_RECURSIVE_MUTEXES 1
-#define configQUEUE_REGISTRY_SIZE 0
-#define configUSE_APPLICATION_TASK_TAG 0
-#define configUSE_COUNTING_SEMAPHORES 1
-#define configUSE_ALTERNATIVE_API 0
-#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 0
-#define configENABLE_BACKWARD_COMPATIBILITY 1
-#define configSUPPORT_STATIC_ALLOCATION 1
-
-/* Hook function related definitions. */
-#define configUSE_TICK_HOOK 0
-#define configUSE_IDLE_HOOK 0
-#define configUSE_MALLOC_FAILED_HOOK 0
-#define configCHECK_FOR_STACK_OVERFLOW 0 /* Not applicable to the Win32 port. */
-
-/* Software timer related definitions. */
-#define configUSE_TIMERS 1
-#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 )
-#define configTIMER_QUEUE_LENGTH 5
-#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 )
-
-/* Event group related definitions. */
-#define configUSE_EVENT_GROUPS 1
-
-/* Run time stats gathering definitions. */
-#define configGENERATE_RUN_TIME_STATS 0
-
-/* Co-routine definitions. */
-#define configUSE_CO_ROUTINES 0
-#define configMAX_CO_ROUTINE_PRIORITIES ( 2 )
-
-/* Set the following definitions to 1 to include the API function, or zero
-to exclude the API function. */
-#define INCLUDE_vTaskPrioritySet 1
-#define INCLUDE_uxTaskPriorityGet 1
-#define INCLUDE_vTaskDelete 1
-#define INCLUDE_vTaskCleanUpResources 0
-#define INCLUDE_vTaskSuspend 1
-#define INCLUDE_vTaskDelayUntil 1
-#define INCLUDE_vTaskDelay 1
-#define INCLUDE_uxTaskGetStackHighWaterMark 1
-#define INCLUDE_xTaskGetSchedulerState 1
-#define INCLUDE_xTimerGetTimerTaskHandle 0
-#define INCLUDE_xTaskGetIdleTaskHandle 0
-#define INCLUDE_xQueueGetMutexHolder 1
-#define INCLUDE_eTaskGetState 1
-#define INCLUDE_xEventGroupSetBitsFromISR 1
-#define INCLUDE_xTimerPendFunctionCall 1
-#define INCLUDE_pcTaskGetTaskName 1
-
-/* This demo makes use of one or more example stats formatting functions. These
-format the raw data provided by the uxTaskGetSystemState() function in to human
-readable ASCII form. See the notes in the implementation of vTaskList() within
-FreeRTOS/Source/tasks.c for limitations. configUSE_STATS_FORMATTING_FUNCTIONS
-is set to 2 so the formatting functions are included without the stdio.h being
-included in tasks.c. That is because this project defines its own sprintf()
-functions. */
-#define configUSE_STATS_FORMATTING_FUNCTIONS 1
-
-/* Assert call defined for debug builds. */
-#ifdef _DEBUG
- extern void vAssertCalled( const char *pcFile, uint32_t ulLine );
- #define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __FILE__, __LINE__ )
-#endif /* _DEBUG */
-
-
-
-/* Application specific definitions follow. **********************************/
-
-/* Only used when running in the FreeRTOS Windows simulator. Defines the
-priority of the task used to simulate Ethernet interrupts. */
-#define configMAC_ISR_SIMULATOR_PRIORITY ( configMAX_PRIORITIES - 1 )
-
-/* This demo creates a virtual network connection by accessing the raw Ethernet
-or WiFi data to and from a real network connection. Many computers have more
-than one real network port, and configNETWORK_INTERFACE_TO_USE is used to tell
-the demo which real port should be used to create the virtual port. The ports
-available are displayed on the console when the application is executed. For
-example, on my development laptop setting configNETWORK_INTERFACE_TO_USE to 4
-results in the wired network being used, while setting
-configNETWORK_INTERFACE_TO_USE to 2 results in the wireless network being
-used. */
-#define configNETWORK_INTERFACE_TO_USE 4L
-
-/* The address of an echo server that will be used by the two demo echo client
-tasks.
-http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Echo_Clients.html
-http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/UDP_Echo_Clients.html */
-#define configECHO_SERVER_ADDR0 192
-#define configECHO_SERVER_ADDR1 168
-#define configECHO_SERVER_ADDR2 0
-#define configECHO_SERVER_ADDR3 11
-
-/* Default MAC address configuration. The demo creates a virtual network
-connection that uses this MAC address by accessing the raw Ethernet/WiFi data
-to and from a real network connection on the host PC. See the
-configNETWORK_INTERFACE_TO_USE definition above for information on how to
-configure the real network connection to use. */
-#define configMAC_ADDR0 0x00
-#define configMAC_ADDR1 0x11
-#define configMAC_ADDR2 0x22
-#define configMAC_ADDR3 0x33
-#define configMAC_ADDR4 0x44
-#define configMAC_ADDR5 0x41
-
-/* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or
-ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configIP_ADDR0 10
-#define configIP_ADDR1 10
-#define configIP_ADDR2 10
-#define configIP_ADDR3 200
-
-/* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to
-0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configGATEWAY_ADDR0 10
-#define configGATEWAY_ADDR1 10
-#define configGATEWAY_ADDR2 10
-#define configGATEWAY_ADDR3 1
-
-/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and
-208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set
-to 1 but a DNS server cannot be contacted.*/
-#define configDNS_SERVER_ADDR0 208
-#define configDNS_SERVER_ADDR1 67
-#define configDNS_SERVER_ADDR2 222
-#define configDNS_SERVER_ADDR3 222
-
-/* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or
-ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */
-#define configNET_MASK0 255
-#define configNET_MASK1 0
-#define configNET_MASK2 0
-#define configNET_MASK3 0
-
-/* The UDP port to which print messages are sent. */
-#define configPRINT_PORT ( 15000 )
-
-#if( defined( _MSC_VER ) && ( _MSC_VER <= 1600 ) && !defined( snprintf ) )
- /* Map to Windows names. */
- #define snprintf _snprintf
- #define vsnprintf _vsnprintf
-#endif
-
-/* Visual studio does not have an implementation of strcasecmp(). */
-#define strcasecmp _stricmp
-#define strncasecmp _strnicmp
-#define strcmpi _strcmpi
-
-#define configPRINTF( X ) printf X
-
-#endif /* FREERTOS_CONFIG_H */
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSIPConfig.h
deleted file mode 100644
index 7092fca6a..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/FreeRTOSIPConfig.h
+++ /dev/null
@@ -1,307 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-
-/*****************************************************************************
- *
- * See the following URL for configuration information.
- * http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html
- *
- *****************************************************************************/
-
-#ifndef FREERTOS_IP_CONFIG_H
-#define FREERTOS_IP_CONFIG_H
-
-/* Prototype for the function used to print out. In this case it prints to the
-console before the network is connected then a UDP port after the network has
-connected. */
-extern void vLoggingPrintf( const char *pcFormatString, ... );
-
-/* Set to 1 to print out debug messages. If ipconfigHAS_DEBUG_PRINTF is set to
-1 then FreeRTOS_debug_printf should be defined to the function used to print
-out the debugging messages. */
-#define ipconfigHAS_DEBUG_PRINTF 0
-#if( ipconfigHAS_DEBUG_PRINTF == 1 )
- #define FreeRTOS_debug_printf(X) vLoggingPrintf X
-#endif
-
-/* Set to 1 to print out non debugging messages, for example the output of the
-FreeRTOS_netstat() command, and ping replies. If ipconfigHAS_PRINTF is set to 1
-then FreeRTOS_printf should be set to the function used to print out the
-messages. */
-#define ipconfigHAS_PRINTF 0
-#if( ipconfigHAS_PRINTF == 1 )
- #define FreeRTOS_printf(X) vLoggingPrintf X
-#endif
-
-/* Define the byte order of the target MCU (the MCU FreeRTOS+TCP is executing
-on). Valid options are pdFREERTOS_BIG_ENDIAN and pdFREERTOS_LITTLE_ENDIAN. */
-#define ipconfigBYTE_ORDER pdFREERTOS_LITTLE_ENDIAN
-
-/* If the network card/driver includes checksum offloading (IP/TCP/UDP checksums)
-then set ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM to 1 to prevent the software
-stack repeating the checksum calculations. */
-#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
-
-/* Several API's will block until the result is known, or the action has been
-performed, for example FreeRTOS_send() and FreeRTOS_recv(). The timeouts can be
-set per socket, using setsockopt(). If not set, the times below will be
-used as defaults. */
-#define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME ( 5000 )
-#define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME ( 5000 )
-
-/* Include support for LLMNR: Link-local Multicast Name Resolution
-(non-Microsoft) */
-#define ipconfigUSE_LLMNR ( 0 )
-
-/* Include support for NBNS: NetBIOS Name Service (Microsoft) */
-#define ipconfigUSE_NBNS ( 0 )
-
-/* Include support for DNS caching. For TCP, having a small DNS cache is very
-useful. When a cache is present, ipconfigDNS_REQUEST_ATTEMPTS can be kept low
-and also DNS may use small timeouts. If a DNS reply comes in after the DNS
-socket has been destroyed, the result will be stored into the cache. The next
-call to FreeRTOS_gethostbyname() will return immediately, without even creating
-a socket. */
-#define ipconfigUSE_DNS_CACHE ( 1 )
-#define ipconfigDNS_CACHE_NAME_LENGTH ( 16 )
-#define ipconfigDNS_CACHE_ENTRIES ( 4 )
-#define ipconfigDNS_REQUEST_ATTEMPTS ( 2 )
-
-/* The IP stack executes it its own task (although any application task can make
-use of its services through the published sockets API). ipconfigUDP_TASK_PRIORITY
-sets the priority of the task that executes the IP stack. The priority is a
-standard FreeRTOS task priority so can take any value from 0 (the lowest
-priority) to (configMAX_PRIORITIES - 1) (the highest priority).
-configMAX_PRIORITIES is a standard FreeRTOS configuration parameter defined in
-FreeRTOSConfig.h, not FreeRTOSIPConfig.h. Consideration needs to be given as to
-the priority assigned to the task executing the IP stack relative to the
-priority assigned to tasks that use the IP stack. */
-#define ipconfigIP_TASK_PRIORITY ( configMAX_PRIORITIES - 2 )
-
-/* The size, in words (not bytes), of the stack allocated to the FreeRTOS+TCP
-task. This setting is less important when the FreeRTOS Win32 simulator is used
-as the Win32 simulator only stores a fixed amount of information on the task
-stack. FreeRTOS includes optional stack overflow detection, see:
-http://www.freertos.org/Stacks-and-stack-overflow-checking.html */
-#define ipconfigIP_TASK_STACK_SIZE_WORDS ( configMINIMAL_STACK_SIZE * 5 )
-
-/* ipconfigRAND32() is called by the IP stack to generate random numbers for
-things such as a DHCP transaction number or initial sequence number. Random
-number generation is performed via this macro to allow applications to use their
-own random number generation method. For example, it might be possible to
-generate a random number by sampling noise on an analogue input. */
-extern UBaseType_t uxRand();
-#define ipconfigRAND32() uxRand()
-
-/* If ipconfigUSE_NETWORK_EVENT_HOOK is set to 1 then FreeRTOS+TCP will call the
-network event hook at the appropriate times. If ipconfigUSE_NETWORK_EVENT_HOOK
-is not set to 1 then the network event hook will never be called. See
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/API/vApplicationIPNetworkEventHook.shtml
-*/
-#define ipconfigUSE_NETWORK_EVENT_HOOK 1
-
-/* Sockets have a send block time attribute. If FreeRTOS_sendto() is called but
-a network buffer cannot be obtained then the calling task is held in the Blocked
-state (so other tasks can continue to executed) until either a network buffer
-becomes available or the send block time expires. If the send block time expires
-then the send operation is aborted. The maximum allowable send block time is
-capped to the value set by ipconfigMAX_SEND_BLOCK_TIME_TICKS. Capping the
-maximum allowable send block time prevents prevents a deadlock occurring when
-all the network buffers are in use and the tasks that process (and subsequently
-free) the network buffers are themselves blocked waiting for a network buffer.
-ipconfigMAX_SEND_BLOCK_TIME_TICKS is specified in RTOS ticks. A time in
-milliseconds can be converted to a time in ticks by dividing the time in
-milliseconds by portTICK_PERIOD_MS. */
-#define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( 5000 / portTICK_PERIOD_MS )
-
-/* If ipconfigUSE_DHCP is 1 then FreeRTOS+TCP will attempt to retrieve an IP
-address, netmask, DNS server address and gateway address from a DHCP server. If
-ipconfigUSE_DHCP is 0 then FreeRTOS+TCP will use a static IP address. The
-stack will revert to using the static IP address even when ipconfigUSE_DHCP is
-set to 1 if a valid configuration cannot be obtained from a DHCP server for any
-reason. The static configuration used is that passed into the stack by the
-FreeRTOS_IPInit() function call. */
-#define ipconfigUSE_DHCP 0
-
-/* When ipconfigUSE_DHCP is set to 1, DHCP requests will be sent out at
-increasing time intervals until either a reply is received from a DHCP server
-and accepted, or the interval between transmissions reaches
-ipconfigMAXIMUM_DISCOVER_TX_PERIOD. The IP stack will revert to using the
-static IP address passed as a parameter to FreeRTOS_IPInit() if the
-re-transmission time interval reaches ipconfigMAXIMUM_DISCOVER_TX_PERIOD without
-a DHCP reply being received. */
-#define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( 120000 / portTICK_PERIOD_MS )
-
-/* The ARP cache is a table that maps IP addresses to MAC addresses. The IP
-stack can only send a UDP message to a remove IP address if it knowns the MAC
-address associated with the IP address, or the MAC address of the router used to
-contact the remote IP address. When a UDP message is received from a remote IP
-address the MAC address and IP address are added to the ARP cache. When a UDP
-message is sent to a remote IP address that does not already appear in the ARP
-cache then the UDP message is replaced by a ARP message that solicits the
-required MAC address information. ipconfigARP_CACHE_ENTRIES defines the maximum
-number of entries that can exist in the ARP table at any one time. */
-#define ipconfigARP_CACHE_ENTRIES 6
-
-/* ARP requests that do not result in an ARP response will be re-transmitted a
-maximum of ipconfigMAX_ARP_RETRANSMISSIONS times before the ARP request is
-aborted. */
-#define ipconfigMAX_ARP_RETRANSMISSIONS ( 5 )
-
-/* ipconfigMAX_ARP_AGE defines the maximum time between an entry in the ARP
-table being created or refreshed and the entry being removed because it is stale.
-New ARP requests are sent for ARP cache entries that are nearing their maximum
-age. ipconfigMAX_ARP_AGE is specified in tens of seconds, so a value of 150 is
-equal to 1500 seconds (or 25 minutes). */
-#define ipconfigMAX_ARP_AGE 150
-
-/* Implementing FreeRTOS_inet_addr() necessitates the use of string handling
-routines, which are relatively large. To save code space the full
-FreeRTOS_inet_addr() implementation is made optional, and a smaller and faster
-alternative called FreeRTOS_inet_addr_quick() is provided. FreeRTOS_inet_addr()
-takes an IP in decimal dot format (for example, "192.168.0.1") as its parameter.
-FreeRTOS_inet_addr_quick() takes an IP address as four separate numerical octets
-(for example, 192, 168, 0, 1) as its parameters. If
-ipconfigINCLUDE_FULL_INET_ADDR is set to 1 then both FreeRTOS_inet_addr() and
-FreeRTOS_indet_addr_quick() are available. If ipconfigINCLUDE_FULL_INET_ADDR is
-not set to 1 then only FreeRTOS_indet_addr_quick() is available. */
-#define ipconfigINCLUDE_FULL_INET_ADDR 1
-
-/* ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS defines the total number of network buffer that
-are available to the IP stack. The total number of network buffers is limited
-to ensure the total amount of RAM that can be consumed by the IP stack is capped
-to a pre-determinable value. */
-#define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 60
-
-/* A FreeRTOS queue is used to send events from application tasks to the IP
-stack. ipconfigEVENT_QUEUE_LENGTH sets the maximum number of events that can
-be queued for processing at any one time. The event queue must be a minimum of
-5 greater than the total number of network buffers. */
-#define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
-
-/* The address of a socket is the combination of its IP address and its port
-number. FreeRTOS_bind() is used to manually allocate a port number to a socket
-(to 'bind' the socket to a port), but manual binding is not normally necessary
-for client sockets (those sockets that initiate outgoing connections rather than
-wait for incoming connections on a known port number). If
-ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 1 then calling
-FreeRTOS_sendto() on a socket that has not yet been bound will result in the IP
-stack automatically binding the socket to a port number from the range
-socketAUTO_PORT_ALLOCATION_START_NUMBER to 0xffff. If
-ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is set to 0 then calling FreeRTOS_sendto()
-on a socket that has not yet been bound will result in the send operation being
-aborted. */
-#define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
-
-/* Defines the Time To Live (TTL) values used in outgoing UDP packets. */
-#define ipconfigUDP_TIME_TO_LIVE 128
-#define ipconfigTCP_TIME_TO_LIVE 128 /* also defined in FreeRTOSIPConfigDefaults.h */
-
-/* USE_TCP: Use TCP and all its features */
-#define ipconfigUSE_TCP ( 1 )
-
-/* USE_WIN: Let TCP use windowing mechanism. */
-#define ipconfigUSE_TCP_WIN ( 1 )
-
-/* The MTU is the maximum number of bytes the payload of a network frame can
-contain. For normal Ethernet V2 frames the maximum MTU is 1500. Setting a
-lower value can save RAM, depending on the buffer management scheme used. If
-ipconfigCAN_FRAGMENT_OUTGOING_PACKETS is 1 then (ipconfigNETWORK_MTU - 28) must
-be divisible by 8. */
-#define ipconfigNETWORK_MTU 1200
-
-/* Set ipconfigUSE_DNS to 1 to include a basic DNS client/resolver. DNS is used
-through the FreeRTOS_gethostbyname() API function. */
-#define ipconfigUSE_DNS 1
-
-/* If ipconfigREPLY_TO_INCOMING_PINGS is set to 1 then the IP stack will
-generate replies to incoming ICMP echo (ping) requests. */
-#define ipconfigREPLY_TO_INCOMING_PINGS 1
-
-/* If ipconfigSUPPORT_OUTGOING_PINGS is set to 1 then the
-FreeRTOS_SendPingRequest() API function is available. */
-#define ipconfigSUPPORT_OUTGOING_PINGS 0
-
-/* If ipconfigSUPPORT_SELECT_FUNCTION is set to 1 then the FreeRTOS_select()
-(and associated) API function is available. */
-#define ipconfigSUPPORT_SELECT_FUNCTION 1
-
-/* If ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES is set to 1 then Ethernet frames
-that are not in Ethernet II format will be dropped. This option is included for
-potential future IP stack developments. */
-#define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1 then it is the
-responsibility of the Ethernet interface to filter out packets that are of no
-interest. If the Ethernet interface does not implement this functionality, then
-set ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES to 0 to have the IP stack
-perform the filtering instead (it is much less efficient for the stack to do it
-because the packet will already have been passed into the stack). If the
-Ethernet driver does all the necessary filtering in hardware then software
-filtering can be removed by using a value other than 1 or 0. */
-#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
-
-/* The windows simulator cannot really simulate MAC interrupts, and needs to
-block occasionally to allow other tasks to run. */
-#define configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY ( 20 / portTICK_PERIOD_MS )
-
-/* Advanced only: in order to access 32-bit fields in the IP packets with
-32-bit memory instructions, all packets will be stored 32-bit-aligned, plus 16-bits.
-This has to do with the contents of the IP-packets: all 32-bit fields are
-32-bit-aligned, plus 16-bit(!) */
-#define ipconfigPACKET_FILLER_SIZE 2
-
-/* Define the size of the pool of TCP window descriptors. On the average, each
-TCP socket will use up to 2 x 6 descriptors, meaning that it can have 2 x 6
-outstanding packets (for Rx and Tx). When using up to 10 TP sockets
-simultaneously, one could define TCP_WIN_SEG_COUNT as 120. */
-#define ipconfigTCP_WIN_SEG_COUNT 240
-
-/* Each TCP socket has a circular buffers for Rx and Tx, which have a fixed
-maximum size. Define the size of Rx buffer for TCP sockets. */
-#define ipconfigTCP_RX_BUFFER_LENGTH ( 1000 )
-
-/* Define the size of Tx buffer for TCP sockets. */
-#define ipconfigTCP_TX_BUFFER_LENGTH ( 1000 )
-
-/* When using call-back handlers, the driver may check if the handler points to
-real program memory (RAM or flash) or just has a random non-zero value. */
-#define ipconfigIS_VALID_PROG_ADDRESS(x) ( (x) != NULL )
-
-/* Include support for TCP hang protection. All sockets in a connecting or
-disconnecting stage will timeout after a period of non-activity. */
-#define ipconfigTCP_HANG_PROTECTION ( 1 )
-#define ipconfigTCP_HANG_PROTECTION_TIME ( 30 )
-
-/* Include support for TCP keep-alive messages. */
-#define ipconfigTCP_KEEP_ALIVE ( 1 )
-#define ipconfigTCP_KEEP_ALIVE_INTERVAL ( 20 ) /* in seconds */
-
-#define portINLINE __inline
-
-#endif /* FREERTOS_IP_CONFIG_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/READ_ME_INSTRUCTIONS.url b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/READ_ME_INSTRUCTIONS.url
deleted file mode 100644
index c00147b27..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/READ_ME_INSTRUCTIONS.url
+++ /dev/null
@@ -1,6 +0,0 @@
-[{000214A0-0000-0000-C000-000000000046}]
-Prop3=19,11
-[InternetShortcut]
-IDList=
-URL=https://www.freertos.org/task-pool/
-HotKey=0
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj
deleted file mode 100644
index 7f9596ad3..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj
+++ /dev/null
@@ -1,210 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup Label="ProjectConfigurations">
- <ProjectConfiguration Include="Debug|Win32">
- <Configuration>Debug</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- <ProjectConfiguration Include="Release|Win32">
- <Configuration>Release</Configuration>
- <Platform>Win32</Platform>
- </ProjectConfiguration>
- </ItemGroup>
- <PropertyGroup Label="Globals">
- <ProjectGuid>{C686325E-3261-42F7-AEB1-DDE5280E1CEB}</ProjectGuid>
- <ProjectName>RTOSDemo</ProjectName>
- <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseOfMfc>false</UseOfMfc>
- <CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v142</PlatformToolset>
- </PropertyGroup>
- <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
- <ConfigurationType>Application</ConfigurationType>
- <UseOfMfc>false</UseOfMfc>
- <CharacterSet>MultiByte</CharacterSet>
- <PlatformToolset>v142</PlatformToolset>
- </PropertyGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
- <ImportGroup Label="ExtensionSettings">
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
- </ImportGroup>
- <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="PropertySheets">
- <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
- <Import Project="$(VCTargetsPath)Microsoft.CPP.UpgradeFromVC60.props" />
- </ImportGroup>
- <PropertyGroup Label="UserMacros" />
- <PropertyGroup>
- <_ProjectFileVersion>10.0.30319.1</_ProjectFileVersion>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.\Debug\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</LinkIncremental>
- <OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</OutDir>
- <IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.\Release\</IntDir>
- <LinkIncremental Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">false</LinkIncremental>
- <CodeAnalysisRuleSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AllRules.ruleset</CodeAnalysisRuleSet>
- </PropertyGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
- <Midl>
- <TypeLibraryName>.\Debug/WIN32.tlb</TypeLibraryName>
- <HeaderFileName>
- </HeaderFileName>
- </Midl>
- <ClCompile>
- <Optimization>Disabled</Optimization>
- <AdditionalIncludeDirectories>..\..\..\Source\FreeRTOS-Plus-TCP\include;..\..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement;..\..\..\Source\FreeRTOS-Plus-TCP\portable\Compiler\MSVC;.\DemoTasks\include;.\WinPCap;..\..\..\..\FreeRTOS\Source\include;..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW;..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include;..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include;..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0500;WINVER=0x400;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
- <RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
- <PrecompiledHeaderOutputFile>.\Debug/WIN32.pch</PrecompiledHeaderOutputFile>
- <AssemblerListingLocation>.\Debug/</AssemblerListingLocation>
- <ObjectFileName>.\Debug/</ObjectFileName>
- <ProgramDataBaseFileName>.\Debug/</ProgramDataBaseFileName>
- <WarningLevel>Level4</WarningLevel>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <DisableLanguageExtensions>false</DisableLanguageExtensions>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
- <AdditionalOptions>/wd4210 /wd4127 /wd4214 /wd4201 /wd4244 /wd4310 %(AdditionalOptions)</AdditionalOptions>
- <BrowseInformation>true</BrowseInformation>
- <PrecompiledHeader>NotUsing</PrecompiledHeader>
- <ExceptionHandling>false</ExceptionHandling>
- <CompileAs>CompileAsC</CompileAs>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <Culture>0x0c09</Culture>
- </ResourceCompile>
- <Link>
- <OutputFile>.\Debug/RTOSDemo.exe</OutputFile>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <GenerateDebugInformation>true</GenerateDebugInformation>
- <ProgramDatabaseFile>.\Debug/WIN32.pdb</ProgramDatabaseFile>
- <SubSystem>Console</SubSystem>
- <TargetMachine>MachineX86</TargetMachine>
- <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
- <AdditionalLibraryDirectories>.\WinPCap</AdditionalLibraryDirectories>
- <Profile>false</Profile>
- <ImageHasSafeExceptionHandlers>false</ImageHasSafeExceptionHandlers>
- </Link>
- <Bscmake>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <OutputFile>.\Debug/WIN32.bsc</OutputFile>
- </Bscmake>
- </ItemDefinitionGroup>
- <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
- <Midl>
- <TypeLibraryName>.\Release/WIN32.tlb</TypeLibraryName>
- <HeaderFileName>
- </HeaderFileName>
- </Midl>
- <ClCompile>
- <Optimization>MaxSpeed</Optimization>
- <InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
- <PreprocessorDefinitions>_WINSOCKAPI_;WIN32;NDEBUG;_CONSOLE;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <StringPooling>true</StringPooling>
- <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
- <FunctionLevelLinking>true</FunctionLevelLinking>
- <PrecompiledHeaderOutputFile>.\Release/WIN32.pch</PrecompiledHeaderOutputFile>
- <AssemblerListingLocation>.\Release/</AssemblerListingLocation>
- <ObjectFileName>.\Release/</ObjectFileName>
- <ProgramDataBaseFileName>.\Release/</ProgramDataBaseFileName>
- <WarningLevel>Level3</WarningLevel>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <AdditionalIncludeDirectories>..\Common\Utils;..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap;..\Common\ethernet\lwip-1.4.0\src\include\ipv4;..\Common\ethernet\lwip-1.4.0\src\include;..\..\..\Source\include;..\..\..\Source\portable\MSVC-MingW;..\Common\ethernet\lwip-1.4.0\ports\win32\include;..\Common\Include;.\lwIP_Apps;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- </ClCompile>
- <ResourceCompile>
- <PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <Culture>0x0c09</Culture>
- </ResourceCompile>
- <Link>
- <OutputFile>.\Release/RTOSDemo.exe</OutputFile>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <ProgramDatabaseFile>.\Release/WIN32.pdb</ProgramDatabaseFile>
- <SubSystem>Console</SubSystem>
- <TargetMachine>MachineX86</TargetMachine>
- <AdditionalLibraryDirectories>..\Common\ethernet\lwip-1.4.0\ports\win32\WinPCap</AdditionalLibraryDirectories>
- <AdditionalDependencies>wpcap.lib;%(AdditionalDependencies)</AdditionalDependencies>
- </Link>
- <Bscmake>
- <SuppressStartupBanner>true</SuppressStartupBanner>
- <OutputFile>.\Release/WIN32.bsc</OutputFile>
- </Bscmake>
- </ItemDefinitionGroup>
- <ItemGroup>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\event_groups.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\list.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\queue.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\tasks.c" />
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\timers.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_clock_freertos.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\logging\iot_logging.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\taskpool\iot_taskpool.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_ARP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DHCP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DNS.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_IP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Sockets.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Stream_Buffer.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_IP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_WIN.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c" />
- <ClCompile Include="DemoTasks\SimpleTaskPoolExamples.c" />
- <ClCompile Include="DemoTasks\SimpleUDPClientAndServer.c" />
- <ClCompile Include="demo_logging.c" />
- <ClCompile Include="main.c">
- <AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
- <PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\event_groups.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\FreeRTOS.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\portable.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\projdefs.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\queue.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\semphr.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\task.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\timers.h" />
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\portmacro.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\include\platform\iot_platform_types_freertos.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\types\iot_platform_types.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\iot_taskpool.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_error.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_logging.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_static_memory.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_taskpool_internal.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\types\iot_taskpool_types.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOSIPConfigDefaults.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_ARP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DHCP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DNS.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP_Private.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Sockets.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Stream_Buffer.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_IP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_WIN.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_UDP_IP.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\IPTraceMacroDefaults.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkBufferManagement.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkInterface.h" />
- <ClInclude Include="FreeRTOSConfig.h" />
- <ClInclude Include="FreeRTOSIPConfig.h" />
- <ClInclude Include="iot_config.h" />
- <ClInclude Include="iot_config_common.h" />
- </ItemGroup>
- <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
- <ImportGroup Label="ExtensionTargets">
- </ImportGroup>
-</Project> \ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj.filters b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj.filters
deleted file mode 100644
index 3653a6cbe..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WIN32.vcxproj.filters
+++ /dev/null
@@ -1,260 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
- <ItemGroup>
- <Filter Include="Resource Files">
- <UniqueIdentifier>{38712199-cebf-4124-bf15-398f7c3419ea}</UniqueIdentifier>
- <Extensions>ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe</Extensions>
- </Filter>
- <Filter Include="FreeRTOS">
- <UniqueIdentifier>{af3445a1-4908-4170-89ed-39345d90d30c}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS\Source">
- <UniqueIdentifier>{f32be356-4763-4cae-9020-974a2638cb08}</UniqueIdentifier>
- <Extensions>*.c</Extensions>
- </Filter>
- <Filter Include="FreeRTOS\Source\Portable">
- <UniqueIdentifier>{88f409e6-d396-4ac5-94bd-7a99c914be46}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+">
- <UniqueIdentifier>{e5ad4ec7-23dc-4295-8add-2acaee488f5a}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS\Source\include">
- <UniqueIdentifier>{d2dcd641-8d91-492b-852f-5563ffadaec6}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS+TCP">
- <UniqueIdentifier>{8672fa26-b119-481f-8b8d-086419c01a3e}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS+TCP\portable">
- <UniqueIdentifier>{4570be11-ec96-4b55-ac58-24b50ada980a}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS+TCP\include">
- <UniqueIdentifier>{5d93ed51-023a-41ad-9243-8d230165d34b}</UniqueIdentifier>
- </Filter>
- <Filter Include="DemoTasks">
- <UniqueIdentifier>{b71e974a-9f28-4815-972b-d930ba8a34d0}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries">
- <UniqueIdentifier>{60717407-397f-4ea5-8492-3314acdd25f0}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard">
- <UniqueIdentifier>{8a90222f-d723-4b4e-8e6e-c57afaf7fa92}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common">
- <UniqueIdentifier>{7c995f05-2a10-4771-ad77-18a755876e46}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\task_pool">
- <UniqueIdentifier>{e07288b6-a8e7-416a-947d-7f0260673dcc}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include">
- <UniqueIdentifier>{9a636cc3-ebc6-48c5-8c18-c72494686e81}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private">
- <UniqueIdentifier>{fe53a296-12ec-4819-bf2b-fd9dca2c6e96}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\types">
- <UniqueIdentifier>{29376c48-bc8b-4624-ad59-16807874c9f2}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions">
- <UniqueIdentifier>{91ef4008-de51-4b41-ba5e-bf24d8cda378}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform">
- <UniqueIdentifier>{ade43c6c-04c5-4897-abdb-91af2df04e5d}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos">
- <UniqueIdentifier>{08a4e35c-19ca-4b1e-af24-bac368c2bf7b}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include">
- <UniqueIdentifier>{1fc5fc25-c18b-45a2-bad3-0c07795db1e9}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\platform">
- <UniqueIdentifier>{f3a69e5b-1462-4e19-8651-274e86c252b0}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\types">
- <UniqueIdentifier>{9a849d9e-91e5-4035-ab4c-70a986c6aed1}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include">
- <UniqueIdentifier>{1e324500-91b4-4c76-b699-59ba75691760}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include\platform">
- <UniqueIdentifier>{bdcbc1ec-99b8-4c72-9075-49035c115488}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include\platform\types">
- <UniqueIdentifier>{35ce7745-52a2-4220-be31-50dfaa35c0ab}</UniqueIdentifier>
- </Filter>
- <Filter Include="FreeRTOS+\FreeRTOS IoT Libraries\standard\common\logging">
- <UniqueIdentifier>{6c8bc003-a388-4666-99f4-a31faa932a36}</UniqueIdentifier>
- </Filter>
- </ItemGroup>
- <ItemGroup>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\port.c">
- <Filter>FreeRTOS\Source\Portable</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\timers.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\list.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\queue.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\tasks.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="DemoTasks\SimpleUDPClientAndServer.c">
- <Filter>DemoTasks</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_UDP_IP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DHCP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_DNS.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Sockets.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\BufferManagement\BufferAllocation_2.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP\portable</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\portable\NetworkInterface\WinPCap\NetworkInterface.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP\portable</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_ARP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_IP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_IP.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_TCP_WIN.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\event_groups.c">
- <Filter>FreeRTOS\Source</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\..\FreeRTOS\Source\portable\MemMang\heap_4.c">
- <Filter>FreeRTOS\Source\Portable</Filter>
- </ClCompile>
- <ClCompile Include="main.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-Plus-TCP\FreeRTOS_Stream_Buffer.c">
- <Filter>FreeRTOS+\FreeRTOS+TCP</Filter>
- </ClCompile>
- <ClCompile Include="demo_logging.c" />
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\taskpool\iot_taskpool.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\task_pool</Filter>
- </ClCompile>
- <ClCompile Include="DemoTasks\SimpleTaskPoolExamples.c">
- <Filter>DemoTasks</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\logging\iot_logging.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\logging</Filter>
- </ClCompile>
- <ClCompile Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\iot_clock_freertos.c">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos</Filter>
- </ClCompile>
- </ItemGroup>
- <ItemGroup>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkInterface.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DNS.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Sockets.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_UDP_IP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\timers.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\event_groups.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\FreeRTOS.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\queue.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\semphr.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\task.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\portable\MSVC-MingW\portmacro.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP_Private.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\NetworkBufferManagement.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_ARP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_DHCP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_IP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_IP.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_TCP_WIN.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOSIPConfigDefaults.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\IPTraceMacroDefaults.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="FreeRTOSConfig.h" />
- <ClInclude Include="FreeRTOSIPConfig.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-Plus-TCP\include\FreeRTOS_Stream_Buffer.h">
- <Filter>FreeRTOS+\FreeRTOS+TCP\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\portable.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\..\FreeRTOS\Source\include\projdefs.h">
- <Filter>FreeRTOS\Source\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\iot_taskpool.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\types\iot_taskpool_types.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\types</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_error.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_logging.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_static_memory.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\c_sdk\standard\common\include\private\iot_taskpool_internal.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\standard\common\include\private</Filter>
- </ClInclude>
- <ClInclude Include="iot_config.h" />
- <ClInclude Include="iot_config_common.h" />
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\include\types\iot_platform_types.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\include\types</Filter>
- </ClInclude>
- <ClInclude Include="..\..\..\Source\FreeRTOS-IoT-Libraries\abstractions\platform\freertos\include\platform\iot_platform_types_freertos.h">
- <Filter>FreeRTOS+\FreeRTOS IoT Libraries\abstractions\platform\freertos\include\platform\types</Filter>
- </ClInclude>
- </ItemGroup>
-</Project> \ No newline at end of file
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Packet32.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Packet32.h
deleted file mode 100644
index 1e0eacd77..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Packet32.h
+++ /dev/null
@@ -1,359 +0,0 @@
-/*
- * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2007 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-/** @ingroup packetapi
- * @{
- */
-
-/** @defgroup packet32h Packet.dll definitions and data structures
- * Packet32.h contains the data structures and the definitions used by packet.dll.
- * The file is used both by the Win9x and the WinNTx versions of packet.dll, and can be included
- * by the applications that use the functions of this library
- * @{
- */
-
-#ifndef __PACKET32
-#define __PACKET32
-
-#include <winsock2.h>
-
-#ifdef HAVE_AIRPCAP_API
-#include <airpcap.h>
-#else
-#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
-#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
-typedef struct _AirpcapHandle *PAirpcapHandle;
-#endif /* AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_ */
-#endif /* HAVE_AIRPCAP_API */
-
-#ifdef HAVE_DAG_API
-#include <dagc.h>
-#endif /* HAVE_DAG_API */
-
-// Working modes
-#define PACKET_MODE_CAPT 0x0 ///< Capture mode
-#define PACKET_MODE_STAT 0x1 ///< Statistical mode
-#define PACKET_MODE_MON 0x2 ///< Monitoring mode
-#define PACKET_MODE_DUMP 0x10 ///< Dump mode
-#define PACKET_MODE_STAT_DUMP MODE_DUMP | MODE_STAT ///< Statistical dump Mode
-
-
-/// Alignment macro. Defines the alignment size.
-#define Packet_ALIGNMENT sizeof(int)
-/// Alignment macro. Rounds up to the next even multiple of Packet_ALIGNMENT.
-#define Packet_WORDALIGN(x) (((x)+(Packet_ALIGNMENT-1))&~(Packet_ALIGNMENT-1))
-
-#define NdisMediumNull -1 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumCHDLC -2 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumPPPSerial -3 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumBare80211 -4 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumRadio80211 -5 ///< Custom linktype: NDIS doesn't provide an equivalent
-#define NdisMediumPpi -6 ///< Custom linktype: NDIS doesn't provide an equivalent
-
-// Loopback behaviour definitions
-#define NPF_DISABLE_LOOPBACK 1 ///< Drop the packets sent by the NPF driver
-#define NPF_ENABLE_LOOPBACK 2 ///< Capture the packets sent by the NPF driver
-
-/*!
- \brief Network type structure.
-
- This structure is used by the PacketGetNetType() function to return information on the current adapter's type and speed.
-*/
-typedef struct NetType
-{
- UINT LinkType; ///< The MAC of the current network adapter (see function PacketGetNetType() for more information)
- ULONGLONG LinkSpeed; ///< The speed of the network in bits per second
-}NetType;
-
-
-//some definitions stolen from libpcap
-
-#ifndef BPF_MAJOR_VERSION
-
-/*!
- \brief A BPF pseudo-assembly program.
-
- The program will be injected in the kernel by the PacketSetBPF() function and applied to every incoming packet.
-*/
-struct bpf_program
-{
- UINT bf_len; ///< Indicates the number of instructions of the program, i.e. the number of struct bpf_insn that will follow.
- struct bpf_insn *bf_insns; ///< A pointer to the first instruction of the program.
-};
-
-/*!
- \brief A single BPF pseudo-instruction.
-
- bpf_insn contains a single instruction for the BPF register-machine. It is used to send a filter program to the driver.
-*/
-struct bpf_insn
-{
- USHORT code; ///< Instruction type and addressing mode.
- UCHAR jt; ///< Jump if true
- UCHAR jf; ///< Jump if false
- int k; ///< Generic field used for various purposes.
-};
-
-/*!
- \brief Structure that contains a couple of statistics values on the current capture.
-
- It is used by packet.dll to return statistics about a capture session.
-*/
-struct bpf_stat
-{
- UINT bs_recv; ///< Number of packets that the driver received from the network adapter
- ///< from the beginning of the current capture. This value includes the packets
- ///< lost by the driver.
- UINT bs_drop; ///< number of packets that the driver lost from the beginning of a capture.
- ///< Basically, a packet is lost when the the buffer of the driver is full.
- ///< In this situation the packet cannot be stored and the driver rejects it.
- UINT ps_ifdrop; ///< drops by interface. XXX not yet supported
- UINT bs_capt; ///< number of packets that pass the filter, find place in the kernel buffer and
- ///< thus reach the application.
-};
-
-/*!
- \brief Packet header.
-
- This structure defines the header associated with every packet delivered to the application.
-*/
-struct bpf_hdr
-{
- struct timeval bh_tstamp; ///< The timestamp associated with the captured packet.
- ///< It is stored in a TimeVal structure.
- UINT bh_caplen; ///< Length of captured portion. The captured portion <b>can be different</b>
- ///< from the original packet, because it is possible (with a proper filter)
- ///< to instruct the driver to capture only a portion of the packets.
- UINT bh_datalen; ///< Original length of packet
- USHORT bh_hdrlen; ///< Length of bpf header (this struct plus alignment padding). In some cases,
- ///< a padding could be added between the end of this structure and the packet
- ///< data for performance reasons. This filed can be used to retrieve the actual data
- ///< of the packet.
-};
-
-/*!
- \brief Dump packet header.
-
- This structure defines the header associated with the packets in a buffer to be used with PacketSendPackets().
- It is simpler than the bpf_hdr, because it corresponds to the header associated by WinPcap and libpcap to a
- packet in a dump file. This makes straightforward sending WinPcap dump files to the network.
-*/
-struct dump_bpf_hdr{
- struct timeval ts; ///< Time stamp of the packet
- UINT caplen; ///< Length of captured portion. The captured portion can smaller than the
- ///< the original packet, because it is possible (with a proper filter) to
- ///< instruct the driver to capture only a portion of the packets.
- UINT len; ///< Length of the original packet (off wire).
-};
-
-
-#endif
-
-struct bpf_stat;
-
-#define DOSNAMEPREFIX TEXT("Packet_") ///< Prefix added to the adapters device names to create the WinPcap devices
-#define MAX_LINK_NAME_LENGTH 64 //< Maximum length of the devices symbolic links
-#define NMAX_PACKET 65535
-
-/*!
- \brief Addresses of a network adapter.
-
- This structure is used by the PacketGetNetInfoEx() function to return the IP addresses associated with
- an adapter.
-*/
-typedef struct npf_if_addr {
- struct sockaddr_storage IPAddress; ///< IP address.
- struct sockaddr_storage SubnetMask; ///< Netmask for that address.
- struct sockaddr_storage Broadcast; ///< Broadcast address.
-}npf_if_addr;
-
-
-#define ADAPTER_NAME_LENGTH 256 + 12 ///< Maximum length for the name of an adapter. The value is the same used by the IP Helper API.
-#define ADAPTER_DESC_LENGTH 128 ///< Maximum length for the description of an adapter. The value is the same used by the IP Helper API.
-#define MAX_MAC_ADDR_LENGTH 8 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
-#define MAX_NETWORK_ADDRESSES 16 ///< Maximum length for the link layer address of an adapter. The value is the same used by the IP Helper API.
-
-
-typedef struct WAN_ADAPTER_INT WAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
-typedef WAN_ADAPTER *PWAN_ADAPTER; ///< Describes an opened wan (dialup, VPN...) network adapter using the NetMon API
-
-#define INFO_FLAG_NDIS_ADAPTER 0 ///< Flag for ADAPTER_INFO: this is a traditional ndis adapter
-#define INFO_FLAG_NDISWAN_ADAPTER 1 ///< Flag for ADAPTER_INFO: this is a NdisWan adapter, and it's managed by WANPACKET
-#define INFO_FLAG_DAG_CARD 2 ///< Flag for ADAPTER_INFO: this is a DAG card
-#define INFO_FLAG_DAG_FILE 6 ///< Flag for ADAPTER_INFO: this is a DAG file
-#define INFO_FLAG_DONT_EXPORT 8 ///< Flag for ADAPTER_INFO: when this flag is set, the adapter will not be listed or openend by winpcap. This allows to prevent exporting broken network adapters, like for example FireWire ones.
-#define INFO_FLAG_AIRPCAP_CARD 16 ///< Flag for ADAPTER_INFO: this is an airpcap card
-#define INFO_FLAG_NPFIM_DEVICE 32
-
-/*!
- \brief Describes an opened network adapter.
-
- This structure is the most important for the functioning of packet.dll, but the great part of its fields
- should be ignored by the user, since the library offers functions that avoid to cope with low-level parameters
-*/
-typedef struct _ADAPTER {
- HANDLE hFile; ///< \internal Handle to an open instance of the NPF driver.
- CHAR SymbolicLink[MAX_LINK_NAME_LENGTH]; ///< \internal A string containing the name of the network adapter currently opened.
- int NumWrites; ///< \internal Number of times a packets written on this adapter will be repeated
- ///< on the wire.
- HANDLE ReadEvent; ///< A notification event associated with the read calls on the adapter.
- ///< It can be passed to standard Win32 functions (like WaitForSingleObject
- ///< or WaitForMultipleObjects) to wait until the driver's buffer contains some
- ///< data. It is particularly useful in GUI applications that need to wait
- ///< concurrently on several events. In Windows NT/2000 the PacketSetMinToCopy()
- ///< function can be used to define the minimum amount of data in the kernel buffer
- ///< that will cause the event to be signalled.
-
- UINT ReadTimeOut; ///< \internal The amount of time after which a read on the driver will be released and
- ///< ReadEvent will be signaled, also if no packets were captured
- CHAR Name[ADAPTER_NAME_LENGTH];
- PWAN_ADAPTER pWanAdapter;
- UINT Flags; ///< Adapter's flags. Tell if this adapter must be treated in a different way, using the Netmon API or the dagc API.
-
-#ifdef HAVE_AIRPCAP_API
- PAirpcapHandle AirpcapAd;
-#endif // HAVE_AIRPCAP_API
-
-#ifdef HAVE_NPFIM_API
- void* NpfImHandle;
-#endif // HAVE_NPFIM_API
-
-#ifdef HAVE_DAG_API
- dagc_t *pDagCard; ///< Pointer to the dagc API adapter descriptor for this adapter
- PCHAR DagBuffer; ///< Pointer to the buffer with the packets that is received from the DAG card
- struct timeval DagReadTimeout; ///< Read timeout. The dagc API requires a timeval structure
- unsigned DagFcsLen; ///< Length of the frame check sequence attached to any packet by the card. Obtained from the registry
- DWORD DagFastProcess; ///< True if the user requests fast capture processing on this card. Higher level applications can use this value to provide a faster but possibly unprecise capture (for example, libpcap doesn't convert the timestamps).
-#endif // HAVE_DAG_API
-} ADAPTER, *LPADAPTER;
-
-/*!
- \brief Structure that contains a group of packets coming from the driver.
-
- This structure defines the header associated with every packet delivered to the application.
-*/
-typedef struct _PACKET {
- HANDLE hEvent; ///< \deprecated Still present for compatibility with old applications.
- OVERLAPPED OverLapped; ///< \deprecated Still present for compatibility with old applications.
- PVOID Buffer; ///< Buffer with containing the packets. See the PacketReceivePacket() for
- ///< details about the organization of the data in this buffer
- UINT Length; ///< Length of the buffer
- DWORD ulBytesReceived; ///< Number of valid bytes present in the buffer, i.e. amount of data
- ///< received by the last call to PacketReceivePacket()
- BOOLEAN bIoComplete; ///< \deprecated Still present for compatibility with old applications.
-} PACKET, *LPPACKET;
-
-/*!
- \brief Structure containing an OID request.
-
- It is used by the PacketRequest() function to send an OID to the interface card driver.
- It can be used, for example, to retrieve the status of the error counters on the adapter, its MAC address,
- the list of the multicast groups defined on it, and so on.
-*/
-struct _PACKET_OID_DATA {
- ULONG Oid; ///< OID code. See the Microsoft DDK documentation or the file ntddndis.h
- ///< for a complete list of valid codes.
- ULONG Length; ///< Length of the data field
- UCHAR Data[1]; ///< variable-lenght field that contains the information passed to or received
- ///< from the adapter.
-};
-typedef struct _PACKET_OID_DATA PACKET_OID_DATA, *PPACKET_OID_DATA;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/**
- * @}
- */
-
-/*
-BOOLEAN QueryWinPcapRegistryStringA(CHAR *SubKeyName,
- CHAR *Value,
- UINT *pValueLen,
- CHAR *DefaultVal);
-
-BOOLEAN QueryWinPcapRegistryStringW(WCHAR *SubKeyName,
- WCHAR *Value,
- UINT *pValueLen,
- WCHAR *DefaultVal);
-*/
-
-//---------------------------------------------------------------------------
-// EXPORTED FUNCTIONS
-//---------------------------------------------------------------------------
-
-PCHAR PacketGetVersion();
-PCHAR PacketGetDriverVersion();
-BOOLEAN PacketSetMinToCopy(LPADAPTER AdapterObject,int nbytes);
-BOOLEAN PacketSetNumWrites(LPADAPTER AdapterObject,int nwrites);
-BOOLEAN PacketSetMode(LPADAPTER AdapterObject,int mode);
-BOOLEAN PacketSetReadTimeout(LPADAPTER AdapterObject,int timeout);
-BOOLEAN PacketSetBpf(LPADAPTER AdapterObject,struct bpf_program *fp);
-BOOLEAN PacketSetLoopbackBehavior(LPADAPTER AdapterObject, UINT LoopbackBehavior);
-INT PacketSetSnapLen(LPADAPTER AdapterObject,int snaplen);
-BOOLEAN PacketGetStats(LPADAPTER AdapterObject,struct bpf_stat *s);
-BOOLEAN PacketGetStatsEx(LPADAPTER AdapterObject,struct bpf_stat *s);
-BOOLEAN PacketSetBuff(LPADAPTER AdapterObject,int dim);
-BOOLEAN PacketGetNetType (LPADAPTER AdapterObject,NetType *type);
-LPADAPTER PacketOpenAdapter(PCHAR AdapterName);
-BOOLEAN PacketSendPacket(LPADAPTER AdapterObject,LPPACKET pPacket,BOOLEAN Sync);
-INT PacketSendPackets(LPADAPTER AdapterObject,PVOID PacketBuff,ULONG Size, BOOLEAN Sync);
-LPPACKET PacketAllocatePacket(void);
-VOID PacketInitPacket(LPPACKET lpPacket,PVOID Buffer,UINT Length);
-VOID PacketFreePacket(LPPACKET lpPacket);
-BOOLEAN PacketReceivePacket(LPADAPTER AdapterObject,LPPACKET lpPacket,BOOLEAN Sync);
-BOOLEAN PacketSetHwFilter(LPADAPTER AdapterObject,ULONG Filter);
-BOOLEAN PacketGetAdapterNames(PTSTR pStr,PULONG BufferSize);
-BOOLEAN PacketGetNetInfoEx(PCHAR AdapterName, npf_if_addr* buffer, PLONG NEntries);
-BOOLEAN PacketRequest(LPADAPTER AdapterObject,BOOLEAN Set,PPACKET_OID_DATA OidData);
-HANDLE PacketGetReadEvent(LPADAPTER AdapterObject);
-BOOLEAN PacketSetDumpName(LPADAPTER AdapterObject, void *name, int len);
-BOOLEAN PacketSetDumpLimits(LPADAPTER AdapterObject, UINT maxfilesize, UINT maxnpacks);
-BOOLEAN PacketIsDumpEnded(LPADAPTER AdapterObject, BOOLEAN sync);
-BOOL PacketStopDriver();
-VOID PacketCloseAdapter(LPADAPTER lpAdapter);
-BOOLEAN PacketStartOem(PCHAR errorString, UINT errorStringLength);
-BOOLEAN PacketStartOemEx(PCHAR errorString, UINT errorStringLength, ULONG flags);
-PAirpcapHandle PacketGetAirPcapHandle(LPADAPTER AdapterObject);
-
-//
-// Used by PacketStartOemEx
-//
-#define PACKET_START_OEM_NO_NETMON 0x00000001
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__PACKET32
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/PacketData.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/PacketData.h
deleted file mode 100644
index 8124db66d..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/PacketData.h
+++ /dev/null
@@ -1,267 +0,0 @@
-char pkt1[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x30, 0x09, 0x9c, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x07, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x35, 0x00, 0x00, 0x00, 0x00, 0x70, 0x02,
-0x40, 0x00, 0xdf, 0xab, 0x00, 0x00, 0x02, 0x04,
-0x05, 0xb4, 0x01, 0x01, 0x04, 0x02 };
-
-char pkt2[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa6, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt3[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0x9e, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt4[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x02, 0x27, 0x09, 0x9f, 0x40, 0x00, 0x80, 0x06,
-0x6d, 0x0d, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18,
-0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45,
-0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50,
-0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63,
-0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c,
-0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78,
-0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70,
-0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
-0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65,
-0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
-0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76,
-0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78,
-0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c,
-0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64,
-0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65,
-0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20,
-0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73,
-0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70,
-0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78,
-0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d,
-0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d,
-0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c,
-0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a,
-0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45,
-0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a,
-0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64,
-0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a,
-0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65,
-0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69,
-0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20,
-0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69,
-0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49,
-0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57,
-0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e,
-0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53,
-0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67,
-0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e,
-0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32,
-0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30,
-0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32,
-0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48,
-0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32,
-0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31,
-0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
-0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b,
-0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76,
-0x65, 0x0d, 0x0a, 0x0d, 0x0a };
-
-char pkt5[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x02, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa5, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt6[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa1, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt7[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x02, 0x27, 0x09, 0xa2, 0x40, 0x00, 0x80, 0x06,
-0x6d, 0x0a, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc7, 0x36, 0x00, 0x00, 0x06, 0x69, 0x50, 0x18,
-0x42, 0xd8, 0x84, 0x3e, 0x00, 0x00, 0x47, 0x45,
-0x54, 0x20, 0x2f, 0x20, 0x48, 0x54, 0x54, 0x50,
-0x2f, 0x31, 0x2e, 0x31, 0x0d, 0x0a, 0x41, 0x63,
-0x63, 0x65, 0x70, 0x74, 0x3a, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x67, 0x69, 0x66, 0x2c,
-0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f, 0x78,
-0x2d, 0x78, 0x62, 0x69, 0x74, 0x6d, 0x61, 0x70,
-0x2c, 0x20, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x2f,
-0x6a, 0x70, 0x65, 0x67, 0x2c, 0x20, 0x69, 0x6d,
-0x61, 0x67, 0x65, 0x2f, 0x70, 0x6a, 0x70, 0x65,
-0x67, 0x2c, 0x20, 0x61, 0x70, 0x70, 0x6c, 0x69,
-0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76,
-0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d, 0x65, 0x78,
-0x63, 0x65, 0x6c, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x6d, 0x73, 0x77, 0x6f, 0x72, 0x64, 0x2c,
-0x20, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2f, 0x76, 0x6e, 0x64,
-0x2e, 0x6d, 0x73, 0x2d, 0x70, 0x6f, 0x77, 0x65,
-0x72, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x2c, 0x20,
-0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74,
-0x69, 0x6f, 0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73,
-0x2d, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61,
-0x74, 0x69, 0x6f, 0x6e, 0x2c, 0x20, 0x61, 0x70,
-0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
-0x6e, 0x2f, 0x78, 0x2d, 0x6d, 0x73, 0x2d, 0x78,
-0x62, 0x61, 0x70, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6d, 0x73, 0x2d,
-0x78, 0x70, 0x73, 0x64, 0x6f, 0x63, 0x75, 0x6d,
-0x65, 0x6e, 0x74, 0x2c, 0x20, 0x61, 0x70, 0x70,
-0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e,
-0x2f, 0x78, 0x61, 0x6d, 0x6c, 0x2b, 0x78, 0x6d,
-0x6c, 0x2c, 0x20, 0x2a, 0x2f, 0x2a, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x4c,
-0x61, 0x6e, 0x67, 0x75, 0x61, 0x67, 0x65, 0x3a,
-0x20, 0x65, 0x6e, 0x2d, 0x67, 0x62, 0x0d, 0x0a,
-0x41, 0x63, 0x63, 0x65, 0x70, 0x74, 0x2d, 0x45,
-0x6e, 0x63, 0x6f, 0x64, 0x69, 0x6e, 0x67, 0x3a,
-0x20, 0x67, 0x7a, 0x69, 0x70, 0x2c, 0x20, 0x64,
-0x65, 0x66, 0x6c, 0x61, 0x74, 0x65, 0x0d, 0x0a,
-0x55, 0x73, 0x65, 0x72, 0x2d, 0x41, 0x67, 0x65,
-0x6e, 0x74, 0x3a, 0x20, 0x4d, 0x6f, 0x7a, 0x69,
-0x6c, 0x6c, 0x61, 0x2f, 0x34, 0x2e, 0x30, 0x20,
-0x28, 0x63, 0x6f, 0x6d, 0x70, 0x61, 0x74, 0x69,
-0x62, 0x6c, 0x65, 0x3b, 0x20, 0x4d, 0x53, 0x49,
-0x45, 0x20, 0x36, 0x2e, 0x30, 0x3b, 0x20, 0x57,
-0x69, 0x6e, 0x64, 0x6f, 0x77, 0x73, 0x20, 0x4e,
-0x54, 0x20, 0x35, 0x2e, 0x31, 0x3b, 0x20, 0x53,
-0x56, 0x31, 0x3b, 0x20, 0x47, 0x6f, 0x6f, 0x67,
-0x6c, 0x65, 0x54, 0x35, 0x3b, 0x20, 0x2e, 0x4e,
-0x45, 0x54, 0x20, 0x43, 0x4c, 0x52, 0x20, 0x32,
-0x2e, 0x30, 0x2e, 0x35, 0x30, 0x37, 0x32, 0x37,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x30, 0x2e, 0x30,
-0x34, 0x35, 0x30, 0x36, 0x2e, 0x36, 0x34, 0x38,
-0x3b, 0x20, 0x2e, 0x4e, 0x45, 0x54, 0x20, 0x43,
-0x4c, 0x52, 0x20, 0x33, 0x2e, 0x35, 0x2e, 0x32,
-0x31, 0x30, 0x32, 0x32, 0x29, 0x0d, 0x0a, 0x48,
-0x6f, 0x73, 0x74, 0x3a, 0x20, 0x31, 0x39, 0x32,
-0x2e, 0x31, 0x36, 0x38, 0x2e, 0x30, 0x2e, 0x31,
-0x32, 0x0d, 0x0a, 0x43, 0x6f, 0x6e, 0x6e, 0x65,
-0x63, 0x74, 0x69, 0x6f, 0x6e, 0x3a, 0x20, 0x4b,
-0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76,
-0x65, 0x0d, 0x0a, 0x0d, 0x0a };
-
-char pkt8[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x03, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa4, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt9[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa3, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x08, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt10[] = {
-0x00, 0x14, 0x22, 0xcb, 0x18, 0x2d, 0x00, 0x01,
-0x02, 0x45, 0x09, 0x11, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x2c, 0x00, 0x04, 0x00, 0x00, 0x40, 0x06,
-0xf8, 0xa3, 0xc0, 0xa8, 0x00, 0x0c, 0xc0, 0xa8,
-0x00, 0xc8, 0x00, 0x50, 0x0f, 0xe2, 0x00, 0x00,
-0x06, 0x68, 0x09, 0xe7, 0xc7, 0x36, 0x60, 0x12,
-0x05, 0x92, 0x28, 0xca, 0x00, 0x00, 0x02, 0x04,
-0x05, 0x92 };
-
-char pkt11[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa6, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x05, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x10,
-0x42, 0xd8, 0x82, 0x3f, 0x00, 0x00 };
-
-char pkt12[] = {
-0x00, 0x01, 0x02, 0x45, 0x09, 0x11, 0x00, 0x14,
-0x22, 0xcb, 0x18, 0x2d, 0x08, 0x00, 0x45, 0x00,
-0x00, 0x28, 0x09, 0xa7, 0x40, 0x00, 0x80, 0x06,
-0x6f, 0x04, 0xc0, 0xa8, 0x00, 0xc8, 0xc0, 0xa8,
-0x00, 0x0c, 0x0f, 0xe2, 0x00, 0x50, 0x09, 0xe7,
-0xc9, 0x35, 0x00, 0x00, 0x06, 0x69, 0x50, 0x14,
-0x00, 0x00, 0x43, 0xf4, 0x00, 0x00 };
-
-
-typedef struct
-{
- char *pcData;
- int iDataLen;
-} xPacketData;
-
-xPacketData xAllPackets[] =
-{
- { pkt1, sizeof( pkt1 ) },
-// { pkt2, sizeof( pkt2 ) },
- { pkt3, sizeof( pkt3 ) },
- { pkt4, sizeof( pkt4 ) },
-// { pkt5, sizeof( pkt5 ) },
- { pkt6, sizeof( pkt6 ) },
- { pkt7, sizeof( pkt7 ) },
- { pkt8, sizeof( pkt8 ) },
- { pkt9, sizeof( pkt9 ) },
- { pkt10, sizeof( pkt10 ) },
-// { pkt11, sizeof( pkt11 ) },
-// { pkt12, sizeof( pkt12 ) },
-// { pkt13, sizeof( pkt13 ) },
-// { pkt14, sizeof( pkt14 ) },
-// { pkt15, sizeof( pkt15 ) },
-// { pkt16, sizeof( pkt16 ) },
-};
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Win32-Extensions.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Win32-Extensions.h
deleted file mode 100644
index be71c85e9..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/Win32-Extensions.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (c) 1999 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2006 CACE Technologies, Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino, CACE Technologies
- * 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef __WIN32_EXTENSIONS_H__
-#define __WIN32_EXTENSIONS_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Definitions */
-
-/*!
- \brief A queue of raw packets that will be sent to the network with pcap_sendqueue_transmit().
-*/
-struct pcap_send_queue
-{
- u_int maxlen; ///< Maximum size of the the queue, in bytes. This variable contains the size of the buffer field.
- u_int len; ///< Current size of the queue, in bytes.
- char *buffer; ///< Buffer containing the packets to be sent.
-};
-
-typedef struct pcap_send_queue pcap_send_queue;
-
-/*!
- \brief This typedef is a support for the pcap_get_airpcap_handle() function
-*/
-#if !defined(AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_)
-#define AIRPCAP_HANDLE__EAE405F5_0171_9592_B3C2_C19EC426AD34__DEFINED_
-typedef struct _AirpcapHandle *PAirpcapHandle;
-#endif
-
-#define BPF_MEM_EX_IMM 0xc0
-#define BPF_MEM_EX_IND 0xe0
-
-/*used for ST*/
-#define BPF_MEM_EX 0xc0
-#define BPF_TME 0x08
-
-#define BPF_LOOKUP 0x90
-#define BPF_EXECUTE 0xa0
-#define BPF_INIT 0xb0
-#define BPF_VALIDATE 0xc0
-#define BPF_SET_ACTIVE 0xd0
-#define BPF_RESET 0xe0
-#define BPF_SET_MEMORY 0x80
-#define BPF_GET_REGISTER_VALUE 0x70
-#define BPF_SET_REGISTER_VALUE 0x60
-#define BPF_SET_WORKING 0x50
-#define BPF_SET_ACTIVE_READ 0x40
-#define BPF_SET_AUTODELETION 0x30
-#define BPF_SEPARATION 0xff
-
-/* Prototypes */
-pcap_send_queue* pcap_sendqueue_alloc(u_int memsize);
-
-void pcap_sendqueue_destroy(pcap_send_queue* queue);
-
-int pcap_sendqueue_queue(pcap_send_queue* queue, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data);
-
-u_int pcap_sendqueue_transmit(pcap_t *p, pcap_send_queue* queue, int sync);
-
-HANDLE pcap_getevent(pcap_t *p);
-
-struct pcap_stat *pcap_stats_ex(pcap_t *p, int *pcap_stat_size);
-
-int pcap_setuserbuffer(pcap_t *p, int size);
-
-int pcap_live_dump(pcap_t *p, char *filename, int maxsize, int maxpacks);
-
-int pcap_live_dump_ended(pcap_t *p, int sync);
-
-int pcap_offline_filter(struct bpf_program *prog, const struct pcap_pkthdr *header, const u_char *pkt_data);
-
-int pcap_start_oem(char* err_str, int flags);
-
-PAirpcapHandle pcap_get_airpcap_handle(pcap_t *p);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif //__WIN32_EXTENSIONS_H__
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/arch.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/arch.c
deleted file mode 100644
index d704da800..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/arch.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/* WinPCap includes. */
-#include "pcap.h"
-#include "remote-ext.h"
-
-/* uIP includes. */
-#include "net/uip.h"
-#include "net/uip_arp.h"
-#include "net/clock-arch.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-/*
- * Query the computer the simulation is being executed on to find the network
- * interfaces it has installed.
- */
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
-
-/*
- * Open the network interface. The number of the interface to be opened is set
- * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- */
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
-
-/*
- * Configure the capture filter to allow blocking reads, and to filter out
- * packets that are not of interest to this demo.
- */
-static void prvConfigureCaptureBehaviour( void );
-
-pcap_t *pxOpenedInterfaceHandle = NULL;
-LARGE_INTEGER freq, sys_start_time;
-
-#define archNUM_BUFFERS 5
-#define archNUM_BUFFER_POINTERS ( archNUM_BUFFERS - 1 )
-
-static void prvInterruptSimulator( void *pvParameters );
-
-static unsigned char ucEthernetBuffer[ archNUM_BUFFERS ][ UIP_CONF_BUFFER_SIZE ];
-static unsigned char *pucEthernetBufferPointers[ archNUM_BUFFER_POINTERS ];
-
-static long lLengthOfDataInBuffer[ archNUM_BUFFER_POINTERS ] = { 0 };
-static unsigned char ucNextBufferToFill = 0U, ucNextBufferToProcess = 0U;
-
-unsigned char *uip_buf = NULL;
-char cErrorBuffer[PCAP_ERRBUF_SIZE];
-
-void vNetifTx( void )
-{
- pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len );
- pcap_sendpacket( pxOpenedInterfaceHandle, uip_buf, uip_len );
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxNetifRx( void )
-{
-UBaseType_t xDataLen;
-unsigned char *pucTemp;
-
- /* Check there is really data available. */
- xDataLen = lLengthOfDataInBuffer[ ucNextBufferToProcess ];
- if( xDataLen != 0L )
- {
-
- /* The buffer pointed to by uip_buf is going to change. Remember which
- buffer uip_buf is currently pointing to. */
- pucTemp = uip_buf;
-
- /* Point uip_buf at the next buffer that contains data. */
- uip_buf = pucEthernetBufferPointers[ ucNextBufferToProcess ];
-
- /* The buffer pointed to by
- pucEthernetBufferPointeres[ ucNextBufferToProcess ] is now in use by
- uip_buf, but the buffer uip_buf was pointing to on entry to this
- function is free. Set
- pucEthernetBufferPointeres[ ucNextBufferToProcess ] to the free
- buffer. */
- pucEthernetBufferPointers[ ucNextBufferToProcess ] = pucTemp;
- lLengthOfDataInBuffer[ ucNextBufferToProcess ] = 0L;
-
- ucNextBufferToProcess++;
- if( ucNextBufferToProcess >= archNUM_BUFFER_POINTERS )
- {
- ucNextBufferToProcess = 0L;
- }
- }
-
- return xDataLen;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetifInit( void )
-{
-BaseType_t x;
-pcap_if_t *pxAllNetworkInterfaces;
-
- /* Allocate a free buffer to each buffer pointer. */
- for( x = 0; x < sizeof( pucEthernetBufferPointers ) / sizeof( unsigned char * ); x++ )
- {
- pucEthernetBufferPointers[ x ] = &( ucEthernetBuffer[ x ][ 0 ] );
- }
-
- /* Start with uip_buf pointing to a buffer that is not referenced from the
- pucEthernetBufferPointers[] array. */
- uip_buf = &( ucEthernetBuffer[ archNUM_BUFFERS - 1 ][ 0 ] );
-
- /* Query the computer the simulation is being executed on to find the
- network interfaces it has installed. */
- pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
-
- /* Open the network interface. The number of the interface to be opened is
- set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- Calling this function will set the pxOpenedInterfaceHandle variable. If,
- after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
- the interface could not be opened. */
- if( pxAllNetworkInterfaces != NULL )
- {
- prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
- }
-
-
- return x;
-}
-/*-----------------------------------------------------------*/
-
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
-{
-pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
-long lInterfaceNumber = 1;
-
- if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
- {
- printf( "\r\nCould not obtain a list of network interfaces\r\n%s\r\n", cErrorBuffer );
- pxAllNetworkInterfaces = NULL;
- }
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Print out the list of network interfaces. The first in the list
- is interface '1', not interface '0'. */
- for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
- {
- printf( "%d. %s", lInterfaceNumber, xInterface->name );
-
- if( xInterface->description != NULL )
- {
- printf( " (%s)\r\n", xInterface->description );
- }
- else
- {
- printf( " (No description available)\r\n") ;
- }
-
- lInterfaceNumber++;
- }
- }
-
- if( lInterfaceNumber == 1 )
- {
- /* The interface number was never incremented, so the above for() loop
- did not execute meaning no interfaces were found. */
- printf( " \r\nNo network interfaces were found.\r\n" );
- pxAllNetworkInterfaces = NULL;
- }
-
- printf( "\r\nThe interface that will be opened is set by configNETWORK_INTERFACE_TO_USE which should be defined in FreeRTOSConfig.h\r\n" );
- printf( "Attempting to open interface number %d.\r\n", configNETWORK_INTERFACE_TO_USE );
-
- if( ( configNETWORK_INTERFACE_TO_USE < 1L ) || ( configNETWORK_INTERFACE_TO_USE > lInterfaceNumber ) )
- {
- printf("\r\nconfigNETWORK_INTERFACE_TO_USE is not in the valid range.\r\n" );
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Free the device list, as no devices are going to be opened. */
- pcap_freealldevs( pxAllNetworkInterfaces );
- pxAllNetworkInterfaces = NULL;
- }
- }
-
- return pxAllNetworkInterfaces;
-}
-/*-----------------------------------------------------------*/
-
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
-{
-pcap_if_t *xInterface;
-long x;
-
- /* Walk the list of devices until the selected device is located. */
- xInterface = pxAllNetworkInterfaces;
- for( x = 0L; x < ( configNETWORK_INTERFACE_TO_USE - 1L ); x++ )
- {
- xInterface = xInterface->next;
- }
-
- /* Open the selected interface. */
- pxOpenedInterfaceHandle = pcap_open( xInterface->name, /* The name of the selected interface. */
- UIP_CONF_BUFFER_SIZE, /* The size of the packet to capture. */
- PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscious mode as the MAC and
- IP address is going to be "simulated", and
- not be the real MAC and IP address. This allows
- trafic to the simulated IP address to be routed
- to uIP, and trafic to the real IP address to be
- routed to the Windows TCP/IP stack. */
- 0xfffffffL, /* The read time out. This is going to block
- until data is available. */
- NULL, /* No authentication is required as this is
- not a remote capture session. */
- cErrorBuffer
- );
-
- if ( pxOpenedInterfaceHandle == NULL )
- {
- printf( "\r\n%s is not supported by WinPcap and cannot be opened\r\n", xInterface->name );
- }
- else
- {
- /* Configure the capture filter to allow blocking reads, and to filter
- out packets that are not of interest to this demo. */
- prvConfigureCaptureBehaviour();
- }
-
- /* The device list is no longer required. */
- pcap_freealldevs( pxAllNetworkInterfaces );
-}
-/*-----------------------------------------------------------*/
-
-static void prvConfigureCaptureBehaviour( void )
-{
-struct bpf_program xFilterCode;
-const long lMinBytesToCopy = 10L, lBlocking = 0L;
-unsigned long ulNetMask;
-
- /* Unblock a read as soon as anything is received. */
- pcap_setmintocopy( pxOpenedInterfaceHandle, lMinBytesToCopy );
-
- /* Allow blocking. */
- pcap_setnonblock( pxOpenedInterfaceHandle, lBlocking, cErrorBuffer );
-
- /* Set up a filter so only the packets of interest are passed to the uIP
- stack. cErrorBuffer is used for convenience to create the string. Don't
- confuse this with an error message. */
- sprintf( cErrorBuffer, "broadcast or multicast or host %d.%d.%d.%d", configIP_ADDR0, configIP_ADDR1, configIP_ADDR2, configIP_ADDR3 );
-
- ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
-
- if( pcap_compile(pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
- {
- printf("\r\nThe packet filter string is invalid\r\n" );
- }
- else
- {
- if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
- {
- printf( "\r\nAn error occurred setting the packet filter.\r\n" );
- }
- }
-
- /* Create a task that simulates an interrupt in a real system. This will
- block waiting for packets, then send a message to the uIP task when data
- is available. */
- xTaskCreate( prvInterruptSimulator, ( signed char * ) "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, ( configuIP_TASK_PRIORITY - 1 ), NULL );
-}
-/*-----------------------------------------------------------*/
-
-static void prvInterruptSimulator( void *pvParameters )
-{
-static struct pcap_pkthdr *pxHeader;
-const unsigned char *pucPacketData;
-extern QueueHandle_t xEMACEventQueue;
-const unsigned long ulRxEvent = uipETHERNET_RX_EVENT;
-long lResult;
-
- /* Just to kill the compiler warning. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- /* Get the next packet. */
- lResult = pcap_next_ex( pxOpenedInterfaceHandle, &pxHeader, &pucPacketData );
- if( lResult )
- {
- /* Is the next buffer into which data should be placed free? */
- if( lLengthOfDataInBuffer[ ucNextBufferToFill ] == 0L )
- {
- /* Copy the data from the captured packet into the buffer. */
- memcpy( pucEthernetBufferPointers[ ucNextBufferToFill ], pucPacketData, pxHeader->len );
-
- /* Note the amount of data that was copied. */
- lLengthOfDataInBuffer[ ucNextBufferToFill ] = pxHeader->len;
-
- /* Move onto the next buffer, wrapping around if necessary. */
- ucNextBufferToFill++;
- if( ucNextBufferToFill >= archNUM_BUFFER_POINTERS )
- {
- ucNextBufferToFill = 0U;
- }
-
- /* Data was received and stored. Send a message to the uIP task
- to let it know. */
- xQueueSendToBack( xEMACEventQueue, &ulRxEvent, portMAX_DELAY );
- }
- }
- }
-}
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/bittypes.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/bittypes.h
deleted file mode 100644
index f55fcecfd..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/bittypes.h
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- * Copyright (C) 1999 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project 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 PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef _BITTYPES_H
-#define _BITTYPES_H
-
-#ifndef HAVE_U_INT8_T
-
-#if SIZEOF_CHAR == 1
-typedef unsigned char u_int8_t;
-typedef signed char _int8_t;
-#elif SIZEOF_INT == 1
-typedef unsigned int u_int8_t;
-typedef signed int int8_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int8_t"
-#endif
-#define HAVE_U_INT8_T 1
-#define HAVE_INT8_T 1
-
-#endif /* HAVE_U_INT8_T */
-
-#ifndef HAVE_U_INT16_T
-
-#if SIZEOF_SHORT == 2
-typedef unsigned short u_int16_t;
-typedef signed short _int16_t;
-#elif SIZEOF_INT == 2
-typedef unsigned int u_int16_t;
-typedef signed int int16_t;
-#elif SIZEOF_CHAR == 2
-typedef unsigned char u_int16_t;
-typedef signed char int16_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int16_t"
-#endif
-#define HAVE_U_INT16_T 1
-#define HAVE_INT16_T 1
-
-#endif /* HAVE_U_INT16_T */
-
-#ifndef HAVE_U_INT32_T
-
-#if SIZEOF_INT == 4
-typedef unsigned int u_int32_t;
-typedef signed int _int32_t;
-#elif SIZEOF_LONG == 4
-typedef unsigned long u_int32_t;
-typedef signed long int32_t;
-#elif SIZEOF_SHORT == 4
-typedef unsigned short u_int32_t;
-typedef signed short int32_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int32_t"
-#endif
-#define HAVE_U_INT32_T 1
-#define HAVE_INT32_T 1
-
-#endif /* HAVE_U_INT32_T */
-
-#ifndef HAVE_U_INT64_T
-#if SIZEOF_LONG_LONG == 8
-typedef unsigned long long u_int64_t;
-typedef long long int64_t;
-#elif defined(_MSC_EXTENSIONS)
-typedef unsigned _int64 u_int64_t;
-typedef _int64 int64_t;
-#elif SIZEOF_INT == 8
-typedef unsigned int u_int64_t;
-#elif SIZEOF_LONG == 8
-typedef unsigned long u_int64_t;
-#elif SIZEOF_SHORT == 8
-typedef unsigned short u_int64_t;
-#else /* XXX */
-#error "there's no appropriate type for u_int64_t"
-#endif
-
-#endif /* HAVE_U_INT64_T */
-
-#ifndef PRId64
-#ifdef _MSC_EXTENSIONS
-#define PRId64 "I64d"
-#else /* _MSC_EXTENSIONS */
-#define PRId64 "lld"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRId64 */
-
-#ifndef PRIo64
-#ifdef _MSC_EXTENSIONS
-#define PRIo64 "I64o"
-#else /* _MSC_EXTENSIONS */
-#define PRIo64 "llo"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRIo64 */
-
-#ifndef PRIx64
-#ifdef _MSC_EXTENSIONS
-#define PRIx64 "I64x"
-#else /* _MSC_EXTENSIONS */
-#define PRIx64 "llx"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRIx64 */
-
-#ifndef PRIu64
-#ifdef _MSC_EXTENSIONS
-#define PRIu64 "I64u"
-#else /* _MSC_EXTENSIONS */
-#define PRIu64 "llu"
-#endif /* _MSC_EXTENSIONS */
-#endif /* PRIu64 */
-
-#endif /* _BITTYPES_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/ip6_misc.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/ip6_misc.h
deleted file mode 100644
index 562fa6184..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/ip6_misc.h
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that: (1) source code distributions
- * retain the above copyright notice and this paragraph in its entirety, (2)
- * distributions including binary code include the above copyright notice and
- * this paragraph in its entirety in the documentation or other materials
- * provided with the distribution, and (3) all advertising materials mentioning
- * features or use of this software display the following acknowledgement:
- * ``This product includes software developed by the University of California,
- * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
- * the University 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 ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/Win32/Include/ip6_misc.h,v 1.5 2006-01-22 18:02:18 gianluca Exp $ (LBL)
- */
-
-/*
- * This file contains a collage of declarations for IPv6 from FreeBSD not present in Windows
- */
-
-#include <winsock2.h>
-
-#include <ws2tcpip.h>
-
-#ifndef __MINGW32__
-#define IN_MULTICAST(a) IN_CLASSD(a)
-#endif
-
-#define IN_EXPERIMENTAL(a) ((((u_int32_t) (a)) & 0xf0000000) == 0xf0000000)
-
-#define IN_LOOPBACKNET 127
-
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
-/* IPv6 address */
-struct in6_addr
- {
- union
- {
- u_int8_t u6_addr8[16];
- u_int16_t u6_addr16[8];
- u_int32_t u6_addr32[4];
- } in6_u;
-#define s6_addr in6_u.u6_addr8
-#define s6_addr16 in6_u.u6_addr16
-#define s6_addr32 in6_u.u6_addr32
-#define s6_addr64 in6_u.u6_addr64
- };
-
-#define IN6ADDR_ANY_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 }
-#define IN6ADDR_LOOPBACK_INIT { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1 }
-#endif /* __MINGW32__ */
-
-
-#if (defined _MSC_VER) || (defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF))
-typedef unsigned short sa_family_t;
-#endif
-
-
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
-
-#define __SOCKADDR_COMMON(sa_prefix) \
- sa_family_t sa_prefix##family
-
-/* Ditto, for IPv6. */
-struct sockaddr_in6
- {
- __SOCKADDR_COMMON (sin6_);
- u_int16_t sin6_port; /* Transport layer port # */
- u_int32_t sin6_flowinfo; /* IPv6 flow information */
- struct in6_addr sin6_addr; /* IPv6 address */
- };
-
-#define IN6_IS_ADDR_V4MAPPED(a) \
- ((((u_int32_t *) (a))[0] == 0) && (((u_int32_t *) (a))[1] == 0) && \
- (((u_int32_t *) (a))[2] == htonl (0xffff)))
-
-#define IN6_IS_ADDR_MULTICAST(a) (((u_int8_t *) (a))[0] == 0xff)
-
-#define IN6_IS_ADDR_LINKLOCAL(a) \
- ((((u_int32_t *) (a))[0] & htonl (0xffc00000)) == htonl (0xfe800000))
-
-#define IN6_IS_ADDR_LOOPBACK(a) \
- (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \
- ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1))
-#endif /* __MINGW32__ */
-
-#define ip6_vfc ip6_ctlun.ip6_un2_vfc
-#define ip6_flow ip6_ctlun.ip6_un1.ip6_un1_flow
-#define ip6_plen ip6_ctlun.ip6_un1.ip6_un1_plen
-#define ip6_nxt ip6_ctlun.ip6_un1.ip6_un1_nxt
-#define ip6_hlim ip6_ctlun.ip6_un1.ip6_un1_hlim
-#define ip6_hops ip6_ctlun.ip6_un1.ip6_un1_hlim
-
-#define nd_rd_type nd_rd_hdr.icmp6_type
-#define nd_rd_code nd_rd_hdr.icmp6_code
-#define nd_rd_cksum nd_rd_hdr.icmp6_cksum
-#define nd_rd_reserved nd_rd_hdr.icmp6_data32[0]
-
-/*
- * IPV6 extension headers
- */
-#define IPPROTO_HOPOPTS 0 /* IPv6 hop-by-hop options */
-#define IPPROTO_IPV6 41 /* IPv6 header. */
-#define IPPROTO_ROUTING 43 /* IPv6 routing header */
-#define IPPROTO_FRAGMENT 44 /* IPv6 fragmentation header */
-#define IPPROTO_ESP 50 /* encapsulating security payload */
-#define IPPROTO_AH 51 /* authentication header */
-#define IPPROTO_ICMPV6 58 /* ICMPv6 */
-#define IPPROTO_NONE 59 /* IPv6 no next header */
-#define IPPROTO_DSTOPTS 60 /* IPv6 destination options */
-#define IPPROTO_PIM 103 /* Protocol Independent Multicast. */
-
-#define IPV6_RTHDR_TYPE_0 0
-
-/* Option types and related macros */
-#define IP6OPT_PAD1 0x00 /* 00 0 00000 */
-#define IP6OPT_PADN 0x01 /* 00 0 00001 */
-#define IP6OPT_JUMBO 0xC2 /* 11 0 00010 = 194 */
-#define IP6OPT_JUMBO_LEN 6
-#define IP6OPT_ROUTER_ALERT 0x05 /* 00 0 00101 */
-
-#define IP6OPT_RTALERT_LEN 4
-#define IP6OPT_RTALERT_MLD 0 /* Datagram contains an MLD message */
-#define IP6OPT_RTALERT_RSVP 1 /* Datagram contains an RSVP message */
-#define IP6OPT_RTALERT_ACTNET 2 /* contains an Active Networks msg */
-#define IP6OPT_MINLEN 2
-
-#define IP6OPT_BINDING_UPDATE 0xc6 /* 11 0 00110 */
-#define IP6OPT_BINDING_ACK 0x07 /* 00 0 00111 */
-#define IP6OPT_BINDING_REQ 0x08 /* 00 0 01000 */
-#define IP6OPT_HOME_ADDRESS 0xc9 /* 11 0 01001 */
-#define IP6OPT_EID 0x8a /* 10 0 01010 */
-
-#define IP6OPT_TYPE(o) ((o) & 0xC0)
-#define IP6OPT_TYPE_SKIP 0x00
-#define IP6OPT_TYPE_DISCARD 0x40
-#define IP6OPT_TYPE_FORCEICMP 0x80
-#define IP6OPT_TYPE_ICMP 0xC0
-
-#define IP6OPT_MUTABLE 0x20
-
-
-#if defined(__MINGW32__) && defined(DEFINE_ADDITIONAL_IPV6_STUFF)
-#ifndef EAI_ADDRFAMILY
-struct addrinfo {
- int ai_flags; /* AI_PASSIVE, AI_CANONNAME */
- int ai_family; /* PF_xxx */
- int ai_socktype; /* SOCK_xxx */
- int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */
- size_t ai_addrlen; /* length of ai_addr */
- char *ai_canonname; /* canonical name for hostname */
- struct sockaddr *ai_addr; /* binary address */
- struct addrinfo *ai_next; /* next structure in linked list */
-};
-#endif
-#endif /* __MINGW32__ */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/netif.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/netif.h
deleted file mode 100644
index 8fe539376..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/netif.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef NET_IF_H
-#define NET_IF_H
-
-/*
- * Send uip_len bytes from uip_buf to the network interface selected by the
- * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h).
- */
-void vNetifTx( void );
-
-/*
- * Receive bytes from the network interface selected by the
- * configNETWORK_INTERFACE_TO_USE constant (defined in FreeRTOSConfig.h). The
- * bytes are placed in uip_buf. The number of bytes copied into uip_buf is
- * returned.
- */
-UBaseType_t uxNetifRx( void );
-
-/*
- * Prepare a packet capture session. This will print out all the network
- * interfaces available, and the one actually used is set by the
- * configNETWORK_INTERFACE_TO_USE constant that is defined in
- * FreeRTOSConfig.h. */
-BaseType_t xNetifInit( void );
-
-#endif /* NET_IF_H */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-bpf.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-bpf.h
deleted file mode 100644
index 5fe129dbb..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-bpf.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-bpf.h,v 1.50 2007/04/01 21:43:55 guy Exp $ (LBL)
- */
-
-/*
- * For backwards compatibility.
- *
- * Note to OS vendors: do NOT get rid of this file! Some applications
- * might expect to be able to include <pcap-bpf.h>.
- */
-#include <pcap/bpf.h>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-namedb.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-namedb.h
deleted file mode 100644
index 80a2f0040..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-namedb.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * Copyright (c) 1994, 1996
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-namedb.h,v 1.13 2006/10/04 18:13:32 guy Exp $ (LBL)
- */
-
-/*
- * For backwards compatibility.
- *
- * Note to OS vendors: do NOT get rid of this file! Some applications
- * might expect to be able to include <pcap-namedb.h>.
- */
-#include <pcap/namedb.h>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-stdinc.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-stdinc.h
deleted file mode 100644
index cbd62d169..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap-stdinc.h
+++ /dev/null
@@ -1,93 +0,0 @@
-/*
- * Copyright (c) 2002 - 2005 NetGroup, Politecnico di Torino (Italy)
- * Copyright (c) 2005 - 2009 CACE Technologies, Inc. Davis (California)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap-stdinc.h,v 1.10.2.1 2008-10-06 15:38:39 gianluca Exp $ (LBL)
- */
-
-#define SIZEOF_CHAR 1
-#define SIZEOF_SHORT 2
-#define SIZEOF_INT 4
-#ifndef _MSC_EXTENSIONS
-#define SIZEOF_LONG_LONG 8
-#endif
-
-/*
- * Avoids a compiler warning in case this was already defined
- * (someone defined _WINSOCKAPI_ when including 'windows.h', in order
- * to prevent it from including 'winsock.h')
- */
-#ifdef _WINSOCKAPI_
-#undef _WINSOCKAPI_
-#endif
-#include <winsock2.h>
-
-#include <fcntl.h>
-
-#include "bittypes.h"
-#include <time.h>
-#include <io.h>
-
-#ifndef __MINGW32__
-#include "IP6_misc.h"
-#endif
-
-#define caddr_t char*
-
-#if _MSC_VER < 1500
-#define snprintf _snprintf
-#define vsnprintf _vsnprintf
-#define strdup _strdup
-#endif
-
-#define inline __inline
-
-#ifdef __MINGW32__
-#include <stdint.h>
-#else /*__MINGW32__*/
-/* MSVC compiler */
-#ifndef _UINTPTR_T_DEFINED
-#ifdef _WIN64
-typedef unsigned __int64 uintptr_t;
-#else
-typedef _W64 unsigned int uintptr_t;
-#endif
-#define _UINTPTR_T_DEFINED
-#endif
-
-#ifndef _INTPTR_T_DEFINED
-#ifdef _WIN64
-typedef __int64 intptr_t;
-#else
-typedef _W64 int intptr_t;
-#endif
-#define _INTPTR_T_DEFINED
-#endif
-
-#endif /*__MINGW32__*/
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap.h
deleted file mode 100644
index 935f9494c..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Copyright (c) 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap.h,v 1.59 2006/10/04 18:09:22 guy Exp $ (LBL)
- */
-
-/*
- * For backwards compatibility.
- *
- * Note to OS vendors: do NOT get rid of this file! Many applications
- * expect to be able to include <pcap.h>, and at least some of them
- * go through contortions in their configure scripts to try to detect
- * OSes that have "helpfully" moved pcap.h to <pcap/pcap.h> without
- * leaving behind a <pcap.h> file.
- */
-#include <pcap/pcap.h>
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bluetooth.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bluetooth.h
deleted file mode 100644
index 7bf65df03..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bluetooth.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Copyright (c) 2006 Paolo Abeni (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- * bluetooth data struct
- * By Paolo Abeni <paolo.abeni@email.it>
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/bluetooth.h,v 1.1 2007/09/22 02:10:17 guy Exp $
- */
-
-#ifndef _PCAP_BLUETOOTH_STRUCTS_H__
-#define _PCAP_BLUETOOTH_STRUCTS_H__
-
-/*
- * Header prepended libpcap to each bluetooth h:4 frame.
- * fields are in network byte order
- */
-typedef struct _pcap_bluetooth_h4_header {
- u_int32_t direction; /* if first bit is set direction is incoming */
-} pcap_bluetooth_h4_header;
-
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bpf.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bpf.h
deleted file mode 100644
index 9f4ca33e3..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/bpf.h
+++ /dev/null
@@ -1,934 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#)bpf.h 7.1 (Berkeley) 5/7/91
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/bpf.h,v 1.19.2.8 2008-09-22 20:16:01 guy Exp $ (LBL)
- */
-
-/*
- * This is libpcap's cut-down version of bpf.h; it includes only
- * the stuff needed for the code generator and the userland BPF
- * interpreter, and the libpcap APIs for setting filters, etc..
- *
- * "pcap-bpf.c" will include the native OS version, as it deals with
- * the OS's BPF implementation.
- *
- * XXX - should this all just be moved to "pcap.h"?
- */
-
-#ifndef BPF_MAJOR_VERSION
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* BSD style release date */
-#define BPF_RELEASE 199606
-
-#ifdef MSDOS /* must be 32-bit */
-typedef long bpf_int32;
-typedef unsigned long bpf_u_int32;
-#else
-typedef int bpf_int32;
-typedef u_int bpf_u_int32;
-#endif
-
-/*
- * Alignment macros. BPF_WORDALIGN rounds up to the next
- * even multiple of BPF_ALIGNMENT.
- */
-#ifndef __NetBSD__
-#define BPF_ALIGNMENT sizeof(bpf_int32)
-#else
-#define BPF_ALIGNMENT sizeof(long)
-#endif
-#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
-
-#define BPF_MAXBUFSIZE 0x8000
-#define BPF_MINBUFSIZE 32
-
-/*
- * Structure for "pcap_compile()", "pcap_setfilter()", etc..
- */
-struct bpf_program {
- u_int bf_len;
- struct bpf_insn *bf_insns;
-};
-
-/*
- * Struct return by BIOCVERSION. This represents the version number of
- * the filter language described by the instruction encodings below.
- * bpf understands a program iff kernel_major == filter_major &&
- * kernel_minor >= filter_minor, that is, if the value returned by the
- * running kernel has the same major number and a minor number equal
- * equal to or less than the filter being downloaded. Otherwise, the
- * results are undefined, meaning an error may be returned or packets
- * may be accepted haphazardly.
- * It has nothing to do with the source code version.
- */
-struct bpf_version {
- u_short bv_major;
- u_short bv_minor;
-};
-/* Current version number of filter architecture. */
-#define BPF_MAJOR_VERSION 1
-#define BPF_MINOR_VERSION 1
-
-/*
- * Data-link level type codes.
- *
- * Do *NOT* add new values to this list without asking
- * "tcpdump-workers@lists.tcpdump.org" for a value. Otherwise, you run
- * the risk of using a value that's already being used for some other
- * purpose, and of having tools that read libpcap-format captures not
- * being able to handle captures with your new DLT_ value, with no hope
- * that they will ever be changed to do so (as that would destroy their
- * ability to read captures using that value for that other purpose).
- */
-
-/*
- * These are the types that are the same on all platforms, and that
- * have been defined by <net/bpf.h> for ages.
- */
-#define DLT_NULL 0 /* BSD loopback encapsulation */
-#define DLT_EN10MB 1 /* Ethernet (10Mb) */
-#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
-#define DLT_AX25 3 /* Amateur Radio AX.25 */
-#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
-#define DLT_CHAOS 5 /* Chaos */
-#define DLT_IEEE802 6 /* 802.5 Token Ring */
-#define DLT_ARCNET 7 /* ARCNET, with BSD-style header */
-#define DLT_SLIP 8 /* Serial Line IP */
-#define DLT_PPP 9 /* Point-to-point Protocol */
-#define DLT_FDDI 10 /* FDDI */
-
-/*
- * These are types that are different on some platforms, and that
- * have been defined by <net/bpf.h> for ages. We use #ifdefs to
- * detect the BSDs that define them differently from the traditional
- * libpcap <net/bpf.h>
- *
- * XXX - DLT_ATM_RFC1483 is 13 in BSD/OS, and DLT_RAW is 14 in BSD/OS,
- * but I don't know what the right #define is for BSD/OS.
- */
-#define DLT_ATM_RFC1483 11 /* LLC-encapsulated ATM */
-
-#ifdef __OpenBSD__
-#define DLT_RAW 14 /* raw IP */
-#else
-#define DLT_RAW 12 /* raw IP */
-#endif
-
-/*
- * Given that the only OS that currently generates BSD/OS SLIP or PPP
- * is, well, BSD/OS, arguably everybody should have chosen its values
- * for DLT_SLIP_BSDOS and DLT_PPP_BSDOS, which are 15 and 16, but they
- * didn't. So it goes.
- */
-#if defined(__NetBSD__) || defined(__FreeBSD__)
-#ifndef DLT_SLIP_BSDOS
-#define DLT_SLIP_BSDOS 13 /* BSD/OS Serial Line IP */
-#define DLT_PPP_BSDOS 14 /* BSD/OS Point-to-point Protocol */
-#endif
-#else
-#define DLT_SLIP_BSDOS 15 /* BSD/OS Serial Line IP */
-#define DLT_PPP_BSDOS 16 /* BSD/OS Point-to-point Protocol */
-#endif
-
-/*
- * 17 is used for DLT_OLD_PFLOG in OpenBSD;
- * OBSOLETE: DLT_PFLOG is 117 in OpenBSD now as well. See below.
- * 18 is used for DLT_PFSYNC in OpenBSD; don't use it for anything else.
- */
-
-#define DLT_ATM_CLIP 19 /* Linux Classical-IP over ATM */
-
-/*
- * Apparently Redback uses this for its SmartEdge 400/800. I hope
- * nobody else decided to use it, too.
- */
-#define DLT_REDBACK_SMARTEDGE 32
-
-/*
- * These values are defined by NetBSD; other platforms should refrain from
- * using them for other purposes, so that NetBSD savefiles with link
- * types of 50 or 51 can be read as this type on all platforms.
- */
-#define DLT_PPP_SERIAL 50 /* PPP over serial with HDLC encapsulation */
-#define DLT_PPP_ETHER 51 /* PPP over Ethernet */
-
-/*
- * The Axent Raptor firewall - now the Symantec Enterprise Firewall - uses
- * a link-layer type of 99 for the tcpdump it supplies. The link-layer
- * header has 6 bytes of unknown data, something that appears to be an
- * Ethernet type, and 36 bytes that appear to be 0 in at least one capture
- * I've seen.
- */
-#define DLT_SYMANTEC_FIREWALL 99
-
-/*
- * Values between 100 and 103 are used in capture file headers as
- * link-layer types corresponding to DLT_ types that differ
- * between platforms; don't use those values for new DLT_ new types.
- */
-
-/*
- * This value was defined by libpcap 0.5; platforms that have defined
- * it with a different value should define it here with that value -
- * a link type of 104 in a save file will be mapped to DLT_C_HDLC,
- * whatever value that happens to be, so programs will correctly
- * handle files with that link type regardless of the value of
- * DLT_C_HDLC.
- *
- * The name DLT_C_HDLC was used by BSD/OS; we use that name for source
- * compatibility with programs written for BSD/OS.
- *
- * libpcap 0.5 defined it as DLT_CHDLC; we define DLT_CHDLC as well,
- * for source compatibility with programs written for libpcap 0.5.
- */
-#define DLT_C_HDLC 104 /* Cisco HDLC */
-#define DLT_CHDLC DLT_C_HDLC
-
-#define DLT_IEEE802_11 105 /* IEEE 802.11 wireless */
-
-/*
- * 106 is reserved for Linux Classical IP over ATM; it's like DLT_RAW,
- * except when it isn't. (I.e., sometimes it's just raw IP, and
- * sometimes it isn't.) We currently handle it as DLT_LINUX_SLL,
- * so that we don't have to worry about the link-layer header.)
- */
-
-/*
- * Frame Relay; BSD/OS has a DLT_FR with a value of 11, but that collides
- * with other values.
- * DLT_FR and DLT_FRELAY packets start with the Q.922 Frame Relay header
- * (DLCI, etc.).
- */
-#define DLT_FRELAY 107
-
-/*
- * OpenBSD DLT_LOOP, for loopback devices; it's like DLT_NULL, except
- * that the AF_ type in the link-layer header is in network byte order.
- *
- * DLT_LOOP is 12 in OpenBSD, but that's DLT_RAW in other OSes, so
- * we don't use 12 for it in OSes other than OpenBSD.
- */
-#ifdef __OpenBSD__
-#define DLT_LOOP 12
-#else
-#define DLT_LOOP 108
-#endif
-
-/*
- * Encapsulated packets for IPsec; DLT_ENC is 13 in OpenBSD, but that's
- * DLT_SLIP_BSDOS in NetBSD, so we don't use 13 for it in OSes other
- * than OpenBSD.
- */
-#ifdef __OpenBSD__
-#define DLT_ENC 13
-#else
-#define DLT_ENC 109
-#endif
-
-/*
- * Values between 110 and 112 are reserved for use in capture file headers
- * as link-layer types corresponding to DLT_ types that might differ
- * between platforms; don't use those values for new DLT_ types
- * other than the corresponding DLT_ types.
- */
-
-/*
- * This is for Linux cooked sockets.
- */
-#define DLT_LINUX_SLL 113
-
-/*
- * Apple LocalTalk hardware.
- */
-#define DLT_LTALK 114
-
-/*
- * Acorn Econet.
- */
-#define DLT_ECONET 115
-
-/*
- * Reserved for use with OpenBSD ipfilter.
- */
-#define DLT_IPFILTER 116
-
-/*
- * OpenBSD DLT_PFLOG; DLT_PFLOG is 17 in OpenBSD, but that's DLT_LANE8023
- * in SuSE 6.3, so we can't use 17 for it in capture-file headers.
- *
- * XXX: is there a conflict with DLT_PFSYNC 18 as well?
- */
-#ifdef __OpenBSD__
-#define DLT_OLD_PFLOG 17
-#define DLT_PFSYNC 18
-#endif
-#define DLT_PFLOG 117
-
-/*
- * Registered for Cisco-internal use.
- */
-#define DLT_CISCO_IOS 118
-
-/*
- * For 802.11 cards using the Prism II chips, with a link-layer
- * header including Prism monitor mode information plus an 802.11
- * header.
- */
-#define DLT_PRISM_HEADER 119
-
-/*
- * Reserved for Aironet 802.11 cards, with an Aironet link-layer header
- * (see Doug Ambrisko's FreeBSD patches).
- */
-#define DLT_AIRONET_HEADER 120
-
-/*
- * Reserved for Siemens HiPath HDLC.
- */
-#define DLT_HHDLC 121
-
-/*
- * This is for RFC 2625 IP-over-Fibre Channel.
- *
- * This is not for use with raw Fibre Channel, where the link-layer
- * header starts with a Fibre Channel frame header; it's for IP-over-FC,
- * where the link-layer header starts with an RFC 2625 Network_Header
- * field.
- */
-#define DLT_IP_OVER_FC 122
-
-/*
- * This is for Full Frontal ATM on Solaris with SunATM, with a
- * pseudo-header followed by an AALn PDU.
- *
- * There may be other forms of Full Frontal ATM on other OSes,
- * with different pseudo-headers.
- *
- * If ATM software returns a pseudo-header with VPI/VCI information
- * (and, ideally, packet type information, e.g. signalling, ILMI,
- * LANE, LLC-multiplexed traffic, etc.), it should not use
- * DLT_ATM_RFC1483, but should get a new DLT_ value, so tcpdump
- * and the like don't have to infer the presence or absence of a
- * pseudo-header and the form of the pseudo-header.
- */
-#define DLT_SUNATM 123 /* Solaris+SunATM */
-
-/*
- * Reserved as per request from Kent Dahlgren <kent@praesum.com>
- * for private use.
- */
-#define DLT_RIO 124 /* RapidIO */
-#define DLT_PCI_EXP 125 /* PCI Express */
-#define DLT_AURORA 126 /* Xilinx Aurora link layer */
-
-/*
- * Header for 802.11 plus a number of bits of link-layer information
- * including radio information, used by some recent BSD drivers as
- * well as the madwifi Atheros driver for Linux.
- */
-#define DLT_IEEE802_11_RADIO 127 /* 802.11 plus radiotap radio header */
-
-/*
- * Reserved for the TZSP encapsulation, as per request from
- * Chris Waters <chris.waters@networkchemistry.com>
- * TZSP is a generic encapsulation for any other link type,
- * which includes a means to include meta-information
- * with the packet, e.g. signal strength and channel
- * for 802.11 packets.
- */
-#define DLT_TZSP 128 /* Tazmen Sniffer Protocol */
-
-/*
- * BSD's ARCNET headers have the source host, destination host,
- * and type at the beginning of the packet; that's what's handed
- * up to userland via BPF.
- *
- * Linux's ARCNET headers, however, have a 2-byte offset field
- * between the host IDs and the type; that's what's handed up
- * to userland via PF_PACKET sockets.
- *
- * We therefore have to have separate DLT_ values for them.
- */
-#define DLT_ARCNET_LINUX 129 /* ARCNET */
-
-/*
- * Juniper-private data link types, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
- * for passing on chassis-internal metainformation such as
- * QOS profiles, etc..
- */
-#define DLT_JUNIPER_MLPPP 130
-#define DLT_JUNIPER_MLFR 131
-#define DLT_JUNIPER_ES 132
-#define DLT_JUNIPER_GGSN 133
-#define DLT_JUNIPER_MFR 134
-#define DLT_JUNIPER_ATM2 135
-#define DLT_JUNIPER_SERVICES 136
-#define DLT_JUNIPER_ATM1 137
-
-/*
- * Apple IP-over-IEEE 1394, as per a request from Dieter Siegmund
- * <dieter@apple.com>. The header that's presented is an Ethernet-like
- * header:
- *
- * #define FIREWIRE_EUI64_LEN 8
- * struct firewire_header {
- * u_char firewire_dhost[FIREWIRE_EUI64_LEN];
- * u_char firewire_shost[FIREWIRE_EUI64_LEN];
- * u_short firewire_type;
- * };
- *
- * with "firewire_type" being an Ethernet type value, rather than,
- * for example, raw GASP frames being handed up.
- */
-#define DLT_APPLE_IP_OVER_IEEE1394 138
-
-/*
- * Various SS7 encapsulations, as per a request from Jeff Morriss
- * <jeff.morriss[AT]ulticom.com> and subsequent discussions.
- */
-#define DLT_MTP2_WITH_PHDR 139 /* pseudo-header with various info, followed by MTP2 */
-#define DLT_MTP2 140 /* MTP2, without pseudo-header */
-#define DLT_MTP3 141 /* MTP3, without pseudo-header or MTP2 */
-#define DLT_SCCP 142 /* SCCP, without pseudo-header or MTP2 or MTP3 */
-
-/*
- * DOCSIS MAC frames.
- */
-#define DLT_DOCSIS 143
-
-/*
- * Linux-IrDA packets. Protocol defined at http://www.irda.org.
- * Those packets include IrLAP headers and above (IrLMP...), but
- * don't include Phy framing (SOF/EOF/CRC & byte stuffing), because Phy
- * framing can be handled by the hardware and depend on the bitrate.
- * This is exactly the format you would get capturing on a Linux-IrDA
- * interface (irdaX), but not on a raw serial port.
- * Note the capture is done in "Linux-cooked" mode, so each packet include
- * a fake packet header (struct sll_header). This is because IrDA packet
- * decoding is dependant on the direction of the packet (incomming or
- * outgoing).
- * When/if other platform implement IrDA capture, we may revisit the
- * issue and define a real DLT_IRDA...
- * Jean II
- */
-#define DLT_LINUX_IRDA 144
-
-/*
- * Reserved for IBM SP switch and IBM Next Federation switch.
- */
-#define DLT_IBM_SP 145
-#define DLT_IBM_SN 146
-
-/*
- * Reserved for private use. If you have some link-layer header type
- * that you want to use within your organization, with the capture files
- * using that link-layer header type not ever be sent outside your
- * organization, you can use these values.
- *
- * No libpcap release will use these for any purpose, nor will any
- * tcpdump release use them, either.
- *
- * Do *NOT* use these in capture files that you expect anybody not using
- * your private versions of capture-file-reading tools to read; in
- * particular, do *NOT* use them in products, otherwise you may find that
- * people won't be able to use tcpdump, or snort, or Ethereal, or... to
- * read capture files from your firewall/intrusion detection/traffic
- * monitoring/etc. appliance, or whatever product uses that DLT_ value,
- * and you may also find that the developers of those applications will
- * not accept patches to let them read those files.
- *
- * Also, do not use them if somebody might send you a capture using them
- * for *their* private type and tools using them for *your* private type
- * would have to read them.
- *
- * Instead, ask "tcpdump-workers@lists.tcpdump.org" for a new DLT_ value,
- * as per the comment above, and use the type you're given.
- */
-#define DLT_USER0 147
-#define DLT_USER1 148
-#define DLT_USER2 149
-#define DLT_USER3 150
-#define DLT_USER4 151
-#define DLT_USER5 152
-#define DLT_USER6 153
-#define DLT_USER7 154
-#define DLT_USER8 155
-#define DLT_USER9 156
-#define DLT_USER10 157
-#define DLT_USER11 158
-#define DLT_USER12 159
-#define DLT_USER13 160
-#define DLT_USER14 161
-#define DLT_USER15 162
-
-/*
- * For future use with 802.11 captures - defined by AbsoluteValue
- * Systems to store a number of bits of link-layer information
- * including radio information:
- *
- * http://www.shaftnet.org/~pizza/software/capturefrm.txt
- *
- * but it might be used by some non-AVS drivers now or in the
- * future.
- */
-#define DLT_IEEE802_11_RADIO_AVS 163 /* 802.11 plus AVS radio header */
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
- * for passing on chassis-internal metainformation such as
- * QOS profiles, etc..
- */
-#define DLT_JUNIPER_MONITOR 164
-
-/*
- * Reserved for BACnet MS/TP.
- */
-#define DLT_BACNET_MS_TP 165
-
-/*
- * Another PPP variant as per request from Karsten Keil <kkeil@suse.de>.
- *
- * This is used in some OSes to allow a kernel socket filter to distinguish
- * between incoming and outgoing packets, on a socket intended to
- * supply pppd with outgoing packets so it can do dial-on-demand and
- * hangup-on-lack-of-demand; incoming packets are filtered out so they
- * don't cause pppd to hold the connection up (you don't want random
- * input packets such as port scans, packets from old lost connections,
- * etc. to force the connection to stay up).
- *
- * The first byte of the PPP header (0xff03) is modified to accomodate
- * the direction - 0x00 = IN, 0x01 = OUT.
- */
-#define DLT_PPP_PPPD 166
-
-/*
- * Names for backwards compatibility with older versions of some PPP
- * software; new software should use DLT_PPP_PPPD.
- */
-#define DLT_PPP_WITH_DIRECTION DLT_PPP_PPPD
-#define DLT_LINUX_PPP_WITHDIRECTION DLT_PPP_PPPD
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_s are used
- * for passing on chassis-internal metainformation such as
- * QOS profiles, cookies, etc..
- */
-#define DLT_JUNIPER_PPPOE 167
-#define DLT_JUNIPER_PPPOE_ATM 168
-
-#define DLT_GPRS_LLC 169 /* GPRS LLC */
-#define DLT_GPF_T 170 /* GPF-T (ITU-T G.7041/Y.1303) */
-#define DLT_GPF_F 171 /* GPF-F (ITU-T G.7041/Y.1303) */
-
-/*
- * Requested by Oolan Zimmer <oz@gcom.com> for use in Gcom's T1/E1 line
- * monitoring equipment.
- */
-#define DLT_GCOM_T1E1 172
-#define DLT_GCOM_SERIAL 173
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>. The DLT_ is used
- * for internal communication to Physical Interface Cards (PIC)
- */
-#define DLT_JUNIPER_PIC_PEER 174
-
-/*
- * Link types requested by Gregor Maier <gregor@endace.com> of Endace
- * Measurement Systems. They add an ERF header (see
- * http://www.endace.com/support/EndaceRecordFormat.pdf) in front of
- * the link-layer header.
- */
-#define DLT_ERF_ETH 175 /* Ethernet */
-#define DLT_ERF_POS 176 /* Packet-over-SONET */
-
-/*
- * Requested by Daniele Orlandi <daniele@orlandi.com> for raw LAPD
- * for vISDN (http://www.orlandi.com/visdn/). Its link-layer header
- * includes additional information before the LAPD header, so it's
- * not necessarily a generic LAPD header.
- */
-#define DLT_LINUX_LAPD 177
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ are used for prepending meta-information
- * like interface index, interface name
- * before standard Ethernet, PPP, Frelay & C-HDLC Frames
- */
-#define DLT_JUNIPER_ETHER 178
-#define DLT_JUNIPER_PPP 179
-#define DLT_JUNIPER_FRELAY 180
-#define DLT_JUNIPER_CHDLC 181
-
-/*
- * Multi Link Frame Relay (FRF.16)
- */
-#define DLT_MFR 182
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ is used for internal communication with a
- * voice Adapter Card (PIC)
- */
-#define DLT_JUNIPER_VP 183
-
-/*
- * Arinc 429 frames.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- * Every frame contains a 32bit A429 label.
- * More documentation on Arinc 429 can be found at
- * http://www.condoreng.com/support/downloads/tutorials/ARINCTutorial.pdf
- */
-#define DLT_A429 184
-
-/*
- * Arinc 653 Interpartition Communication messages.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- * Please refer to the A653-1 standard for more information.
- */
-#define DLT_A653_ICM 185
-
-/*
- * USB packets, beginning with a USB setup header; requested by
- * Paolo Abeni <paolo.abeni@email.it>.
- */
-#define DLT_USB 186
-
-/*
- * Bluetooth HCI UART transport layer (part H:4); requested by
- * Paolo Abeni.
- */
-#define DLT_BLUETOOTH_HCI_H4 187
-
-/*
- * IEEE 802.16 MAC Common Part Sublayer; requested by Maria Cruz
- * <cruz_petagay@bah.com>.
- */
-#define DLT_IEEE802_16_MAC_CPS 188
-
-/*
- * USB packets, beginning with a Linux USB header; requested by
- * Paolo Abeni <paolo.abeni@email.it>.
- */
-#define DLT_USB_LINUX 189
-
-/*
- * Controller Area Network (CAN) v. 2.0B packets.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- * Used to dump CAN packets coming from a CAN Vector board.
- * More documentation on the CAN v2.0B frames can be found at
- * http://www.can-cia.org/downloads/?269
- */
-#define DLT_CAN20B 190
-
-/*
- * IEEE 802.15.4, with address fields padded, as is done by Linux
- * drivers; requested by Juergen Schimmer.
- */
-#define DLT_IEEE802_15_4_LINUX 191
-
-/*
- * Per Packet Information encapsulated packets.
- * DLT_ requested by Gianluca Varenni <gianluca.varenni@cacetech.com>.
- */
-#define DLT_PPI 192
-
-/*
- * Header for 802.16 MAC Common Part Sublayer plus a radiotap radio header;
- * requested by Charles Clancy.
- */
-#define DLT_IEEE802_16_MAC_CPS_RADIO 193
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ is used for internal communication with a
- * integrated service module (ISM).
- */
-#define DLT_JUNIPER_ISM 194
-
-/*
- * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
- * nothing); requested by Mikko Saarnivala <mikko.saarnivala@sensinode.com>.
- */
-#define DLT_IEEE802_15_4 195
-
-/*
- * Various link-layer types, with a pseudo-header, for SITA
- * (http://www.sita.aero/); requested by Fulko Hew (fulko.hew@gmail.com).
- */
-#define DLT_SITA 196
-
-/*
- * Various link-layer types, with a pseudo-header, for Endace DAG cards;
- * encapsulates Endace ERF records. Requested by Stephen Donnelly
- * <stephen@endace.com>.
- */
-#define DLT_ERF 197
-
-/*
- * Special header prepended to Ethernet packets when capturing from a
- * u10 Networks board. Requested by Phil Mulholland
- * <phil@u10networks.com>.
- */
-#define DLT_RAIF1 198
-
-/*
- * IPMB packet for IPMI, beginning with the I2C slave address, followed
- * by the netFn and LUN, etc.. Requested by Chanthy Toeung
- * <chanthy.toeung@ca.kontron.com>.
- */
-#define DLT_IPMB 199
-
-/*
- * Juniper-private data link type, as per request from
- * Hannes Gredler <hannes@juniper.net>.
- * The DLT_ is used for capturing data on a secure tunnel interface.
- */
-#define DLT_JUNIPER_ST 200
-
-/*
- * Bluetooth HCI UART transport layer (part H:4), with pseudo-header
- * that includes direction information; requested by Paolo Abeni.
- */
-#define DLT_BLUETOOTH_HCI_H4_WITH_PHDR 201
-
-/*
- * AX.25 packet with a 1-byte KISS header; see
- *
- * http://www.ax25.net/kiss.htm
- *
- * as per Richard Stearn <richard@rns-stearn.demon.co.uk>.
- */
-#define DLT_AX25_KISS 202
-
-/*
- * LAPD packets from an ISDN channel, starting with the address field,
- * with no pseudo-header.
- * Requested by Varuna De Silva <varunax@gmail.com>.
- */
-#define DLT_LAPD 203
-
-/*
- * Variants of various link-layer headers, with a one-byte direction
- * pseudo-header prepended - zero means "received by this host",
- * non-zero (any non-zero value) means "sent by this host" - as per
- * Will Barker <w.barker@zen.co.uk>.
- */
-#define DLT_PPP_WITH_DIR 204 /* PPP - don't confuse with DLT_PPP_WITH_DIRECTION */
-#define DLT_C_HDLC_WITH_DIR 205 /* Cisco HDLC */
-#define DLT_FRELAY_WITH_DIR 206 /* Frame Relay */
-#define DLT_LAPB_WITH_DIR 207 /* LAPB */
-
-/*
- * 208 is reserved for an as-yet-unspecified proprietary link-layer
- * type, as requested by Will Barker.
- */
-
-/*
- * IPMB with a Linux-specific pseudo-header; as requested by Alexey Neyman
- * <avn@pigeonpoint.com>.
- */
-#define DLT_IPMB_LINUX 209
-
-/*
- * FlexRay automotive bus - http://www.flexray.com/ - as requested
- * by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_FLEXRAY 210
-
-/*
- * Media Oriented Systems Transport (MOST) bus for multimedia
- * transport - http://www.mostcooperation.com/ - as requested
- * by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_MOST 211
-
-/*
- * Local Interconnect Network (LIN) bus for vehicle networks -
- * http://www.lin-subbus.org/ - as requested by Hannes Kaelber
- * <hannes.kaelber@x2e.de>.
- */
-#define DLT_LIN 212
-
-/*
- * X2E-private data link type used for serial line capture,
- * as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_X2E_SERIAL 213
-
-/*
- * X2E-private data link type used for the Xoraya data logger
- * family, as requested by Hannes Kaelber <hannes.kaelber@x2e.de>.
- */
-#define DLT_X2E_XORAYA 214
-
-/*
- * IEEE 802.15.4, exactly as it appears in the spec (no padding, no
- * nothing), but with the PHY-level data for non-ASK PHYs (4 octets
- * of 0 as preamble, one octet of SFD, one octet of frame length+
- * reserved bit, and then the MAC-layer data, starting with the
- * frame control field).
- *
- * Requested by Max Filippov <jcmvbkbc@gmail.com>.
- */
-#define DLT_IEEE802_15_4_NONASK_PHY 215
-
-
-/*
- * DLT and savefile link type values are split into a class and
- * a member of that class. A class value of 0 indicates a regular
- * DLT_/LINKTYPE_ value.
- */
-#define DLT_CLASS(x) ((x) & 0x03ff0000)
-
-/*
- * NetBSD-specific generic "raw" link type. The class value indicates
- * that this is the generic raw type, and the lower 16 bits are the
- * address family we're dealing with. Those values are NetBSD-specific;
- * do not assume that they correspond to AF_ values for your operating
- * system.
- */
-#define DLT_CLASS_NETBSD_RAWAF 0x02240000
-#define DLT_NETBSD_RAWAF(af) (DLT_CLASS_NETBSD_RAWAF | (af))
-#define DLT_NETBSD_RAWAF_AF(x) ((x) & 0x0000ffff)
-#define DLT_IS_NETBSD_RAWAF(x) (DLT_CLASS(x) == DLT_CLASS_NETBSD_RAWAF)
-
-
-/*
- * The instruction encodings.
- */
-/* instruction classes */
-#define BPF_CLASS(code) ((code) & 0x07)
-#define BPF_LD 0x00
-#define BPF_LDX 0x01
-#define BPF_ST 0x02
-#define BPF_STX 0x03
-#define BPF_ALU 0x04
-#define BPF_JMP 0x05
-#define BPF_RET 0x06
-#define BPF_MISC 0x07
-
-/* ld/ldx fields */
-#define BPF_SIZE(code) ((code) & 0x18)
-#define BPF_W 0x00
-#define BPF_H 0x08
-#define BPF_B 0x10
-#define BPF_MODE(code) ((code) & 0xe0)
-#define BPF_IMM 0x00
-#define BPF_ABS 0x20
-#define BPF_IND 0x40
-#define BPF_MEM 0x60
-#define BPF_LEN 0x80
-#define BPF_MSH 0xa0
-
-/* alu/jmp fields */
-#define BPF_OP(code) ((code) & 0xf0)
-#define BPF_ADD 0x00
-#define BPF_SUB 0x10
-#define BPF_MUL 0x20
-#define BPF_DIV 0x30
-#define BPF_OR 0x40
-#define BPF_AND 0x50
-#define BPF_LSH 0x60
-#define BPF_RSH 0x70
-#define BPF_NEG 0x80
-#define BPF_JA 0x00
-#define BPF_JEQ 0x10
-#define BPF_JGT 0x20
-#define BPF_JGE 0x30
-#define BPF_JSET 0x40
-#define BPF_SRC(code) ((code) & 0x08)
-#define BPF_K 0x00
-#define BPF_X 0x08
-
-/* ret - BPF_K and BPF_X also apply */
-#define BPF_RVAL(code) ((code) & 0x18)
-#define BPF_A 0x10
-
-/* misc */
-#define BPF_MISCOP(code) ((code) & 0xf8)
-#define BPF_TAX 0x00
-#define BPF_TXA 0x80
-
-/*
- * The instruction data structure.
- */
-struct bpf_insn {
- u_short code;
- u_char jt;
- u_char jf;
- bpf_u_int32 k;
-};
-
-/*
- * Macros for insn array initializers.
- */
-#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
-#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
-
-#if __STDC__ || defined(__cplusplus)
-extern int bpf_validate(const struct bpf_insn *, int);
-extern u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
-#else
-extern int bpf_validate();
-extern u_int bpf_filter();
-#endif
-
-/*
- * Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
- */
-#define BPF_MEMWORDS 16
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/namedb.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/namedb.h
deleted file mode 100644
index 9002c7509..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/namedb.h
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Copyright (c) 1994, 1996
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/namedb.h,v 1.1 2006/10/04 18:09:22 guy Exp $ (LBL)
- */
-
-#ifndef lib_pcap_namedb_h
-#define lib_pcap_namedb_h
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*
- * As returned by the pcap_next_etherent()
- * XXX this stuff doesn't belong in this interface, but this
- * library already must do name to address translation, so
- * on systems that don't have support for /etc/ethers, we
- * export these hooks since they'll
- */
-struct pcap_etherent {
- u_char addr[6];
- char name[122];
-};
-#ifndef PCAP_ETHERS_FILE
-#define PCAP_ETHERS_FILE "/etc/ethers"
-#endif
-struct pcap_etherent *pcap_next_etherent(FILE *);
-u_char *pcap_ether_hostton(const char*);
-u_char *pcap_ether_aton(const char *);
-
-bpf_u_int32 **pcap_nametoaddr(const char *);
-#ifdef INET6
-struct addrinfo *pcap_nametoaddrinfo(const char *);
-#endif
-bpf_u_int32 pcap_nametonetaddr(const char *);
-
-int pcap_nametoport(const char *, int *, int *);
-int pcap_nametoportrange(const char *, int *, int *, int *);
-int pcap_nametoproto(const char *);
-int pcap_nametoeproto(const char *);
-int pcap_nametollc(const char *);
-/*
- * If a protocol is unknown, PROTO_UNDEF is returned.
- * Also, pcap_nametoport() returns the protocol along with the port number.
- * If there are ambiguous entried in /etc/services (i.e. domain
- * can be either tcp or udp) PROTO_UNDEF is returned.
- */
-#define PROTO_UNDEF -1
-
-/* XXX move these to pcap-int.h? */
-int __pcap_atodn(const char *, bpf_u_int32 *);
-int __pcap_atoin(const char *, bpf_u_int32 *);
-u_short __pcap_nametodnaddr(const char *);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/pcap.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/pcap.h
deleted file mode 100644
index ad8fc40ac..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/pcap.h
+++ /dev/null
@@ -1,407 +0,0 @@
-/* -*- Mode: c; tab-width: 8; indent-tabs-mode: 1; c-basic-offset: 8; -*- */
-/*
- * Copyright (c) 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the Computer Systems
- * Engineering Group at Lawrence Berkeley Laboratory.
- * 4. Neither the name of the University nor of the Laboratory may be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/pcap.h,v 1.4.2.11 2008-10-06 15:38:39 gianluca Exp $ (LBL)
- */
-
-#ifndef lib_pcap_pcap_h
-#define lib_pcap_pcap_h
-
-#if defined(WIN32)
- #include <pcap-stdinc.h>
-#elif defined(MSDOS)
- #include <sys/types.h>
- #include <sys/socket.h> /* u_int, u_char etc. */
-#else /* UN*X */
- #include <sys/types.h>
- #include <sys/time.h>
-#endif /* WIN32/MSDOS/UN*X */
-
-#ifndef PCAP_DONT_INCLUDE_PCAP_BPF_H
-#include <pcap/bpf.h>
-#endif
-
-#include <stdio.h>
-
-#ifdef HAVE_REMOTE
- // We have to define the SOCKET here, although it has been defined in sockutils.h
- // This is to avoid the distribution of the 'sockutils.h' file around
- // (for example in the WinPcap developer's pack)
- #ifndef SOCKET
- #ifdef WIN32
- #define SOCKET unsigned int
- #else
- #define SOCKET int
- #endif
- #endif
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define PCAP_VERSION_MAJOR 2
-#define PCAP_VERSION_MINOR 4
-
-#define PCAP_ERRBUF_SIZE 256
-
-/*
- * Compatibility for systems that have a bpf.h that
- * predates the bpf typedefs for 64-bit support.
- */
-#if BPF_RELEASE - 0 < 199406
-typedef int bpf_int32;
-typedef u_int bpf_u_int32;
-#endif
-
-typedef struct pcap pcap_t;
-typedef struct pcap_dumper pcap_dumper_t;
-typedef struct pcap_if pcap_if_t;
-typedef struct pcap_addr pcap_addr_t;
-
-/*
- * The first record in the file contains saved values for some
- * of the flags used in the printout phases of tcpdump.
- * Many fields here are 32 bit ints so compilers won't insert unwanted
- * padding; these files need to be interchangeable across architectures.
- *
- * Do not change the layout of this structure, in any way (this includes
- * changes that only affect the length of fields in this structure).
- *
- * Also, do not change the interpretation of any of the members of this
- * structure, in any way (this includes using values other than
- * LINKTYPE_ values, as defined in "savefile.c", in the "linktype"
- * field).
- *
- * Instead:
- *
- * introduce a new structure for the new format, if the layout
- * of the structure changed;
- *
- * send mail to "tcpdump-workers@lists.tcpdump.org", requesting
- * a new magic number for your new capture file format, and, when
- * you get the new magic number, put it in "savefile.c";
- *
- * use that magic number for save files with the changed file
- * header;
- *
- * make the code in "savefile.c" capable of reading files with
- * the old file header as well as files with the new file header
- * (using the magic number to determine the header format).
- *
- * Then supply the changes as a patch at
- *
- * http://sourceforge.net/projects/libpcap/
- *
- * so that future versions of libpcap and programs that use it (such as
- * tcpdump) will be able to read your new capture file format.
- */
-struct pcap_file_header {
- bpf_u_int32 magic;
- u_short version_major;
- u_short version_minor;
- bpf_int32 thiszone; /* gmt to local correction */
- bpf_u_int32 sigfigs; /* accuracy of timestamps */
- bpf_u_int32 snaplen; /* max length saved portion of each pkt */
- bpf_u_int32 linktype; /* data link type (LINKTYPE_*) */
-};
-
-/*
- * Macros for the value returned by pcap_datalink_ext().
- *
- * If LT_FCS_LENGTH_PRESENT(x) is true, the LT_FCS_LENGTH(x) macro
- * gives the FCS length of packets in the capture.
- */
-#define LT_FCS_LENGTH_PRESENT(x) ((x) & 0x04000000)
-#define LT_FCS_LENGTH(x) (((x) & 0xF0000000) >> 28)
-#define LT_FCS_DATALINK_EXT(x) ((((x) & 0xF) << 28) | 0x04000000)
-
-typedef enum {
- PCAP_D_INOUT = 0,
- PCAP_D_IN,
- PCAP_D_OUT
-} pcap_direction_t;
-
-/*
- * Generic per-packet information, as supplied by libpcap.
- *
- * The time stamp can and should be a "struct timeval", regardless of
- * whether your system supports 32-bit tv_sec in "struct timeval",
- * 64-bit tv_sec in "struct timeval", or both if it supports both 32-bit
- * and 64-bit applications. The on-disk format of savefiles uses 32-bit
- * tv_sec (and tv_usec); this structure is irrelevant to that. 32-bit
- * and 64-bit versions of libpcap, even if they're on the same platform,
- * should supply the appropriate version of "struct timeval", even if
- * that's not what the underlying packet capture mechanism supplies.
- */
-struct pcap_pkthdr {
- struct timeval ts; /* time stamp */
- bpf_u_int32 caplen; /* length of portion present */
- bpf_u_int32 len; /* length this packet (off wire) */
-};
-
-/*
- * As returned by the pcap_stats()
- */
-struct pcap_stat {
- u_int ps_recv; /* number of packets received */
- u_int ps_drop; /* number of packets dropped */
- u_int ps_ifdrop; /* drops by interface XXX not yet supported */
-#ifdef HAVE_REMOTE
- u_int ps_capt; /* number of packets that are received by the application; please get rid off the Win32 ifdef */
- u_int ps_sent; /* number of packets sent by the server on the network */
- u_int ps_netdrop; /* number of packets lost on the network */
-#endif /* HAVE_REMOTE */
-};
-
-#ifdef MSDOS
-/*
- * As returned by the pcap_stats_ex()
- */
-struct pcap_stat_ex {
- u_long rx_packets; /* total packets received */
- u_long tx_packets; /* total packets transmitted */
- u_long rx_bytes; /* total bytes received */
- u_long tx_bytes; /* total bytes transmitted */
- u_long rx_errors; /* bad packets received */
- u_long tx_errors; /* packet transmit problems */
- u_long rx_dropped; /* no space in Rx buffers */
- u_long tx_dropped; /* no space available for Tx */
- u_long multicast; /* multicast packets received */
- u_long collisions;
-
- /* detailed rx_errors: */
- u_long rx_length_errors;
- u_long rx_over_errors; /* receiver ring buff overflow */
- u_long rx_crc_errors; /* recv'd pkt with crc error */
- u_long rx_frame_errors; /* recv'd frame alignment error */
- u_long rx_fifo_errors; /* recv'r fifo overrun */
- u_long rx_missed_errors; /* recv'r missed packet */
-
- /* detailed tx_errors */
- u_long tx_aborted_errors;
- u_long tx_carrier_errors;
- u_long tx_fifo_errors;
- u_long tx_heartbeat_errors;
- u_long tx_window_errors;
- };
-#endif
-
-/*
- * Item in a list of interfaces.
- */
-struct pcap_if {
- struct pcap_if *next;
- char *name; /* name to hand to "pcap_open_live()" */
- char *description; /* textual description of interface, or NULL */
- struct pcap_addr *addresses;
- bpf_u_int32 flags; /* PCAP_IF_ interface flags */
-};
-
-#define PCAP_IF_LOOPBACK 0x00000001 /* interface is loopback */
-
-/*
- * Representation of an interface address.
- */
-struct pcap_addr {
- struct pcap_addr *next;
- struct sockaddr *addr; /* address */
- struct sockaddr *netmask; /* netmask for that address */
- struct sockaddr *broadaddr; /* broadcast address for that address */
- struct sockaddr *dstaddr; /* P2P destination address for that address */
-};
-
-typedef void (*pcap_handler)(u_char *, const struct pcap_pkthdr *,
- const u_char *);
-
-/*
- * Error codes for the pcap API.
- * These will all be negative, so you can check for the success or
- * failure of a call that returns these codes by checking for a
- * negative value.
- */
-#define PCAP_ERROR -1 /* generic error code */
-#define PCAP_ERROR_BREAK -2 /* loop terminated by pcap_breakloop */
-#define PCAP_ERROR_NOT_ACTIVATED -3 /* the capture needs to be activated */
-#define PCAP_ERROR_ACTIVATED -4 /* the operation can't be performed on already activated captures */
-#define PCAP_ERROR_NO_SUCH_DEVICE -5 /* no such device exists */
-#define PCAP_ERROR_RFMON_NOTSUP -6 /* this device doesn't support rfmon (monitor) mode */
-#define PCAP_ERROR_NOT_RFMON -7 /* operation supported only in monitor mode */
-#define PCAP_ERROR_PERM_DENIED -8 /* no permission to open the device */
-#define PCAP_ERROR_IFACE_NOT_UP -9 /* interface isn't up */
-
-/*
- * Warning codes for the pcap API.
- * These will all be positive and non-zero, so they won't look like
- * errors.
- */
-#define PCAP_WARNING 1 /* generic warning code */
-#define PCAP_WARNING_PROMISC_NOTSUP 2 /* this device doesn't support promiscuous mode */
-
-char *pcap_lookupdev(char *);
-int pcap_lookupnet(const char *, bpf_u_int32 *, bpf_u_int32 *, char *);
-
-pcap_t *pcap_create(const char *, char *);
-int pcap_set_snaplen(pcap_t *, int);
-int pcap_set_promisc(pcap_t *, int);
-int pcap_can_set_rfmon(pcap_t *);
-int pcap_set_rfmon(pcap_t *, int);
-int pcap_set_timeout(pcap_t *, int);
-int pcap_set_buffer_size(pcap_t *, int);
-int pcap_activate(pcap_t *);
-
-pcap_t *pcap_open_live(const char *, int, int, int, char *);
-pcap_t *pcap_open_dead(int, int);
-pcap_t *pcap_open_offline(const char *, char *);
-#if defined(WIN32)
-pcap_t *pcap_hopen_offline(intptr_t, char *);
-#if !defined(LIBPCAP_EXPORTS)
-#define pcap_fopen_offline(f,b) \
- pcap_hopen_offline(_get_osfhandle(_fileno(f)), b)
-#else /*LIBPCAP_EXPORTS*/
-static pcap_t *pcap_fopen_offline(FILE *, char *);
-#endif
-#else /*WIN32*/
-pcap_t *pcap_fopen_offline(FILE *, char *);
-#endif /*WIN32*/
-
-void pcap_close(pcap_t *);
-int pcap_loop(pcap_t *, int, pcap_handler, u_char *);
-int pcap_dispatch(pcap_t *, int, pcap_handler, u_char *);
-const u_char*
- pcap_next(pcap_t *, struct pcap_pkthdr *);
-int pcap_next_ex(pcap_t *, struct pcap_pkthdr **, const u_char **);
-void pcap_breakloop(pcap_t *);
-int pcap_stats(pcap_t *, struct pcap_stat *);
-int pcap_setfilter(pcap_t *, struct bpf_program *);
-int pcap_setdirection(pcap_t *, pcap_direction_t);
-int pcap_getnonblock(pcap_t *, char *);
-int pcap_setnonblock(pcap_t *, int, char *);
-int pcap_inject(pcap_t *, const void *, size_t);
-int pcap_sendpacket(pcap_t *, const u_char *, int);
-const char *pcap_statustostr(int);
-const char *pcap_strerror(int);
-char *pcap_geterr(pcap_t *);
-void pcap_perror(pcap_t *, char *);
-int pcap_compile(pcap_t *, struct bpf_program *, const char *, int,
- bpf_u_int32);
-int pcap_compile_nopcap(int, int, struct bpf_program *,
- const char *, int, bpf_u_int32);
-void pcap_freecode(struct bpf_program *);
-int pcap_offline_filter(struct bpf_program *, const struct pcap_pkthdr *,
- const u_char *);
-int pcap_datalink(pcap_t *);
-int pcap_datalink_ext(pcap_t *);
-int pcap_list_datalinks(pcap_t *, int **);
-int pcap_set_datalink(pcap_t *, int);
-void pcap_free_datalinks(int *);
-int pcap_datalink_name_to_val(const char *);
-const char *pcap_datalink_val_to_name(int);
-const char *pcap_datalink_val_to_description(int);
-int pcap_snapshot(pcap_t *);
-int pcap_is_swapped(pcap_t *);
-int pcap_major_version(pcap_t *);
-int pcap_minor_version(pcap_t *);
-
-/* XXX */
-FILE *pcap_file(pcap_t *);
-int pcap_fileno(pcap_t *);
-
-pcap_dumper_t *pcap_dump_open(pcap_t *, const char *);
-pcap_dumper_t *pcap_dump_fopen(pcap_t *, FILE *fp);
-FILE *pcap_dump_file(pcap_dumper_t *);
-long pcap_dump_ftell(pcap_dumper_t *);
-int pcap_dump_flush(pcap_dumper_t *);
-void pcap_dump_close(pcap_dumper_t *);
-void pcap_dump(u_char *, const struct pcap_pkthdr *, const u_char *);
-
-int pcap_findalldevs(pcap_if_t **, char *);
-void pcap_freealldevs(pcap_if_t *);
-
-const char *pcap_lib_version(void);
-
-/* XXX this guy lives in the bpf tree */
-u_int bpf_filter(const struct bpf_insn *, const u_char *, u_int, u_int);
-int bpf_validate(const struct bpf_insn *f, int len);
-char *bpf_image(const struct bpf_insn *, int);
-void bpf_dump(const struct bpf_program *, int);
-
-#if defined(WIN32)
-
-/*
- * Win32 definitions
- */
-
-int pcap_setbuff(pcap_t *p, int dim);
-int pcap_setmode(pcap_t *p, int mode);
-int pcap_setmintocopy(pcap_t *p, int size);
-
-#ifdef WPCAP
-/* Include file with the wpcap-specific extensions */
-#include <Win32-Extensions.h>
-#endif /* WPCAP */
-
-#define MODE_CAPT 0
-#define MODE_STAT 1
-#define MODE_MON 2
-
-#elif defined(MSDOS)
-
-/*
- * MS-DOS definitions
- */
-
-int pcap_stats_ex (pcap_t *, struct pcap_stat_ex *);
-void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait);
-u_long pcap_mac_packets (void);
-
-#else /* UN*X */
-
-/*
- * UN*X definitions
- */
-
-int pcap_get_selectable_fd(pcap_t *);
-
-#endif /* WIN32/MSDOS/UN*X */
-
-#ifdef HAVE_REMOTE
-/* Includes most of the public stuff that is needed for the remote capture */
-#include <remote-ext.h>
-#endif /* HAVE_REMOTE */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/sll.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/sll.h
deleted file mode 100644
index e9d5452af..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/sll.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * This code is derived from the Stanford/CMU enet packet filter,
- * (net/enet.c) distributed as part of 4.3BSD, and code contributed
- * to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
- * Berkeley Laboratory.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/sll.h,v 1.2.2.1 2008-05-30 01:36:06 guy Exp $ (LBL)
- */
-
-/*
- * For captures on Linux cooked sockets, we construct a fake header
- * that includes:
- *
- * a 2-byte "packet type" which is one of:
- *
- * LINUX_SLL_HOST packet was sent to us
- * LINUX_SLL_BROADCAST packet was broadcast
- * LINUX_SLL_MULTICAST packet was multicast
- * LINUX_SLL_OTHERHOST packet was sent to somebody else
- * LINUX_SLL_OUTGOING packet was sent *by* us;
- *
- * a 2-byte Ethernet protocol field;
- *
- * a 2-byte link-layer type;
- *
- * a 2-byte link-layer address length;
- *
- * an 8-byte source link-layer address, whose actual length is
- * specified by the previous value.
- *
- * All fields except for the link-layer address are in network byte order.
- *
- * DO NOT change the layout of this structure, or change any of the
- * LINUX_SLL_ values below. If you must change the link-layer header
- * for a "cooked" Linux capture, introduce a new DLT_ type (ask
- * "tcpdump-workers@lists.tcpdump.org" for one, so that you don't give it
- * a value that collides with a value already being used), and use the
- * new header in captures of that type, so that programs that can
- * handle DLT_LINUX_SLL captures will continue to handle them correctly
- * without any change, and so that capture files with different headers
- * can be told apart and programs that read them can dissect the
- * packets in them.
- */
-
-#ifndef lib_pcap_sll_h
-#define lib_pcap_sll_h
-
-/*
- * A DLT_LINUX_SLL fake link-layer header.
- */
-#define SLL_HDR_LEN 16 /* total header length */
-#define SLL_ADDRLEN 8 /* length of address field */
-
-struct sll_header {
- u_int16_t sll_pkttype; /* packet type */
- u_int16_t sll_hatype; /* link-layer address type */
- u_int16_t sll_halen; /* link-layer address length */
- u_int8_t sll_addr[SLL_ADDRLEN]; /* link-layer address */
- u_int16_t sll_protocol; /* protocol */
-};
-
-/*
- * The LINUX_SLL_ values for "sll_pkttype"; these correspond to the
- * PACKET_ values on Linux, but are defined here so that they're
- * available even on systems other than Linux, and so that they
- * don't change even if the PACKET_ values change.
- */
-#define LINUX_SLL_HOST 0
-#define LINUX_SLL_BROADCAST 1
-#define LINUX_SLL_MULTICAST 2
-#define LINUX_SLL_OTHERHOST 3
-#define LINUX_SLL_OUTGOING 4
-
-/*
- * The LINUX_SLL_ values for "sll_protocol"; these correspond to the
- * ETH_P_ values on Linux, but are defined here so that they're
- * available even on systems other than Linux. We assume, for now,
- * that the ETH_P_ values won't change in Linux; if they do, then:
- *
- * if we don't translate them in "pcap-linux.c", capture files
- * won't necessarily be readable if captured on a system that
- * defines ETH_P_ values that don't match these values;
- *
- * if we do translate them in "pcap-linux.c", that makes life
- * unpleasant for the BPF code generator, as the values you test
- * for in the kernel aren't the values that you test for when
- * reading a capture file, so the fixup code run on BPF programs
- * handed to the kernel ends up having to do more work.
- *
- * Add other values here as necessary, for handling packet types that
- * might show up on non-Ethernet, non-802.x networks. (Not all the ones
- * in the Linux "if_ether.h" will, I suspect, actually show up in
- * captures.)
- */
-#define LINUX_SLL_P_802_3 0x0001 /* Novell 802.3 frames without 802.2 LLC header */
-#define LINUX_SLL_P_802_2 0x0004 /* 802.2 frames (not D/I/X Ethernet) */
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/usb.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/usb.h
deleted file mode 100644
index adcd19c05..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/usb.h
+++ /dev/null
@@ -1,90 +0,0 @@
-/*
- * Copyright (c) 2006 Paolo Abeni (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior written
- * permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- * Basic USB data struct
- * By Paolo Abeni <paolo.abeni@email.it>
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/usb.h,v 1.6 2007/09/22 02:06:08 guy Exp $
- */
-
-#ifndef _PCAP_USB_STRUCTS_H__
-#define _PCAP_USB_STRUCTS_H__
-
-/*
- * possible transfer mode
- */
-#define URB_TRANSFER_IN 0x80
-#define URB_ISOCHRONOUS 0x0
-#define URB_INTERRUPT 0x1
-#define URB_CONTROL 0x2
-#define URB_BULK 0x3
-
-/*
- * possible event type
- */
-#define URB_SUBMIT 'S'
-#define URB_COMPLETE 'C'
-#define URB_ERROR 'E'
-
-/*
- * USB setup header as defined in USB specification.
- * Appears at the front of each packet in DLT_USB captures.
- */
-typedef struct _usb_setup {
- u_int8_t bmRequestType;
- u_int8_t bRequest;
- u_int16_t wValue;
- u_int16_t wIndex;
- u_int16_t wLength;
-} pcap_usb_setup;
-
-
-/*
- * Header prepended by linux kernel to each event.
- * Appears at the front of each packet in DLT_USB_LINUX captures.
- */
-typedef struct _usb_header {
- u_int64_t id;
- u_int8_t event_type;
- u_int8_t transfer_type;
- u_int8_t endpoint_number;
- u_int8_t device_address;
- u_int16_t bus_id;
- char setup_flag;/*if !=0 the urb setup header is not present*/
- char data_flag; /*if !=0 no urb data is present*/
- int64_t ts_sec;
- int32_t ts_usec;
- int32_t status;
- u_int32_t urb_len;
- u_int32_t data_len; /* amount of urb data really present in this event*/
- pcap_usb_setup setup;
-} pcap_usb_header;
-
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/vlan.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/vlan.h
deleted file mode 100644
index b0cb7949b..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/pcap/vlan.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*-
- * Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- * must display the following acknowledgement:
- * This product includes software developed by the University of
- * California, Berkeley and its contributors.
- * 4. Neither the name of the University 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 REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS 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 THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * @(#) $Header: /tcpdump/master/libpcap/pcap/vlan.h,v 1.1.2.2 2008-08-06 07:45:59 guy Exp $
- */
-
-#ifndef lib_pcap_vlan_h
-#define lib_pcap_vlan_h
-
-struct vlan_tag {
- u_int16_t vlan_tpid; /* ETH_P_8021Q */
- u_int16_t vlan_tci; /* VLAN TCI */
-};
-
-#define VLAN_TAG_LEN 4
-
-#endif
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/remote-ext.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/remote-ext.h
deleted file mode 100644
index 9f54d6974..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/remote-ext.h
+++ /dev/null
@@ -1,444 +0,0 @@
-/*
- * Copyright (c) 2002 - 2003
- * NetGroup, Politecnico di Torino (Italy)
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Politecnico di Torino 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-
-#ifndef __REMOTE_EXT_H__
-#define __REMOTE_EXT_H__
-
-
-#ifndef HAVE_REMOTE
-#error Please do not include this file directly. Just define HAVE_REMOTE and then include pcap.h
-#endif
-
-// Definition for Microsoft Visual Studio
-#if _MSC_VER > 1000
-#pragma once
-#endif
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/*!
- \file remote-ext.h
-
- The goal of this file it to include most of the new definitions that should be
- placed into the pcap.h file.
-
- It includes all new definitions (structures and functions like pcap_open().
- Some of the functions are not really a remote feature, but, right now,
- they are placed here.
-*/
-
-
-
-// All this stuff is public
-/*! \addtogroup remote_struct
- \{
-*/
-
-
-
-
-/*!
- \brief Defines the maximum buffer size in which address, port, interface names are kept.
-
- In case the adapter name or such is larger than this value, it is truncated.
- This is not used by the user; however it must be aware that an hostname / interface
- name longer than this value will be truncated.
-*/
-#define PCAP_BUF_SIZE 1024
-
-
-/*! \addtogroup remote_source_ID
- \{
-*/
-
-
-/*!
- \brief Internal representation of the type of source in use (file,
- remote/local interface).
-
- This indicates a file, i.e. the user want to open a capture from a local file.
-*/
-#define PCAP_SRC_FILE 2
-/*!
- \brief Internal representation of the type of source in use (file,
- remote/local interface).
-
- This indicates a local interface, i.e. the user want to open a capture from
- a local interface. This does not involve the RPCAP protocol.
-*/
-#define PCAP_SRC_IFLOCAL 3
-/*!
- \brief Internal representation of the type of source in use (file,
- remote/local interface).
-
- This indicates a remote interface, i.e. the user want to open a capture from
- an interface on a remote host. This does involve the RPCAP protocol.
-*/
-#define PCAP_SRC_IFREMOTE 4
-
-/*!
- \}
-*/
-
-
-
-/*! \addtogroup remote_source_string
-
- The formats allowed by the pcap_open() are the following:
- - file://path_and_filename [opens a local file]
- - rpcap://devicename [opens the selected device devices available on the local host, without using the RPCAP protocol]
- - rpcap://host/devicename [opens the selected device available on a remote host]
- - rpcap://host:port/devicename [opens the selected device available on a remote host, using a non-standard port for RPCAP]
- - adaptername [to open a local adapter; kept for compability, but it is strongly discouraged]
- - (NULL) [to open the first local adapter; kept for compability, but it is strongly discouraged]
-
- The formats allowed by the pcap_findalldevs_ex() are the following:
- - file://folder/ [lists all the files in the given folder]
- - rpcap:// [lists all local adapters]
- - rpcap://host:port/ [lists the devices available on a remote host]
-
- Referring to the 'host' and 'port' paramters, they can be either numeric or literal. Since
- IPv6 is fully supported, these are the allowed formats:
-
- - host (literal): e.g. host.foo.bar
- - host (numeric IPv4): e.g. 10.11.12.13
- - host (numeric IPv4, IPv6 style): e.g. [10.11.12.13]
- - host (numeric IPv6): e.g. [1:2:3::4]
- - port: can be either numeric (e.g. '80') or literal (e.g. 'http')
-
- Here you find some allowed examples:
- - rpcap://host.foo.bar/devicename [everything literal, no port number]
- - rpcap://host.foo.bar:1234/devicename [everything literal, with port number]
- - rpcap://10.11.12.13/devicename [IPv4 numeric, no port number]
- - rpcap://10.11.12.13:1234/devicename [IPv4 numeric, with port number]
- - rpcap://[10.11.12.13]:1234/devicename [IPv4 numeric with IPv6 format, with port number]
- - rpcap://[1:2:3::4]/devicename [IPv6 numeric, no port number]
- - rpcap://[1:2:3::4]:1234/devicename [IPv6 numeric, with port number]
- - rpcap://[1:2:3::4]:http/devicename [IPv6 numeric, with literal port number]
-
- \{
-*/
-
-
-/*!
- \brief String that will be used to determine the type of source in use (file,
- remote/local interface).
-
- This string will be prepended to the interface name in order to create a string
- that contains all the information required to open the source.
-
- This string indicates that the user wants to open a capture from a local file.
-*/
-#define PCAP_SRC_FILE_STRING "file://"
-/*!
- \brief String that will be used to determine the type of source in use (file,
- remote/local interface).
-
- This string will be prepended to the interface name in order to create a string
- that contains all the information required to open the source.
-
- This string indicates that the user wants to open a capture from a network interface.
- This string does not necessarily involve the use of the RPCAP protocol. If the
- interface required resides on the local host, the RPCAP protocol is not involved
- and the local functions are used.
-*/
-#define PCAP_SRC_IF_STRING "rpcap://"
-
-/*!
- \}
-*/
-
-
-
-
-
-/*!
- \addtogroup remote_open_flags
- \{
-*/
-
-/*!
- \brief Defines if the adapter has to go in promiscuous mode.
-
- It is '1' if you have to open the adapter in promiscuous mode, '0' otherwise.
- Note that even if this parameter is false, the interface could well be in promiscuous
- mode for some other reason (for example because another capture process with
- promiscuous mode enabled is currently using that interface).
- On on Linux systems with 2.2 or later kernels (that have the "any" device), this
- flag does not work on the "any" device; if an argument of "any" is supplied,
- the 'promisc' flag is ignored.
-*/
-#define PCAP_OPENFLAG_PROMISCUOUS 1
-
-/*!
- \brief Defines if the data trasfer (in case of a remote
- capture) has to be done with UDP protocol.
-
- If it is '1' if you want a UDP data connection, '0' if you want
- a TCP data connection; control connection is always TCP-based.
- A UDP connection is much lighter, but it does not guarantee that all
- the captured packets arrive to the client workstation. Moreover,
- it could be harmful in case of network congestion.
- This flag is meaningless if the source is not a remote interface.
- In that case, it is simply ignored.
-*/
-#define PCAP_OPENFLAG_DATATX_UDP 2
-
-
-/*!
- \brief Defines if the remote probe will capture its own generated traffic.
-
- In case the remote probe uses the same interface to capture traffic and to send
- data back to the caller, the captured traffic includes the RPCAP traffic as well.
- If this flag is turned on, the RPCAP traffic is excluded from the capture, so that
- the trace returned back to the collector is does not include this traffic.
-*/
-#define PCAP_OPENFLAG_NOCAPTURE_RPCAP 4
-
-/*!
- \brief Defines if the local adapter will capture its own generated traffic.
-
- This flag tells the underlying capture driver to drop the packets that were sent by itself.
- This is usefult when building applications like bridges, that should ignore the traffic
- they just sent.
-*/
-#define PCAP_OPENFLAG_NOCAPTURE_LOCAL 8
-
-/*!
- \brief This flag configures the adapter for maximum responsiveness.
-
- In presence of a large value for nbytes, WinPcap waits for the arrival of several packets before
- copying the data to the user. This guarantees a low number of system calls, i.e. lower processor usage,
- i.e. better performance, which is good for applications like sniffers. If the user sets the
- PCAP_OPENFLAG_MAX_RESPONSIVENESS flag, the capture driver will copy the packets as soon as the application
- is ready to receive them. This is suggested for real time applications (like, for example, a bridge)
- that need the best responsiveness.*/
-#define PCAP_OPENFLAG_MAX_RESPONSIVENESS 16
-
-/*!
- \}
-*/
-
-
-/*!
- \addtogroup remote_samp_methods
- \{
-*/
-
-/*!
- \brief No sampling has to be done on the current capture.
-
- In this case, no sampling algorithms are applied to the current capture.
-*/
-#define PCAP_SAMP_NOSAMP 0
-
-/*!
- \brief It defines that only 1 out of N packets must be returned to the user.
-
- In this case, the 'value' field of the 'pcap_samp' structure indicates the
- number of packets (minus 1) that must be discarded before one packet got accepted.
- In other words, if 'value = 10', the first packet is returned to the caller, while
- the following 9 are discarded.
-*/
-#define PCAP_SAMP_1_EVERY_N 1
-
-/*!
- \brief It defines that we have to return 1 packet every N milliseconds.
-
- In this case, the 'value' field of the 'pcap_samp' structure indicates the 'waiting
- time' in milliseconds before one packet got accepted.
- In other words, if 'value = 10', the first packet is returned to the caller; the next
- returned one will be the first packet that arrives when 10ms have elapsed.
-*/
-#define PCAP_SAMP_FIRST_AFTER_N_MS 2
-
-/*!
- \}
-*/
-
-
-/*!
- \addtogroup remote_auth_methods
- \{
-*/
-
-/*!
- \brief It defines the NULL authentication.
-
- This value has to be used within the 'type' member of the pcap_rmtauth structure.
- The 'NULL' authentication has to be equal to 'zero', so that old applications
- can just put every field of struct pcap_rmtauth to zero, and it does work.
-*/
-#define RPCAP_RMTAUTH_NULL 0
-/*!
- \brief It defines the username/password authentication.
-
- With this type of authentication, the RPCAP protocol will use the username/
- password provided to authenticate the user on the remote machine. If the
- authentication is successful (and the user has the right to open network devices)
- the RPCAP connection will continue; otherwise it will be dropped.
-
- This value has to be used within the 'type' member of the pcap_rmtauth structure.
-*/
-#define RPCAP_RMTAUTH_PWD 1
-
-/*!
- \}
-*/
-
-
-
-
-/*!
-
- \brief This structure keeps the information needed to autheticate
- the user on a remote machine.
-
- The remote machine can either grant or refuse the access according
- to the information provided.
- In case the NULL authentication is required, both 'username' and
- 'password' can be NULL pointers.
-
- This structure is meaningless if the source is not a remote interface;
- in that case, the functions which requires such a structure can accept
- a NULL pointer as well.
-*/
-struct pcap_rmtauth
-{
- /*!
- \brief Type of the authentication required.
-
- In order to provide maximum flexibility, we can support different types
- of authentication based on the value of this 'type' variable. The currently
- supported authentication methods are defined into the
- \link remote_auth_methods Remote Authentication Methods Section\endlink.
-
- */
- int type;
- /*!
- \brief Zero-terminated string containing the username that has to be
- used on the remote machine for authentication.
-
- This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
- and it can be NULL.
- */
- char *username;
- /*!
- \brief Zero-terminated string containing the password that has to be
- used on the remote machine for authentication.
-
- This field is meaningless in case of the RPCAP_RMTAUTH_NULL authentication
- and it can be NULL.
- */
- char *password;
-};
-
-
-/*!
- \brief This structure defines the information related to sampling.
-
- In case the sampling is requested, the capturing device should read
- only a subset of the packets coming from the source. The returned packets depend
- on the sampling parameters.
-
- \warning The sampling process is applied <strong>after</strong> the filtering process.
- In other words, packets are filtered first, then the sampling process selects a
- subset of the 'filtered' packets and it returns them to the caller.
-*/
-struct pcap_samp
-{
- /*!
- Method used for sampling. Currently, the supported methods are listed in the
- \link remote_samp_methods Sampling Methods Section\endlink.
- */
- int method;
-
- /*!
- This value depends on the sampling method defined. For its meaning, please check
- at the \link remote_samp_methods Sampling Methods Section\endlink.
- */
- int value;
-};
-
-
-
-
-//! Maximum lenght of an host name (needed for the RPCAP active mode)
-#define RPCAP_HOSTLIST_SIZE 1024
-
-
-/*!
- \}
-*/ // end of public documentation
-
-
-// Exported functions
-
-
-
-/** \name New WinPcap functions
-
- This section lists the new functions that are able to help considerably in writing
- WinPcap programs because of their easiness of use.
- */
-//\{
-pcap_t *pcap_open(const char *source, int snaplen, int flags, int read_timeout, struct pcap_rmtauth *auth, char *errbuf);
-int pcap_createsrcstr(char *source, int type, const char *host, const char *port, const char *name, char *errbuf);
-int pcap_parsesrcstr(const char *source, int *type, char *host, char *port, char *name, char *errbuf);
-int pcap_findalldevs_ex(char *source, struct pcap_rmtauth *auth, pcap_if_t **alldevs, char *errbuf);
-struct pcap_samp *pcap_setsampling(pcap_t *p);
-
-//\}
-// End of new winpcap functions
-
-
-
-/** \name Remote Capture functions
- */
-//\{
-SOCKET pcap_remoteact_accept(const char *address, const char *port, const char *hostlist, char *connectinghost, struct pcap_rmtauth *auth, char *errbuf);
-int pcap_remoteact_list(char *hostlist, char sep, int size, char *errbuf);
-int pcap_remoteact_close(const char *host, char *errbuf);
-void pcap_remoteact_cleanup();
-//\}
-// End of remote capture functions
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/wpcap.lib b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/wpcap.lib
deleted file mode 100644
index f832e0445..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/WinPCap/wpcap.lib
+++ /dev/null
Binary files differ
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.c
deleted file mode 100644
index d6a1d2577..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/*
- * Logging utility that allows FreeRTOS tasks to log to a UDP port, stdout, and
- * disk file without making any Win32 system calls themselves.
- *
- * Messages logged to a UDP port are sent directly (using FreeRTOS+TCP), but as
- * FreeRTOS tasks cannot make Win32 system calls messages sent to stdout or a
- * disk file are sent via a stream buffer to a Win32 thread which then performs
- * the actual output.
- */
-
-/* Standard includes. */
-#include <stdio.h>
-#include <stdint.h>
-#include <stdarg.h>
-#include <io.h>
-#include <ctype.h>
-
-/* FreeRTOS includes. */
-#include <FreeRTOS.h>
-#include "task.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_Stream_Buffer.h"
-
-/* Demo includes. */
-#include "demo_logging.h"
-
-/*-----------------------------------------------------------*/
-
-/* The maximum size to which the log file may grow, before being renamed
-to .ful. */
-#define dlLOGGING_FILE_SIZE ( 40ul * 1024ul * 1024ul )
-
-/* Dimensions the arrays into which print messages are created. */
-#define dlMAX_PRINT_STRING_LENGTH 255
-
-/* The size of the stream buffer used to pass messages from FreeRTOS tasks to
-the Win32 thread that is responsible for making any Win32 system calls that are
-necessary for the selected logging method. */
-#define dlLOGGING_STREAM_BUFFER_SIZE 32768
-
-/* A block time of zero simply means don't block. */
-#define dlDONT_BLOCK 0
-
-/*-----------------------------------------------------------*/
-
-/*
- * Called from vLoggingInit() to start a new disk log file.
- */
-static void prvFileLoggingInit( void );
-
-/*
- * Attempt to write a message to the file.
- */
-static void prvLogToFile( const char *pcMessage, size_t xLength );
-
-/*
- * Simply close the logging file, if it is open.
- */
-static void prvFileClose( void );
-
-/*
- * Before the scheduler is started this function is called directly. After the
- * scheduler has started it is called from the Windows thread dedicated to
- * outputting log messages. Only the windows thread actually performs the
- * writing so as not to disrupt the simulation by making Windows system calls
- * from FreeRTOS tasks.
- */
-static void prvLoggingFlushBuffer( void );
-
-/*
- * The windows thread that performs the actual writing of messages that require
- * Win32 system calls. Only the windows thread can make system calls so as not
- * to disrupt the simulation by making Windows calls from FreeRTOS tasks.
- */
-static DWORD WINAPI prvWin32LoggingThread( void *pvParam );
-
-/*
- * Creates the socket to which UDP messages are sent. This function is not
- * called directly to prevent the print socket being created from within the IP
- * task - which could result in a deadlock. Instead the function call is
- * deferred to run in the RTOS daemon task - hence it prototype.
- */
-static void prvCreatePrintSocket( void *pvParameter1, uint32_t ulParameter2 );
-
-/*-----------------------------------------------------------*/
-
-/* Windows event used to wake the Win32 thread which performs any logging that
-needs Win32 system calls. */
-static void *pvLoggingThreadEvent = NULL;
-
-/* Stores the selected logging targets passed in as parameters to the
-vLoggingInit() function. */
-BaseType_t xStdoutLoggingUsed = pdFALSE, xDiskFileLoggingUsed = pdFALSE, xUDPLoggingUsed = pdFALSE;
-
-/* Circular buffer used to pass messages from the FreeRTOS tasks to the Win32
-thread that is responsible for making Win32 calls (when stdout or a disk log is
-used). */
-static StreamBuffer_t *xLogStreamBuffer = NULL;
-
-/* Handle to the file used for logging. This is left open while there are
-messages waiting to be logged, then closed again in between logs. */
-static FILE *pxLoggingFileHandle = NULL;
-
-/* When true prints are performed directly. After start up xDirectPrint is set
-to pdFALSE - at which time prints that require Win32 system calls are done by
-the Win32 thread responsible for logging. */
-BaseType_t xDirectPrint = pdTRUE;
-
-/* File names for the in use and complete (full) log files. */
-static const char *pcLogFileName = "RTOSDemo.log";
-static const char *pcFullLogFileName = "RTOSDemo.ful";
-
-/* Keep the current file size in a variable, as an optimisation. */
-static size_t ulSizeOfLoggingFile = 0ul;
-
-/* The UDP socket and address on/to which print messages are sent. */
-Socket_t xPrintSocket = FREERTOS_INVALID_SOCKET;
-struct freertos_sockaddr xPrintUDPAddress;
-
-/*-----------------------------------------------------------*/
-
-void vLoggingInit( BaseType_t xLogToStdout, BaseType_t xLogToFile, BaseType_t xLogToUDP, uint32_t ulRemoteIPAddress, uint16_t usRemotePort )
-{
- /* Can only be called before the scheduler has started. */
- configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_NOT_STARTED );
-
- #if( ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) )
- {
- HANDLE Win32Thread;
-
- /* Record which output methods are to be used. */
- xStdoutLoggingUsed = xLogToStdout;
- xDiskFileLoggingUsed = xLogToFile;
- xUDPLoggingUsed = xLogToUDP;
-
- /* If a disk file is used then initialise it now. */
- if( xDiskFileLoggingUsed != pdFALSE )
- {
- prvFileLoggingInit();
- }
-
- /* If UDP logging is used then store the address to which the log data
- will be sent - but don't create the socket yet because the network is
- not initialised. */
- if( xUDPLoggingUsed != pdFALSE )
- {
- /* Set the address to which the print messages are sent. */
- xPrintUDPAddress.sin_port = FreeRTOS_htons( usRemotePort );
- xPrintUDPAddress.sin_addr = ulRemoteIPAddress;
- }
-
- /* If a disk file or stdout are to be used then Win32 system calls will
- have to be made. Such system calls cannot be made from FreeRTOS tasks
- so create a stream buffer to pass the messages to a Win32 thread, then
- create the thread itself, along with a Win32 event that can be used to
- unblock the thread. */
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) )
- {
- /* Create the buffer. */
- xLogStreamBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) + dlLOGGING_STREAM_BUFFER_SIZE + 1 );
- configASSERT( xLogStreamBuffer );
- memset( xLogStreamBuffer, '\0', sizeof( *xLogStreamBuffer ) - sizeof( xLogStreamBuffer->ucArray ) );
- xLogStreamBuffer->LENGTH = dlLOGGING_STREAM_BUFFER_SIZE + 1;
-
- /* Create the Windows event. */
- pvLoggingThreadEvent = CreateEvent( NULL, FALSE, TRUE, "StdoutLoggingEvent" );
-
- /* Create the thread itself. */
- Win32Thread = CreateThread(
- NULL, /* Pointer to thread security attributes. */
- 0, /* Initial thread stack size, in bytes. */
- prvWin32LoggingThread, /* Pointer to thread function. */
- NULL, /* Argument for new thread. */
- 0, /* Creation flags. */
- NULL );
-
- /* Use the cores that are not used by the FreeRTOS tasks. */
- SetThreadAffinityMask( Win32Thread, ~0x01u );
- SetThreadPriorityBoost( Win32Thread, TRUE );
- SetThreadPriority( Win32Thread, THREAD_PRIORITY_IDLE );
- }
- }
- #else
- {
- /* FreeRTOSIPConfig is set such that no print messages will be output.
- Avoid compiler warnings about unused parameters. */
- ( void ) xLogToStdout;
- ( void ) xLogToFile;
- ( void ) xLogToUDP;
- ( void ) usRemotePort;
- ( void ) ulRemoteIPAddress;
- }
- #endif /* ( ipconfigHAS_DEBUG_PRINTF == 1 ) || ( ipconfigHAS_PRINTF == 1 ) */
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreatePrintSocket( void *pvParameter1, uint32_t ulParameter2 )
-{
-static const TickType_t xSendTimeOut = pdMS_TO_TICKS( 0 );
-Socket_t xSocket;
-
- /* The function prototype is that of a deferred function, but the parameters
- are not actually used. */
- ( void ) pvParameter1;
- ( void ) ulParameter2;
-
- xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
-
- if( xSocket != FREERTOS_INVALID_SOCKET )
- {
- /* FreeRTOS+TCP decides which port to bind to. */
- FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDTIMEO, &xSendTimeOut, sizeof( xSendTimeOut ) );
- FreeRTOS_bind( xSocket, NULL, 0 );
-
- /* Now the socket is bound it can be assigned to the print socket. */
- xPrintSocket = xSocket;
- }
-}
-/*-----------------------------------------------------------*/
-
-void vLoggingPrintf( const char *pcFormat, ... )
-{
-char cPrintString[ dlMAX_PRINT_STRING_LENGTH ];
-char cOutputString[ dlMAX_PRINT_STRING_LENGTH ];
-char *pcSource, *pcTarget, *pcBegin;
-size_t xLength, xLength2, rc;
-static BaseType_t xMessageNumber = 0;
-va_list args;
-uint32_t ulIPAddress;
-const char *pcTaskName;
-const char *pcNoTask = "None";
-int iOriginalPriority;
-HANDLE xCurrentTask;
-
-
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) || ( xUDPLoggingUsed != pdFALSE ) )
- {
- /* There are a variable number of parameters. */
- va_start( args, pcFormat );
-
- /* Additional info to place at the start of the log. */
- if( xTaskGetSchedulerState() != taskSCHEDULER_NOT_STARTED )
- {
- pcTaskName = pcTaskGetName( NULL );
- }
- else
- {
- pcTaskName = pcNoTask;
- }
-
- if( strcmp( pcFormat, "\n" ) != 0 )
- {
- xLength = snprintf( cPrintString, dlMAX_PRINT_STRING_LENGTH, "%lu %lu [%s] ",
- xMessageNumber++,
- ( unsigned long ) xTaskGetTickCount(),
- pcTaskName );
- }
- else
- {
- xLength = 0;
- memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH );
- }
-
- xLength2 = vsnprintf( cPrintString + xLength, dlMAX_PRINT_STRING_LENGTH - xLength, pcFormat, args );
-
- if( xLength2 < 0 )
- {
- /* Clean up. */
- xLength2 = dlMAX_PRINT_STRING_LENGTH - 1 - xLength;
- cPrintString[ dlMAX_PRINT_STRING_LENGTH - 1 ] = '\0';
- }
-
- xLength += xLength2;
- va_end( args );
-
- /* For ease of viewing, copy the string into another buffer, converting
- IP addresses to dot notation on the way. */
- pcSource = cPrintString;
- pcTarget = cOutputString;
-
- while( ( *pcSource ) != '\0' )
- {
- *pcTarget = *pcSource;
- pcTarget++;
- pcSource++;
-
- /* Look forward for an IP address denoted by 'ip'. */
- if( ( isxdigit( pcSource[ 0 ] ) != pdFALSE ) && ( pcSource[ 1 ] == 'i' ) && ( pcSource[ 2 ] == 'p' ) )
- {
- *pcTarget = *pcSource;
- pcTarget++;
- *pcTarget = '\0';
- pcBegin = pcTarget - 8;
-
- while( ( pcTarget > pcBegin ) && ( isxdigit( pcTarget[ -1 ] ) != pdFALSE ) )
- {
- pcTarget--;
- }
-
- sscanf( pcTarget, "%8X", &ulIPAddress );
- rc = sprintf( pcTarget, "%lu.%lu.%lu.%lu",
- ( unsigned long ) ( ulIPAddress >> 24UL ),
- ( unsigned long ) ( (ulIPAddress >> 16UL) & 0xffUL ),
- ( unsigned long ) ( (ulIPAddress >> 8UL) & 0xffUL ),
- ( unsigned long ) ( ulIPAddress & 0xffUL ) );
- pcTarget += rc;
- pcSource += 3; /* skip "<n>ip" */
- }
- }
-
- /* How far through the buffer was written? */
- xLength = ( BaseType_t ) ( pcTarget - cOutputString );
-
- /* If the message is to be logged to a UDP port then it can be sent directly
- because it only uses FreeRTOS function (not Win32 functions). */
- if( xUDPLoggingUsed != pdFALSE )
- {
- if( ( xPrintSocket == FREERTOS_INVALID_SOCKET ) && ( FreeRTOS_IsNetworkUp() != pdFALSE ) )
- {
- /* Create and bind the socket to which print messages are sent. The
- xTimerPendFunctionCall() function is used even though this is
- not an interrupt because this function is called from the IP task
- and the IP task cannot itself wait for a socket to bind. The
- parameters to prvCreatePrintSocket() are not required so set to
- NULL or 0. */
- xTimerPendFunctionCall( prvCreatePrintSocket, NULL, 0, dlDONT_BLOCK );
- }
-
- if( xPrintSocket != FREERTOS_INVALID_SOCKET )
- {
- FreeRTOS_sendto( xPrintSocket, cOutputString, xLength, 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) );
-
- /* Just because the UDP data logger I'm using is dumb. */
- FreeRTOS_sendto( xPrintSocket, "\r", sizeof( char ), 0, &xPrintUDPAddress, sizeof( xPrintUDPAddress ) );
- }
- }
-
- /* If logging is also to go to either stdout or a disk file then it cannot
- be output here - so instead write the message to the stream buffer and wake
- the Win32 thread which will read it from the stream buffer and perform the
- actual output. */
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( xDiskFileLoggingUsed != pdFALSE ) )
- {
- configASSERT( xLogStreamBuffer );
-
- /* How much space is in the buffer? */
- xLength2 = uxStreamBufferGetSpace( xLogStreamBuffer );
-
- /* There must be enough space to write both the string and the length of
- the string. */
- if( xLength2 >= ( xLength + sizeof( xLength ) ) )
- {
- /* First write in the length of the data, then write in the data
- itself. Raising the thread priority is used as a critical section
- as there are potentially multiple writers. The stream buffer is
- only thread safe when there is a single writer (likewise for
- reading from the buffer). */
- xCurrentTask = GetCurrentThread();
- iOriginalPriority = GetThreadPriority( xCurrentTask );
- SetThreadPriority( GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL );
- uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) &( xLength ), sizeof( xLength ) );
- uxStreamBufferAdd( xLogStreamBuffer, 0, ( const uint8_t * ) cOutputString, xLength );
- SetThreadPriority( GetCurrentThread(), iOriginalPriority );
- }
-
- /* xDirectPrint is initialised to pdTRUE, and while it remains true the
- logging output function is called directly. When the system is running
- the output function cannot be called directly because it would get
- called from both FreeRTOS tasks and Win32 threads - so instead wake the
- Win32 thread responsible for the actual output. */
- if( xDirectPrint != pdFALSE )
- {
- /* While starting up, the thread which calls prvWin32LoggingThread()
- is not running yet and xDirectPrint will be pdTRUE. */
- prvLoggingFlushBuffer();
- }
- else if( pvLoggingThreadEvent != NULL )
- {
- /* While running, wake up prvWin32LoggingThread() to send the
- logging data. */
- SetEvent( pvLoggingThreadEvent );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvLoggingFlushBuffer( void )
-{
-size_t xLength;
-char cPrintString[ dlMAX_PRINT_STRING_LENGTH ];
-
- /* Is there more than the length value stored in the circular buffer
- used to pass data from the FreeRTOS simulator into this Win32 thread? */
- while( uxStreamBufferGetSize( xLogStreamBuffer ) > sizeof( xLength ) )
- {
- memset( cPrintString, 0x00, dlMAX_PRINT_STRING_LENGTH );
- uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
- uxStreamBufferGet( xLogStreamBuffer, 0, ( uint8_t * ) cPrintString, xLength, pdFALSE );
-
- /* Write the message to standard out if requested to do so when
- vLoggingInit() was called, or if the network is not yet up. */
- if( ( xStdoutLoggingUsed != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
- {
- /* Write the message to stdout. */
- printf( "%s", cPrintString ); /*_RB_ Replace with _write(). */
- }
-
- /* Write the message to a file if requested to do so when
- vLoggingInit() was called. */
- if( xDiskFileLoggingUsed != pdFALSE )
- {
- prvLogToFile( cPrintString, xLength );
- }
- }
-
- prvFileClose();
-}
-/*-----------------------------------------------------------*/
-
-static DWORD WINAPI prvWin32LoggingThread( void *pvParameter )
-{
-const DWORD xMaxWait = 1000;
-
- ( void ) pvParameter;
-
- /* From now on, prvLoggingFlushBuffer() will only be called from this
- Windows thread */
- xDirectPrint = pdFALSE;
-
- for( ;; )
- {
- /* Wait to be told there are message waiting to be logged. */
- WaitForSingleObject( pvLoggingThreadEvent, xMaxWait );
-
- /* Write out all waiting messages. */
- prvLoggingFlushBuffer();
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvFileLoggingInit( void )
-{
-FILE *pxHandle = fopen( pcLogFileName, "a" );
-
- if( pxHandle != NULL )
- {
- fseek( pxHandle, SEEK_END, 0ul );
- ulSizeOfLoggingFile = ftell( pxHandle );
- fclose( pxHandle );
- }
- else
- {
- ulSizeOfLoggingFile = 0ul;
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvFileClose( void )
-{
- if( pxLoggingFileHandle != NULL )
- {
- fclose( pxLoggingFileHandle );
- pxLoggingFileHandle = NULL;
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvLogToFile( const char *pcMessage, size_t xLength )
-{
- if( pxLoggingFileHandle == NULL )
- {
- pxLoggingFileHandle = fopen( pcLogFileName, "a" );
- }
-
- if( pxLoggingFileHandle != NULL )
- {
- fwrite( pcMessage, 1, xLength, pxLoggingFileHandle );
- ulSizeOfLoggingFile += xLength;
-
- /* If the file has grown to its maximum permissible size then close and
- rename it - then start with a new file. */
- if( ulSizeOfLoggingFile > ( size_t ) dlLOGGING_FILE_SIZE )
- {
- prvFileClose();
- if( _access( pcFullLogFileName, 00 ) == 0 )
- {
- remove( pcFullLogFileName );
- }
- rename( pcLogFileName, pcFullLogFileName );
- ulSizeOfLoggingFile = 0;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.h
deleted file mode 100644
index 62ae46a52..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/demo_logging.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef DEMO_LOGGING_H
-#define DEMO_LOGGING_H
-
-/*
- * Initialise a logging system that can be used from FreeRTOS tasks and Win32
- * threads. Do not call printf() directly while the scheduler is running.
- *
- * Set xLogToStdout, xLogToFile and xLogToUDP to either pdTRUE or pdFALSE to
- * lot to stdout, a disk file and a UDP port respectively.
- *
- * If xLogToUDP is pdTRUE then ulRemoteIPAddress and usRemotePort must be set
- * to the IP address and port number to which UDP log messages will be sent.
- */
-void vLoggingInit( BaseType_t xLogToStdout,
- BaseType_t xLogToFile,
- BaseType_t xLogToUDP,
- uint32_t ulRemoteIPAddress,
- uint16_t usRemotePort );
-
-#endif /* DEMO_LOGGING_H */
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config.h
deleted file mode 100644
index 68517887a..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config.h
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/* This file contains configuration settings for the demos. */
-
-#ifndef IOT_CONFIG_H_
-#define IOT_CONFIG_H_
-
-
-/*
- * Set this to the number of recyclable tasks for the task pool to cache.
- *
- * Caching dynamically allocated tasks (recyclable tasks) helps the application
- * to limit the number of allocations at runtime. Caching recyclable tasks may
- * help making the application more responsive and predictable, by removing a
- * potential for memory allocation failures, but it may also have negative
- * repercussions on the amount of memory available at any given time. It is up
- * to the application developer to strike the correct balance these competing
- * needs. The task pool will cache when the application calling
- * IotTaskPool_RecycleJob. Any recycled tasks in excess of
- * IOT_TASKPOOL_JOBS_RECYCLE_LIMIT will be destroyed and its memory will be
- * release.
- *
- * Default value (if undefined): 8
- */
-#define IOT_TASKPOOL_JOBS_RECYCLE_LIMIT 8
-
-/*
- * Set this to 1 to perform sanity checks when using the task pool library.
- *
- * Asserts are useful for debugging, but should be disabled in production code.
- * If this is set to 1, IotTaskPool_Assert can be defined to set the assertion
- * function; otherwise, the standard library's assert function will be used.
- *
- * Possible values: 0 (asserts disabled) or 1 (asserts enabled)
- * Recommended values: 1 when debugging; 0 in production code.
- * Default value (if undefined): 0
- */
-#define IOT_TASKPOOL_ENABLE_ASSERTS 1
-
-/*
- * The full IoT Task Pool Library has many use cases, including Linux
- * development.  Typical FreeRTOS use cases do not require the full
- * functionality so an optimised implementation is provided specifically for use
- * with FreeRTOS. The optimised version has a fixed number of tasks in the
- * pool, each of which uses statically allocated memory to ensure creation of
- * the pool is guaranteed (it does not run out of heap space).
- * IOT_TASKPOOL_NUMBER_OF_WORKERS sets the number of tasks in the pool.
- */
-#define IOT_TASKPOOL_NUMBER_OF_WORKERS 3
-
-/*
- * Set the log level of the task pool library.
- *
- * Log messages from the task pool library at or below this setting will be
- * printed.
- *
- * Possible values: One of the Log levels.
- * Default value (if undefined): IOT_LOG_LEVEL_GLOBAL; if that is undefined,
- * then IOT_LOG_NONE.
- */
-#define IOT_LOG_LEVEL_TASKPOOL IOT_LOG_INFO
-
-
-/**
- * @brief The stack size (in bytes) for each worker task in the task pool.
- *
- * The minimal version of the of task pool library only supports one task pool
- * and the configuration of each worker task fixed at the compile time.
- */
-#define IOT_TASKPOOL_WORKER_STACK_SIZE_BYTES 2048
-
-/* Include the common configuration file for FreeRTOS. */
-#include "iot_config_common.h"
-
-#endif /* ifndef IOT_CONFIG_H_ */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config_common.h b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config_common.h
deleted file mode 100644
index 8b976103e..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/iot_config_common.h
+++ /dev/null
@@ -1,197 +0,0 @@
-/*
- * Amazon FreeRTOS V201906.00 Major
- * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* This file contains default configuration settings for the demos on FreeRTOS. */
-
-#ifndef IOT_CONFIG_COMMON_H_
-#define IOT_CONFIG_COMMON_H_
-
-/* FreeRTOS include. */
-#include "FreeRTOS.h" //_RB_Makes common config file FreeRTOS specific
-
-/* Use platform types on FreeRTOS. */
-#include "platform/iot_platform_types_freertos.h" //_RB_Makes common config file FreeRTOS specific
-
-/* SDK version. */
-#define IOT_SDK_VERSION "4.0.0"
-
-/* This config file is for the demos; disable any test code. */
-#define IOT_BUILD_TESTS ( 0 )
-
-/* Logging puts function. */
-#define IotLogging_Puts( str ) configPRINTF( ( "%s\r\n", str ) )
-
-/* Enable asserts in libraries by default. */
-#ifndef IOT_METRICS_ENABLE_ASSERTS
- #define IOT_METRICS_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_CONTAINERS_ENABLE_ASSERTS
- #define IOT_CONTAINERS_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_TASKPOOL_ENABLE_ASSERTS
- #define IOT_TASKPOOL_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_MQTT_ENABLE_ASSERTS
- #define IOT_MQTT_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef AWS_IOT_SHADOW_ENABLE_ASSERTS
- #define AWS_IOT_SHADOW_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef AWS_IOT_DEFENDER_ENABLE_ASSERTS
- #define AWS_IOT_DEFENDER_ENABLE_ASSERTS ( 1 )
-#endif
-#ifndef IOT_BLE_ENABLE_ASSERTS
- #define IOT_BLE_ENABLE_ASSERTS ( 1 )
-#endif
-
-/* Assert functions. */
-#define IotMetrics_Assert( expression ) configASSERT( expression )
-#define IotContainers_Assert( expression ) configASSERT( expression )
-#define IotTaskPool_Assert( expression ) configASSERT( expression )
-#define IotMqtt_Assert( expression ) configASSERT( expression )
-#define AwsIotShadow_Assert( expression ) configASSERT( expression )
-#define AwsIotDefender_Assert( expression ) configASSERT( expression )
-#define IotBle_Assert( expression ) configASSERT( expression )
-
-/* Control the usage of dynamic memory allocation. */
-#ifndef IOT_STATIC_MEMORY_ONLY
- #define IOT_STATIC_MEMORY_ONLY ( 0 )
-#endif
-
-/* Memory allocation configuration. Note that these functions will not be affected
- * by IOT_STATIC_MEMORY_ONLY. */
-#define IotNetwork_Malloc pvPortMalloc
-#define IotNetwork_Free vPortFree
-#define IotThreads_Malloc pvPortMalloc
-#define IotThreads_Free vPortFree
-#define IotLogging_Malloc pvPortMalloc
-#define IotLogging_Free vPortFree
-#define IotBle_Malloc pvPortMalloc
-#define IotBle_Free vPortFree
-/* #define IotLogging_StaticBufferSize */
-
-/* Memory allocation function configuration for the MQTT and Defender library.
- * These libraries will be affected by IOT_STATIC_MEMORY_ONLY. */
-#if IOT_STATIC_MEMORY_ONLY == 0
- #define IotMetrics_MallocTcpConnection pvPortMalloc
- #define IotMetrics_FreeTcpConnection vPortFree
- #define IotMetrics_MallocIpAddress pvPortMalloc
- #define IotMetrics_FreeIpAddress vPortFree
-
- #define IotTaskPool_MallocTaskPool pvPortMalloc
- #define IotTaskPool_FreeTaskPool vPortFree
- #define IotTaskPool_MallocJob pvPortMalloc
- #define IotTaskPool_FreeJob vPortFree
- #define IotTaskPool_MallocTimerEvent pvPortMalloc
- #define IotTaskPool_FreeTimerEvent vPortFree
-
- #define IotMqtt_MallocConnection pvPortMalloc
- #define IotMqtt_FreeConnection vPortFree
- #define IotMqtt_MallocMessage pvPortMalloc
- #define IotMqtt_FreeMessage vPortFree
- #define IotMqtt_MallocOperation pvPortMalloc
- #define IotMqtt_FreeOperation vPortFree
- #define IotMqtt_MallocSubscription pvPortMalloc
- #define IotMqtt_FreeSubscription vPortFree
-
- #define IotSerializer_MallocCborEncoder pvPortMalloc
- #define IotSerializer_FreeCborEncoder vPortFree
- #define IotSerializer_MallocCborParser pvPortMalloc
- #define IotSerializer_FreeCborParser vPortFree
- #define IotSerializer_MallocCborValue pvPortMalloc
- #define IotSerializer_FreeCborValue vPortFree
- #define IotSerializer_MallocDecoderObject pvPortMalloc
- #define IotSerializer_FreeDecoderObject vPortFree
-
- #define AwsIotShadow_MallocOperation pvPortMalloc
- #define AwsIotShadow_FreeOperation vPortFree
- #define AwsIotShadow_MallocString pvPortMalloc
- #define AwsIotShadow_FreeString vPortFree
- #define AwsIotShadow_MallocSubscription pvPortMalloc
- #define AwsIotShadow_FreeSubscription vPortFree
-
- #define AwsIotDefender_MallocReport pvPortMalloc
- #define AwsIotDefender_FreeReport vPortFree
- #define AwsIotDefender_MallocTopic pvPortMalloc
- #define AwsIotDefender_FreeTopic vPortFree
-#endif /* if IOT_STATIC_MEMORY_ONLY == 0 */
-
-/* Default platform thread stack size and priority. */
-#ifndef IOT_THREAD_DEFAULT_STACK_SIZE
- #define IOT_THREAD_DEFAULT_STACK_SIZE 2048
-#endif
-#ifndef IOT_THREAD_DEFAULT_PRIORITY
- #define IOT_THREAD_DEFAULT_PRIORITY tskIDLE_PRIORITY
-#endif
-
-/* Platform network configuration. */
-#ifndef IOT_NETWORK_RECEIVE_TASK_PRIORITY
- #define IOT_NETWORK_RECEIVE_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )
-#endif
-#ifndef IOT_NETWORK_RECEIVE_TASK_STACK_SIZE
- #define IOT_NETWORK_RECEIVE_TASK_STACK_SIZE IOT_THREAD_DEFAULT_STACK_SIZE
-#endif
-
-/* Platform and SDK name for AWS IoT MQTT metrics. Only used when
- * AWS_IOT_MQTT_ENABLE_METRICS is 1. */
-#define IOT_SDK_NAME "AmazonFreeRTOS"
-#ifdef configPLATFORM_NAME
- #define IOT_PLATFORM_NAME configPLATFORM_NAME
-#else
- #define IOT_PLATFORM_NAME "Unknown"
-#endif
-
-/* Cloud endpoint to which the device connects to. */
-#define IOT_CLOUD_ENDPOINT clientcredentialMQTT_BROKER_ENDPOINT
-
-/**
- * @brief Unique identifier used to recognize a device by the cloud.
- * This could be SHA-256 of the device certificate.
- */
-extern const char *getDeviceIdentifier( void );
-#define IOT_DEVICE_IDENTIFIER getDeviceIdentifier()
-
-/**
- * @brief Metrics emitted by the device.
- */
-extern const char *getDeviceMetrics( void );
-#define AWS_IOT_METRICS_USERNAME getDeviceMetrics()
-
-/**
- * @brief Length of the metrics emitted by device.
- */
-extern uint16_t getDeviceMetricsLength( void );
-#define AWS_IOT_METRICS_USERNAME_LENGTH getDeviceMetricsLength()
-
-/* Define the data type of metrics connection id as same as Socket_t in aws_secure_socket.h */
-#define IotMetricsConnectionId_t void *
-
-/* Configuration for defender demo: set format to CBOR. */
-#define AWS_IOT_DEFENDER_FORMAT AWS_IOT_DEFENDER_FORMAT_CBOR
-
-/* Configuration for defender demo: use long tag for readable output. Please use short tag for the real application. */
-#define AWS_IOT_DEFENDER_USE_LONG_TAG ( 1 )
-
-#endif /* ifndef IOT_CONFIG_COMMON_H_ */
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/main.c
deleted file mode 100644
index 2cf6b3829..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/main.c
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * FreeRTOS Kernel V10.2.1
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
- /***
- * See https://www.FreeRTOS.org/task-pool/ for configuration and usage instructions.
- ***/
-
-
-/* Standard includes. */
-#include <stdio.h>
-#include <time.h>
-
-/* Visual studio intrinsics used so the __debugbreak() function is available
-should an assert get hit. */
-#include <intrin.h>
-
-/* FreeRTOS includes. */
-#include <FreeRTOS.h>
-#include "task.h"
-
-/* TCP/IP stack includes. */
-#include "FreeRTOS_IP.h"
-
-/*
- * Prototypes for the demos that can be started from this project.
- */
-extern void vStartSimpleTaskPoolDemo( void );
-
-/* This example is the first in a sequence that adds IoT functionality into
-an existing TCP/IP project. In this first project the TCP/IP stack is not
-actually used, but it is still built, which requires this array to be
-present. */
-const uint8_t ucMACAddress[ 6 ] = { configMAC_ADDR0, configMAC_ADDR1, configMAC_ADDR2, configMAC_ADDR3, configMAC_ADDR4, configMAC_ADDR5 };
-
-/*-----------------------------------------------------------*/
-
-int main( void )
-{
- /***
- * See https://www.FreeRTOS.org/task-pool/ for configuration and usage instructions.
- ***/
-
- /* Create the example that demonstrates task pool functionality. Examples
- that demonstrate networking connectivity will be added in future projects
- and get started after the network has connected (from within the
- vApplicationIPNetworkEventHook() function).*/
- vStartSimpleTaskPoolDemo();
-
- /* Start the scheduler - if all is well from this point on only FreeRTOS
- tasks will execute. */
- vTaskStartScheduler();
-
- /* If all is well, the scheduler will now be running, and the following
- line will never be reached. If the following line does execute, then
- there was insufficient FreeRTOS heap memory available for the idle and/or
- timer tasks to be created. See the memory management section on the
- FreeRTOS web site for more details (this is standard text that is not not
- really applicable to the Win32 simulator port). */
- for( ;; )
- {
- __debugbreak();
- }
-}
-/*-----------------------------------------------------------*/
-
-void vAssertCalled( const char *pcFile, uint32_t ulLine )
-{
-volatile uint32_t ulBlockVariable = 0UL;
-volatile char *pcFileName = ( volatile char * ) pcFile;
-volatile uint32_t ulLineNumber = ulLine;
-
- ( void ) pcFileName;
- ( void ) ulLineNumber;
-
- printf( "vAssertCalled( %s, %u\n", pcFile, ulLine );
-
- /* Setting ulBlockVariable to a non-zero value in the debugger will allow
- this function to be exited. */
- taskDISABLE_INTERRUPTS();
- {
- while( ulBlockVariable == 0UL )
- {
- __debugbreak();
- }
- }
- taskENABLE_INTERRUPTS();
-}
-/*-----------------------------------------------------------*/
-
-/* Called by FreeRTOS+TCP when the network connects or disconnects. Disconnect
-events are only received if implemented in the MAC driver. */
-void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent )
-{
- /* This example is the first in a sequence that adds IoT functionality into
- an existing TCP/IP project. In this first project the TCP/IP stack is not
- actually used, but it is still built, which requires this function to be
- present. For now this function does not need to do anything, so just ensure
- the unused parameters don't cause compiler warnings and that calls to this
- function are trapped by the debugger. */
- __debugbreak();
- ( void ) eNetworkEvent;
-}
-/*-----------------------------------------------------------*/
-
-extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
- uint16_t usSourcePort,
- uint32_t ulDestinationAddress,
- uint16_t usDestinationPort )
-{
- /* This example is the first in a sequence that adds IoT functionality into
- an existing TCP/IP project. In this first project the TCP/IP stack is not
- actually used, but it is still built, which requires this function to be
- present. For now this function does not need to do anything, so just ensure
- the unused parameters don't cause compiler warnings and that calls to this
- function are trapped by the debugger. */
- ( void ) ulSourceAddress;
- ( void ) usSourcePort;
- ( void ) ulDestinationAddress;
- ( void ) usDestinationPort;
- __debugbreak();
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxRand( void )
-{
- /* This example is the first in a sequence that adds IoT functionality into
- an existing TCP/IP project. In this first project the TCP/IP stack is not
- actually used, but it is still built, which requires this function to be
- present. For now this function does not need to do anything, so just ensure
- the calls to the function are trapped by the debugger. */
- __debugbreak();
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-/* configUSE_STATIC_ALLOCATION is set to 1, so the application must provide an
-implementation of vApplicationGetIdleTaskMemory() to provide the memory that is
-used by the Idle task. */
-void vApplicationGetIdleTaskMemory( StaticTask_t** ppxIdleTaskTCBBuffer, StackType_t** ppxIdleTaskStackBuffer, uint32_t* pulIdleTaskStackSize )
-{
- /* If the buffers to be provided to the Idle task are declared inside this
- function then they must be declared static - otherwise they will be allocated on
- the stack and so not exists after this function exits. */
- static StaticTask_t xIdleTaskTCB;
- static StackType_t uxIdleTaskStack[configMINIMAL_STACK_SIZE];
-
- /* Pass out a pointer to the StaticTask_t structure in which the Idle task's
- state will be stored. */
- *ppxIdleTaskTCBBuffer = &xIdleTaskTCB;
-
- /* Pass out the array that will be used as the Idle task's stack. */
- *ppxIdleTaskStackBuffer = uxIdleTaskStack;
-
- /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer.
- Note that, as the array is necessarily of type StackType_t,
- configMINIMAL_STACK_SIZE is specified in words, not bytes. */
- *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE;
-}
-/*-----------------------------------------------------------*/
-
-/* configUSE_STATIC_ALLOCATION and configUSE_TIMERS are both set to 1, so the
-application must provide an implementation of vApplicationGetTimerTaskMemory()
-to provide the memory that is used by the Timer service task. */
-void vApplicationGetTimerTaskMemory( StaticTask_t** ppxTimerTaskTCBBuffer, StackType_t** ppxTimerTaskStackBuffer, uint32_t* pulTimerTaskStackSize )
-{
- /* If the buffers to be provided to the Timer task are declared inside this
- function then they must be declared static - otherwise they will be allocated on
- the stack and so not exists after this function exits. */
- static StaticTask_t xTimerTaskTCB;
- static StackType_t uxTimerTaskStack[configTIMER_TASK_STACK_DEPTH];
-
- /* Pass out a pointer to the StaticTask_t structure in which the Timer
- task's state will be stored. */
- *ppxTimerTaskTCBBuffer = &xTimerTaskTCB;
-
- /* Pass out the array that will be used as the Timer task's stack. */
- *ppxTimerTaskStackBuffer = uxTimerTaskStack;
-
- /* Pass out the size of the array pointed to by *ppxTimerTaskStackBuffer.
- Note that, as the array is necessarily of type StackType_t,
- configMINIMAL_STACK_SIZE is specified in words, not bytes. */
- *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH;
-}
-
-
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/printf-stdarg.c b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/printf-stdarg.c
deleted file mode 100644
index 5505535c1..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/printf-stdarg.c
+++ /dev/null
@@ -1,667 +0,0 @@
-/*
- Copyright 2001, 2002 Georges Menie (www.menie.org)
- stdarg version contributed by Christian Ettinger
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU Lesser General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- Changes for the FreeRTOS ports:
-
- - The dot in "%-8.8s"
- - The specifiers 'l' (long) and 'L' (long long)
- - The specifier 'u' for unsigned
- - Dot notation for IP addresses:
- sprintf("IP = %xip\n", 0xC0A80164);
- will produce "IP = 192.168.1.100\n"
-*/
-
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "FreeRTOS.h"
-
-#define PAD_RIGHT 1
-#define PAD_ZERO 2
-
-/*
- * Return 1 for readable, 2 for writeable, 3 for both.
- * Function must be provided by the application.
- */
-extern BaseType_t xApplicationMemoryPermissions( uint32_t aAddress );
-
-extern void vOutputChar( const char cChar, const TickType_t xTicksToWait );
-static const TickType_t xTicksToWait = pdMS_TO_TICKS( 20 );
-
-struct xPrintFlags
-{
- int base;
- int width;
- int printLimit;
- unsigned
- pad : 8,
- letBase : 8,
- isSigned : 1,
- isNumber : 1,
- long32 : 1,
- long64 : 1;
-};
-
-struct SStringBuf
-{
- char *str;
- const char *orgStr;
- const char *nulPos;
- int curLen;
- struct xPrintFlags flags;
-};
-
-static void strbuf_init( struct SStringBuf *apStr, char *apBuf, const char *apMaxStr )
-{
- apStr->str = apBuf;
- apStr->orgStr = apBuf;
- apStr->nulPos = apMaxStr-1;
- apStr->curLen = 0;
-
- memset( &apStr->flags, '\0', sizeof( apStr->flags ) );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t strbuf_printchar( struct SStringBuf *apStr, int c )
-{
- if( apStr->str == NULL )
- {
- vOutputChar( ( char ) c, xTicksToWait );
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str < apStr->nulPos )
- {
- *( apStr->str++ ) = c;
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str == apStr->nulPos )
- {
- *( apStr->str++ ) = '\0';
- }
- return pdFALSE;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE BaseType_t strbuf_printchar_inline( struct SStringBuf *apStr, int c )
-{
- if( apStr->str == NULL )
- {
- vOutputChar( ( char ) c, xTicksToWait );
- if( c == 0 )
- {
- return pdFALSE;
- }
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str < apStr->nulPos )
- {
- *(apStr->str++) = c;
- if( c == 0 )
- {
- return pdFALSE;
- }
- apStr->curLen++;
- return pdTRUE;
- }
- if( apStr->str == apStr->nulPos )
- {
- *( apStr->str++ ) = '\0';
- }
- return pdFALSE;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE int i2hex( int aCh )
-{
-int iResult;
-
- if( aCh < 10 )
- {
- iResult = '0' + aCh;
- }
- else
- {
- iResult = 'A' + aCh - 10;
- }
-
- return iResult;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prints(struct SStringBuf *apBuf, const char *apString )
-{
- register int padchar = ' ';
- int i,len;
-
- if( xApplicationMemoryPermissions( ( uint32_t )apString ) == 0 )
- {
- /* The user has probably made a mistake with the parameter
- for '%s', the memory is not readbale. */
- apString = "INV_MEM";
- }
-
- if( apBuf->flags.width > 0 )
- {
- register int len = 0;
- register const char *ptr;
- for( ptr = apString; *ptr; ++ptr )
- {
- ++len;
- }
-
- if( len >= apBuf->flags.width )
- {
- apBuf->flags.width = 0;
- }
- else
- {
- apBuf->flags.width -= len;
- }
-
- if( apBuf->flags.pad & PAD_ZERO )
- {
- padchar = '0';
- }
- }
- if( ( apBuf->flags.pad & PAD_RIGHT ) == 0 )
- {
- for( ; apBuf->flags.width > 0; --apBuf->flags.width )
- {
- if( strbuf_printchar( apBuf, padchar ) == 0 )
- {
- return pdFALSE;
- }
- }
- }
- if( ( apBuf->flags.isNumber == pdTRUE ) && ( apBuf->flags.pad == pdTRUE ) )
- {
- /* The string to print represents an integer number.
- * In this case, printLimit is the min number of digits to print
- * If the length of the number to print is less than the min nb of i
- * digits to display, we add 0 before printing the number
- */
- len = strlen( apString );
-
- if( len < apBuf->flags.printLimit )
- {
- i = apBuf->flags.printLimit - len;
- for( ; i; i-- )
- {
- if( strbuf_printchar( apBuf, '0' ) == 0 )
- {
- return pdFALSE;
- }
- }
- }
- }
- /* The string to print is not the result of a number conversion to ascii.
- * For a string, printLimit is the max number of characters to display
- */
- for( ; apBuf->flags.printLimit && *apString ; ++apString, --apBuf->flags.printLimit )
- {
- if( !strbuf_printchar( apBuf, *apString ) )
- {
- return pdFALSE;
- }
- }
-
- for( ; apBuf->flags.width > 0; --apBuf->flags.width )
- {
- if( !strbuf_printchar( apBuf, padchar ) )
- {
- return pdFALSE;
- }
- }
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-/* the following should be enough for 32 bit int */
-#define PRINT_BUF_LEN 12 /* to print 4294967296 */
-
-#if SPRINTF_LONG_LONG
-#warning 64-bit libraries will be included as well
-static BaseType_t printll( struct SStringBuf *apBuf, long long i )
-{
- char print_buf[ 2 * PRINT_BUF_LEN ];
- register char *s;
- register int t, neg = 0;
- register unsigned long long u = i;
- lldiv_t lldiv_result;
-
-/* typedef struct
- * {
- * long long int quot; // quotient
- * long long int rem; // remainder
- * } lldiv_t;
- */
-
- apBuf->flags.isNumber = pdTRUE; /* Parameter for prints */
- if( i == 0LL )
- {
- print_buf[ 0 ] = '0';
- print_buf[ 1 ] = '\0';
- return prints( apBuf, print_buf );
- }
-
- if( ( apBuf->flags.isSigned == pdTRUE ) && ( apBuf->flags.base == 10 ) && ( i < 0LL ) )
- {
- neg = 1;
- u = -i;
- }
-
- s = print_buf + sizeof( print_buf ) - 1;
-
- *s = '\0';
- /* 18446744073709551616 */
- while( u != 0 )
- {
- lldiv_result = lldiv( u, ( unsigned long long ) apBuf->flags.base );
- t = lldiv_result.rem;
- if( t >= 10 )
- {
- t += apBuf->flags.letBase - '0' - 10;
- }
- *( --s ) = t + '0';
- u = lldiv_result.quot;
- }
-
- if( neg != 0 )
- {
- if( ( apBuf->flags.width != 0 ) && ( apBuf->flags.pad & PAD_ZERO ) )
- {
- if( !strbuf_printchar( apBuf, '-' ) )
- {
- return pdFALSE;
- }
- --apBuf->flags.width;
- }
- else
- {
- *( --s ) = '-';
- }
- }
-
- return prints( apBuf, s );
-}
-#endif /* SPRINTF_LONG_LONG */
-/*-----------------------------------------------------------*/
-
-static BaseType_t printi( struct SStringBuf *apBuf, int i )
-{
- char print_buf[ PRINT_BUF_LEN ];
- register char *s;
- register int t, neg = 0;
- register unsigned int u = i;
- register unsigned base = apBuf->flags.base;
-
- apBuf->flags.isNumber = pdTRUE; /* Parameter for prints */
-
- if( i == 0 )
- {
- print_buf[ 0 ] = '0';
- print_buf[ 1 ] = '\0';
- return prints( apBuf, print_buf );
- }
-
- if( ( apBuf->flags.isSigned == pdTRUE ) && ( base == 10 ) && ( i < 0 ) )
- {
- neg = 1;
- u = -i;
- }
-
- s = print_buf + sizeof( print_buf ) - 1;
-
- *s = '\0';
- switch( base )
- {
- case 16:
- while( u != 0 )
- {
- t = u & 0xF;
- if( t >= 10 )
- {
- t += apBuf->flags.letBase - '0' - 10;
- }
- *( --s ) = t + '0';
- u >>= 4;
- }
- break;
-
- case 8:
- case 10:
- /* GCC compiles very efficient */
- while( u )
- {
- t = u % base;
- *( --s ) = t + '0';
- u /= base;
- }
- break;
-/*
- // The generic case, not yet in use
- default:
- while( u )
- {
- t = u % base;
- if( t >= 10)
- {
- t += apBuf->flags.letBase - '0' - 10;
- }
- *( --s ) = t + '0';
- u /= base;
- }
- break;
-*/
- }
-
- if( neg != 0 )
- {
- if( apBuf->flags.width && (apBuf->flags.pad & PAD_ZERO ) )
- {
- if( strbuf_printchar( apBuf, '-' ) == 0 )
- {
- return pdFALSE;
- }
- --apBuf->flags.width;
- }
- else
- {
- *( --s ) = '-';
- }
- }
-
- return prints( apBuf, s );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t printIp(struct SStringBuf *apBuf, unsigned i )
-{
- char print_buf[16];
-
- sprintf( print_buf, "%u.%u.%u.%u",
- i >> 24,
- ( i >> 16 ) & 0xff,
- ( i >> 8 ) & 0xff,
- i & 0xff );
- apBuf->flags.isNumber = pdTRUE; /* Parameter for prints */
- prints( apBuf, print_buf );
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static void tiny_print( struct SStringBuf *apBuf, const char *format, va_list args )
-{
- char scr[2];
-
- for( ; ; )
- {
- int ch = *( format++ );
-
- if( ch != '%' )
- {
- do
- {
- /* Put the most like flow in a small loop */
- if( strbuf_printchar_inline( apBuf, ch ) == 0 )
- {
- return;
- }
- ch = *( format++ );
- } while( ch != '%' );
- }
- ch = *( format++ );
- /* Now ch has character after '%', format pointing to next */
-
- if( ch == '\0' )
- {
- break;
- }
- if( ch == '%' )
- {
- if( strbuf_printchar( apBuf, ch ) == 0 )
- {
- return;
- }
- continue;
- }
- memset( &apBuf->flags, '\0', sizeof( apBuf->flags ) );
-
- if( ch == '-' )
- {
- ch = *( format++ );
- apBuf->flags.pad = PAD_RIGHT;
- }
- while( ch == '0' )
- {
- ch = *( format++ );
- apBuf->flags.pad |= PAD_ZERO;
- }
- if( ch == '*' )
- {
- ch = *( format++ );
- apBuf->flags.width = va_arg( args, int );
- }
- else
- {
- while( ch >= '0' && ch <= '9' )
- {
- apBuf->flags.width *= 10;
- apBuf->flags.width += ch - '0';
- ch = *( format++ );
- }
- }
- if( ch == '.' )
- {
- ch = *( format++ );
- if( ch == '*' )
- {
- apBuf->flags.printLimit = va_arg( args, int );
- ch = *( format++ );
- }
- else
- {
- while( ch >= '0' && ch <= '9' )
- {
- apBuf->flags.printLimit *= 10;
- apBuf->flags.printLimit += ch - '0';
- ch = *( format++ );
- }
- }
- }
- if( apBuf->flags.printLimit == 0 )
- {
- apBuf->flags.printLimit--; /* -1: make it unlimited */
- }
- if( ch == 's' )
- {
- register char *s = ( char * )va_arg( args, int );
- if( prints( apBuf, s ? s : "(null)" ) == 0 )
- {
- break;
- }
- continue;
- }
- if( ch == 'c' )
- {
- /* char are converted to int then pushed on the stack */
- scr[0] = ( char ) va_arg( args, int );
-
- if( strbuf_printchar( apBuf, scr[0] ) == 0 )
- {
- return;
- }
-
- continue;
- }
- if( ch == 'l' )
- {
- ch = *( format++ );
- apBuf->flags.long32 = 1;
- /* Makes not difference as u32 == long */
- }
- if( ch == 'L' )
- {
- ch = *( format++ );
- apBuf->flags.long64 = 1;
- /* Does make a difference */
- }
- apBuf->flags.base = 10;
- apBuf->flags.letBase = 'a';
-
- if( ch == 'd' || ch == 'u' )
- {
- apBuf->flags.isSigned = ( ch == 'd' );
-#if SPRINTF_LONG_LONG
- if( apBuf->flags.long64 != pdFALSE )
- {
- if( printll( apBuf, va_arg( args, long long ) ) == 0 )
- {
- break;
- }
- } else
-#endif /* SPRINTF_LONG_LONG */
- if( printi( apBuf, va_arg( args, int ) ) == 0 )
- {
- break;
- }
- continue;
- }
-
- apBuf->flags.base = 16; /* From here all hexadecimal */
-
- if( ch == 'x' && format[0] == 'i' && format[1] == 'p' )
- {
- format += 2; /* eat the "xi" of "xip" */
- /* Will use base 10 again */
- if( printIp( apBuf, va_arg( args, int ) ) == 0 )
- {
- break;
- }
- continue;
- }
- if( ch == 'x' || ch == 'X' || ch == 'p' || ch == 'o' )
- {
- if( ch == 'X' )
- {
- apBuf->flags.letBase = 'A';
- }
- else if( ch == 'o' )
- {
- apBuf->flags.base = 8;
- }
-#if SPRINTF_LONG_LONG
- if( apBuf->flags.long64 != pdFALSE )
- {
- if( printll( apBuf, va_arg( args, long long ) ) == 0 )
- {
- break;
- }
- } else
-#endif /* SPRINTF_LONG_LONG */
- if( printi( apBuf, va_arg( args, int ) ) == 0 )
- {
- break;
- }
- continue;
- }
- }
- strbuf_printchar( apBuf, '\0' );
-}
-/*-----------------------------------------------------------*/
-
-int vsnprintf( char *apBuf, size_t aMaxLen, const char *apFmt, va_list args )
-{
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char* )apBuf + aMaxLen );
- tiny_print( &strBuf, apFmt, args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-int snprintf( char *apBuf, size_t aMaxLen, const char *apFmt, ... )
-{
- va_list args;
-
- va_start( args, apFmt );
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char* )apBuf + aMaxLen );
- tiny_print( &strBuf, apFmt, args );
- va_end( args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-int sprintf( char *apBuf, const char *apFmt, ... )
-{
- va_list args;
-
- va_start( args, apFmt );
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char * )apBuf + 1024 );
- tiny_print( &strBuf, apFmt, args );
- va_end( args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-int vsprintf( char *apBuf, const char *apFmt, va_list args )
-{
- struct SStringBuf strBuf;
- strbuf_init( &strBuf, apBuf, ( const char* ) apBuf + 1024 );
- tiny_print( &strBuf, apFmt, args );
-
- return strBuf.curLen;
-}
-/*-----------------------------------------------------------*/
-
-const char *mkSize (unsigned long long aSize, char *apBuf, int aLen)
-{
-static char retString[33];
-size_t gb, mb, kb, sb;
-
- if (apBuf == NULL) {
- apBuf = retString;
- aLen = sizeof( retString );
- }
- gb = aSize / (1024*1024*1024);
- aSize -= gb * (1024*1024*1024);
- mb = aSize / (1024*1024);
- aSize -= mb * (1024*1024);
- kb = aSize / (1024);
- aSize -= kb * (1024);
- sb = aSize;
- if( gb )
- {
- snprintf (apBuf, aLen, "%u.%02u GB", ( unsigned ) gb, ( unsigned ) ( ( 100 * mb ) / 1024ul ) );
- }
- else if( mb )
- {
- snprintf (apBuf, aLen, "%u.%02u MB", ( unsigned ) mb, ( unsigned ) ( ( 100 * kb) / 1024ul ) );
- }
- else if( kb != 0ul )
- {
- snprintf (apBuf, aLen, "%u.%02u KB", ( unsigned ) kb, ( unsigned ) ( ( 100 * sb) / 1024ul ) );
- }
- else
- {
- snprintf (apBuf, aLen, "%u bytes", ( unsigned ) sb);
- }
- return apBuf;
-}
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/task_pool_demo.sln b/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/task_pool_demo.sln
deleted file mode 100644
index b362f36c5..000000000
--- a/FreeRTOS-Plus/Demo/FreeRTOS_IoT_Libraries/task_pool/task_pool_demo.sln
+++ /dev/null
@@ -1,23 +0,0 @@
-
-Microsoft Visual Studio Solution File, Format Version 11.00
-# Visual Studio 2010
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "RTOSDemo", "WIN32.vcxproj", "{C686325E-3261-42F7-AEB1-DDE5280E1CEB}"
-EndProject
-Global
- GlobalSection(TestCaseManagementSettings) = postSolution
- CategoryFile = FreeRTOS_Plus_TCP_Minimal.vsmdi
- EndGlobalSection
- GlobalSection(SolutionConfigurationPlatforms) = preSolution
- Debug|Win32 = Debug|Win32
- Release|Win32 = Release|Win32
- EndGlobalSection
- GlobalSection(ProjectConfigurationPlatforms) = postSolution
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.ActiveCfg = Debug|Win32
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Debug|Win32.Build.0 = Debug|Win32
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.ActiveCfg = Release|Win32
- {C686325E-3261-42F7-AEB1-DDE5280E1CEB}.Release|Win32.Build.0 = Release|Win32
- EndGlobalSection
- GlobalSection(SolutionProperties) = preSolution
- HideSolutionNode = FALSE
- EndGlobalSection
-EndGlobal
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c
index 5f4fa3da6..0a0774b1d 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOSConfig.h
index f73e0f352..c0670fe87 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOSConfig.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/FreeRTOSConfig.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c
index 37204d126..ea340418c 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/Run-time-stats-utils.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c
index d155d87a7..6cd24037f 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/UDPCommandServer.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c
index a8e293dce..d02c44aa0 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_CLI_with_Trace_Windows_Simulator/main.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h
index 347140a11..2ff605a6f 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/ConfigurationFiles/FreeRTOSConfig.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c
index 523fc8bad..a2702090e 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-Related-CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c
index 04a8a656e..420a39f75 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/File-system-demo.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c
index 72ed5a425..b87d8c79c 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Run-time-stats-utils.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c
index 42e7cc43c..f36a93f92 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/Sample-CLI-commands.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c
index 565982363..bd7079965 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/UDPCommandServer.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c
index f5bf1673a..182afeac1 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_Reliance_Edge_and_CLI_Windows_Simulator/main.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c
index 54143c367..3bd55b372 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/SimpleUDPClientAndServer.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c
index e89d369dc..c4f8eb146 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/TCPEchoClient_SingleTasks.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h
index 342ab123a..d178d2c2d 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/SimpleUDPClientAndServer.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h
index 0f4676f47..864a3a10f 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/DemoTasks/include/TCPEchoClient_SingleTasks.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h
index 7fdff102b..2ea535408 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSConfig.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSIPConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSIPConfig.h
index 4aa549e8c..9adb448e9 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSIPConfig.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/FreeRTOSIPConfig.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/arch.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/arch.c
index d704da800..ea1c431c0 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/arch.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/arch.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/netif.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/netif.h
index 8fe539376..6a93bea2c 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/netif.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/WinPCap/netif.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.c
index d6a1d2577..61d6f2039 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.h
index 62ae46a52..ad6886b17 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/demo_logging.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c
index fae30bd74..9641e0624 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_TCP_Minimal_Windows_Simulator/main.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOSConfig.h b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOSConfig.h
index e031afb8e..c0898511d 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOSConfig.h
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/FreeRTOSConfig.h
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c
index ad8d22cc4..727a805d0 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPClientTask.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c
index ba678b98c..8667ac2e0 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/SecureTCPServerTask.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c
index 05587047e..08616dc11 100644
--- a/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c
+++ b/FreeRTOS-Plus/Demo/FreeRTOS_Plus_WolfSSL_Windows_Simulator/main.c
@@ -1,5 +1,5 @@
/*
- * FreeRTOS Kernel V10.2.1
+ * FreeRTOS Kernel V10.3.0
* Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
index c98a7e870..7d8ed18c6 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_ARP.c
@@ -1,675 +1,675 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_ARP.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_DHCP.h"
-#if( ipconfigUSE_LLMNR == 1 )
- #include "FreeRTOS_DNS.h"
-#endif /* ipconfigUSE_LLMNR */
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-
-/* When the age of an entry in the ARP table reaches this value (it counts down
-to zero, so this is an old entry) an ARP request will be sent to see if the
-entry is still valid and can therefore be refreshed. */
-#define arpMAX_ARP_AGE_BEFORE_NEW_ARP_REQUEST ( 3 )
-
-/* The time between gratuitous ARPs. */
-#ifndef arpGRATUITOUS_ARP_PERIOD
- #define arpGRATUITOUS_ARP_PERIOD ( pdMS_TO_TICKS( 20000 ) )
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Lookup an MAC address in the ARP cache from the IP address.
- */
-static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup, MACAddress_t * const pxMACAddress );
-
-/*-----------------------------------------------------------*/
-
-/* The ARP cache. */
-static ARPCacheRow_t xARPCache[ ipconfigARP_CACHE_ENTRIES ];
-
-/* The time at which the last gratuitous ARP was sent. Gratuitous ARPs are used
-to ensure ARP tables are up to date and to detect IP address conflicts. */
-static TickType_t xLastGratuitousARPTime = ( TickType_t ) 0;
-
-/*
- * IP-clash detection is currently only used internally. When DHCP doesn't respond, the
- * driver can try out a random LinkLayer IP address (169.254.x.x). It will send out a
- * gratuitos ARP message and, after a period of time, check the variables here below:
- */
-#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
- /* Becomes non-zero if another device responded to a gratuitos ARP message. */
- BaseType_t xARPHadIPClash;
- /* MAC-address of the other device containing the same IP-address. */
- MACAddress_t xARPClashMacAddress;
-#endif /* ipconfigARP_USE_CLASH_DETECTION */
-
-/* Part of the Ethernet and ARP headers are always constant when sending an IPv4
-ARP packet. This array defines the constant parts, allowing this part of the
-packet to be filled in using a simple memcpy() instead of individual writes. */
-static const uint8_t xDefaultPartARPPacketHeader[] =
-{
- 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Ethernet destination address. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Ethernet source address. */
- 0x08, 0x06, /* Ethernet frame type (ipARP_FRAME_TYPE). */
- 0x00, 0x01, /* usHardwareType (ipARP_HARDWARE_TYPE_ETHERNET). */
- 0x08, 0x00, /* usProtocolType. */
- ipMAC_ADDRESS_LENGTH_BYTES, /* ucHardwareAddressLength. */
- ipIP_ADDRESS_LENGTH_BYTES, /* ucProtocolAddressLength. */
- 0x00, 0x01, /* usOperation (ipARP_REQUEST). */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* xSenderHardwareAddress. */
- 0x00, 0x00, 0x00, 0x00, /* ulSenderProtocolAddress. */
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* xTargetHardwareAddress. */
-};
-
-/*-----------------------------------------------------------*/
-
-eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
-{
-eFrameProcessingResult_t eReturn = eReleaseBuffer;
-ARPHeader_t *pxARPHeader;
-uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress;
-
- pxARPHeader = &( pxARPFrame->xARPHeader );
-
- /* The field ulSenderProtocolAddress is badly aligned, copy byte-by-byte. */
- memcpy( ( void *)&( ulSenderProtocolAddress ), ( void * )pxARPHeader->ucSenderProtocolAddress, sizeof( ulSenderProtocolAddress ) );
- /* The field ulTargetProtocolAddress is well-aligned, a 32-bits copy. */
- ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress;
-
- traceARP_PACKET_RECEIVED();
-
- /* Don't do anything if the local IP address is zero because
- that means a DHCP request has not completed. */
- if( *ipLOCAL_IP_ADDRESS_POINTER != 0UL )
- {
- switch( pxARPHeader->usOperation )
- {
- case ipARP_REQUEST :
- /* The packet contained an ARP request. Was it for the IP
- address of the node running this code? */
- if( ulTargetProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER )
- {
- iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress );
-
- /* The request is for the address of this node. Add the
- entry into the ARP cache, or refresh the entry if it
- already exists. */
- vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
-
- /* Generate a reply payload in the same buffer. */
- pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY;
- if( ulTargetProtocolAddress == ulSenderProtocolAddress )
- {
- /* A double IP address is detected! */
- /* Give the sources MAC address the value of the broadcast address, will be swapped later */
- memcpy( pxARPFrame->xEthernetHeader.xSourceAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( xBroadcastMACAddress ) );
- memset( pxARPHeader->xTargetHardwareAddress.ucBytes, '\0', sizeof( MACAddress_t ) );
- pxARPHeader->ulTargetProtocolAddress = 0UL;
- }
- else
- {
- memcpy( pxARPHeader->xTargetHardwareAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( MACAddress_t ) );
- pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress;
- }
- memcpy( pxARPHeader->xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
- memcpy( ( void* )pxARPHeader->ucSenderProtocolAddress, ( void* )ipLOCAL_IP_ADDRESS_POINTER, sizeof( pxARPHeader->ucSenderProtocolAddress ) );
-
- eReturn = eReturnEthernetFrame;
- }
- break;
-
- case ipARP_REPLY :
- iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress );
- vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
- /* Process received ARP frame to see if there is a clash. */
- #if( ipconfigARP_USE_CLASH_DETECTION != 0 )
- {
- if( ulSenderProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER )
- {
- xARPHadIPClash = pdTRUE;
- memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) );
- }
- }
- #endif /* ipconfigARP_USE_CLASH_DETECTION */
- break;
-
- default :
- /* Invalid. */
- break;
- }
- }
-
- return eReturn;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
-
- uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress )
- {
- BaseType_t x;
- uint32_t lResult = 0;
-
- /* For each entry in the ARP cache table. */
- for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
- {
- if( ( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 ) )
- {
- lResult = xARPCache[ x ].ulIPAddress;
- memset( &xARPCache[ x ], '\0', sizeof( xARPCache[ x ] ) );
- break;
- }
- }
-
- return lResult;
- }
-
-#endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
-/*-----------------------------------------------------------*/
-
-void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress )
-{
-BaseType_t x = 0;
-BaseType_t xIpEntry = -1;
-BaseType_t xMacEntry = -1;
-BaseType_t xUseEntry = 0;
-uint8_t ucMinAgeFound = 0U;
-
- #if( ipconfigARP_STORES_REMOTE_ADDRESSES == 0 )
- /* Only process the IP address if it is on the local network.
- Unless: when '*ipLOCAL_IP_ADDRESS_POINTER' equals zero, the IP-address
- and netmask are still unknown. */
- if( ( ( ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) ) ||
- ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ) )
- #else
- /* If ipconfigARP_STORES_REMOTE_ADDRESSES is non-zero, IP addresses with
- a different netmask will also be stored. After when replying to a UDP
- message from a different netmask, the IP address can be looped up and a
- reply sent. This option is useful for systems with multiple gateways,
- the reply will surely arrive. If ipconfigARP_STORES_REMOTE_ADDRESSES is
- zero the the gateway address is the only option. */
- if( pdTRUE )
- #endif
- {
- /* Start with the maximum possible number. */
- ucMinAgeFound--;
-
- /* For each entry in the ARP cache table. */
- for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
- {
- /* Does this line in the cache table hold an entry for the IP
- address being queried? */
- if( xARPCache[ x ].ulIPAddress == ulIPAddress )
- {
- if( pxMACAddress == NULL )
- {
- /* In case the parameter pxMACAddress is NULL, an entry will be reserved to
- indicate that there is an outstanding ARP request, This entry will have
- "ucValid == pdFALSE". */
- xIpEntry = x;
- break;
- }
-
- /* See if the MAC-address also matches. */
- if( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 )
- {
- /* This function will be called for each received packet
- As this is by far the most common path the coding standard
- is relaxed in this case and a return is permitted as an
- optimisation. */
- xARPCache[ x ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
- xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
- return;
- }
-
- /* Found an entry containing ulIPAddress, but the MAC address
- doesn't match. Might be an entry with ucValid=pdFALSE, waiting
- for an ARP reply. Still want to see if there is match with the
- given MAC address.ucBytes. If found, either of the two entries
- must be cleared. */
- xIpEntry = x;
- }
- else if( ( pxMACAddress != NULL ) && ( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 ) )
- {
- /* Found an entry with the given MAC-address, but the IP-address
- is different. Continue looping to find a possible match with
- ulIPAddress. */
- #if( ipconfigARP_STORES_REMOTE_ADDRESSES != 0 )
- /* If ARP stores the MAC address of IP addresses outside the
- network, than the MAC address of the gateway should not be
- overwritten. */
- BaseType_t bIsLocal[ 2 ];
- bIsLocal[ 0 ] = ( ( xARPCache[ x ].ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) );
- bIsLocal[ 1 ] = ( ( ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) );
- if( bIsLocal[ 0 ] == bIsLocal[ 1 ] )
- {
- xMacEntry = x;
- }
- #else
- xMacEntry = x;
- #endif
- }
- /* _HT_
- Shouldn't we test for xARPCache[ x ].ucValid == pdFALSE here ? */
- else if( xARPCache[ x ].ucAge < ucMinAgeFound )
- {
- /* As the table is traversed, remember the table row that
- contains the oldest entry (the lowest age count, as ages are
- decremented to zero) so the row can be re-used if this function
- needs to add an entry that does not already exist. */
- ucMinAgeFound = xARPCache[ x ].ucAge;
- xUseEntry = x;
- }
- }
-
- if( xMacEntry >= 0 )
- {
- xUseEntry = xMacEntry;
-
- if( xIpEntry >= 0 )
- {
- /* Both the MAC address as well as the IP address were found in
- different locations: clear the entry which matches the
- IP-address */
- memset( &xARPCache[ xIpEntry ], '\0', sizeof( xARPCache[ xIpEntry ] ) );
- }
- }
- else if( xIpEntry >= 0 )
- {
- /* An entry containing the IP-address was found, but it had a different MAC address */
- xUseEntry = xIpEntry;
- }
-
- /* If the entry was not found, we use the oldest entry and set the IPaddress */
- xARPCache[ xUseEntry ].ulIPAddress = ulIPAddress;
-
- if( pxMACAddress != NULL )
- {
- memcpy( xARPCache[ xUseEntry ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) );
-
- iptraceARP_TABLE_ENTRY_CREATED( ulIPAddress, (*pxMACAddress) );
- /* And this entry does not need immediate attention */
- xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
- xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdTRUE;
- }
- else if( xIpEntry < 0 )
- {
- xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_RETRANSMISSIONS;
- xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdFALSE;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_ARP_REVERSED_LOOKUP == 1 )
- eARPLookupResult_t eARPGetCacheEntryByMac( MACAddress_t * const pxMACAddress, uint32_t *pulIPAddress )
- {
- BaseType_t x;
- eARPLookupResult_t eReturn = eARPCacheMiss;
-
- /* Loop through each entry in the ARP cache. */
- for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
- {
- /* Does this row in the ARP cache table hold an entry for the MAC
- address being searched? */
- if( memcmp( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
- {
- *pulIPAddress = xARPCache[ x ].ulIPAddress;
- eReturn = eARPCacheHit;
- break;
- }
- }
-
- return eReturn;
- }
-#endif /* ipconfigUSE_ARP_REVERSED_LOOKUP */
-
-/*-----------------------------------------------------------*/
-
-eARPLookupResult_t eARPGetCacheEntry( uint32_t *pulIPAddress, MACAddress_t * const pxMACAddress )
-{
-eARPLookupResult_t eReturn;
-uint32_t ulAddressToLookup;
-
-#if( ipconfigUSE_LLMNR == 1 )
- if( *pulIPAddress == ipLLMNR_IP_ADDR ) /* Is in network byte order. */
- {
- /* The LLMNR IP-address has a fixed virtual MAC address. */
- memcpy( pxMACAddress->ucBytes, xLLMNR_MacAdress.ucBytes, sizeof( MACAddress_t ) );
- eReturn = eARPCacheHit;
- }
- else
-#endif
- if( ( *pulIPAddress == ipBROADCAST_IP_ADDRESS ) || /* Is it the general broadcast address 255.255.255.255? */
- ( *pulIPAddress == xNetworkAddressing.ulBroadcastAddress ) )/* Or a local broadcast address, eg 192.168.1.255? */
- {
- /* This is a broadcast so uses the broadcast MAC address. */
- memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );
- eReturn = eARPCacheHit;
- }
- else if( *ipLOCAL_IP_ADDRESS_POINTER == 0UL )
- {
- /* The IP address has not yet been assigned, so there is nothing that
- can be done. */
- eReturn = eCantSendPacket;
- }
- else
- {
- eReturn = eARPCacheMiss;
-
- if( ( *pulIPAddress & xNetworkAddressing.ulNetMask ) != ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) )
- {
-#if( ipconfigARP_STORES_REMOTE_ADDRESSES == 1 )
- eReturn = prvCacheLookup( *pulIPAddress, pxMACAddress );
-
- if( eReturn == eARPCacheHit )
- {
- /* The stack is configured to store 'remote IP addresses', i.e. addresses
- belonging to a different the netmask. prvCacheLookup() returned a hit, so
- the MAC address is known */
- }
- else
-#endif
- {
- /* The IP address is off the local network, so look up the
- hardware address of the router, if any. */
- if( xNetworkAddressing.ulGatewayAddress != ( uint32_t )0u )
- {
- ulAddressToLookup = xNetworkAddressing.ulGatewayAddress;
- }
- else
- {
- ulAddressToLookup = *pulIPAddress;
- }
- }
- }
- else
- {
- /* The IP address is on the local network, so lookup the requested
- IP address directly. */
- ulAddressToLookup = *pulIPAddress;
- }
-
- if( eReturn == eARPCacheMiss )
- {
- if( ulAddressToLookup == 0UL )
- {
- /* The address is not on the local network, and there is not a
- router. */
- eReturn = eCantSendPacket;
- }
- else
- {
- eReturn = prvCacheLookup( ulAddressToLookup, pxMACAddress );
-
- if( eReturn == eARPCacheMiss )
- {
- /* It might be that the ARP has to go to the gateway. */
- *pulIPAddress = ulAddressToLookup;
- }
- }
- }
- }
-
- return eReturn;
-}
-
-/*-----------------------------------------------------------*/
-
-static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup, MACAddress_t * const pxMACAddress )
-{
-BaseType_t x;
-eARPLookupResult_t eReturn = eARPCacheMiss;
-
- /* Loop through each entry in the ARP cache. */
- for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
- {
- /* Does this row in the ARP cache table hold an entry for the IP address
- being queried? */
- if( xARPCache[ x ].ulIPAddress == ulAddressToLookup )
- {
- /* A matching valid entry was found. */
- if( xARPCache[ x ].ucValid == ( uint8_t ) pdFALSE )
- {
- /* This entry is waiting an ARP reply, so is not valid. */
- eReturn = eCantSendPacket;
- }
- else
- {
- /* A valid entry was found. */
- memcpy( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
- eReturn = eARPCacheHit;
- }
- break;
- }
- }
-
- return eReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vARPAgeCache( void )
-{
-BaseType_t x;
-TickType_t xTimeNow;
-
- /* Loop through each entry in the ARP cache. */
- for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
- {
- /* If the entry is valid (its age is greater than zero). */
- if( xARPCache[ x ].ucAge > 0U )
- {
- /* Decrement the age value of the entry in this ARP cache table row.
- When the age reaches zero it is no longer considered valid. */
- ( xARPCache[ x ].ucAge )--;
-
- /* If the entry is not yet valid, then it is waiting an ARP
- reply, and the ARP request should be retransmitted. */
- if( xARPCache[ x ].ucValid == ( uint8_t ) pdFALSE )
- {
- FreeRTOS_OutputARPRequest( xARPCache[ x ].ulIPAddress );
- }
- else if( xARPCache[ x ].ucAge <= ( uint8_t ) arpMAX_ARP_AGE_BEFORE_NEW_ARP_REQUEST )
- {
- /* This entry will get removed soon. See if the MAC address is
- still valid to prevent this happening. */
- iptraceARP_TABLE_ENTRY_WILL_EXPIRE( xARPCache[ x ].ulIPAddress );
- FreeRTOS_OutputARPRequest( xARPCache[ x ].ulIPAddress );
- }
- else
- {
- /* The age has just ticked down, with nothing to do. */
- }
-
- if( xARPCache[ x ].ucAge == 0u )
- {
- /* The entry is no longer valid. Wipe it out. */
- iptraceARP_TABLE_ENTRY_EXPIRED( xARPCache[ x ].ulIPAddress );
- xARPCache[ x ].ulIPAddress = 0UL;
- }
- }
- }
-
- xTimeNow = xTaskGetTickCount ();
-
- if( ( xLastGratuitousARPTime == ( TickType_t ) 0 ) || ( ( xTimeNow - xLastGratuitousARPTime ) > ( TickType_t ) arpGRATUITOUS_ARP_PERIOD ) )
- {
- FreeRTOS_OutputARPRequest( *ipLOCAL_IP_ADDRESS_POINTER );
- xLastGratuitousARPTime = xTimeNow;
- }
-}
-/*-----------------------------------------------------------*/
-
-void vARPSendGratuitous( void )
-{
- /* Setting xLastGratuitousARPTime to 0 will force a gratuitous ARP the next
- time vARPAgeCache() is called. */
- xLastGratuitousARPTime = ( TickType_t ) 0;
-
- /* Let the IP-task call vARPAgeCache(). */
- xSendEventToIPTask( eARPTimerEvent );
-}
-
-/*-----------------------------------------------------------*/
-void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-
- /* This is called from the context of the IP event task, so a block time
- must not be used. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( ARPPacket_t ), ( TickType_t ) 0 );
-
- if( pxNetworkBuffer != NULL )
- {
- pxNetworkBuffer->ulIPAddress = ulIPAddress;
- vARPGenerateRequestPacket( pxNetworkBuffer );
-
- #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- BaseType_t xIndex;
-
- for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
- {
- pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
- }
- pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
- }
- }
- #endif
- if( xIsCallingFromIPTask() != 0 )
- {
- /* Only the IP-task is allowed to call this function directly. */
- xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
- }
- else
- {
- IPStackEvent_t xSendEvent;
-
- /* Send a message to the IP-task to send this ARP packet. */
- xSendEvent.eEventType = eNetworkTxEvent;
- xSendEvent.pvData = ( void * ) pxNetworkBuffer;
- if( xSendEventStructToIPTask( &xSendEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
- {
- /* Failed to send the message, so release the network buffer. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- }
- }
-}
-
-void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-ARPPacket_t *pxARPPacket;
-
- /* Buffer allocation ensures that buffers always have space
- for an ARP packet. See buffer allocation implementations 1
- and 2 under portable/BufferManagement. */
- configASSERT( pxNetworkBuffer );
- configASSERT( pxNetworkBuffer->xDataLength >= sizeof(ARPPacket_t) );
-
- pxARPPacket = ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
-
- /* memcpy the const part of the header information into the correct
- location in the packet. This copies:
- xEthernetHeader.ulDestinationAddress
- xEthernetHeader.usFrameType;
- xARPHeader.usHardwareType;
- xARPHeader.usProtocolType;
- xARPHeader.ucHardwareAddressLength;
- xARPHeader.ucProtocolAddressLength;
- xARPHeader.usOperation;
- xARPHeader.xTargetHardwareAddress;
- */
- memcpy( ( void * ) pxARPPacket, ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
- memcpy( ( void * ) pxARPPacket->xEthernetHeader.xSourceAddress.ucBytes , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
- memcpy( ( void * ) pxARPPacket->xARPHeader.xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
-
- memcpy( ( void* )pxARPPacket->xARPHeader.ucSenderProtocolAddress, ( void* )ipLOCAL_IP_ADDRESS_POINTER, sizeof( pxARPPacket->xARPHeader.ucSenderProtocolAddress ) );
- pxARPPacket->xARPHeader.ulTargetProtocolAddress = pxNetworkBuffer->ulIPAddress;
-
- pxNetworkBuffer->xDataLength = sizeof( ARPPacket_t );
-
- iptraceCREATING_ARP_REQUEST( pxNetworkBuffer->ulIPAddress );
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_ClearARP( void )
-{
- memset( xARPCache, '\0', sizeof( xARPCache ) );
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigHAS_PRINTF != 0 ) || ( ipconfigHAS_DEBUG_PRINTF != 0 )
-
- void FreeRTOS_PrintARPCache( void )
- {
- BaseType_t x, xCount = 0;
-
- /* Loop through each entry in the ARP cache. */
- for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
- {
- if( ( xARPCache[ x ].ulIPAddress != 0ul ) && ( xARPCache[ x ].ucAge > 0U ) )
- {
- /* See if the MAC-address also matches, and we're all happy */
- FreeRTOS_printf( ( "Arp %2ld: %3u - %16lxip : %02x:%02x:%02x : %02x:%02x:%02x\n",
- x,
- xARPCache[ x ].ucAge,
- xARPCache[ x ].ulIPAddress,
- xARPCache[ x ].xMACAddress.ucBytes[0],
- xARPCache[ x ].xMACAddress.ucBytes[1],
- xARPCache[ x ].xMACAddress.ucBytes[2],
- xARPCache[ x ].xMACAddress.ucBytes[3],
- xARPCache[ x ].xMACAddress.ucBytes[4],
- xARPCache[ x ].xMACAddress.ucBytes[5] ) );
- xCount++;
- }
- }
-
- FreeRTOS_printf( ( "Arp has %ld entries\n", xCount ) );
- }
-
-#endif /* ( ipconfigHAS_PRINTF != 0 ) || ( ipconfigHAS_DEBUG_PRINTF != 0 ) */
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_ARP.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_DHCP.h"
+#if( ipconfigUSE_LLMNR == 1 )
+ #include "FreeRTOS_DNS.h"
+#endif /* ipconfigUSE_LLMNR */
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+
+/* When the age of an entry in the ARP table reaches this value (it counts down
+to zero, so this is an old entry) an ARP request will be sent to see if the
+entry is still valid and can therefore be refreshed. */
+#define arpMAX_ARP_AGE_BEFORE_NEW_ARP_REQUEST ( 3 )
+
+/* The time between gratuitous ARPs. */
+#ifndef arpGRATUITOUS_ARP_PERIOD
+ #define arpGRATUITOUS_ARP_PERIOD ( pdMS_TO_TICKS( 20000 ) )
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Lookup an MAC address in the ARP cache from the IP address.
+ */
+static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup, MACAddress_t * const pxMACAddress );
+
+/*-----------------------------------------------------------*/
+
+/* The ARP cache. */
+static ARPCacheRow_t xARPCache[ ipconfigARP_CACHE_ENTRIES ];
+
+/* The time at which the last gratuitous ARP was sent. Gratuitous ARPs are used
+to ensure ARP tables are up to date and to detect IP address conflicts. */
+static TickType_t xLastGratuitousARPTime = ( TickType_t ) 0;
+
+/*
+ * IP-clash detection is currently only used internally. When DHCP doesn't respond, the
+ * driver can try out a random LinkLayer IP address (169.254.x.x). It will send out a
+ * gratuitos ARP message and, after a period of time, check the variables here below:
+ */
+#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
+ /* Becomes non-zero if another device responded to a gratuitos ARP message. */
+ BaseType_t xARPHadIPClash;
+ /* MAC-address of the other device containing the same IP-address. */
+ MACAddress_t xARPClashMacAddress;
+#endif /* ipconfigARP_USE_CLASH_DETECTION */
+
+/* Part of the Ethernet and ARP headers are always constant when sending an IPv4
+ARP packet. This array defines the constant parts, allowing this part of the
+packet to be filled in using a simple memcpy() instead of individual writes. */
+static const uint8_t xDefaultPartARPPacketHeader[] =
+{
+ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, /* Ethernet destination address. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Ethernet source address. */
+ 0x08, 0x06, /* Ethernet frame type (ipARP_FRAME_TYPE). */
+ 0x00, 0x01, /* usHardwareType (ipARP_HARDWARE_TYPE_ETHERNET). */
+ 0x08, 0x00, /* usProtocolType. */
+ ipMAC_ADDRESS_LENGTH_BYTES, /* ucHardwareAddressLength. */
+ ipIP_ADDRESS_LENGTH_BYTES, /* ucProtocolAddressLength. */
+ 0x00, 0x01, /* usOperation (ipARP_REQUEST). */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* xSenderHardwareAddress. */
+ 0x00, 0x00, 0x00, 0x00, /* ulSenderProtocolAddress. */
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 /* xTargetHardwareAddress. */
+};
+
+/*-----------------------------------------------------------*/
+
+eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame )
+{
+eFrameProcessingResult_t eReturn = eReleaseBuffer;
+ARPHeader_t *pxARPHeader;
+uint32_t ulTargetProtocolAddress, ulSenderProtocolAddress;
+
+ pxARPHeader = &( pxARPFrame->xARPHeader );
+
+ /* The field ulSenderProtocolAddress is badly aligned, copy byte-by-byte. */
+ memcpy( ( void *)&( ulSenderProtocolAddress ), ( void * )pxARPHeader->ucSenderProtocolAddress, sizeof( ulSenderProtocolAddress ) );
+ /* The field ulTargetProtocolAddress is well-aligned, a 32-bits copy. */
+ ulTargetProtocolAddress = pxARPHeader->ulTargetProtocolAddress;
+
+ traceARP_PACKET_RECEIVED();
+
+ /* Don't do anything if the local IP address is zero because
+ that means a DHCP request has not completed. */
+ if( *ipLOCAL_IP_ADDRESS_POINTER != 0UL )
+ {
+ switch( pxARPHeader->usOperation )
+ {
+ case ipARP_REQUEST :
+ /* The packet contained an ARP request. Was it for the IP
+ address of the node running this code? */
+ if( ulTargetProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER )
+ {
+ iptraceSENDING_ARP_REPLY( ulSenderProtocolAddress );
+
+ /* The request is for the address of this node. Add the
+ entry into the ARP cache, or refresh the entry if it
+ already exists. */
+ vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
+
+ /* Generate a reply payload in the same buffer. */
+ pxARPHeader->usOperation = ( uint16_t ) ipARP_REPLY;
+ if( ulTargetProtocolAddress == ulSenderProtocolAddress )
+ {
+ /* A double IP address is detected! */
+ /* Give the sources MAC address the value of the broadcast address, will be swapped later */
+ memcpy( pxARPFrame->xEthernetHeader.xSourceAddress.ucBytes, xBroadcastMACAddress.ucBytes, sizeof( xBroadcastMACAddress ) );
+ memset( pxARPHeader->xTargetHardwareAddress.ucBytes, '\0', sizeof( MACAddress_t ) );
+ pxARPHeader->ulTargetProtocolAddress = 0UL;
+ }
+ else
+ {
+ memcpy( pxARPHeader->xTargetHardwareAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( MACAddress_t ) );
+ pxARPHeader->ulTargetProtocolAddress = ulSenderProtocolAddress;
+ }
+ memcpy( pxARPHeader->xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
+ memcpy( ( void* )pxARPHeader->ucSenderProtocolAddress, ( void* )ipLOCAL_IP_ADDRESS_POINTER, sizeof( pxARPHeader->ucSenderProtocolAddress ) );
+
+ eReturn = eReturnEthernetFrame;
+ }
+ break;
+
+ case ipARP_REPLY :
+ iptracePROCESSING_RECEIVED_ARP_REPLY( ulTargetProtocolAddress );
+ vARPRefreshCacheEntry( &( pxARPHeader->xSenderHardwareAddress ), ulSenderProtocolAddress );
+ /* Process received ARP frame to see if there is a clash. */
+ #if( ipconfigARP_USE_CLASH_DETECTION != 0 )
+ {
+ if( ulSenderProtocolAddress == *ipLOCAL_IP_ADDRESS_POINTER )
+ {
+ xARPHadIPClash = pdTRUE;
+ memcpy( xARPClashMacAddress.ucBytes, pxARPHeader->xSenderHardwareAddress.ucBytes, sizeof( xARPClashMacAddress.ucBytes ) );
+ }
+ }
+ #endif /* ipconfigARP_USE_CLASH_DETECTION */
+ break;
+
+ default :
+ /* Invalid. */
+ break;
+ }
+ }
+
+ return eReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
+
+ uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress )
+ {
+ BaseType_t x;
+ uint32_t lResult = 0;
+
+ /* For each entry in the ARP cache table. */
+ for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
+ {
+ if( ( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 ) )
+ {
+ lResult = xARPCache[ x ].ulIPAddress;
+ memset( &xARPCache[ x ], '\0', sizeof( xARPCache[ x ] ) );
+ break;
+ }
+ }
+
+ return lResult;
+ }
+
+#endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
+/*-----------------------------------------------------------*/
+
+void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress )
+{
+BaseType_t x = 0;
+BaseType_t xIpEntry = -1;
+BaseType_t xMacEntry = -1;
+BaseType_t xUseEntry = 0;
+uint8_t ucMinAgeFound = 0U;
+
+ #if( ipconfigARP_STORES_REMOTE_ADDRESSES == 0 )
+ /* Only process the IP address if it is on the local network.
+ Unless: when '*ipLOCAL_IP_ADDRESS_POINTER' equals zero, the IP-address
+ and netmask are still unknown. */
+ if( ( ( ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) ) ||
+ ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ) )
+ #else
+ /* If ipconfigARP_STORES_REMOTE_ADDRESSES is non-zero, IP addresses with
+ a different netmask will also be stored. After when replying to a UDP
+ message from a different netmask, the IP address can be looped up and a
+ reply sent. This option is useful for systems with multiple gateways,
+ the reply will surely arrive. If ipconfigARP_STORES_REMOTE_ADDRESSES is
+ zero the the gateway address is the only option. */
+ if( pdTRUE )
+ #endif
+ {
+ /* Start with the maximum possible number. */
+ ucMinAgeFound--;
+
+ /* For each entry in the ARP cache table. */
+ for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
+ {
+ /* Does this line in the cache table hold an entry for the IP
+ address being queried? */
+ if( xARPCache[ x ].ulIPAddress == ulIPAddress )
+ {
+ if( pxMACAddress == NULL )
+ {
+ /* In case the parameter pxMACAddress is NULL, an entry will be reserved to
+ indicate that there is an outstanding ARP request, This entry will have
+ "ucValid == pdFALSE". */
+ xIpEntry = x;
+ break;
+ }
+
+ /* See if the MAC-address also matches. */
+ if( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 )
+ {
+ /* This function will be called for each received packet
+ As this is by far the most common path the coding standard
+ is relaxed in this case and a return is permitted as an
+ optimisation. */
+ xARPCache[ x ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
+ xARPCache[ x ].ucValid = ( uint8_t ) pdTRUE;
+ return;
+ }
+
+ /* Found an entry containing ulIPAddress, but the MAC address
+ doesn't match. Might be an entry with ucValid=pdFALSE, waiting
+ for an ARP reply. Still want to see if there is match with the
+ given MAC address.ucBytes. If found, either of the two entries
+ must be cleared. */
+ xIpEntry = x;
+ }
+ else if( ( pxMACAddress != NULL ) && ( memcmp( xARPCache[ x ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) ) == 0 ) )
+ {
+ /* Found an entry with the given MAC-address, but the IP-address
+ is different. Continue looping to find a possible match with
+ ulIPAddress. */
+ #if( ipconfigARP_STORES_REMOTE_ADDRESSES != 0 )
+ /* If ARP stores the MAC address of IP addresses outside the
+ network, than the MAC address of the gateway should not be
+ overwritten. */
+ BaseType_t bIsLocal[ 2 ];
+ bIsLocal[ 0 ] = ( ( xARPCache[ x ].ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) );
+ bIsLocal[ 1 ] = ( ( ulIPAddress & xNetworkAddressing.ulNetMask ) == ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) );
+ if( bIsLocal[ 0 ] == bIsLocal[ 1 ] )
+ {
+ xMacEntry = x;
+ }
+ #else
+ xMacEntry = x;
+ #endif
+ }
+ /* _HT_
+ Shouldn't we test for xARPCache[ x ].ucValid == pdFALSE here ? */
+ else if( xARPCache[ x ].ucAge < ucMinAgeFound )
+ {
+ /* As the table is traversed, remember the table row that
+ contains the oldest entry (the lowest age count, as ages are
+ decremented to zero) so the row can be re-used if this function
+ needs to add an entry that does not already exist. */
+ ucMinAgeFound = xARPCache[ x ].ucAge;
+ xUseEntry = x;
+ }
+ }
+
+ if( xMacEntry >= 0 )
+ {
+ xUseEntry = xMacEntry;
+
+ if( xIpEntry >= 0 )
+ {
+ /* Both the MAC address as well as the IP address were found in
+ different locations: clear the entry which matches the
+ IP-address */
+ memset( &xARPCache[ xIpEntry ], '\0', sizeof( xARPCache[ xIpEntry ] ) );
+ }
+ }
+ else if( xIpEntry >= 0 )
+ {
+ /* An entry containing the IP-address was found, but it had a different MAC address */
+ xUseEntry = xIpEntry;
+ }
+
+ /* If the entry was not found, we use the oldest entry and set the IPaddress */
+ xARPCache[ xUseEntry ].ulIPAddress = ulIPAddress;
+
+ if( pxMACAddress != NULL )
+ {
+ memcpy( xARPCache[ xUseEntry ].xMACAddress.ucBytes, pxMACAddress->ucBytes, sizeof( pxMACAddress->ucBytes ) );
+
+ iptraceARP_TABLE_ENTRY_CREATED( ulIPAddress, (*pxMACAddress) );
+ /* And this entry does not need immediate attention */
+ xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_AGE;
+ xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdTRUE;
+ }
+ else if( xIpEntry < 0 )
+ {
+ xARPCache[ xUseEntry ].ucAge = ( uint8_t ) ipconfigMAX_ARP_RETRANSMISSIONS;
+ xARPCache[ xUseEntry ].ucValid = ( uint8_t ) pdFALSE;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_ARP_REVERSED_LOOKUP == 1 )
+ eARPLookupResult_t eARPGetCacheEntryByMac( MACAddress_t * const pxMACAddress, uint32_t *pulIPAddress )
+ {
+ BaseType_t x;
+ eARPLookupResult_t eReturn = eARPCacheMiss;
+
+ /* Loop through each entry in the ARP cache. */
+ for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
+ {
+ /* Does this row in the ARP cache table hold an entry for the MAC
+ address being searched? */
+ if( memcmp( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
+ {
+ *pulIPAddress = xARPCache[ x ].ulIPAddress;
+ eReturn = eARPCacheHit;
+ break;
+ }
+ }
+
+ return eReturn;
+ }
+#endif /* ipconfigUSE_ARP_REVERSED_LOOKUP */
+
+/*-----------------------------------------------------------*/
+
+eARPLookupResult_t eARPGetCacheEntry( uint32_t *pulIPAddress, MACAddress_t * const pxMACAddress )
+{
+eARPLookupResult_t eReturn;
+uint32_t ulAddressToLookup;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ if( *pulIPAddress == ipLLMNR_IP_ADDR ) /* Is in network byte order. */
+ {
+ /* The LLMNR IP-address has a fixed virtual MAC address. */
+ memcpy( pxMACAddress->ucBytes, xLLMNR_MacAdress.ucBytes, sizeof( MACAddress_t ) );
+ eReturn = eARPCacheHit;
+ }
+ else
+#endif
+ if( ( *pulIPAddress == ipBROADCAST_IP_ADDRESS ) || /* Is it the general broadcast address 255.255.255.255? */
+ ( *pulIPAddress == xNetworkAddressing.ulBroadcastAddress ) )/* Or a local broadcast address, eg 192.168.1.255? */
+ {
+ /* This is a broadcast so uses the broadcast MAC address. */
+ memcpy( pxMACAddress->ucBytes, xBroadcastMACAddress.ucBytes, sizeof( MACAddress_t ) );
+ eReturn = eARPCacheHit;
+ }
+ else if( *ipLOCAL_IP_ADDRESS_POINTER == 0UL )
+ {
+ /* The IP address has not yet been assigned, so there is nothing that
+ can be done. */
+ eReturn = eCantSendPacket;
+ }
+ else
+ {
+ eReturn = eARPCacheMiss;
+
+ if( ( *pulIPAddress & xNetworkAddressing.ulNetMask ) != ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) )
+ {
+#if( ipconfigARP_STORES_REMOTE_ADDRESSES == 1 )
+ eReturn = prvCacheLookup( *pulIPAddress, pxMACAddress );
+
+ if( eReturn == eARPCacheHit )
+ {
+ /* The stack is configured to store 'remote IP addresses', i.e. addresses
+ belonging to a different the netmask. prvCacheLookup() returned a hit, so
+ the MAC address is known */
+ }
+ else
+#endif
+ {
+ /* The IP address is off the local network, so look up the
+ hardware address of the router, if any. */
+ if( xNetworkAddressing.ulGatewayAddress != ( uint32_t )0u )
+ {
+ ulAddressToLookup = xNetworkAddressing.ulGatewayAddress;
+ }
+ else
+ {
+ ulAddressToLookup = *pulIPAddress;
+ }
+ }
+ }
+ else
+ {
+ /* The IP address is on the local network, so lookup the requested
+ IP address directly. */
+ ulAddressToLookup = *pulIPAddress;
+ }
+
+ if( eReturn == eARPCacheMiss )
+ {
+ if( ulAddressToLookup == 0UL )
+ {
+ /* The address is not on the local network, and there is not a
+ router. */
+ eReturn = eCantSendPacket;
+ }
+ else
+ {
+ eReturn = prvCacheLookup( ulAddressToLookup, pxMACAddress );
+
+ if( eReturn == eARPCacheMiss )
+ {
+ /* It might be that the ARP has to go to the gateway. */
+ *pulIPAddress = ulAddressToLookup;
+ }
+ }
+ }
+ }
+
+ return eReturn;
+}
+
+/*-----------------------------------------------------------*/
+
+static eARPLookupResult_t prvCacheLookup( uint32_t ulAddressToLookup, MACAddress_t * const pxMACAddress )
+{
+BaseType_t x;
+eARPLookupResult_t eReturn = eARPCacheMiss;
+
+ /* Loop through each entry in the ARP cache. */
+ for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
+ {
+ /* Does this row in the ARP cache table hold an entry for the IP address
+ being queried? */
+ if( xARPCache[ x ].ulIPAddress == ulAddressToLookup )
+ {
+ /* A matching valid entry was found. */
+ if( xARPCache[ x ].ucValid == ( uint8_t ) pdFALSE )
+ {
+ /* This entry is waiting an ARP reply, so is not valid. */
+ eReturn = eCantSendPacket;
+ }
+ else
+ {
+ /* A valid entry was found. */
+ memcpy( pxMACAddress->ucBytes, xARPCache[ x ].xMACAddress.ucBytes, sizeof( MACAddress_t ) );
+ eReturn = eARPCacheHit;
+ }
+ break;
+ }
+ }
+
+ return eReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vARPAgeCache( void )
+{
+BaseType_t x;
+TickType_t xTimeNow;
+
+ /* Loop through each entry in the ARP cache. */
+ for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
+ {
+ /* If the entry is valid (its age is greater than zero). */
+ if( xARPCache[ x ].ucAge > 0U )
+ {
+ /* Decrement the age value of the entry in this ARP cache table row.
+ When the age reaches zero it is no longer considered valid. */
+ ( xARPCache[ x ].ucAge )--;
+
+ /* If the entry is not yet valid, then it is waiting an ARP
+ reply, and the ARP request should be retransmitted. */
+ if( xARPCache[ x ].ucValid == ( uint8_t ) pdFALSE )
+ {
+ FreeRTOS_OutputARPRequest( xARPCache[ x ].ulIPAddress );
+ }
+ else if( xARPCache[ x ].ucAge <= ( uint8_t ) arpMAX_ARP_AGE_BEFORE_NEW_ARP_REQUEST )
+ {
+ /* This entry will get removed soon. See if the MAC address is
+ still valid to prevent this happening. */
+ iptraceARP_TABLE_ENTRY_WILL_EXPIRE( xARPCache[ x ].ulIPAddress );
+ FreeRTOS_OutputARPRequest( xARPCache[ x ].ulIPAddress );
+ }
+ else
+ {
+ /* The age has just ticked down, with nothing to do. */
+ }
+
+ if( xARPCache[ x ].ucAge == 0u )
+ {
+ /* The entry is no longer valid. Wipe it out. */
+ iptraceARP_TABLE_ENTRY_EXPIRED( xARPCache[ x ].ulIPAddress );
+ xARPCache[ x ].ulIPAddress = 0UL;
+ }
+ }
+ }
+
+ xTimeNow = xTaskGetTickCount ();
+
+ if( ( xLastGratuitousARPTime == ( TickType_t ) 0 ) || ( ( xTimeNow - xLastGratuitousARPTime ) > ( TickType_t ) arpGRATUITOUS_ARP_PERIOD ) )
+ {
+ FreeRTOS_OutputARPRequest( *ipLOCAL_IP_ADDRESS_POINTER );
+ xLastGratuitousARPTime = xTimeNow;
+ }
+}
+/*-----------------------------------------------------------*/
+
+void vARPSendGratuitous( void )
+{
+ /* Setting xLastGratuitousARPTime to 0 will force a gratuitous ARP the next
+ time vARPAgeCache() is called. */
+ xLastGratuitousARPTime = ( TickType_t ) 0;
+
+ /* Let the IP-task call vARPAgeCache(). */
+ xSendEventToIPTask( eARPTimerEvent );
+}
+
+/*-----------------------------------------------------------*/
+void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+
+ /* This is called from the context of the IP event task, so a block time
+ must not be used. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( ARPPacket_t ), ( TickType_t ) 0 );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ pxNetworkBuffer->ulIPAddress = ulIPAddress;
+ vARPGenerateRequestPacket( pxNetworkBuffer );
+
+ #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ BaseType_t xIndex;
+
+ for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
+ {
+ pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
+ }
+ pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
+ }
+ }
+ #endif
+ if( xIsCallingFromIPTask() != 0 )
+ {
+ /* Only the IP-task is allowed to call this function directly. */
+ xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
+ }
+ else
+ {
+ IPStackEvent_t xSendEvent;
+
+ /* Send a message to the IP-task to send this ARP packet. */
+ xSendEvent.eEventType = eNetworkTxEvent;
+ xSendEvent.pvData = ( void * ) pxNetworkBuffer;
+ if( xSendEventStructToIPTask( &xSendEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
+ {
+ /* Failed to send the message, so release the network buffer. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ }
+ }
+}
+
+void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+ARPPacket_t *pxARPPacket;
+
+ /* Buffer allocation ensures that buffers always have space
+ for an ARP packet. See buffer allocation implementations 1
+ and 2 under portable/BufferManagement. */
+ configASSERT( pxNetworkBuffer );
+ configASSERT( pxNetworkBuffer->xDataLength >= sizeof(ARPPacket_t) );
+
+ pxARPPacket = ( ARPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
+
+ /* memcpy the const part of the header information into the correct
+ location in the packet. This copies:
+ xEthernetHeader.ulDestinationAddress
+ xEthernetHeader.usFrameType;
+ xARPHeader.usHardwareType;
+ xARPHeader.usProtocolType;
+ xARPHeader.ucHardwareAddressLength;
+ xARPHeader.ucProtocolAddressLength;
+ xARPHeader.usOperation;
+ xARPHeader.xTargetHardwareAddress;
+ */
+ memcpy( ( void * ) pxARPPacket, ( void * ) xDefaultPartARPPacketHeader, sizeof( xDefaultPartARPPacketHeader ) );
+ memcpy( ( void * ) pxARPPacket->xEthernetHeader.xSourceAddress.ucBytes , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
+ memcpy( ( void * ) pxARPPacket->xARPHeader.xSenderHardwareAddress.ucBytes, ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
+
+ memcpy( ( void* )pxARPPacket->xARPHeader.ucSenderProtocolAddress, ( void* )ipLOCAL_IP_ADDRESS_POINTER, sizeof( pxARPPacket->xARPHeader.ucSenderProtocolAddress ) );
+ pxARPPacket->xARPHeader.ulTargetProtocolAddress = pxNetworkBuffer->ulIPAddress;
+
+ pxNetworkBuffer->xDataLength = sizeof( ARPPacket_t );
+
+ iptraceCREATING_ARP_REQUEST( pxNetworkBuffer->ulIPAddress );
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_ClearARP( void )
+{
+ memset( xARPCache, '\0', sizeof( xARPCache ) );
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigHAS_PRINTF != 0 ) || ( ipconfigHAS_DEBUG_PRINTF != 0 )
+
+ void FreeRTOS_PrintARPCache( void )
+ {
+ BaseType_t x, xCount = 0;
+
+ /* Loop through each entry in the ARP cache. */
+ for( x = 0; x < ipconfigARP_CACHE_ENTRIES; x++ )
+ {
+ if( ( xARPCache[ x ].ulIPAddress != 0ul ) && ( xARPCache[ x ].ucAge > 0U ) )
+ {
+ /* See if the MAC-address also matches, and we're all happy */
+ FreeRTOS_printf( ( "Arp %2ld: %3u - %16lxip : %02x:%02x:%02x : %02x:%02x:%02x\n",
+ x,
+ xARPCache[ x ].ucAge,
+ xARPCache[ x ].ulIPAddress,
+ xARPCache[ x ].xMACAddress.ucBytes[0],
+ xARPCache[ x ].xMACAddress.ucBytes[1],
+ xARPCache[ x ].xMACAddress.ucBytes[2],
+ xARPCache[ x ].xMACAddress.ucBytes[3],
+ xARPCache[ x ].xMACAddress.ucBytes[4],
+ xARPCache[ x ].xMACAddress.ucBytes[5] ) );
+ xCount++;
+ }
+ }
+
+ FreeRTOS_printf( ( "Arp has %ld entries\n", xCount ) );
+ }
+
+#endif /* ( ipconfigHAS_PRINTF != 0 ) || ( ipconfigHAS_DEBUG_PRINTF != 0 ) */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
index 8871d6563..930768055 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DHCP.c
@@ -1,1021 +1,1021 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_TCP_IP.h"
-#include "FreeRTOS_DHCP.h"
-#include "FreeRTOS_ARP.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-/* Exclude the entire file if DHCP is not enabled. */
-#if( ipconfigUSE_DHCP != 0 )
-
-#if ( ipconfigUSE_DHCP != 0 ) && ( ipconfigNETWORK_MTU < 586u )
- /* DHCP must be able to receive an options field of 312 bytes, the fixed
- part of the DHCP packet is 240 bytes, and the IP/UDP headers take 28 bytes. */
- #error ipconfigNETWORK_MTU needs to be at least 586 to use DHCP
-#endif
-
-/* Parameter widths in the DHCP packet. */
-#define dhcpCLIENT_HARDWARE_ADDRESS_LENGTH 16
-#define dhcpSERVER_HOST_NAME_LENGTH 64
-#define dhcpBOOT_FILE_NAME_LENGTH 128
-
-/* Timer parameters */
-#ifndef dhcpINITIAL_DHCP_TX_PERIOD
- #define dhcpINITIAL_TIMER_PERIOD ( pdMS_TO_TICKS( 250 ) )
- #define dhcpINITIAL_DHCP_TX_PERIOD ( pdMS_TO_TICKS( 5000 ) )
-#endif
-
-/* Codes of interest found in the DHCP options field. */
-#define dhcpZERO_PAD_OPTION_CODE ( 0u )
-#define dhcpSUBNET_MASK_OPTION_CODE ( 1u )
-#define dhcpGATEWAY_OPTION_CODE ( 3u )
-#define dhcpDNS_SERVER_OPTIONS_CODE ( 6u )
-#define dhcpDNS_HOSTNAME_OPTIONS_CODE ( 12u )
-#define dhcpREQUEST_IP_ADDRESS_OPTION_CODE ( 50u )
-#define dhcpLEASE_TIME_OPTION_CODE ( 51u )
-#define dhcpMESSAGE_TYPE_OPTION_CODE ( 53u )
-#define dhcpSERVER_IP_ADDRESS_OPTION_CODE ( 54u )
-#define dhcpPARAMETER_REQUEST_OPTION_CODE ( 55u )
-#define dhcpCLIENT_IDENTIFIER_OPTION_CODE ( 61u )
-
-/* The four DHCP message types of interest. */
-#define dhcpMESSAGE_TYPE_DISCOVER ( 1 )
-#define dhcpMESSAGE_TYPE_OFFER ( 2 )
-#define dhcpMESSAGE_TYPE_REQUEST ( 3 )
-#define dhcpMESSAGE_TYPE_ACK ( 5 )
-#define dhcpMESSAGE_TYPE_NACK ( 6 )
-
-/* Offsets into the transmitted DHCP options fields at which various parameters
-are located. */
-#define dhcpCLIENT_IDENTIFIER_OFFSET ( 5 )
-#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 13 )
-#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 19 )
-
-/* Values used in the DHCP packets. */
-#define dhcpREQUEST_OPCODE ( 1 )
-#define dhcpREPLY_OPCODE ( 2 )
-#define dhcpADDRESS_TYPE_ETHERNET ( 1 )
-#define dhcpETHERNET_ADDRESS_LENGTH ( 6 )
-
-/* If a lease time is not received, use the default of two days. */
-/* 48 hours in ticks. Can not use pdMS_TO_TICKS() as integer overflow can occur. */
-#define dhcpDEFAULT_LEASE_TIME ( ( 48UL * 60UL * 60UL ) * configTICK_RATE_HZ )
-
-/* Don't allow the lease time to be too short. */
-#define dhcpMINIMUM_LEASE_TIME ( pdMS_TO_TICKS( 60000UL ) ) /* 60 seconds in ticks. */
-
-/* Marks the end of the variable length options field in the DHCP packet. */
-#define dhcpOPTION_END_BYTE 0xffu
-
-/* Offset into a DHCP message at which the first byte of the options is
-located. */
-#define dhcpFIRST_OPTION_BYTE_OFFSET ( 0xf0 )
-
-/* Standard DHCP port numbers and magic cookie value. */
-#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
- #define dhcpCLIENT_PORT 0x4400u
- #define dhcpSERVER_PORT 0x4300u
- #define dhcpCOOKIE 0x63538263ul
- #define dhcpBROADCAST 0x0080u
-#else
- #define dhcpCLIENT_PORT 0x0044u
- #define dhcpSERVER_PORT 0x0043u
- #define dhcpCOOKIE 0x63825363ul
- #define dhcpBROADCAST 0x8000u
-#endif /* ipconfigBYTE_ORDER */
-
-#include "pack_struct_start.h"
-struct xDHCPMessage
-{
- uint8_t ucOpcode;
- uint8_t ucAddressType;
- uint8_t ucAddressLength;
- uint8_t ucHops;
- uint32_t ulTransactionID;
- uint16_t usElapsedTime;
- uint16_t usFlags;
- uint32_t ulClientIPAddress_ciaddr;
- uint32_t ulYourIPAddress_yiaddr;
- uint32_t ulServerIPAddress_siaddr;
- uint32_t ulRelayAgentIPAddress_giaddr;
- uint8_t ucClientHardwareAddress[ dhcpCLIENT_HARDWARE_ADDRESS_LENGTH ];
- uint8_t ucServerHostName[ dhcpSERVER_HOST_NAME_LENGTH ];
- uint8_t ucBootFileName[ dhcpBOOT_FILE_NAME_LENGTH ];
- uint32_t ulDHCPCookie;
- uint8_t ucFirstOptionByte;
-}
-#include "pack_struct_end.h"
-typedef struct xDHCPMessage DHCPMessage_t;
-
-/* DHCP state machine states. */
-typedef enum
-{
- eWaitingSendFirstDiscover = 0, /* Initial state. Send a discover the first time it is called, and reset all timers. */
- eWaitingOffer, /* Either resend the discover, or, if the offer is forthcoming, send a request. */
- eWaitingAcknowledge, /* Either resend the request. */
- #if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
- eGetLinkLayerAddress, /* When DHCP didn't respond, try to obtain a LinkLayer address 168.254.x.x. */
- #endif
- eLeasedAddress, /* Resend the request at the appropriate time to renew the lease. */
- eNotUsingLeasedAddress /* DHCP failed, and a default IP address is being used. */
-} eDHCPState_t;
-
-/* Hold information in between steps in the DHCP state machine. */
-struct xDHCP_DATA
-{
- uint32_t ulTransactionId;
- uint32_t ulOfferedIPAddress;
- uint32_t ulDHCPServerAddress;
- uint32_t ulLeaseTime;
- /* Hold information on the current timer state. */
- TickType_t xDHCPTxTime;
- TickType_t xDHCPTxPeriod;
- /* Try both without and with the broadcast flag */
- BaseType_t xUseBroadcast;
- /* Maintains the DHCP state machine state. */
- eDHCPState_t eDHCPState;
- /* The UDP socket used for all incoming and outgoing DHCP traffic. */
- Socket_t xDHCPSocket;
-};
-
-typedef struct xDHCP_DATA DHCPData_t;
-
-#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
- /* Define the Link Layer IP address: 169.254.x.x */
- #define LINK_LAYER_ADDRESS_0 169
- #define LINK_LAYER_ADDRESS_1 254
-
- /* Define the netmask used: 255.255.0.0 */
- #define LINK_LAYER_NETMASK_0 255
- #define LINK_LAYER_NETMASK_1 255
- #define LINK_LAYER_NETMASK_2 0
- #define LINK_LAYER_NETMASK_3 0
-#endif
-
-
-/*
- * Generate a DHCP discover message and send it on the DHCP socket.
- */
-static void prvSendDHCPDiscover( void );
-
-/*
- * Interpret message received on the DHCP socket.
- */
-static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType );
-
-/*
- * Generate a DHCP request packet, and send it on the DHCP socket.
- */
-static void prvSendDHCPRequest( void );
-
-/*
- * Prepare to start a DHCP transaction. This initialises some state variables
- * and creates the DHCP socket if necessary.
- */
-static void prvInitialiseDHCP( void );
-
-/*
- * Creates the part of outgoing DHCP messages that are common to all outgoing
- * DHCP messages.
- */
-static uint8_t *prvCreatePartDHCPMessage( struct freertos_sockaddr *pxAddress, BaseType_t xOpcode, const uint8_t * const pucOptionsArray, size_t *pxOptionsArraySize );
-
-/*
- * Create the DHCP socket, if it has not been created already.
- */
-static void prvCreateDHCPSocket( void );
-
-/*
- * After DHCP has failed to answer, prepare everything to start searching
- * for (trying-out) LinkLayer IP-addresses, using the random method: Send
- * a gratuitous ARP request and wait if another device responds to it.
- */
-#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
- static void prvPrepareLinkLayerIPLookUp( void );
-#endif
-
-/*-----------------------------------------------------------*/
-
-/* The next DHCP transaction Id to be used. */
-static DHCPData_t xDHCPData;
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xIsDHCPSocket( Socket_t xSocket )
-{
-BaseType_t xReturn;
-
- if( xDHCPData.xDHCPSocket == xSocket )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vDHCPProcess( BaseType_t xReset )
-{
-BaseType_t xGivingUp = pdFALSE;
-#if( ipconfigUSE_DHCP_HOOK != 0 )
- eDHCPCallbackAnswer_t eAnswer;
-#endif /* ipconfigUSE_DHCP_HOOK */
-
- /* Is DHCP starting over? */
- if( xReset != pdFALSE )
- {
- xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
- }
-
- switch( xDHCPData.eDHCPState )
- {
- case eWaitingSendFirstDiscover :
- /* Ask the user if a DHCP discovery is required. */
- #if( ipconfigUSE_DHCP_HOOK != 0 )
- eAnswer = xApplicationDHCPHook( eDHCPPhasePreDiscover, xNetworkAddressing.ulDefaultIPAddress );
- if( eAnswer == eDHCPContinue )
- #endif /* ipconfigUSE_DHCP_HOOK */
- {
- /* Initial state. Create the DHCP socket, timer, etc. if they
- have not already been created. */
- prvInitialiseDHCP();
-
- /* See if prvInitialiseDHCP() has creates a socket. */
- if( xDHCPData.xDHCPSocket == NULL )
- {
- xGivingUp = pdTRUE;
- break;
- }
-
- *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
-
- /* Send the first discover request. */
- if( xDHCPData.xDHCPSocket != NULL )
- {
- xDHCPData.xDHCPTxTime = xTaskGetTickCount();
- prvSendDHCPDiscover( );
- xDHCPData.eDHCPState = eWaitingOffer;
- }
- }
- #if( ipconfigUSE_DHCP_HOOK != 0 )
- else
- {
- if( eAnswer == eDHCPUseDefaults )
- {
- memcpy( &xNetworkAddressing, &xDefaultAddressing, sizeof( xNetworkAddressing ) );
- }
-
- /* The user indicates that the DHCP process does not continue. */
- xGivingUp = pdTRUE;
- }
- #endif /* ipconfigUSE_DHCP_HOOK */
- break;
-
- case eWaitingOffer :
-
- xGivingUp = pdFALSE;
-
- /* Look for offers coming in. */
- if( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_OFFER ) == pdPASS )
- {
- #if( ipconfigUSE_DHCP_HOOK != 0 )
- /* Ask the user if a DHCP request is required. */
- eAnswer = xApplicationDHCPHook( eDHCPPhasePreRequest, xDHCPData.ulOfferedIPAddress );
-
- if( eAnswer == eDHCPContinue )
- #endif /* ipconfigUSE_DHCP_HOOK */
- {
- /* An offer has been made, the user wants to continue,
- generate the request. */
- xDHCPData.xDHCPTxTime = xTaskGetTickCount();
- xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
- prvSendDHCPRequest( );
- xDHCPData.eDHCPState = eWaitingAcknowledge;
- break;
- }
-
- #if( ipconfigUSE_DHCP_HOOK != 0 )
- if( eAnswer == eDHCPUseDefaults )
- {
- memcpy( &xNetworkAddressing, &xDefaultAddressing, sizeof( xNetworkAddressing ) );
- }
-
- /* The user indicates that the DHCP process does not continue. */
- xGivingUp = pdTRUE;
- #endif /* ipconfigUSE_DHCP_HOOK */
- }
- else if( ( xTaskGetTickCount() - xDHCPData.xDHCPTxTime ) > xDHCPData.xDHCPTxPeriod )
- {
- /* It is time to send another Discover. Increase the time
- period, and if it has not got to the point of giving up - send
- another discovery. */
- xDHCPData.xDHCPTxPeriod <<= 1;
-
- if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
- {
- if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )
- {
- xDHCPData.xDHCPTxTime = xTaskGetTickCount( );
- xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
- prvSendDHCPDiscover( );
- FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );
- }
- else
- {
- FreeRTOS_debug_printf( ( "vDHCPProcess: failed to generate a random Transaction ID\n" ) );
- }
- }
- else
- {
- FreeRTOS_debug_printf( ( "vDHCPProcess: giving up %lu > %lu ticks\n", xDHCPData.xDHCPTxPeriod, ipconfigMAXIMUM_DISCOVER_TX_PERIOD ) );
-
- #if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
- {
- /* Only use a fake Ack if the default IP address == 0x00
- and the link local addressing is used. Start searching
- a free LinkLayer IP-address. Next state will be
- 'eGetLinkLayerAddress'. */
- prvPrepareLinkLayerIPLookUp();
-
- /* Setting an IP address manually so set to not using
- leased address mode. */
- xDHCPData.eDHCPState = eGetLinkLayerAddress;
- }
- #else
- {
- xGivingUp = pdTRUE;
- }
- #endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
- }
- }
- break;
-
- case eWaitingAcknowledge :
-
- /* Look for acks coming in. */
- if( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_ACK ) == pdPASS )
- {
- FreeRTOS_debug_printf( ( "vDHCPProcess: acked %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
-
- /* DHCP completed. The IP address can now be used, and the
- timer set to the lease timeout time. */
- *ipLOCAL_IP_ADDRESS_POINTER = xDHCPData.ulOfferedIPAddress;
-
- /* Setting the 'local' broadcast address, something like
- '192.168.1.255'. */
- xNetworkAddressing.ulBroadcastAddress = ( xDHCPData.ulOfferedIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
- xDHCPData.eDHCPState = eLeasedAddress;
-
- iptraceDHCP_SUCCEDEED( xDHCPData.ulOfferedIPAddress );
-
- /* DHCP failed, the default configured IP-address will be used
- Now call vIPNetworkUpCalls() to send the network-up event and
- start the ARP timer. */
- vIPNetworkUpCalls( );
-
- /* Close socket to ensure packets don't queue on it. */
- vSocketClose( xDHCPData.xDHCPSocket );
- xDHCPData.xDHCPSocket = NULL;
-
- if( xDHCPData.ulLeaseTime == 0UL )
- {
- xDHCPData.ulLeaseTime = dhcpDEFAULT_LEASE_TIME;
- }
- else if( xDHCPData.ulLeaseTime < dhcpMINIMUM_LEASE_TIME )
- {
- xDHCPData.ulLeaseTime = dhcpMINIMUM_LEASE_TIME;
- }
- else
- {
- /* The lease time is already valid. */
- }
-
- /* Check for clashes. */
- vARPSendGratuitous();
- vIPReloadDHCPTimer( xDHCPData.ulLeaseTime );
- }
- else
- {
- /* Is it time to send another Discover? */
- if( ( xTaskGetTickCount() - xDHCPData.xDHCPTxTime ) > xDHCPData.xDHCPTxPeriod )
- {
- /* Increase the time period, and if it has not got to the
- point of giving up - send another request. */
- xDHCPData.xDHCPTxPeriod <<= 1;
-
- if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
- {
- xDHCPData.xDHCPTxTime = xTaskGetTickCount();
- prvSendDHCPRequest( );
- }
- else
- {
- /* Give up, start again. */
- xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
- }
- }
- }
- break;
-
- #if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
- case eGetLinkLayerAddress:
- if( ( xTaskGetTickCount() - xDHCPData.xDHCPTxTime ) > xDHCPData.xDHCPTxPeriod )
- {
- if( xARPHadIPClash == pdFALSE )
- {
- /* ARP OK. proceed. */
- iptraceDHCP_SUCCEDEED( xDHCPData.ulOfferedIPAddress );
-
- /* Auto-IP succeeded, the default configured IP-address will
- be used. Now call vIPNetworkUpCalls() to send the
- network-up event and start the ARP timer. */
- vIPNetworkUpCalls( );
- xDHCPData.eDHCPState = eNotUsingLeasedAddress;
- }
- else
- {
- /* ARP clashed - try another IP address. */
- prvPrepareLinkLayerIPLookUp();
-
- /* Setting an IP address manually so set to not using leased
- address mode. */
- xDHCPData.eDHCPState = eGetLinkLayerAddress;
- }
- }
- break;
- #endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
-
- case eLeasedAddress :
-
- /* Resend the request at the appropriate time to renew the lease. */
- prvCreateDHCPSocket();
-
- if( xDHCPData.xDHCPSocket != NULL )
- {
- xDHCPData.xDHCPTxTime = xTaskGetTickCount();
- xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
- prvSendDHCPRequest( );
- xDHCPData.eDHCPState = eWaitingAcknowledge;
-
- /* From now on, we should be called more often */
- vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
- }
- break;
-
- case eNotUsingLeasedAddress:
-
- vIPSetDHCPTimerEnableState( pdFALSE );
- break;
-
- default:
- break;
- }
-
- if( xGivingUp != pdFALSE )
- {
- /* xGivingUp became true either because of a time-out, or because
- xApplicationDHCPHook() returned another value than 'eDHCPContinue',
- meaning that the conversion is canceled from here. */
-
- /* Revert to static IP address. */
- taskENTER_CRITICAL();
- {
- *ipLOCAL_IP_ADDRESS_POINTER = xNetworkAddressing.ulDefaultIPAddress;
- iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS( xNetworkAddressing.ulDefaultIPAddress );
- }
- taskEXIT_CRITICAL();
-
- xDHCPData.eDHCPState = eNotUsingLeasedAddress;
- vIPSetDHCPTimerEnableState( pdFALSE );
-
- /* DHCP failed, the default configured IP-address will be used. Now
- call vIPNetworkUpCalls() to send the network-up event and start the ARP
- timer. */
- vIPNetworkUpCalls( );
-
- /* Test if socket was indeed created. */
- if( xDHCPData.xDHCPSocket != NULL )
- {
- /* Close socket to ensure packets don't queue on it. */
- vSocketClose( xDHCPData.xDHCPSocket );
- xDHCPData.xDHCPSocket = NULL;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateDHCPSocket( void )
-{
-struct freertos_sockaddr xAddress;
-BaseType_t xReturn;
-TickType_t xTimeoutTime = ( TickType_t ) 0;
-
- /* Create the socket, if it has not already been created. */
- if( xDHCPData.xDHCPSocket == NULL )
- {
- xDHCPData.xDHCPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
- if( xDHCPData.xDHCPSocket != FREERTOS_INVALID_SOCKET )
- {
-
- /* Ensure the Rx and Tx timeouts are zero as the DHCP executes in the
- context of the IP task. */
- FreeRTOS_setsockopt( xDHCPData.xDHCPSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xTimeoutTime, sizeof( TickType_t ) );
- FreeRTOS_setsockopt( xDHCPData.xDHCPSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xTimeoutTime, sizeof( TickType_t ) );
-
- /* Bind to the standard DHCP client port. */
- xAddress.sin_port = ( uint16_t ) dhcpCLIENT_PORT;
- xReturn = vSocketBind( xDHCPData.xDHCPSocket, &xAddress, sizeof( xAddress ), pdFALSE );
- if( xReturn != 0 )
- {
- /* Binding failed, close the socket again. */
- vSocketClose( xDHCPData.xDHCPSocket );
- xDHCPData.xDHCPSocket = NULL;
- }
- }
- else
- {
- /* Change to NULL for easier testing. */
- xDHCPData.xDHCPSocket = NULL;
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvInitialiseDHCP( void )
-{
- /* Initialise the parameters that will be set by the DHCP process. Per
- https://www.ietf.org/rfc/rfc2131.txt, Transaction ID should be a random
- value chosen by the client. */
-
- /* Check for random number generator API failure. */
- if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )
- {
- xDHCPData.xUseBroadcast = 0;
- xDHCPData.ulOfferedIPAddress = 0UL;
- xDHCPData.ulDHCPServerAddress = 0UL;
- xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
-
- /* Create the DHCP socket if it has not already been created. */
- prvCreateDHCPSocket();
- FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
- vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
- }
- else
- {
- /* There was a problem with the randomiser. */
- }
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType )
-{
-uint8_t *pucUDPPayload, *pucLastByte;
-struct freertos_sockaddr xClient;
-uint32_t xClientLength = sizeof( xClient );
-int32_t lBytes;
-DHCPMessage_t *pxDHCPMessage;
-uint8_t *pucByte, ucOptionCode, ucLength;
-uint32_t ulProcessed, ulParameter;
-BaseType_t xReturn = pdFALSE;
-const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct DHCP message type must be present in the options. */
-
- lBytes = FreeRTOS_recvfrom( xDHCPData.xDHCPSocket, ( void * ) &pucUDPPayload, 0ul, FREERTOS_ZERO_COPY, &xClient, &xClientLength );
-
- if( lBytes > 0 )
- {
- /* Map a DHCP structure onto the received data. */
- pxDHCPMessage = ( DHCPMessage_t * ) ( pucUDPPayload );
-
- /* Sanity check. */
- if( ( lBytes >= sizeof( DHCPMessage_t ) ) &&
- ( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&
- ( pxDHCPMessage->ucOpcode == ( uint8_t ) dhcpREPLY_OPCODE ) &&
- ( pxDHCPMessage->ulTransactionID == FreeRTOS_htonl( xDHCPData.ulTransactionId ) ) )
- {
- if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ),
- ( void * ) ipLOCAL_MAC_ADDRESS,
- sizeof( MACAddress_t ) ) == 0 )
- {
- /* None of the essential options have been processed yet. */
- ulProcessed = 0ul;
-
- /* Walk through the options until the dhcpOPTION_END_BYTE byte
- is found, taking care not to walk off the end of the options. */
- pucByte = &( pxDHCPMessage->ucFirstOptionByte );
- /* Maintain a pointer to the last valid byte (i.e. not the first
- invalid byte). */
- pucLastByte = pucUDPPayload + lBytes - 1;
-
- while( pucByte <= pucLastByte )
- {
- ucOptionCode = pucByte[ 0 ];
- if( ucOptionCode == dhcpOPTION_END_BYTE )
- {
- /* Ready, the last byte has been seen. */
- break;
- }
- if( ucOptionCode == dhcpZERO_PAD_OPTION_CODE )
- {
- /* The value zero is used as a pad byte,
- it is not followed by a length byte. */
- pucByte += 1;
- continue;
- }
-
- /* Stop if the response is malformed. */
- if( pucByte < pucLastByte )
- {
- /* There are at least two bytes left. */
- ucLength = pucByte[ 1 ];
- pucByte += 2;
-
- if( pucByte + ucLength > pucLastByte )
- {
- break;
- }
- }
- else
- {
- break;
- }
-
- /* In most cases, a 4-byte network-endian parameter follows,
- just get it once here and use later. */
- if( ucLength >= sizeof( ulParameter ) )
- {
- memcpy( ( void * ) &( ulParameter ),
- ( void * ) pucByte,
- ( size_t ) sizeof( ulParameter ) );
- }
- else
- {
- ulParameter = 0;
- }
-
- /* Option-specific handling. */
- switch( ucOptionCode )
- {
- case dhcpMESSAGE_TYPE_OPTION_CODE :
-
- if( *pucByte == ( uint8_t ) xExpectedMessageType )
- {
- /* The message type is the message type the
- state machine is expecting. */
- ulProcessed++;
- }
- else if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK )
- {
- if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK )
- {
- /* Start again. */
- xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
- }
- }
- else
- {
- /* Don't process other message types. */
- }
- break;
-
- case dhcpSUBNET_MASK_OPTION_CODE :
-
- if( ucLength == sizeof( uint32_t ) )
- {
- xNetworkAddressing.ulNetMask = ulParameter;
- }
- break;
-
- case dhcpGATEWAY_OPTION_CODE :
-
- if( ucLength == sizeof( uint32_t ) )
- {
- /* ulProcessed is not incremented in this case
- because the gateway is not essential. */
- xNetworkAddressing.ulGatewayAddress = ulParameter;
- }
- break;
-
- case dhcpDNS_SERVER_OPTIONS_CODE :
-
- /* ulProcessed is not incremented in this case
- because the DNS server is not essential. Only the
- first DNS server address is taken. */
- xNetworkAddressing.ulDNSServerAddress = ulParameter;
- break;
-
- case dhcpSERVER_IP_ADDRESS_OPTION_CODE :
-
- if( ucLength == sizeof( uint32_t ) )
- {
- if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_OFFER )
- {
- /* Offers state the replying server. */
- ulProcessed++;
- xDHCPData.ulDHCPServerAddress = ulParameter;
- }
- else
- {
- /* The ack must come from the expected server. */
- if( xDHCPData.ulDHCPServerAddress == ulParameter )
- {
- ulProcessed++;
- }
- }
- }
- break;
-
- case dhcpLEASE_TIME_OPTION_CODE :
-
- if( ucLength == sizeof( xDHCPData.ulLeaseTime ) )
- {
- /* ulProcessed is not incremented in this case
- because the lease time is not essential. */
- /* The DHCP parameter is in seconds, convert
- to host-endian format. */
- xDHCPData.ulLeaseTime = FreeRTOS_ntohl( ulParameter );
-
- /* Divide the lease time by two to ensure a
- renew request is sent before the lease actually
- expires. */
- xDHCPData.ulLeaseTime >>= 1UL;
-
- /* Multiply with configTICK_RATE_HZ to get clock
- ticks. */
- xDHCPData.ulLeaseTime = configTICK_RATE_HZ * xDHCPData.ulLeaseTime;
- }
- break;
-
- default :
-
- /* Not interested in this field. */
-
- break;
- }
-
- /* Jump over the data to find the next option code. */
- if( ucLength == 0u )
- {
- break;
- }
- else
- {
- pucByte += ucLength;
- }
- }
-
- /* Were all the mandatory options received? */
- if( ulProcessed >= ulMandatoryOptions )
- {
- /* HT:endian: used to be network order */
- xDHCPData.ulOfferedIPAddress = pxDHCPMessage->ulYourIPAddress_yiaddr;
- FreeRTOS_printf( ( "vDHCPProcess: offer %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
- xReturn = pdPASS;
- }
- }
- }
-
- FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static uint8_t *prvCreatePartDHCPMessage( struct freertos_sockaddr *pxAddress, BaseType_t xOpcode, const uint8_t * const pucOptionsArray, size_t *pxOptionsArraySize )
-{
-DHCPMessage_t *pxDHCPMessage;
-size_t xRequiredBufferSize = sizeof( DHCPMessage_t ) + *pxOptionsArraySize;
-uint8_t *pucUDPPayloadBuffer;
-
-#if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
- const char *pucHostName = pcApplicationHostnameHook ();
- size_t xNameLength = strlen( pucHostName );
- uint8_t *pucPtr;
-
- xRequiredBufferSize += ( 2 + xNameLength );
-#endif
-
- /* Get a buffer. This uses a maximum delay, but the delay will be capped
- to ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS so the return value still needs to
- be test. */
- do
- {
- } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xRequiredBufferSize, portMAX_DELAY ) ) == NULL );
-
- pxDHCPMessage = ( DHCPMessage_t * ) pucUDPPayloadBuffer;
-
- /* Most fields need to be zero. */
- memset( ( void * ) pxDHCPMessage, 0x00, sizeof( DHCPMessage_t ) );
-
- /* Create the message. */
- pxDHCPMessage->ucOpcode = ( uint8_t ) xOpcode;
- pxDHCPMessage->ucAddressType = ( uint8_t ) dhcpADDRESS_TYPE_ETHERNET;
- pxDHCPMessage->ucAddressLength = ( uint8_t ) dhcpETHERNET_ADDRESS_LENGTH;
- pxDHCPMessage->ulTransactionID = FreeRTOS_htonl( xDHCPData.ulTransactionId );
- pxDHCPMessage->ulDHCPCookie = ( uint32_t ) dhcpCOOKIE;
- if( xDHCPData.xUseBroadcast != pdFALSE )
- {
- pxDHCPMessage->usFlags = ( uint16_t ) dhcpBROADCAST;
- }
- else
- {
- pxDHCPMessage->usFlags = 0u;
- }
-
- memcpy( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress[ 0 ] ), ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
-
- /* Copy in the const part of the options options. */
- memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET ] ), ( void * ) pucOptionsArray, *pxOptionsArraySize );
-
- #if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
- {
- /* With this option, the hostname can be registered as well which makes
- it easier to lookup a device in a router's list of DHCP clients. */
-
- /* Point to where the OPTION_END was stored to add data. */
- pucPtr = &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + ( *pxOptionsArraySize - 1 ) ] );
- pucPtr[ 0 ] = dhcpDNS_HOSTNAME_OPTIONS_CODE;
- pucPtr[ 1 ] = ( uint8_t ) xNameLength;
- memcpy( ( void *) ( pucPtr + 2 ), pucHostName, xNameLength );
- pucPtr[ 2 + xNameLength ] = dhcpOPTION_END_BYTE;
- *pxOptionsArraySize += ( 2 + xNameLength );
- }
- #endif
-
- /* Map in the client identifier. */
- memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpCLIENT_IDENTIFIER_OFFSET ] ),
- ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
-
- /* Set the addressing. */
- pxAddress->sin_addr = ipBROADCAST_IP_ADDRESS;
- pxAddress->sin_port = ( uint16_t ) dhcpSERVER_PORT;
-
- return pucUDPPayloadBuffer;
-}
-/*-----------------------------------------------------------*/
-
-static void prvSendDHCPRequest( void )
-{
-uint8_t *pucUDPPayloadBuffer;
-struct freertos_sockaddr xAddress;
-static const uint8_t ucDHCPRequestOptions[] =
-{
- /* Do not change the ordering without also changing
- dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and
- dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */
- dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
- dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
- dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
- dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
- dhcpOPTION_END_BYTE
-};
-size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
-
- pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );
-
- /* Copy in the IP address being requested. */
- memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpREQUESTED_IP_ADDRESS_OFFSET ] ),
- ( void * ) &( xDHCPData.ulOfferedIPAddress ), sizeof( xDHCPData.ulOfferedIPAddress ) );
-
- /* Copy in the address of the DHCP server being used. */
- memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ] ),
- ( void * ) &( xDHCPData.ulDHCPServerAddress ), sizeof( xDHCPData.ulDHCPServerAddress ) );
-
- FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
- iptraceSENDING_DHCP_REQUEST();
-
- /* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
- if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
- {
- /* The packet was not successfully queued for sending and must be
- returned to the stack. */
- FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvSendDHCPDiscover( void )
-{
-uint8_t *pucUDPPayloadBuffer;
-struct freertos_sockaddr xAddress;
-static const uint8_t ucDHCPDiscoverOptions[] =
-{
- /* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */
- dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
- dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
- dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
- dhcpOPTION_END_BYTE
-};
-size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
-
- pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );
-
- FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
- iptraceSENDING_DHCP_DISCOVER();
-
- /* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
- if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
- {
- /* The packet was not successfully queued for sending and must be
- returned to the stack. */
- FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
-
- static void prvPrepareLinkLayerIPLookUp( void )
- {
- uint8_t ucLinkLayerIPAddress[ 2 ];
- uint32_t ulNumbers[ 2 ];
-
- /* After DHCP has failed to answer, prepare everything to start
- trying-out LinkLayer IP-addresses, using the random method. */
- xDHCPData.xDHCPTxTime = xTaskGetTickCount();
-
- xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );
- xApplicationGetRandomNumber( &( ulNumbers[ 1 ] ) );
- ucLinkLayerIPAddress[ 0 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 0 ] % 0xFDu ); /* get value 1..254 for IP-address 3rd byte of IP address to try. */
- ucLinkLayerIPAddress[ 1 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 1 ] % 0xFDu ); /* get value 1..254 for IP-address 4th byte of IP address to try. */
-
- xNetworkAddressing.ulGatewayAddress = FreeRTOS_htonl( 0xA9FE0203 );
-
- /* prepare xDHCPData with data to test. */
- xDHCPData.ulOfferedIPAddress =
- FreeRTOS_inet_addr_quick( LINK_LAYER_ADDRESS_0, LINK_LAYER_ADDRESS_1, ucLinkLayerIPAddress[ 0 ], ucLinkLayerIPAddress[ 1 ] );
-
- xDHCPData.ulLeaseTime = dhcpDEFAULT_LEASE_TIME; /* don't care about lease time. just put anything. */
-
- xNetworkAddressing.ulNetMask =
- FreeRTOS_inet_addr_quick( LINK_LAYER_NETMASK_0, LINK_LAYER_NETMASK_1, LINK_LAYER_NETMASK_2, LINK_LAYER_NETMASK_3 );
-
- /* DHCP completed. The IP address can now be used, and the
- timer set to the lease timeout time. */
- *ipLOCAL_IP_ADDRESS_POINTER = xDHCPData.ulOfferedIPAddress;
-
- /* Setting the 'local' broadcast address, something like 192.168.1.255' */
- xNetworkAddressing.ulBroadcastAddress = ( xDHCPData.ulOfferedIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
-
- /* Close socket to ensure packets don't queue on it. not needed anymore as DHCP failed. but still need timer for ARP testing. */
- if( xDHCPData.xDHCPSocket != NULL )
- {
- /* Close socket to ensure packets don't queue on it. */
- vSocketClose( xDHCPData.xDHCPSocket );
- xDHCPData.xDHCPSocket = NULL;
- }
-
- xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );
- xDHCPData.xDHCPTxPeriod = pdMS_TO_TICKS( 3000ul + ( ulNumbers[ 0 ] & 0x3ffuL ) ); /* do ARP test every (3 + 0-1024mS) seconds. */
-
- xARPHadIPClash = pdFALSE; /* reset flag that shows if have ARP clash. */
- vARPSendGratuitous();
- }
-
-#endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
-/*-----------------------------------------------------------*/
-
-#endif /* ipconfigUSE_DHCP != 0 */
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_TCP_IP.h"
+#include "FreeRTOS_DHCP.h"
+#include "FreeRTOS_ARP.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+/* Exclude the entire file if DHCP is not enabled. */
+#if( ipconfigUSE_DHCP != 0 )
+
+#if ( ipconfigUSE_DHCP != 0 ) && ( ipconfigNETWORK_MTU < 586u )
+ /* DHCP must be able to receive an options field of 312 bytes, the fixed
+ part of the DHCP packet is 240 bytes, and the IP/UDP headers take 28 bytes. */
+ #error ipconfigNETWORK_MTU needs to be at least 586 to use DHCP
+#endif
+
+/* Parameter widths in the DHCP packet. */
+#define dhcpCLIENT_HARDWARE_ADDRESS_LENGTH 16
+#define dhcpSERVER_HOST_NAME_LENGTH 64
+#define dhcpBOOT_FILE_NAME_LENGTH 128
+
+/* Timer parameters */
+#ifndef dhcpINITIAL_DHCP_TX_PERIOD
+ #define dhcpINITIAL_TIMER_PERIOD ( pdMS_TO_TICKS( 250 ) )
+ #define dhcpINITIAL_DHCP_TX_PERIOD ( pdMS_TO_TICKS( 5000 ) )
+#endif
+
+/* Codes of interest found in the DHCP options field. */
+#define dhcpZERO_PAD_OPTION_CODE ( 0u )
+#define dhcpSUBNET_MASK_OPTION_CODE ( 1u )
+#define dhcpGATEWAY_OPTION_CODE ( 3u )
+#define dhcpDNS_SERVER_OPTIONS_CODE ( 6u )
+#define dhcpDNS_HOSTNAME_OPTIONS_CODE ( 12u )
+#define dhcpREQUEST_IP_ADDRESS_OPTION_CODE ( 50u )
+#define dhcpLEASE_TIME_OPTION_CODE ( 51u )
+#define dhcpMESSAGE_TYPE_OPTION_CODE ( 53u )
+#define dhcpSERVER_IP_ADDRESS_OPTION_CODE ( 54u )
+#define dhcpPARAMETER_REQUEST_OPTION_CODE ( 55u )
+#define dhcpCLIENT_IDENTIFIER_OPTION_CODE ( 61u )
+
+/* The four DHCP message types of interest. */
+#define dhcpMESSAGE_TYPE_DISCOVER ( 1 )
+#define dhcpMESSAGE_TYPE_OFFER ( 2 )
+#define dhcpMESSAGE_TYPE_REQUEST ( 3 )
+#define dhcpMESSAGE_TYPE_ACK ( 5 )
+#define dhcpMESSAGE_TYPE_NACK ( 6 )
+
+/* Offsets into the transmitted DHCP options fields at which various parameters
+are located. */
+#define dhcpCLIENT_IDENTIFIER_OFFSET ( 5 )
+#define dhcpREQUESTED_IP_ADDRESS_OFFSET ( 13 )
+#define dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ( 19 )
+
+/* Values used in the DHCP packets. */
+#define dhcpREQUEST_OPCODE ( 1 )
+#define dhcpREPLY_OPCODE ( 2 )
+#define dhcpADDRESS_TYPE_ETHERNET ( 1 )
+#define dhcpETHERNET_ADDRESS_LENGTH ( 6 )
+
+/* If a lease time is not received, use the default of two days. */
+/* 48 hours in ticks. Can not use pdMS_TO_TICKS() as integer overflow can occur. */
+#define dhcpDEFAULT_LEASE_TIME ( ( 48UL * 60UL * 60UL ) * configTICK_RATE_HZ )
+
+/* Don't allow the lease time to be too short. */
+#define dhcpMINIMUM_LEASE_TIME ( pdMS_TO_TICKS( 60000UL ) ) /* 60 seconds in ticks. */
+
+/* Marks the end of the variable length options field in the DHCP packet. */
+#define dhcpOPTION_END_BYTE 0xffu
+
+/* Offset into a DHCP message at which the first byte of the options is
+located. */
+#define dhcpFIRST_OPTION_BYTE_OFFSET ( 0xf0 )
+
+/* Standard DHCP port numbers and magic cookie value. */
+#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
+ #define dhcpCLIENT_PORT 0x4400u
+ #define dhcpSERVER_PORT 0x4300u
+ #define dhcpCOOKIE 0x63538263ul
+ #define dhcpBROADCAST 0x0080u
+#else
+ #define dhcpCLIENT_PORT 0x0044u
+ #define dhcpSERVER_PORT 0x0043u
+ #define dhcpCOOKIE 0x63825363ul
+ #define dhcpBROADCAST 0x8000u
+#endif /* ipconfigBYTE_ORDER */
+
+#include "pack_struct_start.h"
+struct xDHCPMessage
+{
+ uint8_t ucOpcode;
+ uint8_t ucAddressType;
+ uint8_t ucAddressLength;
+ uint8_t ucHops;
+ uint32_t ulTransactionID;
+ uint16_t usElapsedTime;
+ uint16_t usFlags;
+ uint32_t ulClientIPAddress_ciaddr;
+ uint32_t ulYourIPAddress_yiaddr;
+ uint32_t ulServerIPAddress_siaddr;
+ uint32_t ulRelayAgentIPAddress_giaddr;
+ uint8_t ucClientHardwareAddress[ dhcpCLIENT_HARDWARE_ADDRESS_LENGTH ];
+ uint8_t ucServerHostName[ dhcpSERVER_HOST_NAME_LENGTH ];
+ uint8_t ucBootFileName[ dhcpBOOT_FILE_NAME_LENGTH ];
+ uint32_t ulDHCPCookie;
+ uint8_t ucFirstOptionByte;
+}
+#include "pack_struct_end.h"
+typedef struct xDHCPMessage DHCPMessage_t;
+
+/* DHCP state machine states. */
+typedef enum
+{
+ eWaitingSendFirstDiscover = 0, /* Initial state. Send a discover the first time it is called, and reset all timers. */
+ eWaitingOffer, /* Either resend the discover, or, if the offer is forthcoming, send a request. */
+ eWaitingAcknowledge, /* Either resend the request. */
+ #if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+ eGetLinkLayerAddress, /* When DHCP didn't respond, try to obtain a LinkLayer address 168.254.x.x. */
+ #endif
+ eLeasedAddress, /* Resend the request at the appropriate time to renew the lease. */
+ eNotUsingLeasedAddress /* DHCP failed, and a default IP address is being used. */
+} eDHCPState_t;
+
+/* Hold information in between steps in the DHCP state machine. */
+struct xDHCP_DATA
+{
+ uint32_t ulTransactionId;
+ uint32_t ulOfferedIPAddress;
+ uint32_t ulDHCPServerAddress;
+ uint32_t ulLeaseTime;
+ /* Hold information on the current timer state. */
+ TickType_t xDHCPTxTime;
+ TickType_t xDHCPTxPeriod;
+ /* Try both without and with the broadcast flag */
+ BaseType_t xUseBroadcast;
+ /* Maintains the DHCP state machine state. */
+ eDHCPState_t eDHCPState;
+ /* The UDP socket used for all incoming and outgoing DHCP traffic. */
+ Socket_t xDHCPSocket;
+};
+
+typedef struct xDHCP_DATA DHCPData_t;
+
+#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+ /* Define the Link Layer IP address: 169.254.x.x */
+ #define LINK_LAYER_ADDRESS_0 169
+ #define LINK_LAYER_ADDRESS_1 254
+
+ /* Define the netmask used: 255.255.0.0 */
+ #define LINK_LAYER_NETMASK_0 255
+ #define LINK_LAYER_NETMASK_1 255
+ #define LINK_LAYER_NETMASK_2 0
+ #define LINK_LAYER_NETMASK_3 0
+#endif
+
+
+/*
+ * Generate a DHCP discover message and send it on the DHCP socket.
+ */
+static void prvSendDHCPDiscover( void );
+
+/*
+ * Interpret message received on the DHCP socket.
+ */
+static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType );
+
+/*
+ * Generate a DHCP request packet, and send it on the DHCP socket.
+ */
+static void prvSendDHCPRequest( void );
+
+/*
+ * Prepare to start a DHCP transaction. This initialises some state variables
+ * and creates the DHCP socket if necessary.
+ */
+static void prvInitialiseDHCP( void );
+
+/*
+ * Creates the part of outgoing DHCP messages that are common to all outgoing
+ * DHCP messages.
+ */
+static uint8_t *prvCreatePartDHCPMessage( struct freertos_sockaddr *pxAddress, BaseType_t xOpcode, const uint8_t * const pucOptionsArray, size_t *pxOptionsArraySize );
+
+/*
+ * Create the DHCP socket, if it has not been created already.
+ */
+static void prvCreateDHCPSocket( void );
+
+/*
+ * After DHCP has failed to answer, prepare everything to start searching
+ * for (trying-out) LinkLayer IP-addresses, using the random method: Send
+ * a gratuitous ARP request and wait if another device responds to it.
+ */
+#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+ static void prvPrepareLinkLayerIPLookUp( void );
+#endif
+
+/*-----------------------------------------------------------*/
+
+/* The next DHCP transaction Id to be used. */
+static DHCPData_t xDHCPData;
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xIsDHCPSocket( Socket_t xSocket )
+{
+BaseType_t xReturn;
+
+ if( xDHCPData.xDHCPSocket == xSocket )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vDHCPProcess( BaseType_t xReset )
+{
+BaseType_t xGivingUp = pdFALSE;
+#if( ipconfigUSE_DHCP_HOOK != 0 )
+ eDHCPCallbackAnswer_t eAnswer;
+#endif /* ipconfigUSE_DHCP_HOOK */
+
+ /* Is DHCP starting over? */
+ if( xReset != pdFALSE )
+ {
+ xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
+ }
+
+ switch( xDHCPData.eDHCPState )
+ {
+ case eWaitingSendFirstDiscover :
+ /* Ask the user if a DHCP discovery is required. */
+ #if( ipconfigUSE_DHCP_HOOK != 0 )
+ eAnswer = xApplicationDHCPHook( eDHCPPhasePreDiscover, xNetworkAddressing.ulDefaultIPAddress );
+ if( eAnswer == eDHCPContinue )
+ #endif /* ipconfigUSE_DHCP_HOOK */
+ {
+ /* Initial state. Create the DHCP socket, timer, etc. if they
+ have not already been created. */
+ prvInitialiseDHCP();
+
+ /* See if prvInitialiseDHCP() has creates a socket. */
+ if( xDHCPData.xDHCPSocket == NULL )
+ {
+ xGivingUp = pdTRUE;
+ break;
+ }
+
+ *ipLOCAL_IP_ADDRESS_POINTER = 0UL;
+
+ /* Send the first discover request. */
+ if( xDHCPData.xDHCPSocket != NULL )
+ {
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount();
+ prvSendDHCPDiscover( );
+ xDHCPData.eDHCPState = eWaitingOffer;
+ }
+ }
+ #if( ipconfigUSE_DHCP_HOOK != 0 )
+ else
+ {
+ if( eAnswer == eDHCPUseDefaults )
+ {
+ memcpy( &xNetworkAddressing, &xDefaultAddressing, sizeof( xNetworkAddressing ) );
+ }
+
+ /* The user indicates that the DHCP process does not continue. */
+ xGivingUp = pdTRUE;
+ }
+ #endif /* ipconfigUSE_DHCP_HOOK */
+ break;
+
+ case eWaitingOffer :
+
+ xGivingUp = pdFALSE;
+
+ /* Look for offers coming in. */
+ if( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_OFFER ) == pdPASS )
+ {
+ #if( ipconfigUSE_DHCP_HOOK != 0 )
+ /* Ask the user if a DHCP request is required. */
+ eAnswer = xApplicationDHCPHook( eDHCPPhasePreRequest, xDHCPData.ulOfferedIPAddress );
+
+ if( eAnswer == eDHCPContinue )
+ #endif /* ipconfigUSE_DHCP_HOOK */
+ {
+ /* An offer has been made, the user wants to continue,
+ generate the request. */
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount();
+ xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
+ prvSendDHCPRequest( );
+ xDHCPData.eDHCPState = eWaitingAcknowledge;
+ break;
+ }
+
+ #if( ipconfigUSE_DHCP_HOOK != 0 )
+ if( eAnswer == eDHCPUseDefaults )
+ {
+ memcpy( &xNetworkAddressing, &xDefaultAddressing, sizeof( xNetworkAddressing ) );
+ }
+
+ /* The user indicates that the DHCP process does not continue. */
+ xGivingUp = pdTRUE;
+ #endif /* ipconfigUSE_DHCP_HOOK */
+ }
+ else if( ( xTaskGetTickCount() - xDHCPData.xDHCPTxTime ) > xDHCPData.xDHCPTxPeriod )
+ {
+ /* It is time to send another Discover. Increase the time
+ period, and if it has not got to the point of giving up - send
+ another discovery. */
+ xDHCPData.xDHCPTxPeriod <<= 1;
+
+ if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
+ {
+ if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )
+ {
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount( );
+ xDHCPData.xUseBroadcast = !xDHCPData.xUseBroadcast;
+ prvSendDHCPDiscover( );
+ FreeRTOS_debug_printf( ( "vDHCPProcess: timeout %lu ticks\n", xDHCPData.xDHCPTxPeriod ) );
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "vDHCPProcess: failed to generate a random Transaction ID\n" ) );
+ }
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "vDHCPProcess: giving up %lu > %lu ticks\n", xDHCPData.xDHCPTxPeriod, ipconfigMAXIMUM_DISCOVER_TX_PERIOD ) );
+
+ #if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+ {
+ /* Only use a fake Ack if the default IP address == 0x00
+ and the link local addressing is used. Start searching
+ a free LinkLayer IP-address. Next state will be
+ 'eGetLinkLayerAddress'. */
+ prvPrepareLinkLayerIPLookUp();
+
+ /* Setting an IP address manually so set to not using
+ leased address mode. */
+ xDHCPData.eDHCPState = eGetLinkLayerAddress;
+ }
+ #else
+ {
+ xGivingUp = pdTRUE;
+ }
+ #endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
+ }
+ }
+ break;
+
+ case eWaitingAcknowledge :
+
+ /* Look for acks coming in. */
+ if( prvProcessDHCPReplies( dhcpMESSAGE_TYPE_ACK ) == pdPASS )
+ {
+ FreeRTOS_debug_printf( ( "vDHCPProcess: acked %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
+
+ /* DHCP completed. The IP address can now be used, and the
+ timer set to the lease timeout time. */
+ *ipLOCAL_IP_ADDRESS_POINTER = xDHCPData.ulOfferedIPAddress;
+
+ /* Setting the 'local' broadcast address, something like
+ '192.168.1.255'. */
+ xNetworkAddressing.ulBroadcastAddress = ( xDHCPData.ulOfferedIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
+ xDHCPData.eDHCPState = eLeasedAddress;
+
+ iptraceDHCP_SUCCEDEED( xDHCPData.ulOfferedIPAddress );
+
+ /* DHCP failed, the default configured IP-address will be used
+ Now call vIPNetworkUpCalls() to send the network-up event and
+ start the ARP timer. */
+ vIPNetworkUpCalls( );
+
+ /* Close socket to ensure packets don't queue on it. */
+ vSocketClose( xDHCPData.xDHCPSocket );
+ xDHCPData.xDHCPSocket = NULL;
+
+ if( xDHCPData.ulLeaseTime == 0UL )
+ {
+ xDHCPData.ulLeaseTime = dhcpDEFAULT_LEASE_TIME;
+ }
+ else if( xDHCPData.ulLeaseTime < dhcpMINIMUM_LEASE_TIME )
+ {
+ xDHCPData.ulLeaseTime = dhcpMINIMUM_LEASE_TIME;
+ }
+ else
+ {
+ /* The lease time is already valid. */
+ }
+
+ /* Check for clashes. */
+ vARPSendGratuitous();
+ vIPReloadDHCPTimer( xDHCPData.ulLeaseTime );
+ }
+ else
+ {
+ /* Is it time to send another Discover? */
+ if( ( xTaskGetTickCount() - xDHCPData.xDHCPTxTime ) > xDHCPData.xDHCPTxPeriod )
+ {
+ /* Increase the time period, and if it has not got to the
+ point of giving up - send another request. */
+ xDHCPData.xDHCPTxPeriod <<= 1;
+
+ if( xDHCPData.xDHCPTxPeriod <= ipconfigMAXIMUM_DISCOVER_TX_PERIOD )
+ {
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount();
+ prvSendDHCPRequest( );
+ }
+ else
+ {
+ /* Give up, start again. */
+ xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
+ }
+ }
+ }
+ break;
+
+ #if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+ case eGetLinkLayerAddress:
+ if( ( xTaskGetTickCount() - xDHCPData.xDHCPTxTime ) > xDHCPData.xDHCPTxPeriod )
+ {
+ if( xARPHadIPClash == pdFALSE )
+ {
+ /* ARP OK. proceed. */
+ iptraceDHCP_SUCCEDEED( xDHCPData.ulOfferedIPAddress );
+
+ /* Auto-IP succeeded, the default configured IP-address will
+ be used. Now call vIPNetworkUpCalls() to send the
+ network-up event and start the ARP timer. */
+ vIPNetworkUpCalls( );
+ xDHCPData.eDHCPState = eNotUsingLeasedAddress;
+ }
+ else
+ {
+ /* ARP clashed - try another IP address. */
+ prvPrepareLinkLayerIPLookUp();
+
+ /* Setting an IP address manually so set to not using leased
+ address mode. */
+ xDHCPData.eDHCPState = eGetLinkLayerAddress;
+ }
+ }
+ break;
+ #endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
+
+ case eLeasedAddress :
+
+ /* Resend the request at the appropriate time to renew the lease. */
+ prvCreateDHCPSocket();
+
+ if( xDHCPData.xDHCPSocket != NULL )
+ {
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount();
+ xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
+ prvSendDHCPRequest( );
+ xDHCPData.eDHCPState = eWaitingAcknowledge;
+
+ /* From now on, we should be called more often */
+ vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
+ }
+ break;
+
+ case eNotUsingLeasedAddress:
+
+ vIPSetDHCPTimerEnableState( pdFALSE );
+ break;
+
+ default:
+ break;
+ }
+
+ if( xGivingUp != pdFALSE )
+ {
+ /* xGivingUp became true either because of a time-out, or because
+ xApplicationDHCPHook() returned another value than 'eDHCPContinue',
+ meaning that the conversion is canceled from here. */
+
+ /* Revert to static IP address. */
+ taskENTER_CRITICAL();
+ {
+ *ipLOCAL_IP_ADDRESS_POINTER = xNetworkAddressing.ulDefaultIPAddress;
+ iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS( xNetworkAddressing.ulDefaultIPAddress );
+ }
+ taskEXIT_CRITICAL();
+
+ xDHCPData.eDHCPState = eNotUsingLeasedAddress;
+ vIPSetDHCPTimerEnableState( pdFALSE );
+
+ /* DHCP failed, the default configured IP-address will be used. Now
+ call vIPNetworkUpCalls() to send the network-up event and start the ARP
+ timer. */
+ vIPNetworkUpCalls( );
+
+ /* Test if socket was indeed created. */
+ if( xDHCPData.xDHCPSocket != NULL )
+ {
+ /* Close socket to ensure packets don't queue on it. */
+ vSocketClose( xDHCPData.xDHCPSocket );
+ xDHCPData.xDHCPSocket = NULL;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateDHCPSocket( void )
+{
+struct freertos_sockaddr xAddress;
+BaseType_t xReturn;
+TickType_t xTimeoutTime = ( TickType_t ) 0;
+
+ /* Create the socket, if it has not already been created. */
+ if( xDHCPData.xDHCPSocket == NULL )
+ {
+ xDHCPData.xDHCPSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
+ if( xDHCPData.xDHCPSocket != FREERTOS_INVALID_SOCKET )
+ {
+
+ /* Ensure the Rx and Tx timeouts are zero as the DHCP executes in the
+ context of the IP task. */
+ FreeRTOS_setsockopt( xDHCPData.xDHCPSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &xTimeoutTime, sizeof( TickType_t ) );
+ FreeRTOS_setsockopt( xDHCPData.xDHCPSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &xTimeoutTime, sizeof( TickType_t ) );
+
+ /* Bind to the standard DHCP client port. */
+ xAddress.sin_port = ( uint16_t ) dhcpCLIENT_PORT;
+ xReturn = vSocketBind( xDHCPData.xDHCPSocket, &xAddress, sizeof( xAddress ), pdFALSE );
+ if( xReturn != 0 )
+ {
+ /* Binding failed, close the socket again. */
+ vSocketClose( xDHCPData.xDHCPSocket );
+ xDHCPData.xDHCPSocket = NULL;
+ }
+ }
+ else
+ {
+ /* Change to NULL for easier testing. */
+ xDHCPData.xDHCPSocket = NULL;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvInitialiseDHCP( void )
+{
+ /* Initialise the parameters that will be set by the DHCP process. Per
+ https://www.ietf.org/rfc/rfc2131.txt, Transaction ID should be a random
+ value chosen by the client. */
+
+ /* Check for random number generator API failure. */
+ if( xApplicationGetRandomNumber( &( xDHCPData.ulTransactionId ) ) != pdFALSE )
+ {
+ xDHCPData.xUseBroadcast = 0;
+ xDHCPData.ulOfferedIPAddress = 0UL;
+ xDHCPData.ulDHCPServerAddress = 0UL;
+ xDHCPData.xDHCPTxPeriod = dhcpINITIAL_DHCP_TX_PERIOD;
+
+ /* Create the DHCP socket if it has not already been created. */
+ prvCreateDHCPSocket();
+ FreeRTOS_debug_printf( ( "prvInitialiseDHCP: start after %lu ticks\n", dhcpINITIAL_TIMER_PERIOD ) );
+ vIPReloadDHCPTimer( dhcpINITIAL_TIMER_PERIOD );
+ }
+ else
+ {
+ /* There was a problem with the randomiser. */
+ }
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvProcessDHCPReplies( BaseType_t xExpectedMessageType )
+{
+uint8_t *pucUDPPayload, *pucLastByte;
+struct freertos_sockaddr xClient;
+uint32_t xClientLength = sizeof( xClient );
+int32_t lBytes;
+DHCPMessage_t *pxDHCPMessage;
+uint8_t *pucByte, ucOptionCode, ucLength;
+uint32_t ulProcessed, ulParameter;
+BaseType_t xReturn = pdFALSE;
+const uint32_t ulMandatoryOptions = 2ul; /* DHCP server address, and the correct DHCP message type must be present in the options. */
+
+ lBytes = FreeRTOS_recvfrom( xDHCPData.xDHCPSocket, ( void * ) &pucUDPPayload, 0ul, FREERTOS_ZERO_COPY, &xClient, &xClientLength );
+
+ if( lBytes > 0 )
+ {
+ /* Map a DHCP structure onto the received data. */
+ pxDHCPMessage = ( DHCPMessage_t * ) ( pucUDPPayload );
+
+ /* Sanity check. */
+ if( ( lBytes >= sizeof( DHCPMessage_t ) ) &&
+ ( pxDHCPMessage->ulDHCPCookie == ( uint32_t ) dhcpCOOKIE ) &&
+ ( pxDHCPMessage->ucOpcode == ( uint8_t ) dhcpREPLY_OPCODE ) &&
+ ( pxDHCPMessage->ulTransactionID == FreeRTOS_htonl( xDHCPData.ulTransactionId ) ) )
+ {
+ if( memcmp( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress ),
+ ( void * ) ipLOCAL_MAC_ADDRESS,
+ sizeof( MACAddress_t ) ) == 0 )
+ {
+ /* None of the essential options have been processed yet. */
+ ulProcessed = 0ul;
+
+ /* Walk through the options until the dhcpOPTION_END_BYTE byte
+ is found, taking care not to walk off the end of the options. */
+ pucByte = &( pxDHCPMessage->ucFirstOptionByte );
+ /* Maintain a pointer to the last valid byte (i.e. not the first
+ invalid byte). */
+ pucLastByte = pucUDPPayload + lBytes - 1;
+
+ while( pucByte <= pucLastByte )
+ {
+ ucOptionCode = pucByte[ 0 ];
+ if( ucOptionCode == dhcpOPTION_END_BYTE )
+ {
+ /* Ready, the last byte has been seen. */
+ break;
+ }
+ if( ucOptionCode == dhcpZERO_PAD_OPTION_CODE )
+ {
+ /* The value zero is used as a pad byte,
+ it is not followed by a length byte. */
+ pucByte += 1;
+ continue;
+ }
+
+ /* Stop if the response is malformed. */
+ if( pucByte < pucLastByte )
+ {
+ /* There are at least two bytes left. */
+ ucLength = pucByte[ 1 ];
+ pucByte += 2;
+
+ if( pucByte + ucLength > pucLastByte )
+ {
+ break;
+ }
+ }
+ else
+ {
+ break;
+ }
+
+ /* In most cases, a 4-byte network-endian parameter follows,
+ just get it once here and use later. */
+ if( ucLength >= sizeof( ulParameter ) )
+ {
+ memcpy( ( void * ) &( ulParameter ),
+ ( void * ) pucByte,
+ ( size_t ) sizeof( ulParameter ) );
+ }
+ else
+ {
+ ulParameter = 0;
+ }
+
+ /* Option-specific handling. */
+ switch( ucOptionCode )
+ {
+ case dhcpMESSAGE_TYPE_OPTION_CODE :
+
+ if( *pucByte == ( uint8_t ) xExpectedMessageType )
+ {
+ /* The message type is the message type the
+ state machine is expecting. */
+ ulProcessed++;
+ }
+ else if( *pucByte == ( uint8_t ) dhcpMESSAGE_TYPE_NACK )
+ {
+ if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_ACK )
+ {
+ /* Start again. */
+ xDHCPData.eDHCPState = eWaitingSendFirstDiscover;
+ }
+ }
+ else
+ {
+ /* Don't process other message types. */
+ }
+ break;
+
+ case dhcpSUBNET_MASK_OPTION_CODE :
+
+ if( ucLength == sizeof( uint32_t ) )
+ {
+ xNetworkAddressing.ulNetMask = ulParameter;
+ }
+ break;
+
+ case dhcpGATEWAY_OPTION_CODE :
+
+ if( ucLength == sizeof( uint32_t ) )
+ {
+ /* ulProcessed is not incremented in this case
+ because the gateway is not essential. */
+ xNetworkAddressing.ulGatewayAddress = ulParameter;
+ }
+ break;
+
+ case dhcpDNS_SERVER_OPTIONS_CODE :
+
+ /* ulProcessed is not incremented in this case
+ because the DNS server is not essential. Only the
+ first DNS server address is taken. */
+ xNetworkAddressing.ulDNSServerAddress = ulParameter;
+ break;
+
+ case dhcpSERVER_IP_ADDRESS_OPTION_CODE :
+
+ if( ucLength == sizeof( uint32_t ) )
+ {
+ if( xExpectedMessageType == ( BaseType_t ) dhcpMESSAGE_TYPE_OFFER )
+ {
+ /* Offers state the replying server. */
+ ulProcessed++;
+ xDHCPData.ulDHCPServerAddress = ulParameter;
+ }
+ else
+ {
+ /* The ack must come from the expected server. */
+ if( xDHCPData.ulDHCPServerAddress == ulParameter )
+ {
+ ulProcessed++;
+ }
+ }
+ }
+ break;
+
+ case dhcpLEASE_TIME_OPTION_CODE :
+
+ if( ucLength == sizeof( xDHCPData.ulLeaseTime ) )
+ {
+ /* ulProcessed is not incremented in this case
+ because the lease time is not essential. */
+ /* The DHCP parameter is in seconds, convert
+ to host-endian format. */
+ xDHCPData.ulLeaseTime = FreeRTOS_ntohl( ulParameter );
+
+ /* Divide the lease time by two to ensure a
+ renew request is sent before the lease actually
+ expires. */
+ xDHCPData.ulLeaseTime >>= 1UL;
+
+ /* Multiply with configTICK_RATE_HZ to get clock
+ ticks. */
+ xDHCPData.ulLeaseTime = configTICK_RATE_HZ * xDHCPData.ulLeaseTime;
+ }
+ break;
+
+ default :
+
+ /* Not interested in this field. */
+
+ break;
+ }
+
+ /* Jump over the data to find the next option code. */
+ if( ucLength == 0u )
+ {
+ break;
+ }
+ else
+ {
+ pucByte += ucLength;
+ }
+ }
+
+ /* Were all the mandatory options received? */
+ if( ulProcessed >= ulMandatoryOptions )
+ {
+ /* HT:endian: used to be network order */
+ xDHCPData.ulOfferedIPAddress = pxDHCPMessage->ulYourIPAddress_yiaddr;
+ FreeRTOS_printf( ( "vDHCPProcess: offer %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
+ xReturn = pdPASS;
+ }
+ }
+ }
+
+ FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayload );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static uint8_t *prvCreatePartDHCPMessage( struct freertos_sockaddr *pxAddress, BaseType_t xOpcode, const uint8_t * const pucOptionsArray, size_t *pxOptionsArraySize )
+{
+DHCPMessage_t *pxDHCPMessage;
+size_t xRequiredBufferSize = sizeof( DHCPMessage_t ) + *pxOptionsArraySize;
+uint8_t *pucUDPPayloadBuffer;
+
+#if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
+ const char *pucHostName = pcApplicationHostnameHook ();
+ size_t xNameLength = strlen( pucHostName );
+ uint8_t *pucPtr;
+
+ xRequiredBufferSize += ( 2 + xNameLength );
+#endif
+
+ /* Get a buffer. This uses a maximum delay, but the delay will be capped
+ to ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS so the return value still needs to
+ be test. */
+ do
+ {
+ } while( ( pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( xRequiredBufferSize, portMAX_DELAY ) ) == NULL );
+
+ pxDHCPMessage = ( DHCPMessage_t * ) pucUDPPayloadBuffer;
+
+ /* Most fields need to be zero. */
+ memset( ( void * ) pxDHCPMessage, 0x00, sizeof( DHCPMessage_t ) );
+
+ /* Create the message. */
+ pxDHCPMessage->ucOpcode = ( uint8_t ) xOpcode;
+ pxDHCPMessage->ucAddressType = ( uint8_t ) dhcpADDRESS_TYPE_ETHERNET;
+ pxDHCPMessage->ucAddressLength = ( uint8_t ) dhcpETHERNET_ADDRESS_LENGTH;
+ pxDHCPMessage->ulTransactionID = FreeRTOS_htonl( xDHCPData.ulTransactionId );
+ pxDHCPMessage->ulDHCPCookie = ( uint32_t ) dhcpCOOKIE;
+ if( xDHCPData.xUseBroadcast != pdFALSE )
+ {
+ pxDHCPMessage->usFlags = ( uint16_t ) dhcpBROADCAST;
+ }
+ else
+ {
+ pxDHCPMessage->usFlags = 0u;
+ }
+
+ memcpy( ( void * ) &( pxDHCPMessage->ucClientHardwareAddress[ 0 ] ), ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
+
+ /* Copy in the const part of the options options. */
+ memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET ] ), ( void * ) pucOptionsArray, *pxOptionsArraySize );
+
+ #if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
+ {
+ /* With this option, the hostname can be registered as well which makes
+ it easier to lookup a device in a router's list of DHCP clients. */
+
+ /* Point to where the OPTION_END was stored to add data. */
+ pucPtr = &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + ( *pxOptionsArraySize - 1 ) ] );
+ pucPtr[ 0 ] = dhcpDNS_HOSTNAME_OPTIONS_CODE;
+ pucPtr[ 1 ] = ( uint8_t ) xNameLength;
+ memcpy( ( void *) ( pucPtr + 2 ), pucHostName, xNameLength );
+ pucPtr[ 2 + xNameLength ] = dhcpOPTION_END_BYTE;
+ *pxOptionsArraySize += ( 2 + xNameLength );
+ }
+ #endif
+
+ /* Map in the client identifier. */
+ memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpCLIENT_IDENTIFIER_OFFSET ] ),
+ ( void * ) ipLOCAL_MAC_ADDRESS, sizeof( MACAddress_t ) );
+
+ /* Set the addressing. */
+ pxAddress->sin_addr = ipBROADCAST_IP_ADDRESS;
+ pxAddress->sin_port = ( uint16_t ) dhcpSERVER_PORT;
+
+ return pucUDPPayloadBuffer;
+}
+/*-----------------------------------------------------------*/
+
+static void prvSendDHCPRequest( void )
+{
+uint8_t *pucUDPPayloadBuffer;
+struct freertos_sockaddr xAddress;
+static const uint8_t ucDHCPRequestOptions[] =
+{
+ /* Do not change the ordering without also changing
+ dhcpCLIENT_IDENTIFIER_OFFSET, dhcpREQUESTED_IP_ADDRESS_OFFSET and
+ dhcpDHCP_SERVER_IP_ADDRESS_OFFSET. */
+ dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_REQUEST, /* Message type option. */
+ dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
+ dhcpREQUEST_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address being requested. */
+ dhcpSERVER_IP_ADDRESS_OPTION_CODE, 4, 0, 0, 0, 0, /* The IP address of the DHCP server. */
+ dhcpOPTION_END_BYTE
+};
+size_t xOptionsLength = sizeof( ucDHCPRequestOptions );
+
+ pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPRequestOptions, &xOptionsLength );
+
+ /* Copy in the IP address being requested. */
+ memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpREQUESTED_IP_ADDRESS_OFFSET ] ),
+ ( void * ) &( xDHCPData.ulOfferedIPAddress ), sizeof( xDHCPData.ulOfferedIPAddress ) );
+
+ /* Copy in the address of the DHCP server being used. */
+ memcpy( ( void * ) &( pucUDPPayloadBuffer[ dhcpFIRST_OPTION_BYTE_OFFSET + dhcpDHCP_SERVER_IP_ADDRESS_OFFSET ] ),
+ ( void * ) &( xDHCPData.ulDHCPServerAddress ), sizeof( xDHCPData.ulDHCPServerAddress ) );
+
+ FreeRTOS_debug_printf( ( "vDHCPProcess: reply %lxip\n", FreeRTOS_ntohl( xDHCPData.ulOfferedIPAddress ) ) );
+ iptraceSENDING_DHCP_REQUEST();
+
+ /* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
+ if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
+ {
+ /* The packet was not successfully queued for sending and must be
+ returned to the stack. */
+ FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvSendDHCPDiscover( void )
+{
+uint8_t *pucUDPPayloadBuffer;
+struct freertos_sockaddr xAddress;
+static const uint8_t ucDHCPDiscoverOptions[] =
+{
+ /* Do not change the ordering without also changing dhcpCLIENT_IDENTIFIER_OFFSET. */
+ dhcpMESSAGE_TYPE_OPTION_CODE, 1, dhcpMESSAGE_TYPE_DISCOVER, /* Message type option. */
+ dhcpCLIENT_IDENTIFIER_OPTION_CODE, 6, 0, 0, 0, 0, 0, 0, /* Client identifier. */
+ dhcpPARAMETER_REQUEST_OPTION_CODE, 3, dhcpSUBNET_MASK_OPTION_CODE, dhcpGATEWAY_OPTION_CODE, dhcpDNS_SERVER_OPTIONS_CODE, /* Parameter request option. */
+ dhcpOPTION_END_BYTE
+};
+size_t xOptionsLength = sizeof( ucDHCPDiscoverOptions );
+
+ pucUDPPayloadBuffer = prvCreatePartDHCPMessage( &xAddress, dhcpREQUEST_OPCODE, ucDHCPDiscoverOptions, &xOptionsLength );
+
+ FreeRTOS_debug_printf( ( "vDHCPProcess: discover\n" ) );
+ iptraceSENDING_DHCP_DISCOVER();
+
+ /* 'ucFirstOptionByte' is part of DHCP message struct, so subtract one byte. */
+ if( FreeRTOS_sendto( xDHCPData.xDHCPSocket, pucUDPPayloadBuffer, ( sizeof( DHCPMessage_t ) + xOptionsLength - 1 ), FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) == 0 )
+ {
+ /* The packet was not successfully queued for sending and must be
+ returned to the stack. */
+ FreeRTOS_ReleaseUDPPayloadBuffer( pucUDPPayloadBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+
+ static void prvPrepareLinkLayerIPLookUp( void )
+ {
+ uint8_t ucLinkLayerIPAddress[ 2 ];
+ uint32_t ulNumbers[ 2 ];
+
+ /* After DHCP has failed to answer, prepare everything to start
+ trying-out LinkLayer IP-addresses, using the random method. */
+ xDHCPData.xDHCPTxTime = xTaskGetTickCount();
+
+ xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );
+ xApplicationGetRandomNumber( &( ulNumbers[ 1 ] ) );
+ ucLinkLayerIPAddress[ 0 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 0 ] % 0xFDu ); /* get value 1..254 for IP-address 3rd byte of IP address to try. */
+ ucLinkLayerIPAddress[ 1 ] = ( uint8_t )1 + ( uint8_t )( ulNumbers[ 1 ] % 0xFDu ); /* get value 1..254 for IP-address 4th byte of IP address to try. */
+
+ xNetworkAddressing.ulGatewayAddress = FreeRTOS_htonl( 0xA9FE0203 );
+
+ /* prepare xDHCPData with data to test. */
+ xDHCPData.ulOfferedIPAddress =
+ FreeRTOS_inet_addr_quick( LINK_LAYER_ADDRESS_0, LINK_LAYER_ADDRESS_1, ucLinkLayerIPAddress[ 0 ], ucLinkLayerIPAddress[ 1 ] );
+
+ xDHCPData.ulLeaseTime = dhcpDEFAULT_LEASE_TIME; /* don't care about lease time. just put anything. */
+
+ xNetworkAddressing.ulNetMask =
+ FreeRTOS_inet_addr_quick( LINK_LAYER_NETMASK_0, LINK_LAYER_NETMASK_1, LINK_LAYER_NETMASK_2, LINK_LAYER_NETMASK_3 );
+
+ /* DHCP completed. The IP address can now be used, and the
+ timer set to the lease timeout time. */
+ *ipLOCAL_IP_ADDRESS_POINTER = xDHCPData.ulOfferedIPAddress;
+
+ /* Setting the 'local' broadcast address, something like 192.168.1.255' */
+ xNetworkAddressing.ulBroadcastAddress = ( xDHCPData.ulOfferedIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
+
+ /* Close socket to ensure packets don't queue on it. not needed anymore as DHCP failed. but still need timer for ARP testing. */
+ if( xDHCPData.xDHCPSocket != NULL )
+ {
+ /* Close socket to ensure packets don't queue on it. */
+ vSocketClose( xDHCPData.xDHCPSocket );
+ xDHCPData.xDHCPSocket = NULL;
+ }
+
+ xApplicationGetRandomNumber( &( ulNumbers[ 0 ] ) );
+ xDHCPData.xDHCPTxPeriod = pdMS_TO_TICKS( 3000ul + ( ulNumbers[ 0 ] & 0x3ffuL ) ); /* do ARP test every (3 + 0-1024mS) seconds. */
+
+ xARPHadIPClash = pdFALSE; /* reset flag that shows if have ARP clash. */
+ vARPSendGratuitous();
+ }
+
+#endif /* ipconfigDHCP_FALL_BACK_AUTO_IP */
+/*-----------------------------------------------------------*/
+
+#endif /* ipconfigUSE_DHCP != 0 */
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
index 43b246d26..d4f167af1 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_DNS.c
@@ -1,1556 +1,1556 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "list.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_DNS.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-#include "IPTraceMacroDefaults.h"
-
-/* Exclude the entire file if DNS is not enabled. */
-#if( ipconfigUSE_DNS != 0 )
-
-#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
- #define dnsDNS_PORT 0x3500u
- #define dnsONE_QUESTION 0x0100u
- #define dnsOUTGOING_FLAGS 0x0001u /* Standard query. */
- #define dnsRX_FLAGS_MASK 0x0f80u /* The bits of interest in the flags field of incoming DNS messages. */
- #define dnsEXPECTED_RX_FLAGS 0x0080u /* Should be a response, without any errors. */
-#else
- #define dnsDNS_PORT 0x0035u
- #define dnsONE_QUESTION 0x0001u
- #define dnsOUTGOING_FLAGS 0x0100u /* Standard query. */
- #define dnsRX_FLAGS_MASK 0x800fu /* The bits of interest in the flags field of incoming DNS messages. */
- #define dnsEXPECTED_RX_FLAGS 0x8000u /* Should be a response, without any errors. */
-
-#endif /* ipconfigBYTE_ORDER */
-
-/* The maximum number of times a DNS request should be sent out if a response
-is not received, before giving up. */
-#ifndef ipconfigDNS_REQUEST_ATTEMPTS
- #define ipconfigDNS_REQUEST_ATTEMPTS 5
-#endif
-
-/* If the top two bits in the first character of a name field are set then the
-name field is an offset to the string, rather than the string itself. */
-#define dnsNAME_IS_OFFSET ( ( uint8_t ) 0xc0 )
-
-/* NBNS flags. */
-#define dnsNBNS_FLAGS_RESPONSE 0x8000u
-#define dnsNBNS_FLAGS_OPCODE_MASK 0x7800u
-#define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000u
-#define dnsNBNS_FLAGS_OPCODE_REGISTRATION 0x2800u
-
-/* Host types. */
-#define dnsTYPE_A_HOST 0x01u
-#define dnsCLASS_IN 0x01u
-
-/* LLMNR constants. */
-#define dnsLLMNR_TTL_VALUE 300000uL
-#define dnsLLMNR_FLAGS_IS_REPONSE 0x8000u
-
-/* NBNS constants. */
-#define dnsNBNS_TTL_VALUE 3600uL /* 1 hour valid */
-#define dnsNBNS_TYPE_NET_BIOS 0x0020u
-#define dnsNBNS_CLASS_IN 0x01u
-#define dnsNBNS_NAME_FLAGS 0x6000u
-#define dnsNBNS_ENCODED_NAME_LENGTH 32
-
-/* If the queried NBNS name matches with the device's name,
-the query will be responded to with these flags: */
-#define dnsNBNS_QUERY_RESPONSE_FLAGS ( 0x8500u )
-
-/* Flag DNS parsing errors in situations where an IPv4 address is the return
-type. */
-#define dnsPARSE_ERROR 0uL
-
-/*
- * Create a socket and bind it to the standard DNS port number. Return the
- * the created socket - or NULL if the socket could not be created or bound.
- */
-static Socket_t prvCreateDNSSocket( void );
-
-/*
- * Create the DNS message in the zero copy buffer passed in the first parameter.
- */
-static size_t prvCreateDNSMessage( uint8_t *pucUDPPayloadBuffer,
- const char *pcHostName,
- TickType_t uxIdentifier );
-
-/*
- * Simple routine that jumps over the NAME field of a resource record.
- */
-static uint8_t * prvSkipNameField( uint8_t *pucByte,
- size_t uxSourceLen );
-
-/*
- * Process a response packet from a DNS server.
- * The parameter 'xExpected' indicates whether the identifier in the reply
- * was expected, and thus if the DNS cache may be updated with the reply.
- */
-static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer,
- size_t uxBufferLength,
- BaseType_t xExpected );
-
-/*
- * Prepare and send a message to a DNS server. 'uxReadTimeOut_ticks' will be passed as
- * zero, in case the user has supplied a call-back function.
- */
-static uint32_t prvGetHostByName( const char *pcHostName,
- TickType_t uxIdentifier,
- TickType_t uxReadTimeOut_ticks );
-
-/*
- * The NBNS and the LLMNR protocol share this reply function.
- */
-#if( ( ipconfigUSE_NBNS == 1 ) || ( ipconfigUSE_LLMNR == 1 ) )
- static void prvReplyDNSMessage( NetworkBufferDescriptor_t *pxNetworkBuffer,
- BaseType_t lNetLength );
-#endif
-
-#if( ipconfigUSE_NBNS == 1 )
- static portINLINE void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer,
- size_t uxBufferLength,
- uint32_t ulIPAddress );
-#endif /* ipconfigUSE_NBNS */
-
-
-#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
- static uint8_t * prvReadNameField( uint8_t *pucByte,
- size_t uxSourceLen,
- char *pcName,
- size_t uxLen );
-#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
-
-#if( ipconfigUSE_DNS_CACHE == 1 )
- static void prvProcessDNSCache( const char *pcName,
- uint32_t *pulIP,
- uint32_t ulTTL,
- BaseType_t xLookUp );
-
- typedef struct xDNS_CACHE_TABLE_ROW
- {
- uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
- char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ]; /* The name of the host */
- uint32_t ulTTL; /* Time-to-Live (in seconds) from the DNS server. */
- uint32_t ulTimeWhenAddedInSeconds;
- } DNSCacheRow_t;
-
- static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
-
- void FreeRTOS_dnsclear()
- {
- memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
- }
-#endif /* ipconfigUSE_DNS_CACHE == 1 */
-
-#if( ipconfigUSE_LLMNR == 1 )
- const MACAddress_t xLLMNR_MacAdress = { { 0x01, 0x00, 0x5e, 0x00, 0x00, 0xfc } };
-#endif /* ipconfigUSE_LLMNR == 1 */
-
-/*-----------------------------------------------------------*/
-
-#include "pack_struct_start.h"
-struct xDNSMessage
-{
- uint16_t usIdentifier;
- uint16_t usFlags;
- uint16_t usQuestions;
- uint16_t usAnswers;
- uint16_t usAuthorityRRs;
- uint16_t usAdditionalRRs;
-}
-#include "pack_struct_end.h"
-typedef struct xDNSMessage DNSMessage_t;
-
-/* A DNS query consists of a header, as described in 'struct xDNSMessage'
-It is followed by 1 or more queries, each one consisting of a name and a tail,
-with two fields: type and class
-*/
-#include "pack_struct_start.h"
-struct xDNSTail
-{
- uint16_t usType;
- uint16_t usClass;
-}
-#include "pack_struct_end.h"
-typedef struct xDNSTail DNSTail_t;
-
-/* DNS answer record header. */
-#include "pack_struct_start.h"
-struct xDNSAnswerRecord
-{
- uint16_t usType;
- uint16_t usClass;
- uint32_t ulTTL;
- uint16_t usDataLength;
-}
-#include "pack_struct_end.h"
-typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
-
-#if( ipconfigUSE_LLMNR == 1 )
-
- #include "pack_struct_start.h"
- struct xLLMNRAnswer
- {
- uint8_t ucNameCode;
- uint8_t ucNameOffset; /* The name is not repeated in the answer, only the offset is given with "0xc0 <offs>" */
- uint16_t usType;
- uint16_t usClass;
- uint32_t ulTTL;
- uint16_t usDataLength;
- uint32_t ulIPAddress;
- }
- #include "pack_struct_end.h"
- typedef struct xLLMNRAnswer LLMNRAnswer_t;
-
-#endif /* ipconfigUSE_LLMNR == 1 */
-
-#if( ipconfigUSE_NBNS == 1 )
-
- #include "pack_struct_start.h"
- struct xNBNSRequest
- {
- uint16_t usRequestId;
- uint16_t usFlags;
- uint16_t ulRequestCount;
- uint16_t usAnswerRSS;
- uint16_t usAuthRSS;
- uint16_t usAdditionalRSS;
- uint8_t ucNameSpace;
- uint8_t ucName[ dnsNBNS_ENCODED_NAME_LENGTH ];
- uint8_t ucNameZero;
- uint16_t usType;
- uint16_t usClass;
- }
- #include "pack_struct_end.h"
- typedef struct xNBNSRequest NBNSRequest_t;
-
- #include "pack_struct_start.h"
- struct xNBNSAnswer
- {
- uint16_t usType;
- uint16_t usClass;
- uint32_t ulTTL;
- uint16_t usDataLength;
- uint16_t usNbFlags; /* NetBIOS flags 0x6000 : IP-address, big-endian */
- uint32_t ulIPAddress;
- }
- #include "pack_struct_end.h"
- typedef struct xNBNSAnswer NBNSAnswer_t;
-
- #endif /* ipconfigUSE_NBNS == 1 */
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_DNS_CACHE == 1 )
- uint32_t FreeRTOS_dnslookup( const char *pcHostName )
- {
- uint32_t ulIPAddress = 0uL;
-
- prvProcessDNSCache( pcHostName, &ulIPAddress, 0, pdTRUE );
- return ulIPAddress;
- }
-#endif /* ipconfigUSE_DNS_CACHE == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigDNS_USE_CALLBACKS == 1 )
-
- typedef struct xDNS_Callback
- {
- TickType_t uxRemaningTime; /* Timeout in ms */
- FOnDNSEvent pCallbackFunction; /* Function to be called when the address has been found or when a timeout has beeen reached */
- TimeOut_t uxTimeoutState;
- void *pvSearchID;
- struct xLIST_ITEM xListItem;
- char pcName[ 1 ];
- } DNSCallback_t;
-
- static List_t xCallbackList;
-
- /* Define FreeRTOS_gethostbyname() as a normal blocking call. */
- uint32_t FreeRTOS_gethostbyname( const char *pcHostName )
- {
- return FreeRTOS_gethostbyname_a( pcHostName, ( FOnDNSEvent ) NULL, ( void * ) NULL, 0 );
- }
- /*-----------------------------------------------------------*/
-
- /* Initialise the list of call-back structures. */
- void vDNSInitialise( void );
- void vDNSInitialise( void )
- {
- vListInitialise( &xCallbackList );
- }
- /*-----------------------------------------------------------*/
-
- /* Iterate through the list of call-back structures and remove
- old entries which have reached a timeout.
- As soon as the list hase become empty, the DNS timer will be stopped
- In case pvSearchID is supplied, the user wants to cancel a DNS request
- */
- void vDNSCheckCallBack( void *pvSearchID );
- void vDNSCheckCallBack( void *pvSearchID )
- {
- const ListItem_t *pxIterator;
- const MiniListItem_t * xEnd = ( const MiniListItem_t * ) listGET_END_MARKER( &xCallbackList );
-
- vTaskSuspendAll();
- {
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
- pxIterator != ( const ListItem_t * ) xEnd;
- )
- {
- DNSCallback_t *pxCallback = ( DNSCallback_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
-
- /* Move to the next item because we might remove this item */
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
-
- if( ( pvSearchID != NULL ) && ( pvSearchID == pxCallback->pvSearchID ) )
- {
- uxListRemove( &pxCallback->xListItem );
- vPortFree( pxCallback );
- }
- else if( xTaskCheckForTimeOut( &pxCallback->uxTimeoutState, &pxCallback->uxRemaningTime ) != pdFALSE )
- {
- pxCallback->pCallbackFunction( pxCallback->pcName, pxCallback->pvSearchID, 0 );
- uxListRemove( &pxCallback->xListItem );
- vPortFree( ( void * ) pxCallback );
- }
- }
- }
- xTaskResumeAll();
-
- if( listLIST_IS_EMPTY( &xCallbackList ) )
- {
- vIPSetDnsTimerEnableState( pdFALSE );
- }
- }
- /*-----------------------------------------------------------*/
-
- void FreeRTOS_gethostbyname_cancel( void *pvSearchID )
- {
- /* _HT_ Should better become a new API call to have the IP-task remove the callback */
- vDNSCheckCallBack( pvSearchID );
- }
- /*-----------------------------------------------------------*/
-
- /* FreeRTOS_gethostbyname_a() was called along with callback parameters.
- Store them in a list for later reference. */
- static void vDNSSetCallBack( const char *pcHostName,
- void *pvSearchID,
- FOnDNSEvent pCallbackFunction,
- TickType_t uxTimeout,
- TickType_t uxIdentifier );
- static void vDNSSetCallBack( const char *pcHostName,
- void *pvSearchID,
- FOnDNSEvent pCallbackFunction,
- TickType_t uxTimeout,
- TickType_t uxIdentifier )
- {
- size_t lLength = strlen( pcHostName );
- DNSCallback_t *pxCallback = ( DNSCallback_t * ) pvPortMalloc( sizeof( *pxCallback ) + lLength );
-
- /* Translate from ms to number of clock ticks. */
- uxTimeout /= portTICK_PERIOD_MS;
-
- if( pxCallback != NULL )
- {
- if( listLIST_IS_EMPTY( &xCallbackList ) )
- {
- /* This is the first one, start the DNS timer to check for timeouts */
- vIPReloadDNSTimer( FreeRTOS_min_uint32( 1000U, uxTimeout ) );
- }
-
- strcpy( pxCallback->pcName, pcHostName );
- pxCallback->pCallbackFunction = pCallbackFunction;
- pxCallback->pvSearchID = pvSearchID;
- pxCallback->uxRemaningTime = uxTimeout;
- vTaskSetTimeOutState( &pxCallback->uxTimeoutState );
- listSET_LIST_ITEM_OWNER( &( pxCallback->xListItem ), ( void * ) pxCallback );
- listSET_LIST_ITEM_VALUE( &( pxCallback->xListItem ), uxIdentifier );
- vTaskSuspendAll();
- {
- vListInsertEnd( &xCallbackList, &pxCallback->xListItem );
- }
- xTaskResumeAll();
- }
- }
- /*-----------------------------------------------------------*/
-
- /* A DNS reply was received, see if there is any matching entry and
- call the handler. Returns pdTRUE if uxIdentifier was recognised. */
- static BaseType_t xDNSDoCallback( TickType_t uxIdentifier,
- const char *pcName,
- uint32_t ulIPAddress );
- static BaseType_t xDNSDoCallback( TickType_t uxIdentifier,
- const char *pcName,
- uint32_t ulIPAddress )
- {
- BaseType_t xResult = pdFALSE;
- const ListItem_t *pxIterator;
- const MiniListItem_t * xEnd = ( const MiniListItem_t * ) listGET_END_MARKER( &xCallbackList );
-
- vTaskSuspendAll();
- {
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
- pxIterator != ( const ListItem_t * ) xEnd;
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- /* The cast will take away the 'configLIST_VOLATILE' */
- if( uxIdentifier == ( TickType_t ) listGET_LIST_ITEM_VALUE( pxIterator ) )
- {
- DNSCallback_t *pxCallback = ( DNSCallback_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
-
- pxCallback->pCallbackFunction( pcName, pxCallback->pvSearchID, ulIPAddress );
- uxListRemove( &pxCallback->xListItem );
- vPortFree( pxCallback );
-
- if( listLIST_IS_EMPTY( &xCallbackList ) )
- {
- /* The list of outstanding requests is empty. No need for periodic polling. */
- vIPSetDnsTimerEnableState( pdFALSE );
- }
-
- xResult = pdTRUE;
- break;
- }
- }
- }
- xTaskResumeAll();
- return xResult;
- }
-
-#endif /* ipconfigDNS_USE_CALLBACKS == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigDNS_USE_CALLBACKS == 0 )
- uint32_t FreeRTOS_gethostbyname( const char *pcHostName )
-#else
- uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName,
- FOnDNSEvent pCallback,
- void *pvSearchID,
- TickType_t uxTimeout )
-#endif
-{
-uint32_t ulIPAddress = 0uL;
-TickType_t uxReadTimeOut_ticks = ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS;
-TickType_t uxIdentifier = 0u;
-BaseType_t xHasRandom = pdFALSE;
-
- if( pcHostName != NULL )
- {
- /* If the supplied hostname is IP address, convert it to uint32_t
- and return. */
- #if( ipconfigINCLUDE_FULL_INET_ADDR == 1 )
- {
- ulIPAddress = FreeRTOS_inet_addr( pcHostName );
- }
- #endif /* ipconfigINCLUDE_FULL_INET_ADDR == 1 */
-
- /* If a DNS cache is used then check the cache before issuing another DNS
- request. */
- #if( ipconfigUSE_DNS_CACHE == 1 )
- {
- if( ulIPAddress == 0uL )
- {
- ulIPAddress = FreeRTOS_dnslookup( pcHostName );
-
- if( ulIPAddress != 0 )
- {
- FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
- }
- else
- {
- /* prvGetHostByName will be called to start a DNS lookup. */
- }
- }
- }
- #endif /* ipconfigUSE_DNS_CACHE == 1 */
-
- /* Generate a unique identifier. */
- if( ulIPAddress == 0uL )
- {
- uint32_t ulNumber;
-
- xHasRandom = xApplicationGetRandomNumber( &( ulNumber ) );
- /* DNS identifiers are 16-bit. */
- uxIdentifier = ( TickType_t ) ( ulNumber & 0xffffu );
- /* ipconfigRAND32() may not return a non-zero value. */
- }
-
- #if( ipconfigDNS_USE_CALLBACKS == 1 )
- {
- if( pCallback != NULL )
- {
- if( ulIPAddress == 0uL )
- {
- /* The user has provided a callback function, so do not block on recvfrom() */
- if( xHasRandom != pdFALSE )
- {
- uxReadTimeOut_ticks = 0u;
- vDNSSetCallBack( pcHostName, pvSearchID, pCallback, uxTimeout, uxIdentifier );
- }
- }
- else
- {
- /* The IP address is known, do the call-back now. */
- pCallback( pcHostName, pvSearchID, ulIPAddress );
- }
- }
- }
- #endif /* if ( ipconfigDNS_USE_CALLBACKS == 1 ) */
-
- if( ( ulIPAddress == 0uL ) && ( xHasRandom != pdFALSE ) )
- {
- ulIPAddress = prvGetHostByName( pcHostName, uxIdentifier, uxReadTimeOut_ticks );
- }
- }
- return ulIPAddress;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvGetHostByName( const char *pcHostName,
- TickType_t uxIdentifier,
- TickType_t uxReadTimeOut_ticks )
-{
-struct freertos_sockaddr xAddress;
-Socket_t xDNSSocket;
-uint32_t ulIPAddress = 0uL;
-uint8_t *pucUDPPayloadBuffer;
-uint32_t ulAddressLength = sizeof( struct freertos_sockaddr );
-BaseType_t xAttempt;
-int32_t lBytes;
-size_t uxPayloadLength, uxExpectedPayloadLength;
-TickType_t uxWriteTimeOut_ticks = ipconfigDNS_SEND_BLOCK_TIME_TICKS;
-
-#if( ipconfigUSE_LLMNR == 1 )
- BaseType_t bHasDot = pdFALSE;
-#endif /* ipconfigUSE_LLMNR == 1 */
-
- /* If LLMNR is being used then determine if the host name includes a '.' -
- if not then LLMNR can be used as the lookup method. */
- #if( ipconfigUSE_LLMNR == 1 )
- {
- const char *pucPtr;
-
- for( pucPtr = pcHostName; *pucPtr; pucPtr++ )
- {
- if( *pucPtr == '.' )
- {
- bHasDot = pdTRUE;
- break;
- }
- }
- }
- #endif /* ipconfigUSE_LLMNR == 1 */
-
- /* Two is added at the end for the count of characters in the first
- subdomain part and the string end byte. */
- uxExpectedPayloadLength = sizeof( DNSMessage_t ) + strlen( pcHostName ) + sizeof( uint16_t ) + sizeof( uint16_t ) + 2u;
-
- xDNSSocket = prvCreateDNSSocket();
-
- if( xDNSSocket != NULL )
- {
- FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &uxWriteTimeOut_ticks, sizeof( TickType_t ) );
- FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &uxReadTimeOut_ticks, sizeof( TickType_t ) );
-
- for( xAttempt = 0; xAttempt < ipconfigDNS_REQUEST_ATTEMPTS; xAttempt++ )
- {
- /* Get a buffer. This uses a maximum delay, but the delay will be
- capped to ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS so the return value
- still needs to be tested. */
- pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( uxExpectedPayloadLength, portMAX_DELAY );
-
- if( pucUDPPayloadBuffer != NULL )
- {
- /* Create the message in the obtained buffer. */
- uxPayloadLength = prvCreateDNSMessage( pucUDPPayloadBuffer, pcHostName, uxIdentifier );
-
- iptraceSENDING_DNS_REQUEST();
-
- /* Obtain the DNS server address. */
- FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulIPAddress );
-
- /* Send the DNS message. */
-#if( ipconfigUSE_LLMNR == 1 )
- if( bHasDot == pdFALSE )
- {
- /* Use LLMNR addressing. */
- ( ( DNSMessage_t * ) pucUDPPayloadBuffer )->usFlags = 0;
- xAddress.sin_addr = ipLLMNR_IP_ADDR; /* Is in network byte order. */
- xAddress.sin_port = FreeRTOS_ntohs( ipLLMNR_PORT );
- }
- else
-#endif
- {
- /* Use DNS server. */
- xAddress.sin_addr = ulIPAddress;
- xAddress.sin_port = dnsDNS_PORT;
- }
-
- ulIPAddress = 0uL;
-
- if( FreeRTOS_sendto( xDNSSocket, pucUDPPayloadBuffer, uxPayloadLength, FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) != 0 )
- {
- /* Wait for the reply. */
- lBytes = FreeRTOS_recvfrom( xDNSSocket, &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xAddress, &ulAddressLength );
-
- if( lBytes > 0 )
- {
- BaseType_t xExpected;
- DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
-
- /* See if the identifiers match. */
- if( uxIdentifier == ( TickType_t ) pxDNSMessageHeader->usIdentifier )
- {
- xExpected = pdTRUE;
- }
- else
- {
- /* The reply was not expected. */
- xExpected = pdFALSE;
- }
-
- /* The reply was received. Process it. */
- #if( ipconfigDNS_USE_CALLBACKS == 0 )
- /* It is useless to analyse the unexpected reply
- unless asynchronous look-ups are enabled. */
- if( xExpected != pdFALSE )
- #endif /* ipconfigDNS_USE_CALLBACKS == 0 */
- {
- ulIPAddress = prvParseDNSReply( pucUDPPayloadBuffer, ( size_t ) lBytes, xExpected );
- }
-
- /* Finished with the buffer. The zero copy interface
- is being used, so the buffer must be freed by the
- task. */
- FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
-
- if( ulIPAddress != 0uL )
- {
- /* All done. */
- break;
- }
- }
- }
- else
- {
- /* The message was not sent so the stack will not be
- releasing the zero copy - it must be released here. */
- FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
- }
- }
-
- if( uxReadTimeOut_ticks == 0u )
- {
- /* This DNS lookup is asynchronous, using a call-back:
- send the request only once. */
- break;
- }
- }
-
- /* Finished with the socket. */
- FreeRTOS_closesocket( xDNSSocket );
- }
-
- return ulIPAddress;
-}
-/*-----------------------------------------------------------*/
-
-static size_t prvCreateDNSMessage( uint8_t *pucUDPPayloadBuffer,
- const char *pcHostName,
- TickType_t uxIdentifier )
-{
-DNSMessage_t *pxDNSMessageHeader;
-uint8_t *pucStart, *pucByte;
-DNSTail_t *pxTail;
-static const DNSMessage_t xDefaultPartDNSHeader =
-{
- 0, /* The identifier will be overwritten. */
- dnsOUTGOING_FLAGS, /* Flags set for standard query. */
- dnsONE_QUESTION, /* One question is being asked. */
- 0, /* No replies are included. */
- 0, /* No authorities. */
- 0 /* No additional authorities. */
-};
-
- /* Copy in the const part of the header. */
- memcpy( ( void * ) pucUDPPayloadBuffer, ( void * ) &xDefaultPartDNSHeader, sizeof( xDefaultPartDNSHeader ) );
-
- /* Write in a unique identifier. */
- pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
- pxDNSMessageHeader->usIdentifier = ( uint16_t ) uxIdentifier;
-
- /* Create the resource record at the end of the header. First
- find the end of the header. */
- pucStart = pucUDPPayloadBuffer + sizeof( xDefaultPartDNSHeader );
-
- /* Leave a gap for the first length bytes. */
- pucByte = pucStart + 1;
-
- /* Copy in the host name. */
- strcpy( ( char * ) pucByte, pcHostName );
-
- /* Mark the end of the string. */
- pucByte += strlen( pcHostName );
- *pucByte = 0x00u;
-
- /* Walk the string to replace the '.' characters with byte counts.
- pucStart holds the address of the byte count. Walking the string
- starts after the byte count position. */
- pucByte = pucStart;
-
- do
- {
- pucByte++;
-
- while( ( *pucByte != 0x00 ) && ( *pucByte != '.' ) )
- {
- pucByte++;
- }
-
- /* Fill in the byte count, then move the pucStart pointer up to
- the found byte position. */
- *pucStart = ( uint8_t ) ( ( uint32_t ) pucByte - ( uint32_t ) pucStart );
- ( *pucStart )--;
-
- pucStart = pucByte;
- } while( *pucByte != 0x00 );
-
- /* Finish off the record. */
-
- pxTail = ( DNSTail_t * ) ( pucByte + 1 );
-
- vSetField16( pxTail, DNSTail_t, usType, dnsTYPE_A_HOST ); /* Type A: host */
- vSetField16( pxTail, DNSTail_t, usClass, dnsCLASS_IN ); /* 1: Class IN */
-
- /* Return the total size of the generated message, which is the space from
- the last written byte to the beginning of the buffer. */
- return ( ( uint32_t ) pucByte - ( uint32_t ) pucUDPPayloadBuffer + 1 ) + sizeof( *pxTail );
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
-
- static uint8_t * prvReadNameField( uint8_t *pucByte,
- size_t uxSourceLen,
- char *pcName,
- size_t uxDestLen )
- {
- size_t uxNameLen = 0;
- BaseType_t xCount;
-
- if( 0 == uxSourceLen )
- {
- return NULL;
- }
-
- /* Determine if the name is the fully coded name, or an offset to the name
- elsewhere in the message. */
- if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
- {
- /* Jump over the two byte offset. */
- if( uxSourceLen > sizeof( uint16_t ) )
- {
- pucByte += sizeof( uint16_t );
- }
- else
- {
- pucByte = NULL;
- }
- }
- else
- {
- /* pucByte points to the full name. Walk over the string. */
- while( ( NULL != pucByte ) && ( *pucByte != 0x00u ) && ( uxSourceLen > 1u ) )
- {
- /* If this is not the first time through the loop, then add a
- separator in the output. */
- if( ( uxNameLen > 0 ) && ( uxNameLen < ( uxDestLen - 1u ) ) )
- {
- pcName[ uxNameLen++ ] = '.';
- }
-
- /* Process the first/next sub-string. */
- for( xCount = *( pucByte++ ), uxSourceLen--;
- xCount-- && uxSourceLen > 1u;
- pucByte++, uxSourceLen-- )
- {
- if( uxNameLen < uxDestLen - 1u )
- {
- pcName[ uxNameLen++ ] = *( ( char * ) pucByte );
- }
- else
- {
- /* DNS name is too big for the provided buffer. */
- pucByte = NULL;
- break;
- }
- }
- }
-
- /* Confirm that a fully formed name was found. */
- if( NULL != pucByte )
- {
- if( 0x00 == *pucByte )
- {
- pucByte++;
- uxSourceLen--;
- pcName[ uxNameLen++ ] = '\0';
- }
- else
- {
- pucByte = NULL;
- }
- }
- }
-
- return pucByte;
- }
-#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
-/*-----------------------------------------------------------*/
-
-static uint8_t * prvSkipNameField( uint8_t *pucByte,
- size_t uxSourceLen )
-{
-size_t uxChunkLength;
-
- if( 0u == uxSourceLen )
- {
- return NULL;
- }
-
- /* Determine if the name is the fully coded name, or an offset to the name
- elsewhere in the message. */
- if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
- {
- /* Jump over the two byte offset. */
- if( uxSourceLen > sizeof( uint16_t ) )
- {
- pucByte += sizeof( uint16_t );
- }
- else
- {
- pucByte = NULL;
- }
- }
- else
- {
- /* pucByte points to the full name. Walk over the string. */
- while( ( *pucByte != 0x00u ) && ( uxSourceLen > 1u ) )
- {
- uxChunkLength = *pucByte + 1u;
-
- if( uxSourceLen > uxChunkLength )
- {
- uxSourceLen -= uxChunkLength;
- pucByte += uxChunkLength;
- }
- else
- {
- pucByte = NULL;
- break;
- }
- }
-
- /* Confirm that a fully formed name was found. */
- if( NULL != pucByte )
- {
- if( 0x00u == *pucByte )
- {
- pucByte++;
- }
- else
- {
- pucByte = NULL;
- }
- }
- }
-
- return pucByte;
-}
-/*-----------------------------------------------------------*/
-
-/* The function below will only be called :
-when ipconfigDNS_USE_CALLBACKS == 1
-when ipconfigUSE_LLMNR == 1
-for testing purposes, by the module iot_test_freertos_tcp.c
-*/
-uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
-DNSMessage_t *pxDNSMessageHeader;
-size_t uxPayloadSize;
-
- /* Only proceed if the payload length indicated in the header
- appears to be valid. */
- if( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) )
- {
- uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
-
- if( uxPayloadSize >= sizeof( DNSMessage_t ) )
- {
- pxDNSMessageHeader =
- ( DNSMessage_t * ) ( pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t ) );
-
- /* The parameter pdFALSE indicates that the reply was not expected. */
- prvParseDNSReply( ( uint8_t * ) pxDNSMessageHeader,
- uxPayloadSize,
- pdFALSE );
- }
- }
-
- /* The packet was not consumed. */
- return pdFAIL;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_NBNS == 1 )
-
- uint32_t ulNBNSHandlePacket( NetworkBufferDescriptor_t * pxNetworkBuffer )
- {
- UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
- uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
- size_t uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
-
- /* The network buffer data length has already been set to the
- length of the UDP payload. */
- prvTreatNBNS( pucUDPPayloadBuffer,
- uxPayloadSize,
- pxUDPPacket->xIPHeader.ulSourceIPAddress );
-
- /* The packet was not consumed. */
- return pdFAIL;
- }
-
-#endif /* ipconfigUSE_NBNS */
-/*-----------------------------------------------------------*/
-
-static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer,
- size_t uxBufferLength,
- BaseType_t xExpected )
-{
-DNSMessage_t *pxDNSMessageHeader;
-DNSAnswerRecord_t *pxDNSAnswerRecord;
-uint32_t ulIPAddress = 0uL;
-#if( ipconfigUSE_LLMNR == 1 )
- char *pcRequestedName = NULL;
-#endif
-uint8_t *pucByte;
-size_t uxSourceBytesRemaining;
-uint16_t x, usDataLength, usQuestions;
-BaseType_t xDoStore = xExpected;
-#if( ipconfigUSE_LLMNR == 1 )
- uint16_t usType = 0, usClass = 0;
-#endif
-#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
- char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ] = "";
-#endif
-
- /* Ensure that the buffer is of at least minimal DNS message length. */
- if( uxBufferLength < sizeof( DNSMessage_t ) )
- {
- return dnsPARSE_ERROR;
- }
-
- uxSourceBytesRemaining = uxBufferLength;
-
- /* Parse the DNS message header. */
- pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
-
- /* Introduce a do {} while (0) to allow the use of breaks. */
- do
- {
- /* Start at the first byte after the header. */
- pucByte = pucUDPPayloadBuffer + sizeof( DNSMessage_t );
- uxSourceBytesRemaining -= sizeof( DNSMessage_t );
-
- /* Skip any question records. */
- usQuestions = FreeRTOS_ntohs( pxDNSMessageHeader->usQuestions );
-
- for( x = 0; x < usQuestions; x++ )
- {
- #if( ipconfigUSE_LLMNR == 1 )
- {
- if( x == 0 )
- {
- pcRequestedName = ( char * ) pucByte;
- }
- }
- #endif
-
-#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
- if( x == 0 )
- {
- pucByte = prvReadNameField( pucByte,
- uxSourceBytesRemaining,
- pcName,
- sizeof( pcName ) );
-
- /* Check for a malformed response. */
- if( NULL == pucByte )
- {
- return dnsPARSE_ERROR;
- }
-
- uxSourceBytesRemaining = ( pucUDPPayloadBuffer + uxBufferLength ) - pucByte;
- }
- else
-#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
- {
- /* Skip the variable length pcName field. */
- pucByte = prvSkipNameField( pucByte,
- uxSourceBytesRemaining );
-
- /* Check for a malformed response. */
- if( NULL == pucByte )
- {
- return dnsPARSE_ERROR;
- }
-
- uxSourceBytesRemaining = ( size_t )
- ( pucUDPPayloadBuffer + uxBufferLength - pucByte );
- }
-
- /* Check the remaining buffer size. */
- if( uxSourceBytesRemaining >= sizeof( uint32_t ) )
- {
- #if( ipconfigUSE_LLMNR == 1 )
- {
- /* usChar2u16 returns value in host endianness. */
- usType = usChar2u16( pucByte );
- usClass = usChar2u16( pucByte + 2 );
- }
- #endif /* ipconfigUSE_LLMNR */
-
- /* Skip the type and class fields. */
- pucByte += sizeof( uint32_t );
- uxSourceBytesRemaining -= sizeof( uint32_t );
- }
- else
- {
- /* Malformed response. */
- return dnsPARSE_ERROR;
- }
- }
-
- /* Search through the answer records. */
- pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
-
- if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
- {
- for( x = 0; x < pxDNSMessageHeader->usAnswers; x++ )
- {
- pucByte = prvSkipNameField( pucByte,
- uxSourceBytesRemaining );
-
- /* Check for a malformed response. */
- if( NULL == pucByte )
- {
- return dnsPARSE_ERROR;
- }
-
- uxSourceBytesRemaining = ( size_t )
- ( pucUDPPayloadBuffer + uxBufferLength - pucByte );
-
- /* Is there enough data for an IPv4 A record answer and, if so,
- is this an A record? */
- if( ( uxSourceBytesRemaining >= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) ) ) &&
- ( usChar2u16( pucByte ) == dnsTYPE_A_HOST ) )
- {
- /* This is the required record type and is of sufficient size. */
- pxDNSAnswerRecord = ( DNSAnswerRecord_t * ) pucByte;
-
- /* Sanity check the data length of an IPv4 answer. */
- if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == sizeof( uint32_t ) )
- {
- /* Copy the IP address out of the record. */
- memcpy( &ulIPAddress,
- pucByte + sizeof( DNSAnswerRecord_t ),
- sizeof( uint32_t ) );
-
- #if( ipconfigDNS_USE_CALLBACKS == 1 )
- {
- /* See if any asynchronous call was made to FreeRTOS_gethostbyname_a() */
- if( xDNSDoCallback( ( TickType_t ) pxDNSMessageHeader->usIdentifier, pcName, ulIPAddress ) != pdFALSE )
- {
- /* This device has requested this DNS look-up.
- The result may be stored in the DNS cache. */
- xDoStore = pdTRUE;
- }
- }
- #endif /* ipconfigDNS_USE_CALLBACKS == 1 */
- #if( ipconfigUSE_DNS_CACHE == 1 )
- {
- /* The reply will only be stored in the DNS cache when the
- request was issued by this device. */
- if( xDoStore != pdFALSE )
- {
- prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, pdFALSE );
- }
-
- /* Show what has happened. */
- FreeRTOS_printf( ( "DNS[0x%04X]: The answer to '%s' (%xip) will%s be stored\n",
- ( unsigned ) pxDNSMessageHeader->usIdentifier,
- pcName,
- ( unsigned ) FreeRTOS_ntohl( ulIPAddress ),
- ( xDoStore != 0 ) ? "" : " NOT" ) );
- }
- #endif /* ipconfigUSE_DNS_CACHE */
- }
-
- pucByte += sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t );
- uxSourceBytesRemaining -= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) );
- break;
- }
- else if( uxSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) )
- {
- /* It's not an A record, so skip it. Get the header location
- and then jump over the header. */
- pxDNSAnswerRecord = ( DNSAnswerRecord_t * ) pucByte;
- pucByte += sizeof( DNSAnswerRecord_t );
- uxSourceBytesRemaining -= sizeof( DNSAnswerRecord_t );
-
- /* Determine the length of the answer data from the header. */
- usDataLength = FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength );
-
- /* Jump over the answer. */
- if( uxSourceBytesRemaining >= usDataLength )
- {
- pucByte += usDataLength;
- uxSourceBytesRemaining -= usDataLength;
- }
- else
- {
- /* Malformed response. */
- return dnsPARSE_ERROR;
- }
- }
- }
- }
-
-#if( ipconfigUSE_LLMNR == 1 )
- else if( usQuestions && ( usType == dnsTYPE_A_HOST ) && ( usClass == dnsCLASS_IN ) )
- {
- /* If this is not a reply to our DNS request, it might an LLMNR
- request. */
- if( xApplicationDNSQueryHook( ( pcRequestedName + 1 ) ) )
- {
- int16_t usLength;
- NetworkBufferDescriptor_t *pxNewBuffer = NULL;
- NetworkBufferDescriptor_t *pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( pucUDPPayloadBuffer );
- LLMNRAnswer_t *pxAnswer;
-
- if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
- {
- BaseType_t xDataLength = uxBufferLength + sizeof( UDPHeader_t ) + sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
-
- /* Set the size of the outgoing packet. */
- pxNetworkBuffer->xDataLength = xDataLength;
- pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, xDataLength + sizeof( LLMNRAnswer_t ) );
-
- if( pxNewBuffer != NULL )
- {
- BaseType_t xOffset1, xOffset2;
-
- xOffset1 = ( BaseType_t ) ( pucByte - pucUDPPayloadBuffer );
- xOffset2 = ( BaseType_t ) ( ( ( uint8_t * ) pcRequestedName ) - pucUDPPayloadBuffer );
-
- pxNetworkBuffer = pxNewBuffer;
- pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + ipUDP_PAYLOAD_OFFSET_IPv4;
-
- pucByte = pucUDPPayloadBuffer + xOffset1;
- pcRequestedName = ( char * ) ( pucUDPPayloadBuffer + xOffset2 );
- pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
- }
- else
- {
- /* Just to indicate that the message may not be answered. */
- pxNetworkBuffer = NULL;
- }
- }
-
- if( pxNetworkBuffer != NULL )
- {
- pxAnswer = ( LLMNRAnswer_t * ) pucByte;
-
- /* We leave 'usIdentifier' and 'usQuestions' untouched */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usFlags, dnsLLMNR_FLAGS_IS_REPONSE ); /* Set the response flag */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usAnswers, 1 ); /* Provide a single answer */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */
- vSetField16( pxDNSMessageHeader, DNSMessage_t, usAdditionalRRs, 0 ); /* No additional info */
-
- pxAnswer->ucNameCode = dnsNAME_IS_OFFSET;
- pxAnswer->ucNameOffset = ( uint8_t ) ( pcRequestedName - ( char * ) pucUDPPayloadBuffer );
-
- vSetField16( pxAnswer, LLMNRAnswer_t, usType, dnsTYPE_A_HOST ); /* Type A: host */
- vSetField16( pxAnswer, LLMNRAnswer_t, usClass, dnsCLASS_IN ); /* 1: Class IN */
- vSetField32( pxAnswer, LLMNRAnswer_t, ulTTL, dnsLLMNR_TTL_VALUE );
- vSetField16( pxAnswer, LLMNRAnswer_t, usDataLength, 4 );
- vSetField32( pxAnswer, LLMNRAnswer_t, ulIPAddress, FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) );
-
- usLength = ( int16_t ) ( sizeof( *pxAnswer ) + ( size_t ) ( pucByte - pucUDPPayloadBuffer ) );
-
- prvReplyDNSMessage( pxNetworkBuffer, usLength );
-
- if( pxNewBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNewBuffer );
- }
- }
- }
- }
-#endif /* ipconfigUSE_LLMNR == 1 */
- } while( 0 );
-
- if( xExpected == pdFALSE )
- {
- /* Do not return a valid IP-address in case the reply was not expected. */
- ulIPAddress = 0uL;
- }
-
- return ulIPAddress;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_NBNS == 1 )
-
- static void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer,
- size_t uxBufferLength,
- uint32_t ulIPAddress )
- {
- uint16_t usFlags, usType, usClass;
- uint8_t *pucSource, *pucTarget;
- uint8_t ucByte;
- uint8_t ucNBNSName[ 17 ];
-
- /* Check for minimum buffer size. */
- if( uxBufferLength < sizeof( NBNSRequest_t ) )
- {
- return;
- }
-
- /* Read the request flags in host endianness. */
- usFlags = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usFlags ) );
-
- if( ( usFlags & dnsNBNS_FLAGS_OPCODE_MASK ) == dnsNBNS_FLAGS_OPCODE_QUERY )
- {
- usType = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usType ) );
- usClass = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usClass ) );
-
- /* Not used for now */
- ( void ) usClass;
-
- /* For NBNS a name is 16 bytes long, written with capitals only.
- Make sure that the copy is terminated with a zero. */
- pucTarget = ucNBNSName + sizeof( ucNBNSName ) - 2;
- pucTarget[ 1 ] = '\0';
-
- /* Start with decoding the last 2 bytes. */
- pucSource = pucUDPPayloadBuffer + ( offsetof( NBNSRequest_t, ucName ) + ( dnsNBNS_ENCODED_NAME_LENGTH - 2 ) );
-
- for( ;; )
- {
- ucByte = ( uint8_t ) ( ( ( pucSource[ 0 ] - 0x41 ) << 4 ) | ( pucSource[ 1 ] - 0x41 ) );
-
- /* Make sure there are no trailing spaces in the name. */
- if( ( ucByte == ' ' ) && ( pucTarget[ 1 ] == '\0' ) )
- {
- ucByte = '\0';
- }
-
- *pucTarget = ucByte;
-
- if( pucTarget == ucNBNSName )
- {
- break;
- }
-
- pucTarget -= 1;
- pucSource -= 2;
- }
-
- #if( ipconfigUSE_DNS_CACHE == 1 )
- {
- if( ( usFlags & dnsNBNS_FLAGS_RESPONSE ) != 0 )
- {
- /* If this is a response from another device,
- add the name to the DNS cache */
- prvProcessDNSCache( ( char * ) ucNBNSName, &ulIPAddress, 0, pdFALSE );
- }
- }
- #else
- {
- /* Avoid compiler warnings. */
- ( void ) ulIPAddress;
- }
- #endif /* ipconfigUSE_DNS_CACHE */
-
- if( ( ( usFlags & dnsNBNS_FLAGS_RESPONSE ) == 0 ) &&
- ( usType == dnsNBNS_TYPE_NET_BIOS ) &&
- ( xApplicationDNSQueryHook( ( const char * ) ucNBNSName ) != pdFALSE ) )
- {
- uint16_t usLength;
- DNSMessage_t *pxMessage;
- NBNSAnswer_t *pxAnswer;
-
- /* Someone is looking for a device with ucNBNSName,
- prepare a positive reply. */
- NetworkBufferDescriptor_t *pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( pucUDPPayloadBuffer );
-
- if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
- {
- NetworkBufferDescriptor_t *pxNewBuffer;
-
- /* The field xDataLength was set to the total length of the UDP packet,
- i.e. the payload size plus sizeof( UDPPacket_t ). */
- pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, pxNetworkBuffer->xDataLength + sizeof( NBNSAnswer_t ) );
-
- if( pxNewBuffer != NULL )
- {
- pucUDPPayloadBuffer = pxNewBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
- pxNetworkBuffer = pxNewBuffer;
- }
- else
- {
- /* Just prevent that a reply will be sent */
- pxNetworkBuffer = NULL;
- }
- }
-
- /* Should not occur: pucUDPPayloadBuffer is part of a xNetworkBufferDescriptor */
- if( pxNetworkBuffer != NULL )
- {
- pxMessage = ( DNSMessage_t * ) pucUDPPayloadBuffer;
-
- /* As the fields in the structures are not word-aligned, we have to
- copy the values byte-by-byte using macro's vSetField16() and vSetField32() */
- vSetField16( pxMessage, DNSMessage_t, usFlags, dnsNBNS_QUERY_RESPONSE_FLAGS ); /* 0x8500 */
- vSetField16( pxMessage, DNSMessage_t, usQuestions, 0 );
- vSetField16( pxMessage, DNSMessage_t, usAnswers, 1 );
- vSetField16( pxMessage, DNSMessage_t, usAuthorityRRs, 0 );
- vSetField16( pxMessage, DNSMessage_t, usAdditionalRRs, 0 );
-
- pxAnswer = ( NBNSAnswer_t * ) ( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usType ) );
-
- vSetField16( pxAnswer, NBNSAnswer_t, usType, usType ); /* Type */
- vSetField16( pxAnswer, NBNSAnswer_t, usClass, dnsNBNS_CLASS_IN ); /* Class */
- vSetField32( pxAnswer, NBNSAnswer_t, ulTTL, dnsNBNS_TTL_VALUE );
- vSetField16( pxAnswer, NBNSAnswer_t, usDataLength, 6 ); /* 6 bytes including the length field */
- vSetField16( pxAnswer, NBNSAnswer_t, usNbFlags, dnsNBNS_NAME_FLAGS );
- vSetField32( pxAnswer, NBNSAnswer_t, ulIPAddress, FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) );
-
- usLength = ( uint16_t ) ( offsetof( NBNSRequest_t, usType ) + sizeof( NBNSAnswer_t ) );
-
- prvReplyDNSMessage( pxNetworkBuffer, usLength );
- }
- }
- }
- }
-
-#endif /* ipconfigUSE_NBNS */
-/*-----------------------------------------------------------*/
-
-static Socket_t prvCreateDNSSocket( void )
-{
-Socket_t xSocket = NULL;
-struct freertos_sockaddr xAddress;
-BaseType_t xReturn;
-
- /* This must be the first time this function has been called. Create
- the socket. */
- xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
-
- /* Auto bind the port. */
- xAddress.sin_port = 0u;
- xReturn = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
-
- /* Check the bind was successful, and clean up if not. */
- if( xReturn != 0 )
- {
- FreeRTOS_closesocket( xSocket );
- xSocket = NULL;
- }
- else
- {
- /* The send and receive timeouts will be set later on. */
- }
-
- return xSocket;
-}
-/*-----------------------------------------------------------*/
-
-#if( ( ipconfigUSE_NBNS == 1 ) || ( ipconfigUSE_LLMNR == 1 ) )
-
- static void prvReplyDNSMessage( NetworkBufferDescriptor_t *pxNetworkBuffer,
- BaseType_t lNetLength )
- {
- UDPPacket_t *pxUDPPacket;
- IPHeader_t *pxIPHeader;
- UDPHeader_t *pxUDPHeader;
-
- pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
- pxIPHeader = &pxUDPPacket->xIPHeader;
- pxUDPHeader = &pxUDPPacket->xUDPHeader;
- /* HT: started using defines like 'ipSIZE_OF_xxx' */
- pxIPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER );
- /* HT:endian: should not be translated, copying from packet to packet */
- pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
- pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
- pxIPHeader->ucTimeToLive = ipconfigUDP_TIME_TO_LIVE;
- pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );
- usPacketIdentifier++;
- pxUDPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_UDP_HEADER );
- vFlip_16( pxUDPPacket->xUDPHeader.usSourcePort, pxUDPPacket->xUDPHeader.usDestinationPort );
-
- /* Important: tell NIC driver how many bytes must be sent */
- pxNetworkBuffer->xDataLength = ( size_t ) ( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER );
-
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
- {
- /* calculate the IP header checksum */
- pxIPHeader->usHeaderChecksum = 0x00;
- pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0uL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
- pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
-
- /* calculate the UDP checksum for outgoing package */
- usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
- }
- #endif
-
- /* This function will fill in the eth addresses and send the packet */
- vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
- }
-
-#endif /* ipconfigUSE_NBNS == 1 || ipconfigUSE_LLMNR == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_DNS_CACHE == 1 )
-
- static void prvProcessDNSCache( const char *pcName,
- uint32_t *pulIP,
- uint32_t ulTTL,
- BaseType_t xLookUp )
- {
- BaseType_t x;
- BaseType_t xFound = pdFALSE;
- uint32_t ulCurrentTimeSeconds = ( xTaskGetTickCount() / portTICK_PERIOD_MS ) / 1000;
- static BaseType_t xFreeEntry = 0;
- configASSERT(pcName);
-
- /* For each entry in the DNS cache table. */
- for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
- {
- if( xDNSCache[ x ].pcName[ 0 ] == 0 )
- {
- continue;
- }
-
- if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
- {
- /* Is this function called for a lookup or to add/update an IP address? */
- if( xLookUp != pdFALSE )
- {
- /* Confirm that the record is still fresh. */
- if( ulCurrentTimeSeconds < ( xDNSCache[ x ].ulTimeWhenAddedInSeconds + FreeRTOS_ntohl( xDNSCache[ x ].ulTTL ) ) )
- {
- *pulIP = xDNSCache[ x ].ulIPAddress;
- }
- else
- {
- /* Age out the old cached record. */
- xDNSCache[ x ].pcName[ 0 ] = 0;
- }
- }
- else
- {
- xDNSCache[ x ].ulIPAddress = *pulIP;
- xDNSCache[ x ].ulTTL = ulTTL;
- xDNSCache[ x ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
- }
-
- xFound = pdTRUE;
- break;
- }
- }
-
- if( xFound == pdFALSE )
- {
- if( xLookUp != pdFALSE )
- {
- *pulIP = 0;
- }
- else
- {
- /* Add or update the item. */
- if( strlen( pcName ) < ipconfigDNS_CACHE_NAME_LENGTH )
- {
- strcpy( xDNSCache[ xFreeEntry ].pcName, pcName );
-
- xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;
- xDNSCache[ xFreeEntry ].ulTTL = ulTTL;
- xDNSCache[ xFreeEntry ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
-
- xFreeEntry++;
-
- if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
- {
- xFreeEntry = 0;
- }
- }
- }
- }
-
- if( ( xLookUp == 0 ) || ( *pulIP != 0 ) )
- {
- FreeRTOS_debug_printf( ( "prvProcessDNSCache: %s: '%s' @ %lxip\n", xLookUp ? "look-up" : "add", pcName, FreeRTOS_ntohl( *pulIP ) ) );
- }
- }
-
-#endif /* ipconfigUSE_DNS_CACHE */
-
-#endif /* ipconfigUSE_DNS != 0 */
-
-/*-----------------------------------------------------------*/
-
-/* Provide access to private members for testing. */
-#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
- #include "iot_freertos_tcp_test_access_dns_define.h"
-#endif
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "list.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_DNS.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+#include "IPTraceMacroDefaults.h"
+
+/* Exclude the entire file if DNS is not enabled. */
+#if( ipconfigUSE_DNS != 0 )
+
+#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
+ #define dnsDNS_PORT 0x3500u
+ #define dnsONE_QUESTION 0x0100u
+ #define dnsOUTGOING_FLAGS 0x0001u /* Standard query. */
+ #define dnsRX_FLAGS_MASK 0x0f80u /* The bits of interest in the flags field of incoming DNS messages. */
+ #define dnsEXPECTED_RX_FLAGS 0x0080u /* Should be a response, without any errors. */
+#else
+ #define dnsDNS_PORT 0x0035u
+ #define dnsONE_QUESTION 0x0001u
+ #define dnsOUTGOING_FLAGS 0x0100u /* Standard query. */
+ #define dnsRX_FLAGS_MASK 0x800fu /* The bits of interest in the flags field of incoming DNS messages. */
+ #define dnsEXPECTED_RX_FLAGS 0x8000u /* Should be a response, without any errors. */
+
+#endif /* ipconfigBYTE_ORDER */
+
+/* The maximum number of times a DNS request should be sent out if a response
+is not received, before giving up. */
+#ifndef ipconfigDNS_REQUEST_ATTEMPTS
+ #define ipconfigDNS_REQUEST_ATTEMPTS 5
+#endif
+
+/* If the top two bits in the first character of a name field are set then the
+name field is an offset to the string, rather than the string itself. */
+#define dnsNAME_IS_OFFSET ( ( uint8_t ) 0xc0 )
+
+/* NBNS flags. */
+#define dnsNBNS_FLAGS_RESPONSE 0x8000u
+#define dnsNBNS_FLAGS_OPCODE_MASK 0x7800u
+#define dnsNBNS_FLAGS_OPCODE_QUERY 0x0000u
+#define dnsNBNS_FLAGS_OPCODE_REGISTRATION 0x2800u
+
+/* Host types. */
+#define dnsTYPE_A_HOST 0x01u
+#define dnsCLASS_IN 0x01u
+
+/* LLMNR constants. */
+#define dnsLLMNR_TTL_VALUE 300000uL
+#define dnsLLMNR_FLAGS_IS_REPONSE 0x8000u
+
+/* NBNS constants. */
+#define dnsNBNS_TTL_VALUE 3600uL /* 1 hour valid */
+#define dnsNBNS_TYPE_NET_BIOS 0x0020u
+#define dnsNBNS_CLASS_IN 0x01u
+#define dnsNBNS_NAME_FLAGS 0x6000u
+#define dnsNBNS_ENCODED_NAME_LENGTH 32
+
+/* If the queried NBNS name matches with the device's name,
+the query will be responded to with these flags: */
+#define dnsNBNS_QUERY_RESPONSE_FLAGS ( 0x8500u )
+
+/* Flag DNS parsing errors in situations where an IPv4 address is the return
+type. */
+#define dnsPARSE_ERROR 0uL
+
+/*
+ * Create a socket and bind it to the standard DNS port number. Return the
+ * the created socket - or NULL if the socket could not be created or bound.
+ */
+static Socket_t prvCreateDNSSocket( void );
+
+/*
+ * Create the DNS message in the zero copy buffer passed in the first parameter.
+ */
+static size_t prvCreateDNSMessage( uint8_t *pucUDPPayloadBuffer,
+ const char *pcHostName,
+ TickType_t uxIdentifier );
+
+/*
+ * Simple routine that jumps over the NAME field of a resource record.
+ */
+static uint8_t * prvSkipNameField( uint8_t *pucByte,
+ size_t uxSourceLen );
+
+/*
+ * Process a response packet from a DNS server.
+ * The parameter 'xExpected' indicates whether the identifier in the reply
+ * was expected, and thus if the DNS cache may be updated with the reply.
+ */
+static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer,
+ size_t uxBufferLength,
+ BaseType_t xExpected );
+
+/*
+ * Prepare and send a message to a DNS server. 'uxReadTimeOut_ticks' will be passed as
+ * zero, in case the user has supplied a call-back function.
+ */
+static uint32_t prvGetHostByName( const char *pcHostName,
+ TickType_t uxIdentifier,
+ TickType_t uxReadTimeOut_ticks );
+
+/*
+ * The NBNS and the LLMNR protocol share this reply function.
+ */
+#if( ( ipconfigUSE_NBNS == 1 ) || ( ipconfigUSE_LLMNR == 1 ) )
+ static void prvReplyDNSMessage( NetworkBufferDescriptor_t *pxNetworkBuffer,
+ BaseType_t lNetLength );
+#endif
+
+#if( ipconfigUSE_NBNS == 1 )
+ static portINLINE void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer,
+ size_t uxBufferLength,
+ uint32_t ulIPAddress );
+#endif /* ipconfigUSE_NBNS */
+
+
+#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
+ static uint8_t * prvReadNameField( uint8_t *pucByte,
+ size_t uxSourceLen,
+ char *pcName,
+ size_t uxLen );
+#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
+
+#if( ipconfigUSE_DNS_CACHE == 1 )
+ static void prvProcessDNSCache( const char *pcName,
+ uint32_t *pulIP,
+ uint32_t ulTTL,
+ BaseType_t xLookUp );
+
+ typedef struct xDNS_CACHE_TABLE_ROW
+ {
+ uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
+ char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ]; /* The name of the host */
+ uint32_t ulTTL; /* Time-to-Live (in seconds) from the DNS server. */
+ uint32_t ulTimeWhenAddedInSeconds;
+ } DNSCacheRow_t;
+
+ static DNSCacheRow_t xDNSCache[ ipconfigDNS_CACHE_ENTRIES ];
+
+ void FreeRTOS_dnsclear()
+ {
+ memset( xDNSCache, 0x0, sizeof( xDNSCache ) );
+ }
+#endif /* ipconfigUSE_DNS_CACHE == 1 */
+
+#if( ipconfigUSE_LLMNR == 1 )
+ const MACAddress_t xLLMNR_MacAdress = { { 0x01, 0x00, 0x5e, 0x00, 0x00, 0xfc } };
+#endif /* ipconfigUSE_LLMNR == 1 */
+
+/*-----------------------------------------------------------*/
+
+#include "pack_struct_start.h"
+struct xDNSMessage
+{
+ uint16_t usIdentifier;
+ uint16_t usFlags;
+ uint16_t usQuestions;
+ uint16_t usAnswers;
+ uint16_t usAuthorityRRs;
+ uint16_t usAdditionalRRs;
+}
+#include "pack_struct_end.h"
+typedef struct xDNSMessage DNSMessage_t;
+
+/* A DNS query consists of a header, as described in 'struct xDNSMessage'
+It is followed by 1 or more queries, each one consisting of a name and a tail,
+with two fields: type and class
+*/
+#include "pack_struct_start.h"
+struct xDNSTail
+{
+ uint16_t usType;
+ uint16_t usClass;
+}
+#include "pack_struct_end.h"
+typedef struct xDNSTail DNSTail_t;
+
+/* DNS answer record header. */
+#include "pack_struct_start.h"
+struct xDNSAnswerRecord
+{
+ uint16_t usType;
+ uint16_t usClass;
+ uint32_t ulTTL;
+ uint16_t usDataLength;
+}
+#include "pack_struct_end.h"
+typedef struct xDNSAnswerRecord DNSAnswerRecord_t;
+
+#if( ipconfigUSE_LLMNR == 1 )
+
+ #include "pack_struct_start.h"
+ struct xLLMNRAnswer
+ {
+ uint8_t ucNameCode;
+ uint8_t ucNameOffset; /* The name is not repeated in the answer, only the offset is given with "0xc0 <offs>" */
+ uint16_t usType;
+ uint16_t usClass;
+ uint32_t ulTTL;
+ uint16_t usDataLength;
+ uint32_t ulIPAddress;
+ }
+ #include "pack_struct_end.h"
+ typedef struct xLLMNRAnswer LLMNRAnswer_t;
+
+#endif /* ipconfigUSE_LLMNR == 1 */
+
+#if( ipconfigUSE_NBNS == 1 )
+
+ #include "pack_struct_start.h"
+ struct xNBNSRequest
+ {
+ uint16_t usRequestId;
+ uint16_t usFlags;
+ uint16_t ulRequestCount;
+ uint16_t usAnswerRSS;
+ uint16_t usAuthRSS;
+ uint16_t usAdditionalRSS;
+ uint8_t ucNameSpace;
+ uint8_t ucName[ dnsNBNS_ENCODED_NAME_LENGTH ];
+ uint8_t ucNameZero;
+ uint16_t usType;
+ uint16_t usClass;
+ }
+ #include "pack_struct_end.h"
+ typedef struct xNBNSRequest NBNSRequest_t;
+
+ #include "pack_struct_start.h"
+ struct xNBNSAnswer
+ {
+ uint16_t usType;
+ uint16_t usClass;
+ uint32_t ulTTL;
+ uint16_t usDataLength;
+ uint16_t usNbFlags; /* NetBIOS flags 0x6000 : IP-address, big-endian */
+ uint32_t ulIPAddress;
+ }
+ #include "pack_struct_end.h"
+ typedef struct xNBNSAnswer NBNSAnswer_t;
+
+ #endif /* ipconfigUSE_NBNS == 1 */
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_DNS_CACHE == 1 )
+ uint32_t FreeRTOS_dnslookup( const char *pcHostName )
+ {
+ uint32_t ulIPAddress = 0uL;
+
+ prvProcessDNSCache( pcHostName, &ulIPAddress, 0, pdTRUE );
+ return ulIPAddress;
+ }
+#endif /* ipconfigUSE_DNS_CACHE == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigDNS_USE_CALLBACKS == 1 )
+
+ typedef struct xDNS_Callback
+ {
+ TickType_t uxRemaningTime; /* Timeout in ms */
+ FOnDNSEvent pCallbackFunction; /* Function to be called when the address has been found or when a timeout has beeen reached */
+ TimeOut_t uxTimeoutState;
+ void *pvSearchID;
+ struct xLIST_ITEM xListItem;
+ char pcName[ 1 ];
+ } DNSCallback_t;
+
+ static List_t xCallbackList;
+
+ /* Define FreeRTOS_gethostbyname() as a normal blocking call. */
+ uint32_t FreeRTOS_gethostbyname( const char *pcHostName )
+ {
+ return FreeRTOS_gethostbyname_a( pcHostName, ( FOnDNSEvent ) NULL, ( void * ) NULL, 0 );
+ }
+ /*-----------------------------------------------------------*/
+
+ /* Initialise the list of call-back structures. */
+ void vDNSInitialise( void );
+ void vDNSInitialise( void )
+ {
+ vListInitialise( &xCallbackList );
+ }
+ /*-----------------------------------------------------------*/
+
+ /* Iterate through the list of call-back structures and remove
+ old entries which have reached a timeout.
+ As soon as the list hase become empty, the DNS timer will be stopped
+ In case pvSearchID is supplied, the user wants to cancel a DNS request
+ */
+ void vDNSCheckCallBack( void *pvSearchID );
+ void vDNSCheckCallBack( void *pvSearchID )
+ {
+ const ListItem_t *pxIterator;
+ const MiniListItem_t * xEnd = ( const MiniListItem_t * ) listGET_END_MARKER( &xCallbackList );
+
+ vTaskSuspendAll();
+ {
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
+ pxIterator != ( const ListItem_t * ) xEnd;
+ )
+ {
+ DNSCallback_t *pxCallback = ( DNSCallback_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ /* Move to the next item because we might remove this item */
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
+
+ if( ( pvSearchID != NULL ) && ( pvSearchID == pxCallback->pvSearchID ) )
+ {
+ uxListRemove( &pxCallback->xListItem );
+ vPortFree( pxCallback );
+ }
+ else if( xTaskCheckForTimeOut( &pxCallback->uxTimeoutState, &pxCallback->uxRemaningTime ) != pdFALSE )
+ {
+ pxCallback->pCallbackFunction( pxCallback->pcName, pxCallback->pvSearchID, 0 );
+ uxListRemove( &pxCallback->xListItem );
+ vPortFree( ( void * ) pxCallback );
+ }
+ }
+ }
+ xTaskResumeAll();
+
+ if( listLIST_IS_EMPTY( &xCallbackList ) )
+ {
+ vIPSetDnsTimerEnableState( pdFALSE );
+ }
+ }
+ /*-----------------------------------------------------------*/
+
+ void FreeRTOS_gethostbyname_cancel( void *pvSearchID )
+ {
+ /* _HT_ Should better become a new API call to have the IP-task remove the callback */
+ vDNSCheckCallBack( pvSearchID );
+ }
+ /*-----------------------------------------------------------*/
+
+ /* FreeRTOS_gethostbyname_a() was called along with callback parameters.
+ Store them in a list for later reference. */
+ static void vDNSSetCallBack( const char *pcHostName,
+ void *pvSearchID,
+ FOnDNSEvent pCallbackFunction,
+ TickType_t uxTimeout,
+ TickType_t uxIdentifier );
+ static void vDNSSetCallBack( const char *pcHostName,
+ void *pvSearchID,
+ FOnDNSEvent pCallbackFunction,
+ TickType_t uxTimeout,
+ TickType_t uxIdentifier )
+ {
+ size_t lLength = strlen( pcHostName );
+ DNSCallback_t *pxCallback = ( DNSCallback_t * ) pvPortMalloc( sizeof( *pxCallback ) + lLength );
+
+ /* Translate from ms to number of clock ticks. */
+ uxTimeout /= portTICK_PERIOD_MS;
+
+ if( pxCallback != NULL )
+ {
+ if( listLIST_IS_EMPTY( &xCallbackList ) )
+ {
+ /* This is the first one, start the DNS timer to check for timeouts */
+ vIPReloadDNSTimer( FreeRTOS_min_uint32( 1000U, uxTimeout ) );
+ }
+
+ strcpy( pxCallback->pcName, pcHostName );
+ pxCallback->pCallbackFunction = pCallbackFunction;
+ pxCallback->pvSearchID = pvSearchID;
+ pxCallback->uxRemaningTime = uxTimeout;
+ vTaskSetTimeOutState( &pxCallback->uxTimeoutState );
+ listSET_LIST_ITEM_OWNER( &( pxCallback->xListItem ), ( void * ) pxCallback );
+ listSET_LIST_ITEM_VALUE( &( pxCallback->xListItem ), uxIdentifier );
+ vTaskSuspendAll();
+ {
+ vListInsertEnd( &xCallbackList, &pxCallback->xListItem );
+ }
+ xTaskResumeAll();
+ }
+ }
+ /*-----------------------------------------------------------*/
+
+ /* A DNS reply was received, see if there is any matching entry and
+ call the handler. Returns pdTRUE if uxIdentifier was recognised. */
+ static BaseType_t xDNSDoCallback( TickType_t uxIdentifier,
+ const char *pcName,
+ uint32_t ulIPAddress );
+ static BaseType_t xDNSDoCallback( TickType_t uxIdentifier,
+ const char *pcName,
+ uint32_t ulIPAddress )
+ {
+ BaseType_t xResult = pdFALSE;
+ const ListItem_t *pxIterator;
+ const MiniListItem_t * xEnd = ( const MiniListItem_t * ) listGET_END_MARKER( &xCallbackList );
+
+ vTaskSuspendAll();
+ {
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( xEnd );
+ pxIterator != ( const ListItem_t * ) xEnd;
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ /* The cast will take away the 'configLIST_VOLATILE' */
+ if( uxIdentifier == ( TickType_t ) listGET_LIST_ITEM_VALUE( pxIterator ) )
+ {
+ DNSCallback_t *pxCallback = ( DNSCallback_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ pxCallback->pCallbackFunction( pcName, pxCallback->pvSearchID, ulIPAddress );
+ uxListRemove( &pxCallback->xListItem );
+ vPortFree( pxCallback );
+
+ if( listLIST_IS_EMPTY( &xCallbackList ) )
+ {
+ /* The list of outstanding requests is empty. No need for periodic polling. */
+ vIPSetDnsTimerEnableState( pdFALSE );
+ }
+
+ xResult = pdTRUE;
+ break;
+ }
+ }
+ }
+ xTaskResumeAll();
+ return xResult;
+ }
+
+#endif /* ipconfigDNS_USE_CALLBACKS == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigDNS_USE_CALLBACKS == 0 )
+ uint32_t FreeRTOS_gethostbyname( const char *pcHostName )
+#else
+ uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName,
+ FOnDNSEvent pCallback,
+ void *pvSearchID,
+ TickType_t uxTimeout )
+#endif
+{
+uint32_t ulIPAddress = 0uL;
+TickType_t uxReadTimeOut_ticks = ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS;
+TickType_t uxIdentifier = 0u;
+BaseType_t xHasRandom = pdFALSE;
+
+ if( pcHostName != NULL )
+ {
+ /* If the supplied hostname is IP address, convert it to uint32_t
+ and return. */
+ #if( ipconfigINCLUDE_FULL_INET_ADDR == 1 )
+ {
+ ulIPAddress = FreeRTOS_inet_addr( pcHostName );
+ }
+ #endif /* ipconfigINCLUDE_FULL_INET_ADDR == 1 */
+
+ /* If a DNS cache is used then check the cache before issuing another DNS
+ request. */
+ #if( ipconfigUSE_DNS_CACHE == 1 )
+ {
+ if( ulIPAddress == 0uL )
+ {
+ ulIPAddress = FreeRTOS_dnslookup( pcHostName );
+
+ if( ulIPAddress != 0 )
+ {
+ FreeRTOS_debug_printf( ( "FreeRTOS_gethostbyname: found '%s' in cache: %lxip\n", pcHostName, ulIPAddress ) );
+ }
+ else
+ {
+ /* prvGetHostByName will be called to start a DNS lookup. */
+ }
+ }
+ }
+ #endif /* ipconfigUSE_DNS_CACHE == 1 */
+
+ /* Generate a unique identifier. */
+ if( ulIPAddress == 0uL )
+ {
+ uint32_t ulNumber;
+
+ xHasRandom = xApplicationGetRandomNumber( &( ulNumber ) );
+ /* DNS identifiers are 16-bit. */
+ uxIdentifier = ( TickType_t ) ( ulNumber & 0xffffu );
+ /* ipconfigRAND32() may not return a non-zero value. */
+ }
+
+ #if( ipconfigDNS_USE_CALLBACKS == 1 )
+ {
+ if( pCallback != NULL )
+ {
+ if( ulIPAddress == 0uL )
+ {
+ /* The user has provided a callback function, so do not block on recvfrom() */
+ if( xHasRandom != pdFALSE )
+ {
+ uxReadTimeOut_ticks = 0u;
+ vDNSSetCallBack( pcHostName, pvSearchID, pCallback, uxTimeout, uxIdentifier );
+ }
+ }
+ else
+ {
+ /* The IP address is known, do the call-back now. */
+ pCallback( pcHostName, pvSearchID, ulIPAddress );
+ }
+ }
+ }
+ #endif /* if ( ipconfigDNS_USE_CALLBACKS == 1 ) */
+
+ if( ( ulIPAddress == 0uL ) && ( xHasRandom != pdFALSE ) )
+ {
+ ulIPAddress = prvGetHostByName( pcHostName, uxIdentifier, uxReadTimeOut_ticks );
+ }
+ }
+ return ulIPAddress;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvGetHostByName( const char *pcHostName,
+ TickType_t uxIdentifier,
+ TickType_t uxReadTimeOut_ticks )
+{
+struct freertos_sockaddr xAddress;
+Socket_t xDNSSocket;
+uint32_t ulIPAddress = 0uL;
+uint8_t *pucUDPPayloadBuffer;
+uint32_t ulAddressLength = sizeof( struct freertos_sockaddr );
+BaseType_t xAttempt;
+int32_t lBytes;
+size_t uxPayloadLength, uxExpectedPayloadLength;
+TickType_t uxWriteTimeOut_ticks = ipconfigDNS_SEND_BLOCK_TIME_TICKS;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ BaseType_t bHasDot = pdFALSE;
+#endif /* ipconfigUSE_LLMNR == 1 */
+
+ /* If LLMNR is being used then determine if the host name includes a '.' -
+ if not then LLMNR can be used as the lookup method. */
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ const char *pucPtr;
+
+ for( pucPtr = pcHostName; *pucPtr; pucPtr++ )
+ {
+ if( *pucPtr == '.' )
+ {
+ bHasDot = pdTRUE;
+ break;
+ }
+ }
+ }
+ #endif /* ipconfigUSE_LLMNR == 1 */
+
+ /* Two is added at the end for the count of characters in the first
+ subdomain part and the string end byte. */
+ uxExpectedPayloadLength = sizeof( DNSMessage_t ) + strlen( pcHostName ) + sizeof( uint16_t ) + sizeof( uint16_t ) + 2u;
+
+ xDNSSocket = prvCreateDNSSocket();
+
+ if( xDNSSocket != NULL )
+ {
+ FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_SNDTIMEO, ( void * ) &uxWriteTimeOut_ticks, sizeof( TickType_t ) );
+ FreeRTOS_setsockopt( xDNSSocket, 0, FREERTOS_SO_RCVTIMEO, ( void * ) &uxReadTimeOut_ticks, sizeof( TickType_t ) );
+
+ for( xAttempt = 0; xAttempt < ipconfigDNS_REQUEST_ATTEMPTS; xAttempt++ )
+ {
+ /* Get a buffer. This uses a maximum delay, but the delay will be
+ capped to ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS so the return value
+ still needs to be tested. */
+ pucUDPPayloadBuffer = ( uint8_t * ) FreeRTOS_GetUDPPayloadBuffer( uxExpectedPayloadLength, portMAX_DELAY );
+
+ if( pucUDPPayloadBuffer != NULL )
+ {
+ /* Create the message in the obtained buffer. */
+ uxPayloadLength = prvCreateDNSMessage( pucUDPPayloadBuffer, pcHostName, uxIdentifier );
+
+ iptraceSENDING_DNS_REQUEST();
+
+ /* Obtain the DNS server address. */
+ FreeRTOS_GetAddressConfiguration( NULL, NULL, NULL, &ulIPAddress );
+
+ /* Send the DNS message. */
+#if( ipconfigUSE_LLMNR == 1 )
+ if( bHasDot == pdFALSE )
+ {
+ /* Use LLMNR addressing. */
+ ( ( DNSMessage_t * ) pucUDPPayloadBuffer )->usFlags = 0;
+ xAddress.sin_addr = ipLLMNR_IP_ADDR; /* Is in network byte order. */
+ xAddress.sin_port = FreeRTOS_ntohs( ipLLMNR_PORT );
+ }
+ else
+#endif
+ {
+ /* Use DNS server. */
+ xAddress.sin_addr = ulIPAddress;
+ xAddress.sin_port = dnsDNS_PORT;
+ }
+
+ ulIPAddress = 0uL;
+
+ if( FreeRTOS_sendto( xDNSSocket, pucUDPPayloadBuffer, uxPayloadLength, FREERTOS_ZERO_COPY, &xAddress, sizeof( xAddress ) ) != 0 )
+ {
+ /* Wait for the reply. */
+ lBytes = FreeRTOS_recvfrom( xDNSSocket, &pucUDPPayloadBuffer, 0, FREERTOS_ZERO_COPY, &xAddress, &ulAddressLength );
+
+ if( lBytes > 0 )
+ {
+ BaseType_t xExpected;
+ DNSMessage_t *pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
+
+ /* See if the identifiers match. */
+ if( uxIdentifier == ( TickType_t ) pxDNSMessageHeader->usIdentifier )
+ {
+ xExpected = pdTRUE;
+ }
+ else
+ {
+ /* The reply was not expected. */
+ xExpected = pdFALSE;
+ }
+
+ /* The reply was received. Process it. */
+ #if( ipconfigDNS_USE_CALLBACKS == 0 )
+ /* It is useless to analyse the unexpected reply
+ unless asynchronous look-ups are enabled. */
+ if( xExpected != pdFALSE )
+ #endif /* ipconfigDNS_USE_CALLBACKS == 0 */
+ {
+ ulIPAddress = prvParseDNSReply( pucUDPPayloadBuffer, ( size_t ) lBytes, xExpected );
+ }
+
+ /* Finished with the buffer. The zero copy interface
+ is being used, so the buffer must be freed by the
+ task. */
+ FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
+
+ if( ulIPAddress != 0uL )
+ {
+ /* All done. */
+ break;
+ }
+ }
+ }
+ else
+ {
+ /* The message was not sent so the stack will not be
+ releasing the zero copy - it must be released here. */
+ FreeRTOS_ReleaseUDPPayloadBuffer( ( void * ) pucUDPPayloadBuffer );
+ }
+ }
+
+ if( uxReadTimeOut_ticks == 0u )
+ {
+ /* This DNS lookup is asynchronous, using a call-back:
+ send the request only once. */
+ break;
+ }
+ }
+
+ /* Finished with the socket. */
+ FreeRTOS_closesocket( xDNSSocket );
+ }
+
+ return ulIPAddress;
+}
+/*-----------------------------------------------------------*/
+
+static size_t prvCreateDNSMessage( uint8_t *pucUDPPayloadBuffer,
+ const char *pcHostName,
+ TickType_t uxIdentifier )
+{
+DNSMessage_t *pxDNSMessageHeader;
+uint8_t *pucStart, *pucByte;
+DNSTail_t *pxTail;
+static const DNSMessage_t xDefaultPartDNSHeader =
+{
+ 0, /* The identifier will be overwritten. */
+ dnsOUTGOING_FLAGS, /* Flags set for standard query. */
+ dnsONE_QUESTION, /* One question is being asked. */
+ 0, /* No replies are included. */
+ 0, /* No authorities. */
+ 0 /* No additional authorities. */
+};
+
+ /* Copy in the const part of the header. */
+ memcpy( ( void * ) pucUDPPayloadBuffer, ( void * ) &xDefaultPartDNSHeader, sizeof( xDefaultPartDNSHeader ) );
+
+ /* Write in a unique identifier. */
+ pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
+ pxDNSMessageHeader->usIdentifier = ( uint16_t ) uxIdentifier;
+
+ /* Create the resource record at the end of the header. First
+ find the end of the header. */
+ pucStart = pucUDPPayloadBuffer + sizeof( xDefaultPartDNSHeader );
+
+ /* Leave a gap for the first length bytes. */
+ pucByte = pucStart + 1;
+
+ /* Copy in the host name. */
+ strcpy( ( char * ) pucByte, pcHostName );
+
+ /* Mark the end of the string. */
+ pucByte += strlen( pcHostName );
+ *pucByte = 0x00u;
+
+ /* Walk the string to replace the '.' characters with byte counts.
+ pucStart holds the address of the byte count. Walking the string
+ starts after the byte count position. */
+ pucByte = pucStart;
+
+ do
+ {
+ pucByte++;
+
+ while( ( *pucByte != 0x00 ) && ( *pucByte != '.' ) )
+ {
+ pucByte++;
+ }
+
+ /* Fill in the byte count, then move the pucStart pointer up to
+ the found byte position. */
+ *pucStart = ( uint8_t ) ( ( uint32_t ) pucByte - ( uint32_t ) pucStart );
+ ( *pucStart )--;
+
+ pucStart = pucByte;
+ } while( *pucByte != 0x00 );
+
+ /* Finish off the record. */
+
+ pxTail = ( DNSTail_t * ) ( pucByte + 1 );
+
+ vSetField16( pxTail, DNSTail_t, usType, dnsTYPE_A_HOST ); /* Type A: host */
+ vSetField16( pxTail, DNSTail_t, usClass, dnsCLASS_IN ); /* 1: Class IN */
+
+ /* Return the total size of the generated message, which is the space from
+ the last written byte to the beginning of the buffer. */
+ return ( ( uint32_t ) pucByte - ( uint32_t ) pucUDPPayloadBuffer + 1 ) + sizeof( *pxTail );
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
+
+ static uint8_t * prvReadNameField( uint8_t *pucByte,
+ size_t uxSourceLen,
+ char *pcName,
+ size_t uxDestLen )
+ {
+ size_t uxNameLen = 0;
+ BaseType_t xCount;
+
+ if( 0 == uxSourceLen )
+ {
+ return NULL;
+ }
+
+ /* Determine if the name is the fully coded name, or an offset to the name
+ elsewhere in the message. */
+ if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
+ {
+ /* Jump over the two byte offset. */
+ if( uxSourceLen > sizeof( uint16_t ) )
+ {
+ pucByte += sizeof( uint16_t );
+ }
+ else
+ {
+ pucByte = NULL;
+ }
+ }
+ else
+ {
+ /* pucByte points to the full name. Walk over the string. */
+ while( ( NULL != pucByte ) && ( *pucByte != 0x00u ) && ( uxSourceLen > 1u ) )
+ {
+ /* If this is not the first time through the loop, then add a
+ separator in the output. */
+ if( ( uxNameLen > 0 ) && ( uxNameLen < ( uxDestLen - 1u ) ) )
+ {
+ pcName[ uxNameLen++ ] = '.';
+ }
+
+ /* Process the first/next sub-string. */
+ for( xCount = *( pucByte++ ), uxSourceLen--;
+ xCount-- && uxSourceLen > 1u;
+ pucByte++, uxSourceLen-- )
+ {
+ if( uxNameLen < uxDestLen - 1u )
+ {
+ pcName[ uxNameLen++ ] = *( ( char * ) pucByte );
+ }
+ else
+ {
+ /* DNS name is too big for the provided buffer. */
+ pucByte = NULL;
+ break;
+ }
+ }
+ }
+
+ /* Confirm that a fully formed name was found. */
+ if( NULL != pucByte )
+ {
+ if( 0x00 == *pucByte )
+ {
+ pucByte++;
+ uxSourceLen--;
+ pcName[ uxNameLen++ ] = '\0';
+ }
+ else
+ {
+ pucByte = NULL;
+ }
+ }
+ }
+
+ return pucByte;
+ }
+#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
+/*-----------------------------------------------------------*/
+
+static uint8_t * prvSkipNameField( uint8_t *pucByte,
+ size_t uxSourceLen )
+{
+size_t uxChunkLength;
+
+ if( 0u == uxSourceLen )
+ {
+ return NULL;
+ }
+
+ /* Determine if the name is the fully coded name, or an offset to the name
+ elsewhere in the message. */
+ if( ( *pucByte & dnsNAME_IS_OFFSET ) == dnsNAME_IS_OFFSET )
+ {
+ /* Jump over the two byte offset. */
+ if( uxSourceLen > sizeof( uint16_t ) )
+ {
+ pucByte += sizeof( uint16_t );
+ }
+ else
+ {
+ pucByte = NULL;
+ }
+ }
+ else
+ {
+ /* pucByte points to the full name. Walk over the string. */
+ while( ( *pucByte != 0x00u ) && ( uxSourceLen > 1u ) )
+ {
+ uxChunkLength = *pucByte + 1u;
+
+ if( uxSourceLen > uxChunkLength )
+ {
+ uxSourceLen -= uxChunkLength;
+ pucByte += uxChunkLength;
+ }
+ else
+ {
+ pucByte = NULL;
+ break;
+ }
+ }
+
+ /* Confirm that a fully formed name was found. */
+ if( NULL != pucByte )
+ {
+ if( 0x00u == *pucByte )
+ {
+ pucByte++;
+ }
+ else
+ {
+ pucByte = NULL;
+ }
+ }
+ }
+
+ return pucByte;
+}
+/*-----------------------------------------------------------*/
+
+/* The function below will only be called :
+when ipconfigDNS_USE_CALLBACKS == 1
+when ipconfigUSE_LLMNR == 1
+for testing purposes, by the module iot_test_freertos_tcp.c
+*/
+uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+DNSMessage_t *pxDNSMessageHeader;
+size_t uxPayloadSize;
+
+ /* Only proceed if the payload length indicated in the header
+ appears to be valid. */
+ if( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) )
+ {
+ uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
+
+ if( uxPayloadSize >= sizeof( DNSMessage_t ) )
+ {
+ pxDNSMessageHeader =
+ ( DNSMessage_t * ) ( pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t ) );
+
+ /* The parameter pdFALSE indicates that the reply was not expected. */
+ prvParseDNSReply( ( uint8_t * ) pxDNSMessageHeader,
+ uxPayloadSize,
+ pdFALSE );
+ }
+ }
+
+ /* The packet was not consumed. */
+ return pdFAIL;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_NBNS == 1 )
+
+ uint32_t ulNBNSHandlePacket( NetworkBufferDescriptor_t * pxNetworkBuffer )
+ {
+ UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
+ uint8_t *pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
+ size_t uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
+
+ /* The network buffer data length has already been set to the
+ length of the UDP payload. */
+ prvTreatNBNS( pucUDPPayloadBuffer,
+ uxPayloadSize,
+ pxUDPPacket->xIPHeader.ulSourceIPAddress );
+
+ /* The packet was not consumed. */
+ return pdFAIL;
+ }
+
+#endif /* ipconfigUSE_NBNS */
+/*-----------------------------------------------------------*/
+
+static uint32_t prvParseDNSReply( uint8_t *pucUDPPayloadBuffer,
+ size_t uxBufferLength,
+ BaseType_t xExpected )
+{
+DNSMessage_t *pxDNSMessageHeader;
+DNSAnswerRecord_t *pxDNSAnswerRecord;
+uint32_t ulIPAddress = 0uL;
+#if( ipconfigUSE_LLMNR == 1 )
+ char *pcRequestedName = NULL;
+#endif
+uint8_t *pucByte;
+size_t uxSourceBytesRemaining;
+uint16_t x, usDataLength, usQuestions;
+BaseType_t xDoStore = xExpected;
+#if( ipconfigUSE_LLMNR == 1 )
+ uint16_t usType = 0, usClass = 0;
+#endif
+#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
+ char pcName[ ipconfigDNS_CACHE_NAME_LENGTH ] = "";
+#endif
+
+ /* Ensure that the buffer is of at least minimal DNS message length. */
+ if( uxBufferLength < sizeof( DNSMessage_t ) )
+ {
+ return dnsPARSE_ERROR;
+ }
+
+ uxSourceBytesRemaining = uxBufferLength;
+
+ /* Parse the DNS message header. */
+ pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
+
+ /* Introduce a do {} while (0) to allow the use of breaks. */
+ do
+ {
+ /* Start at the first byte after the header. */
+ pucByte = pucUDPPayloadBuffer + sizeof( DNSMessage_t );
+ uxSourceBytesRemaining -= sizeof( DNSMessage_t );
+
+ /* Skip any question records. */
+ usQuestions = FreeRTOS_ntohs( pxDNSMessageHeader->usQuestions );
+
+ for( x = 0; x < usQuestions; x++ )
+ {
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ if( x == 0 )
+ {
+ pcRequestedName = ( char * ) pucByte;
+ }
+ }
+ #endif
+
+#if( ipconfigUSE_DNS_CACHE == 1 ) || ( ipconfigDNS_USE_CALLBACKS == 1 )
+ if( x == 0 )
+ {
+ pucByte = prvReadNameField( pucByte,
+ uxSourceBytesRemaining,
+ pcName,
+ sizeof( pcName ) );
+
+ /* Check for a malformed response. */
+ if( NULL == pucByte )
+ {
+ return dnsPARSE_ERROR;
+ }
+
+ uxSourceBytesRemaining = ( pucUDPPayloadBuffer + uxBufferLength ) - pucByte;
+ }
+ else
+#endif /* ipconfigUSE_DNS_CACHE || ipconfigDNS_USE_CALLBACKS */
+ {
+ /* Skip the variable length pcName field. */
+ pucByte = prvSkipNameField( pucByte,
+ uxSourceBytesRemaining );
+
+ /* Check for a malformed response. */
+ if( NULL == pucByte )
+ {
+ return dnsPARSE_ERROR;
+ }
+
+ uxSourceBytesRemaining = ( size_t )
+ ( pucUDPPayloadBuffer + uxBufferLength - pucByte );
+ }
+
+ /* Check the remaining buffer size. */
+ if( uxSourceBytesRemaining >= sizeof( uint32_t ) )
+ {
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ /* usChar2u16 returns value in host endianness. */
+ usType = usChar2u16( pucByte );
+ usClass = usChar2u16( pucByte + 2 );
+ }
+ #endif /* ipconfigUSE_LLMNR */
+
+ /* Skip the type and class fields. */
+ pucByte += sizeof( uint32_t );
+ uxSourceBytesRemaining -= sizeof( uint32_t );
+ }
+ else
+ {
+ /* Malformed response. */
+ return dnsPARSE_ERROR;
+ }
+ }
+
+ /* Search through the answer records. */
+ pxDNSMessageHeader->usAnswers = FreeRTOS_ntohs( pxDNSMessageHeader->usAnswers );
+
+ if( ( pxDNSMessageHeader->usFlags & dnsRX_FLAGS_MASK ) == dnsEXPECTED_RX_FLAGS )
+ {
+ for( x = 0; x < pxDNSMessageHeader->usAnswers; x++ )
+ {
+ pucByte = prvSkipNameField( pucByte,
+ uxSourceBytesRemaining );
+
+ /* Check for a malformed response. */
+ if( NULL == pucByte )
+ {
+ return dnsPARSE_ERROR;
+ }
+
+ uxSourceBytesRemaining = ( size_t )
+ ( pucUDPPayloadBuffer + uxBufferLength - pucByte );
+
+ /* Is there enough data for an IPv4 A record answer and, if so,
+ is this an A record? */
+ if( ( uxSourceBytesRemaining >= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) ) ) &&
+ ( usChar2u16( pucByte ) == dnsTYPE_A_HOST ) )
+ {
+ /* This is the required record type and is of sufficient size. */
+ pxDNSAnswerRecord = ( DNSAnswerRecord_t * ) pucByte;
+
+ /* Sanity check the data length of an IPv4 answer. */
+ if( FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength ) == sizeof( uint32_t ) )
+ {
+ /* Copy the IP address out of the record. */
+ memcpy( &ulIPAddress,
+ pucByte + sizeof( DNSAnswerRecord_t ),
+ sizeof( uint32_t ) );
+
+ #if( ipconfigDNS_USE_CALLBACKS == 1 )
+ {
+ /* See if any asynchronous call was made to FreeRTOS_gethostbyname_a() */
+ if( xDNSDoCallback( ( TickType_t ) pxDNSMessageHeader->usIdentifier, pcName, ulIPAddress ) != pdFALSE )
+ {
+ /* This device has requested this DNS look-up.
+ The result may be stored in the DNS cache. */
+ xDoStore = pdTRUE;
+ }
+ }
+ #endif /* ipconfigDNS_USE_CALLBACKS == 1 */
+ #if( ipconfigUSE_DNS_CACHE == 1 )
+ {
+ /* The reply will only be stored in the DNS cache when the
+ request was issued by this device. */
+ if( xDoStore != pdFALSE )
+ {
+ prvProcessDNSCache( pcName, &ulIPAddress, pxDNSAnswerRecord->ulTTL, pdFALSE );
+ }
+
+ /* Show what has happened. */
+ FreeRTOS_printf( ( "DNS[0x%04X]: The answer to '%s' (%xip) will%s be stored\n",
+ ( unsigned ) pxDNSMessageHeader->usIdentifier,
+ pcName,
+ ( unsigned ) FreeRTOS_ntohl( ulIPAddress ),
+ ( xDoStore != 0 ) ? "" : " NOT" ) );
+ }
+ #endif /* ipconfigUSE_DNS_CACHE */
+ }
+
+ pucByte += sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t );
+ uxSourceBytesRemaining -= ( sizeof( DNSAnswerRecord_t ) + sizeof( uint32_t ) );
+ break;
+ }
+ else if( uxSourceBytesRemaining >= sizeof( DNSAnswerRecord_t ) )
+ {
+ /* It's not an A record, so skip it. Get the header location
+ and then jump over the header. */
+ pxDNSAnswerRecord = ( DNSAnswerRecord_t * ) pucByte;
+ pucByte += sizeof( DNSAnswerRecord_t );
+ uxSourceBytesRemaining -= sizeof( DNSAnswerRecord_t );
+
+ /* Determine the length of the answer data from the header. */
+ usDataLength = FreeRTOS_ntohs( pxDNSAnswerRecord->usDataLength );
+
+ /* Jump over the answer. */
+ if( uxSourceBytesRemaining >= usDataLength )
+ {
+ pucByte += usDataLength;
+ uxSourceBytesRemaining -= usDataLength;
+ }
+ else
+ {
+ /* Malformed response. */
+ return dnsPARSE_ERROR;
+ }
+ }
+ }
+ }
+
+#if( ipconfigUSE_LLMNR == 1 )
+ else if( usQuestions && ( usType == dnsTYPE_A_HOST ) && ( usClass == dnsCLASS_IN ) )
+ {
+ /* If this is not a reply to our DNS request, it might an LLMNR
+ request. */
+ if( xApplicationDNSQueryHook( ( pcRequestedName + 1 ) ) )
+ {
+ int16_t usLength;
+ NetworkBufferDescriptor_t *pxNewBuffer = NULL;
+ NetworkBufferDescriptor_t *pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( pucUDPPayloadBuffer );
+ LLMNRAnswer_t *pxAnswer;
+
+ if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
+ {
+ BaseType_t xDataLength = uxBufferLength + sizeof( UDPHeader_t ) + sizeof( EthernetHeader_t ) + sizeof( IPHeader_t );
+
+ /* Set the size of the outgoing packet. */
+ pxNetworkBuffer->xDataLength = xDataLength;
+ pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, xDataLength + sizeof( LLMNRAnswer_t ) );
+
+ if( pxNewBuffer != NULL )
+ {
+ BaseType_t xOffset1, xOffset2;
+
+ xOffset1 = ( BaseType_t ) ( pucByte - pucUDPPayloadBuffer );
+ xOffset2 = ( BaseType_t ) ( ( ( uint8_t * ) pcRequestedName ) - pucUDPPayloadBuffer );
+
+ pxNetworkBuffer = pxNewBuffer;
+ pucUDPPayloadBuffer = pxNetworkBuffer->pucEthernetBuffer + ipUDP_PAYLOAD_OFFSET_IPv4;
+
+ pucByte = pucUDPPayloadBuffer + xOffset1;
+ pcRequestedName = ( char * ) ( pucUDPPayloadBuffer + xOffset2 );
+ pxDNSMessageHeader = ( DNSMessage_t * ) pucUDPPayloadBuffer;
+ }
+ else
+ {
+ /* Just to indicate that the message may not be answered. */
+ pxNetworkBuffer = NULL;
+ }
+ }
+
+ if( pxNetworkBuffer != NULL )
+ {
+ pxAnswer = ( LLMNRAnswer_t * ) pucByte;
+
+ /* We leave 'usIdentifier' and 'usQuestions' untouched */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usFlags, dnsLLMNR_FLAGS_IS_REPONSE ); /* Set the response flag */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usAnswers, 1 ); /* Provide a single answer */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usAuthorityRRs, 0 ); /* No authority */
+ vSetField16( pxDNSMessageHeader, DNSMessage_t, usAdditionalRRs, 0 ); /* No additional info */
+
+ pxAnswer->ucNameCode = dnsNAME_IS_OFFSET;
+ pxAnswer->ucNameOffset = ( uint8_t ) ( pcRequestedName - ( char * ) pucUDPPayloadBuffer );
+
+ vSetField16( pxAnswer, LLMNRAnswer_t, usType, dnsTYPE_A_HOST ); /* Type A: host */
+ vSetField16( pxAnswer, LLMNRAnswer_t, usClass, dnsCLASS_IN ); /* 1: Class IN */
+ vSetField32( pxAnswer, LLMNRAnswer_t, ulTTL, dnsLLMNR_TTL_VALUE );
+ vSetField16( pxAnswer, LLMNRAnswer_t, usDataLength, 4 );
+ vSetField32( pxAnswer, LLMNRAnswer_t, ulIPAddress, FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) );
+
+ usLength = ( int16_t ) ( sizeof( *pxAnswer ) + ( size_t ) ( pucByte - pucUDPPayloadBuffer ) );
+
+ prvReplyDNSMessage( pxNetworkBuffer, usLength );
+
+ if( pxNewBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNewBuffer );
+ }
+ }
+ }
+ }
+#endif /* ipconfigUSE_LLMNR == 1 */
+ } while( 0 );
+
+ if( xExpected == pdFALSE )
+ {
+ /* Do not return a valid IP-address in case the reply was not expected. */
+ ulIPAddress = 0uL;
+ }
+
+ return ulIPAddress;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_NBNS == 1 )
+
+ static void prvTreatNBNS( uint8_t *pucUDPPayloadBuffer,
+ size_t uxBufferLength,
+ uint32_t ulIPAddress )
+ {
+ uint16_t usFlags, usType, usClass;
+ uint8_t *pucSource, *pucTarget;
+ uint8_t ucByte;
+ uint8_t ucNBNSName[ 17 ];
+
+ /* Check for minimum buffer size. */
+ if( uxBufferLength < sizeof( NBNSRequest_t ) )
+ {
+ return;
+ }
+
+ /* Read the request flags in host endianness. */
+ usFlags = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usFlags ) );
+
+ if( ( usFlags & dnsNBNS_FLAGS_OPCODE_MASK ) == dnsNBNS_FLAGS_OPCODE_QUERY )
+ {
+ usType = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usType ) );
+ usClass = usChar2u16( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usClass ) );
+
+ /* Not used for now */
+ ( void ) usClass;
+
+ /* For NBNS a name is 16 bytes long, written with capitals only.
+ Make sure that the copy is terminated with a zero. */
+ pucTarget = ucNBNSName + sizeof( ucNBNSName ) - 2;
+ pucTarget[ 1 ] = '\0';
+
+ /* Start with decoding the last 2 bytes. */
+ pucSource = pucUDPPayloadBuffer + ( offsetof( NBNSRequest_t, ucName ) + ( dnsNBNS_ENCODED_NAME_LENGTH - 2 ) );
+
+ for( ;; )
+ {
+ ucByte = ( uint8_t ) ( ( ( pucSource[ 0 ] - 0x41 ) << 4 ) | ( pucSource[ 1 ] - 0x41 ) );
+
+ /* Make sure there are no trailing spaces in the name. */
+ if( ( ucByte == ' ' ) && ( pucTarget[ 1 ] == '\0' ) )
+ {
+ ucByte = '\0';
+ }
+
+ *pucTarget = ucByte;
+
+ if( pucTarget == ucNBNSName )
+ {
+ break;
+ }
+
+ pucTarget -= 1;
+ pucSource -= 2;
+ }
+
+ #if( ipconfigUSE_DNS_CACHE == 1 )
+ {
+ if( ( usFlags & dnsNBNS_FLAGS_RESPONSE ) != 0 )
+ {
+ /* If this is a response from another device,
+ add the name to the DNS cache */
+ prvProcessDNSCache( ( char * ) ucNBNSName, &ulIPAddress, 0, pdFALSE );
+ }
+ }
+ #else
+ {
+ /* Avoid compiler warnings. */
+ ( void ) ulIPAddress;
+ }
+ #endif /* ipconfigUSE_DNS_CACHE */
+
+ if( ( ( usFlags & dnsNBNS_FLAGS_RESPONSE ) == 0 ) &&
+ ( usType == dnsNBNS_TYPE_NET_BIOS ) &&
+ ( xApplicationDNSQueryHook( ( const char * ) ucNBNSName ) != pdFALSE ) )
+ {
+ uint16_t usLength;
+ DNSMessage_t *pxMessage;
+ NBNSAnswer_t *pxAnswer;
+
+ /* Someone is looking for a device with ucNBNSName,
+ prepare a positive reply. */
+ NetworkBufferDescriptor_t *pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( pucUDPPayloadBuffer );
+
+ if( ( xBufferAllocFixedSize == pdFALSE ) && ( pxNetworkBuffer != NULL ) )
+ {
+ NetworkBufferDescriptor_t *pxNewBuffer;
+
+ /* The field xDataLength was set to the total length of the UDP packet,
+ i.e. the payload size plus sizeof( UDPPacket_t ). */
+ pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, pxNetworkBuffer->xDataLength + sizeof( NBNSAnswer_t ) );
+
+ if( pxNewBuffer != NULL )
+ {
+ pucUDPPayloadBuffer = pxNewBuffer->pucEthernetBuffer + sizeof( UDPPacket_t );
+ pxNetworkBuffer = pxNewBuffer;
+ }
+ else
+ {
+ /* Just prevent that a reply will be sent */
+ pxNetworkBuffer = NULL;
+ }
+ }
+
+ /* Should not occur: pucUDPPayloadBuffer is part of a xNetworkBufferDescriptor */
+ if( pxNetworkBuffer != NULL )
+ {
+ pxMessage = ( DNSMessage_t * ) pucUDPPayloadBuffer;
+
+ /* As the fields in the structures are not word-aligned, we have to
+ copy the values byte-by-byte using macro's vSetField16() and vSetField32() */
+ vSetField16( pxMessage, DNSMessage_t, usFlags, dnsNBNS_QUERY_RESPONSE_FLAGS ); /* 0x8500 */
+ vSetField16( pxMessage, DNSMessage_t, usQuestions, 0 );
+ vSetField16( pxMessage, DNSMessage_t, usAnswers, 1 );
+ vSetField16( pxMessage, DNSMessage_t, usAuthorityRRs, 0 );
+ vSetField16( pxMessage, DNSMessage_t, usAdditionalRRs, 0 );
+
+ pxAnswer = ( NBNSAnswer_t * ) ( pucUDPPayloadBuffer + offsetof( NBNSRequest_t, usType ) );
+
+ vSetField16( pxAnswer, NBNSAnswer_t, usType, usType ); /* Type */
+ vSetField16( pxAnswer, NBNSAnswer_t, usClass, dnsNBNS_CLASS_IN ); /* Class */
+ vSetField32( pxAnswer, NBNSAnswer_t, ulTTL, dnsNBNS_TTL_VALUE );
+ vSetField16( pxAnswer, NBNSAnswer_t, usDataLength, 6 ); /* 6 bytes including the length field */
+ vSetField16( pxAnswer, NBNSAnswer_t, usNbFlags, dnsNBNS_NAME_FLAGS );
+ vSetField32( pxAnswer, NBNSAnswer_t, ulIPAddress, FreeRTOS_ntohl( *ipLOCAL_IP_ADDRESS_POINTER ) );
+
+ usLength = ( uint16_t ) ( offsetof( NBNSRequest_t, usType ) + sizeof( NBNSAnswer_t ) );
+
+ prvReplyDNSMessage( pxNetworkBuffer, usLength );
+ }
+ }
+ }
+ }
+
+#endif /* ipconfigUSE_NBNS */
+/*-----------------------------------------------------------*/
+
+static Socket_t prvCreateDNSSocket( void )
+{
+Socket_t xSocket = NULL;
+struct freertos_sockaddr xAddress;
+BaseType_t xReturn;
+
+ /* This must be the first time this function has been called. Create
+ the socket. */
+ xSocket = FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_DGRAM, FREERTOS_IPPROTO_UDP );
+
+ /* Auto bind the port. */
+ xAddress.sin_port = 0u;
+ xReturn = FreeRTOS_bind( xSocket, &xAddress, sizeof( xAddress ) );
+
+ /* Check the bind was successful, and clean up if not. */
+ if( xReturn != 0 )
+ {
+ FreeRTOS_closesocket( xSocket );
+ xSocket = NULL;
+ }
+ else
+ {
+ /* The send and receive timeouts will be set later on. */
+ }
+
+ return xSocket;
+}
+/*-----------------------------------------------------------*/
+
+#if( ( ipconfigUSE_NBNS == 1 ) || ( ipconfigUSE_LLMNR == 1 ) )
+
+ static void prvReplyDNSMessage( NetworkBufferDescriptor_t *pxNetworkBuffer,
+ BaseType_t lNetLength )
+ {
+ UDPPacket_t *pxUDPPacket;
+ IPHeader_t *pxIPHeader;
+ UDPHeader_t *pxUDPHeader;
+
+ pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
+ pxIPHeader = &pxUDPPacket->xIPHeader;
+ pxUDPHeader = &pxUDPPacket->xUDPHeader;
+ /* HT: started using defines like 'ipSIZE_OF_xxx' */
+ pxIPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER );
+ /* HT:endian: should not be translated, copying from packet to packet */
+ pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
+ pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
+ pxIPHeader->ucTimeToLive = ipconfigUDP_TIME_TO_LIVE;
+ pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );
+ usPacketIdentifier++;
+ pxUDPHeader->usLength = FreeRTOS_htons( lNetLength + ipSIZE_OF_UDP_HEADER );
+ vFlip_16( pxUDPPacket->xUDPHeader.usSourcePort, pxUDPPacket->xUDPHeader.usDestinationPort );
+
+ /* Important: tell NIC driver how many bytes must be sent */
+ pxNetworkBuffer->xDataLength = ( size_t ) ( lNetLength + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER + ipSIZE_OF_ETH_HEADER );
+
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ {
+ /* calculate the IP header checksum */
+ pxIPHeader->usHeaderChecksum = 0x00;
+ pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0uL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
+ pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
+
+ /* calculate the UDP checksum for outgoing package */
+ usGenerateProtocolChecksum( ( uint8_t* ) pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
+ }
+ #endif
+
+ /* This function will fill in the eth addresses and send the packet */
+ vReturnEthernetFrame( pxNetworkBuffer, pdFALSE );
+ }
+
+#endif /* ipconfigUSE_NBNS == 1 || ipconfigUSE_LLMNR == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_DNS_CACHE == 1 )
+
+ static void prvProcessDNSCache( const char *pcName,
+ uint32_t *pulIP,
+ uint32_t ulTTL,
+ BaseType_t xLookUp )
+ {
+ BaseType_t x;
+ BaseType_t xFound = pdFALSE;
+ uint32_t ulCurrentTimeSeconds = ( xTaskGetTickCount() / portTICK_PERIOD_MS ) / 1000;
+ static BaseType_t xFreeEntry = 0;
+ configASSERT(pcName);
+
+ /* For each entry in the DNS cache table. */
+ for( x = 0; x < ipconfigDNS_CACHE_ENTRIES; x++ )
+ {
+ if( xDNSCache[ x ].pcName[ 0 ] == 0 )
+ {
+ continue;
+ }
+
+ if( 0 == strcmp( xDNSCache[ x ].pcName, pcName ) )
+ {
+ /* Is this function called for a lookup or to add/update an IP address? */
+ if( xLookUp != pdFALSE )
+ {
+ /* Confirm that the record is still fresh. */
+ if( ulCurrentTimeSeconds < ( xDNSCache[ x ].ulTimeWhenAddedInSeconds + FreeRTOS_ntohl( xDNSCache[ x ].ulTTL ) ) )
+ {
+ *pulIP = xDNSCache[ x ].ulIPAddress;
+ }
+ else
+ {
+ /* Age out the old cached record. */
+ xDNSCache[ x ].pcName[ 0 ] = 0;
+ }
+ }
+ else
+ {
+ xDNSCache[ x ].ulIPAddress = *pulIP;
+ xDNSCache[ x ].ulTTL = ulTTL;
+ xDNSCache[ x ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
+ }
+
+ xFound = pdTRUE;
+ break;
+ }
+ }
+
+ if( xFound == pdFALSE )
+ {
+ if( xLookUp != pdFALSE )
+ {
+ *pulIP = 0;
+ }
+ else
+ {
+ /* Add or update the item. */
+ if( strlen( pcName ) < ipconfigDNS_CACHE_NAME_LENGTH )
+ {
+ strcpy( xDNSCache[ xFreeEntry ].pcName, pcName );
+
+ xDNSCache[ xFreeEntry ].ulIPAddress = *pulIP;
+ xDNSCache[ xFreeEntry ].ulTTL = ulTTL;
+ xDNSCache[ xFreeEntry ].ulTimeWhenAddedInSeconds = ulCurrentTimeSeconds;
+
+ xFreeEntry++;
+
+ if( xFreeEntry == ipconfigDNS_CACHE_ENTRIES )
+ {
+ xFreeEntry = 0;
+ }
+ }
+ }
+ }
+
+ if( ( xLookUp == 0 ) || ( *pulIP != 0 ) )
+ {
+ FreeRTOS_debug_printf( ( "prvProcessDNSCache: %s: '%s' @ %lxip\n", xLookUp ? "look-up" : "add", pcName, FreeRTOS_ntohl( *pulIP ) ) );
+ }
+ }
+
+#endif /* ipconfigUSE_DNS_CACHE */
+
+#endif /* ipconfigUSE_DNS != 0 */
+
+/*-----------------------------------------------------------*/
+
+/* Provide access to private members for testing. */
+#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
+ #include "iot_freertos_tcp_test_access_dns_define.h"
+#endif
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
index c94f55dd7..48e632a01 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_IP.c
@@ -1,2337 +1,2337 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_ARP.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_TCP_IP.h"
-#include "FreeRTOS_DHCP.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-#include "FreeRTOS_DNS.h"
-
-
-/* Used to ensure the structure packing is having the desired effect. The
-'volatile' is used to prevent compiler warnings about comparing a constant with
-a constant. */
-#define ipEXPECTED_EthernetHeader_t_SIZE ( ( size_t ) 14 )
-#define ipEXPECTED_ARPHeader_t_SIZE ( ( size_t ) 28 )
-#define ipEXPECTED_IPHeader_t_SIZE ( ( size_t ) 20 )
-#define ipEXPECTED_IGMPHeader__SIZE ( ( size_t ) 8 )
-#define ipEXPECTED_ICMPHeader_t_SIZE ( ( size_t ) 8 )
-#define ipEXPECTED_UDPHeader_t_SIZE ( ( size_t ) 8 )
-#define ipEXPECTED_TCPHeader_t_SIZE ( ( size_t ) 20 )
-
-
-/* ICMP protocol definitions. */
-#define ipICMP_ECHO_REQUEST ( ( uint8_t ) 8 )
-#define ipICMP_ECHO_REPLY ( ( uint8_t ) 0 )
-
-
-/* Time delay between repeated attempts to initialise the network hardware. */
-#ifndef ipINITIALISATION_RETRY_DELAY
- #define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
-#endif
-
-/* Defines how often the ARP timer callback function is executed. The time is
-shorted in the Windows simulator as simulated time is not real time. */
-#ifndef ipARP_TIMER_PERIOD_MS
- #ifdef _WINDOWS_
- #define ipARP_TIMER_PERIOD_MS ( 500 ) /* For windows simulator builds. */
- #else
- #define ipARP_TIMER_PERIOD_MS ( 10000 )
- #endif
-#endif
-
-#ifndef iptraceIP_TASK_STARTING
- #define iptraceIP_TASK_STARTING() do {} while( 0 )
-#endif
-
-#if( ( ipconfigUSE_TCP == 1 ) && !defined( ipTCP_TIMER_PERIOD_MS ) )
- /* When initialising the TCP timer,
- give it an initial time-out of 1 second. */
- #define ipTCP_TIMER_PERIOD_MS ( 1000 )
-#endif
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. In this case ipCONSIDER_FRAME_FOR_PROCESSING() can
-be #defined away. If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 0
-then the Ethernet driver will pass all received packets to the stack, and the
-stack must do the filtering itself. In this case ipCONSIDER_FRAME_FOR_PROCESSING
-needs to call eConsiderFrameForProcessing. */
-#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#endif
-
-/* The character used to fill ICMP echo requests, and therefore also the
-character expected to fill ICMP echo replies. */
-#define ipECHO_DATA_FILL_BYTE 'x'
-
-#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
- /* The bits in the two byte IP header field that make up the fragment offset value. */
- #define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0xff0f )
-#else
- /* The bits in the two byte IP header field that make up the fragment offset value. */
- #define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff )
-#endif /* ipconfigBYTE_ORDER */
-
-/* The maximum time the IP task is allowed to remain in the Blocked state if no
-events are posted to the network event queue. */
-#ifndef ipconfigMAX_IP_TASK_SLEEP_TIME
- #define ipconfigMAX_IP_TASK_SLEEP_TIME ( pdMS_TO_TICKS( 10000UL ) )
-#endif
-
-/* When a new TCP connection is established, the value of
-'ulNextInitialSequenceNumber' will be used as the initial sequence number. It
-is very important that at start-up, 'ulNextInitialSequenceNumber' contains a
-random value. Also its value must be increased continuously in time, to prevent
-a third party guessing the next sequence number and take-over a TCP connection.
-It is advised to increment it by 1 ever 4us, which makes about 256 times
-per ms: */
-#define ipINITIAL_SEQUENCE_NUMBER_FACTOR 256UL
-
-/* Returned as the (invalid) checksum when the protocol being checked is not
-handled. The value is chosen simply to be easy to spot when debugging. */
-#define ipUNHANDLED_PROTOCOL 0x4321u
-
-/* Returned to indicate a valid checksum when the checksum does not need to be
-calculated. */
-#define ipCORRECT_CRC 0xffffu
-
-/* Returned as the (invalid) checksum when the length of the data being checked
-had an invalid length. */
-#define ipINVALID_LENGTH 0x1234u
-
-/*-----------------------------------------------------------*/
-
-typedef struct xIP_TIMER
-{
- uint32_t
- bActive : 1, /* This timer is running and must be processed. */
- bExpired : 1; /* Timer has expired and a task must be processed. */
- TimeOut_t xTimeOut;
- TickType_t ulRemainingTime;
- TickType_t ulReloadTime;
-} IPTimer_t;
-
-/* Used in checksum calculation. */
-typedef union _xUnion32
-{
- uint32_t u32;
- uint16_t u16[ 2 ];
- uint8_t u8[ 4 ];
-} xUnion32;
-
-/* Used in checksum calculation. */
-typedef union _xUnionPtr
-{
- uint32_t *u32ptr;
- uint16_t *u16ptr;
- uint8_t *u8ptr;
-} xUnionPtr;
-
-/*-----------------------------------------------------------*/
-
-/*
- * The main TCP/IP stack processing task. This task receives commands/events
- * from the network hardware drivers and tasks that are using sockets. It also
- * maintains a set of protocol timers.
- */
-static void prvIPTask( void *pvParameters );
-
-/*
- * Called when new data is available from the network interface.
- */
-static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
-
-/*
- * Process incoming IP packets.
- */
-static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer );
-
-#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
- /*
- * Process incoming ICMP packets.
- */
- static eFrameProcessingResult_t prvProcessICMPPacket( ICMPPacket_t * const pxICMPPacket );
-#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
-
-/*
- * Turns around an incoming ping request to convert it into a ping reply.
- */
-#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
- static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket );
-#endif /* ipconfigREPLY_TO_INCOMING_PINGS */
-
-/*
- * Processes incoming ping replies. The application callback function
- * vApplicationPingReplyHook() is called with the results.
- */
-#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
- static void prvProcessICMPEchoReply( ICMPPacket_t * const pxICMPPacket );
-#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
-
-/*
- * Called to create a network connection when the stack is first started, or
- * when the network connection is lost.
- */
-static void prvProcessNetworkDownEvent( void );
-
-/*
- * Checks the ARP, DHCP and TCP timers to see if any periodic or timeout
- * processing is required.
- */
-static void prvCheckNetworkTimers( void );
-
-/*
- * Determine how long the IP task can sleep for, which depends on when the next
- * periodic or timeout processing must be performed.
- */
-static TickType_t prvCalculateSleepTime( void );
-
-/*
- * The network card driver has received a packet. In the case that it is part
- * of a linked packet chain, walk through it to handle every message.
- */
-static void prvHandleEthernetPacket( NetworkBufferDescriptor_t *pxBuffer );
-
-/*
- * Utility functions for the light weight IP timers.
- */
-static void prvIPTimerStart( IPTimer_t *pxTimer, TickType_t xTime );
-static BaseType_t prvIPTimerCheck( IPTimer_t *pxTimer );
-static void prvIPTimerReload( IPTimer_t *pxTimer, TickType_t xTime );
-
-static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPPacket,
- NetworkBufferDescriptor_t * const pxNetworkBuffer, UBaseType_t uxHeaderLength );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used to pass events into the IP-task for processing. */
-QueueHandle_t xNetworkEventQueue = NULL;
-
-/*_RB_ Requires comment. */
-uint16_t usPacketIdentifier = 0U;
-
-/* For convenience, a MAC address of all 0xffs is defined const for quick
-reference. */
-const MACAddress_t xBroadcastMACAddress = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
-
-/* Structure that stores the netmask, gateway address and DNS server addresses. */
-NetworkAddressingParameters_t xNetworkAddressing = { 0, 0, 0, 0, 0 };
-
-/* Default values for the above struct in case DHCP
-does not lead to a confirmed request. */
-NetworkAddressingParameters_t xDefaultAddressing = { 0, 0, 0, 0, 0 };
-
-/* Used to ensure network down events cannot be missed when they cannot be
-posted to the network event queue because the network event queue is already
-full. */
-static BaseType_t xNetworkDownEventPending = pdFALSE;
-
-/* Stores the handle of the task that handles the stack. The handle is used
-(indirectly) by some utility function to determine if the utility function is
-being called by a task (in which case it is ok to block) or by the IP task
-itself (in which case it is not ok to block). */
-static TaskHandle_t xIPTaskHandle = NULL;
-
-#if( ipconfigUSE_TCP != 0 )
- /* Set to a non-zero value if one or more TCP message have been processed
- within the last round. */
- static BaseType_t xProcessedTCPMessage;
-#endif
-
-/* Simple set to pdTRUE or pdFALSE depending on whether the network is up or
-down (connected, not connected) respectively. */
-static BaseType_t xNetworkUp = pdFALSE;
-
-/*
-A timer for each of the following processes, all of which need attention on a
-regular basis:
- 1. ARP, to check its table entries
- 2. DPHC, to send requests and to renew a reservation
- 3. TCP, to check for timeouts, resends
- 4. DNS, to check for timeouts when looking-up a domain.
- */
-static IPTimer_t xARPTimer;
-#if( ipconfigUSE_DHCP != 0 )
- static IPTimer_t xDHCPTimer;
-#endif
-#if( ipconfigUSE_TCP != 0 )
- static IPTimer_t xTCPTimer;
-#endif
-#if( ipconfigDNS_USE_CALLBACKS != 0 )
- static IPTimer_t xDNSTimer;
-#endif
-
-/* Set to pdTRUE when the IP task is ready to start processing packets. */
-static BaseType_t xIPTaskInitialised = pdFALSE;
-
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- /* Keep track of the lowest amount of space in 'xNetworkEventQueue'. */
- static UBaseType_t uxQueueMinimumSpace = ipconfigEVENT_QUEUE_LENGTH;
-#endif
-
-/*-----------------------------------------------------------*/
-
-static void prvIPTask( void *pvParameters )
-{
-IPStackEvent_t xReceivedEvent;
-TickType_t xNextIPSleep;
-FreeRTOS_Socket_t *pxSocket;
-struct freertos_sockaddr xAddress;
-
- /* Just to prevent compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- /* A possibility to set some additional task properties. */
- iptraceIP_TASK_STARTING();
-
- /* Generate a dummy message to say that the network connection has gone
- down. This will cause this task to initialise the network interface. After
- this it is the responsibility of the network interface hardware driver to
- send this message if a previously connected network is disconnected. */
- FreeRTOS_NetworkDown();
-
- #if( ipconfigUSE_TCP == 1 )
- {
- /* Initialise the TCP timer. */
- prvIPTimerReload( &xTCPTimer, pdMS_TO_TICKS( ipTCP_TIMER_PERIOD_MS ) );
- }
- #endif
-
- /* Initialisation is complete and events can now be processed. */
- xIPTaskInitialised = pdTRUE;
-
- FreeRTOS_debug_printf( ( "prvIPTask started\n" ) );
-
- /* Loop, processing IP events. */
- for( ;; )
- {
- ipconfigWATCHDOG_TIMER();
-
- /* Check the ARP, DHCP and TCP timers to see if there is any periodic
- or timeout processing to perform. */
- prvCheckNetworkTimers();
-
- /* Calculate the acceptable maximum sleep time. */
- xNextIPSleep = prvCalculateSleepTime();
-
- /* Wait until there is something to do. If the following call exits
- * due to a time out rather than a message being received, set a
- * 'NoEvent' value. */
- if ( xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep ) == pdFALSE )
- {
- xReceivedEvent.eEventType = eNoEvent;
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- if( xReceivedEvent.eEventType != eNoEvent )
- {
- UBaseType_t uxCount;
-
- uxCount = uxQueueSpacesAvailable( xNetworkEventQueue );
- if( uxQueueMinimumSpace > uxCount )
- {
- uxQueueMinimumSpace = uxCount;
- }
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- iptraceNETWORK_EVENT_RECEIVED( xReceivedEvent.eEventType );
-
- switch( xReceivedEvent.eEventType )
- {
- case eNetworkDownEvent :
- /* Attempt to establish a connection. */
- xNetworkUp = pdFALSE;
- prvProcessNetworkDownEvent();
- break;
-
- case eNetworkRxEvent:
- /* The network hardware driver has received a new packet. A
- pointer to the received buffer is located in the pvData member
- of the received event structure. */
- prvHandleEthernetPacket( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ) );
- break;
-
- case eNetworkTxEvent:
- /* Send a network packet. The ownership will be transferred to
- the driver, which will release it after delivery. */
- xNetworkInterfaceOutput( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ), pdTRUE );
- break;
-
- case eARPTimerEvent :
- /* The ARP timer has expired, process the ARP cache. */
- vARPAgeCache();
- break;
-
- case eSocketBindEvent:
- /* FreeRTOS_bind (a user API) wants the IP-task to bind a socket
- to a port. The port number is communicated in the socket field
- usLocalPort. vSocketBind() will actually bind the socket and the
- API will unblock as soon as the eSOCKET_BOUND event is
- triggered. */
- pxSocket = ( FreeRTOS_Socket_t * ) ( xReceivedEvent.pvData );
- xAddress.sin_addr = 0u; /* For the moment. */
- xAddress.sin_port = FreeRTOS_ntohs( pxSocket->usLocalPort );
- pxSocket->usLocalPort = 0u;
- vSocketBind( pxSocket, &xAddress, sizeof( xAddress ), pdFALSE );
-
- /* Before 'eSocketBindEvent' was sent it was tested that
- ( xEventGroup != NULL ) so it can be used now to wake up the
- user. */
- pxSocket->xEventBits |= eSOCKET_BOUND;
- vSocketWakeUpUser( pxSocket );
- break;
-
- case eSocketCloseEvent :
- /* The user API FreeRTOS_closesocket() has sent a message to the
- IP-task to actually close a socket. This is handled in
- vSocketClose(). As the socket gets closed, there is no way to
- report back to the API, so the API won't wait for the result */
- vSocketClose( ( FreeRTOS_Socket_t * ) ( xReceivedEvent.pvData ) );
- break;
-
- case eStackTxEvent :
- /* The network stack has generated a packet to send. A
- pointer to the generated buffer is located in the pvData
- member of the received event structure. */
- vProcessGeneratedUDPPacket( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ) );
- break;
-
- case eDHCPEvent:
- /* The DHCP state machine needs processing. */
- #if( ipconfigUSE_DHCP == 1 )
- {
- vDHCPProcess( pdFALSE );
- }
- #endif /* ipconfigUSE_DHCP */
- break;
-
- case eSocketSelectEvent :
- /* FreeRTOS_select() has got unblocked by a socket event,
- vSocketSelect() will check which sockets actually have an event
- and update the socket field xSocketBits. */
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- vSocketSelect( ( SocketSelect_t * ) ( xReceivedEvent.pvData ) );
- }
- #endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
- break;
-
- case eSocketSignalEvent :
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- /* Some task wants to signal the user of this socket in
- order to interrupt a call to recv() or a call to select(). */
- FreeRTOS_SignalSocket( ( Socket_t ) xReceivedEvent.pvData );
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
- break;
-
- case eTCPTimerEvent :
- #if( ipconfigUSE_TCP == 1 )
- {
- /* Simply mark the TCP timer as expired so it gets processed
- the next time prvCheckNetworkTimers() is called. */
- xTCPTimer.bExpired = pdTRUE_UNSIGNED;
- }
- #endif /* ipconfigUSE_TCP */
- break;
-
- case eTCPAcceptEvent:
- /* The API FreeRTOS_accept() was called, the IP-task will now
- check if the listening socket (communicated in pvData) actually
- received a new connection. */
- #if( ipconfigUSE_TCP == 1 )
- {
- pxSocket = ( FreeRTOS_Socket_t * ) ( xReceivedEvent.pvData );
-
- if( xTCPCheckNewClient( pxSocket ) != pdFALSE )
- {
- pxSocket->xEventBits |= eSOCKET_ACCEPT;
- vSocketWakeUpUser( pxSocket );
- }
- }
- #endif /* ipconfigUSE_TCP */
- break;
-
- case eTCPNetStat:
- /* FreeRTOS_netstat() was called to have the IP-task print an
- overview of all sockets and their connections */
- #if( ( ipconfigUSE_TCP == 1 ) && ( ipconfigHAS_PRINTF == 1 ) )
- {
- vTCPNetStat();
- }
- #endif /* ipconfigUSE_TCP */
- break;
-
- default :
- /* Should not get here. */
- break;
- }
-
- if( xNetworkDownEventPending != pdFALSE )
- {
- /* A network down event could not be posted to the network event
- queue because the queue was full. Try posting again. */
- FreeRTOS_NetworkDown();
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xIsCallingFromIPTask( void )
-{
-BaseType_t xReturn;
-
- if( xTaskGetCurrentTaskHandle() == xIPTaskHandle )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvHandleEthernetPacket( NetworkBufferDescriptor_t *pxBuffer )
-{
- #if( ipconfigUSE_LINKED_RX_MESSAGES == 0 )
- {
- /* When ipconfigUSE_LINKED_RX_MESSAGES is not set to 0 then only one
- buffer will be sent at a time. This is the default way for +TCP to pass
- messages from the MAC to the TCP/IP stack. */
- prvProcessEthernetPacket( pxBuffer );
- }
- #else /* ipconfigUSE_LINKED_RX_MESSAGES */
- {
- NetworkBufferDescriptor_t *pxNextBuffer;
-
- /* An optimisation that is useful when there is high network traffic.
- Instead of passing received packets into the IP task one at a time the
- network interface can chain received packets together and pass them into
- the IP task in one go. The packets are chained using the pxNextBuffer
- member. The loop below walks through the chain processing each packet
- in the chain in turn. */
- do
- {
- /* Store a pointer to the buffer after pxBuffer for use later on. */
- pxNextBuffer = pxBuffer->pxNextBuffer;
-
- /* Make it NULL to avoid using it later on. */
- pxBuffer->pxNextBuffer = NULL;
-
- prvProcessEthernetPacket( pxBuffer );
- pxBuffer = pxNextBuffer;
-
- /* While there is another packet in the chain. */
- } while( pxBuffer != NULL );
- }
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
-}
-/*-----------------------------------------------------------*/
-
-static TickType_t prvCalculateSleepTime( void )
-{
-TickType_t xMaximumSleepTime;
-
- /* Start with the maximum sleep time, then check this against the remaining
- time in any other timers that are active. */
- xMaximumSleepTime = ipconfigMAX_IP_TASK_SLEEP_TIME;
-
- if( xARPTimer.bActive != pdFALSE_UNSIGNED )
- {
- if( xARPTimer.ulRemainingTime < xMaximumSleepTime )
- {
- xMaximumSleepTime = xARPTimer.ulReloadTime;
- }
- }
-
- #if( ipconfigUSE_DHCP == 1 )
- {
- if( xDHCPTimer.bActive != pdFALSE_UNSIGNED )
- {
- if( xDHCPTimer.ulRemainingTime < xMaximumSleepTime )
- {
- xMaximumSleepTime = xDHCPTimer.ulRemainingTime;
- }
- }
- }
- #endif /* ipconfigUSE_DHCP */
-
- #if( ipconfigUSE_TCP == 1 )
- {
- if( xTCPTimer.ulRemainingTime < xMaximumSleepTime )
- {
- xMaximumSleepTime = xTCPTimer.ulRemainingTime;
- }
- }
- #endif
-
- #if( ipconfigDNS_USE_CALLBACKS != 0 )
- {
- if( xDNSTimer.bActive != pdFALSE )
- {
- if( xDNSTimer.ulRemainingTime < xMaximumSleepTime )
- {
- xMaximumSleepTime = xDNSTimer.ulRemainingTime;
- }
- }
- }
- #endif
-
- return xMaximumSleepTime;
-}
-/*-----------------------------------------------------------*/
-
-static void prvCheckNetworkTimers( void )
-{
- /* Is it time for ARP processing? */
- if( prvIPTimerCheck( &xARPTimer ) != pdFALSE )
- {
- xSendEventToIPTask( eARPTimerEvent );
- }
-
- #if( ipconfigUSE_DHCP == 1 )
- {
- /* Is it time for DHCP processing? */
- if( prvIPTimerCheck( &xDHCPTimer ) != pdFALSE )
- {
- xSendEventToIPTask( eDHCPEvent );
- }
- }
- #endif /* ipconfigUSE_DHCP */
-
- #if( ipconfigDNS_USE_CALLBACKS != 0 )
- {
- extern void vDNSCheckCallBack( void *pvSearchID );
-
- /* Is it time for DNS processing? */
- if( prvIPTimerCheck( &xDNSTimer ) != pdFALSE )
- {
- vDNSCheckCallBack( NULL );
- }
- }
- #endif /* ipconfigDNS_USE_CALLBACKS */
-
- #if( ipconfigUSE_TCP == 1 )
- {
- BaseType_t xWillSleep;
- TickType_t xNextTime;
- BaseType_t xCheckTCPSockets;
-
- if( uxQueueMessagesWaiting( xNetworkEventQueue ) == 0u )
- {
- xWillSleep = pdTRUE;
- }
- else
- {
- xWillSleep = pdFALSE;
- }
-
- /* Sockets need to be checked if the TCP timer has expired. */
- xCheckTCPSockets = prvIPTimerCheck( &xTCPTimer );
-
- /* Sockets will also be checked if there are TCP messages but the
- message queue is empty (indicated by xWillSleep being true). */
- if( ( xProcessedTCPMessage != pdFALSE ) && ( xWillSleep != pdFALSE ) )
- {
- xCheckTCPSockets = pdTRUE;
- }
-
- if( xCheckTCPSockets != pdFALSE )
- {
- /* Attend to the sockets, returning the period after which the
- check must be repeated. */
- xNextTime = xTCPTimerCheck( xWillSleep );
- prvIPTimerStart( &xTCPTimer, xNextTime );
- xProcessedTCPMessage = 0;
- }
- }
- #endif /* ipconfigUSE_TCP == 1 */
-}
-/*-----------------------------------------------------------*/
-
-static void prvIPTimerStart( IPTimer_t *pxTimer, TickType_t xTime )
-{
- vTaskSetTimeOutState( &pxTimer->xTimeOut );
- pxTimer->ulRemainingTime = xTime;
-
- if( xTime == ( TickType_t ) 0 )
- {
- pxTimer->bExpired = pdTRUE_UNSIGNED;
- }
- else
- {
- pxTimer->bExpired = pdFALSE_UNSIGNED;
- }
-
- pxTimer->bActive = pdTRUE_UNSIGNED;
-}
-/*-----------------------------------------------------------*/
-
-static void prvIPTimerReload( IPTimer_t *pxTimer, TickType_t xTime )
-{
- pxTimer->ulReloadTime = xTime;
- prvIPTimerStart( pxTimer, xTime );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvIPTimerCheck( IPTimer_t *pxTimer )
-{
-BaseType_t xReturn;
-
- if( pxTimer->bActive == pdFALSE_UNSIGNED )
- {
- /* The timer is not enabled. */
- xReturn = pdFALSE;
- }
- else
- {
- /* The timer might have set the bExpired flag already, if not, check the
- value of xTimeOut against ulRemainingTime. */
- if( ( pxTimer->bExpired != pdFALSE_UNSIGNED ) ||
- ( xTaskCheckForTimeOut( &( pxTimer->xTimeOut ), &( pxTimer->ulRemainingTime ) ) != pdFALSE ) )
- {
- prvIPTimerStart( pxTimer, pxTimer->ulReloadTime );
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_NetworkDown( void )
-{
-static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL };
-const TickType_t xDontBlock = ( TickType_t ) 0;
-
- /* Simply send the network task the appropriate event. */
- if( xSendEventStructToIPTask( &xNetworkDownEvent, xDontBlock ) != pdPASS )
- {
- /* Could not send the message, so it is still pending. */
- xNetworkDownEventPending = pdTRUE;
- }
- else
- {
- /* Message was sent so it is not pending. */
- xNetworkDownEventPending = pdFALSE;
- }
-
- iptraceNETWORK_DOWN();
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t FreeRTOS_NetworkDownFromISR( void )
-{
-static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL };
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- /* Simply send the network task the appropriate event. */
- if( xQueueSendToBackFromISR( xNetworkEventQueue, &xNetworkDownEvent, &xHigherPriorityTaskWoken ) != pdPASS )
- {
- xNetworkDownEventPending = pdTRUE;
- }
- else
- {
- xNetworkDownEventPending = pdFALSE;
- }
-
- iptraceNETWORK_DOWN();
-
- return xHigherPriorityTaskWoken;
-}
-/*-----------------------------------------------------------*/
-
-void *FreeRTOS_GetUDPPayloadBuffer( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-void *pvReturn;
-
- /* Cap the block time. The reason for this is explained where
- ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS is defined (assuming an official
- FreeRTOSIPConfig.h header file is being used). */
- if( xBlockTimeTicks > ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS )
- {
- xBlockTimeTicks = ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS;
- }
-
- /* Obtain a network buffer with the required amount of storage. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( UDPPacket_t ) + xRequestedSizeBytes, xBlockTimeTicks );
-
- if( pxNetworkBuffer != NULL )
- {
- /* Set the actual packet size in case a bigger buffer was returned. */
- pxNetworkBuffer->xDataLength = sizeof( UDPPacket_t ) + xRequestedSizeBytes;
-
- /* Leave space for the UPD header. */
- pvReturn = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
- }
- else
- {
- pvReturn = NULL;
- }
-
- return ( void * ) pvReturn;
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
- size_t uxNewLength )
-{
-NetworkBufferDescriptor_t * pxNewBuffer;
-
- /* This function is only used when 'ipconfigZERO_COPY_TX_DRIVER' is set to 1.
- The transmit routine wants to have ownership of the network buffer
- descriptor, because it will pass the buffer straight to DMA. */
- pxNewBuffer = pxGetNetworkBufferWithDescriptor( uxNewLength, ( TickType_t ) 0 );
-
- if( pxNewBuffer != NULL )
- {
- /* Set the actual packet size in case a bigger buffer than requested
- was returned. */
- pxNewBuffer->xDataLength = uxNewLength;
-
- /* Copy the original packet information. */
- pxNewBuffer->ulIPAddress = pxNetworkBuffer->ulIPAddress;
- pxNewBuffer->usPort = pxNetworkBuffer->usPort;
- pxNewBuffer->usBoundPort = pxNetworkBuffer->usBoundPort;
- memcpy( pxNewBuffer->pucEthernetBuffer, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
- }
-
- return pxNewBuffer;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 ) || ( ipconfigZERO_COPY_RX_DRIVER != 0 )
-
- NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer )
- {
- uint8_t *pucBuffer;
- NetworkBufferDescriptor_t *pxResult;
-
- if( pvBuffer == NULL )
- {
- pxResult = NULL;
- }
- else
- {
- /* Obtain the network buffer from the zero copy pointer. */
- pucBuffer = ( uint8_t * ) pvBuffer;
-
- /* The input here is a pointer to a payload buffer. Subtract the
- size of the header in the network buffer, usually 8 + 2 bytes. */
- pucBuffer -= ipBUFFER_PADDING;
-
- /* Here a pointer was placed to the network descriptor. As a
- pointer is dereferenced, make sure it is well aligned. */
- if( ( ( ( uint32_t ) pucBuffer ) & ( sizeof( pucBuffer ) - ( size_t ) 1 ) ) == ( uint32_t ) 0 )
- {
- pxResult = * ( ( NetworkBufferDescriptor_t ** ) pucBuffer );
- }
- else
- {
- pxResult = NULL;
- }
- }
-
- return pxResult;
- }
-
-#endif /* ipconfigZERO_COPY_TX_DRIVER != 0 */
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer )
-{
-uint8_t *pucBuffer;
-NetworkBufferDescriptor_t *pxResult;
-
- if( pvBuffer == NULL )
- {
- pxResult = NULL;
- }
- else
- {
- /* Obtain the network buffer from the zero copy pointer. */
- pucBuffer = ( uint8_t * ) pvBuffer;
-
- /* The input here is a pointer to a payload buffer. Subtract
- the total size of a UDP/IP header plus the size of the header in
- the network buffer, usually 8 + 2 bytes. */
- pucBuffer -= ( sizeof( UDPPacket_t ) + ipBUFFER_PADDING );
-
- /* Here a pointer was placed to the network descriptor,
- As a pointer is dereferenced, make sure it is well aligned */
- if( ( ( ( uint32_t ) pucBuffer ) & ( sizeof( pucBuffer ) - 1 ) ) == 0 )
- {
- /* The following statement may trigger a:
- warning: cast increases required alignment of target type [-Wcast-align].
- It has been confirmed though that the alignment is suitable. */
- pxResult = * ( ( NetworkBufferDescriptor_t ** ) pucBuffer );
- }
- else
- {
- pxResult = NULL;
- }
- }
-
- return pxResult;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_ReleaseUDPPayloadBuffer( void *pvBuffer )
-{
- vReleaseNetworkBufferAndDescriptor( pxUDPPayloadBuffer_to_NetworkBuffer( pvBuffer ) );
-}
-/*-----------------------------------------------------------*/
-
-/*_RB_ Should we add an error or assert if the task priorities are set such that the servers won't function as expected? */
-/*_HT_ There was a bug in FreeRTOS_TCP_IP.c that only occurred when the applications' priority was too high.
- As that bug has been repaired, there is not an urgent reason to warn.
- It is better though to use the advised priority scheme. */
-BaseType_t FreeRTOS_IPInit( const uint8_t ucIPAddress[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucNetMask[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucGatewayAddress[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucDNSServerAddress[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] )
-{
-BaseType_t xReturn = pdFALSE;
-
- /* This function should only be called once. */
- configASSERT( xIPIsNetworkTaskReady() == pdFALSE );
- configASSERT( xNetworkEventQueue == NULL );
- configASSERT( xIPTaskHandle == NULL );
-
- /* Check structure packing is correct. */
- configASSERT( sizeof( EthernetHeader_t ) == ipEXPECTED_EthernetHeader_t_SIZE );
- configASSERT( sizeof( ARPHeader_t ) == ipEXPECTED_ARPHeader_t_SIZE );
- configASSERT( sizeof( IPHeader_t ) == ipEXPECTED_IPHeader_t_SIZE );
- configASSERT( sizeof( ICMPHeader_t ) == ipEXPECTED_ICMPHeader_t_SIZE );
- configASSERT( sizeof( UDPHeader_t ) == ipEXPECTED_UDPHeader_t_SIZE );
-
- /* Attempt to create the queue used to communicate with the IP task. */
- xNetworkEventQueue = xQueueCreate( ( UBaseType_t ) ipconfigEVENT_QUEUE_LENGTH, ( UBaseType_t ) sizeof( IPStackEvent_t ) );
- configASSERT( xNetworkEventQueue );
-
- if( xNetworkEventQueue != NULL )
- {
- #if ( configQUEUE_REGISTRY_SIZE > 0 )
- {
- /* A queue registry is normally used to assist a kernel aware
- debugger. If one is in use then it will be helpful for the debugger
- to show information about the network event queue. */
- vQueueAddToRegistry( xNetworkEventQueue, "NetEvnt" );
- }
- #endif /* configQUEUE_REGISTRY_SIZE */
-
- if( xNetworkBuffersInitialise() == pdPASS )
- {
- /* Store the local IP and MAC address. */
- xNetworkAddressing.ulDefaultIPAddress = FreeRTOS_inet_addr_quick( ucIPAddress[ 0 ], ucIPAddress[ 1 ], ucIPAddress[ 2 ], ucIPAddress[ 3 ] );
- xNetworkAddressing.ulNetMask = FreeRTOS_inet_addr_quick( ucNetMask[ 0 ], ucNetMask[ 1 ], ucNetMask[ 2 ], ucNetMask[ 3 ] );
- xNetworkAddressing.ulGatewayAddress = FreeRTOS_inet_addr_quick( ucGatewayAddress[ 0 ], ucGatewayAddress[ 1 ], ucGatewayAddress[ 2 ], ucGatewayAddress[ 3 ] );
- xNetworkAddressing.ulDNSServerAddress = FreeRTOS_inet_addr_quick( ucDNSServerAddress[ 0 ], ucDNSServerAddress[ 1 ], ucDNSServerAddress[ 2 ], ucDNSServerAddress[ 3 ] );
- xNetworkAddressing.ulBroadcastAddress = ( xNetworkAddressing.ulDefaultIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
-
- memcpy( &xDefaultAddressing, &xNetworkAddressing, sizeof( xDefaultAddressing ) );
-
- #if ipconfigUSE_DHCP == 1
- {
- /* The IP address is not set until DHCP completes. */
- *ipLOCAL_IP_ADDRESS_POINTER = 0x00UL;
- }
- #else
- {
- /* The IP address is set from the value passed in. */
- *ipLOCAL_IP_ADDRESS_POINTER = xNetworkAddressing.ulDefaultIPAddress;
-
- /* Added to prevent ARP flood to gateway. Ensure the
- gateway is on the same subnet as the IP address. */
- if( xNetworkAddressing.ulGatewayAddress != 0ul )
- {
- configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
- }
- }
- #endif /* ipconfigUSE_DHCP == 1 */
-
- /* The MAC address is stored in the start of the default packet
- header fragment, which is used when sending UDP packets. */
- memcpy( ( void * ) ipLOCAL_MAC_ADDRESS, ( void * ) ucMACAddress, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
-
- /* Prepare the sockets interface. */
- xReturn = vNetworkSocketsInit();
-
- if( pdTRUE == xReturn )
- {
- /* Create the task that processes Ethernet and stack events. */
- xReturn = xTaskCreate( prvIPTask, "IP-task", ( uint16_t )ipconfigIP_TASK_STACK_SIZE_WORDS, NULL, ( UBaseType_t )ipconfigIP_TASK_PRIORITY, &xIPTaskHandle );
- }
- }
- else
- {
- FreeRTOS_debug_printf( ( "FreeRTOS_IPInit: xNetworkBuffersInitialise() failed\n") );
-
- /* Clean up. */
- vQueueDelete( xNetworkEventQueue );
- xNetworkEventQueue = NULL;
- }
- }
- else
- {
- FreeRTOS_debug_printf( ( "FreeRTOS_IPInit: Network event queue could not be created\n") );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_GetAddressConfiguration( uint32_t *pulIPAddress, uint32_t *pulNetMask, uint32_t *pulGatewayAddress, uint32_t *pulDNSServerAddress )
-{
- /* Return the address configuration to the caller. */
-
- if( pulIPAddress != NULL )
- {
- *pulIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
- }
-
- if( pulNetMask != NULL )
- {
- *pulNetMask = xNetworkAddressing.ulNetMask;
- }
-
- if( pulGatewayAddress != NULL )
- {
- *pulGatewayAddress = xNetworkAddressing.ulGatewayAddress;
- }
-
- if( pulDNSServerAddress != NULL )
- {
- *pulDNSServerAddress = xNetworkAddressing.ulDNSServerAddress;
- }
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_SetAddressConfiguration( const uint32_t *pulIPAddress, const uint32_t *pulNetMask, const uint32_t *pulGatewayAddress, const uint32_t *pulDNSServerAddress )
-{
- /* Update the address configuration. */
-
- if( pulIPAddress != NULL )
- {
- *ipLOCAL_IP_ADDRESS_POINTER = *pulIPAddress;
- }
-
- if( pulNetMask != NULL )
- {
- xNetworkAddressing.ulNetMask = *pulNetMask;
- }
-
- if( pulGatewayAddress != NULL )
- {
- xNetworkAddressing.ulGatewayAddress = *pulGatewayAddress;
- }
-
- if( pulDNSServerAddress != NULL )
- {
- xNetworkAddressing.ulDNSServerAddress = *pulDNSServerAddress;
- }
-}
-/*-----------------------------------------------------------*/
-
-#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
-
- BaseType_t FreeRTOS_SendPingRequest( uint32_t ulIPAddress, size_t xNumberOfBytesToSend, TickType_t xBlockTimeTicks )
- {
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- ICMPHeader_t *pxICMPHeader;
- BaseType_t xReturn = pdFAIL;
- static uint16_t usSequenceNumber = 0;
- uint8_t *pucChar;
- IPStackEvent_t xStackTxEvent = { eStackTxEvent, NULL };
-
- if( (xNumberOfBytesToSend >= 1 ) && ( xNumberOfBytesToSend < ( ( ipconfigNETWORK_MTU - sizeof( IPHeader_t ) ) - sizeof( ICMPHeader_t ) ) ) && ( uxGetNumberOfFreeNetworkBuffers() >= 3 ) )
- {
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( xNumberOfBytesToSend + sizeof( ICMPPacket_t ), xBlockTimeTicks );
-
- if( pxNetworkBuffer != NULL )
- {
- pxICMPHeader = ( ICMPHeader_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipIP_PAYLOAD_OFFSET ] );
- usSequenceNumber++;
-
- /* Fill in the basic header information. */
- pxICMPHeader->ucTypeOfMessage = ipICMP_ECHO_REQUEST;
- pxICMPHeader->ucTypeOfService = 0;
- pxICMPHeader->usIdentifier = usSequenceNumber;
- pxICMPHeader->usSequenceNumber = usSequenceNumber;
-
- /* Find the start of the data. */
- pucChar = ( uint8_t * ) pxICMPHeader;
- pucChar += sizeof( ICMPHeader_t );
-
- /* Just memset the data to a fixed value. */
- memset( ( void * ) pucChar, ( int ) ipECHO_DATA_FILL_BYTE, xNumberOfBytesToSend );
-
- /* The message is complete, IP and checksum's are handled by
- vProcessGeneratedUDPPacket */
- pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = FREERTOS_SO_UDPCKSUM_OUT;
- pxNetworkBuffer->ulIPAddress = ulIPAddress;
- pxNetworkBuffer->usPort = ipPACKET_CONTAINS_ICMP_DATA;
- /* xDataLength is the size of the total packet, including the Ethernet header. */
- pxNetworkBuffer->xDataLength = xNumberOfBytesToSend + sizeof( ICMPPacket_t );
-
- /* Send to the stack. */
- xStackTxEvent.pvData = pxNetworkBuffer;
-
- if( xSendEventStructToIPTask( &xStackTxEvent, xBlockTimeTicks) != pdPASS )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceSTACK_TX_EVENT_LOST( ipSTACK_TX_EVENT );
- }
- else
- {
- xReturn = usSequenceNumber;
- }
- }
- }
- else
- {
- /* The requested number of bytes will not fit in the available space
- in the network buffer. */
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigSUPPORT_OUTGOING_PINGS == 1 */
-/*-----------------------------------------------------------*/
-
-BaseType_t xSendEventToIPTask( eIPEvent_t eEvent )
-{
-IPStackEvent_t xEventMessage;
-const TickType_t xDontBlock = ( TickType_t ) 0;
-
- xEventMessage.eEventType = eEvent;
- xEventMessage.pvData = ( void* )NULL;
-
- return xSendEventStructToIPTask( &xEventMessage, xDontBlock );
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout )
-{
-BaseType_t xReturn, xSendMessage;
-
- if( ( xIPIsNetworkTaskReady() == pdFALSE ) && ( pxEvent->eEventType != eNetworkDownEvent ) )
- {
- /* Only allow eNetworkDownEvent events if the IP task is not ready
- yet. Not going to attempt to send the message so the send failed. */
- xReturn = pdFAIL;
- }
- else
- {
- xSendMessage = pdTRUE;
-
- #if( ipconfigUSE_TCP == 1 )
- {
- if( pxEvent->eEventType == eTCPTimerEvent )
- {
- /* TCP timer events are sent to wake the timer task when
- xTCPTimer has expired, but there is no point sending them if the
- IP task is already awake processing other message. */
- xTCPTimer.bExpired = pdTRUE_UNSIGNED;
-
- if( uxQueueMessagesWaiting( xNetworkEventQueue ) != 0u )
- {
- /* Not actually going to send the message but this is not a
- failure as the message didn't need to be sent. */
- xSendMessage = pdFALSE;
- }
- }
- }
- #endif /* ipconfigUSE_TCP */
-
- if( xSendMessage != pdFALSE )
- {
- /* The IP task cannot block itself while waiting for itself to
- respond. */
- if( ( xIsCallingFromIPTask() == pdTRUE ) && ( xTimeout > ( TickType_t ) 0 ) )
- {
- xTimeout = ( TickType_t ) 0;
- }
-
- xReturn = xQueueSendToBack( xNetworkEventQueue, pxEvent, xTimeout );
-
- if( xReturn == pdFAIL )
- {
- /* A message should have been sent to the IP task, but wasn't. */
- FreeRTOS_debug_printf( ( "xSendEventStructToIPTask: CAN NOT ADD %d\n", pxEvent->eEventType ) );
- iptraceSTACK_TX_EVENT_LOST( pxEvent->eEventType );
- }
- }
- else
- {
- /* It was not necessary to send the message to process the event so
- even though the message was not sent the call was successful. */
- xReturn = pdPASS;
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer )
-{
-eFrameProcessingResult_t eReturn;
-const EthernetHeader_t *pxEthernetHeader;
-
- pxEthernetHeader = ( const EthernetHeader_t * ) pucEthernetBuffer;
-
- if( memcmp( ( void * ) ipLOCAL_MAC_ADDRESS, ( void * ) &( pxEthernetHeader->xDestinationAddress ), sizeof( MACAddress_t ) ) == 0 )
- {
- /* The packet was directed to this node directly - process it. */
- eReturn = eProcessBuffer;
- }
- else if( memcmp( ( void * ) xBroadcastMACAddress.ucBytes, ( void * ) pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
- {
- /* The packet was a broadcast - process it. */
- eReturn = eProcessBuffer;
- }
- else
-#if( ipconfigUSE_LLMNR == 1 )
- if( memcmp( ( void * ) xLLMNR_MacAdress.ucBytes, ( void * ) pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
- {
- /* The packet is a request for LLMNR - process it. */
- eReturn = eProcessBuffer;
- }
- else
-#endif /* ipconfigUSE_LLMNR */
- {
- /* The packet was not a broadcast, or for this node, just release
- the buffer without taking any other action. */
- eReturn = eReleaseBuffer;
- }
-
- #if( ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES == 1 )
- {
- uint16_t usFrameType;
-
- if( eReturn == eProcessBuffer )
- {
- usFrameType = pxEthernetHeader->usFrameType;
- usFrameType = FreeRTOS_ntohs( usFrameType );
-
- if( usFrameType <= 0x600U )
- {
- /* Not an Ethernet II frame. */
- eReturn = eReleaseBuffer;
- }
- }
- }
- #endif /* ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES == 1 */
-
- return eReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvProcessNetworkDownEvent( void )
-{
- /* Stop the ARP timer while there is no network. */
- xARPTimer.bActive = pdFALSE_UNSIGNED;
-
- #if ipconfigUSE_NETWORK_EVENT_HOOK == 1
- {
- static BaseType_t xCallEventHook = pdFALSE;
-
- /* The first network down event is generated by the IP stack itself to
- initialise the network hardware, so do not call the network down event
- the first time through. */
- if( xCallEventHook == pdTRUE )
- {
- vApplicationIPNetworkEventHook( eNetworkDown );
- }
- xCallEventHook = pdTRUE;
- }
- #endif
-
- /* Per the ARP Cache Validation section of https://tools.ietf.org/html/rfc1122,
- treat network down as a "delivery problem" and flush the ARP cache for this
- interface. */
- FreeRTOS_ClearARP( );
-
- /* The network has been disconnected (or is being initialised for the first
- time). Perform whatever hardware processing is necessary to bring it up
- again, or wait for it to be available again. This is hardware dependent. */
- if( xNetworkInterfaceInitialise() != pdPASS )
- {
- /* Ideally the network interface initialisation function will only
- return when the network is available. In case this is not the case,
- wait a while before retrying the initialisation. */
- vTaskDelay( ipINITIALISATION_RETRY_DELAY );
- FreeRTOS_NetworkDown();
- }
- else
- {
- /* Set remaining time to 0 so it will become active immediately. */
- #if ipconfigUSE_DHCP == 1
- {
- /* The network is not up until DHCP has completed. */
- vDHCPProcess( pdTRUE );
- xSendEventToIPTask( eDHCPEvent );
- }
- #else
- {
- /* Perform any necessary 'network up' processing. */
- vIPNetworkUpCalls();
- }
- #endif
- }
-}
-/*-----------------------------------------------------------*/
-
-void vIPNetworkUpCalls( void )
-{
- xNetworkUp = pdTRUE;
-
- #if( ipconfigUSE_NETWORK_EVENT_HOOK == 1 )
- {
- vApplicationIPNetworkEventHook( eNetworkUp );
- }
- #endif /* ipconfigUSE_NETWORK_EVENT_HOOK */
-
- #if( ipconfigDNS_USE_CALLBACKS != 0 )
- {
- /* The following function is declared in FreeRTOS_DNS.c and 'private' to
- this library */
- extern void vDNSInitialise( void );
- vDNSInitialise();
- }
- #endif /* ipconfigDNS_USE_CALLBACKS != 0 */
-
- /* Set remaining time to 0 so it will become active immediately. */
- prvIPTimerReload( &xARPTimer, pdMS_TO_TICKS( ipARP_TIMER_PERIOD_MS ) );
-}
-/*-----------------------------------------------------------*/
-
-static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-EthernetHeader_t *pxEthernetHeader;
-eFrameProcessingResult_t eReturned = eReleaseBuffer;
-
- configASSERT( pxNetworkBuffer );
-
- /* Interpret the Ethernet frame. */
- if( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) )
- {
- eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
- pxEthernetHeader = ( EthernetHeader_t * )( pxNetworkBuffer->pucEthernetBuffer );
-
- if( eReturned == eProcessBuffer )
- {
- /* Interpret the received Ethernet packet. */
- switch( pxEthernetHeader->usFrameType )
- {
- case ipARP_FRAME_TYPE:
- /* The Ethernet frame contains an ARP packet. */
- if( pxNetworkBuffer->xDataLength >= sizeof( ARPPacket_t ) )
- {
- eReturned = eARPProcessPacket( ( ARPPacket_t * )pxNetworkBuffer->pucEthernetBuffer );
- }
- else
- {
- eReturned = eReleaseBuffer;
- }
- break;
-
- case ipIPv4_FRAME_TYPE:
- /* The Ethernet frame contains an IP packet. */
- if( pxNetworkBuffer->xDataLength >= sizeof( IPPacket_t ) )
- {
- eReturned = prvProcessIPPacket( ( IPPacket_t * )pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
- }
- else
- {
- eReturned = eReleaseBuffer;
- }
- break;
-
- default:
- /* No other packet types are handled. Nothing to do. */
- eReturned = eReleaseBuffer;
- break;
- }
- }
- }
-
- /* Perform any actions that resulted from processing the Ethernet frame. */
- switch( eReturned )
- {
- case eReturnEthernetFrame :
- /* The Ethernet frame will have been updated (maybe it was
- an ARP request or a PING request?) and should be sent back to
- its source. */
- vReturnEthernetFrame( pxNetworkBuffer, pdTRUE );
- /* parameter pdTRUE: the buffer must be released once
- the frame has been transmitted */
- break;
-
- case eFrameConsumed :
- /* The frame is in use somewhere, don't release the buffer
- yet. */
- break;
-
- default :
- /* The frame is not being used anywhere, and the
- NetworkBufferDescriptor_t structure containing the frame should
- just be released back to the list of free buffers. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- break;
- }
-}
-/*-----------------------------------------------------------*/
-
-static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPPacket,
- NetworkBufferDescriptor_t * const pxNetworkBuffer, UBaseType_t uxHeaderLength )
-{
-eFrameProcessingResult_t eReturn = eProcessBuffer;
-
-#if( ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 ) || ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) )
- const IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
-#else
- /* or else, the parameter won't be used and the function will be optimised
- away */
- ( void ) pxIPPacket;
-#endif
-
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
- {
- /* In systems with a very small amount of RAM, it might be advantageous
- to have incoming messages checked earlier, by the network card driver.
- This method may decrease the usage of sparse network buffers. */
- uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
-
- /* Ensure that the incoming packet is not fragmented (only outgoing
- packets can be fragmented) as these are the only handled IP frames
- currently. */
- if( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U )
- {
- /* Can not handle, fragmented packet. */
- eReturn = eReleaseBuffer;
- }
- /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
- * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
- else if( ( pxIPHeader->ucVersionHeaderLength < 0x45u ) || ( pxIPHeader->ucVersionHeaderLength > 0x4Fu ) )
- {
- /* Can not handle, unknown or invalid header version. */
- eReturn = eReleaseBuffer;
- }
- /* Is the packet for this IP address? */
- else if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
- /* Is it the global broadcast address 255.255.255.255 ? */
- ( ulDestinationIPAddress != ipBROADCAST_IP_ADDRESS ) &&
- /* Is it a specific broadcast address 192.168.1.255 ? */
- ( ulDestinationIPAddress != xNetworkAddressing.ulBroadcastAddress ) &&
- #if( ipconfigUSE_LLMNR == 1 )
- /* Is it the LLMNR multicast address? */
- ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
- #endif
- /* Or (during DHCP negotiation) we have no IP-address yet? */
- ( *ipLOCAL_IP_ADDRESS_POINTER != 0UL ) )
- {
- /* Packet is not for this node, release it */
- eReturn = eReleaseBuffer;
- }
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
-
- #if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 )
- {
- /* Some drivers of NIC's with checksum-offloading will enable the above
- define, so that the checksum won't be checked again here */
- if (eReturn == eProcessBuffer )
- {
- /* Is the IP header checksum correct? */
- if( ( pxIPHeader->ucProtocol != ( uint8_t ) ipPROTOCOL_ICMP ) &&
- ( usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength ) != ipCORRECT_CRC ) )
- {
- /* Check sum in IP-header not correct. */
- eReturn = eReleaseBuffer;
- }
- /* Is the upper-layer checksum (TCP/UDP/ICMP) correct? */
- else if( usGenerateProtocolChecksum( ( uint8_t * )( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE ) != ipCORRECT_CRC )
- {
- /* Protocol checksum not accepted. */
- eReturn = eReleaseBuffer;
- }
- }
- }
- #else
- {
- /* to avoid warning unused parameters */
- ( void ) pxNetworkBuffer;
- ( void ) uxHeaderLength;
- }
- #endif /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 */
-
- return eReturn;
-}
-/*-----------------------------------------------------------*/
-
-static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-eFrameProcessingResult_t eReturn;
-IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
-UBaseType_t uxHeaderLength = ( UBaseType_t ) ( ( pxIPHeader->ucVersionHeaderLength & 0x0Fu ) << 2 );
-uint8_t ucProtocol;
-
- /* Bound the calculated header length: take away the Ethernet header size,
- then check if the IP header is claiming to be longer than the remaining
- total packet size. Also check for minimal header field length. */
- if( ( uxHeaderLength > ( pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ) ) ||
- ( uxHeaderLength < ipSIZE_OF_IPv4_HEADER ) )
- {
- return eReleaseBuffer;
- }
-
- ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
- /* Check if the IP headers are acceptable and if it has our destination. */
- eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
-
- if( eReturn == eProcessBuffer )
- {
- if( uxHeaderLength > ipSIZE_OF_IPv4_HEADER )
- {
- /* All structs of headers expect a IP header size of 20 bytes
- * IP header options were included, we'll ignore them and cut them out
- * Note: IP options are mostly use in Multi-cast protocols */
- const size_t optlen = ( ( size_t ) uxHeaderLength ) - ipSIZE_OF_IPv4_HEADER;
- /* From: the previous start of UDP/ICMP/TCP data */
- uint8_t *pucSource = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + uxHeaderLength);
- /* To: the usual start of UDP/ICMP/TCP data at offset 20 from IP header */
- uint8_t *pucTarget = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + ipSIZE_OF_IPv4_HEADER);
- /* How many: total length minus the options and the lower headers */
- const size_t xMoveLen = pxNetworkBuffer->xDataLength - optlen - ipSIZE_OF_IPv4_HEADER - ipSIZE_OF_ETH_HEADER;
-
- memmove( pucTarget, pucSource, xMoveLen );
- pxNetworkBuffer->xDataLength -= optlen;
-
- /* Fix-up new version/header length field in IP packet. */
- pxIPHeader->ucVersionHeaderLength = ( pxIPHeader->ucVersionHeaderLength & 0xF0 ) | /* High nibble is the version. */
- ( ( ipSIZE_OF_IPv4_HEADER >> 2 ) & 0x0F ); /* Low nibble is the header size, in bytes, divided by four. */
- }
-
- /* Add the IP and MAC addresses to the ARP table if they are not
- already there - otherwise refresh the age of the existing
- entry. */
- if( ucProtocol != ( uint8_t ) ipPROTOCOL_UDP )
- {
- /* Refresh the ARP cache with the IP/MAC-address of the received packet
- * For UDP packets, this will be done later in xProcessReceivedUDPPacket()
- * as soon as know that the message will be handled by someone
- * This will prevent that the ARP cache will get overwritten
- * with the IP-address of useless broadcast packets
- */
- vARPRefreshCacheEntry( &( pxIPPacket->xEthernetHeader.xSourceAddress ), pxIPHeader->ulSourceIPAddress );
- }
- switch( ucProtocol )
- {
- case ipPROTOCOL_ICMP :
- /* The IP packet contained an ICMP frame. Don't bother
- checking the ICMP checksum, as if it is wrong then the
- wrong data will also be returned, and the source of the
- ping will know something went wrong because it will not
- be able to validate what it receives. */
- #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
- {
- if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_t ) )
- {
- ICMPPacket_t *pxICMPPacket = ( ICMPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
- if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
- {
- eReturn = prvProcessICMPPacket( pxICMPPacket );
- }
- }
- else
- {
- eReturn = eReleaseBuffer;
- }
- }
- #endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
- break;
-
- case ipPROTOCOL_UDP :
- {
- /* The IP packet contained a UDP frame. */
- UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-
- /* Only proceed if the payload length indicated in the header
- appears to be valid. */
- if ( ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) ) && ( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) >= sizeof( UDPHeader_t ) ) )
- {
- size_t uxPayloadSize_1, uxPayloadSize_2;
- /* The UDP payload size can be calculated by subtracting the
- * header size from `xDataLength`.
- * However, the `xDataLength` may be longer that expected,
- * e.g. when a small packet is padded with zero's.
- * The UDP header contains a field `usLength` reflecting
- * the payload size plus the UDP header ( 8 bytes ).
- * Set `xDataLength` to the size of the headers,
- * plus the lower of the two calculated payload sizes.
- */
-
- uxPayloadSize_1 = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
- uxPayloadSize_2 = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t );
- if( uxPayloadSize_1 > uxPayloadSize_2 )
- {
- pxNetworkBuffer->xDataLength = uxPayloadSize_2 + sizeof( UDPPacket_t );
- }
-
- /* Fields in pxNetworkBuffer (usPort, ulIPAddress) are network order. */
- pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
- pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
-
- /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM:
- * In some cases, the upper-layer checksum has been calculated
- * by the NIC driver.
- *
- * Pass the packet payload to the UDP sockets implementation. */
- if( xProcessReceivedUDPPacket( pxNetworkBuffer,
- pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
- {
- eReturn = eFrameConsumed;
- }
- }
- else
- {
- eReturn = eReleaseBuffer;
- }
- }
- break;
-
-#if ipconfigUSE_TCP == 1
- case ipPROTOCOL_TCP :
- {
-
- if( xProcessReceivedTCPPacket( pxNetworkBuffer ) == pdPASS )
- {
- eReturn = eFrameConsumed;
- }
-
- /* Setting this variable will cause xTCPTimerCheck()
- to be called just before the IP-task blocks. */
- xProcessedTCPMessage++;
- }
- break;
-#endif
- default :
- /* Not a supported frame type. */
- break;
- }
- }
-
- return eReturn;
-}
-/*-----------------------------------------------------------*/
-
-#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
-
- static void prvProcessICMPEchoReply( ICMPPacket_t * const pxICMPPacket )
- {
- ePingReplyStatus_t eStatus = eSuccess;
- uint16_t usDataLength, usCount;
- uint8_t *pucByte;
-
- /* Find the total length of the IP packet. */
- usDataLength = pxICMPPacket->xIPHeader.usLength;
- usDataLength = FreeRTOS_ntohs( usDataLength );
-
- /* Remove the length of the IP headers to obtain the length of the ICMP
- message itself. */
- usDataLength = ( uint16_t ) ( ( ( uint32_t ) usDataLength ) - ipSIZE_OF_IPv4_HEADER );
-
- /* Remove the length of the ICMP header, to obtain the length of
- data contained in the ping. */
- usDataLength = ( uint16_t ) ( ( ( uint32_t ) usDataLength ) - ipSIZE_OF_ICMP_HEADER );
-
- /* Checksum has already been checked before in prvProcessIPPacket */
-
- /* Find the first byte of the data within the ICMP packet. */
- pucByte = ( uint8_t * ) pxICMPPacket;
- pucByte += sizeof( ICMPPacket_t );
-
- /* Check each byte. */
- for( usCount = 0; usCount < usDataLength; usCount++ )
- {
- if( *pucByte != ipECHO_DATA_FILL_BYTE )
- {
- eStatus = eInvalidData;
- break;
- }
-
- pucByte++;
- }
-
- /* Call back into the application to pass it the result. */
- vApplicationPingReplyHook( eStatus, pxICMPPacket->xICMPHeader.usIdentifier );
- }
-
-#endif
-/*-----------------------------------------------------------*/
-
-#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
-
- static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket )
- {
- ICMPHeader_t *pxICMPHeader;
- IPHeader_t *pxIPHeader;
- uint16_t usRequest;
-
- pxICMPHeader = &( pxICMPPacket->xICMPHeader );
- pxIPHeader = &( pxICMPPacket->xIPHeader );
-
- /* HT:endian: changed back */
- iptraceSENDING_PING_REPLY( pxIPHeader->ulSourceIPAddress );
-
- /* The checksum can be checked here - but a ping reply should be
- returned even if the checksum is incorrect so the other end can
- tell that the ping was received - even if the ping reply contains
- invalid data. */
- pxICMPHeader->ucTypeOfMessage = ( uint8_t ) ipICMP_ECHO_REPLY;
- pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
- pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
-
- /* Update the checksum because the ucTypeOfMessage member in the header
- has been changed to ipICMP_ECHO_REPLY. This is faster than calling
- usGenerateChecksum(). */
-
- /* due to compiler warning "integer operation result is out of range" */
-
- usRequest = ( uint16_t ) ( ( uint16_t )ipICMP_ECHO_REQUEST << 8 );
-
- if( pxICMPHeader->usChecksum >= FreeRTOS_htons( 0xFFFFu - usRequest ) )
- {
- pxICMPHeader->usChecksum = ( uint16_t )
- ( ( ( uint32_t ) pxICMPHeader->usChecksum ) +
- FreeRTOS_htons( usRequest + 1UL ) );
- }
- else
- {
- pxICMPHeader->usChecksum = ( uint16_t )
- ( ( ( uint32_t ) pxICMPHeader->usChecksum ) +
- FreeRTOS_htons( usRequest ) );
- }
- return eReturnEthernetFrame;
- }
-
-#endif /* ipconfigREPLY_TO_INCOMING_PINGS == 1 */
-/*-----------------------------------------------------------*/
-
-#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
-
- static eFrameProcessingResult_t prvProcessICMPPacket( ICMPPacket_t * const pxICMPPacket )
- {
- eFrameProcessingResult_t eReturn = eReleaseBuffer;
-
- iptraceICMP_PACKET_RECEIVED();
- switch( pxICMPPacket->xICMPHeader.ucTypeOfMessage )
- {
- case ipICMP_ECHO_REQUEST :
- #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
- {
- eReturn = prvProcessICMPEchoRequest( pxICMPPacket );
- }
- #endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) */
- break;
-
- case ipICMP_ECHO_REPLY :
- #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
- {
- prvProcessICMPEchoReply( pxICMPPacket );
- }
- #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
- break;
-
- default :
- break;
- }
-
- return eReturn;
- }
-
-#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
-/*-----------------------------------------------------------*/
-
-uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket )
-{
-uint32_t ulLength;
-uint16_t usChecksum, *pusChecksum;
-const IPPacket_t * pxIPPacket;
-UBaseType_t uxIPHeaderLength;
-ProtocolPacket_t *pxProtPack;
-uint8_t ucProtocol;
-#if( ipconfigHAS_DEBUG_PRINTF != 0 )
- const char *pcType;
-#endif
-
- /* Check for minimum packet size. */
- if( uxBufferLength < sizeof( IPPacket_t ) )
- {
- return ipINVALID_LENGTH;
- }
-
- /* Parse the packet length. */
- pxIPPacket = ( const IPPacket_t * ) pucEthernetBuffer;
-
- /* Per https://tools.ietf.org/html/rfc791, the four-bit Internet Header
- Length field contains the length of the internet header in 32-bit words. */
- uxIPHeaderLength = ( UBaseType_t ) ( sizeof( uint32_t ) * ( pxIPPacket->xIPHeader.ucVersionHeaderLength & 0x0Fu ) );
-
- /* Check for minimum packet size. */
- if( uxBufferLength < sizeof( IPPacket_t ) + uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER )
- {
- return ipINVALID_LENGTH;
- }
- if( uxBufferLength < ( size_t ) ( ipSIZE_OF_ETH_HEADER + FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) ) )
- {
- return ipINVALID_LENGTH;
- }
-
- /* Identify the next protocol. */
- ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
-
- /* N.B., if this IP packet header includes Options, then the following
- assignment results in a pointer into the protocol packet with the Ethernet
- and IP headers incorrectly aligned. However, either way, the "third"
- protocol (Layer 3 or 4) header will be aligned, which is the convenience
- of this calculation. */
- pxProtPack = ( ProtocolPacket_t * ) ( pucEthernetBuffer + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) );
-
- /* Switch on the Layer 3/4 protocol. */
- if( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP )
- {
- if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_UDP_HEADER ) )
- {
- return ipINVALID_LENGTH;
- }
-
- pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- pcType = "UDP";
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- }
- else if( ucProtocol == ( uint8_t ) ipPROTOCOL_TCP )
- {
- if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_TCP_HEADER ) )
- {
- return ipINVALID_LENGTH;
- }
-
- pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- pcType = "TCP";
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- }
- else if( ( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) ||
- ( ucProtocol == ( uint8_t ) ipPROTOCOL_IGMP ) )
- {
- if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_ICMP_HEADER ) )
- {
- return ipINVALID_LENGTH;
- }
-
- pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- if( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
- {
- pcType = "ICMP";
- }
- else
- {
- pcType = "IGMP";
- }
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
- }
- else
- {
- /* Unhandled protocol, other than ICMP, IGMP, UDP, or TCP. */
- return ipUNHANDLED_PROTOCOL;
- }
-
- /* The protocol and checksum field have been identified. Check the direction
- of the packet. */
- if( xOutgoingPacket != pdFALSE )
- {
- /* This is an outgoing packet. Before calculating the checksum, set it
- to zero. */
- *( pusChecksum ) = 0u;
- }
- else if( ( *pusChecksum == 0u ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
- {
- /* Sender hasn't set the checksum, no use to calculate it. */
- return ipCORRECT_CRC;
- }
-
- ulLength = ( uint32_t )
- ( FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) - ( ( uint16_t ) uxIPHeaderLength ) ); /* normally minus 20 */
-
- if( ( ulLength < sizeof( pxProtPack->xUDPPacket.xUDPHeader ) ) ||
- ( ulLength > ( uint32_t )( ipconfigNETWORK_MTU - uxIPHeaderLength ) ) )
- {
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: len invalid: %lu\n", pcType, ulLength ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
-
- /* Again, in a 16-bit return value there is no space to indicate an
- error. For incoming packets, 0x1234 will cause dropping of the packet.
- For outgoing packets, there is a serious problem with the
- format/length */
- return ipINVALID_LENGTH;
- }
- if( ucProtocol <= ( uint8_t ) ipPROTOCOL_IGMP )
- {
- /* ICMP/IGMP do not have a pseudo header for CRC-calculation. */
- usChecksum = ( uint16_t )
- ( ~usGenerateChecksum( 0UL,
- ( uint8_t * ) &( pxProtPack->xTCPPacket.xTCPHeader ), ( size_t ) ulLength ) );
- }
- else
- {
- /* For UDP and TCP, sum the pseudo header, i.e. IP protocol + length
- fields */
- usChecksum = ( uint16_t ) ( ulLength + ( ( uint16_t ) ucProtocol ) );
-
- /* And then continue at the IPv4 source and destination addresses. */
- usChecksum = ( uint16_t )
- ( ~usGenerateChecksum( ( uint32_t ) usChecksum, ( uint8_t * )&( pxIPPacket->xIPHeader.ulSourceIPAddress ),
- ( 2u * sizeof( pxIPPacket->xIPHeader.ulSourceIPAddress ) + ulLength ) ) );
-
- /* Sum TCP header and data. */
- }
-
- if( xOutgoingPacket == pdFALSE )
- {
- /* This is in incoming packet. If the CRC is correct, it should be zero. */
- if( usChecksum == 0u )
- {
- usChecksum = ( uint16_t )ipCORRECT_CRC;
- }
- }
- else
- {
- if( ( usChecksum == 0u ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
- {
- /* In case of UDP, a calculated checksum of 0x0000 is transmitted
- as 0xffff. A value of zero would mean that the checksum is not used. */
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- if( xOutgoingPacket != pdFALSE )
- {
- FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: crc swap: %04X\n", pcType, usChecksum ) );
- }
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
-
- usChecksum = ( uint16_t )0xffffu;
- }
- }
- usChecksum = FreeRTOS_htons( usChecksum );
-
- if( xOutgoingPacket != pdFALSE )
- {
- *( pusChecksum ) = usChecksum;
- }
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- else if( ( xOutgoingPacket == pdFALSE ) && ( usChecksum != ipCORRECT_CRC ) )
- {
- FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: ID %04X: from %lxip to %lxip bad crc: %04X\n",
- pcType,
- FreeRTOS_ntohs( pxIPPacket->xIPHeader.usIdentification ),
- FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ),
- FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulDestinationIPAddress ),
- FreeRTOS_ntohs( *pusChecksum ) ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
-
- return usChecksum;
-}
-/*-----------------------------------------------------------*/
-
-/**
- * This method generates a checksum for a given IPv4 header, per RFC791 (page 14).
- * The checksum algorithm is decribed as:
- * "[T]he 16 bit one's complement of the one's complement sum of all 16 bit words in the
- * header. For purposes of computing the checksum, the value of the checksum field is zero."
- *
- * In a nutshell, that means that each 16-bit 'word' must be summed, after which
- * the number of 'carries' (overflows) is added to the result. If that addition
- * produces an overflow, that 'carry' must also be added to the final result. The final checksum
- * should be the bitwise 'not' (ones-complement) of the result if the packet is
- * meant to be transmitted, but this method simply returns the raw value, probably
- * because when a packet is received, the checksum is verified by checking that
- * ((received & calculated) == 0) without applying a bitwise 'not' to the 'calculated' checksum.
- *
- * This logic is optimized for microcontrollers which have limited resources, so the logic looks odd.
- * It iterates over the full range of 16-bit words, but it does so by processing several 32-bit
- * words at once whenever possible. Its first step is to align the memory pointer to a 32-bit boundary,
- * after which it runs a fast loop to process multiple 32-bit words at once and adding their 'carries'.
- * Finally, it finishes up by processing any remaining 16-bit words, and adding up all of the 'carries'.
- * With 32-bit arithmetic, the number of 16-bit 'carries' produced by sequential additions can be found
- * by looking at the 16 most-significant bits of the 32-bit integer, since a 32-bit int will continue
- * counting up instead of overflowing after 16 bits. That is why the actual checksum calculations look like:
- * union.u32 = ( uint32_t ) union.u16[ 0 ] + union.u16[ 1 ];
- *
- * Arguments:
- * ulSum: This argument provides a value to initialize the progressive summation
- * of the header's values to. It is often 0, but protocols like TCP or UDP
- * can have pseudo-header fields which need to be included in the checksum.
- * pucNextData: This argument contains the address of the first byte which this
- * method should process. The method's memory iterator is initialized to this value.
- * uxDataLengthBytes: This argument contains the number of bytes that this method
- * should process.
- */
-uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes )
-{
-xUnion32 xSum2, xSum, xTerm;
-xUnionPtr xSource; /* Points to first byte */
-xUnionPtr xLastSource; /* Points to last byte plus one */
-uint32_t ulAlignBits, ulCarry = 0ul;
-
- /* Small MCUs often spend up to 30% of the time doing checksum calculations
- This function is optimised for 32-bit CPUs; Each time it will try to fetch
- 32-bits, sums it with an accumulator and counts the number of carries. */
-
- /* Swap the input (little endian platform only). */
- xSum.u32 = FreeRTOS_ntohs( ulSum );
- xTerm.u32 = 0ul;
-
- xSource.u8ptr = ( uint8_t * ) pucNextData;
- ulAlignBits = ( ( ( uint32_t ) pucNextData ) & 0x03u ); /* gives 0, 1, 2, or 3 */
-
- /* If byte (8-bit) aligned... */
- if( ( ( ulAlignBits & 1ul ) != 0ul ) && ( uxDataLengthBytes >= ( size_t ) 1 ) )
- {
- xTerm.u8[ 1 ] = *( xSource.u8ptr );
- ( xSource.u8ptr )++;
- uxDataLengthBytes--;
- /* Now xSource is word (16-bit) aligned. */
- }
-
- /* If half-word (16-bit) aligned... */
- if( ( ( ulAlignBits == 1u ) || ( ulAlignBits == 2u ) ) && ( uxDataLengthBytes >= 2u ) )
- {
- xSum.u32 += *(xSource.u16ptr);
- ( xSource.u16ptr )++;
- uxDataLengthBytes -= 2u;
- /* Now xSource is word (32-bit) aligned. */
- }
-
- /* Word (32-bit) aligned, do the most part. */
- xLastSource.u32ptr = ( xSource.u32ptr + ( uxDataLengthBytes / 4u ) ) - 3u;
-
- /* In this loop, four 32-bit additions will be done, in total 16 bytes.
- Indexing with constants (0,1,2,3) gives faster code than using
- post-increments. */
- while( xSource.u32ptr < xLastSource.u32ptr )
- {
- /* Use a secondary Sum2, just to see if the addition produced an
- overflow. */
- xSum2.u32 = xSum.u32 + xSource.u32ptr[ 0 ];
- if( xSum2.u32 < xSum.u32 )
- {
- ulCarry++;
- }
-
- /* Now add the secondary sum to the major sum, and remember if there was
- a carry. */
- xSum.u32 = xSum2.u32 + xSource.u32ptr[ 1 ];
- if( xSum2.u32 > xSum.u32 )
- {
- ulCarry++;
- }
-
- /* And do the same trick once again for indexes 2 and 3 */
- xSum2.u32 = xSum.u32 + xSource.u32ptr[ 2 ];
- if( xSum2.u32 < xSum.u32 )
- {
- ulCarry++;
- }
-
- xSum.u32 = xSum2.u32 + xSource.u32ptr[ 3 ];
-
- if( xSum2.u32 > xSum.u32 )
- {
- ulCarry++;
- }
-
- /* And finally advance the pointer 4 * 4 = 16 bytes. */
- xSource.u32ptr += 4;
- }
-
- /* Now add all carries. */
- xSum.u32 = ( uint32_t )xSum.u16[ 0 ] + xSum.u16[ 1 ] + ulCarry;
-
- uxDataLengthBytes %= 16u;
- xLastSource.u8ptr = ( uint8_t * ) ( xSource.u8ptr + ( uxDataLengthBytes & ~( ( size_t ) 1 ) ) );
-
- /* Half-word aligned. */
- while( xSource.u16ptr < xLastSource.u16ptr )
- {
- /* At least one more short. */
- xSum.u32 += xSource.u16ptr[ 0 ];
- xSource.u16ptr++;
- }
-
- if( ( uxDataLengthBytes & ( size_t ) 1 ) != 0u ) /* Maybe one more ? */
- {
- xTerm.u8[ 0 ] = xSource.u8ptr[ 0 ];
- }
- xSum.u32 += xTerm.u32;
-
- /* Now add all carries again. */
- xSum.u32 = ( uint32_t ) xSum.u16[ 0 ] + xSum.u16[ 1 ];
-
- /* The previous summation might have given a 16-bit carry. */
- xSum.u32 = ( uint32_t ) xSum.u16[ 0 ] + xSum.u16[ 1 ];
-
- if( ( ulAlignBits & 1u ) != 0u )
- {
- /* Quite unlikely, but pucNextData might be non-aligned, which would
- mean that a checksum is calculated starting at an odd position. */
- xSum.u32 = ( ( xSum.u32 & 0xffu ) << 8 ) | ( ( xSum.u32 & 0xff00u ) >> 8 );
- }
-
- /* swap the output (little endian platform only). */
- return FreeRTOS_htons( ( (uint16_t) xSum.u32 ) );
-}
-/*-----------------------------------------------------------*/
-
-void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend )
-{
-EthernetHeader_t *pxEthernetHeader;
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNewBuffer;
-#endif
-
- #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- BaseType_t xIndex;
-
- FreeRTOS_printf( ( "vReturnEthernetFrame: length %lu\n", ( uint32_t )pxNetworkBuffer->xDataLength ) );
- for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
- {
- pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
- }
- pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
- }
- }
- #endif
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-
- if( xReleaseAfterSend == pdFALSE )
- {
- pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, ( BaseType_t ) pxNetworkBuffer->xDataLength );
- xReleaseAfterSend = pdTRUE;
- pxNetworkBuffer = pxNewBuffer;
- }
-
- if( pxNetworkBuffer != NULL )
-#endif
- {
- pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-
- /* Swap source and destination MAC addresses. */
- memcpy( ( void * ) &( pxEthernetHeader->xDestinationAddress ), ( void * ) &( pxEthernetHeader->xSourceAddress ), sizeof( pxEthernetHeader->xDestinationAddress ) );
- memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
-
- /* Send! */
- xNetworkInterfaceOutput( pxNetworkBuffer, xReleaseAfterSend );
- }
-}
-/*-----------------------------------------------------------*/
-
-uint32_t FreeRTOS_GetIPAddress( void )
-{
- /* Returns the IP address of the NIC. */
- return *ipLOCAL_IP_ADDRESS_POINTER;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_SetIPAddress( uint32_t ulIPAddress )
-{
- /* Sets the IP address of the NIC. */
- *ipLOCAL_IP_ADDRESS_POINTER = ulIPAddress;
-}
-/*-----------------------------------------------------------*/
-
-uint32_t FreeRTOS_GetGatewayAddress( void )
-{
- return xNetworkAddressing.ulGatewayAddress;
-}
-/*-----------------------------------------------------------*/
-
-uint32_t FreeRTOS_GetDNSServerAddress( void )
-{
- return xNetworkAddressing.ulDNSServerAddress;
-}
-/*-----------------------------------------------------------*/
-
-uint32_t FreeRTOS_GetNetmask( void )
-{
- return xNetworkAddressing.ulNetMask;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] )
-{
- /* Copy the MAC address at the start of the default packet header fragment. */
- memcpy( ( void * )ipLOCAL_MAC_ADDRESS, ( void * )ucMACAddress, ( size_t )ipMAC_ADDRESS_LENGTH_BYTES );
-}
-/*-----------------------------------------------------------*/
-
-const uint8_t * FreeRTOS_GetMACAddress( void )
-{
- return ipLOCAL_MAC_ADDRESS;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_SetNetmask ( uint32_t ulNetmask )
-{
- xNetworkAddressing.ulNetMask = ulNetmask;
-}
-/*-----------------------------------------------------------*/
-
-void FreeRTOS_SetGatewayAddress ( uint32_t ulGatewayAddress )
-{
- xNetworkAddressing.ulGatewayAddress = ulGatewayAddress;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_DHCP == 1 )
- void vIPSetDHCPTimerEnableState( BaseType_t xEnableState )
- {
- if( xEnableState != pdFALSE )
- {
- xDHCPTimer.bActive = pdTRUE_UNSIGNED;
- }
- else
- {
- xDHCPTimer.bActive = pdFALSE_UNSIGNED;
- }
- }
-#endif /* ipconfigUSE_DHCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_DHCP == 1 )
- void vIPReloadDHCPTimer( uint32_t ulLeaseTime )
- {
- prvIPTimerReload( &xDHCPTimer, ulLeaseTime );
- }
-#endif /* ipconfigUSE_DHCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigDNS_USE_CALLBACKS == 1 )
- void vIPSetDnsTimerEnableState( BaseType_t xEnableState )
- {
- if( xEnableState != 0 )
- {
- xDNSTimer.bActive = pdTRUE;
- }
- else
- {
- xDNSTimer.bActive = pdFALSE;
- }
- }
-#endif /* ipconfigUSE_DHCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigDNS_USE_CALLBACKS != 0 )
- void vIPReloadDNSTimer( uint32_t ulCheckTime )
- {
- prvIPTimerReload( &xDNSTimer, ulCheckTime );
- }
-#endif /* ipconfigDNS_USE_CALLBACKS != 0 */
-/*-----------------------------------------------------------*/
-
-BaseType_t xIPIsNetworkTaskReady( void )
-{
- return xIPTaskInitialised;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t FreeRTOS_IsNetworkUp( void )
-{
- return xNetworkUp;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- UBaseType_t uxGetMinimumIPQueueSpace( void )
- {
- return uxQueueMinimumSpace;
- }
-#endif
-/*-----------------------------------------------------------*/
-
-/* Provide access to private members for verification. */
-#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
- #include "aws_freertos_ip_verification_access_ip_define.h"
-#endif
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_ARP.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_TCP_IP.h"
+#include "FreeRTOS_DHCP.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+#include "FreeRTOS_DNS.h"
+
+
+/* Used to ensure the structure packing is having the desired effect. The
+'volatile' is used to prevent compiler warnings about comparing a constant with
+a constant. */
+#define ipEXPECTED_EthernetHeader_t_SIZE ( ( size_t ) 14 )
+#define ipEXPECTED_ARPHeader_t_SIZE ( ( size_t ) 28 )
+#define ipEXPECTED_IPHeader_t_SIZE ( ( size_t ) 20 )
+#define ipEXPECTED_IGMPHeader__SIZE ( ( size_t ) 8 )
+#define ipEXPECTED_ICMPHeader_t_SIZE ( ( size_t ) 8 )
+#define ipEXPECTED_UDPHeader_t_SIZE ( ( size_t ) 8 )
+#define ipEXPECTED_TCPHeader_t_SIZE ( ( size_t ) 20 )
+
+
+/* ICMP protocol definitions. */
+#define ipICMP_ECHO_REQUEST ( ( uint8_t ) 8 )
+#define ipICMP_ECHO_REPLY ( ( uint8_t ) 0 )
+
+
+/* Time delay between repeated attempts to initialise the network hardware. */
+#ifndef ipINITIALISATION_RETRY_DELAY
+ #define ipINITIALISATION_RETRY_DELAY ( pdMS_TO_TICKS( 3000 ) )
+#endif
+
+/* Defines how often the ARP timer callback function is executed. The time is
+shorted in the Windows simulator as simulated time is not real time. */
+#ifndef ipARP_TIMER_PERIOD_MS
+ #ifdef _WINDOWS_
+ #define ipARP_TIMER_PERIOD_MS ( 500 ) /* For windows simulator builds. */
+ #else
+ #define ipARP_TIMER_PERIOD_MS ( 10000 )
+ #endif
+#endif
+
+#ifndef iptraceIP_TASK_STARTING
+ #define iptraceIP_TASK_STARTING() do {} while( 0 )
+#endif
+
+#if( ( ipconfigUSE_TCP == 1 ) && !defined( ipTCP_TIMER_PERIOD_MS ) )
+ /* When initialising the TCP timer,
+ give it an initial time-out of 1 second. */
+ #define ipTCP_TIMER_PERIOD_MS ( 1000 )
+#endif
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. In this case ipCONSIDER_FRAME_FOR_PROCESSING() can
+be #defined away. If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 0
+then the Ethernet driver will pass all received packets to the stack, and the
+stack must do the filtering itself. In this case ipCONSIDER_FRAME_FOR_PROCESSING
+needs to call eConsiderFrameForProcessing. */
+#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#endif
+
+/* The character used to fill ICMP echo requests, and therefore also the
+character expected to fill ICMP echo replies. */
+#define ipECHO_DATA_FILL_BYTE 'x'
+
+#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
+ /* The bits in the two byte IP header field that make up the fragment offset value. */
+ #define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0xff0f )
+#else
+ /* The bits in the two byte IP header field that make up the fragment offset value. */
+ #define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff )
+#endif /* ipconfigBYTE_ORDER */
+
+/* The maximum time the IP task is allowed to remain in the Blocked state if no
+events are posted to the network event queue. */
+#ifndef ipconfigMAX_IP_TASK_SLEEP_TIME
+ #define ipconfigMAX_IP_TASK_SLEEP_TIME ( pdMS_TO_TICKS( 10000UL ) )
+#endif
+
+/* When a new TCP connection is established, the value of
+'ulNextInitialSequenceNumber' will be used as the initial sequence number. It
+is very important that at start-up, 'ulNextInitialSequenceNumber' contains a
+random value. Also its value must be increased continuously in time, to prevent
+a third party guessing the next sequence number and take-over a TCP connection.
+It is advised to increment it by 1 ever 4us, which makes about 256 times
+per ms: */
+#define ipINITIAL_SEQUENCE_NUMBER_FACTOR 256UL
+
+/* Returned as the (invalid) checksum when the protocol being checked is not
+handled. The value is chosen simply to be easy to spot when debugging. */
+#define ipUNHANDLED_PROTOCOL 0x4321u
+
+/* Returned to indicate a valid checksum when the checksum does not need to be
+calculated. */
+#define ipCORRECT_CRC 0xffffu
+
+/* Returned as the (invalid) checksum when the length of the data being checked
+had an invalid length. */
+#define ipINVALID_LENGTH 0x1234u
+
+/*-----------------------------------------------------------*/
+
+typedef struct xIP_TIMER
+{
+ uint32_t
+ bActive : 1, /* This timer is running and must be processed. */
+ bExpired : 1; /* Timer has expired and a task must be processed. */
+ TimeOut_t xTimeOut;
+ TickType_t ulRemainingTime;
+ TickType_t ulReloadTime;
+} IPTimer_t;
+
+/* Used in checksum calculation. */
+typedef union _xUnion32
+{
+ uint32_t u32;
+ uint16_t u16[ 2 ];
+ uint8_t u8[ 4 ];
+} xUnion32;
+
+/* Used in checksum calculation. */
+typedef union _xUnionPtr
+{
+ uint32_t *u32ptr;
+ uint16_t *u16ptr;
+ uint8_t *u8ptr;
+} xUnionPtr;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * The main TCP/IP stack processing task. This task receives commands/events
+ * from the network hardware drivers and tasks that are using sockets. It also
+ * maintains a set of protocol timers.
+ */
+static void prvIPTask( void *pvParameters );
+
+/*
+ * Called when new data is available from the network interface.
+ */
+static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
+
+/*
+ * Process incoming IP packets.
+ */
+static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer );
+
+#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+ /*
+ * Process incoming ICMP packets.
+ */
+ static eFrameProcessingResult_t prvProcessICMPPacket( ICMPPacket_t * const pxICMPPacket );
+#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
+
+/*
+ * Turns around an incoming ping request to convert it into a ping reply.
+ */
+#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
+ static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket );
+#endif /* ipconfigREPLY_TO_INCOMING_PINGS */
+
+/*
+ * Processes incoming ping replies. The application callback function
+ * vApplicationPingReplyHook() is called with the results.
+ */
+#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+ static void prvProcessICMPEchoReply( ICMPPacket_t * const pxICMPPacket );
+#endif /* ipconfigSUPPORT_OUTGOING_PINGS */
+
+/*
+ * Called to create a network connection when the stack is first started, or
+ * when the network connection is lost.
+ */
+static void prvProcessNetworkDownEvent( void );
+
+/*
+ * Checks the ARP, DHCP and TCP timers to see if any periodic or timeout
+ * processing is required.
+ */
+static void prvCheckNetworkTimers( void );
+
+/*
+ * Determine how long the IP task can sleep for, which depends on when the next
+ * periodic or timeout processing must be performed.
+ */
+static TickType_t prvCalculateSleepTime( void );
+
+/*
+ * The network card driver has received a packet. In the case that it is part
+ * of a linked packet chain, walk through it to handle every message.
+ */
+static void prvHandleEthernetPacket( NetworkBufferDescriptor_t *pxBuffer );
+
+/*
+ * Utility functions for the light weight IP timers.
+ */
+static void prvIPTimerStart( IPTimer_t *pxTimer, TickType_t xTime );
+static BaseType_t prvIPTimerCheck( IPTimer_t *pxTimer );
+static void prvIPTimerReload( IPTimer_t *pxTimer, TickType_t xTime );
+
+static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPPacket,
+ NetworkBufferDescriptor_t * const pxNetworkBuffer, UBaseType_t uxHeaderLength );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used to pass events into the IP-task for processing. */
+QueueHandle_t xNetworkEventQueue = NULL;
+
+/*_RB_ Requires comment. */
+uint16_t usPacketIdentifier = 0U;
+
+/* For convenience, a MAC address of all 0xffs is defined const for quick
+reference. */
+const MACAddress_t xBroadcastMACAddress = { { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff } };
+
+/* Structure that stores the netmask, gateway address and DNS server addresses. */
+NetworkAddressingParameters_t xNetworkAddressing = { 0, 0, 0, 0, 0 };
+
+/* Default values for the above struct in case DHCP
+does not lead to a confirmed request. */
+NetworkAddressingParameters_t xDefaultAddressing = { 0, 0, 0, 0, 0 };
+
+/* Used to ensure network down events cannot be missed when they cannot be
+posted to the network event queue because the network event queue is already
+full. */
+static BaseType_t xNetworkDownEventPending = pdFALSE;
+
+/* Stores the handle of the task that handles the stack. The handle is used
+(indirectly) by some utility function to determine if the utility function is
+being called by a task (in which case it is ok to block) or by the IP task
+itself (in which case it is not ok to block). */
+static TaskHandle_t xIPTaskHandle = NULL;
+
+#if( ipconfigUSE_TCP != 0 )
+ /* Set to a non-zero value if one or more TCP message have been processed
+ within the last round. */
+ static BaseType_t xProcessedTCPMessage;
+#endif
+
+/* Simple set to pdTRUE or pdFALSE depending on whether the network is up or
+down (connected, not connected) respectively. */
+static BaseType_t xNetworkUp = pdFALSE;
+
+/*
+A timer for each of the following processes, all of which need attention on a
+regular basis:
+ 1. ARP, to check its table entries
+ 2. DPHC, to send requests and to renew a reservation
+ 3. TCP, to check for timeouts, resends
+ 4. DNS, to check for timeouts when looking-up a domain.
+ */
+static IPTimer_t xARPTimer;
+#if( ipconfigUSE_DHCP != 0 )
+ static IPTimer_t xDHCPTimer;
+#endif
+#if( ipconfigUSE_TCP != 0 )
+ static IPTimer_t xTCPTimer;
+#endif
+#if( ipconfigDNS_USE_CALLBACKS != 0 )
+ static IPTimer_t xDNSTimer;
+#endif
+
+/* Set to pdTRUE when the IP task is ready to start processing packets. */
+static BaseType_t xIPTaskInitialised = pdFALSE;
+
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ /* Keep track of the lowest amount of space in 'xNetworkEventQueue'. */
+ static UBaseType_t uxQueueMinimumSpace = ipconfigEVENT_QUEUE_LENGTH;
+#endif
+
+/*-----------------------------------------------------------*/
+
+static void prvIPTask( void *pvParameters )
+{
+IPStackEvent_t xReceivedEvent;
+TickType_t xNextIPSleep;
+FreeRTOS_Socket_t *pxSocket;
+struct freertos_sockaddr xAddress;
+
+ /* Just to prevent compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ /* A possibility to set some additional task properties. */
+ iptraceIP_TASK_STARTING();
+
+ /* Generate a dummy message to say that the network connection has gone
+ down. This will cause this task to initialise the network interface. After
+ this it is the responsibility of the network interface hardware driver to
+ send this message if a previously connected network is disconnected. */
+ FreeRTOS_NetworkDown();
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ /* Initialise the TCP timer. */
+ prvIPTimerReload( &xTCPTimer, pdMS_TO_TICKS( ipTCP_TIMER_PERIOD_MS ) );
+ }
+ #endif
+
+ /* Initialisation is complete and events can now be processed. */
+ xIPTaskInitialised = pdTRUE;
+
+ FreeRTOS_debug_printf( ( "prvIPTask started\n" ) );
+
+ /* Loop, processing IP events. */
+ for( ;; )
+ {
+ ipconfigWATCHDOG_TIMER();
+
+ /* Check the ARP, DHCP and TCP timers to see if there is any periodic
+ or timeout processing to perform. */
+ prvCheckNetworkTimers();
+
+ /* Calculate the acceptable maximum sleep time. */
+ xNextIPSleep = prvCalculateSleepTime();
+
+ /* Wait until there is something to do. If the following call exits
+ * due to a time out rather than a message being received, set a
+ * 'NoEvent' value. */
+ if ( xQueueReceive( xNetworkEventQueue, ( void * ) &xReceivedEvent, xNextIPSleep ) == pdFALSE )
+ {
+ xReceivedEvent.eEventType = eNoEvent;
+ }
+
+ #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ if( xReceivedEvent.eEventType != eNoEvent )
+ {
+ UBaseType_t uxCount;
+
+ uxCount = uxQueueSpacesAvailable( xNetworkEventQueue );
+ if( uxQueueMinimumSpace > uxCount )
+ {
+ uxQueueMinimumSpace = uxCount;
+ }
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+
+ iptraceNETWORK_EVENT_RECEIVED( xReceivedEvent.eEventType );
+
+ switch( xReceivedEvent.eEventType )
+ {
+ case eNetworkDownEvent :
+ /* Attempt to establish a connection. */
+ xNetworkUp = pdFALSE;
+ prvProcessNetworkDownEvent();
+ break;
+
+ case eNetworkRxEvent:
+ /* The network hardware driver has received a new packet. A
+ pointer to the received buffer is located in the pvData member
+ of the received event structure. */
+ prvHandleEthernetPacket( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ) );
+ break;
+
+ case eNetworkTxEvent:
+ /* Send a network packet. The ownership will be transferred to
+ the driver, which will release it after delivery. */
+ xNetworkInterfaceOutput( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ), pdTRUE );
+ break;
+
+ case eARPTimerEvent :
+ /* The ARP timer has expired, process the ARP cache. */
+ vARPAgeCache();
+ break;
+
+ case eSocketBindEvent:
+ /* FreeRTOS_bind (a user API) wants the IP-task to bind a socket
+ to a port. The port number is communicated in the socket field
+ usLocalPort. vSocketBind() will actually bind the socket and the
+ API will unblock as soon as the eSOCKET_BOUND event is
+ triggered. */
+ pxSocket = ( FreeRTOS_Socket_t * ) ( xReceivedEvent.pvData );
+ xAddress.sin_addr = 0u; /* For the moment. */
+ xAddress.sin_port = FreeRTOS_ntohs( pxSocket->usLocalPort );
+ pxSocket->usLocalPort = 0u;
+ vSocketBind( pxSocket, &xAddress, sizeof( xAddress ), pdFALSE );
+
+ /* Before 'eSocketBindEvent' was sent it was tested that
+ ( xEventGroup != NULL ) so it can be used now to wake up the
+ user. */
+ pxSocket->xEventBits |= eSOCKET_BOUND;
+ vSocketWakeUpUser( pxSocket );
+ break;
+
+ case eSocketCloseEvent :
+ /* The user API FreeRTOS_closesocket() has sent a message to the
+ IP-task to actually close a socket. This is handled in
+ vSocketClose(). As the socket gets closed, there is no way to
+ report back to the API, so the API won't wait for the result */
+ vSocketClose( ( FreeRTOS_Socket_t * ) ( xReceivedEvent.pvData ) );
+ break;
+
+ case eStackTxEvent :
+ /* The network stack has generated a packet to send. A
+ pointer to the generated buffer is located in the pvData
+ member of the received event structure. */
+ vProcessGeneratedUDPPacket( ( NetworkBufferDescriptor_t * ) ( xReceivedEvent.pvData ) );
+ break;
+
+ case eDHCPEvent:
+ /* The DHCP state machine needs processing. */
+ #if( ipconfigUSE_DHCP == 1 )
+ {
+ vDHCPProcess( pdFALSE );
+ }
+ #endif /* ipconfigUSE_DHCP */
+ break;
+
+ case eSocketSelectEvent :
+ /* FreeRTOS_select() has got unblocked by a socket event,
+ vSocketSelect() will check which sockets actually have an event
+ and update the socket field xSocketBits. */
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ vSocketSelect( ( SocketSelect_t * ) ( xReceivedEvent.pvData ) );
+ }
+ #endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+ break;
+
+ case eSocketSignalEvent :
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ /* Some task wants to signal the user of this socket in
+ order to interrupt a call to recv() or a call to select(). */
+ FreeRTOS_SignalSocket( ( Socket_t ) xReceivedEvent.pvData );
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+ break;
+
+ case eTCPTimerEvent :
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ /* Simply mark the TCP timer as expired so it gets processed
+ the next time prvCheckNetworkTimers() is called. */
+ xTCPTimer.bExpired = pdTRUE_UNSIGNED;
+ }
+ #endif /* ipconfigUSE_TCP */
+ break;
+
+ case eTCPAcceptEvent:
+ /* The API FreeRTOS_accept() was called, the IP-task will now
+ check if the listening socket (communicated in pvData) actually
+ received a new connection. */
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ pxSocket = ( FreeRTOS_Socket_t * ) ( xReceivedEvent.pvData );
+
+ if( xTCPCheckNewClient( pxSocket ) != pdFALSE )
+ {
+ pxSocket->xEventBits |= eSOCKET_ACCEPT;
+ vSocketWakeUpUser( pxSocket );
+ }
+ }
+ #endif /* ipconfigUSE_TCP */
+ break;
+
+ case eTCPNetStat:
+ /* FreeRTOS_netstat() was called to have the IP-task print an
+ overview of all sockets and their connections */
+ #if( ( ipconfigUSE_TCP == 1 ) && ( ipconfigHAS_PRINTF == 1 ) )
+ {
+ vTCPNetStat();
+ }
+ #endif /* ipconfigUSE_TCP */
+ break;
+
+ default :
+ /* Should not get here. */
+ break;
+ }
+
+ if( xNetworkDownEventPending != pdFALSE )
+ {
+ /* A network down event could not be posted to the network event
+ queue because the queue was full. Try posting again. */
+ FreeRTOS_NetworkDown();
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xIsCallingFromIPTask( void )
+{
+BaseType_t xReturn;
+
+ if( xTaskGetCurrentTaskHandle() == xIPTaskHandle )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvHandleEthernetPacket( NetworkBufferDescriptor_t *pxBuffer )
+{
+ #if( ipconfigUSE_LINKED_RX_MESSAGES == 0 )
+ {
+ /* When ipconfigUSE_LINKED_RX_MESSAGES is not set to 0 then only one
+ buffer will be sent at a time. This is the default way for +TCP to pass
+ messages from the MAC to the TCP/IP stack. */
+ prvProcessEthernetPacket( pxBuffer );
+ }
+ #else /* ipconfigUSE_LINKED_RX_MESSAGES */
+ {
+ NetworkBufferDescriptor_t *pxNextBuffer;
+
+ /* An optimisation that is useful when there is high network traffic.
+ Instead of passing received packets into the IP task one at a time the
+ network interface can chain received packets together and pass them into
+ the IP task in one go. The packets are chained using the pxNextBuffer
+ member. The loop below walks through the chain processing each packet
+ in the chain in turn. */
+ do
+ {
+ /* Store a pointer to the buffer after pxBuffer for use later on. */
+ pxNextBuffer = pxBuffer->pxNextBuffer;
+
+ /* Make it NULL to avoid using it later on. */
+ pxBuffer->pxNextBuffer = NULL;
+
+ prvProcessEthernetPacket( pxBuffer );
+ pxBuffer = pxNextBuffer;
+
+ /* While there is another packet in the chain. */
+ } while( pxBuffer != NULL );
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+}
+/*-----------------------------------------------------------*/
+
+static TickType_t prvCalculateSleepTime( void )
+{
+TickType_t xMaximumSleepTime;
+
+ /* Start with the maximum sleep time, then check this against the remaining
+ time in any other timers that are active. */
+ xMaximumSleepTime = ipconfigMAX_IP_TASK_SLEEP_TIME;
+
+ if( xARPTimer.bActive != pdFALSE_UNSIGNED )
+ {
+ if( xARPTimer.ulRemainingTime < xMaximumSleepTime )
+ {
+ xMaximumSleepTime = xARPTimer.ulReloadTime;
+ }
+ }
+
+ #if( ipconfigUSE_DHCP == 1 )
+ {
+ if( xDHCPTimer.bActive != pdFALSE_UNSIGNED )
+ {
+ if( xDHCPTimer.ulRemainingTime < xMaximumSleepTime )
+ {
+ xMaximumSleepTime = xDHCPTimer.ulRemainingTime;
+ }
+ }
+ }
+ #endif /* ipconfigUSE_DHCP */
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ if( xTCPTimer.ulRemainingTime < xMaximumSleepTime )
+ {
+ xMaximumSleepTime = xTCPTimer.ulRemainingTime;
+ }
+ }
+ #endif
+
+ #if( ipconfigDNS_USE_CALLBACKS != 0 )
+ {
+ if( xDNSTimer.bActive != pdFALSE )
+ {
+ if( xDNSTimer.ulRemainingTime < xMaximumSleepTime )
+ {
+ xMaximumSleepTime = xDNSTimer.ulRemainingTime;
+ }
+ }
+ }
+ #endif
+
+ return xMaximumSleepTime;
+}
+/*-----------------------------------------------------------*/
+
+static void prvCheckNetworkTimers( void )
+{
+ /* Is it time for ARP processing? */
+ if( prvIPTimerCheck( &xARPTimer ) != pdFALSE )
+ {
+ xSendEventToIPTask( eARPTimerEvent );
+ }
+
+ #if( ipconfigUSE_DHCP == 1 )
+ {
+ /* Is it time for DHCP processing? */
+ if( prvIPTimerCheck( &xDHCPTimer ) != pdFALSE )
+ {
+ xSendEventToIPTask( eDHCPEvent );
+ }
+ }
+ #endif /* ipconfigUSE_DHCP */
+
+ #if( ipconfigDNS_USE_CALLBACKS != 0 )
+ {
+ extern void vDNSCheckCallBack( void *pvSearchID );
+
+ /* Is it time for DNS processing? */
+ if( prvIPTimerCheck( &xDNSTimer ) != pdFALSE )
+ {
+ vDNSCheckCallBack( NULL );
+ }
+ }
+ #endif /* ipconfigDNS_USE_CALLBACKS */
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ BaseType_t xWillSleep;
+ TickType_t xNextTime;
+ BaseType_t xCheckTCPSockets;
+
+ if( uxQueueMessagesWaiting( xNetworkEventQueue ) == 0u )
+ {
+ xWillSleep = pdTRUE;
+ }
+ else
+ {
+ xWillSleep = pdFALSE;
+ }
+
+ /* Sockets need to be checked if the TCP timer has expired. */
+ xCheckTCPSockets = prvIPTimerCheck( &xTCPTimer );
+
+ /* Sockets will also be checked if there are TCP messages but the
+ message queue is empty (indicated by xWillSleep being true). */
+ if( ( xProcessedTCPMessage != pdFALSE ) && ( xWillSleep != pdFALSE ) )
+ {
+ xCheckTCPSockets = pdTRUE;
+ }
+
+ if( xCheckTCPSockets != pdFALSE )
+ {
+ /* Attend to the sockets, returning the period after which the
+ check must be repeated. */
+ xNextTime = xTCPTimerCheck( xWillSleep );
+ prvIPTimerStart( &xTCPTimer, xNextTime );
+ xProcessedTCPMessage = 0;
+ }
+ }
+ #endif /* ipconfigUSE_TCP == 1 */
+}
+/*-----------------------------------------------------------*/
+
+static void prvIPTimerStart( IPTimer_t *pxTimer, TickType_t xTime )
+{
+ vTaskSetTimeOutState( &pxTimer->xTimeOut );
+ pxTimer->ulRemainingTime = xTime;
+
+ if( xTime == ( TickType_t ) 0 )
+ {
+ pxTimer->bExpired = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ pxTimer->bExpired = pdFALSE_UNSIGNED;
+ }
+
+ pxTimer->bActive = pdTRUE_UNSIGNED;
+}
+/*-----------------------------------------------------------*/
+
+static void prvIPTimerReload( IPTimer_t *pxTimer, TickType_t xTime )
+{
+ pxTimer->ulReloadTime = xTime;
+ prvIPTimerStart( pxTimer, xTime );
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvIPTimerCheck( IPTimer_t *pxTimer )
+{
+BaseType_t xReturn;
+
+ if( pxTimer->bActive == pdFALSE_UNSIGNED )
+ {
+ /* The timer is not enabled. */
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ /* The timer might have set the bExpired flag already, if not, check the
+ value of xTimeOut against ulRemainingTime. */
+ if( ( pxTimer->bExpired != pdFALSE_UNSIGNED ) ||
+ ( xTaskCheckForTimeOut( &( pxTimer->xTimeOut ), &( pxTimer->ulRemainingTime ) ) != pdFALSE ) )
+ {
+ prvIPTimerStart( pxTimer, pxTimer->ulReloadTime );
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_NetworkDown( void )
+{
+static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL };
+const TickType_t xDontBlock = ( TickType_t ) 0;
+
+ /* Simply send the network task the appropriate event. */
+ if( xSendEventStructToIPTask( &xNetworkDownEvent, xDontBlock ) != pdPASS )
+ {
+ /* Could not send the message, so it is still pending. */
+ xNetworkDownEventPending = pdTRUE;
+ }
+ else
+ {
+ /* Message was sent so it is not pending. */
+ xNetworkDownEventPending = pdFALSE;
+ }
+
+ iptraceNETWORK_DOWN();
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t FreeRTOS_NetworkDownFromISR( void )
+{
+static const IPStackEvent_t xNetworkDownEvent = { eNetworkDownEvent, NULL };
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ /* Simply send the network task the appropriate event. */
+ if( xQueueSendToBackFromISR( xNetworkEventQueue, &xNetworkDownEvent, &xHigherPriorityTaskWoken ) != pdPASS )
+ {
+ xNetworkDownEventPending = pdTRUE;
+ }
+ else
+ {
+ xNetworkDownEventPending = pdFALSE;
+ }
+
+ iptraceNETWORK_DOWN();
+
+ return xHigherPriorityTaskWoken;
+}
+/*-----------------------------------------------------------*/
+
+void *FreeRTOS_GetUDPPayloadBuffer( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+void *pvReturn;
+
+ /* Cap the block time. The reason for this is explained where
+ ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS is defined (assuming an official
+ FreeRTOSIPConfig.h header file is being used). */
+ if( xBlockTimeTicks > ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS )
+ {
+ xBlockTimeTicks = ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS;
+ }
+
+ /* Obtain a network buffer with the required amount of storage. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( sizeof( UDPPacket_t ) + xRequestedSizeBytes, xBlockTimeTicks );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ /* Set the actual packet size in case a bigger buffer was returned. */
+ pxNetworkBuffer->xDataLength = sizeof( UDPPacket_t ) + xRequestedSizeBytes;
+
+ /* Leave space for the UPD header. */
+ pvReturn = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
+ }
+ else
+ {
+ pvReturn = NULL;
+ }
+
+ return ( void * ) pvReturn;
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
+ size_t uxNewLength )
+{
+NetworkBufferDescriptor_t * pxNewBuffer;
+
+ /* This function is only used when 'ipconfigZERO_COPY_TX_DRIVER' is set to 1.
+ The transmit routine wants to have ownership of the network buffer
+ descriptor, because it will pass the buffer straight to DMA. */
+ pxNewBuffer = pxGetNetworkBufferWithDescriptor( uxNewLength, ( TickType_t ) 0 );
+
+ if( pxNewBuffer != NULL )
+ {
+ /* Set the actual packet size in case a bigger buffer than requested
+ was returned. */
+ pxNewBuffer->xDataLength = uxNewLength;
+
+ /* Copy the original packet information. */
+ pxNewBuffer->ulIPAddress = pxNetworkBuffer->ulIPAddress;
+ pxNewBuffer->usPort = pxNetworkBuffer->usPort;
+ pxNewBuffer->usBoundPort = pxNetworkBuffer->usBoundPort;
+ memcpy( pxNewBuffer->pucEthernetBuffer, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
+ }
+
+ return pxNewBuffer;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 ) || ( ipconfigZERO_COPY_RX_DRIVER != 0 )
+
+ NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer )
+ {
+ uint8_t *pucBuffer;
+ NetworkBufferDescriptor_t *pxResult;
+
+ if( pvBuffer == NULL )
+ {
+ pxResult = NULL;
+ }
+ else
+ {
+ /* Obtain the network buffer from the zero copy pointer. */
+ pucBuffer = ( uint8_t * ) pvBuffer;
+
+ /* The input here is a pointer to a payload buffer. Subtract the
+ size of the header in the network buffer, usually 8 + 2 bytes. */
+ pucBuffer -= ipBUFFER_PADDING;
+
+ /* Here a pointer was placed to the network descriptor. As a
+ pointer is dereferenced, make sure it is well aligned. */
+ if( ( ( ( uint32_t ) pucBuffer ) & ( sizeof( pucBuffer ) - ( size_t ) 1 ) ) == ( uint32_t ) 0 )
+ {
+ pxResult = * ( ( NetworkBufferDescriptor_t ** ) pucBuffer );
+ }
+ else
+ {
+ pxResult = NULL;
+ }
+ }
+
+ return pxResult;
+ }
+
+#endif /* ipconfigZERO_COPY_TX_DRIVER != 0 */
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer )
+{
+uint8_t *pucBuffer;
+NetworkBufferDescriptor_t *pxResult;
+
+ if( pvBuffer == NULL )
+ {
+ pxResult = NULL;
+ }
+ else
+ {
+ /* Obtain the network buffer from the zero copy pointer. */
+ pucBuffer = ( uint8_t * ) pvBuffer;
+
+ /* The input here is a pointer to a payload buffer. Subtract
+ the total size of a UDP/IP header plus the size of the header in
+ the network buffer, usually 8 + 2 bytes. */
+ pucBuffer -= ( sizeof( UDPPacket_t ) + ipBUFFER_PADDING );
+
+ /* Here a pointer was placed to the network descriptor,
+ As a pointer is dereferenced, make sure it is well aligned */
+ if( ( ( ( uint32_t ) pucBuffer ) & ( sizeof( pucBuffer ) - 1 ) ) == 0 )
+ {
+ /* The following statement may trigger a:
+ warning: cast increases required alignment of target type [-Wcast-align].
+ It has been confirmed though that the alignment is suitable. */
+ pxResult = * ( ( NetworkBufferDescriptor_t ** ) pucBuffer );
+ }
+ else
+ {
+ pxResult = NULL;
+ }
+ }
+
+ return pxResult;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_ReleaseUDPPayloadBuffer( void *pvBuffer )
+{
+ vReleaseNetworkBufferAndDescriptor( pxUDPPayloadBuffer_to_NetworkBuffer( pvBuffer ) );
+}
+/*-----------------------------------------------------------*/
+
+/*_RB_ Should we add an error or assert if the task priorities are set such that the servers won't function as expected? */
+/*_HT_ There was a bug in FreeRTOS_TCP_IP.c that only occurred when the applications' priority was too high.
+ As that bug has been repaired, there is not an urgent reason to warn.
+ It is better though to use the advised priority scheme. */
+BaseType_t FreeRTOS_IPInit( const uint8_t ucIPAddress[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucNetMask[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucGatewayAddress[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucDNSServerAddress[ ipIP_ADDRESS_LENGTH_BYTES ], const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] )
+{
+BaseType_t xReturn = pdFALSE;
+
+ /* This function should only be called once. */
+ configASSERT( xIPIsNetworkTaskReady() == pdFALSE );
+ configASSERT( xNetworkEventQueue == NULL );
+ configASSERT( xIPTaskHandle == NULL );
+
+ /* Check structure packing is correct. */
+ configASSERT( sizeof( EthernetHeader_t ) == ipEXPECTED_EthernetHeader_t_SIZE );
+ configASSERT( sizeof( ARPHeader_t ) == ipEXPECTED_ARPHeader_t_SIZE );
+ configASSERT( sizeof( IPHeader_t ) == ipEXPECTED_IPHeader_t_SIZE );
+ configASSERT( sizeof( ICMPHeader_t ) == ipEXPECTED_ICMPHeader_t_SIZE );
+ configASSERT( sizeof( UDPHeader_t ) == ipEXPECTED_UDPHeader_t_SIZE );
+
+ /* Attempt to create the queue used to communicate with the IP task. */
+ xNetworkEventQueue = xQueueCreate( ( UBaseType_t ) ipconfigEVENT_QUEUE_LENGTH, ( UBaseType_t ) sizeof( IPStackEvent_t ) );
+ configASSERT( xNetworkEventQueue );
+
+ if( xNetworkEventQueue != NULL )
+ {
+ #if ( configQUEUE_REGISTRY_SIZE > 0 )
+ {
+ /* A queue registry is normally used to assist a kernel aware
+ debugger. If one is in use then it will be helpful for the debugger
+ to show information about the network event queue. */
+ vQueueAddToRegistry( xNetworkEventQueue, "NetEvnt" );
+ }
+ #endif /* configQUEUE_REGISTRY_SIZE */
+
+ if( xNetworkBuffersInitialise() == pdPASS )
+ {
+ /* Store the local IP and MAC address. */
+ xNetworkAddressing.ulDefaultIPAddress = FreeRTOS_inet_addr_quick( ucIPAddress[ 0 ], ucIPAddress[ 1 ], ucIPAddress[ 2 ], ucIPAddress[ 3 ] );
+ xNetworkAddressing.ulNetMask = FreeRTOS_inet_addr_quick( ucNetMask[ 0 ], ucNetMask[ 1 ], ucNetMask[ 2 ], ucNetMask[ 3 ] );
+ xNetworkAddressing.ulGatewayAddress = FreeRTOS_inet_addr_quick( ucGatewayAddress[ 0 ], ucGatewayAddress[ 1 ], ucGatewayAddress[ 2 ], ucGatewayAddress[ 3 ] );
+ xNetworkAddressing.ulDNSServerAddress = FreeRTOS_inet_addr_quick( ucDNSServerAddress[ 0 ], ucDNSServerAddress[ 1 ], ucDNSServerAddress[ 2 ], ucDNSServerAddress[ 3 ] );
+ xNetworkAddressing.ulBroadcastAddress = ( xNetworkAddressing.ulDefaultIPAddress & xNetworkAddressing.ulNetMask ) | ~xNetworkAddressing.ulNetMask;
+
+ memcpy( &xDefaultAddressing, &xNetworkAddressing, sizeof( xDefaultAddressing ) );
+
+ #if ipconfigUSE_DHCP == 1
+ {
+ /* The IP address is not set until DHCP completes. */
+ *ipLOCAL_IP_ADDRESS_POINTER = 0x00UL;
+ }
+ #else
+ {
+ /* The IP address is set from the value passed in. */
+ *ipLOCAL_IP_ADDRESS_POINTER = xNetworkAddressing.ulDefaultIPAddress;
+
+ /* Added to prevent ARP flood to gateway. Ensure the
+ gateway is on the same subnet as the IP address. */
+ if( xNetworkAddressing.ulGatewayAddress != 0ul )
+ {
+ configASSERT( ( ( *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) == ( xNetworkAddressing.ulGatewayAddress & xNetworkAddressing.ulNetMask ) );
+ }
+ }
+ #endif /* ipconfigUSE_DHCP == 1 */
+
+ /* The MAC address is stored in the start of the default packet
+ header fragment, which is used when sending UDP packets. */
+ memcpy( ( void * ) ipLOCAL_MAC_ADDRESS, ( void * ) ucMACAddress, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
+
+ /* Prepare the sockets interface. */
+ xReturn = vNetworkSocketsInit();
+
+ if( pdTRUE == xReturn )
+ {
+ /* Create the task that processes Ethernet and stack events. */
+ xReturn = xTaskCreate( prvIPTask, "IP-task", ( uint16_t )ipconfigIP_TASK_STACK_SIZE_WORDS, NULL, ( UBaseType_t )ipconfigIP_TASK_PRIORITY, &xIPTaskHandle );
+ }
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "FreeRTOS_IPInit: xNetworkBuffersInitialise() failed\n") );
+
+ /* Clean up. */
+ vQueueDelete( xNetworkEventQueue );
+ xNetworkEventQueue = NULL;
+ }
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "FreeRTOS_IPInit: Network event queue could not be created\n") );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_GetAddressConfiguration( uint32_t *pulIPAddress, uint32_t *pulNetMask, uint32_t *pulGatewayAddress, uint32_t *pulDNSServerAddress )
+{
+ /* Return the address configuration to the caller. */
+
+ if( pulIPAddress != NULL )
+ {
+ *pulIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
+ }
+
+ if( pulNetMask != NULL )
+ {
+ *pulNetMask = xNetworkAddressing.ulNetMask;
+ }
+
+ if( pulGatewayAddress != NULL )
+ {
+ *pulGatewayAddress = xNetworkAddressing.ulGatewayAddress;
+ }
+
+ if( pulDNSServerAddress != NULL )
+ {
+ *pulDNSServerAddress = xNetworkAddressing.ulDNSServerAddress;
+ }
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_SetAddressConfiguration( const uint32_t *pulIPAddress, const uint32_t *pulNetMask, const uint32_t *pulGatewayAddress, const uint32_t *pulDNSServerAddress )
+{
+ /* Update the address configuration. */
+
+ if( pulIPAddress != NULL )
+ {
+ *ipLOCAL_IP_ADDRESS_POINTER = *pulIPAddress;
+ }
+
+ if( pulNetMask != NULL )
+ {
+ xNetworkAddressing.ulNetMask = *pulNetMask;
+ }
+
+ if( pulGatewayAddress != NULL )
+ {
+ xNetworkAddressing.ulGatewayAddress = *pulGatewayAddress;
+ }
+
+ if( pulDNSServerAddress != NULL )
+ {
+ xNetworkAddressing.ulDNSServerAddress = *pulDNSServerAddress;
+ }
+}
+/*-----------------------------------------------------------*/
+
+#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+
+ BaseType_t FreeRTOS_SendPingRequest( uint32_t ulIPAddress, size_t xNumberOfBytesToSend, TickType_t xBlockTimeTicks )
+ {
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ ICMPHeader_t *pxICMPHeader;
+ BaseType_t xReturn = pdFAIL;
+ static uint16_t usSequenceNumber = 0;
+ uint8_t *pucChar;
+ IPStackEvent_t xStackTxEvent = { eStackTxEvent, NULL };
+
+ if( (xNumberOfBytesToSend >= 1 ) && ( xNumberOfBytesToSend < ( ( ipconfigNETWORK_MTU - sizeof( IPHeader_t ) ) - sizeof( ICMPHeader_t ) ) ) && ( uxGetNumberOfFreeNetworkBuffers() >= 3 ) )
+ {
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( xNumberOfBytesToSend + sizeof( ICMPPacket_t ), xBlockTimeTicks );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ pxICMPHeader = ( ICMPHeader_t * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipIP_PAYLOAD_OFFSET ] );
+ usSequenceNumber++;
+
+ /* Fill in the basic header information. */
+ pxICMPHeader->ucTypeOfMessage = ipICMP_ECHO_REQUEST;
+ pxICMPHeader->ucTypeOfService = 0;
+ pxICMPHeader->usIdentifier = usSequenceNumber;
+ pxICMPHeader->usSequenceNumber = usSequenceNumber;
+
+ /* Find the start of the data. */
+ pucChar = ( uint8_t * ) pxICMPHeader;
+ pucChar += sizeof( ICMPHeader_t );
+
+ /* Just memset the data to a fixed value. */
+ memset( ( void * ) pucChar, ( int ) ipECHO_DATA_FILL_BYTE, xNumberOfBytesToSend );
+
+ /* The message is complete, IP and checksum's are handled by
+ vProcessGeneratedUDPPacket */
+ pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = FREERTOS_SO_UDPCKSUM_OUT;
+ pxNetworkBuffer->ulIPAddress = ulIPAddress;
+ pxNetworkBuffer->usPort = ipPACKET_CONTAINS_ICMP_DATA;
+ /* xDataLength is the size of the total packet, including the Ethernet header. */
+ pxNetworkBuffer->xDataLength = xNumberOfBytesToSend + sizeof( ICMPPacket_t );
+
+ /* Send to the stack. */
+ xStackTxEvent.pvData = pxNetworkBuffer;
+
+ if( xSendEventStructToIPTask( &xStackTxEvent, xBlockTimeTicks) != pdPASS )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceSTACK_TX_EVENT_LOST( ipSTACK_TX_EVENT );
+ }
+ else
+ {
+ xReturn = usSequenceNumber;
+ }
+ }
+ }
+ else
+ {
+ /* The requested number of bytes will not fit in the available space
+ in the network buffer. */
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigSUPPORT_OUTGOING_PINGS == 1 */
+/*-----------------------------------------------------------*/
+
+BaseType_t xSendEventToIPTask( eIPEvent_t eEvent )
+{
+IPStackEvent_t xEventMessage;
+const TickType_t xDontBlock = ( TickType_t ) 0;
+
+ xEventMessage.eEventType = eEvent;
+ xEventMessage.pvData = ( void* )NULL;
+
+ return xSendEventStructToIPTask( &xEventMessage, xDontBlock );
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout )
+{
+BaseType_t xReturn, xSendMessage;
+
+ if( ( xIPIsNetworkTaskReady() == pdFALSE ) && ( pxEvent->eEventType != eNetworkDownEvent ) )
+ {
+ /* Only allow eNetworkDownEvent events if the IP task is not ready
+ yet. Not going to attempt to send the message so the send failed. */
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ xSendMessage = pdTRUE;
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ if( pxEvent->eEventType == eTCPTimerEvent )
+ {
+ /* TCP timer events are sent to wake the timer task when
+ xTCPTimer has expired, but there is no point sending them if the
+ IP task is already awake processing other message. */
+ xTCPTimer.bExpired = pdTRUE_UNSIGNED;
+
+ if( uxQueueMessagesWaiting( xNetworkEventQueue ) != 0u )
+ {
+ /* Not actually going to send the message but this is not a
+ failure as the message didn't need to be sent. */
+ xSendMessage = pdFALSE;
+ }
+ }
+ }
+ #endif /* ipconfigUSE_TCP */
+
+ if( xSendMessage != pdFALSE )
+ {
+ /* The IP task cannot block itself while waiting for itself to
+ respond. */
+ if( ( xIsCallingFromIPTask() == pdTRUE ) && ( xTimeout > ( TickType_t ) 0 ) )
+ {
+ xTimeout = ( TickType_t ) 0;
+ }
+
+ xReturn = xQueueSendToBack( xNetworkEventQueue, pxEvent, xTimeout );
+
+ if( xReturn == pdFAIL )
+ {
+ /* A message should have been sent to the IP task, but wasn't. */
+ FreeRTOS_debug_printf( ( "xSendEventStructToIPTask: CAN NOT ADD %d\n", pxEvent->eEventType ) );
+ iptraceSTACK_TX_EVENT_LOST( pxEvent->eEventType );
+ }
+ }
+ else
+ {
+ /* It was not necessary to send the message to process the event so
+ even though the message was not sent the call was successful. */
+ xReturn = pdPASS;
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer )
+{
+eFrameProcessingResult_t eReturn;
+const EthernetHeader_t *pxEthernetHeader;
+
+ pxEthernetHeader = ( const EthernetHeader_t * ) pucEthernetBuffer;
+
+ if( memcmp( ( void * ) ipLOCAL_MAC_ADDRESS, ( void * ) &( pxEthernetHeader->xDestinationAddress ), sizeof( MACAddress_t ) ) == 0 )
+ {
+ /* The packet was directed to this node directly - process it. */
+ eReturn = eProcessBuffer;
+ }
+ else if( memcmp( ( void * ) xBroadcastMACAddress.ucBytes, ( void * ) pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
+ {
+ /* The packet was a broadcast - process it. */
+ eReturn = eProcessBuffer;
+ }
+ else
+#if( ipconfigUSE_LLMNR == 1 )
+ if( memcmp( ( void * ) xLLMNR_MacAdress.ucBytes, ( void * ) pxEthernetHeader->xDestinationAddress.ucBytes, sizeof( MACAddress_t ) ) == 0 )
+ {
+ /* The packet is a request for LLMNR - process it. */
+ eReturn = eProcessBuffer;
+ }
+ else
+#endif /* ipconfigUSE_LLMNR */
+ {
+ /* The packet was not a broadcast, or for this node, just release
+ the buffer without taking any other action. */
+ eReturn = eReleaseBuffer;
+ }
+
+ #if( ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES == 1 )
+ {
+ uint16_t usFrameType;
+
+ if( eReturn == eProcessBuffer )
+ {
+ usFrameType = pxEthernetHeader->usFrameType;
+ usFrameType = FreeRTOS_ntohs( usFrameType );
+
+ if( usFrameType <= 0x600U )
+ {
+ /* Not an Ethernet II frame. */
+ eReturn = eReleaseBuffer;
+ }
+ }
+ }
+ #endif /* ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES == 1 */
+
+ return eReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvProcessNetworkDownEvent( void )
+{
+ /* Stop the ARP timer while there is no network. */
+ xARPTimer.bActive = pdFALSE_UNSIGNED;
+
+ #if ipconfigUSE_NETWORK_EVENT_HOOK == 1
+ {
+ static BaseType_t xCallEventHook = pdFALSE;
+
+ /* The first network down event is generated by the IP stack itself to
+ initialise the network hardware, so do not call the network down event
+ the first time through. */
+ if( xCallEventHook == pdTRUE )
+ {
+ vApplicationIPNetworkEventHook( eNetworkDown );
+ }
+ xCallEventHook = pdTRUE;
+ }
+ #endif
+
+ /* Per the ARP Cache Validation section of https://tools.ietf.org/html/rfc1122,
+ treat network down as a "delivery problem" and flush the ARP cache for this
+ interface. */
+ FreeRTOS_ClearARP( );
+
+ /* The network has been disconnected (or is being initialised for the first
+ time). Perform whatever hardware processing is necessary to bring it up
+ again, or wait for it to be available again. This is hardware dependent. */
+ if( xNetworkInterfaceInitialise() != pdPASS )
+ {
+ /* Ideally the network interface initialisation function will only
+ return when the network is available. In case this is not the case,
+ wait a while before retrying the initialisation. */
+ vTaskDelay( ipINITIALISATION_RETRY_DELAY );
+ FreeRTOS_NetworkDown();
+ }
+ else
+ {
+ /* Set remaining time to 0 so it will become active immediately. */
+ #if ipconfigUSE_DHCP == 1
+ {
+ /* The network is not up until DHCP has completed. */
+ vDHCPProcess( pdTRUE );
+ xSendEventToIPTask( eDHCPEvent );
+ }
+ #else
+ {
+ /* Perform any necessary 'network up' processing. */
+ vIPNetworkUpCalls();
+ }
+ #endif
+ }
+}
+/*-----------------------------------------------------------*/
+
+void vIPNetworkUpCalls( void )
+{
+ xNetworkUp = pdTRUE;
+
+ #if( ipconfigUSE_NETWORK_EVENT_HOOK == 1 )
+ {
+ vApplicationIPNetworkEventHook( eNetworkUp );
+ }
+ #endif /* ipconfigUSE_NETWORK_EVENT_HOOK */
+
+ #if( ipconfigDNS_USE_CALLBACKS != 0 )
+ {
+ /* The following function is declared in FreeRTOS_DNS.c and 'private' to
+ this library */
+ extern void vDNSInitialise( void );
+ vDNSInitialise();
+ }
+ #endif /* ipconfigDNS_USE_CALLBACKS != 0 */
+
+ /* Set remaining time to 0 so it will become active immediately. */
+ prvIPTimerReload( &xARPTimer, pdMS_TO_TICKS( ipARP_TIMER_PERIOD_MS ) );
+}
+/*-----------------------------------------------------------*/
+
+static void prvProcessEthernetPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+EthernetHeader_t *pxEthernetHeader;
+eFrameProcessingResult_t eReturned = eReleaseBuffer;
+
+ configASSERT( pxNetworkBuffer );
+
+ /* Interpret the Ethernet frame. */
+ if( pxNetworkBuffer->xDataLength >= sizeof( EthernetHeader_t ) )
+ {
+ eReturned = ipCONSIDER_FRAME_FOR_PROCESSING( pxNetworkBuffer->pucEthernetBuffer );
+ pxEthernetHeader = ( EthernetHeader_t * )( pxNetworkBuffer->pucEthernetBuffer );
+
+ if( eReturned == eProcessBuffer )
+ {
+ /* Interpret the received Ethernet packet. */
+ switch( pxEthernetHeader->usFrameType )
+ {
+ case ipARP_FRAME_TYPE:
+ /* The Ethernet frame contains an ARP packet. */
+ if( pxNetworkBuffer->xDataLength >= sizeof( ARPPacket_t ) )
+ {
+ eReturned = eARPProcessPacket( ( ARPPacket_t * )pxNetworkBuffer->pucEthernetBuffer );
+ }
+ else
+ {
+ eReturned = eReleaseBuffer;
+ }
+ break;
+
+ case ipIPv4_FRAME_TYPE:
+ /* The Ethernet frame contains an IP packet. */
+ if( pxNetworkBuffer->xDataLength >= sizeof( IPPacket_t ) )
+ {
+ eReturned = prvProcessIPPacket( ( IPPacket_t * )pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer );
+ }
+ else
+ {
+ eReturned = eReleaseBuffer;
+ }
+ break;
+
+ default:
+ /* No other packet types are handled. Nothing to do. */
+ eReturned = eReleaseBuffer;
+ break;
+ }
+ }
+ }
+
+ /* Perform any actions that resulted from processing the Ethernet frame. */
+ switch( eReturned )
+ {
+ case eReturnEthernetFrame :
+ /* The Ethernet frame will have been updated (maybe it was
+ an ARP request or a PING request?) and should be sent back to
+ its source. */
+ vReturnEthernetFrame( pxNetworkBuffer, pdTRUE );
+ /* parameter pdTRUE: the buffer must be released once
+ the frame has been transmitted */
+ break;
+
+ case eFrameConsumed :
+ /* The frame is in use somewhere, don't release the buffer
+ yet. */
+ break;
+
+ default :
+ /* The frame is not being used anywhere, and the
+ NetworkBufferDescriptor_t structure containing the frame should
+ just be released back to the list of free buffers. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ break;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static eFrameProcessingResult_t prvAllowIPPacket( const IPPacket_t * const pxIPPacket,
+ NetworkBufferDescriptor_t * const pxNetworkBuffer, UBaseType_t uxHeaderLength )
+{
+eFrameProcessingResult_t eReturn = eProcessBuffer;
+
+#if( ( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 ) || ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) )
+ const IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
+#else
+ /* or else, the parameter won't be used and the function will be optimised
+ away */
+ ( void ) pxIPPacket;
+#endif
+
+ #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 0 )
+ {
+ /* In systems with a very small amount of RAM, it might be advantageous
+ to have incoming messages checked earlier, by the network card driver.
+ This method may decrease the usage of sparse network buffers. */
+ uint32_t ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
+
+ /* Ensure that the incoming packet is not fragmented (only outgoing
+ packets can be fragmented) as these are the only handled IP frames
+ currently. */
+ if( ( pxIPHeader->usFragmentOffset & ipFRAGMENT_OFFSET_BIT_MASK ) != 0U )
+ {
+ /* Can not handle, fragmented packet. */
+ eReturn = eReleaseBuffer;
+ }
+ /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
+ * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
+ else if( ( pxIPHeader->ucVersionHeaderLength < 0x45u ) || ( pxIPHeader->ucVersionHeaderLength > 0x4Fu ) )
+ {
+ /* Can not handle, unknown or invalid header version. */
+ eReturn = eReleaseBuffer;
+ }
+ /* Is the packet for this IP address? */
+ else if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
+ /* Is it the global broadcast address 255.255.255.255 ? */
+ ( ulDestinationIPAddress != ipBROADCAST_IP_ADDRESS ) &&
+ /* Is it a specific broadcast address 192.168.1.255 ? */
+ ( ulDestinationIPAddress != xNetworkAddressing.ulBroadcastAddress ) &&
+ #if( ipconfigUSE_LLMNR == 1 )
+ /* Is it the LLMNR multicast address? */
+ ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
+ #endif
+ /* Or (during DHCP negotiation) we have no IP-address yet? */
+ ( *ipLOCAL_IP_ADDRESS_POINTER != 0UL ) )
+ {
+ /* Packet is not for this node, release it */
+ eReturn = eReleaseBuffer;
+ }
+ }
+ #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+
+ #if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 )
+ {
+ /* Some drivers of NIC's with checksum-offloading will enable the above
+ define, so that the checksum won't be checked again here */
+ if (eReturn == eProcessBuffer )
+ {
+ /* Is the IP header checksum correct? */
+ if( ( pxIPHeader->ucProtocol != ( uint8_t ) ipPROTOCOL_ICMP ) &&
+ ( usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ( size_t ) uxHeaderLength ) != ipCORRECT_CRC ) )
+ {
+ /* Check sum in IP-header not correct. */
+ eReturn = eReleaseBuffer;
+ }
+ /* Is the upper-layer checksum (TCP/UDP/ICMP) correct? */
+ else if( usGenerateProtocolChecksum( ( uint8_t * )( pxNetworkBuffer->pucEthernetBuffer ), pxNetworkBuffer->xDataLength, pdFALSE ) != ipCORRECT_CRC )
+ {
+ /* Protocol checksum not accepted. */
+ eReturn = eReleaseBuffer;
+ }
+ }
+ }
+ #else
+ {
+ /* to avoid warning unused parameters */
+ ( void ) pxNetworkBuffer;
+ ( void ) uxHeaderLength;
+ }
+ #endif /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 */
+
+ return eReturn;
+}
+/*-----------------------------------------------------------*/
+
+static eFrameProcessingResult_t prvProcessIPPacket( IPPacket_t * const pxIPPacket, NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+eFrameProcessingResult_t eReturn;
+IPHeader_t * pxIPHeader = &( pxIPPacket->xIPHeader );
+UBaseType_t uxHeaderLength = ( UBaseType_t ) ( ( pxIPHeader->ucVersionHeaderLength & 0x0Fu ) << 2 );
+uint8_t ucProtocol;
+
+ /* Bound the calculated header length: take away the Ethernet header size,
+ then check if the IP header is claiming to be longer than the remaining
+ total packet size. Also check for minimal header field length. */
+ if( ( uxHeaderLength > ( pxNetworkBuffer->xDataLength - ipSIZE_OF_ETH_HEADER ) ) ||
+ ( uxHeaderLength < ipSIZE_OF_IPv4_HEADER ) )
+ {
+ return eReleaseBuffer;
+ }
+
+ ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
+ /* Check if the IP headers are acceptable and if it has our destination. */
+ eReturn = prvAllowIPPacket( pxIPPacket, pxNetworkBuffer, uxHeaderLength );
+
+ if( eReturn == eProcessBuffer )
+ {
+ if( uxHeaderLength > ipSIZE_OF_IPv4_HEADER )
+ {
+ /* All structs of headers expect a IP header size of 20 bytes
+ * IP header options were included, we'll ignore them and cut them out
+ * Note: IP options are mostly use in Multi-cast protocols */
+ const size_t optlen = ( ( size_t ) uxHeaderLength ) - ipSIZE_OF_IPv4_HEADER;
+ /* From: the previous start of UDP/ICMP/TCP data */
+ uint8_t *pucSource = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + uxHeaderLength);
+ /* To: the usual start of UDP/ICMP/TCP data at offset 20 from IP header */
+ uint8_t *pucTarget = ( uint8_t* )(pxNetworkBuffer->pucEthernetBuffer + sizeof( EthernetHeader_t ) + ipSIZE_OF_IPv4_HEADER);
+ /* How many: total length minus the options and the lower headers */
+ const size_t xMoveLen = pxNetworkBuffer->xDataLength - optlen - ipSIZE_OF_IPv4_HEADER - ipSIZE_OF_ETH_HEADER;
+
+ memmove( pucTarget, pucSource, xMoveLen );
+ pxNetworkBuffer->xDataLength -= optlen;
+
+ /* Fix-up new version/header length field in IP packet. */
+ pxIPHeader->ucVersionHeaderLength = ( pxIPHeader->ucVersionHeaderLength & 0xF0 ) | /* High nibble is the version. */
+ ( ( ipSIZE_OF_IPv4_HEADER >> 2 ) & 0x0F ); /* Low nibble is the header size, in bytes, divided by four. */
+ }
+
+ /* Add the IP and MAC addresses to the ARP table if they are not
+ already there - otherwise refresh the age of the existing
+ entry. */
+ if( ucProtocol != ( uint8_t ) ipPROTOCOL_UDP )
+ {
+ /* Refresh the ARP cache with the IP/MAC-address of the received packet
+ * For UDP packets, this will be done later in xProcessReceivedUDPPacket()
+ * as soon as know that the message will be handled by someone
+ * This will prevent that the ARP cache will get overwritten
+ * with the IP-address of useless broadcast packets
+ */
+ vARPRefreshCacheEntry( &( pxIPPacket->xEthernetHeader.xSourceAddress ), pxIPHeader->ulSourceIPAddress );
+ }
+ switch( ucProtocol )
+ {
+ case ipPROTOCOL_ICMP :
+ /* The IP packet contained an ICMP frame. Don't bother
+ checking the ICMP checksum, as if it is wrong then the
+ wrong data will also be returned, and the source of the
+ ping will know something went wrong because it will not
+ be able to validate what it receives. */
+ #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+ {
+ if( pxNetworkBuffer->xDataLength >= sizeof( ICMPPacket_t ) )
+ {
+ ICMPPacket_t *pxICMPPacket = ( ICMPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
+ if( pxIPHeader->ulDestinationIPAddress == *ipLOCAL_IP_ADDRESS_POINTER )
+ {
+ eReturn = prvProcessICMPPacket( pxICMPPacket );
+ }
+ }
+ else
+ {
+ eReturn = eReleaseBuffer;
+ }
+ }
+ #endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
+ break;
+
+ case ipPROTOCOL_UDP :
+ {
+ /* The IP packet contained a UDP frame. */
+ UDPPacket_t *pxUDPPacket = ( UDPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+
+ /* Only proceed if the payload length indicated in the header
+ appears to be valid. */
+ if ( ( pxNetworkBuffer->xDataLength >= sizeof( UDPPacket_t ) ) && ( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) >= sizeof( UDPHeader_t ) ) )
+ {
+ size_t uxPayloadSize_1, uxPayloadSize_2;
+ /* The UDP payload size can be calculated by subtracting the
+ * header size from `xDataLength`.
+ * However, the `xDataLength` may be longer that expected,
+ * e.g. when a small packet is padded with zero's.
+ * The UDP header contains a field `usLength` reflecting
+ * the payload size plus the UDP header ( 8 bytes ).
+ * Set `xDataLength` to the size of the headers,
+ * plus the lower of the two calculated payload sizes.
+ */
+
+ uxPayloadSize_1 = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
+ uxPayloadSize_2 = FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usLength ) - sizeof( UDPHeader_t );
+ if( uxPayloadSize_1 > uxPayloadSize_2 )
+ {
+ pxNetworkBuffer->xDataLength = uxPayloadSize_2 + sizeof( UDPPacket_t );
+ }
+
+ /* Fields in pxNetworkBuffer (usPort, ulIPAddress) are network order. */
+ pxNetworkBuffer->usPort = pxUDPPacket->xUDPHeader.usSourcePort;
+ pxNetworkBuffer->ulIPAddress = pxUDPPacket->xIPHeader.ulSourceIPAddress;
+
+ /* ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM:
+ * In some cases, the upper-layer checksum has been calculated
+ * by the NIC driver.
+ *
+ * Pass the packet payload to the UDP sockets implementation. */
+ if( xProcessReceivedUDPPacket( pxNetworkBuffer,
+ pxUDPPacket->xUDPHeader.usDestinationPort ) == pdPASS )
+ {
+ eReturn = eFrameConsumed;
+ }
+ }
+ else
+ {
+ eReturn = eReleaseBuffer;
+ }
+ }
+ break;
+
+#if ipconfigUSE_TCP == 1
+ case ipPROTOCOL_TCP :
+ {
+
+ if( xProcessReceivedTCPPacket( pxNetworkBuffer ) == pdPASS )
+ {
+ eReturn = eFrameConsumed;
+ }
+
+ /* Setting this variable will cause xTCPTimerCheck()
+ to be called just before the IP-task blocks. */
+ xProcessedTCPMessage++;
+ }
+ break;
+#endif
+ default :
+ /* Not a supported frame type. */
+ break;
+ }
+ }
+
+ return eReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+
+ static void prvProcessICMPEchoReply( ICMPPacket_t * const pxICMPPacket )
+ {
+ ePingReplyStatus_t eStatus = eSuccess;
+ uint16_t usDataLength, usCount;
+ uint8_t *pucByte;
+
+ /* Find the total length of the IP packet. */
+ usDataLength = pxICMPPacket->xIPHeader.usLength;
+ usDataLength = FreeRTOS_ntohs( usDataLength );
+
+ /* Remove the length of the IP headers to obtain the length of the ICMP
+ message itself. */
+ usDataLength = ( uint16_t ) ( ( ( uint32_t ) usDataLength ) - ipSIZE_OF_IPv4_HEADER );
+
+ /* Remove the length of the ICMP header, to obtain the length of
+ data contained in the ping. */
+ usDataLength = ( uint16_t ) ( ( ( uint32_t ) usDataLength ) - ipSIZE_OF_ICMP_HEADER );
+
+ /* Checksum has already been checked before in prvProcessIPPacket */
+
+ /* Find the first byte of the data within the ICMP packet. */
+ pucByte = ( uint8_t * ) pxICMPPacket;
+ pucByte += sizeof( ICMPPacket_t );
+
+ /* Check each byte. */
+ for( usCount = 0; usCount < usDataLength; usCount++ )
+ {
+ if( *pucByte != ipECHO_DATA_FILL_BYTE )
+ {
+ eStatus = eInvalidData;
+ break;
+ }
+
+ pucByte++;
+ }
+
+ /* Call back into the application to pass it the result. */
+ vApplicationPingReplyHook( eStatus, pxICMPPacket->xICMPHeader.usIdentifier );
+ }
+
+#endif
+/*-----------------------------------------------------------*/
+
+#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
+
+ static eFrameProcessingResult_t prvProcessICMPEchoRequest( ICMPPacket_t * const pxICMPPacket )
+ {
+ ICMPHeader_t *pxICMPHeader;
+ IPHeader_t *pxIPHeader;
+ uint16_t usRequest;
+
+ pxICMPHeader = &( pxICMPPacket->xICMPHeader );
+ pxIPHeader = &( pxICMPPacket->xIPHeader );
+
+ /* HT:endian: changed back */
+ iptraceSENDING_PING_REPLY( pxIPHeader->ulSourceIPAddress );
+
+ /* The checksum can be checked here - but a ping reply should be
+ returned even if the checksum is incorrect so the other end can
+ tell that the ping was received - even if the ping reply contains
+ invalid data. */
+ pxICMPHeader->ucTypeOfMessage = ( uint8_t ) ipICMP_ECHO_REPLY;
+ pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
+ pxIPHeader->ulSourceIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
+
+ /* Update the checksum because the ucTypeOfMessage member in the header
+ has been changed to ipICMP_ECHO_REPLY. This is faster than calling
+ usGenerateChecksum(). */
+
+ /* due to compiler warning "integer operation result is out of range" */
+
+ usRequest = ( uint16_t ) ( ( uint16_t )ipICMP_ECHO_REQUEST << 8 );
+
+ if( pxICMPHeader->usChecksum >= FreeRTOS_htons( 0xFFFFu - usRequest ) )
+ {
+ pxICMPHeader->usChecksum = ( uint16_t )
+ ( ( ( uint32_t ) pxICMPHeader->usChecksum ) +
+ FreeRTOS_htons( usRequest + 1UL ) );
+ }
+ else
+ {
+ pxICMPHeader->usChecksum = ( uint16_t )
+ ( ( ( uint32_t ) pxICMPHeader->usChecksum ) +
+ FreeRTOS_htons( usRequest ) );
+ }
+ return eReturnEthernetFrame;
+ }
+
+#endif /* ipconfigREPLY_TO_INCOMING_PINGS == 1 */
+/*-----------------------------------------------------------*/
+
+#if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+
+ static eFrameProcessingResult_t prvProcessICMPPacket( ICMPPacket_t * const pxICMPPacket )
+ {
+ eFrameProcessingResult_t eReturn = eReleaseBuffer;
+
+ iptraceICMP_PACKET_RECEIVED();
+ switch( pxICMPPacket->xICMPHeader.ucTypeOfMessage )
+ {
+ case ipICMP_ECHO_REQUEST :
+ #if ( ipconfigREPLY_TO_INCOMING_PINGS == 1 )
+ {
+ eReturn = prvProcessICMPEchoRequest( pxICMPPacket );
+ }
+ #endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) */
+ break;
+
+ case ipICMP_ECHO_REPLY :
+ #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+ {
+ prvProcessICMPEchoReply( pxICMPPacket );
+ }
+ #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
+ break;
+
+ default :
+ break;
+ }
+
+ return eReturn;
+ }
+
+#endif /* ( ipconfigREPLY_TO_INCOMING_PINGS == 1 ) || ( ipconfigSUPPORT_OUTGOING_PINGS == 1 ) */
+/*-----------------------------------------------------------*/
+
+uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket )
+{
+uint32_t ulLength;
+uint16_t usChecksum, *pusChecksum;
+const IPPacket_t * pxIPPacket;
+UBaseType_t uxIPHeaderLength;
+ProtocolPacket_t *pxProtPack;
+uint8_t ucProtocol;
+#if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ const char *pcType;
+#endif
+
+ /* Check for minimum packet size. */
+ if( uxBufferLength < sizeof( IPPacket_t ) )
+ {
+ return ipINVALID_LENGTH;
+ }
+
+ /* Parse the packet length. */
+ pxIPPacket = ( const IPPacket_t * ) pucEthernetBuffer;
+
+ /* Per https://tools.ietf.org/html/rfc791, the four-bit Internet Header
+ Length field contains the length of the internet header in 32-bit words. */
+ uxIPHeaderLength = ( UBaseType_t ) ( sizeof( uint32_t ) * ( pxIPPacket->xIPHeader.ucVersionHeaderLength & 0x0Fu ) );
+
+ /* Check for minimum packet size. */
+ if( uxBufferLength < sizeof( IPPacket_t ) + uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER )
+ {
+ return ipINVALID_LENGTH;
+ }
+ if( uxBufferLength < ( size_t ) ( ipSIZE_OF_ETH_HEADER + FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) ) )
+ {
+ return ipINVALID_LENGTH;
+ }
+
+ /* Identify the next protocol. */
+ ucProtocol = pxIPPacket->xIPHeader.ucProtocol;
+
+ /* N.B., if this IP packet header includes Options, then the following
+ assignment results in a pointer into the protocol packet with the Ethernet
+ and IP headers incorrectly aligned. However, either way, the "third"
+ protocol (Layer 3 or 4) header will be aligned, which is the convenience
+ of this calculation. */
+ pxProtPack = ( ProtocolPacket_t * ) ( pucEthernetBuffer + ( uxIPHeaderLength - ipSIZE_OF_IPv4_HEADER ) );
+
+ /* Switch on the Layer 3/4 protocol. */
+ if( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP )
+ {
+ if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_UDP_HEADER ) )
+ {
+ return ipINVALID_LENGTH;
+ }
+
+ pusChecksum = ( uint16_t * ) ( &( pxProtPack->xUDPPacket.xUDPHeader.usChecksum ) );
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ pcType = "UDP";
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ }
+ else if( ucProtocol == ( uint8_t ) ipPROTOCOL_TCP )
+ {
+ if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_TCP_HEADER ) )
+ {
+ return ipINVALID_LENGTH;
+ }
+
+ pusChecksum = ( uint16_t * ) ( &( pxProtPack->xTCPPacket.xTCPHeader.usChecksum ) );
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ pcType = "TCP";
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ }
+ else if( ( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP ) ||
+ ( ucProtocol == ( uint8_t ) ipPROTOCOL_IGMP ) )
+ {
+ if( uxBufferLength < ( uxIPHeaderLength + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_ICMP_HEADER ) )
+ {
+ return ipINVALID_LENGTH;
+ }
+
+ pusChecksum = ( uint16_t * ) ( &( pxProtPack->xICMPPacket.xICMPHeader.usChecksum ) );
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ if( ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
+ {
+ pcType = "ICMP";
+ }
+ else
+ {
+ pcType = "IGMP";
+ }
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+ }
+ else
+ {
+ /* Unhandled protocol, other than ICMP, IGMP, UDP, or TCP. */
+ return ipUNHANDLED_PROTOCOL;
+ }
+
+ /* The protocol and checksum field have been identified. Check the direction
+ of the packet. */
+ if( xOutgoingPacket != pdFALSE )
+ {
+ /* This is an outgoing packet. Before calculating the checksum, set it
+ to zero. */
+ *( pusChecksum ) = 0u;
+ }
+ else if( ( *pusChecksum == 0u ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
+ {
+ /* Sender hasn't set the checksum, no use to calculate it. */
+ return ipCORRECT_CRC;
+ }
+
+ ulLength = ( uint32_t )
+ ( FreeRTOS_ntohs( pxIPPacket->xIPHeader.usLength ) - ( ( uint16_t ) uxIPHeaderLength ) ); /* normally minus 20 */
+
+ if( ( ulLength < sizeof( pxProtPack->xUDPPacket.xUDPHeader ) ) ||
+ ( ulLength > ( uint32_t )( ipconfigNETWORK_MTU - uxIPHeaderLength ) ) )
+ {
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: len invalid: %lu\n", pcType, ulLength ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+
+ /* Again, in a 16-bit return value there is no space to indicate an
+ error. For incoming packets, 0x1234 will cause dropping of the packet.
+ For outgoing packets, there is a serious problem with the
+ format/length */
+ return ipINVALID_LENGTH;
+ }
+ if( ucProtocol <= ( uint8_t ) ipPROTOCOL_IGMP )
+ {
+ /* ICMP/IGMP do not have a pseudo header for CRC-calculation. */
+ usChecksum = ( uint16_t )
+ ( ~usGenerateChecksum( 0UL,
+ ( uint8_t * ) &( pxProtPack->xTCPPacket.xTCPHeader ), ( size_t ) ulLength ) );
+ }
+ else
+ {
+ /* For UDP and TCP, sum the pseudo header, i.e. IP protocol + length
+ fields */
+ usChecksum = ( uint16_t ) ( ulLength + ( ( uint16_t ) ucProtocol ) );
+
+ /* And then continue at the IPv4 source and destination addresses. */
+ usChecksum = ( uint16_t )
+ ( ~usGenerateChecksum( ( uint32_t ) usChecksum, ( uint8_t * )&( pxIPPacket->xIPHeader.ulSourceIPAddress ),
+ ( 2u * sizeof( pxIPPacket->xIPHeader.ulSourceIPAddress ) + ulLength ) ) );
+
+ /* Sum TCP header and data. */
+ }
+
+ if( xOutgoingPacket == pdFALSE )
+ {
+ /* This is in incoming packet. If the CRC is correct, it should be zero. */
+ if( usChecksum == 0u )
+ {
+ usChecksum = ( uint16_t )ipCORRECT_CRC;
+ }
+ }
+ else
+ {
+ if( ( usChecksum == 0u ) && ( ucProtocol == ( uint8_t ) ipPROTOCOL_UDP ) )
+ {
+ /* In case of UDP, a calculated checksum of 0x0000 is transmitted
+ as 0xffff. A value of zero would mean that the checksum is not used. */
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ if( xOutgoingPacket != pdFALSE )
+ {
+ FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: crc swap: %04X\n", pcType, usChecksum ) );
+ }
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+
+ usChecksum = ( uint16_t )0xffffu;
+ }
+ }
+ usChecksum = FreeRTOS_htons( usChecksum );
+
+ if( xOutgoingPacket != pdFALSE )
+ {
+ *( pusChecksum ) = usChecksum;
+ }
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ else if( ( xOutgoingPacket == pdFALSE ) && ( usChecksum != ipCORRECT_CRC ) )
+ {
+ FreeRTOS_debug_printf( ( "usGenerateProtocolChecksum[%s]: ID %04X: from %lxip to %lxip bad crc: %04X\n",
+ pcType,
+ FreeRTOS_ntohs( pxIPPacket->xIPHeader.usIdentification ),
+ FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulSourceIPAddress ),
+ FreeRTOS_ntohl( pxIPPacket->xIPHeader.ulDestinationIPAddress ),
+ FreeRTOS_ntohs( *pusChecksum ) ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+
+ return usChecksum;
+}
+/*-----------------------------------------------------------*/
+
+/**
+ * This method generates a checksum for a given IPv4 header, per RFC791 (page 14).
+ * The checksum algorithm is decribed as:
+ * "[T]he 16 bit one's complement of the one's complement sum of all 16 bit words in the
+ * header. For purposes of computing the checksum, the value of the checksum field is zero."
+ *
+ * In a nutshell, that means that each 16-bit 'word' must be summed, after which
+ * the number of 'carries' (overflows) is added to the result. If that addition
+ * produces an overflow, that 'carry' must also be added to the final result. The final checksum
+ * should be the bitwise 'not' (ones-complement) of the result if the packet is
+ * meant to be transmitted, but this method simply returns the raw value, probably
+ * because when a packet is received, the checksum is verified by checking that
+ * ((received & calculated) == 0) without applying a bitwise 'not' to the 'calculated' checksum.
+ *
+ * This logic is optimized for microcontrollers which have limited resources, so the logic looks odd.
+ * It iterates over the full range of 16-bit words, but it does so by processing several 32-bit
+ * words at once whenever possible. Its first step is to align the memory pointer to a 32-bit boundary,
+ * after which it runs a fast loop to process multiple 32-bit words at once and adding their 'carries'.
+ * Finally, it finishes up by processing any remaining 16-bit words, and adding up all of the 'carries'.
+ * With 32-bit arithmetic, the number of 16-bit 'carries' produced by sequential additions can be found
+ * by looking at the 16 most-significant bits of the 32-bit integer, since a 32-bit int will continue
+ * counting up instead of overflowing after 16 bits. That is why the actual checksum calculations look like:
+ * union.u32 = ( uint32_t ) union.u16[ 0 ] + union.u16[ 1 ];
+ *
+ * Arguments:
+ * ulSum: This argument provides a value to initialize the progressive summation
+ * of the header's values to. It is often 0, but protocols like TCP or UDP
+ * can have pseudo-header fields which need to be included in the checksum.
+ * pucNextData: This argument contains the address of the first byte which this
+ * method should process. The method's memory iterator is initialized to this value.
+ * uxDataLengthBytes: This argument contains the number of bytes that this method
+ * should process.
+ */
+uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes )
+{
+xUnion32 xSum2, xSum, xTerm;
+xUnionPtr xSource; /* Points to first byte */
+xUnionPtr xLastSource; /* Points to last byte plus one */
+uint32_t ulAlignBits, ulCarry = 0ul;
+
+ /* Small MCUs often spend up to 30% of the time doing checksum calculations
+ This function is optimised for 32-bit CPUs; Each time it will try to fetch
+ 32-bits, sums it with an accumulator and counts the number of carries. */
+
+ /* Swap the input (little endian platform only). */
+ xSum.u32 = FreeRTOS_ntohs( ulSum );
+ xTerm.u32 = 0ul;
+
+ xSource.u8ptr = ( uint8_t * ) pucNextData;
+ ulAlignBits = ( ( ( uint32_t ) pucNextData ) & 0x03u ); /* gives 0, 1, 2, or 3 */
+
+ /* If byte (8-bit) aligned... */
+ if( ( ( ulAlignBits & 1ul ) != 0ul ) && ( uxDataLengthBytes >= ( size_t ) 1 ) )
+ {
+ xTerm.u8[ 1 ] = *( xSource.u8ptr );
+ ( xSource.u8ptr )++;
+ uxDataLengthBytes--;
+ /* Now xSource is word (16-bit) aligned. */
+ }
+
+ /* If half-word (16-bit) aligned... */
+ if( ( ( ulAlignBits == 1u ) || ( ulAlignBits == 2u ) ) && ( uxDataLengthBytes >= 2u ) )
+ {
+ xSum.u32 += *(xSource.u16ptr);
+ ( xSource.u16ptr )++;
+ uxDataLengthBytes -= 2u;
+ /* Now xSource is word (32-bit) aligned. */
+ }
+
+ /* Word (32-bit) aligned, do the most part. */
+ xLastSource.u32ptr = ( xSource.u32ptr + ( uxDataLengthBytes / 4u ) ) - 3u;
+
+ /* In this loop, four 32-bit additions will be done, in total 16 bytes.
+ Indexing with constants (0,1,2,3) gives faster code than using
+ post-increments. */
+ while( xSource.u32ptr < xLastSource.u32ptr )
+ {
+ /* Use a secondary Sum2, just to see if the addition produced an
+ overflow. */
+ xSum2.u32 = xSum.u32 + xSource.u32ptr[ 0 ];
+ if( xSum2.u32 < xSum.u32 )
+ {
+ ulCarry++;
+ }
+
+ /* Now add the secondary sum to the major sum, and remember if there was
+ a carry. */
+ xSum.u32 = xSum2.u32 + xSource.u32ptr[ 1 ];
+ if( xSum2.u32 > xSum.u32 )
+ {
+ ulCarry++;
+ }
+
+ /* And do the same trick once again for indexes 2 and 3 */
+ xSum2.u32 = xSum.u32 + xSource.u32ptr[ 2 ];
+ if( xSum2.u32 < xSum.u32 )
+ {
+ ulCarry++;
+ }
+
+ xSum.u32 = xSum2.u32 + xSource.u32ptr[ 3 ];
+
+ if( xSum2.u32 > xSum.u32 )
+ {
+ ulCarry++;
+ }
+
+ /* And finally advance the pointer 4 * 4 = 16 bytes. */
+ xSource.u32ptr += 4;
+ }
+
+ /* Now add all carries. */
+ xSum.u32 = ( uint32_t )xSum.u16[ 0 ] + xSum.u16[ 1 ] + ulCarry;
+
+ uxDataLengthBytes %= 16u;
+ xLastSource.u8ptr = ( uint8_t * ) ( xSource.u8ptr + ( uxDataLengthBytes & ~( ( size_t ) 1 ) ) );
+
+ /* Half-word aligned. */
+ while( xSource.u16ptr < xLastSource.u16ptr )
+ {
+ /* At least one more short. */
+ xSum.u32 += xSource.u16ptr[ 0 ];
+ xSource.u16ptr++;
+ }
+
+ if( ( uxDataLengthBytes & ( size_t ) 1 ) != 0u ) /* Maybe one more ? */
+ {
+ xTerm.u8[ 0 ] = xSource.u8ptr[ 0 ];
+ }
+ xSum.u32 += xTerm.u32;
+
+ /* Now add all carries again. */
+ xSum.u32 = ( uint32_t ) xSum.u16[ 0 ] + xSum.u16[ 1 ];
+
+ /* The previous summation might have given a 16-bit carry. */
+ xSum.u32 = ( uint32_t ) xSum.u16[ 0 ] + xSum.u16[ 1 ];
+
+ if( ( ulAlignBits & 1u ) != 0u )
+ {
+ /* Quite unlikely, but pucNextData might be non-aligned, which would
+ mean that a checksum is calculated starting at an odd position. */
+ xSum.u32 = ( ( xSum.u32 & 0xffu ) << 8 ) | ( ( xSum.u32 & 0xff00u ) >> 8 );
+ }
+
+ /* swap the output (little endian platform only). */
+ return FreeRTOS_htons( ( (uint16_t) xSum.u32 ) );
+}
+/*-----------------------------------------------------------*/
+
+void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend )
+{
+EthernetHeader_t *pxEthernetHeader;
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNewBuffer;
+#endif
+
+ #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ BaseType_t xIndex;
+
+ FreeRTOS_printf( ( "vReturnEthernetFrame: length %lu\n", ( uint32_t )pxNetworkBuffer->xDataLength ) );
+ for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
+ {
+ pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
+ }
+ pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
+ }
+ }
+ #endif
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+
+ if( xReleaseAfterSend == pdFALSE )
+ {
+ pxNewBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, ( BaseType_t ) pxNetworkBuffer->xDataLength );
+ xReleaseAfterSend = pdTRUE;
+ pxNetworkBuffer = pxNewBuffer;
+ }
+
+ if( pxNetworkBuffer != NULL )
+#endif
+ {
+ pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+
+ /* Swap source and destination MAC addresses. */
+ memcpy( ( void * ) &( pxEthernetHeader->xDestinationAddress ), ( void * ) &( pxEthernetHeader->xSourceAddress ), sizeof( pxEthernetHeader->xDestinationAddress ) );
+ memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
+
+ /* Send! */
+ xNetworkInterfaceOutput( pxNetworkBuffer, xReleaseAfterSend );
+ }
+}
+/*-----------------------------------------------------------*/
+
+uint32_t FreeRTOS_GetIPAddress( void )
+{
+ /* Returns the IP address of the NIC. */
+ return *ipLOCAL_IP_ADDRESS_POINTER;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_SetIPAddress( uint32_t ulIPAddress )
+{
+ /* Sets the IP address of the NIC. */
+ *ipLOCAL_IP_ADDRESS_POINTER = ulIPAddress;
+}
+/*-----------------------------------------------------------*/
+
+uint32_t FreeRTOS_GetGatewayAddress( void )
+{
+ return xNetworkAddressing.ulGatewayAddress;
+}
+/*-----------------------------------------------------------*/
+
+uint32_t FreeRTOS_GetDNSServerAddress( void )
+{
+ return xNetworkAddressing.ulDNSServerAddress;
+}
+/*-----------------------------------------------------------*/
+
+uint32_t FreeRTOS_GetNetmask( void )
+{
+ return xNetworkAddressing.ulNetMask;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] )
+{
+ /* Copy the MAC address at the start of the default packet header fragment. */
+ memcpy( ( void * )ipLOCAL_MAC_ADDRESS, ( void * )ucMACAddress, ( size_t )ipMAC_ADDRESS_LENGTH_BYTES );
+}
+/*-----------------------------------------------------------*/
+
+const uint8_t * FreeRTOS_GetMACAddress( void )
+{
+ return ipLOCAL_MAC_ADDRESS;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_SetNetmask ( uint32_t ulNetmask )
+{
+ xNetworkAddressing.ulNetMask = ulNetmask;
+}
+/*-----------------------------------------------------------*/
+
+void FreeRTOS_SetGatewayAddress ( uint32_t ulGatewayAddress )
+{
+ xNetworkAddressing.ulGatewayAddress = ulGatewayAddress;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_DHCP == 1 )
+ void vIPSetDHCPTimerEnableState( BaseType_t xEnableState )
+ {
+ if( xEnableState != pdFALSE )
+ {
+ xDHCPTimer.bActive = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ xDHCPTimer.bActive = pdFALSE_UNSIGNED;
+ }
+ }
+#endif /* ipconfigUSE_DHCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_DHCP == 1 )
+ void vIPReloadDHCPTimer( uint32_t ulLeaseTime )
+ {
+ prvIPTimerReload( &xDHCPTimer, ulLeaseTime );
+ }
+#endif /* ipconfigUSE_DHCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigDNS_USE_CALLBACKS == 1 )
+ void vIPSetDnsTimerEnableState( BaseType_t xEnableState )
+ {
+ if( xEnableState != 0 )
+ {
+ xDNSTimer.bActive = pdTRUE;
+ }
+ else
+ {
+ xDNSTimer.bActive = pdFALSE;
+ }
+ }
+#endif /* ipconfigUSE_DHCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigDNS_USE_CALLBACKS != 0 )
+ void vIPReloadDNSTimer( uint32_t ulCheckTime )
+ {
+ prvIPTimerReload( &xDNSTimer, ulCheckTime );
+ }
+#endif /* ipconfigDNS_USE_CALLBACKS != 0 */
+/*-----------------------------------------------------------*/
+
+BaseType_t xIPIsNetworkTaskReady( void )
+{
+ return xIPTaskInitialised;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t FreeRTOS_IsNetworkUp( void )
+{
+ return xNetworkUp;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ UBaseType_t uxGetMinimumIPQueueSpace( void )
+ {
+ return uxQueueMinimumSpace;
+ }
+#endif
+/*-----------------------------------------------------------*/
+
+/* Provide access to private members for verification. */
+#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
+ #include "aws_freertos_ip_verification_access_ip_define.h"
+#endif
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
index e15834849..87099ecf1 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Sockets.c
@@ -1,3675 +1,3675 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_DNS.h"
-#include "NetworkBufferManagement.h"
-
-/* The ItemValue of the sockets xBoundSocketListItem member holds the socket's
-port number. */
-#define socketSET_SOCKET_PORT( pxSocket, usPort ) listSET_LIST_ITEM_VALUE( ( &( ( pxSocket )->xBoundSocketListItem ) ), ( usPort ) )
-#define socketGET_SOCKET_PORT( pxSocket ) listGET_LIST_ITEM_VALUE( ( &( ( pxSocket )->xBoundSocketListItem ) ) )
-
-/* Test if a socket it bound which means it is either included in
-xBoundUDPSocketsList or xBoundTCPSocketsList */
-#define socketSOCKET_IS_BOUND( pxSocket ) ( listLIST_ITEM_CONTAINER( & ( pxSocket )->xBoundSocketListItem ) != NULL )
-
-/* If FreeRTOS_sendto() is called on a socket that is not bound to a port
-number then, depending on the FreeRTOSIPConfig.h settings, it might be that a
-port number is automatically generated for the socket. Automatically generated
-port numbers will be between socketAUTO_PORT_ALLOCATION_START_NUMBER and
-0xffff.
-
-Per https://tools.ietf.org/html/rfc6056, "the dynamic ports consist of the range
-49152-65535. However, ephemeral port selection algorithms should use the whole
-range 1024-65535" excluding those already in use (inbound or outbound). */
-#if !defined( socketAUTO_PORT_ALLOCATION_START_NUMBER )
- #define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0x0400 )
-#endif
-
-#define socketAUTO_PORT_ALLOCATION_MAX_NUMBER ( ( uint16_t ) 0xffff )
-
-/* The number of octets that make up an IP address. */
-#define socketMAX_IP_ADDRESS_OCTETS 4u
-
-/* A block time of 0 simply means "don't block". */
-#define socketDONT_BLOCK ( ( TickType_t ) 0 )
-
-#if( ( ipconfigUSE_TCP == 1 ) && !defined( ipTCP_TIMER_PERIOD_MS ) )
- #define ipTCP_TIMER_PERIOD_MS ( 1000 )
-#endif
-
-/* The next private port number to use when binding a client socket is stored in
-the usNextPortToUse[] array - which has either 1 or two indexes depending on
-whether TCP is being supported. */
-#if( ipconfigUSE_TCP == 1 )
- #define socketPROTOCOL_COUNT 2
-#else
- #define socketPROTOCOL_COUNT 1
-#endif
-
-/* Indexes into the usNextPortToUse[] array for UDP and TCP sockets
-respectively. */
-#define socketNEXT_UDP_PORT_NUMBER_INDEX 0
-#define socketNEXT_TCP_PORT_NUMBER_INDEX 1
-
-/* Some helper macro's for defining the 20/80 % limits of uxLittleSpace / uxEnoughSpace. */
-#define sock20_PERCENT 20
-#define sock80_PERCENT 80
-#define sock100_PERCENT 100
-
-
-/*-----------------------------------------------------------*/
-
-/*
- * Allocate the next port number from the private allocation range.
- * TCP and UDP each have their own series of port numbers
- * ulProtocol is either ipPROTOCOL_UDP or ipPROTOCOL_TCP
- */
-static uint16_t prvGetPrivatePortNumber( BaseType_t xProtocol );
-
-/*
- * Return the list item from within pxList that has an item value of
- * xWantedItemValue. If there is no such list item return NULL.
- */
-static const ListItem_t * pxListFindListItemWithValue( const List_t *pxList, TickType_t xWantedItemValue );
-
-/*
- * Return pdTRUE only if pxSocket is valid and bound, as far as can be
- * determined.
- */
-static BaseType_t prvValidSocket( FreeRTOS_Socket_t *pxSocket, BaseType_t xProtocol, BaseType_t xIsBound );
-
-/*
- * Before creating a socket, check the validity of the parameters used
- * and find the size of the socket space, which is different for UDP and TCP
- */
-static BaseType_t prvDetermineSocketSize( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol, size_t *pxSocketSize );
-
-#if( ipconfigUSE_TCP == 1 )
- /*
- * Create a txStream or a rxStream, depending on the parameter 'xIsInputStream'
- */
- static StreamBuffer_t *prvTCPCreateStream (FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream );
-#endif /* ipconfigUSE_TCP == 1 */
-
-#if( ipconfigUSE_TCP == 1 )
- /*
- * Called from FreeRTOS_send(): some checks which will be done before
- * sending a TCP packed.
- */
- static int32_t prvTCPSendCheck( FreeRTOS_Socket_t *pxSocket, size_t xDataLength );
-#endif /* ipconfigUSE_TCP */
-
-#if( ipconfigUSE_TCP == 1 )
- /*
- * When a child socket gets closed, make sure to update the child-count of the parent
- */
- static void prvTCPSetSocketCount( FreeRTOS_Socket_t *pxSocketToDelete );
-#endif /* ipconfigUSE_TCP == 1 */
-
-#if( ipconfigUSE_TCP == 1 )
- /*
- * Called from FreeRTOS_connect(): make some checks and if allowed, send a
- * message to the IP-task to start connecting to a remote socket
- */
- static BaseType_t prvTCPConnectStart( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr *pxAddress );
-#endif /* ipconfigUSE_TCP */
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- /* Executed by the IP-task, it will check all sockets belonging to a set */
- static FreeRTOS_Socket_t *prvFindSelectedSocket( SocketSelect_t *pxSocketSet );
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-/* The list that contains mappings between sockets and port numbers. Accesses
-to this list must be protected by critical sections of one kind or another. */
-List_t xBoundUDPSocketsList;
-
-#if ipconfigUSE_TCP == 1
- List_t xBoundTCPSocketsList;
-#endif /* ipconfigUSE_TCP == 1 */
-
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvValidSocket( FreeRTOS_Socket_t *pxSocket, BaseType_t xProtocol, BaseType_t xIsBound )
-{
-BaseType_t xReturn = pdTRUE;
-
- if( ( pxSocket == NULL ) || ( pxSocket == FREERTOS_INVALID_SOCKET ) )
- {
- xReturn = pdFALSE;
- }
- else if( ( xIsBound != pdFALSE ) && ( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE ) )
- {
- /* The caller expects the socket to be bound, but it isn't. */
- xReturn = pdFALSE;
- }
- else if( pxSocket->ucProtocol != ( uint8_t ) xProtocol )
- {
- /* Socket has a wrong type (UDP != TCP). */
- xReturn = pdFALSE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t vNetworkSocketsInit( void )
-{
- vListInitialise( &xBoundUDPSocketsList );
-
- #if( ipconfigUSE_TCP == 1 )
- {
- vListInitialise( &xBoundTCPSocketsList );
- }
- #endif /* ipconfigUSE_TCP == 1 */
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvDetermineSocketSize( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol, size_t *pxSocketSize )
-{
-BaseType_t xReturn = pdPASS;
-FreeRTOS_Socket_t *pxSocket;
-
- /* Asserts must not appear before it has been determined that the network
- task is ready - otherwise the asserts will fail. */
- if( xIPIsNetworkTaskReady() == pdFALSE )
- {
- xReturn = pdFAIL;
- }
- else
- {
- /* Only Ethernet is currently supported. */
- configASSERT( xDomain == FREERTOS_AF_INET );
-
- /* Check if the UDP socket-list has been initialised. */
- configASSERT( listLIST_IS_INITIALISED( &xBoundUDPSocketsList ) );
- #if( ipconfigUSE_TCP == 1 )
- {
- /* Check if the TCP socket-list has been initialised. */
- configASSERT( listLIST_IS_INITIALISED( &xBoundTCPSocketsList ) );
- }
- #endif /* ipconfigUSE_TCP == 1 */
-
- if( xProtocol == FREERTOS_IPPROTO_UDP )
- {
- if( xType != FREERTOS_SOCK_DGRAM )
- {
- xReturn = pdFAIL;
- configASSERT( xReturn );
- }
- /* In case a UDP socket is created, do not allocate space for TCP data. */
- *pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xUDP );
- }
-#if( ipconfigUSE_TCP == 1 )
- else if( xProtocol == FREERTOS_IPPROTO_TCP )
- {
- if( xType != FREERTOS_SOCK_STREAM )
- {
- xReturn = pdFAIL;
- configASSERT( xReturn );
- }
-
- *pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xTCP );
- }
-#endif /* ipconfigUSE_TCP == 1 */
- else
- {
- xReturn = pdFAIL;
- configASSERT( xReturn );
- }
- }
- /* In case configASSERT() is not used */
- ( void )xDomain;
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-/* FreeRTOS_socket() allocates and initiates a socket */
-Socket_t FreeRTOS_socket( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol )
-{
-FreeRTOS_Socket_t *pxSocket;
-size_t uxSocketSize;
-EventGroupHandle_t xEventGroup;
-Socket_t xReturn;
-
- if( prvDetermineSocketSize( xDomain, xType, xProtocol, &uxSocketSize ) == pdFAIL )
- {
- xReturn = FREERTOS_INVALID_SOCKET;
- }
- else
- {
- /* Allocate the structure that will hold the socket information. The
- size depends on the type of socket: UDP sockets need less space. A
- define 'pvPortMallocSocket' will used to allocate the necessary space.
- By default it points to the FreeRTOS function 'pvPortMalloc()'. */
- pxSocket = ( FreeRTOS_Socket_t * ) pvPortMallocSocket( uxSocketSize );
-
- if( pxSocket == NULL )
- {
- pxSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
- iptraceFAILED_TO_CREATE_SOCKET();
- }
- else if( ( xEventGroup = xEventGroupCreate() ) == NULL )
- {
- vPortFreeSocket( pxSocket );
- pxSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
- iptraceFAILED_TO_CREATE_EVENT_GROUP();
- }
- else
- {
- /* Clear the entire space to avoid nulling individual entries */
- memset( pxSocket, '\0', uxSocketSize );
-
- pxSocket->xEventGroup = xEventGroup;
-
- /* Initialise the socket's members. The semaphore will be created
- if the socket is bound to an address, for now the pointer to the
- semaphore is just set to NULL to show it has not been created. */
- if( xProtocol == FREERTOS_IPPROTO_UDP )
- {
- vListInitialise( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
-
- #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
- {
- pxSocket->u.xUDP.uxMaxPackets = ( UBaseType_t ) ipconfigUDP_MAX_RX_PACKETS;
- }
- #endif /* ipconfigUDP_MAX_RX_PACKETS > 0 */
- }
-
- vListInitialiseItem( &( pxSocket->xBoundSocketListItem ) );
- listSET_LIST_ITEM_OWNER( &( pxSocket->xBoundSocketListItem ), ( void * ) pxSocket );
-
- pxSocket->xReceiveBlockTime = ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME;
- pxSocket->xSendBlockTime = ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME;
- pxSocket->ucSocketOptions = ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT;
- pxSocket->ucProtocol = ( uint8_t ) xProtocol; /* protocol: UDP or TCP */
-
- #if( ipconfigUSE_TCP == 1 )
- {
- if( xProtocol == FREERTOS_IPPROTO_TCP )
- {
- /* StreamSize is expressed in number of bytes */
- /* Round up buffer sizes to nearest multiple of MSS */
- pxSocket->u.xTCP.usInitMSS = pxSocket->u.xTCP.usCurMSS = ipconfigTCP_MSS;
- pxSocket->u.xTCP.uxRxStreamSize = ( size_t ) ipconfigTCP_RX_BUFFER_LENGTH;
- pxSocket->u.xTCP.uxTxStreamSize = ( size_t ) FreeRTOS_round_up( ipconfigTCP_TX_BUFFER_LENGTH, ipconfigTCP_MSS );
- /* Use half of the buffer size of the TCP windows */
- #if ( ipconfigUSE_TCP_WIN == 1 )
- {
- pxSocket->u.xTCP.uxRxWinSize = FreeRTOS_max_uint32( 1UL, ( uint32_t ) ( pxSocket->u.xTCP.uxRxStreamSize / 2 ) / ipconfigTCP_MSS );
- pxSocket->u.xTCP.uxTxWinSize = FreeRTOS_max_uint32( 1UL, ( uint32_t ) ( pxSocket->u.xTCP.uxTxStreamSize / 2 ) / ipconfigTCP_MSS );
- }
- #else
- {
- pxSocket->u.xTCP.uxRxWinSize = 1u;
- pxSocket->u.xTCP.uxTxWinSize = 1u;
- }
- #endif
- /* The above values are just defaults, and can be overridden by
- calling FreeRTOS_setsockopt(). No buffers will be allocated until a
- socket is connected and data is exchanged. */
- }
- }
- #endif /* ipconfigUSE_TCP == 1 */
- }
-
- xReturn = ( Socket_t ) pxSocket;
- }
-
- /* Remove compiler warnings in the case the configASSERT() is not defined. */
- ( void ) xDomain;
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- SocketSet_t FreeRTOS_CreateSocketSet( void )
- {
- SocketSelect_t *pxSocketSet;
-
- pxSocketSet = ( SocketSelect_t * ) pvPortMalloc( sizeof( *pxSocketSet ) );
-
- if( pxSocketSet != NULL )
- {
- memset( pxSocketSet, '\0', sizeof( *pxSocketSet ) );
- pxSocketSet->xSelectGroup = xEventGroupCreate();
-
- if( pxSocketSet->xSelectGroup == NULL )
- {
- vPortFree( ( void* ) pxSocketSet );
- pxSocketSet = NULL;
- }
- }
-
- return ( SocketSet_t ) pxSocketSet;
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- void FreeRTOS_DeleteSocketSet( SocketSet_t xSocketSet )
- {
- SocketSelect_t *pxSocketSet = ( SocketSelect_t*) xSocketSet;
-
- vEventGroupDelete( pxSocketSet->xSelectGroup );
- vPortFree( ( void* ) pxSocketSet );
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- /* Add a socket to a set */
- void FreeRTOS_FD_SET( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xSelectBits )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- SocketSelect_t *pxSocketSet = ( SocketSelect_t * ) xSocketSet;
-
- configASSERT( pxSocket != NULL );
- configASSERT( xSocketSet != NULL );
-
- /* Make sure we're not adding bits which are reserved for internal use,
- such as eSELECT_CALL_IP */
- pxSocket->xSelectBits |= ( xSelectBits & eSELECT_ALL );
-
- if( ( pxSocket->xSelectBits & eSELECT_ALL ) != 0 )
- {
- /* Adding a socket to a socket set. */
- pxSocket->pxSocketSet = ( SocketSelect_t * ) xSocketSet;
-
- /* Now have the IP-task call vSocketSelect() to see if the set contains
- any sockets which are 'ready' and set the proper bits.
- By setting 'bApiCalled = false', vSocketSelect() knows that it was
- not called from a user API */
- pxSocketSet->bApiCalled = pdFALSE;
- prvFindSelectedSocket( pxSocketSet );
- }
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- /* Clear select bits for a socket
- If the mask becomes 0, remove the socket from the set */
- void FreeRTOS_FD_CLR( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xSelectBits )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-
- configASSERT( pxSocket != NULL );
- configASSERT( xSocketSet != NULL );
-
- pxSocket->xSelectBits &= ~( xSelectBits & eSELECT_ALL );
- if( ( pxSocket->xSelectBits & eSELECT_ALL ) != 0 )
- {
- pxSocket->pxSocketSet = ( SocketSelect_t *)xSocketSet;
- }
- else
- {
- /* disconnect it from the socket set */
- pxSocket->pxSocketSet = ( SocketSelect_t *)NULL;
- }
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- /* Test if a socket belongs to a socket-set */
- EventBits_t FreeRTOS_FD_ISSET( Socket_t xSocket, SocketSet_t xSocketSet )
- {
- EventBits_t xReturn;
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-
- configASSERT( pxSocket != NULL );
- configASSERT( xSocketSet != NULL );
-
- if( xSocketSet == ( SocketSet_t ) pxSocket->pxSocketSet )
- {
- /* Make sure we're not adding bits which are reserved for internal
- use. */
- xReturn = pxSocket->xSocketBits & eSELECT_ALL;
- }
- else
- {
- xReturn = 0;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- /* The select() statement: wait for an event to occur on any of the sockets
- included in a socket set */
- BaseType_t FreeRTOS_select( SocketSet_t xSocketSet, TickType_t xBlockTimeTicks )
- {
- TimeOut_t xTimeOut;
- TickType_t xRemainingTime;
- SocketSelect_t *pxSocketSet = ( SocketSelect_t*) xSocketSet;
- BaseType_t xResult;
-
- configASSERT( xSocketSet != NULL );
-
- /* Only in the first round, check for non-blocking */
- xRemainingTime = xBlockTimeTicks;
-
- /* Fetch the current time */
- vTaskSetTimeOutState( &xTimeOut );
-
- for( ;; )
- {
- /* Find a socket which might have triggered the bit
- This function might return immediately or block for a limited time */
- xResult = ( BaseType_t ) xEventGroupWaitBits( pxSocketSet->xSelectGroup, eSELECT_ALL, pdFALSE, pdFALSE, xRemainingTime );
-
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- if( ( xResult & eSELECT_INTR ) != 0u )
- {
- xEventGroupClearBits( pxSocketSet->xSelectGroup, eSELECT_INTR );
- FreeRTOS_debug_printf( ( "FreeRTOS_select: interrupted\n" ) );
- break;
- }
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
-
- /* Have the IP-task find the socket which had an event */
- pxSocketSet->bApiCalled = pdTRUE;
- prvFindSelectedSocket( pxSocketSet );
-
- xResult = ( BaseType_t ) xEventGroupGetBits( pxSocketSet->xSelectGroup );
-
- if( xResult != 0 )
- {
- break;
- }
-
- /* Has the timeout been reached? */
- if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
- {
- break;
- }
- }
-
- return xResult;
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- /* Send a message to the IP-task to have it check all sockets belonging to
- 'pxSocketSet' */
- static FreeRTOS_Socket_t *prvFindSelectedSocket( SocketSelect_t *pxSocketSet )
- {
- IPStackEvent_t xSelectEvent;
- FreeRTOS_Socket_t *xReturn;
-
- xSelectEvent.eEventType = eSocketSelectEvent;
- xSelectEvent.pvData = ( void * ) pxSocketSet;
-
- /* while the IP-task works on the request, the API will block on
- 'eSELECT_CALL_IP'. So clear it first. */
- xEventGroupClearBits( pxSocketSet->xSelectGroup, eSELECT_CALL_IP );
-
- /* Now send the socket select event */
- if( xSendEventStructToIPTask( &xSelectEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
- {
- /* Oops, we failed to wake-up the IP task. No use to wait for it. */
- FreeRTOS_debug_printf( ( "prvFindSelectedSocket: failed\n" ) );
- xReturn = NULL;
- }
- else
- {
- /* As soon as the IP-task is ready, it will set 'eSELECT_CALL_IP' to
- wakeup the calling API */
- xEventGroupWaitBits( pxSocketSet->xSelectGroup, eSELECT_CALL_IP, pdTRUE, pdFALSE, portMAX_DELAY );
-
- /* Return 'pxSocket' which is set by the IP-task */
- xReturn = pxSocketSet->pxSocket;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-/*
- * FreeRTOS_recvfrom: receive data from a bound socket
- * In this library, the function can only be used with connectionsless sockets
- * (UDP)
- */
-int32_t FreeRTOS_recvfrom( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength )
-{
-BaseType_t lPacketCount = 0;
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-TickType_t xRemainingTime = ( TickType_t ) 0; /* Obsolete assignment, but some compilers output a warning if its not done. */
-BaseType_t xTimed = pdFALSE;
-TimeOut_t xTimeOut;
-int32_t lReturn;
-EventBits_t xEventBits = ( EventBits_t ) 0;
-
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_UDP, pdTRUE ) == pdFALSE )
- {
- return -pdFREERTOS_ERRNO_EINVAL;
- }
-
- lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
-
- /* The function prototype is designed to maintain the expected Berkeley
- sockets standard, but this implementation does not use all the parameters. */
- ( void ) pxSourceAddressLength;
-
- while( lPacketCount == 0 )
- {
- if( xTimed == pdFALSE )
- {
- /* Check to see if the socket is non blocking on the first
- iteration. */
- xRemainingTime = pxSocket->xReceiveBlockTime;
-
- if( xRemainingTime == ( TickType_t ) 0 )
- {
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- /* Just check for the interrupt flag. */
- xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_INTR,
- pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, socketDONT_BLOCK );
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
- break;
- }
-
- if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
- {
- break;
- }
-
- /* To ensure this part only executes once. */
- xTimed = pdTRUE;
-
- /* Fetch the current time. */
- vTaskSetTimeOutState( &xTimeOut );
- }
-
- /* Wait for arrival of data. While waiting, the IP-task may set the
- 'eSOCKET_RECEIVE' bit in 'xEventGroup', if it receives data for this
- socket, thus unblocking this API call. */
- xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_RECEIVE | eSOCKET_INTR,
- pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
-
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- if( ( xEventBits & eSOCKET_INTR ) != 0 )
- {
- if( ( xEventBits & eSOCKET_RECEIVE ) != 0 )
- {
- /* Shouldn't have cleared the eSOCKET_RECEIVE flag. */
- xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
- }
- break;
- }
- }
- #else
- {
- ( void ) xEventBits;
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
-
- lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
-
- if( lPacketCount != 0 )
- {
- break;
- }
-
- /* Has the timeout been reached ? */
- if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) )
- {
- break;
- }
- } /* while( lPacketCount == 0 ) */
-
- if( lPacketCount != 0 )
- {
- taskENTER_CRITICAL();
- {
- /* The owner of the list item is the network buffer. */
- pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
-
- if( ( xFlags & FREERTOS_MSG_PEEK ) == 0 )
- {
- /* Remove the network buffer from the list of buffers waiting to
- be processed by the socket. */
- uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
- }
- }
- taskEXIT_CRITICAL();
-
- /* The returned value is the length of the payload data, which is
- calculated at the total packet size minus the headers.
- The validity of `xDataLength` prvProcessIPPacket has been confirmed
- in 'prvProcessIPPacket()'. */
- lReturn = ( int32_t ) ( pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ) );
-
- if( pxSourceAddress != NULL )
- {
- pxSourceAddress->sin_port = pxNetworkBuffer->usPort;
- pxSourceAddress->sin_addr = pxNetworkBuffer->ulIPAddress;
- }
-
- if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
- {
- /* The zero copy flag is not set. Truncate the length if it won't
- fit in the provided buffer. */
- if( lReturn > ( int32_t ) xBufferLength )
- {
- iptraceRECVFROM_DISCARDING_BYTES( ( xBufferLength - lReturn ) );
- lReturn = ( int32_t )xBufferLength;
- }
-
- /* Copy the received data into the provided buffer, then release the
- network buffer. */
- memcpy( pvBuffer, ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ), ( size_t )lReturn );
-
- if( ( xFlags & FREERTOS_MSG_PEEK ) == 0 )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- }
- else
- {
- /* The zero copy flag was set. pvBuffer is not a buffer into which
- the received data can be copied, but a pointer that must be set to
- point to the buffer in which the received data has already been
- placed. */
- *( ( void** ) pvBuffer ) = ( void * ) ( &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ) );
- }
-
- }
-#if( ipconfigSUPPORT_SIGNALS != 0 )
- else if( ( xEventBits & eSOCKET_INTR ) != 0 )
- {
- lReturn = -pdFREERTOS_ERRNO_EINTR;
- iptraceRECVFROM_INTERRUPTED();
- }
-#endif /* ipconfigSUPPORT_SIGNALS */
- else
- {
- lReturn = -pdFREERTOS_ERRNO_EWOULDBLOCK;
- iptraceRECVFROM_TIMEOUT();
- }
-
- return lReturn;
-}
-/*-----------------------------------------------------------*/
-
-int32_t FreeRTOS_sendto( Socket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, BaseType_t xFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xStackTxEvent = { eStackTxEvent, NULL };
-TimeOut_t xTimeOut;
-TickType_t xTicksToWait;
-int32_t lReturn = 0;
-FreeRTOS_Socket_t *pxSocket;
-
- pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-
- /* The function prototype is designed to maintain the expected Berkeley
- sockets standard, but this implementation does not use all the
- parameters. */
- ( void ) xDestinationAddressLength;
- configASSERT( pvBuffer );
-
- if( xTotalDataLength <= ( size_t ) ipMAX_UDP_PAYLOAD_LENGTH )
- {
- /* If the socket is not already bound to an address, bind it now.
- Passing NULL as the address parameter tells FreeRTOS_bind() to select
- the address to bind to. */
- if( ( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE ) ||
- ( FreeRTOS_bind( xSocket, NULL, 0u ) == 0 ) )
- {
- xTicksToWait = pxSocket->xSendBlockTime;
-
- #if( ipconfigUSE_CALLBACKS != 0 )
- {
- if( xIsCallingFromIPTask() != pdFALSE )
- {
- /* If this send function is called from within a call-back
- handler it may not block, otherwise chances would be big to
- get a deadlock: the IP-task waiting for itself. */
- xTicksToWait = ( TickType_t )0;
- }
- }
- #endif /* ipconfigUSE_CALLBACKS */
-
- if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
- {
- xTicksToWait = ( TickType_t ) 0;
- }
-
- if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
- {
- /* Zero copy is not set, so obtain a network buffer into
- which the payload will be copied. */
- vTaskSetTimeOutState( &xTimeOut );
-
- /* Block until a buffer becomes available, or until a
- timeout has been reached */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( xTotalDataLength + sizeof( UDPPacket_t ), xTicksToWait );
-
- if( pxNetworkBuffer != NULL )
- {
- memcpy( ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ), ( void * ) pvBuffer, xTotalDataLength );
-
- if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE )
- {
- /* The entire block time has been used up. */
- xTicksToWait = ( TickType_t ) 0;
- }
- }
- }
- else
- {
- /* When zero copy is used, pvBuffer is a pointer to the
- payload of a buffer that has already been obtained from the
- stack. Obtain the network buffer pointer from the buffer. */
- pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( (void*)pvBuffer );
- }
-
- if( pxNetworkBuffer != NULL )
- {
- /* xDataLength is the size of the total packet, including the Ethernet header. */
- pxNetworkBuffer->xDataLength = xTotalDataLength + sizeof( UDPPacket_t );
- pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
- pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_PORT( pxSocket );
- pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;
-
- /* The socket options are passed to the IP layer in the
- space that will eventually get used by the Ethernet header. */
- pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = pxSocket->ucSocketOptions;
-
- /* Tell the networking task that the packet needs sending. */
- xStackTxEvent.pvData = pxNetworkBuffer;
-
- /* Ask the IP-task to send this packet */
- if( xSendEventStructToIPTask( &xStackTxEvent, xTicksToWait ) == pdPASS )
- {
- /* The packet was successfully sent to the IP task. */
- lReturn = ( int32_t ) xTotalDataLength;
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleSent ) )
- {
- pxSocket->u.xUDP.pxHandleSent( ( Socket_t )pxSocket, xTotalDataLength );
- }
- }
- #endif /* ipconfigUSE_CALLBACKS */
- }
- else
- {
- /* If the buffer was allocated in this function, release
- it. */
- if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- iptraceSTACK_TX_EVENT_LOST( ipSTACK_TX_EVENT );
- }
- }
- else
- {
- /* If errno was available, errno would be set to
- FREERTOS_ENOPKTS. As it is, the function must return the
- number of transmitted bytes, so the calling function knows
- how much data was actually sent. */
- iptraceNO_BUFFER_FOR_SENDTO();
- }
- }
- else
- {
- iptraceSENDTO_SOCKET_NOT_BOUND();
- }
- }
- else
- {
- /* The data is longer than the available buffer space. */
- iptraceSENDTO_DATA_TOO_LONG();
- }
-
- return lReturn;
-} /* Tested */
-/*-----------------------------------------------------------*/
-
-/*
- * FreeRTOS_bind() : binds a sockt to a local port number. If port 0 is
- * provided, a system provided port number will be assigned. This function can
- * be used for both UDP and TCP sockets. The actual binding will be performed
- * by the IP-task to avoid mutual access to the bound-socket-lists
- * (xBoundUDPSocketsList or xBoundTCPSocketsList).
- */
-BaseType_t FreeRTOS_bind( Socket_t xSocket, struct freertos_sockaddr * pxAddress, socklen_t xAddressLength )
-{
-IPStackEvent_t xBindEvent;
-FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-BaseType_t xReturn = 0;
-
- ( void ) xAddressLength;
-
- if( ( pxSocket == NULL ) || ( pxSocket == FREERTOS_INVALID_SOCKET ) )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- /* Once a socket is bound to a port, it can not be bound to a different
- port number */
- else if( socketSOCKET_IS_BOUND( pxSocket) != pdFALSE )
- {
- /* The socket is already bound. */
- FreeRTOS_debug_printf( ( "vSocketBind: Socket already bound to %d\n", pxSocket->usLocalPort ) );
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- /* Prepare a messages to the IP-task in order to perform the binding.
- The desired port number will be passed in usLocalPort. */
- xBindEvent.eEventType = eSocketBindEvent;
- xBindEvent.pvData = ( void * ) xSocket;
- if( pxAddress != NULL )
- {
- pxSocket->usLocalPort = FreeRTOS_ntohs( pxAddress->sin_port );
- }
- else
- {
- /* Caller wants to bind to a random port number. */
- pxSocket->usLocalPort = 0u;
- }
-
- /* portMAX_DELAY is used as a the time-out parameter, as binding *must*
- succeed before the socket can be used. _RB_ The use of an infinite
- block time needs be changed as it could result in the task hanging. */
- if( xSendEventStructToIPTask( &xBindEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
- {
- /* Failed to wake-up the IP-task, no use to wait for it */
- FreeRTOS_debug_printf( ( "FreeRTOS_bind: send event failed\n" ) );
- xReturn = -pdFREERTOS_ERRNO_ECANCELED;
- }
- else
- {
- /* The IP-task will set the 'eSOCKET_BOUND' bit when it has done its
- job. */
- xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_BOUND, pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, portMAX_DELAY );
- if( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- }
- }
-
- return xReturn;
-}
-
-/*
- * vSocketBind(): internal version of bind() that should not be called directly.
- * 'xInternal' is used for TCP sockets only: it allows to have several
- * (connected) child sockets bound to the same server port.
- */
-BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal )
-{
-BaseType_t xReturn = 0; /* In Berkeley sockets, 0 means pass for bind(). */
-List_t *pxSocketList;
-#if( ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 )
- struct freertos_sockaddr xAddress;
-#endif /* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND */
-
-#if( ipconfigUSE_TCP == 1 )
- if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- pxSocketList = &xBoundTCPSocketsList;
- }
- else
-#endif /* ipconfigUSE_TCP == 1 */
- {
- pxSocketList = &xBoundUDPSocketsList;
- }
-
- /* The function prototype is designed to maintain the expected Berkeley
- sockets standard, but this implementation does not use all the parameters. */
- ( void ) uxAddressLength;
-
- configASSERT( pxSocket );
- configASSERT( pxSocket != FREERTOS_INVALID_SOCKET );
-
- #if( ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 )
- {
- /* pxAddress will be NULL if sendto() was called on a socket without the
- socket being bound to an address. In this case, automatically allocate
- an address and port to the socket. */
- if( pxAddress == NULL )
- {
- pxAddress = &xAddress;
- /* Put the port to zero to be assigned later. */
- pxAddress->sin_port = 0u;
- }
- }
- #endif /* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 */
-
- /* Sockets must be bound before calling FreeRTOS_sendto() if
- ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is not set to 1. */
- configASSERT( pxAddress );
-
- if( pxAddress != NULL )
- {
- if( pxAddress->sin_port == 0u )
- {
- pxAddress->sin_port = prvGetPrivatePortNumber( ( BaseType_t )pxSocket->ucProtocol );
- if( 0 == pxAddress->sin_port )
- {
- return -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
- }
- }
-
- /* If vSocketBind() is called from the API FreeRTOS_bind() it has been
- confirmed that the socket was not yet bound to a port. If it is called
- from the IP-task, no such check is necessary. */
-
- /* Check to ensure the port is not already in use. If the bind is
- called internally, a port MAY be used by more than one socket. */
- if( ( ( xInternal == pdFALSE ) || ( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP ) ) &&
- ( pxListFindListItemWithValue( pxSocketList, ( TickType_t ) pxAddress->sin_port ) != NULL ) )
- {
- FreeRTOS_debug_printf( ( "vSocketBind: %sP port %d in use\n",
- pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP ? "TC" : "UD",
- FreeRTOS_ntohs( pxAddress->sin_port ) ) );
- xReturn = -pdFREERTOS_ERRNO_EADDRINUSE;
- }
- else
- {
- /* Allocate the port number to the socket.
- This macro will set 'xBoundSocketListItem->xItemValue' */
- socketSET_SOCKET_PORT( pxSocket, pxAddress->sin_port );
-
- /* And also store it in a socket field 'usLocalPort' in host-byte-order,
- mostly used for logging and debugging purposes */
- pxSocket->usLocalPort = FreeRTOS_ntohs( pxAddress->sin_port );
-
- /* Add the socket to the list of bound ports. */
- {
- /* If the network driver can iterate through 'xBoundUDPSocketsList',
- by calling xPortHasUDPSocket() then the IP-task must temporarily
- suspend the scheduler to keep the list in a consistent state. */
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
- {
- vTaskSuspendAll();
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
-
- /* Add the socket to 'xBoundUDPSocketsList' or 'xBoundTCPSocketsList' */
- vListInsertEnd( pxSocketList, &( pxSocket->xBoundSocketListItem ) );
-
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
- {
- xTaskResumeAll();
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
- }
- }
- }
- else
- {
- xReturn = -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
- FreeRTOS_debug_printf( ( "vSocketBind: Socket no addr\n" ) );
- }
-
- if( xReturn != 0 )
- {
- iptraceBIND_FAILED( xSocket, ( FreeRTOS_ntohs( pxAddress->sin_port ) ) );
- }
-
- return xReturn;
-} /* Tested */
-/*-----------------------------------------------------------*/
-
-/*
- * Close a socket and free the allocated space
- * In case of a TCP socket: the connection will not be closed automatically
- * Subsequent messages for the closed socket will be responded to with a RST
- * The IP-task will actually close the socket, after receiving a 'eSocketCloseEvent' message
- */
-BaseType_t FreeRTOS_closesocket( Socket_t xSocket )
-{
-BaseType_t xResult;
-#if( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_CALLBACKS == 1 )
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
-#endif
-IPStackEvent_t xCloseEvent;
-xCloseEvent.eEventType = eSocketCloseEvent;
-xCloseEvent.pvData = ( void * ) xSocket;
-
- if( ( xSocket == NULL ) || ( xSocket == FREERTOS_INVALID_SOCKET ) )
- {
- xResult = 0;
- }
- else
- {
- #if( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_CALLBACKS == 1 ) )
- {
- if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- /* Make sure that IP-task won't call the user callback's anymore */
- pxSocket->u.xTCP.pxHandleConnected = NULL;
- pxSocket->u.xTCP.pxHandleReceive = NULL;
- pxSocket->u.xTCP.pxHandleSent = NULL;
- }
- }
- #endif /* ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_CALLBACKS == 1 ) ) */
-
- /* Let the IP task close the socket to keep it synchronised with the
- packet handling. */
-
- /* Note when changing the time-out value below, it must be checked who is calling
- this function. If it is called by the IP-task, a deadlock could occur.
- The IP-task would only call it in case of a user call-back */
- if( xSendEventStructToIPTask( &xCloseEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- FreeRTOS_debug_printf( ( "FreeRTOS_closesocket: failed\n" ) );
- xResult = -1;
- }
- else
- {
- xResult = 1;
- }
- }
-
- return xResult;
-}
-
-/* This is the internal version of FreeRTOS_closesocket()
- * It will be called by the IPtask only to avoid problems with synchronicity
- */
-void *vSocketClose( FreeRTOS_Socket_t *pxSocket )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-
- #if( ipconfigUSE_TCP == 1 )
- {
- /* For TCP: clean up a little more. */
- if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- if( pxSocket->u.xTCP.pxAckMessage != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
- }
- /* Free the resources which were claimed by the tcpWin member */
- vTCPWindowDestroy( &pxSocket->u.xTCP.xTCPWindow );
- }
- #endif /* ipconfigUSE_TCP_WIN */
-
- /* Free the input and output streams */
- if( pxSocket->u.xTCP.rxStream != NULL )
- {
- vPortFreeLarge( pxSocket->u.xTCP.rxStream );
- }
-
- if( pxSocket->u.xTCP.txStream != NULL )
- {
- vPortFreeLarge( pxSocket->u.xTCP.txStream );
- }
-
- /* In case this is a child socket, make sure the child-count of the
- parent socket is decreased. */
- prvTCPSetSocketCount( pxSocket );
- }
- }
- #endif /* ipconfigUSE_TCP == 1 */
-
- /* Socket must be unbound first, to ensure no more packets are queued on
- it. */
- if( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE )
- {
- /* If the network driver can iterate through 'xBoundUDPSocketsList',
- by calling xPortHasUDPSocket(), then the IP-task must temporarily
- suspend the scheduler to keep the list in a consistent state. */
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
- {
- vTaskSuspendAll();
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
-
- uxListRemove( &( pxSocket->xBoundSocketListItem ) );
-
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
- {
- xTaskResumeAll();
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
- }
-
- /* Now the socket is not bound the list of waiting packets can be
- drained. */
- if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_UDP )
- {
- while( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) > 0U )
- {
- pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
- uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- }
-
- if( pxSocket->xEventGroup )
- {
- vEventGroupDelete( pxSocket->xEventGroup );
- }
-
- #if( ipconfigUSE_TCP == 1 ) && ( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- FreeRTOS_debug_printf( ( "FreeRTOS_closesocket[%u to %lxip:%u]: buffers %lu socks %lu\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort,
- uxGetNumberOfFreeNetworkBuffers(),
- listCURRENT_LIST_LENGTH( &xBoundTCPSocketsList ) ) );
- }
- }
- #endif /* ( ipconfigUSE_TCP == 1 ) && ( ipconfigHAS_DEBUG_PRINTF != 0 ) */
-
- /* Anf finally, after all resources have been freed, free the socket space */
- vPortFreeSocket( pxSocket );
-
- return 0;
-} /* Tested */
-
-/*-----------------------------------------------------------*/
-
-#if ipconfigUSE_TCP == 1
-
- /*
- * When a child socket gets closed, make sure to update the child-count of the
- * parent. When a listening parent socket is closed, make sure no child-sockets
- * keep a pointer to it.
- */
- static void prvTCPSetSocketCount( FreeRTOS_Socket_t *pxSocketToDelete )
- {
- const ListItem_t *pxIterator;
- const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
- FreeRTOS_Socket_t *pxOtherSocket;
- uint16_t usLocalPort = pxSocketToDelete->usLocalPort;
-
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( const ListItem_t * ) pxEnd;
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- pxOtherSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
- if( ( pxOtherSocket->u.xTCP.ucTCPState == eTCP_LISTEN ) &&
- ( pxOtherSocket->usLocalPort == usLocalPort ) &&
- ( pxOtherSocket->u.xTCP.usChildCount ) )
- {
- pxOtherSocket->u.xTCP.usChildCount--;
- FreeRTOS_debug_printf( ( "Lost: Socket %u now has %u / %u child%s\n",
- pxOtherSocket->usLocalPort,
- pxOtherSocket->u.xTCP.usChildCount,
- pxOtherSocket->u.xTCP.usBacklog,
- pxOtherSocket->u.xTCP.usChildCount == 1u ? "" : "ren" ) );
- break;
- }
- }
- }
-
-#endif /* ipconfigUSE_TCP == 1 */
-
-/*-----------------------------------------------------------*/
-
-BaseType_t FreeRTOS_setsockopt( Socket_t xSocket, int32_t lLevel, int32_t lOptionName, const void *pvOptionValue, size_t xOptionLength )
-{
-/* The standard Berkeley function returns 0 for success. */
-BaseType_t xReturn = -pdFREERTOS_ERRNO_EINVAL;
-BaseType_t lOptionValue;
-FreeRTOS_Socket_t *pxSocket;
-
- pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-
- /* The function prototype is designed to maintain the expected Berkeley
- sockets standard, but this implementation does not use all the parameters. */
- ( void ) lLevel;
- ( void ) xOptionLength;
-
- configASSERT( xSocket );
-
- switch( lOptionName )
- {
- case FREERTOS_SO_RCVTIMEO :
- /* Receive time out. */
- pxSocket->xReceiveBlockTime = *( ( TickType_t * ) pvOptionValue );
- xReturn = 0;
- break;
-
- case FREERTOS_SO_SNDTIMEO :
- pxSocket->xSendBlockTime = *( ( TickType_t * ) pvOptionValue );
- if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_UDP )
- {
- /* The send time out is capped for the reason stated in the
- comments where ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS is defined
- in FreeRTOSIPConfig.h (assuming an official configuration file
- is being used. */
- if( pxSocket->xSendBlockTime > ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS )
- {
- pxSocket->xSendBlockTime = ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS;
- }
- }
- else
- {
- /* For TCP socket, it isn't necessary to limit the blocking time
- because the FreeRTOS_send() function does not wait for a network
- buffer to become available. */
- }
- xReturn = 0;
- break;
- #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
- case FREERTOS_SO_UDP_MAX_RX_PACKETS:
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_UDP )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
- pxSocket->u.xUDP.uxMaxPackets = *( ( UBaseType_t * ) pvOptionValue );
- xReturn = 0;
- break;
- #endif /* ipconfigUDP_MAX_RX_PACKETS */
-
- case FREERTOS_SO_UDPCKSUM_OUT :
- /* Turn calculating of the UDP checksum on/off for this socket. */
- lOptionValue = ( BaseType_t ) pvOptionValue;
-
- if( lOptionValue == 0 )
- {
- pxSocket->ucSocketOptions &= ( uint8_t ) ~FREERTOS_SO_UDPCKSUM_OUT;
- }
- else
- {
- pxSocket->ucSocketOptions |= ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT;
- }
- xReturn = 0;
- break;
-
- #if( ipconfigUSE_CALLBACKS == 1 )
- #if( ipconfigUSE_TCP == 1 )
- case FREERTOS_SO_TCP_CONN_HANDLER: /* Set a callback for (dis)connection events */
- case FREERTOS_SO_TCP_RECV_HANDLER: /* Install a callback for receiving TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- case FREERTOS_SO_TCP_SENT_HANDLER: /* Install a callback for sending TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- #endif /* ipconfigUSE_TCP */
- case FREERTOS_SO_UDP_RECV_HANDLER: /* Install a callback for receiving UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- case FREERTOS_SO_UDP_SENT_HANDLER: /* Install a callback for sending UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- {
- #if( ipconfigUSE_TCP == 1 )
- {
- UBaseType_t uxProtocol;
- if( ( lOptionName == FREERTOS_SO_UDP_RECV_HANDLER ) ||
- ( lOptionName == FREERTOS_SO_UDP_SENT_HANDLER ) )
- {
- uxProtocol = ( UBaseType_t ) FREERTOS_IPPROTO_UDP;
- }
- else
- {
- uxProtocol = ( UBaseType_t ) FREERTOS_IPPROTO_TCP;
- }
-
- if( pxSocket->ucProtocol != ( uint8_t ) uxProtocol )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
- }
- #else
- {
- /* No need to check if the socket has the right
- protocol, because only UDP socket can be created. */
- }
- #endif /* ipconfigUSE_TCP */
-
- switch( lOptionName )
- {
- #if ipconfigUSE_TCP == 1
- case FREERTOS_SO_TCP_CONN_HANDLER:
- pxSocket->u.xTCP.pxHandleConnected = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnTCPConnected;
- break;
- case FREERTOS_SO_TCP_RECV_HANDLER:
- pxSocket->u.xTCP.pxHandleReceive = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnTCPReceive;
- break;
- case FREERTOS_SO_TCP_SENT_HANDLER:
- pxSocket->u.xTCP.pxHandleSent = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnTCPSent;
- break;
- #endif /* ipconfigUSE_TCP */
- case FREERTOS_SO_UDP_RECV_HANDLER:
- pxSocket->u.xUDP.pxHandleReceive = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnUDPReceive;
- break;
- case FREERTOS_SO_UDP_SENT_HANDLER:
- pxSocket->u.xUDP.pxHandleSent = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnUDPSent;
- break;
- default:
- break;
- }
- }
-
- xReturn = 0;
- break;
- #endif /* ipconfigUSE_CALLBACKS */
-
- #if( ipconfigUSE_TCP != 0 )
- #if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
- /* Each socket has a semaphore on which the using task normally
- sleeps. */
- case FREERTOS_SO_SET_SEMAPHORE:
- {
- pxSocket->pxUserSemaphore = *( ( SemaphoreHandle_t * ) pvOptionValue );
- xReturn = 0;
- }
- break;
- #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
-
- #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK != 0 )
- case FREERTOS_SO_WAKEUP_CALLBACK:
- {
- /* Each socket can have a callback function that is executed
- when there is an event the socket's owner might want to
- process. */
- pxSocket->pxUserWakeCallback = ( SocketWakeupCallback_t ) pvOptionValue;
- xReturn = 0;
- }
- break;
- #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
-
- case FREERTOS_SO_SET_LOW_HIGH_WATER:
- {
- LowHighWater_t *pxLowHighWater = ( LowHighWater_t * ) pvOptionValue;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- /* It is not allowed to access 'pxSocket->u.xTCP'. */
- FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: wrong socket type\n" ) );
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
- if( ( pxLowHighWater->uxLittleSpace >= pxLowHighWater->uxEnoughSpace ) ||
- ( pxLowHighWater->uxEnoughSpace > pxSocket->u.xTCP.uxRxStreamSize ) )
- {
- /* Impossible values. */
- FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: bad values\n" ) );
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
- /* Send a STOP when buffer space drops below 'uxLittleSpace' bytes. */
- pxSocket->u.xTCP.uxLittleSpace = pxLowHighWater->uxLittleSpace;
- /* Send a GO when buffer space grows above 'uxEnoughSpace' bytes. */
- pxSocket->u.xTCP.uxEnoughSpace = pxLowHighWater->uxEnoughSpace;
- xReturn = 0;
- }
- break;
-
- case FREERTOS_SO_SNDBUF: /* Set the size of the send buffer, in units of MSS (TCP only) */
- case FREERTOS_SO_RCVBUF: /* Set the size of the receive buffer, in units of MSS (TCP only) */
- {
- uint32_t ulNewValue;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- FreeRTOS_debug_printf( ( "Set SO_%sBUF: wrong socket type\n",
- ( lOptionName == FREERTOS_SO_SNDBUF ) ? "SND" : "RCV" ) );
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- if( ( ( lOptionName == FREERTOS_SO_SNDBUF ) && ( pxSocket->u.xTCP.txStream != NULL ) ) ||
- ( ( lOptionName == FREERTOS_SO_RCVBUF ) && ( pxSocket->u.xTCP.rxStream != NULL ) ) )
- {
- FreeRTOS_debug_printf( ( "Set SO_%sBUF: buffer already created\n",
- ( lOptionName == FREERTOS_SO_SNDBUF ) ? "SND" : "RCV" ) );
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- ulNewValue = *( ( uint32_t * ) pvOptionValue );
-
- if( lOptionName == FREERTOS_SO_SNDBUF )
- {
- /* Round up to nearest MSS size */
- ulNewValue = FreeRTOS_round_up( ulNewValue, ( uint32_t ) pxSocket->u.xTCP.usInitMSS );
- pxSocket->u.xTCP.uxTxStreamSize = ulNewValue;
- }
- else
- {
- pxSocket->u.xTCP.uxRxStreamSize = ulNewValue;
- }
- }
- xReturn = 0;
- break;
-
- case FREERTOS_SO_WIN_PROPERTIES: /* Set all buffer and window properties in one call, parameter is pointer to WinProperties_t */
- {
- WinProperties_t* pxProps;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- FreeRTOS_debug_printf( ( "Set SO_WIN_PROP: wrong socket type\n" ) );
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- if( ( pxSocket->u.xTCP.txStream != NULL ) || ( pxSocket->u.xTCP.rxStream != NULL ) )
- {
- FreeRTOS_debug_printf( ( "Set SO_WIN_PROP: buffer already created\n" ) );
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- pxProps = ( ( WinProperties_t * ) pvOptionValue );
-
- if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) ) != 0 )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) ) != 0 )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- pxSocket->u.xTCP.uxRxWinSize = ( uint32_t )pxProps->lRxWinSize; /* Fixed value: size of the TCP reception window */
- pxSocket->u.xTCP.uxTxWinSize = ( uint32_t )pxProps->lTxWinSize; /* Fixed value: size of the TCP transmit window */
- }
- #else
- {
- pxSocket->u.xTCP.uxRxWinSize = 1u;
- pxSocket->u.xTCP.uxTxWinSize = 1u;
- }
- #endif
-
- /* In case the socket has already initialised its tcpWin,
- adapt the window size parameters */
- if( pxSocket->u.xTCP.xTCPWindow.u.bits.bHasInit != pdFALSE_UNSIGNED )
- {
- pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength = pxSocket->u.xTCP.uxRxWinSize * pxSocket->u.xTCP.usInitMSS;
- pxSocket->u.xTCP.xTCPWindow.xSize.ulTxWindowLength = pxSocket->u.xTCP.uxTxWinSize * pxSocket->u.xTCP.usInitMSS;
- }
- }
-
- xReturn = 0;
- break;
-
- case FREERTOS_SO_REUSE_LISTEN_SOCKET: /* If true, the server-socket will turn into a connected socket */
- {
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
- if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
- {
- pxSocket->u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED;
- }
- else
- {
- pxSocket->u.xTCP.bits.bReuseSocket = pdFALSE_UNSIGNED;
- }
- }
- xReturn = 0;
- break;
-
- case FREERTOS_SO_CLOSE_AFTER_SEND: /* As soon as the last byte has been transmitted, finalise the connection */
- {
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
- {
- pxSocket->u.xTCP.bits.bCloseAfterSend = pdTRUE_UNSIGNED;
- }
- else
- {
- pxSocket->u.xTCP.bits.bCloseAfterSend = pdFALSE_UNSIGNED;
- }
- }
- xReturn = 0;
- break;
-
- case FREERTOS_SO_SET_FULL_SIZE: /* Refuse to send packets smaller than MSS */
- {
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
- {
- pxSocket->u.xTCP.xTCPWindow.u.bits.bSendFullSize = pdTRUE_UNSIGNED;
- }
- else
- {
- pxSocket->u.xTCP.xTCPWindow.u.bits.bSendFullSize = pdFALSE_UNSIGNED;
- }
-
- if( ( pxSocket->u.xTCP.xTCPWindow.u.bits.bSendFullSize == pdFALSE_UNSIGNED ) &&
- ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) &&
- ( FreeRTOS_outstanding( pxSocket ) != 0 ) )
- {
- pxSocket->u.xTCP.usTimeout = 1u; /* to set/clear bSendFullSize */
- xSendEventToIPTask( eTCPTimerEvent );
- }
- }
- xReturn = 0;
- break;
-
- case FREERTOS_SO_STOP_RX: /* Refuse to receive more packts */
- {
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- break; /* will return -pdFREERTOS_ERRNO_EINVAL */
- }
-
- if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
- {
- pxSocket->u.xTCP.bits.bRxStopped = pdTRUE_UNSIGNED;
- }
- else
- {
- pxSocket->u.xTCP.bits.bRxStopped = pdFALSE_UNSIGNED;
- }
-
- pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
- pxSocket->u.xTCP.usTimeout = 1u; /* to set/clear bRxStopped */
- xSendEventToIPTask( eTCPTimerEvent );
- }
- xReturn = 0;
- break;
-
- #endif /* ipconfigUSE_TCP == 1 */
-
- default :
- /* No other options are handled. */
- xReturn = -pdFREERTOS_ERRNO_ENOPROTOOPT;
- break;
- }
-
- return xReturn;
-} /* Tested */
-
-/*-----------------------------------------------------------*/
-
-/* Find an available port number per https://tools.ietf.org/html/rfc6056. */
-static uint16_t prvGetPrivatePortNumber( BaseType_t xProtocol )
-{
-const uint16_t usEphemeralPortCount =
- socketAUTO_PORT_ALLOCATION_MAX_NUMBER - socketAUTO_PORT_ALLOCATION_START_NUMBER + 1;
-uint16_t usIterations = usEphemeralPortCount;
-uint32_t ulRandomSeed = 0;
-uint16_t usResult = 0;
-const List_t *pxList;
-
-#if ipconfigUSE_TCP == 1
- if( xProtocol == ( BaseType_t ) FREERTOS_IPPROTO_TCP )
- {
- pxList = &xBoundTCPSocketsList;
- }
- else
-#endif
- {
- pxList = &xBoundUDPSocketsList;
- }
-
- /* Avoid compiler warnings if ipconfigUSE_TCP is not defined. */
- ( void ) xProtocol;
-
- /* Find the next available port using the random seed as a starting
- point. */
- do
- {
- /* Only proceed if the random number generator succeeded. */
- if( xApplicationGetRandomNumber( &( ulRandomSeed ) ) == pdFALSE )
- {
- break;
- }
-
- /* Map the random to a candidate port. */
- usResult =
- socketAUTO_PORT_ALLOCATION_START_NUMBER +
- ( ( ( uint16_t )ulRandomSeed ) % usEphemeralPortCount );
-
- /* Check if there's already an open socket with the same protocol
- and port. */
- if( NULL == pxListFindListItemWithValue(
- pxList,
- ( TickType_t )FreeRTOS_htons( usResult ) ) )
- {
- usResult = FreeRTOS_htons( usResult );
- break;
- }
- else
- {
- usResult = 0;
- }
-
- usIterations--;
- }
- while( usIterations > 0 );
-
- return usResult;
-}
-/*-----------------------------------------------------------*/
-
-/* pxListFindListItemWithValue: find a list item in a bound socket list
-'xWantedItemValue' refers to a port number */
-static const ListItem_t * pxListFindListItemWithValue( const List_t *pxList, TickType_t xWantedItemValue )
-{
-const ListItem_t * pxResult = NULL;
-
- if( ( xIPIsNetworkTaskReady() != pdFALSE ) && ( pxList != NULL ) )
- {
- const ListItem_t *pxIterator;
- const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( pxList );
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( const ListItem_t * ) pxEnd;
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- if( listGET_LIST_ITEM_VALUE( pxIterator ) == xWantedItemValue )
- {
- pxResult = pxIterator;
- break;
- }
- }
- }
-
- return pxResult;
-} /* Tested */
-
-/*-----------------------------------------------------------*/
-
-FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort )
-{
-const ListItem_t *pxListItem;
-FreeRTOS_Socket_t *pxSocket = NULL;
-
- /* Looking up a socket is quite simple, find a match with the local port.
-
- See if there is a list item associated with the port number on the
- list of bound sockets. */
- pxListItem = pxListFindListItemWithValue( &xBoundUDPSocketsList, ( TickType_t ) uxLocalPort );
-
- if( pxListItem != NULL )
- {
- /* The owner of the list item is the socket itself. */
- pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxListItem );
- configASSERT( pxSocket != NULL );
- }
- return pxSocket;
-}
-
-/*-----------------------------------------------------------*/
-
-#if ipconfigINCLUDE_FULL_INET_ADDR == 1
-
- uint32_t FreeRTOS_inet_addr( const char * pcIPAddress )
- {
- const uint32_t ulDecimalBase = 10u;
- uint8_t ucOctet[ socketMAX_IP_ADDRESS_OCTETS ];
- const char *pcPointerOnEntering;
- uint32_t ulReturn = 0UL, ulValue;
- UBaseType_t uxOctetNumber;
- BaseType_t xResult = pdPASS;
-
- for( uxOctetNumber = 0u; uxOctetNumber < socketMAX_IP_ADDRESS_OCTETS; uxOctetNumber++ )
- {
- ulValue = 0ul;
- pcPointerOnEntering = pcIPAddress;
-
- while( ( *pcIPAddress >= '0' ) && ( *pcIPAddress <= '9' ) )
- {
- /* Move previous read characters into the next decimal
- position. */
- ulValue *= ulDecimalBase;
-
- /* Add the binary value of the ascii character. */
- ulValue += ( ( uint32_t ) ( *pcIPAddress ) - ( uint32_t ) '0' );
-
- /* Move to next character in the string. */
- pcIPAddress++;
- }
-
- /* Check characters were read. */
- if( pcIPAddress == pcPointerOnEntering )
- {
- xResult = pdFAIL;
- }
-
- /* Check the value fits in an 8-bit number. */
- if( ulValue > 0xffUL )
- {
- xResult = pdFAIL;
- }
- else
- {
- ucOctet[ uxOctetNumber ] = ( uint8_t ) ulValue;
-
- /* Check the next character is as expected. */
- if( uxOctetNumber < ( socketMAX_IP_ADDRESS_OCTETS - 1u ) )
- {
- if( *pcIPAddress != '.' )
- {
- xResult = pdFAIL;
- }
- else
- {
- /* Move past the dot. */
- pcIPAddress++;
- }
- }
- }
-
- if( xResult == pdFAIL )
- {
- /* No point going on. */
- break;
- }
- }
-
- if( *pcIPAddress != ( char ) 0 )
- {
- /* Expected the end of the string. */
- xResult = pdFAIL;
- }
-
- if( uxOctetNumber != socketMAX_IP_ADDRESS_OCTETS )
- {
- /* Didn't read enough octets. */
- xResult = pdFAIL;
- }
-
- if( xResult == pdPASS )
- {
- ulReturn = FreeRTOS_inet_addr_quick( ucOctet[ 0 ], ucOctet[ 1 ], ucOctet[ 2 ], ucOctet[ 3 ] );
- }
-
- return ulReturn;
- }
-
-#endif /* ipconfigINCLUDE_FULL_INET_ADDR */
-
-/*-----------------------------------------------------------*/
-
-/* Function to get the local address and IP port */
-size_t FreeRTOS_GetLocalAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress )
-{
-FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-
- /* IP address of local machine. */
- pxAddress->sin_addr = *ipLOCAL_IP_ADDRESS_POINTER;
-
- /* Local port on this machine. */
- pxAddress->sin_port = FreeRTOS_htons( pxSocket->usLocalPort );
-
- return sizeof( *pxAddress );
-}
-
-/*-----------------------------------------------------------*/
-
-void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
-{
-/* _HT_ must work this out, now vSocketWakeUpUser will be called for any important
- * event or transition */
- #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
- {
- if( pxSocket->pxUserSemaphore != NULL )
- {
- xSemaphoreGive( pxSocket->pxUserSemaphore );
- }
- }
- #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
-
- #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
- {
- if( pxSocket->pxUserWakeCallback != NULL )
- {
- pxSocket->pxUserWakeCallback( pxSocket );
- }
- }
- #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- if( pxSocket->pxSocketSet != NULL )
- {
- EventBits_t xSelectBits = ( pxSocket->xEventBits >> SOCKET_EVENT_BIT_COUNT ) & eSELECT_ALL;
- if( xSelectBits != 0ul )
- {
- pxSocket->xSocketBits |= xSelectBits;
- xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, xSelectBits );
- }
- }
-
- pxSocket->xEventBits &= eSOCKET_ALL;
- }
- #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
-
- if( ( pxSocket->xEventGroup != NULL ) && ( pxSocket->xEventBits != 0u ) )
- {
- xEventGroupSetBits( pxSocket->xEventGroup, pxSocket->xEventBits );
- }
-
- pxSocket->xEventBits = 0ul;
-}
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
-
- /* This define makes it possible for network-card drivers to inspect
- * UDP message and see if there is any UDP socket bound to a given port
- * number.
- * This is probably only usefull in systems with a minimum of RAM and
- * when lots of anonymous broadcast messages come in
- */
- BaseType_t xPortHasUDPSocket( uint16_t usPortNr )
- {
- BaseType_t xFound = pdFALSE;
-
- vTaskSuspendAll();
- {
- if( ( pxListFindListItemWithValue( &xBoundUDPSocketsList, ( TickType_t ) usPortNr ) != NULL ) )
- {
- xFound = pdTRUE;
- }
- }
- xTaskResumeAll();
-
- return xFound;
- }
-
-#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- static BaseType_t bMayConnect( FreeRTOS_Socket_t *pxSocket );
- static BaseType_t bMayConnect( FreeRTOS_Socket_t *pxSocket )
- {
- switch( pxSocket->u.xTCP.ucTCPState )
- {
- case eCLOSED:
- case eCLOSE_WAIT: return 0;
- case eCONNECT_SYN: return -pdFREERTOS_ERRNO_EINPROGRESS;
- default: return -pdFREERTOS_ERRNO_EAGAIN;
- }
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- static BaseType_t prvTCPConnectStart( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr *pxAddress )
- {
- BaseType_t xResult = 0;
-
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdFALSE )
- {
- /* Not a valid socket or wrong type */
- xResult = -pdFREERTOS_ERRNO_EBADF;
- }
- else if( FreeRTOS_issocketconnected( pxSocket ) > 0 )
- {
- /* The socket is already connected. */
- xResult = -pdFREERTOS_ERRNO_EISCONN;
- }
- else if( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE )
- {
- /* Bind the socket to the port that the client task will send from.
- Non-standard, so the error returned is that returned by bind(). */
- xResult = FreeRTOS_bind( ( Socket_t ) pxSocket, NULL, 0u );
- }
-
- if( xResult == 0 )
- {
- /* Check if it makes any sense to wait for a connect event, this condition
- might change while sleeping, so it must be checked within each loop */
- xResult = bMayConnect( pxSocket ); /* -EINPROGRESS, -EAGAIN, or 0 for OK */
-
- /* Start the connect procedure, kernel will start working on it */
- if( xResult == 0 )
- {
- pxSocket->u.xTCP.bits.bConnPrepared = pdFALSE_UNSIGNED;
- pxSocket->u.xTCP.ucRepCount = 0u;
-
- FreeRTOS_debug_printf( ( "FreeRTOS_connect: %u to %lxip:%u\n",
- pxSocket->usLocalPort, FreeRTOS_ntohl( pxAddress->sin_addr ), FreeRTOS_ntohs( pxAddress->sin_port ) ) );
-
- /* Port on remote machine. */
- pxSocket->u.xTCP.usRemotePort = FreeRTOS_ntohs( pxAddress->sin_port );
-
- /* IP address of remote machine. */
- pxSocket->u.xTCP.ulRemoteIP = FreeRTOS_ntohl( pxAddress->sin_addr );
-
- /* (client) internal state: socket wants to send a connect. */
- vTCPStateChange( pxSocket, eCONNECT_SYN );
-
- /* To start an active connect. */
- pxSocket->u.xTCP.usTimeout = 1u;
-
- if( xSendEventToIPTask( eTCPTimerEvent ) != pdPASS )
- {
- xResult = -pdFREERTOS_ERRNO_ECANCELED;
- }
- }
- }
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * FreeRTOS_connect: socket wants to connect to a remote port
- */
- BaseType_t FreeRTOS_connect( Socket_t xClientSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t* ) xClientSocket;
- TickType_t xRemainingTime;
- BaseType_t xTimed = pdFALSE;
- BaseType_t xResult;
- TimeOut_t xTimeOut;
-
- ( void ) xAddressLength;
-
- xResult = prvTCPConnectStart( pxSocket, pxAddress );
-
- if( xResult == 0 )
- {
- /* And wait for the result */
- for( ;; )
- {
- if( xTimed == pdFALSE )
- {
- /* Only in the first round, check for non-blocking */
- xRemainingTime = pxSocket->xReceiveBlockTime;
- if( xRemainingTime == ( TickType_t )0 )
- {
- /* Not yet connected, correct state, non-blocking. */
- xResult = -pdFREERTOS_ERRNO_EWOULDBLOCK;
- break;
- }
-
- /* Don't get here a second time. */
- xTimed = pdTRUE;
-
- /* Fetch the current time */
- vTaskSetTimeOutState( &xTimeOut );
- }
-
- /* Did it get connected while sleeping ? */
- xResult = FreeRTOS_issocketconnected( pxSocket );
-
- /* Returns positive when connected, negative means an error */
- if( xResult < 0 )
- {
- /* Return the error */
- break;
- }
-
- if( xResult > 0 )
- {
- /* Socket now connected, return a zero */
- xResult = 0;
- break;
- }
-
- /* Is it allowed to sleep more? */
- if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) )
- {
- xResult = -pdFREERTOS_ERRNO_ETIMEDOUT;
- break;
- }
-
- /* Go sleeping until we get any down-stream event */
- xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_CONNECT, pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
- }
- }
-
- return xResult;
- }
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * FreeRTOS_accept: can return a new connected socket
- * if the server socket is in listen mode and receives a connection request
- * The new socket will be bound already to the same port number as the listing
- * socket.
- */
- Socket_t FreeRTOS_accept( Socket_t xServerSocket, struct freertos_sockaddr *pxAddress, socklen_t *pxAddressLength )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xServerSocket;
- FreeRTOS_Socket_t *pxClientSocket = NULL;
- TickType_t xRemainingTime;
- BaseType_t xTimed = pdFALSE, xAsk = pdFALSE;
- TimeOut_t xTimeOut;
- IPStackEvent_t xAskEvent;
-
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
- {
- /* Not a valid socket or wrong type */
- pxClientSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
- }
- else if( ( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) &&
- ( pxSocket->u.xTCP.ucTCPState != eTCP_LISTEN ) )
- {
- /* Parent socket is not in listening mode */
- pxClientSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
- }
- else
- {
- /* Loop will stop with breaks. */
- for( ; ; )
- {
- /* Is there a new client? */
- vTaskSuspendAll();
- {
- if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
- {
- pxClientSocket = pxSocket->u.xTCP.pxPeerSocket;
- }
- else
- {
- pxClientSocket = pxSocket;
- }
- if( pxClientSocket != NULL )
- {
- pxSocket->u.xTCP.pxPeerSocket = NULL;
-
- /* Is it still not taken ? */
- if( pxClientSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED )
- {
- pxClientSocket->u.xTCP.bits.bPassAccept = pdFALSE_UNSIGNED;
- }
- else
- {
- pxClientSocket = NULL;
- }
- }
- }
- xTaskResumeAll();
-
- if( pxClientSocket != NULL )
- {
- if( pxAddress != NULL )
- {
- /* IP address of remote machine. */
- pxAddress->sin_addr = FreeRTOS_ntohl( pxClientSocket->u.xTCP.ulRemoteIP );
-
- /* Port on remote machine. */
- pxAddress->sin_port = FreeRTOS_ntohs( pxClientSocket->u.xTCP.usRemotePort );
- }
- if( pxAddressLength != NULL )
- {
- *pxAddressLength = sizeof( *pxAddress );
- }
-
- if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
- {
- xAsk = pdTRUE;
- }
- }
-
- if( xAsk != pdFALSE )
- {
- /* Ask to set an event in 'xEventGroup' as soon as a new
- client gets connected for this listening socket. */
- xAskEvent.eEventType = eTCPAcceptEvent;
- xAskEvent.pvData = ( void * ) pxSocket;
- xSendEventStructToIPTask( &xAskEvent, portMAX_DELAY );
- }
-
- if( pxClientSocket != NULL )
- {
- break;
- }
-
- if( xTimed == pdFALSE )
- {
- /* Only in the first round, check for non-blocking */
- xRemainingTime = pxSocket->xReceiveBlockTime;
- if( xRemainingTime == ( TickType_t ) 0 )
- {
- break;
- }
-
- /* Don't get here a second time */
- xTimed = pdTRUE;
-
- /* Fetch the current time */
- vTaskSetTimeOutState( &xTimeOut );
- }
-
- /* Has the timeout been reached? */
- if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
- {
- break;
- }
-
- /* Go sleeping until we get any down-stream event */
- xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_ACCEPT, pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
- }
- }
-
- return ( Socket_t ) pxClientSocket;
- }
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * Read incoming data from a TCP socket
- * Only after the last byte has been read, a close error might be returned
- */
- BaseType_t FreeRTOS_recv( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags )
- {
- BaseType_t xByteCount;
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- TickType_t xRemainingTime;
- BaseType_t xTimed = pdFALSE;
- TimeOut_t xTimeOut;
- EventBits_t xEventBits = ( EventBits_t ) 0;
-
- /* Check if the socket is valid, has type TCP and if it is bound to a
- port. */
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
- {
- xByteCount = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- if( pxSocket->u.xTCP.rxStream != NULL )
- {
- xByteCount = ( BaseType_t )uxStreamBufferGetSize ( pxSocket->u.xTCP.rxStream );
- }
- else
- {
- xByteCount = 0;
- }
-
- while( xByteCount == 0 )
- {
- switch( pxSocket->u.xTCP.ucTCPState )
- {
- case eCLOSED:
- case eCLOSE_WAIT: /* (server + client) waiting for a connection termination request from the local user. */
- case eCLOSING: /* (server + client) waiting for a connection termination request acknowledgement from the remote TCP. */
- if( pxSocket->u.xTCP.bits.bMallocError != pdFALSE_UNSIGNED )
- {
- /* The no-memory error has priority above the non-connected error.
- Both are fatal and will elad to closing the socket. */
- xByteCount = -pdFREERTOS_ERRNO_ENOMEM;
- }
- else
- {
- xByteCount = -pdFREERTOS_ERRNO_ENOTCONN;
- }
- /* Call continue to break out of the switch and also the while
- loop. */
- continue;
- default:
- break;
- }
-
- if( xTimed == pdFALSE )
- {
- /* Only in the first round, check for non-blocking. */
- xRemainingTime = pxSocket->xReceiveBlockTime;
-
- if( xRemainingTime == ( TickType_t ) 0 )
- {
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- /* Just check for the interrupt flag. */
- xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_INTR,
- pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, socketDONT_BLOCK );
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
- break;
- }
-
- if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
- {
- break;
- }
-
- /* Don't get here a second time. */
- xTimed = pdTRUE;
-
- /* Fetch the current time. */
- vTaskSetTimeOutState( &xTimeOut );
- }
-
- /* Has the timeout been reached? */
- if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
- {
- break;
- }
-
- /* Block until there is a down-stream event. */
- xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup,
- eSOCKET_RECEIVE | eSOCKET_CLOSED | eSOCKET_INTR,
- pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- if( ( xEventBits & eSOCKET_INTR ) != 0u )
- {
- break;
- }
- }
- #else
- {
- ( void ) xEventBits;
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
-
- if( pxSocket->u.xTCP.rxStream != NULL )
- {
- xByteCount = ( BaseType_t ) uxStreamBufferGetSize ( pxSocket->u.xTCP.rxStream );
- }
- else
- {
- xByteCount = 0;
- }
- }
-
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- if( ( xEventBits & eSOCKET_INTR ) != 0 )
- {
- if( ( xEventBits & ( eSOCKET_RECEIVE | eSOCKET_CLOSED ) ) != 0 )
- {
- /* Shouldn't have cleared other flags. */
- xEventBits &= ~eSOCKET_INTR;
- xEventGroupSetBits( pxSocket->xEventGroup, xEventBits );
- }
- xByteCount = -pdFREERTOS_ERRNO_EINTR;
- }
- else
- #endif /* ipconfigSUPPORT_SIGNALS */
- if( xByteCount > 0 )
- {
- if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
- {
- xByteCount = ( BaseType_t ) uxStreamBufferGet( pxSocket->u.xTCP.rxStream, 0ul, ( uint8_t * ) pvBuffer, ( size_t ) xBufferLength, ( xFlags & FREERTOS_MSG_PEEK ) != 0 );
- if( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED )
- {
- /* We had reached the low-water mark, now see if the flag
- can be cleared */
- size_t uxFrontSpace = uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
-
- if( uxFrontSpace >= pxSocket->u.xTCP.uxEnoughSpace )
- {
- pxSocket->u.xTCP.bits.bLowWater = pdFALSE_UNSIGNED;
- pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
- pxSocket->u.xTCP.usTimeout = 1u; /* because bLowWater is cleared. */
- xSendEventToIPTask( eTCPTimerEvent );
- }
- }
- }
- else
- {
- /* Zero-copy reception of data: pvBuffer is a pointer to a pointer. */
- xByteCount = ( BaseType_t ) uxStreamBufferGetPtr( pxSocket->u.xTCP.rxStream, (uint8_t **)pvBuffer );
- }
- }
- } /* prvValidSocket() */
-
- return xByteCount;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- static int32_t prvTCPSendCheck( FreeRTOS_Socket_t *pxSocket, size_t xDataLength )
- {
- int32_t xResult = 1;
-
- /* Is this a socket of type TCP and is it already bound to a port number ? */
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
- {
- xResult = -pdFREERTOS_ERRNO_EINVAL;
- }
- else if( pxSocket->u.xTCP.bits.bMallocError != pdFALSE_UNSIGNED )
- {
- xResult = -pdFREERTOS_ERRNO_ENOMEM;
- }
- else if( pxSocket->u.xTCP.ucTCPState == eCLOSED ||
- pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||
- pxSocket->u.xTCP.ucTCPState == eCLOSING )
- {
- xResult = -pdFREERTOS_ERRNO_ENOTCONN;
- }
- else if( pxSocket->u.xTCP.bits.bFinSent != pdFALSE_UNSIGNED )
- {
- /* This TCP connection is closing already, the FIN flag has been sent.
- Maybe it is still delivering or receiving data.
- Return OK in order not to get closed/deleted too quickly */
- xResult = 0;
- }
- else if( xDataLength == 0ul )
- {
- /* send() is being called to send zero bytes */
- xResult = 0;
- }
- else if( pxSocket->u.xTCP.txStream == NULL )
- {
- /* Create the outgoing stream only when it is needed */
- prvTCPCreateStream( pxSocket, pdFALSE );
-
- if( pxSocket->u.xTCP.txStream == NULL )
- {
- xResult = -pdFREERTOS_ERRNO_ENOMEM;
- }
- }
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* Get a direct pointer to the circular transmit buffer.
- '*pxLength' will contain the number of bytes that may be written. */
- uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength )
- {
- uint8_t *pucReturn = NULL;
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- StreamBuffer_t *pxBuffer = NULL;
-
- *pxLength = 0;
-
- /* Confirm that this is a TCP socket before dereferencing structure
- member pointers. */
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
- {
- pxBuffer = pxSocket->u.xTCP.txStream;
- if( pxBuffer != NULL )
- {
- BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );
- BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );
-
- *pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
- pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
- }
- }
-
- return pucReturn;
- }
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
- /*
- * Send data using a TCP socket. It is not necessary to have the socket
- * connected already. Outgoing data will be stored and delivered as soon as
- * the socket gets connected.
- */
- BaseType_t FreeRTOS_send( Socket_t xSocket, const void *pvBuffer, size_t uxDataLength, BaseType_t xFlags )
- {
- BaseType_t xByteCount;
- BaseType_t xBytesLeft;
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- TickType_t xRemainingTime;
- BaseType_t xTimed = pdFALSE;
- TimeOut_t xTimeOut;
- BaseType_t xCloseAfterSend;
-
- /* Prevent compiler warnings about unused parameters. The parameter
- may be used in future versions. */
- ( void ) xFlags;
-
- xByteCount = ( BaseType_t ) prvTCPSendCheck( pxSocket, uxDataLength );
-
- if( xByteCount > 0 )
- {
- /* xBytesLeft is number of bytes to send, will count to zero. */
- xBytesLeft = ( BaseType_t ) uxDataLength;
-
- /* xByteCount is number of bytes that can be sent now. */
- xByteCount = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
-
- /* While there are still bytes to be sent. */
- while( xBytesLeft > 0 )
- {
- /* If txStream has space. */
- if( xByteCount > 0 )
- {
- /* Don't send more than necessary. */
- if( xByteCount > xBytesLeft )
- {
- xByteCount = xBytesLeft;
- }
-
- /* Is the close-after-send flag set and is this really the
- last transmission? */
- if( ( pxSocket->u.xTCP.bits.bCloseAfterSend != pdFALSE_UNSIGNED ) && ( xByteCount == xBytesLeft ) )
- {
- xCloseAfterSend = pdTRUE;
- }
- else
- {
- xCloseAfterSend = pdFALSE;
- }
-
- /* The flag 'bCloseAfterSend' can be set before sending data
- using setsockopt()
-
- When the last data packet is being sent out, a FIN flag will
- be included to let the peer know that no more data is to be
- expected. The use of 'bCloseAfterSend' is not mandatory, it
- is just a faster way of transferring files (e.g. when using
- FTP). */
- if( xCloseAfterSend != pdFALSE )
- {
- /* Now suspend the scheduler: sending the last data and
- setting bCloseRequested must be done together */
- vTaskSuspendAll();
- pxSocket->u.xTCP.bits.bCloseRequested = pdTRUE_UNSIGNED;
- }
-
- xByteCount = ( BaseType_t ) uxStreamBufferAdd( pxSocket->u.xTCP.txStream, 0ul, ( const uint8_t * ) pvBuffer, ( size_t ) xByteCount );
-
- if( xCloseAfterSend != pdFALSE )
- {
- /* Now when the IP-task transmits the data, it will also
- see that bCloseRequested is true and include the FIN
- flag to start closure of the connection. */
- xTaskResumeAll();
- }
-
- /* Send a message to the IP-task so it can work on this
- socket. Data is sent, let the IP-task work on it. */
- pxSocket->u.xTCP.usTimeout = 1u;
-
- if( xIsCallingFromIPTask() == pdFALSE )
- {
- /* Only send a TCP timer event when not called from the
- IP-task. */
- xSendEventToIPTask( eTCPTimerEvent );
- }
-
- xBytesLeft -= xByteCount;
-
- if( xBytesLeft == 0 )
- {
- break;
- }
-
- /* As there are still bytes left to be sent, increase the
- data pointer. */
- pvBuffer = ( void * ) ( ( ( const uint8_t * ) pvBuffer) + xByteCount );
- }
-
- /* Not all bytes have been sent. In case the socket is marked as
- blocking sleep for a while. */
- if( xTimed == pdFALSE )
- {
- /* Only in the first round, check for non-blocking. */
- xRemainingTime = pxSocket->xSendBlockTime;
-
- #if( ipconfigUSE_CALLBACKS != 0 )
- {
- if( xIsCallingFromIPTask() != pdFALSE )
- {
- /* If this send function is called from within a
- call-back handler it may not block, otherwise
- chances would be big to get a deadlock: the IP-task
- waiting for itself. */
- xRemainingTime = ( TickType_t ) 0;
- }
- }
- #endif /* ipconfigUSE_CALLBACKS */
-
- if( xRemainingTime == ( TickType_t ) 0 )
- {
- break;
- }
-
- if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
- {
- break;
- }
-
- /* Don't get here a second time. */
- xTimed = pdTRUE;
-
- /* Fetch the current time. */
- vTaskSetTimeOutState( &xTimeOut );
- }
- else
- {
- /* Has the timeout been reached? */
- if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
- {
- break;
- }
- }
-
- /* Go sleeping until down-stream events are received. */
- xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED,
- pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
-
- xByteCount = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
- }
-
- /* How much was actually sent? */
- xByteCount = ( ( BaseType_t ) uxDataLength ) - xBytesLeft;
-
- if( xByteCount == 0 )
- {
- if( pxSocket->u.xTCP.ucTCPState > eESTABLISHED )
- {
- xByteCount = ( BaseType_t ) -pdFREERTOS_ERRNO_ENOTCONN;
- }
- else
- {
- if( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE )
- {
- FreeRTOS_debug_printf( ( "FreeRTOS_send: %u -> %lxip:%d: no space\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort ) );
- }
-
- xByteCount = ( BaseType_t ) -pdFREERTOS_ERRNO_ENOSPC;
- }
- }
- }
-
- return xByteCount;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * Request to put a socket in listen mode
- */
- BaseType_t FreeRTOS_listen( Socket_t xSocket, BaseType_t xBacklog )
- {
- FreeRTOS_Socket_t *pxSocket;
- BaseType_t xResult = 0;
-
- pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
-
- /* listen() is allowed for a valid TCP socket in Closed state and already
- bound. */
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
- {
- xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
- }
- else if( ( pxSocket->u.xTCP.ucTCPState != eCLOSED ) && ( pxSocket->u.xTCP.ucTCPState != eCLOSE_WAIT ) )
- {
- /* Socket is in a wrong state. */
- xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
- }
- else
- {
- /* Backlog is interpreted here as "the maximum number of child
- sockets. */
- pxSocket->u.xTCP.usBacklog = ( uint16_t )FreeRTOS_min_int32( ( int32_t ) 0xffff, ( int32_t ) xBacklog );
-
- /* This cleaning is necessary only if a listening socket is being
- reused as it might have had a previous connection. */
- if( pxSocket->u.xTCP.bits.bReuseSocket )
- {
- if( pxSocket->u.xTCP.rxStream != NULL )
- {
- vStreamBufferClear( pxSocket->u.xTCP.rxStream );
- }
-
- if( pxSocket->u.xTCP.txStream != NULL )
- {
- vStreamBufferClear( pxSocket->u.xTCP.txStream );
- }
-
- memset( pxSocket->u.xTCP.xPacket.u.ucLastPacket, '\0', sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
- memset( &pxSocket->u.xTCP.xTCPWindow, '\0', sizeof( pxSocket->u.xTCP.xTCPWindow ) );
- memset( &pxSocket->u.xTCP.bits, '\0', sizeof( pxSocket->u.xTCP.bits ) );
-
- /* Now set the bReuseSocket flag again, because the bits have
- just been cleared. */
- pxSocket->u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED;
- }
-
- vTCPStateChange( pxSocket, eTCP_LISTEN );
- }
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* shutdown - shut down part of a full-duplex connection */
- BaseType_t FreeRTOS_shutdown( Socket_t xSocket, BaseType_t xHow )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xResult;
-
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
- {
- /*_RB_ Is this comment correct? The socket is not of a type that
- supports the listen() operation. */
- xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
- }
- else if ( pxSocket->u.xTCP.ucTCPState != eESTABLISHED )
- {
- /*_RB_ Is this comment correct? The socket is not of a type that
- supports the listen() operation. */
- xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
- }
- else
- {
- pxSocket->u.xTCP.bits.bUserShutdown = pdTRUE_UNSIGNED;
-
- /* Let the IP-task perform the shutdown of the connection. */
- pxSocket->u.xTCP.usTimeout = 1u;
- xSendEventToIPTask( eTCPTimerEvent );
- xResult = 0;
- }
- (void) xHow;
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * A TCP timer has expired, now check all TCP sockets for:
- * - Active connect
- * - Send a delayed ACK
- * - Send new data
- * - Send a keep-alive packet
- * - Check for timeout (in non-connected states only)
- */
- TickType_t xTCPTimerCheck( BaseType_t xWillSleep )
- {
- FreeRTOS_Socket_t *pxSocket;
- TickType_t xShortest = pdMS_TO_TICKS( ( TickType_t ) ipTCP_TIMER_PERIOD_MS );
- TickType_t xNow = xTaskGetTickCount();
- static TickType_t xLastTime = 0u;
- TickType_t xDelta = xNow - xLastTime;
- ListItem_t* pxEnd = ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
- ListItem_t *pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
-
- xLastTime = xNow;
-
- if( xDelta == 0u )
- {
- xDelta = 1u;
- }
-
- while( pxIterator != pxEnd )
- {
- pxSocket = ( FreeRTOS_Socket_t * )listGET_LIST_ITEM_OWNER( pxIterator );
- pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator );
-
- /* Sockets with 'tmout == 0' do not need any regular attention. */
- if( pxSocket->u.xTCP.usTimeout == 0u )
- {
- continue;
- }
-
- if( xDelta < ( TickType_t ) pxSocket->u.xTCP.usTimeout )
- {
- pxSocket->u.xTCP.usTimeout = ( uint16_t ) ( ( ( TickType_t ) pxSocket->u.xTCP.usTimeout ) - xDelta );
- }
- else
- {
- int rc ;
- pxSocket->u.xTCP.usTimeout = 0u;
- rc = xTCPSocketCheck( pxSocket );
-
- /* Within this function, the socket might want to send a delayed
- ack or send out data or whatever it needs to do. */
- if( rc < 0 )
- {
- /* Continue because the socket was deleted. */
- continue;
- }
- }
-
- /* In xEventBits the driver may indicate that the socket has
- important events for the user. These are only done just before the
- IP-task goes to sleep. */
- if( pxSocket->xEventBits != 0u )
- {
- if( xWillSleep != pdFALSE )
- {
- /* The IP-task is about to go to sleep, so messages can be
- sent to the socket owners. */
- vSocketWakeUpUser( pxSocket );
- }
- else
- {
- /* Or else make sure this will be called again to wake-up
- the sockets' owner. */
- xShortest = ( TickType_t ) 0;
- }
- }
-
- if( ( pxSocket->u.xTCP.usTimeout != 0u ) && ( xShortest > ( TickType_t ) pxSocket->u.xTCP.usTimeout ) )
- {
- xShortest = ( TickType_t ) pxSocket->u.xTCP.usTimeout;
- }
- }
-
- return xShortest;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * TCP: as multiple sockets may be bound to the same local port number
- * looking up a socket is a little more complex:
- * Both a local port, and a remote port and IP address are being used
- * For a socket in listening mode, the remote port and IP address are both 0
- */
- FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort )
- {
- ListItem_t *pxIterator;
- FreeRTOS_Socket_t *pxResult = NULL, *pxListenSocket = NULL;
- MiniListItem_t *pxEnd = ( MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
-
- /* Parameter not yet supported. */
- ( void ) ulLocalIP;
-
- for( pxIterator = ( ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( ListItem_t * ) pxEnd;
- pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
-
- if( pxSocket->usLocalPort == ( uint16_t ) uxLocalPort )
- {
- if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
- {
- /* If this is a socket listening to uxLocalPort, remember it
- in case there is no perfect match. */
- pxListenSocket = pxSocket;
- }
- else if( ( pxSocket->u.xTCP.usRemotePort == ( uint16_t ) uxRemotePort ) && ( pxSocket->u.xTCP.ulRemoteIP == ulRemoteIP ) )
- {
- /* For sockets not in listening mode, find a match with
- xLocalPort, ulRemoteIP AND xRemotePort. */
- pxResult = pxSocket;
- break;
- }
- }
- }
- if( pxResult == NULL )
- {
- /* An exact match was not found, maybe a listening socket was
- found. */
- pxResult = pxListenSocket;
- }
-
- return pxResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
- struct xSTREAM_BUFFER *pxReturn = NULL;
-
- /* Confirm that this is a TCP socket before dereferencing structure
- member pointers. */
- if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
- {
- pxReturn = pxSocket->u.xTCP.rxStream;
- }
-
- return pxReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- static StreamBuffer_t *prvTCPCreateStream ( FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream )
- {
- StreamBuffer_t *pxBuffer;
- size_t uxLength;
- size_t uxSize;
-
- /* Now that a stream is created, the maximum size is fixed before
- creation, it could still be changed with setsockopt(). */
- if( xIsInputStream != pdFALSE )
- {
- uxLength = pxSocket->u.xTCP.uxRxStreamSize;
-
- if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
- {
- pxSocket->u.xTCP.uxLittleSpace = ( sock20_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
- }
-
- if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )
- {
- pxSocket->u.xTCP.uxEnoughSpace = ( sock80_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
- }
- }
- else
- {
- uxLength = pxSocket->u.xTCP.uxTxStreamSize;
- }
-
- /* Add an extra 4 (or 8) bytes. */
- uxLength += sizeof( size_t );
-
- /* And make the length a multiple of sizeof( size_t ). */
- uxLength &= ~( sizeof( size_t ) - 1u );
-
- uxSize = sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray ) + uxLength;
-
- pxBuffer = ( StreamBuffer_t * )pvPortMallocLarge( uxSize );
-
- if( pxBuffer == NULL )
- {
- FreeRTOS_debug_printf( ( "prvTCPCreateStream: malloc failed\n" ) );
- pxSocket->u.xTCP.bits.bMallocError = pdTRUE_UNSIGNED;
- vTCPStateChange( pxSocket, eCLOSE_WAIT );
- }
- else
- {
- /* Clear the markers of the stream */
- memset( pxBuffer, '\0', sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray ) );
- pxBuffer->LENGTH = ( size_t ) uxLength ;
-
- if( xTCPWindowLoggingLevel != 0 )
- {
- FreeRTOS_debug_printf( ( "prvTCPCreateStream: %cxStream created %lu bytes (total %lu)\n", xIsInputStream ? 'R' : 'T', uxLength, uxSize ) );
- }
-
- if( xIsInputStream != 0 )
- {
- pxSocket->u.xTCP.rxStream = pxBuffer;
- }
- else
- {
- pxSocket->u.xTCP.txStream = pxBuffer;
- }
- }
-
- return pxBuffer;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * Add data to the RxStream. When uxOffset > 0, data has come in out-of-order
- * and will be put in front of the head so it can not be popped by the user.
- */
- int32_t lTCPAddRxdata( FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount )
- {
- StreamBuffer_t *pxStream = pxSocket->u.xTCP.rxStream;
- int32_t xResult;
- #if( ipconfigUSE_CALLBACKS == 1 )
- BaseType_t bHasHandler = ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleReceive );
- const uint8_t *pucBuffer = NULL;
- #endif /* ipconfigUSE_CALLBACKS */
-
- /* int32_t uxStreamBufferAdd( pxBuffer, uxOffset, pucData, aCount )
- if( pucData != NULL ) copy data the the buffer
- if( pucData == NULL ) no copying, just advance rxHead
- if( uxOffset != 0 ) Just store data which has come out-of-order
- if( uxOffset == 0 ) Also advance rxHead */
- if( pxStream == NULL )
- {
- pxStream = prvTCPCreateStream( pxSocket, pdTRUE );
- if( pxStream == NULL )
- {
- return -1;
- }
- }
-
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ( bHasHandler != pdFALSE ) && ( uxStreamBufferGetSize( pxStream ) == 0u ) && ( uxOffset == 0ul ) && ( pcData != NULL ) )
- {
- /* Data can be passed directly to the user */
- pucBuffer = pcData;
-
- /* Zero-copy for call-back: no need to add the bytes to the
- stream, only the pointer will be advanced by uxStreamBufferAdd(). */
- pcData = NULL;
- }
- }
- #endif /* ipconfigUSE_CALLBACKS */
-
- xResult = ( int32_t ) uxStreamBufferAdd( pxStream, uxOffset, pcData, ( size_t ) ulByteCount );
-
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- if( xResult != ( int32_t ) ulByteCount )
- {
- FreeRTOS_debug_printf( ( "lTCPAddRxdata: at %ld: %ld/%lu bytes (tail %lu head %lu space %lu front %lu)\n",
- uxOffset, xResult, ulByteCount,
- pxStream->uxTail,
- pxStream->uxHead,
- uxStreamBufferFrontSpace( pxStream ),
- pxStream->uxFront ) );
- }
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF */
-
- if( uxOffset == 0u )
- {
- /* Data is being added to rxStream at the head (offs = 0) */
- #if( ipconfigUSE_CALLBACKS == 1 )
- if( bHasHandler != pdFALSE )
- {
- /* The socket owner has installed an OnReceive handler. Pass the
- Rx data, without copying from the rxStream, to the user. */
- for (;;)
- {
- uint8_t *ucReadPtr = NULL;
- uint32_t ulCount;
- if( pucBuffer != NULL )
- {
- ucReadPtr = ( uint8_t * )pucBuffer;
- ulCount = ulByteCount;
- pucBuffer = NULL;
- }
- else
- {
- ulCount = ( uint32_t ) uxStreamBufferGetPtr( pxStream, &( ucReadPtr ) );
- }
-
- if( ulCount == 0ul )
- {
- break;
- }
-
- pxSocket->u.xTCP.pxHandleReceive( ( Socket_t )pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );
- uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
- }
- } else
- #endif /* ipconfigUSE_CALLBACKS */
- {
- /* See if running out of space. */
- if( pxSocket->u.xTCP.bits.bLowWater == pdFALSE_UNSIGNED )
- {
- size_t uxFrontSpace = uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
- if( uxFrontSpace <= pxSocket->u.xTCP.uxLittleSpace )
- {
- pxSocket->u.xTCP.bits.bLowWater = pdTRUE_UNSIGNED;
- pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
-
- /* bLowWater was reached, send the changed window size. */
- pxSocket->u.xTCP.usTimeout = 1u;
- xSendEventToIPTask( eTCPTimerEvent );
- }
- }
-
- /* New incoming data is available, wake up the user. User's
- semaphores will be set just before the IP-task goes asleep. */
- pxSocket->xEventBits |= eSOCKET_RECEIVE;
-
- #if ipconfigSUPPORT_SELECT_FUNCTION == 1
- {
- if( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 )
- {
- pxSocket->xEventBits |= ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
- }
- }
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* Function to get the remote address and IP port */
- BaseType_t FreeRTOS_GetRemoteAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xResult;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xResult = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- /* BSD style sockets communicate IP and port addresses in network
- byte order.
-
- IP address of remote machine. */
- pxAddress->sin_addr = FreeRTOS_htonl ( pxSocket->u.xTCP.ulRemoteIP );
-
- /* Port on remote machine. */
- pxAddress->sin_port = FreeRTOS_htons ( pxSocket->u.xTCP.usRemotePort );
-
- xResult = ( BaseType_t ) sizeof( ( *pxAddress ) );
- }
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* Returns the number of bytes that may be added to txStream */
- BaseType_t FreeRTOS_maywrite( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xResult;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xResult = -pdFREERTOS_ERRNO_EINVAL;
- }
- else if( pxSocket->u.xTCP.ucTCPState != eESTABLISHED )
- {
- if( ( pxSocket->u.xTCP.ucTCPState < eCONNECT_SYN ) || ( pxSocket->u.xTCP.ucTCPState > eESTABLISHED ) )
- {
- xResult = -1;
- }
- else
- {
- xResult = 0;
- }
- }
- else if( pxSocket->u.xTCP.txStream == NULL )
- {
- xResult = ( BaseType_t ) pxSocket->u.xTCP.uxTxStreamSize;
- }
- else
- {
- xResult = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
- }
-
- return xResult;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP ==1 )
-
- BaseType_t FreeRTOS_tx_space( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- if( pxSocket->u.xTCP.txStream != NULL )
- {
- xReturn = ( BaseType_t ) uxStreamBufferGetSpace ( pxSocket->u.xTCP.txStream );
- }
- else
- {
- xReturn = ( BaseType_t ) pxSocket->u.xTCP.uxTxStreamSize;
- }
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- BaseType_t FreeRTOS_tx_size( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- if( pxSocket->u.xTCP.txStream != NULL )
- {
- xReturn = ( BaseType_t ) uxStreamBufferGetSize ( pxSocket->u.xTCP.txStream );
- }
- else
- {
- xReturn = 0;
- }
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* Returns pdTRUE if TCP socket is connected. */
- BaseType_t FreeRTOS_issocketconnected( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn = pdFALSE;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- if( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED )
- {
- if( pxSocket->u.xTCP.ucTCPState < eCLOSE_WAIT )
- {
- xReturn = pdTRUE;
- }
- }
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* returns the actual size of MSS being used */
- BaseType_t FreeRTOS_mss( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- /* usCurMSS is declared as uint16_t to save space. FreeRTOS_mss()
- will often be used in signed native-size expressions cast it to
- BaseType_t. */
- xReturn = ( BaseType_t ) ( pxSocket->u.xTCP.usCurMSS );
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /* HT: for internal use only: return the connection status */
- BaseType_t FreeRTOS_connstatus( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- {
- /* Cast it to BaseType_t */
- xReturn = ( BaseType_t ) ( pxSocket->u.xTCP.ucTCPState );
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * Returns the number of bytes which can be read.
- */
- BaseType_t FreeRTOS_rx_size( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
-
- if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else if( pxSocket->u.xTCP.rxStream != NULL )
- {
- xReturn = ( BaseType_t ) uxStreamBufferGetSize( pxSocket->u.xTCP.rxStream );
- }
- else
- {
- xReturn = 0;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP == 1 )
-
- void FreeRTOS_netstat( void )
- {
- IPStackEvent_t xAskEvent;
-
- /* Ask the IP-task to call vTCPNetStat()
- * to avoid accessing xBoundTCPSocketsList
- */
- xAskEvent.eEventType = eTCPNetStat;
- xAskEvent.pvData = ( void * ) NULL;
- xSendEventStructToIPTask( &xAskEvent, 1000u );
- }
-
-#endif /* ipconfigUSE_TCP */
-/*-----------------------------------------------------------*/
-
-#if( ( ipconfigHAS_PRINTF != 0 ) && ( ipconfigUSE_TCP == 1 ) )
-
- void vTCPNetStat( void )
- {
- /* Show a simple listing of all created sockets and their connections */
- ListItem_t *pxIterator;
- BaseType_t count = 0;
-
- if( listLIST_IS_INITIALISED( &xBoundTCPSocketsList ) == pdFALSE )
- {
- FreeRTOS_printf( ( "PLUS-TCP not initialized\n" ) );
- }
- else
- {
- FreeRTOS_printf( ( "Prot Port IP-Remote : Port R/T Status Alive tmout Child\n" ) );
- for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
- pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
- pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
- #if( ipconfigTCP_KEEP_ALIVE == 1 )
- TickType_t age = xTaskGetTickCount() - pxSocket->u.xTCP.xLastAliveTime;
- #else
- TickType_t age = 0u;
- #endif
- #if( ipconfigUSE_CALLBACKS == 1 )
- void *pxHandleReceive = (void*)pxSocket->u.xTCP.pxHandleReceive;
- #else
- void *pxHandleReceive = (void*)NULL;
- #endif
- char ucChildText[16] = "";
- if (pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN)
- {
- const int32_t copied_len = snprintf( ucChildText, sizeof( ucChildText ), " %d/%d",
- ( int ) pxSocket->u.xTCP.usChildCount,
- ( int ) pxSocket->u.xTCP.usBacklog);
- /* These should never evaluate to false since the buffers are both shorter than 5-6 characters (<=65535) */
- configASSERT( copied_len >= 0 );
- configASSERT( copied_len < sizeof( ucChildText ) );
- }
- FreeRTOS_printf( ( "TCP %5d %-16lxip:%5d %d/%d %-13.13s %6lu %6u%s\n",
- pxSocket->usLocalPort, /* Local port on this machine */
- pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine */
- pxSocket->u.xTCP.usRemotePort, /* Port on remote machine */
- pxSocket->u.xTCP.rxStream != NULL,
- pxSocket->u.xTCP.txStream != NULL,
- FreeRTOS_GetTCPStateName( pxSocket->u.xTCP.ucTCPState ),
- (age > 999999 ? 999999 : age), /* Format 'age' for printing */
- pxSocket->u.xTCP.usTimeout,
- ucChildText ) );
- /* Remove compiler warnings if FreeRTOS_debug_printf() is not defined. */
- ( void ) pxHandleReceive;
- count++;
- }
-
- for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundUDPSocketsList );
- pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundUDPSocketsList );
- pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- /* Local port on this machine */
- FreeRTOS_printf( ( "UDP Port %5u\n",
- FreeRTOS_ntohs( listGET_LIST_ITEM_VALUE( pxIterator ) ) ) );
- count++;
- }
-
- FreeRTOS_printf( ( "FreeRTOS_netstat: %lu sockets %lu < %lu < %d buffers free\n",
- count,
- uxGetMinimumFreeNetworkBuffers( ),
- uxGetNumberOfFreeNetworkBuffers( ),
- ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) );
- }
- }
-
-#endif /* ( ( ipconfigHAS_PRINTF != 0 ) && ( ipconfigUSE_TCP == 1 ) ) */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
- void vSocketSelect( SocketSelect_t *pxSocketSet )
- {
- BaseType_t xRound;
- EventBits_t xSocketBits, xBitsToClear;
- #if ipconfigUSE_TCP == 1
- BaseType_t xLastRound = 1;
- #else
- BaseType_t xLastRound = 0;
- #endif
-
- /* These flags will be switched on after checking the socket status. */
- EventBits_t xGroupBits = 0;
- pxSocketSet->pxSocket = NULL;
-
- for( xRound = 0; xRound <= xLastRound; xRound++ )
- {
- const ListItem_t *pxIterator;
- const MiniListItem_t *pxEnd;
- if( xRound == 0 )
- {
- pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundUDPSocketsList );
- }
- #if ipconfigUSE_TCP == 1
- else
- {
- pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
- }
- #endif /* ipconfigUSE_TCP == 1 */
- for( pxIterator = ( const ListItem_t * ) ( listGET_NEXT( pxEnd ) );
- pxIterator != ( const ListItem_t * ) pxEnd;
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
- if( pxSocket->pxSocketSet != pxSocketSet )
- {
- /* Socket does not belong to this select group. */
- continue;
- }
- xSocketBits = 0;
-
- #if( ipconfigUSE_TCP == 1 )
- if( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP )
- {
- /* Check if the socket has already been accepted by the
- owner. If not, it is useless to return it from a
- select(). */
- BaseType_t bAccepted = pdFALSE;
-
- if( pxSocket->u.xTCP.bits.bPassQueued == pdFALSE_UNSIGNED )
- {
- if( pxSocket->u.xTCP.bits.bPassAccept == pdFALSE_UNSIGNED )
- {
- bAccepted = pdTRUE;
- }
- }
-
- /* Is the set owner interested in READ events? */
- if( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 )
- {
- if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
- {
- if( ( pxSocket->u.xTCP.pxPeerSocket != NULL ) && ( pxSocket->u.xTCP.pxPeerSocket->u.xTCP.bits.bPassAccept != 0 ) )
- {
- xSocketBits |= eSELECT_READ;
- }
- }
- else if( ( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED ) && ( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
- {
- /* This socket has the re-use flag. After connecting it turns into
- aconnected socket. Set the READ event, so that accept() will be called. */
- xSocketBits |= eSELECT_READ;
- }
- else if( ( bAccepted != 0 ) && ( FreeRTOS_recvcount( pxSocket ) > 0 ) )
- {
- xSocketBits |= eSELECT_READ;
- }
- }
- /* Is the set owner interested in EXCEPTION events? */
- if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
- {
- if( ( pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ) || ( pxSocket->u.xTCP.ucTCPState == eCLOSED ) )
- {
- xSocketBits |= eSELECT_EXCEPT;
- }
- }
-
- /* Is the set owner interested in WRITE events? */
- if( ( pxSocket->xSelectBits & eSELECT_WRITE ) != 0 )
- {
- BaseType_t bMatch = pdFALSE;
-
- if( bAccepted != 0 )
- {
- if( FreeRTOS_tx_space( pxSocket ) > 0 )
- {
- bMatch = pdTRUE;
- }
- }
-
- if( bMatch == pdFALSE )
- {
- if( ( pxSocket->u.xTCP.bits.bConnPrepared != pdFALSE_UNSIGNED ) &&
- ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) &&
- ( pxSocket->u.xTCP.bits.bConnPassed == pdFALSE_UNSIGNED ) )
- {
- pxSocket->u.xTCP.bits.bConnPassed = pdTRUE_UNSIGNED;
- bMatch = pdTRUE;
- }
- }
-
- if( bMatch != pdFALSE )
- {
- xSocketBits |= eSELECT_WRITE;
- }
- }
- }
- else
- #endif /* ipconfigUSE_TCP == 1 */
- {
- /* Select events for UDP are simpler. */
- if( ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) &&
- ( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) > 0U ) )
- {
- xSocketBits |= eSELECT_READ;
- }
- /* The WRITE and EXCEPT bits are not used for UDP */
- } /* if( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP ) */
-
- /* Each socket keeps its own event flags, which are looked-up
- by FreeRTOS_FD_ISSSET() */
- pxSocket->xSocketBits = xSocketBits;
-
- /* The ORed value will be used to set the bits in the event
- group. */
- xGroupBits |= xSocketBits;
-
- } /* for( pxIterator ... ) */
- } /* for( xRound = 0; xRound <= xLastRound; xRound++ ) */
-
- xBitsToClear = xEventGroupGetBits( pxSocketSet->xSelectGroup );
-
- /* Now set the necessary bits. */
- xBitsToClear = ( xBitsToClear & ~xGroupBits ) & eSELECT_ALL;
-
- #if( ipconfigSUPPORT_SIGNALS != 0 )
- {
- /* Maybe the socketset was signalled, but don't
- clear the 'eSELECT_INTR' bit here, as it will be used
- and cleared in FreeRTOS_select(). */
- xBitsToClear &= ( EventBits_t ) ~eSELECT_INTR;
- }
- #endif /* ipconfigSUPPORT_SIGNALS */
-
- if( xBitsToClear != 0 )
- {
- xEventGroupClearBits( pxSocketSet->xSelectGroup, xBitsToClear );
- }
-
- /* Now include eSELECT_CALL_IP to wakeup the caller. */
- xEventGroupSetBits( pxSocketSet->xSelectGroup, xGroupBits | eSELECT_CALL_IP );
- }
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SIGNALS != 0 )
-
- /* Send a signal to the task which reads from this socket. */
- BaseType_t FreeRTOS_SignalSocket( Socket_t xSocket )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
-
- if( pxSocket == NULL )
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
- else
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- if( ( pxSocket->pxSocketSet != NULL ) && ( pxSocket->pxSocketSet->xSelectGroup != NULL ) )
- {
- xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, eSELECT_INTR );
- xReturn = 0;
- }
- else
- #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
- if( pxSocket->xEventGroup != NULL )
- {
- xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_INTR );
- xReturn = 0;
- }
- else
- {
- xReturn = -pdFREERTOS_ERRNO_EINVAL;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigSUPPORT_SIGNALS */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigSUPPORT_SIGNALS != 0 )
-
- /* Send a signal to the task which reads from this socket (FromISR version). */
- BaseType_t FreeRTOS_SignalSocketFromISR( Socket_t xSocket, BaseType_t *pxHigherPriorityTaskWoken )
- {
- FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
- BaseType_t xReturn;
- IPStackEvent_t xEvent;
- extern QueueHandle_t xNetworkEventQueue;
-
- configASSERT( pxSocket != NULL );
- configASSERT( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP );
- configASSERT( pxSocket->xEventGroup );
-
- xEvent.eEventType = eSocketSignalEvent;
- xEvent.pvData = ( void * )pxSocket;
-
- /* The IP-task will call FreeRTOS_SignalSocket for this socket. */
- xReturn = xQueueSendToBackFromISR( xNetworkEventQueue, &xEvent, pxHigherPriorityTaskWoken );
-
- return xReturn;
- }
-
-#endif /* ipconfigSUPPORT_SIGNALS */
-/*-----------------------------------------------------------*/
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_DNS.h"
+#include "NetworkBufferManagement.h"
+
+/* The ItemValue of the sockets xBoundSocketListItem member holds the socket's
+port number. */
+#define socketSET_SOCKET_PORT( pxSocket, usPort ) listSET_LIST_ITEM_VALUE( ( &( ( pxSocket )->xBoundSocketListItem ) ), ( usPort ) )
+#define socketGET_SOCKET_PORT( pxSocket ) listGET_LIST_ITEM_VALUE( ( &( ( pxSocket )->xBoundSocketListItem ) ) )
+
+/* Test if a socket it bound which means it is either included in
+xBoundUDPSocketsList or xBoundTCPSocketsList */
+#define socketSOCKET_IS_BOUND( pxSocket ) ( listLIST_ITEM_CONTAINER( & ( pxSocket )->xBoundSocketListItem ) != NULL )
+
+/* If FreeRTOS_sendto() is called on a socket that is not bound to a port
+number then, depending on the FreeRTOSIPConfig.h settings, it might be that a
+port number is automatically generated for the socket. Automatically generated
+port numbers will be between socketAUTO_PORT_ALLOCATION_START_NUMBER and
+0xffff.
+
+Per https://tools.ietf.org/html/rfc6056, "the dynamic ports consist of the range
+49152-65535. However, ephemeral port selection algorithms should use the whole
+range 1024-65535" excluding those already in use (inbound or outbound). */
+#if !defined( socketAUTO_PORT_ALLOCATION_START_NUMBER )
+ #define socketAUTO_PORT_ALLOCATION_START_NUMBER ( ( uint16_t ) 0x0400 )
+#endif
+
+#define socketAUTO_PORT_ALLOCATION_MAX_NUMBER ( ( uint16_t ) 0xffff )
+
+/* The number of octets that make up an IP address. */
+#define socketMAX_IP_ADDRESS_OCTETS 4u
+
+/* A block time of 0 simply means "don't block". */
+#define socketDONT_BLOCK ( ( TickType_t ) 0 )
+
+#if( ( ipconfigUSE_TCP == 1 ) && !defined( ipTCP_TIMER_PERIOD_MS ) )
+ #define ipTCP_TIMER_PERIOD_MS ( 1000 )
+#endif
+
+/* The next private port number to use when binding a client socket is stored in
+the usNextPortToUse[] array - which has either 1 or two indexes depending on
+whether TCP is being supported. */
+#if( ipconfigUSE_TCP == 1 )
+ #define socketPROTOCOL_COUNT 2
+#else
+ #define socketPROTOCOL_COUNT 1
+#endif
+
+/* Indexes into the usNextPortToUse[] array for UDP and TCP sockets
+respectively. */
+#define socketNEXT_UDP_PORT_NUMBER_INDEX 0
+#define socketNEXT_TCP_PORT_NUMBER_INDEX 1
+
+/* Some helper macro's for defining the 20/80 % limits of uxLittleSpace / uxEnoughSpace. */
+#define sock20_PERCENT 20
+#define sock80_PERCENT 80
+#define sock100_PERCENT 100
+
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Allocate the next port number from the private allocation range.
+ * TCP and UDP each have their own series of port numbers
+ * ulProtocol is either ipPROTOCOL_UDP or ipPROTOCOL_TCP
+ */
+static uint16_t prvGetPrivatePortNumber( BaseType_t xProtocol );
+
+/*
+ * Return the list item from within pxList that has an item value of
+ * xWantedItemValue. If there is no such list item return NULL.
+ */
+static const ListItem_t * pxListFindListItemWithValue( const List_t *pxList, TickType_t xWantedItemValue );
+
+/*
+ * Return pdTRUE only if pxSocket is valid and bound, as far as can be
+ * determined.
+ */
+static BaseType_t prvValidSocket( FreeRTOS_Socket_t *pxSocket, BaseType_t xProtocol, BaseType_t xIsBound );
+
+/*
+ * Before creating a socket, check the validity of the parameters used
+ * and find the size of the socket space, which is different for UDP and TCP
+ */
+static BaseType_t prvDetermineSocketSize( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol, size_t *pxSocketSize );
+
+#if( ipconfigUSE_TCP == 1 )
+ /*
+ * Create a txStream or a rxStream, depending on the parameter 'xIsInputStream'
+ */
+ static StreamBuffer_t *prvTCPCreateStream (FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream );
+#endif /* ipconfigUSE_TCP == 1 */
+
+#if( ipconfigUSE_TCP == 1 )
+ /*
+ * Called from FreeRTOS_send(): some checks which will be done before
+ * sending a TCP packed.
+ */
+ static int32_t prvTCPSendCheck( FreeRTOS_Socket_t *pxSocket, size_t xDataLength );
+#endif /* ipconfigUSE_TCP */
+
+#if( ipconfigUSE_TCP == 1 )
+ /*
+ * When a child socket gets closed, make sure to update the child-count of the parent
+ */
+ static void prvTCPSetSocketCount( FreeRTOS_Socket_t *pxSocketToDelete );
+#endif /* ipconfigUSE_TCP == 1 */
+
+#if( ipconfigUSE_TCP == 1 )
+ /*
+ * Called from FreeRTOS_connect(): make some checks and if allowed, send a
+ * message to the IP-task to start connecting to a remote socket
+ */
+ static BaseType_t prvTCPConnectStart( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr *pxAddress );
+#endif /* ipconfigUSE_TCP */
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ /* Executed by the IP-task, it will check all sockets belonging to a set */
+ static FreeRTOS_Socket_t *prvFindSelectedSocket( SocketSelect_t *pxSocketSet );
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+/* The list that contains mappings between sockets and port numbers. Accesses
+to this list must be protected by critical sections of one kind or another. */
+List_t xBoundUDPSocketsList;
+
+#if ipconfigUSE_TCP == 1
+ List_t xBoundTCPSocketsList;
+#endif /* ipconfigUSE_TCP == 1 */
+
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvValidSocket( FreeRTOS_Socket_t *pxSocket, BaseType_t xProtocol, BaseType_t xIsBound )
+{
+BaseType_t xReturn = pdTRUE;
+
+ if( ( pxSocket == NULL ) || ( pxSocket == FREERTOS_INVALID_SOCKET ) )
+ {
+ xReturn = pdFALSE;
+ }
+ else if( ( xIsBound != pdFALSE ) && ( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE ) )
+ {
+ /* The caller expects the socket to be bound, but it isn't. */
+ xReturn = pdFALSE;
+ }
+ else if( pxSocket->ucProtocol != ( uint8_t ) xProtocol )
+ {
+ /* Socket has a wrong type (UDP != TCP). */
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t vNetworkSocketsInit( void )
+{
+ vListInitialise( &xBoundUDPSocketsList );
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ vListInitialise( &xBoundTCPSocketsList );
+ }
+ #endif /* ipconfigUSE_TCP == 1 */
+
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvDetermineSocketSize( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol, size_t *pxSocketSize )
+{
+BaseType_t xReturn = pdPASS;
+FreeRTOS_Socket_t *pxSocket;
+
+ /* Asserts must not appear before it has been determined that the network
+ task is ready - otherwise the asserts will fail. */
+ if( xIPIsNetworkTaskReady() == pdFALSE )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ /* Only Ethernet is currently supported. */
+ configASSERT( xDomain == FREERTOS_AF_INET );
+
+ /* Check if the UDP socket-list has been initialised. */
+ configASSERT( listLIST_IS_INITIALISED( &xBoundUDPSocketsList ) );
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ /* Check if the TCP socket-list has been initialised. */
+ configASSERT( listLIST_IS_INITIALISED( &xBoundTCPSocketsList ) );
+ }
+ #endif /* ipconfigUSE_TCP == 1 */
+
+ if( xProtocol == FREERTOS_IPPROTO_UDP )
+ {
+ if( xType != FREERTOS_SOCK_DGRAM )
+ {
+ xReturn = pdFAIL;
+ configASSERT( xReturn );
+ }
+ /* In case a UDP socket is created, do not allocate space for TCP data. */
+ *pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xUDP );
+ }
+#if( ipconfigUSE_TCP == 1 )
+ else if( xProtocol == FREERTOS_IPPROTO_TCP )
+ {
+ if( xType != FREERTOS_SOCK_STREAM )
+ {
+ xReturn = pdFAIL;
+ configASSERT( xReturn );
+ }
+
+ *pxSocketSize = ( sizeof( *pxSocket ) - sizeof( pxSocket->u ) ) + sizeof( pxSocket->u.xTCP );
+ }
+#endif /* ipconfigUSE_TCP == 1 */
+ else
+ {
+ xReturn = pdFAIL;
+ configASSERT( xReturn );
+ }
+ }
+ /* In case configASSERT() is not used */
+ ( void )xDomain;
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+/* FreeRTOS_socket() allocates and initiates a socket */
+Socket_t FreeRTOS_socket( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol )
+{
+FreeRTOS_Socket_t *pxSocket;
+size_t uxSocketSize;
+EventGroupHandle_t xEventGroup;
+Socket_t xReturn;
+
+ if( prvDetermineSocketSize( xDomain, xType, xProtocol, &uxSocketSize ) == pdFAIL )
+ {
+ xReturn = FREERTOS_INVALID_SOCKET;
+ }
+ else
+ {
+ /* Allocate the structure that will hold the socket information. The
+ size depends on the type of socket: UDP sockets need less space. A
+ define 'pvPortMallocSocket' will used to allocate the necessary space.
+ By default it points to the FreeRTOS function 'pvPortMalloc()'. */
+ pxSocket = ( FreeRTOS_Socket_t * ) pvPortMallocSocket( uxSocketSize );
+
+ if( pxSocket == NULL )
+ {
+ pxSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
+ iptraceFAILED_TO_CREATE_SOCKET();
+ }
+ else if( ( xEventGroup = xEventGroupCreate() ) == NULL )
+ {
+ vPortFreeSocket( pxSocket );
+ pxSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
+ iptraceFAILED_TO_CREATE_EVENT_GROUP();
+ }
+ else
+ {
+ /* Clear the entire space to avoid nulling individual entries */
+ memset( pxSocket, '\0', uxSocketSize );
+
+ pxSocket->xEventGroup = xEventGroup;
+
+ /* Initialise the socket's members. The semaphore will be created
+ if the socket is bound to an address, for now the pointer to the
+ semaphore is just set to NULL to show it has not been created. */
+ if( xProtocol == FREERTOS_IPPROTO_UDP )
+ {
+ vListInitialise( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
+
+ #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
+ {
+ pxSocket->u.xUDP.uxMaxPackets = ( UBaseType_t ) ipconfigUDP_MAX_RX_PACKETS;
+ }
+ #endif /* ipconfigUDP_MAX_RX_PACKETS > 0 */
+ }
+
+ vListInitialiseItem( &( pxSocket->xBoundSocketListItem ) );
+ listSET_LIST_ITEM_OWNER( &( pxSocket->xBoundSocketListItem ), ( void * ) pxSocket );
+
+ pxSocket->xReceiveBlockTime = ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME;
+ pxSocket->xSendBlockTime = ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME;
+ pxSocket->ucSocketOptions = ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT;
+ pxSocket->ucProtocol = ( uint8_t ) xProtocol; /* protocol: UDP or TCP */
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ if( xProtocol == FREERTOS_IPPROTO_TCP )
+ {
+ /* StreamSize is expressed in number of bytes */
+ /* Round up buffer sizes to nearest multiple of MSS */
+ pxSocket->u.xTCP.usInitMSS = pxSocket->u.xTCP.usCurMSS = ipconfigTCP_MSS;
+ pxSocket->u.xTCP.uxRxStreamSize = ( size_t ) ipconfigTCP_RX_BUFFER_LENGTH;
+ pxSocket->u.xTCP.uxTxStreamSize = ( size_t ) FreeRTOS_round_up( ipconfigTCP_TX_BUFFER_LENGTH, ipconfigTCP_MSS );
+ /* Use half of the buffer size of the TCP windows */
+ #if ( ipconfigUSE_TCP_WIN == 1 )
+ {
+ pxSocket->u.xTCP.uxRxWinSize = FreeRTOS_max_uint32( 1UL, ( uint32_t ) ( pxSocket->u.xTCP.uxRxStreamSize / 2 ) / ipconfigTCP_MSS );
+ pxSocket->u.xTCP.uxTxWinSize = FreeRTOS_max_uint32( 1UL, ( uint32_t ) ( pxSocket->u.xTCP.uxTxStreamSize / 2 ) / ipconfigTCP_MSS );
+ }
+ #else
+ {
+ pxSocket->u.xTCP.uxRxWinSize = 1u;
+ pxSocket->u.xTCP.uxTxWinSize = 1u;
+ }
+ #endif
+ /* The above values are just defaults, and can be overridden by
+ calling FreeRTOS_setsockopt(). No buffers will be allocated until a
+ socket is connected and data is exchanged. */
+ }
+ }
+ #endif /* ipconfigUSE_TCP == 1 */
+ }
+
+ xReturn = ( Socket_t ) pxSocket;
+ }
+
+ /* Remove compiler warnings in the case the configASSERT() is not defined. */
+ ( void ) xDomain;
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ SocketSet_t FreeRTOS_CreateSocketSet( void )
+ {
+ SocketSelect_t *pxSocketSet;
+
+ pxSocketSet = ( SocketSelect_t * ) pvPortMalloc( sizeof( *pxSocketSet ) );
+
+ if( pxSocketSet != NULL )
+ {
+ memset( pxSocketSet, '\0', sizeof( *pxSocketSet ) );
+ pxSocketSet->xSelectGroup = xEventGroupCreate();
+
+ if( pxSocketSet->xSelectGroup == NULL )
+ {
+ vPortFree( ( void* ) pxSocketSet );
+ pxSocketSet = NULL;
+ }
+ }
+
+ return ( SocketSet_t ) pxSocketSet;
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ void FreeRTOS_DeleteSocketSet( SocketSet_t xSocketSet )
+ {
+ SocketSelect_t *pxSocketSet = ( SocketSelect_t*) xSocketSet;
+
+ vEventGroupDelete( pxSocketSet->xSelectGroup );
+ vPortFree( ( void* ) pxSocketSet );
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ /* Add a socket to a set */
+ void FreeRTOS_FD_SET( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xSelectBits )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ SocketSelect_t *pxSocketSet = ( SocketSelect_t * ) xSocketSet;
+
+ configASSERT( pxSocket != NULL );
+ configASSERT( xSocketSet != NULL );
+
+ /* Make sure we're not adding bits which are reserved for internal use,
+ such as eSELECT_CALL_IP */
+ pxSocket->xSelectBits |= ( xSelectBits & eSELECT_ALL );
+
+ if( ( pxSocket->xSelectBits & eSELECT_ALL ) != 0 )
+ {
+ /* Adding a socket to a socket set. */
+ pxSocket->pxSocketSet = ( SocketSelect_t * ) xSocketSet;
+
+ /* Now have the IP-task call vSocketSelect() to see if the set contains
+ any sockets which are 'ready' and set the proper bits.
+ By setting 'bApiCalled = false', vSocketSelect() knows that it was
+ not called from a user API */
+ pxSocketSet->bApiCalled = pdFALSE;
+ prvFindSelectedSocket( pxSocketSet );
+ }
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ /* Clear select bits for a socket
+ If the mask becomes 0, remove the socket from the set */
+ void FreeRTOS_FD_CLR( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xSelectBits )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+
+ configASSERT( pxSocket != NULL );
+ configASSERT( xSocketSet != NULL );
+
+ pxSocket->xSelectBits &= ~( xSelectBits & eSELECT_ALL );
+ if( ( pxSocket->xSelectBits & eSELECT_ALL ) != 0 )
+ {
+ pxSocket->pxSocketSet = ( SocketSelect_t *)xSocketSet;
+ }
+ else
+ {
+ /* disconnect it from the socket set */
+ pxSocket->pxSocketSet = ( SocketSelect_t *)NULL;
+ }
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ /* Test if a socket belongs to a socket-set */
+ EventBits_t FreeRTOS_FD_ISSET( Socket_t xSocket, SocketSet_t xSocketSet )
+ {
+ EventBits_t xReturn;
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+
+ configASSERT( pxSocket != NULL );
+ configASSERT( xSocketSet != NULL );
+
+ if( xSocketSet == ( SocketSet_t ) pxSocket->pxSocketSet )
+ {
+ /* Make sure we're not adding bits which are reserved for internal
+ use. */
+ xReturn = pxSocket->xSocketBits & eSELECT_ALL;
+ }
+ else
+ {
+ xReturn = 0;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ /* The select() statement: wait for an event to occur on any of the sockets
+ included in a socket set */
+ BaseType_t FreeRTOS_select( SocketSet_t xSocketSet, TickType_t xBlockTimeTicks )
+ {
+ TimeOut_t xTimeOut;
+ TickType_t xRemainingTime;
+ SocketSelect_t *pxSocketSet = ( SocketSelect_t*) xSocketSet;
+ BaseType_t xResult;
+
+ configASSERT( xSocketSet != NULL );
+
+ /* Only in the first round, check for non-blocking */
+ xRemainingTime = xBlockTimeTicks;
+
+ /* Fetch the current time */
+ vTaskSetTimeOutState( &xTimeOut );
+
+ for( ;; )
+ {
+ /* Find a socket which might have triggered the bit
+ This function might return immediately or block for a limited time */
+ xResult = ( BaseType_t ) xEventGroupWaitBits( pxSocketSet->xSelectGroup, eSELECT_ALL, pdFALSE, pdFALSE, xRemainingTime );
+
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ if( ( xResult & eSELECT_INTR ) != 0u )
+ {
+ xEventGroupClearBits( pxSocketSet->xSelectGroup, eSELECT_INTR );
+ FreeRTOS_debug_printf( ( "FreeRTOS_select: interrupted\n" ) );
+ break;
+ }
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+
+ /* Have the IP-task find the socket which had an event */
+ pxSocketSet->bApiCalled = pdTRUE;
+ prvFindSelectedSocket( pxSocketSet );
+
+ xResult = ( BaseType_t ) xEventGroupGetBits( pxSocketSet->xSelectGroup );
+
+ if( xResult != 0 )
+ {
+ break;
+ }
+
+ /* Has the timeout been reached? */
+ if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
+ {
+ break;
+ }
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ /* Send a message to the IP-task to have it check all sockets belonging to
+ 'pxSocketSet' */
+ static FreeRTOS_Socket_t *prvFindSelectedSocket( SocketSelect_t *pxSocketSet )
+ {
+ IPStackEvent_t xSelectEvent;
+ FreeRTOS_Socket_t *xReturn;
+
+ xSelectEvent.eEventType = eSocketSelectEvent;
+ xSelectEvent.pvData = ( void * ) pxSocketSet;
+
+ /* while the IP-task works on the request, the API will block on
+ 'eSELECT_CALL_IP'. So clear it first. */
+ xEventGroupClearBits( pxSocketSet->xSelectGroup, eSELECT_CALL_IP );
+
+ /* Now send the socket select event */
+ if( xSendEventStructToIPTask( &xSelectEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
+ {
+ /* Oops, we failed to wake-up the IP task. No use to wait for it. */
+ FreeRTOS_debug_printf( ( "prvFindSelectedSocket: failed\n" ) );
+ xReturn = NULL;
+ }
+ else
+ {
+ /* As soon as the IP-task is ready, it will set 'eSELECT_CALL_IP' to
+ wakeup the calling API */
+ xEventGroupWaitBits( pxSocketSet->xSelectGroup, eSELECT_CALL_IP, pdTRUE, pdFALSE, portMAX_DELAY );
+
+ /* Return 'pxSocket' which is set by the IP-task */
+ xReturn = pxSocketSet->pxSocket;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+/*
+ * FreeRTOS_recvfrom: receive data from a bound socket
+ * In this library, the function can only be used with connectionsless sockets
+ * (UDP)
+ */
+int32_t FreeRTOS_recvfrom( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength )
+{
+BaseType_t lPacketCount = 0;
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+TickType_t xRemainingTime = ( TickType_t ) 0; /* Obsolete assignment, but some compilers output a warning if its not done. */
+BaseType_t xTimed = pdFALSE;
+TimeOut_t xTimeOut;
+int32_t lReturn;
+EventBits_t xEventBits = ( EventBits_t ) 0;
+
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_UDP, pdTRUE ) == pdFALSE )
+ {
+ return -pdFREERTOS_ERRNO_EINVAL;
+ }
+
+ lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
+
+ /* The function prototype is designed to maintain the expected Berkeley
+ sockets standard, but this implementation does not use all the parameters. */
+ ( void ) pxSourceAddressLength;
+
+ while( lPacketCount == 0 )
+ {
+ if( xTimed == pdFALSE )
+ {
+ /* Check to see if the socket is non blocking on the first
+ iteration. */
+ xRemainingTime = pxSocket->xReceiveBlockTime;
+
+ if( xRemainingTime == ( TickType_t ) 0 )
+ {
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ /* Just check for the interrupt flag. */
+ xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_INTR,
+ pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, socketDONT_BLOCK );
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+ break;
+ }
+
+ if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
+ {
+ break;
+ }
+
+ /* To ensure this part only executes once. */
+ xTimed = pdTRUE;
+
+ /* Fetch the current time. */
+ vTaskSetTimeOutState( &xTimeOut );
+ }
+
+ /* Wait for arrival of data. While waiting, the IP-task may set the
+ 'eSOCKET_RECEIVE' bit in 'xEventGroup', if it receives data for this
+ socket, thus unblocking this API call. */
+ xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_RECEIVE | eSOCKET_INTR,
+ pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
+
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ if( ( xEventBits & eSOCKET_INTR ) != 0 )
+ {
+ if( ( xEventBits & eSOCKET_RECEIVE ) != 0 )
+ {
+ /* Shouldn't have cleared the eSOCKET_RECEIVE flag. */
+ xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
+ }
+ break;
+ }
+ }
+ #else
+ {
+ ( void ) xEventBits;
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+
+ lPacketCount = ( BaseType_t ) listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
+
+ if( lPacketCount != 0 )
+ {
+ break;
+ }
+
+ /* Has the timeout been reached ? */
+ if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) )
+ {
+ break;
+ }
+ } /* while( lPacketCount == 0 ) */
+
+ if( lPacketCount != 0 )
+ {
+ taskENTER_CRITICAL();
+ {
+ /* The owner of the list item is the network buffer. */
+ pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
+
+ if( ( xFlags & FREERTOS_MSG_PEEK ) == 0 )
+ {
+ /* Remove the network buffer from the list of buffers waiting to
+ be processed by the socket. */
+ uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ /* The returned value is the length of the payload data, which is
+ calculated at the total packet size minus the headers.
+ The validity of `xDataLength` prvProcessIPPacket has been confirmed
+ in 'prvProcessIPPacket()'. */
+ lReturn = ( int32_t ) ( pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t ) );
+
+ if( pxSourceAddress != NULL )
+ {
+ pxSourceAddress->sin_port = pxNetworkBuffer->usPort;
+ pxSourceAddress->sin_addr = pxNetworkBuffer->ulIPAddress;
+ }
+
+ if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
+ {
+ /* The zero copy flag is not set. Truncate the length if it won't
+ fit in the provided buffer. */
+ if( lReturn > ( int32_t ) xBufferLength )
+ {
+ iptraceRECVFROM_DISCARDING_BYTES( ( xBufferLength - lReturn ) );
+ lReturn = ( int32_t )xBufferLength;
+ }
+
+ /* Copy the received data into the provided buffer, then release the
+ network buffer. */
+ memcpy( pvBuffer, ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ), ( size_t )lReturn );
+
+ if( ( xFlags & FREERTOS_MSG_PEEK ) == 0 )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ }
+ else
+ {
+ /* The zero copy flag was set. pvBuffer is not a buffer into which
+ the received data can be copied, but a pointer that must be set to
+ point to the buffer in which the received data has already been
+ placed. */
+ *( ( void** ) pvBuffer ) = ( void * ) ( &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ) );
+ }
+
+ }
+#if( ipconfigSUPPORT_SIGNALS != 0 )
+ else if( ( xEventBits & eSOCKET_INTR ) != 0 )
+ {
+ lReturn = -pdFREERTOS_ERRNO_EINTR;
+ iptraceRECVFROM_INTERRUPTED();
+ }
+#endif /* ipconfigSUPPORT_SIGNALS */
+ else
+ {
+ lReturn = -pdFREERTOS_ERRNO_EWOULDBLOCK;
+ iptraceRECVFROM_TIMEOUT();
+ }
+
+ return lReturn;
+}
+/*-----------------------------------------------------------*/
+
+int32_t FreeRTOS_sendto( Socket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, BaseType_t xFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xStackTxEvent = { eStackTxEvent, NULL };
+TimeOut_t xTimeOut;
+TickType_t xTicksToWait;
+int32_t lReturn = 0;
+FreeRTOS_Socket_t *pxSocket;
+
+ pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+
+ /* The function prototype is designed to maintain the expected Berkeley
+ sockets standard, but this implementation does not use all the
+ parameters. */
+ ( void ) xDestinationAddressLength;
+ configASSERT( pvBuffer );
+
+ if( xTotalDataLength <= ( size_t ) ipMAX_UDP_PAYLOAD_LENGTH )
+ {
+ /* If the socket is not already bound to an address, bind it now.
+ Passing NULL as the address parameter tells FreeRTOS_bind() to select
+ the address to bind to. */
+ if( ( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE ) ||
+ ( FreeRTOS_bind( xSocket, NULL, 0u ) == 0 ) )
+ {
+ xTicksToWait = pxSocket->xSendBlockTime;
+
+ #if( ipconfigUSE_CALLBACKS != 0 )
+ {
+ if( xIsCallingFromIPTask() != pdFALSE )
+ {
+ /* If this send function is called from within a call-back
+ handler it may not block, otherwise chances would be big to
+ get a deadlock: the IP-task waiting for itself. */
+ xTicksToWait = ( TickType_t )0;
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
+ {
+ xTicksToWait = ( TickType_t ) 0;
+ }
+
+ if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
+ {
+ /* Zero copy is not set, so obtain a network buffer into
+ which the payload will be copied. */
+ vTaskSetTimeOutState( &xTimeOut );
+
+ /* Block until a buffer becomes available, or until a
+ timeout has been reached */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( xTotalDataLength + sizeof( UDPPacket_t ), xTicksToWait );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ memcpy( ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] ), ( void * ) pvBuffer, xTotalDataLength );
+
+ if( xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE )
+ {
+ /* The entire block time has been used up. */
+ xTicksToWait = ( TickType_t ) 0;
+ }
+ }
+ }
+ else
+ {
+ /* When zero copy is used, pvBuffer is a pointer to the
+ payload of a buffer that has already been obtained from the
+ stack. Obtain the network buffer pointer from the buffer. */
+ pxNetworkBuffer = pxUDPPayloadBuffer_to_NetworkBuffer( (void*)pvBuffer );
+ }
+
+ if( pxNetworkBuffer != NULL )
+ {
+ /* xDataLength is the size of the total packet, including the Ethernet header. */
+ pxNetworkBuffer->xDataLength = xTotalDataLength + sizeof( UDPPacket_t );
+ pxNetworkBuffer->usPort = pxDestinationAddress->sin_port;
+ pxNetworkBuffer->usBoundPort = ( uint16_t ) socketGET_SOCKET_PORT( pxSocket );
+ pxNetworkBuffer->ulIPAddress = pxDestinationAddress->sin_addr;
+
+ /* The socket options are passed to the IP layer in the
+ space that will eventually get used by the Ethernet header. */
+ pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ] = pxSocket->ucSocketOptions;
+
+ /* Tell the networking task that the packet needs sending. */
+ xStackTxEvent.pvData = pxNetworkBuffer;
+
+ /* Ask the IP-task to send this packet */
+ if( xSendEventStructToIPTask( &xStackTxEvent, xTicksToWait ) == pdPASS )
+ {
+ /* The packet was successfully sent to the IP task. */
+ lReturn = ( int32_t ) xTotalDataLength;
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleSent ) )
+ {
+ pxSocket->u.xUDP.pxHandleSent( ( Socket_t )pxSocket, xTotalDataLength );
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+ }
+ else
+ {
+ /* If the buffer was allocated in this function, release
+ it. */
+ if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ iptraceSTACK_TX_EVENT_LOST( ipSTACK_TX_EVENT );
+ }
+ }
+ else
+ {
+ /* If errno was available, errno would be set to
+ FREERTOS_ENOPKTS. As it is, the function must return the
+ number of transmitted bytes, so the calling function knows
+ how much data was actually sent. */
+ iptraceNO_BUFFER_FOR_SENDTO();
+ }
+ }
+ else
+ {
+ iptraceSENDTO_SOCKET_NOT_BOUND();
+ }
+ }
+ else
+ {
+ /* The data is longer than the available buffer space. */
+ iptraceSENDTO_DATA_TOO_LONG();
+ }
+
+ return lReturn;
+} /* Tested */
+/*-----------------------------------------------------------*/
+
+/*
+ * FreeRTOS_bind() : binds a sockt to a local port number. If port 0 is
+ * provided, a system provided port number will be assigned. This function can
+ * be used for both UDP and TCP sockets. The actual binding will be performed
+ * by the IP-task to avoid mutual access to the bound-socket-lists
+ * (xBoundUDPSocketsList or xBoundTCPSocketsList).
+ */
+BaseType_t FreeRTOS_bind( Socket_t xSocket, struct freertos_sockaddr * pxAddress, socklen_t xAddressLength )
+{
+IPStackEvent_t xBindEvent;
+FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+BaseType_t xReturn = 0;
+
+ ( void ) xAddressLength;
+
+ if( ( pxSocket == NULL ) || ( pxSocket == FREERTOS_INVALID_SOCKET ) )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ /* Once a socket is bound to a port, it can not be bound to a different
+ port number */
+ else if( socketSOCKET_IS_BOUND( pxSocket) != pdFALSE )
+ {
+ /* The socket is already bound. */
+ FreeRTOS_debug_printf( ( "vSocketBind: Socket already bound to %d\n", pxSocket->usLocalPort ) );
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ /* Prepare a messages to the IP-task in order to perform the binding.
+ The desired port number will be passed in usLocalPort. */
+ xBindEvent.eEventType = eSocketBindEvent;
+ xBindEvent.pvData = ( void * ) xSocket;
+ if( pxAddress != NULL )
+ {
+ pxSocket->usLocalPort = FreeRTOS_ntohs( pxAddress->sin_port );
+ }
+ else
+ {
+ /* Caller wants to bind to a random port number. */
+ pxSocket->usLocalPort = 0u;
+ }
+
+ /* portMAX_DELAY is used as a the time-out parameter, as binding *must*
+ succeed before the socket can be used. _RB_ The use of an infinite
+ block time needs be changed as it could result in the task hanging. */
+ if( xSendEventStructToIPTask( &xBindEvent, ( TickType_t ) portMAX_DELAY ) == pdFAIL )
+ {
+ /* Failed to wake-up the IP-task, no use to wait for it */
+ FreeRTOS_debug_printf( ( "FreeRTOS_bind: send event failed\n" ) );
+ xReturn = -pdFREERTOS_ERRNO_ECANCELED;
+ }
+ else
+ {
+ /* The IP-task will set the 'eSOCKET_BOUND' bit when it has done its
+ job. */
+ xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_BOUND, pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, portMAX_DELAY );
+ if( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ }
+ }
+
+ return xReturn;
+}
+
+/*
+ * vSocketBind(): internal version of bind() that should not be called directly.
+ * 'xInternal' is used for TCP sockets only: it allows to have several
+ * (connected) child sockets bound to the same server port.
+ */
+BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal )
+{
+BaseType_t xReturn = 0; /* In Berkeley sockets, 0 means pass for bind(). */
+List_t *pxSocketList;
+#if( ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 )
+ struct freertos_sockaddr xAddress;
+#endif /* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND */
+
+#if( ipconfigUSE_TCP == 1 )
+ if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ pxSocketList = &xBoundTCPSocketsList;
+ }
+ else
+#endif /* ipconfigUSE_TCP == 1 */
+ {
+ pxSocketList = &xBoundUDPSocketsList;
+ }
+
+ /* The function prototype is designed to maintain the expected Berkeley
+ sockets standard, but this implementation does not use all the parameters. */
+ ( void ) uxAddressLength;
+
+ configASSERT( pxSocket );
+ configASSERT( pxSocket != FREERTOS_INVALID_SOCKET );
+
+ #if( ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 )
+ {
+ /* pxAddress will be NULL if sendto() was called on a socket without the
+ socket being bound to an address. In this case, automatically allocate
+ an address and port to the socket. */
+ if( pxAddress == NULL )
+ {
+ pxAddress = &xAddress;
+ /* Put the port to zero to be assigned later. */
+ pxAddress->sin_port = 0u;
+ }
+ }
+ #endif /* ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND == 1 */
+
+ /* Sockets must be bound before calling FreeRTOS_sendto() if
+ ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND is not set to 1. */
+ configASSERT( pxAddress );
+
+ if( pxAddress != NULL )
+ {
+ if( pxAddress->sin_port == 0u )
+ {
+ pxAddress->sin_port = prvGetPrivatePortNumber( ( BaseType_t )pxSocket->ucProtocol );
+ if( 0 == pxAddress->sin_port )
+ {
+ return -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
+ }
+ }
+
+ /* If vSocketBind() is called from the API FreeRTOS_bind() it has been
+ confirmed that the socket was not yet bound to a port. If it is called
+ from the IP-task, no such check is necessary. */
+
+ /* Check to ensure the port is not already in use. If the bind is
+ called internally, a port MAY be used by more than one socket. */
+ if( ( ( xInternal == pdFALSE ) || ( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP ) ) &&
+ ( pxListFindListItemWithValue( pxSocketList, ( TickType_t ) pxAddress->sin_port ) != NULL ) )
+ {
+ FreeRTOS_debug_printf( ( "vSocketBind: %sP port %d in use\n",
+ pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP ? "TC" : "UD",
+ FreeRTOS_ntohs( pxAddress->sin_port ) ) );
+ xReturn = -pdFREERTOS_ERRNO_EADDRINUSE;
+ }
+ else
+ {
+ /* Allocate the port number to the socket.
+ This macro will set 'xBoundSocketListItem->xItemValue' */
+ socketSET_SOCKET_PORT( pxSocket, pxAddress->sin_port );
+
+ /* And also store it in a socket field 'usLocalPort' in host-byte-order,
+ mostly used for logging and debugging purposes */
+ pxSocket->usLocalPort = FreeRTOS_ntohs( pxAddress->sin_port );
+
+ /* Add the socket to the list of bound ports. */
+ {
+ /* If the network driver can iterate through 'xBoundUDPSocketsList',
+ by calling xPortHasUDPSocket() then the IP-task must temporarily
+ suspend the scheduler to keep the list in a consistent state. */
+ #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
+ {
+ vTaskSuspendAll();
+ }
+ #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+
+ /* Add the socket to 'xBoundUDPSocketsList' or 'xBoundTCPSocketsList' */
+ vListInsertEnd( pxSocketList, &( pxSocket->xBoundSocketListItem ) );
+
+ #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
+ {
+ xTaskResumeAll();
+ }
+ #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+ }
+ }
+ }
+ else
+ {
+ xReturn = -pdFREERTOS_ERRNO_EADDRNOTAVAIL;
+ FreeRTOS_debug_printf( ( "vSocketBind: Socket no addr\n" ) );
+ }
+
+ if( xReturn != 0 )
+ {
+ iptraceBIND_FAILED( xSocket, ( FreeRTOS_ntohs( pxAddress->sin_port ) ) );
+ }
+
+ return xReturn;
+} /* Tested */
+/*-----------------------------------------------------------*/
+
+/*
+ * Close a socket and free the allocated space
+ * In case of a TCP socket: the connection will not be closed automatically
+ * Subsequent messages for the closed socket will be responded to with a RST
+ * The IP-task will actually close the socket, after receiving a 'eSocketCloseEvent' message
+ */
+BaseType_t FreeRTOS_closesocket( Socket_t xSocket )
+{
+BaseType_t xResult;
+#if( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_CALLBACKS == 1 )
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
+#endif
+IPStackEvent_t xCloseEvent;
+xCloseEvent.eEventType = eSocketCloseEvent;
+xCloseEvent.pvData = ( void * ) xSocket;
+
+ if( ( xSocket == NULL ) || ( xSocket == FREERTOS_INVALID_SOCKET ) )
+ {
+ xResult = 0;
+ }
+ else
+ {
+ #if( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_CALLBACKS == 1 ) )
+ {
+ if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ /* Make sure that IP-task won't call the user callback's anymore */
+ pxSocket->u.xTCP.pxHandleConnected = NULL;
+ pxSocket->u.xTCP.pxHandleReceive = NULL;
+ pxSocket->u.xTCP.pxHandleSent = NULL;
+ }
+ }
+ #endif /* ( ( ipconfigUSE_TCP == 1 ) && ( ipconfigUSE_CALLBACKS == 1 ) ) */
+
+ /* Let the IP task close the socket to keep it synchronised with the
+ packet handling. */
+
+ /* Note when changing the time-out value below, it must be checked who is calling
+ this function. If it is called by the IP-task, a deadlock could occur.
+ The IP-task would only call it in case of a user call-back */
+ if( xSendEventStructToIPTask( &xCloseEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ FreeRTOS_debug_printf( ( "FreeRTOS_closesocket: failed\n" ) );
+ xResult = -1;
+ }
+ else
+ {
+ xResult = 1;
+ }
+ }
+
+ return xResult;
+}
+
+/* This is the internal version of FreeRTOS_closesocket()
+ * It will be called by the IPtask only to avoid problems with synchronicity
+ */
+void *vSocketClose( FreeRTOS_Socket_t *pxSocket )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ /* For TCP: clean up a little more. */
+ if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ if( pxSocket->u.xTCP.pxAckMessage != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
+ }
+ /* Free the resources which were claimed by the tcpWin member */
+ vTCPWindowDestroy( &pxSocket->u.xTCP.xTCPWindow );
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+
+ /* Free the input and output streams */
+ if( pxSocket->u.xTCP.rxStream != NULL )
+ {
+ vPortFreeLarge( pxSocket->u.xTCP.rxStream );
+ }
+
+ if( pxSocket->u.xTCP.txStream != NULL )
+ {
+ vPortFreeLarge( pxSocket->u.xTCP.txStream );
+ }
+
+ /* In case this is a child socket, make sure the child-count of the
+ parent socket is decreased. */
+ prvTCPSetSocketCount( pxSocket );
+ }
+ }
+ #endif /* ipconfigUSE_TCP == 1 */
+
+ /* Socket must be unbound first, to ensure no more packets are queued on
+ it. */
+ if( socketSOCKET_IS_BOUND( pxSocket ) != pdFALSE )
+ {
+ /* If the network driver can iterate through 'xBoundUDPSocketsList',
+ by calling xPortHasUDPSocket(), then the IP-task must temporarily
+ suspend the scheduler to keep the list in a consistent state. */
+ #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
+ {
+ vTaskSuspendAll();
+ }
+ #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+
+ uxListRemove( &( pxSocket->xBoundSocketListItem ) );
+
+ #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
+ {
+ xTaskResumeAll();
+ }
+ #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+ }
+
+ /* Now the socket is not bound the list of waiting packets can be
+ drained. */
+ if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_UDP )
+ {
+ while( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) > 0U )
+ {
+ pxNetworkBuffer = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &( pxSocket->u.xUDP.xWaitingPacketsList ) );
+ uxListRemove( &( pxNetworkBuffer->xBufferListItem ) );
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ }
+
+ if( pxSocket->xEventGroup )
+ {
+ vEventGroupDelete( pxSocket->xEventGroup );
+ }
+
+ #if( ipconfigUSE_TCP == 1 ) && ( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ FreeRTOS_debug_printf( ( "FreeRTOS_closesocket[%u to %lxip:%u]: buffers %lu socks %lu\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort,
+ uxGetNumberOfFreeNetworkBuffers(),
+ listCURRENT_LIST_LENGTH( &xBoundTCPSocketsList ) ) );
+ }
+ }
+ #endif /* ( ipconfigUSE_TCP == 1 ) && ( ipconfigHAS_DEBUG_PRINTF != 0 ) */
+
+ /* Anf finally, after all resources have been freed, free the socket space */
+ vPortFreeSocket( pxSocket );
+
+ return 0;
+} /* Tested */
+
+/*-----------------------------------------------------------*/
+
+#if ipconfigUSE_TCP == 1
+
+ /*
+ * When a child socket gets closed, make sure to update the child-count of the
+ * parent. When a listening parent socket is closed, make sure no child-sockets
+ * keep a pointer to it.
+ */
+ static void prvTCPSetSocketCount( FreeRTOS_Socket_t *pxSocketToDelete )
+ {
+ const ListItem_t *pxIterator;
+ const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
+ FreeRTOS_Socket_t *pxOtherSocket;
+ uint16_t usLocalPort = pxSocketToDelete->usLocalPort;
+
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
+ pxIterator != ( const ListItem_t * ) pxEnd;
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ pxOtherSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+ if( ( pxOtherSocket->u.xTCP.ucTCPState == eTCP_LISTEN ) &&
+ ( pxOtherSocket->usLocalPort == usLocalPort ) &&
+ ( pxOtherSocket->u.xTCP.usChildCount ) )
+ {
+ pxOtherSocket->u.xTCP.usChildCount--;
+ FreeRTOS_debug_printf( ( "Lost: Socket %u now has %u / %u child%s\n",
+ pxOtherSocket->usLocalPort,
+ pxOtherSocket->u.xTCP.usChildCount,
+ pxOtherSocket->u.xTCP.usBacklog,
+ pxOtherSocket->u.xTCP.usChildCount == 1u ? "" : "ren" ) );
+ break;
+ }
+ }
+ }
+
+#endif /* ipconfigUSE_TCP == 1 */
+
+/*-----------------------------------------------------------*/
+
+BaseType_t FreeRTOS_setsockopt( Socket_t xSocket, int32_t lLevel, int32_t lOptionName, const void *pvOptionValue, size_t xOptionLength )
+{
+/* The standard Berkeley function returns 0 for success. */
+BaseType_t xReturn = -pdFREERTOS_ERRNO_EINVAL;
+BaseType_t lOptionValue;
+FreeRTOS_Socket_t *pxSocket;
+
+ pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+
+ /* The function prototype is designed to maintain the expected Berkeley
+ sockets standard, but this implementation does not use all the parameters. */
+ ( void ) lLevel;
+ ( void ) xOptionLength;
+
+ configASSERT( xSocket );
+
+ switch( lOptionName )
+ {
+ case FREERTOS_SO_RCVTIMEO :
+ /* Receive time out. */
+ pxSocket->xReceiveBlockTime = *( ( TickType_t * ) pvOptionValue );
+ xReturn = 0;
+ break;
+
+ case FREERTOS_SO_SNDTIMEO :
+ pxSocket->xSendBlockTime = *( ( TickType_t * ) pvOptionValue );
+ if( pxSocket->ucProtocol == ( uint8_t ) FREERTOS_IPPROTO_UDP )
+ {
+ /* The send time out is capped for the reason stated in the
+ comments where ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS is defined
+ in FreeRTOSIPConfig.h (assuming an official configuration file
+ is being used. */
+ if( pxSocket->xSendBlockTime > ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS )
+ {
+ pxSocket->xSendBlockTime = ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS;
+ }
+ }
+ else
+ {
+ /* For TCP socket, it isn't necessary to limit the blocking time
+ because the FreeRTOS_send() function does not wait for a network
+ buffer to become available. */
+ }
+ xReturn = 0;
+ break;
+ #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
+ case FREERTOS_SO_UDP_MAX_RX_PACKETS:
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_UDP )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+ pxSocket->u.xUDP.uxMaxPackets = *( ( UBaseType_t * ) pvOptionValue );
+ xReturn = 0;
+ break;
+ #endif /* ipconfigUDP_MAX_RX_PACKETS */
+
+ case FREERTOS_SO_UDPCKSUM_OUT :
+ /* Turn calculating of the UDP checksum on/off for this socket. */
+ lOptionValue = ( BaseType_t ) pvOptionValue;
+
+ if( lOptionValue == 0 )
+ {
+ pxSocket->ucSocketOptions &= ( uint8_t ) ~FREERTOS_SO_UDPCKSUM_OUT;
+ }
+ else
+ {
+ pxSocket->ucSocketOptions |= ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT;
+ }
+ xReturn = 0;
+ break;
+
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ #if( ipconfigUSE_TCP == 1 )
+ case FREERTOS_SO_TCP_CONN_HANDLER: /* Set a callback for (dis)connection events */
+ case FREERTOS_SO_TCP_RECV_HANDLER: /* Install a callback for receiving TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ case FREERTOS_SO_TCP_SENT_HANDLER: /* Install a callback for sending TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ #endif /* ipconfigUSE_TCP */
+ case FREERTOS_SO_UDP_RECV_HANDLER: /* Install a callback for receiving UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ case FREERTOS_SO_UDP_SENT_HANDLER: /* Install a callback for sending UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ {
+ #if( ipconfigUSE_TCP == 1 )
+ {
+ UBaseType_t uxProtocol;
+ if( ( lOptionName == FREERTOS_SO_UDP_RECV_HANDLER ) ||
+ ( lOptionName == FREERTOS_SO_UDP_SENT_HANDLER ) )
+ {
+ uxProtocol = ( UBaseType_t ) FREERTOS_IPPROTO_UDP;
+ }
+ else
+ {
+ uxProtocol = ( UBaseType_t ) FREERTOS_IPPROTO_TCP;
+ }
+
+ if( pxSocket->ucProtocol != ( uint8_t ) uxProtocol )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+ }
+ #else
+ {
+ /* No need to check if the socket has the right
+ protocol, because only UDP socket can be created. */
+ }
+ #endif /* ipconfigUSE_TCP */
+
+ switch( lOptionName )
+ {
+ #if ipconfigUSE_TCP == 1
+ case FREERTOS_SO_TCP_CONN_HANDLER:
+ pxSocket->u.xTCP.pxHandleConnected = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnTCPConnected;
+ break;
+ case FREERTOS_SO_TCP_RECV_HANDLER:
+ pxSocket->u.xTCP.pxHandleReceive = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnTCPReceive;
+ break;
+ case FREERTOS_SO_TCP_SENT_HANDLER:
+ pxSocket->u.xTCP.pxHandleSent = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnTCPSent;
+ break;
+ #endif /* ipconfigUSE_TCP */
+ case FREERTOS_SO_UDP_RECV_HANDLER:
+ pxSocket->u.xUDP.pxHandleReceive = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnUDPReceive;
+ break;
+ case FREERTOS_SO_UDP_SENT_HANDLER:
+ pxSocket->u.xUDP.pxHandleSent = ((F_TCP_UDP_Handler_t *)pvOptionValue)->pxOnUDPSent;
+ break;
+ default:
+ break;
+ }
+ }
+
+ xReturn = 0;
+ break;
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ #if( ipconfigUSE_TCP != 0 )
+ #if( ipconfigSOCKET_HAS_USER_SEMAPHORE != 0 )
+ /* Each socket has a semaphore on which the using task normally
+ sleeps. */
+ case FREERTOS_SO_SET_SEMAPHORE:
+ {
+ pxSocket->pxUserSemaphore = *( ( SemaphoreHandle_t * ) pvOptionValue );
+ xReturn = 0;
+ }
+ break;
+ #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
+
+ #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK != 0 )
+ case FREERTOS_SO_WAKEUP_CALLBACK:
+ {
+ /* Each socket can have a callback function that is executed
+ when there is an event the socket's owner might want to
+ process. */
+ pxSocket->pxUserWakeCallback = ( SocketWakeupCallback_t ) pvOptionValue;
+ xReturn = 0;
+ }
+ break;
+ #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
+
+ case FREERTOS_SO_SET_LOW_HIGH_WATER:
+ {
+ LowHighWater_t *pxLowHighWater = ( LowHighWater_t * ) pvOptionValue;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ /* It is not allowed to access 'pxSocket->u.xTCP'. */
+ FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: wrong socket type\n" ) );
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+ if( ( pxLowHighWater->uxLittleSpace >= pxLowHighWater->uxEnoughSpace ) ||
+ ( pxLowHighWater->uxEnoughSpace > pxSocket->u.xTCP.uxRxStreamSize ) )
+ {
+ /* Impossible values. */
+ FreeRTOS_debug_printf( ( "FREERTOS_SO_SET_LOW_HIGH_WATER: bad values\n" ) );
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+ /* Send a STOP when buffer space drops below 'uxLittleSpace' bytes. */
+ pxSocket->u.xTCP.uxLittleSpace = pxLowHighWater->uxLittleSpace;
+ /* Send a GO when buffer space grows above 'uxEnoughSpace' bytes. */
+ pxSocket->u.xTCP.uxEnoughSpace = pxLowHighWater->uxEnoughSpace;
+ xReturn = 0;
+ }
+ break;
+
+ case FREERTOS_SO_SNDBUF: /* Set the size of the send buffer, in units of MSS (TCP only) */
+ case FREERTOS_SO_RCVBUF: /* Set the size of the receive buffer, in units of MSS (TCP only) */
+ {
+ uint32_t ulNewValue;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ FreeRTOS_debug_printf( ( "Set SO_%sBUF: wrong socket type\n",
+ ( lOptionName == FREERTOS_SO_SNDBUF ) ? "SND" : "RCV" ) );
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ if( ( ( lOptionName == FREERTOS_SO_SNDBUF ) && ( pxSocket->u.xTCP.txStream != NULL ) ) ||
+ ( ( lOptionName == FREERTOS_SO_RCVBUF ) && ( pxSocket->u.xTCP.rxStream != NULL ) ) )
+ {
+ FreeRTOS_debug_printf( ( "Set SO_%sBUF: buffer already created\n",
+ ( lOptionName == FREERTOS_SO_SNDBUF ) ? "SND" : "RCV" ) );
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ ulNewValue = *( ( uint32_t * ) pvOptionValue );
+
+ if( lOptionName == FREERTOS_SO_SNDBUF )
+ {
+ /* Round up to nearest MSS size */
+ ulNewValue = FreeRTOS_round_up( ulNewValue, ( uint32_t ) pxSocket->u.xTCP.usInitMSS );
+ pxSocket->u.xTCP.uxTxStreamSize = ulNewValue;
+ }
+ else
+ {
+ pxSocket->u.xTCP.uxRxStreamSize = ulNewValue;
+ }
+ }
+ xReturn = 0;
+ break;
+
+ case FREERTOS_SO_WIN_PROPERTIES: /* Set all buffer and window properties in one call, parameter is pointer to WinProperties_t */
+ {
+ WinProperties_t* pxProps;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ FreeRTOS_debug_printf( ( "Set SO_WIN_PROP: wrong socket type\n" ) );
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ if( ( pxSocket->u.xTCP.txStream != NULL ) || ( pxSocket->u.xTCP.rxStream != NULL ) )
+ {
+ FreeRTOS_debug_printf( ( "Set SO_WIN_PROP: buffer already created\n" ) );
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ pxProps = ( ( WinProperties_t * ) pvOptionValue );
+
+ if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_SNDBUF, &( pxProps->lTxBufSize ), sizeof( pxProps->lTxBufSize ) ) != 0 )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ if ( FreeRTOS_setsockopt( xSocket, 0, FREERTOS_SO_RCVBUF, &( pxProps->lRxBufSize ), sizeof( pxProps->lRxBufSize ) ) != 0 )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ pxSocket->u.xTCP.uxRxWinSize = ( uint32_t )pxProps->lRxWinSize; /* Fixed value: size of the TCP reception window */
+ pxSocket->u.xTCP.uxTxWinSize = ( uint32_t )pxProps->lTxWinSize; /* Fixed value: size of the TCP transmit window */
+ }
+ #else
+ {
+ pxSocket->u.xTCP.uxRxWinSize = 1u;
+ pxSocket->u.xTCP.uxTxWinSize = 1u;
+ }
+ #endif
+
+ /* In case the socket has already initialised its tcpWin,
+ adapt the window size parameters */
+ if( pxSocket->u.xTCP.xTCPWindow.u.bits.bHasInit != pdFALSE_UNSIGNED )
+ {
+ pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength = pxSocket->u.xTCP.uxRxWinSize * pxSocket->u.xTCP.usInitMSS;
+ pxSocket->u.xTCP.xTCPWindow.xSize.ulTxWindowLength = pxSocket->u.xTCP.uxTxWinSize * pxSocket->u.xTCP.usInitMSS;
+ }
+ }
+
+ xReturn = 0;
+ break;
+
+ case FREERTOS_SO_REUSE_LISTEN_SOCKET: /* If true, the server-socket will turn into a connected socket */
+ {
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+ if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
+ {
+ pxSocket->u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ pxSocket->u.xTCP.bits.bReuseSocket = pdFALSE_UNSIGNED;
+ }
+ }
+ xReturn = 0;
+ break;
+
+ case FREERTOS_SO_CLOSE_AFTER_SEND: /* As soon as the last byte has been transmitted, finalise the connection */
+ {
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
+ {
+ pxSocket->u.xTCP.bits.bCloseAfterSend = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ pxSocket->u.xTCP.bits.bCloseAfterSend = pdFALSE_UNSIGNED;
+ }
+ }
+ xReturn = 0;
+ break;
+
+ case FREERTOS_SO_SET_FULL_SIZE: /* Refuse to send packets smaller than MSS */
+ {
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
+ {
+ pxSocket->u.xTCP.xTCPWindow.u.bits.bSendFullSize = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ pxSocket->u.xTCP.xTCPWindow.u.bits.bSendFullSize = pdFALSE_UNSIGNED;
+ }
+
+ if( ( pxSocket->u.xTCP.xTCPWindow.u.bits.bSendFullSize == pdFALSE_UNSIGNED ) &&
+ ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) &&
+ ( FreeRTOS_outstanding( pxSocket ) != 0 ) )
+ {
+ pxSocket->u.xTCP.usTimeout = 1u; /* to set/clear bSendFullSize */
+ xSendEventToIPTask( eTCPTimerEvent );
+ }
+ }
+ xReturn = 0;
+ break;
+
+ case FREERTOS_SO_STOP_RX: /* Refuse to receive more packts */
+ {
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ break; /* will return -pdFREERTOS_ERRNO_EINVAL */
+ }
+
+ if( *( ( BaseType_t * ) pvOptionValue ) != 0 )
+ {
+ pxSocket->u.xTCP.bits.bRxStopped = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ pxSocket->u.xTCP.bits.bRxStopped = pdFALSE_UNSIGNED;
+ }
+
+ pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
+ pxSocket->u.xTCP.usTimeout = 1u; /* to set/clear bRxStopped */
+ xSendEventToIPTask( eTCPTimerEvent );
+ }
+ xReturn = 0;
+ break;
+
+ #endif /* ipconfigUSE_TCP == 1 */
+
+ default :
+ /* No other options are handled. */
+ xReturn = -pdFREERTOS_ERRNO_ENOPROTOOPT;
+ break;
+ }
+
+ return xReturn;
+} /* Tested */
+
+/*-----------------------------------------------------------*/
+
+/* Find an available port number per https://tools.ietf.org/html/rfc6056. */
+static uint16_t prvGetPrivatePortNumber( BaseType_t xProtocol )
+{
+const uint16_t usEphemeralPortCount =
+ socketAUTO_PORT_ALLOCATION_MAX_NUMBER - socketAUTO_PORT_ALLOCATION_START_NUMBER + 1;
+uint16_t usIterations = usEphemeralPortCount;
+uint32_t ulRandomSeed = 0;
+uint16_t usResult = 0;
+const List_t *pxList;
+
+#if ipconfigUSE_TCP == 1
+ if( xProtocol == ( BaseType_t ) FREERTOS_IPPROTO_TCP )
+ {
+ pxList = &xBoundTCPSocketsList;
+ }
+ else
+#endif
+ {
+ pxList = &xBoundUDPSocketsList;
+ }
+
+ /* Avoid compiler warnings if ipconfigUSE_TCP is not defined. */
+ ( void ) xProtocol;
+
+ /* Find the next available port using the random seed as a starting
+ point. */
+ do
+ {
+ /* Only proceed if the random number generator succeeded. */
+ if( xApplicationGetRandomNumber( &( ulRandomSeed ) ) == pdFALSE )
+ {
+ break;
+ }
+
+ /* Map the random to a candidate port. */
+ usResult =
+ socketAUTO_PORT_ALLOCATION_START_NUMBER +
+ ( ( ( uint16_t )ulRandomSeed ) % usEphemeralPortCount );
+
+ /* Check if there's already an open socket with the same protocol
+ and port. */
+ if( NULL == pxListFindListItemWithValue(
+ pxList,
+ ( TickType_t )FreeRTOS_htons( usResult ) ) )
+ {
+ usResult = FreeRTOS_htons( usResult );
+ break;
+ }
+ else
+ {
+ usResult = 0;
+ }
+
+ usIterations--;
+ }
+ while( usIterations > 0 );
+
+ return usResult;
+}
+/*-----------------------------------------------------------*/
+
+/* pxListFindListItemWithValue: find a list item in a bound socket list
+'xWantedItemValue' refers to a port number */
+static const ListItem_t * pxListFindListItemWithValue( const List_t *pxList, TickType_t xWantedItemValue )
+{
+const ListItem_t * pxResult = NULL;
+
+ if( ( xIPIsNetworkTaskReady() != pdFALSE ) && ( pxList != NULL ) )
+ {
+ const ListItem_t *pxIterator;
+ const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( pxList );
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
+ pxIterator != ( const ListItem_t * ) pxEnd;
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ if( listGET_LIST_ITEM_VALUE( pxIterator ) == xWantedItemValue )
+ {
+ pxResult = pxIterator;
+ break;
+ }
+ }
+ }
+
+ return pxResult;
+} /* Tested */
+
+/*-----------------------------------------------------------*/
+
+FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort )
+{
+const ListItem_t *pxListItem;
+FreeRTOS_Socket_t *pxSocket = NULL;
+
+ /* Looking up a socket is quite simple, find a match with the local port.
+
+ See if there is a list item associated with the port number on the
+ list of bound sockets. */
+ pxListItem = pxListFindListItemWithValue( &xBoundUDPSocketsList, ( TickType_t ) uxLocalPort );
+
+ if( pxListItem != NULL )
+ {
+ /* The owner of the list item is the socket itself. */
+ pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxListItem );
+ configASSERT( pxSocket != NULL );
+ }
+ return pxSocket;
+}
+
+/*-----------------------------------------------------------*/
+
+#if ipconfigINCLUDE_FULL_INET_ADDR == 1
+
+ uint32_t FreeRTOS_inet_addr( const char * pcIPAddress )
+ {
+ const uint32_t ulDecimalBase = 10u;
+ uint8_t ucOctet[ socketMAX_IP_ADDRESS_OCTETS ];
+ const char *pcPointerOnEntering;
+ uint32_t ulReturn = 0UL, ulValue;
+ UBaseType_t uxOctetNumber;
+ BaseType_t xResult = pdPASS;
+
+ for( uxOctetNumber = 0u; uxOctetNumber < socketMAX_IP_ADDRESS_OCTETS; uxOctetNumber++ )
+ {
+ ulValue = 0ul;
+ pcPointerOnEntering = pcIPAddress;
+
+ while( ( *pcIPAddress >= '0' ) && ( *pcIPAddress <= '9' ) )
+ {
+ /* Move previous read characters into the next decimal
+ position. */
+ ulValue *= ulDecimalBase;
+
+ /* Add the binary value of the ascii character. */
+ ulValue += ( ( uint32_t ) ( *pcIPAddress ) - ( uint32_t ) '0' );
+
+ /* Move to next character in the string. */
+ pcIPAddress++;
+ }
+
+ /* Check characters were read. */
+ if( pcIPAddress == pcPointerOnEntering )
+ {
+ xResult = pdFAIL;
+ }
+
+ /* Check the value fits in an 8-bit number. */
+ if( ulValue > 0xffUL )
+ {
+ xResult = pdFAIL;
+ }
+ else
+ {
+ ucOctet[ uxOctetNumber ] = ( uint8_t ) ulValue;
+
+ /* Check the next character is as expected. */
+ if( uxOctetNumber < ( socketMAX_IP_ADDRESS_OCTETS - 1u ) )
+ {
+ if( *pcIPAddress != '.' )
+ {
+ xResult = pdFAIL;
+ }
+ else
+ {
+ /* Move past the dot. */
+ pcIPAddress++;
+ }
+ }
+ }
+
+ if( xResult == pdFAIL )
+ {
+ /* No point going on. */
+ break;
+ }
+ }
+
+ if( *pcIPAddress != ( char ) 0 )
+ {
+ /* Expected the end of the string. */
+ xResult = pdFAIL;
+ }
+
+ if( uxOctetNumber != socketMAX_IP_ADDRESS_OCTETS )
+ {
+ /* Didn't read enough octets. */
+ xResult = pdFAIL;
+ }
+
+ if( xResult == pdPASS )
+ {
+ ulReturn = FreeRTOS_inet_addr_quick( ucOctet[ 0 ], ucOctet[ 1 ], ucOctet[ 2 ], ucOctet[ 3 ] );
+ }
+
+ return ulReturn;
+ }
+
+#endif /* ipconfigINCLUDE_FULL_INET_ADDR */
+
+/*-----------------------------------------------------------*/
+
+/* Function to get the local address and IP port */
+size_t FreeRTOS_GetLocalAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress )
+{
+FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+
+ /* IP address of local machine. */
+ pxAddress->sin_addr = *ipLOCAL_IP_ADDRESS_POINTER;
+
+ /* Local port on this machine. */
+ pxAddress->sin_port = FreeRTOS_htons( pxSocket->usLocalPort );
+
+ return sizeof( *pxAddress );
+}
+
+/*-----------------------------------------------------------*/
+
+void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket )
+{
+/* _HT_ must work this out, now vSocketWakeUpUser will be called for any important
+ * event or transition */
+ #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
+ {
+ if( pxSocket->pxUserSemaphore != NULL )
+ {
+ xSemaphoreGive( pxSocket->pxUserSemaphore );
+ }
+ }
+ #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
+
+ #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
+ {
+ if( pxSocket->pxUserWakeCallback != NULL )
+ {
+ pxSocket->pxUserWakeCallback( pxSocket );
+ }
+ }
+ #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ if( pxSocket->pxSocketSet != NULL )
+ {
+ EventBits_t xSelectBits = ( pxSocket->xEventBits >> SOCKET_EVENT_BIT_COUNT ) & eSELECT_ALL;
+ if( xSelectBits != 0ul )
+ {
+ pxSocket->xSocketBits |= xSelectBits;
+ xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, xSelectBits );
+ }
+ }
+
+ pxSocket->xEventBits &= eSOCKET_ALL;
+ }
+ #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+
+ if( ( pxSocket->xEventGroup != NULL ) && ( pxSocket->xEventBits != 0u ) )
+ {
+ xEventGroupSetBits( pxSocket->xEventGroup, pxSocket->xEventBits );
+ }
+
+ pxSocket->xEventBits = 0ul;
+}
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
+
+ /* This define makes it possible for network-card drivers to inspect
+ * UDP message and see if there is any UDP socket bound to a given port
+ * number.
+ * This is probably only usefull in systems with a minimum of RAM and
+ * when lots of anonymous broadcast messages come in
+ */
+ BaseType_t xPortHasUDPSocket( uint16_t usPortNr )
+ {
+ BaseType_t xFound = pdFALSE;
+
+ vTaskSuspendAll();
+ {
+ if( ( pxListFindListItemWithValue( &xBoundUDPSocketsList, ( TickType_t ) usPortNr ) != NULL ) )
+ {
+ xFound = pdTRUE;
+ }
+ }
+ xTaskResumeAll();
+
+ return xFound;
+ }
+
+#endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ static BaseType_t bMayConnect( FreeRTOS_Socket_t *pxSocket );
+ static BaseType_t bMayConnect( FreeRTOS_Socket_t *pxSocket )
+ {
+ switch( pxSocket->u.xTCP.ucTCPState )
+ {
+ case eCLOSED:
+ case eCLOSE_WAIT: return 0;
+ case eCONNECT_SYN: return -pdFREERTOS_ERRNO_EINPROGRESS;
+ default: return -pdFREERTOS_ERRNO_EAGAIN;
+ }
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ static BaseType_t prvTCPConnectStart( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr *pxAddress )
+ {
+ BaseType_t xResult = 0;
+
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdFALSE )
+ {
+ /* Not a valid socket or wrong type */
+ xResult = -pdFREERTOS_ERRNO_EBADF;
+ }
+ else if( FreeRTOS_issocketconnected( pxSocket ) > 0 )
+ {
+ /* The socket is already connected. */
+ xResult = -pdFREERTOS_ERRNO_EISCONN;
+ }
+ else if( socketSOCKET_IS_BOUND( pxSocket ) == pdFALSE )
+ {
+ /* Bind the socket to the port that the client task will send from.
+ Non-standard, so the error returned is that returned by bind(). */
+ xResult = FreeRTOS_bind( ( Socket_t ) pxSocket, NULL, 0u );
+ }
+
+ if( xResult == 0 )
+ {
+ /* Check if it makes any sense to wait for a connect event, this condition
+ might change while sleeping, so it must be checked within each loop */
+ xResult = bMayConnect( pxSocket ); /* -EINPROGRESS, -EAGAIN, or 0 for OK */
+
+ /* Start the connect procedure, kernel will start working on it */
+ if( xResult == 0 )
+ {
+ pxSocket->u.xTCP.bits.bConnPrepared = pdFALSE_UNSIGNED;
+ pxSocket->u.xTCP.ucRepCount = 0u;
+
+ FreeRTOS_debug_printf( ( "FreeRTOS_connect: %u to %lxip:%u\n",
+ pxSocket->usLocalPort, FreeRTOS_ntohl( pxAddress->sin_addr ), FreeRTOS_ntohs( pxAddress->sin_port ) ) );
+
+ /* Port on remote machine. */
+ pxSocket->u.xTCP.usRemotePort = FreeRTOS_ntohs( pxAddress->sin_port );
+
+ /* IP address of remote machine. */
+ pxSocket->u.xTCP.ulRemoteIP = FreeRTOS_ntohl( pxAddress->sin_addr );
+
+ /* (client) internal state: socket wants to send a connect. */
+ vTCPStateChange( pxSocket, eCONNECT_SYN );
+
+ /* To start an active connect. */
+ pxSocket->u.xTCP.usTimeout = 1u;
+
+ if( xSendEventToIPTask( eTCPTimerEvent ) != pdPASS )
+ {
+ xResult = -pdFREERTOS_ERRNO_ECANCELED;
+ }
+ }
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * FreeRTOS_connect: socket wants to connect to a remote port
+ */
+ BaseType_t FreeRTOS_connect( Socket_t xClientSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t* ) xClientSocket;
+ TickType_t xRemainingTime;
+ BaseType_t xTimed = pdFALSE;
+ BaseType_t xResult;
+ TimeOut_t xTimeOut;
+
+ ( void ) xAddressLength;
+
+ xResult = prvTCPConnectStart( pxSocket, pxAddress );
+
+ if( xResult == 0 )
+ {
+ /* And wait for the result */
+ for( ;; )
+ {
+ if( xTimed == pdFALSE )
+ {
+ /* Only in the first round, check for non-blocking */
+ xRemainingTime = pxSocket->xReceiveBlockTime;
+ if( xRemainingTime == ( TickType_t )0 )
+ {
+ /* Not yet connected, correct state, non-blocking. */
+ xResult = -pdFREERTOS_ERRNO_EWOULDBLOCK;
+ break;
+ }
+
+ /* Don't get here a second time. */
+ xTimed = pdTRUE;
+
+ /* Fetch the current time */
+ vTaskSetTimeOutState( &xTimeOut );
+ }
+
+ /* Did it get connected while sleeping ? */
+ xResult = FreeRTOS_issocketconnected( pxSocket );
+
+ /* Returns positive when connected, negative means an error */
+ if( xResult < 0 )
+ {
+ /* Return the error */
+ break;
+ }
+
+ if( xResult > 0 )
+ {
+ /* Socket now connected, return a zero */
+ xResult = 0;
+ break;
+ }
+
+ /* Is it allowed to sleep more? */
+ if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) )
+ {
+ xResult = -pdFREERTOS_ERRNO_ETIMEDOUT;
+ break;
+ }
+
+ /* Go sleeping until we get any down-stream event */
+ xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_CONNECT, pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
+ }
+ }
+
+ return xResult;
+ }
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * FreeRTOS_accept: can return a new connected socket
+ * if the server socket is in listen mode and receives a connection request
+ * The new socket will be bound already to the same port number as the listing
+ * socket.
+ */
+ Socket_t FreeRTOS_accept( Socket_t xServerSocket, struct freertos_sockaddr *pxAddress, socklen_t *pxAddressLength )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xServerSocket;
+ FreeRTOS_Socket_t *pxClientSocket = NULL;
+ TickType_t xRemainingTime;
+ BaseType_t xTimed = pdFALSE, xAsk = pdFALSE;
+ TimeOut_t xTimeOut;
+ IPStackEvent_t xAskEvent;
+
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
+ {
+ /* Not a valid socket or wrong type */
+ pxClientSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
+ }
+ else if( ( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) &&
+ ( pxSocket->u.xTCP.ucTCPState != eTCP_LISTEN ) )
+ {
+ /* Parent socket is not in listening mode */
+ pxClientSocket = ( FreeRTOS_Socket_t * ) FREERTOS_INVALID_SOCKET;
+ }
+ else
+ {
+ /* Loop will stop with breaks. */
+ for( ; ; )
+ {
+ /* Is there a new client? */
+ vTaskSuspendAll();
+ {
+ if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
+ {
+ pxClientSocket = pxSocket->u.xTCP.pxPeerSocket;
+ }
+ else
+ {
+ pxClientSocket = pxSocket;
+ }
+ if( pxClientSocket != NULL )
+ {
+ pxSocket->u.xTCP.pxPeerSocket = NULL;
+
+ /* Is it still not taken ? */
+ if( pxClientSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED )
+ {
+ pxClientSocket->u.xTCP.bits.bPassAccept = pdFALSE_UNSIGNED;
+ }
+ else
+ {
+ pxClientSocket = NULL;
+ }
+ }
+ }
+ xTaskResumeAll();
+
+ if( pxClientSocket != NULL )
+ {
+ if( pxAddress != NULL )
+ {
+ /* IP address of remote machine. */
+ pxAddress->sin_addr = FreeRTOS_ntohl( pxClientSocket->u.xTCP.ulRemoteIP );
+
+ /* Port on remote machine. */
+ pxAddress->sin_port = FreeRTOS_ntohs( pxClientSocket->u.xTCP.usRemotePort );
+ }
+ if( pxAddressLength != NULL )
+ {
+ *pxAddressLength = sizeof( *pxAddress );
+ }
+
+ if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
+ {
+ xAsk = pdTRUE;
+ }
+ }
+
+ if( xAsk != pdFALSE )
+ {
+ /* Ask to set an event in 'xEventGroup' as soon as a new
+ client gets connected for this listening socket. */
+ xAskEvent.eEventType = eTCPAcceptEvent;
+ xAskEvent.pvData = ( void * ) pxSocket;
+ xSendEventStructToIPTask( &xAskEvent, portMAX_DELAY );
+ }
+
+ if( pxClientSocket != NULL )
+ {
+ break;
+ }
+
+ if( xTimed == pdFALSE )
+ {
+ /* Only in the first round, check for non-blocking */
+ xRemainingTime = pxSocket->xReceiveBlockTime;
+ if( xRemainingTime == ( TickType_t ) 0 )
+ {
+ break;
+ }
+
+ /* Don't get here a second time */
+ xTimed = pdTRUE;
+
+ /* Fetch the current time */
+ vTaskSetTimeOutState( &xTimeOut );
+ }
+
+ /* Has the timeout been reached? */
+ if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
+ {
+ break;
+ }
+
+ /* Go sleeping until we get any down-stream event */
+ xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_ACCEPT, pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
+ }
+ }
+
+ return ( Socket_t ) pxClientSocket;
+ }
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * Read incoming data from a TCP socket
+ * Only after the last byte has been read, a close error might be returned
+ */
+ BaseType_t FreeRTOS_recv( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags )
+ {
+ BaseType_t xByteCount;
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ TickType_t xRemainingTime;
+ BaseType_t xTimed = pdFALSE;
+ TimeOut_t xTimeOut;
+ EventBits_t xEventBits = ( EventBits_t ) 0;
+
+ /* Check if the socket is valid, has type TCP and if it is bound to a
+ port. */
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
+ {
+ xByteCount = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ if( pxSocket->u.xTCP.rxStream != NULL )
+ {
+ xByteCount = ( BaseType_t )uxStreamBufferGetSize ( pxSocket->u.xTCP.rxStream );
+ }
+ else
+ {
+ xByteCount = 0;
+ }
+
+ while( xByteCount == 0 )
+ {
+ switch( pxSocket->u.xTCP.ucTCPState )
+ {
+ case eCLOSED:
+ case eCLOSE_WAIT: /* (server + client) waiting for a connection termination request from the local user. */
+ case eCLOSING: /* (server + client) waiting for a connection termination request acknowledgement from the remote TCP. */
+ if( pxSocket->u.xTCP.bits.bMallocError != pdFALSE_UNSIGNED )
+ {
+ /* The no-memory error has priority above the non-connected error.
+ Both are fatal and will elad to closing the socket. */
+ xByteCount = -pdFREERTOS_ERRNO_ENOMEM;
+ }
+ else
+ {
+ xByteCount = -pdFREERTOS_ERRNO_ENOTCONN;
+ }
+ /* Call continue to break out of the switch and also the while
+ loop. */
+ continue;
+ default:
+ break;
+ }
+
+ if( xTimed == pdFALSE )
+ {
+ /* Only in the first round, check for non-blocking. */
+ xRemainingTime = pxSocket->xReceiveBlockTime;
+
+ if( xRemainingTime == ( TickType_t ) 0 )
+ {
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ /* Just check for the interrupt flag. */
+ xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_INTR,
+ pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, socketDONT_BLOCK );
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+ break;
+ }
+
+ if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
+ {
+ break;
+ }
+
+ /* Don't get here a second time. */
+ xTimed = pdTRUE;
+
+ /* Fetch the current time. */
+ vTaskSetTimeOutState( &xTimeOut );
+ }
+
+ /* Has the timeout been reached? */
+ if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
+ {
+ break;
+ }
+
+ /* Block until there is a down-stream event. */
+ xEventBits = xEventGroupWaitBits( pxSocket->xEventGroup,
+ eSOCKET_RECEIVE | eSOCKET_CLOSED | eSOCKET_INTR,
+ pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ if( ( xEventBits & eSOCKET_INTR ) != 0u )
+ {
+ break;
+ }
+ }
+ #else
+ {
+ ( void ) xEventBits;
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+
+ if( pxSocket->u.xTCP.rxStream != NULL )
+ {
+ xByteCount = ( BaseType_t ) uxStreamBufferGetSize ( pxSocket->u.xTCP.rxStream );
+ }
+ else
+ {
+ xByteCount = 0;
+ }
+ }
+
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ if( ( xEventBits & eSOCKET_INTR ) != 0 )
+ {
+ if( ( xEventBits & ( eSOCKET_RECEIVE | eSOCKET_CLOSED ) ) != 0 )
+ {
+ /* Shouldn't have cleared other flags. */
+ xEventBits &= ~eSOCKET_INTR;
+ xEventGroupSetBits( pxSocket->xEventGroup, xEventBits );
+ }
+ xByteCount = -pdFREERTOS_ERRNO_EINTR;
+ }
+ else
+ #endif /* ipconfigSUPPORT_SIGNALS */
+ if( xByteCount > 0 )
+ {
+ if( ( xFlags & FREERTOS_ZERO_COPY ) == 0 )
+ {
+ xByteCount = ( BaseType_t ) uxStreamBufferGet( pxSocket->u.xTCP.rxStream, 0ul, ( uint8_t * ) pvBuffer, ( size_t ) xBufferLength, ( xFlags & FREERTOS_MSG_PEEK ) != 0 );
+ if( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED )
+ {
+ /* We had reached the low-water mark, now see if the flag
+ can be cleared */
+ size_t uxFrontSpace = uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
+
+ if( uxFrontSpace >= pxSocket->u.xTCP.uxEnoughSpace )
+ {
+ pxSocket->u.xTCP.bits.bLowWater = pdFALSE_UNSIGNED;
+ pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
+ pxSocket->u.xTCP.usTimeout = 1u; /* because bLowWater is cleared. */
+ xSendEventToIPTask( eTCPTimerEvent );
+ }
+ }
+ }
+ else
+ {
+ /* Zero-copy reception of data: pvBuffer is a pointer to a pointer. */
+ xByteCount = ( BaseType_t ) uxStreamBufferGetPtr( pxSocket->u.xTCP.rxStream, (uint8_t **)pvBuffer );
+ }
+ }
+ } /* prvValidSocket() */
+
+ return xByteCount;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ static int32_t prvTCPSendCheck( FreeRTOS_Socket_t *pxSocket, size_t xDataLength )
+ {
+ int32_t xResult = 1;
+
+ /* Is this a socket of type TCP and is it already bound to a port number ? */
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
+ {
+ xResult = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else if( pxSocket->u.xTCP.bits.bMallocError != pdFALSE_UNSIGNED )
+ {
+ xResult = -pdFREERTOS_ERRNO_ENOMEM;
+ }
+ else if( pxSocket->u.xTCP.ucTCPState == eCLOSED ||
+ pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ||
+ pxSocket->u.xTCP.ucTCPState == eCLOSING )
+ {
+ xResult = -pdFREERTOS_ERRNO_ENOTCONN;
+ }
+ else if( pxSocket->u.xTCP.bits.bFinSent != pdFALSE_UNSIGNED )
+ {
+ /* This TCP connection is closing already, the FIN flag has been sent.
+ Maybe it is still delivering or receiving data.
+ Return OK in order not to get closed/deleted too quickly */
+ xResult = 0;
+ }
+ else if( xDataLength == 0ul )
+ {
+ /* send() is being called to send zero bytes */
+ xResult = 0;
+ }
+ else if( pxSocket->u.xTCP.txStream == NULL )
+ {
+ /* Create the outgoing stream only when it is needed */
+ prvTCPCreateStream( pxSocket, pdFALSE );
+
+ if( pxSocket->u.xTCP.txStream == NULL )
+ {
+ xResult = -pdFREERTOS_ERRNO_ENOMEM;
+ }
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* Get a direct pointer to the circular transmit buffer.
+ '*pxLength' will contain the number of bytes that may be written. */
+ uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength )
+ {
+ uint8_t *pucReturn = NULL;
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ StreamBuffer_t *pxBuffer = NULL;
+
+ *pxLength = 0;
+
+ /* Confirm that this is a TCP socket before dereferencing structure
+ member pointers. */
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
+ {
+ pxBuffer = pxSocket->u.xTCP.txStream;
+ if( pxBuffer != NULL )
+ {
+ BaseType_t xSpace = ( BaseType_t )uxStreamBufferGetSpace( pxBuffer );
+ BaseType_t xRemain = ( BaseType_t )( pxBuffer->LENGTH - pxBuffer->uxHead );
+
+ *pxLength = FreeRTOS_min_BaseType( xSpace, xRemain );
+ pucReturn = pxBuffer->ucArray + pxBuffer->uxHead;
+ }
+ }
+
+ return pucReturn;
+ }
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+ /*
+ * Send data using a TCP socket. It is not necessary to have the socket
+ * connected already. Outgoing data will be stored and delivered as soon as
+ * the socket gets connected.
+ */
+ BaseType_t FreeRTOS_send( Socket_t xSocket, const void *pvBuffer, size_t uxDataLength, BaseType_t xFlags )
+ {
+ BaseType_t xByteCount;
+ BaseType_t xBytesLeft;
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ TickType_t xRemainingTime;
+ BaseType_t xTimed = pdFALSE;
+ TimeOut_t xTimeOut;
+ BaseType_t xCloseAfterSend;
+
+ /* Prevent compiler warnings about unused parameters. The parameter
+ may be used in future versions. */
+ ( void ) xFlags;
+
+ xByteCount = ( BaseType_t ) prvTCPSendCheck( pxSocket, uxDataLength );
+
+ if( xByteCount > 0 )
+ {
+ /* xBytesLeft is number of bytes to send, will count to zero. */
+ xBytesLeft = ( BaseType_t ) uxDataLength;
+
+ /* xByteCount is number of bytes that can be sent now. */
+ xByteCount = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
+
+ /* While there are still bytes to be sent. */
+ while( xBytesLeft > 0 )
+ {
+ /* If txStream has space. */
+ if( xByteCount > 0 )
+ {
+ /* Don't send more than necessary. */
+ if( xByteCount > xBytesLeft )
+ {
+ xByteCount = xBytesLeft;
+ }
+
+ /* Is the close-after-send flag set and is this really the
+ last transmission? */
+ if( ( pxSocket->u.xTCP.bits.bCloseAfterSend != pdFALSE_UNSIGNED ) && ( xByteCount == xBytesLeft ) )
+ {
+ xCloseAfterSend = pdTRUE;
+ }
+ else
+ {
+ xCloseAfterSend = pdFALSE;
+ }
+
+ /* The flag 'bCloseAfterSend' can be set before sending data
+ using setsockopt()
+
+ When the last data packet is being sent out, a FIN flag will
+ be included to let the peer know that no more data is to be
+ expected. The use of 'bCloseAfterSend' is not mandatory, it
+ is just a faster way of transferring files (e.g. when using
+ FTP). */
+ if( xCloseAfterSend != pdFALSE )
+ {
+ /* Now suspend the scheduler: sending the last data and
+ setting bCloseRequested must be done together */
+ vTaskSuspendAll();
+ pxSocket->u.xTCP.bits.bCloseRequested = pdTRUE_UNSIGNED;
+ }
+
+ xByteCount = ( BaseType_t ) uxStreamBufferAdd( pxSocket->u.xTCP.txStream, 0ul, ( const uint8_t * ) pvBuffer, ( size_t ) xByteCount );
+
+ if( xCloseAfterSend != pdFALSE )
+ {
+ /* Now when the IP-task transmits the data, it will also
+ see that bCloseRequested is true and include the FIN
+ flag to start closure of the connection. */
+ xTaskResumeAll();
+ }
+
+ /* Send a message to the IP-task so it can work on this
+ socket. Data is sent, let the IP-task work on it. */
+ pxSocket->u.xTCP.usTimeout = 1u;
+
+ if( xIsCallingFromIPTask() == pdFALSE )
+ {
+ /* Only send a TCP timer event when not called from the
+ IP-task. */
+ xSendEventToIPTask( eTCPTimerEvent );
+ }
+
+ xBytesLeft -= xByteCount;
+
+ if( xBytesLeft == 0 )
+ {
+ break;
+ }
+
+ /* As there are still bytes left to be sent, increase the
+ data pointer. */
+ pvBuffer = ( void * ) ( ( ( const uint8_t * ) pvBuffer) + xByteCount );
+ }
+
+ /* Not all bytes have been sent. In case the socket is marked as
+ blocking sleep for a while. */
+ if( xTimed == pdFALSE )
+ {
+ /* Only in the first round, check for non-blocking. */
+ xRemainingTime = pxSocket->xSendBlockTime;
+
+ #if( ipconfigUSE_CALLBACKS != 0 )
+ {
+ if( xIsCallingFromIPTask() != pdFALSE )
+ {
+ /* If this send function is called from within a
+ call-back handler it may not block, otherwise
+ chances would be big to get a deadlock: the IP-task
+ waiting for itself. */
+ xRemainingTime = ( TickType_t ) 0;
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ if( xRemainingTime == ( TickType_t ) 0 )
+ {
+ break;
+ }
+
+ if( ( xFlags & FREERTOS_MSG_DONTWAIT ) != 0 )
+ {
+ break;
+ }
+
+ /* Don't get here a second time. */
+ xTimed = pdTRUE;
+
+ /* Fetch the current time. */
+ vTaskSetTimeOutState( &xTimeOut );
+ }
+ else
+ {
+ /* Has the timeout been reached? */
+ if( xTaskCheckForTimeOut( &xTimeOut, &xRemainingTime ) != pdFALSE )
+ {
+ break;
+ }
+ }
+
+ /* Go sleeping until down-stream events are received. */
+ xEventGroupWaitBits( pxSocket->xEventGroup, eSOCKET_SEND | eSOCKET_CLOSED,
+ pdTRUE /*xClearOnExit*/, pdFALSE /*xWaitAllBits*/, xRemainingTime );
+
+ xByteCount = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
+ }
+
+ /* How much was actually sent? */
+ xByteCount = ( ( BaseType_t ) uxDataLength ) - xBytesLeft;
+
+ if( xByteCount == 0 )
+ {
+ if( pxSocket->u.xTCP.ucTCPState > eESTABLISHED )
+ {
+ xByteCount = ( BaseType_t ) -pdFREERTOS_ERRNO_ENOTCONN;
+ }
+ else
+ {
+ if( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE )
+ {
+ FreeRTOS_debug_printf( ( "FreeRTOS_send: %u -> %lxip:%d: no space\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort ) );
+ }
+
+ xByteCount = ( BaseType_t ) -pdFREERTOS_ERRNO_ENOSPC;
+ }
+ }
+ }
+
+ return xByteCount;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * Request to put a socket in listen mode
+ */
+ BaseType_t FreeRTOS_listen( Socket_t xSocket, BaseType_t xBacklog )
+ {
+ FreeRTOS_Socket_t *pxSocket;
+ BaseType_t xResult = 0;
+
+ pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+
+ /* listen() is allowed for a valid TCP socket in Closed state and already
+ bound. */
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
+ {
+ xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
+ }
+ else if( ( pxSocket->u.xTCP.ucTCPState != eCLOSED ) && ( pxSocket->u.xTCP.ucTCPState != eCLOSE_WAIT ) )
+ {
+ /* Socket is in a wrong state. */
+ xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
+ }
+ else
+ {
+ /* Backlog is interpreted here as "the maximum number of child
+ sockets. */
+ pxSocket->u.xTCP.usBacklog = ( uint16_t )FreeRTOS_min_int32( ( int32_t ) 0xffff, ( int32_t ) xBacklog );
+
+ /* This cleaning is necessary only if a listening socket is being
+ reused as it might have had a previous connection. */
+ if( pxSocket->u.xTCP.bits.bReuseSocket )
+ {
+ if( pxSocket->u.xTCP.rxStream != NULL )
+ {
+ vStreamBufferClear( pxSocket->u.xTCP.rxStream );
+ }
+
+ if( pxSocket->u.xTCP.txStream != NULL )
+ {
+ vStreamBufferClear( pxSocket->u.xTCP.txStream );
+ }
+
+ memset( pxSocket->u.xTCP.xPacket.u.ucLastPacket, '\0', sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
+ memset( &pxSocket->u.xTCP.xTCPWindow, '\0', sizeof( pxSocket->u.xTCP.xTCPWindow ) );
+ memset( &pxSocket->u.xTCP.bits, '\0', sizeof( pxSocket->u.xTCP.bits ) );
+
+ /* Now set the bReuseSocket flag again, because the bits have
+ just been cleared. */
+ pxSocket->u.xTCP.bits.bReuseSocket = pdTRUE_UNSIGNED;
+ }
+
+ vTCPStateChange( pxSocket, eTCP_LISTEN );
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* shutdown - shut down part of a full-duplex connection */
+ BaseType_t FreeRTOS_shutdown( Socket_t xSocket, BaseType_t xHow )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xResult;
+
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdTRUE ) == pdFALSE )
+ {
+ /*_RB_ Is this comment correct? The socket is not of a type that
+ supports the listen() operation. */
+ xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
+ }
+ else if ( pxSocket->u.xTCP.ucTCPState != eESTABLISHED )
+ {
+ /*_RB_ Is this comment correct? The socket is not of a type that
+ supports the listen() operation. */
+ xResult = -pdFREERTOS_ERRNO_EOPNOTSUPP;
+ }
+ else
+ {
+ pxSocket->u.xTCP.bits.bUserShutdown = pdTRUE_UNSIGNED;
+
+ /* Let the IP-task perform the shutdown of the connection. */
+ pxSocket->u.xTCP.usTimeout = 1u;
+ xSendEventToIPTask( eTCPTimerEvent );
+ xResult = 0;
+ }
+ (void) xHow;
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * A TCP timer has expired, now check all TCP sockets for:
+ * - Active connect
+ * - Send a delayed ACK
+ * - Send new data
+ * - Send a keep-alive packet
+ * - Check for timeout (in non-connected states only)
+ */
+ TickType_t xTCPTimerCheck( BaseType_t xWillSleep )
+ {
+ FreeRTOS_Socket_t *pxSocket;
+ TickType_t xShortest = pdMS_TO_TICKS( ( TickType_t ) ipTCP_TIMER_PERIOD_MS );
+ TickType_t xNow = xTaskGetTickCount();
+ static TickType_t xLastTime = 0u;
+ TickType_t xDelta = xNow - xLastTime;
+ ListItem_t* pxEnd = ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
+ ListItem_t *pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
+
+ xLastTime = xNow;
+
+ if( xDelta == 0u )
+ {
+ xDelta = 1u;
+ }
+
+ while( pxIterator != pxEnd )
+ {
+ pxSocket = ( FreeRTOS_Socket_t * )listGET_LIST_ITEM_OWNER( pxIterator );
+ pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator );
+
+ /* Sockets with 'tmout == 0' do not need any regular attention. */
+ if( pxSocket->u.xTCP.usTimeout == 0u )
+ {
+ continue;
+ }
+
+ if( xDelta < ( TickType_t ) pxSocket->u.xTCP.usTimeout )
+ {
+ pxSocket->u.xTCP.usTimeout = ( uint16_t ) ( ( ( TickType_t ) pxSocket->u.xTCP.usTimeout ) - xDelta );
+ }
+ else
+ {
+ int rc ;
+ pxSocket->u.xTCP.usTimeout = 0u;
+ rc = xTCPSocketCheck( pxSocket );
+
+ /* Within this function, the socket might want to send a delayed
+ ack or send out data or whatever it needs to do. */
+ if( rc < 0 )
+ {
+ /* Continue because the socket was deleted. */
+ continue;
+ }
+ }
+
+ /* In xEventBits the driver may indicate that the socket has
+ important events for the user. These are only done just before the
+ IP-task goes to sleep. */
+ if( pxSocket->xEventBits != 0u )
+ {
+ if( xWillSleep != pdFALSE )
+ {
+ /* The IP-task is about to go to sleep, so messages can be
+ sent to the socket owners. */
+ vSocketWakeUpUser( pxSocket );
+ }
+ else
+ {
+ /* Or else make sure this will be called again to wake-up
+ the sockets' owner. */
+ xShortest = ( TickType_t ) 0;
+ }
+ }
+
+ if( ( pxSocket->u.xTCP.usTimeout != 0u ) && ( xShortest > ( TickType_t ) pxSocket->u.xTCP.usTimeout ) )
+ {
+ xShortest = ( TickType_t ) pxSocket->u.xTCP.usTimeout;
+ }
+ }
+
+ return xShortest;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * TCP: as multiple sockets may be bound to the same local port number
+ * looking up a socket is a little more complex:
+ * Both a local port, and a remote port and IP address are being used
+ * For a socket in listening mode, the remote port and IP address are both 0
+ */
+ FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort )
+ {
+ ListItem_t *pxIterator;
+ FreeRTOS_Socket_t *pxResult = NULL, *pxListenSocket = NULL;
+ MiniListItem_t *pxEnd = ( MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
+
+ /* Parameter not yet supported. */
+ ( void ) ulLocalIP;
+
+ for( pxIterator = ( ListItem_t * ) listGET_NEXT( pxEnd );
+ pxIterator != ( ListItem_t * ) pxEnd;
+ pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ if( pxSocket->usLocalPort == ( uint16_t ) uxLocalPort )
+ {
+ if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
+ {
+ /* If this is a socket listening to uxLocalPort, remember it
+ in case there is no perfect match. */
+ pxListenSocket = pxSocket;
+ }
+ else if( ( pxSocket->u.xTCP.usRemotePort == ( uint16_t ) uxRemotePort ) && ( pxSocket->u.xTCP.ulRemoteIP == ulRemoteIP ) )
+ {
+ /* For sockets not in listening mode, find a match with
+ xLocalPort, ulRemoteIP AND xRemotePort. */
+ pxResult = pxSocket;
+ break;
+ }
+ }
+ }
+ if( pxResult == NULL )
+ {
+ /* An exact match was not found, maybe a listening socket was
+ found. */
+ pxResult = pxListenSocket;
+ }
+
+ return pxResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * )xSocket;
+ struct xSTREAM_BUFFER *pxReturn = NULL;
+
+ /* Confirm that this is a TCP socket before dereferencing structure
+ member pointers. */
+ if( prvValidSocket( pxSocket, FREERTOS_IPPROTO_TCP, pdFALSE ) == pdTRUE )
+ {
+ pxReturn = pxSocket->u.xTCP.rxStream;
+ }
+
+ return pxReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ static StreamBuffer_t *prvTCPCreateStream ( FreeRTOS_Socket_t *pxSocket, BaseType_t xIsInputStream )
+ {
+ StreamBuffer_t *pxBuffer;
+ size_t uxLength;
+ size_t uxSize;
+
+ /* Now that a stream is created, the maximum size is fixed before
+ creation, it could still be changed with setsockopt(). */
+ if( xIsInputStream != pdFALSE )
+ {
+ uxLength = pxSocket->u.xTCP.uxRxStreamSize;
+
+ if( pxSocket->u.xTCP.uxLittleSpace == 0ul )
+ {
+ pxSocket->u.xTCP.uxLittleSpace = ( sock20_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
+ }
+
+ if( pxSocket->u.xTCP.uxEnoughSpace == 0ul )
+ {
+ pxSocket->u.xTCP.uxEnoughSpace = ( sock80_PERCENT * pxSocket->u.xTCP.uxRxStreamSize ) / sock100_PERCENT;
+ }
+ }
+ else
+ {
+ uxLength = pxSocket->u.xTCP.uxTxStreamSize;
+ }
+
+ /* Add an extra 4 (or 8) bytes. */
+ uxLength += sizeof( size_t );
+
+ /* And make the length a multiple of sizeof( size_t ). */
+ uxLength &= ~( sizeof( size_t ) - 1u );
+
+ uxSize = sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray ) + uxLength;
+
+ pxBuffer = ( StreamBuffer_t * )pvPortMallocLarge( uxSize );
+
+ if( pxBuffer == NULL )
+ {
+ FreeRTOS_debug_printf( ( "prvTCPCreateStream: malloc failed\n" ) );
+ pxSocket->u.xTCP.bits.bMallocError = pdTRUE_UNSIGNED;
+ vTCPStateChange( pxSocket, eCLOSE_WAIT );
+ }
+ else
+ {
+ /* Clear the markers of the stream */
+ memset( pxBuffer, '\0', sizeof( *pxBuffer ) - sizeof( pxBuffer->ucArray ) );
+ pxBuffer->LENGTH = ( size_t ) uxLength ;
+
+ if( xTCPWindowLoggingLevel != 0 )
+ {
+ FreeRTOS_debug_printf( ( "prvTCPCreateStream: %cxStream created %lu bytes (total %lu)\n", xIsInputStream ? 'R' : 'T', uxLength, uxSize ) );
+ }
+
+ if( xIsInputStream != 0 )
+ {
+ pxSocket->u.xTCP.rxStream = pxBuffer;
+ }
+ else
+ {
+ pxSocket->u.xTCP.txStream = pxBuffer;
+ }
+ }
+
+ return pxBuffer;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * Add data to the RxStream. When uxOffset > 0, data has come in out-of-order
+ * and will be put in front of the head so it can not be popped by the user.
+ */
+ int32_t lTCPAddRxdata( FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount )
+ {
+ StreamBuffer_t *pxStream = pxSocket->u.xTCP.rxStream;
+ int32_t xResult;
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ BaseType_t bHasHandler = ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleReceive );
+ const uint8_t *pucBuffer = NULL;
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ /* int32_t uxStreamBufferAdd( pxBuffer, uxOffset, pucData, aCount )
+ if( pucData != NULL ) copy data the the buffer
+ if( pucData == NULL ) no copying, just advance rxHead
+ if( uxOffset != 0 ) Just store data which has come out-of-order
+ if( uxOffset == 0 ) Also advance rxHead */
+ if( pxStream == NULL )
+ {
+ pxStream = prvTCPCreateStream( pxSocket, pdTRUE );
+ if( pxStream == NULL )
+ {
+ return -1;
+ }
+ }
+
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ( bHasHandler != pdFALSE ) && ( uxStreamBufferGetSize( pxStream ) == 0u ) && ( uxOffset == 0ul ) && ( pcData != NULL ) )
+ {
+ /* Data can be passed directly to the user */
+ pucBuffer = pcData;
+
+ /* Zero-copy for call-back: no need to add the bytes to the
+ stream, only the pointer will be advanced by uxStreamBufferAdd(). */
+ pcData = NULL;
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ xResult = ( int32_t ) uxStreamBufferAdd( pxStream, uxOffset, pcData, ( size_t ) ulByteCount );
+
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ if( xResult != ( int32_t ) ulByteCount )
+ {
+ FreeRTOS_debug_printf( ( "lTCPAddRxdata: at %ld: %ld/%lu bytes (tail %lu head %lu space %lu front %lu)\n",
+ uxOffset, xResult, ulByteCount,
+ pxStream->uxTail,
+ pxStream->uxHead,
+ uxStreamBufferFrontSpace( pxStream ),
+ pxStream->uxFront ) );
+ }
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF */
+
+ if( uxOffset == 0u )
+ {
+ /* Data is being added to rxStream at the head (offs = 0) */
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ if( bHasHandler != pdFALSE )
+ {
+ /* The socket owner has installed an OnReceive handler. Pass the
+ Rx data, without copying from the rxStream, to the user. */
+ for (;;)
+ {
+ uint8_t *ucReadPtr = NULL;
+ uint32_t ulCount;
+ if( pucBuffer != NULL )
+ {
+ ucReadPtr = ( uint8_t * )pucBuffer;
+ ulCount = ulByteCount;
+ pucBuffer = NULL;
+ }
+ else
+ {
+ ulCount = ( uint32_t ) uxStreamBufferGetPtr( pxStream, &( ucReadPtr ) );
+ }
+
+ if( ulCount == 0ul )
+ {
+ break;
+ }
+
+ pxSocket->u.xTCP.pxHandleReceive( ( Socket_t )pxSocket, ( void* )ucReadPtr, ( size_t ) ulCount );
+ uxStreamBufferGet( pxStream, 0ul, NULL, ( size_t ) ulCount, pdFALSE );
+ }
+ } else
+ #endif /* ipconfigUSE_CALLBACKS */
+ {
+ /* See if running out of space. */
+ if( pxSocket->u.xTCP.bits.bLowWater == pdFALSE_UNSIGNED )
+ {
+ size_t uxFrontSpace = uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
+ if( uxFrontSpace <= pxSocket->u.xTCP.uxLittleSpace )
+ {
+ pxSocket->u.xTCP.bits.bLowWater = pdTRUE_UNSIGNED;
+ pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
+
+ /* bLowWater was reached, send the changed window size. */
+ pxSocket->u.xTCP.usTimeout = 1u;
+ xSendEventToIPTask( eTCPTimerEvent );
+ }
+ }
+
+ /* New incoming data is available, wake up the user. User's
+ semaphores will be set just before the IP-task goes asleep. */
+ pxSocket->xEventBits |= eSOCKET_RECEIVE;
+
+ #if ipconfigSUPPORT_SELECT_FUNCTION == 1
+ {
+ if( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 )
+ {
+ pxSocket->xEventBits |= ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT );
+ }
+ }
+ #endif
+ }
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* Function to get the remote address and IP port */
+ BaseType_t FreeRTOS_GetRemoteAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xResult;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xResult = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ /* BSD style sockets communicate IP and port addresses in network
+ byte order.
+
+ IP address of remote machine. */
+ pxAddress->sin_addr = FreeRTOS_htonl ( pxSocket->u.xTCP.ulRemoteIP );
+
+ /* Port on remote machine. */
+ pxAddress->sin_port = FreeRTOS_htons ( pxSocket->u.xTCP.usRemotePort );
+
+ xResult = ( BaseType_t ) sizeof( ( *pxAddress ) );
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* Returns the number of bytes that may be added to txStream */
+ BaseType_t FreeRTOS_maywrite( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xResult;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xResult = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else if( pxSocket->u.xTCP.ucTCPState != eESTABLISHED )
+ {
+ if( ( pxSocket->u.xTCP.ucTCPState < eCONNECT_SYN ) || ( pxSocket->u.xTCP.ucTCPState > eESTABLISHED ) )
+ {
+ xResult = -1;
+ }
+ else
+ {
+ xResult = 0;
+ }
+ }
+ else if( pxSocket->u.xTCP.txStream == NULL )
+ {
+ xResult = ( BaseType_t ) pxSocket->u.xTCP.uxTxStreamSize;
+ }
+ else
+ {
+ xResult = ( BaseType_t ) uxStreamBufferGetSpace( pxSocket->u.xTCP.txStream );
+ }
+
+ return xResult;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP ==1 )
+
+ BaseType_t FreeRTOS_tx_space( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ if( pxSocket->u.xTCP.txStream != NULL )
+ {
+ xReturn = ( BaseType_t ) uxStreamBufferGetSpace ( pxSocket->u.xTCP.txStream );
+ }
+ else
+ {
+ xReturn = ( BaseType_t ) pxSocket->u.xTCP.uxTxStreamSize;
+ }
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ BaseType_t FreeRTOS_tx_size( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ if( pxSocket->u.xTCP.txStream != NULL )
+ {
+ xReturn = ( BaseType_t ) uxStreamBufferGetSize ( pxSocket->u.xTCP.txStream );
+ }
+ else
+ {
+ xReturn = 0;
+ }
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* Returns pdTRUE if TCP socket is connected. */
+ BaseType_t FreeRTOS_issocketconnected( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn = pdFALSE;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ if( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED )
+ {
+ if( pxSocket->u.xTCP.ucTCPState < eCLOSE_WAIT )
+ {
+ xReturn = pdTRUE;
+ }
+ }
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* returns the actual size of MSS being used */
+ BaseType_t FreeRTOS_mss( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ /* usCurMSS is declared as uint16_t to save space. FreeRTOS_mss()
+ will often be used in signed native-size expressions cast it to
+ BaseType_t. */
+ xReturn = ( BaseType_t ) ( pxSocket->u.xTCP.usCurMSS );
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /* HT: for internal use only: return the connection status */
+ BaseType_t FreeRTOS_connstatus( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ {
+ /* Cast it to BaseType_t */
+ xReturn = ( BaseType_t ) ( pxSocket->u.xTCP.ucTCPState );
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * Returns the number of bytes which can be read.
+ */
+ BaseType_t FreeRTOS_rx_size( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+
+ if( pxSocket->ucProtocol != ( uint8_t ) FREERTOS_IPPROTO_TCP )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else if( pxSocket->u.xTCP.rxStream != NULL )
+ {
+ xReturn = ( BaseType_t ) uxStreamBufferGetSize( pxSocket->u.xTCP.rxStream );
+ }
+ else
+ {
+ xReturn = 0;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP == 1 )
+
+ void FreeRTOS_netstat( void )
+ {
+ IPStackEvent_t xAskEvent;
+
+ /* Ask the IP-task to call vTCPNetStat()
+ * to avoid accessing xBoundTCPSocketsList
+ */
+ xAskEvent.eEventType = eTCPNetStat;
+ xAskEvent.pvData = ( void * ) NULL;
+ xSendEventStructToIPTask( &xAskEvent, 1000u );
+ }
+
+#endif /* ipconfigUSE_TCP */
+/*-----------------------------------------------------------*/
+
+#if( ( ipconfigHAS_PRINTF != 0 ) && ( ipconfigUSE_TCP == 1 ) )
+
+ void vTCPNetStat( void )
+ {
+ /* Show a simple listing of all created sockets and their connections */
+ ListItem_t *pxIterator;
+ BaseType_t count = 0;
+
+ if( listLIST_IS_INITIALISED( &xBoundTCPSocketsList ) == pdFALSE )
+ {
+ FreeRTOS_printf( ( "PLUS-TCP not initialized\n" ) );
+ }
+ else
+ {
+ FreeRTOS_printf( ( "Prot Port IP-Remote : Port R/T Status Alive tmout Child\n" ) );
+ for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
+ pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
+ pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+ #if( ipconfigTCP_KEEP_ALIVE == 1 )
+ TickType_t age = xTaskGetTickCount() - pxSocket->u.xTCP.xLastAliveTime;
+ #else
+ TickType_t age = 0u;
+ #endif
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ void *pxHandleReceive = (void*)pxSocket->u.xTCP.pxHandleReceive;
+ #else
+ void *pxHandleReceive = (void*)NULL;
+ #endif
+ char ucChildText[16] = "";
+ if (pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN)
+ {
+ const int32_t copied_len = snprintf( ucChildText, sizeof( ucChildText ), " %d/%d",
+ ( int ) pxSocket->u.xTCP.usChildCount,
+ ( int ) pxSocket->u.xTCP.usBacklog);
+ /* These should never evaluate to false since the buffers are both shorter than 5-6 characters (<=65535) */
+ configASSERT( copied_len >= 0 );
+ configASSERT( copied_len < sizeof( ucChildText ) );
+ }
+ FreeRTOS_printf( ( "TCP %5d %-16lxip:%5d %d/%d %-13.13s %6lu %6u%s\n",
+ pxSocket->usLocalPort, /* Local port on this machine */
+ pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine */
+ pxSocket->u.xTCP.usRemotePort, /* Port on remote machine */
+ pxSocket->u.xTCP.rxStream != NULL,
+ pxSocket->u.xTCP.txStream != NULL,
+ FreeRTOS_GetTCPStateName( pxSocket->u.xTCP.ucTCPState ),
+ (age > 999999 ? 999999 : age), /* Format 'age' for printing */
+ pxSocket->u.xTCP.usTimeout,
+ ucChildText ) );
+ /* Remove compiler warnings if FreeRTOS_debug_printf() is not defined. */
+ ( void ) pxHandleReceive;
+ count++;
+ }
+
+ for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundUDPSocketsList );
+ pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundUDPSocketsList );
+ pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ /* Local port on this machine */
+ FreeRTOS_printf( ( "UDP Port %5u\n",
+ FreeRTOS_ntohs( listGET_LIST_ITEM_VALUE( pxIterator ) ) ) );
+ count++;
+ }
+
+ FreeRTOS_printf( ( "FreeRTOS_netstat: %lu sockets %lu < %lu < %d buffers free\n",
+ count,
+ uxGetMinimumFreeNetworkBuffers( ),
+ uxGetNumberOfFreeNetworkBuffers( ),
+ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) );
+ }
+ }
+
+#endif /* ( ( ipconfigHAS_PRINTF != 0 ) && ( ipconfigUSE_TCP == 1 ) ) */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+ void vSocketSelect( SocketSelect_t *pxSocketSet )
+ {
+ BaseType_t xRound;
+ EventBits_t xSocketBits, xBitsToClear;
+ #if ipconfigUSE_TCP == 1
+ BaseType_t xLastRound = 1;
+ #else
+ BaseType_t xLastRound = 0;
+ #endif
+
+ /* These flags will be switched on after checking the socket status. */
+ EventBits_t xGroupBits = 0;
+ pxSocketSet->pxSocket = NULL;
+
+ for( xRound = 0; xRound <= xLastRound; xRound++ )
+ {
+ const ListItem_t *pxIterator;
+ const MiniListItem_t *pxEnd;
+ if( xRound == 0 )
+ {
+ pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundUDPSocketsList );
+ }
+ #if ipconfigUSE_TCP == 1
+ else
+ {
+ pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &xBoundTCPSocketsList );
+ }
+ #endif /* ipconfigUSE_TCP == 1 */
+ for( pxIterator = ( const ListItem_t * ) ( listGET_NEXT( pxEnd ) );
+ pxIterator != ( const ListItem_t * ) pxEnd;
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+ if( pxSocket->pxSocketSet != pxSocketSet )
+ {
+ /* Socket does not belong to this select group. */
+ continue;
+ }
+ xSocketBits = 0;
+
+ #if( ipconfigUSE_TCP == 1 )
+ if( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP )
+ {
+ /* Check if the socket has already been accepted by the
+ owner. If not, it is useless to return it from a
+ select(). */
+ BaseType_t bAccepted = pdFALSE;
+
+ if( pxSocket->u.xTCP.bits.bPassQueued == pdFALSE_UNSIGNED )
+ {
+ if( pxSocket->u.xTCP.bits.bPassAccept == pdFALSE_UNSIGNED )
+ {
+ bAccepted = pdTRUE;
+ }
+ }
+
+ /* Is the set owner interested in READ events? */
+ if( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 )
+ {
+ if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
+ {
+ if( ( pxSocket->u.xTCP.pxPeerSocket != NULL ) && ( pxSocket->u.xTCP.pxPeerSocket->u.xTCP.bits.bPassAccept != 0 ) )
+ {
+ xSocketBits |= eSELECT_READ;
+ }
+ }
+ else if( ( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED ) && ( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
+ {
+ /* This socket has the re-use flag. After connecting it turns into
+ aconnected socket. Set the READ event, so that accept() will be called. */
+ xSocketBits |= eSELECT_READ;
+ }
+ else if( ( bAccepted != 0 ) && ( FreeRTOS_recvcount( pxSocket ) > 0 ) )
+ {
+ xSocketBits |= eSELECT_READ;
+ }
+ }
+ /* Is the set owner interested in EXCEPTION events? */
+ if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
+ {
+ if( ( pxSocket->u.xTCP.ucTCPState == eCLOSE_WAIT ) || ( pxSocket->u.xTCP.ucTCPState == eCLOSED ) )
+ {
+ xSocketBits |= eSELECT_EXCEPT;
+ }
+ }
+
+ /* Is the set owner interested in WRITE events? */
+ if( ( pxSocket->xSelectBits & eSELECT_WRITE ) != 0 )
+ {
+ BaseType_t bMatch = pdFALSE;
+
+ if( bAccepted != 0 )
+ {
+ if( FreeRTOS_tx_space( pxSocket ) > 0 )
+ {
+ bMatch = pdTRUE;
+ }
+ }
+
+ if( bMatch == pdFALSE )
+ {
+ if( ( pxSocket->u.xTCP.bits.bConnPrepared != pdFALSE_UNSIGNED ) &&
+ ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) &&
+ ( pxSocket->u.xTCP.bits.bConnPassed == pdFALSE_UNSIGNED ) )
+ {
+ pxSocket->u.xTCP.bits.bConnPassed = pdTRUE_UNSIGNED;
+ bMatch = pdTRUE;
+ }
+ }
+
+ if( bMatch != pdFALSE )
+ {
+ xSocketBits |= eSELECT_WRITE;
+ }
+ }
+ }
+ else
+ #endif /* ipconfigUSE_TCP == 1 */
+ {
+ /* Select events for UDP are simpler. */
+ if( ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) &&
+ ( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) > 0U ) )
+ {
+ xSocketBits |= eSELECT_READ;
+ }
+ /* The WRITE and EXCEPT bits are not used for UDP */
+ } /* if( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP ) */
+
+ /* Each socket keeps its own event flags, which are looked-up
+ by FreeRTOS_FD_ISSSET() */
+ pxSocket->xSocketBits = xSocketBits;
+
+ /* The ORed value will be used to set the bits in the event
+ group. */
+ xGroupBits |= xSocketBits;
+
+ } /* for( pxIterator ... ) */
+ } /* for( xRound = 0; xRound <= xLastRound; xRound++ ) */
+
+ xBitsToClear = xEventGroupGetBits( pxSocketSet->xSelectGroup );
+
+ /* Now set the necessary bits. */
+ xBitsToClear = ( xBitsToClear & ~xGroupBits ) & eSELECT_ALL;
+
+ #if( ipconfigSUPPORT_SIGNALS != 0 )
+ {
+ /* Maybe the socketset was signalled, but don't
+ clear the 'eSELECT_INTR' bit here, as it will be used
+ and cleared in FreeRTOS_select(). */
+ xBitsToClear &= ( EventBits_t ) ~eSELECT_INTR;
+ }
+ #endif /* ipconfigSUPPORT_SIGNALS */
+
+ if( xBitsToClear != 0 )
+ {
+ xEventGroupClearBits( pxSocketSet->xSelectGroup, xBitsToClear );
+ }
+
+ /* Now include eSELECT_CALL_IP to wakeup the caller. */
+ xEventGroupSetBits( pxSocketSet->xSelectGroup, xGroupBits | eSELECT_CALL_IP );
+ }
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SIGNALS != 0 )
+
+ /* Send a signal to the task which reads from this socket. */
+ BaseType_t FreeRTOS_SignalSocket( Socket_t xSocket )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+
+ if( pxSocket == NULL )
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+ else
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ if( ( pxSocket->pxSocketSet != NULL ) && ( pxSocket->pxSocketSet->xSelectGroup != NULL ) )
+ {
+ xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, eSELECT_INTR );
+ xReturn = 0;
+ }
+ else
+ #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+ if( pxSocket->xEventGroup != NULL )
+ {
+ xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_INTR );
+ xReturn = 0;
+ }
+ else
+ {
+ xReturn = -pdFREERTOS_ERRNO_EINVAL;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigSUPPORT_SIGNALS */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigSUPPORT_SIGNALS != 0 )
+
+ /* Send a signal to the task which reads from this socket (FromISR version). */
+ BaseType_t FreeRTOS_SignalSocketFromISR( Socket_t xSocket, BaseType_t *pxHigherPriorityTaskWoken )
+ {
+ FreeRTOS_Socket_t *pxSocket = ( FreeRTOS_Socket_t * ) xSocket;
+ BaseType_t xReturn;
+ IPStackEvent_t xEvent;
+ extern QueueHandle_t xNetworkEventQueue;
+
+ configASSERT( pxSocket != NULL );
+ configASSERT( pxSocket->ucProtocol == FREERTOS_IPPROTO_TCP );
+ configASSERT( pxSocket->xEventGroup );
+
+ xEvent.eEventType = eSocketSignalEvent;
+ xEvent.pvData = ( void * )pxSocket;
+
+ /* The IP-task will call FreeRTOS_SignalSocket for this socket. */
+ xReturn = xQueueSendToBackFromISR( xNetworkEventQueue, &xEvent, pxHigherPriorityTaskWoken );
+
+ return xReturn;
+ }
+
+#endif /* ipconfigSUPPORT_SIGNALS */
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
index 53a5c69c6..0bda99317 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_Stream_Buffer.c
@@ -1,199 +1,199 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-
-/*
- * uxStreamBufferAdd( )
- * Adds data to a stream buffer. If uxOffset > 0, data will be written at
- * an offset from uxHead while uxHead will not be moved yet. This possibility
- * will be used when TCP data is received while earlier data is still missing.
- * If 'pucData' equals NULL, the function is called to advance 'uxHead' only.
- */
-size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount )
-{
-size_t uxSpace, uxNextHead, uxFirst;
-
- uxSpace = uxStreamBufferGetSpace( pxBuffer );
-
- /* If uxOffset > 0, items can be placed in front of uxHead */
- if( uxSpace > uxOffset )
- {
- uxSpace -= uxOffset;
- }
- else
- {
- uxSpace = 0u;
- }
-
- /* The number of bytes that can be written is the minimum of the number of
- bytes requested and the number available. */
- uxCount = FreeRTOS_min_uint32( uxSpace, uxCount );
-
- if( uxCount != 0u )
- {
- uxNextHead = pxBuffer->uxHead;
-
- if( uxOffset != 0u )
- {
- /* ( uxOffset > 0 ) means: write in front if the uxHead marker */
- uxNextHead += uxOffset;
- if( uxNextHead >= pxBuffer->LENGTH )
- {
- uxNextHead -= pxBuffer->LENGTH;
- }
- }
-
- if( pucData != NULL )
- {
- /* Calculate the number of bytes that can be added in the first
- write - which may be less than the total number of bytes that need
- to be added if the buffer will wrap back to the beginning. */
- uxFirst = FreeRTOS_min_uint32( pxBuffer->LENGTH - uxNextHead, uxCount );
-
- /* Write as many bytes as can be written in the first write. */
- memcpy( ( void* ) ( pxBuffer->ucArray + uxNextHead ), pucData, uxFirst );
-
- /* If the number of bytes written was less than the number that
- could be written in the first write... */
- if( uxCount > uxFirst )
- {
- /* ...then write the remaining bytes to the start of the
- buffer. */
- memcpy( ( void * )pxBuffer->ucArray, pucData + uxFirst, uxCount - uxFirst );
- }
- }
-
- if( uxOffset == 0u )
- {
- /* ( uxOffset == 0 ) means: write at uxHead position */
- uxNextHead += uxCount;
- if( uxNextHead >= pxBuffer->LENGTH )
- {
- uxNextHead -= pxBuffer->LENGTH;
- }
- pxBuffer->uxHead = uxNextHead;
- }
-
- if( xStreamBufferLessThenEqual( pxBuffer, pxBuffer->uxFront, uxNextHead ) != pdFALSE )
- {
- /* Advance the front pointer */
- pxBuffer->uxFront = uxNextHead;
- }
- }
-
- return uxCount;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * uxStreamBufferGet( )
- * 'uxOffset' can be used to read data located at a certain offset from 'lTail'.
- * If 'pucData' equals NULL, the function is called to advance 'lTail' only.
- * if 'xPeek' is pdTRUE, or if 'uxOffset' is non-zero, the 'lTail' pointer will
- * not be advanced.
- */
-size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek )
-{
-size_t uxSize, uxCount, uxFirst, uxNextTail;
-
- /* How much data is available? */
- uxSize = uxStreamBufferGetSize( pxBuffer );
-
- if( uxSize > uxOffset )
- {
- uxSize -= uxOffset;
- }
- else
- {
- uxSize = 0u;
- }
-
- /* Use the minimum of the wanted bytes and the available bytes. */
- uxCount = FreeRTOS_min_uint32( uxSize, uxMaxCount );
-
- if( uxCount > 0u )
- {
- uxNextTail = pxBuffer->uxTail;
-
- if( uxOffset != 0u )
- {
- uxNextTail += uxOffset;
- if( uxNextTail >= pxBuffer->LENGTH )
- {
- uxNextTail -= pxBuffer->LENGTH;
- }
- }
-
- if( pucData != NULL )
- {
- /* Calculate the number of bytes that can be read - which may be
- less than the number wanted if the data wraps around to the start of
- the buffer. */
- uxFirst = FreeRTOS_min_uint32( pxBuffer->LENGTH - uxNextTail, uxCount );
-
- /* Obtain the number of bytes it is possible to obtain in the first
- read. */
- memcpy( pucData, pxBuffer->ucArray + uxNextTail, uxFirst );
-
- /* If the total number of wanted bytes is greater than the number
- that could be read in the first read... */
- if( uxCount > uxFirst )
- {
- /*...then read the remaining bytes from the start of the buffer. */
- memcpy( pucData + uxFirst, pxBuffer->ucArray, uxCount - uxFirst );
- }
- }
-
- if( ( xPeek == pdFALSE ) && ( uxOffset == 0UL ) )
- {
- /* Move the tail pointer to effecively remove the data read from
- the buffer. */
- uxNextTail += uxCount;
-
- if( uxNextTail >= pxBuffer->LENGTH )
- {
- uxNextTail -= pxBuffer->LENGTH;
- }
-
- pxBuffer->uxTail = uxNextTail;
- }
- }
-
- return uxCount;
-}
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+
+/*
+ * uxStreamBufferAdd( )
+ * Adds data to a stream buffer. If uxOffset > 0, data will be written at
+ * an offset from uxHead while uxHead will not be moved yet. This possibility
+ * will be used when TCP data is received while earlier data is still missing.
+ * If 'pucData' equals NULL, the function is called to advance 'uxHead' only.
+ */
+size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount )
+{
+size_t uxSpace, uxNextHead, uxFirst;
+
+ uxSpace = uxStreamBufferGetSpace( pxBuffer );
+
+ /* If uxOffset > 0, items can be placed in front of uxHead */
+ if( uxSpace > uxOffset )
+ {
+ uxSpace -= uxOffset;
+ }
+ else
+ {
+ uxSpace = 0u;
+ }
+
+ /* The number of bytes that can be written is the minimum of the number of
+ bytes requested and the number available. */
+ uxCount = FreeRTOS_min_uint32( uxSpace, uxCount );
+
+ if( uxCount != 0u )
+ {
+ uxNextHead = pxBuffer->uxHead;
+
+ if( uxOffset != 0u )
+ {
+ /* ( uxOffset > 0 ) means: write in front if the uxHead marker */
+ uxNextHead += uxOffset;
+ if( uxNextHead >= pxBuffer->LENGTH )
+ {
+ uxNextHead -= pxBuffer->LENGTH;
+ }
+ }
+
+ if( pucData != NULL )
+ {
+ /* Calculate the number of bytes that can be added in the first
+ write - which may be less than the total number of bytes that need
+ to be added if the buffer will wrap back to the beginning. */
+ uxFirst = FreeRTOS_min_uint32( pxBuffer->LENGTH - uxNextHead, uxCount );
+
+ /* Write as many bytes as can be written in the first write. */
+ memcpy( ( void* ) ( pxBuffer->ucArray + uxNextHead ), pucData, uxFirst );
+
+ /* If the number of bytes written was less than the number that
+ could be written in the first write... */
+ if( uxCount > uxFirst )
+ {
+ /* ...then write the remaining bytes to the start of the
+ buffer. */
+ memcpy( ( void * )pxBuffer->ucArray, pucData + uxFirst, uxCount - uxFirst );
+ }
+ }
+
+ if( uxOffset == 0u )
+ {
+ /* ( uxOffset == 0 ) means: write at uxHead position */
+ uxNextHead += uxCount;
+ if( uxNextHead >= pxBuffer->LENGTH )
+ {
+ uxNextHead -= pxBuffer->LENGTH;
+ }
+ pxBuffer->uxHead = uxNextHead;
+ }
+
+ if( xStreamBufferLessThenEqual( pxBuffer, pxBuffer->uxFront, uxNextHead ) != pdFALSE )
+ {
+ /* Advance the front pointer */
+ pxBuffer->uxFront = uxNextHead;
+ }
+ }
+
+ return uxCount;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * uxStreamBufferGet( )
+ * 'uxOffset' can be used to read data located at a certain offset from 'lTail'.
+ * If 'pucData' equals NULL, the function is called to advance 'lTail' only.
+ * if 'xPeek' is pdTRUE, or if 'uxOffset' is non-zero, the 'lTail' pointer will
+ * not be advanced.
+ */
+size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek )
+{
+size_t uxSize, uxCount, uxFirst, uxNextTail;
+
+ /* How much data is available? */
+ uxSize = uxStreamBufferGetSize( pxBuffer );
+
+ if( uxSize > uxOffset )
+ {
+ uxSize -= uxOffset;
+ }
+ else
+ {
+ uxSize = 0u;
+ }
+
+ /* Use the minimum of the wanted bytes and the available bytes. */
+ uxCount = FreeRTOS_min_uint32( uxSize, uxMaxCount );
+
+ if( uxCount > 0u )
+ {
+ uxNextTail = pxBuffer->uxTail;
+
+ if( uxOffset != 0u )
+ {
+ uxNextTail += uxOffset;
+ if( uxNextTail >= pxBuffer->LENGTH )
+ {
+ uxNextTail -= pxBuffer->LENGTH;
+ }
+ }
+
+ if( pucData != NULL )
+ {
+ /* Calculate the number of bytes that can be read - which may be
+ less than the number wanted if the data wraps around to the start of
+ the buffer. */
+ uxFirst = FreeRTOS_min_uint32( pxBuffer->LENGTH - uxNextTail, uxCount );
+
+ /* Obtain the number of bytes it is possible to obtain in the first
+ read. */
+ memcpy( pucData, pxBuffer->ucArray + uxNextTail, uxFirst );
+
+ /* If the total number of wanted bytes is greater than the number
+ that could be read in the first read... */
+ if( uxCount > uxFirst )
+ {
+ /*...then read the remaining bytes from the start of the buffer. */
+ memcpy( pucData + uxFirst, pxBuffer->ucArray, uxCount - uxFirst );
+ }
+ }
+
+ if( ( xPeek == pdFALSE ) && ( uxOffset == 0UL ) )
+ {
+ /* Move the tail pointer to effecively remove the data read from
+ the buffer. */
+ uxNextTail += uxCount;
+
+ if( uxNextTail >= pxBuffer->LENGTH )
+ {
+ uxNextTail -= pxBuffer->LENGTH;
+ }
+
+ pxBuffer->uxTail = uxNextTail;
+ }
+ }
+
+ return uxCount;
+}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
index d26756589..849796508 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_IP.c
@@ -1,3390 +1,3390 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/*
- * FreeRTOS_TCP_IP.c
- * Module which handles the TCP connections for FreeRTOS+TCP.
- * It depends on FreeRTOS_TCP_WIN.c, which handles the TCP windowing
- * schemes.
- *
- * Endianness: in this module all ports and IP addresses are stored in
- * host byte-order, except fields in the IP-packets
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_TCP_IP.h"
-#include "FreeRTOS_DHCP.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-#include "FreeRTOS_ARP.h"
-#include "FreeRTOS_TCP_WIN.h"
-
-
-/* Just make sure the contents doesn't get compiled if TCP is not enabled. */
-#if ipconfigUSE_TCP == 1
-
-/* This compile-time test was moved to here because some macro's
-were unknown within 'FreeRTOSIPConfigDefaults.h'. It tests whether
-the defined MTU size can contain at least a complete TCP packet. */
-
-#if ( ( ipconfigTCP_MSS + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) > ipconfigNETWORK_MTU )
- #error The ipconfigTCP_MSS setting in FreeRTOSIPConfig.h is too large.
-#endif
-
-/*
- * The meaning of the TCP flags:
- */
-#define ipTCP_FLAG_FIN 0x0001u /* No more data from sender */
-#define ipTCP_FLAG_SYN 0x0002u /* Synchronize sequence numbers */
-#define ipTCP_FLAG_RST 0x0004u /* Reset the connection */
-#define ipTCP_FLAG_PSH 0x0008u /* Push function: please push buffered data to the recv application */
-#define ipTCP_FLAG_ACK 0x0010u /* Acknowledgment field is significant */
-#define ipTCP_FLAG_URG 0x0020u /* Urgent pointer field is significant */
-#define ipTCP_FLAG_ECN 0x0040u /* ECN-Echo */
-#define ipTCP_FLAG_CWR 0x0080u /* Congestion Window Reduced */
-#define ipTCP_FLAG_NS 0x0100u /* ECN-nonce concealment protection */
-#define ipTCP_FLAG_RSV 0x0E00u /* Reserved, keep 0 */
-
-/* A mask to filter all protocol flags. */
-#define ipTCP_FLAG_CTRL 0x001Fu
-
-/*
- * A few values of the TCP options:
- */
-#define TCP_OPT_END 0u /* End of TCP options list */
-#define TCP_OPT_NOOP 1u /* "No-operation" TCP option */
-#define TCP_OPT_MSS 2u /* Maximum segment size TCP option */
-#define TCP_OPT_WSOPT 3u /* TCP Window Scale Option (3-byte long) */
-#define TCP_OPT_SACK_P 4u /* Advertize that SACK is permitted */
-#define TCP_OPT_SACK_A 5u /* SACK option with first/last */
-#define TCP_OPT_TIMESTAMP 8u /* Time-stamp option */
-
-#define TCP_OPT_MSS_LEN 4u /* Length of TCP MSS option. */
-#define TCP_OPT_WSOPT_LEN 3u /* Length of TCP WSOPT option. */
-
-#define TCP_OPT_TIMESTAMP_LEN 10 /* fixed length of the time-stamp option */
-
-#ifndef ipconfigTCP_ACK_EARLIER_PACKET
- #define ipconfigTCP_ACK_EARLIER_PACKET 1
-#endif
-
-/*
- * The macro NOW_CONNECTED() is use to determine if the connection makes a
- * transition from connected to non-connected and vice versa.
- * NOW_CONNECTED() returns true when the status has one of these values:
- * eESTABLISHED, eFIN_WAIT_1, eFIN_WAIT_2, eCLOSING, eLAST_ACK, eTIME_WAIT
- * Technically the connection status is closed earlier, but the library wants
- * to prevent that the socket will be deleted before the last ACK has been
- * and thus causing a 'RST' packet on either side.
- */
-#define NOW_CONNECTED( status )\
- ( ( status >= eESTABLISHED ) && ( status != eCLOSE_WAIT ) )
-
-/*
- * The highest 4 bits in the TCP offset byte indicate the total length of the
- * TCP header, divided by 4.
- */
-#define VALID_BITS_IN_TCP_OFFSET_BYTE ( 0xF0u )
-
-/*
- * Acknowledgements to TCP data packets may be delayed as long as more is being expected.
- * A normal delay would be 200ms. Here a much shorter delay of 20 ms is being used to
- * gain performance.
- */
-#define DELAYED_ACK_SHORT_DELAY_MS ( 2 )
-#define DELAYED_ACK_LONGER_DELAY_MS ( 20 )
-
-/*
- * The MSS (Maximum Segment Size) will be taken as large as possible. However, packets with
- * an MSS of 1460 bytes won't be transported through the internet. The MSS will be reduced
- * to 1400 bytes.
- */
-#define REDUCED_MSS_THROUGH_INTERNET ( 1400 )
-
-/*
- * When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
- * the number 5 (words) in the higher niblle of the TCP-offset byte.
- */
-#define TCP_OFFSET_LENGTH_BITS ( 0xf0u )
-#define TCP_OFFSET_STANDARD_LENGTH ( 0x50u )
-
-/*
- * Each TCP socket is checked regularly to see if it can send data packets.
- * By default, the maximum number of packets sent during one check is limited to 8.
- * This amount may be further limited by setting the socket's TX window size.
- */
-#if( !defined( SEND_REPEATED_COUNT ) )
- #define SEND_REPEATED_COUNT ( 8 )
-#endif /* !defined( SEND_REPEATED_COUNT ) */
-
-/*
- * Define a maximum perdiod of time (ms) to leave a TCP-socket unattended.
- * When a TCP timer expires, retries and keep-alive messages will be checked.
- */
-#ifndef tcpMAXIMUM_TCP_WAKEUP_TIME_MS
- #define tcpMAXIMUM_TCP_WAKEUP_TIME_MS 20000u
-#endif
-
-/*
- * The names of the different TCP states may be useful in logging.
- */
-#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
- static const char *pcStateNames[] = {
- "eCLOSED",
- "eTCP_LISTEN",
- "eCONNECT_SYN",
- "eSYN_FIRST",
- "eSYN_RECEIVED",
- "eESTABLISHED",
- "eFIN_WAIT_1",
- "eFIN_WAIT_2",
- "eCLOSE_WAIT",
- "eCLOSING",
- "eLAST_ACK",
- "eTIME_WAIT",
- "eUNKNOWN",
-};
-#endif /* ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) */
-
-/*
- * Returns true if the socket must be checked. Non-active sockets are waiting
- * for user action, either connect() or close().
- */
-static BaseType_t prvTCPSocketIsActive( UBaseType_t uxStatus );
-
-/*
- * Either sends a SYN or calls prvTCPSendRepeated (for regular messages).
- */
-static int32_t prvTCPSendPacket( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Try to send a series of messages.
- */
-static int32_t prvTCPSendRepeated( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
-
-/*
- * Return or send a packet to the other party.
- */
-static void prvTCPReturnPacket( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
- uint32_t ulLen, BaseType_t xReleaseAfterSend );
-
-/*
- * Initialise the data structures which keep track of the TCP windowing system.
- */
-static void prvTCPCreateWindow( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Let ARP look-up the MAC-address of the peer and initialise the first SYN
- * packet.
- */
-static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket );
-
-#if( ipconfigHAS_DEBUG_PRINTF != 0 )
- /*
- * For logging and debugging: make a string showing the TCP flags.
- */
- static const char *prvTCPFlagMeaning( UBaseType_t xFlags);
-#endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
-
-/*
- * Parse the TCP option(s) received, if present.
- */
-static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-/*
- * Identify and deal with a single TCP header option, advancing the pointer to
- * the header. This function returns pdTRUE or pdFALSE depending on whether the
- * caller should continue to parse more header options or break the loop.
- */
-static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow);
-
-/*
- * Skip past TCP header options when doing Selective ACK, until there are no
- * more options left.
- */
-static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const ppucLen );
-
-/*
- * Set the initial properties in the options fields, like the preferred
- * value of MSS and whether SACK allowed. Will be transmitted in the state
- * 'eCONNECT_SYN'.
- */
-static UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t *pxSocket, TCPPacket_t * pxTCPPacket );
-
-/*
- * For anti-hang protection and TCP keep-alive messages. Called in two places:
- * after receiving a packet and after a state change. The socket's alive timer
- * may be reset.
- */
-static void prvTCPTouchSocket( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Prepare an outgoing message, if anything has to be sent.
- */
-static int32_t prvTCPPrepareSend( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, UBaseType_t uxOptionsLength );
-
-/*
- * Calculate when this socket needs to be checked to do (re-)transmissions.
- */
-static TickType_t prvTCPNextTimeout( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * The API FreeRTOS_send() adds data to the TX stream. Add
- * this data to the windowing system to it can be transmitted.
- */
-static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Called to handle the closure of a TCP connection.
- */
-static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-/*
- * Called from prvTCPHandleState(). Find the TCP payload data and check and
- * return its length.
- */
-static BaseType_t prvCheckRxData( NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData );
-
-/*
- * Called from prvTCPHandleState(). Check if the payload data may be accepted.
- * If so, it will be added to the socket's reception queue.
- */
-static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, uint8_t *pucRecvData,
- NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength );
-
-/*
- * Set the TCP options (if any) for the outgoing packet.
- */
-static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-/*
- * Called from prvTCPHandleState() as long as the TCP status is eSYN_RECEIVED to
- * eCONNECT_SYN.
- */
-static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
- uint32_t ulReceiveLength, UBaseType_t uxOptionsLength );
-
-/*
- * Called from prvTCPHandleState() as long as the TCP status is eESTABLISHED.
- */
-static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
- uint32_t ulReceiveLength, UBaseType_t uxOptionsLength );
-
-/*
- * Called from prvTCPHandleState(). There is data to be sent.
- * If ipconfigUSE_TCP_WIN is defined, and if only an ACK must be sent, it will
- * be checked if it would better be postponed for efficiency.
- */
-static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
- uint32_t ulReceiveLength, BaseType_t xSendLength );
-
-/*
- * The heart of all: check incoming packet for valid data and acks and do what
- * is necessary in each state.
- */
-static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
-
-/*
- * Common code for sending a TCP protocol control packet (i.e. no options, no
- * payload, just flags).
- */
-static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
- uint8_t ucTCPFlags );
-
-/*
- * A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
- * case #3. In summary, an RST was received with a sequence number that is
- * unexpected but still within the window.
- */
-static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-/*
- * Reply to a peer with the RST flag on, in case a packet can not be handled.
- */
-static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-/*
- * Set the initial value for MSS (Maximum Segment Size) to be used.
- */
-static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Return either a newly created socket, or the current socket in a connected
- * state (depends on the 'bReuseSocket' flag).
- */
-static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-/*
- * After a listening socket receives a new connection, it may duplicate itself.
- * The copying takes place in prvTCPSocketCopy.
- */
-static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t *pxNewSocket, FreeRTOS_Socket_t *pxSocket );
-
-/*
- * prvTCPStatusAgeCheck() will see if the socket has been in a non-connected
- * state for too long. If so, the socket will be closed, and -1 will be
- * returned.
- */
-#if( ipconfigTCP_HANG_PROTECTION == 1 )
- static BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t *pxSocket );
-#endif
-
-static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
- int32_t lDataLen, UBaseType_t uxOptionsLength );
-
-#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
- const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState );
-#endif
-
-#if( ipconfigUSE_TCP_WIN != 0 )
- static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket );
-#endif
-
-/*
- * Generate a randomized TCP Initial Sequence Number per RFC.
- */
-extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
- uint16_t usSourcePort,
- uint32_t ulDestinationAddress,
- uint16_t usDestinationPort );
-
-/*-----------------------------------------------------------*/
-
-/* prvTCPSocketIsActive() returns true if the socket must be checked.
- * Non-active sockets are waiting for user action, either connect()
- * or close(). */
-static BaseType_t prvTCPSocketIsActive( UBaseType_t uxStatus )
-{
- switch( uxStatus )
- {
- case eCLOSED:
- case eCLOSE_WAIT:
- case eFIN_WAIT_2:
- case eCLOSING:
- case eTIME_WAIT:
- return pdFALSE;
- default:
- return pdTRUE;
- }
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigTCP_HANG_PROTECTION == 1 )
-
- static BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t *pxSocket )
- {
- BaseType_t xResult;
- switch( pxSocket->u.xTCP.ucTCPState )
- {
- case eESTABLISHED:
- /* If the 'ipconfigTCP_KEEP_ALIVE' option is enabled, sockets in
- state ESTABLISHED can be protected using keep-alive messages. */
- xResult = pdFALSE;
- break;
- case eCLOSED:
- case eTCP_LISTEN:
- case eCLOSE_WAIT:
- /* These 3 states may last for ever, up to the owner. */
- xResult = pdFALSE;
- break;
- default:
- /* All other (non-connected) states will get anti-hanging
- protection. */
- xResult = pdTRUE;
- break;
- }
- if( xResult != pdFALSE )
- {
- /* How much time has past since the last active moment which is
- defined as A) a state change or B) a packet has arrived. */
- TickType_t xAge = xTaskGetTickCount( ) - pxSocket->u.xTCP.xLastActTime;
-
- /* ipconfigTCP_HANG_PROTECTION_TIME is in units of seconds. */
- if( xAge > ( ipconfigTCP_HANG_PROTECTION_TIME * configTICK_RATE_HZ ) )
- {
- #if( ipconfigHAS_DEBUG_PRINTF == 1 )
- {
- FreeRTOS_debug_printf( ( "Inactive socket closed: port %u rem %lxip:%u status %s\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort,
- FreeRTOS_GetTCPStateName( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF */
-
- /* Move to eCLOSE_WAIT, user may close the socket. */
- vTCPStateChange( pxSocket, eCLOSE_WAIT );
-
- /* When 'bPassQueued' true, this socket is an orphan until it
- gets connected. */
- if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
- {
- if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
- {
- /* As it did not get connected, and the user can never
- accept() it anymore, it will be deleted now. Called from
- the IP-task, so it's safe to call the internal Close
- function: vSocketClose(). */
- vSocketClose( pxSocket );
- }
- /* Return a negative value to tell to inform the caller
- xTCPTimerCheck()
- that the socket got closed and may not be accessed anymore. */
- xResult = -1;
- }
- }
- }
- return xResult;
- }
- /*-----------------------------------------------------------*/
-
-#endif
-
-/*
- * As soon as a TCP socket timer expires, this function xTCPSocketCheck
- * will be called (from xTCPTimerCheck)
- * It can send a delayed ACK or new data
- * Sequence of calling (normally) :
- * IP-Task:
- * xTCPTimerCheck() // Check all sockets ( declared in FreeRTOS_Sockets.c )
- * xTCPSocketCheck() // Either send a delayed ACK or call prvTCPSendPacket()
- * prvTCPSendPacket() // Either send a SYN or call prvTCPSendRepeated ( regular messages )
- * prvTCPSendRepeated() // Send at most 8 messages on a row
- * prvTCPReturnPacket() // Prepare for returning
- * xNetworkInterfaceOutput() // Sends data to the NIC ( declared in portable/NetworkInterface/xxx )
- */
-BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket )
-{
-BaseType_t xResult = 0;
-BaseType_t xReady = pdFALSE;
-
- if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.txStream != NULL ) )
- {
- /* The API FreeRTOS_send() might have added data to the TX stream. Add
- this data to the windowing system to it can be transmitted. */
- prvTCPAddTxData( pxSocket );
- }
-
- #if ipconfigUSE_TCP_WIN == 1
- {
- if( pxSocket->u.xTCP.pxAckMessage != NULL )
- {
- /* The first task of this regular socket check is to send-out delayed
- ACK's. */
- if( pxSocket->u.xTCP.bits.bUserShutdown == pdFALSE_UNSIGNED )
- {
- /* Earlier data was received but not yet acknowledged. This
- function is called when the TCP timer for the socket expires, the
- ACK may be sent now. */
- if( pxSocket->u.xTCP.ucTCPState != eCLOSED )
- {
- if( xTCPWindowLoggingLevel > 1 && ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) )
- {
- FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %lu SEQ %lu (len %u)\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usRemotePort,
- pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber,
- pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber,
- ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) );
- }
-
- prvTCPReturnPacket( pxSocket, pxSocket->u.xTCP.pxAckMessage, ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER, ipconfigZERO_COPY_TX_DRIVER );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* The ownership has been passed to the SEND routine,
- clear the pointer to it. */
- pxSocket->u.xTCP.pxAckMessage = NULL;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- }
- if( prvTCPNextTimeout( pxSocket ) > 1 )
- {
- /* Tell the code below that this function is ready. */
- xReady = pdTRUE;
- }
- }
- else
- {
- /* The user wants to perform an active shutdown(), skip sending
- the delayed ACK. The function prvTCPSendPacket() will send the
- FIN along with the ACK's. */
- }
-
- if( pxSocket->u.xTCP.pxAckMessage != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
- pxSocket->u.xTCP.pxAckMessage = NULL;
- }
- }
- }
- #endif /* ipconfigUSE_TCP_WIN */
-
- if( xReady == pdFALSE )
- {
- /* The second task of this regular socket check is sending out data. */
- if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) ||
- ( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ) )
- {
- prvTCPSendPacket( pxSocket );
- }
-
- /* Set the time-out for the next wakeup for this socket. */
- prvTCPNextTimeout( pxSocket );
-
- #if( ipconfigTCP_HANG_PROTECTION == 1 )
- {
- /* In all (non-connected) states in which keep-alive messages can not be sent
- the anti-hang protocol will close sockets that are 'hanging'. */
- xResult = prvTCPStatusAgeCheck( pxSocket );
- }
- #endif
- }
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvTCPSendPacket() will be called when the socket time-out has been reached.
- * It is only called by xTCPSocketCheck().
- */
-static int32_t prvTCPSendPacket( FreeRTOS_Socket_t *pxSocket )
-{
-int32_t lResult = 0;
-UBaseType_t uxOptionsLength;
-TCPPacket_t *pxTCPPacket;
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-
- if( pxSocket->u.xTCP.ucTCPState != eCONNECT_SYN )
- {
- /* The connection is in s state other than SYN. */
- pxNetworkBuffer = NULL;
-
- /* prvTCPSendRepeated() will only create a network buffer if necessary,
- i.e. when data must be sent to the peer. */
- lResult = prvTCPSendRepeated( pxSocket, &pxNetworkBuffer );
-
- if( pxNetworkBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- }
- else
- {
- if( pxSocket->u.xTCP.ucRepCount >= 3u )
- {
- /* The connection is in the SYN status. The packet will be repeated
- to most 3 times. When there is no response, the socket get the
- status 'eCLOSE_WAIT'. */
- FreeRTOS_debug_printf( ( "Connect: giving up %lxip:%u\n",
- pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine. */
- pxSocket->u.xTCP.usRemotePort ) ); /* Port on remote machine. */
- vTCPStateChange( pxSocket, eCLOSE_WAIT );
- }
- else if( ( pxSocket->u.xTCP.bits.bConnPrepared != pdFALSE_UNSIGNED ) || ( prvTCPPrepareConnect( pxSocket ) == pdTRUE ) )
- {
- /* Or else, if the connection has been prepared, or can be prepared
- now, proceed to send the packet with the SYN flag.
- prvTCPPrepareConnect() prepares 'xPacket' and returns pdTRUE if
- the Ethernet address of the peer or the gateway is found. */
- pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
-
- /* About to send a SYN packet. Call prvSetSynAckOptions() to set
- the proper options: The size of MSS and whether SACK's are
- allowed. */
- uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPPacket );
-
- /* Return the number of bytes to be sent. */
- lResult = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
-
- /* Set the TCP offset field: ipSIZE_OF_TCP_HEADER equals 20 and
- uxOptionsLength is always a multiple of 4. The complete expression
- would be:
- ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */
- pxTCPPacket->xTCPHeader.ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
-
- /* Repeat Count is used for a connecting socket, to limit the number
- of tries. */
- pxSocket->u.xTCP.ucRepCount++;
-
- /* Send the SYN message to make a connection. The messages is
- stored in the socket field 'xPacket'. It will be wrapped in a
- pseudo network buffer descriptor before it will be sent. */
- prvTCPReturnPacket( pxSocket, NULL, ( uint32_t ) lResult, pdFALSE );
- }
- }
-
- /* Return the total number of bytes sent. */
- return lResult;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvTCPSendRepeated will try to send a series of messages, as long as there is
- * data to be sent and as long as the transmit window isn't full.
- */
-static int32_t prvTCPSendRepeated( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
-{
-UBaseType_t uxIndex;
-int32_t lResult = 0;
-UBaseType_t uxOptionsLength = 0u;
-int32_t xSendLength;
-
- for( uxIndex = 0u; uxIndex < ( UBaseType_t ) SEND_REPEATED_COUNT; uxIndex++ )
- {
- /* prvTCPPrepareSend() might allocate a network buffer if there is data
- to be sent. */
- xSendLength = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
- if( xSendLength <= 0 )
- {
- break;
- }
-
- /* And return the packet to the peer. */
- prvTCPReturnPacket( pxSocket, *ppxNetworkBuffer, ( uint32_t ) xSendLength, ipconfigZERO_COPY_TX_DRIVER );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- *ppxNetworkBuffer = NULL;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- lResult += xSendLength;
- }
-
- /* Return the total number of bytes sent. */
- return lResult;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Return (or send) a packet the the peer. The data is stored in pxBuffer,
- * which may either point to a real network buffer or to a TCP socket field
- * called 'xTCP.xPacket'. A temporary xNetworkBuffer will be used to pass
- * the data to the NIC.
- */
-static void prvTCPReturnPacket( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulLen, BaseType_t xReleaseAfterSend )
-{
-TCPPacket_t * pxTCPPacket;
-IPHeader_t *pxIPHeader;
-EthernetHeader_t *pxEthernetHeader;
-uint32_t ulFrontSpace, ulSpace, ulSourceAddress, ulWinSize;
-TCPWindow_t *pxTCPWindow;
-NetworkBufferDescriptor_t xTempBuffer;
-/* For sending, a pseudo network buffer will be used, as explained above. */
-
- if( pxNetworkBuffer == NULL )
- {
- pxNetworkBuffer = &xTempBuffer;
-
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- xTempBuffer.pxNextBuffer = NULL;
- }
- #endif
- xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
- xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
- xReleaseAfterSend = pdFALSE;
- }
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- if( xReleaseAfterSend == pdFALSE )
- {
- pxNetworkBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, ( BaseType_t ) pxNetworkBuffer->xDataLength );
- if( pxNetworkBuffer == NULL )
- {
- FreeRTOS_debug_printf( ( "prvTCPReturnPacket: duplicate failed\n" ) );
- }
- xReleaseAfterSend = pdTRUE;
- }
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- if( pxNetworkBuffer != NULL )
- {
- pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
- pxIPHeader = &pxTCPPacket->xIPHeader;
- pxEthernetHeader = &pxTCPPacket->xEthernetHeader;
-
- /* Fill the packet, using hton translations. */
- if( pxSocket != NULL )
- {
- /* Calculate the space in the RX buffer in order to advertise the
- size of this socket's reception window. */
- pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
-
- if( pxSocket->u.xTCP.rxStream != NULL )
- {
- /* An RX stream was created already, see how much space is
- available. */
- ulFrontSpace = ( uint32_t ) uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
- }
- else
- {
- /* No RX stream has been created, the full stream size is
- available. */
- ulFrontSpace = ( uint32_t ) pxSocket->u.xTCP.uxRxStreamSize;
- }
-
- /* Take the minimum of the RX buffer space and the RX window size. */
- ulSpace = FreeRTOS_min_uint32( pxTCPWindow->xSize.ulRxWindowLength, ulFrontSpace );
-
- if( ( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED ) || ( pxSocket->u.xTCP.bits.bRxStopped != pdFALSE_UNSIGNED ) )
- {
- /* The low-water mark was reached, meaning there was little
- space left. The socket will wait until the application has read
- or flushed the incoming data, and 'zero-window' will be
- advertised. */
- ulSpace = 0u;
- }
-
- /* If possible, advertise an RX window size of at least 1 MSS, otherwise
- the peer might start 'zero window probing', i.e. sending small packets
- (1, 2, 4, 8... bytes). */
- if( ( ulSpace < pxSocket->u.xTCP.usCurMSS ) && ( ulFrontSpace >= pxSocket->u.xTCP.usCurMSS ) )
- {
- ulSpace = pxSocket->u.xTCP.usCurMSS;
- }
-
- /* Avoid overflow of the 16-bit win field. */
- #if( ipconfigUSE_TCP_WIN != 0 )
- {
- ulWinSize = ( ulSpace >> pxSocket->u.xTCP.ucMyWinScaleFactor );
- }
- #else
- {
- ulWinSize = ulSpace;
- }
- #endif
- if( ulWinSize > 0xfffcUL )
- {
- ulWinSize = 0xfffcUL;
- }
-
- pxTCPPacket->xTCPHeader.usWindow = FreeRTOS_htons( ( uint16_t ) ulWinSize );
-
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- if( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE )
- {
- if( ( xTCPWindowLoggingLevel != 0 ) && ( pxSocket->u.xTCP.bits.bWinChange != pdFALSE_UNSIGNED ) )
- {
- size_t uxFrontSpace;
-
- if(pxSocket->u.xTCP.rxStream != NULL)
- {
- uxFrontSpace = uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream ) ;
- }
- else
- {
- uxFrontSpace = 0u;
- }
-
- FreeRTOS_debug_printf( ( "%s: %lxip:%u: [%lu < %lu] winSize %ld\n",
- pxSocket->u.xTCP.bits.bLowWater ? "STOP" : "GO ",
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort,
- pxSocket->u.xTCP.bits.bLowWater ? pxSocket->u.xTCP.uxLittleSpace : uxFrontSpace, pxSocket->u.xTCP.uxEnoughSpace,
- (int32_t) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulCurrentSequenceNumber ) ) );
- }
- }
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
-
- /* The new window size has been advertised, switch off the flag. */
- pxSocket->u.xTCP.bits.bWinChange = pdFALSE_UNSIGNED;
-
- /* Later on, when deciding to delay an ACK, a precise estimate is needed
- of the free RX space. At this moment, 'ulHighestRxAllowed' would be the
- highest sequence number minus 1 that the socket will accept. */
- pxSocket->u.xTCP.ulHighestRxAllowed = pxTCPWindow->rx.ulCurrentSequenceNumber + ulSpace;
-
- #if( ipconfigTCP_KEEP_ALIVE == 1 )
- if( pxSocket->u.xTCP.bits.bSendKeepAlive != pdFALSE_UNSIGNED )
- {
- /* Sending a keep-alive packet, send the current sequence number
- minus 1, which will be recognised as a keep-alive packet an
- responded to by acknowledging the last byte. */
- pxSocket->u.xTCP.bits.bSendKeepAlive = pdFALSE_UNSIGNED;
- pxSocket->u.xTCP.bits.bWaitKeepAlive = pdTRUE_UNSIGNED;
-
- pxTCPPacket->xTCPHeader.ulSequenceNumber = pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - 1UL;
- pxTCPPacket->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
- }
- else
- #endif
- {
- pxTCPPacket->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber );
-
- if( ( pxTCPPacket->xTCPHeader.ucTCPFlags & ( uint8_t ) ipTCP_FLAG_FIN ) != 0u )
- {
- /* Suppress FIN in case this packet carries earlier data to be
- retransmitted. */
- uint32_t ulDataLen = ( uint32_t ) ( ulLen - ( ipSIZE_OF_TCP_HEADER + ipSIZE_OF_IPv4_HEADER ) );
- if( ( pxTCPWindow->ulOurSequenceNumber + ulDataLen ) != pxTCPWindow->tx.ulFINSequenceNumber )
- {
- pxTCPPacket->xTCPHeader.ucTCPFlags &= ( ( uint8_t ) ~ipTCP_FLAG_FIN );
- FreeRTOS_debug_printf( ( "Suppress FIN for %lu + %lu < %lu\n",
- pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
- ulDataLen,
- pxTCPWindow->tx.ulFINSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber ) );
- }
- }
- }
-
- /* Tell which sequence number is expected next time */
- pxTCPPacket->xTCPHeader.ulAckNr = FreeRTOS_htonl( pxTCPWindow->rx.ulCurrentSequenceNumber );
- }
- else
- {
- /* Sending data without a socket, probably replying with a RST flag
- Just swap the two sequence numbers. */
- vFlip_32( pxTCPPacket->xTCPHeader.ulSequenceNumber, pxTCPPacket->xTCPHeader.ulAckNr );
- }
-
- pxIPHeader->ucTimeToLive = ( uint8_t ) ipconfigTCP_TIME_TO_LIVE;
- pxIPHeader->usLength = FreeRTOS_htons( ulLen );
- if( ( pxSocket == NULL ) || ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ) )
- {
- /* When pxSocket is NULL, this function is called by prvTCPSendReset()
- and the IP-addresses must be swapped.
- Also swap the IP-addresses in case the IP-tack doesn't have an
- IP-address yet, i.e. when ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ). */
- ulSourceAddress = pxIPHeader->ulDestinationIPAddress;
- }
- else
- {
- ulSourceAddress = *ipLOCAL_IP_ADDRESS_POINTER;
- }
- pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
- pxIPHeader->ulSourceIPAddress = ulSourceAddress;
- vFlip_16( pxTCPPacket->xTCPHeader.usSourcePort, pxTCPPacket->xTCPHeader.usDestinationPort );
-
- /* Just an increasing number. */
- pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );
- usPacketIdentifier++;
- pxIPHeader->usFragmentOffset = 0u;
-
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
- {
- /* calculate the IP header checksum, in case the driver won't do that. */
- pxIPHeader->usHeaderChecksum = 0x00u;
- pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
- pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
-
- /* calculate the TCP checksum for an outgoing packet. */
- usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
-
- /* A calculated checksum of 0 must be inverted as 0 means the checksum
- is disabled. */
- if( pxTCPPacket->xTCPHeader.usChecksum == 0x00u )
- {
- pxTCPPacket->xTCPHeader.usChecksum = 0xffffU;
- }
- }
- #endif
-
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- pxNetworkBuffer->pxNextBuffer = NULL;
- #endif
-
- /* Important: tell NIC driver how many bytes must be sent. */
- pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
-
- /* Fill in the destination MAC addresses. */
- memcpy( ( void * ) &( pxEthernetHeader->xDestinationAddress ), ( void * ) &( pxEthernetHeader->xSourceAddress ),
- sizeof( pxEthernetHeader->xDestinationAddress ) );
-
- /* The source MAC addresses is fixed to 'ipLOCAL_MAC_ADDRESS'. */
- memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
-
- #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- BaseType_t xIndex;
-
- for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
- {
- pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
- }
- pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
- }
- }
- #endif
-
- /* Send! */
- xNetworkInterfaceOutput( pxNetworkBuffer, xReleaseAfterSend );
-
- if( xReleaseAfterSend == pdFALSE )
- {
- /* Swap-back some fields, as pxBuffer probably points to a socket field
- containing the packet header. */
- vFlip_16( pxTCPPacket->xTCPHeader.usSourcePort, pxTCPPacket->xTCPHeader.usDestinationPort);
- pxTCPPacket->xIPHeader.ulSourceIPAddress = pxTCPPacket->xIPHeader.ulDestinationIPAddress;
- memcpy( pxEthernetHeader->xSourceAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
- }
- else
- {
- /* Nothing to do: the buffer has been passed to DMA and will be released after use */
- }
- } /* if( pxNetworkBuffer != NULL ) */
-}
-/*-----------------------------------------------------------*/
-
-/*
- * The SYN event is very important: the sequence numbers, which have a kind of
- * random starting value, are being synchronised. The sliding window manager
- * (in FreeRTOS_TCP_WIN.c) needs to know them, along with the Maximum Segment
- * Size (MSS) in use.
- */
-static void prvTCPCreateWindow( FreeRTOS_Socket_t *pxSocket )
-{
- if( xTCPWindowLoggingLevel )
- FreeRTOS_debug_printf( ( "Limits (using): TCP Win size %lu Water %lu <= %lu <= %lu\n",
- pxSocket->u.xTCP.uxRxWinSize * ipconfigTCP_MSS,
- pxSocket->u.xTCP.uxLittleSpace ,
- pxSocket->u.xTCP.uxEnoughSpace,
- pxSocket->u.xTCP.uxRxStreamSize ) );
- vTCPWindowCreate(
- &pxSocket->u.xTCP.xTCPWindow,
- ipconfigTCP_MSS * pxSocket->u.xTCP.uxRxWinSize,
- ipconfigTCP_MSS * pxSocket->u.xTCP.uxTxWinSize,
- pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber,
- pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber,
- ( uint32_t ) pxSocket->u.xTCP.usInitMSS );
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Connecting sockets have a special state: eCONNECT_SYN. In this phase,
- * the Ethernet address of the target will be found using ARP. In case the
- * target IP address is not within the netmask, the hardware address of the
- * gateway will be used.
- */
-static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket )
-{
-TCPPacket_t *pxTCPPacket;
-IPHeader_t *pxIPHeader;
-eARPLookupResult_t eReturned;
-uint32_t ulRemoteIP;
-MACAddress_t xEthAddress;
-BaseType_t xReturn = pdTRUE;
-uint32_t ulInitialSequenceNumber = 0;
-
- #if( ipconfigHAS_PRINTF != 0 )
- {
- /* Only necessary for nicer logging. */
- memset( xEthAddress.ucBytes, '\0', sizeof( xEthAddress.ucBytes ) );
- }
- #endif /* ipconfigHAS_PRINTF != 0 */
-
- ulRemoteIP = FreeRTOS_htonl( pxSocket->u.xTCP.ulRemoteIP );
-
- /* Determine the ARP cache status for the requested IP address. */
- eReturned = eARPGetCacheEntry( &( ulRemoteIP ), &( xEthAddress ) );
-
- switch( eReturned )
- {
- case eARPCacheHit: /* An ARP table lookup found a valid entry. */
- break; /* We can now prepare the SYN packet. */
- case eARPCacheMiss: /* An ARP table lookup did not find a valid entry. */
- case eCantSendPacket: /* There is no IP address, or an ARP is still in progress. */
- default:
- /* Count the number of times it couldn't find the ARP address. */
- pxSocket->u.xTCP.ucRepCount++;
-
- FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
- pxSocket->u.xTCP.ulRemoteIP,
- FreeRTOS_htonl( ulRemoteIP ),
- eReturned,
- xEthAddress.ucBytes[ 0 ],
- xEthAddress.ucBytes[ 1 ],
- xEthAddress.ucBytes[ 2 ],
- xEthAddress.ucBytes[ 3 ],
- xEthAddress.ucBytes[ 4 ],
- xEthAddress.ucBytes[ 5 ] ) );
-
- /* And issue a (new) ARP request */
- FreeRTOS_OutputARPRequest( ulRemoteIP );
-
- xReturn = pdFALSE;
- }
-
- if( xReturn != pdFALSE )
- {
- /* Get a difficult-to-predict initial sequence number for this 4-tuple. */
- ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER,
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort );
-
- /* Check for a random number generation error. */
- if( 0 == ulInitialSequenceNumber )
- {
- xReturn = pdFALSE;
- }
- }
-
- if( xReturn != pdFALSE )
- {
- /* The MAC-address of the peer (or gateway) has been found,
- now prepare the initial TCP packet and some fields in the socket. */
- pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
- pxIPHeader = &pxTCPPacket->xIPHeader;
-
- /* reset the retry counter to zero. */
- pxSocket->u.xTCP.ucRepCount = 0u;
-
- /* And remember that the connect/SYN data are prepared. */
- pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE_UNSIGNED;
-
- /* Now that the Ethernet address is known, the initial packet can be
- prepared. */
- memset( pxSocket->u.xTCP.xPacket.u.ucLastPacket, '\0', sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
-
- /* Write the Ethernet address in Source, because it will be swapped by
- prvTCPReturnPacket(). */
- memcpy( &pxTCPPacket->xEthernetHeader.xSourceAddress, &xEthAddress, sizeof( xEthAddress ) );
-
- /* 'ipIPv4_FRAME_TYPE' is already in network-byte-order. */
- pxTCPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
-
- pxIPHeader->ucVersionHeaderLength = 0x45u;
- pxIPHeader->usLength = FreeRTOS_htons( sizeof( TCPPacket_t ) - sizeof( pxTCPPacket->xEthernetHeader ) );
- pxIPHeader->ucTimeToLive = ( uint8_t ) ipconfigTCP_TIME_TO_LIVE;
-
- pxIPHeader->ucProtocol = ( uint8_t ) ipPROTOCOL_TCP;
-
- /* Addresses and ports will be stored swapped because prvTCPReturnPacket
- will swap them back while replying. */
- pxIPHeader->ulDestinationIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
- pxIPHeader->ulSourceIPAddress = FreeRTOS_htonl( pxSocket->u.xTCP.ulRemoteIP );
-
- pxTCPPacket->xTCPHeader.usSourcePort = FreeRTOS_htons( pxSocket->u.xTCP.usRemotePort );
- pxTCPPacket->xTCPHeader.usDestinationPort = FreeRTOS_htons( pxSocket->usLocalPort );
-
- /* We are actively connecting, so the peer's Initial Sequence Number (ISN)
- isn't known yet. */
- pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 0ul;
-
- /* Start with ISN (Initial Sequence Number). */
- pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
-
- /* The TCP header size is 20 bytes, divided by 4 equals 5, which is put in
- the high nibble of the TCP offset field. */
- pxTCPPacket->xTCPHeader.ucTCPOffset = 0x50u;
-
- /* Only set the SYN flag. */
- pxTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_SYN;
-
- /* Set the values of usInitMSS / usCurMSS for this socket. */
- prvSocketSetMSS( pxSocket );
-
- /* The initial sequence numbers at our side are known. Later
- vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
- first wait for a SYN+ACK reply. */
- prvTCPCreateWindow( pxSocket );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-/* For logging and debugging: make a string showing the TCP flags
-*/
-#if( ipconfigHAS_DEBUG_PRINTF != 0 )
-
- static const char *prvTCPFlagMeaning( UBaseType_t xFlags)
- {
- static char retString[10];
- snprintf(retString, sizeof( retString ), "%c%c%c%c%c%c%c%c%c",
- ( xFlags & ipTCP_FLAG_FIN ) ? 'F' : '.', /* 0x0001: No more data from sender */
- ( xFlags & ipTCP_FLAG_SYN ) ? 'S' : '.', /* 0x0002: Synchronize sequence numbers */
- ( xFlags & ipTCP_FLAG_RST ) ? 'R' : '.', /* 0x0004: Reset the connection */
- ( xFlags & ipTCP_FLAG_PSH ) ? 'P' : '.', /* 0x0008: Push function: please push buffered data to the recv application */
- ( xFlags & ipTCP_FLAG_ACK ) ? 'A' : '.', /* 0x0010: Acknowledgment field is significant */
- ( xFlags & ipTCP_FLAG_URG ) ? 'U' : '.', /* 0x0020: Urgent pointer field is significant */
- ( xFlags & ipTCP_FLAG_ECN ) ? 'E' : '.', /* 0x0040: ECN-Echo */
- ( xFlags & ipTCP_FLAG_CWR ) ? 'C' : '.', /* 0x0080: Congestion Window Reduced */
- ( xFlags & ipTCP_FLAG_NS ) ? 'N' : '.'); /* 0x0100: ECN-nonce concealment protection */
- return retString;
- }
- /*-----------------------------------------------------------*/
-
-#endif /* ipconfigHAS_DEBUG_PRINTF */
-
-/*
- * Parse the TCP option(s) received, if present. It has already been verified
- * that: ((pxTCPHeader->ucTCPOffset & 0xf0) > 0x50), meaning that the TP header
- * is longer than the usual 20 (5 x 4) bytes.
- */
-static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
-TCPPacket_t * pxTCPPacket;
-TCPHeader_t * pxTCPHeader;
-const unsigned char *pucPtr;
-const unsigned char *pucLast;
-TCPWindow_t *pxTCPWindow;
-BaseType_t xShouldContinueLoop;
-
- pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
- pxTCPHeader = &pxTCPPacket->xTCPHeader;
-
- /* A character pointer to iterate through the option data */
- pucPtr = pxTCPHeader->ucOptdata;
- pucLast = pucPtr + (((pxTCPHeader->ucTCPOffset >> 4) - 5) << 2);
- pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-
- /* Validate options size calculation. */
- if( pucLast > ( pxNetworkBuffer->pucEthernetBuffer + pxNetworkBuffer->xDataLength ) )
- {
- return;
- }
-
- /* The comparison with pucLast is only necessary in case the option data are
- corrupted, we don't like to run into invalid memory and crash. */
- xShouldContinueLoop = pdTRUE;
- while( ( pucPtr < pucLast ) && ( xShouldContinueLoop == pdTRUE ) )
- {
- xShouldContinueLoop = prvSingleStepTCPHeaderOptions( &pucPtr, &pucLast, &pxSocket, &pxTCPWindow );
- }
-}
-
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow)
-{
- UBaseType_t uxNewMSS;
- UBaseType_t xRemainingOptionsBytes = ( *ppucLast ) - ( *ppucPtr );
- unsigned char ucLen;
-
- if( ( *ppucPtr )[ 0 ] == TCP_OPT_END )
- {
- /* End of options. */
- return pdFALSE;
- }
- if( ( *ppucPtr )[ 0 ] == TCP_OPT_NOOP)
- {
- /* NOP option, inserted to make the length a multiple of 4. */
- ( *ppucPtr )++;
- return pdTRUE;
- }
-
- /* Any other well-formed option must be at least two bytes: the option
- type byte followed by a length byte. */
- if( xRemainingOptionsBytes < 2 )
- {
- return pdFALSE;
- }
-#if( ipconfigUSE_TCP_WIN != 0 )
- else if( ( *ppucPtr )[ 0 ] == TCP_OPT_WSOPT )
- {
- /* Confirm that the option fits in the remaining buffer space. */
- if( ( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ) || ( ( *ppucPtr )[ 1 ] != TCP_OPT_WSOPT_LEN ) )
- {
- return pdFALSE;
- }
-
- ( *ppxSocket )->u.xTCP.ucPeerWinScaleFactor = ( *ppucPtr )[ 2 ];
- ( *ppxSocket )->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
- ( *ppucPtr ) += TCP_OPT_WSOPT_LEN;
- }
-#endif /* ipconfigUSE_TCP_WIN */
- else if( ( *ppucPtr )[ 0 ] == TCP_OPT_MSS )
- {
- /* Confirm that the option fits in the remaining buffer space. */
- if( ( xRemainingOptionsBytes < TCP_OPT_MSS_LEN )|| ( ( *ppucPtr )[ 1 ] != TCP_OPT_MSS_LEN ) )
- {
- return pdFALSE;
- }
-
- /* An MSS option with the correct option length. FreeRTOS_htons()
- is not needed here because usChar2u16() already returns a host
- endian number. */
- uxNewMSS = usChar2u16( ( *ppucPtr ) + 2 );
-
- if( ( *ppxSocket )->u.xTCP.usInitMSS != uxNewMSS )
- {
- /* Perform a basic check on the the new MSS. */
- if( uxNewMSS == 0 )
- {
- return pdFALSE;
- }
-
- FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", ( *ppxSocket )->u.xTCP.usInitMSS, uxNewMSS ) );
- }
-
- if( ( *ppxSocket )->u.xTCP.usInitMSS > uxNewMSS )
- {
- /* our MSS was bigger than the MSS of the other party: adapt it. */
- ( *ppxSocket )->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED;
- if( ( ( *ppxTCPWindow ) != NULL ) && ( ( *ppxSocket )->u.xTCP.usCurMSS > uxNewMSS ) )
- {
- /* The peer advertises a smaller MSS than this socket was
- using. Use that as well. */
- FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", ( *ppxSocket )->u.xTCP.usCurMSS, uxNewMSS ) );
- ( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
- }
- ( *ppxTCPWindow )->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( ( *ppxTCPWindow )->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) );
- ( *ppxTCPWindow )->usMSSInit = ( uint16_t ) uxNewMSS;
- ( *ppxTCPWindow )->usMSS = ( uint16_t ) uxNewMSS;
- ( *ppxSocket )->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS;
- ( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
- }
-
- #if( ipconfigUSE_TCP_WIN != 1 )
- /* Without scaled windows, MSS is the only interesting option. */
- return pdFALSE;
- #else
- /* Or else we continue to check another option: selective ACK. */
- ( *ppucPtr ) += TCP_OPT_MSS_LEN;
- #endif /* ipconfigUSE_TCP_WIN != 1 */
- }
- else
- {
- /* All other options have a length field, so that we easily
- can skip past them. */
- ucLen = ( *ppucPtr )[ 1 ];
- if( ( ucLen < 2 ) || ( ucLen > xRemainingOptionsBytes ) )
- {
- /* If the length field is too small or too big, the options are
- * malformed, don't process them further.
- */
- return pdFALSE;
- }
-
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- /* Selective ACK: the peer has received a packet but it is missing
- * earlier packets. At least this packet does not need retransmission
- * anymore. ulTCPWindowTxSack( ) takes care of this administration.
- */
- if( ( *ppucPtr )[0] == TCP_OPT_SACK_A )
- {
- ucLen -= 2;
- ( *ppucPtr ) += 2;
-
- while( ucLen >= 8 )
- {
- prvSkipPastRemainingOptions( ppucPtr, ppxSocket, &ucLen );
- }
- /* ucLen should be 0 by now. */
- }
- }
- #endif /* ipconfigUSE_TCP_WIN == 1 */
-
- ( *ppucPtr ) += ucLen;
- }
- return pdTRUE;
-}
-
-/*-----------------------------------------------------------*/
-
-static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const pucLen )
-{
-uint32_t ulFirst = ulChar2u32( ( *ppucPtr ) );
-uint32_t ulLast = ulChar2u32( ( *ppucPtr ) + 4 );
-uint32_t ulCount = ulTCPWindowTxSack( &( *ppxSocket )->u.xTCP.xTCPWindow, ulFirst, ulLast );
- /* ulTCPWindowTxSack( ) returns the number of bytes which have been acked
- * starting from the head position. Advance the tail pointer in txStream.
- */
- if( ( ( *ppxSocket )->u.xTCP.txStream != NULL ) && ( ulCount > 0 ) )
- {
- /* Just advancing the tail index, 'ulCount' bytes have been confirmed. */
- uxStreamBufferGet( ( *ppxSocket )->u.xTCP.txStream, 0, NULL, ( size_t ) ulCount, pdFALSE );
- ( *ppxSocket )->xEventBits |= eSOCKET_SEND;
-
- #if ipconfigSUPPORT_SELECT_FUNCTION == 1
- {
- if( ( *ppxSocket )->xSelectBits & eSELECT_WRITE )
- {
- /* The field 'xEventBits' is used to store regular socket events
- * (at most 8), as well as 'select events', which will be left-shifted.
- */
- ( *ppxSocket )->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
-
- /* In case the socket owner has installed an OnSent handler, call it now.
- */
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ipconfigIS_VALID_PROG_ADDRESS( ( *ppxSocket )->u.xTCP.pxHandleSent ) )
- {
- ( *ppxSocket )->u.xTCP.pxHandleSent( (Socket_t )( *ppxSocket ), ulCount );
- }
- }
- #endif /* ipconfigUSE_CALLBACKS == 1 */
- }
- ( *ppucPtr ) += 8;
- ( *pucLen ) -= 8;
-}
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN != 0 )
-
- static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket )
- {
- size_t uxWinSize;
- uint8_t ucFactor;
-
- /* 'xTCP.uxRxWinSize' is the size of the reception window in units of MSS. */
- uxWinSize = pxSocket->u.xTCP.uxRxWinSize * ( size_t ) pxSocket->u.xTCP.usInitMSS;
- ucFactor = 0u;
- while( uxWinSize > 0xfffful )
- {
- /* Divide by two and increase the binary factor by 1. */
- uxWinSize >>= 1;
- ucFactor++;
- }
-
- FreeRTOS_debug_printf( ( "prvWinScaleFactor: uxRxWinSize %lu MSS %lu Factor %u\n",
- pxSocket->u.xTCP.uxRxWinSize,
- pxSocket->u.xTCP.usInitMSS,
- ucFactor ) );
-
- return ucFactor;
- }
-
-#endif
-/*-----------------------------------------------------------*/
-
-/*
- * When opening a TCP connection, while SYN's are being sent, the parties may
- * communicate what MSS (Maximum Segment Size) they intend to use. MSS is the
- * nett size of the payload, always smaller than MTU.
-*/
-static UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t *pxSocket, TCPPacket_t * pxTCPPacket )
-{
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-uint16_t usMSS = pxSocket->u.xTCP.usInitMSS;
-UBaseType_t uxOptionsLength;
-
- /* We send out the TCP Maximum Segment Size option with our SYN[+ACK]. */
-
- pxTCPHeader->ucOptdata[ 0 ] = ( uint8_t ) TCP_OPT_MSS;
- pxTCPHeader->ucOptdata[ 1 ] = ( uint8_t ) TCP_OPT_MSS_LEN;
- pxTCPHeader->ucOptdata[ 2 ] = ( uint8_t ) ( usMSS >> 8 );
- pxTCPHeader->ucOptdata[ 3 ] = ( uint8_t ) ( usMSS & 0xffu );
-
- #if( ipconfigUSE_TCP_WIN != 0 )
- {
- pxSocket->u.xTCP.ucMyWinScaleFactor = prvWinScaleFactor( pxSocket );
-
- pxTCPHeader->ucOptdata[ 4 ] = TCP_OPT_NOOP;
- pxTCPHeader->ucOptdata[ 5 ] = ( uint8_t ) ( TCP_OPT_WSOPT );
- pxTCPHeader->ucOptdata[ 6 ] = ( uint8_t ) ( TCP_OPT_WSOPT_LEN );
- pxTCPHeader->ucOptdata[ 7 ] = ( uint8_t ) pxSocket->u.xTCP.ucMyWinScaleFactor;
- uxOptionsLength = 8u;
- }
- #else
- {
- uxOptionsLength = 4u;
- }
- #endif
-
- #if( ipconfigUSE_TCP_WIN == 0 )
- {
- return uxOptionsLength;
- }
- #else
- {
- pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
- pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
- pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
- pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2; /* 2: length of this option. */
- uxOptionsLength += 4u;
-
- return uxOptionsLength; /* bytes, not words. */
- }
- #endif /* ipconfigUSE_TCP_WIN == 0 */
-}
-
-/*
- * For anti-hanging protection and TCP keep-alive messages. Called in two
- * places: after receiving a packet and after a state change. The socket's
- * alive timer may be reset.
- */
-static void prvTCPTouchSocket( FreeRTOS_Socket_t *pxSocket )
-{
- #if( ipconfigTCP_HANG_PROTECTION == 1 )
- {
- pxSocket->u.xTCP.xLastActTime = xTaskGetTickCount( );
- }
- #endif
-
- #if( ipconfigTCP_KEEP_ALIVE == 1 )
- {
- pxSocket->u.xTCP.bits.bWaitKeepAlive = pdFALSE_UNSIGNED;
- pxSocket->u.xTCP.bits.bSendKeepAlive = pdFALSE_UNSIGNED;
- pxSocket->u.xTCP.ucKeepRepCount = 0u;
- pxSocket->u.xTCP.xLastAliveTime = xTaskGetTickCount();
- }
- #endif
-
- ( void ) pxSocket;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Changing to a new state. Centralised here to do specific actions such as
- * resetting the alive timer, calling the user's OnConnect handler to notify
- * that a socket has got (dis)connected, and setting bit to unblock a call to
- * FreeRTOS_select()
- */
-void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState )
-{
-FreeRTOS_Socket_t *xParent = NULL;
-BaseType_t bBefore = ( BaseType_t ) NOW_CONNECTED( pxSocket->u.xTCP.ucTCPState ); /* Was it connected ? */
-BaseType_t bAfter = ( BaseType_t ) NOW_CONNECTED( eTCPState ); /* Is it connected now ? */
-#if( ipconfigHAS_DEBUG_PRINTF != 0 )
- BaseType_t xPreviousState = ( BaseType_t ) pxSocket->u.xTCP.ucTCPState;
-#endif
-#if( ipconfigUSE_CALLBACKS == 1 )
- FreeRTOS_Socket_t *xConnected = NULL;
-#endif
-
- /* Has the connected status changed? */
- if( bBefore != bAfter )
- {
- /* Is the socket connected now ? */
- if( bAfter != pdFALSE )
- {
- /* if bPassQueued is true, this socket is an orphan until it gets connected. */
- if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
- {
- /* Now that it is connected, find it's parent. */
- if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
- {
- xParent = pxSocket;
- }
- else
- {
- xParent = pxSocket->u.xTCP.pxPeerSocket;
- configASSERT( xParent != NULL );
- }
- if( xParent != NULL )
- {
- if( xParent->u.xTCP.pxPeerSocket == NULL )
- {
- xParent->u.xTCP.pxPeerSocket = pxSocket;
- }
-
- xParent->xEventBits |= eSOCKET_ACCEPT;
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- /* Library support FreeRTOS_select(). Receiving a new
- connection is being translated as a READ event. */
- if( ( xParent->xSelectBits & eSELECT_READ ) != 0 )
- {
- xParent->xEventBits |= ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
-
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ( ipconfigIS_VALID_PROG_ADDRESS( xParent->u.xTCP.pxHandleConnected ) != pdFALSE ) &&
- ( xParent->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) )
- {
- /* The listening socket does not become connected itself, in stead
- a child socket is created.
- Postpone a call the OnConnect event until the end of this function. */
- xConnected = xParent;
- }
- }
- #endif
- }
-
- /* Don't need to access the parent socket anymore, so the
- reference 'pxPeerSocket' may be cleared. */
- pxSocket->u.xTCP.pxPeerSocket = NULL;
- pxSocket->u.xTCP.bits.bPassQueued = pdFALSE_UNSIGNED;
-
- /* When true, this socket may be returned in a call to accept(). */
- pxSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
- }
- else
- {
- pxSocket->xEventBits |= eSOCKET_CONNECT;
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- if( pxSocket->xSelectBits & eSELECT_WRITE )
- {
- pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
- }
- }
- else /* bAfter == pdFALSE, connection is closed. */
- {
- /* Notify/wake-up the socket-owner by setting a semaphore. */
- pxSocket->xEventBits |= eSOCKET_CLOSED;
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
- {
- pxSocket->xEventBits |= ( eSELECT_EXCEPT << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
- }
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleConnected ) != pdFALSE ) && ( xConnected == NULL ) )
- {
- /* The 'connected' state has changed, call the user handler. */
- xConnected = pxSocket;
- }
- }
- #endif /* ipconfigUSE_CALLBACKS */
-
- if( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE )
- {
- /* Now the socket isn't in an active state anymore so it
- won't need further attention of the IP-task.
- Setting time-out to zero means that the socket won't get checked during
- timer events. */
- pxSocket->u.xTCP.usTimeout = 0u;
- }
- }
- else
- {
- if( eTCPState == eCLOSED )
- {
- /* Socket goes to status eCLOSED because of a RST.
- When nobody owns the socket yet, delete it. */
- if( ( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED ) ||
- ( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
- {
- FreeRTOS_debug_printf( ( "vTCPStateChange: Closing socket\n" ) );
- if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
- {
- FreeRTOS_closesocket( pxSocket );
- }
- }
- }
- }
-
- /* Fill in the new state. */
- pxSocket->u.xTCP.ucTCPState = ( uint8_t ) eTCPState;
-
- /* touch the alive timers because moving to another state. */
- prvTCPTouchSocket( pxSocket );
-
- #if( ipconfigHAS_DEBUG_PRINTF == 1 )
- {
- if( ( xTCPWindowLoggingLevel >= 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
- FreeRTOS_debug_printf( ( "Socket %d -> %lxip:%u State %s->%s\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort,
- FreeRTOS_GetTCPStateName( ( UBaseType_t ) xPreviousState ),
- FreeRTOS_GetTCPStateName( ( UBaseType_t ) eTCPState ) ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF */
-
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( xConnected != NULL )
- {
- /* The 'connected' state has changed, call the OnConnect handler of the parent. */
- xConnected->u.xTCP.pxHandleConnected( ( Socket_t ) xConnected, bAfter );
- }
- }
- #endif
- if( xParent != NULL )
- {
- vSocketWakeUpUser( xParent );
- }
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
- int32_t lDataLen, UBaseType_t uxOptionsLength )
-{
-NetworkBufferDescriptor_t *pxReturn;
-int32_t lNeeded;
-BaseType_t xResize;
-
- if( xBufferAllocFixedSize != pdFALSE )
- {
- /* Network buffers are created with a fixed size and can hold the largest
- MTU. */
- lNeeded = ( int32_t ) ipTOTAL_ETHERNET_FRAME_SIZE;
- /* and therefore, the buffer won't be too small.
- Only ask for a new network buffer in case none was supplied. */
- xResize = ( pxNetworkBuffer == NULL );
- }
- else
- {
- /* Network buffers are created with a variable size. See if it must
- grow. */
- lNeeded = FreeRTOS_max_int32( ( int32_t ) sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ),
- ( int32_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen );
- /* In case we were called from a TCP timer event, a buffer must be
- created. Otherwise, test 'xDataLength' of the provided buffer. */
- xResize = ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded );
- }
-
- if( xResize != pdFALSE )
- {
- /* The caller didn't provide a network buffer or the provided buffer is
- too small. As we must send-out a data packet, a buffer will be created
- here. */
- pxReturn = pxGetNetworkBufferWithDescriptor( ( uint32_t ) lNeeded, 0u );
-
- if( pxReturn != NULL )
- {
- /* Set the actual packet size, in case the returned buffer is larger. */
- pxReturn->xDataLength = lNeeded;
-
- /* Copy the existing data to the new created buffer. */
- if( pxNetworkBuffer )
- {
- /* Either from the previous buffer... */
- memcpy( pxReturn->pucEthernetBuffer, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
-
- /* ...and release it. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- else
- {
- /* Or from the socket field 'xTCP.xPacket'. */
- memcpy( pxReturn->pucEthernetBuffer, pxSocket->u.xTCP.xPacket.u.ucLastPacket, sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
- }
- }
- }
- else
- {
- /* xResize is false, the network buffer provided was big enough. */
- pxReturn = pxNetworkBuffer;
-
- /* Thanks to Andrey Ivanov from swissEmbedded for reporting that the
- xDataLength member must get the correct length too! */
- pxNetworkBuffer->xDataLength = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + ( size_t ) lDataLen;
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Prepare an outgoing message, in case anything has to be sent.
- */
-static int32_t prvTCPPrepareSend( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, UBaseType_t uxOptionsLength )
-{
-int32_t lDataLen;
-uint8_t *pucEthernetBuffer, *pucSendData;
-TCPPacket_t *pxTCPPacket;
-size_t uxOffset;
-uint32_t ulDataGot, ulDistance;
-TCPWindow_t *pxTCPWindow;
-NetworkBufferDescriptor_t *pxNewBuffer;
-int32_t lStreamPos;
-
- if( ( *ppxNetworkBuffer ) != NULL )
- {
- /* A network buffer descriptor was already supplied */
- pucEthernetBuffer = ( *ppxNetworkBuffer )->pucEthernetBuffer;
- }
- else
- {
- /* For now let it point to the last packet header */
- pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
- }
-
- pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
- pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
- lDataLen = 0;
- lStreamPos = 0;
- pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_ACK;
-
- if( pxSocket->u.xTCP.txStream != NULL )
- {
- /* ulTCPWindowTxGet will return the amount of data which may be sent
- along with the position in the txStream.
- Why check for MSS > 1 ?
- Because some TCP-stacks (like uIP) use it for flow-control. */
- if( pxSocket->u.xTCP.usCurMSS > 1u )
- {
- lDataLen = ( int32_t ) ulTCPWindowTxGet( pxTCPWindow, pxSocket->u.xTCP.ulWindowSize, &lStreamPos );
- }
-
- if( lDataLen > 0 )
- {
- /* Check if the current network buffer is big enough, if not,
- resize it. */
- pxNewBuffer = prvTCPBufferResize( pxSocket, *ppxNetworkBuffer, lDataLen, uxOptionsLength );
-
- if( pxNewBuffer != NULL )
- {
- *ppxNetworkBuffer = pxNewBuffer;
- pucEthernetBuffer = pxNewBuffer->pucEthernetBuffer;
- pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
-
- pucSendData = pucEthernetBuffer + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength;
-
- /* Translate the position in txStream to an offset from the tail
- marker. */
- uxOffset = uxStreamBufferDistance( pxSocket->u.xTCP.txStream, pxSocket->u.xTCP.txStream->uxTail, ( size_t ) lStreamPos );
-
- /* Here data is copied from the txStream in 'peek' mode. Only
- when the packets are acked, the tail marker will be updated. */
- ulDataGot = ( uint32_t ) uxStreamBufferGet( pxSocket->u.xTCP.txStream, uxOffset, pucSendData, ( size_t ) lDataLen, pdTRUE );
-
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- if( ulDataGot != ( uint32_t ) lDataLen )
- {
- FreeRTOS_debug_printf( ( "uxStreamBufferGet: pos %lu offs %lu only %lu != %lu\n",
- lStreamPos, uxOffset, ulDataGot, lDataLen ) );
- }
- }
- #endif
-
- /* If the owner of the socket requests a closure, add the FIN
- flag to the last packet. */
- if( ( pxSocket->u.xTCP.bits.bCloseRequested != pdFALSE_UNSIGNED ) && ( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) )
- {
- ulDistance = ( uint32_t ) uxStreamBufferDistance( pxSocket->u.xTCP.txStream, ( size_t ) lStreamPos, pxSocket->u.xTCP.txStream->uxHead );
-
- if( ulDistance == ulDataGot )
- {
- #if (ipconfigHAS_DEBUG_PRINTF == 1)
- {
- /* the order of volatile accesses is undefined
- so such workaround */
- size_t uxHead = pxSocket->u.xTCP.txStream->uxHead;
- size_t uxMid = pxSocket->u.xTCP.txStream->uxMid;
- size_t uxTail = pxSocket->u.xTCP.txStream->uxTail;
-
- FreeRTOS_debug_printf( ( "CheckClose %lu <= %lu (%lu <= %lu <= %lu)\n", ulDataGot, ulDistance,
- uxTail, uxMid, uxHead ) );
- }
- #endif
- /* Although the socket sends a FIN, it will stay in
- ESTABLISHED until all current data has been received or
- delivered. */
- pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_FIN;
- pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->ulOurSequenceNumber + ( uint32_t ) lDataLen;
- pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
- }
- }
- }
- else
- {
- lDataLen = -1;
- }
- }
- }
-
- if( ( lDataLen >= 0 ) && ( pxSocket->u.xTCP.ucTCPState == eESTABLISHED ) )
- {
- /* See if the socket owner wants to shutdown this connection. */
- if( ( pxSocket->u.xTCP.bits.bUserShutdown != pdFALSE_UNSIGNED ) &&
- ( xTCPWindowTxDone( pxTCPWindow ) != pdFALSE ) )
- {
- pxSocket->u.xTCP.bits.bUserShutdown = pdFALSE_UNSIGNED;
- pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_FIN;
- pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
- pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
- pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
- vTCPStateChange( pxSocket, eFIN_WAIT_1 );
- }
-
- #if( ipconfigTCP_KEEP_ALIVE != 0 )
- {
- if( pxSocket->u.xTCP.ucKeepRepCount > 3u )
- {
- FreeRTOS_debug_printf( ( "keep-alive: giving up %lxip:%u\n",
- pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine. */
- pxSocket->u.xTCP.usRemotePort ) ); /* Port on remote machine. */
- vTCPStateChange( pxSocket, eCLOSE_WAIT );
- lDataLen = -1;
- }
- if( ( lDataLen == 0 ) && ( pxSocket->u.xTCP.bits.bWinChange == pdFALSE_UNSIGNED ) )
- {
- /* If there is no data to be sent, and no window-update message,
- we might want to send a keep-alive message. */
- TickType_t xAge = xTaskGetTickCount( ) - pxSocket->u.xTCP.xLastAliveTime;
- TickType_t xMax;
- xMax = ( ( TickType_t ) ipconfigTCP_KEEP_ALIVE_INTERVAL * configTICK_RATE_HZ );
- if( pxSocket->u.xTCP.ucKeepRepCount )
- {
- xMax = ( 3u * configTICK_RATE_HZ );
- }
- if( xAge > xMax )
- {
- pxSocket->u.xTCP.xLastAliveTime = xTaskGetTickCount( );
- if( xTCPWindowLoggingLevel )
- FreeRTOS_debug_printf( ( "keep-alive: %lxip:%u count %u\n",
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort,
- pxSocket->u.xTCP.ucKeepRepCount ) );
- pxSocket->u.xTCP.bits.bSendKeepAlive = pdTRUE_UNSIGNED;
- pxSocket->u.xTCP.usTimeout = ( ( uint16_t ) pdMS_TO_TICKS( 2500 ) );
- pxSocket->u.xTCP.ucKeepRepCount++;
- }
- }
- }
- #endif /* ipconfigTCP_KEEP_ALIVE */
- }
-
- /* Anything to send, a change of the advertised window size, or maybe send a
- keep-alive message? */
- if( ( lDataLen > 0 ) ||
- ( pxSocket->u.xTCP.bits.bWinChange != pdFALSE_UNSIGNED ) ||
- ( pxSocket->u.xTCP.bits.bSendKeepAlive != pdFALSE_UNSIGNED ) )
- {
- pxTCPPacket->xTCPHeader.ucTCPFlags &= ( ( uint8_t ) ~ipTCP_FLAG_PSH );
- pxTCPPacket->xTCPHeader.ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
-
- pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_ACK;
-
- if( lDataLen != 0l )
- {
- pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_PSH;
- }
-
- lDataLen += ( int32_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
- }
-
- return lDataLen;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Calculate after how much time this socket needs to be checked again.
- */
-static TickType_t prvTCPNextTimeout ( FreeRTOS_Socket_t *pxSocket )
-{
-TickType_t ulDelayMs = ( TickType_t ) tcpMAXIMUM_TCP_WAKEUP_TIME_MS;
-
- if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
- {
- /* The socket is actively connecting to a peer. */
- if( pxSocket->u.xTCP.bits.bConnPrepared )
- {
- /* Ethernet address has been found, use progressive timeout for
- active connect(). */
- if( pxSocket->u.xTCP.ucRepCount < 3u )
- {
- ulDelayMs = ( 3000UL << ( pxSocket->u.xTCP.ucRepCount - 1u ) );
- }
- else
- {
- ulDelayMs = 11000UL;
- }
- }
- else
- {
- /* Still in the ARP phase: check every half second. */
- ulDelayMs = 500UL;
- }
-
- FreeRTOS_debug_printf( ( "Connect[%lxip:%u]: next timeout %u: %lu ms\n",
- pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort,
- pxSocket->u.xTCP.ucRepCount, ulDelayMs ) );
- pxSocket->u.xTCP.usTimeout = ( uint16_t )pdMS_TO_MIN_TICKS( ulDelayMs );
- }
- else if( pxSocket->u.xTCP.usTimeout == 0u )
- {
- /* Let the sliding window mechanism decide what time-out is appropriate. */
- BaseType_t xResult = xTCPWindowTxHasData( &pxSocket->u.xTCP.xTCPWindow, pxSocket->u.xTCP.ulWindowSize, &ulDelayMs );
- if( ulDelayMs == 0u )
- {
- if( xResult != ( BaseType_t )0 )
- {
- ulDelayMs = 1UL;
- }
- else
- {
- ulDelayMs = tcpMAXIMUM_TCP_WAKEUP_TIME_MS;
- }
- }
- else
- {
- /* ulDelayMs contains the time to wait before a re-transmission. */
- }
- pxSocket->u.xTCP.usTimeout = ( uint16_t )pdMS_TO_MIN_TICKS( ulDelayMs );
- }
- else
- {
- /* field '.usTimeout' has already been set (by the
- keep-alive/delayed-ACK mechanism). */
- }
-
- /* Return the number of clock ticks before the timer expires. */
- return ( TickType_t ) pxSocket->u.xTCP.usTimeout;
-}
-/*-----------------------------------------------------------*/
-
-static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket )
-{
-int32_t lCount, lLength;
-
- /* A txStream has been created already, see if the socket has new data for
- the sliding window.
-
- uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It contains new
- Tx data which has not been passed to the sliding window yet. The oldest
- data not-yet-confirmed can be found at rxTail. */
- lLength = ( int32_t ) uxStreamBufferMidSpace( pxSocket->u.xTCP.txStream );
-
- if( lLength > 0 )
- {
- /* All data between txMid and rxHead will now be passed to the sliding
- window manager, so it can start transmitting them.
-
- Hand over the new data to the sliding window handler. It will be
- split-up in chunks of 1460 bytes each (or less, depending on
- ipconfigTCP_MSS). */
- lCount = lTCPWindowTxAdd( &pxSocket->u.xTCP.xTCPWindow,
- ( uint32_t ) lLength,
- ( int32_t ) pxSocket->u.xTCP.txStream->uxMid,
- ( int32_t ) pxSocket->u.xTCP.txStream->LENGTH );
-
- /* Move the rxMid pointer forward up to rxHead. */
- if( lCount > 0 )
- {
- vStreamBufferMoveMid( pxSocket->u.xTCP.txStream, ( size_t ) lCount );
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvTCPHandleFin() will be called to handle socket closure
- * The Closure starts when either a FIN has been received and accepted,
- * Or when the socket has sent a FIN flag to the peer
- * Before being called, it has been checked that both reception and transmission
- * are complete.
- */
-static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
-TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-BaseType_t xSendLength = 0;
-uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );
-
- if( ( ucTCPFlags & ipTCP_FLAG_FIN ) != 0u )
- {
- pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulFINSequenceNumber + 1u;
- }
- if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
- {
- /* We haven't yet replied with a FIN, do so now. */
- pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
- pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
- }
- else
- {
- /* We did send a FIN already, see if it's ACK'd. */
- if( ulAckNr == pxTCPWindow->tx.ulFINSequenceNumber + 1u )
- {
- pxSocket->u.xTCP.bits.bFinAcked = pdTRUE_UNSIGNED;
- }
- }
-
- if( pxSocket->u.xTCP.bits.bFinAcked == pdFALSE_UNSIGNED )
- {
- pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber;
- pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK | ipTCP_FLAG_FIN;
-
- /* And wait for the final ACK. */
- vTCPStateChange( pxSocket, eLAST_ACK );
- }
- else
- {
- /* Our FIN has been ACK'd, the outgoing sequence number is now fixed. */
- pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber + 1u;
- if( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED )
- {
- /* We have sent out a FIN but the peer hasn't replied with a FIN
- yet. Do nothing for the moment. */
- pxTCPHeader->ucTCPFlags = 0u;
- }
- else
- {
- if( pxSocket->u.xTCP.bits.bFinLast == pdFALSE_UNSIGNED )
- {
- /* This is the third of the three-way hand shake: the last
- ACK. */
- pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
- }
- else
- {
- /* The other party started the closure, so we just wait for the
- last ACK. */
- pxTCPHeader->ucTCPFlags = 0u;
- }
-
- /* And wait for the user to close this socket. */
- vTCPStateChange( pxSocket, eCLOSE_WAIT );
- }
- }
-
- pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
-
- if( pxTCPHeader->ucTCPFlags != 0u )
- {
- xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength );
- }
-
- pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength ) << 2 );
-
- if( xTCPWindowLoggingLevel != 0 )
- {
- FreeRTOS_debug_printf( ( "TCP: send FIN+ACK (ack %lu, cur/nxt %lu/%lu) ourSeqNr %lu | Rx %lu\n",
- ulAckNr - pxTCPWindow->tx.ulFirstSequenceNumber,
- pxTCPWindow->tx.ulCurrentSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
- pxTCPWindow->ulNextTxSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
- pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
- pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) );
- }
-
- return xSendLength;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvCheckRxData(): called from prvTCPHandleState()
- *
- * The first thing that will be done is find the TCP payload data
- * and check the length of this data.
- */
-static BaseType_t prvCheckRxData( NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &( pxTCPPacket->xTCPHeader );
-int32_t lLength, lTCPHeaderLength, lReceiveLength, lUrgentLength;
-
- /* Determine the length and the offset of the user-data sent to this
- node.
-
- The size of the TCP header is given in a multiple of 4-byte words (single
- byte, needs no ntoh() translation). A shift-right 2: is the same as
- (offset >> 4) * 4. */
- lTCPHeaderLength = ( BaseType_t ) ( ( pxTCPHeader->ucTCPOffset & VALID_BITS_IN_TCP_OFFSET_BYTE ) >> 2 );
-
- /* Let pucRecvData point to the first byte received. */
- *ppucRecvData = pxNetworkBuffer->pucEthernetBuffer + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + lTCPHeaderLength;
-
- /* Calculate lReceiveLength - the length of the TCP data received. This is
- equal to the total packet length minus:
- ( LinkLayer length (14) + IP header length (20) + size of TCP header(20 +) ).*/
- lReceiveLength = ( ( int32_t ) pxNetworkBuffer->xDataLength ) - ( int32_t ) ipSIZE_OF_ETH_HEADER;
- lLength = ( int32_t )FreeRTOS_htons( pxTCPPacket->xIPHeader.usLength );
-
- if( lReceiveLength > lLength )
- {
- /* More bytes were received than the reported length, often because of
- padding bytes at the end. */
- lReceiveLength = lLength;
- }
-
- /* Subtract the size of the TCP and IP headers and the actual data size is
- known. */
- if( lReceiveLength > ( lTCPHeaderLength + ( int32_t ) ipSIZE_OF_IPv4_HEADER ) )
- {
- lReceiveLength -= ( lTCPHeaderLength + ( int32_t ) ipSIZE_OF_IPv4_HEADER );
- }
- else
- {
- lReceiveLength = 0;
- }
-
- /* Urgent Pointer:
- This field communicates the current value of the urgent pointer as a
- positive offset from the sequence number in this segment. The urgent
- pointer points to the sequence number of the octet following the urgent
- data. This field is only be interpreted in segments with the URG control
- bit set. */
- if( ( pxTCPHeader->ucTCPFlags & ipTCP_FLAG_URG ) != 0u )
- {
- /* Although we ignore the urgent data, we have to skip it. */
- lUrgentLength = ( int32_t ) FreeRTOS_htons( pxTCPHeader->usUrgent );
- *ppucRecvData += lUrgentLength;
- lReceiveLength -= FreeRTOS_min_int32( lReceiveLength, lUrgentLength );
- }
-
- return ( BaseType_t ) lReceiveLength;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvStoreRxData(): called from prvTCPHandleState()
- *
- * The second thing is to do is check if the payload data may be accepted
- * If so, they will be added to the reception queue.
- */
-static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, uint8_t *pucRecvData,
- NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-uint32_t ulSequenceNumber, ulSpace;
-int32_t lOffset, lStored;
-BaseType_t xResult = 0;
-
- ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );
-
- if( ( ulReceiveLength > 0u ) && ( pxSocket->u.xTCP.ucTCPState >= eSYN_RECEIVED ) )
- {
- /* See if way may accept the data contents and forward it to the socket
- owner.
-
- If it can't be "accept"ed it may have to be stored and send a selective
- ack (SACK) option to confirm it. In that case, xTCPWindowRxStore() will be
- called later to store an out-of-order packet (in case lOffset is
- negative). */
- if ( pxSocket->u.xTCP.rxStream )
- {
- ulSpace = ( uint32_t )uxStreamBufferGetSpace ( pxSocket->u.xTCP.rxStream );
- }
- else
- {
- ulSpace = ( uint32_t )pxSocket->u.xTCP.uxRxStreamSize;
- }
-
- lOffset = lTCPWindowRxCheck( pxTCPWindow, ulSequenceNumber, ulReceiveLength, ulSpace );
-
- if( lOffset >= 0 )
- {
- /* New data has arrived and may be made available to the user. See
- if the head marker in rxStream may be advanced, only if lOffset == 0.
- In case the low-water mark is reached, bLowWater will be set
- "low-water" here stands for "little space". */
- lStored = lTCPAddRxdata( pxSocket, ( uint32_t ) lOffset, pucRecvData, ulReceiveLength );
-
- if( lStored != ( int32_t ) ulReceiveLength )
- {
- FreeRTOS_debug_printf( ( "lTCPAddRxdata: stored %ld / %lu bytes??\n", lStored, ulReceiveLength ) );
-
- /* Received data could not be stored. The socket's flag
- bMallocError has been set. The socket now has the status
- eCLOSE_WAIT and a RST packet will be sent back. */
- prvTCPSendReset( pxNetworkBuffer );
- xResult = -1;
- }
- }
-
- /* After a missing packet has come in, higher packets may be passed to
- the user. */
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- /* Now lTCPAddRxdata() will move the rxHead pointer forward
- so data becomes available to the user immediately
- In case the low-water mark is reached, bLowWater will be set. */
- if( ( xResult == 0 ) && ( pxTCPWindow->ulUserDataLength > 0 ) )
- {
- lTCPAddRxdata( pxSocket, 0ul, NULL, pxTCPWindow->ulUserDataLength );
- pxTCPWindow->ulUserDataLength = 0;
- }
- }
- #endif /* ipconfigUSE_TCP_WIN */
- }
- else
- {
- pxTCPWindow->ucOptionLength = 0u;
- }
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-/* Set the TCP options (if any) for the outgoing packet. */
-static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength;
-
- #if( ipconfigUSE_TCP_WIN == 1 )
- if( uxOptionsLength != 0u )
- {
- /* TCP options must be sent because a packet which is out-of-order
- was received. */
- if( xTCPWindowLoggingLevel >= 0 )
- FreeRTOS_debug_printf( ( "SACK[%d,%d]: optlen %lu sending %lu - %lu\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usRemotePort,
- uxOptionsLength,
- FreeRTOS_ntohl( pxTCPWindow->ulOptionsData[ 1 ] ) - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber,
- FreeRTOS_ntohl( pxTCPWindow->ulOptionsData[ 2 ] ) - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber ) );
- memcpy( pxTCPHeader->ucOptdata, pxTCPWindow->ulOptionsData, ( size_t ) uxOptionsLength );
-
- /* The header length divided by 4, goes into the higher nibble,
- effectively a shift-left 2. */
- pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
- }
- else
- #endif /* ipconfigUSE_TCP_WIN */
- if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.bits.bMssChange != pdFALSE_UNSIGNED ) )
- {
- /* TCP options must be sent because the MSS has changed. */
- pxSocket->u.xTCP.bits.bMssChange = pdFALSE_UNSIGNED;
- if( xTCPWindowLoggingLevel >= 0 )
- {
- FreeRTOS_debug_printf( ( "MSS: sending %d\n", pxSocket->u.xTCP.usCurMSS ) );
- }
-
- pxTCPHeader->ucOptdata[ 0 ] = TCP_OPT_MSS;
- pxTCPHeader->ucOptdata[ 1 ] = TCP_OPT_MSS_LEN;
- pxTCPHeader->ucOptdata[ 2 ] = ( uint8_t ) ( ( pxSocket->u.xTCP.usCurMSS ) >> 8 );
- pxTCPHeader->ucOptdata[ 3 ] = ( uint8_t ) ( ( pxSocket->u.xTCP.usCurMSS ) & 0xffu );
- uxOptionsLength = 4u;
- pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
- }
-
- return uxOptionsLength;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvHandleSynReceived(): called from prvTCPHandleState()
- *
- * Called from the states: eSYN_RECEIVED and eCONNECT_SYN
- * If the flags received are correct, the socket will move to eESTABLISHED.
- */
-static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
- uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
-uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );
-BaseType_t xSendLength = 0;
-
- /* Either expect a ACK or a SYN+ACK. */
- uint16_t usExpect = ( uint16_t ) ipTCP_FLAG_ACK;
- if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
- {
- usExpect |= ( uint16_t ) ipTCP_FLAG_SYN;
- }
-
- if( ( ucTCPFlags & 0x17u ) != usExpect )
- {
- /* eSYN_RECEIVED: flags 0010 expected, not 0002. */
- /* eSYN_RECEIVED: flags ACK expected, not SYN. */
- FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n",
- pxSocket->u.xTCP.ucTCPState == eSYN_RECEIVED ? "eSYN_RECEIVED" : "eCONNECT_SYN",
- usExpect, ucTCPFlags ) );
- vTCPStateChange( pxSocket, eCLOSE_WAIT );
- pxTCPHeader->ucTCPFlags |= ipTCP_FLAG_RST;
- xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
- pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
- }
- else
- {
- pxTCPWindow->usPeerPortNumber = pxSocket->u.xTCP.usRemotePort;
- pxTCPWindow->usOurPortNumber = pxSocket->usLocalPort;
-
- if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
- {
- TCPPacket_t *pxLastTCPPacket = ( TCPPacket_t * ) ( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
-
- /* Clear the SYN flag in lastPacket. */
- pxLastTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_ACK;
-
- /* This socket was the one connecting actively so now perofmr the
- synchronisation. */
- vTCPWindowInit( &pxSocket->u.xTCP.xTCPWindow,
- ulSequenceNumber, pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber, ( uint32_t ) pxSocket->u.xTCP.usCurMSS );
- pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1u;
- pxTCPWindow->tx.ulCurrentSequenceNumber++; /* because we send a TCP_SYN [ | TCP_ACK ]; */
- pxTCPWindow->ulNextTxSequenceNumber++;
- }
- else if( ulReceiveLength == 0u )
- {
- pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber;
- }
-
- /* The SYN+ACK has been confirmed, increase the next sequence number by
- 1. */
- pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1u;
-
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- FreeRTOS_debug_printf( ( "TCP: %s %d => %lxip:%d set ESTAB (scaling %u)\n",
- pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ? "active" : "passive",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.ulRemoteIP,
- pxSocket->u.xTCP.usRemotePort,
- ( unsigned ) pxSocket->u.xTCP.bits.bWinScaling ) );
- }
- #endif /* ipconfigUSE_TCP_WIN */
-
- if( ( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ) || ( ulReceiveLength != 0u ) )
- {
- pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
- xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
- pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
- }
- #if( ipconfigUSE_TCP_WIN != 0 )
- {
- if( pxSocket->u.xTCP.bits.bWinScaling == pdFALSE_UNSIGNED )
- {
- /* The other party did not send a scaling factor.
- A shifting factor in this side must be canceled. */
- pxSocket->u.xTCP.ucMyWinScaleFactor = 0;
- pxSocket->u.xTCP.ucPeerWinScaleFactor = 0;
- }
- }
- #endif /* ipconfigUSE_TCP_WIN */
- /* This was the third step of connecting: SYN, SYN+ACK, ACK so now the
- connection is established. */
- vTCPStateChange( pxSocket, eESTABLISHED );
- }
-
- return xSendLength;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvHandleEstablished(): called from prvTCPHandleState()
- *
- * Called if the status is eESTABLISHED. Data reception has been handled
- * earlier. Here the ACK's from peer will be checked, and if a FIN is received,
- * the code will check if it may be accepted, i.e. if all expected data has been
- * completely received.
- */
-static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
- uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
-uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ), ulCount;
-BaseType_t xSendLength = 0, xMayClose = pdFALSE, bRxComplete, bTxDone;
-int32_t lDistance, lSendResult;
-
- /* Remember the window size the peer is advertising. */
- pxSocket->u.xTCP.ulWindowSize = FreeRTOS_ntohs( pxTCPHeader->usWindow );
- #if( ipconfigUSE_TCP_WIN != 0 )
- {
- pxSocket->u.xTCP.ulWindowSize =
- ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor );
- }
- #endif
-
- if( ( ucTCPFlags & ( uint8_t ) ipTCP_FLAG_ACK ) != 0u )
- {
- ulCount = ulTCPWindowTxAck( pxTCPWindow, FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr ) );
-
- /* ulTCPWindowTxAck() returns the number of bytes which have been acked,
- starting at 'tx.ulCurrentSequenceNumber'. Advance the tail pointer in
- txStream. */
- if( ( pxSocket->u.xTCP.txStream != NULL ) && ( ulCount > 0u ) )
- {
- /* Just advancing the tail index, 'ulCount' bytes have been
- confirmed, and because there is new space in the txStream, the
- user/owner should be woken up. */
- /* _HT_ : only in case the socket's waiting? */
- if( uxStreamBufferGet( pxSocket->u.xTCP.txStream, 0u, NULL, ( size_t ) ulCount, pdFALSE ) != 0u )
- {
- pxSocket->xEventBits |= eSOCKET_SEND;
-
- #if ipconfigSUPPORT_SELECT_FUNCTION == 1
- {
- if( ( pxSocket->xSelectBits & eSELECT_WRITE ) != 0 )
- {
- pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
- }
- }
- #endif
- /* In case the socket owner has installed an OnSent handler,
- call it now. */
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleSent ) )
- {
- pxSocket->u.xTCP.pxHandleSent( ( Socket_t )pxSocket, ulCount );
- }
- }
- #endif /* ipconfigUSE_CALLBACKS == 1 */
- }
- }
- }
-
- /* If this socket has a stream for transmission, add the data to the
- outgoing segment(s). */
- if( pxSocket->u.xTCP.txStream != NULL )
- {
- prvTCPAddTxData( pxSocket );
- }
-
- pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
-
- if( ( pxSocket->u.xTCP.bits.bFinAccepted != pdFALSE_UNSIGNED ) || ( ( ucTCPFlags & ( uint8_t ) ipTCP_FLAG_FIN ) != 0u ) )
- {
- /* Peer is requesting to stop, see if we're really finished. */
- xMayClose = pdTRUE;
-
- /* Checks are only necessary if we haven't sent a FIN yet. */
- if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
- {
- /* xTCPWindowTxDone returns true when all Tx queues are empty. */
- bRxComplete = xTCPWindowRxEmpty( pxTCPWindow );
- bTxDone = xTCPWindowTxDone( pxTCPWindow );
-
- if( ( bRxComplete == 0 ) || ( bTxDone == 0 ) )
- {
- /* Refusing FIN: Rx incomp 1 optlen 4 tx done 1. */
- FreeRTOS_debug_printf( ( "Refusing FIN[%u,%u]: RxCompl %lu tx done %ld\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usRemotePort,
- bRxComplete, bTxDone ) );
- xMayClose = pdFALSE;
- }
- else
- {
- lDistance = ( int32_t ) ( ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber );
-
- if( lDistance > 1 )
- {
- FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %ld (cur %lu high %lu)\n",
- lDistance, pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
- pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) );
-
- xMayClose = pdFALSE;
- }
- }
- }
-
- if( xTCPWindowLoggingLevel > 0 )
- {
- FreeRTOS_debug_printf( ( "TCP: FIN received, mayClose = %ld (Rx %lu Len %ld, Tx %lu)\n",
- xMayClose, ulSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber, ulReceiveLength,
- pxTCPWindow->tx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber ) );
- }
-
- if( xMayClose != pdFALSE )
- {
- pxSocket->u.xTCP.bits.bFinAccepted = pdTRUE_UNSIGNED;
- xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer );
- }
- }
-
- if( xMayClose == pdFALSE )
- {
- pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
-
- if( ulReceiveLength != 0u )
- {
- xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
- /* TCP-offsett equals '( ( length / 4 ) << 4 )', resulting in a shift-left 2 */
- pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
-
- if( pxSocket->u.xTCP.bits.bFinSent != pdFALSE_UNSIGNED )
- {
- pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber;
- }
- }
-
- /* Now get data to be transmitted. */
- /* _HT_ patch: since the MTU has be fixed at 1500 in stead of 1526, TCP
- can not send-out both TCP options and also a full packet. Sending
- options (SACK) is always more urgent than sending data, which can be
- sent later. */
- if( uxOptionsLength == 0u )
- {
- /* prvTCPPrepareSend might allocate a bigger network buffer, if
- necessary. */
- lSendResult = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
- if( lSendResult > 0 )
- {
- xSendLength = ( BaseType_t ) lSendResult;
- }
- }
- }
-
- return xSendLength;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Called from prvTCPHandleState(). There is data to be sent. If
- * ipconfigUSE_TCP_WIN is defined, and if only an ACK must be sent, it will be
- * checked if it would better be postponed for efficiency.
- */
-static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
- uint32_t ulReceiveLength, BaseType_t xSendLength )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
-TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
-/* Find out what window size we may advertised. */
-int32_t lRxSpace;
-#if( ipconfigUSE_TCP_WIN == 1 )
- #if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
- const int32_t lMinLength = 0;
- #else
- int32_t lMinLength;
- #endif
-#endif
-
- /* Set the time-out field, so that we'll be called by the IP-task in case no
- next message will be received. */
- lRxSpace = (int32_t)( pxSocket->u.xTCP.ulHighestRxAllowed - pxTCPWindow->rx.ulCurrentSequenceNumber );
- #if ipconfigUSE_TCP_WIN == 1
- {
-
- #if( ipconfigTCP_ACK_EARLIER_PACKET != 0 )
- {
- lMinLength = ( ( int32_t ) 2 ) * ( ( int32_t ) pxSocket->u.xTCP.usCurMSS );
- }
- #endif /* ipconfigTCP_ACK_EARLIER_PACKET */
-
- /* In case we're receiving data continuously, we might postpone sending
- an ACK to gain performance. */
- if( ( ulReceiveLength > 0 ) && /* Data was sent to this socket. */
- ( lRxSpace >= lMinLength ) && /* There is Rx space for more data. */
- ( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) && /* Not in a closure phase. */
- ( xSendLength == ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) ) && /* No Tx data or options to be sent. */
- ( pxSocket->u.xTCP.ucTCPState == eESTABLISHED ) && /* Connection established. */
- ( pxTCPHeader->ucTCPFlags == ipTCP_FLAG_ACK ) ) /* There are no other flags than an ACK. */
- {
- if( pxSocket->u.xTCP.pxAckMessage != *ppxNetworkBuffer )
- {
- /* There was still a delayed in queue, delete it. */
- if( pxSocket->u.xTCP.pxAckMessage != 0 )
- {
- vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
- }
-
- pxSocket->u.xTCP.pxAckMessage = *ppxNetworkBuffer;
- }
- if( ( ulReceiveLength < ( uint32_t ) pxSocket->u.xTCP.usCurMSS ) || /* Received a small message. */
- ( lRxSpace < ( int32_t ) ( 2U * pxSocket->u.xTCP.usCurMSS ) ) ) /* There are less than 2 x MSS space in the Rx buffer. */
- {
- pxSocket->u.xTCP.usTimeout = ( uint16_t ) pdMS_TO_MIN_TICKS( DELAYED_ACK_SHORT_DELAY_MS );
- }
- else
- {
- /* Normally a delayed ACK should wait 200 ms for a next incoming
- packet. Only wait 20 ms here to gain performance. A slow ACK
- for full-size message. */
- pxSocket->u.xTCP.usTimeout = ( uint16_t ) pdMS_TO_MIN_TICKS( DELAYED_ACK_LONGER_DELAY_MS );
- }
-
- if( ( xTCPWindowLoggingLevel > 1 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %lu SEQ %lu (len %lu) tmout %u d %lu\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usRemotePort,
- pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
- pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
- xSendLength,
- pxSocket->u.xTCP.usTimeout, lRxSpace ) );
- }
-
- *ppxNetworkBuffer = NULL;
- xSendLength = 0;
- }
- else if( pxSocket->u.xTCP.pxAckMessage != NULL )
- {
- /* As an ACK is not being delayed, remove any earlier delayed ACK
- message. */
- if( pxSocket->u.xTCP.pxAckMessage != *ppxNetworkBuffer )
- {
- vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
- }
-
- pxSocket->u.xTCP.pxAckMessage = NULL;
- }
- }
- #else
- {
- /* Remove compiler warnings. */
- ( void ) ulReceiveLength;
- ( void ) pxTCPHeader;
- ( void ) lRxSpace;
- }
- #endif /* ipconfigUSE_TCP_WIN */
-
- if( xSendLength != 0 )
- {
- if( ( xTCPWindowLoggingLevel > 1 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "Send[%u->%u] imm ACK %lu SEQ %lu (len %lu)\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usRemotePort,
- pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
- pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
- xSendLength ) );
- }
-
- /* Set the parameter 'xReleaseAfterSend' to the value of
- ipconfigZERO_COPY_TX_DRIVER. */
- prvTCPReturnPacket( pxSocket, *ppxNetworkBuffer, ( uint32_t ) xSendLength, ipconfigZERO_COPY_TX_DRIVER );
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* The driver has taken ownership of the Network Buffer. */
- *ppxNetworkBuffer = NULL;
- }
- #endif
- }
-
- return xSendLength;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * prvTCPHandleState()
- * is the most important function of this TCP stack
- * We've tried to keep it (relatively short) by putting a lot of code in
- * the static functions above:
- *
- * prvCheckRxData()
- * prvStoreRxData()
- * prvSetOptions()
- * prvHandleSynReceived()
- * prvHandleEstablished()
- * prvSendData()
- *
- * As these functions are declared static, and they're called from one location
- * only, most compilers will inline them, thus avoiding a call and return.
- */
-static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
-{
-TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
-TCPHeader_t *pxTCPHeader = &( pxTCPPacket->xTCPHeader );
-BaseType_t xSendLength = 0;
-uint32_t ulReceiveLength; /* Number of bytes contained in the TCP message. */
-uint8_t *pucRecvData;
-uint32_t ulSequenceNumber = FreeRTOS_ntohl (pxTCPHeader->ulSequenceNumber);
-
- /* uxOptionsLength: the size of the options to be sent (always a multiple of
- 4 bytes)
- 1. in the SYN phase, we shall communicate the MSS
- 2. in case of a SACK, Selective ACK, ack a segment which comes in
- out-of-order. */
-UBaseType_t uxOptionsLength = 0u;
-uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
-TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
-
- /* First get the length and the position of the received data, if any.
- pucRecvData will point to the first byte of the TCP payload. */
- ulReceiveLength = ( uint32_t ) prvCheckRxData( *ppxNetworkBuffer, &pucRecvData );
-
- if( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED )
- {
- if ( pxTCPWindow->rx.ulCurrentSequenceNumber == ulSequenceNumber + 1u )
- {
- /* This is most probably a keep-alive message from peer. Setting
- 'bWinChange' doesn't cause a window-size-change, the flag is used
- here to force sending an immediate ACK. */
- pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
- }
- }
-
- /* Keep track of the highest sequence number that might be expected within
- this connection. */
- if( ( ( int32_t ) ( ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulHighestSequenceNumber ) ) > 0 )
- {
- pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + ulReceiveLength;
- }
-
- /* Storing data may result in a fatal error if malloc() fails. */
- if( prvStoreRxData( pxSocket, pucRecvData, *ppxNetworkBuffer, ulReceiveLength ) < 0 )
- {
- xSendLength = -1;
- }
- else
- {
- uxOptionsLength = prvSetOptions( pxSocket, *ppxNetworkBuffer );
-
- if( ( pxSocket->u.xTCP.ucTCPState == eSYN_RECEIVED ) && ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) )
- {
- FreeRTOS_debug_printf( ( "eSYN_RECEIVED: ACK expected, not SYN: peer missed our SYN+ACK\n" ) );
-
- /* In eSYN_RECEIVED a simple ACK is expected, but apparently the
- 'SYN+ACK' didn't arrive. Step back to the previous state in which
- a first incoming SYN is handled. The SYN was counted already so
- decrease it first. */
- vTCPStateChange( pxSocket, eSYN_FIRST );
- }
-
- if( ( ( ucTCPFlags & ipTCP_FLAG_FIN ) != 0u ) && ( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED ) )
- {
- /* It's the first time a FIN has been received, remember its
- sequence number. */
- pxTCPWindow->rx.ulFINSequenceNumber = ulSequenceNumber + ulReceiveLength;
- pxSocket->u.xTCP.bits.bFinRecv = pdTRUE_UNSIGNED;
-
- /* Was peer the first one to send a FIN? */
- if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
- {
- /* If so, don't send the-last-ACK. */
- pxSocket->u.xTCP.bits.bFinLast = pdTRUE_UNSIGNED;
- }
- }
-
- switch (pxSocket->u.xTCP.ucTCPState)
- {
- case eCLOSED: /* (server + client) no connection state at all. */
- /* Nothing to do for a closed socket, except waiting for the
- owner. */
- break;
-
- case eTCP_LISTEN: /* (server) waiting for a connection request from
- any remote TCP and port. */
- /* The listen state was handled in xProcessReceivedTCPPacket().
- Should not come here. */
- break;
-
- case eSYN_FIRST: /* (server) Just received a SYN request for a server
- socket. */
- {
- /* A new socket has been created, reply with a SYN+ACK.
- Acknowledge with seq+1 because the SYN is seen as pseudo data
- with len = 1. */
- uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPPacket );
- pxTCPHeader->ucTCPFlags = ipTCP_FLAG_SYN | ipTCP_FLAG_ACK;
-
- xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
-
- /* Set the TCP offset field: ipSIZE_OF_TCP_HEADER equals 20 and
- uxOptionsLength is a multiple of 4. The complete expression is:
- ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */
- pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
- vTCPStateChange( pxSocket, eSYN_RECEIVED );
-
- pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1u;
- pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->ulNextTxSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1u; /* because we send a TCP_SYN. */
- }
- break;
-
- case eCONNECT_SYN: /* (client) also called SYN_SENT: we've just send a
- SYN, expect a SYN+ACK and send a ACK now. */
- /* Fall through */
- case eSYN_RECEIVED: /* (server) we've had a SYN, replied with SYN+SCK
- expect a ACK and do nothing. */
- xSendLength = prvHandleSynReceived( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength );
- break;
-
- case eESTABLISHED: /* (server + client) an open connection, data
- received can be delivered to the user. The normal
- state for the data transfer phase of the connection
- The closing states are also handled here with the
- use of some flags. */
- xSendLength = prvHandleEstablished( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength );
- break;
-
- case eLAST_ACK: /* (server + client) waiting for an acknowledgement
- of the connection termination request previously
- sent to the remote TCP (which includes an
- acknowledgement of its connection termination
- request). */
- /* Fall through */
- case eFIN_WAIT_1: /* (server + client) waiting for a connection termination request from the remote TCP,
- * or an acknowledgement of the connection termination request previously sent. */
- /* Fall through */
- case eFIN_WAIT_2: /* (server + client) waiting for a connection termination request from the remote TCP. */
- xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer );
- break;
-
- case eCLOSE_WAIT: /* (server + client) waiting for a connection
- termination request from the local user. Nothing to
- do, connection is closed, wait for owner to close
- this socket. */
- break;
-
- case eCLOSING: /* (server + client) waiting for a connection
- termination request acknowledgement from the remote
- TCP. */
- break;
-
- case eTIME_WAIT: /* (either server or client) waiting for enough time
- to pass to be sure the remote TCP received the
- acknowledgement of its connection termination
- request. [According to RFC 793 a connection can stay
- in TIME-WAIT for a maximum of four minutes known as
- a MSL (maximum segment lifetime).] These states are
- implemented implicitly by settings flags like
- 'bFinSent', 'bFinRecv', and 'bFinAcked'. */
- break;
- default:
- break;
- }
- }
-
- if( xSendLength > 0 )
- {
- xSendLength = prvSendData( pxSocket, ppxNetworkBuffer, ulReceiveLength, xSendLength );
- }
-
- return xSendLength;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
- uint8_t ucTCPFlags )
-{
-#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
- {
- TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
- const BaseType_t xSendLength = ( BaseType_t )
- ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
-
- pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
- pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;
-
- prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
- }
-#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
-
- /* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
- ( void )pxNetworkBuffer;
- ( void )ucTCPFlags;
-
- /* The packet was not consumed. */
- return pdFAIL;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
- return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
- return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
- ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
-}
-/*-----------------------------------------------------------*/
-
-static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
-{
-uint32_t ulMSS = ipconfigTCP_MSS;
-
- if( ( ( FreeRTOS_ntohl( pxSocket->u.xTCP.ulRemoteIP ) ^ *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) != 0ul )
- {
- /* Data for this peer will pass through a router, and maybe through
- the internet. Limit the MSS to 1400 bytes or less. */
- ulMSS = FreeRTOS_min_uint32( ( uint32_t ) REDUCED_MSS_THROUGH_INTERNET, ulMSS );
- }
-
- FreeRTOS_debug_printf( ( "prvSocketSetMSS: %lu bytes for %lxip:%u\n", ulMSS, pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort ) );
-
- pxSocket->u.xTCP.usInitMSS = pxSocket->u.xTCP.usCurMSS = ( uint16_t ) ulMSS;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * FreeRTOS_TCP_IP has only 2 public functions, this is the second one:
- * xProcessReceivedTCPPacket()
- * prvTCPHandleState()
- * prvTCPPrepareSend()
- * prvTCPReturnPacket()
- * xNetworkInterfaceOutput() // Sends data to the NIC
- * prvTCPSendRepeated()
- * prvTCPReturnPacket() // Prepare for returning
- * xNetworkInterfaceOutput() // Sends data to the NIC
-*/
-BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
-FreeRTOS_Socket_t *pxSocket;
-TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-uint16_t ucTCPFlags;
-uint32_t ulLocalIP;
-uint16_t xLocalPort;
-uint32_t ulRemoteIP;
-uint16_t xRemotePort;
-uint32_t ulSequenceNumber;
-uint32_t ulAckNumber;
-BaseType_t xResult = pdPASS;
-configASSERT(pxNetworkBuffer);
-configASSERT(pxNetworkBuffer->pucEthernetBuffer);
-
- /* Check for a minimum packet size. */
- if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
- {
- ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
- ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
- xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
- ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
- xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
- ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
- ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );
-
- /* Find the destination socket, and if not found: return a socket listing to
- the destination PORT. */
- pxSocket = ( FreeRTOS_Socket_t * )pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
- }
- else
- {
- return pdFAIL;
- }
-
- if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE ) )
- {
- /* A TCP messages is received but either there is no socket with the
- given port number or the there is a socket, but it is in one of these
- non-active states: eCLOSED, eCLOSE_WAIT, eFIN_WAIT_2, eCLOSING, or
- eTIME_WAIT. */
-
- FreeRTOS_debug_printf( ( "TCP: No active socket on port %d (%lxip:%d)\n", xLocalPort, ulRemoteIP, xRemotePort ) );
-
- /* Send a RST to all packets that can not be handled. As a result
- the other party will get a ECONN error. There are two exceptions:
- 1) A packet that already has the RST flag set.
- 2) A packet that only has the ACK flag set.
- A packet with only the ACK flag set might be the last ACK in
- a three-way hand-shake that closes a connection. */
- if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) != ipTCP_FLAG_ACK ) &&
- ( ( ucTCPFlags & ipTCP_FLAG_RST ) == 0u ) )
- {
- prvTCPSendReset( pxNetworkBuffer );
- }
-
- /* The packet can't be handled. */
- xResult = pdFAIL;
- }
- else
- {
- pxSocket->u.xTCP.ucRepCount = 0u;
-
- if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
- {
- /* The matching socket is in a listening state. Test if the peer
- has set the SYN flag. */
- if( ( ucTCPFlags & ipTCP_FLAG_CTRL ) != ipTCP_FLAG_SYN )
- {
- /* What happens: maybe after a reboot, a client doesn't know the
- connection had gone. Send a RST in order to get a new connect
- request. */
- #if( ipconfigHAS_DEBUG_PRINTF == 1 )
- {
- FreeRTOS_debug_printf( ( "TCP: Server can't handle flags: %s from %lxip:%u to port %u\n",
- prvTCPFlagMeaning( ( UBaseType_t ) ucTCPFlags ), ulRemoteIP, xRemotePort, xLocalPort ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF */
-
- if( ( ucTCPFlags & ipTCP_FLAG_RST ) == 0u )
- {
- prvTCPSendReset( pxNetworkBuffer );
- }
- xResult = pdFAIL;
- }
- else
- {
- /* prvHandleListen() will either return a newly created socket
- (if bReuseSocket is false), otherwise it returns the current
- socket which will later get connected. */
- pxSocket = prvHandleListen( pxSocket, pxNetworkBuffer );
-
- if( pxSocket == NULL )
- {
- xResult = pdFAIL;
- }
- }
- } /* if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN ). */
- else
- {
- /* This is not a socket in listening mode. Check for the RST
- flag. */
- if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
- {
- FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
-
- /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
- if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
- {
- /* Per the above RFC, "In the SYN-SENT state ... the RST is
- acceptable if the ACK field acknowledges the SYN." */
- if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
- {
- vTCPStateChange( pxSocket, eCLOSED );
- }
- }
- else
- {
- /* Check whether the packet matches the next expected sequence number. */
- if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
- {
- vTCPStateChange( pxSocket, eCLOSED );
- }
- /* Otherwise, check whether the packet is within the receive window. */
- else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
- ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
- pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
- {
- /* Send a challenge ACK. */
- prvTCPSendChallengeAck( pxNetworkBuffer );
- }
- }
-
- /* Otherwise, do nothing. In any case, the packet cannot be handled. */
- xResult = pdFAIL;
- }
- else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )
- {
- /* SYN flag while this socket is already connected. */
- FreeRTOS_debug_printf( ( "TCP: SYN unexpected from %lxip:%u\n", ulRemoteIP, xRemotePort ) );
-
- /* The packet cannot be handled. */
- xResult = pdFAIL;
- }
- else
- {
- /* Update the copy of the TCP header only (skipping eth and IP
- headers). It might be used later on, whenever data must be sent
- to the peer. */
- const BaseType_t lOffset = ( BaseType_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER );
- memcpy( pxSocket->u.xTCP.xPacket.u.ucLastPacket + lOffset, pxNetworkBuffer->pucEthernetBuffer + lOffset, ipSIZE_OF_TCP_HEADER );
- }
- }
- }
-
- if( xResult != pdFAIL )
- {
- /* Touch the alive timers because we received a message for this
- socket. */
- prvTCPTouchSocket( pxSocket );
-
- /* Parse the TCP option(s), if present. */
- /* _HT_ : if we're in the SYN phase, and peer does not send a MSS option,
- then we MUST assume an MSS size of 536 bytes for backward compatibility. */
-
- /* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
- the number 5 (words) in the higher niblle of the TCP-offset byte. */
- if( ( pxTCPPacket->xTCPHeader.ucTCPOffset & TCP_OFFSET_LENGTH_BITS ) > TCP_OFFSET_STANDARD_LENGTH )
- {
- prvCheckOptions( pxSocket, pxNetworkBuffer );
- }
-
-
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- pxSocket->u.xTCP.ulWindowSize = FreeRTOS_ntohs( pxTCPPacket->xTCPHeader.usWindow );
- pxSocket->u.xTCP.ulWindowSize =
- ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor );
- }
- #endif
-
- /* In prvTCPHandleState() the incoming messages will be handled
- depending on the current state of the connection. */
- if( prvTCPHandleState( pxSocket, &pxNetworkBuffer ) > 0 )
- {
- /* prvTCPHandleState() has sent a message, see if there are more to
- be transmitted. */
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- prvTCPSendRepeated( pxSocket, &pxNetworkBuffer );
- }
- #endif /* ipconfigUSE_TCP_WIN */
- }
-
- if( pxNetworkBuffer != NULL )
- {
- /* We must check if the buffer is unequal to NULL, because the
- socket might keep a reference to it in case a delayed ACK must be
- sent. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- pxNetworkBuffer = NULL;
- }
-
- /* And finally, calculate when this socket wants to be woken up. */
- prvTCPNextTimeout ( pxSocket );
- /* Return pdPASS to tell that the network buffer is 'consumed'. */
- xResult = pdPASS;
- }
-
- /* pdPASS being returned means the buffer has been consumed. */
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
-{
-TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-FreeRTOS_Socket_t *pxReturn = NULL;
-uint32_t ulInitialSequenceNumber;
-
- /* Assume that a new Initial Sequence Number will be required. Request
- it now in order to fail out if necessary. */
- ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER,
- pxSocket->usLocalPort,
- pxTCPPacket->xIPHeader.ulSourceIPAddress,
- pxTCPPacket->xTCPHeader.usSourcePort );
-
- /* A pure SYN (without ACK) has come in, create a new socket to answer
- it. */
- if( 0 != ulInitialSequenceNumber )
- {
- if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
- {
- /* The flag bReuseSocket indicates that the same instance of the
- listening socket should be used for the connection. */
- pxReturn = pxSocket;
- pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
- pxSocket->u.xTCP.pxPeerSocket = pxSocket;
- }
- else
- {
- /* The socket does not have the bReuseSocket flag set meaning create a
- new socket when a connection comes in. */
- pxReturn = NULL;
-
- if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
- {
- FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usChildCount,
- pxSocket->u.xTCP.usBacklog,
- pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
- prvTCPSendReset( pxNetworkBuffer );
- }
- else
- {
- FreeRTOS_Socket_t *pxNewSocket = ( FreeRTOS_Socket_t * )
- FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
-
- if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
- {
- FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
- prvTCPSendReset( pxNetworkBuffer );
- }
- else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
- {
- /* The socket will be connected immediately, no time for the
- owner to setsockopt's, therefore copy properties of the server
- socket to the new socket. Only the binding might fail (due to
- lack of resources). */
- pxReturn = pxNewSocket;
- }
- }
- }
- }
-
- if( ( 0 != ulInitialSequenceNumber ) && ( pxReturn != NULL ) )
- {
- pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
- pxReturn->u.xTCP.ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
- pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
-
- /* Here is the SYN action. */
- pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
- prvSocketSetMSS( pxReturn );
-
- prvTCPCreateWindow( pxReturn );
-
- vTCPStateChange( pxReturn, eSYN_FIRST );
-
- /* Make a copy of the header up to the TCP header. It is needed later
- on, whenever data must be sent to the peer. */
- memcpy( pxReturn->u.xTCP.xPacket.u.ucLastPacket, pxNetworkBuffer->pucEthernetBuffer, sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) );
- }
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Duplicates a socket after a listening socket receives a connection.
- */
-static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t *pxNewSocket, FreeRTOS_Socket_t *pxSocket )
-{
-struct freertos_sockaddr xAddress;
-
- pxNewSocket->xReceiveBlockTime = pxSocket->xReceiveBlockTime;
- pxNewSocket->xSendBlockTime = pxSocket->xSendBlockTime;
- pxNewSocket->ucSocketOptions = pxSocket->ucSocketOptions;
- pxNewSocket->u.xTCP.uxRxStreamSize = pxSocket->u.xTCP.uxRxStreamSize;
- pxNewSocket->u.xTCP.uxTxStreamSize = pxSocket->u.xTCP.uxTxStreamSize;
- pxNewSocket->u.xTCP.uxLittleSpace = pxSocket->u.xTCP.uxLittleSpace;
- pxNewSocket->u.xTCP.uxEnoughSpace = pxSocket->u.xTCP.uxEnoughSpace;
- pxNewSocket->u.xTCP.uxRxWinSize = pxSocket->u.xTCP.uxRxWinSize;
- pxNewSocket->u.xTCP.uxTxWinSize = pxSocket->u.xTCP.uxTxWinSize;
-
- #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
- {
- pxNewSocket->pxUserSemaphore = pxSocket->pxUserSemaphore;
- }
- #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
-
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- /* In case call-backs are used, copy them from parent to child. */
- pxNewSocket->u.xTCP.pxHandleConnected = pxSocket->u.xTCP.pxHandleConnected;
- pxNewSocket->u.xTCP.pxHandleReceive = pxSocket->u.xTCP.pxHandleReceive;
- pxNewSocket->u.xTCP.pxHandleSent = pxSocket->u.xTCP.pxHandleSent;
- }
- #endif /* ipconfigUSE_CALLBACKS */
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- /* Child socket of listening sockets will inherit the Socket Set
- Otherwise the owner has no chance of including it into the set. */
- if( pxSocket->pxSocketSet )
- {
- pxNewSocket->pxSocketSet = pxSocket->pxSocketSet;
- pxNewSocket->xSelectBits = pxSocket->xSelectBits | eSELECT_READ | eSELECT_EXCEPT;
- }
- }
- #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
-
- /* And bind it to the same local port as its parent. */
- xAddress.sin_addr = *ipLOCAL_IP_ADDRESS_POINTER;
- xAddress.sin_port = FreeRTOS_htons( pxSocket->usLocalPort );
-
- #if( ipconfigTCP_HANG_PROTECTION == 1 )
- {
- /* Only when there is anti-hanging protection, a socket may become an
- orphan temporarily. Once this socket is really connected, the owner of
- the server socket will be notified. */
-
- /* When bPassQueued is true, the socket is an orphan until it gets
- connected. */
- pxNewSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
- pxNewSocket->u.xTCP.pxPeerSocket = pxSocket;
- }
- #else
- {
- /* A reference to the new socket may be stored and the socket is marked
- as 'passable'. */
-
- /* When bPassAccept is pdTRUE_UNSIGNED this socket may be returned in a call to
- accept(). */
- pxNewSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
- if(pxSocket->u.xTCP.pxPeerSocket == NULL )
- {
- pxSocket->u.xTCP.pxPeerSocket = pxNewSocket;
- }
- }
- #endif
-
- pxSocket->u.xTCP.usChildCount++;
-
- FreeRTOS_debug_printf( ( "Gain: Socket %u now has %u / %u child%s\n",
- pxSocket->usLocalPort,
- pxSocket->u.xTCP.usChildCount,
- pxSocket->u.xTCP.usBacklog,
- pxSocket->u.xTCP.usChildCount == 1u ? "" : "ren" ) );
-
- /* Now bind the child socket to the same port as the listening socket. */
- if( vSocketBind ( pxNewSocket, &xAddress, sizeof( xAddress ), pdTRUE ) != 0 )
- {
- FreeRTOS_debug_printf( ( "TCP: Listen: new socket bind error\n" ) );
- vSocketClose( pxNewSocket );
- return pdFALSE;
- }
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
-
- const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState )
- {
- if( ulState >= ( UBaseType_t ) ARRAY_SIZE( pcStateNames ) )
- {
- ulState = ( UBaseType_t ) ARRAY_SIZE( pcStateNames ) - 1u;
- }
- return pcStateNames[ ulState ];
- }
-
-#endif /* ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) ) */
-/*-----------------------------------------------------------*/
-
-/*
- * In the API accept(), the user asks is there is a new client? As API's can
- * not walk through the xBoundTCPSocketsList the IP-task will do this.
- */
-BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket )
-{
-TickType_t xLocalPort = FreeRTOS_htons( pxSocket->usLocalPort );
-ListItem_t *pxIterator;
-FreeRTOS_Socket_t *pxFound;
-BaseType_t xResult = pdFALSE;
-
- /* Here xBoundTCPSocketsList can be accessed safely IP-task is the only one
- who has access. */
- for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
- pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
- pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- if( listGET_LIST_ITEM_VALUE( pxIterator ) == xLocalPort )
- {
- pxFound = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
- if( ( pxFound->ucProtocol == FREERTOS_IPPROTO_TCP ) && ( pxFound->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
- {
- pxSocket->u.xTCP.pxPeerSocket = pxFound;
- FreeRTOS_debug_printf( ( "xTCPCheckNewClient[0]: client on port %u\n", pxSocket->usLocalPort ) );
- xResult = pdTRUE;
- break;
- }
- }
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-#endif /* ipconfigUSE_TCP == 1 */
-
-/* Provide access to private members for testing. */
-#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
- #include "iot_freertos_tcp_test_access_tcp_define.h"
-#endif
-
-/* Provide access to private members for verification. */
-#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
- #include "aws_freertos_tcp_verification_access_tcp_define.h"
-#endif
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
+ * FreeRTOS_TCP_IP.c
+ * Module which handles the TCP connections for FreeRTOS+TCP.
+ * It depends on FreeRTOS_TCP_WIN.c, which handles the TCP windowing
+ * schemes.
+ *
+ * Endianness: in this module all ports and IP addresses are stored in
+ * host byte-order, except fields in the IP-packets
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_TCP_IP.h"
+#include "FreeRTOS_DHCP.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+#include "FreeRTOS_ARP.h"
+#include "FreeRTOS_TCP_WIN.h"
+
+
+/* Just make sure the contents doesn't get compiled if TCP is not enabled. */
+#if ipconfigUSE_TCP == 1
+
+/* This compile-time test was moved to here because some macro's
+were unknown within 'FreeRTOSIPConfigDefaults.h'. It tests whether
+the defined MTU size can contain at least a complete TCP packet. */
+
+#if ( ( ipconfigTCP_MSS + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) > ipconfigNETWORK_MTU )
+ #error The ipconfigTCP_MSS setting in FreeRTOSIPConfig.h is too large.
+#endif
+
+/*
+ * The meaning of the TCP flags:
+ */
+#define ipTCP_FLAG_FIN 0x0001u /* No more data from sender */
+#define ipTCP_FLAG_SYN 0x0002u /* Synchronize sequence numbers */
+#define ipTCP_FLAG_RST 0x0004u /* Reset the connection */
+#define ipTCP_FLAG_PSH 0x0008u /* Push function: please push buffered data to the recv application */
+#define ipTCP_FLAG_ACK 0x0010u /* Acknowledgment field is significant */
+#define ipTCP_FLAG_URG 0x0020u /* Urgent pointer field is significant */
+#define ipTCP_FLAG_ECN 0x0040u /* ECN-Echo */
+#define ipTCP_FLAG_CWR 0x0080u /* Congestion Window Reduced */
+#define ipTCP_FLAG_NS 0x0100u /* ECN-nonce concealment protection */
+#define ipTCP_FLAG_RSV 0x0E00u /* Reserved, keep 0 */
+
+/* A mask to filter all protocol flags. */
+#define ipTCP_FLAG_CTRL 0x001Fu
+
+/*
+ * A few values of the TCP options:
+ */
+#define TCP_OPT_END 0u /* End of TCP options list */
+#define TCP_OPT_NOOP 1u /* "No-operation" TCP option */
+#define TCP_OPT_MSS 2u /* Maximum segment size TCP option */
+#define TCP_OPT_WSOPT 3u /* TCP Window Scale Option (3-byte long) */
+#define TCP_OPT_SACK_P 4u /* Advertize that SACK is permitted */
+#define TCP_OPT_SACK_A 5u /* SACK option with first/last */
+#define TCP_OPT_TIMESTAMP 8u /* Time-stamp option */
+
+#define TCP_OPT_MSS_LEN 4u /* Length of TCP MSS option. */
+#define TCP_OPT_WSOPT_LEN 3u /* Length of TCP WSOPT option. */
+
+#define TCP_OPT_TIMESTAMP_LEN 10 /* fixed length of the time-stamp option */
+
+#ifndef ipconfigTCP_ACK_EARLIER_PACKET
+ #define ipconfigTCP_ACK_EARLIER_PACKET 1
+#endif
+
+/*
+ * The macro NOW_CONNECTED() is use to determine if the connection makes a
+ * transition from connected to non-connected and vice versa.
+ * NOW_CONNECTED() returns true when the status has one of these values:
+ * eESTABLISHED, eFIN_WAIT_1, eFIN_WAIT_2, eCLOSING, eLAST_ACK, eTIME_WAIT
+ * Technically the connection status is closed earlier, but the library wants
+ * to prevent that the socket will be deleted before the last ACK has been
+ * and thus causing a 'RST' packet on either side.
+ */
+#define NOW_CONNECTED( status )\
+ ( ( status >= eESTABLISHED ) && ( status != eCLOSE_WAIT ) )
+
+/*
+ * The highest 4 bits in the TCP offset byte indicate the total length of the
+ * TCP header, divided by 4.
+ */
+#define VALID_BITS_IN_TCP_OFFSET_BYTE ( 0xF0u )
+
+/*
+ * Acknowledgements to TCP data packets may be delayed as long as more is being expected.
+ * A normal delay would be 200ms. Here a much shorter delay of 20 ms is being used to
+ * gain performance.
+ */
+#define DELAYED_ACK_SHORT_DELAY_MS ( 2 )
+#define DELAYED_ACK_LONGER_DELAY_MS ( 20 )
+
+/*
+ * The MSS (Maximum Segment Size) will be taken as large as possible. However, packets with
+ * an MSS of 1460 bytes won't be transported through the internet. The MSS will be reduced
+ * to 1400 bytes.
+ */
+#define REDUCED_MSS_THROUGH_INTERNET ( 1400 )
+
+/*
+ * When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
+ * the number 5 (words) in the higher niblle of the TCP-offset byte.
+ */
+#define TCP_OFFSET_LENGTH_BITS ( 0xf0u )
+#define TCP_OFFSET_STANDARD_LENGTH ( 0x50u )
+
+/*
+ * Each TCP socket is checked regularly to see if it can send data packets.
+ * By default, the maximum number of packets sent during one check is limited to 8.
+ * This amount may be further limited by setting the socket's TX window size.
+ */
+#if( !defined( SEND_REPEATED_COUNT ) )
+ #define SEND_REPEATED_COUNT ( 8 )
+#endif /* !defined( SEND_REPEATED_COUNT ) */
+
+/*
+ * Define a maximum perdiod of time (ms) to leave a TCP-socket unattended.
+ * When a TCP timer expires, retries and keep-alive messages will be checked.
+ */
+#ifndef tcpMAXIMUM_TCP_WAKEUP_TIME_MS
+ #define tcpMAXIMUM_TCP_WAKEUP_TIME_MS 20000u
+#endif
+
+/*
+ * The names of the different TCP states may be useful in logging.
+ */
+#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
+ static const char *pcStateNames[] = {
+ "eCLOSED",
+ "eTCP_LISTEN",
+ "eCONNECT_SYN",
+ "eSYN_FIRST",
+ "eSYN_RECEIVED",
+ "eESTABLISHED",
+ "eFIN_WAIT_1",
+ "eFIN_WAIT_2",
+ "eCLOSE_WAIT",
+ "eCLOSING",
+ "eLAST_ACK",
+ "eTIME_WAIT",
+ "eUNKNOWN",
+};
+#endif /* ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) */
+
+/*
+ * Returns true if the socket must be checked. Non-active sockets are waiting
+ * for user action, either connect() or close().
+ */
+static BaseType_t prvTCPSocketIsActive( UBaseType_t uxStatus );
+
+/*
+ * Either sends a SYN or calls prvTCPSendRepeated (for regular messages).
+ */
+static int32_t prvTCPSendPacket( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Try to send a series of messages.
+ */
+static int32_t prvTCPSendRepeated( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
+
+/*
+ * Return or send a packet to the other party.
+ */
+static void prvTCPReturnPacket( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
+ uint32_t ulLen, BaseType_t xReleaseAfterSend );
+
+/*
+ * Initialise the data structures which keep track of the TCP windowing system.
+ */
+static void prvTCPCreateWindow( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Let ARP look-up the MAC-address of the peer and initialise the first SYN
+ * packet.
+ */
+static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket );
+
+#if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ /*
+ * For logging and debugging: make a string showing the TCP flags.
+ */
+ static const char *prvTCPFlagMeaning( UBaseType_t xFlags);
+#endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+
+/*
+ * Parse the TCP option(s) received, if present.
+ */
+static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+/*
+ * Identify and deal with a single TCP header option, advancing the pointer to
+ * the header. This function returns pdTRUE or pdFALSE depending on whether the
+ * caller should continue to parse more header options or break the loop.
+ */
+static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow);
+
+/*
+ * Skip past TCP header options when doing Selective ACK, until there are no
+ * more options left.
+ */
+static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const ppucLen );
+
+/*
+ * Set the initial properties in the options fields, like the preferred
+ * value of MSS and whether SACK allowed. Will be transmitted in the state
+ * 'eCONNECT_SYN'.
+ */
+static UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t *pxSocket, TCPPacket_t * pxTCPPacket );
+
+/*
+ * For anti-hang protection and TCP keep-alive messages. Called in two places:
+ * after receiving a packet and after a state change. The socket's alive timer
+ * may be reset.
+ */
+static void prvTCPTouchSocket( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Prepare an outgoing message, if anything has to be sent.
+ */
+static int32_t prvTCPPrepareSend( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, UBaseType_t uxOptionsLength );
+
+/*
+ * Calculate when this socket needs to be checked to do (re-)transmissions.
+ */
+static TickType_t prvTCPNextTimeout( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * The API FreeRTOS_send() adds data to the TX stream. Add
+ * this data to the windowing system to it can be transmitted.
+ */
+static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Called to handle the closure of a TCP connection.
+ */
+static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+/*
+ * Called from prvTCPHandleState(). Find the TCP payload data and check and
+ * return its length.
+ */
+static BaseType_t prvCheckRxData( NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData );
+
+/*
+ * Called from prvTCPHandleState(). Check if the payload data may be accepted.
+ * If so, it will be added to the socket's reception queue.
+ */
+static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, uint8_t *pucRecvData,
+ NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength );
+
+/*
+ * Set the TCP options (if any) for the outgoing packet.
+ */
+static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+/*
+ * Called from prvTCPHandleState() as long as the TCP status is eSYN_RECEIVED to
+ * eCONNECT_SYN.
+ */
+static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
+ uint32_t ulReceiveLength, UBaseType_t uxOptionsLength );
+
+/*
+ * Called from prvTCPHandleState() as long as the TCP status is eESTABLISHED.
+ */
+static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
+ uint32_t ulReceiveLength, UBaseType_t uxOptionsLength );
+
+/*
+ * Called from prvTCPHandleState(). There is data to be sent.
+ * If ipconfigUSE_TCP_WIN is defined, and if only an ACK must be sent, it will
+ * be checked if it would better be postponed for efficiency.
+ */
+static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
+ uint32_t ulReceiveLength, BaseType_t xSendLength );
+
+/*
+ * The heart of all: check incoming packet for valid data and acks and do what
+ * is necessary in each state.
+ */
+static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer );
+
+/*
+ * Common code for sending a TCP protocol control packet (i.e. no options, no
+ * payload, just flags).
+ */
+static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
+ uint8_t ucTCPFlags );
+
+/*
+ * A "challenge ACK" is as per https://tools.ietf.org/html/rfc5961#section-3.2,
+ * case #3. In summary, an RST was received with a sequence number that is
+ * unexpected but still within the window.
+ */
+static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+/*
+ * Reply to a peer with the RST flag on, in case a packet can not be handled.
+ */
+static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+/*
+ * Set the initial value for MSS (Maximum Segment Size) to be used.
+ */
+static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Return either a newly created socket, or the current socket in a connected
+ * state (depends on the 'bReuseSocket' flag).
+ */
+static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+/*
+ * After a listening socket receives a new connection, it may duplicate itself.
+ * The copying takes place in prvTCPSocketCopy.
+ */
+static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t *pxNewSocket, FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * prvTCPStatusAgeCheck() will see if the socket has been in a non-connected
+ * state for too long. If so, the socket will be closed, and -1 will be
+ * returned.
+ */
+#if( ipconfigTCP_HANG_PROTECTION == 1 )
+ static BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t *pxSocket );
+#endif
+
+static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
+ int32_t lDataLen, UBaseType_t uxOptionsLength );
+
+#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
+ const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState );
+#endif
+
+#if( ipconfigUSE_TCP_WIN != 0 )
+ static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket );
+#endif
+
+/*
+ * Generate a randomized TCP Initial Sequence Number per RFC.
+ */
+extern uint32_t ulApplicationGetNextSequenceNumber( uint32_t ulSourceAddress,
+ uint16_t usSourcePort,
+ uint32_t ulDestinationAddress,
+ uint16_t usDestinationPort );
+
+/*-----------------------------------------------------------*/
+
+/* prvTCPSocketIsActive() returns true if the socket must be checked.
+ * Non-active sockets are waiting for user action, either connect()
+ * or close(). */
+static BaseType_t prvTCPSocketIsActive( UBaseType_t uxStatus )
+{
+ switch( uxStatus )
+ {
+ case eCLOSED:
+ case eCLOSE_WAIT:
+ case eFIN_WAIT_2:
+ case eCLOSING:
+ case eTIME_WAIT:
+ return pdFALSE;
+ default:
+ return pdTRUE;
+ }
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigTCP_HANG_PROTECTION == 1 )
+
+ static BaseType_t prvTCPStatusAgeCheck( FreeRTOS_Socket_t *pxSocket )
+ {
+ BaseType_t xResult;
+ switch( pxSocket->u.xTCP.ucTCPState )
+ {
+ case eESTABLISHED:
+ /* If the 'ipconfigTCP_KEEP_ALIVE' option is enabled, sockets in
+ state ESTABLISHED can be protected using keep-alive messages. */
+ xResult = pdFALSE;
+ break;
+ case eCLOSED:
+ case eTCP_LISTEN:
+ case eCLOSE_WAIT:
+ /* These 3 states may last for ever, up to the owner. */
+ xResult = pdFALSE;
+ break;
+ default:
+ /* All other (non-connected) states will get anti-hanging
+ protection. */
+ xResult = pdTRUE;
+ break;
+ }
+ if( xResult != pdFALSE )
+ {
+ /* How much time has past since the last active moment which is
+ defined as A) a state change or B) a packet has arrived. */
+ TickType_t xAge = xTaskGetTickCount( ) - pxSocket->u.xTCP.xLastActTime;
+
+ /* ipconfigTCP_HANG_PROTECTION_TIME is in units of seconds. */
+ if( xAge > ( ipconfigTCP_HANG_PROTECTION_TIME * configTICK_RATE_HZ ) )
+ {
+ #if( ipconfigHAS_DEBUG_PRINTF == 1 )
+ {
+ FreeRTOS_debug_printf( ( "Inactive socket closed: port %u rem %lxip:%u status %s\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort,
+ FreeRTOS_GetTCPStateName( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF */
+
+ /* Move to eCLOSE_WAIT, user may close the socket. */
+ vTCPStateChange( pxSocket, eCLOSE_WAIT );
+
+ /* When 'bPassQueued' true, this socket is an orphan until it
+ gets connected. */
+ if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
+ {
+ if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
+ {
+ /* As it did not get connected, and the user can never
+ accept() it anymore, it will be deleted now. Called from
+ the IP-task, so it's safe to call the internal Close
+ function: vSocketClose(). */
+ vSocketClose( pxSocket );
+ }
+ /* Return a negative value to tell to inform the caller
+ xTCPTimerCheck()
+ that the socket got closed and may not be accessed anymore. */
+ xResult = -1;
+ }
+ }
+ }
+ return xResult;
+ }
+ /*-----------------------------------------------------------*/
+
+#endif
+
+/*
+ * As soon as a TCP socket timer expires, this function xTCPSocketCheck
+ * will be called (from xTCPTimerCheck)
+ * It can send a delayed ACK or new data
+ * Sequence of calling (normally) :
+ * IP-Task:
+ * xTCPTimerCheck() // Check all sockets ( declared in FreeRTOS_Sockets.c )
+ * xTCPSocketCheck() // Either send a delayed ACK or call prvTCPSendPacket()
+ * prvTCPSendPacket() // Either send a SYN or call prvTCPSendRepeated ( regular messages )
+ * prvTCPSendRepeated() // Send at most 8 messages on a row
+ * prvTCPReturnPacket() // Prepare for returning
+ * xNetworkInterfaceOutput() // Sends data to the NIC ( declared in portable/NetworkInterface/xxx )
+ */
+BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket )
+{
+BaseType_t xResult = 0;
+BaseType_t xReady = pdFALSE;
+
+ if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.txStream != NULL ) )
+ {
+ /* The API FreeRTOS_send() might have added data to the TX stream. Add
+ this data to the windowing system to it can be transmitted. */
+ prvTCPAddTxData( pxSocket );
+ }
+
+ #if ipconfigUSE_TCP_WIN == 1
+ {
+ if( pxSocket->u.xTCP.pxAckMessage != NULL )
+ {
+ /* The first task of this regular socket check is to send-out delayed
+ ACK's. */
+ if( pxSocket->u.xTCP.bits.bUserShutdown == pdFALSE_UNSIGNED )
+ {
+ /* Earlier data was received but not yet acknowledged. This
+ function is called when the TCP timer for the socket expires, the
+ ACK may be sent now. */
+ if( pxSocket->u.xTCP.ucTCPState != eCLOSED )
+ {
+ if( xTCPWindowLoggingLevel > 1 && ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) )
+ {
+ FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %lu SEQ %lu (len %u)\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usRemotePort,
+ pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber,
+ pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber,
+ ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) );
+ }
+
+ prvTCPReturnPacket( pxSocket, pxSocket->u.xTCP.pxAckMessage, ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER, ipconfigZERO_COPY_TX_DRIVER );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* The ownership has been passed to the SEND routine,
+ clear the pointer to it. */
+ pxSocket->u.xTCP.pxAckMessage = NULL;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ }
+ if( prvTCPNextTimeout( pxSocket ) > 1 )
+ {
+ /* Tell the code below that this function is ready. */
+ xReady = pdTRUE;
+ }
+ }
+ else
+ {
+ /* The user wants to perform an active shutdown(), skip sending
+ the delayed ACK. The function prvTCPSendPacket() will send the
+ FIN along with the ACK's. */
+ }
+
+ if( pxSocket->u.xTCP.pxAckMessage != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
+ pxSocket->u.xTCP.pxAckMessage = NULL;
+ }
+ }
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+
+ if( xReady == pdFALSE )
+ {
+ /* The second task of this regular socket check is sending out data. */
+ if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) ||
+ ( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ) )
+ {
+ prvTCPSendPacket( pxSocket );
+ }
+
+ /* Set the time-out for the next wakeup for this socket. */
+ prvTCPNextTimeout( pxSocket );
+
+ #if( ipconfigTCP_HANG_PROTECTION == 1 )
+ {
+ /* In all (non-connected) states in which keep-alive messages can not be sent
+ the anti-hang protocol will close sockets that are 'hanging'. */
+ xResult = prvTCPStatusAgeCheck( pxSocket );
+ }
+ #endif
+ }
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvTCPSendPacket() will be called when the socket time-out has been reached.
+ * It is only called by xTCPSocketCheck().
+ */
+static int32_t prvTCPSendPacket( FreeRTOS_Socket_t *pxSocket )
+{
+int32_t lResult = 0;
+UBaseType_t uxOptionsLength;
+TCPPacket_t *pxTCPPacket;
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+
+ if( pxSocket->u.xTCP.ucTCPState != eCONNECT_SYN )
+ {
+ /* The connection is in s state other than SYN. */
+ pxNetworkBuffer = NULL;
+
+ /* prvTCPSendRepeated() will only create a network buffer if necessary,
+ i.e. when data must be sent to the peer. */
+ lResult = prvTCPSendRepeated( pxSocket, &pxNetworkBuffer );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ }
+ else
+ {
+ if( pxSocket->u.xTCP.ucRepCount >= 3u )
+ {
+ /* The connection is in the SYN status. The packet will be repeated
+ to most 3 times. When there is no response, the socket get the
+ status 'eCLOSE_WAIT'. */
+ FreeRTOS_debug_printf( ( "Connect: giving up %lxip:%u\n",
+ pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine. */
+ pxSocket->u.xTCP.usRemotePort ) ); /* Port on remote machine. */
+ vTCPStateChange( pxSocket, eCLOSE_WAIT );
+ }
+ else if( ( pxSocket->u.xTCP.bits.bConnPrepared != pdFALSE_UNSIGNED ) || ( prvTCPPrepareConnect( pxSocket ) == pdTRUE ) )
+ {
+ /* Or else, if the connection has been prepared, or can be prepared
+ now, proceed to send the packet with the SYN flag.
+ prvTCPPrepareConnect() prepares 'xPacket' and returns pdTRUE if
+ the Ethernet address of the peer or the gateway is found. */
+ pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
+
+ /* About to send a SYN packet. Call prvSetSynAckOptions() to set
+ the proper options: The size of MSS and whether SACK's are
+ allowed. */
+ uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPPacket );
+
+ /* Return the number of bytes to be sent. */
+ lResult = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
+
+ /* Set the TCP offset field: ipSIZE_OF_TCP_HEADER equals 20 and
+ uxOptionsLength is always a multiple of 4. The complete expression
+ would be:
+ ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */
+ pxTCPPacket->xTCPHeader.ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+
+ /* Repeat Count is used for a connecting socket, to limit the number
+ of tries. */
+ pxSocket->u.xTCP.ucRepCount++;
+
+ /* Send the SYN message to make a connection. The messages is
+ stored in the socket field 'xPacket'. It will be wrapped in a
+ pseudo network buffer descriptor before it will be sent. */
+ prvTCPReturnPacket( pxSocket, NULL, ( uint32_t ) lResult, pdFALSE );
+ }
+ }
+
+ /* Return the total number of bytes sent. */
+ return lResult;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvTCPSendRepeated will try to send a series of messages, as long as there is
+ * data to be sent and as long as the transmit window isn't full.
+ */
+static int32_t prvTCPSendRepeated( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
+{
+UBaseType_t uxIndex;
+int32_t lResult = 0;
+UBaseType_t uxOptionsLength = 0u;
+int32_t xSendLength;
+
+ for( uxIndex = 0u; uxIndex < ( UBaseType_t ) SEND_REPEATED_COUNT; uxIndex++ )
+ {
+ /* prvTCPPrepareSend() might allocate a network buffer if there is data
+ to be sent. */
+ xSendLength = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
+ if( xSendLength <= 0 )
+ {
+ break;
+ }
+
+ /* And return the packet to the peer. */
+ prvTCPReturnPacket( pxSocket, *ppxNetworkBuffer, ( uint32_t ) xSendLength, ipconfigZERO_COPY_TX_DRIVER );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ *ppxNetworkBuffer = NULL;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ lResult += xSendLength;
+ }
+
+ /* Return the total number of bytes sent. */
+ return lResult;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Return (or send) a packet the the peer. The data is stored in pxBuffer,
+ * which may either point to a real network buffer or to a TCP socket field
+ * called 'xTCP.xPacket'. A temporary xNetworkBuffer will be used to pass
+ * the data to the NIC.
+ */
+static void prvTCPReturnPacket( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulLen, BaseType_t xReleaseAfterSend )
+{
+TCPPacket_t * pxTCPPacket;
+IPHeader_t *pxIPHeader;
+EthernetHeader_t *pxEthernetHeader;
+uint32_t ulFrontSpace, ulSpace, ulSourceAddress, ulWinSize;
+TCPWindow_t *pxTCPWindow;
+NetworkBufferDescriptor_t xTempBuffer;
+/* For sending, a pseudo network buffer will be used, as explained above. */
+
+ if( pxNetworkBuffer == NULL )
+ {
+ pxNetworkBuffer = &xTempBuffer;
+
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ xTempBuffer.pxNextBuffer = NULL;
+ }
+ #endif
+ xTempBuffer.pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
+ xTempBuffer.xDataLength = sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
+ xReleaseAfterSend = pdFALSE;
+ }
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ if( xReleaseAfterSend == pdFALSE )
+ {
+ pxNetworkBuffer = pxDuplicateNetworkBufferWithDescriptor( pxNetworkBuffer, ( BaseType_t ) pxNetworkBuffer->xDataLength );
+ if( pxNetworkBuffer == NULL )
+ {
+ FreeRTOS_debug_printf( ( "prvTCPReturnPacket: duplicate failed\n" ) );
+ }
+ xReleaseAfterSend = pdTRUE;
+ }
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ if( pxNetworkBuffer != NULL )
+ {
+ pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+ pxIPHeader = &pxTCPPacket->xIPHeader;
+ pxEthernetHeader = &pxTCPPacket->xEthernetHeader;
+
+ /* Fill the packet, using hton translations. */
+ if( pxSocket != NULL )
+ {
+ /* Calculate the space in the RX buffer in order to advertise the
+ size of this socket's reception window. */
+ pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
+
+ if( pxSocket->u.xTCP.rxStream != NULL )
+ {
+ /* An RX stream was created already, see how much space is
+ available. */
+ ulFrontSpace = ( uint32_t ) uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream );
+ }
+ else
+ {
+ /* No RX stream has been created, the full stream size is
+ available. */
+ ulFrontSpace = ( uint32_t ) pxSocket->u.xTCP.uxRxStreamSize;
+ }
+
+ /* Take the minimum of the RX buffer space and the RX window size. */
+ ulSpace = FreeRTOS_min_uint32( pxTCPWindow->xSize.ulRxWindowLength, ulFrontSpace );
+
+ if( ( pxSocket->u.xTCP.bits.bLowWater != pdFALSE_UNSIGNED ) || ( pxSocket->u.xTCP.bits.bRxStopped != pdFALSE_UNSIGNED ) )
+ {
+ /* The low-water mark was reached, meaning there was little
+ space left. The socket will wait until the application has read
+ or flushed the incoming data, and 'zero-window' will be
+ advertised. */
+ ulSpace = 0u;
+ }
+
+ /* If possible, advertise an RX window size of at least 1 MSS, otherwise
+ the peer might start 'zero window probing', i.e. sending small packets
+ (1, 2, 4, 8... bytes). */
+ if( ( ulSpace < pxSocket->u.xTCP.usCurMSS ) && ( ulFrontSpace >= pxSocket->u.xTCP.usCurMSS ) )
+ {
+ ulSpace = pxSocket->u.xTCP.usCurMSS;
+ }
+
+ /* Avoid overflow of the 16-bit win field. */
+ #if( ipconfigUSE_TCP_WIN != 0 )
+ {
+ ulWinSize = ( ulSpace >> pxSocket->u.xTCP.ucMyWinScaleFactor );
+ }
+ #else
+ {
+ ulWinSize = ulSpace;
+ }
+ #endif
+ if( ulWinSize > 0xfffcUL )
+ {
+ ulWinSize = 0xfffcUL;
+ }
+
+ pxTCPPacket->xTCPHeader.usWindow = FreeRTOS_htons( ( uint16_t ) ulWinSize );
+
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ if( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE )
+ {
+ if( ( xTCPWindowLoggingLevel != 0 ) && ( pxSocket->u.xTCP.bits.bWinChange != pdFALSE_UNSIGNED ) )
+ {
+ size_t uxFrontSpace;
+
+ if(pxSocket->u.xTCP.rxStream != NULL)
+ {
+ uxFrontSpace = uxStreamBufferFrontSpace( pxSocket->u.xTCP.rxStream ) ;
+ }
+ else
+ {
+ uxFrontSpace = 0u;
+ }
+
+ FreeRTOS_debug_printf( ( "%s: %lxip:%u: [%lu < %lu] winSize %ld\n",
+ pxSocket->u.xTCP.bits.bLowWater ? "STOP" : "GO ",
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort,
+ pxSocket->u.xTCP.bits.bLowWater ? pxSocket->u.xTCP.uxLittleSpace : uxFrontSpace, pxSocket->u.xTCP.uxEnoughSpace,
+ (int32_t) ( pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulCurrentSequenceNumber ) ) );
+ }
+ }
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF != 0 */
+
+ /* The new window size has been advertised, switch off the flag. */
+ pxSocket->u.xTCP.bits.bWinChange = pdFALSE_UNSIGNED;
+
+ /* Later on, when deciding to delay an ACK, a precise estimate is needed
+ of the free RX space. At this moment, 'ulHighestRxAllowed' would be the
+ highest sequence number minus 1 that the socket will accept. */
+ pxSocket->u.xTCP.ulHighestRxAllowed = pxTCPWindow->rx.ulCurrentSequenceNumber + ulSpace;
+
+ #if( ipconfigTCP_KEEP_ALIVE == 1 )
+ if( pxSocket->u.xTCP.bits.bSendKeepAlive != pdFALSE_UNSIGNED )
+ {
+ /* Sending a keep-alive packet, send the current sequence number
+ minus 1, which will be recognised as a keep-alive packet an
+ responded to by acknowledging the last byte. */
+ pxSocket->u.xTCP.bits.bSendKeepAlive = pdFALSE_UNSIGNED;
+ pxSocket->u.xTCP.bits.bWaitKeepAlive = pdTRUE_UNSIGNED;
+
+ pxTCPPacket->xTCPHeader.ulSequenceNumber = pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - 1UL;
+ pxTCPPacket->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
+ }
+ else
+ #endif
+ {
+ pxTCPPacket->xTCPHeader.ulSequenceNumber = FreeRTOS_htonl( pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber );
+
+ if( ( pxTCPPacket->xTCPHeader.ucTCPFlags & ( uint8_t ) ipTCP_FLAG_FIN ) != 0u )
+ {
+ /* Suppress FIN in case this packet carries earlier data to be
+ retransmitted. */
+ uint32_t ulDataLen = ( uint32_t ) ( ulLen - ( ipSIZE_OF_TCP_HEADER + ipSIZE_OF_IPv4_HEADER ) );
+ if( ( pxTCPWindow->ulOurSequenceNumber + ulDataLen ) != pxTCPWindow->tx.ulFINSequenceNumber )
+ {
+ pxTCPPacket->xTCPHeader.ucTCPFlags &= ( ( uint8_t ) ~ipTCP_FLAG_FIN );
+ FreeRTOS_debug_printf( ( "Suppress FIN for %lu + %lu < %lu\n",
+ pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
+ ulDataLen,
+ pxTCPWindow->tx.ulFINSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber ) );
+ }
+ }
+ }
+
+ /* Tell which sequence number is expected next time */
+ pxTCPPacket->xTCPHeader.ulAckNr = FreeRTOS_htonl( pxTCPWindow->rx.ulCurrentSequenceNumber );
+ }
+ else
+ {
+ /* Sending data without a socket, probably replying with a RST flag
+ Just swap the two sequence numbers. */
+ vFlip_32( pxTCPPacket->xTCPHeader.ulSequenceNumber, pxTCPPacket->xTCPHeader.ulAckNr );
+ }
+
+ pxIPHeader->ucTimeToLive = ( uint8_t ) ipconfigTCP_TIME_TO_LIVE;
+ pxIPHeader->usLength = FreeRTOS_htons( ulLen );
+ if( ( pxSocket == NULL ) || ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ) )
+ {
+ /* When pxSocket is NULL, this function is called by prvTCPSendReset()
+ and the IP-addresses must be swapped.
+ Also swap the IP-addresses in case the IP-tack doesn't have an
+ IP-address yet, i.e. when ( *ipLOCAL_IP_ADDRESS_POINTER == 0ul ). */
+ ulSourceAddress = pxIPHeader->ulDestinationIPAddress;
+ }
+ else
+ {
+ ulSourceAddress = *ipLOCAL_IP_ADDRESS_POINTER;
+ }
+ pxIPHeader->ulDestinationIPAddress = pxIPHeader->ulSourceIPAddress;
+ pxIPHeader->ulSourceIPAddress = ulSourceAddress;
+ vFlip_16( pxTCPPacket->xTCPHeader.usSourcePort, pxTCPPacket->xTCPHeader.usDestinationPort );
+
+ /* Just an increasing number. */
+ pxIPHeader->usIdentification = FreeRTOS_htons( usPacketIdentifier );
+ usPacketIdentifier++;
+ pxIPHeader->usFragmentOffset = 0u;
+
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ {
+ /* calculate the IP header checksum, in case the driver won't do that. */
+ pxIPHeader->usHeaderChecksum = 0x00u;
+ pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
+ pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
+
+ /* calculate the TCP checksum for an outgoing packet. */
+ usGenerateProtocolChecksum( (uint8_t*)pxTCPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
+
+ /* A calculated checksum of 0 must be inverted as 0 means the checksum
+ is disabled. */
+ if( pxTCPPacket->xTCPHeader.usChecksum == 0x00u )
+ {
+ pxTCPPacket->xTCPHeader.usChecksum = 0xffffU;
+ }
+ }
+ #endif
+
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ pxNetworkBuffer->pxNextBuffer = NULL;
+ #endif
+
+ /* Important: tell NIC driver how many bytes must be sent. */
+ pxNetworkBuffer->xDataLength = ulLen + ipSIZE_OF_ETH_HEADER;
+
+ /* Fill in the destination MAC addresses. */
+ memcpy( ( void * ) &( pxEthernetHeader->xDestinationAddress ), ( void * ) &( pxEthernetHeader->xSourceAddress ),
+ sizeof( pxEthernetHeader->xDestinationAddress ) );
+
+ /* The source MAC addresses is fixed to 'ipLOCAL_MAC_ADDRESS'. */
+ memcpy( ( void * ) &( pxEthernetHeader->xSourceAddress) , ( void * ) ipLOCAL_MAC_ADDRESS, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
+
+ #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ BaseType_t xIndex;
+
+ for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
+ {
+ pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
+ }
+ pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
+ }
+ }
+ #endif
+
+ /* Send! */
+ xNetworkInterfaceOutput( pxNetworkBuffer, xReleaseAfterSend );
+
+ if( xReleaseAfterSend == pdFALSE )
+ {
+ /* Swap-back some fields, as pxBuffer probably points to a socket field
+ containing the packet header. */
+ vFlip_16( pxTCPPacket->xTCPHeader.usSourcePort, pxTCPPacket->xTCPHeader.usDestinationPort);
+ pxTCPPacket->xIPHeader.ulSourceIPAddress = pxTCPPacket->xIPHeader.ulDestinationIPAddress;
+ memcpy( pxEthernetHeader->xSourceAddress.ucBytes, pxEthernetHeader->xDestinationAddress.ucBytes, ( size_t ) ipMAC_ADDRESS_LENGTH_BYTES );
+ }
+ else
+ {
+ /* Nothing to do: the buffer has been passed to DMA and will be released after use */
+ }
+ } /* if( pxNetworkBuffer != NULL ) */
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * The SYN event is very important: the sequence numbers, which have a kind of
+ * random starting value, are being synchronised. The sliding window manager
+ * (in FreeRTOS_TCP_WIN.c) needs to know them, along with the Maximum Segment
+ * Size (MSS) in use.
+ */
+static void prvTCPCreateWindow( FreeRTOS_Socket_t *pxSocket )
+{
+ if( xTCPWindowLoggingLevel )
+ FreeRTOS_debug_printf( ( "Limits (using): TCP Win size %lu Water %lu <= %lu <= %lu\n",
+ pxSocket->u.xTCP.uxRxWinSize * ipconfigTCP_MSS,
+ pxSocket->u.xTCP.uxLittleSpace ,
+ pxSocket->u.xTCP.uxEnoughSpace,
+ pxSocket->u.xTCP.uxRxStreamSize ) );
+ vTCPWindowCreate(
+ &pxSocket->u.xTCP.xTCPWindow,
+ ipconfigTCP_MSS * pxSocket->u.xTCP.uxRxWinSize,
+ ipconfigTCP_MSS * pxSocket->u.xTCP.uxTxWinSize,
+ pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber,
+ pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber,
+ ( uint32_t ) pxSocket->u.xTCP.usInitMSS );
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Connecting sockets have a special state: eCONNECT_SYN. In this phase,
+ * the Ethernet address of the target will be found using ARP. In case the
+ * target IP address is not within the netmask, the hardware address of the
+ * gateway will be used.
+ */
+static BaseType_t prvTCPPrepareConnect( FreeRTOS_Socket_t *pxSocket )
+{
+TCPPacket_t *pxTCPPacket;
+IPHeader_t *pxIPHeader;
+eARPLookupResult_t eReturned;
+uint32_t ulRemoteIP;
+MACAddress_t xEthAddress;
+BaseType_t xReturn = pdTRUE;
+uint32_t ulInitialSequenceNumber = 0;
+
+ #if( ipconfigHAS_PRINTF != 0 )
+ {
+ /* Only necessary for nicer logging. */
+ memset( xEthAddress.ucBytes, '\0', sizeof( xEthAddress.ucBytes ) );
+ }
+ #endif /* ipconfigHAS_PRINTF != 0 */
+
+ ulRemoteIP = FreeRTOS_htonl( pxSocket->u.xTCP.ulRemoteIP );
+
+ /* Determine the ARP cache status for the requested IP address. */
+ eReturned = eARPGetCacheEntry( &( ulRemoteIP ), &( xEthAddress ) );
+
+ switch( eReturned )
+ {
+ case eARPCacheHit: /* An ARP table lookup found a valid entry. */
+ break; /* We can now prepare the SYN packet. */
+ case eARPCacheMiss: /* An ARP table lookup did not find a valid entry. */
+ case eCantSendPacket: /* There is no IP address, or an ARP is still in progress. */
+ default:
+ /* Count the number of times it couldn't find the ARP address. */
+ pxSocket->u.xTCP.ucRepCount++;
+
+ FreeRTOS_debug_printf( ( "ARP for %lxip (using %lxip): rc=%d %02X:%02X:%02X %02X:%02X:%02X\n",
+ pxSocket->u.xTCP.ulRemoteIP,
+ FreeRTOS_htonl( ulRemoteIP ),
+ eReturned,
+ xEthAddress.ucBytes[ 0 ],
+ xEthAddress.ucBytes[ 1 ],
+ xEthAddress.ucBytes[ 2 ],
+ xEthAddress.ucBytes[ 3 ],
+ xEthAddress.ucBytes[ 4 ],
+ xEthAddress.ucBytes[ 5 ] ) );
+
+ /* And issue a (new) ARP request */
+ FreeRTOS_OutputARPRequest( ulRemoteIP );
+
+ xReturn = pdFALSE;
+ }
+
+ if( xReturn != pdFALSE )
+ {
+ /* Get a difficult-to-predict initial sequence number for this 4-tuple. */
+ ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER,
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort );
+
+ /* Check for a random number generation error. */
+ if( 0 == ulInitialSequenceNumber )
+ {
+ xReturn = pdFALSE;
+ }
+ }
+
+ if( xReturn != pdFALSE )
+ {
+ /* The MAC-address of the peer (or gateway) has been found,
+ now prepare the initial TCP packet and some fields in the socket. */
+ pxTCPPacket = ( TCPPacket_t * )pxSocket->u.xTCP.xPacket.u.ucLastPacket;
+ pxIPHeader = &pxTCPPacket->xIPHeader;
+
+ /* reset the retry counter to zero. */
+ pxSocket->u.xTCP.ucRepCount = 0u;
+
+ /* And remember that the connect/SYN data are prepared. */
+ pxSocket->u.xTCP.bits.bConnPrepared = pdTRUE_UNSIGNED;
+
+ /* Now that the Ethernet address is known, the initial packet can be
+ prepared. */
+ memset( pxSocket->u.xTCP.xPacket.u.ucLastPacket, '\0', sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
+
+ /* Write the Ethernet address in Source, because it will be swapped by
+ prvTCPReturnPacket(). */
+ memcpy( &pxTCPPacket->xEthernetHeader.xSourceAddress, &xEthAddress, sizeof( xEthAddress ) );
+
+ /* 'ipIPv4_FRAME_TYPE' is already in network-byte-order. */
+ pxTCPPacket->xEthernetHeader.usFrameType = ipIPv4_FRAME_TYPE;
+
+ pxIPHeader->ucVersionHeaderLength = 0x45u;
+ pxIPHeader->usLength = FreeRTOS_htons( sizeof( TCPPacket_t ) - sizeof( pxTCPPacket->xEthernetHeader ) );
+ pxIPHeader->ucTimeToLive = ( uint8_t ) ipconfigTCP_TIME_TO_LIVE;
+
+ pxIPHeader->ucProtocol = ( uint8_t ) ipPROTOCOL_TCP;
+
+ /* Addresses and ports will be stored swapped because prvTCPReturnPacket
+ will swap them back while replying. */
+ pxIPHeader->ulDestinationIPAddress = *ipLOCAL_IP_ADDRESS_POINTER;
+ pxIPHeader->ulSourceIPAddress = FreeRTOS_htonl( pxSocket->u.xTCP.ulRemoteIP );
+
+ pxTCPPacket->xTCPHeader.usSourcePort = FreeRTOS_htons( pxSocket->u.xTCP.usRemotePort );
+ pxTCPPacket->xTCPHeader.usDestinationPort = FreeRTOS_htons( pxSocket->usLocalPort );
+
+ /* We are actively connecting, so the peer's Initial Sequence Number (ISN)
+ isn't known yet. */
+ pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = 0ul;
+
+ /* Start with ISN (Initial Sequence Number). */
+ pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
+
+ /* The TCP header size is 20 bytes, divided by 4 equals 5, which is put in
+ the high nibble of the TCP offset field. */
+ pxTCPPacket->xTCPHeader.ucTCPOffset = 0x50u;
+
+ /* Only set the SYN flag. */
+ pxTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_SYN;
+
+ /* Set the values of usInitMSS / usCurMSS for this socket. */
+ prvSocketSetMSS( pxSocket );
+
+ /* The initial sequence numbers at our side are known. Later
+ vTCPWindowInit() will be called to fill in the peer's sequence numbers, but
+ first wait for a SYN+ACK reply. */
+ prvTCPCreateWindow( pxSocket );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+/* For logging and debugging: make a string showing the TCP flags
+*/
+#if( ipconfigHAS_DEBUG_PRINTF != 0 )
+
+ static const char *prvTCPFlagMeaning( UBaseType_t xFlags)
+ {
+ static char retString[10];
+ snprintf(retString, sizeof( retString ), "%c%c%c%c%c%c%c%c%c",
+ ( xFlags & ipTCP_FLAG_FIN ) ? 'F' : '.', /* 0x0001: No more data from sender */
+ ( xFlags & ipTCP_FLAG_SYN ) ? 'S' : '.', /* 0x0002: Synchronize sequence numbers */
+ ( xFlags & ipTCP_FLAG_RST ) ? 'R' : '.', /* 0x0004: Reset the connection */
+ ( xFlags & ipTCP_FLAG_PSH ) ? 'P' : '.', /* 0x0008: Push function: please push buffered data to the recv application */
+ ( xFlags & ipTCP_FLAG_ACK ) ? 'A' : '.', /* 0x0010: Acknowledgment field is significant */
+ ( xFlags & ipTCP_FLAG_URG ) ? 'U' : '.', /* 0x0020: Urgent pointer field is significant */
+ ( xFlags & ipTCP_FLAG_ECN ) ? 'E' : '.', /* 0x0040: ECN-Echo */
+ ( xFlags & ipTCP_FLAG_CWR ) ? 'C' : '.', /* 0x0080: Congestion Window Reduced */
+ ( xFlags & ipTCP_FLAG_NS ) ? 'N' : '.'); /* 0x0100: ECN-nonce concealment protection */
+ return retString;
+ }
+ /*-----------------------------------------------------------*/
+
+#endif /* ipconfigHAS_DEBUG_PRINTF */
+
+/*
+ * Parse the TCP option(s) received, if present. It has already been verified
+ * that: ((pxTCPHeader->ucTCPOffset & 0xf0) > 0x50), meaning that the TP header
+ * is longer than the usual 20 (5 x 4) bytes.
+ */
+static void prvCheckOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+TCPPacket_t * pxTCPPacket;
+TCPHeader_t * pxTCPHeader;
+const unsigned char *pucPtr;
+const unsigned char *pucLast;
+TCPWindow_t *pxTCPWindow;
+BaseType_t xShouldContinueLoop;
+
+ pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+ pxTCPHeader = &pxTCPPacket->xTCPHeader;
+
+ /* A character pointer to iterate through the option data */
+ pucPtr = pxTCPHeader->ucOptdata;
+ pucLast = pucPtr + (((pxTCPHeader->ucTCPOffset >> 4) - 5) << 2);
+ pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+
+ /* Validate options size calculation. */
+ if( pucLast > ( pxNetworkBuffer->pucEthernetBuffer + pxNetworkBuffer->xDataLength ) )
+ {
+ return;
+ }
+
+ /* The comparison with pucLast is only necessary in case the option data are
+ corrupted, we don't like to run into invalid memory and crash. */
+ xShouldContinueLoop = pdTRUE;
+ while( ( pucPtr < pucLast ) && ( xShouldContinueLoop == pdTRUE ) )
+ {
+ xShouldContinueLoop = prvSingleStepTCPHeaderOptions( &pucPtr, &pucLast, &pxSocket, &pxTCPWindow );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvSingleStepTCPHeaderOptions( const unsigned char ** const ppucPtr, const unsigned char ** const ppucLast, FreeRTOS_Socket_t ** const ppxSocket, TCPWindow_t ** const ppxTCPWindow)
+{
+ UBaseType_t uxNewMSS;
+ UBaseType_t xRemainingOptionsBytes = ( *ppucLast ) - ( *ppucPtr );
+ unsigned char ucLen;
+
+ if( ( *ppucPtr )[ 0 ] == TCP_OPT_END )
+ {
+ /* End of options. */
+ return pdFALSE;
+ }
+ if( ( *ppucPtr )[ 0 ] == TCP_OPT_NOOP)
+ {
+ /* NOP option, inserted to make the length a multiple of 4. */
+ ( *ppucPtr )++;
+ return pdTRUE;
+ }
+
+ /* Any other well-formed option must be at least two bytes: the option
+ type byte followed by a length byte. */
+ if( xRemainingOptionsBytes < 2 )
+ {
+ return pdFALSE;
+ }
+#if( ipconfigUSE_TCP_WIN != 0 )
+ else if( ( *ppucPtr )[ 0 ] == TCP_OPT_WSOPT )
+ {
+ /* Confirm that the option fits in the remaining buffer space. */
+ if( ( xRemainingOptionsBytes < TCP_OPT_WSOPT_LEN ) || ( ( *ppucPtr )[ 1 ] != TCP_OPT_WSOPT_LEN ) )
+ {
+ return pdFALSE;
+ }
+
+ ( *ppxSocket )->u.xTCP.ucPeerWinScaleFactor = ( *ppucPtr )[ 2 ];
+ ( *ppxSocket )->u.xTCP.bits.bWinScaling = pdTRUE_UNSIGNED;
+ ( *ppucPtr ) += TCP_OPT_WSOPT_LEN;
+ }
+#endif /* ipconfigUSE_TCP_WIN */
+ else if( ( *ppucPtr )[ 0 ] == TCP_OPT_MSS )
+ {
+ /* Confirm that the option fits in the remaining buffer space. */
+ if( ( xRemainingOptionsBytes < TCP_OPT_MSS_LEN )|| ( ( *ppucPtr )[ 1 ] != TCP_OPT_MSS_LEN ) )
+ {
+ return pdFALSE;
+ }
+
+ /* An MSS option with the correct option length. FreeRTOS_htons()
+ is not needed here because usChar2u16() already returns a host
+ endian number. */
+ uxNewMSS = usChar2u16( ( *ppucPtr ) + 2 );
+
+ if( ( *ppxSocket )->u.xTCP.usInitMSS != uxNewMSS )
+ {
+ /* Perform a basic check on the the new MSS. */
+ if( uxNewMSS == 0 )
+ {
+ return pdFALSE;
+ }
+
+ FreeRTOS_debug_printf( ( "MSS change %u -> %lu\n", ( *ppxSocket )->u.xTCP.usInitMSS, uxNewMSS ) );
+ }
+
+ if( ( *ppxSocket )->u.xTCP.usInitMSS > uxNewMSS )
+ {
+ /* our MSS was bigger than the MSS of the other party: adapt it. */
+ ( *ppxSocket )->u.xTCP.bits.bMssChange = pdTRUE_UNSIGNED;
+ if( ( ( *ppxTCPWindow ) != NULL ) && ( ( *ppxSocket )->u.xTCP.usCurMSS > uxNewMSS ) )
+ {
+ /* The peer advertises a smaller MSS than this socket was
+ using. Use that as well. */
+ FreeRTOS_debug_printf( ( "Change mss %d => %lu\n", ( *ppxSocket )->u.xTCP.usCurMSS, uxNewMSS ) );
+ ( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
+ }
+ ( *ppxTCPWindow )->xSize.ulRxWindowLength = ( ( uint32_t ) uxNewMSS ) * ( ( *ppxTCPWindow )->xSize.ulRxWindowLength / ( ( uint32_t ) uxNewMSS ) );
+ ( *ppxTCPWindow )->usMSSInit = ( uint16_t ) uxNewMSS;
+ ( *ppxTCPWindow )->usMSS = ( uint16_t ) uxNewMSS;
+ ( *ppxSocket )->u.xTCP.usInitMSS = ( uint16_t ) uxNewMSS;
+ ( *ppxSocket )->u.xTCP.usCurMSS = ( uint16_t ) uxNewMSS;
+ }
+
+ #if( ipconfigUSE_TCP_WIN != 1 )
+ /* Without scaled windows, MSS is the only interesting option. */
+ return pdFALSE;
+ #else
+ /* Or else we continue to check another option: selective ACK. */
+ ( *ppucPtr ) += TCP_OPT_MSS_LEN;
+ #endif /* ipconfigUSE_TCP_WIN != 1 */
+ }
+ else
+ {
+ /* All other options have a length field, so that we easily
+ can skip past them. */
+ ucLen = ( *ppucPtr )[ 1 ];
+ if( ( ucLen < 2 ) || ( ucLen > xRemainingOptionsBytes ) )
+ {
+ /* If the length field is too small or too big, the options are
+ * malformed, don't process them further.
+ */
+ return pdFALSE;
+ }
+
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ /* Selective ACK: the peer has received a packet but it is missing
+ * earlier packets. At least this packet does not need retransmission
+ * anymore. ulTCPWindowTxSack( ) takes care of this administration.
+ */
+ if( ( *ppucPtr )[0] == TCP_OPT_SACK_A )
+ {
+ ucLen -= 2;
+ ( *ppucPtr ) += 2;
+
+ while( ucLen >= 8 )
+ {
+ prvSkipPastRemainingOptions( ppucPtr, ppxSocket, &ucLen );
+ }
+ /* ucLen should be 0 by now. */
+ }
+ }
+ #endif /* ipconfigUSE_TCP_WIN == 1 */
+
+ ( *ppucPtr ) += ucLen;
+ }
+ return pdTRUE;
+}
+
+/*-----------------------------------------------------------*/
+
+static void prvSkipPastRemainingOptions( const unsigned char ** const ppucPtr, FreeRTOS_Socket_t ** const ppxSocket, unsigned char * const pucLen )
+{
+uint32_t ulFirst = ulChar2u32( ( *ppucPtr ) );
+uint32_t ulLast = ulChar2u32( ( *ppucPtr ) + 4 );
+uint32_t ulCount = ulTCPWindowTxSack( &( *ppxSocket )->u.xTCP.xTCPWindow, ulFirst, ulLast );
+ /* ulTCPWindowTxSack( ) returns the number of bytes which have been acked
+ * starting from the head position. Advance the tail pointer in txStream.
+ */
+ if( ( ( *ppxSocket )->u.xTCP.txStream != NULL ) && ( ulCount > 0 ) )
+ {
+ /* Just advancing the tail index, 'ulCount' bytes have been confirmed. */
+ uxStreamBufferGet( ( *ppxSocket )->u.xTCP.txStream, 0, NULL, ( size_t ) ulCount, pdFALSE );
+ ( *ppxSocket )->xEventBits |= eSOCKET_SEND;
+
+ #if ipconfigSUPPORT_SELECT_FUNCTION == 1
+ {
+ if( ( *ppxSocket )->xSelectBits & eSELECT_WRITE )
+ {
+ /* The field 'xEventBits' is used to store regular socket events
+ * (at most 8), as well as 'select events', which will be left-shifted.
+ */
+ ( *ppxSocket )->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
+ }
+ }
+ #endif
+
+ /* In case the socket owner has installed an OnSent handler, call it now.
+ */
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ipconfigIS_VALID_PROG_ADDRESS( ( *ppxSocket )->u.xTCP.pxHandleSent ) )
+ {
+ ( *ppxSocket )->u.xTCP.pxHandleSent( (Socket_t )( *ppxSocket ), ulCount );
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS == 1 */
+ }
+ ( *ppucPtr ) += 8;
+ ( *pucLen ) -= 8;
+}
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN != 0 )
+
+ static uint8_t prvWinScaleFactor( FreeRTOS_Socket_t *pxSocket )
+ {
+ size_t uxWinSize;
+ uint8_t ucFactor;
+
+ /* 'xTCP.uxRxWinSize' is the size of the reception window in units of MSS. */
+ uxWinSize = pxSocket->u.xTCP.uxRxWinSize * ( size_t ) pxSocket->u.xTCP.usInitMSS;
+ ucFactor = 0u;
+ while( uxWinSize > 0xfffful )
+ {
+ /* Divide by two and increase the binary factor by 1. */
+ uxWinSize >>= 1;
+ ucFactor++;
+ }
+
+ FreeRTOS_debug_printf( ( "prvWinScaleFactor: uxRxWinSize %lu MSS %lu Factor %u\n",
+ pxSocket->u.xTCP.uxRxWinSize,
+ pxSocket->u.xTCP.usInitMSS,
+ ucFactor ) );
+
+ return ucFactor;
+ }
+
+#endif
+/*-----------------------------------------------------------*/
+
+/*
+ * When opening a TCP connection, while SYN's are being sent, the parties may
+ * communicate what MSS (Maximum Segment Size) they intend to use. MSS is the
+ * nett size of the payload, always smaller than MTU.
+*/
+static UBaseType_t prvSetSynAckOptions( FreeRTOS_Socket_t *pxSocket, TCPPacket_t * pxTCPPacket )
+{
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+uint16_t usMSS = pxSocket->u.xTCP.usInitMSS;
+UBaseType_t uxOptionsLength;
+
+ /* We send out the TCP Maximum Segment Size option with our SYN[+ACK]. */
+
+ pxTCPHeader->ucOptdata[ 0 ] = ( uint8_t ) TCP_OPT_MSS;
+ pxTCPHeader->ucOptdata[ 1 ] = ( uint8_t ) TCP_OPT_MSS_LEN;
+ pxTCPHeader->ucOptdata[ 2 ] = ( uint8_t ) ( usMSS >> 8 );
+ pxTCPHeader->ucOptdata[ 3 ] = ( uint8_t ) ( usMSS & 0xffu );
+
+ #if( ipconfigUSE_TCP_WIN != 0 )
+ {
+ pxSocket->u.xTCP.ucMyWinScaleFactor = prvWinScaleFactor( pxSocket );
+
+ pxTCPHeader->ucOptdata[ 4 ] = TCP_OPT_NOOP;
+ pxTCPHeader->ucOptdata[ 5 ] = ( uint8_t ) ( TCP_OPT_WSOPT );
+ pxTCPHeader->ucOptdata[ 6 ] = ( uint8_t ) ( TCP_OPT_WSOPT_LEN );
+ pxTCPHeader->ucOptdata[ 7 ] = ( uint8_t ) pxSocket->u.xTCP.ucMyWinScaleFactor;
+ uxOptionsLength = 8u;
+ }
+ #else
+ {
+ uxOptionsLength = 4u;
+ }
+ #endif
+
+ #if( ipconfigUSE_TCP_WIN == 0 )
+ {
+ return uxOptionsLength;
+ }
+ #else
+ {
+ pxTCPHeader->ucOptdata[ uxOptionsLength + 0 ] = TCP_OPT_NOOP;
+ pxTCPHeader->ucOptdata[ uxOptionsLength + 1 ] = TCP_OPT_NOOP;
+ pxTCPHeader->ucOptdata[ uxOptionsLength + 2 ] = TCP_OPT_SACK_P; /* 4: Sack-Permitted Option. */
+ pxTCPHeader->ucOptdata[ uxOptionsLength + 3 ] = 2; /* 2: length of this option. */
+ uxOptionsLength += 4u;
+
+ return uxOptionsLength; /* bytes, not words. */
+ }
+ #endif /* ipconfigUSE_TCP_WIN == 0 */
+}
+
+/*
+ * For anti-hanging protection and TCP keep-alive messages. Called in two
+ * places: after receiving a packet and after a state change. The socket's
+ * alive timer may be reset.
+ */
+static void prvTCPTouchSocket( FreeRTOS_Socket_t *pxSocket )
+{
+ #if( ipconfigTCP_HANG_PROTECTION == 1 )
+ {
+ pxSocket->u.xTCP.xLastActTime = xTaskGetTickCount( );
+ }
+ #endif
+
+ #if( ipconfigTCP_KEEP_ALIVE == 1 )
+ {
+ pxSocket->u.xTCP.bits.bWaitKeepAlive = pdFALSE_UNSIGNED;
+ pxSocket->u.xTCP.bits.bSendKeepAlive = pdFALSE_UNSIGNED;
+ pxSocket->u.xTCP.ucKeepRepCount = 0u;
+ pxSocket->u.xTCP.xLastAliveTime = xTaskGetTickCount();
+ }
+ #endif
+
+ ( void ) pxSocket;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Changing to a new state. Centralised here to do specific actions such as
+ * resetting the alive timer, calling the user's OnConnect handler to notify
+ * that a socket has got (dis)connected, and setting bit to unblock a call to
+ * FreeRTOS_select()
+ */
+void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState )
+{
+FreeRTOS_Socket_t *xParent = NULL;
+BaseType_t bBefore = ( BaseType_t ) NOW_CONNECTED( pxSocket->u.xTCP.ucTCPState ); /* Was it connected ? */
+BaseType_t bAfter = ( BaseType_t ) NOW_CONNECTED( eTCPState ); /* Is it connected now ? */
+#if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ BaseType_t xPreviousState = ( BaseType_t ) pxSocket->u.xTCP.ucTCPState;
+#endif
+#if( ipconfigUSE_CALLBACKS == 1 )
+ FreeRTOS_Socket_t *xConnected = NULL;
+#endif
+
+ /* Has the connected status changed? */
+ if( bBefore != bAfter )
+ {
+ /* Is the socket connected now ? */
+ if( bAfter != pdFALSE )
+ {
+ /* if bPassQueued is true, this socket is an orphan until it gets connected. */
+ if( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED )
+ {
+ /* Now that it is connected, find it's parent. */
+ if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
+ {
+ xParent = pxSocket;
+ }
+ else
+ {
+ xParent = pxSocket->u.xTCP.pxPeerSocket;
+ configASSERT( xParent != NULL );
+ }
+ if( xParent != NULL )
+ {
+ if( xParent->u.xTCP.pxPeerSocket == NULL )
+ {
+ xParent->u.xTCP.pxPeerSocket = pxSocket;
+ }
+
+ xParent->xEventBits |= eSOCKET_ACCEPT;
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ /* Library support FreeRTOS_select(). Receiving a new
+ connection is being translated as a READ event. */
+ if( ( xParent->xSelectBits & eSELECT_READ ) != 0 )
+ {
+ xParent->xEventBits |= ( eSELECT_READ << SOCKET_EVENT_BIT_COUNT );
+ }
+ }
+ #endif
+
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ( ipconfigIS_VALID_PROG_ADDRESS( xParent->u.xTCP.pxHandleConnected ) != pdFALSE ) &&
+ ( xParent->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED ) )
+ {
+ /* The listening socket does not become connected itself, in stead
+ a child socket is created.
+ Postpone a call the OnConnect event until the end of this function. */
+ xConnected = xParent;
+ }
+ }
+ #endif
+ }
+
+ /* Don't need to access the parent socket anymore, so the
+ reference 'pxPeerSocket' may be cleared. */
+ pxSocket->u.xTCP.pxPeerSocket = NULL;
+ pxSocket->u.xTCP.bits.bPassQueued = pdFALSE_UNSIGNED;
+
+ /* When true, this socket may be returned in a call to accept(). */
+ pxSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ pxSocket->xEventBits |= eSOCKET_CONNECT;
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ if( pxSocket->xSelectBits & eSELECT_WRITE )
+ {
+ pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
+ }
+ }
+ #endif
+ }
+ }
+ else /* bAfter == pdFALSE, connection is closed. */
+ {
+ /* Notify/wake-up the socket-owner by setting a semaphore. */
+ pxSocket->xEventBits |= eSOCKET_CLOSED;
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ if( ( pxSocket->xSelectBits & eSELECT_EXCEPT ) != 0 )
+ {
+ pxSocket->xEventBits |= ( eSELECT_EXCEPT << SOCKET_EVENT_BIT_COUNT );
+ }
+ }
+ #endif
+ }
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleConnected ) != pdFALSE ) && ( xConnected == NULL ) )
+ {
+ /* The 'connected' state has changed, call the user handler. */
+ xConnected = pxSocket;
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ if( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE )
+ {
+ /* Now the socket isn't in an active state anymore so it
+ won't need further attention of the IP-task.
+ Setting time-out to zero means that the socket won't get checked during
+ timer events. */
+ pxSocket->u.xTCP.usTimeout = 0u;
+ }
+ }
+ else
+ {
+ if( eTCPState == eCLOSED )
+ {
+ /* Socket goes to status eCLOSED because of a RST.
+ When nobody owns the socket yet, delete it. */
+ if( ( pxSocket->u.xTCP.bits.bPassQueued != pdFALSE_UNSIGNED ) ||
+ ( pxSocket->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
+ {
+ FreeRTOS_debug_printf( ( "vTCPStateChange: Closing socket\n" ) );
+ if( pxSocket->u.xTCP.bits.bReuseSocket == pdFALSE_UNSIGNED )
+ {
+ FreeRTOS_closesocket( pxSocket );
+ }
+ }
+ }
+ }
+
+ /* Fill in the new state. */
+ pxSocket->u.xTCP.ucTCPState = ( uint8_t ) eTCPState;
+
+ /* touch the alive timers because moving to another state. */
+ prvTCPTouchSocket( pxSocket );
+
+ #if( ipconfigHAS_DEBUG_PRINTF == 1 )
+ {
+ if( ( xTCPWindowLoggingLevel >= 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
+ FreeRTOS_debug_printf( ( "Socket %d -> %lxip:%u State %s->%s\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort,
+ FreeRTOS_GetTCPStateName( ( UBaseType_t ) xPreviousState ),
+ FreeRTOS_GetTCPStateName( ( UBaseType_t ) eTCPState ) ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF */
+
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( xConnected != NULL )
+ {
+ /* The 'connected' state has changed, call the OnConnect handler of the parent. */
+ xConnected->u.xTCP.pxHandleConnected( ( Socket_t ) xConnected, bAfter );
+ }
+ }
+ #endif
+ if( xParent != NULL )
+ {
+ vSocketWakeUpUser( xParent );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvTCPBufferResize( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer,
+ int32_t lDataLen, UBaseType_t uxOptionsLength )
+{
+NetworkBufferDescriptor_t *pxReturn;
+int32_t lNeeded;
+BaseType_t xResize;
+
+ if( xBufferAllocFixedSize != pdFALSE )
+ {
+ /* Network buffers are created with a fixed size and can hold the largest
+ MTU. */
+ lNeeded = ( int32_t ) ipTOTAL_ETHERNET_FRAME_SIZE;
+ /* and therefore, the buffer won't be too small.
+ Only ask for a new network buffer in case none was supplied. */
+ xResize = ( pxNetworkBuffer == NULL );
+ }
+ else
+ {
+ /* Network buffers are created with a variable size. See if it must
+ grow. */
+ lNeeded = FreeRTOS_max_int32( ( int32_t ) sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ),
+ ( int32_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + lDataLen );
+ /* In case we were called from a TCP timer event, a buffer must be
+ created. Otherwise, test 'xDataLength' of the provided buffer. */
+ xResize = ( pxNetworkBuffer == NULL ) || ( pxNetworkBuffer->xDataLength < (size_t)lNeeded );
+ }
+
+ if( xResize != pdFALSE )
+ {
+ /* The caller didn't provide a network buffer or the provided buffer is
+ too small. As we must send-out a data packet, a buffer will be created
+ here. */
+ pxReturn = pxGetNetworkBufferWithDescriptor( ( uint32_t ) lNeeded, 0u );
+
+ if( pxReturn != NULL )
+ {
+ /* Set the actual packet size, in case the returned buffer is larger. */
+ pxReturn->xDataLength = lNeeded;
+
+ /* Copy the existing data to the new created buffer. */
+ if( pxNetworkBuffer )
+ {
+ /* Either from the previous buffer... */
+ memcpy( pxReturn->pucEthernetBuffer, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
+
+ /* ...and release it. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ else
+ {
+ /* Or from the socket field 'xTCP.xPacket'. */
+ memcpy( pxReturn->pucEthernetBuffer, pxSocket->u.xTCP.xPacket.u.ucLastPacket, sizeof( pxSocket->u.xTCP.xPacket.u.ucLastPacket ) );
+ }
+ }
+ }
+ else
+ {
+ /* xResize is false, the network buffer provided was big enough. */
+ pxReturn = pxNetworkBuffer;
+
+ /* Thanks to Andrey Ivanov from swissEmbedded for reporting that the
+ xDataLength member must get the correct length too! */
+ pxNetworkBuffer->xDataLength = ( size_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength ) + ( size_t ) lDataLen;
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Prepare an outgoing message, in case anything has to be sent.
+ */
+static int32_t prvTCPPrepareSend( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer, UBaseType_t uxOptionsLength )
+{
+int32_t lDataLen;
+uint8_t *pucEthernetBuffer, *pucSendData;
+TCPPacket_t *pxTCPPacket;
+size_t uxOffset;
+uint32_t ulDataGot, ulDistance;
+TCPWindow_t *pxTCPWindow;
+NetworkBufferDescriptor_t *pxNewBuffer;
+int32_t lStreamPos;
+
+ if( ( *ppxNetworkBuffer ) != NULL )
+ {
+ /* A network buffer descriptor was already supplied */
+ pucEthernetBuffer = ( *ppxNetworkBuffer )->pucEthernetBuffer;
+ }
+ else
+ {
+ /* For now let it point to the last packet header */
+ pucEthernetBuffer = pxSocket->u.xTCP.xPacket.u.ucLastPacket;
+ }
+
+ pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
+ pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+ lDataLen = 0;
+ lStreamPos = 0;
+ pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_ACK;
+
+ if( pxSocket->u.xTCP.txStream != NULL )
+ {
+ /* ulTCPWindowTxGet will return the amount of data which may be sent
+ along with the position in the txStream.
+ Why check for MSS > 1 ?
+ Because some TCP-stacks (like uIP) use it for flow-control. */
+ if( pxSocket->u.xTCP.usCurMSS > 1u )
+ {
+ lDataLen = ( int32_t ) ulTCPWindowTxGet( pxTCPWindow, pxSocket->u.xTCP.ulWindowSize, &lStreamPos );
+ }
+
+ if( lDataLen > 0 )
+ {
+ /* Check if the current network buffer is big enough, if not,
+ resize it. */
+ pxNewBuffer = prvTCPBufferResize( pxSocket, *ppxNetworkBuffer, lDataLen, uxOptionsLength );
+
+ if( pxNewBuffer != NULL )
+ {
+ *ppxNetworkBuffer = pxNewBuffer;
+ pucEthernetBuffer = pxNewBuffer->pucEthernetBuffer;
+ pxTCPPacket = ( TCPPacket_t * ) ( pucEthernetBuffer );
+
+ pucSendData = pucEthernetBuffer + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength;
+
+ /* Translate the position in txStream to an offset from the tail
+ marker. */
+ uxOffset = uxStreamBufferDistance( pxSocket->u.xTCP.txStream, pxSocket->u.xTCP.txStream->uxTail, ( size_t ) lStreamPos );
+
+ /* Here data is copied from the txStream in 'peek' mode. Only
+ when the packets are acked, the tail marker will be updated. */
+ ulDataGot = ( uint32_t ) uxStreamBufferGet( pxSocket->u.xTCP.txStream, uxOffset, pucSendData, ( size_t ) lDataLen, pdTRUE );
+
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ if( ulDataGot != ( uint32_t ) lDataLen )
+ {
+ FreeRTOS_debug_printf( ( "uxStreamBufferGet: pos %lu offs %lu only %lu != %lu\n",
+ lStreamPos, uxOffset, ulDataGot, lDataLen ) );
+ }
+ }
+ #endif
+
+ /* If the owner of the socket requests a closure, add the FIN
+ flag to the last packet. */
+ if( ( pxSocket->u.xTCP.bits.bCloseRequested != pdFALSE_UNSIGNED ) && ( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) )
+ {
+ ulDistance = ( uint32_t ) uxStreamBufferDistance( pxSocket->u.xTCP.txStream, ( size_t ) lStreamPos, pxSocket->u.xTCP.txStream->uxHead );
+
+ if( ulDistance == ulDataGot )
+ {
+ #if (ipconfigHAS_DEBUG_PRINTF == 1)
+ {
+ /* the order of volatile accesses is undefined
+ so such workaround */
+ size_t uxHead = pxSocket->u.xTCP.txStream->uxHead;
+ size_t uxMid = pxSocket->u.xTCP.txStream->uxMid;
+ size_t uxTail = pxSocket->u.xTCP.txStream->uxTail;
+
+ FreeRTOS_debug_printf( ( "CheckClose %lu <= %lu (%lu <= %lu <= %lu)\n", ulDataGot, ulDistance,
+ uxTail, uxMid, uxHead ) );
+ }
+ #endif
+ /* Although the socket sends a FIN, it will stay in
+ ESTABLISHED until all current data has been received or
+ delivered. */
+ pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_FIN;
+ pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->ulOurSequenceNumber + ( uint32_t ) lDataLen;
+ pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
+ }
+ }
+ }
+ else
+ {
+ lDataLen = -1;
+ }
+ }
+ }
+
+ if( ( lDataLen >= 0 ) && ( pxSocket->u.xTCP.ucTCPState == eESTABLISHED ) )
+ {
+ /* See if the socket owner wants to shutdown this connection. */
+ if( ( pxSocket->u.xTCP.bits.bUserShutdown != pdFALSE_UNSIGNED ) &&
+ ( xTCPWindowTxDone( pxTCPWindow ) != pdFALSE ) )
+ {
+ pxSocket->u.xTCP.bits.bUserShutdown = pdFALSE_UNSIGNED;
+ pxTCPPacket->xTCPHeader.ucTCPFlags |= ipTCP_FLAG_FIN;
+ pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
+ pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
+ pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
+ vTCPStateChange( pxSocket, eFIN_WAIT_1 );
+ }
+
+ #if( ipconfigTCP_KEEP_ALIVE != 0 )
+ {
+ if( pxSocket->u.xTCP.ucKeepRepCount > 3u )
+ {
+ FreeRTOS_debug_printf( ( "keep-alive: giving up %lxip:%u\n",
+ pxSocket->u.xTCP.ulRemoteIP, /* IP address of remote machine. */
+ pxSocket->u.xTCP.usRemotePort ) ); /* Port on remote machine. */
+ vTCPStateChange( pxSocket, eCLOSE_WAIT );
+ lDataLen = -1;
+ }
+ if( ( lDataLen == 0 ) && ( pxSocket->u.xTCP.bits.bWinChange == pdFALSE_UNSIGNED ) )
+ {
+ /* If there is no data to be sent, and no window-update message,
+ we might want to send a keep-alive message. */
+ TickType_t xAge = xTaskGetTickCount( ) - pxSocket->u.xTCP.xLastAliveTime;
+ TickType_t xMax;
+ xMax = ( ( TickType_t ) ipconfigTCP_KEEP_ALIVE_INTERVAL * configTICK_RATE_HZ );
+ if( pxSocket->u.xTCP.ucKeepRepCount )
+ {
+ xMax = ( 3u * configTICK_RATE_HZ );
+ }
+ if( xAge > xMax )
+ {
+ pxSocket->u.xTCP.xLastAliveTime = xTaskGetTickCount( );
+ if( xTCPWindowLoggingLevel )
+ FreeRTOS_debug_printf( ( "keep-alive: %lxip:%u count %u\n",
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort,
+ pxSocket->u.xTCP.ucKeepRepCount ) );
+ pxSocket->u.xTCP.bits.bSendKeepAlive = pdTRUE_UNSIGNED;
+ pxSocket->u.xTCP.usTimeout = ( ( uint16_t ) pdMS_TO_TICKS( 2500 ) );
+ pxSocket->u.xTCP.ucKeepRepCount++;
+ }
+ }
+ }
+ #endif /* ipconfigTCP_KEEP_ALIVE */
+ }
+
+ /* Anything to send, a change of the advertised window size, or maybe send a
+ keep-alive message? */
+ if( ( lDataLen > 0 ) ||
+ ( pxSocket->u.xTCP.bits.bWinChange != pdFALSE_UNSIGNED ) ||
+ ( pxSocket->u.xTCP.bits.bSendKeepAlive != pdFALSE_UNSIGNED ) )
+ {
+ pxTCPPacket->xTCPHeader.ucTCPFlags &= ( ( uint8_t ) ~ipTCP_FLAG_PSH );
+ pxTCPPacket->xTCPHeader.ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+
+ pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_ACK;
+
+ if( lDataLen != 0l )
+ {
+ pxTCPPacket->xTCPHeader.ucTCPFlags |= ( uint8_t ) ipTCP_FLAG_PSH;
+ }
+
+ lDataLen += ( int32_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
+ }
+
+ return lDataLen;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Calculate after how much time this socket needs to be checked again.
+ */
+static TickType_t prvTCPNextTimeout ( FreeRTOS_Socket_t *pxSocket )
+{
+TickType_t ulDelayMs = ( TickType_t ) tcpMAXIMUM_TCP_WAKEUP_TIME_MS;
+
+ if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
+ {
+ /* The socket is actively connecting to a peer. */
+ if( pxSocket->u.xTCP.bits.bConnPrepared )
+ {
+ /* Ethernet address has been found, use progressive timeout for
+ active connect(). */
+ if( pxSocket->u.xTCP.ucRepCount < 3u )
+ {
+ ulDelayMs = ( 3000UL << ( pxSocket->u.xTCP.ucRepCount - 1u ) );
+ }
+ else
+ {
+ ulDelayMs = 11000UL;
+ }
+ }
+ else
+ {
+ /* Still in the ARP phase: check every half second. */
+ ulDelayMs = 500UL;
+ }
+
+ FreeRTOS_debug_printf( ( "Connect[%lxip:%u]: next timeout %u: %lu ms\n",
+ pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort,
+ pxSocket->u.xTCP.ucRepCount, ulDelayMs ) );
+ pxSocket->u.xTCP.usTimeout = ( uint16_t )pdMS_TO_MIN_TICKS( ulDelayMs );
+ }
+ else if( pxSocket->u.xTCP.usTimeout == 0u )
+ {
+ /* Let the sliding window mechanism decide what time-out is appropriate. */
+ BaseType_t xResult = xTCPWindowTxHasData( &pxSocket->u.xTCP.xTCPWindow, pxSocket->u.xTCP.ulWindowSize, &ulDelayMs );
+ if( ulDelayMs == 0u )
+ {
+ if( xResult != ( BaseType_t )0 )
+ {
+ ulDelayMs = 1UL;
+ }
+ else
+ {
+ ulDelayMs = tcpMAXIMUM_TCP_WAKEUP_TIME_MS;
+ }
+ }
+ else
+ {
+ /* ulDelayMs contains the time to wait before a re-transmission. */
+ }
+ pxSocket->u.xTCP.usTimeout = ( uint16_t )pdMS_TO_MIN_TICKS( ulDelayMs );
+ }
+ else
+ {
+ /* field '.usTimeout' has already been set (by the
+ keep-alive/delayed-ACK mechanism). */
+ }
+
+ /* Return the number of clock ticks before the timer expires. */
+ return ( TickType_t ) pxSocket->u.xTCP.usTimeout;
+}
+/*-----------------------------------------------------------*/
+
+static void prvTCPAddTxData( FreeRTOS_Socket_t *pxSocket )
+{
+int32_t lCount, lLength;
+
+ /* A txStream has been created already, see if the socket has new data for
+ the sliding window.
+
+ uxStreamBufferMidSpace() returns the distance between rxHead and rxMid. It contains new
+ Tx data which has not been passed to the sliding window yet. The oldest
+ data not-yet-confirmed can be found at rxTail. */
+ lLength = ( int32_t ) uxStreamBufferMidSpace( pxSocket->u.xTCP.txStream );
+
+ if( lLength > 0 )
+ {
+ /* All data between txMid and rxHead will now be passed to the sliding
+ window manager, so it can start transmitting them.
+
+ Hand over the new data to the sliding window handler. It will be
+ split-up in chunks of 1460 bytes each (or less, depending on
+ ipconfigTCP_MSS). */
+ lCount = lTCPWindowTxAdd( &pxSocket->u.xTCP.xTCPWindow,
+ ( uint32_t ) lLength,
+ ( int32_t ) pxSocket->u.xTCP.txStream->uxMid,
+ ( int32_t ) pxSocket->u.xTCP.txStream->LENGTH );
+
+ /* Move the rxMid pointer forward up to rxHead. */
+ if( lCount > 0 )
+ {
+ vStreamBufferMoveMid( pxSocket->u.xTCP.txStream, ( size_t ) lCount );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvTCPHandleFin() will be called to handle socket closure
+ * The Closure starts when either a FIN has been received and accepted,
+ * Or when the socket has sent a FIN flag to the peer
+ * Before being called, it has been checked that both reception and transmission
+ * are complete.
+ */
+static BaseType_t prvTCPHandleFin( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
+TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+BaseType_t xSendLength = 0;
+uint32_t ulAckNr = FreeRTOS_ntohl( pxTCPHeader->ulAckNr );
+
+ if( ( ucTCPFlags & ipTCP_FLAG_FIN ) != 0u )
+ {
+ pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulFINSequenceNumber + 1u;
+ }
+ if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
+ {
+ /* We haven't yet replied with a FIN, do so now. */
+ pxTCPWindow->tx.ulFINSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
+ pxSocket->u.xTCP.bits.bFinSent = pdTRUE_UNSIGNED;
+ }
+ else
+ {
+ /* We did send a FIN already, see if it's ACK'd. */
+ if( ulAckNr == pxTCPWindow->tx.ulFINSequenceNumber + 1u )
+ {
+ pxSocket->u.xTCP.bits.bFinAcked = pdTRUE_UNSIGNED;
+ }
+ }
+
+ if( pxSocket->u.xTCP.bits.bFinAcked == pdFALSE_UNSIGNED )
+ {
+ pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber;
+ pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK | ipTCP_FLAG_FIN;
+
+ /* And wait for the final ACK. */
+ vTCPStateChange( pxSocket, eLAST_ACK );
+ }
+ else
+ {
+ /* Our FIN has been ACK'd, the outgoing sequence number is now fixed. */
+ pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber + 1u;
+ if( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED )
+ {
+ /* We have sent out a FIN but the peer hasn't replied with a FIN
+ yet. Do nothing for the moment. */
+ pxTCPHeader->ucTCPFlags = 0u;
+ }
+ else
+ {
+ if( pxSocket->u.xTCP.bits.bFinLast == pdFALSE_UNSIGNED )
+ {
+ /* This is the third of the three-way hand shake: the last
+ ACK. */
+ pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
+ }
+ else
+ {
+ /* The other party started the closure, so we just wait for the
+ last ACK. */
+ pxTCPHeader->ucTCPFlags = 0u;
+ }
+
+ /* And wait for the user to close this socket. */
+ vTCPStateChange( pxSocket, eCLOSE_WAIT );
+ }
+ }
+
+ pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
+
+ if( pxTCPHeader->ucTCPFlags != 0u )
+ {
+ xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength );
+ }
+
+ pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + pxTCPWindow->ucOptionLength ) << 2 );
+
+ if( xTCPWindowLoggingLevel != 0 )
+ {
+ FreeRTOS_debug_printf( ( "TCP: send FIN+ACK (ack %lu, cur/nxt %lu/%lu) ourSeqNr %lu | Rx %lu\n",
+ ulAckNr - pxTCPWindow->tx.ulFirstSequenceNumber,
+ pxTCPWindow->tx.ulCurrentSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
+ pxTCPWindow->ulNextTxSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
+ pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
+ pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) );
+ }
+
+ return xSendLength;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvCheckRxData(): called from prvTCPHandleState()
+ *
+ * The first thing that will be done is find the TCP payload data
+ * and check the length of this data.
+ */
+static BaseType_t prvCheckRxData( NetworkBufferDescriptor_t *pxNetworkBuffer, uint8_t **ppucRecvData )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &( pxTCPPacket->xTCPHeader );
+int32_t lLength, lTCPHeaderLength, lReceiveLength, lUrgentLength;
+
+ /* Determine the length and the offset of the user-data sent to this
+ node.
+
+ The size of the TCP header is given in a multiple of 4-byte words (single
+ byte, needs no ntoh() translation). A shift-right 2: is the same as
+ (offset >> 4) * 4. */
+ lTCPHeaderLength = ( BaseType_t ) ( ( pxTCPHeader->ucTCPOffset & VALID_BITS_IN_TCP_OFFSET_BYTE ) >> 2 );
+
+ /* Let pucRecvData point to the first byte received. */
+ *ppucRecvData = pxNetworkBuffer->pucEthernetBuffer + ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + lTCPHeaderLength;
+
+ /* Calculate lReceiveLength - the length of the TCP data received. This is
+ equal to the total packet length minus:
+ ( LinkLayer length (14) + IP header length (20) + size of TCP header(20 +) ).*/
+ lReceiveLength = ( ( int32_t ) pxNetworkBuffer->xDataLength ) - ( int32_t ) ipSIZE_OF_ETH_HEADER;
+ lLength = ( int32_t )FreeRTOS_htons( pxTCPPacket->xIPHeader.usLength );
+
+ if( lReceiveLength > lLength )
+ {
+ /* More bytes were received than the reported length, often because of
+ padding bytes at the end. */
+ lReceiveLength = lLength;
+ }
+
+ /* Subtract the size of the TCP and IP headers and the actual data size is
+ known. */
+ if( lReceiveLength > ( lTCPHeaderLength + ( int32_t ) ipSIZE_OF_IPv4_HEADER ) )
+ {
+ lReceiveLength -= ( lTCPHeaderLength + ( int32_t ) ipSIZE_OF_IPv4_HEADER );
+ }
+ else
+ {
+ lReceiveLength = 0;
+ }
+
+ /* Urgent Pointer:
+ This field communicates the current value of the urgent pointer as a
+ positive offset from the sequence number in this segment. The urgent
+ pointer points to the sequence number of the octet following the urgent
+ data. This field is only be interpreted in segments with the URG control
+ bit set. */
+ if( ( pxTCPHeader->ucTCPFlags & ipTCP_FLAG_URG ) != 0u )
+ {
+ /* Although we ignore the urgent data, we have to skip it. */
+ lUrgentLength = ( int32_t ) FreeRTOS_htons( pxTCPHeader->usUrgent );
+ *ppucRecvData += lUrgentLength;
+ lReceiveLength -= FreeRTOS_min_int32( lReceiveLength, lUrgentLength );
+ }
+
+ return ( BaseType_t ) lReceiveLength;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvStoreRxData(): called from prvTCPHandleState()
+ *
+ * The second thing is to do is check if the payload data may be accepted
+ * If so, they will be added to the reception queue.
+ */
+static BaseType_t prvStoreRxData( FreeRTOS_Socket_t *pxSocket, uint8_t *pucRecvData,
+ NetworkBufferDescriptor_t *pxNetworkBuffer, uint32_t ulReceiveLength )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+uint32_t ulSequenceNumber, ulSpace;
+int32_t lOffset, lStored;
+BaseType_t xResult = 0;
+
+ ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );
+
+ if( ( ulReceiveLength > 0u ) && ( pxSocket->u.xTCP.ucTCPState >= eSYN_RECEIVED ) )
+ {
+ /* See if way may accept the data contents and forward it to the socket
+ owner.
+
+ If it can't be "accept"ed it may have to be stored and send a selective
+ ack (SACK) option to confirm it. In that case, xTCPWindowRxStore() will be
+ called later to store an out-of-order packet (in case lOffset is
+ negative). */
+ if ( pxSocket->u.xTCP.rxStream )
+ {
+ ulSpace = ( uint32_t )uxStreamBufferGetSpace ( pxSocket->u.xTCP.rxStream );
+ }
+ else
+ {
+ ulSpace = ( uint32_t )pxSocket->u.xTCP.uxRxStreamSize;
+ }
+
+ lOffset = lTCPWindowRxCheck( pxTCPWindow, ulSequenceNumber, ulReceiveLength, ulSpace );
+
+ if( lOffset >= 0 )
+ {
+ /* New data has arrived and may be made available to the user. See
+ if the head marker in rxStream may be advanced, only if lOffset == 0.
+ In case the low-water mark is reached, bLowWater will be set
+ "low-water" here stands for "little space". */
+ lStored = lTCPAddRxdata( pxSocket, ( uint32_t ) lOffset, pucRecvData, ulReceiveLength );
+
+ if( lStored != ( int32_t ) ulReceiveLength )
+ {
+ FreeRTOS_debug_printf( ( "lTCPAddRxdata: stored %ld / %lu bytes??\n", lStored, ulReceiveLength ) );
+
+ /* Received data could not be stored. The socket's flag
+ bMallocError has been set. The socket now has the status
+ eCLOSE_WAIT and a RST packet will be sent back. */
+ prvTCPSendReset( pxNetworkBuffer );
+ xResult = -1;
+ }
+ }
+
+ /* After a missing packet has come in, higher packets may be passed to
+ the user. */
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ /* Now lTCPAddRxdata() will move the rxHead pointer forward
+ so data becomes available to the user immediately
+ In case the low-water mark is reached, bLowWater will be set. */
+ if( ( xResult == 0 ) && ( pxTCPWindow->ulUserDataLength > 0 ) )
+ {
+ lTCPAddRxdata( pxSocket, 0ul, NULL, pxTCPWindow->ulUserDataLength );
+ pxTCPWindow->ulUserDataLength = 0;
+ }
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+ }
+ else
+ {
+ pxTCPWindow->ucOptionLength = 0u;
+ }
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+/* Set the TCP options (if any) for the outgoing packet. */
+static UBaseType_t prvSetOptions( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+UBaseType_t uxOptionsLength = pxTCPWindow->ucOptionLength;
+
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ if( uxOptionsLength != 0u )
+ {
+ /* TCP options must be sent because a packet which is out-of-order
+ was received. */
+ if( xTCPWindowLoggingLevel >= 0 )
+ FreeRTOS_debug_printf( ( "SACK[%d,%d]: optlen %lu sending %lu - %lu\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usRemotePort,
+ uxOptionsLength,
+ FreeRTOS_ntohl( pxTCPWindow->ulOptionsData[ 1 ] ) - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber,
+ FreeRTOS_ntohl( pxTCPWindow->ulOptionsData[ 2 ] ) - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber ) );
+ memcpy( pxTCPHeader->ucOptdata, pxTCPWindow->ulOptionsData, ( size_t ) uxOptionsLength );
+
+ /* The header length divided by 4, goes into the higher nibble,
+ effectively a shift-left 2. */
+ pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+ }
+ else
+ #endif /* ipconfigUSE_TCP_WIN */
+ if( ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) && ( pxSocket->u.xTCP.bits.bMssChange != pdFALSE_UNSIGNED ) )
+ {
+ /* TCP options must be sent because the MSS has changed. */
+ pxSocket->u.xTCP.bits.bMssChange = pdFALSE_UNSIGNED;
+ if( xTCPWindowLoggingLevel >= 0 )
+ {
+ FreeRTOS_debug_printf( ( "MSS: sending %d\n", pxSocket->u.xTCP.usCurMSS ) );
+ }
+
+ pxTCPHeader->ucOptdata[ 0 ] = TCP_OPT_MSS;
+ pxTCPHeader->ucOptdata[ 1 ] = TCP_OPT_MSS_LEN;
+ pxTCPHeader->ucOptdata[ 2 ] = ( uint8_t ) ( ( pxSocket->u.xTCP.usCurMSS ) >> 8 );
+ pxTCPHeader->ucOptdata[ 3 ] = ( uint8_t ) ( ( pxSocket->u.xTCP.usCurMSS ) & 0xffu );
+ uxOptionsLength = 4u;
+ pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+ }
+
+ return uxOptionsLength;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvHandleSynReceived(): called from prvTCPHandleState()
+ *
+ * Called from the states: eSYN_RECEIVED and eCONNECT_SYN
+ * If the flags received are correct, the socket will move to eESTABLISHED.
+ */
+static BaseType_t prvHandleSynReceived( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
+ uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
+uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber );
+BaseType_t xSendLength = 0;
+
+ /* Either expect a ACK or a SYN+ACK. */
+ uint16_t usExpect = ( uint16_t ) ipTCP_FLAG_ACK;
+ if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
+ {
+ usExpect |= ( uint16_t ) ipTCP_FLAG_SYN;
+ }
+
+ if( ( ucTCPFlags & 0x17u ) != usExpect )
+ {
+ /* eSYN_RECEIVED: flags 0010 expected, not 0002. */
+ /* eSYN_RECEIVED: flags ACK expected, not SYN. */
+ FreeRTOS_debug_printf( ( "%s: flags %04X expected, not %04X\n",
+ pxSocket->u.xTCP.ucTCPState == eSYN_RECEIVED ? "eSYN_RECEIVED" : "eCONNECT_SYN",
+ usExpect, ucTCPFlags ) );
+ vTCPStateChange( pxSocket, eCLOSE_WAIT );
+ pxTCPHeader->ucTCPFlags |= ipTCP_FLAG_RST;
+ xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
+ pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+ }
+ else
+ {
+ pxTCPWindow->usPeerPortNumber = pxSocket->u.xTCP.usRemotePort;
+ pxTCPWindow->usOurPortNumber = pxSocket->usLocalPort;
+
+ if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
+ {
+ TCPPacket_t *pxLastTCPPacket = ( TCPPacket_t * ) ( pxSocket->u.xTCP.xPacket.u.ucLastPacket );
+
+ /* Clear the SYN flag in lastPacket. */
+ pxLastTCPPacket->xTCPHeader.ucTCPFlags = ipTCP_FLAG_ACK;
+
+ /* This socket was the one connecting actively so now perofmr the
+ synchronisation. */
+ vTCPWindowInit( &pxSocket->u.xTCP.xTCPWindow,
+ ulSequenceNumber, pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber, ( uint32_t ) pxSocket->u.xTCP.usCurMSS );
+ pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1u;
+ pxTCPWindow->tx.ulCurrentSequenceNumber++; /* because we send a TCP_SYN [ | TCP_ACK ]; */
+ pxTCPWindow->ulNextTxSequenceNumber++;
+ }
+ else if( ulReceiveLength == 0u )
+ {
+ pxTCPWindow->rx.ulCurrentSequenceNumber = ulSequenceNumber;
+ }
+
+ /* The SYN+ACK has been confirmed, increase the next sequence number by
+ 1. */
+ pxTCPWindow->ulOurSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1u;
+
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ FreeRTOS_debug_printf( ( "TCP: %s %d => %lxip:%d set ESTAB (scaling %u)\n",
+ pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ? "active" : "passive",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.ulRemoteIP,
+ pxSocket->u.xTCP.usRemotePort,
+ ( unsigned ) pxSocket->u.xTCP.bits.bWinScaling ) );
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+
+ if( ( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN ) || ( ulReceiveLength != 0u ) )
+ {
+ pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
+ xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
+ pxTCPHeader->ucTCPOffset = ( uint8_t ) ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+ }
+ #if( ipconfigUSE_TCP_WIN != 0 )
+ {
+ if( pxSocket->u.xTCP.bits.bWinScaling == pdFALSE_UNSIGNED )
+ {
+ /* The other party did not send a scaling factor.
+ A shifting factor in this side must be canceled. */
+ pxSocket->u.xTCP.ucMyWinScaleFactor = 0;
+ pxSocket->u.xTCP.ucPeerWinScaleFactor = 0;
+ }
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+ /* This was the third step of connecting: SYN, SYN+ACK, ACK so now the
+ connection is established. */
+ vTCPStateChange( pxSocket, eESTABLISHED );
+ }
+
+ return xSendLength;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvHandleEstablished(): called from prvTCPHandleState()
+ *
+ * Called if the status is eESTABLISHED. Data reception has been handled
+ * earlier. Here the ACK's from peer will be checked, and if a FIN is received,
+ * the code will check if it may be accepted, i.e. if all expected data has been
+ * completely received.
+ */
+static BaseType_t prvHandleEstablished( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
+ uint32_t ulReceiveLength, UBaseType_t uxOptionsLength )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
+uint32_t ulSequenceNumber = FreeRTOS_ntohl( pxTCPHeader->ulSequenceNumber ), ulCount;
+BaseType_t xSendLength = 0, xMayClose = pdFALSE, bRxComplete, bTxDone;
+int32_t lDistance, lSendResult;
+
+ /* Remember the window size the peer is advertising. */
+ pxSocket->u.xTCP.ulWindowSize = FreeRTOS_ntohs( pxTCPHeader->usWindow );
+ #if( ipconfigUSE_TCP_WIN != 0 )
+ {
+ pxSocket->u.xTCP.ulWindowSize =
+ ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor );
+ }
+ #endif
+
+ if( ( ucTCPFlags & ( uint8_t ) ipTCP_FLAG_ACK ) != 0u )
+ {
+ ulCount = ulTCPWindowTxAck( pxTCPWindow, FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr ) );
+
+ /* ulTCPWindowTxAck() returns the number of bytes which have been acked,
+ starting at 'tx.ulCurrentSequenceNumber'. Advance the tail pointer in
+ txStream. */
+ if( ( pxSocket->u.xTCP.txStream != NULL ) && ( ulCount > 0u ) )
+ {
+ /* Just advancing the tail index, 'ulCount' bytes have been
+ confirmed, and because there is new space in the txStream, the
+ user/owner should be woken up. */
+ /* _HT_ : only in case the socket's waiting? */
+ if( uxStreamBufferGet( pxSocket->u.xTCP.txStream, 0u, NULL, ( size_t ) ulCount, pdFALSE ) != 0u )
+ {
+ pxSocket->xEventBits |= eSOCKET_SEND;
+
+ #if ipconfigSUPPORT_SELECT_FUNCTION == 1
+ {
+ if( ( pxSocket->xSelectBits & eSELECT_WRITE ) != 0 )
+ {
+ pxSocket->xEventBits |= ( eSELECT_WRITE << SOCKET_EVENT_BIT_COUNT );
+ }
+ }
+ #endif
+ /* In case the socket owner has installed an OnSent handler,
+ call it now. */
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xTCP.pxHandleSent ) )
+ {
+ pxSocket->u.xTCP.pxHandleSent( ( Socket_t )pxSocket, ulCount );
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS == 1 */
+ }
+ }
+ }
+
+ /* If this socket has a stream for transmission, add the data to the
+ outgoing segment(s). */
+ if( pxSocket->u.xTCP.txStream != NULL )
+ {
+ prvTCPAddTxData( pxSocket );
+ }
+
+ pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber = pxTCPWindow->tx.ulCurrentSequenceNumber;
+
+ if( ( pxSocket->u.xTCP.bits.bFinAccepted != pdFALSE_UNSIGNED ) || ( ( ucTCPFlags & ( uint8_t ) ipTCP_FLAG_FIN ) != 0u ) )
+ {
+ /* Peer is requesting to stop, see if we're really finished. */
+ xMayClose = pdTRUE;
+
+ /* Checks are only necessary if we haven't sent a FIN yet. */
+ if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
+ {
+ /* xTCPWindowTxDone returns true when all Tx queues are empty. */
+ bRxComplete = xTCPWindowRxEmpty( pxTCPWindow );
+ bTxDone = xTCPWindowTxDone( pxTCPWindow );
+
+ if( ( bRxComplete == 0 ) || ( bTxDone == 0 ) )
+ {
+ /* Refusing FIN: Rx incomp 1 optlen 4 tx done 1. */
+ FreeRTOS_debug_printf( ( "Refusing FIN[%u,%u]: RxCompl %lu tx done %ld\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usRemotePort,
+ bRxComplete, bTxDone ) );
+ xMayClose = pdFALSE;
+ }
+ else
+ {
+ lDistance = ( int32_t ) ( ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulCurrentSequenceNumber );
+
+ if( lDistance > 1 )
+ {
+ FreeRTOS_debug_printf( ( "Refusing FIN: Rx not complete %ld (cur %lu high %lu)\n",
+ lDistance, pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
+ pxTCPWindow->rx.ulHighestSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber ) );
+
+ xMayClose = pdFALSE;
+ }
+ }
+ }
+
+ if( xTCPWindowLoggingLevel > 0 )
+ {
+ FreeRTOS_debug_printf( ( "TCP: FIN received, mayClose = %ld (Rx %lu Len %ld, Tx %lu)\n",
+ xMayClose, ulSequenceNumber - pxSocket->u.xTCP.xTCPWindow.rx.ulFirstSequenceNumber, ulReceiveLength,
+ pxTCPWindow->tx.ulCurrentSequenceNumber - pxSocket->u.xTCP.xTCPWindow.tx.ulFirstSequenceNumber ) );
+ }
+
+ if( xMayClose != pdFALSE )
+ {
+ pxSocket->u.xTCP.bits.bFinAccepted = pdTRUE_UNSIGNED;
+ xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer );
+ }
+ }
+
+ if( xMayClose == pdFALSE )
+ {
+ pxTCPHeader->ucTCPFlags = ipTCP_FLAG_ACK;
+
+ if( ulReceiveLength != 0u )
+ {
+ xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
+ /* TCP-offsett equals '( ( length / 4 ) << 4 )', resulting in a shift-left 2 */
+ pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+
+ if( pxSocket->u.xTCP.bits.bFinSent != pdFALSE_UNSIGNED )
+ {
+ pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->tx.ulFINSequenceNumber;
+ }
+ }
+
+ /* Now get data to be transmitted. */
+ /* _HT_ patch: since the MTU has be fixed at 1500 in stead of 1526, TCP
+ can not send-out both TCP options and also a full packet. Sending
+ options (SACK) is always more urgent than sending data, which can be
+ sent later. */
+ if( uxOptionsLength == 0u )
+ {
+ /* prvTCPPrepareSend might allocate a bigger network buffer, if
+ necessary. */
+ lSendResult = prvTCPPrepareSend( pxSocket, ppxNetworkBuffer, uxOptionsLength );
+ if( lSendResult > 0 )
+ {
+ xSendLength = ( BaseType_t ) lSendResult;
+ }
+ }
+ }
+
+ return xSendLength;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Called from prvTCPHandleState(). There is data to be sent. If
+ * ipconfigUSE_TCP_WIN is defined, and if only an ACK must be sent, it will be
+ * checked if it would better be postponed for efficiency.
+ */
+static BaseType_t prvSendData( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer,
+ uint32_t ulReceiveLength, BaseType_t xSendLength )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &pxTCPPacket->xTCPHeader;
+TCPWindow_t *pxTCPWindow = &pxSocket->u.xTCP.xTCPWindow;
+/* Find out what window size we may advertised. */
+int32_t lRxSpace;
+#if( ipconfigUSE_TCP_WIN == 1 )
+ #if( ipconfigTCP_ACK_EARLIER_PACKET == 0 )
+ const int32_t lMinLength = 0;
+ #else
+ int32_t lMinLength;
+ #endif
+#endif
+
+ /* Set the time-out field, so that we'll be called by the IP-task in case no
+ next message will be received. */
+ lRxSpace = (int32_t)( pxSocket->u.xTCP.ulHighestRxAllowed - pxTCPWindow->rx.ulCurrentSequenceNumber );
+ #if ipconfigUSE_TCP_WIN == 1
+ {
+
+ #if( ipconfigTCP_ACK_EARLIER_PACKET != 0 )
+ {
+ lMinLength = ( ( int32_t ) 2 ) * ( ( int32_t ) pxSocket->u.xTCP.usCurMSS );
+ }
+ #endif /* ipconfigTCP_ACK_EARLIER_PACKET */
+
+ /* In case we're receiving data continuously, we might postpone sending
+ an ACK to gain performance. */
+ if( ( ulReceiveLength > 0 ) && /* Data was sent to this socket. */
+ ( lRxSpace >= lMinLength ) && /* There is Rx space for more data. */
+ ( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED ) && /* Not in a closure phase. */
+ ( xSendLength == ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) ) && /* No Tx data or options to be sent. */
+ ( pxSocket->u.xTCP.ucTCPState == eESTABLISHED ) && /* Connection established. */
+ ( pxTCPHeader->ucTCPFlags == ipTCP_FLAG_ACK ) ) /* There are no other flags than an ACK. */
+ {
+ if( pxSocket->u.xTCP.pxAckMessage != *ppxNetworkBuffer )
+ {
+ /* There was still a delayed in queue, delete it. */
+ if( pxSocket->u.xTCP.pxAckMessage != 0 )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
+ }
+
+ pxSocket->u.xTCP.pxAckMessage = *ppxNetworkBuffer;
+ }
+ if( ( ulReceiveLength < ( uint32_t ) pxSocket->u.xTCP.usCurMSS ) || /* Received a small message. */
+ ( lRxSpace < ( int32_t ) ( 2U * pxSocket->u.xTCP.usCurMSS ) ) ) /* There are less than 2 x MSS space in the Rx buffer. */
+ {
+ pxSocket->u.xTCP.usTimeout = ( uint16_t ) pdMS_TO_MIN_TICKS( DELAYED_ACK_SHORT_DELAY_MS );
+ }
+ else
+ {
+ /* Normally a delayed ACK should wait 200 ms for a next incoming
+ packet. Only wait 20 ms here to gain performance. A slow ACK
+ for full-size message. */
+ pxSocket->u.xTCP.usTimeout = ( uint16_t ) pdMS_TO_MIN_TICKS( DELAYED_ACK_LONGER_DELAY_MS );
+ }
+
+ if( ( xTCPWindowLoggingLevel > 1 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "Send[%u->%u] del ACK %lu SEQ %lu (len %lu) tmout %u d %lu\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usRemotePort,
+ pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
+ pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
+ xSendLength,
+ pxSocket->u.xTCP.usTimeout, lRxSpace ) );
+ }
+
+ *ppxNetworkBuffer = NULL;
+ xSendLength = 0;
+ }
+ else if( pxSocket->u.xTCP.pxAckMessage != NULL )
+ {
+ /* As an ACK is not being delayed, remove any earlier delayed ACK
+ message. */
+ if( pxSocket->u.xTCP.pxAckMessage != *ppxNetworkBuffer )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxSocket->u.xTCP.pxAckMessage );
+ }
+
+ pxSocket->u.xTCP.pxAckMessage = NULL;
+ }
+ }
+ #else
+ {
+ /* Remove compiler warnings. */
+ ( void ) ulReceiveLength;
+ ( void ) pxTCPHeader;
+ ( void ) lRxSpace;
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+
+ if( xSendLength != 0 )
+ {
+ if( ( xTCPWindowLoggingLevel > 1 ) && ( ipconfigTCP_MAY_LOG_PORT( pxSocket->usLocalPort ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "Send[%u->%u] imm ACK %lu SEQ %lu (len %lu)\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usRemotePort,
+ pxTCPWindow->rx.ulCurrentSequenceNumber - pxTCPWindow->rx.ulFirstSequenceNumber,
+ pxTCPWindow->ulOurSequenceNumber - pxTCPWindow->tx.ulFirstSequenceNumber,
+ xSendLength ) );
+ }
+
+ /* Set the parameter 'xReleaseAfterSend' to the value of
+ ipconfigZERO_COPY_TX_DRIVER. */
+ prvTCPReturnPacket( pxSocket, *ppxNetworkBuffer, ( uint32_t ) xSendLength, ipconfigZERO_COPY_TX_DRIVER );
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* The driver has taken ownership of the Network Buffer. */
+ *ppxNetworkBuffer = NULL;
+ }
+ #endif
+ }
+
+ return xSendLength;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * prvTCPHandleState()
+ * is the most important function of this TCP stack
+ * We've tried to keep it (relatively short) by putting a lot of code in
+ * the static functions above:
+ *
+ * prvCheckRxData()
+ * prvStoreRxData()
+ * prvSetOptions()
+ * prvHandleSynReceived()
+ * prvHandleEstablished()
+ * prvSendData()
+ *
+ * As these functions are declared static, and they're called from one location
+ * only, most compilers will inline them, thus avoiding a call and return.
+ */
+static BaseType_t prvTCPHandleState( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t **ppxNetworkBuffer )
+{
+TCPPacket_t *pxTCPPacket = ( TCPPacket_t * ) ( (*ppxNetworkBuffer)->pucEthernetBuffer );
+TCPHeader_t *pxTCPHeader = &( pxTCPPacket->xTCPHeader );
+BaseType_t xSendLength = 0;
+uint32_t ulReceiveLength; /* Number of bytes contained in the TCP message. */
+uint8_t *pucRecvData;
+uint32_t ulSequenceNumber = FreeRTOS_ntohl (pxTCPHeader->ulSequenceNumber);
+
+ /* uxOptionsLength: the size of the options to be sent (always a multiple of
+ 4 bytes)
+ 1. in the SYN phase, we shall communicate the MSS
+ 2. in case of a SACK, Selective ACK, ack a segment which comes in
+ out-of-order. */
+UBaseType_t uxOptionsLength = 0u;
+uint8_t ucTCPFlags = pxTCPHeader->ucTCPFlags;
+TCPWindow_t *pxTCPWindow = &( pxSocket->u.xTCP.xTCPWindow );
+
+ /* First get the length and the position of the received data, if any.
+ pucRecvData will point to the first byte of the TCP payload. */
+ ulReceiveLength = ( uint32_t ) prvCheckRxData( *ppxNetworkBuffer, &pucRecvData );
+
+ if( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED )
+ {
+ if ( pxTCPWindow->rx.ulCurrentSequenceNumber == ulSequenceNumber + 1u )
+ {
+ /* This is most probably a keep-alive message from peer. Setting
+ 'bWinChange' doesn't cause a window-size-change, the flag is used
+ here to force sending an immediate ACK. */
+ pxSocket->u.xTCP.bits.bWinChange = pdTRUE_UNSIGNED;
+ }
+ }
+
+ /* Keep track of the highest sequence number that might be expected within
+ this connection. */
+ if( ( ( int32_t ) ( ulSequenceNumber + ulReceiveLength - pxTCPWindow->rx.ulHighestSequenceNumber ) ) > 0 )
+ {
+ pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + ulReceiveLength;
+ }
+
+ /* Storing data may result in a fatal error if malloc() fails. */
+ if( prvStoreRxData( pxSocket, pucRecvData, *ppxNetworkBuffer, ulReceiveLength ) < 0 )
+ {
+ xSendLength = -1;
+ }
+ else
+ {
+ uxOptionsLength = prvSetOptions( pxSocket, *ppxNetworkBuffer );
+
+ if( ( pxSocket->u.xTCP.ucTCPState == eSYN_RECEIVED ) && ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) )
+ {
+ FreeRTOS_debug_printf( ( "eSYN_RECEIVED: ACK expected, not SYN: peer missed our SYN+ACK\n" ) );
+
+ /* In eSYN_RECEIVED a simple ACK is expected, but apparently the
+ 'SYN+ACK' didn't arrive. Step back to the previous state in which
+ a first incoming SYN is handled. The SYN was counted already so
+ decrease it first. */
+ vTCPStateChange( pxSocket, eSYN_FIRST );
+ }
+
+ if( ( ( ucTCPFlags & ipTCP_FLAG_FIN ) != 0u ) && ( pxSocket->u.xTCP.bits.bFinRecv == pdFALSE_UNSIGNED ) )
+ {
+ /* It's the first time a FIN has been received, remember its
+ sequence number. */
+ pxTCPWindow->rx.ulFINSequenceNumber = ulSequenceNumber + ulReceiveLength;
+ pxSocket->u.xTCP.bits.bFinRecv = pdTRUE_UNSIGNED;
+
+ /* Was peer the first one to send a FIN? */
+ if( pxSocket->u.xTCP.bits.bFinSent == pdFALSE_UNSIGNED )
+ {
+ /* If so, don't send the-last-ACK. */
+ pxSocket->u.xTCP.bits.bFinLast = pdTRUE_UNSIGNED;
+ }
+ }
+
+ switch (pxSocket->u.xTCP.ucTCPState)
+ {
+ case eCLOSED: /* (server + client) no connection state at all. */
+ /* Nothing to do for a closed socket, except waiting for the
+ owner. */
+ break;
+
+ case eTCP_LISTEN: /* (server) waiting for a connection request from
+ any remote TCP and port. */
+ /* The listen state was handled in xProcessReceivedTCPPacket().
+ Should not come here. */
+ break;
+
+ case eSYN_FIRST: /* (server) Just received a SYN request for a server
+ socket. */
+ {
+ /* A new socket has been created, reply with a SYN+ACK.
+ Acknowledge with seq+1 because the SYN is seen as pseudo data
+ with len = 1. */
+ uxOptionsLength = prvSetSynAckOptions( pxSocket, pxTCPPacket );
+ pxTCPHeader->ucTCPFlags = ipTCP_FLAG_SYN | ipTCP_FLAG_ACK;
+
+ xSendLength = ( BaseType_t ) ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + uxOptionsLength );
+
+ /* Set the TCP offset field: ipSIZE_OF_TCP_HEADER equals 20 and
+ uxOptionsLength is a multiple of 4. The complete expression is:
+ ucTCPOffset = ( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) / 4 ) << 4 */
+ pxTCPHeader->ucTCPOffset = ( uint8_t )( ( ipSIZE_OF_TCP_HEADER + uxOptionsLength ) << 2 );
+ vTCPStateChange( pxSocket, eSYN_RECEIVED );
+
+ pxTCPWindow->rx.ulCurrentSequenceNumber = pxTCPWindow->rx.ulHighestSequenceNumber = ulSequenceNumber + 1u;
+ pxTCPWindow->tx.ulCurrentSequenceNumber = pxTCPWindow->ulNextTxSequenceNumber = pxTCPWindow->tx.ulFirstSequenceNumber + 1u; /* because we send a TCP_SYN. */
+ }
+ break;
+
+ case eCONNECT_SYN: /* (client) also called SYN_SENT: we've just send a
+ SYN, expect a SYN+ACK and send a ACK now. */
+ /* Fall through */
+ case eSYN_RECEIVED: /* (server) we've had a SYN, replied with SYN+SCK
+ expect a ACK and do nothing. */
+ xSendLength = prvHandleSynReceived( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength );
+ break;
+
+ case eESTABLISHED: /* (server + client) an open connection, data
+ received can be delivered to the user. The normal
+ state for the data transfer phase of the connection
+ The closing states are also handled here with the
+ use of some flags. */
+ xSendLength = prvHandleEstablished( pxSocket, ppxNetworkBuffer, ulReceiveLength, uxOptionsLength );
+ break;
+
+ case eLAST_ACK: /* (server + client) waiting for an acknowledgement
+ of the connection termination request previously
+ sent to the remote TCP (which includes an
+ acknowledgement of its connection termination
+ request). */
+ /* Fall through */
+ case eFIN_WAIT_1: /* (server + client) waiting for a connection termination request from the remote TCP,
+ * or an acknowledgement of the connection termination request previously sent. */
+ /* Fall through */
+ case eFIN_WAIT_2: /* (server + client) waiting for a connection termination request from the remote TCP. */
+ xSendLength = prvTCPHandleFin( pxSocket, *ppxNetworkBuffer );
+ break;
+
+ case eCLOSE_WAIT: /* (server + client) waiting for a connection
+ termination request from the local user. Nothing to
+ do, connection is closed, wait for owner to close
+ this socket. */
+ break;
+
+ case eCLOSING: /* (server + client) waiting for a connection
+ termination request acknowledgement from the remote
+ TCP. */
+ break;
+
+ case eTIME_WAIT: /* (either server or client) waiting for enough time
+ to pass to be sure the remote TCP received the
+ acknowledgement of its connection termination
+ request. [According to RFC 793 a connection can stay
+ in TIME-WAIT for a maximum of four minutes known as
+ a MSL (maximum segment lifetime).] These states are
+ implemented implicitly by settings flags like
+ 'bFinSent', 'bFinRecv', and 'bFinAcked'. */
+ break;
+ default:
+ break;
+ }
+ }
+
+ if( xSendLength > 0 )
+ {
+ xSendLength = prvSendData( pxSocket, ppxNetworkBuffer, ulReceiveLength, xSendLength );
+ }
+
+ return xSendLength;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvTCPSendSpecialPacketHelper( NetworkBufferDescriptor_t *pxNetworkBuffer,
+ uint8_t ucTCPFlags )
+{
+#if( ipconfigIGNORE_UNKNOWN_PACKETS == 0 )
+ {
+ TCPPacket_t *pxTCPPacket = ( TCPPacket_t * )( pxNetworkBuffer->pucEthernetBuffer );
+ const BaseType_t xSendLength = ( BaseType_t )
+ ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER + 0u ); /* Plus 0 options. */
+
+ pxTCPPacket->xTCPHeader.ucTCPFlags = ucTCPFlags;
+ pxTCPPacket->xTCPHeader.ucTCPOffset = ( ipSIZE_OF_TCP_HEADER + 0u ) << 2;
+
+ prvTCPReturnPacket( NULL, pxNetworkBuffer, ( uint32_t )xSendLength, pdFALSE );
+ }
+#endif /* !ipconfigIGNORE_UNKNOWN_PACKETS */
+
+ /* Remove compiler warnings if ipconfigIGNORE_UNKNOWN_PACKETS == 1. */
+ ( void )pxNetworkBuffer;
+ ( void )ucTCPFlags;
+
+ /* The packet was not consumed. */
+ return pdFAIL;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvTCPSendChallengeAck( NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+ return prvTCPSendSpecialPacketHelper( pxNetworkBuffer, ipTCP_FLAG_ACK );
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvTCPSendReset( NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+ return prvTCPSendSpecialPacketHelper( pxNetworkBuffer,
+ ipTCP_FLAG_ACK | ipTCP_FLAG_RST );
+}
+/*-----------------------------------------------------------*/
+
+static void prvSocketSetMSS( FreeRTOS_Socket_t *pxSocket )
+{
+uint32_t ulMSS = ipconfigTCP_MSS;
+
+ if( ( ( FreeRTOS_ntohl( pxSocket->u.xTCP.ulRemoteIP ) ^ *ipLOCAL_IP_ADDRESS_POINTER ) & xNetworkAddressing.ulNetMask ) != 0ul )
+ {
+ /* Data for this peer will pass through a router, and maybe through
+ the internet. Limit the MSS to 1400 bytes or less. */
+ ulMSS = FreeRTOS_min_uint32( ( uint32_t ) REDUCED_MSS_THROUGH_INTERNET, ulMSS );
+ }
+
+ FreeRTOS_debug_printf( ( "prvSocketSetMSS: %lu bytes for %lxip:%u\n", ulMSS, pxSocket->u.xTCP.ulRemoteIP, pxSocket->u.xTCP.usRemotePort ) );
+
+ pxSocket->u.xTCP.usInitMSS = pxSocket->u.xTCP.usCurMSS = ( uint16_t ) ulMSS;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * FreeRTOS_TCP_IP has only 2 public functions, this is the second one:
+ * xProcessReceivedTCPPacket()
+ * prvTCPHandleState()
+ * prvTCPPrepareSend()
+ * prvTCPReturnPacket()
+ * xNetworkInterfaceOutput() // Sends data to the NIC
+ * prvTCPSendRepeated()
+ * prvTCPReturnPacket() // Prepare for returning
+ * xNetworkInterfaceOutput() // Sends data to the NIC
+*/
+BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+FreeRTOS_Socket_t *pxSocket;
+TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+uint16_t ucTCPFlags;
+uint32_t ulLocalIP;
+uint16_t xLocalPort;
+uint32_t ulRemoteIP;
+uint16_t xRemotePort;
+uint32_t ulSequenceNumber;
+uint32_t ulAckNumber;
+BaseType_t xResult = pdPASS;
+configASSERT(pxNetworkBuffer);
+configASSERT(pxNetworkBuffer->pucEthernetBuffer);
+
+ /* Check for a minimum packet size. */
+ if( pxNetworkBuffer->xDataLength >= ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_TCP_HEADER ) )
+ {
+ ucTCPFlags = pxTCPPacket->xTCPHeader.ucTCPFlags;
+ ulLocalIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulDestinationIPAddress );
+ xLocalPort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usDestinationPort );
+ ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
+ xRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
+ ulSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
+ ulAckNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulAckNr );
+
+ /* Find the destination socket, and if not found: return a socket listing to
+ the destination PORT. */
+ pxSocket = ( FreeRTOS_Socket_t * )pxTCPSocketLookup( ulLocalIP, xLocalPort, ulRemoteIP, xRemotePort );
+ }
+ else
+ {
+ return pdFAIL;
+ }
+
+ if( ( pxSocket == NULL ) || ( prvTCPSocketIsActive( ( UBaseType_t ) pxSocket->u.xTCP.ucTCPState ) == pdFALSE ) )
+ {
+ /* A TCP messages is received but either there is no socket with the
+ given port number or the there is a socket, but it is in one of these
+ non-active states: eCLOSED, eCLOSE_WAIT, eFIN_WAIT_2, eCLOSING, or
+ eTIME_WAIT. */
+
+ FreeRTOS_debug_printf( ( "TCP: No active socket on port %d (%lxip:%d)\n", xLocalPort, ulRemoteIP, xRemotePort ) );
+
+ /* Send a RST to all packets that can not be handled. As a result
+ the other party will get a ECONN error. There are two exceptions:
+ 1) A packet that already has the RST flag set.
+ 2) A packet that only has the ACK flag set.
+ A packet with only the ACK flag set might be the last ACK in
+ a three-way hand-shake that closes a connection. */
+ if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) != ipTCP_FLAG_ACK ) &&
+ ( ( ucTCPFlags & ipTCP_FLAG_RST ) == 0u ) )
+ {
+ prvTCPSendReset( pxNetworkBuffer );
+ }
+
+ /* The packet can't be handled. */
+ xResult = pdFAIL;
+ }
+ else
+ {
+ pxSocket->u.xTCP.ucRepCount = 0u;
+
+ if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN )
+ {
+ /* The matching socket is in a listening state. Test if the peer
+ has set the SYN flag. */
+ if( ( ucTCPFlags & ipTCP_FLAG_CTRL ) != ipTCP_FLAG_SYN )
+ {
+ /* What happens: maybe after a reboot, a client doesn't know the
+ connection had gone. Send a RST in order to get a new connect
+ request. */
+ #if( ipconfigHAS_DEBUG_PRINTF == 1 )
+ {
+ FreeRTOS_debug_printf( ( "TCP: Server can't handle flags: %s from %lxip:%u to port %u\n",
+ prvTCPFlagMeaning( ( UBaseType_t ) ucTCPFlags ), ulRemoteIP, xRemotePort, xLocalPort ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF */
+
+ if( ( ucTCPFlags & ipTCP_FLAG_RST ) == 0u )
+ {
+ prvTCPSendReset( pxNetworkBuffer );
+ }
+ xResult = pdFAIL;
+ }
+ else
+ {
+ /* prvHandleListen() will either return a newly created socket
+ (if bReuseSocket is false), otherwise it returns the current
+ socket which will later get connected. */
+ pxSocket = prvHandleListen( pxSocket, pxNetworkBuffer );
+
+ if( pxSocket == NULL )
+ {
+ xResult = pdFAIL;
+ }
+ }
+ } /* if( pxSocket->u.xTCP.ucTCPState == eTCP_LISTEN ). */
+ else
+ {
+ /* This is not a socket in listening mode. Check for the RST
+ flag. */
+ if( ( ucTCPFlags & ipTCP_FLAG_RST ) != 0u )
+ {
+ FreeRTOS_debug_printf( ( "TCP: RST received from %lxip:%u for %u\n", ulRemoteIP, xRemotePort, xLocalPort ) );
+
+ /* Implement https://tools.ietf.org/html/rfc5961#section-3.2. */
+ if( pxSocket->u.xTCP.ucTCPState == eCONNECT_SYN )
+ {
+ /* Per the above RFC, "In the SYN-SENT state ... the RST is
+ acceptable if the ACK field acknowledges the SYN." */
+ if( ulAckNumber == pxSocket->u.xTCP.xTCPWindow.ulOurSequenceNumber + 1 )
+ {
+ vTCPStateChange( pxSocket, eCLOSED );
+ }
+ }
+ else
+ {
+ /* Check whether the packet matches the next expected sequence number. */
+ if( ulSequenceNumber == pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber )
+ {
+ vTCPStateChange( pxSocket, eCLOSED );
+ }
+ /* Otherwise, check whether the packet is within the receive window. */
+ else if( ulSequenceNumber > pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber &&
+ ulSequenceNumber < ( pxSocket->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber +
+ pxSocket->u.xTCP.xTCPWindow.xSize.ulRxWindowLength ) )
+ {
+ /* Send a challenge ACK. */
+ prvTCPSendChallengeAck( pxNetworkBuffer );
+ }
+ }
+
+ /* Otherwise, do nothing. In any case, the packet cannot be handled. */
+ xResult = pdFAIL;
+ }
+ else if( ( ( ucTCPFlags & ipTCP_FLAG_CTRL ) == ipTCP_FLAG_SYN ) && ( pxSocket->u.xTCP.ucTCPState >= eESTABLISHED ) )
+ {
+ /* SYN flag while this socket is already connected. */
+ FreeRTOS_debug_printf( ( "TCP: SYN unexpected from %lxip:%u\n", ulRemoteIP, xRemotePort ) );
+
+ /* The packet cannot be handled. */
+ xResult = pdFAIL;
+ }
+ else
+ {
+ /* Update the copy of the TCP header only (skipping eth and IP
+ headers). It might be used later on, whenever data must be sent
+ to the peer. */
+ const BaseType_t lOffset = ( BaseType_t ) ( ipSIZE_OF_ETH_HEADER + ipSIZE_OF_IPv4_HEADER );
+ memcpy( pxSocket->u.xTCP.xPacket.u.ucLastPacket + lOffset, pxNetworkBuffer->pucEthernetBuffer + lOffset, ipSIZE_OF_TCP_HEADER );
+ }
+ }
+ }
+
+ if( xResult != pdFAIL )
+ {
+ /* Touch the alive timers because we received a message for this
+ socket. */
+ prvTCPTouchSocket( pxSocket );
+
+ /* Parse the TCP option(s), if present. */
+ /* _HT_ : if we're in the SYN phase, and peer does not send a MSS option,
+ then we MUST assume an MSS size of 536 bytes for backward compatibility. */
+
+ /* When there are no TCP options, the TCP offset equals 20 bytes, which is stored as
+ the number 5 (words) in the higher niblle of the TCP-offset byte. */
+ if( ( pxTCPPacket->xTCPHeader.ucTCPOffset & TCP_OFFSET_LENGTH_BITS ) > TCP_OFFSET_STANDARD_LENGTH )
+ {
+ prvCheckOptions( pxSocket, pxNetworkBuffer );
+ }
+
+
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ pxSocket->u.xTCP.ulWindowSize = FreeRTOS_ntohs( pxTCPPacket->xTCPHeader.usWindow );
+ pxSocket->u.xTCP.ulWindowSize =
+ ( pxSocket->u.xTCP.ulWindowSize << pxSocket->u.xTCP.ucPeerWinScaleFactor );
+ }
+ #endif
+
+ /* In prvTCPHandleState() the incoming messages will be handled
+ depending on the current state of the connection. */
+ if( prvTCPHandleState( pxSocket, &pxNetworkBuffer ) > 0 )
+ {
+ /* prvTCPHandleState() has sent a message, see if there are more to
+ be transmitted. */
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ prvTCPSendRepeated( pxSocket, &pxNetworkBuffer );
+ }
+ #endif /* ipconfigUSE_TCP_WIN */
+ }
+
+ if( pxNetworkBuffer != NULL )
+ {
+ /* We must check if the buffer is unequal to NULL, because the
+ socket might keep a reference to it in case a delayed ACK must be
+ sent. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ pxNetworkBuffer = NULL;
+ }
+
+ /* And finally, calculate when this socket wants to be woken up. */
+ prvTCPNextTimeout ( pxSocket );
+ /* Return pdPASS to tell that the network buffer is 'consumed'. */
+ xResult = pdPASS;
+ }
+
+ /* pdPASS being returned means the buffer has been consumed. */
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+static FreeRTOS_Socket_t *prvHandleListen( FreeRTOS_Socket_t *pxSocket, NetworkBufferDescriptor_t *pxNetworkBuffer )
+{
+TCPPacket_t * pxTCPPacket = ( TCPPacket_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+FreeRTOS_Socket_t *pxReturn = NULL;
+uint32_t ulInitialSequenceNumber;
+
+ /* Assume that a new Initial Sequence Number will be required. Request
+ it now in order to fail out if necessary. */
+ ulInitialSequenceNumber = ulApplicationGetNextSequenceNumber( *ipLOCAL_IP_ADDRESS_POINTER,
+ pxSocket->usLocalPort,
+ pxTCPPacket->xIPHeader.ulSourceIPAddress,
+ pxTCPPacket->xTCPHeader.usSourcePort );
+
+ /* A pure SYN (without ACK) has come in, create a new socket to answer
+ it. */
+ if( 0 != ulInitialSequenceNumber )
+ {
+ if( pxSocket->u.xTCP.bits.bReuseSocket != pdFALSE_UNSIGNED )
+ {
+ /* The flag bReuseSocket indicates that the same instance of the
+ listening socket should be used for the connection. */
+ pxReturn = pxSocket;
+ pxSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
+ pxSocket->u.xTCP.pxPeerSocket = pxSocket;
+ }
+ else
+ {
+ /* The socket does not have the bReuseSocket flag set meaning create a
+ new socket when a connection comes in. */
+ pxReturn = NULL;
+
+ if( pxSocket->u.xTCP.usChildCount >= pxSocket->u.xTCP.usBacklog )
+ {
+ FreeRTOS_printf( ( "Check: Socket %u already has %u / %u child%s\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usChildCount,
+ pxSocket->u.xTCP.usBacklog,
+ pxSocket->u.xTCP.usChildCount == 1 ? "" : "ren" ) );
+ prvTCPSendReset( pxNetworkBuffer );
+ }
+ else
+ {
+ FreeRTOS_Socket_t *pxNewSocket = ( FreeRTOS_Socket_t * )
+ FreeRTOS_socket( FREERTOS_AF_INET, FREERTOS_SOCK_STREAM, FREERTOS_IPPROTO_TCP );
+
+ if( ( pxNewSocket == NULL ) || ( pxNewSocket == FREERTOS_INVALID_SOCKET ) )
+ {
+ FreeRTOS_debug_printf( ( "TCP: Listen: new socket failed\n" ) );
+ prvTCPSendReset( pxNetworkBuffer );
+ }
+ else if( prvTCPSocketCopy( pxNewSocket, pxSocket ) != pdFALSE )
+ {
+ /* The socket will be connected immediately, no time for the
+ owner to setsockopt's, therefore copy properties of the server
+ socket to the new socket. Only the binding might fail (due to
+ lack of resources). */
+ pxReturn = pxNewSocket;
+ }
+ }
+ }
+ }
+
+ if( ( 0 != ulInitialSequenceNumber ) && ( pxReturn != NULL ) )
+ {
+ pxReturn->u.xTCP.usRemotePort = FreeRTOS_htons( pxTCPPacket->xTCPHeader.usSourcePort );
+ pxReturn->u.xTCP.ulRemoteIP = FreeRTOS_htonl( pxTCPPacket->xIPHeader.ulSourceIPAddress );
+ pxReturn->u.xTCP.xTCPWindow.ulOurSequenceNumber = ulInitialSequenceNumber;
+
+ /* Here is the SYN action. */
+ pxReturn->u.xTCP.xTCPWindow.rx.ulCurrentSequenceNumber = FreeRTOS_ntohl( pxTCPPacket->xTCPHeader.ulSequenceNumber );
+ prvSocketSetMSS( pxReturn );
+
+ prvTCPCreateWindow( pxReturn );
+
+ vTCPStateChange( pxReturn, eSYN_FIRST );
+
+ /* Make a copy of the header up to the TCP header. It is needed later
+ on, whenever data must be sent to the peer. */
+ memcpy( pxReturn->u.xTCP.xPacket.u.ucLastPacket, pxNetworkBuffer->pucEthernetBuffer, sizeof( pxReturn->u.xTCP.xPacket.u.ucLastPacket ) );
+ }
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Duplicates a socket after a listening socket receives a connection.
+ */
+static BaseType_t prvTCPSocketCopy( FreeRTOS_Socket_t *pxNewSocket, FreeRTOS_Socket_t *pxSocket )
+{
+struct freertos_sockaddr xAddress;
+
+ pxNewSocket->xReceiveBlockTime = pxSocket->xReceiveBlockTime;
+ pxNewSocket->xSendBlockTime = pxSocket->xSendBlockTime;
+ pxNewSocket->ucSocketOptions = pxSocket->ucSocketOptions;
+ pxNewSocket->u.xTCP.uxRxStreamSize = pxSocket->u.xTCP.uxRxStreamSize;
+ pxNewSocket->u.xTCP.uxTxStreamSize = pxSocket->u.xTCP.uxTxStreamSize;
+ pxNewSocket->u.xTCP.uxLittleSpace = pxSocket->u.xTCP.uxLittleSpace;
+ pxNewSocket->u.xTCP.uxEnoughSpace = pxSocket->u.xTCP.uxEnoughSpace;
+ pxNewSocket->u.xTCP.uxRxWinSize = pxSocket->u.xTCP.uxRxWinSize;
+ pxNewSocket->u.xTCP.uxTxWinSize = pxSocket->u.xTCP.uxTxWinSize;
+
+ #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
+ {
+ pxNewSocket->pxUserSemaphore = pxSocket->pxUserSemaphore;
+ }
+ #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
+
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ /* In case call-backs are used, copy them from parent to child. */
+ pxNewSocket->u.xTCP.pxHandleConnected = pxSocket->u.xTCP.pxHandleConnected;
+ pxNewSocket->u.xTCP.pxHandleReceive = pxSocket->u.xTCP.pxHandleReceive;
+ pxNewSocket->u.xTCP.pxHandleSent = pxSocket->u.xTCP.pxHandleSent;
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ /* Child socket of listening sockets will inherit the Socket Set
+ Otherwise the owner has no chance of including it into the set. */
+ if( pxSocket->pxSocketSet )
+ {
+ pxNewSocket->pxSocketSet = pxSocket->pxSocketSet;
+ pxNewSocket->xSelectBits = pxSocket->xSelectBits | eSELECT_READ | eSELECT_EXCEPT;
+ }
+ }
+ #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+
+ /* And bind it to the same local port as its parent. */
+ xAddress.sin_addr = *ipLOCAL_IP_ADDRESS_POINTER;
+ xAddress.sin_port = FreeRTOS_htons( pxSocket->usLocalPort );
+
+ #if( ipconfigTCP_HANG_PROTECTION == 1 )
+ {
+ /* Only when there is anti-hanging protection, a socket may become an
+ orphan temporarily. Once this socket is really connected, the owner of
+ the server socket will be notified. */
+
+ /* When bPassQueued is true, the socket is an orphan until it gets
+ connected. */
+ pxNewSocket->u.xTCP.bits.bPassQueued = pdTRUE_UNSIGNED;
+ pxNewSocket->u.xTCP.pxPeerSocket = pxSocket;
+ }
+ #else
+ {
+ /* A reference to the new socket may be stored and the socket is marked
+ as 'passable'. */
+
+ /* When bPassAccept is pdTRUE_UNSIGNED this socket may be returned in a call to
+ accept(). */
+ pxNewSocket->u.xTCP.bits.bPassAccept = pdTRUE_UNSIGNED;
+ if(pxSocket->u.xTCP.pxPeerSocket == NULL )
+ {
+ pxSocket->u.xTCP.pxPeerSocket = pxNewSocket;
+ }
+ }
+ #endif
+
+ pxSocket->u.xTCP.usChildCount++;
+
+ FreeRTOS_debug_printf( ( "Gain: Socket %u now has %u / %u child%s\n",
+ pxSocket->usLocalPort,
+ pxSocket->u.xTCP.usChildCount,
+ pxSocket->u.xTCP.usBacklog,
+ pxSocket->u.xTCP.usChildCount == 1u ? "" : "ren" ) );
+
+ /* Now bind the child socket to the same port as the listening socket. */
+ if( vSocketBind ( pxNewSocket, &xAddress, sizeof( xAddress ), pdTRUE ) != 0 )
+ {
+ FreeRTOS_debug_printf( ( "TCP: Listen: new socket bind error\n" ) );
+ vSocketClose( pxNewSocket );
+ return pdFALSE;
+ }
+
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+#if( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) )
+
+ const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState )
+ {
+ if( ulState >= ( UBaseType_t ) ARRAY_SIZE( pcStateNames ) )
+ {
+ ulState = ( UBaseType_t ) ARRAY_SIZE( pcStateNames ) - 1u;
+ }
+ return pcStateNames[ ulState ];
+ }
+
+#endif /* ( ( ipconfigHAS_DEBUG_PRINTF != 0 ) || ( ipconfigHAS_PRINTF != 0 ) ) */
+/*-----------------------------------------------------------*/
+
+/*
+ * In the API accept(), the user asks is there is a new client? As API's can
+ * not walk through the xBoundTCPSocketsList the IP-task will do this.
+ */
+BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket )
+{
+TickType_t xLocalPort = FreeRTOS_htons( pxSocket->usLocalPort );
+ListItem_t *pxIterator;
+FreeRTOS_Socket_t *pxFound;
+BaseType_t xResult = pdFALSE;
+
+ /* Here xBoundTCPSocketsList can be accessed safely IP-task is the only one
+ who has access. */
+ for( pxIterator = ( ListItem_t * ) listGET_HEAD_ENTRY( &xBoundTCPSocketsList );
+ pxIterator != ( ListItem_t * ) listGET_END_MARKER( &xBoundTCPSocketsList );
+ pxIterator = ( ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ if( listGET_LIST_ITEM_VALUE( pxIterator ) == xLocalPort )
+ {
+ pxFound = ( FreeRTOS_Socket_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+ if( ( pxFound->ucProtocol == FREERTOS_IPPROTO_TCP ) && ( pxFound->u.xTCP.bits.bPassAccept != pdFALSE_UNSIGNED ) )
+ {
+ pxSocket->u.xTCP.pxPeerSocket = pxFound;
+ FreeRTOS_debug_printf( ( "xTCPCheckNewClient[0]: client on port %u\n", pxSocket->usLocalPort ) );
+ xResult = pdTRUE;
+ break;
+ }
+ }
+ }
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+#endif /* ipconfigUSE_TCP == 1 */
+
+/* Provide access to private members for testing. */
+#ifdef AMAZON_FREERTOS_ENABLE_UNIT_TESTS
+ #include "iot_freertos_tcp_test_access_tcp_define.h"
+#endif
+
+/* Provide access to private members for verification. */
+#ifdef FREERTOS_TCP_ENABLE_VERIFICATION
+ #include "aws_freertos_tcp_verification_access_tcp_define.h"
+#endif
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
index cda8acd1c..804088009 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_TCP_WIN.c
@@ -1,1998 +1,1998 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/*
- * FreeRTOS_TCP_WIN.c
- * Module which handles the TCP windowing schemes for FreeRTOS+TCP. Many
- * functions have two versions - one for FreeRTOS+TCP (full) and one for
- * FreeRTOS+TCP (lite).
- *
- * In this module all ports and IP addresses and sequence numbers are
- * being stored in host byte-order.
- */
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "FreeRTOS_TCP_WIN.h"
-
-/* Constants used for Smoothed Round Trip Time (SRTT). */
-#define winSRTT_INCREMENT_NEW 2
-#define winSRTT_INCREMENT_CURRENT 6
-#define winSRTT_DECREMENT_NEW 1
-#define winSRTT_DECREMENT_CURRENT 7
-#define winSRTT_CAP_mS 50
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- #define xTCPWindowRxNew( pxWindow, ulSequenceNumber, lCount ) xTCPWindowNew( pxWindow, ulSequenceNumber, lCount, pdTRUE )
-
- #define xTCPWindowTxNew( pxWindow, ulSequenceNumber, lCount ) xTCPWindowNew( pxWindow, ulSequenceNumber, lCount, pdFALSE )
-
- /* The code to send a single Selective ACK (SACK):
- * NOP (0x01), NOP (0x01), SACK (0x05), LEN (0x0a),
- * followed by a lower and a higher sequence number,
- * where LEN is 2 + 2*4 = 10 bytes. */
- #if( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
- #define OPTION_CODE_SINGLE_SACK ( 0x0101050aUL )
- #else
- #define OPTION_CODE_SINGLE_SACK ( 0x0a050101UL )
- #endif
-
- /* Normal retransmission:
- * A packet will be retransmitted after a Retransmit Time-Out (RTO).
- * Fast retransmission:
- * When 3 packets with a higher sequence number have been acknowledged
- * by the peer, it is very unlikely a current packet will ever arrive.
- * It will be retransmitted far before the RTO.
- */
- #define DUPLICATE_ACKS_BEFORE_FAST_RETRANSMIT ( 3u )
-
- /* If there have been several retransmissions (4), decrease the
- * size of the transmission window to at most 2 times MSS.
- */
- #define MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW ( 4u )
-
-#endif /* configUSE_TCP_WIN */
-/*-----------------------------------------------------------*/
-
-extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere );
-
-/*
- * All TCP sockets share a pool of segment descriptors (TCPSegment_t)
- * Available descriptors are stored in the 'xSegmentList'
- * When a socket owns a descriptor, it will either be stored in
- * 'xTxSegments' or 'xRxSegments'
- * As soon as a package has been confirmed, the descriptor will be returned
- * to the segment pool
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static BaseType_t prvCreateSectors( void );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * Find a segment with a given sequence number in the list of received
- * segments: 'pxWindow->xRxSegments'.
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static TCPSegment_t *xTCPWindowRxFind( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * Allocate a new segment
- * The socket will borrow all segments from a common pool: 'xSegmentList',
- * which is a list of 'TCPSegment_t'
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static TCPSegment_t *xTCPWindowNew( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, int32_t lCount, BaseType_t xIsForRx );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/* When the peer has a close request (FIN flag), the driver will check if
- * there are missing packets in the Rx-queue
- * It will accept the closure of the connection if both conditions are true:
- * - the Rx-queue is empty
- * - we've ACK'd the highest Rx sequence number seen
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * Detaches and returns the head of a queue
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static TCPSegment_t *xTCPWindowGetHead( List_t *pxList );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * Returns the head of a queue but it won't be detached
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static TCPSegment_t *xTCPWindowPeekHead( List_t *pxList );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * Free entry pxSegment because it's not used anymore
- * The ownership will be passed back to the segment pool
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static void vTCPWindowFree( TCPSegment_t *pxSegment );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * A segment has been received with sequence number 'ulSequenceNumber', where
- * 'ulCurrentSequenceNumber == ulSequenceNumber', which means that exactly this
- * segment was expected. xTCPWindowRxConfirm() will check if there is already
- * another segment with a sequence number between (ulSequenceNumber) and
- * (ulSequenceNumber+xLength). Normally none will be found, because the next Rx
- * segment should have a sequence number equal to '(ulSequenceNumber+xLength)'.
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static TCPSegment_t *xTCPWindowRxConfirm( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * FreeRTOS+TCP stores data in circular buffers. Calculate the next position to
- * store.
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static int32_t lTCPIncrementTxPosition( int32_t lPosition, int32_t lMax, int32_t lCount );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * This function will look if there is new transmission data. It will return
- * true if there is data to be sent.
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * An acknowledge was received. See if some outstanding data may be removed
- * from the transmission queue(s).
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static uint32_t prvTCPWindowTxCheckAck( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*
- * A higher Tx block has been acknowledged. Now iterate through the xWaitQueue
- * to find a possible condition for a FAST retransmission.
- */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static uint32_t prvTCPWindowFastRetransmit( TCPWindow_t *pxWindow, uint32_t ulFirst );
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/*-----------------------------------------------------------*/
-
-/* TCP segment pool. */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static TCPSegment_t *xTCPSegments = NULL;
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-
-/* List of free TCP segments. */
-#if( ipconfigUSE_TCP_WIN == 1 )
- static List_t xSegmentList;
-#endif
-
-/* Logging verbosity level. */
-BaseType_t xTCPWindowLoggingLevel = 0;
-
-#if( ipconfigUSE_TCP_WIN == 1 )
- /* Some 32-bit arithmetic: comparing sequence numbers */
- static portINLINE BaseType_t xSequenceLessThanOrEqual( uint32_t a, uint32_t b );
- static portINLINE BaseType_t xSequenceLessThanOrEqual( uint32_t a, uint32_t b )
- {
- /* Test if a <= b
- Return true if the unsigned subtraction of (b-a) doesn't generate an
- arithmetic overflow. */
- return ( ( b - a ) & 0x80000000UL ) == 0UL;
- }
-#endif /* ipconfigUSE_TCP_WIN */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
- static portINLINE BaseType_t xSequenceLessThan( uint32_t a, uint32_t b );
- static portINLINE BaseType_t xSequenceLessThan( uint32_t a, uint32_t b )
- {
- /* Test if a < b */
- return ( ( b - a - 1UL ) & 0x80000000UL ) == 0UL;
- }
-#endif /* ipconfigUSE_TCP_WIN */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
- static portINLINE BaseType_t xSequenceGreaterThan( uint32_t a, uint32_t b );
- static portINLINE BaseType_t xSequenceGreaterThan( uint32_t a, uint32_t b )
- {
- /* Test if a > b */
- return ( ( a - b - 1UL ) & 0x80000000UL ) == 0UL;
- }
-#endif /* ipconfigUSE_TCP_WIN */
-
-/*-----------------------------------------------------------*/
-static portINLINE BaseType_t xSequenceGreaterThanOrEqual( uint32_t a, uint32_t b );
-static portINLINE BaseType_t xSequenceGreaterThanOrEqual( uint32_t a, uint32_t b )
-{
- /* Test if a >= b */
- return ( ( a - b ) & 0x80000000UL ) == 0UL;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
- static portINLINE void vListInsertFifo( List_t * const pxList, ListItem_t * const pxNewListItem );
- static portINLINE void vListInsertFifo( List_t * const pxList, ListItem_t * const pxNewListItem )
- {
- vListInsertGeneric( pxList, pxNewListItem, &pxList->xListEnd );
- }
-#endif
-/*-----------------------------------------------------------*/
-
-static portINLINE void vTCPTimerSet( TCPTimer_t *pxTimer );
-static portINLINE void vTCPTimerSet( TCPTimer_t *pxTimer )
-{
- pxTimer->ulBorn = xTaskGetTickCount ( );
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE uint32_t ulTimerGetAge( TCPTimer_t *pxTimer );
-static portINLINE uint32_t ulTimerGetAge( TCPTimer_t *pxTimer )
-{
- return ( ( xTaskGetTickCount() - pxTimer->ulBorn ) * portTICK_PERIOD_MS );
-}
-/*-----------------------------------------------------------*/
-
-/* _HT_ GCC (using the settings that I'm using) checks for every public function if it is
-preceded by a prototype. Later this prototype will be located in list.h? */
-
-extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere );
-
-void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere )
-{
- /* Insert a new list item into pxList, it does not sort the list,
- but it puts the item just before xListEnd, so it will be the last item
- returned by listGET_HEAD_ENTRY() */
- pxNewListItem->pxNext = (struct xLIST_ITEM * configLIST_VOLATILE)pxWhere;
- pxNewListItem->pxPrevious = pxWhere->pxPrevious;
- pxWhere->pxPrevious->pxNext = pxNewListItem;
- pxWhere->pxPrevious = pxNewListItem;
-
- /* Remember which list the item is in. */
- listLIST_ITEM_CONTAINER( pxNewListItem ) = ( void * ) pxList;
-
- ( pxList->uxNumberOfItems )++;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static BaseType_t prvCreateSectors( void )
- {
- BaseType_t xIndex, xReturn;
-
- /* Allocate space for 'xTCPSegments' and store them in 'xSegmentList'. */
-
- vListInitialise( &xSegmentList );
- xTCPSegments = ( TCPSegment_t * ) pvPortMallocLarge( ipconfigTCP_WIN_SEG_COUNT * sizeof( xTCPSegments[ 0 ] ) );
-
- if( xTCPSegments == NULL )
- {
- FreeRTOS_debug_printf( ( "prvCreateSectors: malloc %lu failed\n",
- ipconfigTCP_WIN_SEG_COUNT * sizeof( xTCPSegments[ 0 ] ) ) );
-
- xReturn = pdFAIL;
- }
- else
- {
- /* Clear the allocated space. */
- memset( xTCPSegments, '\0', ipconfigTCP_WIN_SEG_COUNT * sizeof( xTCPSegments[ 0 ] ) );
-
- for( xIndex = 0; xIndex < ipconfigTCP_WIN_SEG_COUNT; xIndex++ )
- {
- /* Could call vListInitialiseItem here but all data has been
- nulled already. Set the owner to a segment descriptor. */
- listSET_LIST_ITEM_OWNER( &( xTCPSegments[ xIndex ].xListItem ), ( void* ) &( xTCPSegments[ xIndex ] ) );
- listSET_LIST_ITEM_OWNER( &( xTCPSegments[ xIndex ].xQueueItem ), ( void* ) &( xTCPSegments[ xIndex ] ) );
-
- /* And add it to the pool of available segments */
- vListInsertFifo( &xSegmentList, &( xTCPSegments[xIndex].xListItem ) );
- }
-
- xReturn = pdPASS;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static TCPSegment_t *xTCPWindowRxFind( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber )
- {
- const ListItem_t *pxIterator;
- const MiniListItem_t* pxEnd;
- TCPSegment_t *pxSegment, *pxReturn = NULL;
-
- /* Find a segment with a given sequence number in the list of received
- segments. */
-
- pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &pxWindow->xRxSegments );
-
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( const ListItem_t * ) pxEnd;
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
-
- if( pxSegment->ulSequenceNumber == ulSequenceNumber )
- {
- pxReturn = pxSegment;
- break;
- }
- }
-
- return pxReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static TCPSegment_t *xTCPWindowNew( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, int32_t lCount, BaseType_t xIsForRx )
- {
- TCPSegment_t *pxSegment;
- ListItem_t * pxItem;
-
- /* Allocate a new segment. The socket will borrow all segments from a
- common pool: 'xSegmentList', which is a list of 'TCPSegment_t' */
- if( listLIST_IS_EMPTY( &xSegmentList ) != pdFALSE )
- {
- /* If the TCP-stack runs out of segments, you might consider
- increasing 'ipconfigTCP_WIN_SEG_COUNT'. */
- FreeRTOS_debug_printf( ( "xTCPWindow%cxNew: Error: all segments occupied\n", xIsForRx ? 'R' : 'T' ) );
- pxSegment = NULL;
- }
- else
- {
- /* Pop the item at the head of the list. Semaphore protection is
- not required as only the IP task will call these functions. */
- pxItem = ( ListItem_t * ) listGET_HEAD_ENTRY( &xSegmentList );
- pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxItem );
-
- configASSERT( pxItem != NULL );
- configASSERT( pxSegment != NULL );
-
- /* Remove the item from xSegmentList. */
- uxListRemove( pxItem );
-
- /* Add it to either the connections' Rx or Tx queue. */
- vListInsertFifo( xIsForRx ? &pxWindow->xRxSegments : &pxWindow->xTxSegments, pxItem );
-
- /* And set the segment's timer to zero */
- vTCPTimerSet( &pxSegment->xTransmitTimer );
-
- pxSegment->u.ulFlags = 0;
- pxSegment->u.bits.bIsForRx = ( xIsForRx != 0 );
- pxSegment->lMaxLength = lCount;
- pxSegment->lDataLength = lCount;
- pxSegment->ulSequenceNumber = ulSequenceNumber;
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- static UBaseType_t xLowestLength = ipconfigTCP_WIN_SEG_COUNT;
- UBaseType_t xLength = listCURRENT_LIST_LENGTH( &xSegmentList );
-
- if( xLowestLength > xLength )
- {
- xLowestLength = xLength;
- }
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF */
- }
-
- return pxSegment;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow )
- {
- BaseType_t xReturn;
-
- /* When the peer has a close request (FIN flag), the driver will check
- if there are missing packets in the Rx-queue. It will accept the
- closure of the connection if both conditions are true:
- - the Rx-queue is empty
- - the highest Rx sequence number has been ACK'ed */
- if( listLIST_IS_EMPTY( ( &pxWindow->xRxSegments ) ) == pdFALSE )
- {
- /* Rx data has been stored while earlier packets were missing. */
- xReturn = pdFALSE;
- }
- else if( xSequenceGreaterThanOrEqual( pxWindow->rx.ulCurrentSequenceNumber, pxWindow->rx.ulHighestSequenceNumber ) != pdFALSE )
- {
- /* No Rx packets are being stored and the highest sequence number
- that has been received has been ACKed. */
- xReturn = pdTRUE;
- }
- else
- {
- FreeRTOS_debug_printf( ( "xTCPWindowRxEmpty: cur %lu highest %lu (empty)\n",
- ( pxWindow->rx.ulCurrentSequenceNumber - pxWindow->rx.ulFirstSequenceNumber ),
- ( pxWindow->rx.ulHighestSequenceNumber - pxWindow->rx.ulFirstSequenceNumber ) ) );
- xReturn = pdFALSE;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static TCPSegment_t *xTCPWindowGetHead( List_t *pxList )
- {
- TCPSegment_t *pxSegment;
- ListItem_t * pxItem;
-
- /* Detaches and returns the head of a queue. */
- if( listLIST_IS_EMPTY( pxList ) != pdFALSE )
- {
- pxSegment = NULL;
- }
- else
- {
- pxItem = ( ListItem_t * ) listGET_HEAD_ENTRY( pxList );
- pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxItem );
-
- uxListRemove( pxItem );
- }
-
- return pxSegment;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static TCPSegment_t *xTCPWindowPeekHead( List_t *pxList )
- {
- ListItem_t *pxItem;
- TCPSegment_t *pxReturn;
-
- /* Returns the head of a queue but it won't be detached. */
- if( listLIST_IS_EMPTY( pxList ) != pdFALSE )
- {
- pxReturn = NULL;
- }
- else
- {
- pxItem = ( ListItem_t * ) listGET_HEAD_ENTRY( pxList );
- pxReturn = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxItem );
- }
-
- return pxReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static void vTCPWindowFree( TCPSegment_t *pxSegment )
- {
- /* Free entry pxSegment because it's not used any more. The ownership
- will be passed back to the segment pool.
-
- Unlink it from one of the queues, if any. */
- if( listLIST_ITEM_CONTAINER( &( pxSegment->xQueueItem ) ) != NULL )
- {
- uxListRemove( &( pxSegment->xQueueItem ) );
- }
-
- pxSegment->ulSequenceNumber = 0u;
- pxSegment->lDataLength = 0l;
- pxSegment->u.ulFlags = 0u;
-
- /* Take it out of xRxSegments/xTxSegments */
- if( listLIST_ITEM_CONTAINER( &( pxSegment->xListItem ) ) != NULL )
- {
- uxListRemove( &( pxSegment->xListItem ) );
- }
-
- /* Return it to xSegmentList */
- vListInsertFifo( &xSegmentList, &( pxSegment->xListItem ) );
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- void vTCPWindowDestroy( TCPWindow_t *pxWindow )
- {
- List_t * pxSegments;
- BaseType_t xRound;
- TCPSegment_t *pxSegment;
-
- /* Destroy a window. A TCP window doesn't serve any more. Return all
- owned segments to the pool. In order to save code, it will make 2 rounds,
- one to remove the segments from xRxSegments, and a second round to clear
- xTxSegments*/
- for( xRound = 0; xRound < 2; xRound++ )
- {
- if( xRound != 0 )
- {
- pxSegments = &( pxWindow->xRxSegments );
- }
- else
- {
- pxSegments = &( pxWindow->xTxSegments );
- }
-
- if( listLIST_IS_INITIALISED( pxSegments ) != pdFALSE )
- {
- while( listCURRENT_LIST_LENGTH( pxSegments ) > 0U )
- {
- pxSegment = ( TCPSegment_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxSegments );
- vTCPWindowFree( pxSegment );
- }
- }
- }
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
- uint32_t ulTxWindowLength, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS )
-{
- /* Create and initialize a window. */
-
- #if( ipconfigUSE_TCP_WIN == 1 )
- {
- if( xTCPSegments == NULL )
- {
- prvCreateSectors();
- }
-
- vListInitialise( &pxWindow->xTxSegments );
- vListInitialise( &pxWindow->xRxSegments );
-
- vListInitialise( &pxWindow->xPriorityQueue ); /* Priority queue: segments which must be sent immediately */
- vListInitialise( &pxWindow->xTxQueue ); /* Transmit queue: segments queued for transmission */
- vListInitialise( &pxWindow->xWaitQueue ); /* Waiting queue: outstanding segments */
- }
- #endif /* ipconfigUSE_TCP_WIN == 1 */
-
- if( xTCPWindowLoggingLevel != 0 )
- {
- FreeRTOS_debug_printf( ( "vTCPWindowCreate: for WinLen = Rx/Tx: %lu/%lu\n",
- ulRxWindowLength, ulTxWindowLength ) );
- }
-
- pxWindow->xSize.ulRxWindowLength = ulRxWindowLength;
- pxWindow->xSize.ulTxWindowLength = ulTxWindowLength;
-
- vTCPWindowInit( pxWindow, ulAckNumber, ulSequenceNumber, ulMSS );
-}
-/*-----------------------------------------------------------*/
-
-void vTCPWindowInit( TCPWindow_t *pxWindow, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS )
-{
-const int32_t l500ms = 500;
-
- pxWindow->u.ulFlags = 0ul;
- pxWindow->u.bits.bHasInit = pdTRUE_UNSIGNED;
-
- if( ulMSS != 0ul )
- {
- if( pxWindow->usMSSInit != 0u )
- {
- pxWindow->usMSSInit = ( uint16_t ) ulMSS;
- }
-
- if( ( ulMSS < ( uint32_t ) pxWindow->usMSS ) || ( pxWindow->usMSS == 0u ) )
- {
- pxWindow->xSize.ulRxWindowLength = ( pxWindow->xSize.ulRxWindowLength / ulMSS ) * ulMSS;
- pxWindow->usMSS = ( uint16_t ) ulMSS;
- }
- }
-
- #if( ipconfigUSE_TCP_WIN == 0 )
- {
- pxWindow->xTxSegment.lMaxLength = ( int32_t ) pxWindow->usMSS;
- }
- #endif /* ipconfigUSE_TCP_WIN == 1 */
-
- /*Start with a timeout of 2 * 500 ms (1 sec). */
- pxWindow->lSRTT = l500ms;
-
- /* Just for logging, to print relative sequence numbers. */
- pxWindow->rx.ulFirstSequenceNumber = ulAckNumber;
-
- /* The segment asked for in the next transmission. */
- pxWindow->rx.ulCurrentSequenceNumber = ulAckNumber;
-
- /* The right-hand side of the receive window. */
- pxWindow->rx.ulHighestSequenceNumber = ulAckNumber;
-
- pxWindow->tx.ulFirstSequenceNumber = ulSequenceNumber;
-
- /* The segment asked for in next transmission. */
- pxWindow->tx.ulCurrentSequenceNumber = ulSequenceNumber;
-
- /* The sequence number given to the next outgoing byte to be added is
- maintained by lTCPWindowTxAdd(). */
- pxWindow->ulNextTxSequenceNumber = ulSequenceNumber;
-
- /* The right-hand side of the transmit window. */
- pxWindow->tx.ulHighestSequenceNumber = ulSequenceNumber;
- pxWindow->ulOurSequenceNumber = ulSequenceNumber;
-}
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- void vTCPSegmentCleanup( void )
- {
- /* Free and clear the TCP segments pointer. This function should only be called
- * once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
- * function. */
- if( xTCPSegments != NULL )
- {
- vPortFreeLarge( xTCPSegments );
- xTCPSegments = NULL;
- }
- }
-
-#endif /* ipconfgiUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-/*=============================================================================
- *
- * ###### # #
- * # # # #
- * # # # #
- * # # ####
- * ###### ##
- * # ## ####
- * # # # #
- * # # # #
- * ### ## # #
- * Rx functions
- *
- *=============================================================================*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static TCPSegment_t *xTCPWindowRxConfirm( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength )
- {
- TCPSegment_t *pxBest = NULL;
- const ListItem_t *pxIterator;
- uint32_t ulNextSequenceNumber = ulSequenceNumber + ulLength;
- const MiniListItem_t* pxEnd = ( const MiniListItem_t* ) listGET_END_MARKER( &pxWindow->xRxSegments );
- TCPSegment_t *pxSegment;
-
- /* A segment has been received with sequence number 'ulSequenceNumber',
- where 'ulCurrentSequenceNumber == ulSequenceNumber', which means that
- exactly this segment was expected. xTCPWindowRxConfirm() will check if
- there is already another segment with a sequence number between (ulSequenceNumber)
- and (ulSequenceNumber+ulLength). Normally none will be found, because
- the next RX segment should have a sequence number equal to
- '(ulSequenceNumber+ulLength)'. */
-
- /* Iterate through all RX segments that are stored: */
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( const ListItem_t * ) pxEnd;
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
- {
- pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
- /* And see if there is a segment for which:
- 'ulSequenceNumber' <= 'pxSegment->ulSequenceNumber' < 'ulNextSequenceNumber'
- If there are more matching segments, the one with the lowest sequence number
- shall be taken */
- if( ( xSequenceGreaterThanOrEqual( pxSegment->ulSequenceNumber, ulSequenceNumber ) != 0 ) &&
- ( xSequenceLessThan( pxSegment->ulSequenceNumber, ulNextSequenceNumber ) != 0 ) )
- {
- if( ( pxBest == NULL ) || ( xSequenceLessThan( pxSegment->ulSequenceNumber, pxBest->ulSequenceNumber ) != 0 ) )
- {
- pxBest = pxSegment;
- }
- }
- }
-
- if( ( pxBest != NULL ) &&
- ( ( pxBest->ulSequenceNumber != ulSequenceNumber ) || ( pxBest->lDataLength != ( int32_t ) ulLength ) ) )
- {
- FreeRTOS_flush_logging();
- FreeRTOS_debug_printf( ( "xTCPWindowRxConfirm[%u]: search %lu (+%ld=%lu) found %lu (+%ld=%lu)\n",
- pxWindow->usPeerPortNumber,
- ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- ulLength,
- ulSequenceNumber + ulLength - pxWindow->rx.ulFirstSequenceNumber,
- pxBest->ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- pxBest->lDataLength,
- pxBest->ulSequenceNumber + ( ( uint32_t ) pxBest->lDataLength ) - pxWindow->rx.ulFirstSequenceNumber ) );
- }
-
- return pxBest;
- }
-
-#endif /* ipconfgiUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace )
- {
- uint32_t ulCurrentSequenceNumber, ulLast, ulSavedSequenceNumber;
- int32_t lReturn, lDistance;
- TCPSegment_t *pxFound;
-
- /* If lTCPWindowRxCheck( ) returns == 0, the packet will be passed
- directly to user (segment is expected). If it returns a positive
- number, an earlier packet is missing, but this packet may be stored.
- If negative, the packet has already been stored, or it is out-of-order,
- or there is not enough space.
-
- As a side-effect, pxWindow->ulUserDataLength will get set to non-zero,
- if more Rx data may be passed to the user after this packet. */
-
- ulCurrentSequenceNumber = pxWindow->rx.ulCurrentSequenceNumber;
-
- /* For Selective Ack (SACK), used when out-of-sequence data come in. */
- pxWindow->ucOptionLength = 0u;
-
- /* Non-zero if TCP-windows contains data which must be popped. */
- pxWindow->ulUserDataLength = 0ul;
-
- if( ulCurrentSequenceNumber == ulSequenceNumber )
- {
- /* This is the packet with the lowest sequence number we're waiting
- for. It can be passed directly to the rx stream. */
- if( ulLength > ulSpace )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowRxCheck: Refuse %lu bytes, due to lack of space (%lu)\n", ulLength, ulSpace ) );
- lReturn = -1;
- }
- else
- {
- ulCurrentSequenceNumber += ulLength;
-
- if( listCURRENT_LIST_LENGTH( &( pxWindow->xRxSegments ) ) != 0 )
- {
- ulSavedSequenceNumber = ulCurrentSequenceNumber;
-
- /* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
- If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
- So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
- clean them out. */
- do
- {
- pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
-
- if ( pxFound != NULL )
- {
- /* Remove it because it will be passed to user directly. */
- vTCPWindowFree( pxFound );
- }
- } while ( pxFound );
-
- /* Check for following segments that are already in the
- queue and increment ulCurrentSequenceNumber. */
- while( ( pxFound = xTCPWindowRxFind( pxWindow, ulCurrentSequenceNumber ) ) != NULL )
- {
- ulCurrentSequenceNumber += ( uint32_t ) pxFound->lDataLength;
-
- /* As all packet below this one have been passed to the
- user it can be discarded. */
- vTCPWindowFree( pxFound );
- }
-
- if( ulSavedSequenceNumber != ulCurrentSequenceNumber )
- {
- /* After the current data-package, there is more data
- to be popped. */
- pxWindow->ulUserDataLength = ulCurrentSequenceNumber - ulSavedSequenceNumber;
-
- if( xTCPWindowLoggingLevel >= 1 )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowRxCheck[%d,%d]: retran %lu (Found %lu bytes at %lu cnt %ld)\n",
- pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
- ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- pxWindow->ulUserDataLength,
- ulSavedSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- listCURRENT_LIST_LENGTH( &pxWindow->xRxSegments ) ) );
- }
- }
- }
-
- pxWindow->rx.ulCurrentSequenceNumber = ulCurrentSequenceNumber;
-
- /* Packet was expected, may be passed directly to the socket
- buffer or application. Store the packet at offset 0. */
- lReturn = 0;
- }
- }
- else if( ulCurrentSequenceNumber == ( ulSequenceNumber + 1UL ) )
- {
- /* Looks like a TCP keep-alive message. Do not accept/store Rx data
- ulUserDataLength = 0. Not packet out-of-sync. Just reply to it. */
- lReturn = -1;
- }
- else
- {
- /* The packet is not the one expected. See if it falls within the Rx
- window so it can be stored. */
-
- /* An "out-of-sequence" segment was received, must have missed one.
- Prepare a SACK (Selective ACK). */
- ulLast = ulSequenceNumber + ulLength;
- lDistance = ( int32_t ) ( ulLast - ulCurrentSequenceNumber );
-
- if( lDistance <= 0 )
- {
- /* An earlier has been received, must be a retransmission of a
- packet that has been accepted already. No need to send out a
- Selective ACK (SACK). */
- lReturn = -1;
- }
- else if( lDistance > ( int32_t ) ulSpace )
- {
- /* The new segment is ahead of rx.ulCurrentSequenceNumber. The
- sequence number of this packet is too far ahead, ignore it. */
- FreeRTOS_debug_printf( ( "lTCPWindowRxCheck: Refuse %lu+%lu bytes, due to lack of space (%lu)\n", lDistance, ulLength, ulSpace ) );
- lReturn = -1;
- }
- else
- {
- /* See if there is more data in a contiguous block to make the
- SACK describe a longer range of data. */
-
- /* TODO: SACK's may also be delayed for a short period
- * This is useful because subsequent packets will be SACK'd with
- * single one message
- */
- while( ( pxFound = xTCPWindowRxFind( pxWindow, ulLast ) ) != NULL )
- {
- ulLast += ( uint32_t ) pxFound->lDataLength;
- }
-
- if( xTCPWindowLoggingLevel >= 1 )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowRxCheck[%d,%d]: seqnr %lu exp %lu (dist %ld) SACK to %lu\n",
- pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
- ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- ulCurrentSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- ( BaseType_t ) ( ulSequenceNumber - ulCurrentSequenceNumber ), /* want this signed */
- ulLast - pxWindow->rx.ulFirstSequenceNumber ) );
- }
-
- /* Now prepare the SACK message.
- Code OPTION_CODE_SINGLE_SACK already in network byte order. */
- pxWindow->ulOptionsData[0] = OPTION_CODE_SINGLE_SACK;
-
- /* First sequence number that we received. */
- pxWindow->ulOptionsData[1] = FreeRTOS_htonl( ulSequenceNumber );
-
- /* Last + 1 */
- pxWindow->ulOptionsData[2] = FreeRTOS_htonl( ulLast );
-
- /* Which make 12 (3*4) option bytes. */
- pxWindow->ucOptionLength = 3 * sizeof( pxWindow->ulOptionsData[ 0 ] );
-
- pxFound = xTCPWindowRxFind( pxWindow, ulSequenceNumber );
-
- if( pxFound != NULL )
- {
- /* This out-of-sequence packet has been received for a
- second time. It is already stored but do send a SACK
- again. */
- lReturn = -1;
- }
- else
- {
- pxFound = xTCPWindowRxNew( pxWindow, ulSequenceNumber, ( int32_t ) ulLength );
-
- if( pxFound == NULL )
- {
- /* Can not send a SACK, because the segment cannot be
- stored. */
- pxWindow->ucOptionLength = 0u;
-
- /* Needs to be stored but there is no segment
- available. */
- lReturn = -1;
- }
- else
- {
- if( xTCPWindowLoggingLevel != 0 )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowRxCheck[%u,%u]: seqnr %lu (cnt %lu)\n",
- pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber, ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
- listCURRENT_LIST_LENGTH( &pxWindow->xRxSegments ) ) );
- FreeRTOS_flush_logging( );
- }
-
- /* Return a positive value. The packet may be accepted
- and stored but an earlier packet is still missing. */
- lReturn = ( int32_t ) ( ulSequenceNumber - ulCurrentSequenceNumber );
- }
- }
- }
- }
-
- return lReturn;
- }
-
-#endif /* ipconfgiUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-/*=============================================================================
- *
- * ######### # #
- * # # # # #
- * # # #
- * # ####
- * # ##
- * # ####
- * # # #
- * # # #
- * ##### # #
- *
- * Tx functions
- *
- *=============================================================================*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static int32_t lTCPIncrementTxPosition( int32_t lPosition, int32_t lMax, int32_t lCount )
- {
- /* +TCP stores data in circular buffers. Calculate the next position to
- store. */
- lPosition += lCount;
- if( lPosition >= lMax )
- {
- lPosition -= lMax;
- }
-
- return lPosition;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax )
- {
- int32_t lBytesLeft = ( int32_t ) ulLength, lToWrite;
- int32_t lDone = 0;
- TCPSegment_t *pxSegment = pxWindow->pxHeadSegment;
-
- /* Puts a message in the Tx-window (after buffer size has been
- verified). */
- if( pxSegment != NULL )
- {
- if( pxSegment->lDataLength < pxSegment->lMaxLength )
- {
- if( ( pxSegment->u.bits.bOutstanding == pdFALSE_UNSIGNED ) && ( pxSegment->lDataLength != 0 ) )
- {
- /* Adding data to a segment that was already in the TX queue. It
- will be filled-up to a maximum of MSS (maximum segment size). */
- lToWrite = FreeRTOS_min_int32( lBytesLeft, pxSegment->lMaxLength - pxSegment->lDataLength );
-
- pxSegment->lDataLength += lToWrite;
-
- if( pxSegment->lDataLength >= pxSegment->lMaxLength )
- {
- /* This segment is full, don't add more bytes. */
- pxWindow->pxHeadSegment = NULL;
- }
-
- lBytesLeft -= lToWrite;
-
- /* ulNextTxSequenceNumber is the sequence number of the next byte to
- be stored for transmission. */
- pxWindow->ulNextTxSequenceNumber += ( uint32_t ) lToWrite;
-
- /* Increased the return value. */
- lDone += lToWrite;
-
- /* Some detailed logging, for those who're interested. */
- if( ( xTCPWindowLoggingLevel >= 2 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != 0 ) )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: Add %4lu bytes for seqNr %lu len %4lu (nxt %lu) pos %lu\n",
- ulLength,
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxSegment->lDataLength,
- pxWindow->ulNextTxSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxSegment->lStreamPos ) );
- FreeRTOS_flush_logging( );
- }
-
- /* Calculate the next position in the circular data buffer, knowing
- its maximum length 'lMax'. */
- lPosition = lTCPIncrementTxPosition( lPosition, lMax, lToWrite );
- }
- }
- }
-
- while( lBytesLeft > 0 )
- {
- /* The current transmission segment is full, create new segments as
- needed. */
- pxSegment = xTCPWindowTxNew( pxWindow, pxWindow->ulNextTxSequenceNumber, pxWindow->usMSS );
-
- if( pxSegment != NULL )
- {
- /* Store as many as needed, but no more than the maximum
- (MSS). */
- lToWrite = FreeRTOS_min_int32( lBytesLeft, pxSegment->lMaxLength );
-
- pxSegment->lDataLength = lToWrite;
- pxSegment->lStreamPos = lPosition;
- lBytesLeft -= lToWrite;
- lPosition = lTCPIncrementTxPosition( lPosition, lMax, lToWrite );
- pxWindow->ulNextTxSequenceNumber += ( uint32_t ) lToWrite;
- lDone += lToWrite;
-
- /* Link this segment in the Tx-Queue. */
- vListInsertFifo( &( pxWindow->xTxQueue ), &( pxSegment->xQueueItem ) );
-
- /* Let 'pxHeadSegment' point to this segment if there is still
- space. */
- if( pxSegment->lDataLength < pxSegment->lMaxLength )
- {
- pxWindow->pxHeadSegment = pxSegment;
- }
- else
- {
- pxWindow->pxHeadSegment = NULL;
- }
-
- if( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != 0 )
- {
- if( ( xTCPWindowLoggingLevel >= 3 ) ||
- ( ( xTCPWindowLoggingLevel >= 2 ) && ( pxWindow->pxHeadSegment != NULL ) ) )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: New %4ld bytes for seqNr %lu len %4lu (nxt %lu) pos %lu\n",
- ulLength,
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxSegment->lDataLength,
- pxWindow->ulNextTxSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxSegment->lStreamPos ) );
- FreeRTOS_flush_logging( );
- }
- }
- }
- else
- {
- /* A sever situation: running out of segments for transmission.
- No more data can be sent at the moment. */
- if( lDone != 0 )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: Sorry all buffers full (cancel %ld bytes)\n", lBytesLeft ) );
- }
- break;
- }
- }
-
- return lDone;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow )
- {
- return listLIST_IS_EMPTY( ( &pxWindow->xTxSegments) );
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize )
- {
- uint32_t ulTxOutstanding;
- BaseType_t xHasSpace;
- TCPSegment_t *pxSegment;
-
- /* This function will look if there is new transmission data. It will
- return true if there is data to be sent. */
-
- pxSegment = xTCPWindowPeekHead( &( pxWindow->xTxQueue ) );
-
- if( pxSegment == NULL )
- {
- xHasSpace = pdFALSE;
- }
- else
- {
- /* How much data is outstanding, i.e. how much data has been sent
- but not yet acknowledged ? */
- if( pxWindow->tx.ulHighestSequenceNumber >= pxWindow->tx.ulCurrentSequenceNumber )
- {
- ulTxOutstanding = pxWindow->tx.ulHighestSequenceNumber - pxWindow->tx.ulCurrentSequenceNumber;
- }
- else
- {
- ulTxOutstanding = 0UL;
- }
-
- /* Subtract this from the peer's space. */
- ulWindowSize -= FreeRTOS_min_uint32( ulWindowSize, ulTxOutstanding );
-
- /* See if the next segment may be sent. */
- if( ulWindowSize >= ( uint32_t ) pxSegment->lDataLength )
- {
- xHasSpace = pdTRUE;
- }
- else
- {
- xHasSpace = pdFALSE;
- }
-
- /* If 'xHasSpace', it looks like the peer has at least space for 1
- more new segment of size MSS. xSize.ulTxWindowLength is the self-imposed
- limitation of the transmission window (in case of many resends it
- may be decreased). */
- if( ( ulTxOutstanding != 0UL ) && ( pxWindow->xSize.ulTxWindowLength < ulTxOutstanding + ( ( uint32_t ) pxSegment->lDataLength ) ) )
- {
- xHasSpace = pdFALSE;
- }
- }
-
- return xHasSpace;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay )
- {
- TCPSegment_t *pxSegment;
- BaseType_t xReturn;
- TickType_t ulAge, ulMaxAge;
-
- *pulDelay = 0u;
-
- if( listLIST_IS_EMPTY( &pxWindow->xPriorityQueue ) == pdFALSE )
- {
- /* No need to look at retransmissions or new transmission as long as
- there are priority segments. *pulDelay equals zero, meaning it must
- be sent out immediately. */
- xReturn = pdTRUE;
- }
- else
- {
- pxSegment = xTCPWindowPeekHead( &( pxWindow->xWaitQueue ) );
-
- if( pxSegment != NULL )
- {
- /* There is an outstanding segment, see if it is time to resend
- it. */
- ulAge = ulTimerGetAge( &pxSegment->xTransmitTimer );
-
- /* After a packet has been sent for the first time, it will wait
- '1 * lSRTT' ms for an ACK. A second time it will wait '2 * lSRTT' ms,
- each time doubling the time-out */
- ulMaxAge = ( 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
-
- if( ulMaxAge > ulAge )
- {
- /* A segment must be sent after this amount of msecs */
- *pulDelay = ulMaxAge - ulAge;
- }
-
- xReturn = pdTRUE;
- }
- else
- {
- /* No priority segment, no outstanding data, see if there is new
- transmission data. */
- pxSegment = xTCPWindowPeekHead( &pxWindow->xTxQueue );
-
- /* See if it fits in the peer's reception window. */
- if( pxSegment == NULL )
- {
- xReturn = pdFALSE;
- }
- else if( prvTCPWindowTxHasSpace( pxWindow, ulWindowSize ) == pdFALSE )
- {
- /* Too many outstanding messages. */
- xReturn = pdFALSE;
- }
- else if( ( pxWindow->u.bits.bSendFullSize != pdFALSE_UNSIGNED ) && ( pxSegment->lDataLength < pxSegment->lMaxLength ) )
- {
- /* 'bSendFullSize' is a special optimisation. If true, the
- driver will only sent completely filled packets (of MSS
- bytes). */
- xReturn = pdFALSE;
- }
- else
- {
- xReturn = pdTRUE;
- }
- }
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition )
- {
- TCPSegment_t *pxSegment;
- uint32_t ulMaxTime;
- uint32_t ulReturn = ~0UL;
-
-
- /* Fetches data to be sent-out now.
-
- Priority messages: segments with a resend need no check current sliding
- window size. */
- pxSegment = xTCPWindowGetHead( &( pxWindow->xPriorityQueue ) );
- pxWindow->ulOurSequenceNumber = pxWindow->tx.ulHighestSequenceNumber;
-
- if( pxSegment == NULL )
- {
- /* Waiting messages: outstanding messages with a running timer
- neither check peer's reception window size because these packets
- have been sent earlier. */
- pxSegment = xTCPWindowPeekHead( &( pxWindow->xWaitQueue ) );
-
- if( pxSegment != NULL )
- {
- /* Do check the timing. */
- ulMaxTime = ( 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
-
- if( ulTimerGetAge( &pxSegment->xTransmitTimer ) > ulMaxTime )
- {
- /* A normal (non-fast) retransmission. Move it from the
- head of the waiting queue. */
- pxSegment = xTCPWindowGetHead( &( pxWindow->xWaitQueue ) );
- pxSegment->u.bits.ucDupAckCount = pdFALSE_UNSIGNED;
-
- /* Some detailed logging. */
- if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != 0 ) )
- {
- FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u,%u]: WaitQueue %ld bytes for sequence number %lu (%lX)\n",
- pxWindow->usPeerPortNumber,
- pxWindow->usOurPortNumber,
- pxSegment->lDataLength,
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxSegment->ulSequenceNumber ) );
- FreeRTOS_flush_logging( );
- }
- }
- else
- {
- pxSegment = NULL;
- }
- }
-
- if( pxSegment == NULL )
- {
- /* New messages: sent-out for the first time. Check current
- sliding window size of peer. */
- pxSegment = xTCPWindowPeekHead( &( pxWindow->xTxQueue ) );
-
- if( pxSegment == NULL )
- {
- /* No segments queued. */
- ulReturn = 0UL;
- }
- else if( ( pxWindow->u.bits.bSendFullSize != pdFALSE_UNSIGNED ) && ( pxSegment->lDataLength < pxSegment->lMaxLength ) )
- {
- /* A segment has been queued but the driver waits until it
- has a full size of MSS. */
- ulReturn = 0;
- }
- else if( prvTCPWindowTxHasSpace( pxWindow, ulWindowSize ) == pdFALSE )
- {
- /* Peer has no more space at this moment. */
- ulReturn = 0;
- }
- else
- {
- /* Move it out of the Tx queue. */
- pxSegment = xTCPWindowGetHead( &( pxWindow->xTxQueue ) );
-
- /* Don't let pxHeadSegment point to this segment any more,
- so no more data will be added. */
- if( pxWindow->pxHeadSegment == pxSegment )
- {
- pxWindow->pxHeadSegment = NULL;
- }
-
- /* pxWindow->tx.highest registers the highest sequence
- number in our transmission window. */
- pxWindow->tx.ulHighestSequenceNumber = pxSegment->ulSequenceNumber + ( ( uint32_t ) pxSegment->lDataLength );
-
- /* ...and more detailed logging */
- if( ( xTCPWindowLoggingLevel >= 2 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u,%u]: XmitQueue %ld bytes for sequence number %lu (ws %lu)\n",
- pxWindow->usPeerPortNumber,
- pxWindow->usOurPortNumber,
- pxSegment->lDataLength,
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- ulWindowSize ) );
- FreeRTOS_flush_logging( );
- }
- }
- }
- }
- else
- {
- /* There is a priority segment. It doesn't need any checking for
- space or timeouts. */
- if( xTCPWindowLoggingLevel != 0 )
- {
- FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u,%u]: PrioQueue %ld bytes for sequence number %lu (ws %lu)\n",
- pxWindow->usPeerPortNumber,
- pxWindow->usOurPortNumber,
- pxSegment->lDataLength,
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- ulWindowSize ) );
- FreeRTOS_flush_logging( );
- }
- }
-
- /* See if it has already been determined to return 0. */
- if( ulReturn != 0UL )
- {
- configASSERT( listLIST_ITEM_CONTAINER( &(pxSegment->xQueueItem ) ) == NULL );
-
- /* Now that the segment will be transmitted, add it to the tail of
- the waiting queue. */
- vListInsertFifo( &pxWindow->xWaitQueue, &pxSegment->xQueueItem );
-
- /* And mark it as outstanding. */
- pxSegment->u.bits.bOutstanding = pdTRUE_UNSIGNED;
-
- /* Administer the transmit count, needed for fast
- retransmissions. */
- ( pxSegment->u.bits.ucTransmitCount )++;
-
- /* If there have been several retransmissions (4), decrease the
- size of the transmission window to at most 2 times MSS. */
- if( pxSegment->u.bits.ucTransmitCount == MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW )
- {
- if( pxWindow->xSize.ulTxWindowLength > ( 2U * pxWindow->usMSS ) )
- {
- FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u - %d]: Change Tx window: %lu -> %u\n",
- pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
- pxWindow->xSize.ulTxWindowLength, 2 * pxWindow->usMSS ) );
- pxWindow->xSize.ulTxWindowLength = ( 2UL * pxWindow->usMSS );
- }
- }
-
- /* Clear the transmit timer. */
- vTCPTimerSet( &( pxSegment->xTransmitTimer ) );
-
- pxWindow->ulOurSequenceNumber = pxSegment->ulSequenceNumber;
-
- /* Inform the caller where to find the data within the queue. */
- *plPosition = pxSegment->lStreamPos;
-
- /* And return the length of the data segment */
- ulReturn = ( uint32_t ) pxSegment->lDataLength;
- }
-
- return ulReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static uint32_t prvTCPWindowTxCheckAck( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast )
- {
- uint32_t ulBytesConfirmed = 0u;
- uint32_t ulSequenceNumber = ulFirst, ulDataLength;
- const ListItem_t *pxIterator;
- const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &pxWindow->xTxSegments );
- BaseType_t xDoUnlink;
- TCPSegment_t *pxSegment;
- /* An acknowledgement or a selective ACK (SACK) was received. See if some outstanding data
- may be removed from the transmission queue(s).
- All TX segments for which
- ( ( ulSequenceNumber >= ulFirst ) && ( ulSequenceNumber < ulLast ) in a
- contiguous block. Note that the segments are stored in xTxSegments in a
- strict sequential order. */
-
- /* SRTT[i] = (1-a) * SRTT[i-1] + a * RTT
-
- 0 < a < 1; usually a = 1/8
-
- RTO = 2 * SRTT
-
- where:
- RTT is Round Trip Time
- SRTT is Smoothed RTT
- RTO is Retransmit timeout
-
- A Smoothed RTT will increase quickly, but it is conservative when
- becoming smaller. */
-
- for(
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- ( pxIterator != ( const ListItem_t * ) pxEnd ) && ( xSequenceLessThan( ulSequenceNumber, ulLast ) != 0 );
- )
- {
- xDoUnlink = pdFALSE;
- pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
-
- /* Move to the next item because the current item might get
- removed. */
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
-
- /* Continue if this segment does not fall within the ACK'd range. */
- if( xSequenceGreaterThan( ulSequenceNumber, pxSegment->ulSequenceNumber ) != pdFALSE )
- {
- continue;
- }
-
- /* Is it ready? */
- if( ulSequenceNumber != pxSegment->ulSequenceNumber )
- {
- break;
- }
-
- ulDataLength = ( uint32_t ) pxSegment->lDataLength;
-
- if( pxSegment->u.bits.bAcked == pdFALSE_UNSIGNED )
- {
- if( xSequenceGreaterThan( pxSegment->ulSequenceNumber + ( uint32_t )ulDataLength, ulLast ) != pdFALSE )
- {
- /* What happens? Only part of this segment was accepted,
- probably due to WND limits
-
- AAAAAAA BBBBBBB << acked
- aaaaaaa aaaa << sent */
- #if( ipconfigHAS_DEBUG_PRINTF != 0 )
- {
- uint32_t ulFirstSeq = pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber;
- FreeRTOS_debug_printf( ( "prvTCPWindowTxCheckAck[%u.%u]: %lu - %lu Partial sequence number %lu - %lu\n",
- pxWindow->usPeerPortNumber,
- pxWindow->usOurPortNumber,
- ulFirstSeq - pxWindow->tx.ulFirstSequenceNumber,
- ulLast - pxWindow->tx.ulFirstSequenceNumber,
- ulFirstSeq, ulFirstSeq + ulDataLength ) );
- }
- #endif /* ipconfigHAS_DEBUG_PRINTF */
- break;
- }
-
- /* This segment is fully ACK'd, set the flag. */
- pxSegment->u.bits.bAcked = pdTRUE_UNSIGNED;
-
- /* Calculate the RTT only if the segment was sent-out for the
- first time and if this is the last ACK'd segment in a range. */
- if( ( pxSegment->u.bits.ucTransmitCount == 1 ) && ( ( pxSegment->ulSequenceNumber + ulDataLength ) == ulLast ) )
- {
- int32_t mS = ( int32_t ) ulTimerGetAge( &( pxSegment->xTransmitTimer ) );
-
- if( pxWindow->lSRTT >= mS )
- {
- /* RTT becomes smaller: adapt slowly. */
- pxWindow->lSRTT = ( ( winSRTT_DECREMENT_NEW * mS ) + ( winSRTT_DECREMENT_CURRENT * pxWindow->lSRTT ) ) / ( winSRTT_DECREMENT_NEW + winSRTT_DECREMENT_CURRENT );
- }
- else
- {
- /* RTT becomes larger: adapt quicker */
- pxWindow->lSRTT = ( ( winSRTT_INCREMENT_NEW * mS ) + ( winSRTT_INCREMENT_CURRENT * pxWindow->lSRTT ) ) / ( winSRTT_INCREMENT_NEW + winSRTT_INCREMENT_CURRENT );
- }
-
- /* Cap to the minimum of 50ms. */
- if( pxWindow->lSRTT < winSRTT_CAP_mS )
- {
- pxWindow->lSRTT = winSRTT_CAP_mS;
- }
- }
-
- /* Unlink it from the 3 queues, but do not destroy it (yet). */
- xDoUnlink = pdTRUE;
- }
-
- /* pxSegment->u.bits.bAcked is now true. Is it located at the left
- side of the transmission queue? If so, it may be freed. */
- if( ulSequenceNumber == pxWindow->tx.ulCurrentSequenceNumber )
- {
- if( ( xTCPWindowLoggingLevel >= 2 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "prvTCPWindowTxCheckAck: %lu - %lu Ready sequence number %lu\n",
- ulFirst - pxWindow->tx.ulFirstSequenceNumber,
- ulLast - pxWindow->tx.ulFirstSequenceNumber,
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber ) );
- }
-
- /* Increase the left-hand value of the transmission window. */
- pxWindow->tx.ulCurrentSequenceNumber += ulDataLength;
-
- /* This function will return the number of bytes that the tail
- of txStream may be advanced. */
- ulBytesConfirmed += ulDataLength;
-
- /* All segments below tx.ulCurrentSequenceNumber may be freed. */
- vTCPWindowFree( pxSegment );
-
- /* No need to unlink it any more. */
- xDoUnlink = pdFALSE;
- }
-
- if( ( xDoUnlink != pdFALSE ) && ( listLIST_ITEM_CONTAINER( &( pxSegment->xQueueItem ) ) != NULL ) )
- {
- /* Remove item from its queues. */
- uxListRemove( &pxSegment->xQueueItem );
- }
-
- ulSequenceNumber += ulDataLength;
- }
-
- return ulBytesConfirmed;
- }
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- static uint32_t prvTCPWindowFastRetransmit( TCPWindow_t *pxWindow, uint32_t ulFirst )
- {
- const ListItem_t *pxIterator;
- const MiniListItem_t* pxEnd;
- TCPSegment_t *pxSegment;
- uint32_t ulCount = 0UL;
-
- /* A higher Tx block has been acknowledged. Now iterate through the
- xWaitQueue to find a possible condition for a FAST retransmission. */
-
- pxEnd = ( const MiniListItem_t* ) listGET_END_MARKER( &( pxWindow->xWaitQueue ) );
-
- for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
- pxIterator != ( const ListItem_t * ) pxEnd; )
- {
- /* Get the owner, which is a TCP segment. */
- pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
-
- /* Hop to the next item before the current gets unlinked. */
- pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
-
- /* Fast retransmission:
- When 3 packets with a higher sequence number have been acknowledged
- by the peer, it is very unlikely a current packet will ever arrive.
- It will be retransmitted far before the RTO. */
- if( ( pxSegment->u.bits.bAcked == pdFALSE_UNSIGNED ) &&
- ( xSequenceLessThan( pxSegment->ulSequenceNumber, ulFirst ) != pdFALSE ) &&
- ( ++( pxSegment->u.bits.ucDupAckCount ) == DUPLICATE_ACKS_BEFORE_FAST_RETRANSMIT ) )
- {
- pxSegment->u.bits.ucTransmitCount = pdFALSE_UNSIGNED;
-
- /* Not clearing 'ucDupAckCount' yet as more SACK's might come in
- which might lead to a second fast rexmit. */
- if( ( xTCPWindowLoggingLevel >= 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "prvTCPWindowFastRetransmit: Requeue sequence number %lu < %lu\n",
- pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- ulFirst - pxWindow->tx.ulFirstSequenceNumber ) );
- FreeRTOS_flush_logging( );
- }
-
- /* Remove it from xWaitQueue. */
- uxListRemove( &pxSegment->xQueueItem );
-
- /* Add this segment to the priority queue so it gets
- retransmitted immediately. */
- vListInsertFifo( &( pxWindow->xPriorityQueue ), &( pxSegment->xQueueItem ) );
- ulCount++;
- }
- }
-
- return ulCount;
- }
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber )
- {
- uint32_t ulFirstSequence, ulReturn;
-
- /* Receive a normal ACK. */
-
- ulFirstSequence = pxWindow->tx.ulCurrentSequenceNumber;
-
- if( xSequenceLessThanOrEqual( ulSequenceNumber, ulFirstSequence ) != pdFALSE )
- {
- ulReturn = 0UL;
- }
- else
- {
- ulReturn = prvTCPWindowTxCheckAck( pxWindow, ulFirstSequence, ulSequenceNumber );
- }
-
- return ulReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 1 )
-
- uint32_t ulTCPWindowTxSack( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast )
- {
- uint32_t ulAckCount = 0UL;
- uint32_t ulCurrentSequenceNumber = pxWindow->tx.ulCurrentSequenceNumber;
-
- /* Receive a SACK option. */
- ulAckCount = prvTCPWindowTxCheckAck( pxWindow, ulFirst, ulLast );
- prvTCPWindowFastRetransmit( pxWindow, ulFirst );
-
- if( ( xTCPWindowLoggingLevel >= 1 ) && ( xSequenceGreaterThan( ulFirst, ulCurrentSequenceNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "ulTCPWindowTxSack[%u,%u]: from %lu to %lu (ack = %lu)\n",
- pxWindow->usPeerPortNumber,
- pxWindow->usOurPortNumber,
- ulFirst - pxWindow->tx.ulFirstSequenceNumber,
- ulLast - pxWindow->tx.ulFirstSequenceNumber,
- pxWindow->tx.ulCurrentSequenceNumber - pxWindow->tx.ulFirstSequenceNumber ) );
- FreeRTOS_flush_logging( );
- }
-
- return ulAckCount;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 1 */
-/*-----------------------------------------------------------*/
-
-/*
-##### # ##### #### ######
-# # # # # # # # # # #
- # # # # # #
- # ### ##### # # # # # #
- # # # # # # # # #####
- # # # # # # #### # # #
- # # # # # # # # # #
- # # # # #### # # # #
- #### ##### # # # #### #### ####
- #
- ###
-*/
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace )
- {
- int32_t iReturn;
-
- /* Data was received at 'ulSequenceNumber'. See if it was expected
- and if there is enough space to store the new data. */
- if( ( pxWindow->rx.ulCurrentSequenceNumber != ulSequenceNumber ) || ( ulSpace < ulLength ) )
- {
- iReturn = -1;
- }
- else
- {
- pxWindow->rx.ulCurrentSequenceNumber += ( uint32_t ) ulLength;
- iReturn = 0;
- }
-
- return iReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax )
- {
- TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
- int32_t lResult;
-
- /* Data is being scheduled for transmission. */
-
- /* lMax would indicate the size of the txStream. */
- ( void ) lMax;
- /* This is tiny TCP: there is only 1 segment for outgoing data.
- As long as 'lDataLength' is unequal to zero, the segment is still occupied. */
- if( pxSegment->lDataLength > 0 )
- {
- lResult = 0L;
- }
- else
- {
- if( ulLength > ( uint32_t ) pxSegment->lMaxLength )
- {
- if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: can only store %ld / %ld bytes\n", ulLength, pxSegment->lMaxLength ) );
- }
-
- ulLength = ( uint32_t ) pxSegment->lMaxLength;
- }
-
- if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: SeqNr %ld (%ld) Len %ld\n",
- pxWindow->ulNextTxSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxWindow->tx.ulCurrentSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- ulLength ) );
- }
-
- /* The sequence number of the first byte in this packet. */
- pxSegment->ulSequenceNumber = pxWindow->ulNextTxSequenceNumber;
- pxSegment->lDataLength = ( int32_t ) ulLength;
- pxSegment->lStreamPos = lPosition;
- pxSegment->u.ulFlags = 0UL;
- vTCPTimerSet( &( pxSegment->xTransmitTimer ) );
-
- /* Increase the sequence number of the next data to be stored for
- transmission. */
- pxWindow->ulNextTxSequenceNumber += ulLength;
- lResult = ( int32_t )ulLength;
- }
-
- return lResult;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition )
- {
- TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
- uint32_t ulLength = ( uint32_t ) pxSegment->lDataLength;
- uint32_t ulMaxTime;
-
- if( ulLength != 0UL )
- {
- /* _HT_ Still under investigation */
- ( void ) ulWindowSize;
-
- if( pxSegment->u.bits.bOutstanding != pdFALSE_UNSIGNED )
- {
- /* As 'ucTransmitCount' has a minimum of 1, take 2 * RTT */
- ulMaxTime = ( ( uint32_t ) 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
-
- if( ulTimerGetAge( &( pxSegment->xTransmitTimer ) ) < ulMaxTime )
- {
- ulLength = 0ul;
- }
- }
-
- if( ulLength != 0ul )
- {
- pxSegment->u.bits.bOutstanding = pdTRUE_UNSIGNED;
- pxSegment->u.bits.ucTransmitCount++;
- vTCPTimerSet (&pxSegment->xTransmitTimer);
- pxWindow->ulOurSequenceNumber = pxSegment->ulSequenceNumber;
- *plPosition = pxSegment->lStreamPos;
- }
- }
-
- return ulLength;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow )
- {
- BaseType_t xReturn;
-
- /* Has the outstanding data been sent because user wants to shutdown? */
- if( pxWindow->xTxSegment.lDataLength == 0 )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize );
- static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize )
- {
- BaseType_t xReturn;
-
- if( ulWindowSize >= pxWindow->usMSSInit )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay )
- {
- TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
- BaseType_t xReturn;
- TickType_t ulAge, ulMaxAge;
-
- /* Check data to be sent. */
- *pulDelay = ( TickType_t ) 0;
- if( pxSegment->lDataLength == 0 )
- {
- /* Got nothing to send right now. */
- xReturn = pdFALSE;
- }
- else
- {
- if( pxSegment->u.bits.bOutstanding != pdFALSE_UNSIGNED )
- {
- ulAge = ulTimerGetAge ( &pxSegment->xTransmitTimer );
- ulMaxAge = ( ( TickType_t ) 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
-
- if( ulMaxAge > ulAge )
- {
- *pulDelay = ulMaxAge - ulAge;
- }
-
- xReturn = pdTRUE;
- }
- else if( prvTCPWindowTxHasSpace( pxWindow, ulWindowSize ) == pdFALSE )
- {
- /* Too many outstanding messages. */
- xReturn = pdFALSE;
- }
- else
- {
- xReturn = pdTRUE;
- }
- }
-
- return xReturn;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber )
- {
- TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
- uint32_t ulDataLength = ( uint32_t ) pxSegment->lDataLength;
-
- /* Receive a normal ACK */
-
- if( ulDataLength != 0ul )
- {
- if( ulSequenceNumber < ( pxWindow->tx.ulCurrentSequenceNumber + ulDataLength ) )
- {
- if( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE )
- {
- FreeRTOS_debug_printf( ( "win_tx_ack: acked %ld expc %ld len %ld\n",
- ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- pxWindow->tx.ulCurrentSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- ulDataLength ) );
- }
-
- /* Nothing to send right now. */
- ulDataLength = 0ul;
- }
- else
- {
- pxWindow->tx.ulCurrentSequenceNumber += ulDataLength;
-
- if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
- {
- FreeRTOS_debug_printf( ( "win_tx_ack: acked seqnr %ld len %ld\n",
- ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
- ulDataLength ) );
- }
-
- pxSegment->lDataLength = 0;
- }
- }
-
- return ulDataLength;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow )
- {
- /* Return true if 'ulCurrentSequenceNumber >= ulHighestSequenceNumber'
- 'ulCurrentSequenceNumber' is the highest sequence number stored,
- 'ulHighestSequenceNumber' is the highest sequence number seen. */
- return xSequenceGreaterThanOrEqual( pxWindow->rx.ulCurrentSequenceNumber, pxWindow->rx.ulHighestSequenceNumber );
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-#if( ipconfigUSE_TCP_WIN == 0 )
-
- /* Destroy a window (always returns NULL) */
- void vTCPWindowDestroy( TCPWindow_t *pxWindow )
- {
- /* As in tiny TCP there are no shared segments descriptors, there is
- nothing to release. */
- ( void ) pxWindow;
- }
-
-#endif /* ipconfigUSE_TCP_WIN == 0 */
-/*-----------------------------------------------------------*/
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
+ * FreeRTOS_TCP_WIN.c
+ * Module which handles the TCP windowing schemes for FreeRTOS+TCP. Many
+ * functions have two versions - one for FreeRTOS+TCP (full) and one for
+ * FreeRTOS+TCP (lite).
+ *
+ * In this module all ports and IP addresses and sequence numbers are
+ * being stored in host byte-order.
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "FreeRTOS_TCP_WIN.h"
+
+/* Constants used for Smoothed Round Trip Time (SRTT). */
+#define winSRTT_INCREMENT_NEW 2
+#define winSRTT_INCREMENT_CURRENT 6
+#define winSRTT_DECREMENT_NEW 1
+#define winSRTT_DECREMENT_CURRENT 7
+#define winSRTT_CAP_mS 50
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ #define xTCPWindowRxNew( pxWindow, ulSequenceNumber, lCount ) xTCPWindowNew( pxWindow, ulSequenceNumber, lCount, pdTRUE )
+
+ #define xTCPWindowTxNew( pxWindow, ulSequenceNumber, lCount ) xTCPWindowNew( pxWindow, ulSequenceNumber, lCount, pdFALSE )
+
+ /* The code to send a single Selective ACK (SACK):
+ * NOP (0x01), NOP (0x01), SACK (0x05), LEN (0x0a),
+ * followed by a lower and a higher sequence number,
+ * where LEN is 2 + 2*4 = 10 bytes. */
+ #if( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
+ #define OPTION_CODE_SINGLE_SACK ( 0x0101050aUL )
+ #else
+ #define OPTION_CODE_SINGLE_SACK ( 0x0a050101UL )
+ #endif
+
+ /* Normal retransmission:
+ * A packet will be retransmitted after a Retransmit Time-Out (RTO).
+ * Fast retransmission:
+ * When 3 packets with a higher sequence number have been acknowledged
+ * by the peer, it is very unlikely a current packet will ever arrive.
+ * It will be retransmitted far before the RTO.
+ */
+ #define DUPLICATE_ACKS_BEFORE_FAST_RETRANSMIT ( 3u )
+
+ /* If there have been several retransmissions (4), decrease the
+ * size of the transmission window to at most 2 times MSS.
+ */
+ #define MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW ( 4u )
+
+#endif /* configUSE_TCP_WIN */
+/*-----------------------------------------------------------*/
+
+extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere );
+
+/*
+ * All TCP sockets share a pool of segment descriptors (TCPSegment_t)
+ * Available descriptors are stored in the 'xSegmentList'
+ * When a socket owns a descriptor, it will either be stored in
+ * 'xTxSegments' or 'xRxSegments'
+ * As soon as a package has been confirmed, the descriptor will be returned
+ * to the segment pool
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static BaseType_t prvCreateSectors( void );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * Find a segment with a given sequence number in the list of received
+ * segments: 'pxWindow->xRxSegments'.
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static TCPSegment_t *xTCPWindowRxFind( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * Allocate a new segment
+ * The socket will borrow all segments from a common pool: 'xSegmentList',
+ * which is a list of 'TCPSegment_t'
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static TCPSegment_t *xTCPWindowNew( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, int32_t lCount, BaseType_t xIsForRx );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/* When the peer has a close request (FIN flag), the driver will check if
+ * there are missing packets in the Rx-queue
+ * It will accept the closure of the connection if both conditions are true:
+ * - the Rx-queue is empty
+ * - we've ACK'd the highest Rx sequence number seen
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * Detaches and returns the head of a queue
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static TCPSegment_t *xTCPWindowGetHead( List_t *pxList );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * Returns the head of a queue but it won't be detached
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static TCPSegment_t *xTCPWindowPeekHead( List_t *pxList );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * Free entry pxSegment because it's not used anymore
+ * The ownership will be passed back to the segment pool
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static void vTCPWindowFree( TCPSegment_t *pxSegment );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * A segment has been received with sequence number 'ulSequenceNumber', where
+ * 'ulCurrentSequenceNumber == ulSequenceNumber', which means that exactly this
+ * segment was expected. xTCPWindowRxConfirm() will check if there is already
+ * another segment with a sequence number between (ulSequenceNumber) and
+ * (ulSequenceNumber+xLength). Normally none will be found, because the next Rx
+ * segment should have a sequence number equal to '(ulSequenceNumber+xLength)'.
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static TCPSegment_t *xTCPWindowRxConfirm( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * FreeRTOS+TCP stores data in circular buffers. Calculate the next position to
+ * store.
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static int32_t lTCPIncrementTxPosition( int32_t lPosition, int32_t lMax, int32_t lCount );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * This function will look if there is new transmission data. It will return
+ * true if there is data to be sent.
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * An acknowledge was received. See if some outstanding data may be removed
+ * from the transmission queue(s).
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static uint32_t prvTCPWindowTxCheckAck( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*
+ * A higher Tx block has been acknowledged. Now iterate through the xWaitQueue
+ * to find a possible condition for a FAST retransmission.
+ */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static uint32_t prvTCPWindowFastRetransmit( TCPWindow_t *pxWindow, uint32_t ulFirst );
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/*-----------------------------------------------------------*/
+
+/* TCP segment pool. */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static TCPSegment_t *xTCPSegments = NULL;
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+
+/* List of free TCP segments. */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static List_t xSegmentList;
+#endif
+
+/* Logging verbosity level. */
+BaseType_t xTCPWindowLoggingLevel = 0;
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+ /* Some 32-bit arithmetic: comparing sequence numbers */
+ static portINLINE BaseType_t xSequenceLessThanOrEqual( uint32_t a, uint32_t b );
+ static portINLINE BaseType_t xSequenceLessThanOrEqual( uint32_t a, uint32_t b )
+ {
+ /* Test if a <= b
+ Return true if the unsigned subtraction of (b-a) doesn't generate an
+ arithmetic overflow. */
+ return ( ( b - a ) & 0x80000000UL ) == 0UL;
+ }
+#endif /* ipconfigUSE_TCP_WIN */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static portINLINE BaseType_t xSequenceLessThan( uint32_t a, uint32_t b );
+ static portINLINE BaseType_t xSequenceLessThan( uint32_t a, uint32_t b )
+ {
+ /* Test if a < b */
+ return ( ( b - a - 1UL ) & 0x80000000UL ) == 0UL;
+ }
+#endif /* ipconfigUSE_TCP_WIN */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static portINLINE BaseType_t xSequenceGreaterThan( uint32_t a, uint32_t b );
+ static portINLINE BaseType_t xSequenceGreaterThan( uint32_t a, uint32_t b )
+ {
+ /* Test if a > b */
+ return ( ( a - b - 1UL ) & 0x80000000UL ) == 0UL;
+ }
+#endif /* ipconfigUSE_TCP_WIN */
+
+/*-----------------------------------------------------------*/
+static portINLINE BaseType_t xSequenceGreaterThanOrEqual( uint32_t a, uint32_t b );
+static portINLINE BaseType_t xSequenceGreaterThanOrEqual( uint32_t a, uint32_t b )
+{
+ /* Test if a >= b */
+ return ( ( a - b ) & 0x80000000UL ) == 0UL;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+ static portINLINE void vListInsertFifo( List_t * const pxList, ListItem_t * const pxNewListItem );
+ static portINLINE void vListInsertFifo( List_t * const pxList, ListItem_t * const pxNewListItem )
+ {
+ vListInsertGeneric( pxList, pxNewListItem, &pxList->xListEnd );
+ }
+#endif
+/*-----------------------------------------------------------*/
+
+static portINLINE void vTCPTimerSet( TCPTimer_t *pxTimer );
+static portINLINE void vTCPTimerSet( TCPTimer_t *pxTimer )
+{
+ pxTimer->ulBorn = xTaskGetTickCount ( );
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE uint32_t ulTimerGetAge( TCPTimer_t *pxTimer );
+static portINLINE uint32_t ulTimerGetAge( TCPTimer_t *pxTimer )
+{
+ return ( ( xTaskGetTickCount() - pxTimer->ulBorn ) * portTICK_PERIOD_MS );
+}
+/*-----------------------------------------------------------*/
+
+/* _HT_ GCC (using the settings that I'm using) checks for every public function if it is
+preceded by a prototype. Later this prototype will be located in list.h? */
+
+extern void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere );
+
+void vListInsertGeneric( List_t * const pxList, ListItem_t * const pxNewListItem, MiniListItem_t * const pxWhere )
+{
+ /* Insert a new list item into pxList, it does not sort the list,
+ but it puts the item just before xListEnd, so it will be the last item
+ returned by listGET_HEAD_ENTRY() */
+ pxNewListItem->pxNext = (struct xLIST_ITEM * configLIST_VOLATILE)pxWhere;
+ pxNewListItem->pxPrevious = pxWhere->pxPrevious;
+ pxWhere->pxPrevious->pxNext = pxNewListItem;
+ pxWhere->pxPrevious = pxNewListItem;
+
+ /* Remember which list the item is in. */
+ listLIST_ITEM_CONTAINER( pxNewListItem ) = ( void * ) pxList;
+
+ ( pxList->uxNumberOfItems )++;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static BaseType_t prvCreateSectors( void )
+ {
+ BaseType_t xIndex, xReturn;
+
+ /* Allocate space for 'xTCPSegments' and store them in 'xSegmentList'. */
+
+ vListInitialise( &xSegmentList );
+ xTCPSegments = ( TCPSegment_t * ) pvPortMallocLarge( ipconfigTCP_WIN_SEG_COUNT * sizeof( xTCPSegments[ 0 ] ) );
+
+ if( xTCPSegments == NULL )
+ {
+ FreeRTOS_debug_printf( ( "prvCreateSectors: malloc %lu failed\n",
+ ipconfigTCP_WIN_SEG_COUNT * sizeof( xTCPSegments[ 0 ] ) ) );
+
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ /* Clear the allocated space. */
+ memset( xTCPSegments, '\0', ipconfigTCP_WIN_SEG_COUNT * sizeof( xTCPSegments[ 0 ] ) );
+
+ for( xIndex = 0; xIndex < ipconfigTCP_WIN_SEG_COUNT; xIndex++ )
+ {
+ /* Could call vListInitialiseItem here but all data has been
+ nulled already. Set the owner to a segment descriptor. */
+ listSET_LIST_ITEM_OWNER( &( xTCPSegments[ xIndex ].xListItem ), ( void* ) &( xTCPSegments[ xIndex ] ) );
+ listSET_LIST_ITEM_OWNER( &( xTCPSegments[ xIndex ].xQueueItem ), ( void* ) &( xTCPSegments[ xIndex ] ) );
+
+ /* And add it to the pool of available segments */
+ vListInsertFifo( &xSegmentList, &( xTCPSegments[xIndex].xListItem ) );
+ }
+
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static TCPSegment_t *xTCPWindowRxFind( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber )
+ {
+ const ListItem_t *pxIterator;
+ const MiniListItem_t* pxEnd;
+ TCPSegment_t *pxSegment, *pxReturn = NULL;
+
+ /* Find a segment with a given sequence number in the list of received
+ segments. */
+
+ pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &pxWindow->xRxSegments );
+
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
+ pxIterator != ( const ListItem_t * ) pxEnd;
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ if( pxSegment->ulSequenceNumber == ulSequenceNumber )
+ {
+ pxReturn = pxSegment;
+ break;
+ }
+ }
+
+ return pxReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static TCPSegment_t *xTCPWindowNew( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, int32_t lCount, BaseType_t xIsForRx )
+ {
+ TCPSegment_t *pxSegment;
+ ListItem_t * pxItem;
+
+ /* Allocate a new segment. The socket will borrow all segments from a
+ common pool: 'xSegmentList', which is a list of 'TCPSegment_t' */
+ if( listLIST_IS_EMPTY( &xSegmentList ) != pdFALSE )
+ {
+ /* If the TCP-stack runs out of segments, you might consider
+ increasing 'ipconfigTCP_WIN_SEG_COUNT'. */
+ FreeRTOS_debug_printf( ( "xTCPWindow%cxNew: Error: all segments occupied\n", xIsForRx ? 'R' : 'T' ) );
+ pxSegment = NULL;
+ }
+ else
+ {
+ /* Pop the item at the head of the list. Semaphore protection is
+ not required as only the IP task will call these functions. */
+ pxItem = ( ListItem_t * ) listGET_HEAD_ENTRY( &xSegmentList );
+ pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxItem );
+
+ configASSERT( pxItem != NULL );
+ configASSERT( pxSegment != NULL );
+
+ /* Remove the item from xSegmentList. */
+ uxListRemove( pxItem );
+
+ /* Add it to either the connections' Rx or Tx queue. */
+ vListInsertFifo( xIsForRx ? &pxWindow->xRxSegments : &pxWindow->xTxSegments, pxItem );
+
+ /* And set the segment's timer to zero */
+ vTCPTimerSet( &pxSegment->xTransmitTimer );
+
+ pxSegment->u.ulFlags = 0;
+ pxSegment->u.bits.bIsForRx = ( xIsForRx != 0 );
+ pxSegment->lMaxLength = lCount;
+ pxSegment->lDataLength = lCount;
+ pxSegment->ulSequenceNumber = ulSequenceNumber;
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ static UBaseType_t xLowestLength = ipconfigTCP_WIN_SEG_COUNT;
+ UBaseType_t xLength = listCURRENT_LIST_LENGTH( &xSegmentList );
+
+ if( xLowestLength > xLength )
+ {
+ xLowestLength = xLength;
+ }
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF */
+ }
+
+ return pxSegment;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow )
+ {
+ BaseType_t xReturn;
+
+ /* When the peer has a close request (FIN flag), the driver will check
+ if there are missing packets in the Rx-queue. It will accept the
+ closure of the connection if both conditions are true:
+ - the Rx-queue is empty
+ - the highest Rx sequence number has been ACK'ed */
+ if( listLIST_IS_EMPTY( ( &pxWindow->xRxSegments ) ) == pdFALSE )
+ {
+ /* Rx data has been stored while earlier packets were missing. */
+ xReturn = pdFALSE;
+ }
+ else if( xSequenceGreaterThanOrEqual( pxWindow->rx.ulCurrentSequenceNumber, pxWindow->rx.ulHighestSequenceNumber ) != pdFALSE )
+ {
+ /* No Rx packets are being stored and the highest sequence number
+ that has been received has been ACKed. */
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "xTCPWindowRxEmpty: cur %lu highest %lu (empty)\n",
+ ( pxWindow->rx.ulCurrentSequenceNumber - pxWindow->rx.ulFirstSequenceNumber ),
+ ( pxWindow->rx.ulHighestSequenceNumber - pxWindow->rx.ulFirstSequenceNumber ) ) );
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static TCPSegment_t *xTCPWindowGetHead( List_t *pxList )
+ {
+ TCPSegment_t *pxSegment;
+ ListItem_t * pxItem;
+
+ /* Detaches and returns the head of a queue. */
+ if( listLIST_IS_EMPTY( pxList ) != pdFALSE )
+ {
+ pxSegment = NULL;
+ }
+ else
+ {
+ pxItem = ( ListItem_t * ) listGET_HEAD_ENTRY( pxList );
+ pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxItem );
+
+ uxListRemove( pxItem );
+ }
+
+ return pxSegment;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static TCPSegment_t *xTCPWindowPeekHead( List_t *pxList )
+ {
+ ListItem_t *pxItem;
+ TCPSegment_t *pxReturn;
+
+ /* Returns the head of a queue but it won't be detached. */
+ if( listLIST_IS_EMPTY( pxList ) != pdFALSE )
+ {
+ pxReturn = NULL;
+ }
+ else
+ {
+ pxItem = ( ListItem_t * ) listGET_HEAD_ENTRY( pxList );
+ pxReturn = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxItem );
+ }
+
+ return pxReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static void vTCPWindowFree( TCPSegment_t *pxSegment )
+ {
+ /* Free entry pxSegment because it's not used any more. The ownership
+ will be passed back to the segment pool.
+
+ Unlink it from one of the queues, if any. */
+ if( listLIST_ITEM_CONTAINER( &( pxSegment->xQueueItem ) ) != NULL )
+ {
+ uxListRemove( &( pxSegment->xQueueItem ) );
+ }
+
+ pxSegment->ulSequenceNumber = 0u;
+ pxSegment->lDataLength = 0l;
+ pxSegment->u.ulFlags = 0u;
+
+ /* Take it out of xRxSegments/xTxSegments */
+ if( listLIST_ITEM_CONTAINER( &( pxSegment->xListItem ) ) != NULL )
+ {
+ uxListRemove( &( pxSegment->xListItem ) );
+ }
+
+ /* Return it to xSegmentList */
+ vListInsertFifo( &xSegmentList, &( pxSegment->xListItem ) );
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ void vTCPWindowDestroy( TCPWindow_t *pxWindow )
+ {
+ List_t * pxSegments;
+ BaseType_t xRound;
+ TCPSegment_t *pxSegment;
+
+ /* Destroy a window. A TCP window doesn't serve any more. Return all
+ owned segments to the pool. In order to save code, it will make 2 rounds,
+ one to remove the segments from xRxSegments, and a second round to clear
+ xTxSegments*/
+ for( xRound = 0; xRound < 2; xRound++ )
+ {
+ if( xRound != 0 )
+ {
+ pxSegments = &( pxWindow->xRxSegments );
+ }
+ else
+ {
+ pxSegments = &( pxWindow->xTxSegments );
+ }
+
+ if( listLIST_IS_INITIALISED( pxSegments ) != pdFALSE )
+ {
+ while( listCURRENT_LIST_LENGTH( pxSegments ) > 0U )
+ {
+ pxSegment = ( TCPSegment_t * ) listGET_OWNER_OF_HEAD_ENTRY( pxSegments );
+ vTCPWindowFree( pxSegment );
+ }
+ }
+ }
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
+ uint32_t ulTxWindowLength, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS )
+{
+ /* Create and initialize a window. */
+
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ {
+ if( xTCPSegments == NULL )
+ {
+ prvCreateSectors();
+ }
+
+ vListInitialise( &pxWindow->xTxSegments );
+ vListInitialise( &pxWindow->xRxSegments );
+
+ vListInitialise( &pxWindow->xPriorityQueue ); /* Priority queue: segments which must be sent immediately */
+ vListInitialise( &pxWindow->xTxQueue ); /* Transmit queue: segments queued for transmission */
+ vListInitialise( &pxWindow->xWaitQueue ); /* Waiting queue: outstanding segments */
+ }
+ #endif /* ipconfigUSE_TCP_WIN == 1 */
+
+ if( xTCPWindowLoggingLevel != 0 )
+ {
+ FreeRTOS_debug_printf( ( "vTCPWindowCreate: for WinLen = Rx/Tx: %lu/%lu\n",
+ ulRxWindowLength, ulTxWindowLength ) );
+ }
+
+ pxWindow->xSize.ulRxWindowLength = ulRxWindowLength;
+ pxWindow->xSize.ulTxWindowLength = ulTxWindowLength;
+
+ vTCPWindowInit( pxWindow, ulAckNumber, ulSequenceNumber, ulMSS );
+}
+/*-----------------------------------------------------------*/
+
+void vTCPWindowInit( TCPWindow_t *pxWindow, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS )
+{
+const int32_t l500ms = 500;
+
+ pxWindow->u.ulFlags = 0ul;
+ pxWindow->u.bits.bHasInit = pdTRUE_UNSIGNED;
+
+ if( ulMSS != 0ul )
+ {
+ if( pxWindow->usMSSInit != 0u )
+ {
+ pxWindow->usMSSInit = ( uint16_t ) ulMSS;
+ }
+
+ if( ( ulMSS < ( uint32_t ) pxWindow->usMSS ) || ( pxWindow->usMSS == 0u ) )
+ {
+ pxWindow->xSize.ulRxWindowLength = ( pxWindow->xSize.ulRxWindowLength / ulMSS ) * ulMSS;
+ pxWindow->usMSS = ( uint16_t ) ulMSS;
+ }
+ }
+
+ #if( ipconfigUSE_TCP_WIN == 0 )
+ {
+ pxWindow->xTxSegment.lMaxLength = ( int32_t ) pxWindow->usMSS;
+ }
+ #endif /* ipconfigUSE_TCP_WIN == 1 */
+
+ /*Start with a timeout of 2 * 500 ms (1 sec). */
+ pxWindow->lSRTT = l500ms;
+
+ /* Just for logging, to print relative sequence numbers. */
+ pxWindow->rx.ulFirstSequenceNumber = ulAckNumber;
+
+ /* The segment asked for in the next transmission. */
+ pxWindow->rx.ulCurrentSequenceNumber = ulAckNumber;
+
+ /* The right-hand side of the receive window. */
+ pxWindow->rx.ulHighestSequenceNumber = ulAckNumber;
+
+ pxWindow->tx.ulFirstSequenceNumber = ulSequenceNumber;
+
+ /* The segment asked for in next transmission. */
+ pxWindow->tx.ulCurrentSequenceNumber = ulSequenceNumber;
+
+ /* The sequence number given to the next outgoing byte to be added is
+ maintained by lTCPWindowTxAdd(). */
+ pxWindow->ulNextTxSequenceNumber = ulSequenceNumber;
+
+ /* The right-hand side of the transmit window. */
+ pxWindow->tx.ulHighestSequenceNumber = ulSequenceNumber;
+ pxWindow->ulOurSequenceNumber = ulSequenceNumber;
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ void vTCPSegmentCleanup( void )
+ {
+ /* Free and clear the TCP segments pointer. This function should only be called
+ * once FreeRTOS+TCP will no longer be used. No thread-safety is provided for this
+ * function. */
+ if( xTCPSegments != NULL )
+ {
+ vPortFreeLarge( xTCPSegments );
+ xTCPSegments = NULL;
+ }
+ }
+
+#endif /* ipconfgiUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+/*=============================================================================
+ *
+ * ###### # #
+ * # # # #
+ * # # # #
+ * # # ####
+ * ###### ##
+ * # ## ####
+ * # # # #
+ * # # # #
+ * ### ## # #
+ * Rx functions
+ *
+ *=============================================================================*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static TCPSegment_t *xTCPWindowRxConfirm( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength )
+ {
+ TCPSegment_t *pxBest = NULL;
+ const ListItem_t *pxIterator;
+ uint32_t ulNextSequenceNumber = ulSequenceNumber + ulLength;
+ const MiniListItem_t* pxEnd = ( const MiniListItem_t* ) listGET_END_MARKER( &pxWindow->xRxSegments );
+ TCPSegment_t *pxSegment;
+
+ /* A segment has been received with sequence number 'ulSequenceNumber',
+ where 'ulCurrentSequenceNumber == ulSequenceNumber', which means that
+ exactly this segment was expected. xTCPWindowRxConfirm() will check if
+ there is already another segment with a sequence number between (ulSequenceNumber)
+ and (ulSequenceNumber+ulLength). Normally none will be found, because
+ the next RX segment should have a sequence number equal to
+ '(ulSequenceNumber+ulLength)'. */
+
+ /* Iterate through all RX segments that are stored: */
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
+ pxIterator != ( const ListItem_t * ) pxEnd;
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator ) )
+ {
+ pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+ /* And see if there is a segment for which:
+ 'ulSequenceNumber' <= 'pxSegment->ulSequenceNumber' < 'ulNextSequenceNumber'
+ If there are more matching segments, the one with the lowest sequence number
+ shall be taken */
+ if( ( xSequenceGreaterThanOrEqual( pxSegment->ulSequenceNumber, ulSequenceNumber ) != 0 ) &&
+ ( xSequenceLessThan( pxSegment->ulSequenceNumber, ulNextSequenceNumber ) != 0 ) )
+ {
+ if( ( pxBest == NULL ) || ( xSequenceLessThan( pxSegment->ulSequenceNumber, pxBest->ulSequenceNumber ) != 0 ) )
+ {
+ pxBest = pxSegment;
+ }
+ }
+ }
+
+ if( ( pxBest != NULL ) &&
+ ( ( pxBest->ulSequenceNumber != ulSequenceNumber ) || ( pxBest->lDataLength != ( int32_t ) ulLength ) ) )
+ {
+ FreeRTOS_flush_logging();
+ FreeRTOS_debug_printf( ( "xTCPWindowRxConfirm[%u]: search %lu (+%ld=%lu) found %lu (+%ld=%lu)\n",
+ pxWindow->usPeerPortNumber,
+ ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ ulLength,
+ ulSequenceNumber + ulLength - pxWindow->rx.ulFirstSequenceNumber,
+ pxBest->ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ pxBest->lDataLength,
+ pxBest->ulSequenceNumber + ( ( uint32_t ) pxBest->lDataLength ) - pxWindow->rx.ulFirstSequenceNumber ) );
+ }
+
+ return pxBest;
+ }
+
+#endif /* ipconfgiUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace )
+ {
+ uint32_t ulCurrentSequenceNumber, ulLast, ulSavedSequenceNumber;
+ int32_t lReturn, lDistance;
+ TCPSegment_t *pxFound;
+
+ /* If lTCPWindowRxCheck( ) returns == 0, the packet will be passed
+ directly to user (segment is expected). If it returns a positive
+ number, an earlier packet is missing, but this packet may be stored.
+ If negative, the packet has already been stored, or it is out-of-order,
+ or there is not enough space.
+
+ As a side-effect, pxWindow->ulUserDataLength will get set to non-zero,
+ if more Rx data may be passed to the user after this packet. */
+
+ ulCurrentSequenceNumber = pxWindow->rx.ulCurrentSequenceNumber;
+
+ /* For Selective Ack (SACK), used when out-of-sequence data come in. */
+ pxWindow->ucOptionLength = 0u;
+
+ /* Non-zero if TCP-windows contains data which must be popped. */
+ pxWindow->ulUserDataLength = 0ul;
+
+ if( ulCurrentSequenceNumber == ulSequenceNumber )
+ {
+ /* This is the packet with the lowest sequence number we're waiting
+ for. It can be passed directly to the rx stream. */
+ if( ulLength > ulSpace )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowRxCheck: Refuse %lu bytes, due to lack of space (%lu)\n", ulLength, ulSpace ) );
+ lReturn = -1;
+ }
+ else
+ {
+ ulCurrentSequenceNumber += ulLength;
+
+ if( listCURRENT_LIST_LENGTH( &( pxWindow->xRxSegments ) ) != 0 )
+ {
+ ulSavedSequenceNumber = ulCurrentSequenceNumber;
+
+ /* Clean up all sequence received between ulSequenceNumber and ulSequenceNumber + ulLength since they are duplicated.
+ If the server is forced to retransmit packets several time in a row it might send a batch of concatenated packet for speed.
+ So we cannot rely on the packets between ulSequenceNumber and ulSequenceNumber + ulLength to be sequential and it is better to just
+ clean them out. */
+ do
+ {
+ pxFound = xTCPWindowRxConfirm( pxWindow, ulSequenceNumber, ulLength );
+
+ if ( pxFound != NULL )
+ {
+ /* Remove it because it will be passed to user directly. */
+ vTCPWindowFree( pxFound );
+ }
+ } while ( pxFound );
+
+ /* Check for following segments that are already in the
+ queue and increment ulCurrentSequenceNumber. */
+ while( ( pxFound = xTCPWindowRxFind( pxWindow, ulCurrentSequenceNumber ) ) != NULL )
+ {
+ ulCurrentSequenceNumber += ( uint32_t ) pxFound->lDataLength;
+
+ /* As all packet below this one have been passed to the
+ user it can be discarded. */
+ vTCPWindowFree( pxFound );
+ }
+
+ if( ulSavedSequenceNumber != ulCurrentSequenceNumber )
+ {
+ /* After the current data-package, there is more data
+ to be popped. */
+ pxWindow->ulUserDataLength = ulCurrentSequenceNumber - ulSavedSequenceNumber;
+
+ if( xTCPWindowLoggingLevel >= 1 )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowRxCheck[%d,%d]: retran %lu (Found %lu bytes at %lu cnt %ld)\n",
+ pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
+ ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ pxWindow->ulUserDataLength,
+ ulSavedSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ listCURRENT_LIST_LENGTH( &pxWindow->xRxSegments ) ) );
+ }
+ }
+ }
+
+ pxWindow->rx.ulCurrentSequenceNumber = ulCurrentSequenceNumber;
+
+ /* Packet was expected, may be passed directly to the socket
+ buffer or application. Store the packet at offset 0. */
+ lReturn = 0;
+ }
+ }
+ else if( ulCurrentSequenceNumber == ( ulSequenceNumber + 1UL ) )
+ {
+ /* Looks like a TCP keep-alive message. Do not accept/store Rx data
+ ulUserDataLength = 0. Not packet out-of-sync. Just reply to it. */
+ lReturn = -1;
+ }
+ else
+ {
+ /* The packet is not the one expected. See if it falls within the Rx
+ window so it can be stored. */
+
+ /* An "out-of-sequence" segment was received, must have missed one.
+ Prepare a SACK (Selective ACK). */
+ ulLast = ulSequenceNumber + ulLength;
+ lDistance = ( int32_t ) ( ulLast - ulCurrentSequenceNumber );
+
+ if( lDistance <= 0 )
+ {
+ /* An earlier has been received, must be a retransmission of a
+ packet that has been accepted already. No need to send out a
+ Selective ACK (SACK). */
+ lReturn = -1;
+ }
+ else if( lDistance > ( int32_t ) ulSpace )
+ {
+ /* The new segment is ahead of rx.ulCurrentSequenceNumber. The
+ sequence number of this packet is too far ahead, ignore it. */
+ FreeRTOS_debug_printf( ( "lTCPWindowRxCheck: Refuse %lu+%lu bytes, due to lack of space (%lu)\n", lDistance, ulLength, ulSpace ) );
+ lReturn = -1;
+ }
+ else
+ {
+ /* See if there is more data in a contiguous block to make the
+ SACK describe a longer range of data. */
+
+ /* TODO: SACK's may also be delayed for a short period
+ * This is useful because subsequent packets will be SACK'd with
+ * single one message
+ */
+ while( ( pxFound = xTCPWindowRxFind( pxWindow, ulLast ) ) != NULL )
+ {
+ ulLast += ( uint32_t ) pxFound->lDataLength;
+ }
+
+ if( xTCPWindowLoggingLevel >= 1 )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowRxCheck[%d,%d]: seqnr %lu exp %lu (dist %ld) SACK to %lu\n",
+ pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
+ ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ ulCurrentSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ ( BaseType_t ) ( ulSequenceNumber - ulCurrentSequenceNumber ), /* want this signed */
+ ulLast - pxWindow->rx.ulFirstSequenceNumber ) );
+ }
+
+ /* Now prepare the SACK message.
+ Code OPTION_CODE_SINGLE_SACK already in network byte order. */
+ pxWindow->ulOptionsData[0] = OPTION_CODE_SINGLE_SACK;
+
+ /* First sequence number that we received. */
+ pxWindow->ulOptionsData[1] = FreeRTOS_htonl( ulSequenceNumber );
+
+ /* Last + 1 */
+ pxWindow->ulOptionsData[2] = FreeRTOS_htonl( ulLast );
+
+ /* Which make 12 (3*4) option bytes. */
+ pxWindow->ucOptionLength = 3 * sizeof( pxWindow->ulOptionsData[ 0 ] );
+
+ pxFound = xTCPWindowRxFind( pxWindow, ulSequenceNumber );
+
+ if( pxFound != NULL )
+ {
+ /* This out-of-sequence packet has been received for a
+ second time. It is already stored but do send a SACK
+ again. */
+ lReturn = -1;
+ }
+ else
+ {
+ pxFound = xTCPWindowRxNew( pxWindow, ulSequenceNumber, ( int32_t ) ulLength );
+
+ if( pxFound == NULL )
+ {
+ /* Can not send a SACK, because the segment cannot be
+ stored. */
+ pxWindow->ucOptionLength = 0u;
+
+ /* Needs to be stored but there is no segment
+ available. */
+ lReturn = -1;
+ }
+ else
+ {
+ if( xTCPWindowLoggingLevel != 0 )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowRxCheck[%u,%u]: seqnr %lu (cnt %lu)\n",
+ pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber, ulSequenceNumber - pxWindow->rx.ulFirstSequenceNumber,
+ listCURRENT_LIST_LENGTH( &pxWindow->xRxSegments ) ) );
+ FreeRTOS_flush_logging( );
+ }
+
+ /* Return a positive value. The packet may be accepted
+ and stored but an earlier packet is still missing. */
+ lReturn = ( int32_t ) ( ulSequenceNumber - ulCurrentSequenceNumber );
+ }
+ }
+ }
+ }
+
+ return lReturn;
+ }
+
+#endif /* ipconfgiUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+/*=============================================================================
+ *
+ * ######### # #
+ * # # # # #
+ * # # #
+ * # ####
+ * # ##
+ * # ####
+ * # # #
+ * # # #
+ * ##### # #
+ *
+ * Tx functions
+ *
+ *=============================================================================*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static int32_t lTCPIncrementTxPosition( int32_t lPosition, int32_t lMax, int32_t lCount )
+ {
+ /* +TCP stores data in circular buffers. Calculate the next position to
+ store. */
+ lPosition += lCount;
+ if( lPosition >= lMax )
+ {
+ lPosition -= lMax;
+ }
+
+ return lPosition;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax )
+ {
+ int32_t lBytesLeft = ( int32_t ) ulLength, lToWrite;
+ int32_t lDone = 0;
+ TCPSegment_t *pxSegment = pxWindow->pxHeadSegment;
+
+ /* Puts a message in the Tx-window (after buffer size has been
+ verified). */
+ if( pxSegment != NULL )
+ {
+ if( pxSegment->lDataLength < pxSegment->lMaxLength )
+ {
+ if( ( pxSegment->u.bits.bOutstanding == pdFALSE_UNSIGNED ) && ( pxSegment->lDataLength != 0 ) )
+ {
+ /* Adding data to a segment that was already in the TX queue. It
+ will be filled-up to a maximum of MSS (maximum segment size). */
+ lToWrite = FreeRTOS_min_int32( lBytesLeft, pxSegment->lMaxLength - pxSegment->lDataLength );
+
+ pxSegment->lDataLength += lToWrite;
+
+ if( pxSegment->lDataLength >= pxSegment->lMaxLength )
+ {
+ /* This segment is full, don't add more bytes. */
+ pxWindow->pxHeadSegment = NULL;
+ }
+
+ lBytesLeft -= lToWrite;
+
+ /* ulNextTxSequenceNumber is the sequence number of the next byte to
+ be stored for transmission. */
+ pxWindow->ulNextTxSequenceNumber += ( uint32_t ) lToWrite;
+
+ /* Increased the return value. */
+ lDone += lToWrite;
+
+ /* Some detailed logging, for those who're interested. */
+ if( ( xTCPWindowLoggingLevel >= 2 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != 0 ) )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: Add %4lu bytes for seqNr %lu len %4lu (nxt %lu) pos %lu\n",
+ ulLength,
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxSegment->lDataLength,
+ pxWindow->ulNextTxSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxSegment->lStreamPos ) );
+ FreeRTOS_flush_logging( );
+ }
+
+ /* Calculate the next position in the circular data buffer, knowing
+ its maximum length 'lMax'. */
+ lPosition = lTCPIncrementTxPosition( lPosition, lMax, lToWrite );
+ }
+ }
+ }
+
+ while( lBytesLeft > 0 )
+ {
+ /* The current transmission segment is full, create new segments as
+ needed. */
+ pxSegment = xTCPWindowTxNew( pxWindow, pxWindow->ulNextTxSequenceNumber, pxWindow->usMSS );
+
+ if( pxSegment != NULL )
+ {
+ /* Store as many as needed, but no more than the maximum
+ (MSS). */
+ lToWrite = FreeRTOS_min_int32( lBytesLeft, pxSegment->lMaxLength );
+
+ pxSegment->lDataLength = lToWrite;
+ pxSegment->lStreamPos = lPosition;
+ lBytesLeft -= lToWrite;
+ lPosition = lTCPIncrementTxPosition( lPosition, lMax, lToWrite );
+ pxWindow->ulNextTxSequenceNumber += ( uint32_t ) lToWrite;
+ lDone += lToWrite;
+
+ /* Link this segment in the Tx-Queue. */
+ vListInsertFifo( &( pxWindow->xTxQueue ), &( pxSegment->xQueueItem ) );
+
+ /* Let 'pxHeadSegment' point to this segment if there is still
+ space. */
+ if( pxSegment->lDataLength < pxSegment->lMaxLength )
+ {
+ pxWindow->pxHeadSegment = pxSegment;
+ }
+ else
+ {
+ pxWindow->pxHeadSegment = NULL;
+ }
+
+ if( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != 0 )
+ {
+ if( ( xTCPWindowLoggingLevel >= 3 ) ||
+ ( ( xTCPWindowLoggingLevel >= 2 ) && ( pxWindow->pxHeadSegment != NULL ) ) )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: New %4ld bytes for seqNr %lu len %4lu (nxt %lu) pos %lu\n",
+ ulLength,
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxSegment->lDataLength,
+ pxWindow->ulNextTxSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxSegment->lStreamPos ) );
+ FreeRTOS_flush_logging( );
+ }
+ }
+ }
+ else
+ {
+ /* A sever situation: running out of segments for transmission.
+ No more data can be sent at the moment. */
+ if( lDone != 0 )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: Sorry all buffers full (cancel %ld bytes)\n", lBytesLeft ) );
+ }
+ break;
+ }
+ }
+
+ return lDone;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow )
+ {
+ return listLIST_IS_EMPTY( ( &pxWindow->xTxSegments) );
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize )
+ {
+ uint32_t ulTxOutstanding;
+ BaseType_t xHasSpace;
+ TCPSegment_t *pxSegment;
+
+ /* This function will look if there is new transmission data. It will
+ return true if there is data to be sent. */
+
+ pxSegment = xTCPWindowPeekHead( &( pxWindow->xTxQueue ) );
+
+ if( pxSegment == NULL )
+ {
+ xHasSpace = pdFALSE;
+ }
+ else
+ {
+ /* How much data is outstanding, i.e. how much data has been sent
+ but not yet acknowledged ? */
+ if( pxWindow->tx.ulHighestSequenceNumber >= pxWindow->tx.ulCurrentSequenceNumber )
+ {
+ ulTxOutstanding = pxWindow->tx.ulHighestSequenceNumber - pxWindow->tx.ulCurrentSequenceNumber;
+ }
+ else
+ {
+ ulTxOutstanding = 0UL;
+ }
+
+ /* Subtract this from the peer's space. */
+ ulWindowSize -= FreeRTOS_min_uint32( ulWindowSize, ulTxOutstanding );
+
+ /* See if the next segment may be sent. */
+ if( ulWindowSize >= ( uint32_t ) pxSegment->lDataLength )
+ {
+ xHasSpace = pdTRUE;
+ }
+ else
+ {
+ xHasSpace = pdFALSE;
+ }
+
+ /* If 'xHasSpace', it looks like the peer has at least space for 1
+ more new segment of size MSS. xSize.ulTxWindowLength is the self-imposed
+ limitation of the transmission window (in case of many resends it
+ may be decreased). */
+ if( ( ulTxOutstanding != 0UL ) && ( pxWindow->xSize.ulTxWindowLength < ulTxOutstanding + ( ( uint32_t ) pxSegment->lDataLength ) ) )
+ {
+ xHasSpace = pdFALSE;
+ }
+ }
+
+ return xHasSpace;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay )
+ {
+ TCPSegment_t *pxSegment;
+ BaseType_t xReturn;
+ TickType_t ulAge, ulMaxAge;
+
+ *pulDelay = 0u;
+
+ if( listLIST_IS_EMPTY( &pxWindow->xPriorityQueue ) == pdFALSE )
+ {
+ /* No need to look at retransmissions or new transmission as long as
+ there are priority segments. *pulDelay equals zero, meaning it must
+ be sent out immediately. */
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ pxSegment = xTCPWindowPeekHead( &( pxWindow->xWaitQueue ) );
+
+ if( pxSegment != NULL )
+ {
+ /* There is an outstanding segment, see if it is time to resend
+ it. */
+ ulAge = ulTimerGetAge( &pxSegment->xTransmitTimer );
+
+ /* After a packet has been sent for the first time, it will wait
+ '1 * lSRTT' ms for an ACK. A second time it will wait '2 * lSRTT' ms,
+ each time doubling the time-out */
+ ulMaxAge = ( 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
+
+ if( ulMaxAge > ulAge )
+ {
+ /* A segment must be sent after this amount of msecs */
+ *pulDelay = ulMaxAge - ulAge;
+ }
+
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ /* No priority segment, no outstanding data, see if there is new
+ transmission data. */
+ pxSegment = xTCPWindowPeekHead( &pxWindow->xTxQueue );
+
+ /* See if it fits in the peer's reception window. */
+ if( pxSegment == NULL )
+ {
+ xReturn = pdFALSE;
+ }
+ else if( prvTCPWindowTxHasSpace( pxWindow, ulWindowSize ) == pdFALSE )
+ {
+ /* Too many outstanding messages. */
+ xReturn = pdFALSE;
+ }
+ else if( ( pxWindow->u.bits.bSendFullSize != pdFALSE_UNSIGNED ) && ( pxSegment->lDataLength < pxSegment->lMaxLength ) )
+ {
+ /* 'bSendFullSize' is a special optimisation. If true, the
+ driver will only sent completely filled packets (of MSS
+ bytes). */
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+ }
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition )
+ {
+ TCPSegment_t *pxSegment;
+ uint32_t ulMaxTime;
+ uint32_t ulReturn = ~0UL;
+
+
+ /* Fetches data to be sent-out now.
+
+ Priority messages: segments with a resend need no check current sliding
+ window size. */
+ pxSegment = xTCPWindowGetHead( &( pxWindow->xPriorityQueue ) );
+ pxWindow->ulOurSequenceNumber = pxWindow->tx.ulHighestSequenceNumber;
+
+ if( pxSegment == NULL )
+ {
+ /* Waiting messages: outstanding messages with a running timer
+ neither check peer's reception window size because these packets
+ have been sent earlier. */
+ pxSegment = xTCPWindowPeekHead( &( pxWindow->xWaitQueue ) );
+
+ if( pxSegment != NULL )
+ {
+ /* Do check the timing. */
+ ulMaxTime = ( 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
+
+ if( ulTimerGetAge( &pxSegment->xTransmitTimer ) > ulMaxTime )
+ {
+ /* A normal (non-fast) retransmission. Move it from the
+ head of the waiting queue. */
+ pxSegment = xTCPWindowGetHead( &( pxWindow->xWaitQueue ) );
+ pxSegment->u.bits.ucDupAckCount = pdFALSE_UNSIGNED;
+
+ /* Some detailed logging. */
+ if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != 0 ) )
+ {
+ FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u,%u]: WaitQueue %ld bytes for sequence number %lu (%lX)\n",
+ pxWindow->usPeerPortNumber,
+ pxWindow->usOurPortNumber,
+ pxSegment->lDataLength,
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxSegment->ulSequenceNumber ) );
+ FreeRTOS_flush_logging( );
+ }
+ }
+ else
+ {
+ pxSegment = NULL;
+ }
+ }
+
+ if( pxSegment == NULL )
+ {
+ /* New messages: sent-out for the first time. Check current
+ sliding window size of peer. */
+ pxSegment = xTCPWindowPeekHead( &( pxWindow->xTxQueue ) );
+
+ if( pxSegment == NULL )
+ {
+ /* No segments queued. */
+ ulReturn = 0UL;
+ }
+ else if( ( pxWindow->u.bits.bSendFullSize != pdFALSE_UNSIGNED ) && ( pxSegment->lDataLength < pxSegment->lMaxLength ) )
+ {
+ /* A segment has been queued but the driver waits until it
+ has a full size of MSS. */
+ ulReturn = 0;
+ }
+ else if( prvTCPWindowTxHasSpace( pxWindow, ulWindowSize ) == pdFALSE )
+ {
+ /* Peer has no more space at this moment. */
+ ulReturn = 0;
+ }
+ else
+ {
+ /* Move it out of the Tx queue. */
+ pxSegment = xTCPWindowGetHead( &( pxWindow->xTxQueue ) );
+
+ /* Don't let pxHeadSegment point to this segment any more,
+ so no more data will be added. */
+ if( pxWindow->pxHeadSegment == pxSegment )
+ {
+ pxWindow->pxHeadSegment = NULL;
+ }
+
+ /* pxWindow->tx.highest registers the highest sequence
+ number in our transmission window. */
+ pxWindow->tx.ulHighestSequenceNumber = pxSegment->ulSequenceNumber + ( ( uint32_t ) pxSegment->lDataLength );
+
+ /* ...and more detailed logging */
+ if( ( xTCPWindowLoggingLevel >= 2 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u,%u]: XmitQueue %ld bytes for sequence number %lu (ws %lu)\n",
+ pxWindow->usPeerPortNumber,
+ pxWindow->usOurPortNumber,
+ pxSegment->lDataLength,
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ ulWindowSize ) );
+ FreeRTOS_flush_logging( );
+ }
+ }
+ }
+ }
+ else
+ {
+ /* There is a priority segment. It doesn't need any checking for
+ space or timeouts. */
+ if( xTCPWindowLoggingLevel != 0 )
+ {
+ FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u,%u]: PrioQueue %ld bytes for sequence number %lu (ws %lu)\n",
+ pxWindow->usPeerPortNumber,
+ pxWindow->usOurPortNumber,
+ pxSegment->lDataLength,
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ ulWindowSize ) );
+ FreeRTOS_flush_logging( );
+ }
+ }
+
+ /* See if it has already been determined to return 0. */
+ if( ulReturn != 0UL )
+ {
+ configASSERT( listLIST_ITEM_CONTAINER( &(pxSegment->xQueueItem ) ) == NULL );
+
+ /* Now that the segment will be transmitted, add it to the tail of
+ the waiting queue. */
+ vListInsertFifo( &pxWindow->xWaitQueue, &pxSegment->xQueueItem );
+
+ /* And mark it as outstanding. */
+ pxSegment->u.bits.bOutstanding = pdTRUE_UNSIGNED;
+
+ /* Administer the transmit count, needed for fast
+ retransmissions. */
+ ( pxSegment->u.bits.ucTransmitCount )++;
+
+ /* If there have been several retransmissions (4), decrease the
+ size of the transmission window to at most 2 times MSS. */
+ if( pxSegment->u.bits.ucTransmitCount == MAX_TRANSMIT_COUNT_USING_LARGE_WINDOW )
+ {
+ if( pxWindow->xSize.ulTxWindowLength > ( 2U * pxWindow->usMSS ) )
+ {
+ FreeRTOS_debug_printf( ( "ulTCPWindowTxGet[%u - %d]: Change Tx window: %lu -> %u\n",
+ pxWindow->usPeerPortNumber, pxWindow->usOurPortNumber,
+ pxWindow->xSize.ulTxWindowLength, 2 * pxWindow->usMSS ) );
+ pxWindow->xSize.ulTxWindowLength = ( 2UL * pxWindow->usMSS );
+ }
+ }
+
+ /* Clear the transmit timer. */
+ vTCPTimerSet( &( pxSegment->xTransmitTimer ) );
+
+ pxWindow->ulOurSequenceNumber = pxSegment->ulSequenceNumber;
+
+ /* Inform the caller where to find the data within the queue. */
+ *plPosition = pxSegment->lStreamPos;
+
+ /* And return the length of the data segment */
+ ulReturn = ( uint32_t ) pxSegment->lDataLength;
+ }
+
+ return ulReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static uint32_t prvTCPWindowTxCheckAck( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast )
+ {
+ uint32_t ulBytesConfirmed = 0u;
+ uint32_t ulSequenceNumber = ulFirst, ulDataLength;
+ const ListItem_t *pxIterator;
+ const MiniListItem_t *pxEnd = ( const MiniListItem_t* )listGET_END_MARKER( &pxWindow->xTxSegments );
+ BaseType_t xDoUnlink;
+ TCPSegment_t *pxSegment;
+ /* An acknowledgement or a selective ACK (SACK) was received. See if some outstanding data
+ may be removed from the transmission queue(s).
+ All TX segments for which
+ ( ( ulSequenceNumber >= ulFirst ) && ( ulSequenceNumber < ulLast ) in a
+ contiguous block. Note that the segments are stored in xTxSegments in a
+ strict sequential order. */
+
+ /* SRTT[i] = (1-a) * SRTT[i-1] + a * RTT
+
+ 0 < a < 1; usually a = 1/8
+
+ RTO = 2 * SRTT
+
+ where:
+ RTT is Round Trip Time
+ SRTT is Smoothed RTT
+ RTO is Retransmit timeout
+
+ A Smoothed RTT will increase quickly, but it is conservative when
+ becoming smaller. */
+
+ for(
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
+ ( pxIterator != ( const ListItem_t * ) pxEnd ) && ( xSequenceLessThan( ulSequenceNumber, ulLast ) != 0 );
+ )
+ {
+ xDoUnlink = pdFALSE;
+ pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ /* Move to the next item because the current item might get
+ removed. */
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
+
+ /* Continue if this segment does not fall within the ACK'd range. */
+ if( xSequenceGreaterThan( ulSequenceNumber, pxSegment->ulSequenceNumber ) != pdFALSE )
+ {
+ continue;
+ }
+
+ /* Is it ready? */
+ if( ulSequenceNumber != pxSegment->ulSequenceNumber )
+ {
+ break;
+ }
+
+ ulDataLength = ( uint32_t ) pxSegment->lDataLength;
+
+ if( pxSegment->u.bits.bAcked == pdFALSE_UNSIGNED )
+ {
+ if( xSequenceGreaterThan( pxSegment->ulSequenceNumber + ( uint32_t )ulDataLength, ulLast ) != pdFALSE )
+ {
+ /* What happens? Only part of this segment was accepted,
+ probably due to WND limits
+
+ AAAAAAA BBBBBBB << acked
+ aaaaaaa aaaa << sent */
+ #if( ipconfigHAS_DEBUG_PRINTF != 0 )
+ {
+ uint32_t ulFirstSeq = pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber;
+ FreeRTOS_debug_printf( ( "prvTCPWindowTxCheckAck[%u.%u]: %lu - %lu Partial sequence number %lu - %lu\n",
+ pxWindow->usPeerPortNumber,
+ pxWindow->usOurPortNumber,
+ ulFirstSeq - pxWindow->tx.ulFirstSequenceNumber,
+ ulLast - pxWindow->tx.ulFirstSequenceNumber,
+ ulFirstSeq, ulFirstSeq + ulDataLength ) );
+ }
+ #endif /* ipconfigHAS_DEBUG_PRINTF */
+ break;
+ }
+
+ /* This segment is fully ACK'd, set the flag. */
+ pxSegment->u.bits.bAcked = pdTRUE_UNSIGNED;
+
+ /* Calculate the RTT only if the segment was sent-out for the
+ first time and if this is the last ACK'd segment in a range. */
+ if( ( pxSegment->u.bits.ucTransmitCount == 1 ) && ( ( pxSegment->ulSequenceNumber + ulDataLength ) == ulLast ) )
+ {
+ int32_t mS = ( int32_t ) ulTimerGetAge( &( pxSegment->xTransmitTimer ) );
+
+ if( pxWindow->lSRTT >= mS )
+ {
+ /* RTT becomes smaller: adapt slowly. */
+ pxWindow->lSRTT = ( ( winSRTT_DECREMENT_NEW * mS ) + ( winSRTT_DECREMENT_CURRENT * pxWindow->lSRTT ) ) / ( winSRTT_DECREMENT_NEW + winSRTT_DECREMENT_CURRENT );
+ }
+ else
+ {
+ /* RTT becomes larger: adapt quicker */
+ pxWindow->lSRTT = ( ( winSRTT_INCREMENT_NEW * mS ) + ( winSRTT_INCREMENT_CURRENT * pxWindow->lSRTT ) ) / ( winSRTT_INCREMENT_NEW + winSRTT_INCREMENT_CURRENT );
+ }
+
+ /* Cap to the minimum of 50ms. */
+ if( pxWindow->lSRTT < winSRTT_CAP_mS )
+ {
+ pxWindow->lSRTT = winSRTT_CAP_mS;
+ }
+ }
+
+ /* Unlink it from the 3 queues, but do not destroy it (yet). */
+ xDoUnlink = pdTRUE;
+ }
+
+ /* pxSegment->u.bits.bAcked is now true. Is it located at the left
+ side of the transmission queue? If so, it may be freed. */
+ if( ulSequenceNumber == pxWindow->tx.ulCurrentSequenceNumber )
+ {
+ if( ( xTCPWindowLoggingLevel >= 2 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "prvTCPWindowTxCheckAck: %lu - %lu Ready sequence number %lu\n",
+ ulFirst - pxWindow->tx.ulFirstSequenceNumber,
+ ulLast - pxWindow->tx.ulFirstSequenceNumber,
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber ) );
+ }
+
+ /* Increase the left-hand value of the transmission window. */
+ pxWindow->tx.ulCurrentSequenceNumber += ulDataLength;
+
+ /* This function will return the number of bytes that the tail
+ of txStream may be advanced. */
+ ulBytesConfirmed += ulDataLength;
+
+ /* All segments below tx.ulCurrentSequenceNumber may be freed. */
+ vTCPWindowFree( pxSegment );
+
+ /* No need to unlink it any more. */
+ xDoUnlink = pdFALSE;
+ }
+
+ if( ( xDoUnlink != pdFALSE ) && ( listLIST_ITEM_CONTAINER( &( pxSegment->xQueueItem ) ) != NULL ) )
+ {
+ /* Remove item from its queues. */
+ uxListRemove( &pxSegment->xQueueItem );
+ }
+
+ ulSequenceNumber += ulDataLength;
+ }
+
+ return ulBytesConfirmed;
+ }
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ static uint32_t prvTCPWindowFastRetransmit( TCPWindow_t *pxWindow, uint32_t ulFirst )
+ {
+ const ListItem_t *pxIterator;
+ const MiniListItem_t* pxEnd;
+ TCPSegment_t *pxSegment;
+ uint32_t ulCount = 0UL;
+
+ /* A higher Tx block has been acknowledged. Now iterate through the
+ xWaitQueue to find a possible condition for a FAST retransmission. */
+
+ pxEnd = ( const MiniListItem_t* ) listGET_END_MARKER( &( pxWindow->xWaitQueue ) );
+
+ for( pxIterator = ( const ListItem_t * ) listGET_NEXT( pxEnd );
+ pxIterator != ( const ListItem_t * ) pxEnd; )
+ {
+ /* Get the owner, which is a TCP segment. */
+ pxSegment = ( TCPSegment_t * ) listGET_LIST_ITEM_OWNER( pxIterator );
+
+ /* Hop to the next item before the current gets unlinked. */
+ pxIterator = ( const ListItem_t * ) listGET_NEXT( pxIterator );
+
+ /* Fast retransmission:
+ When 3 packets with a higher sequence number have been acknowledged
+ by the peer, it is very unlikely a current packet will ever arrive.
+ It will be retransmitted far before the RTO. */
+ if( ( pxSegment->u.bits.bAcked == pdFALSE_UNSIGNED ) &&
+ ( xSequenceLessThan( pxSegment->ulSequenceNumber, ulFirst ) != pdFALSE ) &&
+ ( ++( pxSegment->u.bits.ucDupAckCount ) == DUPLICATE_ACKS_BEFORE_FAST_RETRANSMIT ) )
+ {
+ pxSegment->u.bits.ucTransmitCount = pdFALSE_UNSIGNED;
+
+ /* Not clearing 'ucDupAckCount' yet as more SACK's might come in
+ which might lead to a second fast rexmit. */
+ if( ( xTCPWindowLoggingLevel >= 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "prvTCPWindowFastRetransmit: Requeue sequence number %lu < %lu\n",
+ pxSegment->ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ ulFirst - pxWindow->tx.ulFirstSequenceNumber ) );
+ FreeRTOS_flush_logging( );
+ }
+
+ /* Remove it from xWaitQueue. */
+ uxListRemove( &pxSegment->xQueueItem );
+
+ /* Add this segment to the priority queue so it gets
+ retransmitted immediately. */
+ vListInsertFifo( &( pxWindow->xPriorityQueue ), &( pxSegment->xQueueItem ) );
+ ulCount++;
+ }
+ }
+
+ return ulCount;
+ }
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber )
+ {
+ uint32_t ulFirstSequence, ulReturn;
+
+ /* Receive a normal ACK. */
+
+ ulFirstSequence = pxWindow->tx.ulCurrentSequenceNumber;
+
+ if( xSequenceLessThanOrEqual( ulSequenceNumber, ulFirstSequence ) != pdFALSE )
+ {
+ ulReturn = 0UL;
+ }
+ else
+ {
+ ulReturn = prvTCPWindowTxCheckAck( pxWindow, ulFirstSequence, ulSequenceNumber );
+ }
+
+ return ulReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 1 )
+
+ uint32_t ulTCPWindowTxSack( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast )
+ {
+ uint32_t ulAckCount = 0UL;
+ uint32_t ulCurrentSequenceNumber = pxWindow->tx.ulCurrentSequenceNumber;
+
+ /* Receive a SACK option. */
+ ulAckCount = prvTCPWindowTxCheckAck( pxWindow, ulFirst, ulLast );
+ prvTCPWindowFastRetransmit( pxWindow, ulFirst );
+
+ if( ( xTCPWindowLoggingLevel >= 1 ) && ( xSequenceGreaterThan( ulFirst, ulCurrentSequenceNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "ulTCPWindowTxSack[%u,%u]: from %lu to %lu (ack = %lu)\n",
+ pxWindow->usPeerPortNumber,
+ pxWindow->usOurPortNumber,
+ ulFirst - pxWindow->tx.ulFirstSequenceNumber,
+ ulLast - pxWindow->tx.ulFirstSequenceNumber,
+ pxWindow->tx.ulCurrentSequenceNumber - pxWindow->tx.ulFirstSequenceNumber ) );
+ FreeRTOS_flush_logging( );
+ }
+
+ return ulAckCount;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 1 */
+/*-----------------------------------------------------------*/
+
+/*
+##### # ##### #### ######
+# # # # # # # # # # #
+ # # # # # #
+ # ### ##### # # # # # #
+ # # # # # # # # #####
+ # # # # # # #### # # #
+ # # # # # # # # # #
+ # # # # #### # # # #
+ #### ##### # # # #### #### ####
+ #
+ ###
+*/
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace )
+ {
+ int32_t iReturn;
+
+ /* Data was received at 'ulSequenceNumber'. See if it was expected
+ and if there is enough space to store the new data. */
+ if( ( pxWindow->rx.ulCurrentSequenceNumber != ulSequenceNumber ) || ( ulSpace < ulLength ) )
+ {
+ iReturn = -1;
+ }
+ else
+ {
+ pxWindow->rx.ulCurrentSequenceNumber += ( uint32_t ) ulLength;
+ iReturn = 0;
+ }
+
+ return iReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax )
+ {
+ TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
+ int32_t lResult;
+
+ /* Data is being scheduled for transmission. */
+
+ /* lMax would indicate the size of the txStream. */
+ ( void ) lMax;
+ /* This is tiny TCP: there is only 1 segment for outgoing data.
+ As long as 'lDataLength' is unequal to zero, the segment is still occupied. */
+ if( pxSegment->lDataLength > 0 )
+ {
+ lResult = 0L;
+ }
+ else
+ {
+ if( ulLength > ( uint32_t ) pxSegment->lMaxLength )
+ {
+ if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: can only store %ld / %ld bytes\n", ulLength, pxSegment->lMaxLength ) );
+ }
+
+ ulLength = ( uint32_t ) pxSegment->lMaxLength;
+ }
+
+ if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "lTCPWindowTxAdd: SeqNr %ld (%ld) Len %ld\n",
+ pxWindow->ulNextTxSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxWindow->tx.ulCurrentSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ ulLength ) );
+ }
+
+ /* The sequence number of the first byte in this packet. */
+ pxSegment->ulSequenceNumber = pxWindow->ulNextTxSequenceNumber;
+ pxSegment->lDataLength = ( int32_t ) ulLength;
+ pxSegment->lStreamPos = lPosition;
+ pxSegment->u.ulFlags = 0UL;
+ vTCPTimerSet( &( pxSegment->xTransmitTimer ) );
+
+ /* Increase the sequence number of the next data to be stored for
+ transmission. */
+ pxWindow->ulNextTxSequenceNumber += ulLength;
+ lResult = ( int32_t )ulLength;
+ }
+
+ return lResult;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition )
+ {
+ TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
+ uint32_t ulLength = ( uint32_t ) pxSegment->lDataLength;
+ uint32_t ulMaxTime;
+
+ if( ulLength != 0UL )
+ {
+ /* _HT_ Still under investigation */
+ ( void ) ulWindowSize;
+
+ if( pxSegment->u.bits.bOutstanding != pdFALSE_UNSIGNED )
+ {
+ /* As 'ucTransmitCount' has a minimum of 1, take 2 * RTT */
+ ulMaxTime = ( ( uint32_t ) 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
+
+ if( ulTimerGetAge( &( pxSegment->xTransmitTimer ) ) < ulMaxTime )
+ {
+ ulLength = 0ul;
+ }
+ }
+
+ if( ulLength != 0ul )
+ {
+ pxSegment->u.bits.bOutstanding = pdTRUE_UNSIGNED;
+ pxSegment->u.bits.ucTransmitCount++;
+ vTCPTimerSet (&pxSegment->xTransmitTimer);
+ pxWindow->ulOurSequenceNumber = pxSegment->ulSequenceNumber;
+ *plPosition = pxSegment->lStreamPos;
+ }
+ }
+
+ return ulLength;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow )
+ {
+ BaseType_t xReturn;
+
+ /* Has the outstanding data been sent because user wants to shutdown? */
+ if( pxWindow->xTxSegment.lDataLength == 0 )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize );
+ static BaseType_t prvTCPWindowTxHasSpace( TCPWindow_t *pxWindow, uint32_t ulWindowSize )
+ {
+ BaseType_t xReturn;
+
+ if( ulWindowSize >= pxWindow->usMSSInit )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay )
+ {
+ TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
+ BaseType_t xReturn;
+ TickType_t ulAge, ulMaxAge;
+
+ /* Check data to be sent. */
+ *pulDelay = ( TickType_t ) 0;
+ if( pxSegment->lDataLength == 0 )
+ {
+ /* Got nothing to send right now. */
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ if( pxSegment->u.bits.bOutstanding != pdFALSE_UNSIGNED )
+ {
+ ulAge = ulTimerGetAge ( &pxSegment->xTransmitTimer );
+ ulMaxAge = ( ( TickType_t ) 1u << pxSegment->u.bits.ucTransmitCount ) * ( ( uint32_t ) pxWindow->lSRTT );
+
+ if( ulMaxAge > ulAge )
+ {
+ *pulDelay = ulMaxAge - ulAge;
+ }
+
+ xReturn = pdTRUE;
+ }
+ else if( prvTCPWindowTxHasSpace( pxWindow, ulWindowSize ) == pdFALSE )
+ {
+ /* Too many outstanding messages. */
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+ }
+
+ return xReturn;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber )
+ {
+ TCPSegment_t *pxSegment = &( pxWindow->xTxSegment );
+ uint32_t ulDataLength = ( uint32_t ) pxSegment->lDataLength;
+
+ /* Receive a normal ACK */
+
+ if( ulDataLength != 0ul )
+ {
+ if( ulSequenceNumber < ( pxWindow->tx.ulCurrentSequenceNumber + ulDataLength ) )
+ {
+ if( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE )
+ {
+ FreeRTOS_debug_printf( ( "win_tx_ack: acked %ld expc %ld len %ld\n",
+ ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ pxWindow->tx.ulCurrentSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ ulDataLength ) );
+ }
+
+ /* Nothing to send right now. */
+ ulDataLength = 0ul;
+ }
+ else
+ {
+ pxWindow->tx.ulCurrentSequenceNumber += ulDataLength;
+
+ if( ( xTCPWindowLoggingLevel != 0 ) && ( ipconfigTCP_MAY_LOG_PORT( pxWindow->usOurPortNumber ) != pdFALSE ) )
+ {
+ FreeRTOS_debug_printf( ( "win_tx_ack: acked seqnr %ld len %ld\n",
+ ulSequenceNumber - pxWindow->tx.ulFirstSequenceNumber,
+ ulDataLength ) );
+ }
+
+ pxSegment->lDataLength = 0;
+ }
+ }
+
+ return ulDataLength;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow )
+ {
+ /* Return true if 'ulCurrentSequenceNumber >= ulHighestSequenceNumber'
+ 'ulCurrentSequenceNumber' is the highest sequence number stored,
+ 'ulHighestSequenceNumber' is the highest sequence number seen. */
+ return xSequenceGreaterThanOrEqual( pxWindow->rx.ulCurrentSequenceNumber, pxWindow->rx.ulHighestSequenceNumber );
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+#if( ipconfigUSE_TCP_WIN == 0 )
+
+ /* Destroy a window (always returns NULL) */
+ void vTCPWindowDestroy( TCPWindow_t *pxWindow )
+ {
+ /* As in tiny TCP there are no shared segments descriptors, there is
+ nothing to release. */
+ ( void ) pxWindow;
+ }
+
+#endif /* ipconfigUSE_TCP_WIN == 0 */
+/*-----------------------------------------------------------*/
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
index e7d2a6c50..14ae96e64 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/FreeRTOS_UDP_IP.c
@@ -1,404 +1,404 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_ARP.h"
-#include "FreeRTOS_DHCP.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-#if( ipconfigUSE_DNS == 1 )
- #include "FreeRTOS_DNS.h"
-#endif
-
-/* The expected IP version and header length coded into the IP header itself. */
-#define ipIP_VERSION_AND_HEADER_LENGTH_BYTE ( ( uint8_t ) 0x45 )
-
-/* Part of the Ethernet and IP headers are always constant when sending an IPv4
-UDP packet. This array defines the constant parts, allowing this part of the
-packet to be filled in using a simple memcpy() instead of individual writes. */
-UDPPacketHeader_t xDefaultPartUDPPacketHeader =
-{
- /* .ucBytes : */
- {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Ethernet source MAC address. */
- 0x08, 0x00, /* Ethernet frame type. */
- ipIP_VERSION_AND_HEADER_LENGTH_BYTE, /* ucVersionHeaderLength. */
- 0x00, /* ucDifferentiatedServicesCode. */
- 0x00, 0x00, /* usLength. */
- 0x00, 0x00, /* usIdentification. */
- 0x00, 0x00, /* usFragmentOffset. */
- ipconfigUDP_TIME_TO_LIVE, /* ucTimeToLive */
- ipPROTOCOL_UDP, /* ucProtocol. */
- 0x00, 0x00, /* usHeaderChecksum. */
- 0x00, 0x00, 0x00, 0x00 /* Source IP address. */
- }
-};
-/*-----------------------------------------------------------*/
-
-void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-UDPPacket_t *pxUDPPacket;
-IPHeader_t *pxIPHeader;
-eARPLookupResult_t eReturned;
-uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
-size_t uxPayloadSize;
-
- /* Map the UDP packet onto the start of the frame. */
- pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
-
-#if ipconfigSUPPORT_OUTGOING_PINGS == 1
- if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
- {
- uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( ICMPPacket_t );
- }
- else
-#endif
- {
- uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
- }
-
- /* Determine the ARP cache status for the requested IP address. */
- eReturned = eARPGetCacheEntry( &( ulIPAddress ), &( pxUDPPacket->xEthernetHeader.xDestinationAddress ) );
-
- if( eReturned != eCantSendPacket )
- {
- if( eReturned == eARPCacheHit )
- {
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
- uint8_t ucSocketOptions;
- #endif
- iptraceSENDING_UDP_PACKET( pxNetworkBuffer->ulIPAddress );
-
- /* Create short cuts to the data within the packet. */
- pxIPHeader = &( pxUDPPacket->xIPHeader );
-
- #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
- /* Is it possible that the packet is not actually a UDP packet
- after all, but an ICMP packet. */
- if( pxNetworkBuffer->usPort != ipPACKET_CONTAINS_ICMP_DATA )
- #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
- {
- UDPHeader_t *pxUDPHeader;
-
- pxUDPHeader = &( pxUDPPacket->xUDPHeader );
-
- pxUDPHeader->usDestinationPort = pxNetworkBuffer->usPort;
- pxUDPHeader->usSourcePort = pxNetworkBuffer->usBoundPort;
- pxUDPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( UDPHeader_t ) );
- pxUDPHeader->usLength = FreeRTOS_htons( pxUDPHeader->usLength );
- pxUDPHeader->usChecksum = 0u;
- }
-
- /* memcpy() the constant parts of the header information into
- the correct location within the packet. This fills in:
- xEthernetHeader.xSourceAddress
- xEthernetHeader.usFrameType
- xIPHeader.ucVersionHeaderLength
- xIPHeader.ucDifferentiatedServicesCode
- xIPHeader.usLength
- xIPHeader.usIdentification
- xIPHeader.usFragmentOffset
- xIPHeader.ucTimeToLive
- xIPHeader.ucProtocol
- and
- xIPHeader.usHeaderChecksum
- */
- /* Save options now, as they will be overwritten by memcpy */
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
- ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];
- #endif
- /*
- * Offset the memcpy by the size of a MAC address to start at the packet's
- * Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.
- */
- char *pxUdpSrcAddrOffset = ( char *) pxUDPPacket + sizeof( MACAddress_t );
- memcpy( pxUdpSrcAddrOffset, xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
-
- #if ipconfigSUPPORT_OUTGOING_PINGS == 1
- if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
- {
- pxIPHeader->ucProtocol = ipPROTOCOL_ICMP;
- pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( ICMPHeader_t ) );
- }
- else
- #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
- {
- pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );
- }
-
- pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
- /* HT:endian: changed back to network endian */
- pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;
-
- #if( ipconfigUSE_LLMNR == 1 )
- {
- /* LLMNR messages are typically used on a LAN and they're
- * not supposed to cross routers */
- if( pxNetworkBuffer->ulIPAddress == ipLLMNR_IP_ADDR )
- {
- pxIPHeader->ucTimeToLive = 0x01;
- }
- }
- #endif
-
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
- {
- pxIPHeader->usHeaderChecksum = 0u;
- pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
- pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
-
- if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0u )
- {
- usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
- }
- else
- {
- pxUDPPacket->xUDPHeader.usChecksum = 0u;
- }
- }
- #endif
- }
- else if( eReturned == eARPCacheMiss )
- {
- /* Add an entry to the ARP table with a null hardware address.
- This allows the ARP timer to know that an ARP reply is
- outstanding, and perform retransmissions if necessary. */
- vARPRefreshCacheEntry( NULL, ulIPAddress );
-
- /* Generate an ARP for the required IP address. */
- iptracePACKET_DROPPED_TO_GENERATE_ARP( pxNetworkBuffer->ulIPAddress );
- pxNetworkBuffer->ulIPAddress = ulIPAddress;
- vARPGenerateRequestPacket( pxNetworkBuffer );
- }
- else
- {
- /* The lookup indicated that an ARP request has already been
- sent out for the queried IP address. */
- eReturned = eCantSendPacket;
- }
- }
-
- if( eReturned != eCantSendPacket )
- {
- /* The network driver is responsible for freeing the network buffer
- after the packet has been sent. */
-
- #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- {
- BaseType_t xIndex;
-
- for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
- {
- pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
- }
- pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
- }
- }
- #endif
-
- xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
- }
- else
- {
- /* The packet can't be sent (DHCP not completed?). Just drop the
- packet. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort )
-{
-BaseType_t xReturn = pdPASS;
-FreeRTOS_Socket_t *pxSocket;
-configASSERT(pxNetworkBuffer);
-configASSERT(pxNetworkBuffer->pucEthernetBuffer);
-
-
-UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
-
- /* Caller must check for minimum packet size. */
- pxSocket = pxUDPSocketLookup( usPort );
-
- if( pxSocket )
- {
-
- /* When refreshing the ARP cache with received UDP packets we must be
- careful; hundreds of broadcast messages may pass and if we're not
- handling them, no use to fill the ARP cache with those IP addresses. */
- vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
-
- #if( ipconfigUSE_CALLBACKS == 1 )
- {
- /* Did the owner of this socket register a reception handler ? */
- if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleReceive ) )
- {
- struct freertos_sockaddr xSourceAddress, destinationAddress;
- void *pcData = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
- FOnUDPReceive_t xHandler = ( FOnUDPReceive_t ) pxSocket->u.xUDP.pxHandleReceive;
- xSourceAddress.sin_port = pxNetworkBuffer->usPort;
- xSourceAddress.sin_addr = pxNetworkBuffer->ulIPAddress;
- destinationAddress.sin_port = usPort;
- destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
-
- if( xHandler( ( Socket_t ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
- &xSourceAddress, &destinationAddress ) )
- {
- xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
- }
- }
- }
- #endif /* ipconfigUSE_CALLBACKS */
-
- #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
- {
- if( xReturn == pdPASS )
- {
- if ( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) >= pxSocket->u.xUDP.uxMaxPackets )
- {
- FreeRTOS_debug_printf( ( "xProcessReceivedUDPPacket: buffer full %ld >= %ld port %u\n",
- listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ),
- pxSocket->u.xUDP.uxMaxPackets, pxSocket->usLocalPort ) );
- xReturn = pdFAIL; /* we did not consume or release the buffer */
- }
- }
- }
- #endif
-
- if( xReturn == pdPASS )
- {
- vTaskSuspendAll();
- {
- if( xReturn == pdPASS )
- {
- taskENTER_CRITICAL();
- {
- /* Add the network packet to the list of packets to be
- processed by the socket. */
- vListInsertEnd( &( pxSocket->u.xUDP.xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
- }
- taskEXIT_CRITICAL();
- }
- }
- xTaskResumeAll();
-
- /* Set the socket's receive event */
- if( pxSocket->xEventGroup != NULL )
- {
- xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
- }
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- {
- if( ( pxSocket->pxSocketSet != NULL ) && ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) )
- {
- xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, eSELECT_READ );
- }
- }
- #endif
-
- #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
- {
- if( pxSocket->pxUserSemaphore != NULL )
- {
- xSemaphoreGive( pxSocket->pxUserSemaphore );
- }
- }
- #endif
-
- #if( ipconfigUSE_DHCP == 1 )
- {
- if( xIsDHCPSocket( pxSocket ) )
- {
- xSendEventToIPTask( eDHCPEvent );
- }
- }
- #endif
- }
- }
- else
- {
- /* There is no socket listening to the target port, but still it might
- be for this node. */
-
- #if( ipconfigUSE_DNS == 1 ) && ( ipconfigDNS_USE_CALLBACKS == 1 )
- /* A DNS reply, check for the source port. Although the DNS client
- does open a UDP socket to send a messages, this socket will be
- closed after a short timeout. Messages that come late (after the
- socket is closed) will be treated here. */
- if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ipDNS_PORT )
- {
- vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
- xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
- }
- else
- #endif
-
- #if( ipconfigUSE_LLMNR == 1 )
- /* a LLMNR request, check for the destination port. */
- if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
- ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )
- {
- vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
- xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
- }
- else
- #endif /* ipconfigUSE_LLMNR */
-
- #if( ipconfigUSE_NBNS == 1 )
- /* a NetBIOS request, check for the destination port */
- if( ( usPort == FreeRTOS_ntohs( ipNBNS_PORT ) ) ||
- ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipNBNS_PORT ) ) )
- {
- vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
- xReturn = ( BaseType_t )ulNBNSHandlePacket( pxNetworkBuffer );
- }
- else
- #endif /* ipconfigUSE_NBNS */
- {
- xReturn = pdFAIL;
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_ARP.h"
+#include "FreeRTOS_DHCP.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+#if( ipconfigUSE_DNS == 1 )
+ #include "FreeRTOS_DNS.h"
+#endif
+
+/* The expected IP version and header length coded into the IP header itself. */
+#define ipIP_VERSION_AND_HEADER_LENGTH_BYTE ( ( uint8_t ) 0x45 )
+
+/* Part of the Ethernet and IP headers are always constant when sending an IPv4
+UDP packet. This array defines the constant parts, allowing this part of the
+packet to be filled in using a simple memcpy() instead of individual writes. */
+UDPPacketHeader_t xDefaultPartUDPPacketHeader =
+{
+ /* .ucBytes : */
+ {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Ethernet source MAC address. */
+ 0x08, 0x00, /* Ethernet frame type. */
+ ipIP_VERSION_AND_HEADER_LENGTH_BYTE, /* ucVersionHeaderLength. */
+ 0x00, /* ucDifferentiatedServicesCode. */
+ 0x00, 0x00, /* usLength. */
+ 0x00, 0x00, /* usIdentification. */
+ 0x00, 0x00, /* usFragmentOffset. */
+ ipconfigUDP_TIME_TO_LIVE, /* ucTimeToLive */
+ ipPROTOCOL_UDP, /* ucProtocol. */
+ 0x00, 0x00, /* usHeaderChecksum. */
+ 0x00, 0x00, 0x00, 0x00 /* Source IP address. */
+ }
+};
+/*-----------------------------------------------------------*/
+
+void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+UDPPacket_t *pxUDPPacket;
+IPHeader_t *pxIPHeader;
+eARPLookupResult_t eReturned;
+uint32_t ulIPAddress = pxNetworkBuffer->ulIPAddress;
+size_t uxPayloadSize;
+
+ /* Map the UDP packet onto the start of the frame. */
+ pxUDPPacket = ( UDPPacket_t * ) pxNetworkBuffer->pucEthernetBuffer;
+
+#if ipconfigSUPPORT_OUTGOING_PINGS == 1
+ if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
+ {
+ uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( ICMPPacket_t );
+ }
+ else
+#endif
+ {
+ uxPayloadSize = pxNetworkBuffer->xDataLength - sizeof( UDPPacket_t );
+ }
+
+ /* Determine the ARP cache status for the requested IP address. */
+ eReturned = eARPGetCacheEntry( &( ulIPAddress ), &( pxUDPPacket->xEthernetHeader.xDestinationAddress ) );
+
+ if( eReturned != eCantSendPacket )
+ {
+ if( eReturned == eARPCacheHit )
+ {
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ uint8_t ucSocketOptions;
+ #endif
+ iptraceSENDING_UDP_PACKET( pxNetworkBuffer->ulIPAddress );
+
+ /* Create short cuts to the data within the packet. */
+ pxIPHeader = &( pxUDPPacket->xIPHeader );
+
+ #if ( ipconfigSUPPORT_OUTGOING_PINGS == 1 )
+ /* Is it possible that the packet is not actually a UDP packet
+ after all, but an ICMP packet. */
+ if( pxNetworkBuffer->usPort != ipPACKET_CONTAINS_ICMP_DATA )
+ #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
+ {
+ UDPHeader_t *pxUDPHeader;
+
+ pxUDPHeader = &( pxUDPPacket->xUDPHeader );
+
+ pxUDPHeader->usDestinationPort = pxNetworkBuffer->usPort;
+ pxUDPHeader->usSourcePort = pxNetworkBuffer->usBoundPort;
+ pxUDPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( UDPHeader_t ) );
+ pxUDPHeader->usLength = FreeRTOS_htons( pxUDPHeader->usLength );
+ pxUDPHeader->usChecksum = 0u;
+ }
+
+ /* memcpy() the constant parts of the header information into
+ the correct location within the packet. This fills in:
+ xEthernetHeader.xSourceAddress
+ xEthernetHeader.usFrameType
+ xIPHeader.ucVersionHeaderLength
+ xIPHeader.ucDifferentiatedServicesCode
+ xIPHeader.usLength
+ xIPHeader.usIdentification
+ xIPHeader.usFragmentOffset
+ xIPHeader.ucTimeToLive
+ xIPHeader.ucProtocol
+ and
+ xIPHeader.usHeaderChecksum
+ */
+ /* Save options now, as they will be overwritten by memcpy */
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ ucSocketOptions = pxNetworkBuffer->pucEthernetBuffer[ ipSOCKET_OPTIONS_OFFSET ];
+ #endif
+ /*
+ * Offset the memcpy by the size of a MAC address to start at the packet's
+ * Ethernet header 'source' MAC address; the preceding 'destination' should not be altered.
+ */
+ char *pxUdpSrcAddrOffset = ( char *) pxUDPPacket + sizeof( MACAddress_t );
+ memcpy( pxUdpSrcAddrOffset, xDefaultPartUDPPacketHeader.ucBytes, sizeof( xDefaultPartUDPPacketHeader ) );
+
+ #if ipconfigSUPPORT_OUTGOING_PINGS == 1
+ if( pxNetworkBuffer->usPort == ipPACKET_CONTAINS_ICMP_DATA )
+ {
+ pxIPHeader->ucProtocol = ipPROTOCOL_ICMP;
+ pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( ICMPHeader_t ) );
+ }
+ else
+ #endif /* ipconfigSUPPORT_OUTGOING_PINGS */
+ {
+ pxIPHeader->usLength = ( uint16_t ) ( uxPayloadSize + sizeof( IPHeader_t ) + sizeof( UDPHeader_t ) );
+ }
+
+ pxIPHeader->usLength = FreeRTOS_htons( pxIPHeader->usLength );
+ /* HT:endian: changed back to network endian */
+ pxIPHeader->ulDestinationIPAddress = pxNetworkBuffer->ulIPAddress;
+
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ /* LLMNR messages are typically used on a LAN and they're
+ * not supposed to cross routers */
+ if( pxNetworkBuffer->ulIPAddress == ipLLMNR_IP_ADDR )
+ {
+ pxIPHeader->ucTimeToLive = 0x01;
+ }
+ }
+ #endif
+
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 )
+ {
+ pxIPHeader->usHeaderChecksum = 0u;
+ pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0UL, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
+ pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
+
+ if( ( ucSocketOptions & ( uint8_t ) FREERTOS_SO_UDPCKSUM_OUT ) != 0u )
+ {
+ usGenerateProtocolChecksum( (uint8_t*)pxUDPPacket, pxNetworkBuffer->xDataLength, pdTRUE );
+ }
+ else
+ {
+ pxUDPPacket->xUDPHeader.usChecksum = 0u;
+ }
+ }
+ #endif
+ }
+ else if( eReturned == eARPCacheMiss )
+ {
+ /* Add an entry to the ARP table with a null hardware address.
+ This allows the ARP timer to know that an ARP reply is
+ outstanding, and perform retransmissions if necessary. */
+ vARPRefreshCacheEntry( NULL, ulIPAddress );
+
+ /* Generate an ARP for the required IP address. */
+ iptracePACKET_DROPPED_TO_GENERATE_ARP( pxNetworkBuffer->ulIPAddress );
+ pxNetworkBuffer->ulIPAddress = ulIPAddress;
+ vARPGenerateRequestPacket( pxNetworkBuffer );
+ }
+ else
+ {
+ /* The lookup indicated that an ARP request has already been
+ sent out for the queried IP address. */
+ eReturned = eCantSendPacket;
+ }
+ }
+
+ if( eReturned != eCantSendPacket )
+ {
+ /* The network driver is responsible for freeing the network buffer
+ after the packet has been sent. */
+
+ #if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ if( pxNetworkBuffer->xDataLength < ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ {
+ BaseType_t xIndex;
+
+ for( xIndex = ( BaseType_t ) pxNetworkBuffer->xDataLength; xIndex < ( BaseType_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES; xIndex++ )
+ {
+ pxNetworkBuffer->pucEthernetBuffer[ xIndex ] = 0u;
+ }
+ pxNetworkBuffer->xDataLength = ( size_t ) ipconfigETHERNET_MINIMUM_PACKET_BYTES;
+ }
+ }
+ #endif
+
+ xNetworkInterfaceOutput( pxNetworkBuffer, pdTRUE );
+ }
+ else
+ {
+ /* The packet can't be sent (DHCP not completed?). Just drop the
+ packet. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort )
+{
+BaseType_t xReturn = pdPASS;
+FreeRTOS_Socket_t *pxSocket;
+configASSERT(pxNetworkBuffer);
+configASSERT(pxNetworkBuffer->pucEthernetBuffer);
+
+
+UDPPacket_t *pxUDPPacket = (UDPPacket_t *) pxNetworkBuffer->pucEthernetBuffer;
+
+ /* Caller must check for minimum packet size. */
+ pxSocket = pxUDPSocketLookup( usPort );
+
+ if( pxSocket )
+ {
+
+ /* When refreshing the ARP cache with received UDP packets we must be
+ careful; hundreds of broadcast messages may pass and if we're not
+ handling them, no use to fill the ARP cache with those IP addresses. */
+ vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
+
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ {
+ /* Did the owner of this socket register a reception handler ? */
+ if( ipconfigIS_VALID_PROG_ADDRESS( pxSocket->u.xUDP.pxHandleReceive ) )
+ {
+ struct freertos_sockaddr xSourceAddress, destinationAddress;
+ void *pcData = ( void * ) &( pxNetworkBuffer->pucEthernetBuffer[ ipUDP_PAYLOAD_OFFSET_IPv4 ] );
+ FOnUDPReceive_t xHandler = ( FOnUDPReceive_t ) pxSocket->u.xUDP.pxHandleReceive;
+ xSourceAddress.sin_port = pxNetworkBuffer->usPort;
+ xSourceAddress.sin_addr = pxNetworkBuffer->ulIPAddress;
+ destinationAddress.sin_port = usPort;
+ destinationAddress.sin_addr = pxUDPPacket->xIPHeader.ulDestinationIPAddress;
+
+ if( xHandler( ( Socket_t ) pxSocket, ( void* ) pcData, ( size_t ) pxNetworkBuffer->xDataLength,
+ &xSourceAddress, &destinationAddress ) )
+ {
+ xReturn = pdFAIL; /* FAIL means that we did not consume or release the buffer */
+ }
+ }
+ }
+ #endif /* ipconfigUSE_CALLBACKS */
+
+ #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
+ {
+ if( xReturn == pdPASS )
+ {
+ if ( listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ) >= pxSocket->u.xUDP.uxMaxPackets )
+ {
+ FreeRTOS_debug_printf( ( "xProcessReceivedUDPPacket: buffer full %ld >= %ld port %u\n",
+ listCURRENT_LIST_LENGTH( &( pxSocket->u.xUDP.xWaitingPacketsList ) ),
+ pxSocket->u.xUDP.uxMaxPackets, pxSocket->usLocalPort ) );
+ xReturn = pdFAIL; /* we did not consume or release the buffer */
+ }
+ }
+ }
+ #endif
+
+ if( xReturn == pdPASS )
+ {
+ vTaskSuspendAll();
+ {
+ if( xReturn == pdPASS )
+ {
+ taskENTER_CRITICAL();
+ {
+ /* Add the network packet to the list of packets to be
+ processed by the socket. */
+ vListInsertEnd( &( pxSocket->u.xUDP.xWaitingPacketsList ), &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ taskEXIT_CRITICAL();
+ }
+ }
+ xTaskResumeAll();
+
+ /* Set the socket's receive event */
+ if( pxSocket->xEventGroup != NULL )
+ {
+ xEventGroupSetBits( pxSocket->xEventGroup, eSOCKET_RECEIVE );
+ }
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ {
+ if( ( pxSocket->pxSocketSet != NULL ) && ( ( pxSocket->xSelectBits & eSELECT_READ ) != 0 ) )
+ {
+ xEventGroupSetBits( pxSocket->pxSocketSet->xSelectGroup, eSELECT_READ );
+ }
+ }
+ #endif
+
+ #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
+ {
+ if( pxSocket->pxUserSemaphore != NULL )
+ {
+ xSemaphoreGive( pxSocket->pxUserSemaphore );
+ }
+ }
+ #endif
+
+ #if( ipconfigUSE_DHCP == 1 )
+ {
+ if( xIsDHCPSocket( pxSocket ) )
+ {
+ xSendEventToIPTask( eDHCPEvent );
+ }
+ }
+ #endif
+ }
+ }
+ else
+ {
+ /* There is no socket listening to the target port, but still it might
+ be for this node. */
+
+ #if( ipconfigUSE_DNS == 1 ) && ( ipconfigDNS_USE_CALLBACKS == 1 )
+ /* A DNS reply, check for the source port. Although the DNS client
+ does open a UDP socket to send a messages, this socket will be
+ closed after a short timeout. Messages that come late (after the
+ socket is closed) will be treated here. */
+ if( FreeRTOS_ntohs( pxUDPPacket->xUDPHeader.usSourcePort ) == ipDNS_PORT )
+ {
+ vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
+ xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
+ }
+ else
+ #endif
+
+ #if( ipconfigUSE_LLMNR == 1 )
+ /* a LLMNR request, check for the destination port. */
+ if( ( usPort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) ||
+ ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipLLMNR_PORT ) ) )
+ {
+ vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
+ xReturn = ( BaseType_t )ulDNSHandlePacket( pxNetworkBuffer );
+ }
+ else
+ #endif /* ipconfigUSE_LLMNR */
+
+ #if( ipconfigUSE_NBNS == 1 )
+ /* a NetBIOS request, check for the destination port */
+ if( ( usPort == FreeRTOS_ntohs( ipNBNS_PORT ) ) ||
+ ( pxUDPPacket->xUDPHeader.usSourcePort == FreeRTOS_ntohs( ipNBNS_PORT ) ) )
+ {
+ vARPRefreshCacheEntry( &( pxUDPPacket->xEthernetHeader.xSourceAddress ), pxUDPPacket->xIPHeader.ulSourceIPAddress );
+ xReturn = ( BaseType_t )ulNBNSHandlePacket( pxNetworkBuffer );
+ }
+ else
+ #endif /* ipconfigUSE_NBNS */
+ {
+ xReturn = pdFAIL;
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt
index 52565cc86..0bbfaa505 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/History.txt
@@ -1,177 +1,177 @@
-Changes between 160919 and 180821 releases:
-
- + Multiple security improvements and fixes in packet parsing routines, DNS
- caching, and TCP sequence number and ID generation.
- + Disable NBNS and LLMNR by default.
- + Add TCP hang protection by default.
-
-We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
-
-Changes between 160908 and 160919 releases:
-
- + Add a NULL check before attempting to close the DHCP socket. [Prior to
- 160823 the IP task closed the DHCP socket by calling a public API function
- - which checked for the socket being NULL. This was changed to call a
- local private function, which did not have a NULL check, in place of the
- public API function.]
- + Various [internal only] naming changes to better comply with the FreeRTOS
- naming conventions.
- + Improvements to the Zynq network driver. DMA transmission buffers now use
- a counting semaphore. When all TX-buffers are in-use, the IP-task will
- block momentarily until a TX-buffer becomes available.
- + Experimental implementation of the TCP window scaling protocol. The
- scaling option will always be offered, at least with a factor 1. If the
- TCP sliding window size becomes more than 64KB, the factor will increase
- automatically.
- + ipconfigETHERNET_MINIMUM_PACKET_BYTES is now applied for every protocol:
- TCP, UDP, and ARP.
- + Updated the Zynq project to use BufferAllocation_1.c rather than
- BufferAllocation_2.c - which is a requirement with its current
- configuration (due to the alignment requirements on the combined cache and
- DMA configuration).
-
-Changes between 160823 and 160908 releases:
-
- + Use ipconfigZERO_COPY_TX_DRIVER as the xReleaseAfterSend() parameter where
- prvTCPReturnPacket() is called in prvSendData() to prevent unnecessary
- copying of data.
- + Remove the use of the uxGetRxEventCount variable, which was used to give
- priority to incoming messages, but could result in the IP task starving
- application tasks of processing time.
-
-Changes between 160112 and 160823 releases
-
- NOTE: The 160908 release is a maintenance release for the 160112 single
- interface labs release - not a release of the current development branch.
-
- + Various minor stability enhancements, including the ability to work with
- configTICK_RATE_HZ set to less than 1KHz, closing DHCP sockets directly
- rather than via FreeRTOS_closesocket(), and better handling of unknown
- TCP packets before an IP address has been assigned.
- + ipBUFFER_PADDING is now configurable through the ipconfigBUFFER_PADDING
- constant to improve network buffer alignment handling capabilities (expert
- users/driver writers only).
- + Multiple improvements to the FTP server, including to how read only and
- zero length files are handled.
- + ipconfigFTP_HAS_USER_PROPERTIES_HOOK (to allow each user to have a
- different root directory and access rights) and
- ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK (to handle AJAX style data)
- introduced, although these are not yet fully tested and the constant names
- are likely to change.
- + Introduce ipconfigHAS_TX_CRC_OFFLOADING.
- + ipconfigUSE_DHCP_HOOK is now called ipconfigUSE_DHCP_HOOK, and the name
- of the callback function has also changed. See the web documentation for
- details.
- + ipconfigTCP_RX_BUF_LEN is now ipconfigTCP_RX_BUFFER_LENGTH, and
- ipconfigTCP_TX_BUF_LEN is now ipconfigTCP_TX_BUFFER_LENGTH, which is
- actually how they have always been documented.
- + Added example TFTP server capable of receiving (not sending) files.
- Intended for bootloader type functionality.
- + Various variable name changes for consistency (mainly ensuring UDP, TCP,
- DNS, etc. always use the same case letters, and type prefixes are correct).
- + Various minor edits to improve types used by internal variables.
- + Simplified mapping of standard library functions to their Visual Studio
- equivalents.
- + Improve robustness of network drivers.
- + Introduce pxResizeNetworkBufferWithDescriptor().
- + Removed obsolete FreeRTOSIPConfig.h constants from
- FreeRTOSIPConfigDefaults.h.
- + Added additional asserts() - predominantly to catch incorrect structure
- packing.
-
-Changes between 160112 and 160111 releases
-
- + Updated the STM32 network driver so checksums are calculated by the
- hardware.
- + Implemented a simple "quit" command in the TCP command console.
-
-Changes between 150825 and 160111 releases
-
- + New device support: Demo applications and example drivers are provided
- for Atmel SAM4E and ST STM32F4 microcontrollers.
- + Various updates to improve compliance with the FreeRTOS coding standard.
- + Added a command console example that uses TCP/IP for input and output (the
- pre-existing command console example uses UDP/IP).
- + Updated the UDP logging example so it will send log messages to the local
- UDP broadcast address if a specific IP address is not provided. This
- simplifies configuration, but note not all switches and routers will pass
- broadcast messages.
- + Add TCP echo client and TCP echo server examples to the Zynq demo.
- + Minor updates to the Zynq network driver.
- + Update the Zynq project to use version 2015.4 of the Xilinx SDK.
- + Introduce FreeRTOS_SignalSocket(), which can be used to interrupt a task
- that is blocked while reading from a socket ( FreeRTOS_recv[from] ).
- + Make use of FreeRTOS_SignalSocket() in the FTP and HTTP servers.
- + Major updates to the NTP client, although this is not included in any of
- the pre-configured demo applications yet.
- + Added support for DHCP zero pad option.
- + Added uxGetMinimumIPQueueSpace(), a function to monitor the minimum amount
- of space on the message queue.
- + Better handling of zero length files in the FTP server.
- + Fixed a bug reported by Andrey Ivanov from swissEmbedded that affects
- users of 'ipconfigZERO_COPY_TX_DRIVER'.
-
-
-Changes between 150825 150825 (?)
-
- + Added xApplicationDHCPUserHook() so a user defined hook will be
- called at certain points in the DHCP process if
- ipconfigDHCP_USES_USER_HOOK is set to 1.
- + Added FreeRTOS_get_tx_head() to improve TCP zero copy behaviour - for
- expert use only.
- + RST is no longer sent if only the ACK flag is set.
- + Previously, an immediate ACK was only sent when buffer space was
- exhausted. Now, to improve performance, it is possible to send an
- immediate ACK earlier - dependent on the ipconfigTCP_ACK_EARLIER_PACKET
- setting.
- + LLMNR and NBNS requests can now be sent to locate other devices -
- previously these protocols would only be replied to, not generated.
- + Added Auto-IP functionality (still in test) in case DHCP fails. Dependent
- on the ipconfigDHCP_FALL_BACK_LINK_LAYER_ADDRESS and
- ipconfigARP_USE_CLASH_DETECTION settings.
- + Added NTP code and demo.
- + FTP can now STOR and RETR zero-length files.
- + Added LLMNR demo to Win32 demo - so now the Win32 responds to
- "ping RTOSDemo".
-
-Changes between 141019 and 150825
-
- + Added FTP server, which uses the new FreeRTOS+FAT component.
- + Added basic HTTP server, which uses the new FreeRTOS+FAT component.
- + Multiple definitions that are now common with FreeRTOS+FAT have been moved
- into FreeRTOS's ProjDefs.h header file, and so prefixed with 'pd'.
- + Introduced ipconfigZERO_COPY_TX_DRIVER, which defines who is responsible
- for freeing a buffer sent to to the MAC driver for transmission, and
- facilitates the development of zero copy drivers.
- + Introduced the FREERTOS_MSG_DONTWAIT flag. The flag can be used as a
- simpler and faster alternative to using FreeRTOS_setsockopt() to set the
- send or receive timeout to 0.
- + A few functions that were previously all lower case are now mixed case, as
- lower case function names are only used when they are equivalent to a
- a Berkeley sockets API function of the same name.
- + Introduced uxGetMinimumFreeNetworkBuffers() to return the minimum number
- of network buffers that have ever existed since the application started
- executing.
- + Introduce ipconfigETHERNET_MINIMUM_PACKET_BYTES to allow the application
- writer to set their own minimum buffer size should the hardware not be
- capable of padding under-sized Ethernet frames.
- + vNetworkBufferRelease() renamed vReleaseNetworkBuffer() - just for
- consistency with the names of other functions in the same file.
- + Grouped DHCP status data into a structure.
- + DHCP is now tried both with and without the broadcast flag.
- + Replaced occurrences of configASSERT_VOID() with configASSERT().
- + ipconfigDNS_USE_CALLBACKS introduced to allow FreeRTOS_gethostbyname() to
- be used without blocking.
- + Fix: LLMNR and NBNS behaviour when the reply is in a larger buffer than the
- request, and BufferAllocation_2 was used.
- + Introduced ipMAX_IP_TASK_SLEEP_TIME to allow the application writer to
- override the default value of 10 seconds.
- + Fix: Correct error in *pxUDPPayloadBuffer_to_NetworkBuffer().
- + FreeRTOS_recv() now recognises the FREERTOS_ZERO_COPY flag, which, when
- set, the void *pvBuffer parameter is interpreted as void **pvBuffer.
- + FreeRTOS_listen() now returns an error code. Previously it always
- returned 0.
- + Fix: Previously if a listening socket was reused, and a connection
- failed, the TCP/IP stack closed the socket, now the socket is correctly
- left unclosed as it is owned by the application.
- + Various other formatting and minor fix alterations.
+Changes between 160919 and 180821 releases:
+
+ + Multiple security improvements and fixes in packet parsing routines, DNS
+ caching, and TCP sequence number and ID generation.
+ + Disable NBNS and LLMNR by default.
+ + Add TCP hang protection by default.
+
+We thank Ori Karliner of Zimperium zLabs Team for reporting these issues.
+
+Changes between 160908 and 160919 releases:
+
+ + Add a NULL check before attempting to close the DHCP socket. [Prior to
+ 160823 the IP task closed the DHCP socket by calling a public API function
+ - which checked for the socket being NULL. This was changed to call a
+ local private function, which did not have a NULL check, in place of the
+ public API function.]
+ + Various [internal only] naming changes to better comply with the FreeRTOS
+ naming conventions.
+ + Improvements to the Zynq network driver. DMA transmission buffers now use
+ a counting semaphore. When all TX-buffers are in-use, the IP-task will
+ block momentarily until a TX-buffer becomes available.
+ + Experimental implementation of the TCP window scaling protocol. The
+ scaling option will always be offered, at least with a factor 1. If the
+ TCP sliding window size becomes more than 64KB, the factor will increase
+ automatically.
+ + ipconfigETHERNET_MINIMUM_PACKET_BYTES is now applied for every protocol:
+ TCP, UDP, and ARP.
+ + Updated the Zynq project to use BufferAllocation_1.c rather than
+ BufferAllocation_2.c - which is a requirement with its current
+ configuration (due to the alignment requirements on the combined cache and
+ DMA configuration).
+
+Changes between 160823 and 160908 releases:
+
+ + Use ipconfigZERO_COPY_TX_DRIVER as the xReleaseAfterSend() parameter where
+ prvTCPReturnPacket() is called in prvSendData() to prevent unnecessary
+ copying of data.
+ + Remove the use of the uxGetRxEventCount variable, which was used to give
+ priority to incoming messages, but could result in the IP task starving
+ application tasks of processing time.
+
+Changes between 160112 and 160823 releases
+
+ NOTE: The 160908 release is a maintenance release for the 160112 single
+ interface labs release - not a release of the current development branch.
+
+ + Various minor stability enhancements, including the ability to work with
+ configTICK_RATE_HZ set to less than 1KHz, closing DHCP sockets directly
+ rather than via FreeRTOS_closesocket(), and better handling of unknown
+ TCP packets before an IP address has been assigned.
+ + ipBUFFER_PADDING is now configurable through the ipconfigBUFFER_PADDING
+ constant to improve network buffer alignment handling capabilities (expert
+ users/driver writers only).
+ + Multiple improvements to the FTP server, including to how read only and
+ zero length files are handled.
+ + ipconfigFTP_HAS_USER_PROPERTIES_HOOK (to allow each user to have a
+ different root directory and access rights) and
+ ipconfigHTTP_HAS_HANDLE_REQUEST_HOOK (to handle AJAX style data)
+ introduced, although these are not yet fully tested and the constant names
+ are likely to change.
+ + Introduce ipconfigHAS_TX_CRC_OFFLOADING.
+ + ipconfigUSE_DHCP_HOOK is now called ipconfigUSE_DHCP_HOOK, and the name
+ of the callback function has also changed. See the web documentation for
+ details.
+ + ipconfigTCP_RX_BUF_LEN is now ipconfigTCP_RX_BUFFER_LENGTH, and
+ ipconfigTCP_TX_BUF_LEN is now ipconfigTCP_TX_BUFFER_LENGTH, which is
+ actually how they have always been documented.
+ + Added example TFTP server capable of receiving (not sending) files.
+ Intended for bootloader type functionality.
+ + Various variable name changes for consistency (mainly ensuring UDP, TCP,
+ DNS, etc. always use the same case letters, and type prefixes are correct).
+ + Various minor edits to improve types used by internal variables.
+ + Simplified mapping of standard library functions to their Visual Studio
+ equivalents.
+ + Improve robustness of network drivers.
+ + Introduce pxResizeNetworkBufferWithDescriptor().
+ + Removed obsolete FreeRTOSIPConfig.h constants from
+ FreeRTOSIPConfigDefaults.h.
+ + Added additional asserts() - predominantly to catch incorrect structure
+ packing.
+
+Changes between 160112 and 160111 releases
+
+ + Updated the STM32 network driver so checksums are calculated by the
+ hardware.
+ + Implemented a simple "quit" command in the TCP command console.
+
+Changes between 150825 and 160111 releases
+
+ + New device support: Demo applications and example drivers are provided
+ for Atmel SAM4E and ST STM32F4 microcontrollers.
+ + Various updates to improve compliance with the FreeRTOS coding standard.
+ + Added a command console example that uses TCP/IP for input and output (the
+ pre-existing command console example uses UDP/IP).
+ + Updated the UDP logging example so it will send log messages to the local
+ UDP broadcast address if a specific IP address is not provided. This
+ simplifies configuration, but note not all switches and routers will pass
+ broadcast messages.
+ + Add TCP echo client and TCP echo server examples to the Zynq demo.
+ + Minor updates to the Zynq network driver.
+ + Update the Zynq project to use version 2015.4 of the Xilinx SDK.
+ + Introduce FreeRTOS_SignalSocket(), which can be used to interrupt a task
+ that is blocked while reading from a socket ( FreeRTOS_recv[from] ).
+ + Make use of FreeRTOS_SignalSocket() in the FTP and HTTP servers.
+ + Major updates to the NTP client, although this is not included in any of
+ the pre-configured demo applications yet.
+ + Added support for DHCP zero pad option.
+ + Added uxGetMinimumIPQueueSpace(), a function to monitor the minimum amount
+ of space on the message queue.
+ + Better handling of zero length files in the FTP server.
+ + Fixed a bug reported by Andrey Ivanov from swissEmbedded that affects
+ users of 'ipconfigZERO_COPY_TX_DRIVER'.
+
+
+Changes between 150825 150825 (?)
+
+ + Added xApplicationDHCPUserHook() so a user defined hook will be
+ called at certain points in the DHCP process if
+ ipconfigDHCP_USES_USER_HOOK is set to 1.
+ + Added FreeRTOS_get_tx_head() to improve TCP zero copy behaviour - for
+ expert use only.
+ + RST is no longer sent if only the ACK flag is set.
+ + Previously, an immediate ACK was only sent when buffer space was
+ exhausted. Now, to improve performance, it is possible to send an
+ immediate ACK earlier - dependent on the ipconfigTCP_ACK_EARLIER_PACKET
+ setting.
+ + LLMNR and NBNS requests can now be sent to locate other devices -
+ previously these protocols would only be replied to, not generated.
+ + Added Auto-IP functionality (still in test) in case DHCP fails. Dependent
+ on the ipconfigDHCP_FALL_BACK_LINK_LAYER_ADDRESS and
+ ipconfigARP_USE_CLASH_DETECTION settings.
+ + Added NTP code and demo.
+ + FTP can now STOR and RETR zero-length files.
+ + Added LLMNR demo to Win32 demo - so now the Win32 responds to
+ "ping RTOSDemo".
+
+Changes between 141019 and 150825
+
+ + Added FTP server, which uses the new FreeRTOS+FAT component.
+ + Added basic HTTP server, which uses the new FreeRTOS+FAT component.
+ + Multiple definitions that are now common with FreeRTOS+FAT have been moved
+ into FreeRTOS's ProjDefs.h header file, and so prefixed with 'pd'.
+ + Introduced ipconfigZERO_COPY_TX_DRIVER, which defines who is responsible
+ for freeing a buffer sent to to the MAC driver for transmission, and
+ facilitates the development of zero copy drivers.
+ + Introduced the FREERTOS_MSG_DONTWAIT flag. The flag can be used as a
+ simpler and faster alternative to using FreeRTOS_setsockopt() to set the
+ send or receive timeout to 0.
+ + A few functions that were previously all lower case are now mixed case, as
+ lower case function names are only used when they are equivalent to a
+ a Berkeley sockets API function of the same name.
+ + Introduced uxGetMinimumFreeNetworkBuffers() to return the minimum number
+ of network buffers that have ever existed since the application started
+ executing.
+ + Introduce ipconfigETHERNET_MINIMUM_PACKET_BYTES to allow the application
+ writer to set their own minimum buffer size should the hardware not be
+ capable of padding under-sized Ethernet frames.
+ + vNetworkBufferRelease() renamed vReleaseNetworkBuffer() - just for
+ consistency with the names of other functions in the same file.
+ + Grouped DHCP status data into a structure.
+ + DHCP is now tried both with and without the broadcast flag.
+ + Replaced occurrences of configASSERT_VOID() with configASSERT().
+ + ipconfigDNS_USE_CALLBACKS introduced to allow FreeRTOS_gethostbyname() to
+ be used without blocking.
+ + Fix: LLMNR and NBNS behaviour when the reply is in a larger buffer than the
+ request, and BufferAllocation_2 was used.
+ + Introduced ipMAX_IP_TASK_SLEEP_TIME to allow the application writer to
+ override the default value of 10 seconds.
+ + Fix: Correct error in *pxUDPPayloadBuffer_to_NetworkBuffer().
+ + FreeRTOS_recv() now recognises the FREERTOS_ZERO_COPY flag, which, when
+ set, the void *pvBuffer parameter is interpreted as void **pvBuffer.
+ + FreeRTOS_listen() now returns an error code. Previously it always
+ returned 0.
+ + Fix: Previously if a listening socket was reused, and a connection
+ failed, the TCP/IP stack closed the socket, now the socket is correctly
+ left unclosed as it is owned by the application.
+ + Various other formatting and minor fix alterations.
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url
index 8a8017f6b..417407677 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/ReadMe.url
@@ -1,5 +1,5 @@
-[{000214A0-0000-0000-C000-000000000046}]
-Prop3=19,2
-[InternetShortcut]
-URL=http://www.freertos.org/tcp
-IDList=
+[{000214A0-0000-0000-C000-000000000046}]
+Prop3=19,2
+[InternetShortcut]
+URL=http://www.freertos.org/tcp
+IDList=
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
index 20cdf739f..d23410f5f 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOSIPConfigDefaults.h
@@ -1,569 +1,569 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-#ifndef FREERTOS_DEFAULT_IP_CONFIG_H
-#define FREERTOS_DEFAULT_IP_CONFIG_H
-
-/* The error numbers defined in this file will be moved to the core FreeRTOS
-code in future versions of FreeRTOS - at which time the following header file
-will be removed. */
-#include "FreeRTOS_errno_TCP.h"
-
-/* This file provides default values for configuration options that are missing
-from the FreeRTOSIPConfig.h configuration header file. */
-
-
-/* Ensure defined configuration constants are using the most up to date naming. */
-#ifdef tcpconfigIP_TIME_TO_LIVE
- #error now called: ipconfigTCP_TIME_TO_LIVE
-#endif
-
-#ifdef updconfigIP_TIME_TO_LIVE
- #error now called: ipconfigUDP_TIME_TO_LIVE
-#endif
-
-#ifdef ipFILLER_SIZE
- #error now called: ipconfigPACKET_FILLER_SIZE
-#endif
-
-#ifdef dnsMAX_REQUEST_ATTEMPTS
- #error now called: ipconfigDNS_REQUEST_ATTEMPTS
-#endif
-
-#ifdef ipconfigUDP_TASK_PRIORITY
- #error now called: ipconfigIP_TASK_PRIORITY
-#endif
-
-#ifdef ipconfigUDP_TASK_STACK_SIZE_WORDS
- #error now called: ipconfigIP_TASK_STACK_SIZE_WORDS
-#endif
-
-#ifdef ipconfigDRIVER_INCLUDED_RX_IP_FILTERING
- #error now called: ipconfigETHERNET_DRIVER_FILTERS_PACKETS
-#endif
-
-#ifdef ipconfigMAX_SEND_BLOCK_TIME_TICKS
- #error now called: ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS
-#endif
-
-#ifdef ipconfigUSE_RECEIVE_CONNECT_CALLBACKS
- #error now called: ipconfigUSE_CALLBACKS
-#endif
-
-#ifdef ipconfigNUM_NETWORK_BUFFERS
- #error now called: ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
-#endif
-
-#ifdef ipconfigTCP_HANG_PROT
- #error now called: ipconfigTCP_HANG_PROTECTION
-#endif
-
-#ifdef ipconfigTCP_HANG_PROT_TIME
- #error now called: ipconfigTCP_HANG_PROTECTION_TIME
-#endif
-
-#ifdef FreeRTOS_lprintf
- #error now called: FreeRTOS_debug_printf
-#endif
-
-#if ( ipconfigEVENT_QUEUE_LENGTH < ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) )
- #error The ipconfigEVENT_QUEUE_LENGTH parameter must be at least ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5
-#endif
-
-#if ( ipconfigNETWORK_MTU < 46 )
- #error ipconfigNETWORK_MTU must be at least 46.
-#endif
-
-#ifdef ipconfigBUFFER_ALLOC_FIXED_SIZE
- #error ipconfigBUFFER_ALLOC_FIXED_SIZE was dropped and replaced by a const value, declared in BufferAllocation[12].c
-#endif
-
-#ifdef ipconfigNIC_SEND_PASSES_DMA
- #error now called: ipconfigZERO_COPY_TX_DRIVER
-#endif
-
-#ifdef HAS_TX_CRC_OFFLOADING
- /* _HT_ As these macro names have changed, throw an error
- if they're still defined. */
- #error now called: ipconfigHAS_TX_CRC_OFFLOADING
-#endif
-
-#ifdef HAS_RX_CRC_OFFLOADING
- #error now called: ipconfigHAS_RX_CRC_OFFLOADING
-#endif
-
-#ifdef ipconfigTCP_RX_BUF_LEN
- #error ipconfigTCP_RX_BUF_LEN is now called ipconfigTCP_RX_BUFFER_LENGTH
-#endif
-
-#ifdef ipconfigTCP_TX_BUF_LEN
- #error ipconfigTCP_TX_BUF_LEN is now called ipconfigTCP_TX_BUFFER_LENGTH
-#endif
-
-#ifdef ipconfigDHCP_USES_USER_HOOK
- #error ipconfigDHCP_USES_USER_HOOK and its associated callback have been superceeded - see http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html#ipconfigUSE_DHCP_HOOK
-#endif
-
-#ifndef ipconfigUSE_TCP
- #define ipconfigUSE_TCP ( 1 )
-#endif
-
-#if ipconfigUSE_TCP
-
- /* Include support for TCP scaling windows */
- #ifndef ipconfigUSE_TCP_WIN
- #define ipconfigUSE_TCP_WIN ( 1 )
- #endif
-
- #ifndef ipconfigTCP_WIN_SEG_COUNT
- #define ipconfigTCP_WIN_SEG_COUNT ( 256 )
- #endif
-
- #ifndef ipconfigIGNORE_UNKNOWN_PACKETS
- /* When non-zero, TCP will not send RST packets in reply to
- TCP packets which are unknown, or out-of-order. */
- #define ipconfigIGNORE_UNKNOWN_PACKETS ( 0 )
- #endif
-#endif
-
-/*
- * For debuging/logging: check if the port number is used for telnet
- * Some events will not be logged for telnet connections
- * because it would produce logging about the transmission of the logging...
- * This macro will only be used if FreeRTOS_debug_printf() is defined for logging
- */
-#ifndef ipconfigTCP_MAY_LOG_PORT
- #define ipconfigTCP_MAY_LOG_PORT(xPort) ( ( xPort ) != 23u )
-#endif
-
-
-#ifndef ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME
- #define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME portMAX_DELAY
-#endif
-
-#ifndef ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME
- #define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME portMAX_DELAY
-#endif
-
-
-#ifndef ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS
- #define ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS pdMS_TO_TICKS( 500u )
-#endif
-
-#ifndef ipconfigDNS_SEND_BLOCK_TIME_TICKS
- #define ipconfigDNS_SEND_BLOCK_TIME_TICKS pdMS_TO_TICKS( 500u )
-#endif
-/*
- * FreeRTOS debug logging routine (proposal)
- * The macro will be called in the printf() style. Users can define
- * their own logging routine as:
- *
- * #define FreeRTOS_debug_printf( MSG ) my_printf MSG
- *
- * The FreeRTOS_debug_printf() must be thread-safe but does not have to be
- * interrupt-safe.
- */
-#ifdef ipconfigHAS_DEBUG_PRINTF
- #if( ipconfigHAS_DEBUG_PRINTF == 0 )
- #ifdef FreeRTOS_debug_printf
- #error Do not define FreeRTOS_debug_print if ipconfigHAS_DEBUG_PRINTF is set to 0
- #endif /* ifdef FreeRTOS_debug_printf */
- #endif /* ( ipconfigHAS_DEBUG_PRINTF == 0 ) */
-#endif /* ifdef ipconfigHAS_DEBUG_PRINTF */
-
-#ifndef FreeRTOS_debug_printf
- #define FreeRTOS_debug_printf( MSG ) do{} while(0)
- #define ipconfigHAS_DEBUG_PRINTF 0
-#endif
-
-/*
- * FreeRTOS general logging routine (proposal)
- * Used in some utility functions such as FreeRTOS_netstat() and FreeRTOS_PrintARPCache()
- *
- * #define FreeRTOS_printf( MSG ) my_printf MSG
- *
- * The FreeRTOS_printf() must be thread-safe but does not have to be interrupt-safe
- */
-#ifdef ipconfigHAS_PRINTF
- #if( ipconfigHAS_PRINTF == 0 )
- #ifdef FreeRTOS_printf
- #error Do not define FreeRTOS_print if ipconfigHAS_PRINTF is set to 0
- #endif /* ifdef FreeRTOS_debug_printf */
- #endif /* ( ipconfigHAS_PRINTF == 0 ) */
-#endif /* ifdef ipconfigHAS_PRINTF */
-
-#ifndef FreeRTOS_printf
- #define FreeRTOS_printf( MSG ) do{} while(0)
- #define ipconfigHAS_PRINTF 0
-#endif
-
-/*
- * In cases where a lot of logging is produced, FreeRTOS_flush_logging( )
- * will be called to give the logging module a chance to flush the data
- * An example of this is the netstat command, which produces many lines of logging
- */
-#ifndef FreeRTOS_flush_logging
- #define FreeRTOS_flush_logging( ) do{} while(0)
-#endif
-
-/* Malloc functions. Within most applications of FreeRTOS, the couple
- * pvPortMalloc()/vPortFree() will be used.
- * If there is also SDRAM, the user may decide to use a different memory
- * allocator:
- * MallocLarge is used to allocate large TCP buffers (for Rx/Tx)
- * MallocSocket is used to allocate the space for the sockets
- */
-#ifndef pvPortMallocLarge
- #define pvPortMallocLarge( x ) pvPortMalloc( x )
-#endif
-
-#ifndef vPortFreeLarge
- #define vPortFreeLarge(ptr) vPortFree(ptr)
-#endif
-
-#ifndef pvPortMallocSocket
- #define pvPortMallocSocket( x ) pvPortMalloc( x )
-#endif
-
-#ifndef vPortFreeSocket
- #define vPortFreeSocket(ptr) vPortFree(ptr)
-#endif
-
-/*
- * At several places within the library, random numbers are needed:
- * - DHCP: For creating a DHCP transaction number
- * - TCP: Set the Initial Sequence Number: this is the value of the first outgoing
- * sequence number being used when connecting to a peer.
- * Having a well randomised ISN is important to avoid spoofing
- * - UDP/TCP: for setting the first port number to be used, in case a socket
- * uses a 'random' or anonymous port number
- */
-#ifndef ipconfigRAND32
- #define ipconfigRAND32() rand()
-#endif
-/* --------------------------------------------------------
- * End of: HT Added some macro defaults for the PLUS-UDP project
- * -------------------------------------------------------- */
-
-#ifndef ipconfigUSE_NETWORK_EVENT_HOOK
- #define ipconfigUSE_NETWORK_EVENT_HOOK 0
-#endif
-
-#ifndef ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS
- #define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( pdMS_TO_TICKS( 20 ) )
-#endif
-
-#ifndef ipconfigARP_CACHE_ENTRIES
- #define ipconfigARP_CACHE_ENTRIES 10
-#endif
-
-#ifndef ipconfigMAX_ARP_RETRANSMISSIONS
- #define ipconfigMAX_ARP_RETRANSMISSIONS ( 5u )
-#endif
-
-#ifndef ipconfigMAX_ARP_AGE
- #define ipconfigMAX_ARP_AGE 150u
-#endif
-
-#ifndef ipconfigUSE_ARP_REVERSED_LOOKUP
- #define ipconfigUSE_ARP_REVERSED_LOOKUP 0
-#endif
-
-#ifndef ipconfigUSE_ARP_REMOVE_ENTRY
- #define ipconfigUSE_ARP_REMOVE_ENTRY 0
-#endif
-
-#ifndef ipconfigINCLUDE_FULL_INET_ADDR
- #define ipconfigINCLUDE_FULL_INET_ADDR 1
-#endif
-
-#ifndef ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
- #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 45
-#endif
-
-#ifndef ipconfigEVENT_QUEUE_LENGTH
- #define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
-#endif
-
-#ifndef ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND
- #define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
-#endif
-
-#ifndef ipconfigUDP_TIME_TO_LIVE
- #define ipconfigUDP_TIME_TO_LIVE 128
-#endif
-
-#ifndef ipconfigTCP_TIME_TO_LIVE
- #define ipconfigTCP_TIME_TO_LIVE 128
-#endif
-
-#ifndef ipconfigUDP_MAX_RX_PACKETS
- /* Make postive to define the maximum number of packets which will be buffered
- * for each UDP socket.
- * Can be overridden with the socket option FREERTOS_SO_UDP_MAX_RX_PACKETS
- */
- #define ipconfigUDP_MAX_RX_PACKETS 0u
-#endif
-
-#ifndef ipconfigUSE_DHCP
- #define ipconfigUSE_DHCP 1
-#endif
-
-#ifndef ipconfigUSE_DHCP_HOOK
- #define ipconfigUSE_DHCP_HOOK 0
-#endif
-
-#ifndef ipconfigDHCP_FALL_BACK_AUTO_IP
- /*
- * Only applicable when DHCP is in use:
- * If no DHCP server responds, use "Auto-IP" : the
- * device will allocate a random LinkLayer IP address.
- */
- #define ipconfigDHCP_FALL_BACK_AUTO_IP ( 0 )
-#endif
-
-#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
- #define ipconfigARP_USE_CLASH_DETECTION 1
-#endif
-
-#ifndef ipconfigARP_USE_CLASH_DETECTION
- #define ipconfigARP_USE_CLASH_DETECTION 0
-#endif
-
-#ifndef ipconfigNETWORK_MTU
- #define ipconfigNETWORK_MTU 1500
-#endif
-
-#ifndef ipconfigTCP_MSS
- #define ipconfigTCP_MSS ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER - ipSIZE_OF_TCP_HEADER )
-#endif
-
-/* Each TCP socket has circular stream buffers for Rx and Tx, which
- * have a fixed maximum size.
- * The defaults for these size are defined here, although
- * they can be overridden at runtime by using the setsockopt() call */
-#ifndef ipconfigTCP_RX_BUFFER_LENGTH
- #define ipconfigTCP_RX_BUFFER_LENGTH ( 4u * ipconfigTCP_MSS ) /* defaults to 5840 bytes */
-#endif
-
-/* Define the size of Tx stream buffer for TCP sockets */
-#ifndef ipconfigTCP_TX_BUFFER_LENGTH
-# define ipconfigTCP_TX_BUFFER_LENGTH ( 4u * ipconfigTCP_MSS ) /* defaults to 5840 bytes */
-#endif
-
-#ifndef ipconfigMAXIMUM_DISCOVER_TX_PERIOD
- #ifdef _WINDOWS_
- #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 999 ) )
- #else
- #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 30000 ) )
- #endif /* _WINDOWS_ */
-#endif /* ipconfigMAXIMUM_DISCOVER_TX_PERIOD */
-
-#if( ipconfigUSE_DNS == 0 )
- /* The DNS module will not be included. */
- #if( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) )
- /* LLMNR and NBNS depend on DNS because those protocols share a lot of code. */
- #error When either LLMNR or NBNS is used, ipconfigUSE_DNS must be defined
- #endif
-#endif
-
-#ifndef ipconfigUSE_DNS
- #define ipconfigUSE_DNS 1
-#endif
-
-#ifndef ipconfigDNS_REQUEST_ATTEMPTS
- #define ipconfigDNS_REQUEST_ATTEMPTS 5
-#endif
-
-#ifndef ipconfigUSE_DNS_CACHE
- #define ipconfigUSE_DNS_CACHE 0
-#endif
-
-#if( ipconfigUSE_DNS_CACHE != 0 )
- #ifndef ipconfigDNS_CACHE_NAME_LENGTH
- /* Per https://tools.ietf.org/html/rfc1035, 253 is the maximum string length
- of a DNS name. The following default accounts for a null terminator. */
- #define ipconfigDNS_CACHE_NAME_LENGTH 254
- #endif
-
- #ifndef ipconfigDNS_CACHE_ENTRIES
- #define ipconfigDNS_CACHE_ENTRIES 1
- #endif
-#endif /* ipconfigUSE_DNS_CACHE != 0 */
-
-#ifndef ipconfigCHECK_IP_QUEUE_SPACE
- #define ipconfigCHECK_IP_QUEUE_SPACE 0
-#endif
-
-#ifndef ipconfigUSE_LLMNR
- /* Include support for LLMNR: Link-local Multicast Name Resolution (non-Microsoft) */
- #define ipconfigUSE_LLMNR ( 0 )
-#endif
-
-#ifndef ipconfigREPLY_TO_INCOMING_PINGS
- #define ipconfigREPLY_TO_INCOMING_PINGS 1
-#endif
-
-#ifndef ipconfigSUPPORT_OUTGOING_PINGS
- #define ipconfigSUPPORT_OUTGOING_PINGS 0
-#endif
-
-#ifndef ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES
- #define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
-#endif
-
-#ifndef ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES
- #define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
-#endif
-
-#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
- #define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS 0
-#else
- #define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS configINCLUDE_TRACE_RELATED_CLI_COMMANDS
-#endif
-
-#ifndef ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
- #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM ( 0 )
-#endif
-
-#ifndef ipconfigETHERNET_DRIVER_FILTERS_PACKETS
- #define ipconfigETHERNET_DRIVER_FILTERS_PACKETS ( 0 )
-#endif
-
-#ifndef ipconfigWATCHDOG_TIMER
- /* This macro will be called in every loop the IP-task makes. It may be
- replaced by user-code that triggers a watchdog */
- #define ipconfigWATCHDOG_TIMER()
-#endif
-
-#ifndef ipconfigUSE_CALLBACKS
- #define ipconfigUSE_CALLBACKS ( 0 )
-#endif
-
-#if( ipconfigUSE_CALLBACKS != 0 )
- #ifndef ipconfigIS_VALID_PROG_ADDRESS
- /* Replace this macro with a test returning non-zero if the memory pointer to by x
- * is valid memory which can contain executable code
- * In fact this is an extra safety measure: if a handler points to invalid memory,
- * it will not be called
- */
- #define ipconfigIS_VALID_PROG_ADDRESS(x) ( ( x ) != NULL )
- #endif
-#endif
-
-#ifndef ipconfigHAS_INLINE_FUNCTIONS
- #define ipconfigHAS_INLINE_FUNCTIONS ( 1 )
-#endif
-
-#ifndef portINLINE
- #define portINLINE inline
-#endif
-
-#ifndef ipconfigZERO_COPY_TX_DRIVER
- /* When non-zero, the buffers passed to the SEND routine may be passed
- to DMA. As soon as sending is ready, the buffers must be released by
- calling vReleaseNetworkBufferAndDescriptor(), */
- #define ipconfigZERO_COPY_TX_DRIVER ( 0 )
-#endif
-
-#ifndef ipconfigZERO_COPY_RX_DRIVER
- /* This define doesn't mean much to the driver, except that it makes
- sure that pxPacketBuffer_to_NetworkBuffer() will be included. */
- #define ipconfigZERO_COPY_RX_DRIVER ( 0 )
-#endif
-
-#ifndef ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM
- #define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 0
-#endif
-
-#ifndef ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
- #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 0
-#endif
-
-#ifndef ipconfigDHCP_REGISTER_HOSTNAME
- #define ipconfigDHCP_REGISTER_HOSTNAME 0
-#endif
-
-#ifndef ipconfigSOCKET_HAS_USER_SEMAPHORE
- #define ipconfigSOCKET_HAS_USER_SEMAPHORE 0
-#endif
-
-#ifndef ipconfigSOCKET_HAS_USER_WAKE_CALLBACK
- #define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK 0
-#endif
-
-#ifndef ipconfigSUPPORT_SELECT_FUNCTION
- #define ipconfigSUPPORT_SELECT_FUNCTION 0
-#endif
-
-#ifndef ipconfigTCP_KEEP_ALIVE
- #define ipconfigTCP_KEEP_ALIVE 0
-#endif
-
-#ifndef ipconfigDNS_USE_CALLBACKS
- #define ipconfigDNS_USE_CALLBACKS 0
-#endif
-
-#ifndef ipconfigSUPPORT_SIGNALS
- #define ipconfigSUPPORT_SIGNALS 0
-#endif
-
-#ifndef ipconfigUSE_NBNS
- #define ipconfigUSE_NBNS 0
-#endif
-
-/* As an attack surface reduction for ports that listen for inbound
-connections, hang protection can help reduce the impact of SYN floods. */
-#ifndef ipconfigTCP_HANG_PROTECTION
- #define ipconfigTCP_HANG_PROTECTION 1
-#endif
-
-/* Non-activity timeout is expressed in seconds. */
-#ifndef ipconfigTCP_HANG_PROTECTION_TIME
- #define ipconfigTCP_HANG_PROTECTION_TIME 30
-#endif
-
-#ifndef ipconfigTCP_IP_SANITY
- #define ipconfigTCP_IP_SANITY 0
-#endif
-
-#ifndef ipconfigARP_STORES_REMOTE_ADDRESSES
- #define ipconfigARP_STORES_REMOTE_ADDRESSES 0
-#endif
-
-#ifndef ipconfigBUFFER_PADDING
- /* Expert option: define a value for 'ipBUFFER_PADDING'.
- When 'ipconfigBUFFER_PADDING' equals 0,
- 'ipBUFFER_PADDING' will get a default value of 8 + 2 bytes. */
- #define ipconfigBUFFER_PADDING 0
-#endif
-
-#ifndef ipconfigPACKET_FILLER_SIZE
- #define ipconfigPACKET_FILLER_SIZE 2
-#endif
-
-#endif /* FREERTOS_DEFAULT_IP_CONFIG_H */
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+#ifndef FREERTOS_DEFAULT_IP_CONFIG_H
+#define FREERTOS_DEFAULT_IP_CONFIG_H
+
+/* The error numbers defined in this file will be moved to the core FreeRTOS
+code in future versions of FreeRTOS - at which time the following header file
+will be removed. */
+#include "FreeRTOS_errno_TCP.h"
+
+/* This file provides default values for configuration options that are missing
+from the FreeRTOSIPConfig.h configuration header file. */
+
+
+/* Ensure defined configuration constants are using the most up to date naming. */
+#ifdef tcpconfigIP_TIME_TO_LIVE
+ #error now called: ipconfigTCP_TIME_TO_LIVE
+#endif
+
+#ifdef updconfigIP_TIME_TO_LIVE
+ #error now called: ipconfigUDP_TIME_TO_LIVE
+#endif
+
+#ifdef ipFILLER_SIZE
+ #error now called: ipconfigPACKET_FILLER_SIZE
+#endif
+
+#ifdef dnsMAX_REQUEST_ATTEMPTS
+ #error now called: ipconfigDNS_REQUEST_ATTEMPTS
+#endif
+
+#ifdef ipconfigUDP_TASK_PRIORITY
+ #error now called: ipconfigIP_TASK_PRIORITY
+#endif
+
+#ifdef ipconfigUDP_TASK_STACK_SIZE_WORDS
+ #error now called: ipconfigIP_TASK_STACK_SIZE_WORDS
+#endif
+
+#ifdef ipconfigDRIVER_INCLUDED_RX_IP_FILTERING
+ #error now called: ipconfigETHERNET_DRIVER_FILTERS_PACKETS
+#endif
+
+#ifdef ipconfigMAX_SEND_BLOCK_TIME_TICKS
+ #error now called: ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS
+#endif
+
+#ifdef ipconfigUSE_RECEIVE_CONNECT_CALLBACKS
+ #error now called: ipconfigUSE_CALLBACKS
+#endif
+
+#ifdef ipconfigNUM_NETWORK_BUFFERS
+ #error now called: ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
+#endif
+
+#ifdef ipconfigTCP_HANG_PROT
+ #error now called: ipconfigTCP_HANG_PROTECTION
+#endif
+
+#ifdef ipconfigTCP_HANG_PROT_TIME
+ #error now called: ipconfigTCP_HANG_PROTECTION_TIME
+#endif
+
+#ifdef FreeRTOS_lprintf
+ #error now called: FreeRTOS_debug_printf
+#endif
+
+#if ( ipconfigEVENT_QUEUE_LENGTH < ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 ) )
+ #error The ipconfigEVENT_QUEUE_LENGTH parameter must be at least ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5
+#endif
+
+#if ( ipconfigNETWORK_MTU < 46 )
+ #error ipconfigNETWORK_MTU must be at least 46.
+#endif
+
+#ifdef ipconfigBUFFER_ALLOC_FIXED_SIZE
+ #error ipconfigBUFFER_ALLOC_FIXED_SIZE was dropped and replaced by a const value, declared in BufferAllocation[12].c
+#endif
+
+#ifdef ipconfigNIC_SEND_PASSES_DMA
+ #error now called: ipconfigZERO_COPY_TX_DRIVER
+#endif
+
+#ifdef HAS_TX_CRC_OFFLOADING
+ /* _HT_ As these macro names have changed, throw an error
+ if they're still defined. */
+ #error now called: ipconfigHAS_TX_CRC_OFFLOADING
+#endif
+
+#ifdef HAS_RX_CRC_OFFLOADING
+ #error now called: ipconfigHAS_RX_CRC_OFFLOADING
+#endif
+
+#ifdef ipconfigTCP_RX_BUF_LEN
+ #error ipconfigTCP_RX_BUF_LEN is now called ipconfigTCP_RX_BUFFER_LENGTH
+#endif
+
+#ifdef ipconfigTCP_TX_BUF_LEN
+ #error ipconfigTCP_TX_BUF_LEN is now called ipconfigTCP_TX_BUFFER_LENGTH
+#endif
+
+#ifdef ipconfigDHCP_USES_USER_HOOK
+ #error ipconfigDHCP_USES_USER_HOOK and its associated callback have been superceeded - see http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html#ipconfigUSE_DHCP_HOOK
+#endif
+
+#ifndef ipconfigUSE_TCP
+ #define ipconfigUSE_TCP ( 1 )
+#endif
+
+#if ipconfigUSE_TCP
+
+ /* Include support for TCP scaling windows */
+ #ifndef ipconfigUSE_TCP_WIN
+ #define ipconfigUSE_TCP_WIN ( 1 )
+ #endif
+
+ #ifndef ipconfigTCP_WIN_SEG_COUNT
+ #define ipconfigTCP_WIN_SEG_COUNT ( 256 )
+ #endif
+
+ #ifndef ipconfigIGNORE_UNKNOWN_PACKETS
+ /* When non-zero, TCP will not send RST packets in reply to
+ TCP packets which are unknown, or out-of-order. */
+ #define ipconfigIGNORE_UNKNOWN_PACKETS ( 0 )
+ #endif
+#endif
+
+/*
+ * For debuging/logging: check if the port number is used for telnet
+ * Some events will not be logged for telnet connections
+ * because it would produce logging about the transmission of the logging...
+ * This macro will only be used if FreeRTOS_debug_printf() is defined for logging
+ */
+#ifndef ipconfigTCP_MAY_LOG_PORT
+ #define ipconfigTCP_MAY_LOG_PORT(xPort) ( ( xPort ) != 23u )
+#endif
+
+
+#ifndef ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME
+ #define ipconfigSOCK_DEFAULT_RECEIVE_BLOCK_TIME portMAX_DELAY
+#endif
+
+#ifndef ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME
+ #define ipconfigSOCK_DEFAULT_SEND_BLOCK_TIME portMAX_DELAY
+#endif
+
+
+#ifndef ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS
+ #define ipconfigDNS_RECEIVE_BLOCK_TIME_TICKS pdMS_TO_TICKS( 500u )
+#endif
+
+#ifndef ipconfigDNS_SEND_BLOCK_TIME_TICKS
+ #define ipconfigDNS_SEND_BLOCK_TIME_TICKS pdMS_TO_TICKS( 500u )
+#endif
+/*
+ * FreeRTOS debug logging routine (proposal)
+ * The macro will be called in the printf() style. Users can define
+ * their own logging routine as:
+ *
+ * #define FreeRTOS_debug_printf( MSG ) my_printf MSG
+ *
+ * The FreeRTOS_debug_printf() must be thread-safe but does not have to be
+ * interrupt-safe.
+ */
+#ifdef ipconfigHAS_DEBUG_PRINTF
+ #if( ipconfigHAS_DEBUG_PRINTF == 0 )
+ #ifdef FreeRTOS_debug_printf
+ #error Do not define FreeRTOS_debug_print if ipconfigHAS_DEBUG_PRINTF is set to 0
+ #endif /* ifdef FreeRTOS_debug_printf */
+ #endif /* ( ipconfigHAS_DEBUG_PRINTF == 0 ) */
+#endif /* ifdef ipconfigHAS_DEBUG_PRINTF */
+
+#ifndef FreeRTOS_debug_printf
+ #define FreeRTOS_debug_printf( MSG ) do{} while(0)
+ #define ipconfigHAS_DEBUG_PRINTF 0
+#endif
+
+/*
+ * FreeRTOS general logging routine (proposal)
+ * Used in some utility functions such as FreeRTOS_netstat() and FreeRTOS_PrintARPCache()
+ *
+ * #define FreeRTOS_printf( MSG ) my_printf MSG
+ *
+ * The FreeRTOS_printf() must be thread-safe but does not have to be interrupt-safe
+ */
+#ifdef ipconfigHAS_PRINTF
+ #if( ipconfigHAS_PRINTF == 0 )
+ #ifdef FreeRTOS_printf
+ #error Do not define FreeRTOS_print if ipconfigHAS_PRINTF is set to 0
+ #endif /* ifdef FreeRTOS_debug_printf */
+ #endif /* ( ipconfigHAS_PRINTF == 0 ) */
+#endif /* ifdef ipconfigHAS_PRINTF */
+
+#ifndef FreeRTOS_printf
+ #define FreeRTOS_printf( MSG ) do{} while(0)
+ #define ipconfigHAS_PRINTF 0
+#endif
+
+/*
+ * In cases where a lot of logging is produced, FreeRTOS_flush_logging( )
+ * will be called to give the logging module a chance to flush the data
+ * An example of this is the netstat command, which produces many lines of logging
+ */
+#ifndef FreeRTOS_flush_logging
+ #define FreeRTOS_flush_logging( ) do{} while(0)
+#endif
+
+/* Malloc functions. Within most applications of FreeRTOS, the couple
+ * pvPortMalloc()/vPortFree() will be used.
+ * If there is also SDRAM, the user may decide to use a different memory
+ * allocator:
+ * MallocLarge is used to allocate large TCP buffers (for Rx/Tx)
+ * MallocSocket is used to allocate the space for the sockets
+ */
+#ifndef pvPortMallocLarge
+ #define pvPortMallocLarge( x ) pvPortMalloc( x )
+#endif
+
+#ifndef vPortFreeLarge
+ #define vPortFreeLarge(ptr) vPortFree(ptr)
+#endif
+
+#ifndef pvPortMallocSocket
+ #define pvPortMallocSocket( x ) pvPortMalloc( x )
+#endif
+
+#ifndef vPortFreeSocket
+ #define vPortFreeSocket(ptr) vPortFree(ptr)
+#endif
+
+/*
+ * At several places within the library, random numbers are needed:
+ * - DHCP: For creating a DHCP transaction number
+ * - TCP: Set the Initial Sequence Number: this is the value of the first outgoing
+ * sequence number being used when connecting to a peer.
+ * Having a well randomised ISN is important to avoid spoofing
+ * - UDP/TCP: for setting the first port number to be used, in case a socket
+ * uses a 'random' or anonymous port number
+ */
+#ifndef ipconfigRAND32
+ #define ipconfigRAND32() rand()
+#endif
+/* --------------------------------------------------------
+ * End of: HT Added some macro defaults for the PLUS-UDP project
+ * -------------------------------------------------------- */
+
+#ifndef ipconfigUSE_NETWORK_EVENT_HOOK
+ #define ipconfigUSE_NETWORK_EVENT_HOOK 0
+#endif
+
+#ifndef ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS
+ #define ipconfigUDP_MAX_SEND_BLOCK_TIME_TICKS ( pdMS_TO_TICKS( 20 ) )
+#endif
+
+#ifndef ipconfigARP_CACHE_ENTRIES
+ #define ipconfigARP_CACHE_ENTRIES 10
+#endif
+
+#ifndef ipconfigMAX_ARP_RETRANSMISSIONS
+ #define ipconfigMAX_ARP_RETRANSMISSIONS ( 5u )
+#endif
+
+#ifndef ipconfigMAX_ARP_AGE
+ #define ipconfigMAX_ARP_AGE 150u
+#endif
+
+#ifndef ipconfigUSE_ARP_REVERSED_LOOKUP
+ #define ipconfigUSE_ARP_REVERSED_LOOKUP 0
+#endif
+
+#ifndef ipconfigUSE_ARP_REMOVE_ENTRY
+ #define ipconfigUSE_ARP_REMOVE_ENTRY 0
+#endif
+
+#ifndef ipconfigINCLUDE_FULL_INET_ADDR
+ #define ipconfigINCLUDE_FULL_INET_ADDR 1
+#endif
+
+#ifndef ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS
+ #define ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS 45
+#endif
+
+#ifndef ipconfigEVENT_QUEUE_LENGTH
+ #define ipconfigEVENT_QUEUE_LENGTH ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS + 5 )
+#endif
+
+#ifndef ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND
+ #define ipconfigALLOW_SOCKET_SEND_WITHOUT_BIND 1
+#endif
+
+#ifndef ipconfigUDP_TIME_TO_LIVE
+ #define ipconfigUDP_TIME_TO_LIVE 128
+#endif
+
+#ifndef ipconfigTCP_TIME_TO_LIVE
+ #define ipconfigTCP_TIME_TO_LIVE 128
+#endif
+
+#ifndef ipconfigUDP_MAX_RX_PACKETS
+ /* Make postive to define the maximum number of packets which will be buffered
+ * for each UDP socket.
+ * Can be overridden with the socket option FREERTOS_SO_UDP_MAX_RX_PACKETS
+ */
+ #define ipconfigUDP_MAX_RX_PACKETS 0u
+#endif
+
+#ifndef ipconfigUSE_DHCP
+ #define ipconfigUSE_DHCP 1
+#endif
+
+#ifndef ipconfigUSE_DHCP_HOOK
+ #define ipconfigUSE_DHCP_HOOK 0
+#endif
+
+#ifndef ipconfigDHCP_FALL_BACK_AUTO_IP
+ /*
+ * Only applicable when DHCP is in use:
+ * If no DHCP server responds, use "Auto-IP" : the
+ * device will allocate a random LinkLayer IP address.
+ */
+ #define ipconfigDHCP_FALL_BACK_AUTO_IP ( 0 )
+#endif
+
+#if( ipconfigDHCP_FALL_BACK_AUTO_IP != 0 )
+ #define ipconfigARP_USE_CLASH_DETECTION 1
+#endif
+
+#ifndef ipconfigARP_USE_CLASH_DETECTION
+ #define ipconfigARP_USE_CLASH_DETECTION 0
+#endif
+
+#ifndef ipconfigNETWORK_MTU
+ #define ipconfigNETWORK_MTU 1500
+#endif
+
+#ifndef ipconfigTCP_MSS
+ #define ipconfigTCP_MSS ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER - ipSIZE_OF_TCP_HEADER )
+#endif
+
+/* Each TCP socket has circular stream buffers for Rx and Tx, which
+ * have a fixed maximum size.
+ * The defaults for these size are defined here, although
+ * they can be overridden at runtime by using the setsockopt() call */
+#ifndef ipconfigTCP_RX_BUFFER_LENGTH
+ #define ipconfigTCP_RX_BUFFER_LENGTH ( 4u * ipconfigTCP_MSS ) /* defaults to 5840 bytes */
+#endif
+
+/* Define the size of Tx stream buffer for TCP sockets */
+#ifndef ipconfigTCP_TX_BUFFER_LENGTH
+# define ipconfigTCP_TX_BUFFER_LENGTH ( 4u * ipconfigTCP_MSS ) /* defaults to 5840 bytes */
+#endif
+
+#ifndef ipconfigMAXIMUM_DISCOVER_TX_PERIOD
+ #ifdef _WINDOWS_
+ #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 999 ) )
+ #else
+ #define ipconfigMAXIMUM_DISCOVER_TX_PERIOD ( pdMS_TO_TICKS( 30000 ) )
+ #endif /* _WINDOWS_ */
+#endif /* ipconfigMAXIMUM_DISCOVER_TX_PERIOD */
+
+#if( ipconfigUSE_DNS == 0 )
+ /* The DNS module will not be included. */
+ #if( ( ipconfigUSE_LLMNR != 0 ) || ( ipconfigUSE_NBNS != 0 ) )
+ /* LLMNR and NBNS depend on DNS because those protocols share a lot of code. */
+ #error When either LLMNR or NBNS is used, ipconfigUSE_DNS must be defined
+ #endif
+#endif
+
+#ifndef ipconfigUSE_DNS
+ #define ipconfigUSE_DNS 1
+#endif
+
+#ifndef ipconfigDNS_REQUEST_ATTEMPTS
+ #define ipconfigDNS_REQUEST_ATTEMPTS 5
+#endif
+
+#ifndef ipconfigUSE_DNS_CACHE
+ #define ipconfigUSE_DNS_CACHE 0
+#endif
+
+#if( ipconfigUSE_DNS_CACHE != 0 )
+ #ifndef ipconfigDNS_CACHE_NAME_LENGTH
+ /* Per https://tools.ietf.org/html/rfc1035, 253 is the maximum string length
+ of a DNS name. The following default accounts for a null terminator. */
+ #define ipconfigDNS_CACHE_NAME_LENGTH 254
+ #endif
+
+ #ifndef ipconfigDNS_CACHE_ENTRIES
+ #define ipconfigDNS_CACHE_ENTRIES 1
+ #endif
+#endif /* ipconfigUSE_DNS_CACHE != 0 */
+
+#ifndef ipconfigCHECK_IP_QUEUE_SPACE
+ #define ipconfigCHECK_IP_QUEUE_SPACE 0
+#endif
+
+#ifndef ipconfigUSE_LLMNR
+ /* Include support for LLMNR: Link-local Multicast Name Resolution (non-Microsoft) */
+ #define ipconfigUSE_LLMNR ( 0 )
+#endif
+
+#ifndef ipconfigREPLY_TO_INCOMING_PINGS
+ #define ipconfigREPLY_TO_INCOMING_PINGS 1
+#endif
+
+#ifndef ipconfigSUPPORT_OUTGOING_PINGS
+ #define ipconfigSUPPORT_OUTGOING_PINGS 0
+#endif
+
+#ifndef ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES
+ #define ipconfigFILTER_OUT_NON_ETHERNET_II_FRAMES 1
+#endif
+
+#ifndef ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES
+ #define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
+#endif
+
+#ifndef configINCLUDE_TRACE_RELATED_CLI_COMMANDS
+ #define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS 0
+#else
+ #define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS configINCLUDE_TRACE_RELATED_CLI_COMMANDS
+#endif
+
+#ifndef ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
+ #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM ( 0 )
+#endif
+
+#ifndef ipconfigETHERNET_DRIVER_FILTERS_PACKETS
+ #define ipconfigETHERNET_DRIVER_FILTERS_PACKETS ( 0 )
+#endif
+
+#ifndef ipconfigWATCHDOG_TIMER
+ /* This macro will be called in every loop the IP-task makes. It may be
+ replaced by user-code that triggers a watchdog */
+ #define ipconfigWATCHDOG_TIMER()
+#endif
+
+#ifndef ipconfigUSE_CALLBACKS
+ #define ipconfigUSE_CALLBACKS ( 0 )
+#endif
+
+#if( ipconfigUSE_CALLBACKS != 0 )
+ #ifndef ipconfigIS_VALID_PROG_ADDRESS
+ /* Replace this macro with a test returning non-zero if the memory pointer to by x
+ * is valid memory which can contain executable code
+ * In fact this is an extra safety measure: if a handler points to invalid memory,
+ * it will not be called
+ */
+ #define ipconfigIS_VALID_PROG_ADDRESS(x) ( ( x ) != NULL )
+ #endif
+#endif
+
+#ifndef ipconfigHAS_INLINE_FUNCTIONS
+ #define ipconfigHAS_INLINE_FUNCTIONS ( 1 )
+#endif
+
+#ifndef portINLINE
+ #define portINLINE inline
+#endif
+
+#ifndef ipconfigZERO_COPY_TX_DRIVER
+ /* When non-zero, the buffers passed to the SEND routine may be passed
+ to DMA. As soon as sending is ready, the buffers must be released by
+ calling vReleaseNetworkBufferAndDescriptor(), */
+ #define ipconfigZERO_COPY_TX_DRIVER ( 0 )
+#endif
+
+#ifndef ipconfigZERO_COPY_RX_DRIVER
+ /* This define doesn't mean much to the driver, except that it makes
+ sure that pxPacketBuffer_to_NetworkBuffer() will be included. */
+ #define ipconfigZERO_COPY_RX_DRIVER ( 0 )
+#endif
+
+#ifndef ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM
+ #define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 0
+#endif
+
+#ifndef ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM
+ #define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 0
+#endif
+
+#ifndef ipconfigDHCP_REGISTER_HOSTNAME
+ #define ipconfigDHCP_REGISTER_HOSTNAME 0
+#endif
+
+#ifndef ipconfigSOCKET_HAS_USER_SEMAPHORE
+ #define ipconfigSOCKET_HAS_USER_SEMAPHORE 0
+#endif
+
+#ifndef ipconfigSOCKET_HAS_USER_WAKE_CALLBACK
+ #define ipconfigSOCKET_HAS_USER_WAKE_CALLBACK 0
+#endif
+
+#ifndef ipconfigSUPPORT_SELECT_FUNCTION
+ #define ipconfigSUPPORT_SELECT_FUNCTION 0
+#endif
+
+#ifndef ipconfigTCP_KEEP_ALIVE
+ #define ipconfigTCP_KEEP_ALIVE 0
+#endif
+
+#ifndef ipconfigDNS_USE_CALLBACKS
+ #define ipconfigDNS_USE_CALLBACKS 0
+#endif
+
+#ifndef ipconfigSUPPORT_SIGNALS
+ #define ipconfigSUPPORT_SIGNALS 0
+#endif
+
+#ifndef ipconfigUSE_NBNS
+ #define ipconfigUSE_NBNS 0
+#endif
+
+/* As an attack surface reduction for ports that listen for inbound
+connections, hang protection can help reduce the impact of SYN floods. */
+#ifndef ipconfigTCP_HANG_PROTECTION
+ #define ipconfigTCP_HANG_PROTECTION 1
+#endif
+
+/* Non-activity timeout is expressed in seconds. */
+#ifndef ipconfigTCP_HANG_PROTECTION_TIME
+ #define ipconfigTCP_HANG_PROTECTION_TIME 30
+#endif
+
+#ifndef ipconfigTCP_IP_SANITY
+ #define ipconfigTCP_IP_SANITY 0
+#endif
+
+#ifndef ipconfigARP_STORES_REMOTE_ADDRESSES
+ #define ipconfigARP_STORES_REMOTE_ADDRESSES 0
+#endif
+
+#ifndef ipconfigBUFFER_PADDING
+ /* Expert option: define a value for 'ipBUFFER_PADDING'.
+ When 'ipconfigBUFFER_PADDING' equals 0,
+ 'ipBUFFER_PADDING' will get a default value of 8 + 2 bytes. */
+ #define ipconfigBUFFER_PADDING 0
+#endif
+
+#ifndef ipconfigPACKET_FILLER_SIZE
+ #define ipconfigPACKET_FILLER_SIZE 2
+#endif
+
+#endif /* FREERTOS_DEFAULT_IP_CONFIG_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h
index 166bf3a97..363fca425 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_ARP.h
@@ -1,141 +1,141 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_ARP_H
-#define FREERTOS_ARP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-#include "FreeRTOSIPConfigDefaults.h"
-#include "IPTraceMacroDefaults.h"
-
-/*-----------------------------------------------------------*/
-/* Miscellaneous structure and definitions. */
-/*-----------------------------------------------------------*/
-
-typedef struct xARP_CACHE_TABLE_ROW
-{
- uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
- MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
- uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
- uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
-} ARPCacheRow_t;
-
-typedef enum
-{
- eARPCacheMiss = 0, /* 0 An ARP table lookup did not find a valid entry. */
- eARPCacheHit, /* 1 An ARP table lookup found a valid entry. */
- eCantSendPacket /* 2 There is no IP address, or an ARP is still in progress, so the packet cannot be sent. */
-} eARPLookupResult_t;
-
-typedef enum
-{
- eNotFragment = 0, /* The IP packet being sent is not part of a fragment. */
- eFirstFragment, /* The IP packet being sent is the first in a set of fragmented packets. */
- eFollowingFragment /* The IP packet being sent is part of a set of fragmented packets. */
-} eIPFragmentStatus_t;
-
-/*
- * If ulIPAddress is already in the ARP cache table then reset the age of the
- * entry back to its maximum value. If ulIPAddress is not already in the ARP
- * cache table then add it - replacing the oldest current entry if there is not
- * a free space available.
- */
-void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress );
-
-#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
- /* Becomes non-zero if another device responded to a gratuitos ARP message. */
- extern BaseType_t xARPHadIPClash;
- /* MAC-address of the other device containing the same IP-address. */
- extern MACAddress_t xARPClashMacAddress;
-#endif /* ipconfigARP_USE_CLASH_DETECTION */
-
-#if( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
-
- /*
- * In some rare cases, it might be useful to remove a ARP cache entry of a
- * known MAC address to make sure it gets refreshed.
- */
- uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress );
-
-#endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
-
-/*
- * Look for ulIPAddress in the ARP cache. If the IP address exists, copy the
- * associated MAC address into pxMACAddress, refresh the ARP cache entry's
- * age, and return eARPCacheHit. If the IP address does not exist in the ARP
- * cache return eARPCacheMiss. If the packet cannot be sent for any reason
- * (maybe DHCP is still in process, or the addressing needs a gateway but there
- * isn't a gateway defined) then return eCantSendPacket.
- */
-eARPLookupResult_t eARPGetCacheEntry( uint32_t *pulIPAddress, MACAddress_t * const pxMACAddress );
-
-#if( ipconfigUSE_ARP_REVERSED_LOOKUP != 0 )
-
- /* Lookup an IP-address if only the MAC-address is known */
- eARPLookupResult_t eARPGetCacheEntryByMac( MACAddress_t * const pxMACAddress, uint32_t *pulIPAddress );
-
-#endif
-/*
- * Reduce the age count in each entry within the ARP cache. An entry is no
- * longer considered valid and is deleted if its age reaches zero.
- */
-void vARPAgeCache( void );
-
-/*
- * Send out an ARP request for the IP address contained in pxNetworkBuffer, and
- * add an entry into the ARP table that indicates that an ARP reply is
- * outstanding so re-transmissions can be generated.
- */
-void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
-
-/*
- * After DHCP is ready and when changing IP address, force a quick send of our new IP
- * address
- */
-void vARPSendGratuitous( void );
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* FREERTOS_ARP_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_ARP_H
+#define FREERTOS_ARP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+#include "FreeRTOSIPConfigDefaults.h"
+#include "IPTraceMacroDefaults.h"
+
+/*-----------------------------------------------------------*/
+/* Miscellaneous structure and definitions. */
+/*-----------------------------------------------------------*/
+
+typedef struct xARP_CACHE_TABLE_ROW
+{
+ uint32_t ulIPAddress; /* The IP address of an ARP cache entry. */
+ MACAddress_t xMACAddress; /* The MAC address of an ARP cache entry. */
+ uint8_t ucAge; /* A value that is periodically decremented but can also be refreshed by active communication. The ARP cache entry is removed if the value reaches zero. */
+ uint8_t ucValid; /* pdTRUE: xMACAddress is valid, pdFALSE: waiting for ARP reply */
+} ARPCacheRow_t;
+
+typedef enum
+{
+ eARPCacheMiss = 0, /* 0 An ARP table lookup did not find a valid entry. */
+ eARPCacheHit, /* 1 An ARP table lookup found a valid entry. */
+ eCantSendPacket /* 2 There is no IP address, or an ARP is still in progress, so the packet cannot be sent. */
+} eARPLookupResult_t;
+
+typedef enum
+{
+ eNotFragment = 0, /* The IP packet being sent is not part of a fragment. */
+ eFirstFragment, /* The IP packet being sent is the first in a set of fragmented packets. */
+ eFollowingFragment /* The IP packet being sent is part of a set of fragmented packets. */
+} eIPFragmentStatus_t;
+
+/*
+ * If ulIPAddress is already in the ARP cache table then reset the age of the
+ * entry back to its maximum value. If ulIPAddress is not already in the ARP
+ * cache table then add it - replacing the oldest current entry if there is not
+ * a free space available.
+ */
+void vARPRefreshCacheEntry( const MACAddress_t * pxMACAddress, const uint32_t ulIPAddress );
+
+#if( ipconfigARP_USE_CLASH_DETECTION != 0 )
+ /* Becomes non-zero if another device responded to a gratuitos ARP message. */
+ extern BaseType_t xARPHadIPClash;
+ /* MAC-address of the other device containing the same IP-address. */
+ extern MACAddress_t xARPClashMacAddress;
+#endif /* ipconfigARP_USE_CLASH_DETECTION */
+
+#if( ipconfigUSE_ARP_REMOVE_ENTRY != 0 )
+
+ /*
+ * In some rare cases, it might be useful to remove a ARP cache entry of a
+ * known MAC address to make sure it gets refreshed.
+ */
+ uint32_t ulARPRemoveCacheEntryByMac( const MACAddress_t * pxMACAddress );
+
+#endif /* ipconfigUSE_ARP_REMOVE_ENTRY != 0 */
+
+/*
+ * Look for ulIPAddress in the ARP cache. If the IP address exists, copy the
+ * associated MAC address into pxMACAddress, refresh the ARP cache entry's
+ * age, and return eARPCacheHit. If the IP address does not exist in the ARP
+ * cache return eARPCacheMiss. If the packet cannot be sent for any reason
+ * (maybe DHCP is still in process, or the addressing needs a gateway but there
+ * isn't a gateway defined) then return eCantSendPacket.
+ */
+eARPLookupResult_t eARPGetCacheEntry( uint32_t *pulIPAddress, MACAddress_t * const pxMACAddress );
+
+#if( ipconfigUSE_ARP_REVERSED_LOOKUP != 0 )
+
+ /* Lookup an IP-address if only the MAC-address is known */
+ eARPLookupResult_t eARPGetCacheEntryByMac( MACAddress_t * const pxMACAddress, uint32_t *pulIPAddress );
+
+#endif
+/*
+ * Reduce the age count in each entry within the ARP cache. An entry is no
+ * longer considered valid and is deleted if its age reaches zero.
+ */
+void vARPAgeCache( void );
+
+/*
+ * Send out an ARP request for the IP address contained in pxNetworkBuffer, and
+ * add an entry into the ARP table that indicates that an ARP reply is
+ * outstanding so re-transmissions can be generated.
+ */
+void vARPGenerateRequestPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
+
+/*
+ * After DHCP is ready and when changing IP address, force a quick send of our new IP
+ * address
+ */
+void vARPSendGratuitous( void );
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* FREERTOS_ARP_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h
index 6a6d372b6..a49909eb2 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DHCP.h
@@ -1,87 +1,87 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_DHCP_H
-#define FREERTOS_DHCP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-#include "IPTraceMacroDefaults.h"
-
-/* Used in the DHCP callback if ipconfigUSE_DHCP_HOOK is set to 1. */
-typedef enum eDHCP_PHASE
-{
- eDHCPPhasePreDiscover, /* Driver is about to send a DHCP discovery. */
- eDHCPPhasePreRequest, /* Driver is about to request DHCP an IP address. */
-#if( ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP != 0 )
- eDHCPPhasePreLLA, /* Driver is about to try get an LLA address */
-#endif /* ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP */
-} eDHCPCallbackPhase_t;
-
-/* Used in the DHCP callback if ipconfigUSE_DHCP_HOOK is set to 1. */
-typedef enum eDHCP_ANSWERS
-{
- eDHCPContinue, /* Continue the DHCP process */
- eDHCPUseDefaults, /* Stop DHCP and use the static defaults. */
- eDHCPStopNoChanges, /* Stop DHCP and continue with current settings. */
-} eDHCPCallbackAnswer_t;
-
-/*
- * NOT A PUBLIC API FUNCTION.
- */
-void vDHCPProcess( BaseType_t xReset );
-
-/* Internal call: returns true if socket is the current DHCP socket */
-BaseType_t xIsDHCPSocket( Socket_t xSocket );
-
-/* Prototype of the hook (or callback) function that must be provided by the
-application if ipconfigUSE_DHCP_HOOK is set to 1. See the following URL for
-usage information:
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html#ipconfigUSE_DHCP_HOOK
-*/
-eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress );
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* FREERTOS_DHCP_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_DHCP_H
+#define FREERTOS_DHCP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+#include "IPTraceMacroDefaults.h"
+
+/* Used in the DHCP callback if ipconfigUSE_DHCP_HOOK is set to 1. */
+typedef enum eDHCP_PHASE
+{
+ eDHCPPhasePreDiscover, /* Driver is about to send a DHCP discovery. */
+ eDHCPPhasePreRequest, /* Driver is about to request DHCP an IP address. */
+#if( ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP != 0 )
+ eDHCPPhasePreLLA, /* Driver is about to try get an LLA address */
+#endif /* ipconfigDHCP_SEND_DISCOVER_AFTER_AUTO_IP */
+} eDHCPCallbackPhase_t;
+
+/* Used in the DHCP callback if ipconfigUSE_DHCP_HOOK is set to 1. */
+typedef enum eDHCP_ANSWERS
+{
+ eDHCPContinue, /* Continue the DHCP process */
+ eDHCPUseDefaults, /* Stop DHCP and use the static defaults. */
+ eDHCPStopNoChanges, /* Stop DHCP and continue with current settings. */
+} eDHCPCallbackAnswer_t;
+
+/*
+ * NOT A PUBLIC API FUNCTION.
+ */
+void vDHCPProcess( BaseType_t xReset );
+
+/* Internal call: returns true if socket is the current DHCP socket */
+BaseType_t xIsDHCPSocket( Socket_t xSocket );
+
+/* Prototype of the hook (or callback) function that must be provided by the
+application if ipconfigUSE_DHCP_HOOK is set to 1. See the following URL for
+usage information:
+http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Configuration.html#ipconfigUSE_DHCP_HOOK
+*/
+eDHCPCallbackAnswer_t xApplicationDHCPHook( eDHCPCallbackPhase_t eDHCPPhase, uint32_t ulIPAddress );
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* FREERTOS_DHCP_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h
index 449fa514f..0458d7621 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_DNS.h
@@ -1,137 +1,137 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_DNS_H
-#define FREERTOS_DNS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-#include "IPTraceMacroDefaults.h"
-
-
-/* The Link-local Multicast Name Resolution (LLMNR)
- * is included.
- * Note that a special MAC address is required in addition to the NIC's actual
- * MAC address: 01:00:5E:00:00:FC
- *
- * The target IP address will be 224.0.0.252
- */
-#if( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
- #define ipLLMNR_IP_ADDR 0xE00000FC
-#else
- #define ipLLMNR_IP_ADDR 0xFC0000E0
-#endif /* ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN */
-
-#define ipLLMNR_PORT 5355 /* Standard LLMNR port. */
-#define ipDNS_PORT 53 /* Standard DNS port. */
-#define ipDHCP_CLIENT 67
-#define ipDHCP_SERVER 68
-#define ipNBNS_PORT 137 /* NetBIOS Name Service. */
-#define ipNBDGM_PORT 138 /* Datagram Service, not included. */
-
-/*
- * The following function should be provided by the user and return true if it
- * matches the domain name.
- */
-extern BaseType_t xApplicationDNSQueryHook( const char *pcName );
-
-/*
- * LLMNR is very similar to DNS, so is handled by the DNS routines.
- */
-uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-#if( ipconfigUSE_LLMNR == 1 )
- extern const MACAddress_t xLLMNR_MacAdress;
-#endif /* ipconfigUSE_LLMNR */
-
-#if( ipconfigUSE_NBNS != 0 )
-
- /*
- * Inspect a NetBIOS Names-Service message. If the name matches with ours
- * (xApplicationDNSQueryHook returns true) an answer will be sent back.
- * Note that LLMNR is a better protocol for name services on a LAN as it is
- * less polluted
- */
- uint32_t ulNBNSHandlePacket (NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-#endif /* ipconfigUSE_NBNS */
-
-#if( ipconfigUSE_DNS_CACHE != 0 )
-
- /* Look for the indicated host name in the DNS cache. Returns the IPv4
- address if present, or 0x0 otherwise. */
- uint32_t FreeRTOS_dnslookup( const char *pcHostName );
-
- /* Remove all entries from the DNS cache. */
- void FreeRTOS_dnsclear();
-#endif /* ipconfigUSE_DNS_CACHE != 0 */
-
-#if( ipconfigDNS_USE_CALLBACKS != 0 )
-
- /*
- * Users may define this type of function as a callback.
- * It will be called when a DNS reply is received or when a timeout has been reached.
- */
- typedef void (* FOnDNSEvent ) ( const char * /* pcName */, void * /* pvSearchID */, uint32_t /* ulIPAddress */ );
-
- /*
- * Asynchronous version of gethostbyname()
- * xTimeout is in units of ms.
- */
- uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName, FOnDNSEvent pCallback, void *pvSearchID, TickType_t xTimeout );
- void FreeRTOS_gethostbyname_cancel( void *pvSearchID );
-
-#endif
-
-/*
- * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
- * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
- * _TBD_ Add URL
- */
-uint32_t FreeRTOS_gethostbyname( const char *pcHostName );
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* FREERTOS_DNS_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_DNS_H
+#define FREERTOS_DNS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+#include "IPTraceMacroDefaults.h"
+
+
+/* The Link-local Multicast Name Resolution (LLMNR)
+ * is included.
+ * Note that a special MAC address is required in addition to the NIC's actual
+ * MAC address: 01:00:5E:00:00:FC
+ *
+ * The target IP address will be 224.0.0.252
+ */
+#if( ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN )
+ #define ipLLMNR_IP_ADDR 0xE00000FC
+#else
+ #define ipLLMNR_IP_ADDR 0xFC0000E0
+#endif /* ipconfigBYTE_ORDER == pdFREERTOS_BIG_ENDIAN */
+
+#define ipLLMNR_PORT 5355 /* Standard LLMNR port. */
+#define ipDNS_PORT 53 /* Standard DNS port. */
+#define ipDHCP_CLIENT 67
+#define ipDHCP_SERVER 68
+#define ipNBNS_PORT 137 /* NetBIOS Name Service. */
+#define ipNBDGM_PORT 138 /* Datagram Service, not included. */
+
+/*
+ * The following function should be provided by the user and return true if it
+ * matches the domain name.
+ */
+extern BaseType_t xApplicationDNSQueryHook( const char *pcName );
+
+/*
+ * LLMNR is very similar to DNS, so is handled by the DNS routines.
+ */
+uint32_t ulDNSHandlePacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+#if( ipconfigUSE_LLMNR == 1 )
+ extern const MACAddress_t xLLMNR_MacAdress;
+#endif /* ipconfigUSE_LLMNR */
+
+#if( ipconfigUSE_NBNS != 0 )
+
+ /*
+ * Inspect a NetBIOS Names-Service message. If the name matches with ours
+ * (xApplicationDNSQueryHook returns true) an answer will be sent back.
+ * Note that LLMNR is a better protocol for name services on a LAN as it is
+ * less polluted
+ */
+ uint32_t ulNBNSHandlePacket (NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+#endif /* ipconfigUSE_NBNS */
+
+#if( ipconfigUSE_DNS_CACHE != 0 )
+
+ /* Look for the indicated host name in the DNS cache. Returns the IPv4
+ address if present, or 0x0 otherwise. */
+ uint32_t FreeRTOS_dnslookup( const char *pcHostName );
+
+ /* Remove all entries from the DNS cache. */
+ void FreeRTOS_dnsclear();
+#endif /* ipconfigUSE_DNS_CACHE != 0 */
+
+#if( ipconfigDNS_USE_CALLBACKS != 0 )
+
+ /*
+ * Users may define this type of function as a callback.
+ * It will be called when a DNS reply is received or when a timeout has been reached.
+ */
+ typedef void (* FOnDNSEvent ) ( const char * /* pcName */, void * /* pvSearchID */, uint32_t /* ulIPAddress */ );
+
+ /*
+ * Asynchronous version of gethostbyname()
+ * xTimeout is in units of ms.
+ */
+ uint32_t FreeRTOS_gethostbyname_a( const char *pcHostName, FOnDNSEvent pCallback, void *pvSearchID, TickType_t xTimeout );
+ void FreeRTOS_gethostbyname_cancel( void *pvSearchID );
+
+#endif
+
+/*
+ * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
+ * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
+ * _TBD_ Add URL
+ */
+uint32_t FreeRTOS_gethostbyname( const char *pcHostName );
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* FREERTOS_DNS_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
index 6bfb4ad42..46a215777 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP.h
@@ -1,337 +1,337 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_IP_H
-#define FREERTOS_IP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-#include "FreeRTOSIPConfigDefaults.h"
-#include "IPTraceMacroDefaults.h"
-
-/* Some constants defining the sizes of several parts of a packet */
-#define ipSIZE_OF_ETH_HEADER 14u
-#define ipSIZE_OF_IPv4_HEADER 20u
-#define ipSIZE_OF_IGMP_HEADER 8u
-#define ipSIZE_OF_ICMP_HEADER 8u
-#define ipSIZE_OF_UDP_HEADER 8u
-#define ipSIZE_OF_TCP_HEADER 20u
-
-
-/* The number of octets in the MAC and IP addresses respectively. */
-#define ipMAC_ADDRESS_LENGTH_BYTES ( 6 )
-#define ipIP_ADDRESS_LENGTH_BYTES ( 4 )
-
-/* IP protocol definitions. */
-#define ipPROTOCOL_ICMP ( 1 )
-#define ipPROTOCOL_IGMP ( 2 )
-#define ipPROTOCOL_TCP ( 6 )
-#define ipPROTOCOL_UDP ( 17 )
-
-/* Dimensions the buffers that are filled by received Ethernet frames. */
-#define ipSIZE_OF_ETH_CRC_BYTES ( 4UL )
-#define ipSIZE_OF_ETH_OPTIONAL_802_1Q_TAG_BYTES ( 4UL )
-#define ipTOTAL_ETHERNET_FRAME_SIZE ( ( ( uint32_t ) ipconfigNETWORK_MTU ) + ( ( uint32_t ) ipSIZE_OF_ETH_HEADER ) + ipSIZE_OF_ETH_CRC_BYTES + ipSIZE_OF_ETH_OPTIONAL_802_1Q_TAG_BYTES )
-
-/*_RB_ Comment may need updating. */
-/* Space left at the beginning of a network buffer storage area to store a
-pointer back to the network buffer. Should be a multiple of 8 to ensure 8 byte
-alignment is maintained on architectures that require it.
-
-In order to get a 32-bit alignment of network packets, an offset of 2 bytes
-would be desirable, as defined by ipconfigPACKET_FILLER_SIZE. So the malloc'd
-buffer will have the following contents:
- uint32_t pointer; // word-aligned
- uchar_8 filler[6];
- << ETH-header >> // half-word-aligned
- uchar_8 dest[6]; // start of pucEthernetBuffer
- uchar_8 dest[6];
- uchar16_t type;
- << IP-header >> // word-aligned
- uint8_t ucVersionHeaderLength;
- etc
- */
-#if( ipconfigBUFFER_PADDING != 0 )
- #define ipBUFFER_PADDING ipconfigBUFFER_PADDING
-#else
- #define ipBUFFER_PADDING ( 8u + ipconfigPACKET_FILLER_SIZE )
-#endif
-
-/* The structure used to store buffers and pass them around the network stack.
-Buffers can be in use by the stack, in use by the network interface hardware
-driver, or free (not in use). */
-typedef struct xNETWORK_BUFFER
-{
- ListItem_t xBufferListItem; /* Used to reference the buffer form the free buffer list or a socket. */
- uint32_t ulIPAddress; /* Source or destination IP address, depending on usage scenario. */
- uint8_t *pucEthernetBuffer; /* Pointer to the start of the Ethernet frame. */
- size_t xDataLength; /* Starts by holding the total Ethernet frame length, then the UDP/TCP payload length. */
- uint16_t usPort; /* Source or destination port, depending on usage scenario. */
- uint16_t usBoundPort; /* The port to which a transmitting socket is bound. */
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- struct xNETWORK_BUFFER *pxNextBuffer; /* Possible optimisation for expert users - requires network driver support. */
- #endif
-} NetworkBufferDescriptor_t;
-
-#include "pack_struct_start.h"
-struct xMAC_ADDRESS
-{
- uint8_t ucBytes[ ipMAC_ADDRESS_LENGTH_BYTES ];
-}
-#include "pack_struct_end.h"
-
-typedef struct xMAC_ADDRESS MACAddress_t;
-
-typedef enum eNETWORK_EVENTS
-{
- eNetworkUp, /* The network is configured. */
- eNetworkDown /* The network connection has been lost. */
-} eIPCallbackEvent_t;
-
-typedef enum ePING_REPLY_STATUS
-{
- eSuccess = 0, /* A correct reply has been received for an outgoing ping. */
- eInvalidChecksum, /* A reply was received for an outgoing ping but the checksum of the reply was incorrect. */
- eInvalidData /* A reply was received to an outgoing ping but the payload of the reply was not correct. */
-} ePingReplyStatus_t;
-
-typedef enum eNETWORK_ADDRESS_TYPE
-{
- eNetWorkAddressTypeIPV4,
- eNetWorkAddressTypeIPV6,
- eNetWorkAddressTypeHostName
-} eNetWorkAddressType_t;
-
-/* Endian related definitions. */
-#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
-
- /* FreeRTOS_htons / FreeRTOS_htonl: some platforms might have built-in versions
- using a single instruction so allow these versions to be overridden. */
- #ifndef FreeRTOS_htons
- #define FreeRTOS_htons( usIn ) ( (uint16_t) ( ( ( usIn ) << 8U ) | ( ( usIn ) >> 8U ) ) )
- #endif
-
- #ifndef FreeRTOS_htonl
- #define FreeRTOS_htonl( ulIn ) \
- ( \
- ( uint32_t ) \
- ( \
- ( ( ( ( uint32_t ) ( ulIn ) ) ) << 24 ) | \
- ( ( ( ( uint32_t ) ( ulIn ) ) & 0x0000ff00UL ) << 8 ) | \
- ( ( ( ( uint32_t ) ( ulIn ) ) & 0x00ff0000UL ) >> 8 ) | \
- ( ( ( ( uint32_t ) ( ulIn ) ) ) >> 24 ) \
- ) \
- )
- #endif
-
-#else /* ipconfigBYTE_ORDER */
-
- #define FreeRTOS_htons( x ) ( ( uint16_t ) ( x ) )
- #define FreeRTOS_htonl( x ) ( ( uint32_t ) ( x ) )
-
-#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */
-
-#define FreeRTOS_ntohs( x ) FreeRTOS_htons( x )
-#define FreeRTOS_ntohl( x ) FreeRTOS_htonl( x )
-
-#if( ipconfigHAS_INLINE_FUNCTIONS == 1 )
-
- static portINLINE int32_t FreeRTOS_max_int32 (int32_t a, int32_t b);
- static portINLINE uint32_t FreeRTOS_max_uint32 (uint32_t a, uint32_t b);
- static portINLINE int32_t FreeRTOS_min_int32 (int32_t a, int32_t b);
- static portINLINE uint32_t FreeRTOS_min_uint32 (uint32_t a, uint32_t b);
- static portINLINE uint32_t FreeRTOS_round_up (uint32_t a, uint32_t d);
- static portINLINE uint32_t FreeRTOS_round_down (uint32_t a, uint32_t d);
- static portINLINE BaseType_t FreeRTOS_min_BaseType (BaseType_t a, BaseType_t b);
- static portINLINE BaseType_t FreeRTOS_max_BaseType (BaseType_t a, BaseType_t b);
- static portINLINE UBaseType_t FreeRTOS_max_UBaseType (UBaseType_t a, UBaseType_t b);
- static portINLINE UBaseType_t FreeRTOS_min_UBaseType (UBaseType_t a, UBaseType_t b);
-
-
- static portINLINE int32_t FreeRTOS_max_int32 (int32_t a, int32_t b) { return a >= b ? a : b; }
- static portINLINE uint32_t FreeRTOS_max_uint32 (uint32_t a, uint32_t b) { return a >= b ? a : b; }
- static portINLINE int32_t FreeRTOS_min_int32 (int32_t a, int32_t b) { return a <= b ? a : b; }
- static portINLINE uint32_t FreeRTOS_min_uint32 (uint32_t a, uint32_t b) { return a <= b ? a : b; }
- static portINLINE uint32_t FreeRTOS_round_up (uint32_t a, uint32_t d) { return d * ( ( a + d - 1u ) / d ); }
- static portINLINE uint32_t FreeRTOS_round_down (uint32_t a, uint32_t d) { return d * ( a / d ); }
-
- static portINLINE BaseType_t FreeRTOS_max_BaseType (BaseType_t a, BaseType_t b) { return a >= b ? a : b; }
- static portINLINE UBaseType_t FreeRTOS_max_UBaseType (UBaseType_t a, UBaseType_t b) { return a >= b ? a : b; }
- static portINLINE BaseType_t FreeRTOS_min_BaseType (BaseType_t a, BaseType_t b) { return a <= b ? a : b; }
- static portINLINE UBaseType_t FreeRTOS_min_UBaseType (UBaseType_t a, UBaseType_t b) { return a <= b ? a : b; }
-
-#else
-
- #define FreeRTOS_max_int32(a,b) ( ( ( int32_t ) ( a ) ) >= ( ( int32_t ) ( b ) ) ? ( ( int32_t ) ( a ) ) : ( ( int32_t ) ( b ) ) )
- #define FreeRTOS_max_uint32(a,b) ( ( ( uint32_t ) ( a ) ) >= ( ( uint32_t ) ( b ) ) ? ( ( uint32_t ) ( a ) ) : ( ( uint32_t ) ( b ) ) )
-
- #define FreeRTOS_min_int32(a,b) ( ( ( int32_t ) a ) <= ( ( int32_t ) b ) ? ( ( int32_t ) a ) : ( ( int32_t ) b ) )
- #define FreeRTOS_min_uint32(a,b) ( ( ( uint32_t ) a ) <= ( ( uint32_t ) b ) ? ( ( uint32_t ) a ) : ( ( uint32_t ) b ) )
-
- /* Round-up: a = d * ( ( a + d - 1 ) / d ) */
- #define FreeRTOS_round_up(a,d) ( ( ( uint32_t ) ( d ) ) * ( ( ( ( uint32_t ) ( a ) ) + ( ( uint32_t ) ( d ) ) - 1UL ) / ( ( uint32_t ) ( d ) ) ) )
- #define FreeRTOS_round_down(a,d) ( ( ( uint32_t ) ( d ) ) * ( ( ( uint32_t ) ( a ) ) / ( ( uint32_t ) ( d ) ) ) )
-
- #define FreeRTOS_ms_to_tick(ms) ( ( ms * configTICK_RATE_HZ + 500 ) / 1000 )
-
- #define FreeRTOS_max_BaseType(a, b) ( ( ( BaseType_t ) ( a ) ) >= ( ( BaseType_t ) ( b ) ) ? ( ( BaseType_t ) ( a ) ) : ( ( BaseType_t ) ( b ) ) )
- #define FreeRTOS_max_UBaseType(a, b) ( ( ( UBaseType_t ) ( a ) ) >= ( ( UBaseType_t ) ( b ) ) ? ( ( UBaseType_t ) ( a ) ) : ( ( UBaseType_t ) ( b ) ) )
- #define FreeRTOS_min_BaseType(a, b) ( ( ( BaseType_t ) ( a ) ) <= ( ( BaseType_t ) ( b ) ) ? ( ( BaseType_t ) ( a ) ) : ( ( BaseType_t ) ( b ) ) )
- #define FreeRTOS_min_UBaseType(a, b) ( ( ( UBaseType_t ) ( a ) ) <= ( ( UBaseType_t ) ( b ) ) ? ( ( UBaseType_t ) ( a ) ) : ( ( UBaseType_t ) ( b ) ) )
-
-#endif /* ipconfigHAS_INLINE_FUNCTIONS */
-
-#define pdMS_TO_MIN_TICKS( xTimeInMs ) ( pdMS_TO_TICKS( ( xTimeInMs ) ) < ( ( TickType_t ) 1 ) ? ( ( TickType_t ) 1 ) : pdMS_TO_TICKS( ( xTimeInMs ) ) )
-
-#ifndef pdTRUE_SIGNED
- /* Temporary solution: eventually the defines below will appear in 'Source\include\projdefs.h' */
- #define pdTRUE_SIGNED pdTRUE
- #define pdFALSE_SIGNED pdFALSE
- #define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1u )
- #define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0u )
-#endif
-
-/*
- * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
- * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html
- */
-BaseType_t FreeRTOS_IPInit( const uint8_t ucIPAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
- const uint8_t ucNetMask[ ipIP_ADDRESS_LENGTH_BYTES ],
- const uint8_t ucGatewayAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
- const uint8_t ucDNSServerAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
- const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] );
-
-void * FreeRTOS_GetUDPPayloadBuffer( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks );
-void FreeRTOS_GetAddressConfiguration( uint32_t *pulIPAddress, uint32_t *pulNetMask, uint32_t *pulGatewayAddress, uint32_t *pulDNSServerAddress );
-void FreeRTOS_SetAddressConfiguration( const uint32_t *pulIPAddress, const uint32_t *pulNetMask, const uint32_t *pulGatewayAddress, const uint32_t *pulDNSServerAddress );
-BaseType_t FreeRTOS_SendPingRequest( uint32_t ulIPAddress, size_t xNumberOfBytesToSend, TickType_t xBlockTimeTicks );
-void FreeRTOS_ReleaseUDPPayloadBuffer( void *pvBuffer );
-const uint8_t * FreeRTOS_GetMACAddress( void );
-void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] );
-void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent );
-void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier );
-uint32_t FreeRTOS_GetIPAddress( void );
-void FreeRTOS_SetIPAddress( uint32_t ulIPAddress );
-void FreeRTOS_SetNetmask( uint32_t ulNetmask );
-void FreeRTOS_SetGatewayAddress( uint32_t ulGatewayAddress );
-uint32_t FreeRTOS_GetGatewayAddress( void );
-uint32_t FreeRTOS_GetDNSServerAddress( void );
-uint32_t FreeRTOS_GetNetmask( void );
-void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress );
-BaseType_t FreeRTOS_IsNetworkUp( void );
-
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- UBaseType_t uxGetMinimumIPQueueSpace( void );
-#endif
-
-/*
- * Defined in FreeRTOS_Sockets.c
- * //_RB_ Don't think this comment is correct. If this is for internal use only it should appear after all the public API functions and not start with FreeRTOS_.
- * Socket has had activity, reset the timer so it will not be closed
- * because of inactivity
- */
-const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState);
-
-/* _HT_ Temporary: show all valid ARP entries
- */
-void FreeRTOS_PrintARPCache( void );
-void FreeRTOS_ClearARP( void );
-
-#if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
-
- /* DHCP has an option for clients to register their hostname. It doesn't
- have much use, except that a device can be found in a router along with its
- name. If this option is used the callback below must be provided by the
- application writer to return a const string, denoting the device's name. */
- const char *pcApplicationHostnameHook( void );
-
-#endif /* ipconfigDHCP_REGISTER_HOSTNAME */
-
-
-/* This xApplicationGetRandomNumber() will set *pulNumber to a random number,
-and return pdTRUE. When the random number generator is broken, it shall return
-pdFALSE.
-The function is defined in 'iot_secure_sockets.c'.
-If that module is not included in the project, the application must provide an
-implementation of it.
-The macro's ipconfigRAND32() and configRAND32() are not in use anymore. */
-BaseType_t xApplicationGetRandomNumber( uint32_t *pulNumber );
-
-/* For backward compatibility define old structure names to the newer equivalent
-structure name. */
-#ifndef ipconfigENABLE_BACKWARD_COMPATIBILITY
- #define ipconfigENABLE_BACKWARD_COMPATIBILITY 1
-#endif
-
-#if( ipconfigENABLE_BACKWARD_COMPATIBILITY == 1 )
- #define xIPStackEvent_t IPStackEvent_t
- #define xNetworkBufferDescriptor_t NetworkBufferDescriptor_t
- #define xMACAddress_t MACAddress_t
- #define xWinProperties_t WinProperties_t
- #define xSocket_t Socket_t
- #define xSocketSet_t SocketSet_t
- #define ipSIZE_OF_IP_HEADER ipSIZE_OF_IPv4_HEADER
-
- /* Since August 2016, the public types and fields below have changed name:
- abbreviations TCP/UDP are now written in capitals, and type names now end with "_t". */
- #define FOnConnected FOnConnected_t
- #define FOnTcpReceive FOnTCPReceive_t
- #define FOnTcpSent FOnTCPSent_t
- #define FOnUdpReceive FOnUDPReceive_t
- #define FOnUdpSent FOnUDPSent_t
-
- #define pOnTcpConnected pxOnTCPConnected
- #define pOnTcpReceive pxOnTCPReceive
- #define pOnTcpSent pxOnTCPSent
- #define pOnUdpReceive pxOnUDPReceive
- #define pOnUdpSent pxOnUDPSent
-
- #define FOnUdpSent FOnUDPSent_t
- #define FOnTcpSent FOnTCPSent_t
-#endif /* ipconfigENABLE_BACKWARD_COMPATIBILITY */
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* FREERTOS_IP_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_IP_H
+#define FREERTOS_IP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+#include "FreeRTOSIPConfigDefaults.h"
+#include "IPTraceMacroDefaults.h"
+
+/* Some constants defining the sizes of several parts of a packet */
+#define ipSIZE_OF_ETH_HEADER 14u
+#define ipSIZE_OF_IPv4_HEADER 20u
+#define ipSIZE_OF_IGMP_HEADER 8u
+#define ipSIZE_OF_ICMP_HEADER 8u
+#define ipSIZE_OF_UDP_HEADER 8u
+#define ipSIZE_OF_TCP_HEADER 20u
+
+
+/* The number of octets in the MAC and IP addresses respectively. */
+#define ipMAC_ADDRESS_LENGTH_BYTES ( 6 )
+#define ipIP_ADDRESS_LENGTH_BYTES ( 4 )
+
+/* IP protocol definitions. */
+#define ipPROTOCOL_ICMP ( 1 )
+#define ipPROTOCOL_IGMP ( 2 )
+#define ipPROTOCOL_TCP ( 6 )
+#define ipPROTOCOL_UDP ( 17 )
+
+/* Dimensions the buffers that are filled by received Ethernet frames. */
+#define ipSIZE_OF_ETH_CRC_BYTES ( 4UL )
+#define ipSIZE_OF_ETH_OPTIONAL_802_1Q_TAG_BYTES ( 4UL )
+#define ipTOTAL_ETHERNET_FRAME_SIZE ( ( ( uint32_t ) ipconfigNETWORK_MTU ) + ( ( uint32_t ) ipSIZE_OF_ETH_HEADER ) + ipSIZE_OF_ETH_CRC_BYTES + ipSIZE_OF_ETH_OPTIONAL_802_1Q_TAG_BYTES )
+
+/*_RB_ Comment may need updating. */
+/* Space left at the beginning of a network buffer storage area to store a
+pointer back to the network buffer. Should be a multiple of 8 to ensure 8 byte
+alignment is maintained on architectures that require it.
+
+In order to get a 32-bit alignment of network packets, an offset of 2 bytes
+would be desirable, as defined by ipconfigPACKET_FILLER_SIZE. So the malloc'd
+buffer will have the following contents:
+ uint32_t pointer; // word-aligned
+ uchar_8 filler[6];
+ << ETH-header >> // half-word-aligned
+ uchar_8 dest[6]; // start of pucEthernetBuffer
+ uchar_8 dest[6];
+ uchar16_t type;
+ << IP-header >> // word-aligned
+ uint8_t ucVersionHeaderLength;
+ etc
+ */
+#if( ipconfigBUFFER_PADDING != 0 )
+ #define ipBUFFER_PADDING ipconfigBUFFER_PADDING
+#else
+ #define ipBUFFER_PADDING ( 8u + ipconfigPACKET_FILLER_SIZE )
+#endif
+
+/* The structure used to store buffers and pass them around the network stack.
+Buffers can be in use by the stack, in use by the network interface hardware
+driver, or free (not in use). */
+typedef struct xNETWORK_BUFFER
+{
+ ListItem_t xBufferListItem; /* Used to reference the buffer form the free buffer list or a socket. */
+ uint32_t ulIPAddress; /* Source or destination IP address, depending on usage scenario. */
+ uint8_t *pucEthernetBuffer; /* Pointer to the start of the Ethernet frame. */
+ size_t xDataLength; /* Starts by holding the total Ethernet frame length, then the UDP/TCP payload length. */
+ uint16_t usPort; /* Source or destination port, depending on usage scenario. */
+ uint16_t usBoundPort; /* The port to which a transmitting socket is bound. */
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ struct xNETWORK_BUFFER *pxNextBuffer; /* Possible optimisation for expert users - requires network driver support. */
+ #endif
+} NetworkBufferDescriptor_t;
+
+#include "pack_struct_start.h"
+struct xMAC_ADDRESS
+{
+ uint8_t ucBytes[ ipMAC_ADDRESS_LENGTH_BYTES ];
+}
+#include "pack_struct_end.h"
+
+typedef struct xMAC_ADDRESS MACAddress_t;
+
+typedef enum eNETWORK_EVENTS
+{
+ eNetworkUp, /* The network is configured. */
+ eNetworkDown /* The network connection has been lost. */
+} eIPCallbackEvent_t;
+
+typedef enum ePING_REPLY_STATUS
+{
+ eSuccess = 0, /* A correct reply has been received for an outgoing ping. */
+ eInvalidChecksum, /* A reply was received for an outgoing ping but the checksum of the reply was incorrect. */
+ eInvalidData /* A reply was received to an outgoing ping but the payload of the reply was not correct. */
+} ePingReplyStatus_t;
+
+typedef enum eNETWORK_ADDRESS_TYPE
+{
+ eNetWorkAddressTypeIPV4,
+ eNetWorkAddressTypeIPV6,
+ eNetWorkAddressTypeHostName
+} eNetWorkAddressType_t;
+
+/* Endian related definitions. */
+#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
+
+ /* FreeRTOS_htons / FreeRTOS_htonl: some platforms might have built-in versions
+ using a single instruction so allow these versions to be overridden. */
+ #ifndef FreeRTOS_htons
+ #define FreeRTOS_htons( usIn ) ( (uint16_t) ( ( ( usIn ) << 8U ) | ( ( usIn ) >> 8U ) ) )
+ #endif
+
+ #ifndef FreeRTOS_htonl
+ #define FreeRTOS_htonl( ulIn ) \
+ ( \
+ ( uint32_t ) \
+ ( \
+ ( ( ( ( uint32_t ) ( ulIn ) ) ) << 24 ) | \
+ ( ( ( ( uint32_t ) ( ulIn ) ) & 0x0000ff00UL ) << 8 ) | \
+ ( ( ( ( uint32_t ) ( ulIn ) ) & 0x00ff0000UL ) >> 8 ) | \
+ ( ( ( ( uint32_t ) ( ulIn ) ) ) >> 24 ) \
+ ) \
+ )
+ #endif
+
+#else /* ipconfigBYTE_ORDER */
+
+ #define FreeRTOS_htons( x ) ( ( uint16_t ) ( x ) )
+ #define FreeRTOS_htonl( x ) ( ( uint32_t ) ( x ) )
+
+#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */
+
+#define FreeRTOS_ntohs( x ) FreeRTOS_htons( x )
+#define FreeRTOS_ntohl( x ) FreeRTOS_htonl( x )
+
+#if( ipconfigHAS_INLINE_FUNCTIONS == 1 )
+
+ static portINLINE int32_t FreeRTOS_max_int32 (int32_t a, int32_t b);
+ static portINLINE uint32_t FreeRTOS_max_uint32 (uint32_t a, uint32_t b);
+ static portINLINE int32_t FreeRTOS_min_int32 (int32_t a, int32_t b);
+ static portINLINE uint32_t FreeRTOS_min_uint32 (uint32_t a, uint32_t b);
+ static portINLINE uint32_t FreeRTOS_round_up (uint32_t a, uint32_t d);
+ static portINLINE uint32_t FreeRTOS_round_down (uint32_t a, uint32_t d);
+ static portINLINE BaseType_t FreeRTOS_min_BaseType (BaseType_t a, BaseType_t b);
+ static portINLINE BaseType_t FreeRTOS_max_BaseType (BaseType_t a, BaseType_t b);
+ static portINLINE UBaseType_t FreeRTOS_max_UBaseType (UBaseType_t a, UBaseType_t b);
+ static portINLINE UBaseType_t FreeRTOS_min_UBaseType (UBaseType_t a, UBaseType_t b);
+
+
+ static portINLINE int32_t FreeRTOS_max_int32 (int32_t a, int32_t b) { return a >= b ? a : b; }
+ static portINLINE uint32_t FreeRTOS_max_uint32 (uint32_t a, uint32_t b) { return a >= b ? a : b; }
+ static portINLINE int32_t FreeRTOS_min_int32 (int32_t a, int32_t b) { return a <= b ? a : b; }
+ static portINLINE uint32_t FreeRTOS_min_uint32 (uint32_t a, uint32_t b) { return a <= b ? a : b; }
+ static portINLINE uint32_t FreeRTOS_round_up (uint32_t a, uint32_t d) { return d * ( ( a + d - 1u ) / d ); }
+ static portINLINE uint32_t FreeRTOS_round_down (uint32_t a, uint32_t d) { return d * ( a / d ); }
+
+ static portINLINE BaseType_t FreeRTOS_max_BaseType (BaseType_t a, BaseType_t b) { return a >= b ? a : b; }
+ static portINLINE UBaseType_t FreeRTOS_max_UBaseType (UBaseType_t a, UBaseType_t b) { return a >= b ? a : b; }
+ static portINLINE BaseType_t FreeRTOS_min_BaseType (BaseType_t a, BaseType_t b) { return a <= b ? a : b; }
+ static portINLINE UBaseType_t FreeRTOS_min_UBaseType (UBaseType_t a, UBaseType_t b) { return a <= b ? a : b; }
+
+#else
+
+ #define FreeRTOS_max_int32(a,b) ( ( ( int32_t ) ( a ) ) >= ( ( int32_t ) ( b ) ) ? ( ( int32_t ) ( a ) ) : ( ( int32_t ) ( b ) ) )
+ #define FreeRTOS_max_uint32(a,b) ( ( ( uint32_t ) ( a ) ) >= ( ( uint32_t ) ( b ) ) ? ( ( uint32_t ) ( a ) ) : ( ( uint32_t ) ( b ) ) )
+
+ #define FreeRTOS_min_int32(a,b) ( ( ( int32_t ) a ) <= ( ( int32_t ) b ) ? ( ( int32_t ) a ) : ( ( int32_t ) b ) )
+ #define FreeRTOS_min_uint32(a,b) ( ( ( uint32_t ) a ) <= ( ( uint32_t ) b ) ? ( ( uint32_t ) a ) : ( ( uint32_t ) b ) )
+
+ /* Round-up: a = d * ( ( a + d - 1 ) / d ) */
+ #define FreeRTOS_round_up(a,d) ( ( ( uint32_t ) ( d ) ) * ( ( ( ( uint32_t ) ( a ) ) + ( ( uint32_t ) ( d ) ) - 1UL ) / ( ( uint32_t ) ( d ) ) ) )
+ #define FreeRTOS_round_down(a,d) ( ( ( uint32_t ) ( d ) ) * ( ( ( uint32_t ) ( a ) ) / ( ( uint32_t ) ( d ) ) ) )
+
+ #define FreeRTOS_ms_to_tick(ms) ( ( ms * configTICK_RATE_HZ + 500 ) / 1000 )
+
+ #define FreeRTOS_max_BaseType(a, b) ( ( ( BaseType_t ) ( a ) ) >= ( ( BaseType_t ) ( b ) ) ? ( ( BaseType_t ) ( a ) ) : ( ( BaseType_t ) ( b ) ) )
+ #define FreeRTOS_max_UBaseType(a, b) ( ( ( UBaseType_t ) ( a ) ) >= ( ( UBaseType_t ) ( b ) ) ? ( ( UBaseType_t ) ( a ) ) : ( ( UBaseType_t ) ( b ) ) )
+ #define FreeRTOS_min_BaseType(a, b) ( ( ( BaseType_t ) ( a ) ) <= ( ( BaseType_t ) ( b ) ) ? ( ( BaseType_t ) ( a ) ) : ( ( BaseType_t ) ( b ) ) )
+ #define FreeRTOS_min_UBaseType(a, b) ( ( ( UBaseType_t ) ( a ) ) <= ( ( UBaseType_t ) ( b ) ) ? ( ( UBaseType_t ) ( a ) ) : ( ( UBaseType_t ) ( b ) ) )
+
+#endif /* ipconfigHAS_INLINE_FUNCTIONS */
+
+#define pdMS_TO_MIN_TICKS( xTimeInMs ) ( pdMS_TO_TICKS( ( xTimeInMs ) ) < ( ( TickType_t ) 1 ) ? ( ( TickType_t ) 1 ) : pdMS_TO_TICKS( ( xTimeInMs ) ) )
+
+#ifndef pdTRUE_SIGNED
+ /* Temporary solution: eventually the defines below will appear in 'Source\include\projdefs.h' */
+ #define pdTRUE_SIGNED pdTRUE
+ #define pdFALSE_SIGNED pdFALSE
+ #define pdTRUE_UNSIGNED ( ( UBaseType_t ) 1u )
+ #define pdFALSE_UNSIGNED ( ( UBaseType_t ) 0u )
+#endif
+
+/*
+ * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
+ * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html
+ */
+BaseType_t FreeRTOS_IPInit( const uint8_t ucIPAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
+ const uint8_t ucNetMask[ ipIP_ADDRESS_LENGTH_BYTES ],
+ const uint8_t ucGatewayAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
+ const uint8_t ucDNSServerAddress[ ipIP_ADDRESS_LENGTH_BYTES ],
+ const uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ] );
+
+void * FreeRTOS_GetUDPPayloadBuffer( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks );
+void FreeRTOS_GetAddressConfiguration( uint32_t *pulIPAddress, uint32_t *pulNetMask, uint32_t *pulGatewayAddress, uint32_t *pulDNSServerAddress );
+void FreeRTOS_SetAddressConfiguration( const uint32_t *pulIPAddress, const uint32_t *pulNetMask, const uint32_t *pulGatewayAddress, const uint32_t *pulDNSServerAddress );
+BaseType_t FreeRTOS_SendPingRequest( uint32_t ulIPAddress, size_t xNumberOfBytesToSend, TickType_t xBlockTimeTicks );
+void FreeRTOS_ReleaseUDPPayloadBuffer( void *pvBuffer );
+const uint8_t * FreeRTOS_GetMACAddress( void );
+void FreeRTOS_UpdateMACAddress( const uint8_t ucMACAddress[ipMAC_ADDRESS_LENGTH_BYTES] );
+void vApplicationIPNetworkEventHook( eIPCallbackEvent_t eNetworkEvent );
+void vApplicationPingReplyHook( ePingReplyStatus_t eStatus, uint16_t usIdentifier );
+uint32_t FreeRTOS_GetIPAddress( void );
+void FreeRTOS_SetIPAddress( uint32_t ulIPAddress );
+void FreeRTOS_SetNetmask( uint32_t ulNetmask );
+void FreeRTOS_SetGatewayAddress( uint32_t ulGatewayAddress );
+uint32_t FreeRTOS_GetGatewayAddress( void );
+uint32_t FreeRTOS_GetDNSServerAddress( void );
+uint32_t FreeRTOS_GetNetmask( void );
+void FreeRTOS_OutputARPRequest( uint32_t ulIPAddress );
+BaseType_t FreeRTOS_IsNetworkUp( void );
+
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ UBaseType_t uxGetMinimumIPQueueSpace( void );
+#endif
+
+/*
+ * Defined in FreeRTOS_Sockets.c
+ * //_RB_ Don't think this comment is correct. If this is for internal use only it should appear after all the public API functions and not start with FreeRTOS_.
+ * Socket has had activity, reset the timer so it will not be closed
+ * because of inactivity
+ */
+const char *FreeRTOS_GetTCPStateName( UBaseType_t ulState);
+
+/* _HT_ Temporary: show all valid ARP entries
+ */
+void FreeRTOS_PrintARPCache( void );
+void FreeRTOS_ClearARP( void );
+
+#if( ipconfigDHCP_REGISTER_HOSTNAME == 1 )
+
+ /* DHCP has an option for clients to register their hostname. It doesn't
+ have much use, except that a device can be found in a router along with its
+ name. If this option is used the callback below must be provided by the
+ application writer to return a const string, denoting the device's name. */
+ const char *pcApplicationHostnameHook( void );
+
+#endif /* ipconfigDHCP_REGISTER_HOSTNAME */
+
+
+/* This xApplicationGetRandomNumber() will set *pulNumber to a random number,
+and return pdTRUE. When the random number generator is broken, it shall return
+pdFALSE.
+The function is defined in 'iot_secure_sockets.c'.
+If that module is not included in the project, the application must provide an
+implementation of it.
+The macro's ipconfigRAND32() and configRAND32() are not in use anymore. */
+BaseType_t xApplicationGetRandomNumber( uint32_t *pulNumber );
+
+/* For backward compatibility define old structure names to the newer equivalent
+structure name. */
+#ifndef ipconfigENABLE_BACKWARD_COMPATIBILITY
+ #define ipconfigENABLE_BACKWARD_COMPATIBILITY 1
+#endif
+
+#if( ipconfigENABLE_BACKWARD_COMPATIBILITY == 1 )
+ #define xIPStackEvent_t IPStackEvent_t
+ #define xNetworkBufferDescriptor_t NetworkBufferDescriptor_t
+ #define xMACAddress_t MACAddress_t
+ #define xWinProperties_t WinProperties_t
+ #define xSocket_t Socket_t
+ #define xSocketSet_t SocketSet_t
+ #define ipSIZE_OF_IP_HEADER ipSIZE_OF_IPv4_HEADER
+
+ /* Since August 2016, the public types and fields below have changed name:
+ abbreviations TCP/UDP are now written in capitals, and type names now end with "_t". */
+ #define FOnConnected FOnConnected_t
+ #define FOnTcpReceive FOnTCPReceive_t
+ #define FOnTcpSent FOnTCPSent_t
+ #define FOnUdpReceive FOnUDPReceive_t
+ #define FOnUdpSent FOnUDPSent_t
+
+ #define pOnTcpConnected pxOnTCPConnected
+ #define pOnTcpReceive pxOnTCPReceive
+ #define pOnTcpSent pxOnTCPSent
+ #define pOnUdpReceive pxOnUDPReceive
+ #define pOnUdpSent pxOnUDPSent
+
+ #define FOnUdpSent FOnUDPSent_t
+ #define FOnTcpSent FOnTCPSent_t
+#endif /* ipconfigENABLE_BACKWARD_COMPATIBILITY */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* FREERTOS_IP_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h
index 8604abed0..0d8c03872 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_IP_Private.h
@@ -1,827 +1,827 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_IP_PRIVATE_H
-#define FREERTOS_IP_PRIVATE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-#include "FreeRTOSIPConfigDefaults.h"
-#include "FreeRTOS_Sockets.h"
-#include "IPTraceMacroDefaults.h"
-#include "FreeRTOS_Stream_Buffer.h"
-#if( ipconfigUSE_TCP == 1 )
- #include "FreeRTOS_TCP_WIN.h"
- #include "FreeRTOS_TCP_IP.h"
-#endif
-
-#include "event_groups.h"
-
-typedef struct xNetworkAddressingParameters
-{
- uint32_t ulDefaultIPAddress;
- uint32_t ulNetMask;
- uint32_t ulGatewayAddress;
- uint32_t ulDNSServerAddress;
- uint32_t ulBroadcastAddress;
-} NetworkAddressingParameters_t;
-
-extern BaseType_t xTCPWindowLoggingLevel;
-
-/*-----------------------------------------------------------*/
-/* Protocol headers. */
-/*-----------------------------------------------------------*/
-
-#include "pack_struct_start.h"
-struct xETH_HEADER
-{
- MACAddress_t xDestinationAddress; /* 0 + 6 = 6 */
- MACAddress_t xSourceAddress; /* 6 + 6 = 12 */
- uint16_t usFrameType; /* 12 + 2 = 14 */
-}
-#include "pack_struct_end.h"
-typedef struct xETH_HEADER EthernetHeader_t;
-
-#include "pack_struct_start.h"
-struct xARP_HEADER
-{
- uint16_t usHardwareType; /* 0 + 2 = 2 */
- uint16_t usProtocolType; /* 2 + 2 = 4 */
- uint8_t ucHardwareAddressLength; /* 4 + 1 = 5 */
- uint8_t ucProtocolAddressLength; /* 5 + 1 = 6 */
- uint16_t usOperation; /* 6 + 2 = 8 */
- MACAddress_t xSenderHardwareAddress; /* 8 + 6 = 14 */
- uint8_t ucSenderProtocolAddress[ 4 ]; /* 14 + 4 = 18 */
- MACAddress_t xTargetHardwareAddress; /* 18 + 6 = 24 */
- uint32_t ulTargetProtocolAddress; /* 24 + 4 = 28 */
-}
-#include "pack_struct_end.h"
-typedef struct xARP_HEADER ARPHeader_t;
-
-#include "pack_struct_start.h"
-struct xIP_HEADER
-{
- uint8_t ucVersionHeaderLength; /* 0 + 1 = 1 */
- uint8_t ucDifferentiatedServicesCode; /* 1 + 1 = 2 */
- uint16_t usLength; /* 2 + 2 = 4 */
- uint16_t usIdentification; /* 4 + 2 = 6 */
- uint16_t usFragmentOffset; /* 6 + 2 = 8 */
- uint8_t ucTimeToLive; /* 8 + 1 = 9 */
- uint8_t ucProtocol; /* 9 + 1 = 10 */
- uint16_t usHeaderChecksum; /* 10 + 2 = 12 */
- uint32_t ulSourceIPAddress; /* 12 + 4 = 16 */
- uint32_t ulDestinationIPAddress; /* 16 + 4 = 20 */
-}
-#include "pack_struct_end.h"
-typedef struct xIP_HEADER IPHeader_t;
-
-#include "pack_struct_start.h"
-struct xIGMP_HEADER
-{
- uint8_t ucVersionType; /* 0 + 1 = 1 */
- uint8_t ucMaxResponseTime; /* 1 + 1 = 2 */
- uint16_t usChecksum; /* 2 + 2 = 4 */
- uint32_t usGroupAddress; /* 4 + 4 = 8 */
-}
-#include "pack_struct_end.h"
-typedef struct xIGMP_HEADER IGMPHeader_t;
-
-#include "pack_struct_start.h"
-struct xICMP_HEADER
-{
- uint8_t ucTypeOfMessage; /* 0 + 1 = 1 */
- uint8_t ucTypeOfService; /* 1 + 1 = 2 */
- uint16_t usChecksum; /* 2 + 2 = 4 */
- uint16_t usIdentifier; /* 4 + 2 = 6 */
- uint16_t usSequenceNumber; /* 6 + 2 = 8 */
-}
-#include "pack_struct_end.h"
-typedef struct xICMP_HEADER ICMPHeader_t;
-
-#include "pack_struct_start.h"
-struct xUDP_HEADER
-{
- uint16_t usSourcePort; /* 0 + 2 = 2 */
- uint16_t usDestinationPort; /* 2 + 2 = 4 */
- uint16_t usLength; /* 4 + 2 = 6 */
- uint16_t usChecksum; /* 6 + 2 = 8 */
-}
-#include "pack_struct_end.h"
-typedef struct xUDP_HEADER UDPHeader_t;
-
-#include "pack_struct_start.h"
-struct xTCP_HEADER
-{
- uint16_t usSourcePort; /* + 2 = 2 */
- uint16_t usDestinationPort; /* + 2 = 4 */
- uint32_t ulSequenceNumber; /* + 4 = 8 */
- uint32_t ulAckNr; /* + 4 = 12 */
- uint8_t ucTCPOffset; /* + 1 = 13 */
- uint8_t ucTCPFlags; /* + 1 = 14 */
- uint16_t usWindow; /* + 2 = 15 */
- uint16_t usChecksum; /* + 2 = 18 */
- uint16_t usUrgent; /* + 2 = 20 */
-#if ipconfigUSE_TCP == 1
- /* the option data is not a part of the TCP header */
- uint8_t ucOptdata[ipSIZE_TCP_OPTIONS]; /* + 12 = 32 */
-#endif
-}
-#include "pack_struct_end.h"
-typedef struct xTCP_HEADER TCPHeader_t;
-
-#include "pack_struct_start.h"
-struct xPSEUDO_HEADER
-{
- uint32_t ulSourceAddress;
- uint32_t ulDestinationAddress;
- uint8_t ucZeros;
- uint8_t ucProtocol;
- uint16_t usUDPLength;
-}
-#include "pack_struct_end.h"
-typedef struct xPSEUDO_HEADER PseudoHeader_t;
-
-/*-----------------------------------------------------------*/
-/* Nested protocol packets. */
-/*-----------------------------------------------------------*/
-
-#include "pack_struct_start.h"
-struct xARP_PACKET
-{
- EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
- ARPHeader_t xARPHeader; /* 14 + 28 = 42 */
-}
-#include "pack_struct_end.h"
-typedef struct xARP_PACKET ARPPacket_t;
-
-#include "pack_struct_start.h"
-struct xIP_PACKET
-{
- EthernetHeader_t xEthernetHeader;
- IPHeader_t xIPHeader;
-}
-#include "pack_struct_end.h"
-typedef struct xIP_PACKET IPPacket_t;
-
-#include "pack_struct_start.h"
-struct xICMP_PACKET
-{
- EthernetHeader_t xEthernetHeader;
- IPHeader_t xIPHeader;
- ICMPHeader_t xICMPHeader;
-}
-#include "pack_struct_end.h"
-typedef struct xICMP_PACKET ICMPPacket_t;
-
-#include "pack_struct_start.h"
-struct xUDP_PACKET
-{
- EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
- IPHeader_t xIPHeader; /* 14 + 20 = 34 */
- UDPHeader_t xUDPHeader; /* 34 + 8 = 42 */
-}
-#include "pack_struct_end.h"
-typedef struct xUDP_PACKET UDPPacket_t;
-
-#include "pack_struct_start.h"
-struct xTCP_PACKET
-{
- EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
- IPHeader_t xIPHeader; /* 14 + 20 = 34 */
- TCPHeader_t xTCPHeader; /* 34 + 32 = 66 */
-}
-#include "pack_struct_end.h"
-typedef struct xTCP_PACKET TCPPacket_t;
-
-typedef union XPROT_PACKET
-{
- ARPPacket_t xARPPacket;
- TCPPacket_t xTCPPacket;
- UDPPacket_t xUDPPacket;
- ICMPPacket_t xICMPPacket;
-} ProtocolPacket_t;
-
-
-/* The maximum UDP payload length. */
-#define ipMAX_UDP_PAYLOAD_LENGTH ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER )
-
-typedef enum
-{
- eReleaseBuffer = 0, /* Processing the frame did not find anything to do - just release the buffer. */
- eProcessBuffer, /* An Ethernet frame has a valid address - continue process its contents. */
- eReturnEthernetFrame, /* The Ethernet frame contains an ARP or ICMP packet that can be returned to its source. */
- eFrameConsumed /* Processing the Ethernet packet contents resulted in the payload being sent to the stack. */
-} eFrameProcessingResult_t;
-
-typedef enum
-{
- eNoEvent = -1,
- eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */
- eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */
- eNetworkTxEvent, /* 2: Let the IP-task send a network packet. */
- eARPTimerEvent, /* 3: The ARP timer expired. */
- eStackTxEvent, /* 4: The software stack has queued a packet to transmit. */
- eDHCPEvent, /* 5: Process the DHCP state machine. */
- eTCPTimerEvent, /* 6: See if any TCP socket needs attention. */
- eTCPAcceptEvent, /* 7: Client API FreeRTOS_accept() waiting for client connections. */
- eTCPNetStat, /* 8: IP-task is asked to produce a netstat listing. */
- eSocketBindEvent, /* 9: Send a message to the IP-task to bind a socket to a port. */
- eSocketCloseEvent, /*10: Send a message to the IP-task to close a socket. */
- eSocketSelectEvent, /*11: Send a message to the IP-task for select(). */
- eSocketSignalEvent, /*12: A socket must be signalled. */
-} eIPEvent_t;
-
-typedef struct IP_TASK_COMMANDS
-{
- eIPEvent_t eEventType;
- void *pvData;
-} IPStackEvent_t;
-
-#define ipBROADCAST_IP_ADDRESS 0xffffffffUL
-
-/* Offset into the Ethernet frame that is used to temporarily store information
-on the fragmentation status of the packet being sent. The value is important,
-as it is past the location into which the destination address will get placed. */
-#define ipFRAGMENTATION_PARAMETERS_OFFSET ( 6 )
-#define ipSOCKET_OPTIONS_OFFSET ( 6 )
-
-/* Only used when outgoing fragmentation is being used (FreeRTOSIPConfig.h
-setting. */
-#define ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset ) ( ( ( usFragmentOffset ) == 0 ) ? ipUDP_PAYLOAD_OFFSET_IPv4 : ipIP_PAYLOAD_OFFSET )
-
-/* The offset into a UDP packet at which the UDP data (payload) starts. */
-#define ipUDP_PAYLOAD_OFFSET_IPv4 ( sizeof( UDPPacket_t ) )
-
-/* The offset into an IP packet into which the IP data (payload) starts. */
-#define ipIP_PAYLOAD_OFFSET ( sizeof( IPPacket_t ) )
-
-#include "pack_struct_start.h"
-struct xUDP_IP_FRAGMENT_PARAMETERS
-{
- uint8_t ucSocketOptions;
- uint8_t ucPadFor16BitAlignment;
- uint16_t usFragmentedPacketOffset;
- uint16_t usFragmentLength;
- uint16_t usPayloadChecksum;
-}
-#include "pack_struct_end.h"
-typedef struct xUDP_IP_FRAGMENT_PARAMETERS IPFragmentParameters_t;
-
-#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
-
- /* Ethernet frame types. */
- #define ipARP_FRAME_TYPE ( 0x0608U )
- #define ipIPv4_FRAME_TYPE ( 0x0008U )
-
- /* ARP related definitions. */
- #define ipARP_PROTOCOL_TYPE ( 0x0008U )
- #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0100U )
- #define ipARP_REQUEST ( 0x0100U )
- #define ipARP_REPLY ( 0x0200U )
-
-#else
-
- /* Ethernet frame types. */
- #define ipARP_FRAME_TYPE ( 0x0806U )
- #define ipIPv4_FRAME_TYPE ( 0x0800U )
-
- /* ARP related definitions. */
- #define ipARP_PROTOCOL_TYPE ( 0x0800U )
- #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0001U )
- #define ipARP_REQUEST ( 0x0001 )
- #define ipARP_REPLY ( 0x0002 )
-
-#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */
-
-
-/* For convenience, a MAC address of all zeros and another of all 0xffs are
-defined const for quick reference. */
-extern const MACAddress_t xBroadcastMACAddress; /* all 0xff's */
-extern uint16_t usPacketIdentifier;
-
-/* Define a default UDP packet header (declared in FreeRTOS_UDP_IP.c) */
-typedef union xUDPPacketHeader
-{
- uint8_t ucBytes[24];
- uint32_t ulWords[6];
-} UDPPacketHeader_t;
-extern UDPPacketHeader_t xDefaultPartUDPPacketHeader;
-
-/* Structure that stores the netmask, gateway address and DNS server addresses. */
-extern NetworkAddressingParameters_t xNetworkAddressing;
-
-/* Structure that stores the defaults for netmask, gateway address and DNS.
-These values will be copied to 'xNetworkAddressing' in case DHCP is not used,
-and also in case DHCP does not lead to a confirmed request. */
-extern NetworkAddressingParameters_t xDefaultAddressing;
-
-/* True when BufferAllocation_1.c was included, false for BufferAllocation_2.c */
-extern const BaseType_t xBufferAllocFixedSize;
-
-/* Defined in FreeRTOS_Sockets.c */
-#if ( ipconfigUSE_TCP == 1 )
- extern List_t xBoundTCPSocketsList;
-#endif
-
-/* The local IP address is accessed from within xDefaultPartUDPPacketHeader,
-rather than duplicated in its own variable. */
-#define ipLOCAL_IP_ADDRESS_POINTER ( ( uint32_t * ) &( xDefaultPartUDPPacketHeader.ulWords[ 20u / sizeof(uint32_t) ] ) )
-
-/* The local MAC address is accessed from within xDefaultPartUDPPacketHeader,
-rather than duplicated in its own variable. */
-#define ipLOCAL_MAC_ADDRESS ( &xDefaultPartUDPPacketHeader.ucBytes[0] )
-
-/* ICMP packets are sent using the same function as UDP packets. The port
-number is used to distinguish between the two, as 0 is an invalid UDP port. */
-#define ipPACKET_CONTAINS_ICMP_DATA ( 0 )
-
-/* For now, the lower 8 bits in 'xEventBits' will be reserved for the above
-socket events. */
-#define SOCKET_EVENT_BIT_COUNT 8
-
-#define vSetField16( pxBase, xType, xField, usValue ) \
-{ \
- ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( usValue ) >> 8 ); \
- ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( usValue ) & 0xff ); \
-}
-
-#define vSetField32( pxBase, xType, xField, ulValue ) \
-{ \
- ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( ulValue ) >> 24 ); \
- ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( ( ulValue ) >> 16 ) & 0xff ); \
- ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 2 ] = ( uint8_t ) ( ( ( ulValue ) >> 8 ) & 0xff ); \
- ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 3 ] = ( uint8_t ) ( ( ulValue ) & 0xff ); \
-}
-
-#define vFlip_16( left, right ) \
- do { \
- uint16_t tmp = (left); \
- (left) = (right); \
- (right) = tmp; \
- } while (0)
-
-#define vFlip_32( left, right ) \
- do { \
- uint32_t tmp = (left); \
- (left) = (right); \
- (right) = tmp; \
- } while (0)
-
-#ifndef ARRAY_SIZE
- #define ARRAY_SIZE(x) (BaseType_t)(sizeof(x)/sizeof(x)[0])
-#endif
-
-/*
- * A version of FreeRTOS_GetReleaseNetworkBuffer() that can be called from an
- * interrupt. If a non zero value is returned, then the calling ISR should
- * perform a context switch before exiting the ISR.
- */
-BaseType_t FreeRTOS_ReleaseFreeNetworkBufferFromISR( void );
-
-/*
- * Create a message that contains a command to initialise the network interface.
- * This is used during initialisation, and at any time the network interface
- * goes down thereafter. The network interface hardware driver is responsible
- * for sending the message that contains the network interface down command/
- * event.
- *
- * Only use the FreeRTOS_NetworkDownFromISR() version if the function is to be
- * called from an interrupt service routine. If FreeRTOS_NetworkDownFromISR()
- * returns a non-zero value then a context switch should be performed ebfore
- * the interrupt is exited.
- */
-void FreeRTOS_NetworkDown( void );
-BaseType_t FreeRTOS_NetworkDownFromISR( void );
-
-/*
- * Processes incoming ARP packets.
- */
-eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame );
-
-/*
- * Inspect an Ethernet frame to see if it contains data that the stack needs to
- * process. eProcessBuffer is returned if the frame should be processed by the
- * stack. eReleaseBuffer is returned if the frame should be discarded.
- */
-eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer );
-
-/*
- * Return the checksum generated over xDataLengthBytes from pucNextData.
- */
-uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes );
-
-/* Socket related private functions. */
-
-/*
- * The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
- * payload size (excluding packet headers) and that the packet in pucEthernetBuffer
- * is at least the size of UDPPacket_t.
- */
-BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort );
-
-/*
- * Initialize the socket list data structures for TCP and UDP.
- */
-BaseType_t vNetworkSocketsInit( void );
-
-/*
- * Returns pdTRUE if the IP task has been created and is initialised. Otherwise
- * returns pdFALSE.
- */
-BaseType_t xIPIsNetworkTaskReady( void );
-
-#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
- struct xSOCKET;
- typedef void (*SocketWakeupCallback_t)( struct xSOCKET * pxSocket );
-#endif
-
-#if( ipconfigUSE_TCP == 1 )
-
- /*
- * Actually a user thing, but because xBoundTCPSocketsList, let it do by the
- * IP-task
- */
- void vTCPNetStat( void );
-
- /*
- * At least one socket needs to check for timeouts
- */
- TickType_t xTCPTimerCheck( BaseType_t xWillSleep );
-
- /* Every TCP socket has a buffer space just big enough to store
- the last TCP header received.
- As a reference of this field may be passed to DMA, force the
- alignment to 8 bytes. */
- typedef union
- {
- struct
- {
- /* Increase the alignment of this union by adding a 64-bit variable. */
- uint64_t ullAlignmentWord;
- } a;
- struct
- {
- /* The next field only serves to give 'ucLastPacket' a correct
- alignment of 8 + 2. See comments in FreeRTOS_IP.h */
- uint8_t ucFillPacket[ ipconfigPACKET_FILLER_SIZE ];
- uint8_t ucLastPacket[ sizeof( TCPPacket_t ) ];
- } u;
- } LastTCPPacket_t;
-
- /*
- * Note that the values of all short and long integers in these structs
- * are being stored in the native-endian way
- * Translation should take place when accessing any structure which defines
- * network packets, such as IPHeader_t and TCPHeader_t
- */
- typedef struct TCPSOCKET
- {
- uint32_t ulRemoteIP; /* IP address of remote machine */
- uint16_t usRemotePort; /* Port on remote machine */
- struct {
- /* Most compilers do like bit-flags */
- uint32_t
- bMssChange : 1, /* This socket has seen a change in MSS */
- bPassAccept : 1, /* when true, this socket may be returned in a call to accept() */
- bPassQueued : 1, /* when true, this socket is an orphan until it gets connected
- * Why an orphan? Because it may not be returned in a accept() call until it
- * gets the state eESTABLISHED */
- bReuseSocket : 1, /* When a listening socket gets a connection, do not create a new instance but keep on using it */
- bCloseAfterSend : 1,/* As soon as the last byte has been transmitted, finalise the connection
- * Useful in e.g. FTP connections, where the last data bytes are sent along with the FIN flag */
- bUserShutdown : 1, /* User requesting a graceful shutdown */
- bCloseRequested : 1,/* Request to finalise the connection */
- bLowWater : 1, /* high-water level has been reached. Cleared as soon as 'rx-count < lo-water' */
- bWinChange : 1, /* The value of bLowWater has changed, must send a window update */
- bSendKeepAlive : 1, /* When this flag is true, a TCP keep-alive message must be send */
- bWaitKeepAlive : 1, /* When this flag is true, a TCP keep-alive reply is expected */
- bConnPrepared : 1, /* Connecting socket: Message has been prepared */
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- bConnPassed : 1, /* Connecting socket: Socket has been passed in a successful select() */
- #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
- bFinAccepted : 1, /* This socket has received (or sent) a FIN and accepted it */
- bFinSent : 1, /* We've sent out a FIN */
- bFinRecv : 1, /* We've received a FIN from our peer */
- bFinAcked : 1, /* Our FIN packet has been acked */
- bFinLast : 1, /* The last ACK (after FIN and FIN+ACK) has been sent or will be sent by the peer */
- bRxStopped : 1, /* Application asked to temporarily stop reception */
- bMallocError : 1, /* There was an error allocating a stream */
- bWinScaling : 1; /* A TCP-Window Scaling option was offered and accepted in the SYN phase. */
- } bits;
- uint32_t ulHighestRxAllowed;
- /* The highest sequence number that we can receive at any moment */
- uint16_t usTimeout; /* Time (in ticks) after which this socket needs attention */
- uint16_t usCurMSS; /* Current Maximum Segment Size */
- uint16_t usInitMSS; /* Initial maximum segment Size */
- uint16_t usChildCount; /* In case of a listening socket: number of connections on this port number */
- uint16_t usBacklog; /* In case of a listening socket: maximum number of concurrent connections on this port number */
- uint8_t ucRepCount; /* Send repeat count, for retransmissions
- * This counter is separate from the xmitCount in the
- * TCP win segments */
- uint8_t ucTCPState; /* TCP state: see eTCP_STATE */
- struct xSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */
- #if( ipconfigTCP_KEEP_ALIVE == 1 )
- uint8_t ucKeepRepCount;
- TickType_t xLastAliveTime;
- #endif /* ipconfigTCP_KEEP_ALIVE */
- #if( ipconfigTCP_HANG_PROTECTION == 1 )
- TickType_t xLastActTime;
- #endif /* ipconfigTCP_HANG_PROTECTION */
- size_t uxLittleSpace;
- size_t uxEnoughSpace;
- size_t uxRxStreamSize;
- size_t uxTxStreamSize;
- StreamBuffer_t *rxStream;
- StreamBuffer_t *txStream;
- #if( ipconfigUSE_TCP_WIN == 1 )
- NetworkBufferDescriptor_t *pxAckMessage;
- #endif /* ipconfigUSE_TCP_WIN */
- /* Buffer space to store the last TCP header received. */
- LastTCPPacket_t xPacket;
- uint8_t tcpflags; /* TCP flags */
- #if( ipconfigUSE_TCP_WIN != 0 )
- uint8_t ucMyWinScaleFactor;
- uint8_t ucPeerWinScaleFactor;
- #endif
- #if( ipconfigUSE_CALLBACKS == 1 )
- FOnTCPReceive_t pxHandleReceive; /*
- * In case of a TCP socket:
- * typedef void (* FOnTCPReceive_t) (Socket_t xSocket, void *pData, size_t xLength );
- */
- FOnTCPSent_t pxHandleSent;
- FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
- #endif /* ipconfigUSE_CALLBACKS */
- uint32_t ulWindowSize; /* Current Window size advertised by peer */
- size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */
- size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */
-
- TCPWindow_t xTCPWindow;
- } IPTCPSocket_t;
-
-#endif /* ipconfigUSE_TCP */
-
-typedef struct UDPSOCKET
-{
- List_t xWaitingPacketsList; /* Incoming packets */
- #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
- UBaseType_t uxMaxPackets; /* Protection: limits the number of packets buffered per socket */
- #endif /* ipconfigUDP_MAX_RX_PACKETS */
- #if( ipconfigUSE_CALLBACKS == 1 )
- FOnUDPReceive_t pxHandleReceive; /*
- * In case of a UDP socket:
- * typedef void (* FOnUDPReceive_t) (Socket_t xSocket, void *pData, size_t xLength, struct freertos_sockaddr *pxAddr );
- */
- FOnUDPSent_t pxHandleSent;
- #endif /* ipconfigUSE_CALLBACKS */
-} IPUDPSocket_t;
-
-typedef enum eSOCKET_EVENT {
- eSOCKET_RECEIVE = 0x0001,
- eSOCKET_SEND = 0x0002,
- eSOCKET_ACCEPT = 0x0004,
- eSOCKET_CONNECT = 0x0008,
- eSOCKET_BOUND = 0x0010,
- eSOCKET_CLOSED = 0x0020,
- eSOCKET_INTR = 0x0040,
- eSOCKET_ALL = 0x007F,
-} eSocketEvent_t;
-
-typedef struct xSOCKET
-{
- EventBits_t xEventBits;
- EventGroupHandle_t xEventGroup;
-
- ListItem_t xBoundSocketListItem; /* Used to reference the socket from a bound sockets list. */
- TickType_t xReceiveBlockTime; /* if recv[to] is called while no data is available, wait this amount of time. Unit in clock-ticks */
- TickType_t xSendBlockTime; /* if send[to] is called while there is not enough space to send, wait this amount of time. Unit in clock-ticks */
-
- uint16_t usLocalPort; /* Local port on this machine */
- uint8_t ucSocketOptions;
- uint8_t ucProtocol; /* choice of FREERTOS_IPPROTO_UDP/TCP */
- #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
- SemaphoreHandle_t pxUserSemaphore;
- #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
- #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
- SocketWakeupCallback_t pxUserWakeCallback;
- #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
-
- #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
- struct xSOCKET_SET *pxSocketSet;
- /* User may indicate which bits are interesting for this socket. */
- EventBits_t xSelectBits;
- /* These bits indicate the events which have actually occurred.
- They are maintained by the IP-task */
- EventBits_t xSocketBits;
- #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
- /* TCP/UDP specific fields: */
- /* Before accessing any member of this structure, it should be confirmed */
- /* that the protocol corresponds with the type of structure */
-
- union
- {
- IPUDPSocket_t xUDP;
- #if( ipconfigUSE_TCP == 1 )
- IPTCPSocket_t xTCP;
- /* Make sure that xTCP is 8-bytes aligned by
- declaring a 64-bit variable in the same union */
- uint64_t ullTCPAlignment;
- #endif /* ipconfigUSE_TCP */
- } u;
-} FreeRTOS_Socket_t;
-
-#if( ipconfigUSE_TCP == 1 )
- /*
- * Lookup a TCP socket, using a multiple matching: both port numbers and
- * return IP address.
- */
- FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort );
-
-#endif /* ipconfigUSE_TCP */
-
-/*
- * Look up a local socket by finding a match with the local port.
- */
-FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort );
-
-/*
- * Called when the application has generated a UDP packet to send.
- */
-void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
-
-/*
- * Calculate the upper-layer checksum
- * Works both for UDP, ICMP and TCP packages
- * bOut = true: checksum will be set in outgoing packets
- * bOut = false: checksum will be calculated for incoming packets
- * returning 0xffff means: checksum was correct
- */
-uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket );
-
-/*
- * An Ethernet frame has been updated (maybe it was an ARP request or a PING
- * request?) and is to be sent back to its source.
- */
-void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend );
-
-/*
- * The internal version of bind()
- * If 'ulInternal' is true, it is called by the driver
- * The TCP driver needs to bind a socket at the moment a listening socket
- * creates a new connected socket
- */
-BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal );
-
-/*
- * Internal function to add streaming data to a TCP socket. If ulIn == true,
- * data will be added to the rxStream, otherwise to the tXStream. Normally data
- * will be written with ulOffset == 0, meaning: at the end of the FIFO. When
- * packet come in out-of-order, an offset will be used to put it in front and
- * the head will not change yet.
- */
-int32_t lTCPAddRxdata(FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount);
-
-/*
- * Currently called for any important event.
- */
-void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Some helping function, their meaning should be clear
- */
-static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr);
-static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr)
-{
- return ( ( ( uint32_t )apChr[0] ) << 24) |
- ( ( ( uint32_t )apChr[1] ) << 16) |
- ( ( ( uint32_t )apChr[2] ) << 8) |
- ( ( ( uint32_t )apChr[3] ) );
-}
-
-static portINLINE uint16_t usChar2u16 (const uint8_t *apChr);
-static portINLINE uint16_t usChar2u16 (const uint8_t *apChr)
-{
- return ( uint16_t )
- ( ( ( ( uint32_t )apChr[0] ) << 8) |
- ( ( ( uint32_t )apChr[1] ) ) );
-}
-
-/* Check a single socket for retransmissions and timeouts */
-BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket );
-
-BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket );
-
-/* Defined in FreeRTOS_Sockets.c
- * Close a socket
- */
-void *vSocketClose( FreeRTOS_Socket_t *pxSocket );
-
-/*
- * Send the event eEvent to the IP task event queue, using a block time of
- * zero. Return pdPASS if the message was sent successfully, otherwise return
- * pdFALSE.
-*/
-BaseType_t xSendEventToIPTask( eIPEvent_t eEvent );
-
-/*
- * The same as above, but a struct as a parameter, containing:
- * eIPEvent_t eEventType;
- * void *pvData;
- */
-BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout );
-
-/*
- * Returns a pointer to the original NetworkBuffer from a pointer to a UDP
- * payload buffer.
- */
-NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer );
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /*
- * For the case where the network driver passes a buffer directly to a DMA
- * descriptor, this function can be used to translate a 'network buffer' to
- * a 'network buffer descriptor'.
- */
- NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer );
-#endif
-
-/*
- * Internal: Sets a new state for a TCP socket and performs the necessary
- * actions like calling a OnConnected handler to notify the socket owner.
- */
-#if( ipconfigUSE_TCP == 1 )
- void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState );
-#endif /* ipconfigUSE_TCP */
-
-/*_RB_ Should this be part of the public API? */
-void FreeRTOS_netstat( void );
-
-/* Returns pdTRUE is this function is called from the IP-task */
-BaseType_t xIsCallingFromIPTask( void );
-
-#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
-
-typedef struct xSOCKET_SET
-{
- EventGroupHandle_t xSelectGroup;
- BaseType_t bApiCalled; /* True if the API was calling the private vSocketSelect */
- FreeRTOS_Socket_t *pxSocket;
-} SocketSelect_t;
-
-extern void vSocketSelect( SocketSelect_t *pxSocketSelect );
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
-
-void vIPSetDHCPTimerEnableState( BaseType_t xEnableState );
-void vIPReloadDHCPTimer( uint32_t ulLeaseTime );
-#if( ipconfigDNS_USE_CALLBACKS != 0 )
- void vIPReloadDNSTimer( uint32_t ulCheckTime );
- void vIPSetDnsTimerEnableState( BaseType_t xEnableState );
-#endif
-
-/* Send the network-up event and start the ARP timer. */
-void vIPNetworkUpCalls( void );
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* FREERTOS_IP_PRIVATE_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_IP_PRIVATE_H
+#define FREERTOS_IP_PRIVATE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+#include "FreeRTOSIPConfigDefaults.h"
+#include "FreeRTOS_Sockets.h"
+#include "IPTraceMacroDefaults.h"
+#include "FreeRTOS_Stream_Buffer.h"
+#if( ipconfigUSE_TCP == 1 )
+ #include "FreeRTOS_TCP_WIN.h"
+ #include "FreeRTOS_TCP_IP.h"
+#endif
+
+#include "event_groups.h"
+
+typedef struct xNetworkAddressingParameters
+{
+ uint32_t ulDefaultIPAddress;
+ uint32_t ulNetMask;
+ uint32_t ulGatewayAddress;
+ uint32_t ulDNSServerAddress;
+ uint32_t ulBroadcastAddress;
+} NetworkAddressingParameters_t;
+
+extern BaseType_t xTCPWindowLoggingLevel;
+
+/*-----------------------------------------------------------*/
+/* Protocol headers. */
+/*-----------------------------------------------------------*/
+
+#include "pack_struct_start.h"
+struct xETH_HEADER
+{
+ MACAddress_t xDestinationAddress; /* 0 + 6 = 6 */
+ MACAddress_t xSourceAddress; /* 6 + 6 = 12 */
+ uint16_t usFrameType; /* 12 + 2 = 14 */
+}
+#include "pack_struct_end.h"
+typedef struct xETH_HEADER EthernetHeader_t;
+
+#include "pack_struct_start.h"
+struct xARP_HEADER
+{
+ uint16_t usHardwareType; /* 0 + 2 = 2 */
+ uint16_t usProtocolType; /* 2 + 2 = 4 */
+ uint8_t ucHardwareAddressLength; /* 4 + 1 = 5 */
+ uint8_t ucProtocolAddressLength; /* 5 + 1 = 6 */
+ uint16_t usOperation; /* 6 + 2 = 8 */
+ MACAddress_t xSenderHardwareAddress; /* 8 + 6 = 14 */
+ uint8_t ucSenderProtocolAddress[ 4 ]; /* 14 + 4 = 18 */
+ MACAddress_t xTargetHardwareAddress; /* 18 + 6 = 24 */
+ uint32_t ulTargetProtocolAddress; /* 24 + 4 = 28 */
+}
+#include "pack_struct_end.h"
+typedef struct xARP_HEADER ARPHeader_t;
+
+#include "pack_struct_start.h"
+struct xIP_HEADER
+{
+ uint8_t ucVersionHeaderLength; /* 0 + 1 = 1 */
+ uint8_t ucDifferentiatedServicesCode; /* 1 + 1 = 2 */
+ uint16_t usLength; /* 2 + 2 = 4 */
+ uint16_t usIdentification; /* 4 + 2 = 6 */
+ uint16_t usFragmentOffset; /* 6 + 2 = 8 */
+ uint8_t ucTimeToLive; /* 8 + 1 = 9 */
+ uint8_t ucProtocol; /* 9 + 1 = 10 */
+ uint16_t usHeaderChecksum; /* 10 + 2 = 12 */
+ uint32_t ulSourceIPAddress; /* 12 + 4 = 16 */
+ uint32_t ulDestinationIPAddress; /* 16 + 4 = 20 */
+}
+#include "pack_struct_end.h"
+typedef struct xIP_HEADER IPHeader_t;
+
+#include "pack_struct_start.h"
+struct xIGMP_HEADER
+{
+ uint8_t ucVersionType; /* 0 + 1 = 1 */
+ uint8_t ucMaxResponseTime; /* 1 + 1 = 2 */
+ uint16_t usChecksum; /* 2 + 2 = 4 */
+ uint32_t usGroupAddress; /* 4 + 4 = 8 */
+}
+#include "pack_struct_end.h"
+typedef struct xIGMP_HEADER IGMPHeader_t;
+
+#include "pack_struct_start.h"
+struct xICMP_HEADER
+{
+ uint8_t ucTypeOfMessage; /* 0 + 1 = 1 */
+ uint8_t ucTypeOfService; /* 1 + 1 = 2 */
+ uint16_t usChecksum; /* 2 + 2 = 4 */
+ uint16_t usIdentifier; /* 4 + 2 = 6 */
+ uint16_t usSequenceNumber; /* 6 + 2 = 8 */
+}
+#include "pack_struct_end.h"
+typedef struct xICMP_HEADER ICMPHeader_t;
+
+#include "pack_struct_start.h"
+struct xUDP_HEADER
+{
+ uint16_t usSourcePort; /* 0 + 2 = 2 */
+ uint16_t usDestinationPort; /* 2 + 2 = 4 */
+ uint16_t usLength; /* 4 + 2 = 6 */
+ uint16_t usChecksum; /* 6 + 2 = 8 */
+}
+#include "pack_struct_end.h"
+typedef struct xUDP_HEADER UDPHeader_t;
+
+#include "pack_struct_start.h"
+struct xTCP_HEADER
+{
+ uint16_t usSourcePort; /* + 2 = 2 */
+ uint16_t usDestinationPort; /* + 2 = 4 */
+ uint32_t ulSequenceNumber; /* + 4 = 8 */
+ uint32_t ulAckNr; /* + 4 = 12 */
+ uint8_t ucTCPOffset; /* + 1 = 13 */
+ uint8_t ucTCPFlags; /* + 1 = 14 */
+ uint16_t usWindow; /* + 2 = 15 */
+ uint16_t usChecksum; /* + 2 = 18 */
+ uint16_t usUrgent; /* + 2 = 20 */
+#if ipconfigUSE_TCP == 1
+ /* the option data is not a part of the TCP header */
+ uint8_t ucOptdata[ipSIZE_TCP_OPTIONS]; /* + 12 = 32 */
+#endif
+}
+#include "pack_struct_end.h"
+typedef struct xTCP_HEADER TCPHeader_t;
+
+#include "pack_struct_start.h"
+struct xPSEUDO_HEADER
+{
+ uint32_t ulSourceAddress;
+ uint32_t ulDestinationAddress;
+ uint8_t ucZeros;
+ uint8_t ucProtocol;
+ uint16_t usUDPLength;
+}
+#include "pack_struct_end.h"
+typedef struct xPSEUDO_HEADER PseudoHeader_t;
+
+/*-----------------------------------------------------------*/
+/* Nested protocol packets. */
+/*-----------------------------------------------------------*/
+
+#include "pack_struct_start.h"
+struct xARP_PACKET
+{
+ EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
+ ARPHeader_t xARPHeader; /* 14 + 28 = 42 */
+}
+#include "pack_struct_end.h"
+typedef struct xARP_PACKET ARPPacket_t;
+
+#include "pack_struct_start.h"
+struct xIP_PACKET
+{
+ EthernetHeader_t xEthernetHeader;
+ IPHeader_t xIPHeader;
+}
+#include "pack_struct_end.h"
+typedef struct xIP_PACKET IPPacket_t;
+
+#include "pack_struct_start.h"
+struct xICMP_PACKET
+{
+ EthernetHeader_t xEthernetHeader;
+ IPHeader_t xIPHeader;
+ ICMPHeader_t xICMPHeader;
+}
+#include "pack_struct_end.h"
+typedef struct xICMP_PACKET ICMPPacket_t;
+
+#include "pack_struct_start.h"
+struct xUDP_PACKET
+{
+ EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
+ IPHeader_t xIPHeader; /* 14 + 20 = 34 */
+ UDPHeader_t xUDPHeader; /* 34 + 8 = 42 */
+}
+#include "pack_struct_end.h"
+typedef struct xUDP_PACKET UDPPacket_t;
+
+#include "pack_struct_start.h"
+struct xTCP_PACKET
+{
+ EthernetHeader_t xEthernetHeader; /* 0 + 14 = 14 */
+ IPHeader_t xIPHeader; /* 14 + 20 = 34 */
+ TCPHeader_t xTCPHeader; /* 34 + 32 = 66 */
+}
+#include "pack_struct_end.h"
+typedef struct xTCP_PACKET TCPPacket_t;
+
+typedef union XPROT_PACKET
+{
+ ARPPacket_t xARPPacket;
+ TCPPacket_t xTCPPacket;
+ UDPPacket_t xUDPPacket;
+ ICMPPacket_t xICMPPacket;
+} ProtocolPacket_t;
+
+
+/* The maximum UDP payload length. */
+#define ipMAX_UDP_PAYLOAD_LENGTH ( ( ipconfigNETWORK_MTU - ipSIZE_OF_IPv4_HEADER ) - ipSIZE_OF_UDP_HEADER )
+
+typedef enum
+{
+ eReleaseBuffer = 0, /* Processing the frame did not find anything to do - just release the buffer. */
+ eProcessBuffer, /* An Ethernet frame has a valid address - continue process its contents. */
+ eReturnEthernetFrame, /* The Ethernet frame contains an ARP or ICMP packet that can be returned to its source. */
+ eFrameConsumed /* Processing the Ethernet packet contents resulted in the payload being sent to the stack. */
+} eFrameProcessingResult_t;
+
+typedef enum
+{
+ eNoEvent = -1,
+ eNetworkDownEvent, /* 0: The network interface has been lost and/or needs [re]connecting. */
+ eNetworkRxEvent, /* 1: The network interface has queued a received Ethernet frame. */
+ eNetworkTxEvent, /* 2: Let the IP-task send a network packet. */
+ eARPTimerEvent, /* 3: The ARP timer expired. */
+ eStackTxEvent, /* 4: The software stack has queued a packet to transmit. */
+ eDHCPEvent, /* 5: Process the DHCP state machine. */
+ eTCPTimerEvent, /* 6: See if any TCP socket needs attention. */
+ eTCPAcceptEvent, /* 7: Client API FreeRTOS_accept() waiting for client connections. */
+ eTCPNetStat, /* 8: IP-task is asked to produce a netstat listing. */
+ eSocketBindEvent, /* 9: Send a message to the IP-task to bind a socket to a port. */
+ eSocketCloseEvent, /*10: Send a message to the IP-task to close a socket. */
+ eSocketSelectEvent, /*11: Send a message to the IP-task for select(). */
+ eSocketSignalEvent, /*12: A socket must be signalled. */
+} eIPEvent_t;
+
+typedef struct IP_TASK_COMMANDS
+{
+ eIPEvent_t eEventType;
+ void *pvData;
+} IPStackEvent_t;
+
+#define ipBROADCAST_IP_ADDRESS 0xffffffffUL
+
+/* Offset into the Ethernet frame that is used to temporarily store information
+on the fragmentation status of the packet being sent. The value is important,
+as it is past the location into which the destination address will get placed. */
+#define ipFRAGMENTATION_PARAMETERS_OFFSET ( 6 )
+#define ipSOCKET_OPTIONS_OFFSET ( 6 )
+
+/* Only used when outgoing fragmentation is being used (FreeRTOSIPConfig.h
+setting. */
+#define ipGET_UDP_PAYLOAD_OFFSET_FOR_FRAGMENT( usFragmentOffset ) ( ( ( usFragmentOffset ) == 0 ) ? ipUDP_PAYLOAD_OFFSET_IPv4 : ipIP_PAYLOAD_OFFSET )
+
+/* The offset into a UDP packet at which the UDP data (payload) starts. */
+#define ipUDP_PAYLOAD_OFFSET_IPv4 ( sizeof( UDPPacket_t ) )
+
+/* The offset into an IP packet into which the IP data (payload) starts. */
+#define ipIP_PAYLOAD_OFFSET ( sizeof( IPPacket_t ) )
+
+#include "pack_struct_start.h"
+struct xUDP_IP_FRAGMENT_PARAMETERS
+{
+ uint8_t ucSocketOptions;
+ uint8_t ucPadFor16BitAlignment;
+ uint16_t usFragmentedPacketOffset;
+ uint16_t usFragmentLength;
+ uint16_t usPayloadChecksum;
+}
+#include "pack_struct_end.h"
+typedef struct xUDP_IP_FRAGMENT_PARAMETERS IPFragmentParameters_t;
+
+#if( ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN )
+
+ /* Ethernet frame types. */
+ #define ipARP_FRAME_TYPE ( 0x0608U )
+ #define ipIPv4_FRAME_TYPE ( 0x0008U )
+
+ /* ARP related definitions. */
+ #define ipARP_PROTOCOL_TYPE ( 0x0008U )
+ #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0100U )
+ #define ipARP_REQUEST ( 0x0100U )
+ #define ipARP_REPLY ( 0x0200U )
+
+#else
+
+ /* Ethernet frame types. */
+ #define ipARP_FRAME_TYPE ( 0x0806U )
+ #define ipIPv4_FRAME_TYPE ( 0x0800U )
+
+ /* ARP related definitions. */
+ #define ipARP_PROTOCOL_TYPE ( 0x0800U )
+ #define ipARP_HARDWARE_TYPE_ETHERNET ( 0x0001U )
+ #define ipARP_REQUEST ( 0x0001 )
+ #define ipARP_REPLY ( 0x0002 )
+
+#endif /* ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN */
+
+
+/* For convenience, a MAC address of all zeros and another of all 0xffs are
+defined const for quick reference. */
+extern const MACAddress_t xBroadcastMACAddress; /* all 0xff's */
+extern uint16_t usPacketIdentifier;
+
+/* Define a default UDP packet header (declared in FreeRTOS_UDP_IP.c) */
+typedef union xUDPPacketHeader
+{
+ uint8_t ucBytes[24];
+ uint32_t ulWords[6];
+} UDPPacketHeader_t;
+extern UDPPacketHeader_t xDefaultPartUDPPacketHeader;
+
+/* Structure that stores the netmask, gateway address and DNS server addresses. */
+extern NetworkAddressingParameters_t xNetworkAddressing;
+
+/* Structure that stores the defaults for netmask, gateway address and DNS.
+These values will be copied to 'xNetworkAddressing' in case DHCP is not used,
+and also in case DHCP does not lead to a confirmed request. */
+extern NetworkAddressingParameters_t xDefaultAddressing;
+
+/* True when BufferAllocation_1.c was included, false for BufferAllocation_2.c */
+extern const BaseType_t xBufferAllocFixedSize;
+
+/* Defined in FreeRTOS_Sockets.c */
+#if ( ipconfigUSE_TCP == 1 )
+ extern List_t xBoundTCPSocketsList;
+#endif
+
+/* The local IP address is accessed from within xDefaultPartUDPPacketHeader,
+rather than duplicated in its own variable. */
+#define ipLOCAL_IP_ADDRESS_POINTER ( ( uint32_t * ) &( xDefaultPartUDPPacketHeader.ulWords[ 20u / sizeof(uint32_t) ] ) )
+
+/* The local MAC address is accessed from within xDefaultPartUDPPacketHeader,
+rather than duplicated in its own variable. */
+#define ipLOCAL_MAC_ADDRESS ( &xDefaultPartUDPPacketHeader.ucBytes[0] )
+
+/* ICMP packets are sent using the same function as UDP packets. The port
+number is used to distinguish between the two, as 0 is an invalid UDP port. */
+#define ipPACKET_CONTAINS_ICMP_DATA ( 0 )
+
+/* For now, the lower 8 bits in 'xEventBits' will be reserved for the above
+socket events. */
+#define SOCKET_EVENT_BIT_COUNT 8
+
+#define vSetField16( pxBase, xType, xField, usValue ) \
+{ \
+ ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( usValue ) >> 8 ); \
+ ( ( uint8_t* )( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( usValue ) & 0xff ); \
+}
+
+#define vSetField32( pxBase, xType, xField, ulValue ) \
+{ \
+ ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 0 ] = ( uint8_t ) ( ( ulValue ) >> 24 ); \
+ ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 1 ] = ( uint8_t ) ( ( ( ulValue ) >> 16 ) & 0xff ); \
+ ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 2 ] = ( uint8_t ) ( ( ( ulValue ) >> 8 ) & 0xff ); \
+ ( (uint8_t*)( pxBase ) ) [ offsetof( xType, xField ) + 3 ] = ( uint8_t ) ( ( ulValue ) & 0xff ); \
+}
+
+#define vFlip_16( left, right ) \
+ do { \
+ uint16_t tmp = (left); \
+ (left) = (right); \
+ (right) = tmp; \
+ } while (0)
+
+#define vFlip_32( left, right ) \
+ do { \
+ uint32_t tmp = (left); \
+ (left) = (right); \
+ (right) = tmp; \
+ } while (0)
+
+#ifndef ARRAY_SIZE
+ #define ARRAY_SIZE(x) (BaseType_t)(sizeof(x)/sizeof(x)[0])
+#endif
+
+/*
+ * A version of FreeRTOS_GetReleaseNetworkBuffer() that can be called from an
+ * interrupt. If a non zero value is returned, then the calling ISR should
+ * perform a context switch before exiting the ISR.
+ */
+BaseType_t FreeRTOS_ReleaseFreeNetworkBufferFromISR( void );
+
+/*
+ * Create a message that contains a command to initialise the network interface.
+ * This is used during initialisation, and at any time the network interface
+ * goes down thereafter. The network interface hardware driver is responsible
+ * for sending the message that contains the network interface down command/
+ * event.
+ *
+ * Only use the FreeRTOS_NetworkDownFromISR() version if the function is to be
+ * called from an interrupt service routine. If FreeRTOS_NetworkDownFromISR()
+ * returns a non-zero value then a context switch should be performed ebfore
+ * the interrupt is exited.
+ */
+void FreeRTOS_NetworkDown( void );
+BaseType_t FreeRTOS_NetworkDownFromISR( void );
+
+/*
+ * Processes incoming ARP packets.
+ */
+eFrameProcessingResult_t eARPProcessPacket( ARPPacket_t * const pxARPFrame );
+
+/*
+ * Inspect an Ethernet frame to see if it contains data that the stack needs to
+ * process. eProcessBuffer is returned if the frame should be processed by the
+ * stack. eReleaseBuffer is returned if the frame should be discarded.
+ */
+eFrameProcessingResult_t eConsiderFrameForProcessing( const uint8_t * const pucEthernetBuffer );
+
+/*
+ * Return the checksum generated over xDataLengthBytes from pucNextData.
+ */
+uint16_t usGenerateChecksum( uint32_t ulSum, const uint8_t * pucNextData, size_t uxDataLengthBytes );
+
+/* Socket related private functions. */
+
+/*
+ * The caller must ensure that pxNetworkBuffer->xDataLength is the UDP packet
+ * payload size (excluding packet headers) and that the packet in pucEthernetBuffer
+ * is at least the size of UDPPacket_t.
+ */
+BaseType_t xProcessReceivedUDPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer, uint16_t usPort );
+
+/*
+ * Initialize the socket list data structures for TCP and UDP.
+ */
+BaseType_t vNetworkSocketsInit( void );
+
+/*
+ * Returns pdTRUE if the IP task has been created and is initialised. Otherwise
+ * returns pdFALSE.
+ */
+BaseType_t xIPIsNetworkTaskReady( void );
+
+#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
+ struct xSOCKET;
+ typedef void (*SocketWakeupCallback_t)( struct xSOCKET * pxSocket );
+#endif
+
+#if( ipconfigUSE_TCP == 1 )
+
+ /*
+ * Actually a user thing, but because xBoundTCPSocketsList, let it do by the
+ * IP-task
+ */
+ void vTCPNetStat( void );
+
+ /*
+ * At least one socket needs to check for timeouts
+ */
+ TickType_t xTCPTimerCheck( BaseType_t xWillSleep );
+
+ /* Every TCP socket has a buffer space just big enough to store
+ the last TCP header received.
+ As a reference of this field may be passed to DMA, force the
+ alignment to 8 bytes. */
+ typedef union
+ {
+ struct
+ {
+ /* Increase the alignment of this union by adding a 64-bit variable. */
+ uint64_t ullAlignmentWord;
+ } a;
+ struct
+ {
+ /* The next field only serves to give 'ucLastPacket' a correct
+ alignment of 8 + 2. See comments in FreeRTOS_IP.h */
+ uint8_t ucFillPacket[ ipconfigPACKET_FILLER_SIZE ];
+ uint8_t ucLastPacket[ sizeof( TCPPacket_t ) ];
+ } u;
+ } LastTCPPacket_t;
+
+ /*
+ * Note that the values of all short and long integers in these structs
+ * are being stored in the native-endian way
+ * Translation should take place when accessing any structure which defines
+ * network packets, such as IPHeader_t and TCPHeader_t
+ */
+ typedef struct TCPSOCKET
+ {
+ uint32_t ulRemoteIP; /* IP address of remote machine */
+ uint16_t usRemotePort; /* Port on remote machine */
+ struct {
+ /* Most compilers do like bit-flags */
+ uint32_t
+ bMssChange : 1, /* This socket has seen a change in MSS */
+ bPassAccept : 1, /* when true, this socket may be returned in a call to accept() */
+ bPassQueued : 1, /* when true, this socket is an orphan until it gets connected
+ * Why an orphan? Because it may not be returned in a accept() call until it
+ * gets the state eESTABLISHED */
+ bReuseSocket : 1, /* When a listening socket gets a connection, do not create a new instance but keep on using it */
+ bCloseAfterSend : 1,/* As soon as the last byte has been transmitted, finalise the connection
+ * Useful in e.g. FTP connections, where the last data bytes are sent along with the FIN flag */
+ bUserShutdown : 1, /* User requesting a graceful shutdown */
+ bCloseRequested : 1,/* Request to finalise the connection */
+ bLowWater : 1, /* high-water level has been reached. Cleared as soon as 'rx-count < lo-water' */
+ bWinChange : 1, /* The value of bLowWater has changed, must send a window update */
+ bSendKeepAlive : 1, /* When this flag is true, a TCP keep-alive message must be send */
+ bWaitKeepAlive : 1, /* When this flag is true, a TCP keep-alive reply is expected */
+ bConnPrepared : 1, /* Connecting socket: Message has been prepared */
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ bConnPassed : 1, /* Connecting socket: Socket has been passed in a successful select() */
+ #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+ bFinAccepted : 1, /* This socket has received (or sent) a FIN and accepted it */
+ bFinSent : 1, /* We've sent out a FIN */
+ bFinRecv : 1, /* We've received a FIN from our peer */
+ bFinAcked : 1, /* Our FIN packet has been acked */
+ bFinLast : 1, /* The last ACK (after FIN and FIN+ACK) has been sent or will be sent by the peer */
+ bRxStopped : 1, /* Application asked to temporarily stop reception */
+ bMallocError : 1, /* There was an error allocating a stream */
+ bWinScaling : 1; /* A TCP-Window Scaling option was offered and accepted in the SYN phase. */
+ } bits;
+ uint32_t ulHighestRxAllowed;
+ /* The highest sequence number that we can receive at any moment */
+ uint16_t usTimeout; /* Time (in ticks) after which this socket needs attention */
+ uint16_t usCurMSS; /* Current Maximum Segment Size */
+ uint16_t usInitMSS; /* Initial maximum segment Size */
+ uint16_t usChildCount; /* In case of a listening socket: number of connections on this port number */
+ uint16_t usBacklog; /* In case of a listening socket: maximum number of concurrent connections on this port number */
+ uint8_t ucRepCount; /* Send repeat count, for retransmissions
+ * This counter is separate from the xmitCount in the
+ * TCP win segments */
+ uint8_t ucTCPState; /* TCP state: see eTCP_STATE */
+ struct xSOCKET *pxPeerSocket; /* for server socket: child, for child socket: parent */
+ #if( ipconfigTCP_KEEP_ALIVE == 1 )
+ uint8_t ucKeepRepCount;
+ TickType_t xLastAliveTime;
+ #endif /* ipconfigTCP_KEEP_ALIVE */
+ #if( ipconfigTCP_HANG_PROTECTION == 1 )
+ TickType_t xLastActTime;
+ #endif /* ipconfigTCP_HANG_PROTECTION */
+ size_t uxLittleSpace;
+ size_t uxEnoughSpace;
+ size_t uxRxStreamSize;
+ size_t uxTxStreamSize;
+ StreamBuffer_t *rxStream;
+ StreamBuffer_t *txStream;
+ #if( ipconfigUSE_TCP_WIN == 1 )
+ NetworkBufferDescriptor_t *pxAckMessage;
+ #endif /* ipconfigUSE_TCP_WIN */
+ /* Buffer space to store the last TCP header received. */
+ LastTCPPacket_t xPacket;
+ uint8_t tcpflags; /* TCP flags */
+ #if( ipconfigUSE_TCP_WIN != 0 )
+ uint8_t ucMyWinScaleFactor;
+ uint8_t ucPeerWinScaleFactor;
+ #endif
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ FOnTCPReceive_t pxHandleReceive; /*
+ * In case of a TCP socket:
+ * typedef void (* FOnTCPReceive_t) (Socket_t xSocket, void *pData, size_t xLength );
+ */
+ FOnTCPSent_t pxHandleSent;
+ FOnConnected_t pxHandleConnected; /* Actually type: typedef void (* FOnConnected_t) (Socket_t xSocket, BaseType_t ulConnected ); */
+ #endif /* ipconfigUSE_CALLBACKS */
+ uint32_t ulWindowSize; /* Current Window size advertised by peer */
+ size_t uxRxWinSize; /* Fixed value: size of the TCP reception window */
+ size_t uxTxWinSize; /* Fixed value: size of the TCP transmit window */
+
+ TCPWindow_t xTCPWindow;
+ } IPTCPSocket_t;
+
+#endif /* ipconfigUSE_TCP */
+
+typedef struct UDPSOCKET
+{
+ List_t xWaitingPacketsList; /* Incoming packets */
+ #if( ipconfigUDP_MAX_RX_PACKETS > 0 )
+ UBaseType_t uxMaxPackets; /* Protection: limits the number of packets buffered per socket */
+ #endif /* ipconfigUDP_MAX_RX_PACKETS */
+ #if( ipconfigUSE_CALLBACKS == 1 )
+ FOnUDPReceive_t pxHandleReceive; /*
+ * In case of a UDP socket:
+ * typedef void (* FOnUDPReceive_t) (Socket_t xSocket, void *pData, size_t xLength, struct freertos_sockaddr *pxAddr );
+ */
+ FOnUDPSent_t pxHandleSent;
+ #endif /* ipconfigUSE_CALLBACKS */
+} IPUDPSocket_t;
+
+typedef enum eSOCKET_EVENT {
+ eSOCKET_RECEIVE = 0x0001,
+ eSOCKET_SEND = 0x0002,
+ eSOCKET_ACCEPT = 0x0004,
+ eSOCKET_CONNECT = 0x0008,
+ eSOCKET_BOUND = 0x0010,
+ eSOCKET_CLOSED = 0x0020,
+ eSOCKET_INTR = 0x0040,
+ eSOCKET_ALL = 0x007F,
+} eSocketEvent_t;
+
+typedef struct xSOCKET
+{
+ EventBits_t xEventBits;
+ EventGroupHandle_t xEventGroup;
+
+ ListItem_t xBoundSocketListItem; /* Used to reference the socket from a bound sockets list. */
+ TickType_t xReceiveBlockTime; /* if recv[to] is called while no data is available, wait this amount of time. Unit in clock-ticks */
+ TickType_t xSendBlockTime; /* if send[to] is called while there is not enough space to send, wait this amount of time. Unit in clock-ticks */
+
+ uint16_t usLocalPort; /* Local port on this machine */
+ uint8_t ucSocketOptions;
+ uint8_t ucProtocol; /* choice of FREERTOS_IPPROTO_UDP/TCP */
+ #if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
+ SemaphoreHandle_t pxUserSemaphore;
+ #endif /* ipconfigSOCKET_HAS_USER_SEMAPHORE */
+ #if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
+ SocketWakeupCallback_t pxUserWakeCallback;
+ #endif /* ipconfigSOCKET_HAS_USER_WAKE_CALLBACK */
+
+ #if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+ struct xSOCKET_SET *pxSocketSet;
+ /* User may indicate which bits are interesting for this socket. */
+ EventBits_t xSelectBits;
+ /* These bits indicate the events which have actually occurred.
+ They are maintained by the IP-task */
+ EventBits_t xSocketBits;
+ #endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+ /* TCP/UDP specific fields: */
+ /* Before accessing any member of this structure, it should be confirmed */
+ /* that the protocol corresponds with the type of structure */
+
+ union
+ {
+ IPUDPSocket_t xUDP;
+ #if( ipconfigUSE_TCP == 1 )
+ IPTCPSocket_t xTCP;
+ /* Make sure that xTCP is 8-bytes aligned by
+ declaring a 64-bit variable in the same union */
+ uint64_t ullTCPAlignment;
+ #endif /* ipconfigUSE_TCP */
+ } u;
+} FreeRTOS_Socket_t;
+
+#if( ipconfigUSE_TCP == 1 )
+ /*
+ * Lookup a TCP socket, using a multiple matching: both port numbers and
+ * return IP address.
+ */
+ FreeRTOS_Socket_t *pxTCPSocketLookup( uint32_t ulLocalIP, UBaseType_t uxLocalPort, uint32_t ulRemoteIP, UBaseType_t uxRemotePort );
+
+#endif /* ipconfigUSE_TCP */
+
+/*
+ * Look up a local socket by finding a match with the local port.
+ */
+FreeRTOS_Socket_t *pxUDPSocketLookup( UBaseType_t uxLocalPort );
+
+/*
+ * Called when the application has generated a UDP packet to send.
+ */
+void vProcessGeneratedUDPPacket( NetworkBufferDescriptor_t * const pxNetworkBuffer );
+
+/*
+ * Calculate the upper-layer checksum
+ * Works both for UDP, ICMP and TCP packages
+ * bOut = true: checksum will be set in outgoing packets
+ * bOut = false: checksum will be calculated for incoming packets
+ * returning 0xffff means: checksum was correct
+ */
+uint16_t usGenerateProtocolChecksum( const uint8_t * const pucEthernetBuffer, size_t uxBufferLength, BaseType_t xOutgoingPacket );
+
+/*
+ * An Ethernet frame has been updated (maybe it was an ARP request or a PING
+ * request?) and is to be sent back to its source.
+ */
+void vReturnEthernetFrame( NetworkBufferDescriptor_t * pxNetworkBuffer, BaseType_t xReleaseAfterSend );
+
+/*
+ * The internal version of bind()
+ * If 'ulInternal' is true, it is called by the driver
+ * The TCP driver needs to bind a socket at the moment a listening socket
+ * creates a new connected socket
+ */
+BaseType_t vSocketBind( FreeRTOS_Socket_t *pxSocket, struct freertos_sockaddr * pxAddress, size_t uxAddressLength, BaseType_t xInternal );
+
+/*
+ * Internal function to add streaming data to a TCP socket. If ulIn == true,
+ * data will be added to the rxStream, otherwise to the tXStream. Normally data
+ * will be written with ulOffset == 0, meaning: at the end of the FIFO. When
+ * packet come in out-of-order, an offset will be used to put it in front and
+ * the head will not change yet.
+ */
+int32_t lTCPAddRxdata(FreeRTOS_Socket_t *pxSocket, size_t uxOffset, const uint8_t *pcData, uint32_t ulByteCount);
+
+/*
+ * Currently called for any important event.
+ */
+void vSocketWakeUpUser( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Some helping function, their meaning should be clear
+ */
+static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr);
+static portINLINE uint32_t ulChar2u32 (const uint8_t *apChr)
+{
+ return ( ( ( uint32_t )apChr[0] ) << 24) |
+ ( ( ( uint32_t )apChr[1] ) << 16) |
+ ( ( ( uint32_t )apChr[2] ) << 8) |
+ ( ( ( uint32_t )apChr[3] ) );
+}
+
+static portINLINE uint16_t usChar2u16 (const uint8_t *apChr);
+static portINLINE uint16_t usChar2u16 (const uint8_t *apChr)
+{
+ return ( uint16_t )
+ ( ( ( ( uint32_t )apChr[0] ) << 8) |
+ ( ( ( uint32_t )apChr[1] ) ) );
+}
+
+/* Check a single socket for retransmissions and timeouts */
+BaseType_t xTCPSocketCheck( FreeRTOS_Socket_t *pxSocket );
+
+BaseType_t xTCPCheckNewClient( FreeRTOS_Socket_t *pxSocket );
+
+/* Defined in FreeRTOS_Sockets.c
+ * Close a socket
+ */
+void *vSocketClose( FreeRTOS_Socket_t *pxSocket );
+
+/*
+ * Send the event eEvent to the IP task event queue, using a block time of
+ * zero. Return pdPASS if the message was sent successfully, otherwise return
+ * pdFALSE.
+*/
+BaseType_t xSendEventToIPTask( eIPEvent_t eEvent );
+
+/*
+ * The same as above, but a struct as a parameter, containing:
+ * eIPEvent_t eEventType;
+ * void *pvData;
+ */
+BaseType_t xSendEventStructToIPTask( const IPStackEvent_t *pxEvent, TickType_t xTimeout );
+
+/*
+ * Returns a pointer to the original NetworkBuffer from a pointer to a UDP
+ * payload buffer.
+ */
+NetworkBufferDescriptor_t *pxUDPPayloadBuffer_to_NetworkBuffer( void *pvBuffer );
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ /*
+ * For the case where the network driver passes a buffer directly to a DMA
+ * descriptor, this function can be used to translate a 'network buffer' to
+ * a 'network buffer descriptor'.
+ */
+ NetworkBufferDescriptor_t *pxPacketBuffer_to_NetworkBuffer( const void *pvBuffer );
+#endif
+
+/*
+ * Internal: Sets a new state for a TCP socket and performs the necessary
+ * actions like calling a OnConnected handler to notify the socket owner.
+ */
+#if( ipconfigUSE_TCP == 1 )
+ void vTCPStateChange( FreeRTOS_Socket_t *pxSocket, enum eTCP_STATE eTCPState );
+#endif /* ipconfigUSE_TCP */
+
+/*_RB_ Should this be part of the public API? */
+void FreeRTOS_netstat( void );
+
+/* Returns pdTRUE is this function is called from the IP-task */
+BaseType_t xIsCallingFromIPTask( void );
+
+#if( ipconfigSUPPORT_SELECT_FUNCTION == 1 )
+
+typedef struct xSOCKET_SET
+{
+ EventGroupHandle_t xSelectGroup;
+ BaseType_t bApiCalled; /* True if the API was calling the private vSocketSelect */
+ FreeRTOS_Socket_t *pxSocket;
+} SocketSelect_t;
+
+extern void vSocketSelect( SocketSelect_t *pxSocketSelect );
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+
+void vIPSetDHCPTimerEnableState( BaseType_t xEnableState );
+void vIPReloadDHCPTimer( uint32_t ulLeaseTime );
+#if( ipconfigDNS_USE_CALLBACKS != 0 )
+ void vIPReloadDNSTimer( uint32_t ulCheckTime );
+ void vIPSetDnsTimerEnableState( BaseType_t xEnableState );
+#endif
+
+/* Send the network-up event and start the ARP timer. */
+void vIPNetworkUpCalls( void );
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* FREERTOS_IP_PRIVATE_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h
index 88d3bba65..926ccebbd 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Sockets.h
@@ -1,402 +1,402 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_SOCKETS_H
-#define FREERTOS_SOCKETS_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Standard includes. */
-#include <string.h>
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-
-#ifndef FREERTOS_IP_CONFIG_H
- #error FreeRTOSIPConfig.h has not been included yet
-#endif
-
-/* Event bit definitions are required by the select functions. */
-#include "event_groups.h"
-
-#ifndef INC_FREERTOS_H
- #error FreeRTOS.h must be included before FreeRTOS_Sockets.h.
-#endif
-
-#ifndef INC_TASK_H
- #ifndef TASK_H /* For compatibility with older FreeRTOS versions. */
- #error The FreeRTOS header file task.h must be included before FreeRTOS_Sockets.h.
- #endif
-#endif
-
-/* Assigned to an Socket_t variable when the socket is not valid, probably
-because it could not be created. */
-#define FREERTOS_INVALID_SOCKET ( ( Socket_t ) ~0U )
-
-/* API function error values. As errno is supported, the FreeRTOS sockets
-functions return error codes rather than just a pass or fail indication. */
-/* HT: Extended the number of error codes, gave them positive values and if possible
-the corresponding found in errno.h
-In case of an error, API's will still return negative numbers, e.g.
- return -pdFREERTOS_ERRNO_EWOULDBLOCK;
-in case an operation would block */
-
-/* The following defines are obsolete, please use -pdFREERTOS_ERRNO_Exxx */
-
-#define FREERTOS_SOCKET_ERROR ( -1 )
-#define FREERTOS_EWOULDBLOCK ( - pdFREERTOS_ERRNO_EWOULDBLOCK )
-#define FREERTOS_EINVAL ( - pdFREERTOS_ERRNO_EINVAL )
-#define FREERTOS_EADDRNOTAVAIL ( - pdFREERTOS_ERRNO_EADDRNOTAVAIL )
-#define FREERTOS_EADDRINUSE ( - pdFREERTOS_ERRNO_EADDRINUSE )
-#define FREERTOS_ENOBUFS ( - pdFREERTOS_ERRNO_ENOBUFS )
-#define FREERTOS_ENOPROTOOPT ( - pdFREERTOS_ERRNO_ENOPROTOOPT )
-#define FREERTOS_ECLOSED ( - pdFREERTOS_ERRNO_ENOTCONN )
-
-/* Values for the parameters to FreeRTOS_socket(), inline with the Berkeley
-standard. See the documentation of FreeRTOS_socket() for more information. */
-#define FREERTOS_AF_INET ( 2 )
-#define FREERTOS_AF_INET6 ( 10 )
-#define FREERTOS_SOCK_DGRAM ( 2 )
-#define FREERTOS_IPPROTO_UDP ( 17 )
-
-#define FREERTOS_SOCK_STREAM ( 1 )
-#define FREERTOS_IPPROTO_TCP ( 6 )
-/* IP packet of type "Any local network"
- * can be used in stead of TCP for testing with sockets in raw mode
- */
-#define FREERTOS_IPPROTO_USR_LAN ( 63 )
-
-/* A bit value that can be passed into the FreeRTOS_sendto() function as part of
-the flags parameter. Setting the FREERTOS_ZERO_COPY in the flags parameter
-indicates that the zero copy interface is being used. See the documentation for
-FreeRTOS_sockets() for more information. */
-#define FREERTOS_ZERO_COPY ( 1 )
-
-/* Values that can be passed in the option name parameter of calls to
-FreeRTOS_setsockopt(). */
-#define FREERTOS_SO_RCVTIMEO ( 0 ) /* Used to set the receive time out. */
-#define FREERTOS_SO_SNDTIMEO ( 1 ) /* Used to set the send time out. */
-#define FREERTOS_SO_UDPCKSUM_OUT ( 2 ) /* Used to turn the use of the UDP checksum by a socket on or off. This also doubles as part of an 8-bit bitwise socket option. */
-#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
- #define FREERTOS_SO_SET_SEMAPHORE ( 3 ) /* Used to set a user's semaphore */
-#endif
-#define FREERTOS_SO_SNDBUF ( 4 ) /* Set the size of the send buffer (TCP only) */
-#define FREERTOS_SO_RCVBUF ( 5 ) /* Set the size of the receive buffer (TCP only) */
-
-#if ipconfigUSE_CALLBACKS == 1
- #define FREERTOS_SO_TCP_CONN_HANDLER ( 6 ) /* Install a callback for (dis) connection events. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- #define FREERTOS_SO_TCP_RECV_HANDLER ( 7 ) /* Install a callback for receiving TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- #define FREERTOS_SO_TCP_SENT_HANDLER ( 8 ) /* Install a callback for sending TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- #define FREERTOS_SO_UDP_RECV_HANDLER ( 9 ) /* Install a callback for receiving UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
- #define FREERTOS_SO_UDP_SENT_HANDLER ( 10 ) /* Install a callback for sending UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
-#endif /* ipconfigUSE_CALLBACKS */
-
-#define FREERTOS_SO_REUSE_LISTEN_SOCKET ( 11 ) /* When a listening socket gets connected, do not create a new one but re-use it */
-#define FREERTOS_SO_CLOSE_AFTER_SEND ( 12 ) /* As soon as the last byte has been transmitted, finalise the connection */
-#define FREERTOS_SO_WIN_PROPERTIES ( 13 ) /* Set all buffer and window properties in one call, parameter is pointer to WinProperties_t */
-#define FREERTOS_SO_SET_FULL_SIZE ( 14 ) /* Refuse to send packets smaller than MSS */
-
-#define FREERTOS_SO_STOP_RX ( 15 ) /* Temporarily hold up reception, used by streaming client */
-
-#if( ipconfigUDP_MAX_RX_PACKETS > 0 )
- #define FREERTOS_SO_UDP_MAX_RX_PACKETS ( 16 ) /* This option helps to limit the maximum number of packets a UDP socket will buffer */
-#endif
-
-#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
- #define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
-#endif
-
-#define FREERTOS_SO_SET_LOW_HIGH_WATER ( 18 )
-
-#define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) /* For internal use only, but also part of an 8-bit bitwise value. */
-#define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) /* For internal use only, but also part of an 8-bit bitwise value. */
-
-/* Values for flag for FreeRTOS_shutdown(). */
-#define FREERTOS_SHUT_RD ( 0 ) /* Not really at this moment, just for compatibility of the interface */
-#define FREERTOS_SHUT_WR ( 1 )
-#define FREERTOS_SHUT_RDWR ( 2 )
-
-/* Values for flag for FreeRTOS_recv(). */
-#define FREERTOS_MSG_OOB ( 2 ) /* process out-of-band data */
-#define FREERTOS_MSG_PEEK ( 4 ) /* peek at incoming message */
-#define FREERTOS_MSG_DONTROUTE ( 8 ) /* send without using routing tables */
-#define FREERTOS_MSG_DONTWAIT ( 16 ) /* Can be used with recvfrom(), sendto(), recv(), and send(). */
-
-typedef struct xWIN_PROPS {
- /* Properties of the Tx buffer and Tx window */
- int32_t lTxBufSize; /* Unit: bytes */
- int32_t lTxWinSize; /* Unit: MSS */
-
- /* Properties of the Rx buffer and Rx window */
- int32_t lRxBufSize; /* Unit: bytes */
- int32_t lRxWinSize; /* Unit: MSS */
-} WinProperties_t;
-
-typedef struct xLOW_HIGH_WATER {
- /* Structure to pass for the 'FREERTOS_SO_SET_LOW_HIGH_WATER' option */
- size_t uxLittleSpace; /* Send a STOP when buffer space drops below X bytes */
- size_t uxEnoughSpace; /* Send a GO when buffer space grows above X bytes */
-} LowHighWater_t;
-
-/* For compatibility with the expected Berkeley sockets naming. */
-#define socklen_t uint32_t
-
-/* For this limited implementation, only two members are required in the
-Berkeley style sockaddr structure. */
-struct freertos_sockaddr
-{
- /* _HT_ On 32- and 64-bit architectures, the addition of the two uint8_t
- fields doesn't make the structure bigger, due to alignment.
- The fields are inserted as a preparation for IPv6. */
-
- /* sin_len and sin_family not used in the IPv4-only release. */
- uint8_t sin_len; /* length of this structure. */
- uint8_t sin_family; /* FREERTOS_AF_INET. */
- uint16_t sin_port;
- uint32_t sin_addr;
-};
-
-#if ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN
-
- #define FreeRTOS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \
- ( ( ( ( uint32_t ) ( ucOctet3 ) ) << 24UL ) | \
- ( ( ( uint32_t ) ( ucOctet2 ) ) << 16UL ) | \
- ( ( ( uint32_t ) ( ucOctet1 ) ) << 8UL ) | \
- ( ( uint32_t ) ( ucOctet0 ) ) )
-
- #define FreeRTOS_inet_ntoa( ulIPAddress, pucBuffer ) \
- sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u", \
- ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ), \
- ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ), \
- ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ),\
- ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ) )
-
-#else /* ipconfigBYTE_ORDER */
-
- #define FreeRTOS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \
- ( ( ( ( uint32_t ) ( ucOctet0 ) ) << 24UL ) | \
- ( ( ( uint32_t ) ( ucOctet1 ) ) << 16UL ) | \
- ( ( ( uint32_t ) ( ucOctet2 ) ) << 8UL ) | \
- ( ( uint32_t ) ( ucOctet3 ) ) )
-
- #define FreeRTOS_inet_ntoa( ulIPAddress, pucBuffer ) \
- sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u", \
- ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ), \
- ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ),\
- ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ), \
- ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ) )
-
-#endif /* ipconfigBYTE_ORDER */
-
-/* The socket type itself. */
-struct xSOCKET;
-typedef struct xSOCKET *Socket_t;
-
-/* The SocketSet_t type is the equivalent to the fd_set type used by the
-Berkeley API. */
-struct xSOCKET_SET;
-typedef struct xSOCKET_SET *SocketSet_t;
-
-/**
- * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
- * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html
- */
-Socket_t FreeRTOS_socket( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol );
-int32_t FreeRTOS_recvfrom( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength );
-int32_t FreeRTOS_sendto( Socket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, BaseType_t xFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength );
-BaseType_t FreeRTOS_bind( Socket_t xSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength );
-
-/* function to get the local address and IP port */
-size_t FreeRTOS_GetLocalAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress );
-
-/* Made available when ipconfigETHERNET_DRIVER_FILTERS_PACKETS is set to 1. */
-BaseType_t xPortHasUDPSocket( uint16_t usPortNr );
-
-#if ipconfigUSE_TCP == 1
-
-BaseType_t FreeRTOS_connect( Socket_t xClientSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength );
-BaseType_t FreeRTOS_listen( Socket_t xSocket, BaseType_t xBacklog );
-BaseType_t FreeRTOS_recv( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags );
-BaseType_t FreeRTOS_send( Socket_t xSocket, const void *pvBuffer, size_t uxDataLength, BaseType_t xFlags );
-Socket_t FreeRTOS_accept( Socket_t xServerSocket, struct freertos_sockaddr *pxAddress, socklen_t *pxAddressLength );
-BaseType_t FreeRTOS_shutdown (Socket_t xSocket, BaseType_t xHow);
-
-#if( ipconfigSUPPORT_SIGNALS != 0 )
- /* Send a signal to the task which is waiting for a given socket. */
- BaseType_t FreeRTOS_SignalSocket( Socket_t xSocket );
-
- /* Send a signal to the task which reads from this socket (FromISR
- version). */
- BaseType_t FreeRTOS_SignalSocketFromISR( Socket_t xSocket, BaseType_t *pxHigherPriorityTaskWoken );
-#endif /* ipconfigSUPPORT_SIGNALS */
-
-/* Return the remote address and IP port. */
-BaseType_t FreeRTOS_GetRemoteAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress );
-
-/* returns pdTRUE if TCP socket is connected */
-BaseType_t FreeRTOS_issocketconnected( Socket_t xSocket );
-
-/* returns the actual size of MSS being used */
-BaseType_t FreeRTOS_mss( Socket_t xSocket );
-
-/* for internal use only: return the connection status */
-BaseType_t FreeRTOS_connstatus( Socket_t xSocket );
-
-/* Returns the number of bytes that may be added to txStream */
-BaseType_t FreeRTOS_maywrite( Socket_t xSocket );
-
-/*
- * Two helper functions, mostly for testing
- * rx_size returns the number of bytes available in the Rx buffer
- * tx_space returns the free space in the Tx buffer
- */
-BaseType_t FreeRTOS_rx_size( Socket_t xSocket );
-BaseType_t FreeRTOS_tx_space( Socket_t xSocket );
-BaseType_t FreeRTOS_tx_size( Socket_t xSocket );
-
-/* Returns the number of outstanding bytes in txStream. */
-/* The function FreeRTOS_outstanding() was already implemented
-FreeRTOS_tx_size(). */
-#define FreeRTOS_outstanding( xSocket ) FreeRTOS_tx_size( xSocket )
-
-/* Returns the number of bytes in the socket's rxStream. */
-/* The function FreeRTOS_recvcount() was already implemented
-FreeRTOS_rx_size(). */
-#define FreeRTOS_recvcount( xSocket ) FreeRTOS_rx_size( xSocket )
-
-/*
- * For advanced applications only:
- * Get a direct pointer to the circular transmit buffer.
- * '*pxLength' will contain the number of bytes that may be written.
- */
-uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength );
-
-#endif /* ipconfigUSE_TCP */
-
-/*
- * Connect / disconnect handler for a TCP socket
- * For example:
- * static void vMyConnectHandler (Socket_t xSocket, BaseType_t ulConnected)
- * {
- * }
- * F_TCP_UDP_Handler_t xHnd = { vMyConnectHandler };
- * FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_CONN_HANDLER, ( void * ) &xHnd, sizeof( xHnd ) );
- */
-
-typedef void (* FOnConnected_t )( Socket_t /* xSocket */, BaseType_t /* ulConnected */ );
-
-/*
- * Reception handler for a TCP socket
- * A user-proved function will be called on reception of a message
- * If the handler returns a positive number, the messages will not be stored
- * For example:
- * static BaseType_t xOnTCPReceive( Socket_t xSocket, void * pData, size_t xLength )
- * {
- * // handle the message
- * return 1;
- * }
- * F_TCP_UDP_Handler_t xHand = { xOnTCPReceive };
- * FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_RECV_HANDLER, ( void * ) &xHand, sizeof( xHand ) );
- */
-typedef BaseType_t (* FOnTCPReceive_t )( Socket_t /* xSocket */, void * /* pData */, size_t /* xLength */ );
-typedef void (* FOnTCPSent_t )( Socket_t /* xSocket */, size_t /* xLength */ );
-
-/*
- * Reception handler for a UDP socket
- * A user-proved function will be called on reception of a message
- * If the handler returns a positive number, the messages will not be stored
- */
-typedef BaseType_t (* FOnUDPReceive_t ) (Socket_t /* xSocket */, void * /* pData */, size_t /* xLength */,
- const struct freertos_sockaddr * /* pxFrom */, const struct freertos_sockaddr * /* pxDest */ );
-typedef void (* FOnUDPSent_t )( Socket_t /* xSocket */, size_t /* xLength */ );
-
-
-typedef union xTCP_UDP_HANDLER
-{
- FOnConnected_t pxOnTCPConnected; /* FREERTOS_SO_TCP_CONN_HANDLER */
- FOnTCPReceive_t pxOnTCPReceive; /* FREERTOS_SO_TCP_RECV_HANDLER */
- FOnTCPSent_t pxOnTCPSent; /* FREERTOS_SO_TCP_SENT_HANDLER */
- FOnUDPReceive_t pxOnUDPReceive; /* FREERTOS_SO_UDP_RECV_HANDLER */
- FOnUDPSent_t pxOnUDPSent; /* FREERTOS_SO_UDP_SENT_HANDLER */
-} F_TCP_UDP_Handler_t;
-
-BaseType_t FreeRTOS_setsockopt( Socket_t xSocket, int32_t lLevel, int32_t lOptionName, const void *pvOptionValue, size_t xOptionLength );
-BaseType_t FreeRTOS_closesocket( Socket_t xSocket );
-uint32_t FreeRTOS_gethostbyname( const char *pcHostName );
-uint32_t FreeRTOS_inet_addr( const char * pcIPAddress );
-
-/*
- * For the web server: borrow the circular Rx buffer for inspection
- * HTML driver wants to see if a sequence of 13/10/13/10 is available
- */
-const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket );
-
-void FreeRTOS_netstat( void );
-
-#if ipconfigSUPPORT_SELECT_FUNCTION == 1
-
- /* For FD_SET and FD_CLR, a combination of the following bits can be used: */
-
- typedef enum eSELECT_EVENT {
- eSELECT_READ = 0x0001,
- eSELECT_WRITE = 0x0002,
- eSELECT_EXCEPT = 0x0004,
- eSELECT_INTR = 0x0008,
- eSELECT_ALL = 0x000F,
- /* Reserved for internal use: */
- eSELECT_CALL_IP = 0x0010,
- /* end */
- } eSelectEvent_t;
-
- SocketSet_t FreeRTOS_CreateSocketSet( void );
- void FreeRTOS_DeleteSocketSet( SocketSet_t xSocketSet );
- void FreeRTOS_FD_SET( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xBitsToSet );
- void FreeRTOS_FD_CLR( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xBitsToClear );
- EventBits_t FreeRTOS_FD_ISSET( Socket_t xSocket, SocketSet_t xSocketSet );
- BaseType_t FreeRTOS_select( SocketSet_t xSocketSet, TickType_t xBlockTimeTicks );
-
-#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* FREERTOS_SOCKETS_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_SOCKETS_H
+#define FREERTOS_SOCKETS_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Standard includes. */
+#include <string.h>
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+
+#ifndef FREERTOS_IP_CONFIG_H
+ #error FreeRTOSIPConfig.h has not been included yet
+#endif
+
+/* Event bit definitions are required by the select functions. */
+#include "event_groups.h"
+
+#ifndef INC_FREERTOS_H
+ #error FreeRTOS.h must be included before FreeRTOS_Sockets.h.
+#endif
+
+#ifndef INC_TASK_H
+ #ifndef TASK_H /* For compatibility with older FreeRTOS versions. */
+ #error The FreeRTOS header file task.h must be included before FreeRTOS_Sockets.h.
+ #endif
+#endif
+
+/* Assigned to an Socket_t variable when the socket is not valid, probably
+because it could not be created. */
+#define FREERTOS_INVALID_SOCKET ( ( Socket_t ) ~0U )
+
+/* API function error values. As errno is supported, the FreeRTOS sockets
+functions return error codes rather than just a pass or fail indication. */
+/* HT: Extended the number of error codes, gave them positive values and if possible
+the corresponding found in errno.h
+In case of an error, API's will still return negative numbers, e.g.
+ return -pdFREERTOS_ERRNO_EWOULDBLOCK;
+in case an operation would block */
+
+/* The following defines are obsolete, please use -pdFREERTOS_ERRNO_Exxx */
+
+#define FREERTOS_SOCKET_ERROR ( -1 )
+#define FREERTOS_EWOULDBLOCK ( - pdFREERTOS_ERRNO_EWOULDBLOCK )
+#define FREERTOS_EINVAL ( - pdFREERTOS_ERRNO_EINVAL )
+#define FREERTOS_EADDRNOTAVAIL ( - pdFREERTOS_ERRNO_EADDRNOTAVAIL )
+#define FREERTOS_EADDRINUSE ( - pdFREERTOS_ERRNO_EADDRINUSE )
+#define FREERTOS_ENOBUFS ( - pdFREERTOS_ERRNO_ENOBUFS )
+#define FREERTOS_ENOPROTOOPT ( - pdFREERTOS_ERRNO_ENOPROTOOPT )
+#define FREERTOS_ECLOSED ( - pdFREERTOS_ERRNO_ENOTCONN )
+
+/* Values for the parameters to FreeRTOS_socket(), inline with the Berkeley
+standard. See the documentation of FreeRTOS_socket() for more information. */
+#define FREERTOS_AF_INET ( 2 )
+#define FREERTOS_AF_INET6 ( 10 )
+#define FREERTOS_SOCK_DGRAM ( 2 )
+#define FREERTOS_IPPROTO_UDP ( 17 )
+
+#define FREERTOS_SOCK_STREAM ( 1 )
+#define FREERTOS_IPPROTO_TCP ( 6 )
+/* IP packet of type "Any local network"
+ * can be used in stead of TCP for testing with sockets in raw mode
+ */
+#define FREERTOS_IPPROTO_USR_LAN ( 63 )
+
+/* A bit value that can be passed into the FreeRTOS_sendto() function as part of
+the flags parameter. Setting the FREERTOS_ZERO_COPY in the flags parameter
+indicates that the zero copy interface is being used. See the documentation for
+FreeRTOS_sockets() for more information. */
+#define FREERTOS_ZERO_COPY ( 1 )
+
+/* Values that can be passed in the option name parameter of calls to
+FreeRTOS_setsockopt(). */
+#define FREERTOS_SO_RCVTIMEO ( 0 ) /* Used to set the receive time out. */
+#define FREERTOS_SO_SNDTIMEO ( 1 ) /* Used to set the send time out. */
+#define FREERTOS_SO_UDPCKSUM_OUT ( 2 ) /* Used to turn the use of the UDP checksum by a socket on or off. This also doubles as part of an 8-bit bitwise socket option. */
+#if( ipconfigSOCKET_HAS_USER_SEMAPHORE == 1 )
+ #define FREERTOS_SO_SET_SEMAPHORE ( 3 ) /* Used to set a user's semaphore */
+#endif
+#define FREERTOS_SO_SNDBUF ( 4 ) /* Set the size of the send buffer (TCP only) */
+#define FREERTOS_SO_RCVBUF ( 5 ) /* Set the size of the receive buffer (TCP only) */
+
+#if ipconfigUSE_CALLBACKS == 1
+ #define FREERTOS_SO_TCP_CONN_HANDLER ( 6 ) /* Install a callback for (dis) connection events. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ #define FREERTOS_SO_TCP_RECV_HANDLER ( 7 ) /* Install a callback for receiving TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ #define FREERTOS_SO_TCP_SENT_HANDLER ( 8 ) /* Install a callback for sending TCP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ #define FREERTOS_SO_UDP_RECV_HANDLER ( 9 ) /* Install a callback for receiving UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+ #define FREERTOS_SO_UDP_SENT_HANDLER ( 10 ) /* Install a callback for sending UDP data. Supply pointer to 'F_TCP_UDP_Handler_t' (see below) */
+#endif /* ipconfigUSE_CALLBACKS */
+
+#define FREERTOS_SO_REUSE_LISTEN_SOCKET ( 11 ) /* When a listening socket gets connected, do not create a new one but re-use it */
+#define FREERTOS_SO_CLOSE_AFTER_SEND ( 12 ) /* As soon as the last byte has been transmitted, finalise the connection */
+#define FREERTOS_SO_WIN_PROPERTIES ( 13 ) /* Set all buffer and window properties in one call, parameter is pointer to WinProperties_t */
+#define FREERTOS_SO_SET_FULL_SIZE ( 14 ) /* Refuse to send packets smaller than MSS */
+
+#define FREERTOS_SO_STOP_RX ( 15 ) /* Temporarily hold up reception, used by streaming client */
+
+#if( ipconfigUDP_MAX_RX_PACKETS > 0 )
+ #define FREERTOS_SO_UDP_MAX_RX_PACKETS ( 16 ) /* This option helps to limit the maximum number of packets a UDP socket will buffer */
+#endif
+
+#if( ipconfigSOCKET_HAS_USER_WAKE_CALLBACK == 1 )
+ #define FREERTOS_SO_WAKEUP_CALLBACK ( 17 )
+#endif
+
+#define FREERTOS_SO_SET_LOW_HIGH_WATER ( 18 )
+
+#define FREERTOS_NOT_LAST_IN_FRAGMENTED_PACKET ( 0x80 ) /* For internal use only, but also part of an 8-bit bitwise value. */
+#define FREERTOS_FRAGMENTED_PACKET ( 0x40 ) /* For internal use only, but also part of an 8-bit bitwise value. */
+
+/* Values for flag for FreeRTOS_shutdown(). */
+#define FREERTOS_SHUT_RD ( 0 ) /* Not really at this moment, just for compatibility of the interface */
+#define FREERTOS_SHUT_WR ( 1 )
+#define FREERTOS_SHUT_RDWR ( 2 )
+
+/* Values for flag for FreeRTOS_recv(). */
+#define FREERTOS_MSG_OOB ( 2 ) /* process out-of-band data */
+#define FREERTOS_MSG_PEEK ( 4 ) /* peek at incoming message */
+#define FREERTOS_MSG_DONTROUTE ( 8 ) /* send without using routing tables */
+#define FREERTOS_MSG_DONTWAIT ( 16 ) /* Can be used with recvfrom(), sendto(), recv(), and send(). */
+
+typedef struct xWIN_PROPS {
+ /* Properties of the Tx buffer and Tx window */
+ int32_t lTxBufSize; /* Unit: bytes */
+ int32_t lTxWinSize; /* Unit: MSS */
+
+ /* Properties of the Rx buffer and Rx window */
+ int32_t lRxBufSize; /* Unit: bytes */
+ int32_t lRxWinSize; /* Unit: MSS */
+} WinProperties_t;
+
+typedef struct xLOW_HIGH_WATER {
+ /* Structure to pass for the 'FREERTOS_SO_SET_LOW_HIGH_WATER' option */
+ size_t uxLittleSpace; /* Send a STOP when buffer space drops below X bytes */
+ size_t uxEnoughSpace; /* Send a GO when buffer space grows above X bytes */
+} LowHighWater_t;
+
+/* For compatibility with the expected Berkeley sockets naming. */
+#define socklen_t uint32_t
+
+/* For this limited implementation, only two members are required in the
+Berkeley style sockaddr structure. */
+struct freertos_sockaddr
+{
+ /* _HT_ On 32- and 64-bit architectures, the addition of the two uint8_t
+ fields doesn't make the structure bigger, due to alignment.
+ The fields are inserted as a preparation for IPv6. */
+
+ /* sin_len and sin_family not used in the IPv4-only release. */
+ uint8_t sin_len; /* length of this structure. */
+ uint8_t sin_family; /* FREERTOS_AF_INET. */
+ uint16_t sin_port;
+ uint32_t sin_addr;
+};
+
+#if ipconfigBYTE_ORDER == pdFREERTOS_LITTLE_ENDIAN
+
+ #define FreeRTOS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \
+ ( ( ( ( uint32_t ) ( ucOctet3 ) ) << 24UL ) | \
+ ( ( ( uint32_t ) ( ucOctet2 ) ) << 16UL ) | \
+ ( ( ( uint32_t ) ( ucOctet1 ) ) << 8UL ) | \
+ ( ( uint32_t ) ( ucOctet0 ) ) )
+
+ #define FreeRTOS_inet_ntoa( ulIPAddress, pucBuffer ) \
+ sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u", \
+ ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ), \
+ ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ), \
+ ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ),\
+ ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ) )
+
+#else /* ipconfigBYTE_ORDER */
+
+ #define FreeRTOS_inet_addr_quick( ucOctet0, ucOctet1, ucOctet2, ucOctet3 ) \
+ ( ( ( ( uint32_t ) ( ucOctet0 ) ) << 24UL ) | \
+ ( ( ( uint32_t ) ( ucOctet1 ) ) << 16UL ) | \
+ ( ( ( uint32_t ) ( ucOctet2 ) ) << 8UL ) | \
+ ( ( uint32_t ) ( ucOctet3 ) ) )
+
+ #define FreeRTOS_inet_ntoa( ulIPAddress, pucBuffer ) \
+ sprintf( ( char * ) ( pucBuffer ), "%u.%u.%u.%u", \
+ ( ( unsigned ) ( ( ulIPAddress ) >> 24 ) ), \
+ ( ( unsigned ) ( ( ( ulIPAddress ) >> 16 ) & 0xffUL ) ),\
+ ( ( unsigned ) ( ( ( ulIPAddress ) >> 8 ) & 0xffUL ) ), \
+ ( ( unsigned ) ( ( ulIPAddress ) & 0xffUL ) ) )
+
+#endif /* ipconfigBYTE_ORDER */
+
+/* The socket type itself. */
+struct xSOCKET;
+typedef struct xSOCKET *Socket_t;
+
+/* The SocketSet_t type is the equivalent to the fd_set type used by the
+Berkeley API. */
+struct xSOCKET_SET;
+typedef struct xSOCKET_SET *SocketSet_t;
+
+/**
+ * FULL, UP-TO-DATE AND MAINTAINED REFERENCE DOCUMENTATION FOR ALL THESE
+ * FUNCTIONS IS AVAILABLE ON THE FOLLOWING URL:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_API_Functions.html
+ */
+Socket_t FreeRTOS_socket( BaseType_t xDomain, BaseType_t xType, BaseType_t xProtocol );
+int32_t FreeRTOS_recvfrom( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags, struct freertos_sockaddr *pxSourceAddress, socklen_t *pxSourceAddressLength );
+int32_t FreeRTOS_sendto( Socket_t xSocket, const void *pvBuffer, size_t xTotalDataLength, BaseType_t xFlags, const struct freertos_sockaddr *pxDestinationAddress, socklen_t xDestinationAddressLength );
+BaseType_t FreeRTOS_bind( Socket_t xSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength );
+
+/* function to get the local address and IP port */
+size_t FreeRTOS_GetLocalAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress );
+
+/* Made available when ipconfigETHERNET_DRIVER_FILTERS_PACKETS is set to 1. */
+BaseType_t xPortHasUDPSocket( uint16_t usPortNr );
+
+#if ipconfigUSE_TCP == 1
+
+BaseType_t FreeRTOS_connect( Socket_t xClientSocket, struct freertos_sockaddr *pxAddress, socklen_t xAddressLength );
+BaseType_t FreeRTOS_listen( Socket_t xSocket, BaseType_t xBacklog );
+BaseType_t FreeRTOS_recv( Socket_t xSocket, void *pvBuffer, size_t xBufferLength, BaseType_t xFlags );
+BaseType_t FreeRTOS_send( Socket_t xSocket, const void *pvBuffer, size_t uxDataLength, BaseType_t xFlags );
+Socket_t FreeRTOS_accept( Socket_t xServerSocket, struct freertos_sockaddr *pxAddress, socklen_t *pxAddressLength );
+BaseType_t FreeRTOS_shutdown (Socket_t xSocket, BaseType_t xHow);
+
+#if( ipconfigSUPPORT_SIGNALS != 0 )
+ /* Send a signal to the task which is waiting for a given socket. */
+ BaseType_t FreeRTOS_SignalSocket( Socket_t xSocket );
+
+ /* Send a signal to the task which reads from this socket (FromISR
+ version). */
+ BaseType_t FreeRTOS_SignalSocketFromISR( Socket_t xSocket, BaseType_t *pxHigherPriorityTaskWoken );
+#endif /* ipconfigSUPPORT_SIGNALS */
+
+/* Return the remote address and IP port. */
+BaseType_t FreeRTOS_GetRemoteAddress( Socket_t xSocket, struct freertos_sockaddr *pxAddress );
+
+/* returns pdTRUE if TCP socket is connected */
+BaseType_t FreeRTOS_issocketconnected( Socket_t xSocket );
+
+/* returns the actual size of MSS being used */
+BaseType_t FreeRTOS_mss( Socket_t xSocket );
+
+/* for internal use only: return the connection status */
+BaseType_t FreeRTOS_connstatus( Socket_t xSocket );
+
+/* Returns the number of bytes that may be added to txStream */
+BaseType_t FreeRTOS_maywrite( Socket_t xSocket );
+
+/*
+ * Two helper functions, mostly for testing
+ * rx_size returns the number of bytes available in the Rx buffer
+ * tx_space returns the free space in the Tx buffer
+ */
+BaseType_t FreeRTOS_rx_size( Socket_t xSocket );
+BaseType_t FreeRTOS_tx_space( Socket_t xSocket );
+BaseType_t FreeRTOS_tx_size( Socket_t xSocket );
+
+/* Returns the number of outstanding bytes in txStream. */
+/* The function FreeRTOS_outstanding() was already implemented
+FreeRTOS_tx_size(). */
+#define FreeRTOS_outstanding( xSocket ) FreeRTOS_tx_size( xSocket )
+
+/* Returns the number of bytes in the socket's rxStream. */
+/* The function FreeRTOS_recvcount() was already implemented
+FreeRTOS_rx_size(). */
+#define FreeRTOS_recvcount( xSocket ) FreeRTOS_rx_size( xSocket )
+
+/*
+ * For advanced applications only:
+ * Get a direct pointer to the circular transmit buffer.
+ * '*pxLength' will contain the number of bytes that may be written.
+ */
+uint8_t *FreeRTOS_get_tx_head( Socket_t xSocket, BaseType_t *pxLength );
+
+#endif /* ipconfigUSE_TCP */
+
+/*
+ * Connect / disconnect handler for a TCP socket
+ * For example:
+ * static void vMyConnectHandler (Socket_t xSocket, BaseType_t ulConnected)
+ * {
+ * }
+ * F_TCP_UDP_Handler_t xHnd = { vMyConnectHandler };
+ * FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_CONN_HANDLER, ( void * ) &xHnd, sizeof( xHnd ) );
+ */
+
+typedef void (* FOnConnected_t )( Socket_t /* xSocket */, BaseType_t /* ulConnected */ );
+
+/*
+ * Reception handler for a TCP socket
+ * A user-proved function will be called on reception of a message
+ * If the handler returns a positive number, the messages will not be stored
+ * For example:
+ * static BaseType_t xOnTCPReceive( Socket_t xSocket, void * pData, size_t xLength )
+ * {
+ * // handle the message
+ * return 1;
+ * }
+ * F_TCP_UDP_Handler_t xHand = { xOnTCPReceive };
+ * FreeRTOS_setsockopt( sock, 0, FREERTOS_SO_TCP_RECV_HANDLER, ( void * ) &xHand, sizeof( xHand ) );
+ */
+typedef BaseType_t (* FOnTCPReceive_t )( Socket_t /* xSocket */, void * /* pData */, size_t /* xLength */ );
+typedef void (* FOnTCPSent_t )( Socket_t /* xSocket */, size_t /* xLength */ );
+
+/*
+ * Reception handler for a UDP socket
+ * A user-proved function will be called on reception of a message
+ * If the handler returns a positive number, the messages will not be stored
+ */
+typedef BaseType_t (* FOnUDPReceive_t ) (Socket_t /* xSocket */, void * /* pData */, size_t /* xLength */,
+ const struct freertos_sockaddr * /* pxFrom */, const struct freertos_sockaddr * /* pxDest */ );
+typedef void (* FOnUDPSent_t )( Socket_t /* xSocket */, size_t /* xLength */ );
+
+
+typedef union xTCP_UDP_HANDLER
+{
+ FOnConnected_t pxOnTCPConnected; /* FREERTOS_SO_TCP_CONN_HANDLER */
+ FOnTCPReceive_t pxOnTCPReceive; /* FREERTOS_SO_TCP_RECV_HANDLER */
+ FOnTCPSent_t pxOnTCPSent; /* FREERTOS_SO_TCP_SENT_HANDLER */
+ FOnUDPReceive_t pxOnUDPReceive; /* FREERTOS_SO_UDP_RECV_HANDLER */
+ FOnUDPSent_t pxOnUDPSent; /* FREERTOS_SO_UDP_SENT_HANDLER */
+} F_TCP_UDP_Handler_t;
+
+BaseType_t FreeRTOS_setsockopt( Socket_t xSocket, int32_t lLevel, int32_t lOptionName, const void *pvOptionValue, size_t xOptionLength );
+BaseType_t FreeRTOS_closesocket( Socket_t xSocket );
+uint32_t FreeRTOS_gethostbyname( const char *pcHostName );
+uint32_t FreeRTOS_inet_addr( const char * pcIPAddress );
+
+/*
+ * For the web server: borrow the circular Rx buffer for inspection
+ * HTML driver wants to see if a sequence of 13/10/13/10 is available
+ */
+const struct xSTREAM_BUFFER *FreeRTOS_get_rx_buf( Socket_t xSocket );
+
+void FreeRTOS_netstat( void );
+
+#if ipconfigSUPPORT_SELECT_FUNCTION == 1
+
+ /* For FD_SET and FD_CLR, a combination of the following bits can be used: */
+
+ typedef enum eSELECT_EVENT {
+ eSELECT_READ = 0x0001,
+ eSELECT_WRITE = 0x0002,
+ eSELECT_EXCEPT = 0x0004,
+ eSELECT_INTR = 0x0008,
+ eSELECT_ALL = 0x000F,
+ /* Reserved for internal use: */
+ eSELECT_CALL_IP = 0x0010,
+ /* end */
+ } eSelectEvent_t;
+
+ SocketSet_t FreeRTOS_CreateSocketSet( void );
+ void FreeRTOS_DeleteSocketSet( SocketSet_t xSocketSet );
+ void FreeRTOS_FD_SET( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xBitsToSet );
+ void FreeRTOS_FD_CLR( Socket_t xSocket, SocketSet_t xSocketSet, EventBits_t xBitsToClear );
+ EventBits_t FreeRTOS_FD_ISSET( Socket_t xSocket, SocketSet_t xSocketSet );
+ BaseType_t FreeRTOS_select( SocketSet_t xSocketSet, TickType_t xBlockTimeTicks );
+
+#endif /* ipconfigSUPPORT_SELECT_FUNCTION */
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* FREERTOS_SOCKETS_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
index 95bbbdf0a..9698227c6 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_Stream_Buffer.h
@@ -1,231 +1,231 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/*
- * FreeRTOS_Stream_Buffer.h
- *
- * A cicular character buffer
- * An implementation of a circular buffer without a length field
- * If LENGTH defines the size of the buffer, a maximum of (LENGT-1) bytes can be stored
- * In order to add or read data from the buffer, memcpy() will be called at most 2 times
- */
-
-#ifndef FREERTOS_STREAM_BUFFER_H
-#define FREERTOS_STREAM_BUFFER_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-typedef struct xSTREAM_BUFFER {
- volatile size_t uxTail; /* next item to read */
- volatile size_t uxMid; /* iterator within the valid items */
- volatile size_t uxHead; /* next position store a new item */
- volatile size_t uxFront; /* iterator within the free space */
- size_t LENGTH; /* const value: number of reserved elements */
- uint8_t ucArray[ sizeof( size_t ) ];
-} StreamBuffer_t;
-
-static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer );
-static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer )
-{
- /* Make the circular buffer empty */
- pxBuffer->uxHead = 0u;
- pxBuffer->uxTail = 0u;
- pxBuffer->uxFront = 0u;
- pxBuffer->uxMid = 0u;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );
-static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )
-{
-/* Returns the space between uxLower and uxUpper, which equals to the distance minus 1 */
-size_t uxCount;
-
- uxCount = pxBuffer->LENGTH + uxUpper - uxLower - 1u;
- if( uxCount >= pxBuffer->LENGTH )
- {
- uxCount -= pxBuffer->LENGTH;
- }
-
- return uxCount;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );
-static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )
-{
-/* Returns the distance between uxLower and uxUpper */
-size_t uxCount;
-
- uxCount = pxBuffer->LENGTH + uxUpper - uxLower;
- if ( uxCount >= pxBuffer->LENGTH )
- {
- uxCount -= pxBuffer->LENGTH;
- }
-
- return uxCount;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer );
-static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer )
-{
-/* Returns the number of items which can still be added to uxHead
-before hitting on uxTail */
-size_t uxHead = pxBuffer->uxHead;
-size_t uxTail = pxBuffer->uxTail;
-
- return uxStreamBufferSpace( pxBuffer, uxHead, uxTail );
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer );
-static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer )
-{
-/* Distance between uxFront and uxTail
-or the number of items which can still be added to uxFront,
-before hitting on uxTail */
-
-size_t uxFront = pxBuffer->uxFront;
-size_t uxTail = pxBuffer->uxTail;
-
- return uxStreamBufferSpace( pxBuffer, uxFront, uxTail );
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer );
-static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer )
-{
-/* Returns the number of items which can be read from uxTail
-before reaching uxHead */
-size_t uxHead = pxBuffer->uxHead;
-size_t uxTail = pxBuffer->uxTail;
-
- return uxStreamBufferDistance( pxBuffer, uxTail, uxHead );
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer );
-static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer )
-{
-/* Returns the distance between uxHead and uxMid */
-size_t uxHead = pxBuffer->uxHead;
-size_t uxMid = pxBuffer->uxMid;
-
- return uxStreamBufferDistance( pxBuffer, uxMid, uxHead );
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount );
-static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount )
-{
-/* Increment uxMid, but no further than uxHead */
-size_t uxSize = uxStreamBufferMidSpace( pxBuffer );
-
- if( uxCount > uxSize )
- {
- uxCount = uxSize;
- }
- pxBuffer->uxMid += uxCount;
- if( pxBuffer->uxMid >= pxBuffer->LENGTH )
- {
- pxBuffer->uxMid -= pxBuffer->LENGTH;
- }
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );
-static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )
-{
-BaseType_t xReturn;
-size_t uxTail = pxBuffer->uxTail;
-
- /* Returns true if ( uxLeft < uxRight ) */
- if( ( uxLeft < uxTail ) ^ ( uxRight < uxTail ) )
- {
- if( uxRight < uxTail )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
- }
- else
- {
- if( uxLeft <= uxRight )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
- }
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData );
-static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData )
-{
-size_t uxNextTail = pxBuffer->uxTail;
-size_t uxSize = uxStreamBufferGetSize( pxBuffer );
-
- *ppucData = pxBuffer->ucArray + uxNextTail;
-
- return FreeRTOS_min_uint32( uxSize, pxBuffer->LENGTH - uxNextTail );
-}
-
-/*
- * Add bytes to a stream buffer.
- *
- * pxBuffer - The buffer to which the bytes will be added.
- * uxOffset - If uxOffset > 0, data will be written at an offset from uxHead
- * while uxHead will not be moved yet.
- * pucData - A pointer to the data to be added.
- * uxCount - The number of bytes to add.
- */
-size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount );
-
-/*
- * Read bytes from a stream buffer.
- *
- * pxBuffer - The buffer from which the bytes will be read.
- * uxOffset - Can be used to read data located at a certain offset from 'uxTail'.
- * pucData - A pointer to the buffer into which data will be read.
- * uxMaxCount - The number of bytes to read.
- * xPeek - If set to pdTRUE the data will remain in the buffer.
- */
-size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek );
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* !defined( FREERTOS_STREAM_BUFFER_H ) */
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
+ * FreeRTOS_Stream_Buffer.h
+ *
+ * A cicular character buffer
+ * An implementation of a circular buffer without a length field
+ * If LENGTH defines the size of the buffer, a maximum of (LENGT-1) bytes can be stored
+ * In order to add or read data from the buffer, memcpy() will be called at most 2 times
+ */
+
+#ifndef FREERTOS_STREAM_BUFFER_H
+#define FREERTOS_STREAM_BUFFER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct xSTREAM_BUFFER {
+ volatile size_t uxTail; /* next item to read */
+ volatile size_t uxMid; /* iterator within the valid items */
+ volatile size_t uxHead; /* next position store a new item */
+ volatile size_t uxFront; /* iterator within the free space */
+ size_t LENGTH; /* const value: number of reserved elements */
+ uint8_t ucArray[ sizeof( size_t ) ];
+} StreamBuffer_t;
+
+static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer );
+static portINLINE void vStreamBufferClear( StreamBuffer_t *pxBuffer )
+{
+ /* Make the circular buffer empty */
+ pxBuffer->uxHead = 0u;
+ pxBuffer->uxTail = 0u;
+ pxBuffer->uxFront = 0u;
+ pxBuffer->uxMid = 0u;
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );
+static portINLINE size_t uxStreamBufferSpace( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )
+{
+/* Returns the space between uxLower and uxUpper, which equals to the distance minus 1 */
+size_t uxCount;
+
+ uxCount = pxBuffer->LENGTH + uxUpper - uxLower - 1u;
+ if( uxCount >= pxBuffer->LENGTH )
+ {
+ uxCount -= pxBuffer->LENGTH;
+ }
+
+ return uxCount;
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper );
+static portINLINE size_t uxStreamBufferDistance( const StreamBuffer_t *pxBuffer, const size_t uxLower, const size_t uxUpper )
+{
+/* Returns the distance between uxLower and uxUpper */
+size_t uxCount;
+
+ uxCount = pxBuffer->LENGTH + uxUpper - uxLower;
+ if ( uxCount >= pxBuffer->LENGTH )
+ {
+ uxCount -= pxBuffer->LENGTH;
+ }
+
+ return uxCount;
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer );
+static portINLINE size_t uxStreamBufferGetSpace( const StreamBuffer_t *pxBuffer )
+{
+/* Returns the number of items which can still be added to uxHead
+before hitting on uxTail */
+size_t uxHead = pxBuffer->uxHead;
+size_t uxTail = pxBuffer->uxTail;
+
+ return uxStreamBufferSpace( pxBuffer, uxHead, uxTail );
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer );
+static portINLINE size_t uxStreamBufferFrontSpace( const StreamBuffer_t *pxBuffer )
+{
+/* Distance between uxFront and uxTail
+or the number of items which can still be added to uxFront,
+before hitting on uxTail */
+
+size_t uxFront = pxBuffer->uxFront;
+size_t uxTail = pxBuffer->uxTail;
+
+ return uxStreamBufferSpace( pxBuffer, uxFront, uxTail );
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer );
+static portINLINE size_t uxStreamBufferGetSize( const StreamBuffer_t *pxBuffer )
+{
+/* Returns the number of items which can be read from uxTail
+before reaching uxHead */
+size_t uxHead = pxBuffer->uxHead;
+size_t uxTail = pxBuffer->uxTail;
+
+ return uxStreamBufferDistance( pxBuffer, uxTail, uxHead );
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer );
+static portINLINE size_t uxStreamBufferMidSpace( const StreamBuffer_t *pxBuffer )
+{
+/* Returns the distance between uxHead and uxMid */
+size_t uxHead = pxBuffer->uxHead;
+size_t uxMid = pxBuffer->uxMid;
+
+ return uxStreamBufferDistance( pxBuffer, uxMid, uxHead );
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount );
+static portINLINE void vStreamBufferMoveMid( StreamBuffer_t *pxBuffer, size_t uxCount )
+{
+/* Increment uxMid, but no further than uxHead */
+size_t uxSize = uxStreamBufferMidSpace( pxBuffer );
+
+ if( uxCount > uxSize )
+ {
+ uxCount = uxSize;
+ }
+ pxBuffer->uxMid += uxCount;
+ if( pxBuffer->uxMid >= pxBuffer->LENGTH )
+ {
+ pxBuffer->uxMid -= pxBuffer->LENGTH;
+ }
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight );
+static portINLINE BaseType_t xStreamBufferLessThenEqual( const StreamBuffer_t *pxBuffer, const size_t uxLeft, const size_t uxRight )
+{
+BaseType_t xReturn;
+size_t uxTail = pxBuffer->uxTail;
+
+ /* Returns true if ( uxLeft < uxRight ) */
+ if( ( uxLeft < uxTail ) ^ ( uxRight < uxTail ) )
+ {
+ if( uxRight < uxTail )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ else
+ {
+ if( uxLeft <= uxRight )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+ }
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData );
+static portINLINE size_t uxStreamBufferGetPtr( StreamBuffer_t *pxBuffer, uint8_t **ppucData )
+{
+size_t uxNextTail = pxBuffer->uxTail;
+size_t uxSize = uxStreamBufferGetSize( pxBuffer );
+
+ *ppucData = pxBuffer->ucArray + uxNextTail;
+
+ return FreeRTOS_min_uint32( uxSize, pxBuffer->LENGTH - uxNextTail );
+}
+
+/*
+ * Add bytes to a stream buffer.
+ *
+ * pxBuffer - The buffer to which the bytes will be added.
+ * uxOffset - If uxOffset > 0, data will be written at an offset from uxHead
+ * while uxHead will not be moved yet.
+ * pucData - A pointer to the data to be added.
+ * uxCount - The number of bytes to add.
+ */
+size_t uxStreamBufferAdd( StreamBuffer_t *pxBuffer, size_t uxOffset, const uint8_t *pucData, size_t uxCount );
+
+/*
+ * Read bytes from a stream buffer.
+ *
+ * pxBuffer - The buffer from which the bytes will be read.
+ * uxOffset - Can be used to read data located at a certain offset from 'uxTail'.
+ * pucData - A pointer to the buffer into which data will be read.
+ * uxMaxCount - The number of bytes to read.
+ * xPeek - If set to pdTRUE the data will remain in the buffer.
+ */
+size_t uxStreamBufferGet( StreamBuffer_t *pxBuffer, size_t uxOffset, uint8_t *pucData, size_t uxMaxCount, BaseType_t xPeek );
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* !defined( FREERTOS_STREAM_BUFFER_H ) */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h
index 76738c460..e26edf653 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_IP.h
@@ -1,80 +1,80 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_TCP_IP_H
-#define FREERTOS_TCP_IP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
-
-typedef enum eTCP_STATE {
- /* Comments about the TCP states are borrowed from the very useful
- * Wiki page:
- * http://en.wikipedia.org/wiki/Transmission_Control_Protocol */
- eCLOSED = 0u, /* 0 (server + client) no connection state at all. */
- eTCP_LISTEN, /* 1 (server) waiting for a connection request
- from any remote TCP and port. */
- eCONNECT_SYN, /* 2 (client) internal state: socket wants to send
- a connect */
- eSYN_FIRST, /* 3 (server) Just created, must ACK the SYN request. */
- eSYN_RECEIVED, /* 4 (server) waiting for a confirming connection request
- acknowledgement after having both received and sent a connection request. */
- eESTABLISHED, /* 5 (server + client) an open connection, data received can be
- delivered to the user. The normal state for the data transfer phase of the connection. */
- eFIN_WAIT_1, /* 6 (server + client) waiting for a connection termination request from the remote TCP,
- or an acknowledgement of the connection termination request previously sent. */
- eFIN_WAIT_2, /* 7 (server + client) waiting for a connection termination request from the remote TCP. */
- eCLOSE_WAIT, /* 8 (server + client) waiting for a connection termination request from the local user. */
- eCLOSING, /* (server + client) waiting for a connection termination request acknowledgement from the remote TCP. */
- eLAST_ACK, /* 9 (server + client) waiting for an acknowledgement of the connection termination request
- previously sent to the remote TCP
- (which includes an acknowledgement of its connection termination request). */
- eTIME_WAIT, /* 10 (either server or client) waiting for enough time to pass to be sure the remote TCP received the
- acknowledgement of its connection termination request. [According to RFC 793 a connection can
- stay in TIME-WAIT for a maximum of four minutes known as a MSL (maximum segment lifetime).] */
-} eIPTCPState_t;
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* FREERTOS_TCP_IP_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_TCP_IP_H
+#define FREERTOS_TCP_IP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+BaseType_t xProcessReceivedTCPPacket( NetworkBufferDescriptor_t *pxNetworkBuffer );
+
+typedef enum eTCP_STATE {
+ /* Comments about the TCP states are borrowed from the very useful
+ * Wiki page:
+ * http://en.wikipedia.org/wiki/Transmission_Control_Protocol */
+ eCLOSED = 0u, /* 0 (server + client) no connection state at all. */
+ eTCP_LISTEN, /* 1 (server) waiting for a connection request
+ from any remote TCP and port. */
+ eCONNECT_SYN, /* 2 (client) internal state: socket wants to send
+ a connect */
+ eSYN_FIRST, /* 3 (server) Just created, must ACK the SYN request. */
+ eSYN_RECEIVED, /* 4 (server) waiting for a confirming connection request
+ acknowledgement after having both received and sent a connection request. */
+ eESTABLISHED, /* 5 (server + client) an open connection, data received can be
+ delivered to the user. The normal state for the data transfer phase of the connection. */
+ eFIN_WAIT_1, /* 6 (server + client) waiting for a connection termination request from the remote TCP,
+ or an acknowledgement of the connection termination request previously sent. */
+ eFIN_WAIT_2, /* 7 (server + client) waiting for a connection termination request from the remote TCP. */
+ eCLOSE_WAIT, /* 8 (server + client) waiting for a connection termination request from the local user. */
+ eCLOSING, /* (server + client) waiting for a connection termination request acknowledgement from the remote TCP. */
+ eLAST_ACK, /* 9 (server + client) waiting for an acknowledgement of the connection termination request
+ previously sent to the remote TCP
+ (which includes an acknowledgement of its connection termination request). */
+ eTIME_WAIT, /* 10 (either server or client) waiting for enough time to pass to be sure the remote TCP received the
+ acknowledgement of its connection termination request. [According to RFC 793 a connection can
+ stay in TIME-WAIT for a maximum of four minutes known as a MSL (maximum segment lifetime).] */
+} eIPTCPState_t;
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* FREERTOS_TCP_IP_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h
index 9532fd159..1cb7eebc0 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_TCP_WIN.h
@@ -1,213 +1,213 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/*
- * FreeRTOS_TCP_WIN.c
- * Module which handles the TCP windowing schemes for FreeRTOS-PLUS-TCP
- */
-
-#ifndef FREERTOS_TCP_WIN_H
-#define FREERTOS_TCP_WIN_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern BaseType_t xTCPWindowLoggingLevel;
-
-typedef struct xTCPTimer
-{
- uint32_t ulBorn;
-} TCPTimer_t;
-
-typedef struct xTCP_SEGMENT
-{
- uint32_t ulSequenceNumber; /* The sequence number of the first byte in this packet */
- int32_t lMaxLength; /* Maximum space, number of bytes which can be stored in this segment */
- int32_t lDataLength; /* Actual number of bytes */
- int32_t lStreamPos; /* reference to the [t|r]xStream of the socket */
- TCPTimer_t xTransmitTimer; /* saves a timestamp at the moment this segment gets transmitted (TX only) */
- union
- {
- struct
- {
- uint32_t
- ucTransmitCount : 8,/* Number of times the segment has been transmitted, used to calculate the RTT */
- ucDupAckCount : 8, /* Counts the number of times that a higher segment was ACK'd. After 3 times a Fast Retransmission takes place */
- bOutstanding : 1, /* It the peer's turn, we're just waiting for an ACK */
- bAcked : 1, /* This segment has been acknowledged */
- bIsForRx : 1; /* pdTRUE if segment is used for reception */
- } bits;
- uint32_t ulFlags;
- } u;
-#if( ipconfigUSE_TCP_WIN != 0 )
- struct xLIST_ITEM xQueueItem; /* TX only: segments can be linked in one of three queues: xPriorityQueue, xTxQueue, and xWaitQueue */
- struct xLIST_ITEM xListItem; /* With this item the segment can be connected to a list, depending on who is owning it */
-#endif
-} TCPSegment_t;
-
-typedef struct xTCP_WINSIZE
-{
- uint32_t ulRxWindowLength;
- uint32_t ulTxWindowLength;
-} TCPWinSize_t;
-
-/*
- * If TCP time-stamps are being used, they will occupy 12 bytes in
- * each packet, and thus the message space will become smaller
- */
-/* Keep this as a multiple of 4 */
-#if( ipconfigUSE_TCP_WIN == 1 )
- #define ipSIZE_TCP_OPTIONS 16u
-#else
- #define ipSIZE_TCP_OPTIONS 12u
-#endif
-
-/*
- * Every TCP connection owns a TCP window for the administration of all packets
- * It owns two sets of segment descriptors, incoming and outgoing
- */
-typedef struct xTCP_WINDOW
-{
- union
- {
- struct
- {
- uint32_t
- bHasInit : 1, /* The window structure has been initialised */
- bSendFullSize : 1, /* May only send packets with a size equal to MSS (for optimisation) */
- bTimeStamps : 1; /* Socket is supposed to use TCP time-stamps. This depends on the */
- } bits; /* party which opens the connection */
- uint32_t ulFlags;
- } u;
- TCPWinSize_t xSize;
- struct
- {
- uint32_t ulFirstSequenceNumber; /* Logging & debug: the first segment received/sent in this connection
- * for Tx: initial send sequence number (ISS)
- * for Rx: initial receive sequence number (IRS) */
- uint32_t ulCurrentSequenceNumber;/* Tx/Rx: the oldest sequence number not yet confirmed, also SND.UNA / RCV.NXT
- * In other words: the sequence number of the left side of the sliding window */
- uint32_t ulFINSequenceNumber; /* The sequence number which carried the FIN flag */
- uint32_t ulHighestSequenceNumber;/* Sequence number of the right-most byte + 1 */
- } rx, tx;
- uint32_t ulOurSequenceNumber; /* The SEQ number we're sending out */
- uint32_t ulUserDataLength; /* Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
- uint32_t ulNextTxSequenceNumber; /* The sequence number given to the next byte to be added for transmission */
- int32_t lSRTT; /* Smoothed Round Trip Time, it may increment quickly and it decrements slower */
- uint8_t ucOptionLength; /* Number of valid bytes in ulOptionsData[] */
-#if( ipconfigUSE_TCP_WIN == 1 )
- List_t xPriorityQueue; /* Priority queue: segments which must be sent immediately */
- List_t xTxQueue; /* Transmit queue: segments queued for transmission */
- List_t xWaitQueue; /* Waiting queue: outstanding segments */
- TCPSegment_t *pxHeadSegment; /* points to a segment which has not been transmitted and it's size is still growing (user data being added) */
- uint32_t ulOptionsData[ipSIZE_TCP_OPTIONS/sizeof(uint32_t)]; /* Contains the options we send out */
- List_t xTxSegments; /* A linked list of all transmission segments, sorted on sequence number */
- List_t xRxSegments; /* A linked list of reception segments, order depends on sequence of arrival */
-#else
- /* For tiny TCP, there is only 1 outstanding TX segment */
- TCPSegment_t xTxSegment; /* Priority queue */
-#endif
- uint16_t usOurPortNumber; /* Mostly for debugging/logging: our TCP port number */
- uint16_t usPeerPortNumber; /* debugging/logging: the peer's TCP port number */
- uint16_t usMSS; /* Current accepted MSS */
- uint16_t usMSSInit; /* MSS as configured by the socket owner */
-} TCPWindow_t;
-
-
-/*=============================================================================
- *
- * Creation and destruction
- *
- *=============================================================================*/
-
-/* Create and initialize a window */
-void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
- uint32_t ulTxWindowLength, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
-
-/* Destroy a window (always returns NULL)
- * It will free some resources: a collection of segments */
-void vTCPWindowDestroy( TCPWindow_t *pxWindow );
-
-/* Initialize a window */
-void vTCPWindowInit( TCPWindow_t *pxWindow, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
-
-/* Clean up allocated segments. Should only be called when FreeRTOS+TCP will no longer be used. */
-void vTCPSegmentCleanup( void );
-
-/*=============================================================================
- *
- * Rx functions
- *
- *=============================================================================*/
-
-/* if true may be passed directly to user (segment expected and window is empty)
- * But pxWindow->ackno should always be used to set "BUF->ackno" */
-int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace );
-
-/* When lTCPWindowRxCheck returned false, please call store for this unexpected data */
-BaseType_t xTCPWindowRxStore( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength );
-
-/* This function will be called as soon as a FIN is received. It will return true
- * if there are no 'open' reception segments */
-BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow );
-
-/* _HT_ Temporary function for testing/debugging
- * Not used at this moment */
-void vTCPWinShowSegments( TCPWindow_t *pxWindow, BaseType_t bForRx );
-
-/*=============================================================================
- *
- * Tx functions
- *
- *=============================================================================*/
-
-/* Adds data to the Tx-window */
-int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax );
-
-/* Check data to be sent and calculate the time period we may sleep */
-BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay );
-
-/* See if anything is left to be sent
- * Function will be called when a FIN has been received. Only when the TX window is clean,
- * it will return pdTRUE */
-BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow );
-
-/* Fetches data to be sent.
- * apPos will point to a location with the circular data buffer: txStream */
-uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition );
-
-/* Receive a normal ACK */
-uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber );
-
-/* Receive a SACK option */
-uint32_t ulTCPWindowTxSack( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast );
-
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* FREERTOS_TCP_WIN_H */
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/*
+ * FreeRTOS_TCP_WIN.c
+ * Module which handles the TCP windowing schemes for FreeRTOS-PLUS-TCP
+ */
+
+#ifndef FREERTOS_TCP_WIN_H
+#define FREERTOS_TCP_WIN_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern BaseType_t xTCPWindowLoggingLevel;
+
+typedef struct xTCPTimer
+{
+ uint32_t ulBorn;
+} TCPTimer_t;
+
+typedef struct xTCP_SEGMENT
+{
+ uint32_t ulSequenceNumber; /* The sequence number of the first byte in this packet */
+ int32_t lMaxLength; /* Maximum space, number of bytes which can be stored in this segment */
+ int32_t lDataLength; /* Actual number of bytes */
+ int32_t lStreamPos; /* reference to the [t|r]xStream of the socket */
+ TCPTimer_t xTransmitTimer; /* saves a timestamp at the moment this segment gets transmitted (TX only) */
+ union
+ {
+ struct
+ {
+ uint32_t
+ ucTransmitCount : 8,/* Number of times the segment has been transmitted, used to calculate the RTT */
+ ucDupAckCount : 8, /* Counts the number of times that a higher segment was ACK'd. After 3 times a Fast Retransmission takes place */
+ bOutstanding : 1, /* It the peer's turn, we're just waiting for an ACK */
+ bAcked : 1, /* This segment has been acknowledged */
+ bIsForRx : 1; /* pdTRUE if segment is used for reception */
+ } bits;
+ uint32_t ulFlags;
+ } u;
+#if( ipconfigUSE_TCP_WIN != 0 )
+ struct xLIST_ITEM xQueueItem; /* TX only: segments can be linked in one of three queues: xPriorityQueue, xTxQueue, and xWaitQueue */
+ struct xLIST_ITEM xListItem; /* With this item the segment can be connected to a list, depending on who is owning it */
+#endif
+} TCPSegment_t;
+
+typedef struct xTCP_WINSIZE
+{
+ uint32_t ulRxWindowLength;
+ uint32_t ulTxWindowLength;
+} TCPWinSize_t;
+
+/*
+ * If TCP time-stamps are being used, they will occupy 12 bytes in
+ * each packet, and thus the message space will become smaller
+ */
+/* Keep this as a multiple of 4 */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ #define ipSIZE_TCP_OPTIONS 16u
+#else
+ #define ipSIZE_TCP_OPTIONS 12u
+#endif
+
+/*
+ * Every TCP connection owns a TCP window for the administration of all packets
+ * It owns two sets of segment descriptors, incoming and outgoing
+ */
+typedef struct xTCP_WINDOW
+{
+ union
+ {
+ struct
+ {
+ uint32_t
+ bHasInit : 1, /* The window structure has been initialised */
+ bSendFullSize : 1, /* May only send packets with a size equal to MSS (for optimisation) */
+ bTimeStamps : 1; /* Socket is supposed to use TCP time-stamps. This depends on the */
+ } bits; /* party which opens the connection */
+ uint32_t ulFlags;
+ } u;
+ TCPWinSize_t xSize;
+ struct
+ {
+ uint32_t ulFirstSequenceNumber; /* Logging & debug: the first segment received/sent in this connection
+ * for Tx: initial send sequence number (ISS)
+ * for Rx: initial receive sequence number (IRS) */
+ uint32_t ulCurrentSequenceNumber;/* Tx/Rx: the oldest sequence number not yet confirmed, also SND.UNA / RCV.NXT
+ * In other words: the sequence number of the left side of the sliding window */
+ uint32_t ulFINSequenceNumber; /* The sequence number which carried the FIN flag */
+ uint32_t ulHighestSequenceNumber;/* Sequence number of the right-most byte + 1 */
+ } rx, tx;
+ uint32_t ulOurSequenceNumber; /* The SEQ number we're sending out */
+ uint32_t ulUserDataLength; /* Number of bytes in Rx buffer which may be passed to the user, after having received a 'missing packet' */
+ uint32_t ulNextTxSequenceNumber; /* The sequence number given to the next byte to be added for transmission */
+ int32_t lSRTT; /* Smoothed Round Trip Time, it may increment quickly and it decrements slower */
+ uint8_t ucOptionLength; /* Number of valid bytes in ulOptionsData[] */
+#if( ipconfigUSE_TCP_WIN == 1 )
+ List_t xPriorityQueue; /* Priority queue: segments which must be sent immediately */
+ List_t xTxQueue; /* Transmit queue: segments queued for transmission */
+ List_t xWaitQueue; /* Waiting queue: outstanding segments */
+ TCPSegment_t *pxHeadSegment; /* points to a segment which has not been transmitted and it's size is still growing (user data being added) */
+ uint32_t ulOptionsData[ipSIZE_TCP_OPTIONS/sizeof(uint32_t)]; /* Contains the options we send out */
+ List_t xTxSegments; /* A linked list of all transmission segments, sorted on sequence number */
+ List_t xRxSegments; /* A linked list of reception segments, order depends on sequence of arrival */
+#else
+ /* For tiny TCP, there is only 1 outstanding TX segment */
+ TCPSegment_t xTxSegment; /* Priority queue */
+#endif
+ uint16_t usOurPortNumber; /* Mostly for debugging/logging: our TCP port number */
+ uint16_t usPeerPortNumber; /* debugging/logging: the peer's TCP port number */
+ uint16_t usMSS; /* Current accepted MSS */
+ uint16_t usMSSInit; /* MSS as configured by the socket owner */
+} TCPWindow_t;
+
+
+/*=============================================================================
+ *
+ * Creation and destruction
+ *
+ *=============================================================================*/
+
+/* Create and initialize a window */
+void vTCPWindowCreate( TCPWindow_t *pxWindow, uint32_t ulRxWindowLength,
+ uint32_t ulTxWindowLength, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
+
+/* Destroy a window (always returns NULL)
+ * It will free some resources: a collection of segments */
+void vTCPWindowDestroy( TCPWindow_t *pxWindow );
+
+/* Initialize a window */
+void vTCPWindowInit( TCPWindow_t *pxWindow, uint32_t ulAckNumber, uint32_t ulSequenceNumber, uint32_t ulMSS );
+
+/* Clean up allocated segments. Should only be called when FreeRTOS+TCP will no longer be used. */
+void vTCPSegmentCleanup( void );
+
+/*=============================================================================
+ *
+ * Rx functions
+ *
+ *=============================================================================*/
+
+/* if true may be passed directly to user (segment expected and window is empty)
+ * But pxWindow->ackno should always be used to set "BUF->ackno" */
+int32_t lTCPWindowRxCheck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength, uint32_t ulSpace );
+
+/* When lTCPWindowRxCheck returned false, please call store for this unexpected data */
+BaseType_t xTCPWindowRxStore( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber, uint32_t ulLength );
+
+/* This function will be called as soon as a FIN is received. It will return true
+ * if there are no 'open' reception segments */
+BaseType_t xTCPWindowRxEmpty( TCPWindow_t *pxWindow );
+
+/* _HT_ Temporary function for testing/debugging
+ * Not used at this moment */
+void vTCPWinShowSegments( TCPWindow_t *pxWindow, BaseType_t bForRx );
+
+/*=============================================================================
+ *
+ * Tx functions
+ *
+ *=============================================================================*/
+
+/* Adds data to the Tx-window */
+int32_t lTCPWindowTxAdd( TCPWindow_t *pxWindow, uint32_t ulLength, int32_t lPosition, int32_t lMax );
+
+/* Check data to be sent and calculate the time period we may sleep */
+BaseType_t xTCPWindowTxHasData( TCPWindow_t *pxWindow, uint32_t ulWindowSize, TickType_t *pulDelay );
+
+/* See if anything is left to be sent
+ * Function will be called when a FIN has been received. Only when the TX window is clean,
+ * it will return pdTRUE */
+BaseType_t xTCPWindowTxDone( TCPWindow_t *pxWindow );
+
+/* Fetches data to be sent.
+ * apPos will point to a location with the circular data buffer: txStream */
+uint32_t ulTCPWindowTxGet( TCPWindow_t *pxWindow, uint32_t ulWindowSize, int32_t *plPosition );
+
+/* Receive a normal ACK */
+uint32_t ulTCPWindowTxAck( TCPWindow_t *pxWindow, uint32_t ulSequenceNumber );
+
+/* Receive a SACK option */
+uint32_t ulTCPWindowTxSack( TCPWindow_t *pxWindow, uint32_t ulFirst, uint32_t ulLast );
+
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* FREERTOS_TCP_WIN_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h
index a7463fcee..cb3dd3556 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_UDP_IP.h
@@ -1,56 +1,56 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_UDP_IP_H
-#define FREERTOS_UDP_IP_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* Application level configuration options. */
-#include "FreeRTOSIPConfig.h"
-#include "FreeRTOSIPConfigDefaults.h"
-#include "IPTraceMacroDefaults.h"
-
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* FREERTOS_UDP_IP_H */
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_UDP_IP_H
+#define FREERTOS_UDP_IP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Application level configuration options. */
+#include "FreeRTOSIPConfig.h"
+#include "FreeRTOSIPConfigDefaults.h"
+#include "IPTraceMacroDefaults.h"
+
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* FREERTOS_UDP_IP_H */
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h
index 534f5261d..0253a200d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/FreeRTOS_errno_TCP.h
@@ -1,90 +1,90 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef FREERTOS_ERRNO_TCP
-#define FREERTOS_ERRNO_TCP
-
-/* The following definitions will be included in the core FreeRTOS code in
-future versions of FreeRTOS - hence the 'pd' (ProjDefs) prefix - at which time
-this file will be removed. */
-
-/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
-itself. */
-
-/* For future compatibility (see comment above), check the definitions have not
-already been made. */
-#ifndef pdFREERTOS_ERRNO_NONE
- #define pdFREERTOS_ERRNO_NONE 0 /* No errors */
- #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
- #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
- #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
- #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
- #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
- #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
- #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
- #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
- #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
- #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
- #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
- #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
- #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
- #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
- #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
- #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
- #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
- #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
- #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
- #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
- #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
- #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
- #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
- #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
- #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
- #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
- #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
- #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
- #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
- #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
- #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
- #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
- #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
- #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
- #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
- #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
- #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
- #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
- #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
-
- /* The following endian values are used by FreeRTOS+ components, not FreeRTOS
- itself. */
- #define pdFREERTOS_LITTLE_ENDIAN 0
- #define pdFREERTOS_BIG_ENDIAN 1
-
-#endif /* pdFREERTOS_ERRNO_NONE */
-
-#endif /* FREERTOS_ERRNO_TCP */
-
-
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef FREERTOS_ERRNO_TCP
+#define FREERTOS_ERRNO_TCP
+
+/* The following definitions will be included in the core FreeRTOS code in
+future versions of FreeRTOS - hence the 'pd' (ProjDefs) prefix - at which time
+this file will be removed. */
+
+/* The following errno values are used by FreeRTOS+ components, not FreeRTOS
+itself. */
+
+/* For future compatibility (see comment above), check the definitions have not
+already been made. */
+#ifndef pdFREERTOS_ERRNO_NONE
+ #define pdFREERTOS_ERRNO_NONE 0 /* No errors */
+ #define pdFREERTOS_ERRNO_ENOENT 2 /* No such file or directory */
+ #define pdFREERTOS_ERRNO_EINTR 4 /* Interrupted system call */
+ #define pdFREERTOS_ERRNO_EIO 5 /* I/O error */
+ #define pdFREERTOS_ERRNO_ENXIO 6 /* No such device or address */
+ #define pdFREERTOS_ERRNO_EBADF 9 /* Bad file number */
+ #define pdFREERTOS_ERRNO_EAGAIN 11 /* No more processes */
+ #define pdFREERTOS_ERRNO_EWOULDBLOCK 11 /* Operation would block */
+ #define pdFREERTOS_ERRNO_ENOMEM 12 /* Not enough memory */
+ #define pdFREERTOS_ERRNO_EACCES 13 /* Permission denied */
+ #define pdFREERTOS_ERRNO_EFAULT 14 /* Bad address */
+ #define pdFREERTOS_ERRNO_EBUSY 16 /* Mount device busy */
+ #define pdFREERTOS_ERRNO_EEXIST 17 /* File exists */
+ #define pdFREERTOS_ERRNO_EXDEV 18 /* Cross-device link */
+ #define pdFREERTOS_ERRNO_ENODEV 19 /* No such device */
+ #define pdFREERTOS_ERRNO_ENOTDIR 20 /* Not a directory */
+ #define pdFREERTOS_ERRNO_EISDIR 21 /* Is a directory */
+ #define pdFREERTOS_ERRNO_EINVAL 22 /* Invalid argument */
+ #define pdFREERTOS_ERRNO_ENOSPC 28 /* No space left on device */
+ #define pdFREERTOS_ERRNO_ESPIPE 29 /* Illegal seek */
+ #define pdFREERTOS_ERRNO_EROFS 30 /* Read only file system */
+ #define pdFREERTOS_ERRNO_EUNATCH 42 /* Protocol driver not attached */
+ #define pdFREERTOS_ERRNO_EBADE 50 /* Invalid exchange */
+ #define pdFREERTOS_ERRNO_EFTYPE 79 /* Inappropriate file type or format */
+ #define pdFREERTOS_ERRNO_ENMFILE 89 /* No more files */
+ #define pdFREERTOS_ERRNO_ENOTEMPTY 90 /* Directory not empty */
+ #define pdFREERTOS_ERRNO_ENAMETOOLONG 91 /* File or path name too long */
+ #define pdFREERTOS_ERRNO_EOPNOTSUPP 95 /* Operation not supported on transport endpoint */
+ #define pdFREERTOS_ERRNO_ENOBUFS 105 /* No buffer space available */
+ #define pdFREERTOS_ERRNO_ENOPROTOOPT 109 /* Protocol not available */
+ #define pdFREERTOS_ERRNO_EADDRINUSE 112 /* Address already in use */
+ #define pdFREERTOS_ERRNO_ETIMEDOUT 116 /* Connection timed out */
+ #define pdFREERTOS_ERRNO_EINPROGRESS 119 /* Connection already in progress */
+ #define pdFREERTOS_ERRNO_EALREADY 120 /* Socket already connected */
+ #define pdFREERTOS_ERRNO_EADDRNOTAVAIL 125 /* Address not available */
+ #define pdFREERTOS_ERRNO_EISCONN 127 /* Socket is already connected */
+ #define pdFREERTOS_ERRNO_ENOTCONN 128 /* Socket is not connected */
+ #define pdFREERTOS_ERRNO_ENOMEDIUM 135 /* No medium inserted */
+ #define pdFREERTOS_ERRNO_EILSEQ 138 /* An invalid UTF-16 sequence was encountered. */
+ #define pdFREERTOS_ERRNO_ECANCELED 140 /* Operation canceled. */
+
+ /* The following endian values are used by FreeRTOS+ components, not FreeRTOS
+ itself. */
+ #define pdFREERTOS_LITTLE_ENDIAN 0
+ #define pdFREERTOS_BIG_ENDIAN 1
+
+#endif /* pdFREERTOS_ERRNO_NONE */
+
+#endif /* FREERTOS_ERRNO_TCP */
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h
index 316e18f56..0af7189dd 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/IPTraceMacroDefaults.h
@@ -1,193 +1,193 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-/* This file provides default (empty) implementations for any IP trace macros
-that are not defined by the user. See
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Trace.html */
-
-#ifndef UDP_TRACE_MACRO_DEFAULTS_H
-#define UDP_TRACE_MACRO_DEFAULTS_H
-
-#ifndef iptraceNETWORK_DOWN
- #define iptraceNETWORK_DOWN()
-#endif
-
-#ifndef iptraceNETWORK_BUFFER_RELEASED
- #define iptraceNETWORK_BUFFER_RELEASED( pxBufferAddress )
-#endif
-
-#ifndef iptraceNETWORK_BUFFER_OBTAINED
- #define iptraceNETWORK_BUFFER_OBTAINED( pxBufferAddress )
-#endif
-
-#ifndef iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR
- #define iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxBufferAddress )
-#endif
-
-#ifndef iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER
- #define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER()
-#endif
-
-#ifndef iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR
- #define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR()
-#endif
-
-#ifndef iptraceCREATING_ARP_REQUEST
- #define iptraceCREATING_ARP_REQUEST( ulIPAddress )
-#endif
-
-#ifndef iptraceARP_TABLE_ENTRY_WILL_EXPIRE
- #define iptraceARP_TABLE_ENTRY_WILL_EXPIRE( ulIPAddress )
-#endif
-
-#ifndef iptraceARP_TABLE_ENTRY_EXPIRED
- #define iptraceARP_TABLE_ENTRY_EXPIRED( ulIPAddress )
-#endif
-
-#ifndef iptraceARP_TABLE_ENTRY_CREATED
- #define iptraceARP_TABLE_ENTRY_CREATED( ulIPAddress, ucMACAddress )
-#endif
-
-#ifndef iptraceSENDING_UDP_PACKET
- #define iptraceSENDING_UDP_PACKET( ulIPAddress )
-#endif
-
-#ifndef iptracePACKET_DROPPED_TO_GENERATE_ARP
- #define iptracePACKET_DROPPED_TO_GENERATE_ARP( ulIPAddress )
-#endif
-
-#ifndef iptraceICMP_PACKET_RECEIVED
- #define iptraceICMP_PACKET_RECEIVED()
-#endif
-
-#ifndef iptraceSENDING_PING_REPLY
- #define iptraceSENDING_PING_REPLY( ulIPAddress )
-#endif
-
-#ifndef traceARP_PACKET_RECEIVED
- #define traceARP_PACKET_RECEIVED()
-#endif
-
-#ifndef iptracePROCESSING_RECEIVED_ARP_REPLY
- #define iptracePROCESSING_RECEIVED_ARP_REPLY( ulIPAddress )
-#endif
-
-#ifndef iptraceSENDING_ARP_REPLY
- #define iptraceSENDING_ARP_REPLY( ulIPAddress )
-#endif
-
-#ifndef iptraceFAILED_TO_CREATE_SOCKET
- #define iptraceFAILED_TO_CREATE_SOCKET()
-#endif
-
-#ifndef iptraceFAILED_TO_CREATE_EVENT_GROUP
- #define iptraceFAILED_TO_CREATE_EVENT_GROUP()
-#endif
-
-#ifndef iptraceRECVFROM_DISCARDING_BYTES
- #define iptraceRECVFROM_DISCARDING_BYTES( xNumberOfBytesDiscarded )
-#endif
-
-#ifndef iptraceETHERNET_RX_EVENT_LOST
- #define iptraceETHERNET_RX_EVENT_LOST()
-#endif
-
-#ifndef iptraceSTACK_TX_EVENT_LOST
- #define iptraceSTACK_TX_EVENT_LOST( xEvent )
-#endif
-
-#ifndef iptraceNETWORK_EVENT_RECEIVED
- #define iptraceNETWORK_EVENT_RECEIVED( eEvent )
-#endif
-
-#ifndef iptraceBIND_FAILED
- #define iptraceBIND_FAILED( xSocket, usPort )
-#endif
-
-#ifndef iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS
- #define iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS( ulIPAddress )
-#endif
-
-#ifndef iptraceSENDING_DHCP_DISCOVER
- #define iptraceSENDING_DHCP_DISCOVER()
-#endif
-
-#ifndef iptraceSENDING_DHCP_REQUEST
- #define iptraceSENDING_DHCP_REQUEST()
-#endif
-
-#ifndef iptraceDHCP_SUCCEDEED
- #define iptraceDHCP_SUCCEDEED( address )
-#endif
-
-#ifndef iptraceNETWORK_INTERFACE_TRANSMIT
- #define iptraceNETWORK_INTERFACE_TRANSMIT()
-#endif
-
-#ifndef iptraceNETWORK_INTERFACE_RECEIVE
- #define iptraceNETWORK_INTERFACE_RECEIVE()
-#endif
-
-#ifndef iptraceSENDING_DNS_REQUEST
- #define iptraceSENDING_DNS_REQUEST()
-#endif
-
-#ifndef iptraceWAITING_FOR_TX_DMA_DESCRIPTOR
- #define iptraceWAITING_FOR_TX_DMA_DESCRIPTOR()
-#endif
-
-#ifndef ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS
- #define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS 0
-#endif
-
-#ifndef iptraceFAILED_TO_NOTIFY_SELECT_GROUP
- #define iptraceFAILED_TO_NOTIFY_SELECT_GROUP( xSocket )
-#endif
-
-#ifndef pvPortMallocSocket
- #define pvPortMallocSocket(xSize) pvPortMalloc( ( xSize ) )
-#endif
-
-#ifndef iptraceRECVFROM_TIMEOUT
- #define iptraceRECVFROM_TIMEOUT()
-#endif
-
-#ifndef iptraceRECVFROM_INTERRUPTED
- #define iptraceRECVFROM_INTERRUPTED()
-#endif
-
-#ifndef iptraceNO_BUFFER_FOR_SENDTO
- #define iptraceNO_BUFFER_FOR_SENDTO()
-#endif
-
-#ifndef iptraceSENDTO_SOCKET_NOT_BOUND
- #define iptraceSENDTO_SOCKET_NOT_BOUND()
-#endif
-
-#ifndef iptraceSENDTO_DATA_TOO_LONG
- #define iptraceSENDTO_DATA_TOO_LONG()
-#endif
-
-#endif /* UDP_TRACE_MACRO_DEFAULTS_H */
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+/* This file provides default (empty) implementations for any IP trace macros
+that are not defined by the user. See
+http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_IP_Trace.html */
+
+#ifndef UDP_TRACE_MACRO_DEFAULTS_H
+#define UDP_TRACE_MACRO_DEFAULTS_H
+
+#ifndef iptraceNETWORK_DOWN
+ #define iptraceNETWORK_DOWN()
+#endif
+
+#ifndef iptraceNETWORK_BUFFER_RELEASED
+ #define iptraceNETWORK_BUFFER_RELEASED( pxBufferAddress )
+#endif
+
+#ifndef iptraceNETWORK_BUFFER_OBTAINED
+ #define iptraceNETWORK_BUFFER_OBTAINED( pxBufferAddress )
+#endif
+
+#ifndef iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR
+ #define iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxBufferAddress )
+#endif
+
+#ifndef iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER
+ #define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER()
+#endif
+
+#ifndef iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR
+ #define iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR()
+#endif
+
+#ifndef iptraceCREATING_ARP_REQUEST
+ #define iptraceCREATING_ARP_REQUEST( ulIPAddress )
+#endif
+
+#ifndef iptraceARP_TABLE_ENTRY_WILL_EXPIRE
+ #define iptraceARP_TABLE_ENTRY_WILL_EXPIRE( ulIPAddress )
+#endif
+
+#ifndef iptraceARP_TABLE_ENTRY_EXPIRED
+ #define iptraceARP_TABLE_ENTRY_EXPIRED( ulIPAddress )
+#endif
+
+#ifndef iptraceARP_TABLE_ENTRY_CREATED
+ #define iptraceARP_TABLE_ENTRY_CREATED( ulIPAddress, ucMACAddress )
+#endif
+
+#ifndef iptraceSENDING_UDP_PACKET
+ #define iptraceSENDING_UDP_PACKET( ulIPAddress )
+#endif
+
+#ifndef iptracePACKET_DROPPED_TO_GENERATE_ARP
+ #define iptracePACKET_DROPPED_TO_GENERATE_ARP( ulIPAddress )
+#endif
+
+#ifndef iptraceICMP_PACKET_RECEIVED
+ #define iptraceICMP_PACKET_RECEIVED()
+#endif
+
+#ifndef iptraceSENDING_PING_REPLY
+ #define iptraceSENDING_PING_REPLY( ulIPAddress )
+#endif
+
+#ifndef traceARP_PACKET_RECEIVED
+ #define traceARP_PACKET_RECEIVED()
+#endif
+
+#ifndef iptracePROCESSING_RECEIVED_ARP_REPLY
+ #define iptracePROCESSING_RECEIVED_ARP_REPLY( ulIPAddress )
+#endif
+
+#ifndef iptraceSENDING_ARP_REPLY
+ #define iptraceSENDING_ARP_REPLY( ulIPAddress )
+#endif
+
+#ifndef iptraceFAILED_TO_CREATE_SOCKET
+ #define iptraceFAILED_TO_CREATE_SOCKET()
+#endif
+
+#ifndef iptraceFAILED_TO_CREATE_EVENT_GROUP
+ #define iptraceFAILED_TO_CREATE_EVENT_GROUP()
+#endif
+
+#ifndef iptraceRECVFROM_DISCARDING_BYTES
+ #define iptraceRECVFROM_DISCARDING_BYTES( xNumberOfBytesDiscarded )
+#endif
+
+#ifndef iptraceETHERNET_RX_EVENT_LOST
+ #define iptraceETHERNET_RX_EVENT_LOST()
+#endif
+
+#ifndef iptraceSTACK_TX_EVENT_LOST
+ #define iptraceSTACK_TX_EVENT_LOST( xEvent )
+#endif
+
+#ifndef iptraceNETWORK_EVENT_RECEIVED
+ #define iptraceNETWORK_EVENT_RECEIVED( eEvent )
+#endif
+
+#ifndef iptraceBIND_FAILED
+ #define iptraceBIND_FAILED( xSocket, usPort )
+#endif
+
+#ifndef iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS
+ #define iptraceDHCP_REQUESTS_FAILED_USING_DEFAULT_IP_ADDRESS( ulIPAddress )
+#endif
+
+#ifndef iptraceSENDING_DHCP_DISCOVER
+ #define iptraceSENDING_DHCP_DISCOVER()
+#endif
+
+#ifndef iptraceSENDING_DHCP_REQUEST
+ #define iptraceSENDING_DHCP_REQUEST()
+#endif
+
+#ifndef iptraceDHCP_SUCCEDEED
+ #define iptraceDHCP_SUCCEDEED( address )
+#endif
+
+#ifndef iptraceNETWORK_INTERFACE_TRANSMIT
+ #define iptraceNETWORK_INTERFACE_TRANSMIT()
+#endif
+
+#ifndef iptraceNETWORK_INTERFACE_RECEIVE
+ #define iptraceNETWORK_INTERFACE_RECEIVE()
+#endif
+
+#ifndef iptraceSENDING_DNS_REQUEST
+ #define iptraceSENDING_DNS_REQUEST()
+#endif
+
+#ifndef iptraceWAITING_FOR_TX_DMA_DESCRIPTOR
+ #define iptraceWAITING_FOR_TX_DMA_DESCRIPTOR()
+#endif
+
+#ifndef ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS
+ #define ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS 0
+#endif
+
+#ifndef iptraceFAILED_TO_NOTIFY_SELECT_GROUP
+ #define iptraceFAILED_TO_NOTIFY_SELECT_GROUP( xSocket )
+#endif
+
+#ifndef pvPortMallocSocket
+ #define pvPortMallocSocket(xSize) pvPortMalloc( ( xSize ) )
+#endif
+
+#ifndef iptraceRECVFROM_TIMEOUT
+ #define iptraceRECVFROM_TIMEOUT()
+#endif
+
+#ifndef iptraceRECVFROM_INTERRUPTED
+ #define iptraceRECVFROM_INTERRUPTED()
+#endif
+
+#ifndef iptraceNO_BUFFER_FOR_SENDTO
+ #define iptraceNO_BUFFER_FOR_SENDTO()
+#endif
+
+#ifndef iptraceSENDTO_SOCKET_NOT_BOUND
+ #define iptraceSENDTO_SOCKET_NOT_BOUND()
+#endif
+
+#ifndef iptraceSENDTO_DATA_TOO_LONG
+ #define iptraceSENDTO_DATA_TOO_LONG()
+#endif
+
+#endif /* UDP_TRACE_MACRO_DEFAULTS_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h
index 0fcde3439..d57e607ac 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkBufferManagement.h
@@ -1,70 +1,70 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef NETWORK_BUFFER_MANAGEMENT_H
-#define NETWORK_BUFFER_MANAGEMENT_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NOTE PUBLIC API FUNCTIONS. */
-BaseType_t xNetworkBuffersInitialise( void );
-NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks );
-NetworkBufferDescriptor_t *pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes );
-void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer );
-BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer );
-uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes );
-void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer );
-
-/* Get the current number of free network buffers. */
-UBaseType_t uxGetNumberOfFreeNetworkBuffers( void );
-
-/* Get the lowest number of free network buffers. */
-UBaseType_t uxGetMinimumFreeNetworkBuffers( void );
-
-/* Copy a network buffer into a bigger buffer. */
-NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
- size_t uxNewLength);
-
-/* Increase the size of a Network Buffer.
-In case BufferAllocation_2.c is used, the new space must be allocated. */
-NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
- size_t xNewSizeBytes );
-
-#if ipconfigTCP_IP_SANITY
- /*
- * Check if an address is a valid pointer to a network descriptor
- * by looking it up in the array of network descriptors
- */
- UBaseType_t bIsValidNetworkDescriptor (const NetworkBufferDescriptor_t * pxDesc);
- BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr );
-#endif
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* NETWORK_BUFFER_MANAGEMENT_H */
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef NETWORK_BUFFER_MANAGEMENT_H
+#define NETWORK_BUFFER_MANAGEMENT_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* NOTE PUBLIC API FUNCTIONS. */
+BaseType_t xNetworkBuffersInitialise( void );
+NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks );
+NetworkBufferDescriptor_t *pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes );
+void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer );
+BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer );
+uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes );
+void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer );
+
+/* Get the current number of free network buffers. */
+UBaseType_t uxGetNumberOfFreeNetworkBuffers( void );
+
+/* Get the lowest number of free network buffers. */
+UBaseType_t uxGetMinimumFreeNetworkBuffers( void );
+
+/* Copy a network buffer into a bigger buffer. */
+NetworkBufferDescriptor_t *pxDuplicateNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer,
+ size_t uxNewLength);
+
+/* Increase the size of a Network Buffer.
+In case BufferAllocation_2.c is used, the new space must be allocated. */
+NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
+ size_t xNewSizeBytes );
+
+#if ipconfigTCP_IP_SANITY
+ /*
+ * Check if an address is a valid pointer to a network descriptor
+ * by looking it up in the array of network descriptors
+ */
+ UBaseType_t bIsValidNetworkDescriptor (const NetworkBufferDescriptor_t * pxDesc);
+ BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr );
+#endif
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* NETWORK_BUFFER_MANAGEMENT_H */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h
index c3d3fb4bc..8f1fb3219 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/include/NetworkInterface.h
@@ -1,44 +1,44 @@
-/*
- * FreeRTOS+TCP V2.2.0
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://aws.amazon.com/freertos
- * http://www.FreeRTOS.org
- */
-
-#ifndef NETWORK_INTERFACE_H
-#define NETWORK_INTERFACE_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* NOTE PUBLIC API FUNCTIONS. */
-BaseType_t xNetworkInterfaceInitialise( void );
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend );
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] );
-BaseType_t xGetPhyLinkStatus( void );
-
-#ifdef __cplusplus
-} // extern "C"
-#endif
-
-#endif /* NETWORK_INTERFACE_H */
-
+/*
+ * FreeRTOS+TCP V2.2.0
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://aws.amazon.com/freertos
+ * http://www.FreeRTOS.org
+ */
+
+#ifndef NETWORK_INTERFACE_H
+#define NETWORK_INTERFACE_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* NOTE PUBLIC API FUNCTIONS. */
+BaseType_t xNetworkInterfaceInitialise( void );
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend );
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] );
+BaseType_t xGetPhyLinkStatus( void );
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#endif /* NETWORK_INTERFACE_H */
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c
index fa3f4333f..e70eb80eb 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_1.c
@@ -1,411 +1,411 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/******************************************************************************
- *
- * See the following web page for essential buffer allocation scheme usage and
- * configuration details:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
- *
- ******************************************************************************/
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-/* For an Ethernet interrupt to be able to obtain a network buffer there must
-be at least this number of buffers available. */
-#define baINTERRUPT_BUFFER_GET_THRESHOLD ( 3 )
-
-/* A list of free (available) NetworkBufferDescriptor_t structures. */
-static List_t xFreeBuffersList;
-
-/* Some statistics about the use of buffers. */
-static UBaseType_t uxMinimumFreeNetworkBuffers = 0u;
-
-/* Declares the pool of NetworkBufferDescriptor_t structures that are available
-to the system. All the network buffers referenced from xFreeBuffersList exist
-in this array. The array is not accessed directly except during initialisation,
-when the xFreeBuffersList is filled (as all the buffers are free when the system
-is booted). */
-static NetworkBufferDescriptor_t xNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
-
-/* This constant is defined as true to let FreeRTOS_TCP_IP.c know that the
-network buffers have constant size, large enough to hold the biggest Ethernet
-packet. No resizing will be done. */
-const BaseType_t xBufferAllocFixedSize = pdTRUE;
-
-/* The semaphore used to obtain network buffers. */
-static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
-
-#if( ipconfigTCP_IP_SANITY != 0 )
- static char cIsLow = pdFALSE;
- UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
-#else
- static UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
-#endif /* ipconfigTCP_IP_SANITY */
-
-static void prvShowWarnings( void );
-
-/* The user can define their own ipconfigBUFFER_ALLOC_LOCK() and
-ipconfigBUFFER_ALLOC_UNLOCK() macros, especially for use form an ISR. If these
-are not defined then default them to call the normal enter/exit critical
-section macros. */
-#if !defined( ipconfigBUFFER_ALLOC_LOCK )
-
- #define ipconfigBUFFER_ALLOC_INIT( ) do {} while (0)
- #define ipconfigBUFFER_ALLOC_LOCK_FROM_ISR() \
- UBaseType_t uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
- {
-
- #define ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR() \
- portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
- }
-
- #define ipconfigBUFFER_ALLOC_LOCK() taskENTER_CRITICAL()
- #define ipconfigBUFFER_ALLOC_UNLOCK() taskEXIT_CRITICAL()
-
-#endif /* ipconfigBUFFER_ALLOC_LOCK */
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigTCP_IP_SANITY != 0 )
-
- /* HT: SANITY code will be removed as soon as the library is stable
- * and and ready to become public
- * Function below gives information about the use of buffers */
- #define WARN_LOW ( 2 )
- #define WARN_HIGH ( ( 5 * ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) / 10 )
-
-#endif /* ipconfigTCP_IP_SANITY */
-
-/*-----------------------------------------------------------*/
-
-#if( ipconfigTCP_IP_SANITY != 0 )
-
- BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr )
- {
- return ( bIsValidNetworkDescriptor( pxDescr ) != 0 ) &&
- ( listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxDescr->xBufferListItem ) ) != 0 );
- }
- /*-----------------------------------------------------------*/
-
- static void prvShowWarnings( void )
- {
- UBaseType_t uxCount = uxGetNumberOfFreeNetworkBuffers( );
- if( ( ( cIsLow == 0 ) && ( uxCount <= WARN_LOW ) ) || ( ( cIsLow != 0 ) && ( uxCount >= WARN_HIGH ) ) )
- {
- cIsLow = !cIsLow;
- FreeRTOS_debug_printf( ( "*** Warning *** %s %lu buffers left\n", cIsLow ? "only" : "now", uxCount ) );
- }
- }
- /*-----------------------------------------------------------*/
-
- UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
- {
- uint32_t offset = ( uint32_t ) ( ((const char *)pxDesc) - ((const char *)xNetworkBuffers) );
- if( ( offset >= sizeof( xNetworkBuffers ) ) ||
- ( ( offset % sizeof( xNetworkBuffers[0] ) ) != 0 ) )
- return pdFALSE;
- return (UBaseType_t) (pxDesc - xNetworkBuffers) + 1;
- }
- /*-----------------------------------------------------------*/
-
-#else
- static UBaseType_t bIsValidNetworkDescriptor (const NetworkBufferDescriptor_t * pxDesc)
- {
- ( void ) pxDesc;
- return ( UBaseType_t ) pdTRUE;
- }
- /*-----------------------------------------------------------*/
-
- static void prvShowWarnings( void )
- {
- }
- /*-----------------------------------------------------------*/
-
-#endif /* ipconfigTCP_IP_SANITY */
-
-BaseType_t xNetworkBuffersInitialise( void )
-{
-BaseType_t xReturn, x;
-
- /* Only initialise the buffers and their associated kernel objects if they
- have not been initialised before. */
- if( xNetworkBufferSemaphore == NULL )
- {
- /* In case alternative locking is used, the mutexes can be initialised
- here */
- ipconfigBUFFER_ALLOC_INIT();
-
- xNetworkBufferSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
- configASSERT( xNetworkBufferSemaphore );
-
- if( xNetworkBufferSemaphore != NULL )
- {
- vListInitialise( &xFreeBuffersList );
-
- /* Initialise all the network buffers. The buffer storage comes
- from the network interface, and different hardware has different
- requirements. */
- vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers );
- for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
- {
- /* Initialise and set the owner of the buffer list items. */
- vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) );
- listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] );
-
- /* Currently, all buffers are available for use. */
- vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) );
- }
-
- uxMinimumFreeNetworkBuffers = ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
- }
- }
-
- if( xNetworkBufferSemaphore == NULL )
- {
- xReturn = pdFAIL;
- }
- else
- {
- xReturn = pdPASS;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
-{
-NetworkBufferDescriptor_t *pxReturn = NULL;
-BaseType_t xInvalid = pdFALSE;
-UBaseType_t uxCount;
-
- /* The current implementation only has a single size memory block, so
- the requested size parameter is not used (yet). */
- ( void ) xRequestedSizeBytes;
-
- if( xNetworkBufferSemaphore != NULL )
- {
- /* If there is a semaphore available, there is a network buffer
- available. */
- if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
- {
- /* Protect the structure as they are accessed from tasks and
- interrupts. */
- ipconfigBUFFER_ALLOC_LOCK();
- {
- pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
-
- if( ( bIsValidNetworkDescriptor( pxReturn ) != pdFALSE_UNSIGNED ) &&
- listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) )
- {
- uxListRemove( &( pxReturn->xBufferListItem ) );
- }
- else
- {
- xInvalid = pdTRUE;
- }
- }
- ipconfigBUFFER_ALLOC_UNLOCK();
-
- if( xInvalid == pdTRUE )
- {
- /* _RB_ Can printf() be called from an interrupt? (comment
- above says this can be called from an interrupt too) */
- /* _HT_ The function shall not be called from an ISR. Comment
- was indeed misleading. Hopefully clear now?
- So the printf()is OK here. */
- FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n",
- pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) );
- pxReturn = NULL;
- }
- else
- {
- /* Reading UBaseType_t, no critical section needed. */
- uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-
- /* For stats, latch the lowest number of network buffers since
- booting. */
- if( uxMinimumFreeNetworkBuffers > uxCount )
- {
- uxMinimumFreeNetworkBuffers = uxCount;
- }
-
- pxReturn->xDataLength = xRequestedSizeBytes;
-
- #if( ipconfigTCP_IP_SANITY != 0 )
- {
- prvShowWarnings();
- }
- #endif /* ipconfigTCP_IP_SANITY */
-
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- /* make sure the buffer is not linked */
- pxReturn->pxNextBuffer = NULL;
- }
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- }
- iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
- }
- else
- {
- iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
- }
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t *pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes )
-{
-NetworkBufferDescriptor_t *pxReturn = NULL;
-
- /* The current implementation only has a single size memory block, so
- the requested size parameter is not used (yet). */
- ( void ) xRequestedSizeBytes;
-
- /* If there is a semaphore available then there is a buffer available, but,
- as this is called from an interrupt, only take a buffer if there are at
- least baINTERRUPT_BUFFER_GET_THRESHOLD buffers remaining. This prevents,
- to a certain degree at least, a rapidly executing interrupt exhausting
- buffer and in so doing preventing tasks from continuing. */
- if( uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) xNetworkBufferSemaphore ) > ( UBaseType_t ) baINTERRUPT_BUFFER_GET_THRESHOLD )
- {
- if( xSemaphoreTakeFromISR( xNetworkBufferSemaphore, NULL ) == pdPASS )
- {
- /* Protect the structure as it is accessed from tasks and interrupts. */
- ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
- {
- pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
- uxListRemove( &( pxReturn->xBufferListItem ) );
- }
- ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
-
- iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxReturn );
- }
- }
-
- if( pxReturn == NULL )
- {
- iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR();
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- /* Ensure the buffer is returned to the list of free buffers before the
- counting semaphore is 'given' to say a buffer is available. */
- ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
- {
- vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
- }
- ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
-
- xSemaphoreGiveFromISR( xNetworkBufferSemaphore, &xHigherPriorityTaskWoken );
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
-
- return xHigherPriorityTaskWoken;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-BaseType_t xListItemAlreadyInFreeList;
-
- if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED )
- {
- FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) );
- return ;
- }
- /* Ensure the buffer is returned to the list of free buffers before the
- counting semaphore is 'given' to say a buffer is available. */
- ipconfigBUFFER_ALLOC_LOCK();
- {
- {
- xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
-
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
- }
- }
- }
- ipconfigBUFFER_ALLOC_UNLOCK();
-
- if( xListItemAlreadyInFreeList )
- {
- FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n",
- pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) );
- }
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- xSemaphoreGive( xNetworkBufferSemaphore );
- prvShowWarnings();
- }
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
-{
- return uxMinimumFreeNetworkBuffers;
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
-{
- return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-}
-
-NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
-{
- /* In BufferAllocation_1.c all network buffer are allocated with a
- maximum size of 'ipTOTAL_ETHERNET_FRAME_SIZE'.No need to resize the
- network buffer. */
- ( void ) xNewSizeBytes;
- return pxNetworkBuffer;
-}
-
-/*#endif */ /* ipconfigINCLUDE_TEST_CODE */
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/******************************************************************************
+ *
+ * See the following web page for essential buffer allocation scheme usage and
+ * configuration details:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
+ *
+ ******************************************************************************/
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+/* For an Ethernet interrupt to be able to obtain a network buffer there must
+be at least this number of buffers available. */
+#define baINTERRUPT_BUFFER_GET_THRESHOLD ( 3 )
+
+/* A list of free (available) NetworkBufferDescriptor_t structures. */
+static List_t xFreeBuffersList;
+
+/* Some statistics about the use of buffers. */
+static UBaseType_t uxMinimumFreeNetworkBuffers = 0u;
+
+/* Declares the pool of NetworkBufferDescriptor_t structures that are available
+to the system. All the network buffers referenced from xFreeBuffersList exist
+in this array. The array is not accessed directly except during initialisation,
+when the xFreeBuffersList is filled (as all the buffers are free when the system
+is booted). */
+static NetworkBufferDescriptor_t xNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
+
+/* This constant is defined as true to let FreeRTOS_TCP_IP.c know that the
+network buffers have constant size, large enough to hold the biggest Ethernet
+packet. No resizing will be done. */
+const BaseType_t xBufferAllocFixedSize = pdTRUE;
+
+/* The semaphore used to obtain network buffers. */
+static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
+
+#if( ipconfigTCP_IP_SANITY != 0 )
+ static char cIsLow = pdFALSE;
+ UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
+#else
+ static UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc );
+#endif /* ipconfigTCP_IP_SANITY */
+
+static void prvShowWarnings( void );
+
+/* The user can define their own ipconfigBUFFER_ALLOC_LOCK() and
+ipconfigBUFFER_ALLOC_UNLOCK() macros, especially for use form an ISR. If these
+are not defined then default them to call the normal enter/exit critical
+section macros. */
+#if !defined( ipconfigBUFFER_ALLOC_LOCK )
+
+ #define ipconfigBUFFER_ALLOC_INIT( ) do {} while (0)
+ #define ipconfigBUFFER_ALLOC_LOCK_FROM_ISR() \
+ UBaseType_t uxSavedInterruptStatus = ( UBaseType_t ) portSET_INTERRUPT_MASK_FROM_ISR(); \
+ {
+
+ #define ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR() \
+ portCLEAR_INTERRUPT_MASK_FROM_ISR( uxSavedInterruptStatus ); \
+ }
+
+ #define ipconfigBUFFER_ALLOC_LOCK() taskENTER_CRITICAL()
+ #define ipconfigBUFFER_ALLOC_UNLOCK() taskEXIT_CRITICAL()
+
+#endif /* ipconfigBUFFER_ALLOC_LOCK */
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigTCP_IP_SANITY != 0 )
+
+ /* HT: SANITY code will be removed as soon as the library is stable
+ * and and ready to become public
+ * Function below gives information about the use of buffers */
+ #define WARN_LOW ( 2 )
+ #define WARN_HIGH ( ( 5 * ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) / 10 )
+
+#endif /* ipconfigTCP_IP_SANITY */
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigTCP_IP_SANITY != 0 )
+
+ BaseType_t prvIsFreeBuffer( const NetworkBufferDescriptor_t *pxDescr )
+ {
+ return ( bIsValidNetworkDescriptor( pxDescr ) != 0 ) &&
+ ( listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxDescr->xBufferListItem ) ) != 0 );
+ }
+ /*-----------------------------------------------------------*/
+
+ static void prvShowWarnings( void )
+ {
+ UBaseType_t uxCount = uxGetNumberOfFreeNetworkBuffers( );
+ if( ( ( cIsLow == 0 ) && ( uxCount <= WARN_LOW ) ) || ( ( cIsLow != 0 ) && ( uxCount >= WARN_HIGH ) ) )
+ {
+ cIsLow = !cIsLow;
+ FreeRTOS_debug_printf( ( "*** Warning *** %s %lu buffers left\n", cIsLow ? "only" : "now", uxCount ) );
+ }
+ }
+ /*-----------------------------------------------------------*/
+
+ UBaseType_t bIsValidNetworkDescriptor( const NetworkBufferDescriptor_t * pxDesc )
+ {
+ uint32_t offset = ( uint32_t ) ( ((const char *)pxDesc) - ((const char *)xNetworkBuffers) );
+ if( ( offset >= sizeof( xNetworkBuffers ) ) ||
+ ( ( offset % sizeof( xNetworkBuffers[0] ) ) != 0 ) )
+ return pdFALSE;
+ return (UBaseType_t) (pxDesc - xNetworkBuffers) + 1;
+ }
+ /*-----------------------------------------------------------*/
+
+#else
+ static UBaseType_t bIsValidNetworkDescriptor (const NetworkBufferDescriptor_t * pxDesc)
+ {
+ ( void ) pxDesc;
+ return ( UBaseType_t ) pdTRUE;
+ }
+ /*-----------------------------------------------------------*/
+
+ static void prvShowWarnings( void )
+ {
+ }
+ /*-----------------------------------------------------------*/
+
+#endif /* ipconfigTCP_IP_SANITY */
+
+BaseType_t xNetworkBuffersInitialise( void )
+{
+BaseType_t xReturn, x;
+
+ /* Only initialise the buffers and their associated kernel objects if they
+ have not been initialised before. */
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ /* In case alternative locking is used, the mutexes can be initialised
+ here */
+ ipconfigBUFFER_ALLOC_INIT();
+
+ xNetworkBufferSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
+ configASSERT( xNetworkBufferSemaphore );
+
+ if( xNetworkBufferSemaphore != NULL )
+ {
+ vListInitialise( &xFreeBuffersList );
+
+ /* Initialise all the network buffers. The buffer storage comes
+ from the network interface, and different hardware has different
+ requirements. */
+ vNetworkInterfaceAllocateRAMToBuffers( xNetworkBuffers );
+ for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
+ {
+ /* Initialise and set the owner of the buffer list items. */
+ vListInitialiseItem( &( xNetworkBuffers[ x ].xBufferListItem ) );
+ listSET_LIST_ITEM_OWNER( &( xNetworkBuffers[ x ].xBufferListItem ), &xNetworkBuffers[ x ] );
+
+ /* Currently, all buffers are available for use. */
+ vListInsert( &xFreeBuffersList, &( xNetworkBuffers[ x ].xBufferListItem ) );
+ }
+
+ uxMinimumFreeNetworkBuffers = ( UBaseType_t ) ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
+ }
+ }
+
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
+{
+NetworkBufferDescriptor_t *pxReturn = NULL;
+BaseType_t xInvalid = pdFALSE;
+UBaseType_t uxCount;
+
+ /* The current implementation only has a single size memory block, so
+ the requested size parameter is not used (yet). */
+ ( void ) xRequestedSizeBytes;
+
+ if( xNetworkBufferSemaphore != NULL )
+ {
+ /* If there is a semaphore available, there is a network buffer
+ available. */
+ if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
+ {
+ /* Protect the structure as they are accessed from tasks and
+ interrupts. */
+ ipconfigBUFFER_ALLOC_LOCK();
+ {
+ pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
+
+ if( ( bIsValidNetworkDescriptor( pxReturn ) != pdFALSE_UNSIGNED ) &&
+ listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxReturn->xBufferListItem ) ) )
+ {
+ uxListRemove( &( pxReturn->xBufferListItem ) );
+ }
+ else
+ {
+ xInvalid = pdTRUE;
+ }
+ }
+ ipconfigBUFFER_ALLOC_UNLOCK();
+
+ if( xInvalid == pdTRUE )
+ {
+ /* _RB_ Can printf() be called from an interrupt? (comment
+ above says this can be called from an interrupt too) */
+ /* _HT_ The function shall not be called from an ISR. Comment
+ was indeed misleading. Hopefully clear now?
+ So the printf()is OK here. */
+ FreeRTOS_debug_printf( ( "pxGetNetworkBufferWithDescriptor: INVALID BUFFER: %p (valid %lu)\n",
+ pxReturn, bIsValidNetworkDescriptor( pxReturn ) ) );
+ pxReturn = NULL;
+ }
+ else
+ {
+ /* Reading UBaseType_t, no critical section needed. */
+ uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+
+ /* For stats, latch the lowest number of network buffers since
+ booting. */
+ if( uxMinimumFreeNetworkBuffers > uxCount )
+ {
+ uxMinimumFreeNetworkBuffers = uxCount;
+ }
+
+ pxReturn->xDataLength = xRequestedSizeBytes;
+
+ #if( ipconfigTCP_IP_SANITY != 0 )
+ {
+ prvShowWarnings();
+ }
+ #endif /* ipconfigTCP_IP_SANITY */
+
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ /* make sure the buffer is not linked */
+ pxReturn->pxNextBuffer = NULL;
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+ }
+ iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
+ }
+ else
+ {
+ iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
+ }
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t *pxNetworkBufferGetFromISR( size_t xRequestedSizeBytes )
+{
+NetworkBufferDescriptor_t *pxReturn = NULL;
+
+ /* The current implementation only has a single size memory block, so
+ the requested size parameter is not used (yet). */
+ ( void ) xRequestedSizeBytes;
+
+ /* If there is a semaphore available then there is a buffer available, but,
+ as this is called from an interrupt, only take a buffer if there are at
+ least baINTERRUPT_BUFFER_GET_THRESHOLD buffers remaining. This prevents,
+ to a certain degree at least, a rapidly executing interrupt exhausting
+ buffer and in so doing preventing tasks from continuing. */
+ if( uxQueueMessagesWaitingFromISR( ( QueueHandle_t ) xNetworkBufferSemaphore ) > ( UBaseType_t ) baINTERRUPT_BUFFER_GET_THRESHOLD )
+ {
+ if( xSemaphoreTakeFromISR( xNetworkBufferSemaphore, NULL ) == pdPASS )
+ {
+ /* Protect the structure as it is accessed from tasks and interrupts. */
+ ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
+ {
+ pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
+ uxListRemove( &( pxReturn->xBufferListItem ) );
+ }
+ ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
+
+ iptraceNETWORK_BUFFER_OBTAINED_FROM_ISR( pxReturn );
+ }
+ }
+
+ if( pxReturn == NULL )
+ {
+ iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER_FROM_ISR();
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t vNetworkBufferReleaseFromISR( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ /* Ensure the buffer is returned to the list of free buffers before the
+ counting semaphore is 'given' to say a buffer is available. */
+ ipconfigBUFFER_ALLOC_LOCK_FROM_ISR();
+ {
+ vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ ipconfigBUFFER_ALLOC_UNLOCK_FROM_ISR();
+
+ xSemaphoreGiveFromISR( xNetworkBufferSemaphore, &xHigherPriorityTaskWoken );
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+
+ return xHigherPriorityTaskWoken;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+BaseType_t xListItemAlreadyInFreeList;
+
+ if( bIsValidNetworkDescriptor( pxNetworkBuffer ) == pdFALSE_UNSIGNED )
+ {
+ FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: Invalid buffer %p\n", pxNetworkBuffer ) );
+ return ;
+ }
+ /* Ensure the buffer is returned to the list of free buffers before the
+ counting semaphore is 'given' to say a buffer is available. */
+ ipconfigBUFFER_ALLOC_LOCK();
+ {
+ {
+ xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ }
+ }
+ ipconfigBUFFER_ALLOC_UNLOCK();
+
+ if( xListItemAlreadyInFreeList )
+ {
+ FreeRTOS_debug_printf( ( "vReleaseNetworkBufferAndDescriptor: %p ALREADY RELEASED (now %lu)\n",
+ pxNetworkBuffer, uxGetNumberOfFreeNetworkBuffers( ) ) );
+ }
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ xSemaphoreGive( xNetworkBufferSemaphore );
+ prvShowWarnings();
+ }
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
+{
+ return uxMinimumFreeNetworkBuffers;
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
+{
+ return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+}
+
+NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
+{
+ /* In BufferAllocation_1.c all network buffer are allocated with a
+ maximum size of 'ipTOTAL_ETHERNET_FRAME_SIZE'.No need to resize the
+ network buffer. */
+ ( void ) xNewSizeBytes;
+ return pxNetworkBuffer;
+}
+
+/*#endif */ /* ipconfigINCLUDE_TEST_CODE */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c
index e008da07a..51f5410a4 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/BufferManagement/BufferAllocation_2.c
@@ -1,393 +1,393 @@
-/*
- * FreeRTOS+TCP V2.0.11
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/******************************************************************************
- *
- * See the following web page for essential buffer allocation scheme usage and
- * configuration details:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
- *
- ******************************************************************************/
-
-/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
-THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
-heap_4 can be used. */
-
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-/* The obtained network buffer must be large enough to hold a packet that might
-replace the packet that was requested to be sent. */
-#if ipconfigUSE_TCP == 1
- #define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
-#else
- #define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
-#endif /* ipconfigUSE_TCP == 1 */
-
-/*_RB_ This is too complex not to have an explanation. */
-#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- #define ASSERT_CONCAT_(a, b) a##b
- #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
- #define STATIC_ASSERT(e) \
- ;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
-
- STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
-#endif
-
-/* A list of free (available) NetworkBufferDescriptor_t structures. */
-static List_t xFreeBuffersList;
-
-/* Some statistics about the use of buffers. */
-static size_t uxMinimumFreeNetworkBuffers;
-
-/* Declares the pool of NetworkBufferDescriptor_t structures that are available
-to the system. All the network buffers referenced from xFreeBuffersList exist
-in this array. The array is not accessed directly except during initialisation,
-when the xFreeBuffersList is filled (as all the buffers are free when the system
-is booted). */
-static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
-
-/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
-network buffers have a variable size: resizing may be necessary */
-const BaseType_t xBufferAllocFixedSize = pdFALSE;
-
-/* The semaphore used to obtain network buffers. */
-static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkBuffersInitialise( void )
-{
-BaseType_t xReturn, x;
-
- /* Only initialise the buffers and their associated kernel objects if they
- have not been initialised before. */
- if( xNetworkBufferSemaphore == NULL )
- {
- xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
- configASSERT( xNetworkBufferSemaphore );
-
- if( xNetworkBufferSemaphore != NULL )
- {
- #if ( configQUEUE_REGISTRY_SIZE > 0 )
- {
- vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
- }
- #endif /* configQUEUE_REGISTRY_SIZE */
-
- /* If the trace recorder code is included name the semaphore for viewing
- in FreeRTOS+Trace. */
- #if( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
- {
- extern QueueHandle_t xNetworkEventQueue;
- vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
- vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
- }
- #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
-
- vListInitialise( &xFreeBuffersList );
-
- /* Initialise all the network buffers. No storage is allocated to
- the buffers yet. */
- for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
- {
- /* Initialise and set the owner of the buffer list items. */
- xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
- vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
- listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
-
- /* Currently, all buffers are available for use. */
- vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
- }
-
- uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
- }
- }
-
- if( xNetworkBufferSemaphore == NULL )
- {
- xReturn = pdFAIL;
- }
- else
- {
- xReturn = pdPASS;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes )
-{
-uint8_t *pucEthernetBuffer;
-size_t xSize = *pxRequestedSizeBytes;
-
- if( xSize < baMINIMAL_BUFFER_SIZE )
- {
- /* Buffers must be at least large enough to hold a TCP-packet with
- headers, or an ARP packet, in case TCP is not included. */
- xSize = baMINIMAL_BUFFER_SIZE;
- }
-
- /* Round up xSize to the nearest multiple of N bytes,
- where N equals 'sizeof( size_t )'. */
- if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
- {
- xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
- }
- *pxRequestedSizeBytes = xSize;
-
- /* Allocate a buffer large enough to store the requested Ethernet frame size
- and a pointer to a network buffer structure (hence the addition of
- ipBUFFER_PADDING bytes). */
- pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
- configASSERT( pucEthernetBuffer );
-
- if( pucEthernetBuffer != NULL )
- {
- /* Enough space is left at the start of the buffer to place a pointer to
- the network buffer structure that references this Ethernet buffer.
- Return a pointer to the start of the Ethernet buffer itself. */
- pucEthernetBuffer += ipBUFFER_PADDING;
- }
-
- return pucEthernetBuffer;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer )
-{
- /* There is space before the Ethernet buffer in which a pointer to the
- network buffer that references this Ethernet buffer is stored. Remove the
- space before freeing the buffer. */
- if( pucEthernetBuffer != NULL )
- {
- pucEthernetBuffer -= ipBUFFER_PADDING;
- vPortFree( ( void * ) pucEthernetBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
-{
-NetworkBufferDescriptor_t *pxReturn = NULL;
-size_t uxCount;
-
- if( xNetworkBufferSemaphore != NULL )
- {
- if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
- {
- /* ARP packets can replace application packets, so the storage must be
- at least large enough to hold an ARP. */
- xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
- }
-
- /* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
- to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
- xRequestedSizeBytes += 2u;
- if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
- {
- xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
- }
-
- /* If there is a semaphore available, there is a network buffer available. */
- if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
- {
- /* Protect the structure as it is accessed from tasks and interrupts. */
- taskENTER_CRITICAL();
- {
- pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
- uxListRemove( &( pxReturn->xBufferListItem ) );
- }
- taskEXIT_CRITICAL();
-
- /* Reading UBaseType_t, no critical section needed. */
- uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-
- if( uxMinimumFreeNetworkBuffers > uxCount )
- {
- uxMinimumFreeNetworkBuffers = uxCount;
- }
-
- /* Allocate storage of exactly the requested size to the buffer. */
- configASSERT( pxReturn->pucEthernetBuffer == NULL );
- if( xRequestedSizeBytes > 0 )
- {
- /* Extra space is obtained so a pointer to the network buffer can
- be stored at the beginning of the buffer. */
- pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
-
- if( pxReturn->pucEthernetBuffer == NULL )
- {
- /* The attempt to allocate storage for the buffer payload failed,
- so the network buffer structure cannot be used and must be
- released. */
- vReleaseNetworkBufferAndDescriptor( pxReturn );
- pxReturn = NULL;
- }
- else
- {
- /* Store a pointer to the network buffer structure in the
- buffer storage area, then move the buffer pointer on past the
- stored pointer so the pointer value is not overwritten by the
- application when the buffer is used. */
- *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
- pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
-
- /* Store the actual size of the allocated buffer, which may be
- greater than the original requested size. */
- pxReturn->xDataLength = xRequestedSizeBytes;
-
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- /* make sure the buffer is not linked */
- pxReturn->pxNextBuffer = NULL;
- }
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- }
- }
- else
- {
- /* A descriptor is being returned without an associated buffer being
- allocated. */
- }
- }
- }
-
- if( pxReturn == NULL )
- {
- iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
- }
- else
- {
- iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-BaseType_t xListItemAlreadyInFreeList;
-
- /* Ensure the buffer is returned to the list of free buffers before the
- counting semaphore is 'given' to say a buffer is available. Release the
- storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
- IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
- MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
- vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
- pxNetworkBuffer->pucEthernetBuffer = NULL;
-
- taskENTER_CRITICAL();
- {
- xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
-
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
- }
- }
- taskEXIT_CRITICAL();
-
- /*
- * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
- * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
- */
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
- {
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
- }
- }
- else
- {
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Returns the number of free network buffers
- */
-UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
-{
- return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
-{
- return uxMinimumFreeNetworkBuffers;
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
-{
-size_t xOriginalLength;
-uint8_t *pucBuffer;
-
- xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
- xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
-
- pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
-
- if( pucBuffer == NULL )
- {
- /* In case the allocation fails, return NULL. */
- pxNetworkBuffer = NULL;
- }
- else
- {
- pxNetworkBuffer->xDataLength = xNewSizeBytes;
- if( xNewSizeBytes > xOriginalLength )
- {
- xNewSizeBytes = xOriginalLength;
- }
-
- memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
- vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
- pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
- }
-
- return pxNetworkBuffer;
-}
-
+/*
+ * FreeRTOS+TCP V2.0.11
+ * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy of
+ * this software and associated documentation files (the "Software"), to deal in
+ * the Software without restriction, including without limitation the rights to
+ * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+ * the Software, and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+ * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+ * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * http://www.FreeRTOS.org
+ * http://aws.amazon.com/freertos
+ *
+ * 1 tab == 4 spaces!
+ */
+
+/******************************************************************************
+ *
+ * See the following web page for essential buffer allocation scheme usage and
+ * configuration details:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
+ *
+ ******************************************************************************/
+
+/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
+THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
+heap_4 can be used. */
+
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+/* The obtained network buffer must be large enough to hold a packet that might
+replace the packet that was requested to be sent. */
+#if ipconfigUSE_TCP == 1
+ #define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
+#else
+ #define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
+#endif /* ipconfigUSE_TCP == 1 */
+
+/*_RB_ This is too complex not to have an explanation. */
+#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ #define ASSERT_CONCAT_(a, b) a##b
+ #define ASSERT_CONCAT(a, b) ASSERT_CONCAT_(a, b)
+ #define STATIC_ASSERT(e) \
+ ;enum { ASSERT_CONCAT(assert_line_, __LINE__) = 1/(!!(e)) }
+
+ STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
+#endif
+
+/* A list of free (available) NetworkBufferDescriptor_t structures. */
+static List_t xFreeBuffersList;
+
+/* Some statistics about the use of buffers. */
+static size_t uxMinimumFreeNetworkBuffers;
+
+/* Declares the pool of NetworkBufferDescriptor_t structures that are available
+to the system. All the network buffers referenced from xFreeBuffersList exist
+in this array. The array is not accessed directly except during initialisation,
+when the xFreeBuffersList is filled (as all the buffers are free when the system
+is booted). */
+static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
+
+/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
+network buffers have a variable size: resizing may be necessary */
+const BaseType_t xBufferAllocFixedSize = pdFALSE;
+
+/* The semaphore used to obtain network buffers. */
+static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkBuffersInitialise( void )
+{
+BaseType_t xReturn, x;
+
+ /* Only initialise the buffers and their associated kernel objects if they
+ have not been initialised before. */
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
+ configASSERT( xNetworkBufferSemaphore );
+
+ if( xNetworkBufferSemaphore != NULL )
+ {
+ #if ( configQUEUE_REGISTRY_SIZE > 0 )
+ {
+ vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
+ }
+ #endif /* configQUEUE_REGISTRY_SIZE */
+
+ /* If the trace recorder code is included name the semaphore for viewing
+ in FreeRTOS+Trace. */
+ #if( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
+ {
+ extern QueueHandle_t xNetworkEventQueue;
+ vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
+ vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
+ }
+ #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
+
+ vListInitialise( &xFreeBuffersList );
+
+ /* Initialise all the network buffers. No storage is allocated to
+ the buffers yet. */
+ for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
+ {
+ /* Initialise and set the owner of the buffer list items. */
+ xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
+ vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
+ listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
+
+ /* Currently, all buffers are available for use. */
+ vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
+ }
+
+ uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
+ }
+ }
+
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+uint8_t *pucGetNetworkBuffer( size_t *pxRequestedSizeBytes )
+{
+uint8_t *pucEthernetBuffer;
+size_t xSize = *pxRequestedSizeBytes;
+
+ if( xSize < baMINIMAL_BUFFER_SIZE )
+ {
+ /* Buffers must be at least large enough to hold a TCP-packet with
+ headers, or an ARP packet, in case TCP is not included. */
+ xSize = baMINIMAL_BUFFER_SIZE;
+ }
+
+ /* Round up xSize to the nearest multiple of N bytes,
+ where N equals 'sizeof( size_t )'. */
+ if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
+ {
+ xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
+ }
+ *pxRequestedSizeBytes = xSize;
+
+ /* Allocate a buffer large enough to store the requested Ethernet frame size
+ and a pointer to a network buffer structure (hence the addition of
+ ipBUFFER_PADDING bytes). */
+ pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
+ configASSERT( pucEthernetBuffer );
+
+ if( pucEthernetBuffer != NULL )
+ {
+ /* Enough space is left at the start of the buffer to place a pointer to
+ the network buffer structure that references this Ethernet buffer.
+ Return a pointer to the start of the Ethernet buffer itself. */
+ pucEthernetBuffer += ipBUFFER_PADDING;
+ }
+
+ return pucEthernetBuffer;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBuffer( uint8_t *pucEthernetBuffer )
+{
+ /* There is space before the Ethernet buffer in which a pointer to the
+ network buffer that references this Ethernet buffer is stored. Remove the
+ space before freeing the buffer. */
+ if( pucEthernetBuffer != NULL )
+ {
+ pucEthernetBuffer -= ipBUFFER_PADDING;
+ vPortFree( ( void * ) pucEthernetBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t *pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes, TickType_t xBlockTimeTicks )
+{
+NetworkBufferDescriptor_t *pxReturn = NULL;
+size_t uxCount;
+
+ if( xNetworkBufferSemaphore != NULL )
+ {
+ if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
+ {
+ /* ARP packets can replace application packets, so the storage must be
+ at least large enough to hold an ARP. */
+ xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
+ }
+
+ /* Add 2 bytes to xRequestedSizeBytes and round up xRequestedSizeBytes
+ to the nearest multiple of N bytes, where N equals 'sizeof( size_t )'. */
+ xRequestedSizeBytes += 2u;
+ if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
+ {
+ xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
+ }
+
+ /* If there is a semaphore available, there is a network buffer available. */
+ if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
+ {
+ /* Protect the structure as it is accessed from tasks and interrupts. */
+ taskENTER_CRITICAL();
+ {
+ pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
+ uxListRemove( &( pxReturn->xBufferListItem ) );
+ }
+ taskEXIT_CRITICAL();
+
+ /* Reading UBaseType_t, no critical section needed. */
+ uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+
+ if( uxMinimumFreeNetworkBuffers > uxCount )
+ {
+ uxMinimumFreeNetworkBuffers = uxCount;
+ }
+
+ /* Allocate storage of exactly the requested size to the buffer. */
+ configASSERT( pxReturn->pucEthernetBuffer == NULL );
+ if( xRequestedSizeBytes > 0 )
+ {
+ /* Extra space is obtained so a pointer to the network buffer can
+ be stored at the beginning of the buffer. */
+ pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
+
+ if( pxReturn->pucEthernetBuffer == NULL )
+ {
+ /* The attempt to allocate storage for the buffer payload failed,
+ so the network buffer structure cannot be used and must be
+ released. */
+ vReleaseNetworkBufferAndDescriptor( pxReturn );
+ pxReturn = NULL;
+ }
+ else
+ {
+ /* Store a pointer to the network buffer structure in the
+ buffer storage area, then move the buffer pointer on past the
+ stored pointer so the pointer value is not overwritten by the
+ application when the buffer is used. */
+ *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
+ pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
+
+ /* Store the actual size of the allocated buffer, which may be
+ greater than the original requested size. */
+ pxReturn->xDataLength = xRequestedSizeBytes;
+
+ #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ /* make sure the buffer is not linked */
+ pxReturn->pxNextBuffer = NULL;
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+ }
+ }
+ else
+ {
+ /* A descriptor is being returned without an associated buffer being
+ allocated. */
+ }
+ }
+ }
+
+ if( pxReturn == NULL )
+ {
+ iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
+ }
+ else
+ {
+ iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+BaseType_t xListItemAlreadyInFreeList;
+
+ /* Ensure the buffer is returned to the list of free buffers before the
+ counting semaphore is 'given' to say a buffer is available. Release the
+ storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
+ IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
+ MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
+ vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
+ pxNetworkBuffer->pucEthernetBuffer = NULL;
+
+ taskENTER_CRITICAL();
+ {
+ xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ /*
+ * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
+ * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
+ */
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
+ {
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+ }
+ }
+ else
+ {
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Returns the number of free network buffers
+ */
+UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
+{
+ return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
+{
+ return uxMinimumFreeNetworkBuffers;
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t *pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer, size_t xNewSizeBytes )
+{
+size_t xOriginalLength;
+uint8_t *pucBuffer;
+
+ xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
+ xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
+
+ pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
+
+ if( pucBuffer == NULL )
+ {
+ /* In case the allocation fails, return NULL. */
+ pxNetworkBuffer = NULL;
+ }
+ else
+ {
+ pxNetworkBuffer->xDataLength = xNewSizeBytes;
+ if( xNewSizeBytes > xOriginalLength )
+ {
+ xNewSizeBytes = xOriginalLength;
+ }
+
+ memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
+ vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
+ pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
+ }
+
+ return pxNetworkBuffer;
+}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt
new file mode 100644
index 000000000..17aca5764
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/ReadMe.txt
@@ -0,0 +1,3 @@
+Update pack_struct_start.h and pack_struct_end.h for your architecure.
+These files define the specifiers needed by your compiler to properly pack struct data
+need by FreeRTOS+TCP. \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h
new file mode 100644
index 000000000..cdbad17c4
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_end.h
@@ -0,0 +1,32 @@
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+; /* FIX ME. Update for the compiler specifier needed at end of a struct declartion to pack the struct. */ \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h
new file mode 100644
index 000000000..7fe533a06
--- /dev/null
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/CompilerName/pack_struct_start.h
@@ -0,0 +1,32 @@
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+/* FIX ME. Update for the compiler specifier needed at the start of a struct declartion to pack the struct. */ \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h
index d61b8d003..73455f910 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_end.h
@@ -1,46 +1,46 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-__attribute__( (packed) );
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+__attribute__( (packed) );
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h
index 5a88f78cf..658cc4a5e 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/GCC/pack_struct_start.h
@@ -1,48 +1,48 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-/* Nothing to do here. */
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+/* Nothing to do here. */
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h
index 85e670819..f0a73881d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_end.h
@@ -1,47 +1,47 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h
index 15e6eb69b..95cc089b2 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/IAR/pack_struct_start.h
@@ -1,49 +1,49 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-__packed
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+__packed
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_end.h
index 816b0b3b6..48a8ef963 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_end.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_end.h
@@ -1,33 +1,33 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-;
-#pragma pack(pop)
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+;
+#pragma pack(pop)
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_start.h
index 29ea9ae3e..32c98e859 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_start.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Keil/pack_struct_start.h
@@ -1,48 +1,48 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-#pragma pack(push,1)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+#pragma pack(push,1)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h
index 19a0f39ef..e486c1c30 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_end.h
@@ -1,48 +1,48 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-;
-#pragma pack( pop )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+;
+#pragma pack( pop )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h
index 54a3e6885..52b90803b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/MSVC/pack_struct_start.h
@@ -1,47 +1,47 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-#pragma pack( push, 1 )
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+#pragma pack( push, 1 )
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h
index 2e6d2f997..49e276960 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_end.h
@@ -1,60 +1,60 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-
-#ifdef _SH
- #ifdef __RENESAS__
- ;
- #pragma unpack
- #endif
-#endif
-#ifdef __RX
- #ifdef __CCRX__
- ;
- #pragma packoption
- #endif
-#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+
+#ifdef _SH
+ #ifdef __RENESAS__
+ ;
+ #pragma unpack
+ #endif
+#endif
+#ifdef __RX
+ #ifdef __CCRX__
+ ;
+ #pragma packoption
+ #endif
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h
index 7c8750c6a..88c4c1f38 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/Compiler/Renesas/pack_struct_start.h
@@ -1,58 +1,58 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/*****************************************************************************
- *
- * See the following URL for an explanation of this file:
- * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
- *
- *****************************************************************************/
-
-
-#ifdef _SH
- #ifdef __RENESAS__
- #pragma pack 1
- #endif
-#endif
-#ifdef __RX
- #ifdef __CCRX__
- #pragma pack
- #endif
-#endif
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/*****************************************************************************
+ *
+ * See the following URL for an explanation of this file:
+ * http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Compiler_Porting.html
+ *
+ *****************************************************************************/
+
+
+#ifdef _SH
+ #ifdef __RENESAS__
+ #pragma pack 1
+ #endif
+#endif
+#ifdef __RX
+ #ifdef __CCRX__
+ #pragma pack
+ #endif
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c
index 83c96a07c..3528269bd 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/NetworkInterface.c
@@ -1,637 +1,637 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-/* Some files from the Atmel Software Framework */
-/*_RB_ The SAM4E portable layer has three different header files called gmac.h! */
-#include "instance/gmac.h"
-#include <sysclk.h>
-#include <ethernet_phy.h>
-
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004 //!< Link status
-#endif
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/* Interrupt events to process. Currently only the Rx event is processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
-
-#define HZ_PER_MHZ ( 1000000UL )
-
-#ifndef EMAC_MAX_BLOCK_TIME_MS
- #define EMAC_MAX_BLOCK_TIME_MS 100ul
-#endif
-
-#if !defined( GMAC_USES_TX_CALLBACK ) || ( GMAC_USES_TX_CALLBACK != 1 )
- #error Please define GMAC_USES_TX_CALLBACK as 1
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to 4x
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 4 * configMINIMAL_STACK_SIZE )
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Wait a fixed time for the link status to indicate the network is up.
- */
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
-
-#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
- void vGMACGenerateChecksum( uint8_t *apBuffer );
-#endif
-
-/*
- * Called from the ASF GMAC driver.
- */
-static void prvRxCallback( uint32_t ulStatus );
-static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer );
-
-/*
- * A deferred interrupt handler task that processes GMAC interrupts.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Initialise the ASF GMAC driver.
- */
-static BaseType_t prvGMACInit( void );
-
-/*
- * Try to obtain an Rx packet from the hardware.
- */
-static uint32_t prvEMACRxPoll( void );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx interrupt is handled, although code is included for other events to
-enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-static volatile BaseType_t xGMACSwitchRequired;
-
-/* ethernet_phy_addr: the address of the PHY in use.
-Atmel was a bit ambiguous about it so the address will be stored
-in this variable, see ethernet_phy.c */
-extern int ethernet_phy_addr;
-
-/* LLMNR multicast address. */
-static const uint8_t llmnr_mac_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
-
-/* The GMAC object as defined by the ASF drivers. */
-static gmac_device_t gs_gmac_dev;
-
-/* MAC address to use. */
-extern const uint8_t ucMACAddress[ 6 ];
-
-/* Holds the handle of the task used as a deferred interrupt processor. The
-handle is used so direct notifications can be sent to the task for all EMAC/DMA
-related interrupts. */
-TaskHandle_t xEMACTaskHandle = NULL;
-
-static QueueHandle_t xTxBufferQueue;
-int tx_release_count[ 4 ];
-
-/* xTXDescriptorSemaphore is a counting semaphore with
-a maximum count of GMAC_TX_BUFFERS, which is the number of
-DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-/*
- * GMAC interrupt handler.
- */
-void GMAC_Handler(void)
-{
- xGMACSwitchRequired = pdFALSE;
-
- /* gmac_handler() may call prvRxCallback() which may change
- the value of xGMACSwitchRequired. */
- gmac_handler( &gs_gmac_dev );
-
- if( xGMACSwitchRequired != pdFALSE )
- {
- portEND_SWITCHING_ISR( xGMACSwitchRequired );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvRxCallback( uint32_t ulStatus )
-{
- if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
- {
- /* let the prvEMACHandlerTask know that there was an RX event. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- /* Only an RX interrupt can wakeup prvEMACHandlerTask. */
- vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer )
-{
- if( ( xTxBufferQueue != NULL ) && ( xEMACTaskHandle != NULL ) )
- {
- /* let the prvEMACHandlerTask know that there was an RX event. */
- ulISREvents |= EMAC_IF_TX_EVENT;
-
- vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
- xQueueSendFromISR( xTxBufferQueue, &puc_buffer, ( BaseType_t * ) &xGMACSwitchRequired );
- tx_release_count[ 2 ]++;
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-const TickType_t x5_Seconds = 5000UL;
-
- if( xEMACTaskHandle == NULL )
- {
- prvGMACInit();
-
- /* Wait at most 5 seconds for a Link Status in the PHY. */
- xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- configASSERT( xEMACTaskHandle );
- }
-
- if( xTxBufferQueue == NULL )
- {
- xTxBufferQueue = xQueueCreate( GMAC_TX_BUFFERS, sizeof( void * ) );
- configASSERT( xTxBufferQueue );
- }
-
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) GMAC_TX_BUFFERS, ( UBaseType_t ) GMAC_TX_BUFFERS );
- configASSERT( xTXDescriptorSemaphore );
- }
- /* When returning non-zero, the stack will become active and
- start DHCP (in configured) */
- return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xResult;
-
- /* This function returns true if the Link Status in the PHY is high. */
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xResult = pdTRUE;
- }
- else
- {
- xResult = pdFALSE;
- }
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
-{
-/* Do not wait too long for a free TX DMA buffer. */
-const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
-
- do {
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
- {
- /* Do not attempt to send packets as long as the Link Status is low. */
- break;
- }
- if( xTXDescriptorSemaphore == NULL )
- {
- /* Semaphore has not been created yet? */
- break;
- }
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- tx_release_count[ 3 ]++;
- break;
- }
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Confirm that the pxDescriptor may be kept by the driver. */
- configASSERT( bReleaseAfterSend != pdFALSE );
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- gmac_dev_write( &gs_gmac_dev, (void *)pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, prvTxCallback );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Confirm that the pxDescriptor may be kept by the driver. */
- bReleaseAfterSend = pdFALSE;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- /* Not interested in a call-back after TX. */
- iptraceNETWORK_INTERFACE_TRANSMIT();
- } while( 0 );
-
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvGMACInit( void )
-{
-uint32_t ncfgr;
-
- gmac_options_t gmac_option;
-
- memset( &gmac_option, '\0', sizeof( gmac_option ) );
- gmac_option.uc_copy_all_frame = 0;
- gmac_option.uc_no_boardcast = 0;
- memcpy( gmac_option.uc_mac_addr, ucMACAddress, sizeof( gmac_option.uc_mac_addr ) );
-
- gs_gmac_dev.p_hw = GMAC;
- gmac_dev_init( GMAC, &gs_gmac_dev, &gmac_option );
-
- NVIC_SetPriority( GMAC_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ( GMAC_IRQn );
-
- /* Contact the Ethernet PHY and store it's address in 'ethernet_phy_addr' */
- ethernet_phy_init( GMAC, ETHERNET_CONF_PHY_ADDR, sysclk_get_cpu_hz() );
-
- ethernet_phy_auto_negotiate( GMAC, ethernet_phy_addr );
- ethernet_phy_set_link( GMAC, ethernet_phy_addr, 1 );
-
- /* The GMAC driver will call a hook prvRxCallback(), which
- in turn will wake-up the task by calling vTaskNotifyGiveFromISR() */
- gmac_dev_set_rx_callback( &gs_gmac_dev, prvRxCallback );
- gmac_set_address( GMAC, 1, (uint8_t*)llmnr_mac_address );
-
- ncfgr = GMAC_NCFGR_SPD | GMAC_NCFGR_FD;
-
- GMAC->GMAC_NCFGR = ( GMAC->GMAC_NCFGR & ~( GMAC_NCFGR_SPD | GMAC_NCFGR_FD ) ) | ncfgr;
-
- return 1;
-}
-/*-----------------------------------------------------------*/
-
-static inline unsigned long ulReadMDIO( unsigned /*short*/ usAddress )
-{
-uint32_t ulValue, ulReturn;
-int rc;
-
- gmac_enable_management( GMAC, 1 );
- rc = gmac_phy_read( GMAC, ethernet_phy_addr, usAddress, &ulValue );
- gmac_enable_management( GMAC, 0 );
- if( rc == GMAC_OK )
- {
- ulReturn = ulValue;
- }
- else
- {
- ulReturn = 0UL;
- }
-
- return ulReturn;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
-{
-TickType_t xStartTime = xTaskGetTickCount();
-TickType_t xEndTime;
-BaseType_t xReturn;
-const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
-
- for( ;; )
- {
- xEndTime = xTaskGetTickCount();
-
- if( ( xEndTime - xStartTime ) > xMaxTime )
- {
- /* Wated more than xMaxTime, return. */
- xReturn = pdFALSE;
- break;
- }
-
- /* Check the link status again. */
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- /* Link is up - return. */
- xReturn = pdTRUE;
- break;
- }
-
- /* Link is down - wait in the Blocked state for a short while (to allow
- other tasks to execute) before checking again. */
- vTaskDelay( xShortTime );
- }
-
- FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
- xReturn,
- ethernet_phy_addr,
- sysclk_get_cpu_hz() / HZ_PER_MHZ ) );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-//#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
-
- void vGMACGenerateChecksum( uint8_t *apBuffer )
- {
- ProtocolPacket_t *xProtPacket = (ProtocolPacket_t *)apBuffer;
-
- if ( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
- {
- IPHeader_t *pxIPHeader = &(xProtPacket->xTCPPacket.xIPHeader);
-
- /* Calculate the IP header checksum. */
- pxIPHeader->usHeaderChecksum = 0x00;
- pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
- pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
-
- /* Calculate the TCP checksum for an outgoing packet. */
- usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, pdTRUE );
- }
- }
-
-//#endif
-/*-----------------------------------------------------------*/
-
-static uint32_t prvEMACRxPoll( void )
-{
-unsigned char *pucUseBuffer;
-uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
-static NetworkBufferDescriptor_t *pxNextNetworkBufferDescriptor = NULL;
-const UBaseType_t xMinDescriptorsToLeave = 2UL;
-const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
-static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- for( ;; )
- {
- /* If pxNextNetworkBufferDescriptor was not left pointing at a valid
- descriptor then allocate one now. */
- if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
- {
- pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
- }
-
- if( pxNextNetworkBufferDescriptor != NULL )
- {
- /* Point pucUseBuffer to the buffer pointed to by the descriptor. */
- pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
- }
- else
- {
- /* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
- messages will be flushed and ignored. */
- pucUseBuffer = NULL;
- }
-
- /* Read the next packet from the hardware into pucUseBuffer. */
- ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount );
-
- if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
- {
- /* No data from the hardware. */
- break;
- }
-
- if( pxNextNetworkBufferDescriptor == NULL )
- {
- /* Data was read from the hardware, but no descriptor was available
- for it, so it will be dropped. */
- iptraceETHERNET_RX_EVENT_LOST();
- continue;
- }
-
- iptraceNETWORK_INTERFACE_RECEIVE();
- pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
- xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;
-
- /* Send the descriptor to the IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
- {
- /* The buffer could not be sent to the stack so must be released
- again. */
- vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
- }
-
- /* Now the buffer has either been passed to the IP-task,
- or it has been released in the code above. */
- pxNextNetworkBufferDescriptor = NULL;
- ulReturnValue++;
- }
-
- return ulReturnValue;
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0, uxCount;
-UBaseType_t uxCurrentCount;
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- UBaseType_t uxLastMinQueueSpace;
-#endif
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxBuffer;
-#endif
-uint8_t *pucBuffer;
-BaseType_t xResult = 0;
-uint32_t xStatus;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- configASSERT( xEMACTaskHandle );
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- for( ;; )
- {
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- /* Wait for the EMAC interrupt to indicate that another packet has been
- received. */
- xResult = prvEMACRxPoll();
- }
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Future extension: code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
- if( pxBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- tx_release_count[ 0 ]++;
- }
- else
- {
- tx_release_count[ 1 ]++;
- }
- }
- #else
- {
- tx_release_count[ 0 ]++;
- }
- #endif
- uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
- if( uxCount < GMAC_TX_BUFFERS )
- {
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
- }
- }
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
- {
- /* Future extension: logging about errors that occurred. */
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
- }
-
- if( xResult > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- /* Check the link status again. */
- xStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* Some files from the Atmel Software Framework */
+/*_RB_ The SAM4E portable layer has three different header files called gmac.h! */
+#include "instance/gmac.h"
+#include <sysclk.h>
+#include <ethernet_phy.h>
+
+#ifndef BMSR_LINK_STATUS
+ #define BMSR_LINK_STATUS 0x0004 //!< Link status
+#endif
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* Interrupt events to process. Currently only the Rx event is processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
+
+#define HZ_PER_MHZ ( 1000000UL )
+
+#ifndef EMAC_MAX_BLOCK_TIME_MS
+ #define EMAC_MAX_BLOCK_TIME_MS 100ul
+#endif
+
+#if !defined( GMAC_USES_TX_CALLBACK ) || ( GMAC_USES_TX_CALLBACK != 1 )
+ #error Please define GMAC_USES_TX_CALLBACK as 1
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to 4x
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 4 * configMINIMAL_STACK_SIZE )
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Wait a fixed time for the link status to indicate the network is up.
+ */
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
+
+#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
+ void vGMACGenerateChecksum( uint8_t *apBuffer );
+#endif
+
+/*
+ * Called from the ASF GMAC driver.
+ */
+static void prvRxCallback( uint32_t ulStatus );
+static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer );
+
+/*
+ * A deferred interrupt handler task that processes GMAC interrupts.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Initialise the ASF GMAC driver.
+ */
+static BaseType_t prvGMACInit( void );
+
+/*
+ * Try to obtain an Rx packet from the hardware.
+ */
+static uint32_t prvEMACRxPoll( void );
+
+/*-----------------------------------------------------------*/
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx interrupt is handled, although code is included for other events to
+enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+static volatile BaseType_t xGMACSwitchRequired;
+
+/* ethernet_phy_addr: the address of the PHY in use.
+Atmel was a bit ambiguous about it so the address will be stored
+in this variable, see ethernet_phy.c */
+extern int ethernet_phy_addr;
+
+/* LLMNR multicast address. */
+static const uint8_t llmnr_mac_address[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
+
+/* The GMAC object as defined by the ASF drivers. */
+static gmac_device_t gs_gmac_dev;
+
+/* MAC address to use. */
+extern const uint8_t ucMACAddress[ 6 ];
+
+/* Holds the handle of the task used as a deferred interrupt processor. The
+handle is used so direct notifications can be sent to the task for all EMAC/DMA
+related interrupts. */
+TaskHandle_t xEMACTaskHandle = NULL;
+
+static QueueHandle_t xTxBufferQueue;
+int tx_release_count[ 4 ];
+
+/* xTXDescriptorSemaphore is a counting semaphore with
+a maximum count of GMAC_TX_BUFFERS, which is the number of
+DMA TX descriptors. */
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * GMAC interrupt handler.
+ */
+void GMAC_Handler(void)
+{
+ xGMACSwitchRequired = pdFALSE;
+
+ /* gmac_handler() may call prvRxCallback() which may change
+ the value of xGMACSwitchRequired. */
+ gmac_handler( &gs_gmac_dev );
+
+ if( xGMACSwitchRequired != pdFALSE )
+ {
+ portEND_SWITCHING_ISR( xGMACSwitchRequired );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvRxCallback( uint32_t ulStatus )
+{
+ if( ( ( ulStatus & GMAC_RSR_REC ) != 0 ) && ( xEMACTaskHandle != NULL ) )
+ {
+ /* let the prvEMACHandlerTask know that there was an RX event. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ /* Only an RX interrupt can wakeup prvEMACHandlerTask. */
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvTxCallback( uint32_t ulStatus, uint8_t *puc_buffer )
+{
+ if( ( xTxBufferQueue != NULL ) && ( xEMACTaskHandle != NULL ) )
+ {
+ /* let the prvEMACHandlerTask know that there was an RX event. */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xGMACSwitchRequired );
+ xQueueSendFromISR( xTxBufferQueue, &puc_buffer, ( BaseType_t * ) &xGMACSwitchRequired );
+ tx_release_count[ 2 ]++;
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+const TickType_t x5_Seconds = 5000UL;
+
+ if( xEMACTaskHandle == NULL )
+ {
+ prvGMACInit();
+
+ /* Wait at most 5 seconds for a Link Status in the PHY. */
+ xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ configASSERT( xEMACTaskHandle );
+ }
+
+ if( xTxBufferQueue == NULL )
+ {
+ xTxBufferQueue = xQueueCreate( GMAC_TX_BUFFERS, sizeof( void * ) );
+ configASSERT( xTxBufferQueue );
+ }
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) GMAC_TX_BUFFERS, ( UBaseType_t ) GMAC_TX_BUFFERS );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+ /* When returning non-zero, the stack will become active and
+ start DHCP (in configured) */
+ return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xResult;
+
+ /* This function returns true if the Link Status in the PHY is high. */
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xResult = pdTRUE;
+ }
+ else
+ {
+ xResult = pdFALSE;
+ }
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
+{
+/* Do not wait too long for a free TX DMA buffer. */
+const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
+
+ do {
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ {
+ /* Do not attempt to send packets as long as the Link Status is low. */
+ break;
+ }
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ /* Semaphore has not been created yet? */
+ break;
+ }
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ /* Time-out waiting for a free TX descriptor. */
+ tx_release_count[ 3 ]++;
+ break;
+ }
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Confirm that the pxDescriptor may be kept by the driver. */
+ configASSERT( bReleaseAfterSend != pdFALSE );
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ gmac_dev_write( &gs_gmac_dev, (void *)pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength, prvTxCallback );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Confirm that the pxDescriptor may be kept by the driver. */
+ bReleaseAfterSend = pdFALSE;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ /* Not interested in a call-back after TX. */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ } while( 0 );
+
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvGMACInit( void )
+{
+uint32_t ncfgr;
+
+ gmac_options_t gmac_option;
+
+ memset( &gmac_option, '\0', sizeof( gmac_option ) );
+ gmac_option.uc_copy_all_frame = 0;
+ gmac_option.uc_no_boardcast = 0;
+ memcpy( gmac_option.uc_mac_addr, ucMACAddress, sizeof( gmac_option.uc_mac_addr ) );
+
+ gs_gmac_dev.p_hw = GMAC;
+ gmac_dev_init( GMAC, &gs_gmac_dev, &gmac_option );
+
+ NVIC_SetPriority( GMAC_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_EnableIRQ( GMAC_IRQn );
+
+ /* Contact the Ethernet PHY and store it's address in 'ethernet_phy_addr' */
+ ethernet_phy_init( GMAC, ETHERNET_CONF_PHY_ADDR, sysclk_get_cpu_hz() );
+
+ ethernet_phy_auto_negotiate( GMAC, ethernet_phy_addr );
+ ethernet_phy_set_link( GMAC, ethernet_phy_addr, 1 );
+
+ /* The GMAC driver will call a hook prvRxCallback(), which
+ in turn will wake-up the task by calling vTaskNotifyGiveFromISR() */
+ gmac_dev_set_rx_callback( &gs_gmac_dev, prvRxCallback );
+ gmac_set_address( GMAC, 1, (uint8_t*)llmnr_mac_address );
+
+ ncfgr = GMAC_NCFGR_SPD | GMAC_NCFGR_FD;
+
+ GMAC->GMAC_NCFGR = ( GMAC->GMAC_NCFGR & ~( GMAC_NCFGR_SPD | GMAC_NCFGR_FD ) ) | ncfgr;
+
+ return 1;
+}
+/*-----------------------------------------------------------*/
+
+static inline unsigned long ulReadMDIO( unsigned /*short*/ usAddress )
+{
+uint32_t ulValue, ulReturn;
+int rc;
+
+ gmac_enable_management( GMAC, 1 );
+ rc = gmac_phy_read( GMAC, ethernet_phy_addr, usAddress, &ulValue );
+ gmac_enable_management( GMAC, 0 );
+ if( rc == GMAC_OK )
+ {
+ ulReturn = ulValue;
+ }
+ else
+ {
+ ulReturn = 0UL;
+ }
+
+ return ulReturn;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
+{
+TickType_t xStartTime = xTaskGetTickCount();
+TickType_t xEndTime;
+BaseType_t xReturn;
+const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
+
+ for( ;; )
+ {
+ xEndTime = xTaskGetTickCount();
+
+ if( ( xEndTime - xStartTime ) > xMaxTime )
+ {
+ /* Wated more than xMaxTime, return. */
+ xReturn = pdFALSE;
+ break;
+ }
+
+ /* Check the link status again. */
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ /* Link is up - return. */
+ xReturn = pdTRUE;
+ break;
+ }
+
+ /* Link is down - wait in the Blocked state for a short while (to allow
+ other tasks to execute) before checking again. */
+ vTaskDelay( xShortTime );
+ }
+
+ FreeRTOS_printf( ( "xGMACWaitLS: %ld (PHY %d) freq %lu Mz\n",
+ xReturn,
+ ethernet_phy_addr,
+ sysclk_get_cpu_hz() / HZ_PER_MHZ ) );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+//#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 1 ) && ( ipconfigHAS_TX_CRC_OFFLOADING == 0 )
+
+ void vGMACGenerateChecksum( uint8_t *apBuffer )
+ {
+ ProtocolPacket_t *xProtPacket = (ProtocolPacket_t *)apBuffer;
+
+ if ( xProtPacket->xTCPPacket.xEthernetHeader.usFrameType == ipIPv4_FRAME_TYPE )
+ {
+ IPHeader_t *pxIPHeader = &(xProtPacket->xTCPPacket.xIPHeader);
+
+ /* Calculate the IP header checksum. */
+ pxIPHeader->usHeaderChecksum = 0x00;
+ pxIPHeader->usHeaderChecksum = usGenerateChecksum( 0, ( uint8_t * ) &( pxIPHeader->ucVersionHeaderLength ), ipSIZE_OF_IPv4_HEADER );
+ pxIPHeader->usHeaderChecksum = ~FreeRTOS_htons( pxIPHeader->usHeaderChecksum );
+
+ /* Calculate the TCP checksum for an outgoing packet. */
+ usGenerateProtocolChecksum( ( uint8_t * ) apBuffer, pdTRUE );
+ }
+ }
+
+//#endif
+/*-----------------------------------------------------------*/
+
+static uint32_t prvEMACRxPoll( void )
+{
+unsigned char *pucUseBuffer;
+uint32_t ulReceiveCount, ulResult, ulReturnValue = 0;
+static NetworkBufferDescriptor_t *pxNextNetworkBufferDescriptor = NULL;
+const UBaseType_t xMinDescriptorsToLeave = 2UL;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 100UL );
+static IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+ for( ;; )
+ {
+ /* If pxNextNetworkBufferDescriptor was not left pointing at a valid
+ descriptor then allocate one now. */
+ if( ( pxNextNetworkBufferDescriptor == NULL ) && ( uxGetNumberOfFreeNetworkBuffers() > xMinDescriptorsToLeave ) )
+ {
+ pxNextNetworkBufferDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xBlockTime );
+ }
+
+ if( pxNextNetworkBufferDescriptor != NULL )
+ {
+ /* Point pucUseBuffer to the buffer pointed to by the descriptor. */
+ pucUseBuffer = ( unsigned char* ) ( pxNextNetworkBufferDescriptor->pucEthernetBuffer - ipconfigPACKET_FILLER_SIZE );
+ }
+ else
+ {
+ /* As long as pxNextNetworkBufferDescriptor is NULL, the incoming
+ messages will be flushed and ignored. */
+ pucUseBuffer = NULL;
+ }
+
+ /* Read the next packet from the hardware into pucUseBuffer. */
+ ulResult = gmac_dev_read( &gs_gmac_dev, pucUseBuffer, ipTOTAL_ETHERNET_FRAME_SIZE, &ulReceiveCount );
+
+ if( ( ulResult != GMAC_OK ) || ( ulReceiveCount == 0 ) )
+ {
+ /* No data from the hardware. */
+ break;
+ }
+
+ if( pxNextNetworkBufferDescriptor == NULL )
+ {
+ /* Data was read from the hardware, but no descriptor was available
+ for it, so it will be dropped. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ continue;
+ }
+
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ pxNextNetworkBufferDescriptor->xDataLength = ( size_t ) ulReceiveCount;
+ xRxEvent.pvData = ( void * ) pxNextNetworkBufferDescriptor;
+
+ /* Send the descriptor to the IP task for processing. */
+ if( xSendEventStructToIPTask( &xRxEvent, xBlockTime ) != pdTRUE )
+ {
+ /* The buffer could not be sent to the stack so must be released
+ again. */
+ vReleaseNetworkBufferAndDescriptor( pxNextNetworkBufferDescriptor );
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
+ }
+
+ /* Now the buffer has either been passed to the IP-task,
+ or it has been released in the code above. */
+ pxNextNetworkBufferDescriptor = NULL;
+ ulReturnValue++;
+ }
+
+ return ulReturnValue;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0, uxCount;
+UBaseType_t uxCurrentCount;
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ UBaseType_t uxLastMinQueueSpace;
+#endif
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxBuffer;
+#endif
+uint8_t *pucBuffer;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ configASSERT( xEMACTaskHandle );
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
+ if( uxLastMinBufferCount != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
+ }
+
+ #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+
+ if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ /* Wait for the EMAC interrupt to indicate that another packet has been
+ received. */
+ xResult = prvEMACRxPoll();
+ }
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Future extension: code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ while( xQueueReceive( xTxBufferQueue, &pucBuffer, 0 ) != pdFALSE )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ pxBuffer = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
+ if( pxBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ tx_release_count[ 0 ]++;
+ }
+ else
+ {
+ tx_release_count[ 1 ]++;
+ }
+ }
+ #else
+ {
+ tx_release_count[ 0 ]++;
+ }
+ #endif
+ uxCount = uxQueueMessagesWaiting( ( QueueHandle_t ) xTXDescriptorSemaphore );
+ if( uxCount < GMAC_TX_BUFFERS )
+ {
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+ }
+ }
+
+ if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
+ {
+ /* Future extension: logging about errors that occurred. */
+ ulISREvents &= ~EMAC_IF_ERR_EVENT;
+ }
+
+ if( xResult > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ /* Check the link status again. */
+ xStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h
index 6eb069f55..ae40ac960 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/component/gmac.h
@@ -1,746 +1,746 @@
-/**
- * \file
- *
- * Copyright (c) 2012 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef _SAM4E_GMAC_COMPONENT_
-#define _SAM4E_GMAC_COMPONENT_
-
-/* ============================================================================= */
-/** SOFTWARE API DEFINITION FOR Gigabit Ethernet MAC */
-/* ============================================================================= */
-/** \addtogroup SAM4E_GMAC Gigabit Ethernet MAC */
-/*@{*/
-
-#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
-/** \brief GmacSa hardware registers */
-typedef struct {
- RwReg GMAC_SAB; /**< \brief (GmacSa Offset: 0x0) Specific Address 1 Bottom [31:0] Register */
- RwReg GMAC_SAT; /**< \brief (GmacSa Offset: 0x4) Specific Address 1 Top [47:32] Register */
-} GmacSa;
-/** \brief Gmac hardware registers */
-#define GMACSA_NUMBER 4
-typedef struct {
- RwReg GMAC_NCR; /**< \brief (Gmac Offset: 0x000) Network Control Register */
- RwReg GMAC_NCFGR; /**< \brief (Gmac Offset: 0x004) Network Configuration Register */
- RoReg GMAC_NSR; /**< \brief (Gmac Offset: 0x008) Network Status Register */
- RwReg GMAC_UR; /**< \brief (Gmac Offset: 0x00C) User Register */
- RwReg GMAC_DCFGR; /**< \brief (Gmac Offset: 0x010) DMA Configuration Register */
- RwReg GMAC_TSR; /**< \brief (Gmac Offset: 0x014) Transmit Status Register */
- RwReg GMAC_RBQB; /**< \brief (Gmac Offset: 0x018) Receive Buffer Queue Base Address */
- RwReg GMAC_TBQB; /**< \brief (Gmac Offset: 0x01C) Transmit Buffer Queue Base Address */
- RwReg GMAC_RSR; /**< \brief (Gmac Offset: 0x020) Receive Status Register */
- RoReg GMAC_ISR; /**< \brief (Gmac Offset: 0x024) Interrupt Status Register */
- WoReg GMAC_IER; /**< \brief (Gmac Offset: 0x028) Interrupt Enable Register */
- WoReg GMAC_IDR; /**< \brief (Gmac Offset: 0x02C) Interrupt Disable Register */
- RoReg GMAC_IMR; /**< \brief (Gmac Offset: 0x030) Interrupt Mask Register */
- RwReg GMAC_MAN; /**< \brief (Gmac Offset: 0x034) PHY Maintenance Register */
- RoReg GMAC_RPQ; /**< \brief (Gmac Offset: 0x038) Received Pause Quantum Register */
- RwReg GMAC_TPQ; /**< \brief (Gmac Offset: 0x03C) Transmit Pause Quantum Register */
- RwReg GMAC_TPSF; /**< \brief (Gmac Offset: 0x040) TX Partial Store and Forward Register */
- RwReg GMAC_RPSF; /**< \brief (Gmac Offset: 0x044) RX Partial Store and Forward Register */
- RoReg Reserved1[14];
- RwReg GMAC_HRB; /**< \brief (Gmac Offset: 0x080) Hash Register Bottom [31:0] */
- RwReg GMAC_HRT; /**< \brief (Gmac Offset: 0x084) Hash Register Top [63:32] */
- GmacSa GMAC_SA[GMACSA_NUMBER]; /**< \brief (Gmac Offset: 0x088) 1 .. 4 */
- RwReg GMAC_TIDM[4]; /**< \brief (Gmac Offset: 0x0A8) Type ID Match 1 Register */
- RwReg GMAC_WOL; /**< \brief (Gmac Offset: 0x0B8) Wake on LAN Register */
- RwReg GMAC_IPGS; /**< \brief (Gmac Offset: 0x0BC) IPG Stretch Register */
- RwReg GMAC_SVLAN; /**< \brief (Gmac Offset: 0x0C0) Stacked VLAN Register */
- RwReg GMAC_TPFCP; /**< \brief (Gmac Offset: 0x0C4) Transmit PFC Pause Register */
- RwReg GMAC_SAMB1; /**< \brief (Gmac Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register */
- RwReg GMAC_SAMT1; /**< \brief (Gmac Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register */
- RoReg Reserved2[12];
- RoReg GMAC_OTLO; /**< \brief (Gmac Offset: 0x100) Octets Transmitted [31:0] Register */
- RoReg GMAC_OTHI; /**< \brief (Gmac Offset: 0x104) Octets Transmitted [47:32] Register */
- RoReg GMAC_FT; /**< \brief (Gmac Offset: 0x108) Frames Transmitted Register */
- RoReg GMAC_BCFT; /**< \brief (Gmac Offset: 0x10C) Broadcast Frames Transmitted Register */
- RoReg GMAC_MFT; /**< \brief (Gmac Offset: 0x110) Multicast Frames Transmitted Register */
- RoReg GMAC_PFT; /**< \brief (Gmac Offset: 0x114) Pause Frames Transmitted Register */
- RoReg GMAC_BFT64; /**< \brief (Gmac Offset: 0x118) 64 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT127; /**< \brief (Gmac Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT255; /**< \brief (Gmac Offset: 0x120) 128 to 255 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT511; /**< \brief (Gmac Offset: 0x124) 256 to 511 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT1023; /**< \brief (Gmac Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register */
- RoReg GMAC_TBFT1518; /**< \brief (Gmac Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register */
- RoReg GMAC_GTBFT1518; /**< \brief (Gmac Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register */
- RoReg GMAC_TUR; /**< \brief (Gmac Offset: 0x134) Transmit Under Runs Register */
- RoReg GMAC_SCF; /**< \brief (Gmac Offset: 0x138) Single Collision Frames Register */
- RoReg GMAC_MCF; /**< \brief (Gmac Offset: 0x13C) Multiple Collision Frames Register */
- RoReg GMAC_EC; /**< \brief (Gmac Offset: 0x140) Excessive Collisions Register */
- RoReg GMAC_LC; /**< \brief (Gmac Offset: 0x144) Late Collisions Register */
- RoReg GMAC_DTF; /**< \brief (Gmac Offset: 0x148) Deferred Transmission Frames Register */
- RoReg GMAC_CSE; /**< \brief (Gmac Offset: 0x14C) Carrier Sense Errors Register */
- RoReg GMAC_ORLO; /**< \brief (Gmac Offset: 0x150) Octets Received [31:0] Received */
- RoReg GMAC_ORHI; /**< \brief (Gmac Offset: 0x154) Octets Received [47:32] Received */
- RoReg GMAC_FR; /**< \brief (Gmac Offset: 0x158) Frames Received Register */
- RoReg GMAC_BCFR; /**< \brief (Gmac Offset: 0x15C) Broadcast Frames Received Register */
- RoReg GMAC_MFR; /**< \brief (Gmac Offset: 0x160) Multicast Frames Received Register */
- RoReg GMAC_PFR; /**< \brief (Gmac Offset: 0x164) Pause Frames Received Register */
- RoReg GMAC_BFR64; /**< \brief (Gmac Offset: 0x168) 64 Byte Frames Received Register */
- RoReg GMAC_TBFR127; /**< \brief (Gmac Offset: 0x16C) 65 to 127 Byte Frames Received Register */
- RoReg GMAC_TBFR255; /**< \brief (Gmac Offset: 0x170) 128 to 255 Byte Frames Received Register */
- RoReg GMAC_TBFR511; /**< \brief (Gmac Offset: 0x174) 256 to 511Byte Frames Received Register */
- RoReg GMAC_TBFR1023; /**< \brief (Gmac Offset: 0x178) 512 to 1023 Byte Frames Received Register */
- RoReg GMAC_TBFR1518; /**< \brief (Gmac Offset: 0x17C) 1024 to 1518 Byte Frames Received Register */
- RoReg GMAC_TMXBFR; /**< \brief (Gmac Offset: 0x180) 1519 to Maximum Byte Frames Received Register */
- RoReg GMAC_UFR; /**< \brief (Gmac Offset: 0x184) Undersize Frames Received Register */
- RoReg GMAC_OFR; /**< \brief (Gmac Offset: 0x188) Oversize Frames Received Register */
- RoReg GMAC_JR; /**< \brief (Gmac Offset: 0x18C) Jabbers Received Register */
- RoReg GMAC_FCSE; /**< \brief (Gmac Offset: 0x190) Frame Check Sequence Errors Register */
- RoReg GMAC_LFFE; /**< \brief (Gmac Offset: 0x194) Length Field Frame Errors Register */
- RoReg GMAC_RSE; /**< \brief (Gmac Offset: 0x198) Receive Symbol Errors Register */
- RoReg GMAC_AE; /**< \brief (Gmac Offset: 0x19C) Alignment Errors Register */
- RoReg GMAC_RRE; /**< \brief (Gmac Offset: 0x1A0) Receive Resource Errors Register */
- RoReg GMAC_ROE; /**< \brief (Gmac Offset: 0x1A4) Receive Overrun Register */
- RoReg GMAC_IHCE; /**< \brief (Gmac Offset: 0x1A8) IP Header Checksum Errors Register */
- RoReg GMAC_TCE; /**< \brief (Gmac Offset: 0x1AC) TCP Checksum Errors Register */
- RoReg GMAC_UCE; /**< \brief (Gmac Offset: 0x1B0) UDP Checksum Errors Register */
- RoReg Reserved3[5];
- RwReg GMAC_TSSS; /**< \brief (Gmac Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register */
- RwReg GMAC_TSSN; /**< \brief (Gmac Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register */
- RwReg GMAC_TS; /**< \brief (Gmac Offset: 0x1D0) 1588 Timer Seconds Register */
- RwReg GMAC_TN; /**< \brief (Gmac Offset: 0x1D4) 1588 Timer Nanoseconds Register */
- WoReg GMAC_TA; /**< \brief (Gmac Offset: 0x1D8) 1588 Timer Adjust Register */
- RwReg GMAC_TI; /**< \brief (Gmac Offset: 0x1DC) 1588 Timer Increment Register */
- RoReg GMAC_EFTS; /**< \brief (Gmac Offset: 0x1E0) PTP Event Frame Transmitted Seconds */
- RoReg GMAC_EFTN; /**< \brief (Gmac Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds */
- RoReg GMAC_EFRS; /**< \brief (Gmac Offset: 0x1E8) PTP Event Frame Received Seconds */
- RoReg GMAC_EFRN; /**< \brief (Gmac Offset: 0x1EC) PTP Event Frame Received Nanoseconds */
- RoReg GMAC_PEFTS; /**< \brief (Gmac Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds */
- RoReg GMAC_PEFTN; /**< \brief (Gmac Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds */
- RoReg GMAC_PEFRS; /**< \brief (Gmac Offset: 0x1F8) PTP Peer Event Frame Received Seconds */
- RoReg GMAC_PEFRN; /**< \brief (Gmac Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds */
- RoReg Reserved4[128];
- RoReg GMAC_ISRPQ[7]; /**< \brief (Gmac Offset: 0x400) Interrupt Status Register Priority Queue */
- RoReg Reserved5[9];
- RwReg GMAC_TBQBAPQ[7]; /**< \brief (Gmac Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue */
- RoReg Reserved6[9];
- RwReg GMAC_RBQBAPQ[7]; /**< \brief (Gmac Offset: 0x480) Receive Buffer Queue Base Address Priority Queue */
- RoReg Reserved7[1];
- RwReg GMAC_RBSRPQ[7]; /**< \brief (Gmac Offset: 0x4A0) Receive Buffer Size Register Priority Queue */
- RoReg Reserved8[17];
- RwReg GMAC_ST1RPQ[16]; /**< \brief (Gmac Offset: 0x500) Screening Type1 Register Priority Queue */
- RwReg GMAC_ST2RPQ[16]; /**< \brief (Gmac Offset: 0x540) Screening Type2 Register Priority Queue */
- RoReg Reserved9[32];
- WoReg GMAC_IERPQ[7]; /**< \brief (Gmac Offset: 0x600) Interrupt Enable Register Priority Queue */
- RoReg Reserved10[1];
- WoReg GMAC_IDRPQ[7]; /**< \brief (Gmac Offset: 0x620) Interrupt Disable Register Priority Queue */
- RoReg Reserved11[1];
- RwReg GMAC_IMRPQ[7]; /**< \brief (Gmac Offset: 0x640) Interrupt Mask Register Priority Queue */
-} Gmac;
-#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
-/* -------- GMAC_NCR : (GMAC Offset: 0x000) Network Control Register -------- */
-#define GMAC_NCR_LB (0x1u << 0) /**< \brief (GMAC_NCR) Loop Back */
-#define GMAC_NCR_LBL (0x1u << 1) /**< \brief (GMAC_NCR) Loop Back Local */
-#define GMAC_NCR_RXEN (0x1u << 2) /**< \brief (GMAC_NCR) Receive Enable */
-#define GMAC_NCR_TXEN (0x1u << 3) /**< \brief (GMAC_NCR) Transmit Enable */
-#define GMAC_NCR_MPE (0x1u << 4) /**< \brief (GMAC_NCR) Management Port Enable */
-#define GMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (GMAC_NCR) Clear Statistics Registers */
-#define GMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (GMAC_NCR) Increment Statistics Registers */
-#define GMAC_NCR_WESTAT (0x1u << 7) /**< \brief (GMAC_NCR) Write Enable for Statistics Registers */
-#define GMAC_NCR_BP (0x1u << 8) /**< \brief (GMAC_NCR) Back pressure */
-#define GMAC_NCR_TSTART (0x1u << 9) /**< \brief (GMAC_NCR) Start Transmission */
-#define GMAC_NCR_THALT (0x1u << 10) /**< \brief (GMAC_NCR) Transmit Halt */
-#define GMAC_NCR_TXPF (0x1u << 11) /**< \brief (GMAC_NCR) Transmit Pause Frame */
-#define GMAC_NCR_TXZQPF (0x1u << 12) /**< \brief (GMAC_NCR) Transmit Zero Quantum Pause Frame */
-#define GMAC_NCR_RDS (0x1u << 14) /**< \brief (GMAC_NCR) Read Snapshot */
-#define GMAC_NCR_SRTSM (0x1u << 15) /**< \brief (GMAC_NCR) Store Receive Time Stamp to Memory */
-#define GMAC_NCR_ENPBPR (0x1u << 16) /**< \brief (GMAC_NCR) Enable PFC Priority-based Pause Reception */
-#define GMAC_NCR_TXPBPF (0x1u << 17) /**< \brief (GMAC_NCR) Transmit PFC Priority-based Pause Frame */
-#define GMAC_NCR_FNP (0x1u << 18) /**< \brief (GMAC_NCR) Flush Next Packet */
-/* -------- GMAC_NCFGR : (GMAC Offset: 0x004) Network Configuration Register -------- */
-#define GMAC_NCFGR_SPD (0x1u << 0) /**< \brief (GMAC_NCFGR) Speed */
-#define GMAC_NCFGR_FD (0x1u << 1) /**< \brief (GMAC_NCFGR) Full Duplex */
-#define GMAC_NCFGR_DNVLAN (0x1u << 2) /**< \brief (GMAC_NCFGR) Discard Non-VLAN FRAMES */
-#define GMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (GMAC_NCFGR) Jumbo Frame Size */
-#define GMAC_NCFGR_CAF (0x1u << 4) /**< \brief (GMAC_NCFGR) Copy All Frames */
-#define GMAC_NCFGR_NBC (0x1u << 5) /**< \brief (GMAC_NCFGR) No Broadcast */
-#define GMAC_NCFGR_MTIHEN (0x1u << 6) /**< \brief (GMAC_NCFGR) Multicast Hash Enable */
-#define GMAC_NCFGR_UNIHEN (0x1u << 7) /**< \brief (GMAC_NCFGR) Unicast Hash Enable */
-#define GMAC_NCFGR_MAXFS (0x1u << 8) /**< \brief (GMAC_NCFGR) 1536 Maximum Frame Size */
-#define GMAC_NCFGR_GBE (0x1u << 10) /**< \brief (GMAC_NCFGR) Gigabit Mode Enable */
-#define GMAC_NCFGR_PIS (0x1u << 11) /**< \brief (GMAC_NCFGR) Physical Interface Select */
-#define GMAC_NCFGR_RTY (0x1u << 12) /**< \brief (GMAC_NCFGR) Retry Test */
-#define GMAC_NCFGR_PEN (0x1u << 13) /**< \brief (GMAC_NCFGR) Pause Enable */
-#define GMAC_NCFGR_RXBUFO_Pos 14
-#define GMAC_NCFGR_RXBUFO_Msk (0x3u << GMAC_NCFGR_RXBUFO_Pos) /**< \brief (GMAC_NCFGR) Receive Buffer Offset */
-#define GMAC_NCFGR_RXBUFO(value) ((GMAC_NCFGR_RXBUFO_Msk & ((value) << GMAC_NCFGR_RXBUFO_Pos)))
-#define GMAC_NCFGR_LFERD (0x1u << 16) /**< \brief (GMAC_NCFGR) Length Field Error Frame Discard */
-#define GMAC_NCFGR_RFCS (0x1u << 17) /**< \brief (GMAC_NCFGR) Remove FCS */
-#define GMAC_NCFGR_CLK_Pos 18
-#define GMAC_NCFGR_CLK_Msk (0x7u << GMAC_NCFGR_CLK_Pos) /**< \brief (GMAC_NCFGR) MDC CLock Division */
-#define GMAC_NCFGR_CLK_MCK_8 (0x0u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz) */
-#define GMAC_NCFGR_CLK_MCK_16 (0x1u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz) */
-#define GMAC_NCFGR_CLK_MCK_32 (0x2u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz) */
-#define GMAC_NCFGR_CLK_MCK_48 (0x3u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 48 (MCK up to 120MHz) */
-#define GMAC_NCFGR_CLK_MCK_64 (0x4u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz) */
-#define GMAC_NCFGR_CLK_MCK_96 (0x5u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 96 (MCK up to 240 MHz) */
-#define GMAC_NCFGR_CLK_MCK_128 (0x6u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 128 (MCK up to 320 MHz) */
-#define GMAC_NCFGR_CLK_MCK_224 (0x7u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 224 (MCK up to 540 MHz) */
-#define GMAC_NCFGR_DBW_Pos 21
-#define GMAC_NCFGR_DBW_Msk (0x3u << GMAC_NCFGR_DBW_Pos) /**< \brief (GMAC_NCFGR) Data Bus Width */
-#define GMAC_NCFGR_DBW_DBW32 (0x0u << 21) /**< \brief (GMAC_NCFGR) 32-bit data bus width */
-#define GMAC_NCFGR_DBW_DBW64 (0x1u << 21) /**< \brief (GMAC_NCFGR) 64-bit data bus width */
-#define GMAC_NCFGR_DCPF (0x1u << 23) /**< \brief (GMAC_NCFGR) Disable Copy of Pause Frames */
-#define GMAC_NCFGR_RXCOEN (0x1u << 24) /**< \brief (GMAC_NCFGR) Receive Checksum Offload Enable */
-#define GMAC_NCFGR_EFRHD (0x1u << 25) /**< \brief (GMAC_NCFGR) Enable Frames Received in Half Duplex */
-#define GMAC_NCFGR_IRXFCS (0x1u << 26) /**< \brief (GMAC_NCFGR) Ignore RX FCS */
-#define GMAC_NCFGR_IPGSEN (0x1u << 28) /**< \brief (GMAC_NCFGR) IP Stretch Enable */
-#define GMAC_NCFGR_RXBP (0x1u << 29) /**< \brief (GMAC_NCFGR) Receive Bad Preamble */
-#define GMAC_NCFGR_IRXER (0x1u << 30) /**< \brief (GMAC_NCFGR) Ignore IPG rx_er */
-/* -------- GMAC_NSR : (GMAC Offset: 0x008) Network Status Register -------- */
-#define GMAC_NSR_MDIO (0x1u << 1) /**< \brief (GMAC_NSR) MDIO Input Status */
-#define GMAC_NSR_IDLE (0x1u << 2) /**< \brief (GMAC_NSR) PHY Management Logic Idle */
-/* -------- GMAC_UR : (GMAC Offset: 0x00C) User Register -------- */
-#define GMAC_UR_RGMII (0x1u << 0) /**< \brief (GMAC_UR) RGMII Mode */
-#define GMAC_UR_HDFC (0x1u << 6) /**< \brief (GMAC_UR) Half Duplex Flow Control */
-#define GMAC_UR_BPDG (0x1u << 7) /**< \brief (GMAC_UR) BPDG Bypass Deglitchers */
-/* -------- GMAC_DCFGR : (GMAC Offset: 0x010) DMA Configuration Register -------- */
-#define GMAC_DCFGR_FBLDO_Pos 0
-#define GMAC_DCFGR_FBLDO_Msk (0x1fu << GMAC_DCFGR_FBLDO_Pos) /**< \brief (GMAC_DCFGR) Fixed Burst Length for DMA Data Operations: */
-#define GMAC_DCFGR_FBLDO_SINGLE (0x1u << 0) /**< \brief (GMAC_DCFGR) 00001: Always use SINGLE AHB bursts */
-#define GMAC_DCFGR_FBLDO_INCR4 (0x4u << 0) /**< \brief (GMAC_DCFGR) 001xx: Attempt to use INCR4 AHB bursts (Default) */
-#define GMAC_DCFGR_FBLDO_INCR8 (0x8u << 0) /**< \brief (GMAC_DCFGR) 01xxx: Attempt to use INCR8 AHB bursts */
-#define GMAC_DCFGR_FBLDO_INCR16 (0x10u << 0) /**< \brief (GMAC_DCFGR) 1xxxx: Attempt to use INCR16 AHB bursts */
-#define GMAC_DCFGR_ESMA (0x1u << 6) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Management Descriptor Accesses */
-#define GMAC_DCFGR_ESPA (0x1u << 7) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Packet Data Accesses */
-#define GMAC_DCFGR_RXBMS_Pos 8
-#define GMAC_DCFGR_RXBMS_Msk (0x3u << GMAC_DCFGR_RXBMS_Pos) /**< \brief (GMAC_DCFGR) Receiver Packet Buffer Memory Size Select */
-#define GMAC_DCFGR_RXBMS_EIGHTH (0x0u << 8) /**< \brief (GMAC_DCFGR) 1 Kbyte Memory Size */
-#define GMAC_DCFGR_RXBMS_QUARTER (0x1u << 8) /**< \brief (GMAC_DCFGR) 2 Kbytes Memory Size */
-#define GMAC_DCFGR_RXBMS_HALF (0x2u << 8) /**< \brief (GMAC_DCFGR) 4 Kbytes Memory Size */
-#define GMAC_DCFGR_RXBMS_FULL (0x3u << 8) /**< \brief (GMAC_DCFGR) 8 Kbytes Memory Size */
-#define GMAC_DCFGR_TXPBMS (0x1u << 10) /**< \brief (GMAC_DCFGR) Transmitter Packet Buffer Memory Size Select */
-#define GMAC_DCFGR_TXCOEN (0x1u << 11) /**< \brief (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable */
-#define GMAC_DCFGR_DRBS_Pos 16
-#define GMAC_DCFGR_DRBS_Msk (0xffu << GMAC_DCFGR_DRBS_Pos) /**< \brief (GMAC_DCFGR) DMA Receive Buffer Size */
-#define GMAC_DCFGR_DRBS(value) ((GMAC_DCFGR_DRBS_Msk & ((value) << GMAC_DCFGR_DRBS_Pos)))
-#define GMAC_DCFGR_DDRP (0x1u << 24) /**< \brief (GMAC_DCFGR) DMA Discard Receive Packets */
-/* -------- GMAC_TSR : (GMAC Offset: 0x014) Transmit Status Register -------- */
-#define GMAC_TSR_UBR (0x1u << 0) /**< \brief (GMAC_TSR) Used Bit Read */
-#define GMAC_TSR_COL (0x1u << 1) /**< \brief (GMAC_TSR) Collision Occurred */
-#define GMAC_TSR_RLE (0x1u << 2) /**< \brief (GMAC_TSR) Retry Limit Exceeded */
-#define GMAC_TSR_TXGO (0x1u << 3) /**< \brief (GMAC_TSR) Transmit Go */
-#define GMAC_TSR_TFC (0x1u << 4) /**< \brief (GMAC_TSR) Transmit Frame Corruption due to AHB error */
-#define GMAC_TSR_TXCOMP (0x1u << 5) /**< \brief (GMAC_TSR) Transmit Complete */
-#define GMAC_TSR_UND (0x1u << 6) /**< \brief (GMAC_TSR) Transmit Under Run */
-#define GMAC_TSR_LCO (0x1u << 7) /**< \brief (GMAC_TSR) Late Collision Occurred */
-#define GMAC_TSR_HRESP (0x1u << 8) /**< \brief (GMAC_TSR) HRESP Not OK */
-/* -------- GMAC_RBQB : (GMAC Offset: 0x018) Receive Buffer Queue Base Address -------- */
-#define GMAC_RBQB_ADDR_Pos 2
-#define GMAC_RBQB_ADDR_Msk (0x3fffffffu << GMAC_RBQB_ADDR_Pos) /**< \brief (GMAC_RBQB) Receive buffer queue base address */
-#define GMAC_RBQB_ADDR(value) ((GMAC_RBQB_ADDR_Msk & ((value) << GMAC_RBQB_ADDR_Pos)))
-/* -------- GMAC_TBQB : (GMAC Offset: 0x01C) Transmit Buffer Queue Base Address -------- */
-#define GMAC_TBQB_ADDR_Pos 2
-#define GMAC_TBQB_ADDR_Msk (0x3fffffffu << GMAC_TBQB_ADDR_Pos) /**< \brief (GMAC_TBQB) Transmit Buffer Queue Base Address */
-#define GMAC_TBQB_ADDR(value) ((GMAC_TBQB_ADDR_Msk & ((value) << GMAC_TBQB_ADDR_Pos)))
-/* -------- GMAC_RSR : (GMAC Offset: 0x020) Receive Status Register -------- */
-#define GMAC_RSR_BNA (0x1u << 0) /**< \brief (GMAC_RSR) Buffer Not Available */
-#define GMAC_RSR_REC (0x1u << 1) /**< \brief (GMAC_RSR) Frame Received */
-#define GMAC_RSR_RXOVR (0x1u << 2) /**< \brief (GMAC_RSR) Receive Overrun */
-#define GMAC_RSR_HNO (0x1u << 3) /**< \brief (GMAC_RSR) HRESP Not OK */
-/* -------- GMAC_ISR : (GMAC Offset: 0x024) Interrupt Status Register -------- */
-#define GMAC_ISR_MFS (0x1u << 0) /**< \brief (GMAC_ISR) Management Frame Sent */
-#define GMAC_ISR_RCOMP (0x1u << 1) /**< \brief (GMAC_ISR) Receive Complete */
-#define GMAC_ISR_RXUBR (0x1u << 2) /**< \brief (GMAC_ISR) RX Used Bit Read */
-#define GMAC_ISR_TXUBR (0x1u << 3) /**< \brief (GMAC_ISR) TX Used Bit Read */
-#define GMAC_ISR_TUR (0x1u << 4) /**< \brief (GMAC_ISR) Transmit Under Run */
-#define GMAC_ISR_RLEX (0x1u << 5) /**< \brief (GMAC_ISR) Retry Limit Exceeded or Late Collision */
-#define GMAC_ISR_TFC (0x1u << 6) /**< \brief (GMAC_ISR) Transmit Frame Corruption due to AHB error */
-#define GMAC_ISR_TCOMP (0x1u << 7) /**< \brief (GMAC_ISR) Transmit Complete */
-#define GMAC_ISR_ROVR (0x1u << 10) /**< \brief (GMAC_ISR) Receive Overrun */
-#define GMAC_ISR_HRESP (0x1u << 11) /**< \brief (GMAC_ISR) HRESP Not OK */
-#define GMAC_ISR_PFNZ (0x1u << 12) /**< \brief (GMAC_ISR) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_ISR_PTZ (0x1u << 13) /**< \brief (GMAC_ISR) Pause Time Zero */
-#define GMAC_ISR_PFTR (0x1u << 14) /**< \brief (GMAC_ISR) Pause Frame Transmitted */
-#define GMAC_ISR_EXINT (0x1u << 15) /**< \brief (GMAC_ISR) External Interrupt */
-#define GMAC_ISR_DRQFR (0x1u << 18) /**< \brief (GMAC_ISR) PTP Delay Request Frame Received */
-#define GMAC_ISR_SFR (0x1u << 19) /**< \brief (GMAC_ISR) PTP Sync Frame Received */
-#define GMAC_ISR_DRQFT (0x1u << 20) /**< \brief (GMAC_ISR) PTP Delay Request Frame Transmitted */
-#define GMAC_ISR_SFT (0x1u << 21) /**< \brief (GMAC_ISR) PTP Sync Frame Transmitted */
-#define GMAC_ISR_PDRQFR (0x1u << 22) /**< \brief (GMAC_ISR) PDelay Request Frame Received */
-#define GMAC_ISR_PDRSFR (0x1u << 23) /**< \brief (GMAC_ISR) PDelay Response Frame Received */
-#define GMAC_ISR_PDRQFT (0x1u << 24) /**< \brief (GMAC_ISR) PDelay Request Frame Transmitted */
-#define GMAC_ISR_PDRSFT (0x1u << 25) /**< \brief (GMAC_ISR) PDelay Response Frame Transmitted */
-#define GMAC_ISR_SRI (0x1u << 26) /**< \brief (GMAC_ISR) TSU Seconds Register Increment */
-#define GMAC_ISR_WOL (0x1u << 28) /**< \brief (GMAC_ISR) Wake On LAN */
-/* -------- GMAC_IER : (GMAC Offset: 0x028) Interrupt Enable Register -------- */
-#define GMAC_IER_MFS (0x1u << 0) /**< \brief (GMAC_IER) Management Frame Sent */
-#define GMAC_IER_RCOMP (0x1u << 1) /**< \brief (GMAC_IER) Receive Complete */
-#define GMAC_IER_RXUBR (0x1u << 2) /**< \brief (GMAC_IER) RX Used Bit Read */
-#define GMAC_IER_TXUBR (0x1u << 3) /**< \brief (GMAC_IER) TX Used Bit Read */
-#define GMAC_IER_TUR (0x1u << 4) /**< \brief (GMAC_IER) Transmit Under Run */
-#define GMAC_IER_RLEX (0x1u << 5) /**< \brief (GMAC_IER) Retry Limit Exceeded or Late Collision */
-#define GMAC_IER_TFC (0x1u << 6) /**< \brief (GMAC_IER) Transmit Frame Corruption due to AHB error */
-#define GMAC_IER_TCOMP (0x1u << 7) /**< \brief (GMAC_IER) Transmit Complete */
-#define GMAC_IER_ROVR (0x1u << 10) /**< \brief (GMAC_IER) Receive Overrun */
-#define GMAC_IER_HRESP (0x1u << 11) /**< \brief (GMAC_IER) HRESP Not OK */
-#define GMAC_IER_PFNZ (0x1u << 12) /**< \brief (GMAC_IER) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_IER_PTZ (0x1u << 13) /**< \brief (GMAC_IER) Pause Time Zero */
-#define GMAC_IER_PFTR (0x1u << 14) /**< \brief (GMAC_IER) Pause Frame Transmitted */
-#define GMAC_IER_EXINT (0x1u << 15) /**< \brief (GMAC_IER) External Interrupt */
-#define GMAC_IER_DRQFR (0x1u << 18) /**< \brief (GMAC_IER) PTP Delay Request Frame Received */
-#define GMAC_IER_SFR (0x1u << 19) /**< \brief (GMAC_IER) PTP Sync Frame Received */
-#define GMAC_IER_DRQFT (0x1u << 20) /**< \brief (GMAC_IER) PTP Delay Request Frame Transmitted */
-#define GMAC_IER_SFT (0x1u << 21) /**< \brief (GMAC_IER) PTP Sync Frame Transmitted */
-#define GMAC_IER_PDRQFR (0x1u << 22) /**< \brief (GMAC_IER) PDelay Request Frame Received */
-#define GMAC_IER_PDRSFR (0x1u << 23) /**< \brief (GMAC_IER) PDelay Response Frame Received */
-#define GMAC_IER_PDRQFT (0x1u << 24) /**< \brief (GMAC_IER) PDelay Request Frame Transmitted */
-#define GMAC_IER_PDRSFT (0x1u << 25) /**< \brief (GMAC_IER) PDelay Response Frame Transmitted */
-#define GMAC_IER_SRI (0x1u << 26) /**< \brief (GMAC_IER) TSU Seconds Register Increment */
-#define GMAC_IER_WOL (0x1u << 28) /**< \brief (GMAC_IER) Wake On LAN */
-/* -------- GMAC_IDR : (GMAC Offset: 0x02C) Interrupt Disable Register -------- */
-#define GMAC_IDR_MFS (0x1u << 0) /**< \brief (GMAC_IDR) Management Frame Sent */
-#define GMAC_IDR_RCOMP (0x1u << 1) /**< \brief (GMAC_IDR) Receive Complete */
-#define GMAC_IDR_RXUBR (0x1u << 2) /**< \brief (GMAC_IDR) RX Used Bit Read */
-#define GMAC_IDR_TXUBR (0x1u << 3) /**< \brief (GMAC_IDR) TX Used Bit Read */
-#define GMAC_IDR_TUR (0x1u << 4) /**< \brief (GMAC_IDR) Transmit Under Run */
-#define GMAC_IDR_RLEX (0x1u << 5) /**< \brief (GMAC_IDR) Retry Limit Exceeded or Late Collision */
-#define GMAC_IDR_TFC (0x1u << 6) /**< \brief (GMAC_IDR) Transmit Frame Corruption due to AHB error */
-#define GMAC_IDR_TCOMP (0x1u << 7) /**< \brief (GMAC_IDR) Transmit Complete */
-#define GMAC_IDR_ROVR (0x1u << 10) /**< \brief (GMAC_IDR) Receive Overrun */
-#define GMAC_IDR_HRESP (0x1u << 11) /**< \brief (GMAC_IDR) HRESP Not OK */
-#define GMAC_IDR_PFNZ (0x1u << 12) /**< \brief (GMAC_IDR) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_IDR_PTZ (0x1u << 13) /**< \brief (GMAC_IDR) Pause Time Zero */
-#define GMAC_IDR_PFTR (0x1u << 14) /**< \brief (GMAC_IDR) Pause Frame Transmitted */
-#define GMAC_IDR_EXINT (0x1u << 15) /**< \brief (GMAC_IDR) External Interrupt */
-#define GMAC_IDR_DRQFR (0x1u << 18) /**< \brief (GMAC_IDR) PTP Delay Request Frame Received */
-#define GMAC_IDR_SFR (0x1u << 19) /**< \brief (GMAC_IDR) PTP Sync Frame Received */
-#define GMAC_IDR_DRQFT (0x1u << 20) /**< \brief (GMAC_IDR) PTP Delay Request Frame Transmitted */
-#define GMAC_IDR_SFT (0x1u << 21) /**< \brief (GMAC_IDR) PTP Sync Frame Transmitted */
-#define GMAC_IDR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IDR) PDelay Request Frame Received */
-#define GMAC_IDR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IDR) PDelay Response Frame Received */
-#define GMAC_IDR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IDR) PDelay Request Frame Transmitted */
-#define GMAC_IDR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IDR) PDelay Response Frame Transmitted */
-#define GMAC_IDR_SRI (0x1u << 26) /**< \brief (GMAC_IDR) TSU Seconds Register Increment */
-#define GMAC_IDR_WOL (0x1u << 28) /**< \brief (GMAC_IDR) Wake On LAN */
-/* -------- GMAC_IMR : (GMAC Offset: 0x030) Interrupt Mask Register -------- */
-#define GMAC_IMR_MFS (0x1u << 0) /**< \brief (GMAC_IMR) Management Frame Sent */
-#define GMAC_IMR_RCOMP (0x1u << 1) /**< \brief (GMAC_IMR) Receive Complete */
-#define GMAC_IMR_RXUBR (0x1u << 2) /**< \brief (GMAC_IMR) RX Used Bit Read */
-#define GMAC_IMR_TXUBR (0x1u << 3) /**< \brief (GMAC_IMR) TX Used Bit Read */
-#define GMAC_IMR_TUR (0x1u << 4) /**< \brief (GMAC_IMR) Transmit Under Run */
-#define GMAC_IMR_RLEX (0x1u << 5) /**< \brief (GMAC_IMR) Retry Limit Exceeded or Late Collision */
-#define GMAC_IMR_TFC (0x1u << 6) /**< \brief (GMAC_IMR) Transmit Frame Corruption due to AHB error */
-#define GMAC_IMR_TCOMP (0x1u << 7) /**< \brief (GMAC_IMR) Transmit Complete */
-#define GMAC_IMR_ROVR (0x1u << 10) /**< \brief (GMAC_IMR) Receive Overrun */
-#define GMAC_IMR_HRESP (0x1u << 11) /**< \brief (GMAC_IMR) HRESP Not OK */
-#define GMAC_IMR_PFNZ (0x1u << 12) /**< \brief (GMAC_IMR) Pause Frame with Non-zero Pause Quantum Received */
-#define GMAC_IMR_PTZ (0x1u << 13) /**< \brief (GMAC_IMR) Pause Time Zero */
-#define GMAC_IMR_PFTR (0x1u << 14) /**< \brief (GMAC_IMR) Pause Frame Transmitted */
-#define GMAC_IMR_EXINT (0x1u << 15) /**< \brief (GMAC_IMR) External Interrupt */
-#define GMAC_IMR_DRQFR (0x1u << 18) /**< \brief (GMAC_IMR) PTP Delay Request Frame Received */
-#define GMAC_IMR_SFR (0x1u << 19) /**< \brief (GMAC_IMR) PTP Sync Frame Received */
-#define GMAC_IMR_DRQFT (0x1u << 20) /**< \brief (GMAC_IMR) PTP Delay Request Frame Transmitted */
-#define GMAC_IMR_SFT (0x1u << 21) /**< \brief (GMAC_IMR) PTP Sync Frame Transmitted */
-#define GMAC_IMR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IMR) PDelay Request Frame Received */
-#define GMAC_IMR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IMR) PDelay Response Frame Received */
-#define GMAC_IMR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IMR) PDelay Request Frame Transmitted */
-#define GMAC_IMR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IMR) PDelay Response Frame Transmitted */
-/* -------- GMAC_MAN : (GMAC Offset: 0x034) PHY Maintenance Register -------- */
-#define GMAC_MAN_DATA_Pos 0
-#define GMAC_MAN_DATA_Msk (0xffffu << GMAC_MAN_DATA_Pos) /**< \brief (GMAC_MAN) PHY Data */
-#define GMAC_MAN_DATA(value) ((GMAC_MAN_DATA_Msk & ((value) << GMAC_MAN_DATA_Pos)))
-#define GMAC_MAN_WTN_Pos 16
-#define GMAC_MAN_WTN_Msk (0x3u << GMAC_MAN_WTN_Pos) /**< \brief (GMAC_MAN) Write Ten */
-#define GMAC_MAN_WTN(value) ((GMAC_MAN_WTN_Msk & ((value) << GMAC_MAN_WTN_Pos)))
-#define GMAC_MAN_REGA_Pos 18
-#define GMAC_MAN_REGA_Msk (0x1fu << GMAC_MAN_REGA_Pos) /**< \brief (GMAC_MAN) Register Address */
-#define GMAC_MAN_REGA(value) ((GMAC_MAN_REGA_Msk & ((value) << GMAC_MAN_REGA_Pos)))
-#define GMAC_MAN_PHYA_Pos 23
-#define GMAC_MAN_PHYA_Msk (0x1fu << GMAC_MAN_PHYA_Pos) /**< \brief (GMAC_MAN) PHY Address */
-#define GMAC_MAN_PHYA(value) ((GMAC_MAN_PHYA_Msk & ((value) << GMAC_MAN_PHYA_Pos)))
-#define GMAC_MAN_OP_Pos 28
-#define GMAC_MAN_OP_Msk (0x3u << GMAC_MAN_OP_Pos) /**< \brief (GMAC_MAN) Operation */
-#define GMAC_MAN_OP(value) ((GMAC_MAN_OP_Msk & ((value) << GMAC_MAN_OP_Pos)))
-#define GMAC_MAN_CLTTO (0x1u << 30) /**< \brief (GMAC_MAN) Clause 22 Operation */
-#define GMAC_MAN_WZO (0x1u << 31) /**< \brief (GMAC_MAN) Write ZERO */
-/* -------- GMAC_RPQ : (GMAC Offset: 0x038) Received Pause Quantum Register -------- */
-#define GMAC_RPQ_RPQ_Pos 0
-#define GMAC_RPQ_RPQ_Msk (0xffffu << GMAC_RPQ_RPQ_Pos) /**< \brief (GMAC_RPQ) Received Pause Quantum */
-/* -------- GMAC_TPQ : (GMAC Offset: 0x03C) Transmit Pause Quantum Register -------- */
-#define GMAC_TPQ_TPQ_Pos 0
-#define GMAC_TPQ_TPQ_Msk (0xffffu << GMAC_TPQ_TPQ_Pos) /**< \brief (GMAC_TPQ) Transmit Pause Quantum */
-#define GMAC_TPQ_TPQ(value) ((GMAC_TPQ_TPQ_Msk & ((value) << GMAC_TPQ_TPQ_Pos)))
-/* -------- GMAC_TPSF : (GMAC Offset: 0x040) TX Partial Store and Forward Register -------- */
-#define GMAC_TPSF_TPB1ADR_Pos 0
-#define GMAC_TPSF_TPB1ADR_Msk (0xfffu << GMAC_TPSF_TPB1ADR_Pos) /**< \brief (GMAC_TPSF) tx_pbuf_addr-1:0 */
-#define GMAC_TPSF_TPB1ADR(value) ((GMAC_TPSF_TPB1ADR_Msk & ((value) << GMAC_TPSF_TPB1ADR_Pos)))
-#define GMAC_TPSF_ENTXP (0x1u << 31) /**< \brief (GMAC_TPSF) Enable TX Partial Store and Forward Operation */
-/* -------- GMAC_RPSF : (GMAC Offset: 0x044) RX Partial Store and Forward Register -------- */
-#define GMAC_RPSF_RPB1ADR_Pos 0
-#define GMAC_RPSF_RPB1ADR_Msk (0xfffu << GMAC_RPSF_RPB1ADR_Pos) /**< \brief (GMAC_RPSF) rx_pbuf_addr-1:0 */
-#define GMAC_RPSF_RPB1ADR(value) ((GMAC_RPSF_RPB1ADR_Msk & ((value) << GMAC_RPSF_RPB1ADR_Pos)))
-#define GMAC_RPSF_ENRXP (0x1u << 31) /**< \brief (GMAC_RPSF) Enable RX Partial Store and Forward Operation */
-/* -------- GMAC_HRB : (GMAC Offset: 0x080) Hash Register Bottom [31:0] -------- */
-#define GMAC_HRB_ADDR_Pos 0
-#define GMAC_HRB_ADDR_Msk (0xffffffffu << GMAC_HRB_ADDR_Pos) /**< \brief (GMAC_HRB) Hash Address */
-#define GMAC_HRB_ADDR(value) ((GMAC_HRB_ADDR_Msk & ((value) << GMAC_HRB_ADDR_Pos)))
-/* -------- GMAC_HRT : (GMAC Offset: 0x084) Hash Register Top [63:32] -------- */
-#define GMAC_HRT_ADDR_Pos 0
-#define GMAC_HRT_ADDR_Msk (0xffffffffu << GMAC_HRT_ADDR_Pos) /**< \brief (GMAC_HRT) Hash Address */
-#define GMAC_HRT_ADDR(value) ((GMAC_HRT_ADDR_Msk & ((value) << GMAC_HRT_ADDR_Pos)))
-/* -------- GMAC_SAB1 : (GMAC Offset: 0x088) Specific Address 1 Bottom [31:0] Register -------- */
-#define GMAC_SAB1_ADDR_Pos 0
-#define GMAC_SAB1_ADDR_Msk (0xffffffffu << GMAC_SAB1_ADDR_Pos) /**< \brief (GMAC_SAB1) Specific Address 1 */
-#define GMAC_SAB1_ADDR(value) ((GMAC_SAB1_ADDR_Msk & ((value) << GMAC_SAB1_ADDR_Pos)))
-/* -------- GMAC_SAT1 : (GMAC Offset: 0x08C) Specific Address 1 Top [47:32] Register -------- */
-#define GMAC_SAT1_ADDR_Pos 0
-#define GMAC_SAT1_ADDR_Msk (0xffffu << GMAC_SAT1_ADDR_Pos) /**< \brief (GMAC_SAT1) Specific Address 1 */
-#define GMAC_SAT1_ADDR(value) ((GMAC_SAT1_ADDR_Msk & ((value) << GMAC_SAT1_ADDR_Pos)))
-/* -------- GMAC_SAB2 : (GMAC Offset: 0x090) Specific Address 2 Bottom [31:0] Register -------- */
-#define GMAC_SAB2_ADDR_Pos 0
-#define GMAC_SAB2_ADDR_Msk (0xffffffffu << GMAC_SAB2_ADDR_Pos) /**< \brief (GMAC_SAB2) Specific Address 2 */
-#define GMAC_SAB2_ADDR(value) ((GMAC_SAB2_ADDR_Msk & ((value) << GMAC_SAB2_ADDR_Pos)))
-/* -------- GMAC_SAT2 : (GMAC Offset: 0x094) Specific Address 2 Top [47:32] Register -------- */
-#define GMAC_SAT2_ADDR_Pos 0
-#define GMAC_SAT2_ADDR_Msk (0xffffu << GMAC_SAT2_ADDR_Pos) /**< \brief (GMAC_SAT2) Specific Address 2 */
-#define GMAC_SAT2_ADDR(value) ((GMAC_SAT2_ADDR_Msk & ((value) << GMAC_SAT2_ADDR_Pos)))
-/* -------- GMAC_SAB3 : (GMAC Offset: 0x098) Specific Address 3 Bottom [31:0] Register -------- */
-#define GMAC_SAB3_ADDR_Pos 0
-#define GMAC_SAB3_ADDR_Msk (0xffffffffu << GMAC_SAB3_ADDR_Pos) /**< \brief (GMAC_SAB3) Specific Address 3 */
-#define GMAC_SAB3_ADDR(value) ((GMAC_SAB3_ADDR_Msk & ((value) << GMAC_SAB3_ADDR_Pos)))
-/* -------- GMAC_SAT3 : (GMAC Offset: 0x09C) Specific Address 3 Top [47:32] Register -------- */
-#define GMAC_SAT3_ADDR_Pos 0
-#define GMAC_SAT3_ADDR_Msk (0xffffu << GMAC_SAT3_ADDR_Pos) /**< \brief (GMAC_SAT3) Specific Address 3 */
-#define GMAC_SAT3_ADDR(value) ((GMAC_SAT3_ADDR_Msk & ((value) << GMAC_SAT3_ADDR_Pos)))
-/* -------- GMAC_SAB4 : (GMAC Offset: 0x0A0) Specific Address 4 Bottom [31:0] Register -------- */
-#define GMAC_SAB4_ADDR_Pos 0
-#define GMAC_SAB4_ADDR_Msk (0xffffffffu << GMAC_SAB4_ADDR_Pos) /**< \brief (GMAC_SAB4) Specific Address 4 */
-#define GMAC_SAB4_ADDR(value) ((GMAC_SAB4_ADDR_Msk & ((value) << GMAC_SAB4_ADDR_Pos)))
-/* -------- GMAC_SAT4 : (GMAC Offset: 0x0A4) Specific Address 4 Top [47:32] Register -------- */
-#define GMAC_SAT4_ADDR_Pos 0
-#define GMAC_SAT4_ADDR_Msk (0xffffu << GMAC_SAT4_ADDR_Pos) /**< \brief (GMAC_SAT4) Specific Address 4 */
-#define GMAC_SAT4_ADDR(value) ((GMAC_SAT4_ADDR_Msk & ((value) << GMAC_SAT4_ADDR_Pos)))
-/* -------- GMAC_TIDM[4] : (GMAC Offset: 0x0A8) Type ID Match 1 Register -------- */
-#define GMAC_TIDM_TID_Pos 0
-#define GMAC_TIDM_TID_Msk (0xffffu << GMAC_TIDM_TID_Pos) /**< \brief (GMAC_TIDM[4]) Type ID Match 1 */
-#define GMAC_TIDM_TID(value) ((GMAC_TIDM_TID_Msk & ((value) << GMAC_TIDM_TID_Pos)))
-/* -------- GMAC_WOL : (GMAC Offset: 0x0B8) Wake on LAN Register -------- */
-#define GMAC_WOL_IP_Pos 0
-#define GMAC_WOL_IP_Msk (0xffffu << GMAC_WOL_IP_Pos) /**< \brief (GMAC_WOL) ARP Request IP Address */
-#define GMAC_WOL_IP(value) ((GMAC_WOL_IP_Msk & ((value) << GMAC_WOL_IP_Pos)))
-#define GMAC_WOL_MAG (0x1u << 16) /**< \brief (GMAC_WOL) Magic Packet Event Enable */
-#define GMAC_WOL_ARP (0x1u << 17) /**< \brief (GMAC_WOL) ARP Request IP Address */
-#define GMAC_WOL_SA1 (0x1u << 18) /**< \brief (GMAC_WOL) Specific Address Register 1 Event Enable */
-#define GMAC_WOL_MTI (0x1u << 19) /**< \brief (GMAC_WOL) Multicast Hash Event Enable */
-/* -------- GMAC_IPGS : (GMAC Offset: 0x0BC) IPG Stretch Register -------- */
-#define GMAC_IPGS_FL_Pos 0
-#define GMAC_IPGS_FL_Msk (0xffffu << GMAC_IPGS_FL_Pos) /**< \brief (GMAC_IPGS) Frame Length */
-#define GMAC_IPGS_FL(value) ((GMAC_IPGS_FL_Msk & ((value) << GMAC_IPGS_FL_Pos)))
-/* -------- GMAC_SVLAN : (GMAC Offset: 0x0C0) Stacked VLAN Register -------- */
-#define GMAC_SVLAN_VLAN_TYPE_Pos 0
-#define GMAC_SVLAN_VLAN_TYPE_Msk (0xffffu << GMAC_SVLAN_VLAN_TYPE_Pos) /**< \brief (GMAC_SVLAN) User Defined VLAN_TYPE Field */
-#define GMAC_SVLAN_VLAN_TYPE(value) ((GMAC_SVLAN_VLAN_TYPE_Msk & ((value) << GMAC_SVLAN_VLAN_TYPE_Pos)))
-#define GMAC_SVLAN_ESVLAN (0x1u << 31) /**< \brief (GMAC_SVLAN) Enable Stacked VLAN Processing Mode */
-/* -------- GMAC_TPFCP : (GMAC Offset: 0x0C4) Transmit PFC Pause Register -------- */
-#define GMAC_TPFCP_PEV_Pos 0
-#define GMAC_TPFCP_PEV_Msk (0xffu << GMAC_TPFCP_PEV_Pos) /**< \brief (GMAC_TPFCP) Priority Enable Vector */
-#define GMAC_TPFCP_PEV(value) ((GMAC_TPFCP_PEV_Msk & ((value) << GMAC_TPFCP_PEV_Pos)))
-#define GMAC_TPFCP_PQ_Pos 8
-#define GMAC_TPFCP_PQ_Msk (0xffu << GMAC_TPFCP_PQ_Pos) /**< \brief (GMAC_TPFCP) Pause Quantum */
-#define GMAC_TPFCP_PQ(value) ((GMAC_TPFCP_PQ_Msk & ((value) << GMAC_TPFCP_PQ_Pos)))
-/* -------- GMAC_SAMB1 : (GMAC Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register -------- */
-#define GMAC_SAMB1_ADDR_Pos 0
-#define GMAC_SAMB1_ADDR_Msk (0xffffffffu << GMAC_SAMB1_ADDR_Pos) /**< \brief (GMAC_SAMB1) Specific Address 1 Mask */
-#define GMAC_SAMB1_ADDR(value) ((GMAC_SAMB1_ADDR_Msk & ((value) << GMAC_SAMB1_ADDR_Pos)))
-/* -------- GMAC_SAMT1 : (GMAC Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register -------- */
-#define GMAC_SAMT1_ADDR_Pos 0
-#define GMAC_SAMT1_ADDR_Msk (0xffffu << GMAC_SAMT1_ADDR_Pos) /**< \brief (GMAC_SAMT1) Specific Address 1 Mask */
-#define GMAC_SAMT1_ADDR(value) ((GMAC_SAMT1_ADDR_Msk & ((value) << GMAC_SAMT1_ADDR_Pos)))
-/* -------- GMAC_OTLO : (GMAC Offset: 0x100) Octets Transmitted [31:0] Register -------- */
-#define GMAC_OTLO_TXO_Pos 0
-#define GMAC_OTLO_TXO_Msk (0xffffffffu << GMAC_OTLO_TXO_Pos) /**< \brief (GMAC_OTLO) Transmitted Octets */
-/* -------- GMAC_OTHI : (GMAC Offset: 0x104) Octets Transmitted [47:32] Register -------- */
-#define GMAC_OTHI_TXO_Pos 0
-#define GMAC_OTHI_TXO_Msk (0xffffu << GMAC_OTHI_TXO_Pos) /**< \brief (GMAC_OTHI) Transmitted Octets */
-/* -------- GMAC_FT : (GMAC Offset: 0x108) Frames Transmitted Register -------- */
-#define GMAC_FT_FTX_Pos 0
-#define GMAC_FT_FTX_Msk (0xffffffffu << GMAC_FT_FTX_Pos) /**< \brief (GMAC_FT) Frames Transmitted without Error */
-/* -------- GMAC_BCFT : (GMAC Offset: 0x10C) Broadcast Frames Transmitted Register -------- */
-#define GMAC_BCFT_BFTX_Pos 0
-#define GMAC_BCFT_BFTX_Msk (0xffffffffu << GMAC_BCFT_BFTX_Pos) /**< \brief (GMAC_BCFT) Broadcast Frames Transmitted without Error */
-/* -------- GMAC_MFT : (GMAC Offset: 0x110) Multicast Frames Transmitted Register -------- */
-#define GMAC_MFT_MFTX_Pos 0
-#define GMAC_MFT_MFTX_Msk (0xffffffffu << GMAC_MFT_MFTX_Pos) /**< \brief (GMAC_MFT) Multicast Frames Transmitted without Error */
-/* -------- GMAC_PFT : (GMAC Offset: 0x114) Pause Frames Transmitted Register -------- */
-#define GMAC_PFT_PFTX_Pos 0
-#define GMAC_PFT_PFTX_Msk (0xffffu << GMAC_PFT_PFTX_Pos) /**< \brief (GMAC_PFT) Pause Frames Transmitted Register */
-/* -------- GMAC_BFT64 : (GMAC Offset: 0x118) 64 Byte Frames Transmitted Register -------- */
-#define GMAC_BFT64_NFTX_Pos 0
-#define GMAC_BFT64_NFTX_Msk (0xffffffffu << GMAC_BFT64_NFTX_Pos) /**< \brief (GMAC_BFT64) 64 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT127 : (GMAC Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT127_NFTX_Pos 0
-#define GMAC_TBFT127_NFTX_Msk (0xffffffffu << GMAC_TBFT127_NFTX_Pos) /**< \brief (GMAC_TBFT127) 65 to 127 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT255 : (GMAC Offset: 0x120) 128 to 255 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT255_NFTX_Pos 0
-#define GMAC_TBFT255_NFTX_Msk (0xffffffffu << GMAC_TBFT255_NFTX_Pos) /**< \brief (GMAC_TBFT255) 128 to 255 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT511 : (GMAC Offset: 0x124) 256 to 511 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT511_NFTX_Pos 0
-#define GMAC_TBFT511_NFTX_Msk (0xffffffffu << GMAC_TBFT511_NFTX_Pos) /**< \brief (GMAC_TBFT511) 256 to 511 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT1023 : (GMAC Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT1023_NFTX_Pos 0
-#define GMAC_TBFT1023_NFTX_Msk (0xffffffffu << GMAC_TBFT1023_NFTX_Pos) /**< \brief (GMAC_TBFT1023) 512 to 1023 Byte Frames Transmitted without Error */
-/* -------- GMAC_TBFT1518 : (GMAC Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register -------- */
-#define GMAC_TBFT1518_NFTX_Pos 0
-#define GMAC_TBFT1518_NFTX_Msk (0xffffffffu << GMAC_TBFT1518_NFTX_Pos) /**< \brief (GMAC_TBFT1518) 1024 to 1518 Byte Frames Transmitted without Error */
-/* -------- GMAC_GTBFT1518 : (GMAC Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register -------- */
-#define GMAC_GTBFT1518_NFTX_Pos 0
-#define GMAC_GTBFT1518_NFTX_Msk (0xffffffffu << GMAC_GTBFT1518_NFTX_Pos) /**< \brief (GMAC_GTBFT1518) Greater than 1518 Byte Frames Transmitted without Error */
-/* -------- GMAC_TUR : (GMAC Offset: 0x134) Transmit Under Runs Register -------- */
-#define GMAC_TUR_TXUNR_Pos 0
-#define GMAC_TUR_TXUNR_Msk (0x3ffu << GMAC_TUR_TXUNR_Pos) /**< \brief (GMAC_TUR) Transmit Under Runs */
-/* -------- GMAC_SCF : (GMAC Offset: 0x138) Single Collision Frames Register -------- */
-#define GMAC_SCF_SCOL_Pos 0
-#define GMAC_SCF_SCOL_Msk (0x3ffffu << GMAC_SCF_SCOL_Pos) /**< \brief (GMAC_SCF) Single Collision */
-/* -------- GMAC_MCF : (GMAC Offset: 0x13C) Multiple Collision Frames Register -------- */
-#define GMAC_MCF_MCOL_Pos 0
-#define GMAC_MCF_MCOL_Msk (0x3ffffu << GMAC_MCF_MCOL_Pos) /**< \brief (GMAC_MCF) Multiple Collision */
-/* -------- GMAC_EC : (GMAC Offset: 0x140) Excessive Collisions Register -------- */
-#define GMAC_EC_XCOL_Pos 0
-#define GMAC_EC_XCOL_Msk (0x3ffu << GMAC_EC_XCOL_Pos) /**< \brief (GMAC_EC) Excessive Collisions */
-/* -------- GMAC_LC : (GMAC Offset: 0x144) Late Collisions Register -------- */
-#define GMAC_LC_LCOL_Pos 0
-#define GMAC_LC_LCOL_Msk (0x3ffu << GMAC_LC_LCOL_Pos) /**< \brief (GMAC_LC) Late Collisions */
-/* -------- GMAC_DTF : (GMAC Offset: 0x148) Deferred Transmission Frames Register -------- */
-#define GMAC_DTF_DEFT_Pos 0
-#define GMAC_DTF_DEFT_Msk (0x3ffffu << GMAC_DTF_DEFT_Pos) /**< \brief (GMAC_DTF) Deferred Transmission */
-/* -------- GMAC_CSE : (GMAC Offset: 0x14C) Carrier Sense Errors Register -------- */
-#define GMAC_CSE_CSR_Pos 0
-#define GMAC_CSE_CSR_Msk (0x3ffu << GMAC_CSE_CSR_Pos) /**< \brief (GMAC_CSE) Carrier Sense Error */
-/* -------- GMAC_ORLO : (GMAC Offset: 0x150) Octets Received [31:0] Received -------- */
-#define GMAC_ORLO_RXO_Pos 0
-#define GMAC_ORLO_RXO_Msk (0xffffffffu << GMAC_ORLO_RXO_Pos) /**< \brief (GMAC_ORLO) Received Octets */
-/* -------- GMAC_ORHI : (GMAC Offset: 0x154) Octets Received [47:32] Received -------- */
-#define GMAC_ORHI_RXO_Pos 0
-#define GMAC_ORHI_RXO_Msk (0xffffu << GMAC_ORHI_RXO_Pos) /**< \brief (GMAC_ORHI) Received Octets */
-/* -------- GMAC_FR : (GMAC Offset: 0x158) Frames Received Register -------- */
-#define GMAC_FR_FRX_Pos 0
-#define GMAC_FR_FRX_Msk (0xffffffffu << GMAC_FR_FRX_Pos) /**< \brief (GMAC_FR) Frames Received without Error */
-/* -------- GMAC_BCFR : (GMAC Offset: 0x15C) Broadcast Frames Received Register -------- */
-#define GMAC_BCFR_BFRX_Pos 0
-#define GMAC_BCFR_BFRX_Msk (0xffffffffu << GMAC_BCFR_BFRX_Pos) /**< \brief (GMAC_BCFR) Broadcast Frames Received without Error */
-/* -------- GMAC_MFR : (GMAC Offset: 0x160) Multicast Frames Received Register -------- */
-#define GMAC_MFR_MFRX_Pos 0
-#define GMAC_MFR_MFRX_Msk (0xffffffffu << GMAC_MFR_MFRX_Pos) /**< \brief (GMAC_MFR) Multicast Frames Received without Error */
-/* -------- GMAC_PFR : (GMAC Offset: 0x164) Pause Frames Received Register -------- */
-#define GMAC_PFR_PFRX_Pos 0
-#define GMAC_PFR_PFRX_Msk (0xffffu << GMAC_PFR_PFRX_Pos) /**< \brief (GMAC_PFR) Pause Frames Received Register */
-/* -------- GMAC_BFR64 : (GMAC Offset: 0x168) 64 Byte Frames Received Register -------- */
-#define GMAC_BFR64_NFRX_Pos 0
-#define GMAC_BFR64_NFRX_Msk (0xffffffffu << GMAC_BFR64_NFRX_Pos) /**< \brief (GMAC_BFR64) 64 Byte Frames Received without Error */
-/* -------- GMAC_TBFR127 : (GMAC Offset: 0x16C) 65 to 127 Byte Frames Received Register -------- */
-#define GMAC_TBFR127_NFRX_Pos 0
-#define GMAC_TBFR127_NFRX_Msk (0xffffffffu << GMAC_TBFR127_NFRX_Pos) /**< \brief (GMAC_TBFR127) 65 to 127 Byte Frames Received without Error */
-/* -------- GMAC_TBFR255 : (GMAC Offset: 0x170) 128 to 255 Byte Frames Received Register -------- */
-#define GMAC_TBFR255_NFRX_Pos 0
-#define GMAC_TBFR255_NFRX_Msk (0xffffffffu << GMAC_TBFR255_NFRX_Pos) /**< \brief (GMAC_TBFR255) 128 to 255 Byte Frames Received without Error */
-/* -------- GMAC_TBFR511 : (GMAC Offset: 0x174) 256 to 511Byte Frames Received Register -------- */
-#define GMAC_TBFR511_NFRX_Pos 0
-#define GMAC_TBFR511_NFRX_Msk (0xffffffffu << GMAC_TBFR511_NFRX_Pos) /**< \brief (GMAC_TBFR511) 256 to 511 Byte Frames Received without Error */
-/* -------- GMAC_TBFR1023 : (GMAC Offset: 0x178) 512 to 1023 Byte Frames Received Register -------- */
-#define GMAC_TBFR1023_NFRX_Pos 0
-#define GMAC_TBFR1023_NFRX_Msk (0xffffffffu << GMAC_TBFR1023_NFRX_Pos) /**< \brief (GMAC_TBFR1023) 512 to 1023 Byte Frames Received without Error */
-/* -------- GMAC_TBFR1518 : (GMAC Offset: 0x17C) 1024 to 1518 Byte Frames Received Register -------- */
-#define GMAC_TBFR1518_NFRX_Pos 0
-#define GMAC_TBFR1518_NFRX_Msk (0xffffffffu << GMAC_TBFR1518_NFRX_Pos) /**< \brief (GMAC_TBFR1518) 1024 to 1518 Byte Frames Received without Error */
-/* -------- GMAC_TMXBFR : (GMAC Offset: 0x180) 1519 to Maximum Byte Frames Received Register -------- */
-#define GMAC_TMXBFR_NFRX_Pos 0
-#define GMAC_TMXBFR_NFRX_Msk (0xffffffffu << GMAC_TMXBFR_NFRX_Pos) /**< \brief (GMAC_TMXBFR) 1519 to Maximum Byte Frames Received without Error */
-/* -------- GMAC_UFR : (GMAC Offset: 0x184) Undersize Frames Received Register -------- */
-#define GMAC_UFR_UFRX_Pos 0
-#define GMAC_UFR_UFRX_Msk (0x3ffu << GMAC_UFR_UFRX_Pos) /**< \brief (GMAC_UFR) Undersize Frames Received */
-/* -------- GMAC_OFR : (GMAC Offset: 0x188) Oversize Frames Received Register -------- */
-#define GMAC_OFR_OFRX_Pos 0
-#define GMAC_OFR_OFRX_Msk (0x3ffu << GMAC_OFR_OFRX_Pos) /**< \brief (GMAC_OFR) Oversized Frames Received */
-/* -------- GMAC_JR : (GMAC Offset: 0x18C) Jabbers Received Register -------- */
-#define GMAC_JR_JRX_Pos 0
-#define GMAC_JR_JRX_Msk (0x3ffu << GMAC_JR_JRX_Pos) /**< \brief (GMAC_JR) Jabbers Received */
-/* -------- GMAC_FCSE : (GMAC Offset: 0x190) Frame Check Sequence Errors Register -------- */
-#define GMAC_FCSE_FCKR_Pos 0
-#define GMAC_FCSE_FCKR_Msk (0x3ffu << GMAC_FCSE_FCKR_Pos) /**< \brief (GMAC_FCSE) Frame Check Sequence Errors */
-/* -------- GMAC_LFFE : (GMAC Offset: 0x194) Length Field Frame Errors Register -------- */
-#define GMAC_LFFE_LFER_Pos 0
-#define GMAC_LFFE_LFER_Msk (0x3ffu << GMAC_LFFE_LFER_Pos) /**< \brief (GMAC_LFFE) Length Field Frame Errors */
-/* -------- GMAC_RSE : (GMAC Offset: 0x198) Receive Symbol Errors Register -------- */
-#define GMAC_RSE_RXSE_Pos 0
-#define GMAC_RSE_RXSE_Msk (0x3ffu << GMAC_RSE_RXSE_Pos) /**< \brief (GMAC_RSE) Receive Symbol Errors */
-/* -------- GMAC_AE : (GMAC Offset: 0x19C) Alignment Errors Register -------- */
-#define GMAC_AE_AER_Pos 0
-#define GMAC_AE_AER_Msk (0x3ffu << GMAC_AE_AER_Pos) /**< \brief (GMAC_AE) Alignment Errors */
-/* -------- GMAC_RRE : (GMAC Offset: 0x1A0) Receive Resource Errors Register -------- */
-#define GMAC_RRE_RXRER_Pos 0
-#define GMAC_RRE_RXRER_Msk (0x3ffffu << GMAC_RRE_RXRER_Pos) /**< \brief (GMAC_RRE) Receive Resource Errors */
-/* -------- GMAC_ROE : (GMAC Offset: 0x1A4) Receive Overrun Register -------- */
-#define GMAC_ROE_RXOVR_Pos 0
-#define GMAC_ROE_RXOVR_Msk (0x3ffu << GMAC_ROE_RXOVR_Pos) /**< \brief (GMAC_ROE) Receive Overruns */
-/* -------- GMAC_IHCE : (GMAC Offset: 0x1A8) IP Header Checksum Errors Register -------- */
-#define GMAC_IHCE_HCKER_Pos 0
-#define GMAC_IHCE_HCKER_Msk (0xffu << GMAC_IHCE_HCKER_Pos) /**< \brief (GMAC_IHCE) IP Header Checksum Errors */
-/* -------- GMAC_TCE : (GMAC Offset: 0x1AC) TCP Checksum Errors Register -------- */
-#define GMAC_TCE_TCKER_Pos 0
-#define GMAC_TCE_TCKER_Msk (0xffu << GMAC_TCE_TCKER_Pos) /**< \brief (GMAC_TCE) TCP Checksum Errors */
-/* -------- GMAC_UCE : (GMAC Offset: 0x1B0) UDP Checksum Errors Register -------- */
-#define GMAC_UCE_UCKER_Pos 0
-#define GMAC_UCE_UCKER_Msk (0xffu << GMAC_UCE_UCKER_Pos) /**< \brief (GMAC_UCE) UDP Checksum Errors */
-/* -------- GMAC_TSSS : (GMAC Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register -------- */
-#define GMAC_TSSS_VTS_Pos 0
-#define GMAC_TSSS_VTS_Msk (0xffffffffu << GMAC_TSSS_VTS_Pos) /**< \brief (GMAC_TSSS) Value of Timer Seconds Register Capture */
-#define GMAC_TSSS_VTS(value) ((GMAC_TSSS_VTS_Msk & ((value) << GMAC_TSSS_VTS_Pos)))
-/* -------- GMAC_TSSN : (GMAC Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register -------- */
-#define GMAC_TSSN_VTN_Pos 0
-#define GMAC_TSSN_VTN_Msk (0x3fffffffu << GMAC_TSSN_VTN_Pos) /**< \brief (GMAC_TSSN) Value Timer Nanoseconds Register Capture */
-#define GMAC_TSSN_VTN(value) ((GMAC_TSSN_VTN_Msk & ((value) << GMAC_TSSN_VTN_Pos)))
-/* -------- GMAC_TS : (GMAC Offset: 0x1D0) 1588 Timer Seconds Register -------- */
-#define GMAC_TS_TCS_Pos 0
-#define GMAC_TS_TCS_Msk (0xffffffffu << GMAC_TS_TCS_Pos) /**< \brief (GMAC_TS) Timer Count in Seconds */
-#define GMAC_TS_TCS(value) ((GMAC_TS_TCS_Msk & ((value) << GMAC_TS_TCS_Pos)))
-/* -------- GMAC_TN : (GMAC Offset: 0x1D4) 1588 Timer Nanoseconds Register -------- */
-#define GMAC_TN_TNS_Pos 0
-#define GMAC_TN_TNS_Msk (0x3fffffffu << GMAC_TN_TNS_Pos) /**< \brief (GMAC_TN) Timer Count in Nanoseconds */
-#define GMAC_TN_TNS(value) ((GMAC_TN_TNS_Msk & ((value) << GMAC_TN_TNS_Pos)))
-/* -------- GMAC_TA : (GMAC Offset: 0x1D8) 1588 Timer Adjust Register -------- */
-#define GMAC_TA_ITDT_Pos 0
-#define GMAC_TA_ITDT_Msk (0x3fffffffu << GMAC_TA_ITDT_Pos) /**< \brief (GMAC_TA) Increment/Decrement */
-#define GMAC_TA_ITDT(value) ((GMAC_TA_ITDT_Msk & ((value) << GMAC_TA_ITDT_Pos)))
-#define GMAC_TA_ADJ (0x1u << 31) /**< \brief (GMAC_TA) Adjust 1588 Timer */
-/* -------- GMAC_TI : (GMAC Offset: 0x1DC) 1588 Timer Increment Register -------- */
-#define GMAC_TI_CNS_Pos 0
-#define GMAC_TI_CNS_Msk (0xffu << GMAC_TI_CNS_Pos) /**< \brief (GMAC_TI) Count Nanoseconds */
-#define GMAC_TI_CNS(value) ((GMAC_TI_CNS_Msk & ((value) << GMAC_TI_CNS_Pos)))
-#define GMAC_TI_ACNS_Pos 8
-#define GMAC_TI_ACNS_Msk (0xffu << GMAC_TI_ACNS_Pos) /**< \brief (GMAC_TI) Alternative Count Nanoseconds */
-#define GMAC_TI_ACNS(value) ((GMAC_TI_ACNS_Msk & ((value) << GMAC_TI_ACNS_Pos)))
-#define GMAC_TI_NIT_Pos 16
-#define GMAC_TI_NIT_Msk (0xffu << GMAC_TI_NIT_Pos) /**< \brief (GMAC_TI) Number of Increments */
-#define GMAC_TI_NIT(value) ((GMAC_TI_NIT_Msk & ((value) << GMAC_TI_NIT_Pos)))
-/* -------- GMAC_EFTS : (GMAC Offset: 0x1E0) PTP Event Frame Transmitted Seconds -------- */
-#define GMAC_EFTS_RUD_Pos 0
-#define GMAC_EFTS_RUD_Msk (0xffffffffu << GMAC_EFTS_RUD_Pos) /**< \brief (GMAC_EFTS) Register Update */
-/* -------- GMAC_EFTN : (GMAC Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds -------- */
-#define GMAC_EFTN_RUD_Pos 0
-#define GMAC_EFTN_RUD_Msk (0x3fffffffu << GMAC_EFTN_RUD_Pos) /**< \brief (GMAC_EFTN) Register Update */
-/* -------- GMAC_EFRS : (GMAC Offset: 0x1E8) PTP Event Frame Received Seconds -------- */
-#define GMAC_EFRS_RUD_Pos 0
-#define GMAC_EFRS_RUD_Msk (0xffffffffu << GMAC_EFRS_RUD_Pos) /**< \brief (GMAC_EFRS) Register Update */
-/* -------- GMAC_EFRN : (GMAC Offset: 0x1EC) PTP Event Frame Received Nanoseconds -------- */
-#define GMAC_EFRN_RUD_Pos 0
-#define GMAC_EFRN_RUD_Msk (0x3fffffffu << GMAC_EFRN_RUD_Pos) /**< \brief (GMAC_EFRN) Register Update */
-/* -------- GMAC_PEFTS : (GMAC Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds -------- */
-#define GMAC_PEFTS_RUD_Pos 0
-#define GMAC_PEFTS_RUD_Msk (0xffffffffu << GMAC_PEFTS_RUD_Pos) /**< \brief (GMAC_PEFTS) Register Update */
-/* -------- GMAC_PEFTN : (GMAC Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds -------- */
-#define GMAC_PEFTN_RUD_Pos 0
-#define GMAC_PEFTN_RUD_Msk (0x3fffffffu << GMAC_PEFTN_RUD_Pos) /**< \brief (GMAC_PEFTN) Register Update */
-/* -------- GMAC_PEFRS : (GMAC Offset: 0x1F8) PTP Peer Event Frame Received Seconds -------- */
-#define GMAC_PEFRS_RUD_Pos 0
-#define GMAC_PEFRS_RUD_Msk (0xffffffffu << GMAC_PEFRS_RUD_Pos) /**< \brief (GMAC_PEFRS) Register Update */
-/* -------- GMAC_PEFRN : (GMAC Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds -------- */
-#define GMAC_PEFRN_RUD_Pos 0
-#define GMAC_PEFRN_RUD_Msk (0x3fffffffu << GMAC_PEFRN_RUD_Pos) /**< \brief (GMAC_PEFRN) Register Update */
-/* -------- GMAC_ISRPQ[7] : (GMAC Offset: 0x400) Interrupt Status Register Priority Queue -------- */
-#define GMAC_ISRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_ISRPQ[7]) Receive Complete */
-#define GMAC_ISRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_ISRPQ[7]) RX Used Bit Read */
-#define GMAC_ISRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_ISRPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_ISRPQ_TFC (0x1u << 6) /**< \brief (GMAC_ISRPQ[7]) Transmit Frame Corruption due to AHB error */
-#define GMAC_ISRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_ISRPQ[7]) Transmit Complete */
-#define GMAC_ISRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_ISRPQ[7]) Receive Overrun */
-#define GMAC_ISRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_ISRPQ[7]) HRESP Not OK */
-/* -------- GMAC_TBQBAPQ[7] : (GMAC Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue -------- */
-#define GMAC_TBQBAPQ_TXBQBA_Pos 2
-#define GMAC_TBQBAPQ_TXBQBA_Msk (0x3fu << GMAC_TBQBAPQ_TXBQBA_Pos) /**< \brief (GMAC_TBQBAPQ[7]) Transmit Buffer Queue Base Address */
-#define GMAC_TBQBAPQ_TXBQBA(value) ((GMAC_TBQBAPQ_TXBQBA_Msk & ((value) << GMAC_TBQBAPQ_TXBQBA_Pos)))
-/* -------- GMAC_RBQBAPQ[7] : (GMAC Offset: 0x480) Receive Buffer Queue Base Address Priority Queue -------- */
-#define GMAC_RBQBAPQ_RXBQBA_Pos 2
-#define GMAC_RBQBAPQ_RXBQBA_Msk (0x3fu << GMAC_RBQBAPQ_RXBQBA_Pos) /**< \brief (GMAC_RBQBAPQ[7]) Receive Buffer Queue Base Address */
-#define GMAC_RBQBAPQ_RXBQBA(value) ((GMAC_RBQBAPQ_RXBQBA_Msk & ((value) << GMAC_RBQBAPQ_RXBQBA_Pos)))
-/* -------- GMAC_RBSRPQ[7] : (GMAC Offset: 0x4A0) Receive Buffer Size Register Priority Queue -------- */
-#define GMAC_RBSRPQ_RBS_Pos 0
-#define GMAC_RBSRPQ_RBS_Msk (0xffffu << GMAC_RBSRPQ_RBS_Pos) /**< \brief (GMAC_RBSRPQ[7]) Receive Buffer Size */
-#define GMAC_RBSRPQ_RBS(value) ((GMAC_RBSRPQ_RBS_Msk & ((value) << GMAC_RBSRPQ_RBS_Pos)))
-/* -------- GMAC_ST1RPQ[16] : (GMAC Offset: 0x500) Screening Type1 Register Priority Queue -------- */
-#define GMAC_ST1RPQ_QNB_Pos 0
-#define GMAC_ST1RPQ_QNB_Msk (0xfu << GMAC_ST1RPQ_QNB_Pos) /**< \brief (GMAC_ST1RPQ[16]) Que Number (0->7) */
-#define GMAC_ST1RPQ_QNB(value) ((GMAC_ST1RPQ_QNB_Msk & ((value) << GMAC_ST1RPQ_QNB_Pos)))
-#define GMAC_ST1RPQ_DSTCM_Pos 4
-#define GMAC_ST1RPQ_DSTCM_Msk (0xffu << GMAC_ST1RPQ_DSTCM_Pos) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match */
-#define GMAC_ST1RPQ_DSTCM(value) ((GMAC_ST1RPQ_DSTCM_Msk & ((value) << GMAC_ST1RPQ_DSTCM_Pos)))
-#define GMAC_ST1RPQ_UDPM_Pos 12
-#define GMAC_ST1RPQ_UDPM_Msk (0xffffu << GMAC_ST1RPQ_UDPM_Pos) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match */
-#define GMAC_ST1RPQ_UDPM(value) ((GMAC_ST1RPQ_UDPM_Msk & ((value) << GMAC_ST1RPQ_UDPM_Pos)))
-#define GMAC_ST1RPQ_DSTCE (0x1u << 28) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match Enable */
-#define GMAC_ST1RPQ_UDPE (0x1u << 29) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match Enable */
-/* -------- GMAC_ST2RPQ[16] : (GMAC Offset: 0x540) Screening Type2 Register Priority Queue -------- */
-#define GMAC_ST2RPQ_QNB_Pos 0
-#define GMAC_ST2RPQ_QNB_Msk (0xfu << GMAC_ST2RPQ_QNB_Pos) /**< \brief (GMAC_ST2RPQ[16]) Que Number (0->7) */
-#define GMAC_ST2RPQ_QNB(value) ((GMAC_ST2RPQ_QNB_Msk & ((value) << GMAC_ST2RPQ_QNB_Pos)))
-#define GMAC_ST2RPQ_VLANP_Pos 4
-#define GMAC_ST2RPQ_VLANP_Msk (0xfu << GMAC_ST2RPQ_VLANP_Pos) /**< \brief (GMAC_ST2RPQ[16]) VLAN Priority */
-#define GMAC_ST2RPQ_VLANP(value) ((GMAC_ST2RPQ_VLANP_Msk & ((value) << GMAC_ST2RPQ_VLANP_Pos)))
-#define GMAC_ST2RPQ_VLANE (0x1u << 8) /**< \brief (GMAC_ST2RPQ[16]) VLAN Enable */
-/* -------- GMAC_IERPQ[7] : (GMAC Offset: 0x600) Interrupt Enable Register Priority Queue -------- */
-#define GMAC_IERPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IERPQ[7]) Receive Complete */
-#define GMAC_IERPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IERPQ[7]) RX Used Bit Read */
-#define GMAC_IERPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IERPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_IERPQ_TFC (0x1u << 6) /**< \brief (GMAC_IERPQ[7]) Transmit Frame Corruption due to AHB error */
-#define GMAC_IERPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IERPQ[7]) Transmit Complete */
-#define GMAC_IERPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IERPQ[7]) Receive Overrun */
-#define GMAC_IERPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IERPQ[7]) HRESP Not OK */
-/* -------- GMAC_IDRPQ[7] : (GMAC Offset: 0x620) Interrupt Disable Register Priority Queue -------- */
-#define GMAC_IDRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IDRPQ[7]) Receive Complete */
-#define GMAC_IDRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IDRPQ[7]) RX Used Bit Read */
-#define GMAC_IDRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IDRPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_IDRPQ_TFC (0x1u << 6) /**< \brief (GMAC_IDRPQ[7]) Transmit Frame Corruption due to AHB error */
-#define GMAC_IDRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IDRPQ[7]) Transmit Complete */
-#define GMAC_IDRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IDRPQ[7]) Receive Overrun */
-#define GMAC_IDRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IDRPQ[7]) HRESP Not OK */
-/* -------- GMAC_IMRPQ[7] : (GMAC Offset: 0x640) Interrupt Mask Register Priority Queue -------- */
-#define GMAC_IMRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IMRPQ[7]) Receive Complete */
-#define GMAC_IMRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IMRPQ[7]) RX Used Bit Read */
-#define GMAC_IMRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IMRPQ[7]) Retry Limit Exceeded or Late Collision */
-#define GMAC_IMRPQ_AHB (0x1u << 6) /**< \brief (GMAC_IMRPQ[7]) AHB Error */
-#define GMAC_IMRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IMRPQ[7]) Transmit Complete */
-#define GMAC_IMRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IMRPQ[7]) Receive Overrun */
-#define GMAC_IMRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IMRPQ[7]) HRESP Not OK */
-
-/*@}*/
-
-
-#endif /* _SAM4E_GMAC_COMPONENT_ */
+/**
+ * \file
+ *
+ * Copyright (c) 2012 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef _SAM4E_GMAC_COMPONENT_
+#define _SAM4E_GMAC_COMPONENT_
+
+/* ============================================================================= */
+/** SOFTWARE API DEFINITION FOR Gigabit Ethernet MAC */
+/* ============================================================================= */
+/** \addtogroup SAM4E_GMAC Gigabit Ethernet MAC */
+/*@{*/
+
+#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__))
+/** \brief GmacSa hardware registers */
+typedef struct {
+ RwReg GMAC_SAB; /**< \brief (GmacSa Offset: 0x0) Specific Address 1 Bottom [31:0] Register */
+ RwReg GMAC_SAT; /**< \brief (GmacSa Offset: 0x4) Specific Address 1 Top [47:32] Register */
+} GmacSa;
+/** \brief Gmac hardware registers */
+#define GMACSA_NUMBER 4
+typedef struct {
+ RwReg GMAC_NCR; /**< \brief (Gmac Offset: 0x000) Network Control Register */
+ RwReg GMAC_NCFGR; /**< \brief (Gmac Offset: 0x004) Network Configuration Register */
+ RoReg GMAC_NSR; /**< \brief (Gmac Offset: 0x008) Network Status Register */
+ RwReg GMAC_UR; /**< \brief (Gmac Offset: 0x00C) User Register */
+ RwReg GMAC_DCFGR; /**< \brief (Gmac Offset: 0x010) DMA Configuration Register */
+ RwReg GMAC_TSR; /**< \brief (Gmac Offset: 0x014) Transmit Status Register */
+ RwReg GMAC_RBQB; /**< \brief (Gmac Offset: 0x018) Receive Buffer Queue Base Address */
+ RwReg GMAC_TBQB; /**< \brief (Gmac Offset: 0x01C) Transmit Buffer Queue Base Address */
+ RwReg GMAC_RSR; /**< \brief (Gmac Offset: 0x020) Receive Status Register */
+ RoReg GMAC_ISR; /**< \brief (Gmac Offset: 0x024) Interrupt Status Register */
+ WoReg GMAC_IER; /**< \brief (Gmac Offset: 0x028) Interrupt Enable Register */
+ WoReg GMAC_IDR; /**< \brief (Gmac Offset: 0x02C) Interrupt Disable Register */
+ RoReg GMAC_IMR; /**< \brief (Gmac Offset: 0x030) Interrupt Mask Register */
+ RwReg GMAC_MAN; /**< \brief (Gmac Offset: 0x034) PHY Maintenance Register */
+ RoReg GMAC_RPQ; /**< \brief (Gmac Offset: 0x038) Received Pause Quantum Register */
+ RwReg GMAC_TPQ; /**< \brief (Gmac Offset: 0x03C) Transmit Pause Quantum Register */
+ RwReg GMAC_TPSF; /**< \brief (Gmac Offset: 0x040) TX Partial Store and Forward Register */
+ RwReg GMAC_RPSF; /**< \brief (Gmac Offset: 0x044) RX Partial Store and Forward Register */
+ RoReg Reserved1[14];
+ RwReg GMAC_HRB; /**< \brief (Gmac Offset: 0x080) Hash Register Bottom [31:0] */
+ RwReg GMAC_HRT; /**< \brief (Gmac Offset: 0x084) Hash Register Top [63:32] */
+ GmacSa GMAC_SA[GMACSA_NUMBER]; /**< \brief (Gmac Offset: 0x088) 1 .. 4 */
+ RwReg GMAC_TIDM[4]; /**< \brief (Gmac Offset: 0x0A8) Type ID Match 1 Register */
+ RwReg GMAC_WOL; /**< \brief (Gmac Offset: 0x0B8) Wake on LAN Register */
+ RwReg GMAC_IPGS; /**< \brief (Gmac Offset: 0x0BC) IPG Stretch Register */
+ RwReg GMAC_SVLAN; /**< \brief (Gmac Offset: 0x0C0) Stacked VLAN Register */
+ RwReg GMAC_TPFCP; /**< \brief (Gmac Offset: 0x0C4) Transmit PFC Pause Register */
+ RwReg GMAC_SAMB1; /**< \brief (Gmac Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register */
+ RwReg GMAC_SAMT1; /**< \brief (Gmac Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register */
+ RoReg Reserved2[12];
+ RoReg GMAC_OTLO; /**< \brief (Gmac Offset: 0x100) Octets Transmitted [31:0] Register */
+ RoReg GMAC_OTHI; /**< \brief (Gmac Offset: 0x104) Octets Transmitted [47:32] Register */
+ RoReg GMAC_FT; /**< \brief (Gmac Offset: 0x108) Frames Transmitted Register */
+ RoReg GMAC_BCFT; /**< \brief (Gmac Offset: 0x10C) Broadcast Frames Transmitted Register */
+ RoReg GMAC_MFT; /**< \brief (Gmac Offset: 0x110) Multicast Frames Transmitted Register */
+ RoReg GMAC_PFT; /**< \brief (Gmac Offset: 0x114) Pause Frames Transmitted Register */
+ RoReg GMAC_BFT64; /**< \brief (Gmac Offset: 0x118) 64 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT127; /**< \brief (Gmac Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT255; /**< \brief (Gmac Offset: 0x120) 128 to 255 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT511; /**< \brief (Gmac Offset: 0x124) 256 to 511 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT1023; /**< \brief (Gmac Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register */
+ RoReg GMAC_TBFT1518; /**< \brief (Gmac Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register */
+ RoReg GMAC_GTBFT1518; /**< \brief (Gmac Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register */
+ RoReg GMAC_TUR; /**< \brief (Gmac Offset: 0x134) Transmit Under Runs Register */
+ RoReg GMAC_SCF; /**< \brief (Gmac Offset: 0x138) Single Collision Frames Register */
+ RoReg GMAC_MCF; /**< \brief (Gmac Offset: 0x13C) Multiple Collision Frames Register */
+ RoReg GMAC_EC; /**< \brief (Gmac Offset: 0x140) Excessive Collisions Register */
+ RoReg GMAC_LC; /**< \brief (Gmac Offset: 0x144) Late Collisions Register */
+ RoReg GMAC_DTF; /**< \brief (Gmac Offset: 0x148) Deferred Transmission Frames Register */
+ RoReg GMAC_CSE; /**< \brief (Gmac Offset: 0x14C) Carrier Sense Errors Register */
+ RoReg GMAC_ORLO; /**< \brief (Gmac Offset: 0x150) Octets Received [31:0] Received */
+ RoReg GMAC_ORHI; /**< \brief (Gmac Offset: 0x154) Octets Received [47:32] Received */
+ RoReg GMAC_FR; /**< \brief (Gmac Offset: 0x158) Frames Received Register */
+ RoReg GMAC_BCFR; /**< \brief (Gmac Offset: 0x15C) Broadcast Frames Received Register */
+ RoReg GMAC_MFR; /**< \brief (Gmac Offset: 0x160) Multicast Frames Received Register */
+ RoReg GMAC_PFR; /**< \brief (Gmac Offset: 0x164) Pause Frames Received Register */
+ RoReg GMAC_BFR64; /**< \brief (Gmac Offset: 0x168) 64 Byte Frames Received Register */
+ RoReg GMAC_TBFR127; /**< \brief (Gmac Offset: 0x16C) 65 to 127 Byte Frames Received Register */
+ RoReg GMAC_TBFR255; /**< \brief (Gmac Offset: 0x170) 128 to 255 Byte Frames Received Register */
+ RoReg GMAC_TBFR511; /**< \brief (Gmac Offset: 0x174) 256 to 511Byte Frames Received Register */
+ RoReg GMAC_TBFR1023; /**< \brief (Gmac Offset: 0x178) 512 to 1023 Byte Frames Received Register */
+ RoReg GMAC_TBFR1518; /**< \brief (Gmac Offset: 0x17C) 1024 to 1518 Byte Frames Received Register */
+ RoReg GMAC_TMXBFR; /**< \brief (Gmac Offset: 0x180) 1519 to Maximum Byte Frames Received Register */
+ RoReg GMAC_UFR; /**< \brief (Gmac Offset: 0x184) Undersize Frames Received Register */
+ RoReg GMAC_OFR; /**< \brief (Gmac Offset: 0x188) Oversize Frames Received Register */
+ RoReg GMAC_JR; /**< \brief (Gmac Offset: 0x18C) Jabbers Received Register */
+ RoReg GMAC_FCSE; /**< \brief (Gmac Offset: 0x190) Frame Check Sequence Errors Register */
+ RoReg GMAC_LFFE; /**< \brief (Gmac Offset: 0x194) Length Field Frame Errors Register */
+ RoReg GMAC_RSE; /**< \brief (Gmac Offset: 0x198) Receive Symbol Errors Register */
+ RoReg GMAC_AE; /**< \brief (Gmac Offset: 0x19C) Alignment Errors Register */
+ RoReg GMAC_RRE; /**< \brief (Gmac Offset: 0x1A0) Receive Resource Errors Register */
+ RoReg GMAC_ROE; /**< \brief (Gmac Offset: 0x1A4) Receive Overrun Register */
+ RoReg GMAC_IHCE; /**< \brief (Gmac Offset: 0x1A8) IP Header Checksum Errors Register */
+ RoReg GMAC_TCE; /**< \brief (Gmac Offset: 0x1AC) TCP Checksum Errors Register */
+ RoReg GMAC_UCE; /**< \brief (Gmac Offset: 0x1B0) UDP Checksum Errors Register */
+ RoReg Reserved3[5];
+ RwReg GMAC_TSSS; /**< \brief (Gmac Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register */
+ RwReg GMAC_TSSN; /**< \brief (Gmac Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register */
+ RwReg GMAC_TS; /**< \brief (Gmac Offset: 0x1D0) 1588 Timer Seconds Register */
+ RwReg GMAC_TN; /**< \brief (Gmac Offset: 0x1D4) 1588 Timer Nanoseconds Register */
+ WoReg GMAC_TA; /**< \brief (Gmac Offset: 0x1D8) 1588 Timer Adjust Register */
+ RwReg GMAC_TI; /**< \brief (Gmac Offset: 0x1DC) 1588 Timer Increment Register */
+ RoReg GMAC_EFTS; /**< \brief (Gmac Offset: 0x1E0) PTP Event Frame Transmitted Seconds */
+ RoReg GMAC_EFTN; /**< \brief (Gmac Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds */
+ RoReg GMAC_EFRS; /**< \brief (Gmac Offset: 0x1E8) PTP Event Frame Received Seconds */
+ RoReg GMAC_EFRN; /**< \brief (Gmac Offset: 0x1EC) PTP Event Frame Received Nanoseconds */
+ RoReg GMAC_PEFTS; /**< \brief (Gmac Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds */
+ RoReg GMAC_PEFTN; /**< \brief (Gmac Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds */
+ RoReg GMAC_PEFRS; /**< \brief (Gmac Offset: 0x1F8) PTP Peer Event Frame Received Seconds */
+ RoReg GMAC_PEFRN; /**< \brief (Gmac Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds */
+ RoReg Reserved4[128];
+ RoReg GMAC_ISRPQ[7]; /**< \brief (Gmac Offset: 0x400) Interrupt Status Register Priority Queue */
+ RoReg Reserved5[9];
+ RwReg GMAC_TBQBAPQ[7]; /**< \brief (Gmac Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue */
+ RoReg Reserved6[9];
+ RwReg GMAC_RBQBAPQ[7]; /**< \brief (Gmac Offset: 0x480) Receive Buffer Queue Base Address Priority Queue */
+ RoReg Reserved7[1];
+ RwReg GMAC_RBSRPQ[7]; /**< \brief (Gmac Offset: 0x4A0) Receive Buffer Size Register Priority Queue */
+ RoReg Reserved8[17];
+ RwReg GMAC_ST1RPQ[16]; /**< \brief (Gmac Offset: 0x500) Screening Type1 Register Priority Queue */
+ RwReg GMAC_ST2RPQ[16]; /**< \brief (Gmac Offset: 0x540) Screening Type2 Register Priority Queue */
+ RoReg Reserved9[32];
+ WoReg GMAC_IERPQ[7]; /**< \brief (Gmac Offset: 0x600) Interrupt Enable Register Priority Queue */
+ RoReg Reserved10[1];
+ WoReg GMAC_IDRPQ[7]; /**< \brief (Gmac Offset: 0x620) Interrupt Disable Register Priority Queue */
+ RoReg Reserved11[1];
+ RwReg GMAC_IMRPQ[7]; /**< \brief (Gmac Offset: 0x640) Interrupt Mask Register Priority Queue */
+} Gmac;
+#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */
+/* -------- GMAC_NCR : (GMAC Offset: 0x000) Network Control Register -------- */
+#define GMAC_NCR_LB (0x1u << 0) /**< \brief (GMAC_NCR) Loop Back */
+#define GMAC_NCR_LBL (0x1u << 1) /**< \brief (GMAC_NCR) Loop Back Local */
+#define GMAC_NCR_RXEN (0x1u << 2) /**< \brief (GMAC_NCR) Receive Enable */
+#define GMAC_NCR_TXEN (0x1u << 3) /**< \brief (GMAC_NCR) Transmit Enable */
+#define GMAC_NCR_MPE (0x1u << 4) /**< \brief (GMAC_NCR) Management Port Enable */
+#define GMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (GMAC_NCR) Clear Statistics Registers */
+#define GMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (GMAC_NCR) Increment Statistics Registers */
+#define GMAC_NCR_WESTAT (0x1u << 7) /**< \brief (GMAC_NCR) Write Enable for Statistics Registers */
+#define GMAC_NCR_BP (0x1u << 8) /**< \brief (GMAC_NCR) Back pressure */
+#define GMAC_NCR_TSTART (0x1u << 9) /**< \brief (GMAC_NCR) Start Transmission */
+#define GMAC_NCR_THALT (0x1u << 10) /**< \brief (GMAC_NCR) Transmit Halt */
+#define GMAC_NCR_TXPF (0x1u << 11) /**< \brief (GMAC_NCR) Transmit Pause Frame */
+#define GMAC_NCR_TXZQPF (0x1u << 12) /**< \brief (GMAC_NCR) Transmit Zero Quantum Pause Frame */
+#define GMAC_NCR_RDS (0x1u << 14) /**< \brief (GMAC_NCR) Read Snapshot */
+#define GMAC_NCR_SRTSM (0x1u << 15) /**< \brief (GMAC_NCR) Store Receive Time Stamp to Memory */
+#define GMAC_NCR_ENPBPR (0x1u << 16) /**< \brief (GMAC_NCR) Enable PFC Priority-based Pause Reception */
+#define GMAC_NCR_TXPBPF (0x1u << 17) /**< \brief (GMAC_NCR) Transmit PFC Priority-based Pause Frame */
+#define GMAC_NCR_FNP (0x1u << 18) /**< \brief (GMAC_NCR) Flush Next Packet */
+/* -------- GMAC_NCFGR : (GMAC Offset: 0x004) Network Configuration Register -------- */
+#define GMAC_NCFGR_SPD (0x1u << 0) /**< \brief (GMAC_NCFGR) Speed */
+#define GMAC_NCFGR_FD (0x1u << 1) /**< \brief (GMAC_NCFGR) Full Duplex */
+#define GMAC_NCFGR_DNVLAN (0x1u << 2) /**< \brief (GMAC_NCFGR) Discard Non-VLAN FRAMES */
+#define GMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (GMAC_NCFGR) Jumbo Frame Size */
+#define GMAC_NCFGR_CAF (0x1u << 4) /**< \brief (GMAC_NCFGR) Copy All Frames */
+#define GMAC_NCFGR_NBC (0x1u << 5) /**< \brief (GMAC_NCFGR) No Broadcast */
+#define GMAC_NCFGR_MTIHEN (0x1u << 6) /**< \brief (GMAC_NCFGR) Multicast Hash Enable */
+#define GMAC_NCFGR_UNIHEN (0x1u << 7) /**< \brief (GMAC_NCFGR) Unicast Hash Enable */
+#define GMAC_NCFGR_MAXFS (0x1u << 8) /**< \brief (GMAC_NCFGR) 1536 Maximum Frame Size */
+#define GMAC_NCFGR_GBE (0x1u << 10) /**< \brief (GMAC_NCFGR) Gigabit Mode Enable */
+#define GMAC_NCFGR_PIS (0x1u << 11) /**< \brief (GMAC_NCFGR) Physical Interface Select */
+#define GMAC_NCFGR_RTY (0x1u << 12) /**< \brief (GMAC_NCFGR) Retry Test */
+#define GMAC_NCFGR_PEN (0x1u << 13) /**< \brief (GMAC_NCFGR) Pause Enable */
+#define GMAC_NCFGR_RXBUFO_Pos 14
+#define GMAC_NCFGR_RXBUFO_Msk (0x3u << GMAC_NCFGR_RXBUFO_Pos) /**< \brief (GMAC_NCFGR) Receive Buffer Offset */
+#define GMAC_NCFGR_RXBUFO(value) ((GMAC_NCFGR_RXBUFO_Msk & ((value) << GMAC_NCFGR_RXBUFO_Pos)))
+#define GMAC_NCFGR_LFERD (0x1u << 16) /**< \brief (GMAC_NCFGR) Length Field Error Frame Discard */
+#define GMAC_NCFGR_RFCS (0x1u << 17) /**< \brief (GMAC_NCFGR) Remove FCS */
+#define GMAC_NCFGR_CLK_Pos 18
+#define GMAC_NCFGR_CLK_Msk (0x7u << GMAC_NCFGR_CLK_Pos) /**< \brief (GMAC_NCFGR) MDC CLock Division */
+#define GMAC_NCFGR_CLK_MCK_8 (0x0u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz) */
+#define GMAC_NCFGR_CLK_MCK_16 (0x1u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz) */
+#define GMAC_NCFGR_CLK_MCK_32 (0x2u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz) */
+#define GMAC_NCFGR_CLK_MCK_48 (0x3u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 48 (MCK up to 120MHz) */
+#define GMAC_NCFGR_CLK_MCK_64 (0x4u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz) */
+#define GMAC_NCFGR_CLK_MCK_96 (0x5u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 96 (MCK up to 240 MHz) */
+#define GMAC_NCFGR_CLK_MCK_128 (0x6u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 128 (MCK up to 320 MHz) */
+#define GMAC_NCFGR_CLK_MCK_224 (0x7u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 224 (MCK up to 540 MHz) */
+#define GMAC_NCFGR_DBW_Pos 21
+#define GMAC_NCFGR_DBW_Msk (0x3u << GMAC_NCFGR_DBW_Pos) /**< \brief (GMAC_NCFGR) Data Bus Width */
+#define GMAC_NCFGR_DBW_DBW32 (0x0u << 21) /**< \brief (GMAC_NCFGR) 32-bit data bus width */
+#define GMAC_NCFGR_DBW_DBW64 (0x1u << 21) /**< \brief (GMAC_NCFGR) 64-bit data bus width */
+#define GMAC_NCFGR_DCPF (0x1u << 23) /**< \brief (GMAC_NCFGR) Disable Copy of Pause Frames */
+#define GMAC_NCFGR_RXCOEN (0x1u << 24) /**< \brief (GMAC_NCFGR) Receive Checksum Offload Enable */
+#define GMAC_NCFGR_EFRHD (0x1u << 25) /**< \brief (GMAC_NCFGR) Enable Frames Received in Half Duplex */
+#define GMAC_NCFGR_IRXFCS (0x1u << 26) /**< \brief (GMAC_NCFGR) Ignore RX FCS */
+#define GMAC_NCFGR_IPGSEN (0x1u << 28) /**< \brief (GMAC_NCFGR) IP Stretch Enable */
+#define GMAC_NCFGR_RXBP (0x1u << 29) /**< \brief (GMAC_NCFGR) Receive Bad Preamble */
+#define GMAC_NCFGR_IRXER (0x1u << 30) /**< \brief (GMAC_NCFGR) Ignore IPG rx_er */
+/* -------- GMAC_NSR : (GMAC Offset: 0x008) Network Status Register -------- */
+#define GMAC_NSR_MDIO (0x1u << 1) /**< \brief (GMAC_NSR) MDIO Input Status */
+#define GMAC_NSR_IDLE (0x1u << 2) /**< \brief (GMAC_NSR) PHY Management Logic Idle */
+/* -------- GMAC_UR : (GMAC Offset: 0x00C) User Register -------- */
+#define GMAC_UR_RGMII (0x1u << 0) /**< \brief (GMAC_UR) RGMII Mode */
+#define GMAC_UR_HDFC (0x1u << 6) /**< \brief (GMAC_UR) Half Duplex Flow Control */
+#define GMAC_UR_BPDG (0x1u << 7) /**< \brief (GMAC_UR) BPDG Bypass Deglitchers */
+/* -------- GMAC_DCFGR : (GMAC Offset: 0x010) DMA Configuration Register -------- */
+#define GMAC_DCFGR_FBLDO_Pos 0
+#define GMAC_DCFGR_FBLDO_Msk (0x1fu << GMAC_DCFGR_FBLDO_Pos) /**< \brief (GMAC_DCFGR) Fixed Burst Length for DMA Data Operations: */
+#define GMAC_DCFGR_FBLDO_SINGLE (0x1u << 0) /**< \brief (GMAC_DCFGR) 00001: Always use SINGLE AHB bursts */
+#define GMAC_DCFGR_FBLDO_INCR4 (0x4u << 0) /**< \brief (GMAC_DCFGR) 001xx: Attempt to use INCR4 AHB bursts (Default) */
+#define GMAC_DCFGR_FBLDO_INCR8 (0x8u << 0) /**< \brief (GMAC_DCFGR) 01xxx: Attempt to use INCR8 AHB bursts */
+#define GMAC_DCFGR_FBLDO_INCR16 (0x10u << 0) /**< \brief (GMAC_DCFGR) 1xxxx: Attempt to use INCR16 AHB bursts */
+#define GMAC_DCFGR_ESMA (0x1u << 6) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Management Descriptor Accesses */
+#define GMAC_DCFGR_ESPA (0x1u << 7) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Packet Data Accesses */
+#define GMAC_DCFGR_RXBMS_Pos 8
+#define GMAC_DCFGR_RXBMS_Msk (0x3u << GMAC_DCFGR_RXBMS_Pos) /**< \brief (GMAC_DCFGR) Receiver Packet Buffer Memory Size Select */
+#define GMAC_DCFGR_RXBMS_EIGHTH (0x0u << 8) /**< \brief (GMAC_DCFGR) 1 Kbyte Memory Size */
+#define GMAC_DCFGR_RXBMS_QUARTER (0x1u << 8) /**< \brief (GMAC_DCFGR) 2 Kbytes Memory Size */
+#define GMAC_DCFGR_RXBMS_HALF (0x2u << 8) /**< \brief (GMAC_DCFGR) 4 Kbytes Memory Size */
+#define GMAC_DCFGR_RXBMS_FULL (0x3u << 8) /**< \brief (GMAC_DCFGR) 8 Kbytes Memory Size */
+#define GMAC_DCFGR_TXPBMS (0x1u << 10) /**< \brief (GMAC_DCFGR) Transmitter Packet Buffer Memory Size Select */
+#define GMAC_DCFGR_TXCOEN (0x1u << 11) /**< \brief (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable */
+#define GMAC_DCFGR_DRBS_Pos 16
+#define GMAC_DCFGR_DRBS_Msk (0xffu << GMAC_DCFGR_DRBS_Pos) /**< \brief (GMAC_DCFGR) DMA Receive Buffer Size */
+#define GMAC_DCFGR_DRBS(value) ((GMAC_DCFGR_DRBS_Msk & ((value) << GMAC_DCFGR_DRBS_Pos)))
+#define GMAC_DCFGR_DDRP (0x1u << 24) /**< \brief (GMAC_DCFGR) DMA Discard Receive Packets */
+/* -------- GMAC_TSR : (GMAC Offset: 0x014) Transmit Status Register -------- */
+#define GMAC_TSR_UBR (0x1u << 0) /**< \brief (GMAC_TSR) Used Bit Read */
+#define GMAC_TSR_COL (0x1u << 1) /**< \brief (GMAC_TSR) Collision Occurred */
+#define GMAC_TSR_RLE (0x1u << 2) /**< \brief (GMAC_TSR) Retry Limit Exceeded */
+#define GMAC_TSR_TXGO (0x1u << 3) /**< \brief (GMAC_TSR) Transmit Go */
+#define GMAC_TSR_TFC (0x1u << 4) /**< \brief (GMAC_TSR) Transmit Frame Corruption due to AHB error */
+#define GMAC_TSR_TXCOMP (0x1u << 5) /**< \brief (GMAC_TSR) Transmit Complete */
+#define GMAC_TSR_UND (0x1u << 6) /**< \brief (GMAC_TSR) Transmit Under Run */
+#define GMAC_TSR_LCO (0x1u << 7) /**< \brief (GMAC_TSR) Late Collision Occurred */
+#define GMAC_TSR_HRESP (0x1u << 8) /**< \brief (GMAC_TSR) HRESP Not OK */
+/* -------- GMAC_RBQB : (GMAC Offset: 0x018) Receive Buffer Queue Base Address -------- */
+#define GMAC_RBQB_ADDR_Pos 2
+#define GMAC_RBQB_ADDR_Msk (0x3fffffffu << GMAC_RBQB_ADDR_Pos) /**< \brief (GMAC_RBQB) Receive buffer queue base address */
+#define GMAC_RBQB_ADDR(value) ((GMAC_RBQB_ADDR_Msk & ((value) << GMAC_RBQB_ADDR_Pos)))
+/* -------- GMAC_TBQB : (GMAC Offset: 0x01C) Transmit Buffer Queue Base Address -------- */
+#define GMAC_TBQB_ADDR_Pos 2
+#define GMAC_TBQB_ADDR_Msk (0x3fffffffu << GMAC_TBQB_ADDR_Pos) /**< \brief (GMAC_TBQB) Transmit Buffer Queue Base Address */
+#define GMAC_TBQB_ADDR(value) ((GMAC_TBQB_ADDR_Msk & ((value) << GMAC_TBQB_ADDR_Pos)))
+/* -------- GMAC_RSR : (GMAC Offset: 0x020) Receive Status Register -------- */
+#define GMAC_RSR_BNA (0x1u << 0) /**< \brief (GMAC_RSR) Buffer Not Available */
+#define GMAC_RSR_REC (0x1u << 1) /**< \brief (GMAC_RSR) Frame Received */
+#define GMAC_RSR_RXOVR (0x1u << 2) /**< \brief (GMAC_RSR) Receive Overrun */
+#define GMAC_RSR_HNO (0x1u << 3) /**< \brief (GMAC_RSR) HRESP Not OK */
+/* -------- GMAC_ISR : (GMAC Offset: 0x024) Interrupt Status Register -------- */
+#define GMAC_ISR_MFS (0x1u << 0) /**< \brief (GMAC_ISR) Management Frame Sent */
+#define GMAC_ISR_RCOMP (0x1u << 1) /**< \brief (GMAC_ISR) Receive Complete */
+#define GMAC_ISR_RXUBR (0x1u << 2) /**< \brief (GMAC_ISR) RX Used Bit Read */
+#define GMAC_ISR_TXUBR (0x1u << 3) /**< \brief (GMAC_ISR) TX Used Bit Read */
+#define GMAC_ISR_TUR (0x1u << 4) /**< \brief (GMAC_ISR) Transmit Under Run */
+#define GMAC_ISR_RLEX (0x1u << 5) /**< \brief (GMAC_ISR) Retry Limit Exceeded or Late Collision */
+#define GMAC_ISR_TFC (0x1u << 6) /**< \brief (GMAC_ISR) Transmit Frame Corruption due to AHB error */
+#define GMAC_ISR_TCOMP (0x1u << 7) /**< \brief (GMAC_ISR) Transmit Complete */
+#define GMAC_ISR_ROVR (0x1u << 10) /**< \brief (GMAC_ISR) Receive Overrun */
+#define GMAC_ISR_HRESP (0x1u << 11) /**< \brief (GMAC_ISR) HRESP Not OK */
+#define GMAC_ISR_PFNZ (0x1u << 12) /**< \brief (GMAC_ISR) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_ISR_PTZ (0x1u << 13) /**< \brief (GMAC_ISR) Pause Time Zero */
+#define GMAC_ISR_PFTR (0x1u << 14) /**< \brief (GMAC_ISR) Pause Frame Transmitted */
+#define GMAC_ISR_EXINT (0x1u << 15) /**< \brief (GMAC_ISR) External Interrupt */
+#define GMAC_ISR_DRQFR (0x1u << 18) /**< \brief (GMAC_ISR) PTP Delay Request Frame Received */
+#define GMAC_ISR_SFR (0x1u << 19) /**< \brief (GMAC_ISR) PTP Sync Frame Received */
+#define GMAC_ISR_DRQFT (0x1u << 20) /**< \brief (GMAC_ISR) PTP Delay Request Frame Transmitted */
+#define GMAC_ISR_SFT (0x1u << 21) /**< \brief (GMAC_ISR) PTP Sync Frame Transmitted */
+#define GMAC_ISR_PDRQFR (0x1u << 22) /**< \brief (GMAC_ISR) PDelay Request Frame Received */
+#define GMAC_ISR_PDRSFR (0x1u << 23) /**< \brief (GMAC_ISR) PDelay Response Frame Received */
+#define GMAC_ISR_PDRQFT (0x1u << 24) /**< \brief (GMAC_ISR) PDelay Request Frame Transmitted */
+#define GMAC_ISR_PDRSFT (0x1u << 25) /**< \brief (GMAC_ISR) PDelay Response Frame Transmitted */
+#define GMAC_ISR_SRI (0x1u << 26) /**< \brief (GMAC_ISR) TSU Seconds Register Increment */
+#define GMAC_ISR_WOL (0x1u << 28) /**< \brief (GMAC_ISR) Wake On LAN */
+/* -------- GMAC_IER : (GMAC Offset: 0x028) Interrupt Enable Register -------- */
+#define GMAC_IER_MFS (0x1u << 0) /**< \brief (GMAC_IER) Management Frame Sent */
+#define GMAC_IER_RCOMP (0x1u << 1) /**< \brief (GMAC_IER) Receive Complete */
+#define GMAC_IER_RXUBR (0x1u << 2) /**< \brief (GMAC_IER) RX Used Bit Read */
+#define GMAC_IER_TXUBR (0x1u << 3) /**< \brief (GMAC_IER) TX Used Bit Read */
+#define GMAC_IER_TUR (0x1u << 4) /**< \brief (GMAC_IER) Transmit Under Run */
+#define GMAC_IER_RLEX (0x1u << 5) /**< \brief (GMAC_IER) Retry Limit Exceeded or Late Collision */
+#define GMAC_IER_TFC (0x1u << 6) /**< \brief (GMAC_IER) Transmit Frame Corruption due to AHB error */
+#define GMAC_IER_TCOMP (0x1u << 7) /**< \brief (GMAC_IER) Transmit Complete */
+#define GMAC_IER_ROVR (0x1u << 10) /**< \brief (GMAC_IER) Receive Overrun */
+#define GMAC_IER_HRESP (0x1u << 11) /**< \brief (GMAC_IER) HRESP Not OK */
+#define GMAC_IER_PFNZ (0x1u << 12) /**< \brief (GMAC_IER) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_IER_PTZ (0x1u << 13) /**< \brief (GMAC_IER) Pause Time Zero */
+#define GMAC_IER_PFTR (0x1u << 14) /**< \brief (GMAC_IER) Pause Frame Transmitted */
+#define GMAC_IER_EXINT (0x1u << 15) /**< \brief (GMAC_IER) External Interrupt */
+#define GMAC_IER_DRQFR (0x1u << 18) /**< \brief (GMAC_IER) PTP Delay Request Frame Received */
+#define GMAC_IER_SFR (0x1u << 19) /**< \brief (GMAC_IER) PTP Sync Frame Received */
+#define GMAC_IER_DRQFT (0x1u << 20) /**< \brief (GMAC_IER) PTP Delay Request Frame Transmitted */
+#define GMAC_IER_SFT (0x1u << 21) /**< \brief (GMAC_IER) PTP Sync Frame Transmitted */
+#define GMAC_IER_PDRQFR (0x1u << 22) /**< \brief (GMAC_IER) PDelay Request Frame Received */
+#define GMAC_IER_PDRSFR (0x1u << 23) /**< \brief (GMAC_IER) PDelay Response Frame Received */
+#define GMAC_IER_PDRQFT (0x1u << 24) /**< \brief (GMAC_IER) PDelay Request Frame Transmitted */
+#define GMAC_IER_PDRSFT (0x1u << 25) /**< \brief (GMAC_IER) PDelay Response Frame Transmitted */
+#define GMAC_IER_SRI (0x1u << 26) /**< \brief (GMAC_IER) TSU Seconds Register Increment */
+#define GMAC_IER_WOL (0x1u << 28) /**< \brief (GMAC_IER) Wake On LAN */
+/* -------- GMAC_IDR : (GMAC Offset: 0x02C) Interrupt Disable Register -------- */
+#define GMAC_IDR_MFS (0x1u << 0) /**< \brief (GMAC_IDR) Management Frame Sent */
+#define GMAC_IDR_RCOMP (0x1u << 1) /**< \brief (GMAC_IDR) Receive Complete */
+#define GMAC_IDR_RXUBR (0x1u << 2) /**< \brief (GMAC_IDR) RX Used Bit Read */
+#define GMAC_IDR_TXUBR (0x1u << 3) /**< \brief (GMAC_IDR) TX Used Bit Read */
+#define GMAC_IDR_TUR (0x1u << 4) /**< \brief (GMAC_IDR) Transmit Under Run */
+#define GMAC_IDR_RLEX (0x1u << 5) /**< \brief (GMAC_IDR) Retry Limit Exceeded or Late Collision */
+#define GMAC_IDR_TFC (0x1u << 6) /**< \brief (GMAC_IDR) Transmit Frame Corruption due to AHB error */
+#define GMAC_IDR_TCOMP (0x1u << 7) /**< \brief (GMAC_IDR) Transmit Complete */
+#define GMAC_IDR_ROVR (0x1u << 10) /**< \brief (GMAC_IDR) Receive Overrun */
+#define GMAC_IDR_HRESP (0x1u << 11) /**< \brief (GMAC_IDR) HRESP Not OK */
+#define GMAC_IDR_PFNZ (0x1u << 12) /**< \brief (GMAC_IDR) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_IDR_PTZ (0x1u << 13) /**< \brief (GMAC_IDR) Pause Time Zero */
+#define GMAC_IDR_PFTR (0x1u << 14) /**< \brief (GMAC_IDR) Pause Frame Transmitted */
+#define GMAC_IDR_EXINT (0x1u << 15) /**< \brief (GMAC_IDR) External Interrupt */
+#define GMAC_IDR_DRQFR (0x1u << 18) /**< \brief (GMAC_IDR) PTP Delay Request Frame Received */
+#define GMAC_IDR_SFR (0x1u << 19) /**< \brief (GMAC_IDR) PTP Sync Frame Received */
+#define GMAC_IDR_DRQFT (0x1u << 20) /**< \brief (GMAC_IDR) PTP Delay Request Frame Transmitted */
+#define GMAC_IDR_SFT (0x1u << 21) /**< \brief (GMAC_IDR) PTP Sync Frame Transmitted */
+#define GMAC_IDR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IDR) PDelay Request Frame Received */
+#define GMAC_IDR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IDR) PDelay Response Frame Received */
+#define GMAC_IDR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IDR) PDelay Request Frame Transmitted */
+#define GMAC_IDR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IDR) PDelay Response Frame Transmitted */
+#define GMAC_IDR_SRI (0x1u << 26) /**< \brief (GMAC_IDR) TSU Seconds Register Increment */
+#define GMAC_IDR_WOL (0x1u << 28) /**< \brief (GMAC_IDR) Wake On LAN */
+/* -------- GMAC_IMR : (GMAC Offset: 0x030) Interrupt Mask Register -------- */
+#define GMAC_IMR_MFS (0x1u << 0) /**< \brief (GMAC_IMR) Management Frame Sent */
+#define GMAC_IMR_RCOMP (0x1u << 1) /**< \brief (GMAC_IMR) Receive Complete */
+#define GMAC_IMR_RXUBR (0x1u << 2) /**< \brief (GMAC_IMR) RX Used Bit Read */
+#define GMAC_IMR_TXUBR (0x1u << 3) /**< \brief (GMAC_IMR) TX Used Bit Read */
+#define GMAC_IMR_TUR (0x1u << 4) /**< \brief (GMAC_IMR) Transmit Under Run */
+#define GMAC_IMR_RLEX (0x1u << 5) /**< \brief (GMAC_IMR) Retry Limit Exceeded or Late Collision */
+#define GMAC_IMR_TFC (0x1u << 6) /**< \brief (GMAC_IMR) Transmit Frame Corruption due to AHB error */
+#define GMAC_IMR_TCOMP (0x1u << 7) /**< \brief (GMAC_IMR) Transmit Complete */
+#define GMAC_IMR_ROVR (0x1u << 10) /**< \brief (GMAC_IMR) Receive Overrun */
+#define GMAC_IMR_HRESP (0x1u << 11) /**< \brief (GMAC_IMR) HRESP Not OK */
+#define GMAC_IMR_PFNZ (0x1u << 12) /**< \brief (GMAC_IMR) Pause Frame with Non-zero Pause Quantum Received */
+#define GMAC_IMR_PTZ (0x1u << 13) /**< \brief (GMAC_IMR) Pause Time Zero */
+#define GMAC_IMR_PFTR (0x1u << 14) /**< \brief (GMAC_IMR) Pause Frame Transmitted */
+#define GMAC_IMR_EXINT (0x1u << 15) /**< \brief (GMAC_IMR) External Interrupt */
+#define GMAC_IMR_DRQFR (0x1u << 18) /**< \brief (GMAC_IMR) PTP Delay Request Frame Received */
+#define GMAC_IMR_SFR (0x1u << 19) /**< \brief (GMAC_IMR) PTP Sync Frame Received */
+#define GMAC_IMR_DRQFT (0x1u << 20) /**< \brief (GMAC_IMR) PTP Delay Request Frame Transmitted */
+#define GMAC_IMR_SFT (0x1u << 21) /**< \brief (GMAC_IMR) PTP Sync Frame Transmitted */
+#define GMAC_IMR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IMR) PDelay Request Frame Received */
+#define GMAC_IMR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IMR) PDelay Response Frame Received */
+#define GMAC_IMR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IMR) PDelay Request Frame Transmitted */
+#define GMAC_IMR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IMR) PDelay Response Frame Transmitted */
+/* -------- GMAC_MAN : (GMAC Offset: 0x034) PHY Maintenance Register -------- */
+#define GMAC_MAN_DATA_Pos 0
+#define GMAC_MAN_DATA_Msk (0xffffu << GMAC_MAN_DATA_Pos) /**< \brief (GMAC_MAN) PHY Data */
+#define GMAC_MAN_DATA(value) ((GMAC_MAN_DATA_Msk & ((value) << GMAC_MAN_DATA_Pos)))
+#define GMAC_MAN_WTN_Pos 16
+#define GMAC_MAN_WTN_Msk (0x3u << GMAC_MAN_WTN_Pos) /**< \brief (GMAC_MAN) Write Ten */
+#define GMAC_MAN_WTN(value) ((GMAC_MAN_WTN_Msk & ((value) << GMAC_MAN_WTN_Pos)))
+#define GMAC_MAN_REGA_Pos 18
+#define GMAC_MAN_REGA_Msk (0x1fu << GMAC_MAN_REGA_Pos) /**< \brief (GMAC_MAN) Register Address */
+#define GMAC_MAN_REGA(value) ((GMAC_MAN_REGA_Msk & ((value) << GMAC_MAN_REGA_Pos)))
+#define GMAC_MAN_PHYA_Pos 23
+#define GMAC_MAN_PHYA_Msk (0x1fu << GMAC_MAN_PHYA_Pos) /**< \brief (GMAC_MAN) PHY Address */
+#define GMAC_MAN_PHYA(value) ((GMAC_MAN_PHYA_Msk & ((value) << GMAC_MAN_PHYA_Pos)))
+#define GMAC_MAN_OP_Pos 28
+#define GMAC_MAN_OP_Msk (0x3u << GMAC_MAN_OP_Pos) /**< \brief (GMAC_MAN) Operation */
+#define GMAC_MAN_OP(value) ((GMAC_MAN_OP_Msk & ((value) << GMAC_MAN_OP_Pos)))
+#define GMAC_MAN_CLTTO (0x1u << 30) /**< \brief (GMAC_MAN) Clause 22 Operation */
+#define GMAC_MAN_WZO (0x1u << 31) /**< \brief (GMAC_MAN) Write ZERO */
+/* -------- GMAC_RPQ : (GMAC Offset: 0x038) Received Pause Quantum Register -------- */
+#define GMAC_RPQ_RPQ_Pos 0
+#define GMAC_RPQ_RPQ_Msk (0xffffu << GMAC_RPQ_RPQ_Pos) /**< \brief (GMAC_RPQ) Received Pause Quantum */
+/* -------- GMAC_TPQ : (GMAC Offset: 0x03C) Transmit Pause Quantum Register -------- */
+#define GMAC_TPQ_TPQ_Pos 0
+#define GMAC_TPQ_TPQ_Msk (0xffffu << GMAC_TPQ_TPQ_Pos) /**< \brief (GMAC_TPQ) Transmit Pause Quantum */
+#define GMAC_TPQ_TPQ(value) ((GMAC_TPQ_TPQ_Msk & ((value) << GMAC_TPQ_TPQ_Pos)))
+/* -------- GMAC_TPSF : (GMAC Offset: 0x040) TX Partial Store and Forward Register -------- */
+#define GMAC_TPSF_TPB1ADR_Pos 0
+#define GMAC_TPSF_TPB1ADR_Msk (0xfffu << GMAC_TPSF_TPB1ADR_Pos) /**< \brief (GMAC_TPSF) tx_pbuf_addr-1:0 */
+#define GMAC_TPSF_TPB1ADR(value) ((GMAC_TPSF_TPB1ADR_Msk & ((value) << GMAC_TPSF_TPB1ADR_Pos)))
+#define GMAC_TPSF_ENTXP (0x1u << 31) /**< \brief (GMAC_TPSF) Enable TX Partial Store and Forward Operation */
+/* -------- GMAC_RPSF : (GMAC Offset: 0x044) RX Partial Store and Forward Register -------- */
+#define GMAC_RPSF_RPB1ADR_Pos 0
+#define GMAC_RPSF_RPB1ADR_Msk (0xfffu << GMAC_RPSF_RPB1ADR_Pos) /**< \brief (GMAC_RPSF) rx_pbuf_addr-1:0 */
+#define GMAC_RPSF_RPB1ADR(value) ((GMAC_RPSF_RPB1ADR_Msk & ((value) << GMAC_RPSF_RPB1ADR_Pos)))
+#define GMAC_RPSF_ENRXP (0x1u << 31) /**< \brief (GMAC_RPSF) Enable RX Partial Store and Forward Operation */
+/* -------- GMAC_HRB : (GMAC Offset: 0x080) Hash Register Bottom [31:0] -------- */
+#define GMAC_HRB_ADDR_Pos 0
+#define GMAC_HRB_ADDR_Msk (0xffffffffu << GMAC_HRB_ADDR_Pos) /**< \brief (GMAC_HRB) Hash Address */
+#define GMAC_HRB_ADDR(value) ((GMAC_HRB_ADDR_Msk & ((value) << GMAC_HRB_ADDR_Pos)))
+/* -------- GMAC_HRT : (GMAC Offset: 0x084) Hash Register Top [63:32] -------- */
+#define GMAC_HRT_ADDR_Pos 0
+#define GMAC_HRT_ADDR_Msk (0xffffffffu << GMAC_HRT_ADDR_Pos) /**< \brief (GMAC_HRT) Hash Address */
+#define GMAC_HRT_ADDR(value) ((GMAC_HRT_ADDR_Msk & ((value) << GMAC_HRT_ADDR_Pos)))
+/* -------- GMAC_SAB1 : (GMAC Offset: 0x088) Specific Address 1 Bottom [31:0] Register -------- */
+#define GMAC_SAB1_ADDR_Pos 0
+#define GMAC_SAB1_ADDR_Msk (0xffffffffu << GMAC_SAB1_ADDR_Pos) /**< \brief (GMAC_SAB1) Specific Address 1 */
+#define GMAC_SAB1_ADDR(value) ((GMAC_SAB1_ADDR_Msk & ((value) << GMAC_SAB1_ADDR_Pos)))
+/* -------- GMAC_SAT1 : (GMAC Offset: 0x08C) Specific Address 1 Top [47:32] Register -------- */
+#define GMAC_SAT1_ADDR_Pos 0
+#define GMAC_SAT1_ADDR_Msk (0xffffu << GMAC_SAT1_ADDR_Pos) /**< \brief (GMAC_SAT1) Specific Address 1 */
+#define GMAC_SAT1_ADDR(value) ((GMAC_SAT1_ADDR_Msk & ((value) << GMAC_SAT1_ADDR_Pos)))
+/* -------- GMAC_SAB2 : (GMAC Offset: 0x090) Specific Address 2 Bottom [31:0] Register -------- */
+#define GMAC_SAB2_ADDR_Pos 0
+#define GMAC_SAB2_ADDR_Msk (0xffffffffu << GMAC_SAB2_ADDR_Pos) /**< \brief (GMAC_SAB2) Specific Address 2 */
+#define GMAC_SAB2_ADDR(value) ((GMAC_SAB2_ADDR_Msk & ((value) << GMAC_SAB2_ADDR_Pos)))
+/* -------- GMAC_SAT2 : (GMAC Offset: 0x094) Specific Address 2 Top [47:32] Register -------- */
+#define GMAC_SAT2_ADDR_Pos 0
+#define GMAC_SAT2_ADDR_Msk (0xffffu << GMAC_SAT2_ADDR_Pos) /**< \brief (GMAC_SAT2) Specific Address 2 */
+#define GMAC_SAT2_ADDR(value) ((GMAC_SAT2_ADDR_Msk & ((value) << GMAC_SAT2_ADDR_Pos)))
+/* -------- GMAC_SAB3 : (GMAC Offset: 0x098) Specific Address 3 Bottom [31:0] Register -------- */
+#define GMAC_SAB3_ADDR_Pos 0
+#define GMAC_SAB3_ADDR_Msk (0xffffffffu << GMAC_SAB3_ADDR_Pos) /**< \brief (GMAC_SAB3) Specific Address 3 */
+#define GMAC_SAB3_ADDR(value) ((GMAC_SAB3_ADDR_Msk & ((value) << GMAC_SAB3_ADDR_Pos)))
+/* -------- GMAC_SAT3 : (GMAC Offset: 0x09C) Specific Address 3 Top [47:32] Register -------- */
+#define GMAC_SAT3_ADDR_Pos 0
+#define GMAC_SAT3_ADDR_Msk (0xffffu << GMAC_SAT3_ADDR_Pos) /**< \brief (GMAC_SAT3) Specific Address 3 */
+#define GMAC_SAT3_ADDR(value) ((GMAC_SAT3_ADDR_Msk & ((value) << GMAC_SAT3_ADDR_Pos)))
+/* -------- GMAC_SAB4 : (GMAC Offset: 0x0A0) Specific Address 4 Bottom [31:0] Register -------- */
+#define GMAC_SAB4_ADDR_Pos 0
+#define GMAC_SAB4_ADDR_Msk (0xffffffffu << GMAC_SAB4_ADDR_Pos) /**< \brief (GMAC_SAB4) Specific Address 4 */
+#define GMAC_SAB4_ADDR(value) ((GMAC_SAB4_ADDR_Msk & ((value) << GMAC_SAB4_ADDR_Pos)))
+/* -------- GMAC_SAT4 : (GMAC Offset: 0x0A4) Specific Address 4 Top [47:32] Register -------- */
+#define GMAC_SAT4_ADDR_Pos 0
+#define GMAC_SAT4_ADDR_Msk (0xffffu << GMAC_SAT4_ADDR_Pos) /**< \brief (GMAC_SAT4) Specific Address 4 */
+#define GMAC_SAT4_ADDR(value) ((GMAC_SAT4_ADDR_Msk & ((value) << GMAC_SAT4_ADDR_Pos)))
+/* -------- GMAC_TIDM[4] : (GMAC Offset: 0x0A8) Type ID Match 1 Register -------- */
+#define GMAC_TIDM_TID_Pos 0
+#define GMAC_TIDM_TID_Msk (0xffffu << GMAC_TIDM_TID_Pos) /**< \brief (GMAC_TIDM[4]) Type ID Match 1 */
+#define GMAC_TIDM_TID(value) ((GMAC_TIDM_TID_Msk & ((value) << GMAC_TIDM_TID_Pos)))
+/* -------- GMAC_WOL : (GMAC Offset: 0x0B8) Wake on LAN Register -------- */
+#define GMAC_WOL_IP_Pos 0
+#define GMAC_WOL_IP_Msk (0xffffu << GMAC_WOL_IP_Pos) /**< \brief (GMAC_WOL) ARP Request IP Address */
+#define GMAC_WOL_IP(value) ((GMAC_WOL_IP_Msk & ((value) << GMAC_WOL_IP_Pos)))
+#define GMAC_WOL_MAG (0x1u << 16) /**< \brief (GMAC_WOL) Magic Packet Event Enable */
+#define GMAC_WOL_ARP (0x1u << 17) /**< \brief (GMAC_WOL) ARP Request IP Address */
+#define GMAC_WOL_SA1 (0x1u << 18) /**< \brief (GMAC_WOL) Specific Address Register 1 Event Enable */
+#define GMAC_WOL_MTI (0x1u << 19) /**< \brief (GMAC_WOL) Multicast Hash Event Enable */
+/* -------- GMAC_IPGS : (GMAC Offset: 0x0BC) IPG Stretch Register -------- */
+#define GMAC_IPGS_FL_Pos 0
+#define GMAC_IPGS_FL_Msk (0xffffu << GMAC_IPGS_FL_Pos) /**< \brief (GMAC_IPGS) Frame Length */
+#define GMAC_IPGS_FL(value) ((GMAC_IPGS_FL_Msk & ((value) << GMAC_IPGS_FL_Pos)))
+/* -------- GMAC_SVLAN : (GMAC Offset: 0x0C0) Stacked VLAN Register -------- */
+#define GMAC_SVLAN_VLAN_TYPE_Pos 0
+#define GMAC_SVLAN_VLAN_TYPE_Msk (0xffffu << GMAC_SVLAN_VLAN_TYPE_Pos) /**< \brief (GMAC_SVLAN) User Defined VLAN_TYPE Field */
+#define GMAC_SVLAN_VLAN_TYPE(value) ((GMAC_SVLAN_VLAN_TYPE_Msk & ((value) << GMAC_SVLAN_VLAN_TYPE_Pos)))
+#define GMAC_SVLAN_ESVLAN (0x1u << 31) /**< \brief (GMAC_SVLAN) Enable Stacked VLAN Processing Mode */
+/* -------- GMAC_TPFCP : (GMAC Offset: 0x0C4) Transmit PFC Pause Register -------- */
+#define GMAC_TPFCP_PEV_Pos 0
+#define GMAC_TPFCP_PEV_Msk (0xffu << GMAC_TPFCP_PEV_Pos) /**< \brief (GMAC_TPFCP) Priority Enable Vector */
+#define GMAC_TPFCP_PEV(value) ((GMAC_TPFCP_PEV_Msk & ((value) << GMAC_TPFCP_PEV_Pos)))
+#define GMAC_TPFCP_PQ_Pos 8
+#define GMAC_TPFCP_PQ_Msk (0xffu << GMAC_TPFCP_PQ_Pos) /**< \brief (GMAC_TPFCP) Pause Quantum */
+#define GMAC_TPFCP_PQ(value) ((GMAC_TPFCP_PQ_Msk & ((value) << GMAC_TPFCP_PQ_Pos)))
+/* -------- GMAC_SAMB1 : (GMAC Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register -------- */
+#define GMAC_SAMB1_ADDR_Pos 0
+#define GMAC_SAMB1_ADDR_Msk (0xffffffffu << GMAC_SAMB1_ADDR_Pos) /**< \brief (GMAC_SAMB1) Specific Address 1 Mask */
+#define GMAC_SAMB1_ADDR(value) ((GMAC_SAMB1_ADDR_Msk & ((value) << GMAC_SAMB1_ADDR_Pos)))
+/* -------- GMAC_SAMT1 : (GMAC Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register -------- */
+#define GMAC_SAMT1_ADDR_Pos 0
+#define GMAC_SAMT1_ADDR_Msk (0xffffu << GMAC_SAMT1_ADDR_Pos) /**< \brief (GMAC_SAMT1) Specific Address 1 Mask */
+#define GMAC_SAMT1_ADDR(value) ((GMAC_SAMT1_ADDR_Msk & ((value) << GMAC_SAMT1_ADDR_Pos)))
+/* -------- GMAC_OTLO : (GMAC Offset: 0x100) Octets Transmitted [31:0] Register -------- */
+#define GMAC_OTLO_TXO_Pos 0
+#define GMAC_OTLO_TXO_Msk (0xffffffffu << GMAC_OTLO_TXO_Pos) /**< \brief (GMAC_OTLO) Transmitted Octets */
+/* -------- GMAC_OTHI : (GMAC Offset: 0x104) Octets Transmitted [47:32] Register -------- */
+#define GMAC_OTHI_TXO_Pos 0
+#define GMAC_OTHI_TXO_Msk (0xffffu << GMAC_OTHI_TXO_Pos) /**< \brief (GMAC_OTHI) Transmitted Octets */
+/* -------- GMAC_FT : (GMAC Offset: 0x108) Frames Transmitted Register -------- */
+#define GMAC_FT_FTX_Pos 0
+#define GMAC_FT_FTX_Msk (0xffffffffu << GMAC_FT_FTX_Pos) /**< \brief (GMAC_FT) Frames Transmitted without Error */
+/* -------- GMAC_BCFT : (GMAC Offset: 0x10C) Broadcast Frames Transmitted Register -------- */
+#define GMAC_BCFT_BFTX_Pos 0
+#define GMAC_BCFT_BFTX_Msk (0xffffffffu << GMAC_BCFT_BFTX_Pos) /**< \brief (GMAC_BCFT) Broadcast Frames Transmitted without Error */
+/* -------- GMAC_MFT : (GMAC Offset: 0x110) Multicast Frames Transmitted Register -------- */
+#define GMAC_MFT_MFTX_Pos 0
+#define GMAC_MFT_MFTX_Msk (0xffffffffu << GMAC_MFT_MFTX_Pos) /**< \brief (GMAC_MFT) Multicast Frames Transmitted without Error */
+/* -------- GMAC_PFT : (GMAC Offset: 0x114) Pause Frames Transmitted Register -------- */
+#define GMAC_PFT_PFTX_Pos 0
+#define GMAC_PFT_PFTX_Msk (0xffffu << GMAC_PFT_PFTX_Pos) /**< \brief (GMAC_PFT) Pause Frames Transmitted Register */
+/* -------- GMAC_BFT64 : (GMAC Offset: 0x118) 64 Byte Frames Transmitted Register -------- */
+#define GMAC_BFT64_NFTX_Pos 0
+#define GMAC_BFT64_NFTX_Msk (0xffffffffu << GMAC_BFT64_NFTX_Pos) /**< \brief (GMAC_BFT64) 64 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT127 : (GMAC Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT127_NFTX_Pos 0
+#define GMAC_TBFT127_NFTX_Msk (0xffffffffu << GMAC_TBFT127_NFTX_Pos) /**< \brief (GMAC_TBFT127) 65 to 127 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT255 : (GMAC Offset: 0x120) 128 to 255 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT255_NFTX_Pos 0
+#define GMAC_TBFT255_NFTX_Msk (0xffffffffu << GMAC_TBFT255_NFTX_Pos) /**< \brief (GMAC_TBFT255) 128 to 255 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT511 : (GMAC Offset: 0x124) 256 to 511 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT511_NFTX_Pos 0
+#define GMAC_TBFT511_NFTX_Msk (0xffffffffu << GMAC_TBFT511_NFTX_Pos) /**< \brief (GMAC_TBFT511) 256 to 511 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT1023 : (GMAC Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT1023_NFTX_Pos 0
+#define GMAC_TBFT1023_NFTX_Msk (0xffffffffu << GMAC_TBFT1023_NFTX_Pos) /**< \brief (GMAC_TBFT1023) 512 to 1023 Byte Frames Transmitted without Error */
+/* -------- GMAC_TBFT1518 : (GMAC Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register -------- */
+#define GMAC_TBFT1518_NFTX_Pos 0
+#define GMAC_TBFT1518_NFTX_Msk (0xffffffffu << GMAC_TBFT1518_NFTX_Pos) /**< \brief (GMAC_TBFT1518) 1024 to 1518 Byte Frames Transmitted without Error */
+/* -------- GMAC_GTBFT1518 : (GMAC Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register -------- */
+#define GMAC_GTBFT1518_NFTX_Pos 0
+#define GMAC_GTBFT1518_NFTX_Msk (0xffffffffu << GMAC_GTBFT1518_NFTX_Pos) /**< \brief (GMAC_GTBFT1518) Greater than 1518 Byte Frames Transmitted without Error */
+/* -------- GMAC_TUR : (GMAC Offset: 0x134) Transmit Under Runs Register -------- */
+#define GMAC_TUR_TXUNR_Pos 0
+#define GMAC_TUR_TXUNR_Msk (0x3ffu << GMAC_TUR_TXUNR_Pos) /**< \brief (GMAC_TUR) Transmit Under Runs */
+/* -------- GMAC_SCF : (GMAC Offset: 0x138) Single Collision Frames Register -------- */
+#define GMAC_SCF_SCOL_Pos 0
+#define GMAC_SCF_SCOL_Msk (0x3ffffu << GMAC_SCF_SCOL_Pos) /**< \brief (GMAC_SCF) Single Collision */
+/* -------- GMAC_MCF : (GMAC Offset: 0x13C) Multiple Collision Frames Register -------- */
+#define GMAC_MCF_MCOL_Pos 0
+#define GMAC_MCF_MCOL_Msk (0x3ffffu << GMAC_MCF_MCOL_Pos) /**< \brief (GMAC_MCF) Multiple Collision */
+/* -------- GMAC_EC : (GMAC Offset: 0x140) Excessive Collisions Register -------- */
+#define GMAC_EC_XCOL_Pos 0
+#define GMAC_EC_XCOL_Msk (0x3ffu << GMAC_EC_XCOL_Pos) /**< \brief (GMAC_EC) Excessive Collisions */
+/* -------- GMAC_LC : (GMAC Offset: 0x144) Late Collisions Register -------- */
+#define GMAC_LC_LCOL_Pos 0
+#define GMAC_LC_LCOL_Msk (0x3ffu << GMAC_LC_LCOL_Pos) /**< \brief (GMAC_LC) Late Collisions */
+/* -------- GMAC_DTF : (GMAC Offset: 0x148) Deferred Transmission Frames Register -------- */
+#define GMAC_DTF_DEFT_Pos 0
+#define GMAC_DTF_DEFT_Msk (0x3ffffu << GMAC_DTF_DEFT_Pos) /**< \brief (GMAC_DTF) Deferred Transmission */
+/* -------- GMAC_CSE : (GMAC Offset: 0x14C) Carrier Sense Errors Register -------- */
+#define GMAC_CSE_CSR_Pos 0
+#define GMAC_CSE_CSR_Msk (0x3ffu << GMAC_CSE_CSR_Pos) /**< \brief (GMAC_CSE) Carrier Sense Error */
+/* -------- GMAC_ORLO : (GMAC Offset: 0x150) Octets Received [31:0] Received -------- */
+#define GMAC_ORLO_RXO_Pos 0
+#define GMAC_ORLO_RXO_Msk (0xffffffffu << GMAC_ORLO_RXO_Pos) /**< \brief (GMAC_ORLO) Received Octets */
+/* -------- GMAC_ORHI : (GMAC Offset: 0x154) Octets Received [47:32] Received -------- */
+#define GMAC_ORHI_RXO_Pos 0
+#define GMAC_ORHI_RXO_Msk (0xffffu << GMAC_ORHI_RXO_Pos) /**< \brief (GMAC_ORHI) Received Octets */
+/* -------- GMAC_FR : (GMAC Offset: 0x158) Frames Received Register -------- */
+#define GMAC_FR_FRX_Pos 0
+#define GMAC_FR_FRX_Msk (0xffffffffu << GMAC_FR_FRX_Pos) /**< \brief (GMAC_FR) Frames Received without Error */
+/* -------- GMAC_BCFR : (GMAC Offset: 0x15C) Broadcast Frames Received Register -------- */
+#define GMAC_BCFR_BFRX_Pos 0
+#define GMAC_BCFR_BFRX_Msk (0xffffffffu << GMAC_BCFR_BFRX_Pos) /**< \brief (GMAC_BCFR) Broadcast Frames Received without Error */
+/* -------- GMAC_MFR : (GMAC Offset: 0x160) Multicast Frames Received Register -------- */
+#define GMAC_MFR_MFRX_Pos 0
+#define GMAC_MFR_MFRX_Msk (0xffffffffu << GMAC_MFR_MFRX_Pos) /**< \brief (GMAC_MFR) Multicast Frames Received without Error */
+/* -------- GMAC_PFR : (GMAC Offset: 0x164) Pause Frames Received Register -------- */
+#define GMAC_PFR_PFRX_Pos 0
+#define GMAC_PFR_PFRX_Msk (0xffffu << GMAC_PFR_PFRX_Pos) /**< \brief (GMAC_PFR) Pause Frames Received Register */
+/* -------- GMAC_BFR64 : (GMAC Offset: 0x168) 64 Byte Frames Received Register -------- */
+#define GMAC_BFR64_NFRX_Pos 0
+#define GMAC_BFR64_NFRX_Msk (0xffffffffu << GMAC_BFR64_NFRX_Pos) /**< \brief (GMAC_BFR64) 64 Byte Frames Received without Error */
+/* -------- GMAC_TBFR127 : (GMAC Offset: 0x16C) 65 to 127 Byte Frames Received Register -------- */
+#define GMAC_TBFR127_NFRX_Pos 0
+#define GMAC_TBFR127_NFRX_Msk (0xffffffffu << GMAC_TBFR127_NFRX_Pos) /**< \brief (GMAC_TBFR127) 65 to 127 Byte Frames Received without Error */
+/* -------- GMAC_TBFR255 : (GMAC Offset: 0x170) 128 to 255 Byte Frames Received Register -------- */
+#define GMAC_TBFR255_NFRX_Pos 0
+#define GMAC_TBFR255_NFRX_Msk (0xffffffffu << GMAC_TBFR255_NFRX_Pos) /**< \brief (GMAC_TBFR255) 128 to 255 Byte Frames Received without Error */
+/* -------- GMAC_TBFR511 : (GMAC Offset: 0x174) 256 to 511Byte Frames Received Register -------- */
+#define GMAC_TBFR511_NFRX_Pos 0
+#define GMAC_TBFR511_NFRX_Msk (0xffffffffu << GMAC_TBFR511_NFRX_Pos) /**< \brief (GMAC_TBFR511) 256 to 511 Byte Frames Received without Error */
+/* -------- GMAC_TBFR1023 : (GMAC Offset: 0x178) 512 to 1023 Byte Frames Received Register -------- */
+#define GMAC_TBFR1023_NFRX_Pos 0
+#define GMAC_TBFR1023_NFRX_Msk (0xffffffffu << GMAC_TBFR1023_NFRX_Pos) /**< \brief (GMAC_TBFR1023) 512 to 1023 Byte Frames Received without Error */
+/* -------- GMAC_TBFR1518 : (GMAC Offset: 0x17C) 1024 to 1518 Byte Frames Received Register -------- */
+#define GMAC_TBFR1518_NFRX_Pos 0
+#define GMAC_TBFR1518_NFRX_Msk (0xffffffffu << GMAC_TBFR1518_NFRX_Pos) /**< \brief (GMAC_TBFR1518) 1024 to 1518 Byte Frames Received without Error */
+/* -------- GMAC_TMXBFR : (GMAC Offset: 0x180) 1519 to Maximum Byte Frames Received Register -------- */
+#define GMAC_TMXBFR_NFRX_Pos 0
+#define GMAC_TMXBFR_NFRX_Msk (0xffffffffu << GMAC_TMXBFR_NFRX_Pos) /**< \brief (GMAC_TMXBFR) 1519 to Maximum Byte Frames Received without Error */
+/* -------- GMAC_UFR : (GMAC Offset: 0x184) Undersize Frames Received Register -------- */
+#define GMAC_UFR_UFRX_Pos 0
+#define GMAC_UFR_UFRX_Msk (0x3ffu << GMAC_UFR_UFRX_Pos) /**< \brief (GMAC_UFR) Undersize Frames Received */
+/* -------- GMAC_OFR : (GMAC Offset: 0x188) Oversize Frames Received Register -------- */
+#define GMAC_OFR_OFRX_Pos 0
+#define GMAC_OFR_OFRX_Msk (0x3ffu << GMAC_OFR_OFRX_Pos) /**< \brief (GMAC_OFR) Oversized Frames Received */
+/* -------- GMAC_JR : (GMAC Offset: 0x18C) Jabbers Received Register -------- */
+#define GMAC_JR_JRX_Pos 0
+#define GMAC_JR_JRX_Msk (0x3ffu << GMAC_JR_JRX_Pos) /**< \brief (GMAC_JR) Jabbers Received */
+/* -------- GMAC_FCSE : (GMAC Offset: 0x190) Frame Check Sequence Errors Register -------- */
+#define GMAC_FCSE_FCKR_Pos 0
+#define GMAC_FCSE_FCKR_Msk (0x3ffu << GMAC_FCSE_FCKR_Pos) /**< \brief (GMAC_FCSE) Frame Check Sequence Errors */
+/* -------- GMAC_LFFE : (GMAC Offset: 0x194) Length Field Frame Errors Register -------- */
+#define GMAC_LFFE_LFER_Pos 0
+#define GMAC_LFFE_LFER_Msk (0x3ffu << GMAC_LFFE_LFER_Pos) /**< \brief (GMAC_LFFE) Length Field Frame Errors */
+/* -------- GMAC_RSE : (GMAC Offset: 0x198) Receive Symbol Errors Register -------- */
+#define GMAC_RSE_RXSE_Pos 0
+#define GMAC_RSE_RXSE_Msk (0x3ffu << GMAC_RSE_RXSE_Pos) /**< \brief (GMAC_RSE) Receive Symbol Errors */
+/* -------- GMAC_AE : (GMAC Offset: 0x19C) Alignment Errors Register -------- */
+#define GMAC_AE_AER_Pos 0
+#define GMAC_AE_AER_Msk (0x3ffu << GMAC_AE_AER_Pos) /**< \brief (GMAC_AE) Alignment Errors */
+/* -------- GMAC_RRE : (GMAC Offset: 0x1A0) Receive Resource Errors Register -------- */
+#define GMAC_RRE_RXRER_Pos 0
+#define GMAC_RRE_RXRER_Msk (0x3ffffu << GMAC_RRE_RXRER_Pos) /**< \brief (GMAC_RRE) Receive Resource Errors */
+/* -------- GMAC_ROE : (GMAC Offset: 0x1A4) Receive Overrun Register -------- */
+#define GMAC_ROE_RXOVR_Pos 0
+#define GMAC_ROE_RXOVR_Msk (0x3ffu << GMAC_ROE_RXOVR_Pos) /**< \brief (GMAC_ROE) Receive Overruns */
+/* -------- GMAC_IHCE : (GMAC Offset: 0x1A8) IP Header Checksum Errors Register -------- */
+#define GMAC_IHCE_HCKER_Pos 0
+#define GMAC_IHCE_HCKER_Msk (0xffu << GMAC_IHCE_HCKER_Pos) /**< \brief (GMAC_IHCE) IP Header Checksum Errors */
+/* -------- GMAC_TCE : (GMAC Offset: 0x1AC) TCP Checksum Errors Register -------- */
+#define GMAC_TCE_TCKER_Pos 0
+#define GMAC_TCE_TCKER_Msk (0xffu << GMAC_TCE_TCKER_Pos) /**< \brief (GMAC_TCE) TCP Checksum Errors */
+/* -------- GMAC_UCE : (GMAC Offset: 0x1B0) UDP Checksum Errors Register -------- */
+#define GMAC_UCE_UCKER_Pos 0
+#define GMAC_UCE_UCKER_Msk (0xffu << GMAC_UCE_UCKER_Pos) /**< \brief (GMAC_UCE) UDP Checksum Errors */
+/* -------- GMAC_TSSS : (GMAC Offset: 0x1C8) 1588 Timer Sync Strobe Seconds Register -------- */
+#define GMAC_TSSS_VTS_Pos 0
+#define GMAC_TSSS_VTS_Msk (0xffffffffu << GMAC_TSSS_VTS_Pos) /**< \brief (GMAC_TSSS) Value of Timer Seconds Register Capture */
+#define GMAC_TSSS_VTS(value) ((GMAC_TSSS_VTS_Msk & ((value) << GMAC_TSSS_VTS_Pos)))
+/* -------- GMAC_TSSN : (GMAC Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register -------- */
+#define GMAC_TSSN_VTN_Pos 0
+#define GMAC_TSSN_VTN_Msk (0x3fffffffu << GMAC_TSSN_VTN_Pos) /**< \brief (GMAC_TSSN) Value Timer Nanoseconds Register Capture */
+#define GMAC_TSSN_VTN(value) ((GMAC_TSSN_VTN_Msk & ((value) << GMAC_TSSN_VTN_Pos)))
+/* -------- GMAC_TS : (GMAC Offset: 0x1D0) 1588 Timer Seconds Register -------- */
+#define GMAC_TS_TCS_Pos 0
+#define GMAC_TS_TCS_Msk (0xffffffffu << GMAC_TS_TCS_Pos) /**< \brief (GMAC_TS) Timer Count in Seconds */
+#define GMAC_TS_TCS(value) ((GMAC_TS_TCS_Msk & ((value) << GMAC_TS_TCS_Pos)))
+/* -------- GMAC_TN : (GMAC Offset: 0x1D4) 1588 Timer Nanoseconds Register -------- */
+#define GMAC_TN_TNS_Pos 0
+#define GMAC_TN_TNS_Msk (0x3fffffffu << GMAC_TN_TNS_Pos) /**< \brief (GMAC_TN) Timer Count in Nanoseconds */
+#define GMAC_TN_TNS(value) ((GMAC_TN_TNS_Msk & ((value) << GMAC_TN_TNS_Pos)))
+/* -------- GMAC_TA : (GMAC Offset: 0x1D8) 1588 Timer Adjust Register -------- */
+#define GMAC_TA_ITDT_Pos 0
+#define GMAC_TA_ITDT_Msk (0x3fffffffu << GMAC_TA_ITDT_Pos) /**< \brief (GMAC_TA) Increment/Decrement */
+#define GMAC_TA_ITDT(value) ((GMAC_TA_ITDT_Msk & ((value) << GMAC_TA_ITDT_Pos)))
+#define GMAC_TA_ADJ (0x1u << 31) /**< \brief (GMAC_TA) Adjust 1588 Timer */
+/* -------- GMAC_TI : (GMAC Offset: 0x1DC) 1588 Timer Increment Register -------- */
+#define GMAC_TI_CNS_Pos 0
+#define GMAC_TI_CNS_Msk (0xffu << GMAC_TI_CNS_Pos) /**< \brief (GMAC_TI) Count Nanoseconds */
+#define GMAC_TI_CNS(value) ((GMAC_TI_CNS_Msk & ((value) << GMAC_TI_CNS_Pos)))
+#define GMAC_TI_ACNS_Pos 8
+#define GMAC_TI_ACNS_Msk (0xffu << GMAC_TI_ACNS_Pos) /**< \brief (GMAC_TI) Alternative Count Nanoseconds */
+#define GMAC_TI_ACNS(value) ((GMAC_TI_ACNS_Msk & ((value) << GMAC_TI_ACNS_Pos)))
+#define GMAC_TI_NIT_Pos 16
+#define GMAC_TI_NIT_Msk (0xffu << GMAC_TI_NIT_Pos) /**< \brief (GMAC_TI) Number of Increments */
+#define GMAC_TI_NIT(value) ((GMAC_TI_NIT_Msk & ((value) << GMAC_TI_NIT_Pos)))
+/* -------- GMAC_EFTS : (GMAC Offset: 0x1E0) PTP Event Frame Transmitted Seconds -------- */
+#define GMAC_EFTS_RUD_Pos 0
+#define GMAC_EFTS_RUD_Msk (0xffffffffu << GMAC_EFTS_RUD_Pos) /**< \brief (GMAC_EFTS) Register Update */
+/* -------- GMAC_EFTN : (GMAC Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds -------- */
+#define GMAC_EFTN_RUD_Pos 0
+#define GMAC_EFTN_RUD_Msk (0x3fffffffu << GMAC_EFTN_RUD_Pos) /**< \brief (GMAC_EFTN) Register Update */
+/* -------- GMAC_EFRS : (GMAC Offset: 0x1E8) PTP Event Frame Received Seconds -------- */
+#define GMAC_EFRS_RUD_Pos 0
+#define GMAC_EFRS_RUD_Msk (0xffffffffu << GMAC_EFRS_RUD_Pos) /**< \brief (GMAC_EFRS) Register Update */
+/* -------- GMAC_EFRN : (GMAC Offset: 0x1EC) PTP Event Frame Received Nanoseconds -------- */
+#define GMAC_EFRN_RUD_Pos 0
+#define GMAC_EFRN_RUD_Msk (0x3fffffffu << GMAC_EFRN_RUD_Pos) /**< \brief (GMAC_EFRN) Register Update */
+/* -------- GMAC_PEFTS : (GMAC Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds -------- */
+#define GMAC_PEFTS_RUD_Pos 0
+#define GMAC_PEFTS_RUD_Msk (0xffffffffu << GMAC_PEFTS_RUD_Pos) /**< \brief (GMAC_PEFTS) Register Update */
+/* -------- GMAC_PEFTN : (GMAC Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds -------- */
+#define GMAC_PEFTN_RUD_Pos 0
+#define GMAC_PEFTN_RUD_Msk (0x3fffffffu << GMAC_PEFTN_RUD_Pos) /**< \brief (GMAC_PEFTN) Register Update */
+/* -------- GMAC_PEFRS : (GMAC Offset: 0x1F8) PTP Peer Event Frame Received Seconds -------- */
+#define GMAC_PEFRS_RUD_Pos 0
+#define GMAC_PEFRS_RUD_Msk (0xffffffffu << GMAC_PEFRS_RUD_Pos) /**< \brief (GMAC_PEFRS) Register Update */
+/* -------- GMAC_PEFRN : (GMAC Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds -------- */
+#define GMAC_PEFRN_RUD_Pos 0
+#define GMAC_PEFRN_RUD_Msk (0x3fffffffu << GMAC_PEFRN_RUD_Pos) /**< \brief (GMAC_PEFRN) Register Update */
+/* -------- GMAC_ISRPQ[7] : (GMAC Offset: 0x400) Interrupt Status Register Priority Queue -------- */
+#define GMAC_ISRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_ISRPQ[7]) Receive Complete */
+#define GMAC_ISRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_ISRPQ[7]) RX Used Bit Read */
+#define GMAC_ISRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_ISRPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_ISRPQ_TFC (0x1u << 6) /**< \brief (GMAC_ISRPQ[7]) Transmit Frame Corruption due to AHB error */
+#define GMAC_ISRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_ISRPQ[7]) Transmit Complete */
+#define GMAC_ISRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_ISRPQ[7]) Receive Overrun */
+#define GMAC_ISRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_ISRPQ[7]) HRESP Not OK */
+/* -------- GMAC_TBQBAPQ[7] : (GMAC Offset: 0x440) Transmit Buffer Queue Base Address Priority Queue -------- */
+#define GMAC_TBQBAPQ_TXBQBA_Pos 2
+#define GMAC_TBQBAPQ_TXBQBA_Msk (0x3fu << GMAC_TBQBAPQ_TXBQBA_Pos) /**< \brief (GMAC_TBQBAPQ[7]) Transmit Buffer Queue Base Address */
+#define GMAC_TBQBAPQ_TXBQBA(value) ((GMAC_TBQBAPQ_TXBQBA_Msk & ((value) << GMAC_TBQBAPQ_TXBQBA_Pos)))
+/* -------- GMAC_RBQBAPQ[7] : (GMAC Offset: 0x480) Receive Buffer Queue Base Address Priority Queue -------- */
+#define GMAC_RBQBAPQ_RXBQBA_Pos 2
+#define GMAC_RBQBAPQ_RXBQBA_Msk (0x3fu << GMAC_RBQBAPQ_RXBQBA_Pos) /**< \brief (GMAC_RBQBAPQ[7]) Receive Buffer Queue Base Address */
+#define GMAC_RBQBAPQ_RXBQBA(value) ((GMAC_RBQBAPQ_RXBQBA_Msk & ((value) << GMAC_RBQBAPQ_RXBQBA_Pos)))
+/* -------- GMAC_RBSRPQ[7] : (GMAC Offset: 0x4A0) Receive Buffer Size Register Priority Queue -------- */
+#define GMAC_RBSRPQ_RBS_Pos 0
+#define GMAC_RBSRPQ_RBS_Msk (0xffffu << GMAC_RBSRPQ_RBS_Pos) /**< \brief (GMAC_RBSRPQ[7]) Receive Buffer Size */
+#define GMAC_RBSRPQ_RBS(value) ((GMAC_RBSRPQ_RBS_Msk & ((value) << GMAC_RBSRPQ_RBS_Pos)))
+/* -------- GMAC_ST1RPQ[16] : (GMAC Offset: 0x500) Screening Type1 Register Priority Queue -------- */
+#define GMAC_ST1RPQ_QNB_Pos 0
+#define GMAC_ST1RPQ_QNB_Msk (0xfu << GMAC_ST1RPQ_QNB_Pos) /**< \brief (GMAC_ST1RPQ[16]) Que Number (0->7) */
+#define GMAC_ST1RPQ_QNB(value) ((GMAC_ST1RPQ_QNB_Msk & ((value) << GMAC_ST1RPQ_QNB_Pos)))
+#define GMAC_ST1RPQ_DSTCM_Pos 4
+#define GMAC_ST1RPQ_DSTCM_Msk (0xffu << GMAC_ST1RPQ_DSTCM_Pos) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match */
+#define GMAC_ST1RPQ_DSTCM(value) ((GMAC_ST1RPQ_DSTCM_Msk & ((value) << GMAC_ST1RPQ_DSTCM_Pos)))
+#define GMAC_ST1RPQ_UDPM_Pos 12
+#define GMAC_ST1RPQ_UDPM_Msk (0xffffu << GMAC_ST1RPQ_UDPM_Pos) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match */
+#define GMAC_ST1RPQ_UDPM(value) ((GMAC_ST1RPQ_UDPM_Msk & ((value) << GMAC_ST1RPQ_UDPM_Pos)))
+#define GMAC_ST1RPQ_DSTCE (0x1u << 28) /**< \brief (GMAC_ST1RPQ[16]) Differentiated Services or Traffic Class Match Enable */
+#define GMAC_ST1RPQ_UDPE (0x1u << 29) /**< \brief (GMAC_ST1RPQ[16]) UDP Port Match Enable */
+/* -------- GMAC_ST2RPQ[16] : (GMAC Offset: 0x540) Screening Type2 Register Priority Queue -------- */
+#define GMAC_ST2RPQ_QNB_Pos 0
+#define GMAC_ST2RPQ_QNB_Msk (0xfu << GMAC_ST2RPQ_QNB_Pos) /**< \brief (GMAC_ST2RPQ[16]) Que Number (0->7) */
+#define GMAC_ST2RPQ_QNB(value) ((GMAC_ST2RPQ_QNB_Msk & ((value) << GMAC_ST2RPQ_QNB_Pos)))
+#define GMAC_ST2RPQ_VLANP_Pos 4
+#define GMAC_ST2RPQ_VLANP_Msk (0xfu << GMAC_ST2RPQ_VLANP_Pos) /**< \brief (GMAC_ST2RPQ[16]) VLAN Priority */
+#define GMAC_ST2RPQ_VLANP(value) ((GMAC_ST2RPQ_VLANP_Msk & ((value) << GMAC_ST2RPQ_VLANP_Pos)))
+#define GMAC_ST2RPQ_VLANE (0x1u << 8) /**< \brief (GMAC_ST2RPQ[16]) VLAN Enable */
+/* -------- GMAC_IERPQ[7] : (GMAC Offset: 0x600) Interrupt Enable Register Priority Queue -------- */
+#define GMAC_IERPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IERPQ[7]) Receive Complete */
+#define GMAC_IERPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IERPQ[7]) RX Used Bit Read */
+#define GMAC_IERPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IERPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_IERPQ_TFC (0x1u << 6) /**< \brief (GMAC_IERPQ[7]) Transmit Frame Corruption due to AHB error */
+#define GMAC_IERPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IERPQ[7]) Transmit Complete */
+#define GMAC_IERPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IERPQ[7]) Receive Overrun */
+#define GMAC_IERPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IERPQ[7]) HRESP Not OK */
+/* -------- GMAC_IDRPQ[7] : (GMAC Offset: 0x620) Interrupt Disable Register Priority Queue -------- */
+#define GMAC_IDRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IDRPQ[7]) Receive Complete */
+#define GMAC_IDRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IDRPQ[7]) RX Used Bit Read */
+#define GMAC_IDRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IDRPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_IDRPQ_TFC (0x1u << 6) /**< \brief (GMAC_IDRPQ[7]) Transmit Frame Corruption due to AHB error */
+#define GMAC_IDRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IDRPQ[7]) Transmit Complete */
+#define GMAC_IDRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IDRPQ[7]) Receive Overrun */
+#define GMAC_IDRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IDRPQ[7]) HRESP Not OK */
+/* -------- GMAC_IMRPQ[7] : (GMAC Offset: 0x640) Interrupt Mask Register Priority Queue -------- */
+#define GMAC_IMRPQ_RCOMP (0x1u << 1) /**< \brief (GMAC_IMRPQ[7]) Receive Complete */
+#define GMAC_IMRPQ_RXUBR (0x1u << 2) /**< \brief (GMAC_IMRPQ[7]) RX Used Bit Read */
+#define GMAC_IMRPQ_RLEX (0x1u << 5) /**< \brief (GMAC_IMRPQ[7]) Retry Limit Exceeded or Late Collision */
+#define GMAC_IMRPQ_AHB (0x1u << 6) /**< \brief (GMAC_IMRPQ[7]) AHB Error */
+#define GMAC_IMRPQ_TCOMP (0x1u << 7) /**< \brief (GMAC_IMRPQ[7]) Transmit Complete */
+#define GMAC_IMRPQ_ROVR (0x1u << 10) /**< \brief (GMAC_IMRPQ[7]) Receive Overrun */
+#define GMAC_IMRPQ_HRESP (0x1u << 11) /**< \brief (GMAC_IMRPQ[7]) HRESP Not OK */
+
+/*@}*/
+
+
+#endif /* _SAM4E_GMAC_COMPONENT_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c
index fe9e2960f..fc72c6ad9 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.c
@@ -1,454 +1,454 @@
- /**
- * \file
- *
- * \brief API driver for KSZ8051MNL PHY component.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "FreeRTOSIPConfig.h"
-
-#include "ethernet_phy.h"
-#include "instance/gmac.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \defgroup ksz8051mnl_ethernet_phy_group PHY component (KSZ8051MNL)
- *
- * Driver for the ksz8051mnl component. This driver provides access to the main
- * features of the PHY.
- *
- * \section dependencies Dependencies
- * This driver depends on the following modules:
- * - \ref gmac_group Ethernet Media Access Controller (GMAC) module.
- *
- * @{
- */
-
-SPhyProps phyProps;
-
-/* Max PHY number */
-#define ETH_PHY_MAX_ADDR 31
-
-/* Ethernet PHY operation max retry count */
-#define ETH_PHY_RETRY_MAX 1000000
-
-/* Ethernet PHY operation timeout */
-#define ETH_PHY_TIMEOUT 10
-
-/**
- * \brief Find a valid PHY Address ( from addrStart to 31 ).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_start_addr Start address of the PHY to be searched.
- *
- * \return 0xFF when no valid PHY address is found.
- */
-int ethernet_phy_addr = 0;
-static uint8_t ethernet_phy_find_valid(Gmac *p_gmac, uint8_t uc_phy_addr,
- uint8_t uc_start_addr)
-{
- uint32_t ul_value = 0;
- uint8_t uc_cnt;
- uint8_t uc_phy_address = uc_phy_addr;
-
- gmac_enable_management(p_gmac, true);
-/*
-#define GMII_OUI_MSB 0x0022
-#define GMII_OUI_LSB 0x05
-
-PHYID1 = 0x0022
-PHYID2 = 0x1550
-0001_0101_0101_0000 = 0x1550 <= mask should be 0xFFF0
-*/
- /* Check the current PHY address */
- gmac_phy_read(p_gmac, uc_phy_addr, GMII_PHYID1, &ul_value);
-
- /* Find another one */
- if (ul_value != GMII_OUI_MSB) {
- ethernet_phy_addr = 0xFF;
- for (uc_cnt = uc_start_addr; uc_cnt <= ETH_PHY_MAX_ADDR; uc_cnt++) {
- uc_phy_address = (uc_phy_address + 1) & 0x1F;
- ul_value = 0;
- gmac_phy_read(p_gmac, uc_phy_address, GMII_PHYID1, &ul_value);
- if (ul_value == GMII_OUI_MSB) {
- ethernet_phy_addr = uc_phy_address;
- break;
- }
- }
- }
-
- gmac_enable_management(p_gmac, false);
-
- if (ethernet_phy_addr != 0xFF) {
- gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_value);
- }
- return ethernet_phy_addr;
-}
-
-
-/**
- * \brief Perform a HW initialization to the PHY and set up clocks.
- *
- * This should be called only once to initialize the PHY pre-settings.
- * The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups).
- * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
- * The RXDV pin is used to select test mode on reset (pulled up for test mode).
- * The above pins should be predefined for corresponding settings in resetPins.
- * The GMAC peripheral pins are configured after the reset is done.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param ul_mck GMAC MCK.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck)
-{
- uint8_t uc_rc = GMAC_TIMEOUT;
- uint8_t uc_phy;
-
- ethernet_phy_reset(GMAC,uc_phy_addr);
-
- /* Configure GMAC runtime clock */
- uc_rc = gmac_set_mdc_clock(p_gmac, mck);
- if (uc_rc != GMAC_OK) {
- return 0;
- }
-
- /* Check PHY Address */
- uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0);
- if (uc_phy == 0xFF) {
- return 0;
- }
- if (uc_phy != uc_phy_addr) {
- ethernet_phy_reset(p_gmac, uc_phy_addr);
- }
- phy_props.phy_chn = uc_phy;
- return uc_phy;
-}
-
-
-/**
- * \brief Get the Link & speed settings, and automatically set up the GMAC with the
- * settings.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
- uint8_t uc_apply_setting_flag)
-{
- uint32_t ul_stat1;
- uint32_t ul_stat2;
- uint8_t uc_phy_address, uc_speed = true, uc_fd = true;
- uint8_t uc_rc = GMAC_TIMEOUT;
-
- gmac_enable_management(p_gmac, true);
-
- uc_phy_address = uc_phy_addr;
-
- uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_stat1);
- if (uc_rc != GMAC_OK) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return uc_rc;
- }
- if ((ul_stat1 & GMII_LINK_STATUS) == 0) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return GMAC_INVALID;
- }
-
- if (uc_apply_setting_flag == 0) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return uc_rc;
- }
-
- /* Read advertisement */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_ANAR, &ul_stat2);
-phy_props.phy_stat1 = ul_stat1;
-phy_props.phy_stat2 = ul_stat2;
- if (uc_rc != GMAC_OK) {
- /* Disable PHY management and start the GMAC transfer */
- gmac_enable_management(p_gmac, false);
-
- return uc_rc;
- }
-
- if ((ul_stat1 & GMII_100BASE_TX_FD) && (ul_stat2 & GMII_100TX_FDX)) {
- /* Set GMAC for 100BaseTX and Full Duplex */
- uc_speed = true;
- uc_fd = true;
- } else
- if ((ul_stat1 & GMII_100BASE_T4_HD) && (ul_stat2 & GMII_100TX_HDX)) {
- /* Set MII for 100BaseTX and Half Duplex */
- uc_speed = true;
- uc_fd = false;
- } else
- if ((ul_stat1 & GMII_10BASE_T_FD) && (ul_stat2 & GMII_10_FDX)) {
- /* Set MII for 10BaseT and Full Duplex */
- uc_speed = false;
- uc_fd = true;
- } else
- if ((ul_stat1 & GMII_10BASE_T_HD) && (ul_stat2 & GMII_10_HDX)) {
- /* Set MII for 10BaseT and Half Duplex */
- uc_speed = false;
- uc_fd = false;
- }
-
- gmac_set_speed(p_gmac, uc_speed);
- gmac_enable_full_duplex(p_gmac, uc_fd);
-
- /* Start the GMAC transfers */
- gmac_enable_management(p_gmac, false);
- return uc_rc;
-}
-
-PhyProps_t phy_props;
-
-/**
- * \brief Issue an auto negotiation of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr)
-{
- uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
- uint32_t ul_value;
- uint32_t ul_phy_anar;
- uint32_t ul_retry_count = 0;
- uint8_t uc_speed = 0;
- uint8_t uc_fd=0;
- uint8_t uc_rc = GMAC_TIMEOUT;
-
- gmac_enable_management(p_gmac, true);
-
- /* Set up control register */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -1;
- return uc_rc;
- }
-
- ul_value &= ~(uint32_t)GMII_AUTONEG; /* Remove auto-negotiation enable */
- ul_value &= ~(uint32_t)(GMII_LOOPBACK | GMII_POWER_DOWN);
- ul_value |= (uint32_t)GMII_ISOLATE; /* Electrically isolate PHY */
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -2;
- return uc_rc;
- }
-
- /*
- * Set the Auto_negotiation Advertisement Register.
- * MII advertising for Next page.
- * 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
- */
- ul_phy_anar = GMII_100TX_FDX | GMII_100TX_HDX | GMII_10_FDX | GMII_10_HDX |
- GMII_AN_IEEE_802_3;
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_ANAR, ul_phy_anar);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -3;
- return uc_rc;
- }
-
- /* Read & modify control register */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -4;
- return uc_rc;
- }
-
- ul_value |= GMII_SPEED_SELECT | GMII_AUTONEG | GMII_DUPLEX_MODE;
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -5;
- return uc_rc;
- }
-
- /* Restart auto negotiation */
- ul_value |= (uint32_t)GMII_RESTART_AUTONEG;
- ul_value &= ~(uint32_t)GMII_ISOLATE;
- uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -6;
- return uc_rc;
- }
-
- /* Check if auto negotiation is completed */
- while (1) {
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -7;
- return uc_rc;
- }
- /* Done successfully */
- if (ul_value & GMII_AUTONEG_COMP) {
- break;
- }
-
- /* Timeout check */
- if (ul_retry_max) {
- if (++ul_retry_count >= ul_retry_max) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -8;
- return GMAC_TIMEOUT;
- }
- }
- }
-
- /* Get the auto negotiate link partner base page */
- uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_PCR1, &phy_props.phy_params);
- if (uc_rc != GMAC_OK) {
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = -9;
- return uc_rc;
- }
-
-
- /* Set up the GMAC link speed */
- if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_FDX) {
- /* Set MII for 100BaseTX and Full Duplex */
- uc_speed = true;
- uc_fd = true;
- } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_FDX) {
- /* Set MII for 10BaseT and Full Duplex */
- uc_speed = false;
- uc_fd = true;
- } else if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_HDX) {
- /* Set MII for 100BaseTX and half Duplex */
- uc_speed = true;
- uc_fd = false;
- } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_HDX) {
- /* Set MII for 10BaseT and half Duplex */
- uc_speed = false;
- uc_fd = false;
- }
-
- gmac_set_speed(p_gmac, uc_speed);
- gmac_enable_full_duplex(p_gmac, uc_fd);
-
- /* Select Media Independent Interface type */
- gmac_select_mii_mode(p_gmac, ETH_PHY_MODE);
-
- gmac_enable_transmit(GMAC, true);
- gmac_enable_receive(GMAC, true);
-
- gmac_enable_management(p_gmac, false);
-phy_props.phy_result = 1;
- return uc_rc;
-}
-
-/**
- * \brief Issue a SW reset to reset all registers of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr)
-{
- uint32_t ul_bmcr = GMII_RESET;
- uint8_t uc_phy_address = uc_phy_addr;
- uint32_t ul_timeout = ETH_PHY_TIMEOUT;
- uint8_t uc_rc = GMAC_TIMEOUT;
-
- gmac_enable_management(p_gmac, true);
-
- ul_bmcr = GMII_RESET;
- gmac_phy_write(p_gmac, uc_phy_address, GMII_BMCR, ul_bmcr);
-
- do {
- gmac_phy_read(p_gmac, uc_phy_address, GMII_BMCR, &ul_bmcr);
- ul_timeout--;
- } while ((ul_bmcr & GMII_RESET) && ul_timeout);
-
- gmac_enable_management(p_gmac, false);
-
- if (!ul_timeout) {
- uc_rc = GMAC_OK;
- }
-
- return (uc_rc);
-}
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \}
- */
+ /**
+ * \file
+ *
+ * \brief API driver for KSZ8051MNL PHY component.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "FreeRTOSIPConfig.h"
+
+#include "ethernet_phy.h"
+#include "instance/gmac.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \defgroup ksz8051mnl_ethernet_phy_group PHY component (KSZ8051MNL)
+ *
+ * Driver for the ksz8051mnl component. This driver provides access to the main
+ * features of the PHY.
+ *
+ * \section dependencies Dependencies
+ * This driver depends on the following modules:
+ * - \ref gmac_group Ethernet Media Access Controller (GMAC) module.
+ *
+ * @{
+ */
+
+SPhyProps phyProps;
+
+/* Max PHY number */
+#define ETH_PHY_MAX_ADDR 31
+
+/* Ethernet PHY operation max retry count */
+#define ETH_PHY_RETRY_MAX 1000000
+
+/* Ethernet PHY operation timeout */
+#define ETH_PHY_TIMEOUT 10
+
+/**
+ * \brief Find a valid PHY Address ( from addrStart to 31 ).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_start_addr Start address of the PHY to be searched.
+ *
+ * \return 0xFF when no valid PHY address is found.
+ */
+int ethernet_phy_addr = 0;
+static uint8_t ethernet_phy_find_valid(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_start_addr)
+{
+ uint32_t ul_value = 0;
+ uint8_t uc_cnt;
+ uint8_t uc_phy_address = uc_phy_addr;
+
+ gmac_enable_management(p_gmac, true);
+/*
+#define GMII_OUI_MSB 0x0022
+#define GMII_OUI_LSB 0x05
+
+PHYID1 = 0x0022
+PHYID2 = 0x1550
+0001_0101_0101_0000 = 0x1550 <= mask should be 0xFFF0
+*/
+ /* Check the current PHY address */
+ gmac_phy_read(p_gmac, uc_phy_addr, GMII_PHYID1, &ul_value);
+
+ /* Find another one */
+ if (ul_value != GMII_OUI_MSB) {
+ ethernet_phy_addr = 0xFF;
+ for (uc_cnt = uc_start_addr; uc_cnt <= ETH_PHY_MAX_ADDR; uc_cnt++) {
+ uc_phy_address = (uc_phy_address + 1) & 0x1F;
+ ul_value = 0;
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_PHYID1, &ul_value);
+ if (ul_value == GMII_OUI_MSB) {
+ ethernet_phy_addr = uc_phy_address;
+ break;
+ }
+ }
+ }
+
+ gmac_enable_management(p_gmac, false);
+
+ if (ethernet_phy_addr != 0xFF) {
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_value);
+ }
+ return ethernet_phy_addr;
+}
+
+
+/**
+ * \brief Perform a HW initialization to the PHY and set up clocks.
+ *
+ * This should be called only once to initialize the PHY pre-settings.
+ * The PHY address is the reset status of CRS, RXD[3:0] (the emacPins' pullups).
+ * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
+ * The RXDV pin is used to select test mode on reset (pulled up for test mode).
+ * The above pins should be predefined for corresponding settings in resetPins.
+ * The GMAC peripheral pins are configured after the reset is done.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param ul_mck GMAC MCK.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t mck)
+{
+ uint8_t uc_rc = GMAC_TIMEOUT;
+ uint8_t uc_phy;
+
+ ethernet_phy_reset(GMAC,uc_phy_addr);
+
+ /* Configure GMAC runtime clock */
+ uc_rc = gmac_set_mdc_clock(p_gmac, mck);
+ if (uc_rc != GMAC_OK) {
+ return 0;
+ }
+
+ /* Check PHY Address */
+ uc_phy = ethernet_phy_find_valid(p_gmac, uc_phy_addr, 0);
+ if (uc_phy == 0xFF) {
+ return 0;
+ }
+ if (uc_phy != uc_phy_addr) {
+ ethernet_phy_reset(p_gmac, uc_phy_addr);
+ }
+ phy_props.phy_chn = uc_phy;
+ return uc_phy;
+}
+
+
+/**
+ * \brief Get the Link & speed settings, and automatically set up the GMAC with the
+ * settings.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_apply_setting_flag)
+{
+ uint32_t ul_stat1;
+ uint32_t ul_stat2;
+ uint8_t uc_phy_address, uc_speed = true, uc_fd = true;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ uc_phy_address = uc_phy_addr;
+
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_BMSR, &ul_stat1);
+ if (uc_rc != GMAC_OK) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+ if ((ul_stat1 & GMII_LINK_STATUS) == 0) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return GMAC_INVALID;
+ }
+
+ if (uc_apply_setting_flag == 0) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ /* Read advertisement */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_address, GMII_ANAR, &ul_stat2);
+phy_props.phy_stat1 = ul_stat1;
+phy_props.phy_stat2 = ul_stat2;
+ if (uc_rc != GMAC_OK) {
+ /* Disable PHY management and start the GMAC transfer */
+ gmac_enable_management(p_gmac, false);
+
+ return uc_rc;
+ }
+
+ if ((ul_stat1 & GMII_100BASE_TX_FD) && (ul_stat2 & GMII_100TX_FDX)) {
+ /* Set GMAC for 100BaseTX and Full Duplex */
+ uc_speed = true;
+ uc_fd = true;
+ } else
+ if ((ul_stat1 & GMII_100BASE_T4_HD) && (ul_stat2 & GMII_100TX_HDX)) {
+ /* Set MII for 100BaseTX and Half Duplex */
+ uc_speed = true;
+ uc_fd = false;
+ } else
+ if ((ul_stat1 & GMII_10BASE_T_FD) && (ul_stat2 & GMII_10_FDX)) {
+ /* Set MII for 10BaseT and Full Duplex */
+ uc_speed = false;
+ uc_fd = true;
+ } else
+ if ((ul_stat1 & GMII_10BASE_T_HD) && (ul_stat2 & GMII_10_HDX)) {
+ /* Set MII for 10BaseT and Half Duplex */
+ uc_speed = false;
+ uc_fd = false;
+ }
+
+ gmac_set_speed(p_gmac, uc_speed);
+ gmac_enable_full_duplex(p_gmac, uc_fd);
+
+ /* Start the GMAC transfers */
+ gmac_enable_management(p_gmac, false);
+ return uc_rc;
+}
+
+PhyProps_t phy_props;
+
+/**
+ * \brief Issue an auto negotiation of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr)
+{
+ uint32_t ul_retry_max = ETH_PHY_RETRY_MAX;
+ uint32_t ul_value;
+ uint32_t ul_phy_anar;
+ uint32_t ul_retry_count = 0;
+ uint8_t uc_speed = 0;
+ uint8_t uc_fd=0;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ /* Set up control register */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -1;
+ return uc_rc;
+ }
+
+ ul_value &= ~(uint32_t)GMII_AUTONEG; /* Remove auto-negotiation enable */
+ ul_value &= ~(uint32_t)(GMII_LOOPBACK | GMII_POWER_DOWN);
+ ul_value |= (uint32_t)GMII_ISOLATE; /* Electrically isolate PHY */
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -2;
+ return uc_rc;
+ }
+
+ /*
+ * Set the Auto_negotiation Advertisement Register.
+ * MII advertising for Next page.
+ * 100BaseTxFD and HD, 10BaseTFD and HD, IEEE 802.3.
+ */
+ ul_phy_anar = GMII_100TX_FDX | GMII_100TX_HDX | GMII_10_FDX | GMII_10_HDX |
+ GMII_AN_IEEE_802_3;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_ANAR, ul_phy_anar);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -3;
+ return uc_rc;
+ }
+
+ /* Read & modify control register */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMCR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -4;
+ return uc_rc;
+ }
+
+ ul_value |= GMII_SPEED_SELECT | GMII_AUTONEG | GMII_DUPLEX_MODE;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -5;
+ return uc_rc;
+ }
+
+ /* Restart auto negotiation */
+ ul_value |= (uint32_t)GMII_RESTART_AUTONEG;
+ ul_value &= ~(uint32_t)GMII_ISOLATE;
+ uc_rc = gmac_phy_write(p_gmac, uc_phy_addr, GMII_BMCR, ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -6;
+ return uc_rc;
+ }
+
+ /* Check if auto negotiation is completed */
+ while (1) {
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_BMSR, &ul_value);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -7;
+ return uc_rc;
+ }
+ /* Done successfully */
+ if (ul_value & GMII_AUTONEG_COMP) {
+ break;
+ }
+
+ /* Timeout check */
+ if (ul_retry_max) {
+ if (++ul_retry_count >= ul_retry_max) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -8;
+ return GMAC_TIMEOUT;
+ }
+ }
+ }
+
+ /* Get the auto negotiate link partner base page */
+ uc_rc = gmac_phy_read(p_gmac, uc_phy_addr, GMII_PCR1, &phy_props.phy_params);
+ if (uc_rc != GMAC_OK) {
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = -9;
+ return uc_rc;
+ }
+
+
+ /* Set up the GMAC link speed */
+ if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_FDX) {
+ /* Set MII for 100BaseTX and Full Duplex */
+ uc_speed = true;
+ uc_fd = true;
+ } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_FDX) {
+ /* Set MII for 10BaseT and Full Duplex */
+ uc_speed = false;
+ uc_fd = true;
+ } else if ((ul_phy_anar & phy_props.phy_params) & GMII_100TX_HDX) {
+ /* Set MII for 100BaseTX and half Duplex */
+ uc_speed = true;
+ uc_fd = false;
+ } else if ((ul_phy_anar & phy_props.phy_params) & GMII_10_HDX) {
+ /* Set MII for 10BaseT and half Duplex */
+ uc_speed = false;
+ uc_fd = false;
+ }
+
+ gmac_set_speed(p_gmac, uc_speed);
+ gmac_enable_full_duplex(p_gmac, uc_fd);
+
+ /* Select Media Independent Interface type */
+ gmac_select_mii_mode(p_gmac, ETH_PHY_MODE);
+
+ gmac_enable_transmit(GMAC, true);
+ gmac_enable_receive(GMAC, true);
+
+ gmac_enable_management(p_gmac, false);
+phy_props.phy_result = 1;
+ return uc_rc;
+}
+
+/**
+ * \brief Issue a SW reset to reset all registers of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr)
+{
+ uint32_t ul_bmcr = GMII_RESET;
+ uint8_t uc_phy_address = uc_phy_addr;
+ uint32_t ul_timeout = ETH_PHY_TIMEOUT;
+ uint8_t uc_rc = GMAC_TIMEOUT;
+
+ gmac_enable_management(p_gmac, true);
+
+ ul_bmcr = GMII_RESET;
+ gmac_phy_write(p_gmac, uc_phy_address, GMII_BMCR, ul_bmcr);
+
+ do {
+ gmac_phy_read(p_gmac, uc_phy_address, GMII_BMCR, &ul_bmcr);
+ ul_timeout--;
+ } while ((ul_bmcr & GMII_RESET) && ul_timeout);
+
+ gmac_enable_management(p_gmac, false);
+
+ if (!ul_timeout) {
+ uc_rc = GMAC_OK;
+ }
+
+ return (uc_rc);
+}
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \}
+ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h
index 8ea5fa0c7..6729df0fe 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/ethernet_phy.h
@@ -1,281 +1,281 @@
-/**
- * \file
- *
- * \brief KSZ8051MNL (Ethernet PHY) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef ETHERNET_PHY_H_INCLUDED
-#define ETHERNET_PHY_H_INCLUDED
-
-#include "compiler.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// IEEE defined Registers
-#define GMII_BMCR 0x00 // Basic Control
-#define GMII_BMSR 0x01 // Basic Status
-#define GMII_PHYID1 0x02 // PHY Idendifier 1
-#define GMII_PHYID2 0x03 // PHY Idendifier 2
-#define GMII_ANAR 0x04 // Auto_Negotiation Advertisement
-#define GMII_ANLPAR 0x05 // Auto_negotiation Link Partner Ability
-#define GMII_ANER 0x06 // Auto-negotiation Expansion
-#define GMII_ANNPR 0x07 // Auto-negotiation Next Page
-#define GMII_ANLPNPAR 0x08 // Link Partner Next Page Ability
-//#define GMII_1000BTCR 9 // 1000Base-T Control // Reserved
-//#define GMII_1000BTSR 10 // 1000Base-T Status // Reserved
-#define GMII_AFECR1 0x11 // AFE Control 1
-//#define GMII_ERDWR 12 // Extend Register - Data Write Register
-//#define GMII_ERDRR 13 // Extend Register - Data Read Register
-//14 reserved
-#define GMII_RXERCR 0x15 // RXER Counter
-
- #define PHY_REG_01_BMSR 0x01 // Basic mode status register
- #define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
- #define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
- #define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
- #define PHY_REG_05_LPA 0x05 // Link partner ability reg
- #define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
- #define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
- #define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
-
- #define PHY_REG_10_PHYSTS 0x10 // 16 RO PHY Status Register
- #define PHY_REG_11_MICR 0x11 // 17 RW MII Interrupt Control Register
- #define PHY_REG_12_MISR 0x12 // 18 RO MII Interrupt Status Register
- #define PHY_REG_13_RESERVED1 0x13 // 19 RW RESERVED
- #define PHY_REG_14_FCSCR 0x14 // 20 RO False Carrier Sense Counter Register
- #define PHY_REG_15_RECR 0x15 // 21 RO Receive Error Counter Register
- #define PHY_REG_16_PCSR 0x16 // 22 RW PCS Sub-Layer Configuration and Status Register
- #define PHY_REG_17_RBR 0x17 // 23 RW RMII and Bypass Register
- #define PHY_REG_18_LEDCR 0x18 // 24 RW LED Direct Control Register
- #define PHY_REG_19_PHYCR 0x19 // 25 RW PHY Control Register
- #define PHY_REG_1A_10BTSCR 0x1A // 26 RW 10Base-T Status/Control Register
- #define PHY_REG_1B_CDCTRL1 0x1B // 27 RW CD Test Control Register and BIST Extensions Register
- #define PHY_REG_1B_INT_CTRL 0x1B // 27 RW KSZ8041NL interrupt control
- #define PHY_REG_1C_RESERVED2 0x1C // 28 RW RESERVED
- #define PHY_REG_1D_EDCR 0x1D // 29 RW Energy Detect Control Register
- #define PHY_REG_1E_RESERVED3 0x1E //
- #define PHY_REG_1F_RESERVED4 0x1F // 30-31 RW RESERVED
-
- #define PHY_REG_1E_PHYCR_1 0x1E //
- #define PHY_REG_1F_PHYCR_2 0x1F //
-
- #define PHY_SPEED_10 1
- #define PHY_SPEED_100 2
- #define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
-
- #define PHY_MDIX_DIRECT 1
- #define PHY_MDIX_CROSSED 2
- #define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
-
- #define PHY_DUPLEX_HALF 1
- #define PHY_DUPLEX_FULL 2
- #define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
-
- typedef struct _SPhyProps {
- unsigned char speed;
- unsigned char mdix;
- unsigned char duplex;
- unsigned char spare;
- } SPhyProps;
-
- const char *phyPrintable (const SPhyProps *apProps);
-
- extern SPhyProps phyProps;
-
-#define GMII_OMSOR 0x16 // Operation Mode Strap Override
-#define GMII_OMSSR 0x17 // Operation Mode Strap Status
-#define GMII_ECR 0x18 // Expanded Control
-//#define GMII_DPPSR 19 // Digital PMA/PCS Status
-//20 reserved
-//#define GMII_RXERCR 21 // RXER Counter Register
-//22-26 reserved
-#define GMII_ICSR 0x1B // Interrupt Control/Status
-//#define GMII_DDC1R 28 // Digital Debug Control 1 Register
-#define GMII_LCSR 0x1D // LinkMD Control/Status
-
-//29-30 reserved
-#define GMII_PCR1 0x1E // PHY Control 1
-#define GMII_PCR2 0x1F // PHY Control 2
-
-/*
-//Extend Registers
-#define GMII_CCR 256 // Common Control Register
-#define GMII_SSR 257 // Strap Status Register
-#define GMII_OMSOR 258 // Operation Mode Strap Override Register
-#define GMII_OMSSR 259 // Operation Mode Strap Status Register
-#define GMII_RCCPSR 260 // RGMII Clock and Control Pad Skew Register
-#define GMII_RRDPSR 261 // RGMII RX Data Pad Skew Register
-#define GMII_ATR 263 // Analog Test Register
-*/
-
-
-// Bit definitions: GMII_BMCR 0x00 Basic Control
-#define GMII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
-#define GMII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
-#define GMII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
-#define GMII_AUTONEG (1 << 12) // Auto-negotiation Enable
-#define GMII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
-#define GMII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
-#define GMII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
-#define GMII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
-#define GMII_COLLISION_TEST (1 << 7) // 1 = Enable COL test; 0 = Disable COL test
-//#define GMII_SPEED_SELECT_MSB (1 << 6) // Reserved
-// Reserved 6 to 0 // Read as 0, ignore on write
-
-// Bit definitions: GMII_BMSR 0x01 Basic Status
-#define GMII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
-#define GMII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
-#define GMII_100BASE_T4_HD (1 << 13) // 100BASE-TX Half Duplex Capable
-#define GMII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
-#define GMII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
-// Reserved 10 to79 // Read as 0, ignore on write
-//#define GMII_EXTEND_STATUS (1 << 8) // 1 = Extend Status Information In Reg 15
-// Reserved 7
-#define GMII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
-#define GMII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
-#define GMII_REMOTE_FAULT (1 << 4) // Remote Fault
-#define GMII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
-#define GMII_LINK_STATUS (1 << 2) // Link Status
-#define GMII_JABBER_DETECT (1 << 1) // Jabber Detect
-#define GMII_EXTEND_CAPAB (1 << 0) // Extended Capability
-
-
-// Bit definitions: GMII_PHYID1 0x02 PHY Idendifier 1
-// Bit definitions: GMII_PHYID2 0x03 PHY Idendifier 2
-#define GMII_LSB_MASK 0x3F
-#define GMII_OUI_MSB 0x0022
-#define GMII_OUI_LSB 0x05
-
-
-// Bit definitions: GMII_ANAR 0x04 Auto_Negotiation Advertisement
-// Bit definitions: GMII_ANLPAR 0x05 Auto_negotiation Link Partner Ability
-#define GMII_NP (1 << 15) // Next page Indication
-// Reserved 7
-#define GMII_RF (1 << 13) // Remote Fault
-// Reserved 12 // Write as 0, ignore on read
-#define GMII_PAUSE_MASK (3 << 11) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
- // 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
-#define GMII_100T4 (1 << 9) // 100BASE-T4 Support
-#define GMII_100TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
-#define GMII_100TX_HDX (1 << 7) // 100BASE-TX Support
-#define GMII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
-#define GMII_10_HDX (1 << 5) // 10BASE-T Support
-// Selector 4 to 0 // Protocol Selection Bits
-#define GMII_AN_IEEE_802_3 0x0001 // [00001] = IEEE 802.3
-
-
-// Bit definitions: GMII_ANER 0x06 Auto-negotiation Expansion
-// Reserved 15 to 5 // Read as 0, ignore on write
-#define GMII_PDF (1 << 4) // Local Device Parallel Detection Fault
-#define GMII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
-#define GMII_NP_ABLE (1 << 2) // Local Device Next Page Able
-#define GMII_PAGE_RX (1 << 1) // New Page Received
-#define GMII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
-
-/**
- * \brief Perform a HW initialization to the PHY and set up clocks.
- *
- * This should be called only once to initialize the PHY pre-settings.
- * The PHY address is the reset status of CRS, RXD[3:0] (the GmacPins' pullups).
- * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
- * The RXDV pin is used to select test mode on reset (pulled up for test mode).
- * The above pins should be predefined for corresponding settings in resetPins.
- * The GMAC peripheral pins are configured after the reset is done.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param ul_mck GMAC MCK.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t ul_mck);
-
-
-/**
- * \brief Get the Link & speed settings, and automatically set up the GMAC with the
- * settings.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
- uint8_t uc_apply_setting_flag);
-
-
-/**
- * \brief Issue an auto negotiation of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr);
-
-/**
- * \brief Issue a SW reset to reset all registers of the PHY.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr);
-
-typedef struct xPHY_PROPS {
- signed char phy_result;
- uint32_t phy_params;
- uint32_t phy_stat1;
- uint32_t phy_stat2;
- unsigned char phy_chn;
-} PhyProps_t;
-extern PhyProps_t phy_props;
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif /* #ifndef ETHERNET_PHY_H_INCLUDED */
-
+/**
+ * \file
+ *
+ * \brief KSZ8051MNL (Ethernet PHY) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef ETHERNET_PHY_H_INCLUDED
+#define ETHERNET_PHY_H_INCLUDED
+
+#include "compiler.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// IEEE defined Registers
+#define GMII_BMCR 0x00 // Basic Control
+#define GMII_BMSR 0x01 // Basic Status
+#define GMII_PHYID1 0x02 // PHY Idendifier 1
+#define GMII_PHYID2 0x03 // PHY Idendifier 2
+#define GMII_ANAR 0x04 // Auto_Negotiation Advertisement
+#define GMII_ANLPAR 0x05 // Auto_negotiation Link Partner Ability
+#define GMII_ANER 0x06 // Auto-negotiation Expansion
+#define GMII_ANNPR 0x07 // Auto-negotiation Next Page
+#define GMII_ANLPNPAR 0x08 // Link Partner Next Page Ability
+//#define GMII_1000BTCR 9 // 1000Base-T Control // Reserved
+//#define GMII_1000BTSR 10 // 1000Base-T Status // Reserved
+#define GMII_AFECR1 0x11 // AFE Control 1
+//#define GMII_ERDWR 12 // Extend Register - Data Write Register
+//#define GMII_ERDRR 13 // Extend Register - Data Read Register
+//14 reserved
+#define GMII_RXERCR 0x15 // RXER Counter
+
+ #define PHY_REG_01_BMSR 0x01 // Basic mode status register
+ #define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
+ #define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
+ #define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
+ #define PHY_REG_05_LPA 0x05 // Link partner ability reg
+ #define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
+ #define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
+ #define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
+
+ #define PHY_REG_10_PHYSTS 0x10 // 16 RO PHY Status Register
+ #define PHY_REG_11_MICR 0x11 // 17 RW MII Interrupt Control Register
+ #define PHY_REG_12_MISR 0x12 // 18 RO MII Interrupt Status Register
+ #define PHY_REG_13_RESERVED1 0x13 // 19 RW RESERVED
+ #define PHY_REG_14_FCSCR 0x14 // 20 RO False Carrier Sense Counter Register
+ #define PHY_REG_15_RECR 0x15 // 21 RO Receive Error Counter Register
+ #define PHY_REG_16_PCSR 0x16 // 22 RW PCS Sub-Layer Configuration and Status Register
+ #define PHY_REG_17_RBR 0x17 // 23 RW RMII and Bypass Register
+ #define PHY_REG_18_LEDCR 0x18 // 24 RW LED Direct Control Register
+ #define PHY_REG_19_PHYCR 0x19 // 25 RW PHY Control Register
+ #define PHY_REG_1A_10BTSCR 0x1A // 26 RW 10Base-T Status/Control Register
+ #define PHY_REG_1B_CDCTRL1 0x1B // 27 RW CD Test Control Register and BIST Extensions Register
+ #define PHY_REG_1B_INT_CTRL 0x1B // 27 RW KSZ8041NL interrupt control
+ #define PHY_REG_1C_RESERVED2 0x1C // 28 RW RESERVED
+ #define PHY_REG_1D_EDCR 0x1D // 29 RW Energy Detect Control Register
+ #define PHY_REG_1E_RESERVED3 0x1E //
+ #define PHY_REG_1F_RESERVED4 0x1F // 30-31 RW RESERVED
+
+ #define PHY_REG_1E_PHYCR_1 0x1E //
+ #define PHY_REG_1F_PHYCR_2 0x1F //
+
+ #define PHY_SPEED_10 1
+ #define PHY_SPEED_100 2
+ #define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
+
+ #define PHY_MDIX_DIRECT 1
+ #define PHY_MDIX_CROSSED 2
+ #define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
+
+ #define PHY_DUPLEX_HALF 1
+ #define PHY_DUPLEX_FULL 2
+ #define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
+
+ typedef struct _SPhyProps {
+ unsigned char speed;
+ unsigned char mdix;
+ unsigned char duplex;
+ unsigned char spare;
+ } SPhyProps;
+
+ const char *phyPrintable (const SPhyProps *apProps);
+
+ extern SPhyProps phyProps;
+
+#define GMII_OMSOR 0x16 // Operation Mode Strap Override
+#define GMII_OMSSR 0x17 // Operation Mode Strap Status
+#define GMII_ECR 0x18 // Expanded Control
+//#define GMII_DPPSR 19 // Digital PMA/PCS Status
+//20 reserved
+//#define GMII_RXERCR 21 // RXER Counter Register
+//22-26 reserved
+#define GMII_ICSR 0x1B // Interrupt Control/Status
+//#define GMII_DDC1R 28 // Digital Debug Control 1 Register
+#define GMII_LCSR 0x1D // LinkMD Control/Status
+
+//29-30 reserved
+#define GMII_PCR1 0x1E // PHY Control 1
+#define GMII_PCR2 0x1F // PHY Control 2
+
+/*
+//Extend Registers
+#define GMII_CCR 256 // Common Control Register
+#define GMII_SSR 257 // Strap Status Register
+#define GMII_OMSOR 258 // Operation Mode Strap Override Register
+#define GMII_OMSSR 259 // Operation Mode Strap Status Register
+#define GMII_RCCPSR 260 // RGMII Clock and Control Pad Skew Register
+#define GMII_RRDPSR 261 // RGMII RX Data Pad Skew Register
+#define GMII_ATR 263 // Analog Test Register
+*/
+
+
+// Bit definitions: GMII_BMCR 0x00 Basic Control
+#define GMII_RESET (1 << 15) // 1= Software Reset; 0=Normal Operation
+#define GMII_LOOPBACK (1 << 14) // 1=loopback Enabled; 0=Normal Operation
+#define GMII_SPEED_SELECT (1 << 13) // 1=100Mbps; 0=10Mbps
+#define GMII_AUTONEG (1 << 12) // Auto-negotiation Enable
+#define GMII_POWER_DOWN (1 << 11) // 1=Power down 0=Normal operation
+#define GMII_ISOLATE (1 << 10) // 1 = Isolates 0 = Normal operation
+#define GMII_RESTART_AUTONEG (1 << 9) // 1 = Restart auto-negotiation 0 = Normal operation
+#define GMII_DUPLEX_MODE (1 << 8) // 1 = Full duplex operation 0 = Normal operation
+#define GMII_COLLISION_TEST (1 << 7) // 1 = Enable COL test; 0 = Disable COL test
+//#define GMII_SPEED_SELECT_MSB (1 << 6) // Reserved
+// Reserved 6 to 0 // Read as 0, ignore on write
+
+// Bit definitions: GMII_BMSR 0x01 Basic Status
+#define GMII_100BASE_T4 (1 << 15) // 100BASE-T4 Capable
+#define GMII_100BASE_TX_FD (1 << 14) // 100BASE-TX Full Duplex Capable
+#define GMII_100BASE_T4_HD (1 << 13) // 100BASE-TX Half Duplex Capable
+#define GMII_10BASE_T_FD (1 << 12) // 10BASE-T Full Duplex Capable
+#define GMII_10BASE_T_HD (1 << 11) // 10BASE-T Half Duplex Capable
+// Reserved 10 to79 // Read as 0, ignore on write
+//#define GMII_EXTEND_STATUS (1 << 8) // 1 = Extend Status Information In Reg 15
+// Reserved 7
+#define GMII_MF_PREAMB_SUPPR (1 << 6) // MII Frame Preamble Suppression
+#define GMII_AUTONEG_COMP (1 << 5) // Auto-negotiation Complete
+#define GMII_REMOTE_FAULT (1 << 4) // Remote Fault
+#define GMII_AUTONEG_ABILITY (1 << 3) // Auto Configuration Ability
+#define GMII_LINK_STATUS (1 << 2) // Link Status
+#define GMII_JABBER_DETECT (1 << 1) // Jabber Detect
+#define GMII_EXTEND_CAPAB (1 << 0) // Extended Capability
+
+
+// Bit definitions: GMII_PHYID1 0x02 PHY Idendifier 1
+// Bit definitions: GMII_PHYID2 0x03 PHY Idendifier 2
+#define GMII_LSB_MASK 0x3F
+#define GMII_OUI_MSB 0x0022
+#define GMII_OUI_LSB 0x05
+
+
+// Bit definitions: GMII_ANAR 0x04 Auto_Negotiation Advertisement
+// Bit definitions: GMII_ANLPAR 0x05 Auto_negotiation Link Partner Ability
+#define GMII_NP (1 << 15) // Next page Indication
+// Reserved 7
+#define GMII_RF (1 << 13) // Remote Fault
+// Reserved 12 // Write as 0, ignore on read
+#define GMII_PAUSE_MASK (3 << 11) // 0,0 = No Pause 1,0 = Asymmetric Pause(link partner)
+ // 0,1 = Symmetric Pause 1,1 = Symmetric&Asymmetric Pause(local device)
+#define GMII_100T4 (1 << 9) // 100BASE-T4 Support
+#define GMII_100TX_FDX (1 << 8) // 100BASE-TX Full Duplex Support
+#define GMII_100TX_HDX (1 << 7) // 100BASE-TX Support
+#define GMII_10_FDX (1 << 6) // 10BASE-T Full Duplex Support
+#define GMII_10_HDX (1 << 5) // 10BASE-T Support
+// Selector 4 to 0 // Protocol Selection Bits
+#define GMII_AN_IEEE_802_3 0x0001 // [00001] = IEEE 802.3
+
+
+// Bit definitions: GMII_ANER 0x06 Auto-negotiation Expansion
+// Reserved 15 to 5 // Read as 0, ignore on write
+#define GMII_PDF (1 << 4) // Local Device Parallel Detection Fault
+#define GMII_LP_NP_ABLE (1 << 3) // Link Partner Next Page Able
+#define GMII_NP_ABLE (1 << 2) // Local Device Next Page Able
+#define GMII_PAGE_RX (1 << 1) // New Page Received
+#define GMII_LP_AN_ABLE (1 << 0) // Link Partner Auto-negotiation Able
+
+/**
+ * \brief Perform a HW initialization to the PHY and set up clocks.
+ *
+ * This should be called only once to initialize the PHY pre-settings.
+ * The PHY address is the reset status of CRS, RXD[3:0] (the GmacPins' pullups).
+ * The COL pin is used to select MII mode on reset (pulled up for Reduced MII).
+ * The RXDV pin is used to select test mode on reset (pulled up for test mode).
+ * The above pins should be predefined for corresponding settings in resetPins.
+ * The GMAC peripheral pins are configured after the reset is done.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param ul_mck GMAC MCK.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_init(Gmac *p_gmac, uint8_t uc_phy_addr, uint32_t ul_mck);
+
+
+/**
+ * \brief Get the Link & speed settings, and automatically set up the GMAC with the
+ * settings.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_apply_setting_flag Set to 0 to not apply the PHY configurations, else to apply.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_set_link(Gmac *p_gmac, uint8_t uc_phy_addr,
+ uint8_t uc_apply_setting_flag);
+
+
+/**
+ * \brief Issue an auto negotiation of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_auto_negotiate(Gmac *p_gmac, uint8_t uc_phy_addr);
+
+/**
+ * \brief Issue a SW reset to reset all registers of the PHY.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t ethernet_phy_reset(Gmac *p_gmac, uint8_t uc_phy_addr);
+
+typedef struct xPHY_PROPS {
+ signed char phy_result;
+ uint32_t phy_params;
+ uint32_t phy_stat1;
+ uint32_t phy_stat2;
+ unsigned char phy_chn;
+} PhyProps_t;
+extern PhyProps_t phy_props;
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* #ifndef ETHERNET_PHY_H_INCLUDED */
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c
index 948f9a661..e4a3ba988 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.c
@@ -1,944 +1,944 @@
- /**
- * \file
- *
- * \brief GMAC (Ethernet MAC) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-
-#include "FreeRTOSIPConfig.h"
-
-#include "compiler.h"
-#include "instance/gmac.h"
-#include "ethernet_phy.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (int)( sizeof(x) / sizeof(x)[0] )
-#endif
-/**
- * \defgroup gmac_group Ethernet Media Access Controller
- *
- * See \ref gmac_quickstart.
- *
- * Driver for the GMAC (Ethernet Media Access Controller).
- * This file contains basic functions for the GMAC, with support for all modes, settings
- * and clock speeds.
- *
- * \section dependencies Dependencies
- * This driver does not depend on other modules.
- *
- * @{
- */
-
-/** TX descriptor lists */
-COMPILER_ALIGNED(8)
-static gmac_tx_descriptor_t gs_tx_desc[ GMAC_TX_BUFFERS ];
-#if( GMAC_USES_TX_CALLBACK != 0 )
-/** TX callback lists */
-static gmac_dev_tx_cb_t gs_tx_callback[ GMAC_TX_BUFFERS ];
-#endif
-/** RX descriptors lists */
-COMPILER_ALIGNED(8)
-static gmac_rx_descriptor_t gs_rx_desc[ GMAC_RX_BUFFERS ];
-
-#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- /** Send Buffer. Section 3.6 of AMBA 2.0 spec states that burst should not cross the
- * 1K Boundaries. Receive buffer manager write operations are burst of 2 words => 3 lsb bits
- * of the address shall be set to 0.
- */
- COMPILER_ALIGNED(8)
- static uint8_t gs_uc_tx_buffer[ GMAC_TX_BUFFERS * GMAC_TX_UNITSIZE ];
-#endif /* ipconfigZERO_COPY_TX_DRIVER */
-
-/** Receive Buffer */
-COMPILER_ALIGNED(8)
-static uint8_t gs_uc_rx_buffer[ GMAC_RX_BUFFERS * GMAC_RX_UNITSIZE ];
-
-/**
- * GMAC device memory management struct.
- */
-typedef struct gmac_dev_mem {
- /* Pointer to allocated buffer for RX. The address should be 8-byte aligned
- and the size should be GMAC_RX_UNITSIZE * wRxSize. */
- uint8_t *p_rx_buffer;
- /* Pointer to allocated RX descriptor list. */
- gmac_rx_descriptor_t *p_rx_dscr;
- /* RX size, in number of registered units (RX descriptors). */
- /* Increased size from 16- to 32-bits, because it's more efficient */
- uint32_t us_rx_size;
- /* Pointer to allocated buffer for TX. The address should be 8-byte aligned
- and the size should be GMAC_TX_UNITSIZE * wTxSize. */
- uint8_t *p_tx_buffer;
- /* Pointer to allocated TX descriptor list. */
- gmac_tx_descriptor_t *p_tx_dscr;
- /* TX size, in number of registered units (TX descriptors). */
- uint32_t us_tx_size;
-} gmac_dev_mem_t;
-
-/** Return count in buffer */
-#define CIRC_CNT( head, tail, size ) ( ( ( head ) - ( tail ) ) % ( size ) )
-
-/*
- * Return space available, from 0 to size-1.
- * Always leave one free char as a completely full buffer that has (head == tail),
- * which is the same as empty.
- */
-#define CIRC_SPACE( head, tail, size ) CIRC_CNT( ( tail ), ( ( head ) + 1 ), ( size ) )
-
-/** Circular buffer is empty ? */
-#define CIRC_EMPTY( head, tail ) ( head == tail )
-/** Clear circular buffer */
-#define CIRC_CLEAR( head, tail ) do { ( head ) = 0; ( tail ) = 0; } while( 0 )
-
-/** Increment head or tail */
-static __inline void circ_inc32( int32_t *lHeadOrTail, uint32_t ulSize )
-{
- ( *lHeadOrTail ) ++;
- if( ( *lHeadOrTail ) >= ( int32_t )ulSize )
- {
- ( *lHeadOrTail ) = 0;
- }
-}
-
-/**
- * \brief Wait PHY operation to be completed.
- *
- * \param p_gmac HW controller address.
- * \param ul_retry The retry times, 0 to wait forever until completeness.
- *
- * Return GMAC_OK if the operation is completed successfully.
- */
-static uint8_t gmac_wait_phy(Gmac* p_gmac, const uint32_t ul_retry)
-{
- volatile uint32_t ul_retry_count = 0;
- const uint32_t xPHYPollDelay = pdMS_TO_TICKS( 1ul );
-
- while (!gmac_is_phy_idle(p_gmac)) {
- if (ul_retry == 0) {
- continue;
- }
-
- ul_retry_count++;
-
- if (ul_retry_count >= ul_retry) {
- return GMAC_TIMEOUT;
- }
-
- /* Block the task to allow other tasks to execute while the PHY
- is not connected. */
- vTaskDelay( xPHYPollDelay );
- }
- return GMAC_OK;
-}
-
-/**
- * \brief Disable transfer, reset registers and descriptor lists.
- *
- * \param p_dev Pointer to GMAC driver instance.
- *
- */
-static void gmac_reset_tx_mem(gmac_device_t* p_dev)
-{
- Gmac *p_hw = p_dev->p_hw;
- uint8_t *p_tx_buff = p_dev->p_tx_buffer;
- gmac_tx_descriptor_t *p_td = p_dev->p_tx_dscr;
-
- uint32_t ul_index;
- uint32_t ul_address;
-
- /* Disable TX */
- gmac_enable_transmit(p_hw, 0);
-
- /* Set up the TX descriptors */
- CIRC_CLEAR(p_dev->l_tx_head, p_dev->l_tx_tail);
- for( ul_index = 0; ul_index < p_dev->ul_tx_list_size; ul_index++ )
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- ul_address = (uint32_t) 0u;
- }
- #else
- {
- ul_address = (uint32_t) (&(p_tx_buff[ul_index * GMAC_TX_UNITSIZE]));
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- p_td[ul_index].addr = ul_address;
- p_td[ul_index].status.val = GMAC_TXD_USED;
- }
- p_td[p_dev->ul_tx_list_size - 1].status.val =
- GMAC_TXD_USED | GMAC_TXD_WRAP;
-
- /* Set transmit buffer queue */
- gmac_set_tx_queue(p_hw, (uint32_t) p_td);
-}
-
-/**
- * \brief Disable receiver, reset registers and descriptor list.
- *
- * \param p_drv Pointer to GMAC Driver instance.
- */
-static void gmac_reset_rx_mem(gmac_device_t* p_dev)
-{
- Gmac *p_hw = p_dev->p_hw;
- uint8_t *p_rx_buff = p_dev->p_rx_buffer;
- gmac_rx_descriptor_t *pRd = p_dev->p_rx_dscr;
-
- uint32_t ul_index;
- uint32_t ul_address;
-
- /* Disable RX */
- gmac_enable_receive(p_hw, 0);
-
- /* Set up the RX descriptors */
- p_dev->ul_rx_idx = 0;
- for( ul_index = 0; ul_index < p_dev->ul_rx_list_size; ul_index++ )
- {
- ul_address = (uint32_t) (&(p_rx_buff[ul_index * GMAC_RX_UNITSIZE]));
- pRd[ul_index].addr.val = ul_address & GMAC_RXD_ADDR_MASK;
- pRd[ul_index].status.val = 0;
- }
- pRd[p_dev->ul_rx_list_size - 1].addr.val |= GMAC_RXD_WRAP;
-
- /* Set receive buffer queue */
- gmac_set_rx_queue(p_hw, (uint32_t) pRd);
-}
-
-
-/**
- * \brief Initialize the allocated buffer lists for GMAC driver to transfer data.
- * Must be invoked after gmac_dev_init() but before RX/TX starts.
- *
- * \note If input address is not 8-byte aligned, the address is automatically
- * adjusted and the list size is reduced by one.
- *
- * \param p_gmac Pointer to GMAC instance.
- * \param p_gmac_dev Pointer to GMAC device instance.
- * \param p_dev_mm Pointer to the GMAC memory management control block.
- * \param p_tx_cb Pointer to allocated TX callback list.
- *
- * \return GMAC_OK or GMAC_PARAM.
- */
-static uint8_t gmac_init_mem(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_dev_mem_t* p_dev_mm
-#if( GMAC_USES_TX_CALLBACK != 0 )
- , gmac_dev_tx_cb_t* p_tx_cb
-#endif
- )
-{
- if (p_dev_mm->us_rx_size <= 1 || p_dev_mm->us_tx_size <= 1
-#if( GMAC_USES_TX_CALLBACK != 0 )
- || p_tx_cb == NULL
-#endif
- ) {
- return GMAC_PARAM;
- }
-
- /* Assign RX buffers */
- if (((uint32_t) p_dev_mm->p_rx_buffer & 0x7)
- || ((uint32_t) p_dev_mm->p_rx_dscr & 0x7)) {
- p_dev_mm->us_rx_size--;
- }
- p_gmac_dev->p_rx_buffer =
- (uint8_t *) ((uint32_t) p_dev_mm->p_rx_buffer & 0xFFFFFFF8);
- p_gmac_dev->p_rx_dscr =
- (gmac_rx_descriptor_t *) ((uint32_t) p_dev_mm->p_rx_dscr
- & 0xFFFFFFF8);
- p_gmac_dev->ul_rx_list_size = p_dev_mm->us_rx_size;
-
- /* Assign TX buffers */
- if (((uint32_t) p_dev_mm->p_tx_buffer & 0x7)
- || ((uint32_t) p_dev_mm->p_tx_dscr & 0x7)) {
- p_dev_mm->us_tx_size--;
- }
- p_gmac_dev->p_tx_buffer =
- (uint8_t *) ((uint32_t) p_dev_mm->p_tx_buffer & 0xFFFFFFF8);
- p_gmac_dev->p_tx_dscr =
- (gmac_tx_descriptor_t *) ((uint32_t) p_dev_mm->p_tx_dscr
- & 0xFFFFFFF8);
- p_gmac_dev->ul_tx_list_size = p_dev_mm->us_tx_size;
-#if( GMAC_USES_TX_CALLBACK != 0 )
- p_gmac_dev->func_tx_cb_list = p_tx_cb;
-#endif
- /* Reset TX & RX */
- gmac_reset_rx_mem(p_gmac_dev);
- gmac_reset_tx_mem(p_gmac_dev);
-
- /* Enable Rx and Tx, plus the statistics register */
- gmac_enable_transmit(p_gmac, true);
- gmac_enable_receive(p_gmac, true);
- gmac_enable_statistics_write(p_gmac, true);
-
- /* Set up the interrupts for transmission and errors */
- gmac_enable_interrupt(p_gmac,
- GMAC_IER_RXUBR | /* Enable receive used bit read interrupt. */
- GMAC_IER_TUR | /* Enable transmit underrun interrupt. */
- GMAC_IER_RLEX | /* Enable retry limit exceeded interrupt. */
- GMAC_IER_TFC | /* Enable transmit buffers exhausted in mid-frame interrupt. */
- GMAC_IER_TCOMP | /* Enable transmit complete interrupt. */
- GMAC_IER_ROVR | /* Enable receive overrun interrupt. */
- GMAC_IER_HRESP | /* Enable Hresp not OK interrupt. */
- GMAC_IER_PFNZ | /* Enable pause frame received interrupt. */
- GMAC_IER_PTZ); /* Enable pause time zero interrupt. */
-
- return GMAC_OK;
-}
-
-/**
- * \brief Read the PHY register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_address PHY address.
- * \param uc_address Register address.
- * \param p_value Pointer to a 32-bit location to store read data.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
- uint32_t* p_value)
-{
- gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 1, 0);
-
- if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
- return GMAC_TIMEOUT;
- }
- *p_value = gmac_get_phy_data(p_gmac);
- return GMAC_OK;
-}
-
-/**
- * \brief Write the PHY register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_address PHY Address.
- * \param uc_address Register Address.
- * \param ul_value Data to write, actually 16-bit data.
- *
- * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
- */
-uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
- uint8_t uc_address, uint32_t ul_value)
-{
- gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 0, ul_value);
-
- if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
- return GMAC_TIMEOUT;
- }
- return GMAC_OK;
-}
-
-/**
- * \brief Initialize the GMAC driver.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param p_opt GMAC configure options.
- */
-void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_options_t* p_opt)
-{
- gmac_dev_mem_t gmac_dev_mm;
-
- /* Disable TX & RX and more */
- gmac_network_control(p_gmac, 0);
- gmac_disable_interrupt(p_gmac, ~0u);
-
-
- gmac_clear_statistics(p_gmac);
-
- /* Clear all status bits in the receive status register. */
- gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA);
-
- /* Clear all status bits in the transmit status register */
- gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
- | GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND);
-
- /* Clear interrupts */
- gmac_get_interrupt_status(p_gmac);
-#if !defined(ETHERNET_CONF_DATA_OFFSET)
- /* Receive Buffer Offset
- * Indicates the number of bytes by which the received data
- * is offset from the start of the receive buffer
- * which can be handy for alignment reasons */
- /* Note: FreeRTOS+TCP wants to have this offset set to 2 bytes */
- #error ETHERNET_CONF_DATA_OFFSET not defined, assuming 0
-#endif
- /* Enable the copy of data into the buffers
- ignore broadcasts, and not copy FCS. */
-
- gmac_set_configure(p_gmac,
- ( gmac_get_configure(p_gmac) & ~GMAC_NCFGR_RXBUFO_Msk ) |
- GMAC_NCFGR_RFCS | /* Remove FCS, frame check sequence (last 4 bytes) */
- GMAC_NCFGR_PEN | /* Pause Enable */
- GMAC_NCFGR_RXBUFO( ETHERNET_CONF_DATA_OFFSET ) |
- GMAC_RXD_RXCOEN );
-
- /*
- * GMAC_DCFGR_TXCOEN: (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable.
- * Note: tha SAM4E does have RX checksum offloading
- * but TX checksum offloading has NOT been implemented.
- */
-
- gmac_set_dma(p_gmac,
- gmac_get_dma(p_gmac) | GMAC_DCFGR_TXCOEN );
-
- gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame);
- gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast);
-
- /* Fill in GMAC device memory management */
- gmac_dev_mm.p_rx_buffer = gs_uc_rx_buffer;
- gmac_dev_mm.p_rx_dscr = gs_rx_desc;
- gmac_dev_mm.us_rx_size = GMAC_RX_BUFFERS;
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- gmac_dev_mm.p_tx_buffer = NULL;
- }
- #else
- {
- gmac_dev_mm.p_tx_buffer = gs_uc_tx_buffer;
- }
- #endif
- gmac_dev_mm.p_tx_dscr = gs_tx_desc;
- gmac_dev_mm.us_tx_size = GMAC_TX_BUFFERS;
-
- gmac_init_mem(p_gmac, p_gmac_dev, &gmac_dev_mm
-#if( GMAC_USES_TX_CALLBACK != 0 )
- , gs_tx_callback
-#endif
- );
-
- gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr);
-}
-
-/**
- * \brief Frames can be read from the GMAC in multiple sections.
- *
- * Returns > 0 if a complete frame is available
- * It also it cleans up incomplete older frames
- */
-
-static uint32_t gmac_dev_poll(gmac_device_t* p_gmac_dev)
-{
- uint32_t ulReturn = 0;
- int32_t ulIndex = p_gmac_dev->ul_rx_idx;
- gmac_rx_descriptor_t *pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
-
- /* Discard any incomplete frames */
- while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) &&
- (pxHead->status.val & GMAC_RXD_SOF) == 0) {
- pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
- circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
- pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
- p_gmac_dev->ul_rx_idx = ulIndex;
- #if( GMAC_STATS != 0 )
- {
- gmacStats.incompCount++;
- }
- #endif
- }
-
- while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) != 0) {
- if ((pxHead->status.val & GMAC_RXD_EOF) != 0) {
- /* Here a complete frame has been seen with SOF and EOF */
- ulReturn = pxHead->status.bm.len;
- break;
- }
- circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
- pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
- if ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) == 0) {
- /* CPU is not the owner (yet) */
- break;
- }
- if ((pxHead->status.val & GMAC_RXD_SOF) != 0) {
- /* Strange, we found a new Start Of Frame
- * discard previous segments */
- int32_t ulPrev = p_gmac_dev->ul_rx_idx;
- pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
- do {
- pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
- circ_inc32 (&ulPrev, p_gmac_dev->ul_rx_list_size);
- pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
- #if( GMAC_STATS != 0 )
- {
- gmacStats.truncCount++;
- }
- #endif
- } while (ulPrev != ulIndex);
- p_gmac_dev->ul_rx_idx = ulIndex;
- }
- }
- return ulReturn;
-}
-
-/**
- * \brief Frames can be read from the GMAC in multiple sections.
- * Read ul_frame_size bytes from the GMAC receive buffers to pcTo.
- * p_rcv_size is the size of the entire frame. Generally gmac_read
- * will be repeatedly called until the sum of all the ul_frame_size equals
- * the value of p_rcv_size.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param p_frame Address of the frame buffer.
- * \param ul_frame_size Length of the frame.
- * \param p_rcv_size Received frame size.
- *
- * \return GMAC_OK if receiving frame successfully, otherwise failed.
- */
-uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
- uint32_t ul_frame_size, uint32_t* p_rcv_size)
-{
- int32_t nextIdx; /* A copy of the Rx-index 'ul_rx_idx' */
- int32_t bytesLeft = gmac_dev_poll (p_gmac_dev);
- gmac_rx_descriptor_t *pxHead;
-
- if (bytesLeft == 0 )
- {
- return GMAC_RX_NULL;
- }
-
- /* gmac_dev_poll has confirmed that there is a complete frame at
- * the current position 'ul_rx_idx'
- */
- nextIdx = p_gmac_dev->ul_rx_idx;
-
- /* Read +2 bytes because buffers are aligned at -2 bytes */
- bytesLeft = min( bytesLeft + 2, ( int32_t )ul_frame_size );
-
- /* The frame will be copied in 1 or 2 memcpy's */
- if( ( p_frame != NULL ) && ( bytesLeft != 0 ) )
- {
- const uint8_t *source;
- int32_t left;
- int32_t toCopy;
-
- source = p_gmac_dev->p_rx_buffer + nextIdx * GMAC_RX_UNITSIZE;
- left = bytesLeft;
- toCopy = ( p_gmac_dev->ul_rx_list_size - nextIdx ) * GMAC_RX_UNITSIZE;
- if(toCopy > left )
- {
- toCopy = left;
- }
- memcpy (p_frame, source, toCopy);
- left -= toCopy;
-
- if( left != 0ul )
- {
- memcpy (p_frame + toCopy, (void*)p_gmac_dev->p_rx_buffer, left);
- }
- }
-
- do
- {
- pxHead = &p_gmac_dev->p_rx_dscr[nextIdx];
- pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
- circ_inc32 (&nextIdx, p_gmac_dev->ul_rx_list_size);
- } while ((pxHead->status.val & GMAC_RXD_EOF) == 0);
-
- p_gmac_dev->ul_rx_idx = nextIdx;
-
- *p_rcv_size = bytesLeft;
-
- return GMAC_OK;
-}
-
-
-extern void vGMACGenerateChecksum( uint8_t *apBuffer );
-
-/**
- * \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
- * GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready.
- * If lEndOfFrame is true then the data being copied is the end of the frame
- * and the frame can be transmitted.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param p_buffer Pointer to the data buffer.
- * \param ul_size Length of the frame.
- * \param func_tx_cb Transmit callback function.
- *
- * \return Length sent.
- */
-uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
- uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb)
-{
-
- volatile gmac_tx_descriptor_t *p_tx_td;
-#if( GMAC_USES_TX_CALLBACK != 0 )
- volatile gmac_dev_tx_cb_t *p_func_tx_cb;
-#endif
-
- Gmac *p_hw = p_gmac_dev->p_hw;
-
-#if( GMAC_USES_TX_CALLBACK == 0 )
- ( void )func_tx_cb;
-#endif
-
- /* Check parameter */
- if (ul_size > GMAC_TX_UNITSIZE) {
- return GMAC_PARAM;
- }
-
- /* Pointers to the current transmit descriptor */
- p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_head];
-
- /* If no free TxTd, buffer can't be sent, schedule the wakeup callback */
-// if (CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
-// p_gmac_dev->ul_tx_list_size) == 0)
- {
- if ((p_tx_td->status.val & GMAC_TXD_USED) == 0)
- return GMAC_TX_BUSY;
- }
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /* Pointers to the current Tx callback */
- p_func_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_head];
-#endif
-
- /* Set up/copy data to transmission buffer */
- if (p_buffer && ul_size) {
- /* Driver manages the ring buffer */
- /* Calculating the checksum here is faster than calculating it from the GMAC buffer
- * because withing p_buffer, it is well aligned */
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Zero-copy... */
- p_tx_td->addr = ( uint32_t ) p_buffer;
- }
- #else
- {
- /* Or Memcopy... */
- memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr );
- }
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /* Tx callback */
- *p_func_tx_cb = func_tx_cb;
-#endif
-
- /* Update transmit descriptor status */
-
- /* The buffer size defined is the length of ethernet frame,
- so it's always the last buffer of the frame. */
- if( p_gmac_dev->l_tx_head == ( int32_t )( p_gmac_dev->ul_tx_list_size - 1 ) )
- {
- /* No need to 'and' with GMAC_TXD_LEN_MASK because ul_size has been checked */
- p_tx_td->status.val =
- ul_size | GMAC_TXD_LAST | GMAC_TXD_WRAP;
- } else {
- p_tx_td->status.val =
- ul_size | GMAC_TXD_LAST;
- }
-
- circ_inc32( &p_gmac_dev->l_tx_head, p_gmac_dev->ul_tx_list_size );
-
- /* Now start to transmit if it is still not done */
- gmac_start_transmission(p_hw);
-
- return GMAC_OK;
-}
-
-/**
- * \brief Get current load of transmit.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- *
- * \return Current load of transmit.
- */
-#if( GMAC_USES_TX_CALLBACK != 0 )
-/* Without defining GMAC_USES_TX_CALLBACK, l_tx_tail won't be updated */
-uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev)
-{
- uint16_t us_head = p_gmac_dev->l_tx_head;
- uint16_t us_tail = p_gmac_dev->l_tx_tail;
- return CIRC_CNT(us_head, us_tail, p_gmac_dev->ul_tx_list_size);
-}
-#endif
-
-/**
- * \brief Register/Clear RX callback. Callback will be invoked after the next received
- * frame.
- *
- * When gmac_dev_read() returns GMAC_RX_NULL, the application task calls
- * gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state.
- * The callback is in charge to resume the task once a new frame has been
- * received. The next time gmac_dev_read() is called, it will be successful.
- *
- * This function is usually invoked from the RX callback itself with NULL
- * callback, to unregister. Once the callback has resumed the application task,
- * there is no need to invoke the callback again.
- *
- * \param p_gmac_dev Pointer to the GMAC device instance.
- * \param func_tx_cb Receive callback function.
- */
-void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_rx_cb_t func_rx_cb)
-{
- Gmac *p_hw = p_gmac_dev->p_hw;
-
- if (func_rx_cb == NULL) {
- gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP);
- p_gmac_dev->func_rx_cb = NULL;
- } else {
- p_gmac_dev->func_rx_cb = func_rx_cb;
- gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP);
- }
-}
-
-/**
- * \brief Register/Clear TX wakeup callback.
- *
- * When gmac_dev_write() returns GMAC_TX_BUSY (all transmit descriptor busy), the application
- * task calls gmac_dev_set_tx_wakeup_callback() to register func_wakeup() callback and
- * enters suspend state. The callback is in charge to resume the task once
- * several transmit descriptors have been released. The next time gmac_dev_write() will be called,
- * it shall be successful.
- *
- * This function is usually invoked with NULL callback from the TX wakeup
- * callback itself, to unregister. Once the callback has resumed the
- * application task, there is no need to invoke the callback again.
- *
- * \param p_gmac_dev Pointer to GMAC device instance.
- * \param func_wakeup Pointer to wakeup callback function.
- * \param uc_threshold Number of free transmit descriptor before wakeup callback invoked.
- *
- * \return GMAC_OK, GMAC_PARAM on parameter error.
- */
-#if( GMAC_USES_WAKEUP_CALLBACK )
-uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_wakeup_cb_t func_wakeup_cb, uint8_t uc_threshold)
-{
- if (func_wakeup_cb == NULL) {
- p_gmac_dev->func_wakeup_cb = NULL;
- } else {
- if (uc_threshold <= p_gmac_dev->ul_tx_list_size) {
- p_gmac_dev->func_wakeup_cb = func_wakeup_cb;
- p_gmac_dev->uc_wakeup_threshold = uc_threshold;
- } else {
- return GMAC_PARAM;
- }
- }
-
- return GMAC_OK;
-}
-#endif /* GMAC_USES_WAKEUP_CALLBACK */
-
-/**
- * \brief Reset TX & RX queue & statistics.
- *
- * \param p_gmac_dev Pointer to GMAC device instance.
- */
-void gmac_dev_reset(gmac_device_t* p_gmac_dev)
-{
- Gmac *p_hw = p_gmac_dev->p_hw;
-
- gmac_reset_rx_mem(p_gmac_dev);
- gmac_reset_tx_mem(p_gmac_dev);
- gmac_network_control(p_hw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
- | GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
-}
-
-void gmac_dev_halt(Gmac* p_gmac);
-
-void gmac_dev_halt(Gmac* p_gmac)
-{
- gmac_network_control(p_gmac, GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
- gmac_disable_interrupt(p_gmac, ~0u);
-}
-
-
-/**
- * \brief GMAC Interrupt handler.
- *
- * \param p_gmac_dev Pointer to GMAC device instance.
- */
-
-#if( GMAC_STATS != 0 )
- extern int logPrintf( const char *pcFormat, ... );
-
- void gmac_show_irq_counts ()
- {
- int index;
- for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
- if (gmacStats.intStatus[intPairs[index].index]) {
- logPrintf("%s : %6u\n", intPairs[index].name, gmacStats.intStatus[intPairs[index].index]);
- }
- }
- }
-#endif
-
-void gmac_handler(gmac_device_t* p_gmac_dev)
-{
- Gmac *p_hw = p_gmac_dev->p_hw;
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- gmac_tx_descriptor_t *p_tx_td;
- gmac_dev_tx_cb_t *p_tx_cb = NULL;
- uint32_t ul_tx_status_flag;
-#endif
-#if( GMAC_STATS != 0 )
- int index;
-#endif
-
- /* volatile */ uint32_t ul_isr;
- /* volatile */ uint32_t ul_rsr;
- /* volatile */ uint32_t ul_tsr;
-
- ul_isr = gmac_get_interrupt_status(p_hw);
- ul_rsr = gmac_get_rx_status(p_hw);
- ul_tsr = gmac_get_tx_status(p_hw);
-
-/* Why clear bits that are ignored anyway ? */
-/* ul_isr &= ~(gmac_get_interrupt_mask(p_hw) | 0xF8030300); */
- #if( GMAC_STATS != 0 )
- {
- for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
- if (ul_isr & intPairs[index].mask)
- gmacStats.intStatus[intPairs[index].index]++;
- }
- }
- #endif /* GMAC_STATS != 0 */
-
- /* RX packet */
- if ((ul_isr & GMAC_ISR_RCOMP) || (ul_rsr & (GMAC_RSR_REC|GMAC_RSR_RXOVR|GMAC_RSR_BNA))) {
- /* Clear status */
- gmac_clear_rx_status(p_hw, ul_rsr);
-
- if (ul_isr & GMAC_ISR_RCOMP)
- ul_rsr |= GMAC_RSR_REC;
- /* Invoke callbacks which can be useful to wake op a task */
- if (p_gmac_dev->func_rx_cb) {
- p_gmac_dev->func_rx_cb(ul_rsr);
- }
- }
-
- /* TX packet */
- if ((ul_isr & GMAC_ISR_TCOMP) || (ul_tsr & (GMAC_TSR_TXCOMP|GMAC_TSR_COL|GMAC_TSR_RLE|GMAC_TSR_UND))) {
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- ul_tx_status_flag = GMAC_TSR_TXCOMP;
-#endif
- /* A frame transmitted */
-
- /* Check RLE */
- if (ul_tsr & GMAC_TSR_RLE) {
- /* Status RLE & Number of discarded buffers */
-#if( GMAC_USES_TX_CALLBACK != 0 )
- ul_tx_status_flag = GMAC_TSR_RLE | CIRC_CNT(p_gmac_dev->l_tx_head,
- p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
- p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
-#endif
- gmac_reset_tx_mem(p_gmac_dev);
- gmac_enable_transmit(p_hw, 1);
- }
- /* Clear status */
- gmac_clear_tx_status(p_hw, ul_tsr);
-
-#if( GMAC_USES_TX_CALLBACK != 0 )
- if (!CIRC_EMPTY(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail)) {
- /* Check the buffers */
- do {
- p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_tail];
- p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
- /* Any error? Exit if buffer has not been sent yet */
- if ((p_tx_td->status.val & GMAC_TXD_USED) == 0) {
- break;
- }
-
- /* Notify upper layer that a packet has been sent */
- if (*p_tx_cb) {
- (*p_tx_cb) (ul_tx_status_flag, (void*)p_tx_td->addr);
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- p_tx_td->addr = 0ul;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
- }
-
- circ_inc32(&p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
- } while (CIRC_CNT(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
- p_gmac_dev->ul_tx_list_size));
- }
-
- if (ul_tsr & GMAC_TSR_RLE) {
- /* Notify upper layer RLE */
- if (*p_tx_cb) {
- (*p_tx_cb) (ul_tx_status_flag, NULL);
- }
- }
-#endif /* GMAC_USES_TX_CALLBACK */
-
-#if( GMAC_USES_WAKEUP_CALLBACK )
- /* If a wakeup has been scheduled, notify upper layer that it can
- send other packets, and the sending will be successful. */
- if ((CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
- p_gmac_dev->ul_tx_list_size) >= p_gmac_dev->uc_wakeup_threshold)
- && p_gmac_dev->func_wakeup_cb) {
- p_gmac_dev->func_wakeup_cb();
- }
-#endif
- }
-}
-
-//@}
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
+ /**
+ * \file
+ *
+ * \brief GMAC (Ethernet MAC) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+
+#include "FreeRTOSIPConfig.h"
+
+#include "compiler.h"
+#include "instance/gmac.h"
+#include "ethernet_phy.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+#ifndef ARRAY_SIZE
+#define ARRAY_SIZE(x) (int)( sizeof(x) / sizeof(x)[0] )
+#endif
+/**
+ * \defgroup gmac_group Ethernet Media Access Controller
+ *
+ * See \ref gmac_quickstart.
+ *
+ * Driver for the GMAC (Ethernet Media Access Controller).
+ * This file contains basic functions for the GMAC, with support for all modes, settings
+ * and clock speeds.
+ *
+ * \section dependencies Dependencies
+ * This driver does not depend on other modules.
+ *
+ * @{
+ */
+
+/** TX descriptor lists */
+COMPILER_ALIGNED(8)
+static gmac_tx_descriptor_t gs_tx_desc[ GMAC_TX_BUFFERS ];
+#if( GMAC_USES_TX_CALLBACK != 0 )
+/** TX callback lists */
+static gmac_dev_tx_cb_t gs_tx_callback[ GMAC_TX_BUFFERS ];
+#endif
+/** RX descriptors lists */
+COMPILER_ALIGNED(8)
+static gmac_rx_descriptor_t gs_rx_desc[ GMAC_RX_BUFFERS ];
+
+#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ /** Send Buffer. Section 3.6 of AMBA 2.0 spec states that burst should not cross the
+ * 1K Boundaries. Receive buffer manager write operations are burst of 2 words => 3 lsb bits
+ * of the address shall be set to 0.
+ */
+ COMPILER_ALIGNED(8)
+ static uint8_t gs_uc_tx_buffer[ GMAC_TX_BUFFERS * GMAC_TX_UNITSIZE ];
+#endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+/** Receive Buffer */
+COMPILER_ALIGNED(8)
+static uint8_t gs_uc_rx_buffer[ GMAC_RX_BUFFERS * GMAC_RX_UNITSIZE ];
+
+/**
+ * GMAC device memory management struct.
+ */
+typedef struct gmac_dev_mem {
+ /* Pointer to allocated buffer for RX. The address should be 8-byte aligned
+ and the size should be GMAC_RX_UNITSIZE * wRxSize. */
+ uint8_t *p_rx_buffer;
+ /* Pointer to allocated RX descriptor list. */
+ gmac_rx_descriptor_t *p_rx_dscr;
+ /* RX size, in number of registered units (RX descriptors). */
+ /* Increased size from 16- to 32-bits, because it's more efficient */
+ uint32_t us_rx_size;
+ /* Pointer to allocated buffer for TX. The address should be 8-byte aligned
+ and the size should be GMAC_TX_UNITSIZE * wTxSize. */
+ uint8_t *p_tx_buffer;
+ /* Pointer to allocated TX descriptor list. */
+ gmac_tx_descriptor_t *p_tx_dscr;
+ /* TX size, in number of registered units (TX descriptors). */
+ uint32_t us_tx_size;
+} gmac_dev_mem_t;
+
+/** Return count in buffer */
+#define CIRC_CNT( head, tail, size ) ( ( ( head ) - ( tail ) ) % ( size ) )
+
+/*
+ * Return space available, from 0 to size-1.
+ * Always leave one free char as a completely full buffer that has (head == tail),
+ * which is the same as empty.
+ */
+#define CIRC_SPACE( head, tail, size ) CIRC_CNT( ( tail ), ( ( head ) + 1 ), ( size ) )
+
+/** Circular buffer is empty ? */
+#define CIRC_EMPTY( head, tail ) ( head == tail )
+/** Clear circular buffer */
+#define CIRC_CLEAR( head, tail ) do { ( head ) = 0; ( tail ) = 0; } while( 0 )
+
+/** Increment head or tail */
+static __inline void circ_inc32( int32_t *lHeadOrTail, uint32_t ulSize )
+{
+ ( *lHeadOrTail ) ++;
+ if( ( *lHeadOrTail ) >= ( int32_t )ulSize )
+ {
+ ( *lHeadOrTail ) = 0;
+ }
+}
+
+/**
+ * \brief Wait PHY operation to be completed.
+ *
+ * \param p_gmac HW controller address.
+ * \param ul_retry The retry times, 0 to wait forever until completeness.
+ *
+ * Return GMAC_OK if the operation is completed successfully.
+ */
+static uint8_t gmac_wait_phy(Gmac* p_gmac, const uint32_t ul_retry)
+{
+ volatile uint32_t ul_retry_count = 0;
+ const uint32_t xPHYPollDelay = pdMS_TO_TICKS( 1ul );
+
+ while (!gmac_is_phy_idle(p_gmac)) {
+ if (ul_retry == 0) {
+ continue;
+ }
+
+ ul_retry_count++;
+
+ if (ul_retry_count >= ul_retry) {
+ return GMAC_TIMEOUT;
+ }
+
+ /* Block the task to allow other tasks to execute while the PHY
+ is not connected. */
+ vTaskDelay( xPHYPollDelay );
+ }
+ return GMAC_OK;
+}
+
+/**
+ * \brief Disable transfer, reset registers and descriptor lists.
+ *
+ * \param p_dev Pointer to GMAC driver instance.
+ *
+ */
+static void gmac_reset_tx_mem(gmac_device_t* p_dev)
+{
+ Gmac *p_hw = p_dev->p_hw;
+ uint8_t *p_tx_buff = p_dev->p_tx_buffer;
+ gmac_tx_descriptor_t *p_td = p_dev->p_tx_dscr;
+
+ uint32_t ul_index;
+ uint32_t ul_address;
+
+ /* Disable TX */
+ gmac_enable_transmit(p_hw, 0);
+
+ /* Set up the TX descriptors */
+ CIRC_CLEAR(p_dev->l_tx_head, p_dev->l_tx_tail);
+ for( ul_index = 0; ul_index < p_dev->ul_tx_list_size; ul_index++ )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ ul_address = (uint32_t) 0u;
+ }
+ #else
+ {
+ ul_address = (uint32_t) (&(p_tx_buff[ul_index * GMAC_TX_UNITSIZE]));
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ p_td[ul_index].addr = ul_address;
+ p_td[ul_index].status.val = GMAC_TXD_USED;
+ }
+ p_td[p_dev->ul_tx_list_size - 1].status.val =
+ GMAC_TXD_USED | GMAC_TXD_WRAP;
+
+ /* Set transmit buffer queue */
+ gmac_set_tx_queue(p_hw, (uint32_t) p_td);
+}
+
+/**
+ * \brief Disable receiver, reset registers and descriptor list.
+ *
+ * \param p_drv Pointer to GMAC Driver instance.
+ */
+static void gmac_reset_rx_mem(gmac_device_t* p_dev)
+{
+ Gmac *p_hw = p_dev->p_hw;
+ uint8_t *p_rx_buff = p_dev->p_rx_buffer;
+ gmac_rx_descriptor_t *pRd = p_dev->p_rx_dscr;
+
+ uint32_t ul_index;
+ uint32_t ul_address;
+
+ /* Disable RX */
+ gmac_enable_receive(p_hw, 0);
+
+ /* Set up the RX descriptors */
+ p_dev->ul_rx_idx = 0;
+ for( ul_index = 0; ul_index < p_dev->ul_rx_list_size; ul_index++ )
+ {
+ ul_address = (uint32_t) (&(p_rx_buff[ul_index * GMAC_RX_UNITSIZE]));
+ pRd[ul_index].addr.val = ul_address & GMAC_RXD_ADDR_MASK;
+ pRd[ul_index].status.val = 0;
+ }
+ pRd[p_dev->ul_rx_list_size - 1].addr.val |= GMAC_RXD_WRAP;
+
+ /* Set receive buffer queue */
+ gmac_set_rx_queue(p_hw, (uint32_t) pRd);
+}
+
+
+/**
+ * \brief Initialize the allocated buffer lists for GMAC driver to transfer data.
+ * Must be invoked after gmac_dev_init() but before RX/TX starts.
+ *
+ * \note If input address is not 8-byte aligned, the address is automatically
+ * adjusted and the list size is reduced by one.
+ *
+ * \param p_gmac Pointer to GMAC instance.
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ * \param p_dev_mm Pointer to the GMAC memory management control block.
+ * \param p_tx_cb Pointer to allocated TX callback list.
+ *
+ * \return GMAC_OK or GMAC_PARAM.
+ */
+static uint8_t gmac_init_mem(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_dev_mem_t* p_dev_mm
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ , gmac_dev_tx_cb_t* p_tx_cb
+#endif
+ )
+{
+ if (p_dev_mm->us_rx_size <= 1 || p_dev_mm->us_tx_size <= 1
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ || p_tx_cb == NULL
+#endif
+ ) {
+ return GMAC_PARAM;
+ }
+
+ /* Assign RX buffers */
+ if (((uint32_t) p_dev_mm->p_rx_buffer & 0x7)
+ || ((uint32_t) p_dev_mm->p_rx_dscr & 0x7)) {
+ p_dev_mm->us_rx_size--;
+ }
+ p_gmac_dev->p_rx_buffer =
+ (uint8_t *) ((uint32_t) p_dev_mm->p_rx_buffer & 0xFFFFFFF8);
+ p_gmac_dev->p_rx_dscr =
+ (gmac_rx_descriptor_t *) ((uint32_t) p_dev_mm->p_rx_dscr
+ & 0xFFFFFFF8);
+ p_gmac_dev->ul_rx_list_size = p_dev_mm->us_rx_size;
+
+ /* Assign TX buffers */
+ if (((uint32_t) p_dev_mm->p_tx_buffer & 0x7)
+ || ((uint32_t) p_dev_mm->p_tx_dscr & 0x7)) {
+ p_dev_mm->us_tx_size--;
+ }
+ p_gmac_dev->p_tx_buffer =
+ (uint8_t *) ((uint32_t) p_dev_mm->p_tx_buffer & 0xFFFFFFF8);
+ p_gmac_dev->p_tx_dscr =
+ (gmac_tx_descriptor_t *) ((uint32_t) p_dev_mm->p_tx_dscr
+ & 0xFFFFFFF8);
+ p_gmac_dev->ul_tx_list_size = p_dev_mm->us_tx_size;
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ p_gmac_dev->func_tx_cb_list = p_tx_cb;
+#endif
+ /* Reset TX & RX */
+ gmac_reset_rx_mem(p_gmac_dev);
+ gmac_reset_tx_mem(p_gmac_dev);
+
+ /* Enable Rx and Tx, plus the statistics register */
+ gmac_enable_transmit(p_gmac, true);
+ gmac_enable_receive(p_gmac, true);
+ gmac_enable_statistics_write(p_gmac, true);
+
+ /* Set up the interrupts for transmission and errors */
+ gmac_enable_interrupt(p_gmac,
+ GMAC_IER_RXUBR | /* Enable receive used bit read interrupt. */
+ GMAC_IER_TUR | /* Enable transmit underrun interrupt. */
+ GMAC_IER_RLEX | /* Enable retry limit exceeded interrupt. */
+ GMAC_IER_TFC | /* Enable transmit buffers exhausted in mid-frame interrupt. */
+ GMAC_IER_TCOMP | /* Enable transmit complete interrupt. */
+ GMAC_IER_ROVR | /* Enable receive overrun interrupt. */
+ GMAC_IER_HRESP | /* Enable Hresp not OK interrupt. */
+ GMAC_IER_PFNZ | /* Enable pause frame received interrupt. */
+ GMAC_IER_PTZ); /* Enable pause time zero interrupt. */
+
+ return GMAC_OK;
+}
+
+/**
+ * \brief Read the PHY register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_address PHY address.
+ * \param uc_address Register address.
+ * \param p_value Pointer to a 32-bit location to store read data.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
+ uint32_t* p_value)
+{
+ gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 1, 0);
+
+ if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
+ return GMAC_TIMEOUT;
+ }
+ *p_value = gmac_get_phy_data(p_gmac);
+ return GMAC_OK;
+}
+
+/**
+ * \brief Write the PHY register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_address PHY Address.
+ * \param uc_address Register Address.
+ * \param ul_value Data to write, actually 16-bit data.
+ *
+ * \Return GMAC_OK if successfully, GMAC_TIMEOUT if timeout.
+ */
+uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
+ uint8_t uc_address, uint32_t ul_value)
+{
+ gmac_maintain_phy(p_gmac, uc_phy_address, uc_address, 0, ul_value);
+
+ if (gmac_wait_phy(p_gmac, MAC_PHY_RETRY_MAX) == GMAC_TIMEOUT) {
+ return GMAC_TIMEOUT;
+ }
+ return GMAC_OK;
+}
+
+/**
+ * \brief Initialize the GMAC driver.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param p_opt GMAC configure options.
+ */
+void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_options_t* p_opt)
+{
+ gmac_dev_mem_t gmac_dev_mm;
+
+ /* Disable TX & RX and more */
+ gmac_network_control(p_gmac, 0);
+ gmac_disable_interrupt(p_gmac, ~0u);
+
+
+ gmac_clear_statistics(p_gmac);
+
+ /* Clear all status bits in the receive status register. */
+ gmac_clear_rx_status(p_gmac, GMAC_RSR_RXOVR | GMAC_RSR_REC | GMAC_RSR_BNA);
+
+ /* Clear all status bits in the transmit status register */
+ gmac_clear_tx_status(p_gmac, GMAC_TSR_UBR | GMAC_TSR_COL | GMAC_TSR_RLE
+ | GMAC_TSR_TFC | GMAC_TSR_TXCOMP | GMAC_TSR_UND);
+
+ /* Clear interrupts */
+ gmac_get_interrupt_status(p_gmac);
+#if !defined(ETHERNET_CONF_DATA_OFFSET)
+ /* Receive Buffer Offset
+ * Indicates the number of bytes by which the received data
+ * is offset from the start of the receive buffer
+ * which can be handy for alignment reasons */
+ /* Note: FreeRTOS+TCP wants to have this offset set to 2 bytes */
+ #error ETHERNET_CONF_DATA_OFFSET not defined, assuming 0
+#endif
+ /* Enable the copy of data into the buffers
+ ignore broadcasts, and not copy FCS. */
+
+ gmac_set_configure(p_gmac,
+ ( gmac_get_configure(p_gmac) & ~GMAC_NCFGR_RXBUFO_Msk ) |
+ GMAC_NCFGR_RFCS | /* Remove FCS, frame check sequence (last 4 bytes) */
+ GMAC_NCFGR_PEN | /* Pause Enable */
+ GMAC_NCFGR_RXBUFO( ETHERNET_CONF_DATA_OFFSET ) |
+ GMAC_RXD_RXCOEN );
+
+ /*
+ * GMAC_DCFGR_TXCOEN: (GMAC_DCFGR) Transmitter Checksum Generation Offload Enable.
+ * Note: tha SAM4E does have RX checksum offloading
+ * but TX checksum offloading has NOT been implemented.
+ */
+
+ gmac_set_dma(p_gmac,
+ gmac_get_dma(p_gmac) | GMAC_DCFGR_TXCOEN );
+
+ gmac_enable_copy_all(p_gmac, p_opt->uc_copy_all_frame);
+ gmac_disable_broadcast(p_gmac, p_opt->uc_no_boardcast);
+
+ /* Fill in GMAC device memory management */
+ gmac_dev_mm.p_rx_buffer = gs_uc_rx_buffer;
+ gmac_dev_mm.p_rx_dscr = gs_rx_desc;
+ gmac_dev_mm.us_rx_size = GMAC_RX_BUFFERS;
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ gmac_dev_mm.p_tx_buffer = NULL;
+ }
+ #else
+ {
+ gmac_dev_mm.p_tx_buffer = gs_uc_tx_buffer;
+ }
+ #endif
+ gmac_dev_mm.p_tx_dscr = gs_tx_desc;
+ gmac_dev_mm.us_tx_size = GMAC_TX_BUFFERS;
+
+ gmac_init_mem(p_gmac, p_gmac_dev, &gmac_dev_mm
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ , gs_tx_callback
+#endif
+ );
+
+ gmac_set_address(p_gmac, 0, p_opt->uc_mac_addr);
+}
+
+/**
+ * \brief Frames can be read from the GMAC in multiple sections.
+ *
+ * Returns > 0 if a complete frame is available
+ * It also it cleans up incomplete older frames
+ */
+
+static uint32_t gmac_dev_poll(gmac_device_t* p_gmac_dev)
+{
+ uint32_t ulReturn = 0;
+ int32_t ulIndex = p_gmac_dev->ul_rx_idx;
+ gmac_rx_descriptor_t *pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
+
+ /* Discard any incomplete frames */
+ while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) &&
+ (pxHead->status.val & GMAC_RXD_SOF) == 0) {
+ pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
+ circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
+ pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
+ p_gmac_dev->ul_rx_idx = ulIndex;
+ #if( GMAC_STATS != 0 )
+ {
+ gmacStats.incompCount++;
+ }
+ #endif
+ }
+
+ while ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) != 0) {
+ if ((pxHead->status.val & GMAC_RXD_EOF) != 0) {
+ /* Here a complete frame has been seen with SOF and EOF */
+ ulReturn = pxHead->status.bm.len;
+ break;
+ }
+ circ_inc32 (&ulIndex, p_gmac_dev->ul_rx_list_size);
+ pxHead = &p_gmac_dev->p_rx_dscr[ulIndex];
+ if ((pxHead->addr.val & GMAC_RXD_OWNERSHIP) == 0) {
+ /* CPU is not the owner (yet) */
+ break;
+ }
+ if ((pxHead->status.val & GMAC_RXD_SOF) != 0) {
+ /* Strange, we found a new Start Of Frame
+ * discard previous segments */
+ int32_t ulPrev = p_gmac_dev->ul_rx_idx;
+ pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
+ do {
+ pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
+ circ_inc32 (&ulPrev, p_gmac_dev->ul_rx_list_size);
+ pxHead = &p_gmac_dev->p_rx_dscr[ulPrev];
+ #if( GMAC_STATS != 0 )
+ {
+ gmacStats.truncCount++;
+ }
+ #endif
+ } while (ulPrev != ulIndex);
+ p_gmac_dev->ul_rx_idx = ulIndex;
+ }
+ }
+ return ulReturn;
+}
+
+/**
+ * \brief Frames can be read from the GMAC in multiple sections.
+ * Read ul_frame_size bytes from the GMAC receive buffers to pcTo.
+ * p_rcv_size is the size of the entire frame. Generally gmac_read
+ * will be repeatedly called until the sum of all the ul_frame_size equals
+ * the value of p_rcv_size.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param p_frame Address of the frame buffer.
+ * \param ul_frame_size Length of the frame.
+ * \param p_rcv_size Received frame size.
+ *
+ * \return GMAC_OK if receiving frame successfully, otherwise failed.
+ */
+uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
+ uint32_t ul_frame_size, uint32_t* p_rcv_size)
+{
+ int32_t nextIdx; /* A copy of the Rx-index 'ul_rx_idx' */
+ int32_t bytesLeft = gmac_dev_poll (p_gmac_dev);
+ gmac_rx_descriptor_t *pxHead;
+
+ if (bytesLeft == 0 )
+ {
+ return GMAC_RX_NULL;
+ }
+
+ /* gmac_dev_poll has confirmed that there is a complete frame at
+ * the current position 'ul_rx_idx'
+ */
+ nextIdx = p_gmac_dev->ul_rx_idx;
+
+ /* Read +2 bytes because buffers are aligned at -2 bytes */
+ bytesLeft = min( bytesLeft + 2, ( int32_t )ul_frame_size );
+
+ /* The frame will be copied in 1 or 2 memcpy's */
+ if( ( p_frame != NULL ) && ( bytesLeft != 0 ) )
+ {
+ const uint8_t *source;
+ int32_t left;
+ int32_t toCopy;
+
+ source = p_gmac_dev->p_rx_buffer + nextIdx * GMAC_RX_UNITSIZE;
+ left = bytesLeft;
+ toCopy = ( p_gmac_dev->ul_rx_list_size - nextIdx ) * GMAC_RX_UNITSIZE;
+ if(toCopy > left )
+ {
+ toCopy = left;
+ }
+ memcpy (p_frame, source, toCopy);
+ left -= toCopy;
+
+ if( left != 0ul )
+ {
+ memcpy (p_frame + toCopy, (void*)p_gmac_dev->p_rx_buffer, left);
+ }
+ }
+
+ do
+ {
+ pxHead = &p_gmac_dev->p_rx_dscr[nextIdx];
+ pxHead->addr.val &= ~(GMAC_RXD_OWNERSHIP);
+ circ_inc32 (&nextIdx, p_gmac_dev->ul_rx_list_size);
+ } while ((pxHead->status.val & GMAC_RXD_EOF) == 0);
+
+ p_gmac_dev->ul_rx_idx = nextIdx;
+
+ *p_rcv_size = bytesLeft;
+
+ return GMAC_OK;
+}
+
+
+extern void vGMACGenerateChecksum( uint8_t *apBuffer );
+
+/**
+ * \brief Send ulLength bytes from pcFrom. This copies the buffer to one of the
+ * GMAC Tx buffers, and then indicates to the GMAC that the buffer is ready.
+ * If lEndOfFrame is true then the data being copied is the end of the frame
+ * and the frame can be transmitted.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param p_buffer Pointer to the data buffer.
+ * \param ul_size Length of the frame.
+ * \param func_tx_cb Transmit callback function.
+ *
+ * \return Length sent.
+ */
+uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
+ uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb)
+{
+
+ volatile gmac_tx_descriptor_t *p_tx_td;
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ volatile gmac_dev_tx_cb_t *p_func_tx_cb;
+#endif
+
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+#if( GMAC_USES_TX_CALLBACK == 0 )
+ ( void )func_tx_cb;
+#endif
+
+ /* Check parameter */
+ if (ul_size > GMAC_TX_UNITSIZE) {
+ return GMAC_PARAM;
+ }
+
+ /* Pointers to the current transmit descriptor */
+ p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_head];
+
+ /* If no free TxTd, buffer can't be sent, schedule the wakeup callback */
+// if (CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
+// p_gmac_dev->ul_tx_list_size) == 0)
+ {
+ if ((p_tx_td->status.val & GMAC_TXD_USED) == 0)
+ return GMAC_TX_BUSY;
+ }
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /* Pointers to the current Tx callback */
+ p_func_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_head];
+#endif
+
+ /* Set up/copy data to transmission buffer */
+ if (p_buffer && ul_size) {
+ /* Driver manages the ring buffer */
+ /* Calculating the checksum here is faster than calculating it from the GMAC buffer
+ * because withing p_buffer, it is well aligned */
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Zero-copy... */
+ p_tx_td->addr = ( uint32_t ) p_buffer;
+ }
+ #else
+ {
+ /* Or Memcopy... */
+ memcpy((void *)p_tx_td->addr, p_buffer, ul_size);
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ vGMACGenerateChecksum( ( uint8_t * ) p_tx_td->addr );
+ }
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /* Tx callback */
+ *p_func_tx_cb = func_tx_cb;
+#endif
+
+ /* Update transmit descriptor status */
+
+ /* The buffer size defined is the length of ethernet frame,
+ so it's always the last buffer of the frame. */
+ if( p_gmac_dev->l_tx_head == ( int32_t )( p_gmac_dev->ul_tx_list_size - 1 ) )
+ {
+ /* No need to 'and' with GMAC_TXD_LEN_MASK because ul_size has been checked */
+ p_tx_td->status.val =
+ ul_size | GMAC_TXD_LAST | GMAC_TXD_WRAP;
+ } else {
+ p_tx_td->status.val =
+ ul_size | GMAC_TXD_LAST;
+ }
+
+ circ_inc32( &p_gmac_dev->l_tx_head, p_gmac_dev->ul_tx_list_size );
+
+ /* Now start to transmit if it is still not done */
+ gmac_start_transmission(p_hw);
+
+ return GMAC_OK;
+}
+
+/**
+ * \brief Get current load of transmit.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ *
+ * \return Current load of transmit.
+ */
+#if( GMAC_USES_TX_CALLBACK != 0 )
+/* Without defining GMAC_USES_TX_CALLBACK, l_tx_tail won't be updated */
+uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev)
+{
+ uint16_t us_head = p_gmac_dev->l_tx_head;
+ uint16_t us_tail = p_gmac_dev->l_tx_tail;
+ return CIRC_CNT(us_head, us_tail, p_gmac_dev->ul_tx_list_size);
+}
+#endif
+
+/**
+ * \brief Register/Clear RX callback. Callback will be invoked after the next received
+ * frame.
+ *
+ * When gmac_dev_read() returns GMAC_RX_NULL, the application task calls
+ * gmac_dev_set_rx_callback() to register func_rx_cb() callback and enters suspend state.
+ * The callback is in charge to resume the task once a new frame has been
+ * received. The next time gmac_dev_read() is called, it will be successful.
+ *
+ * This function is usually invoked from the RX callback itself with NULL
+ * callback, to unregister. Once the callback has resumed the application task,
+ * there is no need to invoke the callback again.
+ *
+ * \param p_gmac_dev Pointer to the GMAC device instance.
+ * \param func_tx_cb Receive callback function.
+ */
+void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_rx_cb_t func_rx_cb)
+{
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+ if (func_rx_cb == NULL) {
+ gmac_disable_interrupt(p_hw, GMAC_IDR_RCOMP);
+ p_gmac_dev->func_rx_cb = NULL;
+ } else {
+ p_gmac_dev->func_rx_cb = func_rx_cb;
+ gmac_enable_interrupt(p_hw, GMAC_IER_RCOMP);
+ }
+}
+
+/**
+ * \brief Register/Clear TX wakeup callback.
+ *
+ * When gmac_dev_write() returns GMAC_TX_BUSY (all transmit descriptor busy), the application
+ * task calls gmac_dev_set_tx_wakeup_callback() to register func_wakeup() callback and
+ * enters suspend state. The callback is in charge to resume the task once
+ * several transmit descriptors have been released. The next time gmac_dev_write() will be called,
+ * it shall be successful.
+ *
+ * This function is usually invoked with NULL callback from the TX wakeup
+ * callback itself, to unregister. Once the callback has resumed the
+ * application task, there is no need to invoke the callback again.
+ *
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ * \param func_wakeup Pointer to wakeup callback function.
+ * \param uc_threshold Number of free transmit descriptor before wakeup callback invoked.
+ *
+ * \return GMAC_OK, GMAC_PARAM on parameter error.
+ */
+#if( GMAC_USES_WAKEUP_CALLBACK )
+uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_wakeup_cb_t func_wakeup_cb, uint8_t uc_threshold)
+{
+ if (func_wakeup_cb == NULL) {
+ p_gmac_dev->func_wakeup_cb = NULL;
+ } else {
+ if (uc_threshold <= p_gmac_dev->ul_tx_list_size) {
+ p_gmac_dev->func_wakeup_cb = func_wakeup_cb;
+ p_gmac_dev->uc_wakeup_threshold = uc_threshold;
+ } else {
+ return GMAC_PARAM;
+ }
+ }
+
+ return GMAC_OK;
+}
+#endif /* GMAC_USES_WAKEUP_CALLBACK */
+
+/**
+ * \brief Reset TX & RX queue & statistics.
+ *
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ */
+void gmac_dev_reset(gmac_device_t* p_gmac_dev)
+{
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+ gmac_reset_rx_mem(p_gmac_dev);
+ gmac_reset_tx_mem(p_gmac_dev);
+ gmac_network_control(p_hw, GMAC_NCR_TXEN | GMAC_NCR_RXEN
+ | GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
+}
+
+void gmac_dev_halt(Gmac* p_gmac);
+
+void gmac_dev_halt(Gmac* p_gmac)
+{
+ gmac_network_control(p_gmac, GMAC_NCR_WESTAT | GMAC_NCR_CLRSTAT);
+ gmac_disable_interrupt(p_gmac, ~0u);
+}
+
+
+/**
+ * \brief GMAC Interrupt handler.
+ *
+ * \param p_gmac_dev Pointer to GMAC device instance.
+ */
+
+#if( GMAC_STATS != 0 )
+ extern int logPrintf( const char *pcFormat, ... );
+
+ void gmac_show_irq_counts ()
+ {
+ int index;
+ for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
+ if (gmacStats.intStatus[intPairs[index].index]) {
+ logPrintf("%s : %6u\n", intPairs[index].name, gmacStats.intStatus[intPairs[index].index]);
+ }
+ }
+ }
+#endif
+
+void gmac_handler(gmac_device_t* p_gmac_dev)
+{
+ Gmac *p_hw = p_gmac_dev->p_hw;
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ gmac_tx_descriptor_t *p_tx_td;
+ gmac_dev_tx_cb_t *p_tx_cb = NULL;
+ uint32_t ul_tx_status_flag;
+#endif
+#if( GMAC_STATS != 0 )
+ int index;
+#endif
+
+ /* volatile */ uint32_t ul_isr;
+ /* volatile */ uint32_t ul_rsr;
+ /* volatile */ uint32_t ul_tsr;
+
+ ul_isr = gmac_get_interrupt_status(p_hw);
+ ul_rsr = gmac_get_rx_status(p_hw);
+ ul_tsr = gmac_get_tx_status(p_hw);
+
+/* Why clear bits that are ignored anyway ? */
+/* ul_isr &= ~(gmac_get_interrupt_mask(p_hw) | 0xF8030300); */
+ #if( GMAC_STATS != 0 )
+ {
+ for (index = 0; index < ARRAY_SIZE(intPairs); index++) {
+ if (ul_isr & intPairs[index].mask)
+ gmacStats.intStatus[intPairs[index].index]++;
+ }
+ }
+ #endif /* GMAC_STATS != 0 */
+
+ /* RX packet */
+ if ((ul_isr & GMAC_ISR_RCOMP) || (ul_rsr & (GMAC_RSR_REC|GMAC_RSR_RXOVR|GMAC_RSR_BNA))) {
+ /* Clear status */
+ gmac_clear_rx_status(p_hw, ul_rsr);
+
+ if (ul_isr & GMAC_ISR_RCOMP)
+ ul_rsr |= GMAC_RSR_REC;
+ /* Invoke callbacks which can be useful to wake op a task */
+ if (p_gmac_dev->func_rx_cb) {
+ p_gmac_dev->func_rx_cb(ul_rsr);
+ }
+ }
+
+ /* TX packet */
+ if ((ul_isr & GMAC_ISR_TCOMP) || (ul_tsr & (GMAC_TSR_TXCOMP|GMAC_TSR_COL|GMAC_TSR_RLE|GMAC_TSR_UND))) {
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ ul_tx_status_flag = GMAC_TSR_TXCOMP;
+#endif
+ /* A frame transmitted */
+
+ /* Check RLE */
+ if (ul_tsr & GMAC_TSR_RLE) {
+ /* Status RLE & Number of discarded buffers */
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ ul_tx_status_flag = GMAC_TSR_RLE | CIRC_CNT(p_gmac_dev->l_tx_head,
+ p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
+ p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
+#endif
+ gmac_reset_tx_mem(p_gmac_dev);
+ gmac_enable_transmit(p_hw, 1);
+ }
+ /* Clear status */
+ gmac_clear_tx_status(p_hw, ul_tsr);
+
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ if (!CIRC_EMPTY(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail)) {
+ /* Check the buffers */
+ do {
+ p_tx_td = &p_gmac_dev->p_tx_dscr[p_gmac_dev->l_tx_tail];
+ p_tx_cb = &p_gmac_dev->func_tx_cb_list[p_gmac_dev->l_tx_tail];
+ /* Any error? Exit if buffer has not been sent yet */
+ if ((p_tx_td->status.val & GMAC_TXD_USED) == 0) {
+ break;
+ }
+
+ /* Notify upper layer that a packet has been sent */
+ if (*p_tx_cb) {
+ (*p_tx_cb) (ul_tx_status_flag, (void*)p_tx_td->addr);
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ p_tx_td->addr = 0ul;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+ }
+
+ circ_inc32(&p_gmac_dev->l_tx_tail, p_gmac_dev->ul_tx_list_size);
+ } while (CIRC_CNT(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
+ p_gmac_dev->ul_tx_list_size));
+ }
+
+ if (ul_tsr & GMAC_TSR_RLE) {
+ /* Notify upper layer RLE */
+ if (*p_tx_cb) {
+ (*p_tx_cb) (ul_tx_status_flag, NULL);
+ }
+ }
+#endif /* GMAC_USES_TX_CALLBACK */
+
+#if( GMAC_USES_WAKEUP_CALLBACK )
+ /* If a wakeup has been scheduled, notify upper layer that it can
+ send other packets, and the sending will be successful. */
+ if ((CIRC_SPACE(p_gmac_dev->l_tx_head, p_gmac_dev->l_tx_tail,
+ p_gmac_dev->ul_tx_list_size) >= p_gmac_dev->uc_wakeup_threshold)
+ && p_gmac_dev->func_wakeup_cb) {
+ p_gmac_dev->func_wakeup_cb();
+ }
+#endif
+ }
+}
+
+//@}
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
index fca3ece33..d741a2a0a 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/gmac.h
@@ -1,1346 +1,1346 @@
- /**
- * \file
- *
- * \brief GMAC (Ethernet MAC) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef GMAC_H_INCLUDED
-#define GMAC_H_INCLUDED
-
-#include "compiler.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/** The buffer addresses written into the descriptors must be aligned, so the
- last few bits are zero. These bits have special meaning for the GMAC
- peripheral and cannot be used as part of the address. */
-#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
-#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
-#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
-
-#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
-#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
-#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
-#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
-#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
-#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
-#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
-#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
-#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
-#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
-#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
-#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
-#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
-#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
-#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
-#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
-#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
-
-#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
-#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
-#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
-#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
-#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
-#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
-#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
-#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
-#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
-#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
-
-/** The MAC can support frame lengths up to 1536 bytes */
-#define GMAC_FRAME_LENTGH_MAX 1536
-
-#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
-#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
-
-/** GMAC clock speed */
-#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
-#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
-#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
-#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
-#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
-#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
-
-/** GMAC maintain code default value*/
-#define GMAC_MAN_CODE_VALUE (10)
-
-/** GMAC maintain start of frame default value*/
-#define GMAC_MAN_SOF_VALUE (1)
-
-/** GMAC maintain read/write*/
-#define GMAC_MAN_RW_TYPE (2)
-
-/** GMAC maintain read only*/
-#define GMAC_MAN_READ_ONLY (1)
-
-/** GMAC address length */
-#define GMAC_ADDR_LENGTH (6)
-
-
-#define GMAC_DUPLEX_HALF 0
-#define GMAC_DUPLEX_FULL 1
-
-#define GMAC_SPEED_10M 0
-#define GMAC_SPEED_100M 1
-
-/**
- * \brief Return codes for GMAC APIs.
- */
-typedef enum {
- GMAC_OK = 0, /** 0 Operation OK */
- GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
- GMAC_TX_BUSY, /** 2 TX in progress */
- GMAC_RX_NULL, /** 3 No data received */
- GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
- GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
- GMAC_INVALID = 0xFF, /* Invalid */
-} gmac_status_t;
-
-/**
- * \brief Media Independent Interface (MII) type.
- */
-typedef enum {
- GMAC_PHY_MII = 0, /** MII mode */
- GMAC_PHY_RMII = 1, /** Reduced MII mode */
- GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
-} gmac_mii_mode_t;
-
-/** Receive buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_rx_descriptor {
- union gmac_rx_addr {
- uint32_t val;
- struct gmac_rx_addr_bm {
- uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
- b_wrap:1, /**< Marks last descriptor in receive buffer */
- addr_dw:30; /**< Address in number of DW */
- } bm;
- } addr; /**< Address, Wrap & Ownership */
- union gmac_rx_status {
- uint32_t val;
- struct gmac_rx_status_bm {
- uint32_t len:13, /** 0..12 Length of frame including FCS */
- b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
- b_sof:1, /** 14 Start of frame */
- b_eof:1, /** 15 End of frame */
- b_cfi:1, /** 16 Concatenation Format Indicator */
- vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
- b_priority_detected:1, /** 20 Priority tag detected */
- b_vlan_detected:1, /** 21 VLAN tag detected */
- b_type_id_match:2, /** 22..23 Type ID match */
- b_checksumoffload:1, /** 24 Checksum offload specific function */
- b_addrmatch:2, /** 25..26 Address register match */
- b_ext_addr_match:1, /** 27 External address match found */
- reserved:1, /** 28 */
- b_uni_hash_match:1, /** 29 Unicast hash match */
- b_multi_hash_match:1, /** 30 Multicast hash match */
- b_boardcast_detect:1; /** 31 Global broadcast address detected */
- } bm;
- } status;
-} gmac_rx_descriptor_t;
-
-/** Transmit buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_tx_descriptor {
- uint32_t addr;
- union gmac_tx_status {
- uint32_t val;
- struct gmac_tx_status_bm {
- uint32_t len:14, /** 0..13 Length of buffer */
- reserved:1, /** 14 */
- b_last_buffer:1, /** 15 Last buffer (in the current frame) */
- b_no_crc:1, /** 16 No CRC */
- reserved1:3, /** 17..19 */
- b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
- reserved2:3, /** 23..25 */
- b_lco:1, /** 26 Late collision, transmit error detected */
- b_exhausted:1, /** 27 Buffer exhausted in mid frame */
- b_underrun:1, /** 28 Transmit underrun */
- b_error:1, /** 29 Retry limit exceeded, error detected */
- b_wrap:1, /** 30 Marks last descriptor in TD list */
- b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
- } bm;
- } status;
-} gmac_tx_descriptor_t;
-
-COMPILER_PACK_RESET()
-
-/**
- * \brief Input parameters when initializing the gmac module mode.
- */
-typedef struct gmac_options {
- /* Enable/Disable CopyAllFrame */
- uint8_t uc_copy_all_frame;
- /* Enable/Disable NoBroadCast */
- uint8_t uc_no_boardcast;
- /* MAC address */
- uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
-} gmac_options_t;
-
-/** RX callback */
-typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status);
-/** Wakeup callback */
-typedef void (*gmac_dev_wakeup_cb_t) (void);
-
-/**
- * GMAC driver structure.
- */
-typedef struct gmac_device {
-
- /** Pointer to HW register base */
- Gmac *p_hw;
- /**
- * Pointer to allocated TX buffer.
- * Section 3.6 of AMBA 2.0 spec states that burst should not cross
- * 1K Boundaries.
- * Receive buffer manager writes are burst of 2 words => 3 lsb bits
- * of the address shall be set to 0.
- */
- uint8_t *p_tx_buffer;
- /** Pointer to allocated RX buffer */
- uint8_t *p_rx_buffer;
- /** Pointer to Rx TDs (must be 8-byte aligned) */
- gmac_rx_descriptor_t *p_rx_dscr;
- /** Pointer to Tx TDs (must be 8-byte aligned) */
- gmac_tx_descriptor_t *p_tx_dscr;
- /** Optional callback to be invoked once a frame has been received */
- gmac_dev_tx_cb_t func_rx_cb;
-#if( GMAC_USES_WAKEUP_CALLBACK )
- /** Optional callback to be invoked once several TDs have been released */
- gmac_dev_wakeup_cb_t func_wakeup_cb;
-#endif
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /** Optional callback list to be invoked once TD has been processed */
- gmac_dev_tx_cb_t *func_tx_cb_list;
-#endif
- /** RX TD list size */
- uint32_t ul_rx_list_size;
- /** RX index for current processing TD */
- uint32_t ul_rx_idx;
- /** TX TD list size */
- uint32_t ul_tx_list_size;
- /** Circular buffer head pointer by upper layer (buffer to be sent) */
- int32_t l_tx_head;
- /** Circular buffer tail pointer incremented by handlers (buffer sent) */
- int32_t l_tx_tail;
-
- /** Number of free TD before wakeup callback is invoked */
- uint32_t uc_wakeup_threshold;
-} gmac_device_t;
-
-/**
- * \brief Write network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_ncr Network control value.
- */
-static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
-{
- p_gmac->GMAC_NCR = ul_ncr;
-}
-
-/**
- * \brief Get network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-
-static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCR;
-}
-
-/**
- * \brief Enable/Disable GMAC receive.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC transmit.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC transmit, else to enable it.
- */
-static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC management.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC management, else to enable it.
- */
-static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
- }
-}
-
-/**
- * \brief Clear all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_clear_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
-}
-
-/**
- * \brief Increase all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_increase_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
-}
-
-/**
- * \brief Enable/Disable statistics registers writing.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
- */
-static inline void gmac_enable_statistics_write(Gmac* p_gmac,
- uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
- }
-}
-
-/**
- * \brief In half-duplex mode, forces collisions on all received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the back pressure, else to enable it.
- */
-static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_BP;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
- }
-}
-
-/**
- * \brief Start transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_start_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
-}
-
-/**
- * \brief Halt transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_halt_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
-}
-
-/**
- * \brief Transmit pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
-}
-
-/**
- * \brief Transmit zero quantum pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
-}
-
-/**
- * \brief Read snapshot.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_read_snapshot(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
-}
-
-/**
- * \brief Store receivetime stamp to memory.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to normal operation, else to enable the store.
- */
-static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
- }
-}
-
-/**
- * \brief Enable PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to set the reception, 0 to disable.
- */
-static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
- }
-}
-
-/**
- * \brief Transmit PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
-}
-
-/**
- * \brief Flush next packet.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_flush_next_packet(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
-}
-
-/**
- * \brief Set up network configuration register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_cfg Network configuration value.
- */
-static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_NCFGR = ul_cfg;
-}
-
-/**
- * \brief Get network configuration.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network configuration.
- */
-static inline uint32_t gmac_get_configure(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCFGR;
-}
-
-
-/* Get and set DMA Configuration Register */
-static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_DCFGR = ul_cfg;
-}
-
-static inline uint32_t gmac_get_dma(Gmac* p_gmac)
-{
- return p_gmac->GMAC_DCFGR;
-}
-
-/**
- * \brief Set speed.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
- */
-static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
-{
- if (uc_speed) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
- }
-}
-
-/**
- * \brief Enable/Disable Full-Duplex mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
- */
-static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
- }
-}
-
-/**
- * \brief Enable/Disable Copy(Receive) All Valid Frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable copying all valid frames, else to enable it.
- */
-static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
- }
-}
-
-/**
- * \brief Enable/Disable jumbo frames (up to 10240 bytes).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the jumbo frames, else to enable it.
- */
-static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
- }
-}
-
-/**
- * \brief Disable/Enable broadcast receiving.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to disable the broadcast, else to enable it.
- */
-static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
- }
-}
-
-/**
- * \brief Enable/Disable multicast hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the multicast hash, else to enable it.
- */
-static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
- }
-}
-
-/**
- * \brief Enable/Disable big frames (over 1518, up to 1536).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable big frames else to enable it.
- */
-static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
- }
-}
-
-/**
- * \brief Set MDC clock divider.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_mck GMAC MCK.
- *
- * \return GMAC_OK if successfully.
- */
-static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
-{
- uint32_t ul_clk;
-
- if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
- return GMAC_INVALID;
- } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_96;
- } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_64;
- } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_48;
- } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_32;
- } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_16;
- } else {
- ul_clk = GMAC_NCFGR_CLK_MCK_8;
- }
- ;
- p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
- return GMAC_OK;
-}
-
-/**
- * \brief Enable/Disable retry test.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
- }
-}
-
-/**
- * \brief Enable/Disable pause (when a valid pause frame is received).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable pause frame, else to enable it.
- */
-static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
- }
-}
-
-/**
- * \brief Set receive buffer offset to 0 ~ 3.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
-{
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
-}
-
-/**
- * \brief Enable/Disable receive length field checking.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable receive length field checking, else to enable it.
- */
-static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
- }
-}
-
-/**
- * \brief Enable/Disable discarding FCS field of received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
- */
-static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
- }
-}
-
-
-/**
- * \brief Enable/Disable frames to be received in half-duplex mode
- * while transmitting.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
- */
-static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
- }
-}
-
-/**
- * \brief Enable/Disable ignore RX FCS.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
- */
-static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
- }
-}
-
-/**
- * \brief Get Network Status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network status.
- */
-static inline uint32_t gmac_get_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NSR;
-}
-
-/**
- * \brief Get MDIO IN pin status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return MDIO IN pin status.
- */
-static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
-}
-
-/**
- * \brief Check if PHY is idle.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return 1 if PHY is idle.
- */
-static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
-}
-
-/**
- * \brief Return transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Transmit status.
- */
-static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TSR;
-}
-
-/**
- * \brief Clear transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Transmit status.
- */
-static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_TSR = ul_status;
-}
-
-/**
- * \brief Return receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RSR;
-}
-
-/**
- * \brief Clear receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Receive status.
- */
-static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_RSR = ul_status;
-}
-
-/**
- * \brief Set Rx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Rx queue address.
- */
-static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Rx Queue Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RBQB;
-}
-
-/**
- * \brief Set Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Tx queue address.
- */
-static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TBQB;
-}
-
-/**
- * \brief Enable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be enabled.
- */
-static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IER = ul_source;
-}
-
-/**
- * \brief Disable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be disabled.
- */
-static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IDR = ul_source;
-}
-
-/**
- * \brief Return interrupt status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt status.
- */
-static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_ISR;
-}
-
-/**
- * \brief Return interrupt mask.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt mask.
- */
-static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
-{
- return p_gmac->GMAC_IMR;
-}
-
-/**
- * \brief Execute PHY maintenance command.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_reg_addr Register address.
- * \param uc_rw 1 to Read, 0 to write.
- * \param us_data Data to be performed, write only.
- */
-static inline void gmac_maintain_phy(Gmac* p_gmac,
- uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
- uint16_t us_data)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Write maintain register */
- p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
- | GMAC_MAN_CLTTO
- | GMAC_MAN_PHYA(uc_phy_addr)
- | GMAC_MAN_REGA(uc_reg_addr)
- | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
- | GMAC_MAN_DATA(us_data);
-}
-
-/**
- * \brief Get PHY maintenance data returned.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Get PHY data.
- */
-static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Return data */
- return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
-}
-
-/**
- * \brief Set Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_hash_top Hash top.
- * \param ul_hash_bottom Hash bottom.
- */
-static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
- uint32_t ul_hash_bottom)
-{
- p_gmac->GMAC_HRB = ul_hash_bottom;
- p_gmac->GMAC_HRT = ul_hash_top;
-}
-
-/**
- * \brief Set 64 bits Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ull_hash 64 bits hash value.
- */
-static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
-{
- p_gmac->GMAC_HRB = (uint32_t) ull_hash;
- p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
-}
-
-/**
- * \brief Set MAC Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param p_mac_addr GMAC address.
- */
-static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
- uint8_t* p_mac_addr)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
- | (p_mac_addr[2] << 16)
- | (p_mac_addr[1] << 8)
- | (p_mac_addr[0]);
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
- | (p_mac_addr[4]);
-}
-
-/**
- * \brief Set MAC Address via 2 dword.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ul_mac_top GMAC top address.
- * \param ul_mac_bottom GMAC bottom address.
- */
-static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
- uint32_t ul_mac_top, uint32_t ul_mac_bottom)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
-}
-
-/**
- * \brief Set MAC Address via int64.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ull_mac 64-bit GMAC address.
- */
-static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
- uint64_t ull_mac)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
-}
-
-/**
- * \brief Select media independent interface mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param mode Media independent interface mode.
- */
-static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
-{
- switch (mode) {
- case GMAC_PHY_MII:
- case GMAC_PHY_RMII:
- p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
- break;
-
- default:
- p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
- break;
- }
-}
-
-uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
- uint32_t* p_value);
-uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
- uint8_t uc_address, uint32_t ul_value);
-void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_options_t* p_opt);
-uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
- uint32_t ul_frame_size, uint32_t* p_rcv_size);
-uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
- uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
-uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
-void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_tx_cb_t func_rx_cb);
-uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
-void gmac_dev_reset(gmac_device_t* p_gmac_dev);
-void gmac_handler(gmac_device_t* p_gmac_dev);
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \page gmac_quickstart Quickstart guide for GMAC driver.
- *
- * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
- * with step-by-step instructions on how to configure and use the driver in a
- * selection of use cases.
- *
- * The use cases contain several code fragments. The code fragments in the
- * steps for setup can be copied into a custom initialization function, while
- * the steps for usage can be copied into, e.g., the main application function.
- *
- * \section gmac_basic_use_case Basic use case
- * In the basic use case, the GMAC driver are configured for:
- * - PHY component KSZ8051MNL is used
- * - GMAC uses MII mode
- * - The number of receive buffer is 16
- * - The number of transfer buffer is 8
- * - MAC address is set to 00-04-25-1c-a0-02
- * - IP address is set to 192.168.0.2
- * - IP address is set to 192.168.0.2
- * - Gateway is set to 192.168.0.1
- * - Network mask is 255.255.255.0
- * - PHY operation max retry count is 1000000
- * - GMAC is configured to not support copy all frame and support broadcast
- * - The data will be read from the ethernet
- *
- * \section gmac_basic_use_case_setup Setup steps
- *
- * \subsection gmac_basic_use_case_setup_prereq Prerequisites
- * -# \ref sysclk_group "System Clock Management (sysclock)"
- * -# \ref pmc_group "Power Management Controller (pmc)"
- * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
- *
- * \subsection gmac_basic_use_case_setup_code Example code
- * Content of conf_eth.h
- * \code
- * #define GMAC_RX_BUFFERS 16
- * #define GMAC_TX_BUFFERS 8
- * #define MAC_PHY_RETRY_MAX 1000000
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * #define ETH_PHY_MODE ETH_PHY_MODE
- * \endcode
- *
- * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
- * to trace the actual size of the data received.
- * \code
- * static gmac_device_t gs_gmac_dev;
- * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
- *
- * uint32_t ul_frm_size;
- * \endcode
- *
- * Add to application C-file:
- * \code
- * void gmac_init(void)
- * {
- * sysclk_init();
- *
- * board_init();
- *
- * pmc_enable_periph_clk(ID_GMAC);
- *
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- *
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- *
- * NVIC_EnableIRQ(GMAC_IRQn);
- *
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- *
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- *
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \subsection gmac_basic_use_case_setup_flow Workflow
- * - Ensure that conf_eth.h is present and contains the
- * following configuration symbol. This configuration file is used
- * by the driver and should not be included by the application.
- * -# Define the receiving buffer size used in the internal GMAC driver.
- * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
- * If it was supposed receiving a large number of frame, the
- * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
- * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
- * (2048/128)=16, and as there are additional frames coming, a preferred
- * number is 24 depending on a normal Ethernet throughput.
- * - \code
- * #define GMAC_RX_BUFFERS 16
- * \endcode
- * -# Define the transmitting buffer size used in the internal GMAC driver.
- * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
- * - \code
- * #define GMAC_TX_BUFFERS 8
- * \endcode
- * -# Define maximum retry time for a PHY read/write operation.
- * - \code
- * #define MAC_PHY_RETRY_MAX 1000000
- * \endcode
- * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
- * for ATMEL, application should always change this address to its' own.
- * - \code
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * \endcode
- * -# Define the IP address configration used in the application. When DHCP
- * is enabled, this configuration is not effected.
- * - \code
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * \endcode
- * -# Configure the PHY maintainance interface.
- * - \code
- * #define ETH_PHY_MODE GMAC_PHY_MII
- * \endcode
- * -# Enable the system clock:
- * - \code sysclk_init(); \endcode
- * -# Enable PIO configurations for GMAC:
- * - \code board_init(); \endcode
- * -# Enable PMC clock for GMAC:
- * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
- * -# Set the GMAC options; it's set to copy all frame and support broadcast:
- * - \code
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- * \endcode
- * -# Initialize GMAC device with the filled option:
- * - \code
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- * \endcode
- * -# Enable the interrupt service for GMAC:
- * - \code
- * NVIC_EnableIRQ(GMAC_IRQn);
- * \endcode
- * -# Initialize the PHY component:
- * - \code
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- * \endcode
- * -# The link will be established based on auto negotiation.
- * - \code
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- * \endcode
- * -# Establish the ethernet link; the network can be worked from now on:
- * - \code
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \section gmac_basic_use_case_usage Usage steps
- * \subsection gmac_basic_use_case_usage_code Example code
- * Add to, e.g., main loop in application C-file:
- * \code
- * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
- * \endcode
- *
- * \subsection gmac_basic_use_case_usage_flow Workflow
- * -# Start reading the data from the ethernet:
- * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
- */
-
-# define GMAC_STATS 0
-
-#if( GMAC_STATS != 0 )
-
- /* Here below some code to study the types and
- frequencies of GMAC interrupts. */
- #define GMAC_IDX_RXUBR 0
- #define GMAC_IDX_TUR 1
- #define GMAC_IDX_RLEX 2
- #define GMAC_IDX_TFC 3
- #define GMAC_IDX_RCOMP 4
- #define GMAC_IDX_TCOMP 5
- #define GMAC_IDX_ROVR 6
- #define GMAC_IDX_HRESP 7
- #define GMAC_IDX_PFNZ 8
- #define GMAC_IDX_PTZ 9
-
- struct SGmacStats {
- unsigned recvCount;
- unsigned rovrCount;
- unsigned bnaCount;
- unsigned sendCount;
- unsigned sovrCount;
- unsigned incompCount;
- unsigned truncCount;
-
- unsigned intStatus[10];
- };
- extern struct SGmacStats gmacStats;
-
- struct SIntPair {
- const char *name;
- unsigned mask;
- int index;
- };
-
- #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
- static const struct SIntPair intPairs[] = {
- { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
- { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
- { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
- { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
- { MK_PAIR( RCOMP ) }, /* Receive complete */
- { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
- { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
- { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
- { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
- { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
- };
-
- void gmac_show_irq_counts ();
-
-#endif
-
-#endif /* GMAC_H_INCLUDED */
+ /**
+ * \file
+ *
+ * \brief GMAC (Ethernet MAC) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef GMAC_H_INCLUDED
+#define GMAC_H_INCLUDED
+
+#include "compiler.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/** The buffer addresses written into the descriptors must be aligned, so the
+ last few bits are zero. These bits have special meaning for the GMAC
+ peripheral and cannot be used as part of the address. */
+#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
+#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
+#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
+
+#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
+#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
+#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
+#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
+#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
+#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
+#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
+#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
+#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
+#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
+#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
+#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
+#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
+#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
+#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
+#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
+#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
+
+#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
+#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
+#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
+#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
+#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
+#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
+#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
+#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
+#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
+#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
+
+/** The MAC can support frame lengths up to 1536 bytes */
+#define GMAC_FRAME_LENTGH_MAX 1536
+
+#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
+#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
+
+/** GMAC clock speed */
+#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
+#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
+#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
+#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
+#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
+#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
+
+/** GMAC maintain code default value*/
+#define GMAC_MAN_CODE_VALUE (10)
+
+/** GMAC maintain start of frame default value*/
+#define GMAC_MAN_SOF_VALUE (1)
+
+/** GMAC maintain read/write*/
+#define GMAC_MAN_RW_TYPE (2)
+
+/** GMAC maintain read only*/
+#define GMAC_MAN_READ_ONLY (1)
+
+/** GMAC address length */
+#define GMAC_ADDR_LENGTH (6)
+
+
+#define GMAC_DUPLEX_HALF 0
+#define GMAC_DUPLEX_FULL 1
+
+#define GMAC_SPEED_10M 0
+#define GMAC_SPEED_100M 1
+
+/**
+ * \brief Return codes for GMAC APIs.
+ */
+typedef enum {
+ GMAC_OK = 0, /** 0 Operation OK */
+ GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
+ GMAC_TX_BUSY, /** 2 TX in progress */
+ GMAC_RX_NULL, /** 3 No data received */
+ GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
+ GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
+ GMAC_INVALID = 0xFF, /* Invalid */
+} gmac_status_t;
+
+/**
+ * \brief Media Independent Interface (MII) type.
+ */
+typedef enum {
+ GMAC_PHY_MII = 0, /** MII mode */
+ GMAC_PHY_RMII = 1, /** Reduced MII mode */
+ GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
+} gmac_mii_mode_t;
+
+/** Receive buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_rx_descriptor {
+ union gmac_rx_addr {
+ uint32_t val;
+ struct gmac_rx_addr_bm {
+ uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
+ b_wrap:1, /**< Marks last descriptor in receive buffer */
+ addr_dw:30; /**< Address in number of DW */
+ } bm;
+ } addr; /**< Address, Wrap & Ownership */
+ union gmac_rx_status {
+ uint32_t val;
+ struct gmac_rx_status_bm {
+ uint32_t len:13, /** 0..12 Length of frame including FCS */
+ b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
+ b_sof:1, /** 14 Start of frame */
+ b_eof:1, /** 15 End of frame */
+ b_cfi:1, /** 16 Concatenation Format Indicator */
+ vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
+ b_priority_detected:1, /** 20 Priority tag detected */
+ b_vlan_detected:1, /** 21 VLAN tag detected */
+ b_type_id_match:2, /** 22..23 Type ID match */
+ b_checksumoffload:1, /** 24 Checksum offload specific function */
+ b_addrmatch:2, /** 25..26 Address register match */
+ b_ext_addr_match:1, /** 27 External address match found */
+ reserved:1, /** 28 */
+ b_uni_hash_match:1, /** 29 Unicast hash match */
+ b_multi_hash_match:1, /** 30 Multicast hash match */
+ b_boardcast_detect:1; /** 31 Global broadcast address detected */
+ } bm;
+ } status;
+} gmac_rx_descriptor_t;
+
+/** Transmit buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_tx_descriptor {
+ uint32_t addr;
+ union gmac_tx_status {
+ uint32_t val;
+ struct gmac_tx_status_bm {
+ uint32_t len:14, /** 0..13 Length of buffer */
+ reserved:1, /** 14 */
+ b_last_buffer:1, /** 15 Last buffer (in the current frame) */
+ b_no_crc:1, /** 16 No CRC */
+ reserved1:3, /** 17..19 */
+ b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
+ reserved2:3, /** 23..25 */
+ b_lco:1, /** 26 Late collision, transmit error detected */
+ b_exhausted:1, /** 27 Buffer exhausted in mid frame */
+ b_underrun:1, /** 28 Transmit underrun */
+ b_error:1, /** 29 Retry limit exceeded, error detected */
+ b_wrap:1, /** 30 Marks last descriptor in TD list */
+ b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
+ } bm;
+ } status;
+} gmac_tx_descriptor_t;
+
+COMPILER_PACK_RESET()
+
+/**
+ * \brief Input parameters when initializing the gmac module mode.
+ */
+typedef struct gmac_options {
+ /* Enable/Disable CopyAllFrame */
+ uint8_t uc_copy_all_frame;
+ /* Enable/Disable NoBroadCast */
+ uint8_t uc_no_boardcast;
+ /* MAC address */
+ uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
+} gmac_options_t;
+
+/** RX callback */
+typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status);
+/** Wakeup callback */
+typedef void (*gmac_dev_wakeup_cb_t) (void);
+
+/**
+ * GMAC driver structure.
+ */
+typedef struct gmac_device {
+
+ /** Pointer to HW register base */
+ Gmac *p_hw;
+ /**
+ * Pointer to allocated TX buffer.
+ * Section 3.6 of AMBA 2.0 spec states that burst should not cross
+ * 1K Boundaries.
+ * Receive buffer manager writes are burst of 2 words => 3 lsb bits
+ * of the address shall be set to 0.
+ */
+ uint8_t *p_tx_buffer;
+ /** Pointer to allocated RX buffer */
+ uint8_t *p_rx_buffer;
+ /** Pointer to Rx TDs (must be 8-byte aligned) */
+ gmac_rx_descriptor_t *p_rx_dscr;
+ /** Pointer to Tx TDs (must be 8-byte aligned) */
+ gmac_tx_descriptor_t *p_tx_dscr;
+ /** Optional callback to be invoked once a frame has been received */
+ gmac_dev_tx_cb_t func_rx_cb;
+#if( GMAC_USES_WAKEUP_CALLBACK )
+ /** Optional callback to be invoked once several TDs have been released */
+ gmac_dev_wakeup_cb_t func_wakeup_cb;
+#endif
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /** Optional callback list to be invoked once TD has been processed */
+ gmac_dev_tx_cb_t *func_tx_cb_list;
+#endif
+ /** RX TD list size */
+ uint32_t ul_rx_list_size;
+ /** RX index for current processing TD */
+ uint32_t ul_rx_idx;
+ /** TX TD list size */
+ uint32_t ul_tx_list_size;
+ /** Circular buffer head pointer by upper layer (buffer to be sent) */
+ int32_t l_tx_head;
+ /** Circular buffer tail pointer incremented by handlers (buffer sent) */
+ int32_t l_tx_tail;
+
+ /** Number of free TD before wakeup callback is invoked */
+ uint32_t uc_wakeup_threshold;
+} gmac_device_t;
+
+/**
+ * \brief Write network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_ncr Network control value.
+ */
+static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
+{
+ p_gmac->GMAC_NCR = ul_ncr;
+}
+
+/**
+ * \brief Get network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+
+static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCR;
+}
+
+/**
+ * \brief Enable/Disable GMAC receive.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC transmit.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC transmit, else to enable it.
+ */
+static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC management.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC management, else to enable it.
+ */
+static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
+ }
+}
+
+/**
+ * \brief Clear all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_clear_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
+}
+
+/**
+ * \brief Increase all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_increase_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
+}
+
+/**
+ * \brief Enable/Disable statistics registers writing.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
+ */
+static inline void gmac_enable_statistics_write(Gmac* p_gmac,
+ uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
+ }
+}
+
+/**
+ * \brief In half-duplex mode, forces collisions on all received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the back pressure, else to enable it.
+ */
+static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_BP;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
+ }
+}
+
+/**
+ * \brief Start transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_start_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
+}
+
+/**
+ * \brief Halt transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_halt_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
+}
+
+/**
+ * \brief Transmit pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
+}
+
+/**
+ * \brief Transmit zero quantum pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
+}
+
+/**
+ * \brief Read snapshot.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_read_snapshot(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
+}
+
+/**
+ * \brief Store receivetime stamp to memory.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to normal operation, else to enable the store.
+ */
+static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
+ }
+}
+
+/**
+ * \brief Enable PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to set the reception, 0 to disable.
+ */
+static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
+ }
+}
+
+/**
+ * \brief Transmit PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
+}
+
+/**
+ * \brief Flush next packet.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_flush_next_packet(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
+}
+
+/**
+ * \brief Set up network configuration register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_cfg Network configuration value.
+ */
+static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_NCFGR = ul_cfg;
+}
+
+/**
+ * \brief Get network configuration.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network configuration.
+ */
+static inline uint32_t gmac_get_configure(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCFGR;
+}
+
+
+/* Get and set DMA Configuration Register */
+static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_DCFGR = ul_cfg;
+}
+
+static inline uint32_t gmac_get_dma(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_DCFGR;
+}
+
+/**
+ * \brief Set speed.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
+ */
+static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
+{
+ if (uc_speed) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Full-Duplex mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
+ */
+static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Copy(Receive) All Valid Frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable copying all valid frames, else to enable it.
+ */
+static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
+ }
+}
+
+/**
+ * \brief Enable/Disable jumbo frames (up to 10240 bytes).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the jumbo frames, else to enable it.
+ */
+static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
+ }
+}
+
+/**
+ * \brief Disable/Enable broadcast receiving.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to disable the broadcast, else to enable it.
+ */
+static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
+ }
+}
+
+/**
+ * \brief Enable/Disable multicast hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the multicast hash, else to enable it.
+ */
+static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable big frames (over 1518, up to 1536).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable big frames else to enable it.
+ */
+static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
+ }
+}
+
+/**
+ * \brief Set MDC clock divider.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_mck GMAC MCK.
+ *
+ * \return GMAC_OK if successfully.
+ */
+static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
+{
+ uint32_t ul_clk;
+
+ if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
+ return GMAC_INVALID;
+ } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_96;
+ } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_64;
+ } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_48;
+ } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_32;
+ } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_16;
+ } else {
+ ul_clk = GMAC_NCFGR_CLK_MCK_8;
+ }
+ ;
+ p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
+ return GMAC_OK;
+}
+
+/**
+ * \brief Enable/Disable retry test.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
+ }
+}
+
+/**
+ * \brief Enable/Disable pause (when a valid pause frame is received).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable pause frame, else to enable it.
+ */
+static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
+ }
+}
+
+/**
+ * \brief Set receive buffer offset to 0 ~ 3.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
+{
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
+}
+
+/**
+ * \brief Enable/Disable receive length field checking.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable receive length field checking, else to enable it.
+ */
+static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
+ }
+}
+
+/**
+ * \brief Enable/Disable discarding FCS field of received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
+ */
+static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
+ }
+}
+
+
+/**
+ * \brief Enable/Disable frames to be received in half-duplex mode
+ * while transmitting.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
+ */
+static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
+ }
+}
+
+/**
+ * \brief Enable/Disable ignore RX FCS.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
+ */
+static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
+ }
+}
+
+/**
+ * \brief Get Network Status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network status.
+ */
+static inline uint32_t gmac_get_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NSR;
+}
+
+/**
+ * \brief Get MDIO IN pin status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return MDIO IN pin status.
+ */
+static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
+}
+
+/**
+ * \brief Check if PHY is idle.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return 1 if PHY is idle.
+ */
+static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
+}
+
+/**
+ * \brief Return transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Transmit status.
+ */
+static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TSR;
+}
+
+/**
+ * \brief Clear transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Transmit status.
+ */
+static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_TSR = ul_status;
+}
+
+/**
+ * \brief Return receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RSR;
+}
+
+/**
+ * \brief Clear receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Receive status.
+ */
+static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_RSR = ul_status;
+}
+
+/**
+ * \brief Set Rx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Rx queue address.
+ */
+static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Rx Queue Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RBQB;
+}
+
+/**
+ * \brief Set Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Tx queue address.
+ */
+static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TBQB;
+}
+
+/**
+ * \brief Enable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be enabled.
+ */
+static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IER = ul_source;
+}
+
+/**
+ * \brief Disable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be disabled.
+ */
+static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IDR = ul_source;
+}
+
+/**
+ * \brief Return interrupt status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt status.
+ */
+static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_ISR;
+}
+
+/**
+ * \brief Return interrupt mask.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt mask.
+ */
+static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_IMR;
+}
+
+/**
+ * \brief Execute PHY maintenance command.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_reg_addr Register address.
+ * \param uc_rw 1 to Read, 0 to write.
+ * \param us_data Data to be performed, write only.
+ */
+static inline void gmac_maintain_phy(Gmac* p_gmac,
+ uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
+ uint16_t us_data)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Write maintain register */
+ p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
+ | GMAC_MAN_CLTTO
+ | GMAC_MAN_PHYA(uc_phy_addr)
+ | GMAC_MAN_REGA(uc_reg_addr)
+ | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
+ | GMAC_MAN_DATA(us_data);
+}
+
+/**
+ * \brief Get PHY maintenance data returned.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Get PHY data.
+ */
+static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Return data */
+ return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
+}
+
+/**
+ * \brief Set Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_hash_top Hash top.
+ * \param ul_hash_bottom Hash bottom.
+ */
+static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
+ uint32_t ul_hash_bottom)
+{
+ p_gmac->GMAC_HRB = ul_hash_bottom;
+ p_gmac->GMAC_HRT = ul_hash_top;
+}
+
+/**
+ * \brief Set 64 bits Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ull_hash 64 bits hash value.
+ */
+static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
+{
+ p_gmac->GMAC_HRB = (uint32_t) ull_hash;
+ p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
+}
+
+/**
+ * \brief Set MAC Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param p_mac_addr GMAC address.
+ */
+static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
+ uint8_t* p_mac_addr)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
+ | (p_mac_addr[2] << 16)
+ | (p_mac_addr[1] << 8)
+ | (p_mac_addr[0]);
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
+ | (p_mac_addr[4]);
+}
+
+/**
+ * \brief Set MAC Address via 2 dword.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ul_mac_top GMAC top address.
+ * \param ul_mac_bottom GMAC bottom address.
+ */
+static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
+ uint32_t ul_mac_top, uint32_t ul_mac_bottom)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
+}
+
+/**
+ * \brief Set MAC Address via int64.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ull_mac 64-bit GMAC address.
+ */
+static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
+ uint64_t ull_mac)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
+}
+
+/**
+ * \brief Select media independent interface mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param mode Media independent interface mode.
+ */
+static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
+{
+ switch (mode) {
+ case GMAC_PHY_MII:
+ case GMAC_PHY_RMII:
+ p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
+ break;
+
+ default:
+ p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
+ break;
+ }
+}
+
+uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
+ uint32_t* p_value);
+uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
+ uint8_t uc_address, uint32_t ul_value);
+void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_options_t* p_opt);
+uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
+ uint32_t ul_frame_size, uint32_t* p_rcv_size);
+uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
+ uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
+uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
+void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_tx_cb_t func_rx_cb);
+uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
+void gmac_dev_reset(gmac_device_t* p_gmac_dev);
+void gmac_handler(gmac_device_t* p_gmac_dev);
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \page gmac_quickstart Quickstart guide for GMAC driver.
+ *
+ * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
+ * with step-by-step instructions on how to configure and use the driver in a
+ * selection of use cases.
+ *
+ * The use cases contain several code fragments. The code fragments in the
+ * steps for setup can be copied into a custom initialization function, while
+ * the steps for usage can be copied into, e.g., the main application function.
+ *
+ * \section gmac_basic_use_case Basic use case
+ * In the basic use case, the GMAC driver are configured for:
+ * - PHY component KSZ8051MNL is used
+ * - GMAC uses MII mode
+ * - The number of receive buffer is 16
+ * - The number of transfer buffer is 8
+ * - MAC address is set to 00-04-25-1c-a0-02
+ * - IP address is set to 192.168.0.2
+ * - IP address is set to 192.168.0.2
+ * - Gateway is set to 192.168.0.1
+ * - Network mask is 255.255.255.0
+ * - PHY operation max retry count is 1000000
+ * - GMAC is configured to not support copy all frame and support broadcast
+ * - The data will be read from the ethernet
+ *
+ * \section gmac_basic_use_case_setup Setup steps
+ *
+ * \subsection gmac_basic_use_case_setup_prereq Prerequisites
+ * -# \ref sysclk_group "System Clock Management (sysclock)"
+ * -# \ref pmc_group "Power Management Controller (pmc)"
+ * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
+ *
+ * \subsection gmac_basic_use_case_setup_code Example code
+ * Content of conf_eth.h
+ * \code
+ * #define GMAC_RX_BUFFERS 16
+ * #define GMAC_TX_BUFFERS 8
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * #define ETH_PHY_MODE ETH_PHY_MODE
+ * \endcode
+ *
+ * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
+ * to trace the actual size of the data received.
+ * \code
+ * static gmac_device_t gs_gmac_dev;
+ * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
+ *
+ * uint32_t ul_frm_size;
+ * \endcode
+ *
+ * Add to application C-file:
+ * \code
+ * void gmac_init(void)
+ * {
+ * sysclk_init();
+ *
+ * board_init();
+ *
+ * pmc_enable_periph_clk(ID_GMAC);
+ *
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ *
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ *
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ *
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ *
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ *
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_setup_flow Workflow
+ * - Ensure that conf_eth.h is present and contains the
+ * following configuration symbol. This configuration file is used
+ * by the driver and should not be included by the application.
+ * -# Define the receiving buffer size used in the internal GMAC driver.
+ * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
+ * If it was supposed receiving a large number of frame, the
+ * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
+ * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
+ * (2048/128)=16, and as there are additional frames coming, a preferred
+ * number is 24 depending on a normal Ethernet throughput.
+ * - \code
+ * #define GMAC_RX_BUFFERS 16
+ * \endcode
+ * -# Define the transmitting buffer size used in the internal GMAC driver.
+ * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
+ * - \code
+ * #define GMAC_TX_BUFFERS 8
+ * \endcode
+ * -# Define maximum retry time for a PHY read/write operation.
+ * - \code
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * \endcode
+ * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
+ * for ATMEL, application should always change this address to its' own.
+ * - \code
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * \endcode
+ * -# Define the IP address configration used in the application. When DHCP
+ * is enabled, this configuration is not effected.
+ * - \code
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * \endcode
+ * -# Configure the PHY maintainance interface.
+ * - \code
+ * #define ETH_PHY_MODE GMAC_PHY_MII
+ * \endcode
+ * -# Enable the system clock:
+ * - \code sysclk_init(); \endcode
+ * -# Enable PIO configurations for GMAC:
+ * - \code board_init(); \endcode
+ * -# Enable PMC clock for GMAC:
+ * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
+ * -# Set the GMAC options; it's set to copy all frame and support broadcast:
+ * - \code
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ * \endcode
+ * -# Initialize GMAC device with the filled option:
+ * - \code
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ * \endcode
+ * -# Enable the interrupt service for GMAC:
+ * - \code
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ * \endcode
+ * -# Initialize the PHY component:
+ * - \code
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ * \endcode
+ * -# The link will be established based on auto negotiation.
+ * - \code
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ * \endcode
+ * -# Establish the ethernet link; the network can be worked from now on:
+ * - \code
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \section gmac_basic_use_case_usage Usage steps
+ * \subsection gmac_basic_use_case_usage_code Example code
+ * Add to, e.g., main loop in application C-file:
+ * \code
+ * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_usage_flow Workflow
+ * -# Start reading the data from the ethernet:
+ * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
+ */
+
+# define GMAC_STATS 0
+
+#if( GMAC_STATS != 0 )
+
+ /* Here below some code to study the types and
+ frequencies of GMAC interrupts. */
+ #define GMAC_IDX_RXUBR 0
+ #define GMAC_IDX_TUR 1
+ #define GMAC_IDX_RLEX 2
+ #define GMAC_IDX_TFC 3
+ #define GMAC_IDX_RCOMP 4
+ #define GMAC_IDX_TCOMP 5
+ #define GMAC_IDX_ROVR 6
+ #define GMAC_IDX_HRESP 7
+ #define GMAC_IDX_PFNZ 8
+ #define GMAC_IDX_PTZ 9
+
+ struct SGmacStats {
+ unsigned recvCount;
+ unsigned rovrCount;
+ unsigned bnaCount;
+ unsigned sendCount;
+ unsigned sovrCount;
+ unsigned incompCount;
+ unsigned truncCount;
+
+ unsigned intStatus[10];
+ };
+ extern struct SGmacStats gmacStats;
+
+ struct SIntPair {
+ const char *name;
+ unsigned mask;
+ int index;
+ };
+
+ #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
+ static const struct SIntPair intPairs[] = {
+ { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
+ { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
+ { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
+ { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
+ { MK_PAIR( RCOMP ) }, /* Receive complete */
+ { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
+ { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
+ { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
+ { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
+ { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
+ };
+
+ void gmac_show_irq_counts ();
+
+#endif
+
+#endif /* GMAC_H_INCLUDED */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h
index 24d806d94..dd29dfe78 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ATSAM4E/instance/gmac.h
@@ -1,1349 +1,1349 @@
- /**
- * \file
- *
- * \brief GMAC (Ethernet MAC) driver for SAM.
- *
- * Copyright (c) 2013 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-
-#ifndef GMAC_H_INCLUDED
-#define GMAC_H_INCLUDED
-
-#include "compiler.h"
-#include "component/gmac.h"
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-extern "C" {
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/** The buffer addresses written into the descriptors must be aligned, so the
- last few bits are zero. These bits have special meaning for the GMAC
- peripheral and cannot be used as part of the address. */
-#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
-#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
-#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
-
-#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
-#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
-#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
-#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
-#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
-#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
-#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
-#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
-#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
-#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
-#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
-#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
-#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
-#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
-#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
-#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
-#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
-
-#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
-#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
-#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
-#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
-#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
-#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
-#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
-#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
-#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
-#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
-
-/** The MAC can support frame lengths up to 1536 bytes */
-#define GMAC_FRAME_LENTGH_MAX 1536
-
-#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
-#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
-
-/** GMAC clock speed */
-#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
-#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
-#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
-#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
-#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
-#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
-
-/** GMAC maintain code default value*/
-#define GMAC_MAN_CODE_VALUE (10)
-
-/** GMAC maintain start of frame default value*/
-#define GMAC_MAN_SOF_VALUE (1)
-
-/** GMAC maintain read/write*/
-#define GMAC_MAN_RW_TYPE (2)
-
-/** GMAC maintain read only*/
-#define GMAC_MAN_READ_ONLY (1)
-
-/** GMAC address length */
-#define GMAC_ADDR_LENGTH (6)
-
-
-#define GMAC_DUPLEX_HALF 0
-#define GMAC_DUPLEX_FULL 1
-
-#define GMAC_SPEED_10M 0
-#define GMAC_SPEED_100M 1
-
-/**
- * \brief Return codes for GMAC APIs.
- */
-typedef enum {
- GMAC_OK = 0, /** 0 Operation OK */
- GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
- GMAC_TX_BUSY, /** 2 TX in progress */
- GMAC_RX_NULL, /** 3 No data received */
- GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
- GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
- GMAC_INVALID = 0xFF, /* Invalid */
-} gmac_status_t;
-
-/**
- * \brief Media Independent Interface (MII) type.
- */
-typedef enum {
- GMAC_PHY_MII = 0, /** MII mode */
- GMAC_PHY_RMII = 1, /** Reduced MII mode */
- GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
-} gmac_mii_mode_t;
-
-/** Receive buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_rx_descriptor {
- union gmac_rx_addr {
- uint32_t val;
- struct gmac_rx_addr_bm {
- uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
- b_wrap:1, /**< Marks last descriptor in receive buffer */
- addr_dw:30; /**< Address in number of DW */
- } bm;
- } addr; /**< Address, Wrap & Ownership */
- union gmac_rx_status {
- uint32_t val;
- struct gmac_rx_status_bm {
- uint32_t len:13, /** 0..12 Length of frame including FCS */
- b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
- b_sof:1, /** 14 Start of frame */
- b_eof:1, /** 15 End of frame */
- b_cfi:1, /** 16 Concatenation Format Indicator */
- vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
- b_priority_detected:1, /** 20 Priority tag detected */
- b_vlan_detected:1, /** 21 VLAN tag detected */
- b_type_id_match:2, /** 22..23 Type ID match */
- b_checksumoffload:1, /** 24 Checksum offload specific function */
- b_addrmatch:2, /** 25..26 Address register match */
- b_ext_addr_match:1, /** 27 External address match found */
- reserved:1, /** 28 */
- b_uni_hash_match:1, /** 29 Unicast hash match */
- b_multi_hash_match:1, /** 30 Multicast hash match */
- b_boardcast_detect:1; /** 31 Global broadcast address detected */
- } bm;
- } status;
-} gmac_rx_descriptor_t;
-
-/** Transmit buffer descriptor struct */
-COMPILER_PACK_SET(8)
-typedef struct gmac_tx_descriptor {
- uint32_t addr;
- union gmac_tx_status {
- uint32_t val;
- struct gmac_tx_status_bm {
- uint32_t len:14, /** 0..13 Length of buffer */
- reserved:1, /** 14 */
- b_last_buffer:1, /** 15 Last buffer (in the current frame) */
- b_no_crc:1, /** 16 No CRC */
- reserved1:3, /** 17..19 */
- b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
- reserved2:3, /** 23..25 */
- b_lco:1, /** 26 Late collision, transmit error detected */
- b_exhausted:1, /** 27 Buffer exhausted in mid frame */
- b_underrun:1, /** 28 Transmit underrun */
- b_error:1, /** 29 Retry limit exceeded, error detected */
- b_wrap:1, /** 30 Marks last descriptor in TD list */
- b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
- } bm;
- } status;
-} gmac_tx_descriptor_t;
-
-COMPILER_PACK_RESET()
-
-/**
- * \brief Input parameters when initializing the gmac module mode.
- */
-typedef struct gmac_options {
- /* Enable/Disable CopyAllFrame */
- uint8_t uc_copy_all_frame;
- /* Enable/Disable NoBroadCast */
- uint8_t uc_no_boardcast;
- /* MAC address */
- uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
-} gmac_options_t;
-
-/** TX callback */
-typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status, uint8_t *puc_buffer);
-/** RX callback */
-typedef void (*gmac_dev_rx_cb_t) (uint32_t ul_status);
-/** Wakeup callback */
-typedef void (*gmac_dev_wakeup_cb_t) (void);
-
-/**
- * GMAC driver structure.
- */
-typedef struct gmac_device {
-
- /** Pointer to HW register base */
- Gmac *p_hw;
- /**
- * Pointer to allocated TX buffer.
- * Section 3.6 of AMBA 2.0 spec states that burst should not cross
- * 1K Boundaries.
- * Receive buffer manager writes are burst of 2 words => 3 lsb bits
- * of the address shall be set to 0.
- */
- uint8_t *p_tx_buffer;
- /** Pointer to allocated RX buffer */
- uint8_t *p_rx_buffer;
- /** Pointer to Rx TDs (must be 8-byte aligned) */
- gmac_rx_descriptor_t *p_rx_dscr;
- /** Pointer to Tx TDs (must be 8-byte aligned) */
- gmac_tx_descriptor_t *p_tx_dscr;
- /** Optional callback to be invoked once a frame has been received */
- gmac_dev_rx_cb_t func_rx_cb;
-#if( GMAC_USES_WAKEUP_CALLBACK )
- /** Optional callback to be invoked once several TDs have been released */
- gmac_dev_wakeup_cb_t func_wakeup_cb;
-#endif
-#if( GMAC_USES_TX_CALLBACK != 0 )
- /** Optional callback list to be invoked once TD has been processed */
- gmac_dev_tx_cb_t *func_tx_cb_list;
-#endif
- /** RX TD list size */
- uint32_t ul_rx_list_size;
- /** RX index for current processing TD */
- uint32_t ul_rx_idx;
- /** TX TD list size */
- uint32_t ul_tx_list_size;
- /** Circular buffer head pointer by upper layer (buffer to be sent) */
- int32_t l_tx_head;
- /** Circular buffer tail pointer incremented by handlers (buffer sent) */
- int32_t l_tx_tail;
-
- /** Number of free TD before wakeup callback is invoked */
- uint32_t uc_wakeup_threshold;
-} gmac_device_t;
-
-/**
- * \brief Write network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_ncr Network control value.
- */
-static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
-{
- p_gmac->GMAC_NCR = ul_ncr;
-}
-
-/**
- * \brief Get network control value.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-
-static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCR;
-}
-
-/**
- * \brief Enable/Disable GMAC receive.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC transmit.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC transmit, else to enable it.
- */
-static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
- }
-}
-
-/**
- * \brief Enable/Disable GMAC management.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable GMAC management, else to enable it.
- */
-static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
- }
-}
-
-/**
- * \brief Clear all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_clear_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
-}
-
-/**
- * \brief Increase all statistics registers.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_increase_statistics(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
-}
-
-/**
- * \brief Enable/Disable statistics registers writing.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
- */
-static inline void gmac_enable_statistics_write(Gmac* p_gmac,
- uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
- }
-}
-
-/**
- * \brief In half-duplex mode, forces collisions on all received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the back pressure, else to enable it.
- */
-static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_BP;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
- }
-}
-
-/**
- * \brief Start transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_start_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
-}
-
-/**
- * \brief Halt transmission.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_halt_transmission(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
-}
-
-/**
- * \brief Transmit pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
-}
-
-/**
- * \brief Transmit zero quantum pause frame.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
-}
-
-/**
- * \brief Read snapshot.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_read_snapshot(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
-}
-
-/**
- * \brief Store receivetime stamp to memory.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to normal operation, else to enable the store.
- */
-static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
- }
-}
-
-/**
- * \brief Enable PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to set the reception, 0 to disable.
- */
-static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
- } else {
- p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
- }
-}
-
-/**
- * \brief Transmit PFC priority-based pause reception.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
-}
-
-/**
- * \brief Flush next packet.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_flush_next_packet(Gmac* p_gmac)
-{
- p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
-}
-
-/**
- * \brief Set up network configuration register.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_cfg Network configuration value.
- */
-static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_NCFGR = ul_cfg;
-}
-
-/**
- * \brief Get network configuration.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network configuration.
- */
-static inline uint32_t gmac_get_configure(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NCFGR;
-}
-
-
-/* Get and set DMA Configuration Register */
-static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
-{
- p_gmac->GMAC_DCFGR = ul_cfg;
-}
-
-static inline uint32_t gmac_get_dma(Gmac* p_gmac)
-{
- return p_gmac->GMAC_DCFGR;
-}
-
-/**
- * \brief Set speed.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
- */
-static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
-{
- if (uc_speed) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
- }
-}
-
-/**
- * \brief Enable/Disable Full-Duplex mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
- */
-static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
- }
-}
-
-/**
- * \brief Enable/Disable Copy(Receive) All Valid Frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable copying all valid frames, else to enable it.
- */
-static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
- }
-}
-
-/**
- * \brief Enable/Disable jumbo frames (up to 10240 bytes).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the jumbo frames, else to enable it.
- */
-static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
- }
-}
-
-/**
- * \brief Disable/Enable broadcast receiving.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 1 to disable the broadcast, else to enable it.
- */
-static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
- }
-}
-
-/**
- * \brief Enable/Disable multicast hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the multicast hash, else to enable it.
- */
-static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
- }
-}
-
-/**
- * \brief Enable/Disable big frames (over 1518, up to 1536).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable big frames else to enable it.
- */
-static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
- }
-}
-
-/**
- * \brief Set MDC clock divider.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_mck GMAC MCK.
- *
- * \return GMAC_OK if successfully.
- */
-static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
-{
- uint32_t ul_clk;
-
- if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
- return GMAC_INVALID;
- } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_96;
- } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_64;
- } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_48;
- } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_32;
- } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
- ul_clk = GMAC_NCFGR_CLK_MCK_16;
- } else {
- ul_clk = GMAC_NCFGR_CLK_MCK_8;
- }
- ;
- p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
- return GMAC_OK;
-}
-
-/**
- * \brief Enable/Disable retry test.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
- */
-static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
- }
-}
-
-/**
- * \brief Enable/Disable pause (when a valid pause frame is received).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable pause frame, else to enable it.
- */
-static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
- }
-}
-
-/**
- * \brief Set receive buffer offset to 0 ~ 3.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
-{
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
-}
-
-/**
- * \brief Enable/Disable receive length field checking.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable receive length field checking, else to enable it.
- */
-static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
- }
-}
-
-/**
- * \brief Enable/Disable discarding FCS field of received frames.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
- */
-static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
- }
-}
-
-
-/**
- * \brief Enable/Disable frames to be received in half-duplex mode
- * while transmitting.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
- */
-static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
- }
-}
-
-/**
- * \brief Enable/Disable ignore RX FCS.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
- */
-static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
-{
- if (uc_enable) {
- p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
- } else {
- p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
- }
-}
-
-/**
- * \brief Get Network Status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Network status.
- */
-static inline uint32_t gmac_get_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_NSR;
-}
-
-/**
- * \brief Get MDIO IN pin status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return MDIO IN pin status.
- */
-static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
-}
-
-/**
- * \brief Check if PHY is idle.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return 1 if PHY is idle.
- */
-static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
-{
- return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
-}
-
-/**
- * \brief Return transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Transmit status.
- */
-static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TSR;
-}
-
-/**
- * \brief Clear transmit status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Transmit status.
- */
-static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_TSR = ul_status;
-}
-
-/**
- * \brief Return receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- */
-static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RSR;
-}
-
-/**
- * \brief Clear receive status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_status Receive status.
- */
-static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
-{
- p_gmac->GMAC_RSR = ul_status;
-}
-
-/**
- * \brief Set Rx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Rx queue address.
- */
-static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Rx Queue Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_RBQB;
-}
-
-/**
- * \brief Set Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_addr Tx queue address.
- */
-static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
-{
- p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
-}
-
-/**
- * \brief Get Tx Queue.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Rx queue address.
- */
-static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
-{
- return p_gmac->GMAC_TBQB;
-}
-
-/**
- * \brief Enable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be enabled.
- */
-static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IER = ul_source;
-}
-
-/**
- * \brief Disable interrupt(s).
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_source Interrupt source(s) to be disabled.
- */
-static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
-{
- p_gmac->GMAC_IDR = ul_source;
-}
-
-/**
- * \brief Return interrupt status.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt status.
- */
-static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
-{
- return p_gmac->GMAC_ISR;
-}
-
-/**
- * \brief Return interrupt mask.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Interrupt mask.
- */
-static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
-{
- return p_gmac->GMAC_IMR;
-}
-
-/**
- * \brief Execute PHY maintenance command.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_phy_addr PHY address.
- * \param uc_reg_addr Register address.
- * \param uc_rw 1 to Read, 0 to write.
- * \param us_data Data to be performed, write only.
- */
-static inline void gmac_maintain_phy(Gmac* p_gmac,
- uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
- uint16_t us_data)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Write maintain register */
- p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
- | GMAC_MAN_CLTTO
- | GMAC_MAN_PHYA(uc_phy_addr)
- | GMAC_MAN_REGA(uc_reg_addr)
- | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
- | GMAC_MAN_DATA(us_data);
-}
-
-/**
- * \brief Get PHY maintenance data returned.
- *
- * \param p_gmac Pointer to the GMAC instance.
- *
- * \return Get PHY data.
- */
-static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
-{
- /* Wait until bus idle */
- while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
- /* Return data */
- return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
-}
-
-/**
- * \brief Set Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ul_hash_top Hash top.
- * \param ul_hash_bottom Hash bottom.
- */
-static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
- uint32_t ul_hash_bottom)
-{
- p_gmac->GMAC_HRB = ul_hash_bottom;
- p_gmac->GMAC_HRT = ul_hash_top;
-}
-
-/**
- * \brief Set 64 bits Hash.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param ull_hash 64 bits hash value.
- */
-static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
-{
- p_gmac->GMAC_HRB = (uint32_t) ull_hash;
- p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
-}
-
-/**
- * \brief Set MAC Address.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param p_mac_addr GMAC address.
- */
-static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
- uint8_t* p_mac_addr)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
- | (p_mac_addr[2] << 16)
- | (p_mac_addr[1] << 8)
- | (p_mac_addr[0]);
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
- | (p_mac_addr[4]);
-}
-
-/**
- * \brief Set MAC Address via 2 dword.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ul_mac_top GMAC top address.
- * \param ul_mac_bottom GMAC bottom address.
- */
-static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
- uint32_t ul_mac_top, uint32_t ul_mac_bottom)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
-}
-
-/**
- * \brief Set MAC Address via int64.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param uc_index GMAC specific address register index.
- * \param ull_mac 64-bit GMAC address.
- */
-static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
- uint64_t ull_mac)
-{
- p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
- p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
-}
-
-/**
- * \brief Select media independent interface mode.
- *
- * \param p_gmac Pointer to the GMAC instance.
- * \param mode Media independent interface mode.
- */
-static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
-{
- switch (mode) {
- case GMAC_PHY_MII:
- case GMAC_PHY_RMII:
- p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
- break;
-
- default:
- p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
- break;
- }
-}
-
-uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
- uint32_t* p_value);
-uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
- uint8_t uc_address, uint32_t ul_value);
-void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
- gmac_options_t* p_opt);
-uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
- uint32_t ul_frame_size, uint32_t* p_rcv_size);
-uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
- uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
-uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
-void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_rx_cb_t func_rx_cb);
-uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
- gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
-void gmac_dev_reset(gmac_device_t* p_gmac_dev);
-void gmac_handler(gmac_device_t* p_gmac_dev);
-
-/// @cond 0
-/**INDENT-OFF**/
-#ifdef __cplusplus
-}
-#endif
-/**INDENT-ON**/
-/// @endcond
-
-/**
- * \page gmac_quickstart Quickstart guide for GMAC driver.
- *
- * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
- * with step-by-step instructions on how to configure and use the driver in a
- * selection of use cases.
- *
- * The use cases contain several code fragments. The code fragments in the
- * steps for setup can be copied into a custom initialization function, while
- * the steps for usage can be copied into, e.g., the main application function.
- *
- * \section gmac_basic_use_case Basic use case
- * In the basic use case, the GMAC driver are configured for:
- * - PHY component KSZ8051MNL is used
- * - GMAC uses MII mode
- * - The number of receive buffer is 16
- * - The number of transfer buffer is 8
- * - MAC address is set to 00-04-25-1c-a0-02
- * - IP address is set to 192.168.0.2
- * - IP address is set to 192.168.0.2
- * - Gateway is set to 192.168.0.1
- * - Network mask is 255.255.255.0
- * - PHY operation max retry count is 1000000
- * - GMAC is configured to not support copy all frame and support broadcast
- * - The data will be read from the ethernet
- *
- * \section gmac_basic_use_case_setup Setup steps
- *
- * \subsection gmac_basic_use_case_setup_prereq Prerequisites
- * -# \ref sysclk_group "System Clock Management (sysclock)"
- * -# \ref pmc_group "Power Management Controller (pmc)"
- * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
- *
- * \subsection gmac_basic_use_case_setup_code Example code
- * Content of conf_eth.h
- * \code
- * #define GMAC_RX_BUFFERS 16
- * #define GMAC_TX_BUFFERS 8
- * #define MAC_PHY_RETRY_MAX 1000000
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * #define ETH_PHY_MODE ETH_PHY_MODE
- * \endcode
- *
- * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
- * to trace the actual size of the data received.
- * \code
- * static gmac_device_t gs_gmac_dev;
- * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
- *
- * uint32_t ul_frm_size;
- * \endcode
- *
- * Add to application C-file:
- * \code
- * void gmac_init(void)
- * {
- * sysclk_init();
- *
- * board_init();
- *
- * pmc_enable_periph_clk(ID_GMAC);
- *
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- *
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- *
- * NVIC_EnableIRQ(GMAC_IRQn);
- *
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- *
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- *
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \subsection gmac_basic_use_case_setup_flow Workflow
- * - Ensure that conf_eth.h is present and contains the
- * following configuration symbol. This configuration file is used
- * by the driver and should not be included by the application.
- * -# Define the receiving buffer size used in the internal GMAC driver.
- * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
- * If it was supposed receiving a large number of frame, the
- * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
- * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
- * (2048/128)=16, and as there are additional frames coming, a preferred
- * number is 24 depending on a normal Ethernet throughput.
- * - \code
- * #define GMAC_RX_BUFFERS 16
- * \endcode
- * -# Define the transmitting buffer size used in the internal GMAC driver.
- * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
- * - \code
- * #define GMAC_TX_BUFFERS 8
- * \endcode
- * -# Define maximum retry time for a PHY read/write operation.
- * - \code
- * #define MAC_PHY_RETRY_MAX 1000000
- * \endcode
- * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
- * for ATMEL, application should always change this address to its' own.
- * - \code
- * #define ETHERNET_CONF_ETHADDR0 0x00
- * #define ETHERNET_CONF_ETHADDR1 0x04
- * #define ETHERNET_CONF_ETHADDR2 0x25
- * #define ETHERNET_CONF_ETHADDR3 0x1C
- * #define ETHERNET_CONF_ETHADDR4 0xA0
- * #define ETHERNET_CONF_ETHADDR5 0x02
- * \endcode
- * -# Define the IP address configration used in the application. When DHCP
- * is enabled, this configuration is not effected.
- * - \code
- * #define ETHERNET_CONF_IPADDR0 192
- * #define ETHERNET_CONF_IPADDR1 168
- * #define ETHERNET_CONF_IPADDR2 0
- * #define ETHERNET_CONF_IPADDR3 2
- * #define ETHERNET_CONF_GATEWAY_ADDR0 192
- * #define ETHERNET_CONF_GATEWAY_ADDR1 168
- * #define ETHERNET_CONF_GATEWAY_ADDR2 0
- * #define ETHERNET_CONF_GATEWAY_ADDR3 1
- * #define ETHERNET_CONF_NET_MASK0 255
- * #define ETHERNET_CONF_NET_MASK1 255
- * #define ETHERNET_CONF_NET_MASK2 255
- * #define ETHERNET_CONF_NET_MASK3 0
- * \endcode
- * -# Configure the PHY maintainance interface.
- * - \code
- * #define ETH_PHY_MODE GMAC_PHY_MII
- * \endcode
- * -# Enable the system clock:
- * - \code sysclk_init(); \endcode
- * -# Enable PIO configurations for GMAC:
- * - \code board_init(); \endcode
- * -# Enable PMC clock for GMAC:
- * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
- * -# Set the GMAC options; it's set to copy all frame and support broadcast:
- * - \code
- * gmac_option.uc_copy_all_frame = 0;
- * gmac_option.uc_no_boardcast = 0;
- * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
- * gs_gmac_dev.p_hw = GMAC;
- * \endcode
- * -# Initialize GMAC device with the filled option:
- * - \code
- * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
- * \endcode
- * -# Enable the interrupt service for GMAC:
- * - \code
- * NVIC_EnableIRQ(GMAC_IRQn);
- * \endcode
- * -# Initialize the PHY component:
- * - \code
- * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
- * \endcode
- * -# The link will be established based on auto negotiation.
- * - \code
- * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
- * \endcode
- * -# Establish the ethernet link; the network can be worked from now on:
- * - \code
- * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
- * \endcode
- *
- * \section gmac_basic_use_case_usage Usage steps
- * \subsection gmac_basic_use_case_usage_code Example code
- * Add to, e.g., main loop in application C-file:
- * \code
- * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
- * \endcode
- *
- * \subsection gmac_basic_use_case_usage_flow Workflow
- * -# Start reading the data from the ethernet:
- * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
- */
-
-# define GMAC_STATS 0
-
-#if( GMAC_STATS != 0 )
-
- /* Here below some code to study the types and
- frequencies of GMAC interrupts. */
- #define GMAC_IDX_RXUBR 0
- #define GMAC_IDX_TUR 1
- #define GMAC_IDX_RLEX 2
- #define GMAC_IDX_TFC 3
- #define GMAC_IDX_RCOMP 4
- #define GMAC_IDX_TCOMP 5
- #define GMAC_IDX_ROVR 6
- #define GMAC_IDX_HRESP 7
- #define GMAC_IDX_PFNZ 8
- #define GMAC_IDX_PTZ 9
-
- struct SGmacStats {
- unsigned recvCount;
- unsigned rovrCount;
- unsigned bnaCount;
- unsigned sendCount;
- unsigned sovrCount;
- unsigned incompCount;
- unsigned truncCount;
-
- unsigned intStatus[10];
- };
- extern struct SGmacStats gmacStats;
-
- struct SIntPair {
- const char *name;
- unsigned mask;
- int index;
- };
-
- #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
- static const struct SIntPair intPairs[] = {
- { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
- { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
- { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
- { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
- { MK_PAIR( RCOMP ) }, /* Receive complete */
- { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
- { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
- { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
- { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
- { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
- };
-
- void gmac_show_irq_counts ();
-
-#endif
-
-#endif /* GMAC_H_INCLUDED */
+ /**
+ * \file
+ *
+ * \brief GMAC (Ethernet MAC) driver for SAM.
+ *
+ * Copyright (c) 2013 Atmel Corporation. All rights reserved.
+ *
+ * \asf_license_start
+ *
+ * \page License
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * 3. The name of Atmel may not be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * 4. This software may only be redistributed and used in connection with an
+ * Atmel microcontroller product.
+ *
+ * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
+ * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ *
+ * \asf_license_stop
+ *
+ */
+
+#ifndef GMAC_H_INCLUDED
+#define GMAC_H_INCLUDED
+
+#include "compiler.h"
+#include "component/gmac.h"
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+extern "C" {
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/** The buffer addresses written into the descriptors must be aligned, so the
+ last few bits are zero. These bits have special meaning for the GMAC
+ peripheral and cannot be used as part of the address. */
+#define GMAC_RXD_ADDR_MASK 0xFFFFFFFC
+#define GMAC_RXD_WRAP (1ul << 1) /**< Wrap bit */
+#define GMAC_RXD_OWNERSHIP (1ul << 0) /**< Ownership bit */
+
+#define GMAC_RXD_BROADCAST (1ul << 31) /**< Broadcast detected */
+#define GMAC_RXD_MULTIHASH (1ul << 30) /**< Multicast hash match */
+#define GMAC_RXD_UNIHASH (1ul << 29) /**< Unicast hash match */
+#define GMAC_RXD_ADDR_FOUND (1ul << 27) /**< Specific address match found */
+#define GMAC_RXD_ADDR (3ul << 25) /**< Address match */
+#define GMAC_RXD_RXCOEN (1ul << 24) /**< RXCOEN related function */
+#define GMAC_RXD_TYPE (3ul << 22) /**< Type ID match */
+#define GMAC_RXD_VLAN (1ul << 21) /**< VLAN tag detected */
+#define GMAC_RXD_PRIORITY (1ul << 20) /**< Priority tag detected */
+#define GMAC_RXD_PRIORITY_MASK (3ul << 17) /**< VLAN priority */
+#define GMAC_RXD_CFI (1ul << 16) /**< Concatenation Format Indicator only if bit 21 is set */
+#define GMAC_RXD_EOF (1ul << 15) /**< End of frame */
+#define GMAC_RXD_SOF (1ul << 14) /**< Start of frame */
+#define GMAC_RXD_FCS (1ul << 13) /**< Frame check sequence */
+#define GMAC_RXD_OFFSET_MASK /**< Receive buffer offset */
+#define GMAC_RXD_LEN_MASK (0xFFF) /**< Length of frame including FCS (if selected) */
+#define GMAC_RXD_LENJUMBO_MASK (0x3FFF) /**< Jumbo frame length */
+
+#define GMAC_TXD_USED (1ul << 31) /**< Frame is transmitted */
+#define GMAC_TXD_WRAP (1ul << 30) /**< Last descriptor */
+#define GMAC_TXD_ERROR (1ul << 29) /**< Retry limit exceeded, error */
+#define GMAC_TXD_UNDERRUN (1ul << 28) /**< Transmit underrun */
+#define GMAC_TXD_EXHAUSTED (1ul << 27) /**< Buffer exhausted */
+#define GMAC_TXD_LATE (1ul << 26) /**< Late collision,transmit error */
+#define GMAC_TXD_CHECKSUM_ERROR (7ul << 20) /**< Checksum error */
+#define GMAC_TXD_NOCRC (1ul << 16) /**< No CRC */
+#define GMAC_TXD_LAST (1ul << 15) /**< Last buffer in frame */
+#define GMAC_TXD_LEN_MASK (0x1FFF) /**< Length of buffer */
+
+/** The MAC can support frame lengths up to 1536 bytes */
+#define GMAC_FRAME_LENTGH_MAX 1536
+
+#define GMAC_RX_UNITSIZE 128 /**< Fixed size for RX buffer */
+#define GMAC_TX_UNITSIZE 1518 /**< Size for ETH frame length */
+
+/** GMAC clock speed */
+#define GMAC_MCK_SPEED_240MHZ (240*1000*1000)
+#define GMAC_MCK_SPEED_160MHZ (160*1000*1000)
+#define GMAC_MCK_SPEED_120MHZ (120*1000*1000)
+#define GMAC_MCK_SPEED_80MHZ (80*1000*1000)
+#define GMAC_MCK_SPEED_40MHZ (40*1000*1000)
+#define GMAC_MCK_SPEED_20MHZ (20*1000*1000)
+
+/** GMAC maintain code default value*/
+#define GMAC_MAN_CODE_VALUE (10)
+
+/** GMAC maintain start of frame default value*/
+#define GMAC_MAN_SOF_VALUE (1)
+
+/** GMAC maintain read/write*/
+#define GMAC_MAN_RW_TYPE (2)
+
+/** GMAC maintain read only*/
+#define GMAC_MAN_READ_ONLY (1)
+
+/** GMAC address length */
+#define GMAC_ADDR_LENGTH (6)
+
+
+#define GMAC_DUPLEX_HALF 0
+#define GMAC_DUPLEX_FULL 1
+
+#define GMAC_SPEED_10M 0
+#define GMAC_SPEED_100M 1
+
+/**
+ * \brief Return codes for GMAC APIs.
+ */
+typedef enum {
+ GMAC_OK = 0, /** 0 Operation OK */
+ GMAC_TIMEOUT = 1, /** 1 GMAC operation timeout */
+ GMAC_TX_BUSY, /** 2 TX in progress */
+ GMAC_RX_NULL, /** 3 No data received */
+ GMAC_SIZE_TOO_SMALL, /** 4 Buffer size not enough */
+ GMAC_PARAM, /** 5 Parameter error, TX packet invalid or RX size too small */
+ GMAC_INVALID = 0xFF, /* Invalid */
+} gmac_status_t;
+
+/**
+ * \brief Media Independent Interface (MII) type.
+ */
+typedef enum {
+ GMAC_PHY_MII = 0, /** MII mode */
+ GMAC_PHY_RMII = 1, /** Reduced MII mode */
+ GMAC_PHY_INVALID = 0xFF, /* Invalid mode*/
+} gmac_mii_mode_t;
+
+/** Receive buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_rx_descriptor {
+ union gmac_rx_addr {
+ uint32_t val;
+ struct gmac_rx_addr_bm {
+ uint32_t b_ownership:1, /**< User clear, GMAC sets this to 1 once it has successfully written a frame to memory */
+ b_wrap:1, /**< Marks last descriptor in receive buffer */
+ addr_dw:30; /**< Address in number of DW */
+ } bm;
+ } addr; /**< Address, Wrap & Ownership */
+ union gmac_rx_status {
+ uint32_t val;
+ struct gmac_rx_status_bm {
+ uint32_t len:13, /** 0..12 Length of frame including FCS */
+ b_fcs:1, /** 13 Receive buffer offset, bits 13:12 of frame length for jumbo frame */
+ b_sof:1, /** 14 Start of frame */
+ b_eof:1, /** 15 End of frame */
+ b_cfi:1, /** 16 Concatenation Format Indicator */
+ vlan_priority:3, /** 17..19 VLAN priority (if VLAN detected) */
+ b_priority_detected:1, /** 20 Priority tag detected */
+ b_vlan_detected:1, /** 21 VLAN tag detected */
+ b_type_id_match:2, /** 22..23 Type ID match */
+ b_checksumoffload:1, /** 24 Checksum offload specific function */
+ b_addrmatch:2, /** 25..26 Address register match */
+ b_ext_addr_match:1, /** 27 External address match found */
+ reserved:1, /** 28 */
+ b_uni_hash_match:1, /** 29 Unicast hash match */
+ b_multi_hash_match:1, /** 30 Multicast hash match */
+ b_boardcast_detect:1; /** 31 Global broadcast address detected */
+ } bm;
+ } status;
+} gmac_rx_descriptor_t;
+
+/** Transmit buffer descriptor struct */
+COMPILER_PACK_SET(8)
+typedef struct gmac_tx_descriptor {
+ uint32_t addr;
+ union gmac_tx_status {
+ uint32_t val;
+ struct gmac_tx_status_bm {
+ uint32_t len:14, /** 0..13 Length of buffer */
+ reserved:1, /** 14 */
+ b_last_buffer:1, /** 15 Last buffer (in the current frame) */
+ b_no_crc:1, /** 16 No CRC */
+ reserved1:3, /** 17..19 */
+ b_checksumoffload:3, /** 20..22 Transmit checksum generation offload errors */
+ reserved2:3, /** 23..25 */
+ b_lco:1, /** 26 Late collision, transmit error detected */
+ b_exhausted:1, /** 27 Buffer exhausted in mid frame */
+ b_underrun:1, /** 28 Transmit underrun */
+ b_error:1, /** 29 Retry limit exceeded, error detected */
+ b_wrap:1, /** 30 Marks last descriptor in TD list */
+ b_used:1; /** 31 User clear, GMAC sets this to 1 once a frame has been successfully transmitted */
+ } bm;
+ } status;
+} gmac_tx_descriptor_t;
+
+COMPILER_PACK_RESET()
+
+/**
+ * \brief Input parameters when initializing the gmac module mode.
+ */
+typedef struct gmac_options {
+ /* Enable/Disable CopyAllFrame */
+ uint8_t uc_copy_all_frame;
+ /* Enable/Disable NoBroadCast */
+ uint8_t uc_no_boardcast;
+ /* MAC address */
+ uint8_t uc_mac_addr[GMAC_ADDR_LENGTH];
+} gmac_options_t;
+
+/** TX callback */
+typedef void (*gmac_dev_tx_cb_t) (uint32_t ul_status, uint8_t *puc_buffer);
+/** RX callback */
+typedef void (*gmac_dev_rx_cb_t) (uint32_t ul_status);
+/** Wakeup callback */
+typedef void (*gmac_dev_wakeup_cb_t) (void);
+
+/**
+ * GMAC driver structure.
+ */
+typedef struct gmac_device {
+
+ /** Pointer to HW register base */
+ Gmac *p_hw;
+ /**
+ * Pointer to allocated TX buffer.
+ * Section 3.6 of AMBA 2.0 spec states that burst should not cross
+ * 1K Boundaries.
+ * Receive buffer manager writes are burst of 2 words => 3 lsb bits
+ * of the address shall be set to 0.
+ */
+ uint8_t *p_tx_buffer;
+ /** Pointer to allocated RX buffer */
+ uint8_t *p_rx_buffer;
+ /** Pointer to Rx TDs (must be 8-byte aligned) */
+ gmac_rx_descriptor_t *p_rx_dscr;
+ /** Pointer to Tx TDs (must be 8-byte aligned) */
+ gmac_tx_descriptor_t *p_tx_dscr;
+ /** Optional callback to be invoked once a frame has been received */
+ gmac_dev_rx_cb_t func_rx_cb;
+#if( GMAC_USES_WAKEUP_CALLBACK )
+ /** Optional callback to be invoked once several TDs have been released */
+ gmac_dev_wakeup_cb_t func_wakeup_cb;
+#endif
+#if( GMAC_USES_TX_CALLBACK != 0 )
+ /** Optional callback list to be invoked once TD has been processed */
+ gmac_dev_tx_cb_t *func_tx_cb_list;
+#endif
+ /** RX TD list size */
+ uint32_t ul_rx_list_size;
+ /** RX index for current processing TD */
+ uint32_t ul_rx_idx;
+ /** TX TD list size */
+ uint32_t ul_tx_list_size;
+ /** Circular buffer head pointer by upper layer (buffer to be sent) */
+ int32_t l_tx_head;
+ /** Circular buffer tail pointer incremented by handlers (buffer sent) */
+ int32_t l_tx_tail;
+
+ /** Number of free TD before wakeup callback is invoked */
+ uint32_t uc_wakeup_threshold;
+} gmac_device_t;
+
+/**
+ * \brief Write network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_ncr Network control value.
+ */
+static inline void gmac_network_control(Gmac* p_gmac, uint32_t ul_ncr)
+{
+ p_gmac->GMAC_NCR = ul_ncr;
+}
+
+/**
+ * \brief Get network control value.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+
+static inline uint32_t gmac_get_network_control(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCR;
+}
+
+/**
+ * \brief Enable/Disable GMAC receive.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_receive(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_RXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_RXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC transmit.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC transmit, else to enable it.
+ */
+static inline void gmac_enable_transmit(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXEN;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_TXEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable GMAC management.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable GMAC management, else to enable it.
+ */
+static inline void gmac_enable_management(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_MPE;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_MPE;
+ }
+}
+
+/**
+ * \brief Clear all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_clear_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_CLRSTAT;
+}
+
+/**
+ * \brief Increase all statistics registers.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_increase_statistics(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_INCSTAT;
+}
+
+/**
+ * \brief Enable/Disable statistics registers writing.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the statistics registers writing, else to enable it.
+ */
+static inline void gmac_enable_statistics_write(Gmac* p_gmac,
+ uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_WESTAT;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_WESTAT;
+ }
+}
+
+/**
+ * \brief In half-duplex mode, forces collisions on all received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the back pressure, else to enable it.
+ */
+static inline void gmac_enable_back_pressure(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_BP;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_BP;
+ }
+}
+
+/**
+ * \brief Start transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_start_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TSTART;
+}
+
+/**
+ * \brief Halt transmission.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_halt_transmission(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_THALT;
+}
+
+/**
+ * \brief Transmit pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPF;
+}
+
+/**
+ * \brief Transmit zero quantum pause frame.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_tx_pause_zero_quantum_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXZQPF;
+}
+
+/**
+ * \brief Read snapshot.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_read_snapshot(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_RDS;
+}
+
+/**
+ * \brief Store receivetime stamp to memory.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to normal operation, else to enable the store.
+ */
+static inline void gmac_store_rx_time_stamp(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_SRTSM;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_SRTSM;
+ }
+}
+
+/**
+ * \brief Enable PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to set the reception, 0 to disable.
+ */
+static inline void gmac_enable_pfc_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCR |= GMAC_NCR_ENPBPR;
+ } else {
+ p_gmac->GMAC_NCR &= ~GMAC_NCR_ENPBPR;
+ }
+}
+
+/**
+ * \brief Transmit PFC priority-based pause reception.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_transmit_pfc_pause_frame(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_TXPBPF;
+}
+
+/**
+ * \brief Flush next packet.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_flush_next_packet(Gmac* p_gmac)
+{
+ p_gmac->GMAC_NCR |= GMAC_NCR_FNP;
+}
+
+/**
+ * \brief Set up network configuration register.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_cfg Network configuration value.
+ */
+static inline void gmac_set_configure(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_NCFGR = ul_cfg;
+}
+
+/**
+ * \brief Get network configuration.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network configuration.
+ */
+static inline uint32_t gmac_get_configure(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NCFGR;
+}
+
+
+/* Get and set DMA Configuration Register */
+static inline void gmac_set_dma(Gmac* p_gmac, uint32_t ul_cfg)
+{
+ p_gmac->GMAC_DCFGR = ul_cfg;
+}
+
+static inline uint32_t gmac_get_dma(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_DCFGR;
+}
+
+/**
+ * \brief Set speed.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_speed 1 to indicate 100Mbps, 0 to 10Mbps.
+ */
+static inline void gmac_set_speed(Gmac* p_gmac, uint8_t uc_speed)
+{
+ if (uc_speed) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_SPD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_SPD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Full-Duplex mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the Full-Duplex mode, else to enable it.
+ */
+static inline void gmac_enable_full_duplex(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_FD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_FD;
+ }
+}
+
+/**
+ * \brief Enable/Disable Copy(Receive) All Valid Frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable copying all valid frames, else to enable it.
+ */
+static inline void gmac_enable_copy_all(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_CAF;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_CAF;
+ }
+}
+
+/**
+ * \brief Enable/Disable jumbo frames (up to 10240 bytes).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the jumbo frames, else to enable it.
+ */
+static inline void gmac_enable_jumbo_frames(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_JFRAME;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_JFRAME;
+ }
+}
+
+/**
+ * \brief Disable/Enable broadcast receiving.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 1 to disable the broadcast, else to enable it.
+ */
+static inline void gmac_disable_broadcast(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_NBC;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_NBC;
+ }
+}
+
+/**
+ * \brief Enable/Disable multicast hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the multicast hash, else to enable it.
+ */
+static inline void gmac_enable_multicast_hash(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_UNIHEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_UNIHEN;
+ }
+}
+
+/**
+ * \brief Enable/Disable big frames (over 1518, up to 1536).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable big frames else to enable it.
+ */
+static inline void gmac_enable_big_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_MAXFS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_MAXFS;
+ }
+}
+
+/**
+ * \brief Set MDC clock divider.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_mck GMAC MCK.
+ *
+ * \return GMAC_OK if successfully.
+ */
+static inline uint8_t gmac_set_mdc_clock(Gmac* p_gmac, uint32_t ul_mck)
+{
+ uint32_t ul_clk;
+
+ if (ul_mck > GMAC_MCK_SPEED_240MHZ) {
+ return GMAC_INVALID;
+ } else if (ul_mck > GMAC_MCK_SPEED_160MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_96;
+ } else if (ul_mck > GMAC_MCK_SPEED_120MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_64;
+ } else if (ul_mck > GMAC_MCK_SPEED_80MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_48;
+ } else if (ul_mck > GMAC_MCK_SPEED_40MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_32;
+ } else if (ul_mck > GMAC_MCK_SPEED_20MHZ) {
+ ul_clk = GMAC_NCFGR_CLK_MCK_16;
+ } else {
+ ul_clk = GMAC_NCFGR_CLK_MCK_8;
+ }
+ ;
+ p_gmac->GMAC_NCFGR = (p_gmac->GMAC_NCFGR & ~GMAC_NCFGR_CLK_Msk) | ul_clk;
+ return GMAC_OK;
+}
+
+/**
+ * \brief Enable/Disable retry test.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the GMAC receiver, else to enable it.
+ */
+static inline void gmac_enable_retry_test(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RTY;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RTY;
+ }
+}
+
+/**
+ * \brief Enable/Disable pause (when a valid pause frame is received).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable pause frame, else to enable it.
+ */
+static inline void gmac_enable_pause_frame(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_PEN;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_PEN;
+ }
+}
+
+/**
+ * \brief Set receive buffer offset to 0 ~ 3.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline void gmac_set_rx_buffer_offset(Gmac* p_gmac, uint8_t uc_offset)
+{
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RXBUFO_Msk;
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RXBUFO(uc_offset);
+}
+
+/**
+ * \brief Enable/Disable receive length field checking.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable receive length field checking, else to enable it.
+ */
+static inline void gmac_enable_rx_length_check(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_LFERD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_LFERD;
+ }
+}
+
+/**
+ * \brief Enable/Disable discarding FCS field of received frames.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable discarding FCS field of received frames, else to enable it.
+ */
+static inline void gmac_enable_discard_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_RFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_RFCS;
+ }
+}
+
+
+/**
+ * \brief Enable/Disable frames to be received in half-duplex mode
+ * while transmitting.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable the received in half-duplex mode, else to enable it.
+ */
+static inline void gmac_enable_efrhd(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_EFRHD;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_EFRHD;
+ }
+}
+
+/**
+ * \brief Enable/Disable ignore RX FCS.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_enable 0 to disable ignore RX FCS, else to enable it.
+ */
+static inline void gmac_enable_ignore_rx_fcs(Gmac* p_gmac, uint8_t uc_enable)
+{
+ if (uc_enable) {
+ p_gmac->GMAC_NCFGR |= GMAC_NCFGR_IRXFCS;
+ } else {
+ p_gmac->GMAC_NCFGR &= ~GMAC_NCFGR_IRXFCS;
+ }
+}
+
+/**
+ * \brief Get Network Status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Network status.
+ */
+static inline uint32_t gmac_get_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_NSR;
+}
+
+/**
+ * \brief Get MDIO IN pin status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return MDIO IN pin status.
+ */
+static inline uint8_t gmac_get_MDIO(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_MDIO) > 0);
+}
+
+/**
+ * \brief Check if PHY is idle.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return 1 if PHY is idle.
+ */
+static inline uint8_t gmac_is_phy_idle(Gmac* p_gmac)
+{
+ return ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) > 0);
+}
+
+/**
+ * \brief Return transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Transmit status.
+ */
+static inline uint32_t gmac_get_tx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TSR;
+}
+
+/**
+ * \brief Clear transmit status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Transmit status.
+ */
+static inline void gmac_clear_tx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_TSR = ul_status;
+}
+
+/**
+ * \brief Return receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ */
+static inline uint32_t gmac_get_rx_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RSR;
+}
+
+/**
+ * \brief Clear receive status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_status Receive status.
+ */
+static inline void gmac_clear_rx_status(Gmac* p_gmac, uint32_t ul_status)
+{
+ p_gmac->GMAC_RSR = ul_status;
+}
+
+/**
+ * \brief Set Rx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Rx queue address.
+ */
+static inline void gmac_set_rx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_RBQB = GMAC_RBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Rx Queue Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_rx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_RBQB;
+}
+
+/**
+ * \brief Set Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_addr Tx queue address.
+ */
+static inline void gmac_set_tx_queue(Gmac* p_gmac, uint32_t ul_addr)
+{
+ p_gmac->GMAC_TBQB = GMAC_TBQB_ADDR_Msk & ul_addr;
+}
+
+/**
+ * \brief Get Tx Queue.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Rx queue address.
+ */
+static inline uint32_t gmac_get_tx_queue(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_TBQB;
+}
+
+/**
+ * \brief Enable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be enabled.
+ */
+static inline void gmac_enable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IER = ul_source;
+}
+
+/**
+ * \brief Disable interrupt(s).
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_source Interrupt source(s) to be disabled.
+ */
+static inline void gmac_disable_interrupt(Gmac* p_gmac, uint32_t ul_source)
+{
+ p_gmac->GMAC_IDR = ul_source;
+}
+
+/**
+ * \brief Return interrupt status.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt status.
+ */
+static inline uint32_t gmac_get_interrupt_status(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_ISR;
+}
+
+/**
+ * \brief Return interrupt mask.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Interrupt mask.
+ */
+static inline uint32_t gmac_get_interrupt_mask(Gmac* p_gmac)
+{
+ return p_gmac->GMAC_IMR;
+}
+
+/**
+ * \brief Execute PHY maintenance command.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_phy_addr PHY address.
+ * \param uc_reg_addr Register address.
+ * \param uc_rw 1 to Read, 0 to write.
+ * \param us_data Data to be performed, write only.
+ */
+static inline void gmac_maintain_phy(Gmac* p_gmac,
+ uint8_t uc_phy_addr, uint8_t uc_reg_addr, uint8_t uc_rw,
+ uint16_t us_data)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Write maintain register */
+ p_gmac->GMAC_MAN = GMAC_MAN_WTN(GMAC_MAN_CODE_VALUE)
+ | GMAC_MAN_CLTTO
+ | GMAC_MAN_PHYA(uc_phy_addr)
+ | GMAC_MAN_REGA(uc_reg_addr)
+ | GMAC_MAN_OP((uc_rw ? GMAC_MAN_RW_TYPE : GMAC_MAN_READ_ONLY))
+ | GMAC_MAN_DATA(us_data);
+}
+
+/**
+ * \brief Get PHY maintenance data returned.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ *
+ * \return Get PHY data.
+ */
+static inline uint16_t gmac_get_phy_data(Gmac* p_gmac)
+{
+ /* Wait until bus idle */
+ while ((p_gmac->GMAC_NSR & GMAC_NSR_IDLE) == 0);
+ /* Return data */
+ return (uint16_t) (p_gmac->GMAC_MAN & GMAC_MAN_DATA_Msk);
+}
+
+/**
+ * \brief Set Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ul_hash_top Hash top.
+ * \param ul_hash_bottom Hash bottom.
+ */
+static inline void gmac_set_hash(Gmac* p_gmac, uint32_t ul_hash_top,
+ uint32_t ul_hash_bottom)
+{
+ p_gmac->GMAC_HRB = ul_hash_bottom;
+ p_gmac->GMAC_HRT = ul_hash_top;
+}
+
+/**
+ * \brief Set 64 bits Hash.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param ull_hash 64 bits hash value.
+ */
+static inline void gmac_set_hash64(Gmac* p_gmac, uint64_t ull_hash)
+{
+ p_gmac->GMAC_HRB = (uint32_t) ull_hash;
+ p_gmac->GMAC_HRT = (uint32_t) (ull_hash >> 32);
+}
+
+/**
+ * \brief Set MAC Address.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param p_mac_addr GMAC address.
+ */
+static inline void gmac_set_address(Gmac* p_gmac, uint8_t uc_index,
+ uint8_t* p_mac_addr)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (p_mac_addr[3] << 24)
+ | (p_mac_addr[2] << 16)
+ | (p_mac_addr[1] << 8)
+ | (p_mac_addr[0]);
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (p_mac_addr[5] << 8)
+ | (p_mac_addr[4]);
+}
+
+/**
+ * \brief Set MAC Address via 2 dword.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ul_mac_top GMAC top address.
+ * \param ul_mac_bottom GMAC bottom address.
+ */
+static inline void gmac_set_address32(Gmac* p_gmac, uint8_t uc_index,
+ uint32_t ul_mac_top, uint32_t ul_mac_bottom)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = ul_mac_bottom;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = ul_mac_top;
+}
+
+/**
+ * \brief Set MAC Address via int64.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param uc_index GMAC specific address register index.
+ * \param ull_mac 64-bit GMAC address.
+ */
+static inline void gmac_set_address64(Gmac* p_gmac, uint8_t uc_index,
+ uint64_t ull_mac)
+{
+ p_gmac->GMAC_SA[uc_index].GMAC_SAB = (uint32_t) ull_mac;
+ p_gmac->GMAC_SA[uc_index].GMAC_SAT = (uint32_t) (ull_mac >> 32);
+}
+
+/**
+ * \brief Select media independent interface mode.
+ *
+ * \param p_gmac Pointer to the GMAC instance.
+ * \param mode Media independent interface mode.
+ */
+static inline void gmac_select_mii_mode(Gmac* p_gmac, gmac_mii_mode_t mode)
+{
+ switch (mode) {
+ case GMAC_PHY_MII:
+ case GMAC_PHY_RMII:
+ p_gmac->GMAC_UR |= GMAC_UR_RMIIMII;
+ break;
+
+ default:
+ p_gmac->GMAC_UR &= ~GMAC_UR_RMIIMII;
+ break;
+ }
+}
+
+uint8_t gmac_phy_read(Gmac* p_gmac, uint8_t uc_phy_address, uint8_t uc_address,
+ uint32_t* p_value);
+uint8_t gmac_phy_write(Gmac* p_gmac, uint8_t uc_phy_address,
+ uint8_t uc_address, uint32_t ul_value);
+void gmac_dev_init(Gmac* p_gmac, gmac_device_t* p_gmac_dev,
+ gmac_options_t* p_opt);
+uint32_t gmac_dev_read(gmac_device_t* p_gmac_dev, uint8_t* p_frame,
+ uint32_t ul_frame_size, uint32_t* p_rcv_size);
+uint32_t gmac_dev_write(gmac_device_t* p_gmac_dev, void *p_buffer,
+ uint32_t ul_size, gmac_dev_tx_cb_t func_tx_cb);
+uint32_t gmac_dev_get_tx_load(gmac_device_t* p_gmac_dev);
+void gmac_dev_set_rx_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_rx_cb_t func_rx_cb);
+uint8_t gmac_dev_set_tx_wakeup_callback(gmac_device_t* p_gmac_dev,
+ gmac_dev_wakeup_cb_t func_wakeup, uint8_t uc_threshold);
+void gmac_dev_reset(gmac_device_t* p_gmac_dev);
+void gmac_handler(gmac_device_t* p_gmac_dev);
+
+/// @cond 0
+/**INDENT-OFF**/
+#ifdef __cplusplus
+}
+#endif
+/**INDENT-ON**/
+/// @endcond
+
+/**
+ * \page gmac_quickstart Quickstart guide for GMAC driver.
+ *
+ * This is the quickstart guide for the \ref gmac_group "Ethernet MAC",
+ * with step-by-step instructions on how to configure and use the driver in a
+ * selection of use cases.
+ *
+ * The use cases contain several code fragments. The code fragments in the
+ * steps for setup can be copied into a custom initialization function, while
+ * the steps for usage can be copied into, e.g., the main application function.
+ *
+ * \section gmac_basic_use_case Basic use case
+ * In the basic use case, the GMAC driver are configured for:
+ * - PHY component KSZ8051MNL is used
+ * - GMAC uses MII mode
+ * - The number of receive buffer is 16
+ * - The number of transfer buffer is 8
+ * - MAC address is set to 00-04-25-1c-a0-02
+ * - IP address is set to 192.168.0.2
+ * - IP address is set to 192.168.0.2
+ * - Gateway is set to 192.168.0.1
+ * - Network mask is 255.255.255.0
+ * - PHY operation max retry count is 1000000
+ * - GMAC is configured to not support copy all frame and support broadcast
+ * - The data will be read from the ethernet
+ *
+ * \section gmac_basic_use_case_setup Setup steps
+ *
+ * \subsection gmac_basic_use_case_setup_prereq Prerequisites
+ * -# \ref sysclk_group "System Clock Management (sysclock)"
+ * -# \ref pmc_group "Power Management Controller (pmc)"
+ * -# \ref ksz8051mnl_ethernet_phy_group "PHY component (KSZ8051MNL)"
+ *
+ * \subsection gmac_basic_use_case_setup_code Example code
+ * Content of conf_eth.h
+ * \code
+ * #define GMAC_RX_BUFFERS 16
+ * #define GMAC_TX_BUFFERS 8
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * #define ETH_PHY_MODE ETH_PHY_MODE
+ * \endcode
+ *
+ * A specific gmac device and the receive data buffer must be defined; another ul_frm_size should be defined
+ * to trace the actual size of the data received.
+ * \code
+ * static gmac_device_t gs_gmac_dev;
+ * static volatile uint8_t gs_uc_eth_buffer[GMAC_FRAME_LENTGH_MAX];
+ *
+ * uint32_t ul_frm_size;
+ * \endcode
+ *
+ * Add to application C-file:
+ * \code
+ * void gmac_init(void)
+ * {
+ * sysclk_init();
+ *
+ * board_init();
+ *
+ * pmc_enable_periph_clk(ID_GMAC);
+ *
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ *
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ *
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ *
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ *
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ *
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_setup_flow Workflow
+ * - Ensure that conf_eth.h is present and contains the
+ * following configuration symbol. This configuration file is used
+ * by the driver and should not be included by the application.
+ * -# Define the receiving buffer size used in the internal GMAC driver.
+ * The buffer size used for RX is GMAC_RX_BUFFERS * 128.
+ * If it was supposed receiving a large number of frame, the
+ * GMAC_RX_BUFFERS should be set higher. E.g., the application wants to accept
+ * a ping echo test of 2048, the GMAC_RX_BUFFERS should be set at least
+ * (2048/128)=16, and as there are additional frames coming, a preferred
+ * number is 24 depending on a normal Ethernet throughput.
+ * - \code
+ * #define GMAC_RX_BUFFERS 16
+ * \endcode
+ * -# Define the transmitting buffer size used in the internal GMAC driver.
+ * The buffer size used for TX is GMAC_TX_BUFFERS * 1518.
+ * - \code
+ * #define GMAC_TX_BUFFERS 8
+ * \endcode
+ * -# Define maximum retry time for a PHY read/write operation.
+ * - \code
+ * #define MAC_PHY_RETRY_MAX 1000000
+ * \endcode
+ * -# Define the MAC address. 00:04:25:1C:A0:02 is the address reserved
+ * for ATMEL, application should always change this address to its' own.
+ * - \code
+ * #define ETHERNET_CONF_ETHADDR0 0x00
+ * #define ETHERNET_CONF_ETHADDR1 0x04
+ * #define ETHERNET_CONF_ETHADDR2 0x25
+ * #define ETHERNET_CONF_ETHADDR3 0x1C
+ * #define ETHERNET_CONF_ETHADDR4 0xA0
+ * #define ETHERNET_CONF_ETHADDR5 0x02
+ * \endcode
+ * -# Define the IP address configration used in the application. When DHCP
+ * is enabled, this configuration is not effected.
+ * - \code
+ * #define ETHERNET_CONF_IPADDR0 192
+ * #define ETHERNET_CONF_IPADDR1 168
+ * #define ETHERNET_CONF_IPADDR2 0
+ * #define ETHERNET_CONF_IPADDR3 2
+ * #define ETHERNET_CONF_GATEWAY_ADDR0 192
+ * #define ETHERNET_CONF_GATEWAY_ADDR1 168
+ * #define ETHERNET_CONF_GATEWAY_ADDR2 0
+ * #define ETHERNET_CONF_GATEWAY_ADDR3 1
+ * #define ETHERNET_CONF_NET_MASK0 255
+ * #define ETHERNET_CONF_NET_MASK1 255
+ * #define ETHERNET_CONF_NET_MASK2 255
+ * #define ETHERNET_CONF_NET_MASK3 0
+ * \endcode
+ * -# Configure the PHY maintainance interface.
+ * - \code
+ * #define ETH_PHY_MODE GMAC_PHY_MII
+ * \endcode
+ * -# Enable the system clock:
+ * - \code sysclk_init(); \endcode
+ * -# Enable PIO configurations for GMAC:
+ * - \code board_init(); \endcode
+ * -# Enable PMC clock for GMAC:
+ * - \code pmc_enable_periph_clk(ID_GMAC); \endcode
+ * -# Set the GMAC options; it's set to copy all frame and support broadcast:
+ * - \code
+ * gmac_option.uc_copy_all_frame = 0;
+ * gmac_option.uc_no_boardcast = 0;
+ * memcpy(gmac_option.uc_mac_addr, gs_uc_mac_address, sizeof(gs_uc_mac_address));
+ * gs_gmac_dev.p_hw = GMAC;
+ * \endcode
+ * -# Initialize GMAC device with the filled option:
+ * - \code
+ * gmac_dev_init(GMAC, &gs_gmac_dev, &gmac_option);
+ * \endcode
+ * -# Enable the interrupt service for GMAC:
+ * - \code
+ * NVIC_EnableIRQ(GMAC_IRQn);
+ * \endcode
+ * -# Initialize the PHY component:
+ * - \code
+ * ethernet_phy_init(GMAC, BOARD_GMAC_PHY_ADDR, sysclk_get_cpu_hz());
+ * \endcode
+ * -# The link will be established based on auto negotiation.
+ * - \code
+ * ethernet_phy_auto_negotiate(GMAC, BOARD_GMAC_PHY_ADDR);
+ * \endcode
+ * -# Establish the ethernet link; the network can be worked from now on:
+ * - \code
+ * ethernet_phy_set_link(GMAC, BOARD_GMAC_PHY_ADDR, 1);
+ * \endcode
+ *
+ * \section gmac_basic_use_case_usage Usage steps
+ * \subsection gmac_basic_use_case_usage_code Example code
+ * Add to, e.g., main loop in application C-file:
+ * \code
+ * gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size));
+ * \endcode
+ *
+ * \subsection gmac_basic_use_case_usage_flow Workflow
+ * -# Start reading the data from the ethernet:
+ * - \code gmac_dev_read(&gs_gmac_dev, (uint8_t *) gs_uc_eth_buffer, sizeof(gs_uc_eth_buffer), &ul_frm_size)); \endcode
+ */
+
+# define GMAC_STATS 0
+
+#if( GMAC_STATS != 0 )
+
+ /* Here below some code to study the types and
+ frequencies of GMAC interrupts. */
+ #define GMAC_IDX_RXUBR 0
+ #define GMAC_IDX_TUR 1
+ #define GMAC_IDX_RLEX 2
+ #define GMAC_IDX_TFC 3
+ #define GMAC_IDX_RCOMP 4
+ #define GMAC_IDX_TCOMP 5
+ #define GMAC_IDX_ROVR 6
+ #define GMAC_IDX_HRESP 7
+ #define GMAC_IDX_PFNZ 8
+ #define GMAC_IDX_PTZ 9
+
+ struct SGmacStats {
+ unsigned recvCount;
+ unsigned rovrCount;
+ unsigned bnaCount;
+ unsigned sendCount;
+ unsigned sovrCount;
+ unsigned incompCount;
+ unsigned truncCount;
+
+ unsigned intStatus[10];
+ };
+ extern struct SGmacStats gmacStats;
+
+ struct SIntPair {
+ const char *name;
+ unsigned mask;
+ int index;
+ };
+
+ #define MK_PAIR( NAME ) #NAME, GMAC_IER_##NAME, GMAC_IDX_##NAME
+ static const struct SIntPair intPairs[] = {
+ { MK_PAIR( RXUBR ) }, /* Enable receive used bit read interrupt. */
+ { MK_PAIR( TUR ) }, /* Enable transmit underrun interrupt. */
+ { MK_PAIR( RLEX ) }, /* Enable retry limit exceeded interrupt. */
+ { MK_PAIR( TFC ) }, /* Enable transmit buffers exhausted in mid-frame interrupt. */
+ { MK_PAIR( RCOMP ) }, /* Receive complete */
+ { MK_PAIR( TCOMP ) }, /* Enable transmit complete interrupt. */
+ { MK_PAIR( ROVR ) }, /* Enable receive overrun interrupt. */
+ { MK_PAIR( HRESP ) }, /* Enable Hresp not OK interrupt. */
+ { MK_PAIR( PFNZ ) }, /* Enable pause frame received interrupt. */
+ { MK_PAIR( PTZ ) } /* Enable pause time zero interrupt. */
+ };
+
+ void gmac_show_irq_counts ();
+
+#endif
+
+#endif /* GMAC_H_INCLUDED */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Common/phyHandling.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Common/phyHandling.c
deleted file mode 100644
index fa7695942..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Common/phyHandling.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * Handling of Ethernet PHY's
- * PHY's communicate with an EMAC either through
- * a Media-Independent Interface (MII), or a Reduced Media-Independent Interface (RMII).
- * The EMAC can poll for PHY ports on 32 different addresses. Each of the PHY ports
- * shall be treated independently.
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-
-#include "phyHandling.h"
-
-#define phyMIN_PHY_ADDRESS 0
-#define phyMAX_PHY_ADDRESS 31
-
-#if defined( PHY_LS_HIGH_CHECK_TIME_MS ) || defined( PHY_LS_LOW_CHECK_TIME_MS )
- #warning please use the new defines with 'ipconfig' prefix
-#endif
-
-#ifndef ipconfigPHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define ipconfigPHY_LS_HIGH_CHECK_TIME_MS 15000uL
-#endif
-
-#ifndef ipconfigPHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkStatus in the PHY is still low every second. */
- #define ipconfigPHY_LS_LOW_CHECK_TIME_MS 1000uL
-#endif
-
-/* As the following 3 macro's are OK in most situations, and so they're not
-included in 'FreeRTOSIPConfigDefaults.h'.
-Users can change their values in the project's 'FreeRTOSIPConfig.h'. */
-#ifndef phyPHY_MAX_RESET_TIME_MS
- #define phyPHY_MAX_RESET_TIME_MS 1000uL
-#endif
-
-#ifndef phyPHY_MAX_NEGOTIATE_TIME_MS
- #define phyPHY_MAX_NEGOTIATE_TIME_MS 3000uL
-#endif
-
-#ifndef phySHORT_DELAY_MS
- #define phySHORT_DELAY_MS 50uL
-#endif
-
-/* Naming and numbering of basic PHY registers. */
-#define phyREG_00_BMCR 0x00u /* Basic Mode Control Register. */
-#define phyREG_01_BMSR 0x01u /* Basic Mode Status Register. */
-#define phyREG_02_PHYSID1 0x02u /* PHYS ID 1 */
-#define phyREG_03_PHYSID2 0x03u /* PHYS ID 2 */
-#define phyREG_04_ADVERTISE 0x04u /* Advertisement control reg */
-
-/* Naming and numbering of extended PHY registers. */
-#define PHYREG_10_PHYSTS 0x10u /* 16 PHY status register Offset */
-#define phyREG_19_PHYCR 0x19u /* 25 RW PHY Control Register */
-#define phyREG_1F_PHYSPCS 0x1Fu /* 31 RW PHY Special Control Status */
-
-/* Bit fields for 'phyREG_00_BMCR', the 'Basic Mode Control Register'. */
-#define phyBMCR_FULL_DUPLEX 0x0100u /* Full duplex. */
-#define phyBMCR_AN_RESTART 0x0200u /* Auto negotiation restart. */
-#define phyBMCR_ISOLATE 0x0400u /* 1 = Isolates 0 = Normal operation. */
-#define phyBMCR_AN_ENABLE 0x1000u /* Enable auto negotiation. */
-#define phyBMCR_SPEED_100 0x2000u /* Select 100Mbps. */
-#define phyBMCR_RESET 0x8000u /* Reset the PHY. */
-
-/* Bit fields for 'phyREG_19_PHYCR', the 'PHY Control Register'. */
-#define PHYCR_MDIX_EN 0x8000u /* Enable Auto MDIX. */
-#define PHYCR_MDIX_FORCE 0x4000u /* Force MDIX crossed. */
-
-#define phyBMSR_AN_COMPLETE 0x0020u /* Auto-Negotiation process completed */
-
-#define phyBMSR_LINK_STATUS 0x0004u
-
-#define phyPHYSTS_LINK_STATUS 0x0001u /* PHY Link mask */
-#define phyPHYSTS_SPEED_STATUS 0x0002u /* PHY Speed mask */
-#define phyPHYSTS_DUPLEX_STATUS 0x0004u /* PHY Duplex mask */
-
-/* Bit fields for 'phyREG_1F_PHYSPCS
- 001 = 10BASE-T half-duplex
- 101 = 10BASE-T full-duplex
- 010 = 100BASE-TX half-duplex
- 110 = 100BASE-TX full-duplex
-*/
-#define phyPHYSPCS_SPEED_MASK 0x000Cu
-#define phyPHYSPCS_SPEED_10 0x0004u
-#define phyPHYSPCS_FULL_DUPLEX 0x0010u
-
-/*
- * Description of all capabilities that can be advertised to
- * the peer (usually a switch or router).
- */
-
-#define phyADVERTISE_CSMA 0x0001u /* Supports IEEE 802.3u: Fast Ethernet at 100 Mbit/s */
-#define phyADVERTISE_10HALF 0x0020u /* Try for 10mbps half-duplex. */
-#define phyADVERTISE_10FULL 0x0040u /* Try for 10mbps full-duplex. */
-#define phyADVERTISE_100HALF 0x0080u /* Try for 100mbps half-duplex. */
-#define phyADVERTISE_100FULL 0x0100u /* Try for 100mbps full-duplex. */
-
-#define phyADVERTISE_ALL ( phyADVERTISE_10HALF | phyADVERTISE_10FULL | \
- phyADVERTISE_100HALF | phyADVERTISE_100FULL | \
- phyADVERTISE_CSMA )
-
-/* Send a reset command to a set of PHY-ports. */
-static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask );
-
-static BaseType_t xHas_1F_PHYSPCS( uint32_t ulPhyID )
-{
-BaseType_t xResult;
-
- switch( ulPhyID )
- {
- case PHY_ID_LAN8720:
- case PHY_ID_LAN8742A:
- case PHY_ID_KSZ8041:
-/*
- case PHY_ID_KSZ8051: // same ID as 8041
- case PHY_ID_KSZ8081: // same ID as 8041
-*/
- case PHY_ID_KSZ8081MNXIA:
-
- case PHY_ID_KSZ8863:
- default:
- /* Most PHY's have a 1F_PHYSPCS */
- xResult = pdTRUE;
- break;
- case PHY_ID_DP83848I:
- xResult = pdFALSE;
- break;
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xHas_19_PHYCR( uint32_t ulPhyID )
-{
-BaseType_t xResult;
-
- switch( ulPhyID )
- {
- case PHY_ID_LAN8742A:
- case PHY_ID_DP83848I:
- xResult = pdTRUE;
- break;
- default:
- /* Most PHY's do not have a 19_PHYCR */
- xResult = pdFALSE;
- break;
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-/* Initialise the struct and assign a PHY-read and -write function. */
-void vPhyInitialise( EthernetPhy_t *pxPhyObject, xApplicationPhyReadHook_t fnPhyRead, xApplicationPhyWriteHook_t fnPhyWrite )
-{
- memset( ( void * )pxPhyObject, '\0', sizeof( *pxPhyObject ) );
-
- pxPhyObject->fnPhyRead = fnPhyRead;
- pxPhyObject->fnPhyWrite = fnPhyWrite;
-}
-/*-----------------------------------------------------------*/
-
-/* Discover all PHY's connected by polling 32 indexes ( zero-based ) */
-BaseType_t xPhyDiscover( EthernetPhy_t *pxPhyObject )
-{
-BaseType_t xPhyAddress;
-
- pxPhyObject->xPortCount = 0;
-
- for( xPhyAddress = phyMIN_PHY_ADDRESS; xPhyAddress <= phyMAX_PHY_ADDRESS; xPhyAddress++ )
- {
- uint32_t ulLowerID;
-
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_03_PHYSID2, &ulLowerID );
- /* A valid PHY id can not be all zeros or all ones. */
- if( ( ulLowerID != ( uint16_t )~0u ) && ( ulLowerID != ( uint16_t )0u ) )
- {
- uint32_t ulUpperID;
- uint32_t ulPhyID;
-
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_02_PHYSID1, &ulUpperID );
- ulPhyID = ( ( ( uint32_t ) ulUpperID ) << 16 ) | ( ulLowerID & 0xFFF0 );
-
- pxPhyObject->ucPhyIndexes[ pxPhyObject->xPortCount ] = xPhyAddress;
- pxPhyObject->ulPhyIDs[ pxPhyObject->xPortCount ] = ulPhyID;
-
- pxPhyObject->xPortCount++;
-
- /* See if there is more storage space. */
- if( pxPhyObject->xPortCount == ipconfigPHY_MAX_PORTS )
- {
- break;
- }
- }
- }
- if( pxPhyObject->xPortCount > 0 )
- {
- FreeRTOS_printf( ( "PHY ID %lX\n", pxPhyObject->ulPhyIDs[ 0 ] ) );
- }
-
- return pxPhyObject->xPortCount;
-}
-/*-----------------------------------------------------------*/
-
-/* Send a reset command to a set of PHY-ports. */
-static uint32_t xPhyReset( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
-{
-uint32_t ulDoneMask, ulConfig;
-TickType_t xRemainingTime;
-TimeOut_t xTimer;
-BaseType_t xPhyIndex;
-
- /* A bit-mask of PHY ports that are ready. */
- ulDoneMask = 0ul;
-
- /* Set the RESET bits high. */
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- /* Read Control register. */
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig | phyBMCR_RESET );
- }
-
- xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( phyPHY_MAX_RESET_TIME_MS );
- vTaskSetTimeOutState( &xTimer );
-
- /* The reset should last less than a second. */
- for( ;; )
- {
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
- if( ( ulConfig & phyBMCR_RESET ) == 0 )
- {
- FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET %d ready\n", (int)xPhyIndex ) );
- ulDoneMask |= ( 1ul << xPhyIndex );
- }
- }
- if( ulDoneMask == ulPhyMask )
- {
- break;
- }
- if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
- {
- FreeRTOS_printf( ( "xPhyReset: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
- break;
- }
- /* Block for a while */
- vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
- }
-
- /* Clear the reset bits. */
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
- {
- if( ( ulDoneMask & ( 1ul << xPhyIndex ) ) == 0uL )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- /* The reset operation timed out, clear the bit manually. */
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulConfig & ~phyBMCR_RESET );
- }
- }
-
- vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
-
- return ulDoneMask;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xPhyConfigure( EthernetPhy_t *pxPhyObject, const PhyProperties_t *pxPhyProperties )
-{
-uint32_t ulConfig, ulAdvertise;
-BaseType_t xPhyIndex;
-
- if( pxPhyObject->xPortCount < 1 )
- {
- FreeRTOS_printf( ( "xPhyConfigure: No PHY's detected.\n" ) );
- return -1;
- }
-
- /* The expected ID for the 'LAN8742A' is 0x0007c130. */
- /* The expected ID for the 'LAN8720' is 0x0007c0f0. */
- /* The expected ID for the 'DP83848I' is 0x20005C90. */
-
- /* Set advertise register. */
- if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) && ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
- {
- ulAdvertise = phyADVERTISE_ALL;
- /* Reset auto-negotiation capability. */
- }
- else
- {
- /* Always select protocol 802.3u. */
- ulAdvertise = phyADVERTISE_CSMA;
-
- if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO )
- {
- if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
- {
- ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_100FULL;
- }
- else
- {
- ulAdvertise |= phyADVERTISE_10HALF | phyADVERTISE_100HALF;
- }
- }
- else if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO )
- {
- if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_10 )
- {
- ulAdvertise |= phyADVERTISE_10FULL | phyADVERTISE_10HALF;
- }
- else
- {
- ulAdvertise |= phyADVERTISE_100FULL | phyADVERTISE_100HALF;
- }
- }
- else if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 )
- {
- if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
- {
- ulAdvertise |= phyADVERTISE_100FULL;
- }
- else
- {
- ulAdvertise |= phyADVERTISE_100HALF;
- }
- }
- else
- {
- if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL )
- {
- ulAdvertise |= phyADVERTISE_10FULL;
- }
- else
- {
- ulAdvertise |= phyADVERTISE_10HALF;
- }
- }
- }
-
- /* Send a reset command to a set of PHY-ports. */
- xPhyReset( pxPhyObject, xPhyGetMask( pxPhyObject ) );
-
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++ )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
- uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
-
- /* Write advertise register. */
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, ulAdvertise );
-
- /*
- AN_EN AN1 AN0 Forced Mode
- 0 0 0 10BASE-T, Half-Duplex
- 0 0 1 10BASE-T, Full-Duplex
- 0 1 0 100BASE-TX, Half-Duplex
- 0 1 1 100BASE-TX, Full-Duplex
- AN_EN AN1 AN0 Advertised Mode
- 1 0 0 10BASE-T, Half/Full-Duplex
- 1 0 1 100BASE-TX, Half/Full-Duplex
- 1 1 0 10BASE-T Half-Duplex
- 100BASE-TX, Half-Duplex
- 1 1 1 10BASE-T, Half/Full-Duplex
- 100BASE-TX, Half/Full-Duplex
- */
-
- /* Read Control register. */
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_00_BMCR, &ulConfig );
-
- ulConfig &= ~( phyBMCR_SPEED_100 | phyBMCR_FULL_DUPLEX );
-
- ulConfig |= phyBMCR_AN_ENABLE;
-
- if( ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_100 ) || ( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_AUTO ) )
- {
- ulConfig |= phyBMCR_SPEED_100;
- }
- else if( pxPhyProperties->ucSpeed == ( uint8_t )PHY_SPEED_10 )
- {
- ulConfig &= ~phyBMCR_SPEED_100;
- }
-
- if( ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_FULL ) || ( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_AUTO ) )
- {
- ulConfig |= phyBMCR_FULL_DUPLEX;
- }
- else if( pxPhyProperties->ucDuplex == ( uint8_t )PHY_DUPLEX_HALF )
- {
- ulConfig &= ~phyBMCR_FULL_DUPLEX;
- }
-
- if( xHas_19_PHYCR( ulPhyID ) )
- {
- uint32_t ulPhyControl;
- /* Read PHY Control register. */
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_19_PHYCR, &ulPhyControl );
-
- /* Clear bits which might get set: */
- ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );
-
- if( pxPhyProperties->ucMDI_X == PHY_MDIX_AUTO )
- {
- ulPhyControl |= PHYCR_MDIX_EN;
- }
- else if( pxPhyProperties->ucMDI_X == PHY_MDIX_CROSSED )
- {
- /* Force direct link = Use crossed RJ45 cable. */
- ulPhyControl &= ~PHYCR_MDIX_FORCE;
- }
- else
- {
- /* Force crossed link = Use direct RJ45 cable. */
- ulPhyControl |= PHYCR_MDIX_FORCE;
- }
- /* update PHY Control Register. */
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_19_PHYCR, ulPhyControl );
- }
-
- FreeRTOS_printf( ( "+TCP: advertise: %04lX config %04lX\n", ulAdvertise, ulConfig ) );
- }
-
- /* Keep these values for later use. */
- pxPhyObject->ulBCRValue = ulConfig & ~phyBMCR_ISOLATE;
- pxPhyObject->ulACRValue = ulAdvertise;
-
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-/* xPhyFixedValue(): this function is called in case auto-negotiation is disabled.
-The caller has set the values in 'xPhyPreferences' (ucDuplex and ucSpeed).
-The PHY register phyREG_00_BMCR will be set for every connected PHY that matches
-with ulPhyMask. */
-BaseType_t xPhyFixedValue( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
-{
-BaseType_t xPhyIndex;
-uint32_t ulValue, ulBitMask = ( uint32_t )1u;
-
- ulValue = ( uint32_t )0u;
-
- if( pxPhyObject->xPhyPreferences.ucDuplex == PHY_DUPLEX_FULL )
- {
- ulValue |= phyBMCR_FULL_DUPLEX;
- }
- if( pxPhyObject->xPhyPreferences.ucSpeed == PHY_SPEED_100 )
- {
- ulValue |= phyBMCR_SPEED_100;
- }
-
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
- {
- if( ( ulPhyMask & ulBitMask ) != 0lu )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- /* Enable Auto-Negotiation. */
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, ulValue );
- }
- }
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-/* xPhyStartAutoNegotiation() is the alternative xPhyFixedValue():
-It sets the BMCR_AN_RESTART bit and waits for the auto-negotiation completion
-( phyBMSR_AN_COMPLETE ). */
-BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask )
-{
-uint32_t xPhyIndex, ulDoneMask, ulBitMask;
-uint32_t ulPHYLinkStatus, ulRegValue;
-TickType_t xRemainingTime;
-TimeOut_t xTimer;
-
- if( ulPhyMask == ( uint32_t )0u )
- {
- return 0;
- }
- for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++ )
- {
- if( ( ulPhyMask & ( 1lu << xPhyIndex ) ) != 0lu )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- /* Enable Auto-Negotiation. */
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_04_ADVERTISE, pxPhyObject->ulACRValue);
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue | phyBMCR_AN_RESTART );
- }
- }
- xRemainingTime = ( TickType_t ) pdMS_TO_TICKS( phyPHY_MAX_NEGOTIATE_TIME_MS );
- vTaskSetTimeOutState( &xTimer );
- ulDoneMask = 0;
- /* Wait until the auto-negotiation will be completed */
- for( ;; )
- {
- ulBitMask = ( uint32_t )1u;
- for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
- {
- if( ( ulPhyMask & ulBitMask ) != 0lu )
- {
- if( ( ulDoneMask & ulBitMask ) == 0lu )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue );
- if( ( ulRegValue & phyBMSR_AN_COMPLETE ) != 0 )
- {
- ulDoneMask |= ulBitMask;
- }
- }
- }
- }
- if( ulPhyMask == ulDoneMask )
- {
- break;
- }
- if( xTaskCheckForTimeOut( &xTimer, &xRemainingTime ) != pdFALSE )
- {
- FreeRTOS_printf( ( "xPhyStartAutoNegotiation: phyBMCR_RESET timed out ( done 0x%02lX )\n", ulDoneMask ) );
- break;
- }
- vTaskDelay( pdMS_TO_TICKS( phySHORT_DELAY_MS ) );
- }
-
- if( ulDoneMask != ( uint32_t)0u )
- {
- ulBitMask = ( uint32_t )1u;
- pxPhyObject->ulLinkStatusMask &= ~( ulDoneMask );
- for( xPhyIndex = 0; xPhyIndex < ( uint32_t ) pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
- uint32_t ulPhyID = pxPhyObject->ulPhyIDs[ xPhyIndex ];
-
- if( ( ulDoneMask & ulBitMask ) == ( uint32_t )0u )
- {
- continue;
- }
-
- /* Clear the 'phyBMCR_AN_RESTART' bit. */
- pxPhyObject->fnPhyWrite( xPhyAddress, phyREG_00_BMCR, pxPhyObject->ulBCRValue );
-
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulRegValue);
- if( ( ulRegValue & phyBMSR_LINK_STATUS ) != 0 )
- {
- ulPHYLinkStatus |= phyBMSR_LINK_STATUS;
- pxPhyObject->ulLinkStatusMask |= ulBitMask;
- }
- else
- {
- ulPHYLinkStatus &= ~( phyBMSR_LINK_STATUS );
- }
-
- if( ulPhyID == PHY_ID_KSZ8081MNXIA )
- {
- uint32_t ulControlStatus;
-
- pxPhyObject->fnPhyRead( xPhyAddress, 0x1E, &ulControlStatus);
- switch( ulControlStatus & 0x07 )
- {
- case 0x01:
- case 0x05:
-// [001] = 10BASE-T half-duplex
-// [101] = 10BASE-T full-duplex
- /* 10 Mbps. */
- ulRegValue |= phyPHYSTS_SPEED_STATUS;
- break;
- case 0x02:
- case 0x06:
-// [010] = 100BASE-TX half-duplex
-// [110] = 100BASE-TX full-duplex
- break;
- }
- switch( ulControlStatus & 0x07 )
- {
- case 0x05:
- case 0x06:
-// [101] = 10BASE-T full-duplex
-// [110] = 100BASE-TX full-duplex
- /* Full duplex. */
- ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
- break;
- case 0x01:
- case 0x02:
-// [001] = 10BASE-T half-duplex
-// [010] = 100BASE-TX half-duplex
- break;
- }
- }
- else if( xHas_1F_PHYSPCS( ulPhyID ) )
- {
- /* 31 RW PHY Special Control Status */
- uint32_t ulControlStatus;
-
- pxPhyObject->fnPhyRead( xPhyAddress, phyREG_1F_PHYSPCS, &ulControlStatus);
- ulRegValue = 0;
- if( ( ulControlStatus & phyPHYSPCS_FULL_DUPLEX ) != 0 )
- {
- ulRegValue |= phyPHYSTS_DUPLEX_STATUS;
- }
- if( ( ulControlStatus & phyPHYSPCS_SPEED_MASK ) == phyPHYSPCS_SPEED_10 )
- {
- ulRegValue |= phyPHYSTS_SPEED_STATUS;
- }
- }
- else
- {
- /* Read the result of the auto-negotiation. */
- pxPhyObject->fnPhyRead( xPhyAddress, PHYREG_10_PHYSTS, &ulRegValue);
- }
-
- FreeRTOS_printf( ( "Autonego ready: %08lx: %s duplex %u mbit %s status\n",
- ulRegValue,
- ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) ? "full" : "half",
- ( ulRegValue & phyPHYSTS_SPEED_STATUS ) ? 10 : 100,
- ( ( ulPHYLinkStatus |= phyBMSR_LINK_STATUS ) != 0) ? "high" : "low" ) );
- if( ( ulRegValue & phyPHYSTS_DUPLEX_STATUS ) != ( uint32_t )0u )
- {
- pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_FULL;
- }
- else
- {
- pxPhyObject->xPhyProperties.ucDuplex = PHY_DUPLEX_HALF;
- }
-
- if( ( ulRegValue & phyPHYSTS_SPEED_STATUS ) != 0 )
- {
- pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_10;
- }
- else
- {
- pxPhyObject->xPhyProperties.ucSpeed = PHY_SPEED_100;
- }
- }
- } /* if( ulDoneMask != ( uint32_t)0u ) */
-
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xPhyCheckLinkStatus( EthernetPhy_t *pxPhyObject, BaseType_t xHadReception )
-{
-uint32_t ulStatus, ulBitMask = 1u;
-BaseType_t xPhyIndex;
-BaseType_t xNeedCheck = pdFALSE;
-
- if( xHadReception > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
- pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
- {
- if( ( pxPhyObject->ulLinkStatusMask & ulBitMask ) == 0ul )
- {
- pxPhyObject->ulLinkStatusMask |= ulBitMask;
- FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
- xNeedCheck = pdTRUE;
- }
- }
- }
- else if( xTaskCheckForTimeOut( &( pxPhyObject->xLinkStatusTimer ), &( pxPhyObject->xLinkStatusRemaining ) ) != pdFALSE )
- {
- /* Frequent checking the PHY Link Status can affect for the performance of Ethernet controller.
- As long as packets are received, no polling is needed.
- Otherwise, polling will be done when the 'xLinkStatusTimer' expires. */
- for( xPhyIndex = 0; xPhyIndex < pxPhyObject->xPortCount; xPhyIndex++, ulBitMask <<= 1 )
- {
- BaseType_t xPhyAddress = pxPhyObject->ucPhyIndexes[ xPhyIndex ];
-
- if( pxPhyObject->fnPhyRead( xPhyAddress, phyREG_01_BMSR, &ulStatus ) == 0 )
- {
- if( !!( pxPhyObject->ulLinkStatusMask & ulBitMask ) != !!( ulStatus & phyBMSR_LINK_STATUS ) )
- {
- if( ( ulStatus & phyBMSR_LINK_STATUS ) != 0 )
- {
- pxPhyObject->ulLinkStatusMask |= ulBitMask;
- }
- else
- {
- pxPhyObject->ulLinkStatusMask &= ~( ulBitMask );
- }
- FreeRTOS_printf( ( "xPhyCheckLinkStatus: PHY LS now %02lX\n", pxPhyObject->ulLinkStatusMask ) );
- xNeedCheck = pdTRUE;
- }
- }
- }
- vTaskSetTimeOutState( &( pxPhyObject->xLinkStatusTimer ) );
- if( ( pxPhyObject->ulLinkStatusMask & phyBMSR_LINK_STATUS ) != 0 )
- {
- /* The link status is high, so don't poll the PHY too often. */
- pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- /* The link status is low, polling may be done more frequently. */
- pxPhyObject->xLinkStatusRemaining = pdMS_TO_TICKS( ipconfigPHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- return xNeedCheck;
-}
-/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c
index e0d04e454..7cee711cd 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC17xx/NetworkInterface.c
@@ -1,267 +1,267 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* Hardware abstraction. */
-#include "FreeRTOS_IO.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "NetworkBufferManagement.h"
-
-/* Driver includes. */
-#include "lpc17xx_emac.h"
-#include "lpc17xx_pinsel.h"
-
-/* Demo includes. */
-#include "NetworkInterface.h"
-
-#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* When a packet is ready to be sent, if it cannot be sent immediately then the
-task performing the transmit will block for niTX_BUFFER_FREE_WAIT
-milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
-up. */
-#define niTX_BUFFER_FREE_WAIT ( pdMS_TO_TICKS( 2UL ) )
-#define niMAX_TX_ATTEMPTS ( 5 )
-
-/* The length of the queue used to send interrupt status words from the
-interrupt handler to the deferred handler task. */
-#define niINTERRUPT_QUEUE_LENGTH ( 10 )
-
-/*-----------------------------------------------------------*/
-
-/*
- * A deferred interrupt handler task that processes
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used to communicate Ethernet events with the IP task. */
-extern QueueHandle_t xNetworkEventQueue;
-
-/* The semaphore used to wake the deferred interrupt handler task when an Rx
-interrupt is received. */
-static SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-EMAC_CFG_Type Emac_Config;
-PINSEL_CFG_Type xPinConfig;
-BaseType_t xStatus, xReturn;
-extern uint8_t ucMACAddress[ 6 ];
-
- /* Enable Ethernet Pins */
- boardCONFIGURE_ENET_PINS( xPinConfig );
-
- Emac_Config.Mode = EMAC_MODE_AUTO;
- Emac_Config.pbEMAC_Addr = ucMACAddress;
- xStatus = EMAC_Init( &Emac_Config );
-
- LPC_EMAC->IntEnable &= ~( EMAC_INT_TX_DONE );
-
- if( xStatus != ERROR )
- {
- vSemaphoreCreateBinary( xEMACRxEventSemaphore );
- configASSERT( xEMACRxEventSemaphore );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
-
- /* Enable the interrupt and set its priority to the minimum
- interrupt priority. */
- NVIC_SetPriority( ENET_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ( ENET_IRQn );
-
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- configASSERT( xStatus != ERROR );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-BaseType_t xReturn = pdFAIL;
-int32_t x;
-extern void EMAC_StartTransmitNextBuffer( uint32_t ulLength );
-extern void EMAC_SetNextPacketToSend( uint8_t * pucBuffer );
-
-
- /* Attempt to obtain access to a Tx buffer. */
- for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )
- {
- if( EMAC_CheckTransmitIndex() == TRUE )
- {
- /* Will the data fit in the Tx buffer? */
- if( pxNetworkBuffer->xDataLength < EMAC_ETH_MAX_FLEN ) /*_RB_ The size needs to come from FreeRTOSIPConfig.h. */
- {
- /* Assign the buffer to the Tx descriptor that is now known to
- be free. */
- EMAC_SetNextPacketToSend( pxNetworkBuffer->pucBuffer );
-
- /* The EMAC now owns the buffer. */
- pxNetworkBuffer->pucBuffer = NULL;
-
- /* Initiate the Tx. */
- EMAC_StartTransmitNextBuffer( pxNetworkBuffer->xDataLength );
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- /* The Tx has been initiated. */
- xReturn = pdPASS;
- }
- break;
- }
- else
- {
- vTaskDelay( niTX_BUFFER_FREE_WAIT );
- }
- }
-
- /* Finished with the network buffer. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void ENET_IRQHandler( void )
-{
-uint32_t ulInterruptCause;
-
- while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 )
- {
- /* Clear the interrupt. */
- LPC_EMAC->IntClear = ulInterruptCause;
-
- /* Clear fatal error conditions. NOTE: The driver does not clear all
- errors, only those actually experienced. For future reference, range
- errors are not actually errors so can be ignored. */
- if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U )
- {
- LPC_EMAC->Command |= EMAC_CR_TX_RES;
- }
-
- /* Unblock the deferred interrupt handler task if the event was an
- Rx. */
- if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL )
- {
- xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );
- }
- }
-
- /* ulInterruptCause is used for convenience here. A context switch is
- wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a
- compiler warning. */
- portEND_SWITCHING_ISR( ulInterruptCause );
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-size_t xDataLength;
-const uint16_t usCRCLength = 4;
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
-/* This is not included in the header file for some reason. */
-extern uint8_t *EMAC_NextPacketToRead( void );
-
- ( void ) pvParameters;
- configASSERT( xEMACRxEventSemaphore );
-
- for( ;; )
- {
- /* Wait for the EMAC interrupt to indicate that another packet has been
- received. The while() loop is only needed if INCLUDE_vTaskSuspend is
- set to 0 in FreeRTOSConfig.h. */
- while( xSemaphoreTake( xEMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );
-
- /* At least one packet has been received. */
- while( EMAC_CheckReceiveIndex() != FALSE )
- {
- /* Obtain the length, minus the CRC. The CRC is four bytes
- but the length is already minus 1. */
- xDataLength = ( size_t ) EMAC_GetReceiveDataSize() - ( usCRCLength - 1U );
-
- if( xDataLength > 0U )
- {
- /* Obtain a network buffer to pass this data into the
- stack. No storage is required as the network buffer
- will point directly to the buffer that already holds
- the received data. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( 0, ( TickType_t ) 0 );
-
- if( pxNetworkBuffer != NULL )
- {
- pxNetworkBuffer->pucBuffer = EMAC_NextPacketToRead();
- pxNetworkBuffer->xDataLength = xDataLength;
- xRxEvent.pvData = ( void * ) pxNetworkBuffer;
-
- /* Data was received and stored. Send a message to the IP
- task to let it know. */
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- else
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
-
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-
- /* Release the frame. */
- EMAC_UpdateRxConsumeIndex();
- }
- }
-}
-/*-----------------------------------------------------------*/
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* Hardware abstraction. */
+#include "FreeRTOS_IO.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "NetworkBufferManagement.h"
+
+/* Driver includes. */
+#include "lpc17xx_emac.h"
+#include "lpc17xx_pinsel.h"
+
+/* Demo includes. */
+#include "NetworkInterface.h"
+
+#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* When a packet is ready to be sent, if it cannot be sent immediately then the
+task performing the transmit will block for niTX_BUFFER_FREE_WAIT
+milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
+up. */
+#define niTX_BUFFER_FREE_WAIT ( pdMS_TO_TICKS( 2UL ) )
+#define niMAX_TX_ATTEMPTS ( 5 )
+
+/* The length of the queue used to send interrupt status words from the
+interrupt handler to the deferred handler task. */
+#define niINTERRUPT_QUEUE_LENGTH ( 10 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * A deferred interrupt handler task that processes
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used to communicate Ethernet events with the IP task. */
+extern QueueHandle_t xNetworkEventQueue;
+
+/* The semaphore used to wake the deferred interrupt handler task when an Rx
+interrupt is received. */
+static SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+EMAC_CFG_Type Emac_Config;
+PINSEL_CFG_Type xPinConfig;
+BaseType_t xStatus, xReturn;
+extern uint8_t ucMACAddress[ 6 ];
+
+ /* Enable Ethernet Pins */
+ boardCONFIGURE_ENET_PINS( xPinConfig );
+
+ Emac_Config.Mode = EMAC_MODE_AUTO;
+ Emac_Config.pbEMAC_Addr = ucMACAddress;
+ xStatus = EMAC_Init( &Emac_Config );
+
+ LPC_EMAC->IntEnable &= ~( EMAC_INT_TX_DONE );
+
+ if( xStatus != ERROR )
+ {
+ vSemaphoreCreateBinary( xEMACRxEventSemaphore );
+ configASSERT( xEMACRxEventSemaphore );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
+
+ /* Enable the interrupt and set its priority to the minimum
+ interrupt priority. */
+ NVIC_SetPriority( ENET_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_EnableIRQ( ENET_IRQn );
+
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ configASSERT( xStatus != ERROR );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+BaseType_t xReturn = pdFAIL;
+int32_t x;
+extern void EMAC_StartTransmitNextBuffer( uint32_t ulLength );
+extern void EMAC_SetNextPacketToSend( uint8_t * pucBuffer );
+
+
+ /* Attempt to obtain access to a Tx buffer. */
+ for( x = 0; x < niMAX_TX_ATTEMPTS; x++ )
+ {
+ if( EMAC_CheckTransmitIndex() == TRUE )
+ {
+ /* Will the data fit in the Tx buffer? */
+ if( pxNetworkBuffer->xDataLength < EMAC_ETH_MAX_FLEN ) /*_RB_ The size needs to come from FreeRTOSIPConfig.h. */
+ {
+ /* Assign the buffer to the Tx descriptor that is now known to
+ be free. */
+ EMAC_SetNextPacketToSend( pxNetworkBuffer->pucBuffer );
+
+ /* The EMAC now owns the buffer. */
+ pxNetworkBuffer->pucBuffer = NULL;
+
+ /* Initiate the Tx. */
+ EMAC_StartTransmitNextBuffer( pxNetworkBuffer->xDataLength );
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+
+ /* The Tx has been initiated. */
+ xReturn = pdPASS;
+ }
+ break;
+ }
+ else
+ {
+ vTaskDelay( niTX_BUFFER_FREE_WAIT );
+ }
+ }
+
+ /* Finished with the network buffer. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void ENET_IRQHandler( void )
+{
+uint32_t ulInterruptCause;
+
+ while( ( ulInterruptCause = LPC_EMAC->IntStatus ) != 0 )
+ {
+ /* Clear the interrupt. */
+ LPC_EMAC->IntClear = ulInterruptCause;
+
+ /* Clear fatal error conditions. NOTE: The driver does not clear all
+ errors, only those actually experienced. For future reference, range
+ errors are not actually errors so can be ignored. */
+ if( ( ulInterruptCause & EMAC_INT_TX_UNDERRUN ) != 0U )
+ {
+ LPC_EMAC->Command |= EMAC_CR_TX_RES;
+ }
+
+ /* Unblock the deferred interrupt handler task if the event was an
+ Rx. */
+ if( ( ulInterruptCause & EMAC_INT_RX_DONE ) != 0UL )
+ {
+ xSemaphoreGiveFromISR( xEMACRxEventSemaphore, NULL );
+ }
+ }
+
+ /* ulInterruptCause is used for convenience here. A context switch is
+ wanted, but coding portEND_SWITCHING_ISR( 1 ) would likely result in a
+ compiler warning. */
+ portEND_SWITCHING_ISR( ulInterruptCause );
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+size_t xDataLength;
+const uint16_t usCRCLength = 4;
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+/* This is not included in the header file for some reason. */
+extern uint8_t *EMAC_NextPacketToRead( void );
+
+ ( void ) pvParameters;
+ configASSERT( xEMACRxEventSemaphore );
+
+ for( ;; )
+ {
+ /* Wait for the EMAC interrupt to indicate that another packet has been
+ received. The while() loop is only needed if INCLUDE_vTaskSuspend is
+ set to 0 in FreeRTOSConfig.h. */
+ while( xSemaphoreTake( xEMACRxEventSemaphore, portMAX_DELAY ) == pdFALSE );
+
+ /* At least one packet has been received. */
+ while( EMAC_CheckReceiveIndex() != FALSE )
+ {
+ /* Obtain the length, minus the CRC. The CRC is four bytes
+ but the length is already minus 1. */
+ xDataLength = ( size_t ) EMAC_GetReceiveDataSize() - ( usCRCLength - 1U );
+
+ if( xDataLength > 0U )
+ {
+ /* Obtain a network buffer to pass this data into the
+ stack. No storage is required as the network buffer
+ will point directly to the buffer that already holds
+ the received data. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( 0, ( TickType_t ) 0 );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ pxNetworkBuffer->pucBuffer = EMAC_NextPacketToRead();
+ pxNetworkBuffer->xDataLength = xDataLength;
+ xRxEvent.pvData = ( void * ) pxNetworkBuffer;
+
+ /* Data was received and stored. Send a message to the IP
+ task to let it know. */
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ else
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+
+ /* Release the frame. */
+ EMAC_UpdateRxConsumeIndex();
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c
index ac01d41af..0b1f74d07 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/NetworkInterface.c
@@ -1,1068 +1,1068 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-/* LPCOpen includes. */
-#include "chip.h"
-#include "lpc_phy.h"
-
-/* The size of the stack allocated to the task that handles Rx packets. */
-#define nwRX_TASK_STACK_SIZE 140
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-#ifndef configUSE_RMII
- #define configUSE_RMII 1
-#endif
-
-#ifndef configNUM_RX_DESCRIPTORS
- #error please define configNUM_RX_DESCRIPTORS in your FreeRTOSIPConfig.h
-#endif
-
-#ifndef configNUM_TX_DESCRIPTORS
- #error please define configNUM_TX_DESCRIPTORS in your FreeRTOSIPConfig.h
-#endif
-
-#ifndef NETWORK_IRQHandler
- #error NETWORK_IRQHandler must be defined to the name of the function that is installed in the interrupt vector table to handle Ethernet interrupts.
-#endif
-
-#if !defined( MAC_FF_HMC )
- /* Hash for multicast. */
- #define MAC_FF_HMC ( 1UL << 2UL )
-#endif
-
-#ifndef iptraceEMAC_TASK_STARTING
- #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
-#endif
-
-/* Define the bits of .STATUS that indicate a reception error. */
-#define nwRX_STATUS_ERROR_BITS \
- ( RDES_CE /* CRC Error */ | \
- RDES_RE /* Receive Error */ | \
- RDES_DE /* Descriptor Error */ | \
- RDES_RWT /* Receive Watchdog Timeout */ | \
- RDES_LC /* Late Collision */ | \
- RDES_OE /* Overflow Error */ | \
- RDES_SAF /* Source Address Filter Fail */ | \
- RDES_AFM /* Destination Address Filter Fail */ | \
- RDES_LE /* Length Error */ )
-
-/* Define the EMAC status bits that should trigger an interrupt. */
-#define nwDMA_INTERRUPT_MASK \
- ( DMA_IE_TIE /* Transmit interrupt enable */ | \
- DMA_IE_TSE /* Transmit stopped enable */ | \
- DMA_IE_OVE /* Overflow interrupt enable */ | \
- DMA_IE_RIE /* Receive interrupt enable */ | \
- DMA_IE_NIE /* Normal interrupt summary enable */ | \
- DMA_IE_AIE /* Abnormal interrupt summary enable */ | \
- DMA_IE_RUE /* Receive buffer unavailable enable */ | \
- DMA_IE_UNE /* Underflow interrupt enable. */ | \
- DMA_IE_TJE /* Transmit jabber timeout enable */ | \
- DMA_IE_RSE /* Received stopped enable */ | \
- DMA_IE_RWE /* Receive watchdog timeout enable */ | \
- DMA_IE_FBE )/* Fatal bus error enable */
-
-/* Interrupt events to process. Currently only the RX/TX events are processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
- /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
- driver will filter incoming packets and only pass the stack those packets it
- considers need processing. */
- #if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
- #else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
- #endif
-
-#if( ipconfigZERO_COPY_RX_DRIVER == 0 ) || ( ipconfigZERO_COPY_TX_DRIVER == 0 )
- #warning It is adviced to enable both macros
-#endif
-
-#ifndef configPLACE_IN_SECTION_RAM
- #define configPLACE_IN_SECTION_RAM
-/*
- #define configPLACE_IN_SECTION_RAM __attribute__ ((section(".ramfunc")))
-*/
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Delay function passed into the library. The implementation uses FreeRTOS
- * calls so the scheduler must be started before the driver can be used.
- */
-static void prvDelay( uint32_t ulMilliSeconds );
-
-/*
- * Initialises the Tx and Rx descriptors respectively.
- */
-static void prvSetupTxDescriptors( void );
-static void prvSetupRxDescriptors( void );
-
-/*
- * A task that processes received frames.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Sets up the MAC with the results of an auto-negotiation.
- */
-static BaseType_t prvSetLinkSpeed( void );
-
-/*
- * Generates a CRC for a MAC address that is then used to generate a hash index.
- */
-static uint32_t prvGenerateCRC32( const uint8_t *ucAddress );
-
-/*
- * Generates a hash index when setting a filter to permit a MAC address.
- */
-static uint32_t prvGetHashIndex( const uint8_t *ucAddress );
-
-/*
- * Update the hash table to allow a MAC address.
- */
-static void prvAddMACAddress( const uint8_t* ucMacAddress );
-
-/*
- * Sometimes the DMA will report received data as being longer than the actual
- * received from length. This function checks the reported length and corrects
- * if if necessary.
- */
-static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx and Tx interrupt is handled, although code is included for other events
-to enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-
-/* Tx descriptors and index. */
-static ENET_ENHTXDESC_T xDMATxDescriptors[ configNUM_TX_DESCRIPTORS ];
-
-/* ulNextFreeTxDescriptor is declared volatile, because it is accessed from
-to different tasks. */
-static volatile uint32_t ulNextFreeTxDescriptor;
-static uint32_t ulTxDescriptorToClear;
-
-/* Rx descriptors and index. */
-static ENET_ENHRXDESC_T xDMARxDescriptors[ configNUM_RX_DESCRIPTORS ];
-static uint32_t ulNextRxDescriptorToProcess;
-
-/* Must be defined externally - the demo applications define this in main.c. */
-extern uint8_t ucMACAddress[ 6 ];
-
-/* The handle of the task that processes Rx packets. The handle is required so
-the task can be notified when new packets arrive. */
-static TaskHandle_t xRxHanderTask = NULL;
-
-#if( ipconfigUSE_LLMNR == 1 )
- static const uint8_t xLLMNR_MACAddress[] = { '\x01', '\x00', '\x5E', '\x00', '\x00', '\xFC' };
-#endif /* ipconfigUSE_LLMNR == 1 */
-
-/* xTXDescriptorSemaphore is a counting semaphore with
-a maximum count of ETH_TXBUFNB, which is the number of
-DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-BaseType_t xReturn = pdPASS;
-
- /* The interrupt will be turned on when a link is established. */
- NVIC_DisableIRQ( ETHERNET_IRQn );
-
- /* Disable receive and transmit DMA processes. */
- LPC_ETHERNET->DMA_OP_MODE &= ~( DMA_OM_ST | DMA_OM_SR );
-
- /* Disable packet reception. */
- LPC_ETHERNET->MAC_CONFIG &= ~( MAC_CFG_RE | MAC_CFG_TE );
-
- /* Call the LPCOpen function to initialise the hardware. */
- Chip_ENET_Init( LPC_ETHERNET );
-
- /* Save MAC address. */
- Chip_ENET_SetADDR( LPC_ETHERNET, ucMACAddress );
-
- /* Clear all MAC address hash entries. */
- LPC_ETHERNET->MAC_HASHTABLE_HIGH = 0;
- LPC_ETHERNET->MAC_HASHTABLE_LOW = 0;
-
- #if( ipconfigUSE_LLMNR == 1 )
- {
- prvAddMACAddress( xLLMNR_MACAddress );
- }
- #endif /* ipconfigUSE_LLMNR == 1 */
-
- /* Promiscuous flag (PR) and Receive All flag (RA) set to zero. The
- registers MAC_HASHTABLE_[LOW|HIGH] will be loaded to allow certain
- multi-cast addresses. */
- LPC_ETHERNET->MAC_FRAME_FILTER = MAC_FF_HMC;
-
- #if( configUSE_RMII == 1 )
- {
- if( lpc_phy_init( pdTRUE, prvDelay ) != SUCCESS )
- {
- xReturn = pdFAIL;
- }
- }
- #else
- {
- #warning This path has not been tested.
- if( lpc_phy_init( pdFALSE, prvDelay ) != SUCCESS )
- {
- xReturn = pdFAIL;
- }
- }
- #endif
-
- if( xReturn == pdPASS )
- {
- /* Guard against the task being created more than once and the
- descriptors being initialised more than once. */
- if( xRxHanderTask == NULL )
- {
- xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", nwRX_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
- configASSERT( xReturn );
- }
-
- if( xTXDescriptorSemaphore == NULL )
- {
- /* Create a counting semaphore, with a value of 'configNUM_TX_DESCRIPTORS'
- and a maximum of 'configNUM_TX_DESCRIPTORS'. */
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) configNUM_TX_DESCRIPTORS, ( UBaseType_t ) configNUM_TX_DESCRIPTORS );
- configASSERT( xTXDescriptorSemaphore );
- }
-
- /* Enable MAC interrupts. */
- LPC_ETHERNET->DMA_INT_EN = nwDMA_INTERRUPT_MASK;
- }
-
- if( xReturn != pdFAIL )
- {
- /* Auto-negotiate was already started. Wait for it to complete. */
- xReturn = prvSetLinkSpeed();
-
- if( xReturn == pdPASS )
- {
- /* Initialise the descriptors. */
- prvSetupTxDescriptors();
- prvSetupRxDescriptors();
-
- /* Clear all interrupts. */
- LPC_ETHERNET->DMA_STAT = DMA_ST_ALL;
-
- /* Enable receive and transmit DMA processes. */
- LPC_ETHERNET->DMA_OP_MODE |= DMA_OM_ST | DMA_OM_SR;
-
- /* Set Receiver / Transmitter Enable. */
- LPC_ETHERNET->MAC_CONFIG |= MAC_CFG_RE | MAC_CFG_TE;
-
- /* Start receive polling. */
- LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
-
- /* Enable interrupts in the NVIC. */
- NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_EnableIRQ( ETHERNET_IRQn );
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-#define niBUFFER_1_PACKET_SIZE 1536
-
-static __attribute__ ((section("._ramAHB32"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-
-uint8_t *ucRAMBuffer = ucNetworkPackets;
-uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-static void vClearTXBuffers()
-{
-uint32_t ulLastDescriptor = ulNextFreeTxDescriptor;
-size_t uxCount = ( ( size_t ) configNUM_TX_DESCRIPTORS ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- uint8_t *ucPayLoad;
-#endif
-
- /* This function is called after a TX-completion interrupt.
- It will release each Network Buffer used in xNetworkInterfaceOutput().
- 'uxCount' represents the number of descriptors given to DMA for transmission.
- After sending a packet, the DMA will clear the 'TDES_OWN' bit. */
- while( ( uxCount > ( size_t ) 0u ) && ( ( xDMATxDescriptors[ ulTxDescriptorToClear ].CTRLSTAT & TDES_OWN ) == 0 ) )
- {
- if( ( ulTxDescriptorToClear == ulLastDescriptor ) && ( uxCount != ( size_t ) configNUM_TX_DESCRIPTORS ) )
- {
- break;
- }
-
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- ucPayLoad = ( uint8_t * )xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD;
- if( ucPayLoad != NULL )
- {
- /* B1ADD points to a pucEthernetBuffer of a Network Buffer descriptor. */
- pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
-
- configASSERT( pxNetworkBuffer != NULL );
-
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
- xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD = ( uint32_t )0u;
- }
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- /* Move onto the next descriptor, wrapping if necessary. */
- ulTxDescriptorToClear++;
- if( ulTxDescriptorToClear >= configNUM_TX_DESCRIPTORS )
- {
- ulTxDescriptorToClear = 0;
- }
-
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
-}
-
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
-{
-BaseType_t xReturn = pdFAIL;
-const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50 );
-
- /* Attempt to obtain access to a Tx descriptor. */
- do
- {
- if( xTXDescriptorSemaphore == NULL )
- {
- break;
- }
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- break;
- }
-
- /* If the descriptor is still owned by the DMA it can't be used. */
- if( ( xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT & TDES_OWN ) != 0 )
- {
- /* The semaphore was taken, the TX DMA-descriptor is still not available.
- Actually that should not occur, the 'TDES_OWN' was already confirmed low in vClearTXBuffers(). */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
- else
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* bReleaseAfterSend should always be set when using the zero
- copy driver. */
- configASSERT( bReleaseAfterSend != pdFALSE );
-
- /* The DMA's descriptor to point directly to the data in the
- network buffer descriptor. The data is not copied. */
- xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD = ( uint32_t ) pxDescriptor->pucEthernetBuffer;
-
- /* The DMA descriptor will 'own' this Network Buffer,
- until it has been sent. So don't release it now. */
- bReleaseAfterSend = false;
- }
- #else
- {
- /* The data is copied from the network buffer descriptor into
- the DMA's descriptor. */
- memcpy( ( void * ) xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD, ( void * ) pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength );
- }
- #endif
-
- xDMATxDescriptors[ ulNextFreeTxDescriptor ].BSIZE = ( uint32_t ) TDES_ENH_BS1( pxDescriptor->xDataLength );
-
- /* This descriptor is given back to the DMA. */
- xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT |= TDES_OWN;
-
- /* Ensure the DMA is polling Tx descriptors. */
- LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;
-
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- /* Move onto the next descriptor, wrapping if necessary. */
- ulNextFreeTxDescriptor++;
- if( ulNextFreeTxDescriptor >= configNUM_TX_DESCRIPTORS )
- {
- ulNextFreeTxDescriptor = 0;
- }
-
- /* The Tx has been initiated. */
- xReturn = pdPASS;
- }
- } while( 0 );
-
- /* The buffer has been sent so can be released. */
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvDelay( uint32_t ulMilliSeconds )
-{
- /* Ensure the scheduler was started before attempting to use the scheduler to
- create a delay. */
- configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING );
-
- vTaskDelay( pdMS_TO_TICKS( ulMilliSeconds ) );
-}
-/*-----------------------------------------------------------*/
-
-static void prvSetupTxDescriptors( void )
-{
-BaseType_t x;
-
- /* Start with Tx descriptors clear. */
- memset( ( void * ) xDMATxDescriptors, 0, sizeof( xDMATxDescriptors ) );
-
- /* Index to the next Tx descriptor to use. */
- ulNextFreeTxDescriptor = 0ul;
-
- /* Index to the next Tx descriptor to clear ( after transmission ). */
- ulTxDescriptorToClear = 0ul;
-
- for( x = 0; x < configNUM_TX_DESCRIPTORS; x++ )
- {
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* Nothing to do, B1ADD will be set when data is ready to transmit.
- Currently the memset above will have set it to NULL. */
- }
- #else
- {
- /* Allocate a buffer to the Tx descriptor. This is the most basic
- way of creating a driver as the data is then copied into the
- buffer. */
- xDMATxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
-
- /* Use an assert to check the allocation as +TCP applications will
- often not use a malloc() failed hook as the TCP stack will recover
- from allocation failures. */
- configASSERT( xDMATxDescriptors[ x ].B1ADD );
- }
- #endif
-
- /* Buffers hold an entire frame so all buffers are both the start and
- end of a frame. */
- /* TDES_ENH_TCH Second Address Chained. */
- /* TDES_ENH_CIC(n) Checksum Insertion Control, tried but it does not work for the LPC18xx... */
- /* TDES_ENH_FS First Segment. */
- /* TDES_ENH_LS Last Segment. */
- /* TDES_ENH_IC Interrupt on Completion. */
- xDMATxDescriptors[ x ].CTRLSTAT = TDES_ENH_TCH | TDES_ENH_CIC( 3 ) | TDES_ENH_FS | TDES_ENH_LS | TDES_ENH_IC;
- xDMATxDescriptors[ x ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ x + 1 ];
- }
-
- xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].CTRLSTAT |= TDES_ENH_TER;
- xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ 0 ];
-
- /* Point the DMA to the base of the descriptor list. */
- LPC_ETHERNET->DMA_TRANS_DES_ADDR = ( uint32_t ) xDMATxDescriptors;
-}
-/*-----------------------------------------------------------*/
-
-static void prvSetupRxDescriptors( void )
-{
-BaseType_t x;
-#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-#endif
-
- /* Index to the next Rx descriptor to use. */
- ulNextRxDescriptorToProcess = 0;
-
- /* Clear RX descriptor list. */
- memset( ( void * ) xDMARxDescriptors, 0, sizeof( xDMARxDescriptors ) );
-
- for( x = 0; x < configNUM_RX_DESCRIPTORS; x++ )
- {
- /* Allocate a buffer of the largest possible frame size as it is not
- known what size received frames will be. */
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, 0 );
-
- /* During start-up there should be enough Network Buffers available,
- so it is safe to use configASSERT().
- In case this assert fails, please check: configNUM_RX_DESCRIPTORS,
- ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, and in case BufferAllocation_2.c
- is included, check the amount of available heap. */
- configASSERT( pxNetworkBuffer != NULL );
-
- /* Pass the actual buffer to DMA. */
- xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pxNetworkBuffer->pucEthernetBuffer;
- }
- #else
- {
- /* All DMA descriptors are populated with permanent memory blocks.
- Their contents will be copy to Network Buffers. */
- xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- /* Use an assert to check the allocation as +TCP applications will often
- not use a malloc failed hook as the TCP stack will recover from
- allocation failures. */
- configASSERT( xDMARxDescriptors[ x ].B1ADD );
-
- xDMARxDescriptors[ x ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ x + 1 ] );
- xDMARxDescriptors[ x ].CTRL = ( uint32_t ) RDES_ENH_BS1( ipTOTAL_ETHERNET_FRAME_SIZE ) | RDES_ENH_RCH;
-
- /* The descriptor is available for use by the DMA. */
- xDMARxDescriptors[ x ].STATUS = RDES_OWN;
- }
-
- /* RDES_ENH_RER Receive End of Ring. */
- xDMARxDescriptors[ ( configNUM_RX_DESCRIPTORS - 1 ) ].CTRL |= RDES_ENH_RER;
- xDMARxDescriptors[ configNUM_RX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ 0 ] );
-
- /* Point the DMA to the base of the descriptor list. */
- LPC_ETHERNET->DMA_REC_DES_ADDR = ( uint32_t ) xDMARxDescriptors;
-}
-/*-----------------------------------------------------------*/
-configPLACE_IN_SECTION_RAM
-static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor )
-{
-size_t xExpectedLength;
-IPPacket_t *pxIPPacket;
-
- pxIPPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer;
- /* Look at the actual length of the packet, translate it to a host-endial notation. */
- xExpectedLength = sizeof( EthernetHeader_t ) + ( size_t ) FreeRTOS_htons( pxIPPacket->xIPHeader.usLength );
-
- if( xExpectedLength == ( pxDescriptor->xDataLength + 4 ) )
- {
- pxDescriptor->xDataLength -= 4;
- }
- else
- {
- if( pxDescriptor->xDataLength > xExpectedLength )
- {
- pxDescriptor->xDataLength = ( size_t ) xExpectedLength;
- }
- }
-}
-/*-----------------------------------------------------------*/
-configPLACE_IN_SECTION_RAM
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xReturn;
-
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
- {
- xReturn = pdFALSE;
- }
- else
- {
- xReturn = pdTRUE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-uint32_t ulDataAvailable;
-
-configPLACE_IN_SECTION_RAM
-static BaseType_t prvNetworkInterfaceInput()
-{
-BaseType_t xResult = pdFALSE;
-uint32_t ulStatus;
-eFrameProcessingResult_t eResult;
-const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-const UBaseType_t uxMinimumBuffersRemaining = 3UL;
-uint16_t usLength;
-NetworkBufferDescriptor_t *pxDescriptor;
-#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNewDescriptor;
-#endif /* ipconfigZERO_COPY_RX_DRIVER */
-#if( ipconfigUSE_LINKED_RX_MESSAGES == 0 )
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-#endif
-
- /* Process each descriptor that is not still in use by the DMA. */
- ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
- if( ( ulStatus & RDES_OWN ) == 0 )
- {
- /* Check packet for errors */
- if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 )
- {
- /* There is some reception error. */
- intCount[ 3 ]++;
- /* Clear error bits. */
- ulStatus &= ~( ( uint32_t )nwRX_STATUS_ERROR_BITS );
- }
- else
- {
- xResult++;
-
- eResult = ipCONSIDER_FRAME_FOR_PROCESSING( ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD ) );
- if( eResult == eProcessBuffer )
- {
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
- {
- ulPHYLinkStatus |= PHY_LINK_CONNECTED;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (message received)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
- }
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
- {
- pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xDescriptorWaitTime );
- }
- else
- {
- /* Too risky to allocate a new Network Buffer. */
- pxNewDescriptor = NULL;
- }
- if( pxNewDescriptor != NULL )
- #else
- if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
- {
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- const uint8_t *pucBuffer;
- #endif
-
- /* Get the actual length. */
- usLength = RDES_FLMSK( ulStatus );
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Replace the character buffer 'B1ADD'. */
- pucBuffer = ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD );
- xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD = ( uint32_t ) pxNewDescriptor->pucEthernetBuffer;
-
- /* 'B1ADD' contained the address of a 'pucEthernetBuffer' that
- belongs to a Network Buffer. Find the original Network Buffer. */
- pxDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
- /* This zero-copy driver makes sure that every 'xDMARxDescriptors' contains
- a reference to a Network Buffer at any time.
- In case it runs out of Network Buffers, a DMA buffer won't be replaced,
- and the received messages is dropped. */
- configASSERT( pxDescriptor != NULL );
- }
- #else
- {
- /* Create a buffer of exactly the required length. */
- pxDescriptor = pxGetNetworkBufferWithDescriptor( usLength, xDescriptorWaitTime );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- if( pxDescriptor != NULL )
- {
- pxDescriptor->xDataLength = ( size_t ) usLength;
- #if( ipconfigZERO_COPY_RX_DRIVER == 0 )
- {
- /* Copy the data into the allocated buffer. */
- memcpy( ( void * ) pxDescriptor->pucEthernetBuffer, ( void * ) xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD, usLength );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
- /* It is possible that more data was copied than
- actually makes up the frame. If this is the case
- adjust the length to remove any trailing bytes. */
- prvRemoveTrailingBytes( pxDescriptor );
-
- /* Pass the data to the TCP/IP task for processing. */
- xRxEvent.pvData = ( void * ) pxDescriptor;
- if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
- {
- /* Could not send the descriptor into the TCP/IP
- stack, it must be released. */
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- else
- {
- iptraceNETWORK_INTERFACE_RECEIVE();
-
- /* The data that was available at the top of this
- loop has been sent, so is no longer available. */
- ulDataAvailable = pdFALSE;
- }
- }
- }
- }
- else
- {
- /* The packet is discarded as uninteresting. */
- ulDataAvailable = pdFALSE;
- }
- /* Got here because received data was sent to the IP task or the
- data contained an error and was discarded. Give the descriptor
- back to the DMA. */
- xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS = ulStatus | RDES_OWN;
-
- /* Move onto the next descriptor. */
- ulNextRxDescriptorToProcess++;
- if( ulNextRxDescriptorToProcess >= configNUM_RX_DESCRIPTORS )
- {
- ulNextRxDescriptorToProcess = 0;
- }
-
- ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
- } /* if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 ) */
- } /* if( ( ulStatus & RDES_OWN ) == 0 ) */
-
- /* Restart receive polling. */
- LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-void NETWORK_IRQHandler( void )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-uint32_t ulDMAStatus;
-const uint32_t ulRxInterruptMask =
- DMA_ST_RI | /* Receive interrupt */
- DMA_ST_RU; /* Receive buffer unavailable */
-const uint32_t ulTxInterruptMask =
- DMA_ST_TI | /* Transmit interrupt */
- DMA_ST_TPS; /* Transmit process stopped */
-
- configASSERT( xRxHanderTask );
-
- /* Get pending interrupts. */
- ulDMAStatus = LPC_ETHERNET->DMA_STAT;
-
- /* RX group interrupt(s). */
- if( ( ulDMAStatus & ulRxInterruptMask ) != 0x00 )
- {
- /* Remember that an RX event has happened. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
- intCount[ 0 ]++;
- }
-
- /* TX group interrupt(s). */
- if( ( ulDMAStatus & ulTxInterruptMask ) != 0x00 )
- {
- /* Remember that a TX event has happened. */
- ulISREvents |= EMAC_IF_TX_EVENT;
- vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
- intCount[ 1 ]++;
- }
-
- /* Test for 'Abnormal interrupt summary'. */
- if( ( ulDMAStatus & DMA_ST_AIE ) != 0x00 )
- {
- /* The trace macro must be written such that it can be called from
- an interrupt. */
- iptraceETHERNET_RX_EVENT_LOST();
- }
-
- /* Clear pending interrupts */
- LPC_ETHERNET->DMA_STAT = ulDMAStatus;
-
- /* Context switch needed? */
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvSetLinkSpeed( void )
-{
-BaseType_t xReturn = pdFAIL;
-TickType_t xTimeOnEntering;
-uint32_t ulPhyStatus;
-const TickType_t xAutoNegotiateDelay = pdMS_TO_TICKS( 5000UL );
-
- /* Ensure polling does not starve lower priority tasks by temporarily
- setting the priority of this task to that of the idle task. */
- vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
-
- xTimeOnEntering = xTaskGetTickCount();
- do
- {
- ulPhyStatus = lpcPHYStsPoll();
- if( ( ulPhyStatus & PHY_LINK_CONNECTED ) != 0x00 )
- {
- /* Set interface speed and duplex. */
- if( ( ulPhyStatus & PHY_LINK_SPEED100 ) != 0x00 )
- {
- Chip_ENET_SetSpeed( LPC_ETHERNET, 1 );
- }
- else
- {
- Chip_ENET_SetSpeed( LPC_ETHERNET, 0 );
- }
-
- if( ( ulPhyStatus & PHY_LINK_FULLDUPLX ) != 0x00 )
- {
- Chip_ENET_SetDuplex( LPC_ETHERNET, true );
- }
- else
- {
- Chip_ENET_SetDuplex( LPC_ETHERNET, false );
- }
-
- xReturn = pdPASS;
- break;
- }
- } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xAutoNegotiateDelay );
-
- /* Reset the priority of this task back to its original value. */
- vTaskPrioritySet( NULL, ipconfigIP_TASK_PRIORITY );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvGenerateCRC32( const uint8_t *ucAddress )
-{
-unsigned int j;
-const uint32_t Polynomial = 0xEDB88320;
-uint32_t crc = ~0ul;
-const uint8_t *pucCurrent = ( const uint8_t * ) ucAddress;
-const uint8_t *pucLast = pucCurrent + 6;
-
- /* Calculate normal CRC32 */
- while( pucCurrent < pucLast )
- {
- crc ^= *( pucCurrent++ );
- for( j = 0; j < 8; j++ )
- {
- if( ( crc & 1 ) != 0 )
- {
- crc = (crc >> 1) ^ Polynomial;
- }
- else
- {
- crc >>= 1;
- }
- }
- }
- return ~crc;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvGetHashIndex( const uint8_t *ucAddress )
-{
-uint32_t ulCrc = prvGenerateCRC32( ucAddress );
-uint32_t ulIndex = 0ul;
-BaseType_t xCount = 6;
-
- /* Take the lowest 6 bits of the CRC32 and reverse them */
- while( xCount-- )
- {
- ulIndex <<= 1;
- ulIndex |= ( ulCrc & 1 );
- ulCrc >>= 1;
- }
-
- /* This is the has value of 'ucAddress' */
- return ulIndex;
-}
-/*-----------------------------------------------------------*/
-
-static void prvAddMACAddress( const uint8_t* ucMacAddress )
-{
-BaseType_t xIndex;
-
- xIndex = prvGetHashIndex( ucMacAddress );
- if( xIndex >= 32 )
- {
- LPC_ETHERNET->MAC_HASHTABLE_HIGH |= ( 1u << ( xIndex - 32 ) );
- }
- else
- {
- LPC_ETHERNET->MAC_HASHTABLE_LOW |= ( 1u << xIndex );
- }
-}
-/*-----------------------------------------------------------*/
-
-configPLACE_IN_SECTION_RAM
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t ulStatus;
-const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
-
- /* Remove compiler warning about unused parameter. */
- ( void ) pvParameters;
-
- /* A possibility to set some additional task properties. */
- iptraceEMAC_TASK_STARTING();
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- for( ;; )
- {
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- ulTaskNotifyTake( pdTRUE, xBlockTime );
-
- xResult = ( BaseType_t ) 0;
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- {
- /* Check if DMA packets have been delivered. */
- vClearTXBuffers();
- }
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- xResult = prvNetworkInterfaceInput();
- if( xResult > 0 )
- {
- while( prvNetworkInterfaceInput() > 0 )
- {
- }
- }
- }
-
- if( xResult > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- ulStatus = lpcPHYStsPoll();
-
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != ( ulStatus & PHY_LINK_CONNECTED ) )
- {
- ulPHYLinkStatus = ulStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (polled PHY)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* LPCOpen includes. */
+#include "chip.h"
+#include "lpc_phy.h"
+
+/* The size of the stack allocated to the task that handles Rx packets. */
+#define nwRX_TASK_STACK_SIZE 140
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+#ifndef configUSE_RMII
+ #define configUSE_RMII 1
+#endif
+
+#ifndef configNUM_RX_DESCRIPTORS
+ #error please define configNUM_RX_DESCRIPTORS in your FreeRTOSIPConfig.h
+#endif
+
+#ifndef configNUM_TX_DESCRIPTORS
+ #error please define configNUM_TX_DESCRIPTORS in your FreeRTOSIPConfig.h
+#endif
+
+#ifndef NETWORK_IRQHandler
+ #error NETWORK_IRQHandler must be defined to the name of the function that is installed in the interrupt vector table to handle Ethernet interrupts.
+#endif
+
+#if !defined( MAC_FF_HMC )
+ /* Hash for multicast. */
+ #define MAC_FF_HMC ( 1UL << 2UL )
+#endif
+
+#ifndef iptraceEMAC_TASK_STARTING
+ #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
+#endif
+
+/* Define the bits of .STATUS that indicate a reception error. */
+#define nwRX_STATUS_ERROR_BITS \
+ ( RDES_CE /* CRC Error */ | \
+ RDES_RE /* Receive Error */ | \
+ RDES_DE /* Descriptor Error */ | \
+ RDES_RWT /* Receive Watchdog Timeout */ | \
+ RDES_LC /* Late Collision */ | \
+ RDES_OE /* Overflow Error */ | \
+ RDES_SAF /* Source Address Filter Fail */ | \
+ RDES_AFM /* Destination Address Filter Fail */ | \
+ RDES_LE /* Length Error */ )
+
+/* Define the EMAC status bits that should trigger an interrupt. */
+#define nwDMA_INTERRUPT_MASK \
+ ( DMA_IE_TIE /* Transmit interrupt enable */ | \
+ DMA_IE_TSE /* Transmit stopped enable */ | \
+ DMA_IE_OVE /* Overflow interrupt enable */ | \
+ DMA_IE_RIE /* Receive interrupt enable */ | \
+ DMA_IE_NIE /* Normal interrupt summary enable */ | \
+ DMA_IE_AIE /* Abnormal interrupt summary enable */ | \
+ DMA_IE_RUE /* Receive buffer unavailable enable */ | \
+ DMA_IE_UNE /* Underflow interrupt enable. */ | \
+ DMA_IE_TJE /* Transmit jabber timeout enable */ | \
+ DMA_IE_RSE /* Received stopped enable */ | \
+ DMA_IE_RWE /* Receive watchdog timeout enable */ | \
+ DMA_IE_FBE )/* Fatal bus error enable */
+
+/* Interrupt events to process. Currently only the RX/TX events are processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+ /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+ driver will filter incoming packets and only pass the stack those packets it
+ considers need processing. */
+ #if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+ #else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+ #endif
+
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 ) || ( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ #warning It is adviced to enable both macros
+#endif
+
+#ifndef configPLACE_IN_SECTION_RAM
+ #define configPLACE_IN_SECTION_RAM
+/*
+ #define configPLACE_IN_SECTION_RAM __attribute__ ((section(".ramfunc")))
+*/
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Delay function passed into the library. The implementation uses FreeRTOS
+ * calls so the scheduler must be started before the driver can be used.
+ */
+static void prvDelay( uint32_t ulMilliSeconds );
+
+/*
+ * Initialises the Tx and Rx descriptors respectively.
+ */
+static void prvSetupTxDescriptors( void );
+static void prvSetupRxDescriptors( void );
+
+/*
+ * A task that processes received frames.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Sets up the MAC with the results of an auto-negotiation.
+ */
+static BaseType_t prvSetLinkSpeed( void );
+
+/*
+ * Generates a CRC for a MAC address that is then used to generate a hash index.
+ */
+static uint32_t prvGenerateCRC32( const uint8_t *ucAddress );
+
+/*
+ * Generates a hash index when setting a filter to permit a MAC address.
+ */
+static uint32_t prvGetHashIndex( const uint8_t *ucAddress );
+
+/*
+ * Update the hash table to allow a MAC address.
+ */
+static void prvAddMACAddress( const uint8_t* ucMacAddress );
+
+/*
+ * Sometimes the DMA will report received data as being longer than the actual
+ * received from length. This function checks the reported length and corrects
+ * if if necessary.
+ */
+static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor );
+
+/*-----------------------------------------------------------*/
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx and Tx interrupt is handled, although code is included for other events
+to enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+
+/* Tx descriptors and index. */
+static ENET_ENHTXDESC_T xDMATxDescriptors[ configNUM_TX_DESCRIPTORS ];
+
+/* ulNextFreeTxDescriptor is declared volatile, because it is accessed from
+to different tasks. */
+static volatile uint32_t ulNextFreeTxDescriptor;
+static uint32_t ulTxDescriptorToClear;
+
+/* Rx descriptors and index. */
+static ENET_ENHRXDESC_T xDMARxDescriptors[ configNUM_RX_DESCRIPTORS ];
+static uint32_t ulNextRxDescriptorToProcess;
+
+/* Must be defined externally - the demo applications define this in main.c. */
+extern uint8_t ucMACAddress[ 6 ];
+
+/* The handle of the task that processes Rx packets. The handle is required so
+the task can be notified when new packets arrive. */
+static TaskHandle_t xRxHanderTask = NULL;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ static const uint8_t xLLMNR_MACAddress[] = { '\x01', '\x00', '\x5E', '\x00', '\x00', '\xFC' };
+#endif /* ipconfigUSE_LLMNR == 1 */
+
+/* xTXDescriptorSemaphore is a counting semaphore with
+a maximum count of ETH_TXBUFNB, which is the number of
+DMA TX descriptors. */
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+BaseType_t xReturn = pdPASS;
+
+ /* The interrupt will be turned on when a link is established. */
+ NVIC_DisableIRQ( ETHERNET_IRQn );
+
+ /* Disable receive and transmit DMA processes. */
+ LPC_ETHERNET->DMA_OP_MODE &= ~( DMA_OM_ST | DMA_OM_SR );
+
+ /* Disable packet reception. */
+ LPC_ETHERNET->MAC_CONFIG &= ~( MAC_CFG_RE | MAC_CFG_TE );
+
+ /* Call the LPCOpen function to initialise the hardware. */
+ Chip_ENET_Init( LPC_ETHERNET );
+
+ /* Save MAC address. */
+ Chip_ENET_SetADDR( LPC_ETHERNET, ucMACAddress );
+
+ /* Clear all MAC address hash entries. */
+ LPC_ETHERNET->MAC_HASHTABLE_HIGH = 0;
+ LPC_ETHERNET->MAC_HASHTABLE_LOW = 0;
+
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ prvAddMACAddress( xLLMNR_MACAddress );
+ }
+ #endif /* ipconfigUSE_LLMNR == 1 */
+
+ /* Promiscuous flag (PR) and Receive All flag (RA) set to zero. The
+ registers MAC_HASHTABLE_[LOW|HIGH] will be loaded to allow certain
+ multi-cast addresses. */
+ LPC_ETHERNET->MAC_FRAME_FILTER = MAC_FF_HMC;
+
+ #if( configUSE_RMII == 1 )
+ {
+ if( lpc_phy_init( pdTRUE, prvDelay ) != SUCCESS )
+ {
+ xReturn = pdFAIL;
+ }
+ }
+ #else
+ {
+ #warning This path has not been tested.
+ if( lpc_phy_init( pdFALSE, prvDelay ) != SUCCESS )
+ {
+ xReturn = pdFAIL;
+ }
+ }
+ #endif
+
+ if( xReturn == pdPASS )
+ {
+ /* Guard against the task being created more than once and the
+ descriptors being initialised more than once. */
+ if( xRxHanderTask == NULL )
+ {
+ xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", nwRX_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
+ configASSERT( xReturn );
+ }
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ /* Create a counting semaphore, with a value of 'configNUM_TX_DESCRIPTORS'
+ and a maximum of 'configNUM_TX_DESCRIPTORS'. */
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) configNUM_TX_DESCRIPTORS, ( UBaseType_t ) configNUM_TX_DESCRIPTORS );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+
+ /* Enable MAC interrupts. */
+ LPC_ETHERNET->DMA_INT_EN = nwDMA_INTERRUPT_MASK;
+ }
+
+ if( xReturn != pdFAIL )
+ {
+ /* Auto-negotiate was already started. Wait for it to complete. */
+ xReturn = prvSetLinkSpeed();
+
+ if( xReturn == pdPASS )
+ {
+ /* Initialise the descriptors. */
+ prvSetupTxDescriptors();
+ prvSetupRxDescriptors();
+
+ /* Clear all interrupts. */
+ LPC_ETHERNET->DMA_STAT = DMA_ST_ALL;
+
+ /* Enable receive and transmit DMA processes. */
+ LPC_ETHERNET->DMA_OP_MODE |= DMA_OM_ST | DMA_OM_SR;
+
+ /* Set Receiver / Transmitter Enable. */
+ LPC_ETHERNET->MAC_CONFIG |= MAC_CFG_RE | MAC_CFG_TE;
+
+ /* Start receive polling. */
+ LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
+
+ /* Enable interrupts in the NVIC. */
+ NVIC_SetPriority( ETHERNET_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_EnableIRQ( ETHERNET_IRQn );
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+#define niBUFFER_1_PACKET_SIZE 1536
+
+static __attribute__ ((section("._ramAHB32"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+
+uint8_t *ucRAMBuffer = ucNetworkPackets;
+uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ }
+}
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+static void vClearTXBuffers()
+{
+uint32_t ulLastDescriptor = ulNextFreeTxDescriptor;
+size_t uxCount = ( ( size_t ) configNUM_TX_DESCRIPTORS ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ uint8_t *ucPayLoad;
+#endif
+
+ /* This function is called after a TX-completion interrupt.
+ It will release each Network Buffer used in xNetworkInterfaceOutput().
+ 'uxCount' represents the number of descriptors given to DMA for transmission.
+ After sending a packet, the DMA will clear the 'TDES_OWN' bit. */
+ while( ( uxCount > ( size_t ) 0u ) && ( ( xDMATxDescriptors[ ulTxDescriptorToClear ].CTRLSTAT & TDES_OWN ) == 0 ) )
+ {
+ if( ( ulTxDescriptorToClear == ulLastDescriptor ) && ( uxCount != ( size_t ) configNUM_TX_DESCRIPTORS ) )
+ {
+ break;
+ }
+
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ ucPayLoad = ( uint8_t * )xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD;
+ if( ucPayLoad != NULL )
+ {
+ /* B1ADD points to a pucEthernetBuffer of a Network Buffer descriptor. */
+ pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
+
+ configASSERT( pxNetworkBuffer != NULL );
+
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
+ xDMATxDescriptors[ ulTxDescriptorToClear ].B1ADD = ( uint32_t )0u;
+ }
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ /* Move onto the next descriptor, wrapping if necessary. */
+ ulTxDescriptorToClear++;
+ if( ulTxDescriptorToClear >= configNUM_TX_DESCRIPTORS )
+ {
+ ulTxDescriptorToClear = 0;
+ }
+
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+}
+
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
+{
+BaseType_t xReturn = pdFAIL;
+const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50 );
+
+ /* Attempt to obtain access to a Tx descriptor. */
+ do
+ {
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ break;
+ }
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ /* Time-out waiting for a free TX descriptor. */
+ break;
+ }
+
+ /* If the descriptor is still owned by the DMA it can't be used. */
+ if( ( xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT & TDES_OWN ) != 0 )
+ {
+ /* The semaphore was taken, the TX DMA-descriptor is still not available.
+ Actually that should not occur, the 'TDES_OWN' was already confirmed low in vClearTXBuffers(). */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+ else
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* bReleaseAfterSend should always be set when using the zero
+ copy driver. */
+ configASSERT( bReleaseAfterSend != pdFALSE );
+
+ /* The DMA's descriptor to point directly to the data in the
+ network buffer descriptor. The data is not copied. */
+ xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD = ( uint32_t ) pxDescriptor->pucEthernetBuffer;
+
+ /* The DMA descriptor will 'own' this Network Buffer,
+ until it has been sent. So don't release it now. */
+ bReleaseAfterSend = false;
+ }
+ #else
+ {
+ /* The data is copied from the network buffer descriptor into
+ the DMA's descriptor. */
+ memcpy( ( void * ) xDMATxDescriptors[ ulNextFreeTxDescriptor ].B1ADD, ( void * ) pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength );
+ }
+ #endif
+
+ xDMATxDescriptors[ ulNextFreeTxDescriptor ].BSIZE = ( uint32_t ) TDES_ENH_BS1( pxDescriptor->xDataLength );
+
+ /* This descriptor is given back to the DMA. */
+ xDMATxDescriptors[ ulNextFreeTxDescriptor ].CTRLSTAT |= TDES_OWN;
+
+ /* Ensure the DMA is polling Tx descriptors. */
+ LPC_ETHERNET->DMA_TRANS_POLL_DEMAND = 1;
+
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+
+ /* Move onto the next descriptor, wrapping if necessary. */
+ ulNextFreeTxDescriptor++;
+ if( ulNextFreeTxDescriptor >= configNUM_TX_DESCRIPTORS )
+ {
+ ulNextFreeTxDescriptor = 0;
+ }
+
+ /* The Tx has been initiated. */
+ xReturn = pdPASS;
+ }
+ } while( 0 );
+
+ /* The buffer has been sent so can be released. */
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvDelay( uint32_t ulMilliSeconds )
+{
+ /* Ensure the scheduler was started before attempting to use the scheduler to
+ create a delay. */
+ configASSERT( xTaskGetSchedulerState() == taskSCHEDULER_RUNNING );
+
+ vTaskDelay( pdMS_TO_TICKS( ulMilliSeconds ) );
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupTxDescriptors( void )
+{
+BaseType_t x;
+
+ /* Start with Tx descriptors clear. */
+ memset( ( void * ) xDMATxDescriptors, 0, sizeof( xDMATxDescriptors ) );
+
+ /* Index to the next Tx descriptor to use. */
+ ulNextFreeTxDescriptor = 0ul;
+
+ /* Index to the next Tx descriptor to clear ( after transmission ). */
+ ulTxDescriptorToClear = 0ul;
+
+ for( x = 0; x < configNUM_TX_DESCRIPTORS; x++ )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Nothing to do, B1ADD will be set when data is ready to transmit.
+ Currently the memset above will have set it to NULL. */
+ }
+ #else
+ {
+ /* Allocate a buffer to the Tx descriptor. This is the most basic
+ way of creating a driver as the data is then copied into the
+ buffer. */
+ xDMATxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
+
+ /* Use an assert to check the allocation as +TCP applications will
+ often not use a malloc() failed hook as the TCP stack will recover
+ from allocation failures. */
+ configASSERT( xDMATxDescriptors[ x ].B1ADD );
+ }
+ #endif
+
+ /* Buffers hold an entire frame so all buffers are both the start and
+ end of a frame. */
+ /* TDES_ENH_TCH Second Address Chained. */
+ /* TDES_ENH_CIC(n) Checksum Insertion Control, tried but it does not work for the LPC18xx... */
+ /* TDES_ENH_FS First Segment. */
+ /* TDES_ENH_LS Last Segment. */
+ /* TDES_ENH_IC Interrupt on Completion. */
+ xDMATxDescriptors[ x ].CTRLSTAT = TDES_ENH_TCH | TDES_ENH_CIC( 3 ) | TDES_ENH_FS | TDES_ENH_LS | TDES_ENH_IC;
+ xDMATxDescriptors[ x ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ x + 1 ];
+ }
+
+ xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].CTRLSTAT |= TDES_ENH_TER;
+ xDMATxDescriptors[ configNUM_TX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &xDMATxDescriptors[ 0 ];
+
+ /* Point the DMA to the base of the descriptor list. */
+ LPC_ETHERNET->DMA_TRANS_DES_ADDR = ( uint32_t ) xDMATxDescriptors;
+}
+/*-----------------------------------------------------------*/
+
+static void prvSetupRxDescriptors( void )
+{
+BaseType_t x;
+#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+#endif
+
+ /* Index to the next Rx descriptor to use. */
+ ulNextRxDescriptorToProcess = 0;
+
+ /* Clear RX descriptor list. */
+ memset( ( void * ) xDMARxDescriptors, 0, sizeof( xDMARxDescriptors ) );
+
+ for( x = 0; x < configNUM_RX_DESCRIPTORS; x++ )
+ {
+ /* Allocate a buffer of the largest possible frame size as it is not
+ known what size received frames will be. */
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, 0 );
+
+ /* During start-up there should be enough Network Buffers available,
+ so it is safe to use configASSERT().
+ In case this assert fails, please check: configNUM_RX_DESCRIPTORS,
+ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, and in case BufferAllocation_2.c
+ is included, check the amount of available heap. */
+ configASSERT( pxNetworkBuffer != NULL );
+
+ /* Pass the actual buffer to DMA. */
+ xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pxNetworkBuffer->pucEthernetBuffer;
+ }
+ #else
+ {
+ /* All DMA descriptors are populated with permanent memory blocks.
+ Their contents will be copy to Network Buffers. */
+ xDMARxDescriptors[ x ].B1ADD = ( uint32_t ) pvPortMalloc( ipTOTAL_ETHERNET_FRAME_SIZE );
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+
+ /* Use an assert to check the allocation as +TCP applications will often
+ not use a malloc failed hook as the TCP stack will recover from
+ allocation failures. */
+ configASSERT( xDMARxDescriptors[ x ].B1ADD );
+
+ xDMARxDescriptors[ x ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ x + 1 ] );
+ xDMARxDescriptors[ x ].CTRL = ( uint32_t ) RDES_ENH_BS1( ipTOTAL_ETHERNET_FRAME_SIZE ) | RDES_ENH_RCH;
+
+ /* The descriptor is available for use by the DMA. */
+ xDMARxDescriptors[ x ].STATUS = RDES_OWN;
+ }
+
+ /* RDES_ENH_RER Receive End of Ring. */
+ xDMARxDescriptors[ ( configNUM_RX_DESCRIPTORS - 1 ) ].CTRL |= RDES_ENH_RER;
+ xDMARxDescriptors[ configNUM_RX_DESCRIPTORS - 1 ].B2ADD = ( uint32_t ) &( xDMARxDescriptors[ 0 ] );
+
+ /* Point the DMA to the base of the descriptor list. */
+ LPC_ETHERNET->DMA_REC_DES_ADDR = ( uint32_t ) xDMARxDescriptors;
+}
+/*-----------------------------------------------------------*/
+configPLACE_IN_SECTION_RAM
+static void prvRemoveTrailingBytes( NetworkBufferDescriptor_t *pxDescriptor )
+{
+size_t xExpectedLength;
+IPPacket_t *pxIPPacket;
+
+ pxIPPacket = ( IPPacket_t * ) pxDescriptor->pucEthernetBuffer;
+ /* Look at the actual length of the packet, translate it to a host-endial notation. */
+ xExpectedLength = sizeof( EthernetHeader_t ) + ( size_t ) FreeRTOS_htons( pxIPPacket->xIPHeader.usLength );
+
+ if( xExpectedLength == ( pxDescriptor->xDataLength + 4 ) )
+ {
+ pxDescriptor->xDataLength -= 4;
+ }
+ else
+ {
+ if( pxDescriptor->xDataLength > xExpectedLength )
+ {
+ pxDescriptor->xDataLength = ( size_t ) xExpectedLength;
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+configPLACE_IN_SECTION_RAM
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xReturn;
+
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
+ {
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+uint32_t ulDataAvailable;
+
+configPLACE_IN_SECTION_RAM
+static BaseType_t prvNetworkInterfaceInput()
+{
+BaseType_t xResult = pdFALSE;
+uint32_t ulStatus;
+eFrameProcessingResult_t eResult;
+const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+const UBaseType_t uxMinimumBuffersRemaining = 3UL;
+uint16_t usLength;
+NetworkBufferDescriptor_t *pxDescriptor;
+#if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ NetworkBufferDescriptor_t *pxNewDescriptor;
+#endif /* ipconfigZERO_COPY_RX_DRIVER */
+#if( ipconfigUSE_LINKED_RX_MESSAGES == 0 )
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+#endif
+
+ /* Process each descriptor that is not still in use by the DMA. */
+ ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
+ if( ( ulStatus & RDES_OWN ) == 0 )
+ {
+ /* Check packet for errors */
+ if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 )
+ {
+ /* There is some reception error. */
+ intCount[ 3 ]++;
+ /* Clear error bits. */
+ ulStatus &= ~( ( uint32_t )nwRX_STATUS_ERROR_BITS );
+ }
+ else
+ {
+ xResult++;
+
+ eResult = ipCONSIDER_FRAME_FOR_PROCESSING( ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD ) );
+ if( eResult == eProcessBuffer )
+ {
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) == 0 )
+ {
+ ulPHYLinkStatus |= PHY_LINK_CONNECTED;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (message received)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
+ }
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
+ {
+ pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE, xDescriptorWaitTime );
+ }
+ else
+ {
+ /* Too risky to allocate a new Network Buffer. */
+ pxNewDescriptor = NULL;
+ }
+ if( pxNewDescriptor != NULL )
+ #else
+ if( uxGetNumberOfFreeNetworkBuffers() > uxMinimumBuffersRemaining )
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+ {
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ const uint8_t *pucBuffer;
+ #endif
+
+ /* Get the actual length. */
+ usLength = RDES_FLMSK( ulStatus );
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ /* Replace the character buffer 'B1ADD'. */
+ pucBuffer = ( const uint8_t * const ) ( xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD );
+ xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD = ( uint32_t ) pxNewDescriptor->pucEthernetBuffer;
+
+ /* 'B1ADD' contained the address of a 'pucEthernetBuffer' that
+ belongs to a Network Buffer. Find the original Network Buffer. */
+ pxDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
+ /* This zero-copy driver makes sure that every 'xDMARxDescriptors' contains
+ a reference to a Network Buffer at any time.
+ In case it runs out of Network Buffers, a DMA buffer won't be replaced,
+ and the received messages is dropped. */
+ configASSERT( pxDescriptor != NULL );
+ }
+ #else
+ {
+ /* Create a buffer of exactly the required length. */
+ pxDescriptor = pxGetNetworkBufferWithDescriptor( usLength, xDescriptorWaitTime );
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+
+ if( pxDescriptor != NULL )
+ {
+ pxDescriptor->xDataLength = ( size_t ) usLength;
+ #if( ipconfigZERO_COPY_RX_DRIVER == 0 )
+ {
+ /* Copy the data into the allocated buffer. */
+ memcpy( ( void * ) pxDescriptor->pucEthernetBuffer, ( void * ) xDMARxDescriptors[ ulNextRxDescriptorToProcess ].B1ADD, usLength );
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+ /* It is possible that more data was copied than
+ actually makes up the frame. If this is the case
+ adjust the length to remove any trailing bytes. */
+ prvRemoveTrailingBytes( pxDescriptor );
+
+ /* Pass the data to the TCP/IP task for processing. */
+ xRxEvent.pvData = ( void * ) pxDescriptor;
+ if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
+ {
+ /* Could not send the descriptor into the TCP/IP
+ stack, it must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ else
+ {
+ iptraceNETWORK_INTERFACE_RECEIVE();
+
+ /* The data that was available at the top of this
+ loop has been sent, so is no longer available. */
+ ulDataAvailable = pdFALSE;
+ }
+ }
+ }
+ }
+ else
+ {
+ /* The packet is discarded as uninteresting. */
+ ulDataAvailable = pdFALSE;
+ }
+ /* Got here because received data was sent to the IP task or the
+ data contained an error and was discarded. Give the descriptor
+ back to the DMA. */
+ xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS = ulStatus | RDES_OWN;
+
+ /* Move onto the next descriptor. */
+ ulNextRxDescriptorToProcess++;
+ if( ulNextRxDescriptorToProcess >= configNUM_RX_DESCRIPTORS )
+ {
+ ulNextRxDescriptorToProcess = 0;
+ }
+
+ ulStatus = xDMARxDescriptors[ ulNextRxDescriptorToProcess ].STATUS;
+ } /* if( ( ulStatus & nwRX_STATUS_ERROR_BITS ) != 0 ) */
+ } /* if( ( ulStatus & RDES_OWN ) == 0 ) */
+
+ /* Restart receive polling. */
+ LPC_ETHERNET->DMA_REC_POLL_DEMAND = 1;
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+void NETWORK_IRQHandler( void )
+{
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+uint32_t ulDMAStatus;
+const uint32_t ulRxInterruptMask =
+ DMA_ST_RI | /* Receive interrupt */
+ DMA_ST_RU; /* Receive buffer unavailable */
+const uint32_t ulTxInterruptMask =
+ DMA_ST_TI | /* Transmit interrupt */
+ DMA_ST_TPS; /* Transmit process stopped */
+
+ configASSERT( xRxHanderTask );
+
+ /* Get pending interrupts. */
+ ulDMAStatus = LPC_ETHERNET->DMA_STAT;
+
+ /* RX group interrupt(s). */
+ if( ( ulDMAStatus & ulRxInterruptMask ) != 0x00 )
+ {
+ /* Remember that an RX event has happened. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
+ intCount[ 0 ]++;
+ }
+
+ /* TX group interrupt(s). */
+ if( ( ulDMAStatus & ulTxInterruptMask ) != 0x00 )
+ {
+ /* Remember that a TX event has happened. */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
+ intCount[ 1 ]++;
+ }
+
+ /* Test for 'Abnormal interrupt summary'. */
+ if( ( ulDMAStatus & DMA_ST_AIE ) != 0x00 )
+ {
+ /* The trace macro must be written such that it can be called from
+ an interrupt. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+
+ /* Clear pending interrupts */
+ LPC_ETHERNET->DMA_STAT = ulDMAStatus;
+
+ /* Context switch needed? */
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvSetLinkSpeed( void )
+{
+BaseType_t xReturn = pdFAIL;
+TickType_t xTimeOnEntering;
+uint32_t ulPhyStatus;
+const TickType_t xAutoNegotiateDelay = pdMS_TO_TICKS( 5000UL );
+
+ /* Ensure polling does not starve lower priority tasks by temporarily
+ setting the priority of this task to that of the idle task. */
+ vTaskPrioritySet( NULL, tskIDLE_PRIORITY );
+
+ xTimeOnEntering = xTaskGetTickCount();
+ do
+ {
+ ulPhyStatus = lpcPHYStsPoll();
+ if( ( ulPhyStatus & PHY_LINK_CONNECTED ) != 0x00 )
+ {
+ /* Set interface speed and duplex. */
+ if( ( ulPhyStatus & PHY_LINK_SPEED100 ) != 0x00 )
+ {
+ Chip_ENET_SetSpeed( LPC_ETHERNET, 1 );
+ }
+ else
+ {
+ Chip_ENET_SetSpeed( LPC_ETHERNET, 0 );
+ }
+
+ if( ( ulPhyStatus & PHY_LINK_FULLDUPLX ) != 0x00 )
+ {
+ Chip_ENET_SetDuplex( LPC_ETHERNET, true );
+ }
+ else
+ {
+ Chip_ENET_SetDuplex( LPC_ETHERNET, false );
+ }
+
+ xReturn = pdPASS;
+ break;
+ }
+ } while( ( xTaskGetTickCount() - xTimeOnEntering ) < xAutoNegotiateDelay );
+
+ /* Reset the priority of this task back to its original value. */
+ vTaskPrioritySet( NULL, ipconfigIP_TASK_PRIORITY );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvGenerateCRC32( const uint8_t *ucAddress )
+{
+unsigned int j;
+const uint32_t Polynomial = 0xEDB88320;
+uint32_t crc = ~0ul;
+const uint8_t *pucCurrent = ( const uint8_t * ) ucAddress;
+const uint8_t *pucLast = pucCurrent + 6;
+
+ /* Calculate normal CRC32 */
+ while( pucCurrent < pucLast )
+ {
+ crc ^= *( pucCurrent++ );
+ for( j = 0; j < 8; j++ )
+ {
+ if( ( crc & 1 ) != 0 )
+ {
+ crc = (crc >> 1) ^ Polynomial;
+ }
+ else
+ {
+ crc >>= 1;
+ }
+ }
+ }
+ return ~crc;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvGetHashIndex( const uint8_t *ucAddress )
+{
+uint32_t ulCrc = prvGenerateCRC32( ucAddress );
+uint32_t ulIndex = 0ul;
+BaseType_t xCount = 6;
+
+ /* Take the lowest 6 bits of the CRC32 and reverse them */
+ while( xCount-- )
+ {
+ ulIndex <<= 1;
+ ulIndex |= ( ulCrc & 1 );
+ ulCrc >>= 1;
+ }
+
+ /* This is the has value of 'ucAddress' */
+ return ulIndex;
+}
+/*-----------------------------------------------------------*/
+
+static void prvAddMACAddress( const uint8_t* ucMacAddress )
+{
+BaseType_t xIndex;
+
+ xIndex = prvGetHashIndex( ucMacAddress );
+ if( xIndex >= 32 )
+ {
+ LPC_ETHERNET->MAC_HASHTABLE_HIGH |= ( 1u << ( xIndex - 32 ) );
+ }
+ else
+ {
+ LPC_ETHERNET->MAC_HASHTABLE_LOW |= ( 1u << xIndex );
+ }
+}
+/*-----------------------------------------------------------*/
+
+configPLACE_IN_SECTION_RAM
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0;
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t ulStatus;
+const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
+
+ /* Remove compiler warning about unused parameter. */
+ ( void ) pvParameters;
+
+ /* A possibility to set some additional task properties. */
+ iptraceEMAC_TASK_STARTING();
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
+ if( uxLastMinBufferCount != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
+ }
+
+ #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+
+ ulTaskNotifyTake( pdTRUE, xBlockTime );
+
+ xResult = ( BaseType_t ) 0;
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ {
+ /* Check if DMA packets have been delivered. */
+ vClearTXBuffers();
+ }
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ xResult = prvNetworkInterfaceInput();
+ if( xResult > 0 )
+ {
+ while( prvNetworkInterfaceInput() > 0 )
+ {
+ }
+ }
+ }
+
+ if( xResult > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ ulStatus = lpcPHYStsPoll();
+
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != ( ulStatus & PHY_LINK_CONNECTED ) )
+ {
+ ulPHYLinkStatus = ulStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d (polled PHY)\n", ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & PHY_LINK_CONNECTED ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/ReadMe.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/ReadMe.txt
index 86a7f9121..cde8e0e3d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/ReadMe.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/LPC18xx/ReadMe.txt
@@ -1,3 +1,3 @@
-NetworkInterface.c:
-Requires NXP's LPCOpen library and was developed on an LPC1830 and LPC1835 Xplorer
+NetworkInterface.c:
+Requires NXP's LPCOpen library and was developed on an LPC1830 and LPC1835 Xplorer
boards from NGX. \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c
index e759141cc..6b926c811 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/NetworkInterface.c
@@ -1,331 +1,331 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "list.h"
-#include "queue.h"
-#include "semphr.h"
-#include "task.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-
-#include "m480_eth.h"
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to twice
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-#endif
-
-
-static SemaphoreHandle_t xTXMutex = NULL;
-
-/* The handle of the task that processes Rx packets. The handle is required so
-the task can be notified when new packets arrive. */
-static TaskHandle_t xRxHanderTask = NULL;
-static TimerHandle_t xPhyHandlerTask = NULL;
-/*
- * A task that processes received frames.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-static void prvPhyTmrCallback( TimerHandle_t xTimer );
-
-/* The size of each buffer when BufferAllocation_1 is used:
-http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
-
-#define niBUFFER_1_PACKET_SIZE 1536
-#ifdef __ICCARM__
-#pragma data_alignment=4
-static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ]
-#else
-static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ((aligned(4)));
-#endif
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- uint8_t hwaddr[6];
- BaseType_t xReturn = pdPASS;
-
- /* Init ETH */
- numaker_mac_address(hwaddr);
- FreeRTOS_UpdateMACAddress(hwaddr);
- FreeRTOS_printf( ("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", hwaddr[0], hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]) );
- /* Enable clock & set EMAC configuration */
- /* Enable MAC and DMA transmission and reception */
- if( numaker_eth_init(hwaddr) < 0)
- {
- xReturn = pdFAIL;
- } else {
- xReturn = pdPASS;
- /* Guard against the task being created more than once and the
- descriptors being initialized more than once. */
- /* Timer task to monitor PHY Link status */
- if( xPhyHandlerTask == NULL )
- {
- xPhyHandlerTask = xTimerCreate( "TimerPhy", pdMS_TO_TICKS( 1000 ), pdTRUE, 0, prvPhyTmrCallback );
- configASSERT(xPhyHandlerTask);
- xReturn = xTimerStart( xPhyHandlerTask, 0 ) ;
- configASSERT( xReturn );
- }
- /* Rx task */
- if( xRxHanderTask == NULL )
- {
- xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
- configASSERT( xReturn );
- }
-
- if( xTXMutex == NULL )
- {
- xTXMutex = xSemaphoreCreateMutex();
- configASSERT( xTXMutex );
- }
- }
-
- NVIC_SetPriority( EMAC_RX_IRQn, configMAC_INTERRUPT_PRIORITY );
- NVIC_SetPriority( EMAC_TX_IRQn, configMAC_INTERRUPT_PRIORITY );
-
- numaker_eth_enable_interrupts();
-
- FreeRTOS_printf( ("ETH-RX priority:%d\n",NVIC_GetPriority( EMAC_RX_IRQn)) );
-
- return xReturn;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t xReleaseAfterSend )
-{
- uint8_t *buffer=NULL;
-// FreeRTOS_printf(("<-- dataLength=%d\n",pxDescriptor->xDataLength));
- if( pxDescriptor->xDataLength >= PACKET_BUFFER_SIZE )
- {
- FreeRTOS_printf(("TX buffer length %d over %d\n", pxDescriptor->xDataLength, PACKET_BUFFER_SIZE));
- return pdFALSE;
- }
-
- buffer = numaker_eth_get_tx_buf();
- if( buffer == NULL )
- {
- NU_DEBUGF(("Eth TX slots are busy\n"));
- return pdFALSE;
- }
-
- /* Get exclusive access */
- xSemaphoreTake(xTXMutex, portMAX_DELAY);
- NU_DEBUGF(("%s ... buffer=0x%x\r\n",__FUNCTION__, buffer));
- //SendData: pt = pxDescriptor->pucBuffer, length = pxDescriptor->xDataLength
- memcpy(buffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
- numaker_eth_trigger_tx(pxDescriptor->xDataLength, NULL);
- /* Call the standard trace macro to log the send event. */
- iptraceNETWORK_INTERFACE_TRANSMIT();
-
- if( xReleaseAfterSend != pdFALSE )
- {
- /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
- buffer. The Ethernet buffer is therefore no longer needed, and must be
- freed for re-use. */
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- xSemaphoreGive(xTXMutex);
-
- return pdTRUE;
-}
-
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-
- uint8_t *ucRAMBuffer = ucNetworkPackets;
- uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-
-
-BaseType_t xGetPhyLinkStatus( void )
-{
- BaseType_t xReturn;
-
- if( numaker_eth_link_ok() )
- {
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- return xReturn;
-}
-
-static void prvPhyTmrCallback( TimerHandle_t xTimer )
-{
- IPStackEvent_t xRxEvent;
- static BaseType_t lastLink = pdFAIL;
- BaseType_t currLink = xGetPhyLinkStatus();
- if( currLink != lastLink )
- {
- FreeRTOS_printf(("PHY Link %s\n", (currLink) ? "Up" : "Down"));
- if( !currLink )
- {
- xRxEvent.eEventType = eNetworkDownEvent;
- xSendEventStructToIPTask( &xRxEvent, 0 );
- }
- lastLink = currLink;
- }
-
-}
-
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
- TimeOut_t xPhyTime;
- TickType_t xPhyRemTime;
- UBaseType_t uxLastMinBufferCount = 0;
- UBaseType_t uxCurrentCount;
- BaseType_t xResult = 0;
- uint32_t ulStatus;
- uint16_t dataLength = 0;
- uint8_t *buffer = NULL;
- NetworkBufferDescriptor_t *pxBufferDescriptor = NULL;
- IPStackEvent_t xRxEvent;
- const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
- /* A possibility to set some additional task properties. */
-
- for( ;; )
- {
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
- while(1)
- {
- /* get received frame */
- if ( numaker_eth_get_rx_buf(&dataLength, &buffer) != 0) {
- /* The event was lost because a network buffer was not available.
- Call the standard trace macro to log the occurrence. */
- iptraceETHERNET_RX_EVENT_LOST();
- break;
- }
-
- /* Allocate a network buffer descriptor that points to a buffer
- large enough to hold the received frame. As this is the simple
- rather than efficient example the received data will just be copied
- into this buffer. */
-
- pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( PACKET_BUFFER_SIZE, 0 );
-
- if( pxBufferDescriptor != NULL )
- {
- memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer, dataLength );
-// FreeRTOS_printf(("--> dataLength=%d\n",dataLength));
- pxBufferDescriptor->xDataLength = dataLength;
- } else {
- numaker_eth_rx_next();
- iptraceETHERNET_RX_EVENT_LOST();
- break;
- }
- /* The event about to be sent to the TCP/IP is an Rx event. */
- xRxEvent.eEventType = eNetworkRxEvent;
-
- /* pvData is used to point to the network buffer descriptor that
- now references the received data. */
- xRxEvent.pvData = ( void * ) pxBufferDescriptor;
-
- /* Send the data to the TCP/IP stack. */
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- {
- /* The buffer could not be sent to the IP task so the buffer
- must be released. */
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
-
- /* Make a call to the standard trace macro to log the
- occurrence. */
-
- iptraceETHERNET_RX_EVENT_LOST();
- } else
- {
- /* The message was successfully sent to the TCP/IP stack.
- Call the standard trace macro to log the occurrence. */
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
- numaker_eth_rx_next();
- }
- numaker_eth_trigger_rx();
- }
-}
-
-void xNetworkCallback(char event)
-{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- switch (event)
- {
- case 'R': //For RX event
- /* Wakeup the prvEMACHandlerTask. */
- if( xRxHanderTask != NULL )
- {
- vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
- break;
- case 'T': //For TX event
- // ack of tx done, no-op in this stage
- break;
- default:
- break;
- }
-}
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+#include "queue.h"
+#include "semphr.h"
+#include "task.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+
+#include "m480_eth.h"
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to twice
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
+#endif
+
+
+static SemaphoreHandle_t xTXMutex = NULL;
+
+/* The handle of the task that processes Rx packets. The handle is required so
+the task can be notified when new packets arrive. */
+static TaskHandle_t xRxHanderTask = NULL;
+static TimerHandle_t xPhyHandlerTask = NULL;
+/*
+ * A task that processes received frames.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+static void prvPhyTmrCallback( TimerHandle_t xTimer );
+
+/* The size of each buffer when BufferAllocation_1 is used:
+http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
+
+#define niBUFFER_1_PACKET_SIZE 1536
+#ifdef __ICCARM__
+#pragma data_alignment=4
+static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ]
+#else
+static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ((aligned(4)));
+#endif
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ uint8_t hwaddr[6];
+ BaseType_t xReturn = pdPASS;
+
+ /* Init ETH */
+ numaker_mac_address(hwaddr);
+ FreeRTOS_UpdateMACAddress(hwaddr);
+ FreeRTOS_printf( ("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", hwaddr[0], hwaddr[1],hwaddr[2],hwaddr[3],hwaddr[4],hwaddr[5]) );
+ /* Enable clock & set EMAC configuration */
+ /* Enable MAC and DMA transmission and reception */
+ if( numaker_eth_init(hwaddr) < 0)
+ {
+ xReturn = pdFAIL;
+ } else {
+ xReturn = pdPASS;
+ /* Guard against the task being created more than once and the
+ descriptors being initialized more than once. */
+ /* Timer task to monitor PHY Link status */
+ if( xPhyHandlerTask == NULL )
+ {
+ xPhyHandlerTask = xTimerCreate( "TimerPhy", pdMS_TO_TICKS( 1000 ), pdTRUE, 0, prvPhyTmrCallback );
+ configASSERT(xPhyHandlerTask);
+ xReturn = xTimerStart( xPhyHandlerTask, 0 ) ;
+ configASSERT( xReturn );
+ }
+ /* Rx task */
+ if( xRxHanderTask == NULL )
+ {
+ xReturn = xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xRxHanderTask );
+ configASSERT( xReturn );
+ }
+
+ if( xTXMutex == NULL )
+ {
+ xTXMutex = xSemaphoreCreateMutex();
+ configASSERT( xTXMutex );
+ }
+ }
+
+ NVIC_SetPriority( EMAC_RX_IRQn, configMAC_INTERRUPT_PRIORITY );
+ NVIC_SetPriority( EMAC_TX_IRQn, configMAC_INTERRUPT_PRIORITY );
+
+ numaker_eth_enable_interrupts();
+
+ FreeRTOS_printf( ("ETH-RX priority:%d\n",NVIC_GetPriority( EMAC_RX_IRQn)) );
+
+ return xReturn;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t xReleaseAfterSend )
+{
+ uint8_t *buffer=NULL;
+// FreeRTOS_printf(("<-- dataLength=%d\n",pxDescriptor->xDataLength));
+ if( pxDescriptor->xDataLength >= PACKET_BUFFER_SIZE )
+ {
+ FreeRTOS_printf(("TX buffer length %d over %d\n", pxDescriptor->xDataLength, PACKET_BUFFER_SIZE));
+ return pdFALSE;
+ }
+
+ buffer = numaker_eth_get_tx_buf();
+ if( buffer == NULL )
+ {
+ NU_DEBUGF(("Eth TX slots are busy\n"));
+ return pdFALSE;
+ }
+
+ /* Get exclusive access */
+ xSemaphoreTake(xTXMutex, portMAX_DELAY);
+ NU_DEBUGF(("%s ... buffer=0x%x\r\n",__FUNCTION__, buffer));
+ //SendData: pt = pxDescriptor->pucBuffer, length = pxDescriptor->xDataLength
+ memcpy(buffer, pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength);
+ numaker_eth_trigger_tx(pxDescriptor->xDataLength, NULL);
+ /* Call the standard trace macro to log the send event. */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
+ buffer. The Ethernet buffer is therefore no longer needed, and must be
+ freed for re-use. */
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ xSemaphoreGive(xTXMutex);
+
+ return pdTRUE;
+}
+
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+
+ uint8_t *ucRAMBuffer = ucNetworkPackets;
+ uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ }
+}
+
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+ BaseType_t xReturn;
+
+ if( numaker_eth_link_ok() )
+ {
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+
+static void prvPhyTmrCallback( TimerHandle_t xTimer )
+{
+ IPStackEvent_t xRxEvent;
+ static BaseType_t lastLink = pdFAIL;
+ BaseType_t currLink = xGetPhyLinkStatus();
+ if( currLink != lastLink )
+ {
+ FreeRTOS_printf(("PHY Link %s\n", (currLink) ? "Up" : "Down"));
+ if( !currLink )
+ {
+ xRxEvent.eEventType = eNetworkDownEvent;
+ xSendEventStructToIPTask( &xRxEvent, 0 );
+ }
+ lastLink = currLink;
+ }
+
+}
+
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+ TimeOut_t xPhyTime;
+ TickType_t xPhyRemTime;
+ UBaseType_t uxLastMinBufferCount = 0;
+ UBaseType_t uxCurrentCount;
+ BaseType_t xResult = 0;
+ uint32_t ulStatus;
+ uint16_t dataLength = 0;
+ uint8_t *buffer = NULL;
+ NetworkBufferDescriptor_t *pxBufferDescriptor = NULL;
+ IPStackEvent_t xRxEvent;
+ const TickType_t xBlockTime = pdMS_TO_TICKS( 5000ul );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+ /* A possibility to set some additional task properties. */
+
+ for( ;; )
+ {
+ uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
+ if( uxLastMinBufferCount != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
+ }
+
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, portMAX_DELAY );
+ while(1)
+ {
+ /* get received frame */
+ if ( numaker_eth_get_rx_buf(&dataLength, &buffer) != 0) {
+ /* The event was lost because a network buffer was not available.
+ Call the standard trace macro to log the occurrence. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ break;
+ }
+
+ /* Allocate a network buffer descriptor that points to a buffer
+ large enough to hold the received frame. As this is the simple
+ rather than efficient example the received data will just be copied
+ into this buffer. */
+
+ pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( PACKET_BUFFER_SIZE, 0 );
+
+ if( pxBufferDescriptor != NULL )
+ {
+ memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer, dataLength );
+// FreeRTOS_printf(("--> dataLength=%d\n",dataLength));
+ pxBufferDescriptor->xDataLength = dataLength;
+ } else {
+ numaker_eth_rx_next();
+ iptraceETHERNET_RX_EVENT_LOST();
+ break;
+ }
+ /* The event about to be sent to the TCP/IP is an Rx event. */
+ xRxEvent.eEventType = eNetworkRxEvent;
+
+ /* pvData is used to point to the network buffer descriptor that
+ now references the received data. */
+ xRxEvent.pvData = ( void * ) pxBufferDescriptor;
+
+ /* Send the data to the TCP/IP stack. */
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ {
+ /* The buffer could not be sent to the IP task so the buffer
+ must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+
+ /* Make a call to the standard trace macro to log the
+ occurrence. */
+
+ iptraceETHERNET_RX_EVENT_LOST();
+ } else
+ {
+ /* The message was successfully sent to the TCP/IP stack.
+ Call the standard trace macro to log the occurrence. */
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+ numaker_eth_rx_next();
+ }
+ numaker_eth_trigger_rx();
+ }
+}
+
+void xNetworkCallback(char event)
+{
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ switch (event)
+ {
+ case 'R': //For RX event
+ /* Wakeup the prvEMACHandlerTask. */
+ if( xRxHanderTask != NULL )
+ {
+ vTaskNotifyGiveFromISR( xRxHanderTask, &xHigherPriorityTaskWoken );
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ }
+ break;
+ case 'T': //For TX event
+ // ack of tx done, no-op in this stage
+ break;
+ default:
+ break;
+ }
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c
index 2d45661d0..cf862da3e 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.c
@@ -1,448 +1,448 @@
-/**************************************************************************//**
- * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Nuvoton Technology Corp. 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
-*****************************************************************************/
-#include "FreeRTOS.h"
-#include "list.h"
-#include "FreeRTOS_IP.h"
-
-#include "m480_eth.h"
-
-#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
-#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
-#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
-#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
-#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
-#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
-
-
-struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-#ifdef __ICCARM__
-#pragma data_alignment=4
-struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
-struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
-uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
-uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
-#else
-struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
-uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
-uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
-#endif
-struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
-
-
-// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
-// Assume we want to set each tick to 100ns.
-// Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
-// Addend register = 2^32 * tick_freq / (84MHz), where tick_freq = (2^31 / 215) MHz
-// From above equation, addend register = 2^63 / (84M * 215) ~= 510707200 = 0x1E70C600
-
-
-
-static void mdio_write(uint8_t addr, uint8_t reg, uint16_t val)
-{
-
- EMAC->MIIMDAT = val;
- EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
-
- while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
-
-}
-
-
-static uint16_t mdio_read(uint8_t addr, uint8_t reg)
-{
- EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
- while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
-
- return(EMAC->MIIMDAT);
-}
-
-static int reset_phy(void)
-{
-
- uint16_t reg;
- uint32_t delayCnt;
-
-
- mdio_write(CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET);
-
- delayCnt = 2000;
- while(delayCnt-- > 0) {
- if((mdio_read(CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0)
- break;
-
- }
-
- if(delayCnt == 0) {
- NU_DEBUGF(("Reset phy failed\n"));
- return(-1);
- }
-
- mdio_write(CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA |
- ADVERTISE_10HALF |
- ADVERTISE_10FULL |
- ADVERTISE_100HALF |
- ADVERTISE_100FULL);
-
- reg = mdio_read(CONFIG_PHY_ADDR, MII_BMCR);
- mdio_write(CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART);
-
- delayCnt = 200000;
- while(delayCnt-- > 0) {
- if((mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
- == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
- break;
- }
-
- if(delayCnt == 0) {
- NU_DEBUGF(("AN failed. Set to 100 FULL\n"));
- EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- return(-1);
- } else {
- reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
-
- if(reg & ADVERTISE_100FULL) {
- NU_DEBUGF(("100 full\n"));
- EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- } else if(reg & ADVERTISE_100HALF) {
- NU_DEBUGF(("100 half\n"));
- EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
- } else if(reg & ADVERTISE_10FULL) {
- NU_DEBUGF(("10 full\n"));
- EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
- } else {
- NU_DEBUGF(("10 half\n"));
- EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
- }
- }
- FreeRTOS_printf(("PHY ID 1:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID1)));
- FreeRTOS_printf(("PHY ID 2:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID2)));
-
- return(0);
-}
-
-
-static void init_tx_desc(void)
-{
- uint32_t i;
-
-
- cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
-
- for(i = 0; i < TX_DESCRIPTOR_NUM; i++) {
- tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
- tx_desc[i].buf = &tx_buf[i][0];
- tx_desc[i].status2 = 0;
- tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
-
- }
- EMAC->TXDSA = (unsigned int)&tx_desc[0];
- return;
-}
-
-static void init_rx_desc(void)
-{
- uint32_t i;
-
-
- cur_rx_desc_ptr = &rx_desc[0];
-
- for(i = 0; i < RX_DESCRIPTOR_NUM; i++) {
- rx_desc[i].status1 = OWNERSHIP_EMAC;
- rx_desc[i].buf = &rx_buf[i][0];
- rx_desc[i].status2 = 0;
- rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
- }
- EMAC->RXDSA = (unsigned int)&rx_desc[0];
- return;
-}
-
-void numaker_set_mac_addr(uint8_t *addr)
-{
-
- EMAC->CAM0M = (addr[0] << 24) |
- (addr[1] << 16) |
- (addr[2] << 8) |
- addr[3];
-
- EMAC->CAM0L = (addr[4] << 24) |
- (addr[5] << 16);
-
-
-}
-
-static void __eth_clk_pin_init()
-{
- /* Unlock protected registers */
- SYS_UnlockReg();
-
- /* Enable IP clock */
- CLK_EnableModuleClock(EMAC_MODULE);
-
- // Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
- CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
-
- /* Update System Core Clock */
- SystemCoreClockUpdate();
-
- /*---------------------------------------------------------------------------------------------------------*/
- /* Init I/O Multi-function */
- /*---------------------------------------------------------------------------------------------------------*/
- // Configure RMII pins
- SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
- SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
- SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk);
- SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
- SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
- SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
- SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
- SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk);
- SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
- SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
- SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
- SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
- SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
-
- // Enable high slew rate on all RMII TX output pins
- PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
- (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
- (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
-
-
- /* Lock protected registers */
- SYS_LockReg();
-
-
-}
-
-int numaker_eth_init(uint8_t *mac_addr)
-{
- int ret = 0;
- // init CLK & pins
- __eth_clk_pin_init();
-
- // Reset MAC
- EMAC->CTL = EMAC_CTL_RST_Msk;
- while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
-
- init_tx_desc();
- init_rx_desc();
-
- numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
-
-
- /* Configure the MAC interrupt enable register. */
- EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
- EMAC_INTEN_TXIEN_Msk |
- EMAC_INTEN_RXGDIEN_Msk |
- EMAC_INTEN_TXCPIEN_Msk |
- EMAC_INTEN_RXBEIEN_Msk |
- EMAC_INTEN_TXBEIEN_Msk |
- EMAC_INTEN_RDUIEN_Msk |
- EMAC_INTEN_TSALMIEN_Msk |
- EMAC_INTEN_WOLIEN_Msk;
-
- /* Configure the MAC control register. */
- EMAC->CTL = EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RMIIEN_Msk;
-
- /* Accept packets for us and all broadcast and multicast packets */
- EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
- EMAC_CAMCTL_AMP_Msk |
- EMAC_CAMCTL_ABP_Msk;
- EMAC->CAMEN = 1; // Enable CAM entry 0
-
- ret= reset_phy();
-
- EMAC_ENABLE_RX();
- EMAC_ENABLE_TX();
- return ret;
-}
-
-
-
-void ETH_halt(void)
-{
-
- EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
-}
-
-unsigned int m_status;
-
-void EMAC_RX_IRQHandler(void)
-{
-// NU_DEBUGF(("%s ... \r\n", __FUNCTION__));
- m_status = EMAC->INTSTS & 0xFFFF;
- EMAC->INTSTS = m_status;
- if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
- // Shouldn't goes here, unless descriptor corrupted
- NU_DEBUGF(("RX descriptor corrupted \r\n"));
- //return;
- }
- // FIX ME: for rx-event, to ack rx_isr into event queue
- xNetworkCallback('R');
-}
-
-
-void numaker_eth_trigger_rx(void)
-{
- ETH_TRIGGER_RX();
-}
-
-int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
-{
- unsigned int cur_entry, status;
-
- cur_entry = EMAC->CRXDSA;
- if ((cur_entry == (uint32_t)cur_rx_desc_ptr) && (!(m_status & EMAC_INTSTS_RDUIF_Msk))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
- return -1;
- status = cur_rx_desc_ptr->status1;
-
- if(status & OWNERSHIP_EMAC)
- return -1;
-
- if (status & RXFD_RXGD) {
- *buf = cur_rx_desc_ptr->buf;
- *len = status & 0xFFFF;
- }
- return 0;
-}
-
-void numaker_eth_rx_next(void)
-{
- cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
- cur_rx_desc_ptr = cur_rx_desc_ptr->next;
-}
-
-void EMAC_TX_IRQHandler(void)
-{
- unsigned int cur_entry, status;
-
- status = EMAC->INTSTS & 0xFFFF0000;
- EMAC->INTSTS = status;
- if(status & EMAC_INTSTS_TXBEIF_Msk) {
- // Shouldn't goes here, unless descriptor corrupted
- return;
- }
-
- cur_entry = EMAC->CTXDSA;
-
- while (cur_entry != (uint32_t)fin_tx_desc_ptr) {
-
- fin_tx_desc_ptr = fin_tx_desc_ptr->next;
- }
- // FIX ME: for tx-event, no-op at this stage
- xNetworkCallback('T');
-}
-
-uint8_t *numaker_eth_get_tx_buf(void)
-{
- if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
- return(NULL);
- else
- return(cur_tx_desc_ptr->buf);
-}
-
-void numaker_eth_trigger_tx(uint16_t length, void *p)
-{
- struct eth_descriptor volatile *desc;
- cur_tx_desc_ptr->status2 = (unsigned int)length;
- desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
- cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
- cur_tx_desc_ptr = desc;
-
- ETH_TRIGGER_TX();
-
-}
-
-int numaker_eth_link_ok(void)
-{
- /* first, a dummy read to latch */
- mdio_read(CONFIG_PHY_ADDR, MII_BMSR);
- if(mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & BMSR_LSTATUS)
- return 1;
- return 0;
-}
-
-//void numaker_eth_set_cb(eth_callback_t eth_cb, void *userData)
-//{
-// nu_eth_txrx_cb = eth_cb;
-// nu_userData = userData;
-//}
-
-// Provide ethernet devices with a semi-unique MAC address
-void numaker_mac_address(uint8_t *mac)
-{
- uint32_t uID1;
- // Fetch word 0
- uint32_t word0 = *(uint32_t *)0x7F804; // 2KB Data Flash at 0x7F800
- // Fetch word 1
- // we only want bottom 16 bits of word1 (MAC bits 32-47)
- // and bit 9 forced to 1, bit 8 forced to 0
- // Locally administered MAC, reduced conflicts
- // http://en.wikipedia.org/wiki/MAC_address
- uint32_t word1 = *(uint32_t *)0x7F800; // 2KB Data Flash at 0x7F800
-
- if( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
- {
- // with a semi-unique MAC address from the UUID
- /* Enable FMC ISP function */
- SYS_UnlockReg();
- FMC_Open();
- // = FMC_ReadUID(0);
- uID1 = FMC_ReadUID(1);
- word1 = (uID1 & 0x003FFFFF) | ((uID1 & 0x030000) << 6) >> 8;
- word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uID1 & 0xFF)<<12) | (FMC_ReadUID(2) & 0xFFF);
- /* Disable FMC ISP function */
- FMC_Close();
- /* Lock protected registers */
- SYS_LockReg();
- }
-
- word1 |= 0x00000200;
- word1 &= 0x0000FEFF;
-
- mac[0] = (word1 & 0x0000ff00) >> 8;
- mac[1] = (word1 & 0x000000ff);
- mac[2] = (word0 & 0xff000000) >> 24;
- mac[3] = (word0 & 0x00ff0000) >> 16;
- mac[4] = (word0 & 0x0000ff00) >> 8;
- mac[5] = (word0 & 0x000000ff);
-
- NU_DEBUGF(("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]));
-}
-
-void numaker_eth_enable_interrupts(void) {
- EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
- EMAC_INTEN_TXIEN_Msk ;
- NVIC_EnableIRQ(EMAC_RX_IRQn);
- NVIC_EnableIRQ(EMAC_TX_IRQn);
-}
-
-void numaker_eth_disable_interrupts(void) {
- NVIC_DisableIRQ(EMAC_RX_IRQn);
- NVIC_DisableIRQ(EMAC_TX_IRQn);
-}
+/**************************************************************************//**
+ * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Nuvoton Technology Corp. 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
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
+*****************************************************************************/
+#include "FreeRTOS.h"
+#include "list.h"
+#include "FreeRTOS_IP.h"
+
+#include "m480_eth.h"
+
+#define ETH_TRIGGER_RX() do{EMAC->RXST = 0;}while(0)
+#define ETH_TRIGGER_TX() do{EMAC->TXST = 0;}while(0)
+#define ETH_ENABLE_TX() do{EMAC->CTL |= EMAC_CTL_TXON;}while(0)
+#define ETH_ENABLE_RX() do{EMAC->CTL |= EMAC_CTL_RXON;}while(0)
+#define ETH_DISABLE_TX() do{EMAC->CTL &= ~EMAC_CTL_TXON;}while(0)
+#define ETH_DISABLE_RX() do{EMAC->CTL &= ~EMAC_CTL_RXON;}while(0)
+
+
+struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+#ifdef __ICCARM__
+#pragma data_alignment=4
+struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM];
+struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM];
+uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
+uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE];
+#else
+struct eth_descriptor rx_desc[RX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+struct eth_descriptor tx_desc[TX_DESCRIPTOR_NUM] __attribute__ ((aligned(4)));
+uint8_t rx_buf[RX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
+uint8_t tx_buf[TX_DESCRIPTOR_NUM][PACKET_BUFFER_SIZE] __attribute__ ((aligned(4)));
+#endif
+struct eth_descriptor volatile *cur_tx_desc_ptr, *cur_rx_desc_ptr, *fin_tx_desc_ptr;
+
+
+// PTP source clock is 84MHz (Real chip using PLL). Each tick is 11.90ns
+// Assume we want to set each tick to 100ns.
+// Increase register = (100 * 2^31) / (10^9) = 214.71 =~ 215 = 0xD7
+// Addend register = 2^32 * tick_freq / (84MHz), where tick_freq = (2^31 / 215) MHz
+// From above equation, addend register = 2^63 / (84M * 215) ~= 510707200 = 0x1E70C600
+
+
+
+static void mdio_write(uint8_t addr, uint8_t reg, uint16_t val)
+{
+
+ EMAC->MIIMDAT = val;
+ EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_WRITE_Msk | EMAC_MIIMCTL_MDCON_Msk;
+
+ while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
+
+}
+
+
+static uint16_t mdio_read(uint8_t addr, uint8_t reg)
+{
+ EMAC->MIIMCTL = (addr << EMAC_MIIMCTL_PHYADDR_Pos) | reg | EMAC_MIIMCTL_BUSY_Msk | EMAC_MIIMCTL_MDCON_Msk;
+ while (EMAC->MIIMCTL & EMAC_MIIMCTL_BUSY_Msk);
+
+ return(EMAC->MIIMDAT);
+}
+
+static int reset_phy(void)
+{
+
+ uint16_t reg;
+ uint32_t delayCnt;
+
+
+ mdio_write(CONFIG_PHY_ADDR, MII_BMCR, BMCR_RESET);
+
+ delayCnt = 2000;
+ while(delayCnt-- > 0) {
+ if((mdio_read(CONFIG_PHY_ADDR, MII_BMCR) & BMCR_RESET) == 0)
+ break;
+
+ }
+
+ if(delayCnt == 0) {
+ NU_DEBUGF(("Reset phy failed\n"));
+ return(-1);
+ }
+
+ mdio_write(CONFIG_PHY_ADDR, MII_ADVERTISE, ADVERTISE_CSMA |
+ ADVERTISE_10HALF |
+ ADVERTISE_10FULL |
+ ADVERTISE_100HALF |
+ ADVERTISE_100FULL);
+
+ reg = mdio_read(CONFIG_PHY_ADDR, MII_BMCR);
+ mdio_write(CONFIG_PHY_ADDR, MII_BMCR, reg | BMCR_ANRESTART);
+
+ delayCnt = 200000;
+ while(delayCnt-- > 0) {
+ if((mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
+ == (BMSR_ANEGCOMPLETE | BMSR_LSTATUS))
+ break;
+ }
+
+ if(delayCnt == 0) {
+ NU_DEBUGF(("AN failed. Set to 100 FULL\n"));
+ EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
+ return(-1);
+ } else {
+ reg = mdio_read(CONFIG_PHY_ADDR, MII_LPA);
+
+ if(reg & ADVERTISE_100FULL) {
+ NU_DEBUGF(("100 full\n"));
+ EMAC->CTL |= (EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
+ } else if(reg & ADVERTISE_100HALF) {
+ NU_DEBUGF(("100 half\n"));
+ EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_FUDUP_Msk) | EMAC_CTL_OPMODE_Msk;
+ } else if(reg & ADVERTISE_10FULL) {
+ NU_DEBUGF(("10 full\n"));
+ EMAC->CTL = (EMAC->CTL & ~EMAC_CTL_OPMODE_Msk) | EMAC_CTL_FUDUP_Msk;
+ } else {
+ NU_DEBUGF(("10 half\n"));
+ EMAC->CTL &= ~(EMAC_CTL_OPMODE_Msk | EMAC_CTL_FUDUP_Msk);
+ }
+ }
+ FreeRTOS_printf(("PHY ID 1:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID1)));
+ FreeRTOS_printf(("PHY ID 2:0x%x\r\n", mdio_read(CONFIG_PHY_ADDR, MII_PHYSID2)));
+
+ return(0);
+}
+
+
+static void init_tx_desc(void)
+{
+ uint32_t i;
+
+
+ cur_tx_desc_ptr = fin_tx_desc_ptr = &tx_desc[0];
+
+ for(i = 0; i < TX_DESCRIPTOR_NUM; i++) {
+ tx_desc[i].status1 = TXFD_PADEN | TXFD_CRCAPP | TXFD_INTEN;
+ tx_desc[i].buf = &tx_buf[i][0];
+ tx_desc[i].status2 = 0;
+ tx_desc[i].next = &tx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
+
+ }
+ EMAC->TXDSA = (unsigned int)&tx_desc[0];
+ return;
+}
+
+static void init_rx_desc(void)
+{
+ uint32_t i;
+
+
+ cur_rx_desc_ptr = &rx_desc[0];
+
+ for(i = 0; i < RX_DESCRIPTOR_NUM; i++) {
+ rx_desc[i].status1 = OWNERSHIP_EMAC;
+ rx_desc[i].buf = &rx_buf[i][0];
+ rx_desc[i].status2 = 0;
+ rx_desc[i].next = &rx_desc[(i + 1) % TX_DESCRIPTOR_NUM];
+ }
+ EMAC->RXDSA = (unsigned int)&rx_desc[0];
+ return;
+}
+
+void numaker_set_mac_addr(uint8_t *addr)
+{
+
+ EMAC->CAM0M = (addr[0] << 24) |
+ (addr[1] << 16) |
+ (addr[2] << 8) |
+ addr[3];
+
+ EMAC->CAM0L = (addr[4] << 24) |
+ (addr[5] << 16);
+
+
+}
+
+static void __eth_clk_pin_init()
+{
+ /* Unlock protected registers */
+ SYS_UnlockReg();
+
+ /* Enable IP clock */
+ CLK_EnableModuleClock(EMAC_MODULE);
+
+ // Configure MDC clock rate to HCLK / (127 + 1) = 1.25 MHz if system is running at 160 MH
+ CLK_SetModuleClock(EMAC_MODULE, 0, CLK_CLKDIV3_EMAC(127));
+
+ /* Update System Core Clock */
+ SystemCoreClockUpdate();
+
+ /*---------------------------------------------------------------------------------------------------------*/
+ /* Init I/O Multi-function */
+ /*---------------------------------------------------------------------------------------------------------*/
+ // Configure RMII pins
+ SYS->GPA_MFPL &= ~(SYS_GPA_MFPL_PA6MFP_Msk | SYS_GPA_MFPL_PA7MFP_Msk);
+ SYS->GPA_MFPL |= SYS_GPA_MFPL_PA6MFP_EMAC_RMII_RXERR | SYS_GPA_MFPL_PA7MFP_EMAC_RMII_CRSDV;
+ SYS->GPC_MFPL &= ~(SYS_GPC_MFPL_PC6MFP_Msk | SYS_GPC_MFPL_PC7MFP_Msk);
+ SYS->GPC_MFPL |= SYS_GPC_MFPL_PC6MFP_EMAC_RMII_RXD1 | SYS_GPC_MFPL_PC7MFP_EMAC_RMII_RXD0;
+ SYS->GPC_MFPH &= ~SYS_GPC_MFPH_PC8MFP_Msk;
+ SYS->GPC_MFPH |= SYS_GPC_MFPH_PC8MFP_EMAC_RMII_REFCLK;
+ SYS->GPE_MFPH &= ~(SYS_GPE_MFPH_PE8MFP_Msk | SYS_GPE_MFPH_PE9MFP_Msk | SYS_GPE_MFPH_PE10MFP_Msk |
+ SYS_GPE_MFPH_PE11MFP_Msk | SYS_GPE_MFPH_PE12MFP_Msk);
+ SYS->GPE_MFPH |= SYS_GPE_MFPH_PE8MFP_EMAC_RMII_MDC |
+ SYS_GPE_MFPH_PE9MFP_EMAC_RMII_MDIO |
+ SYS_GPE_MFPH_PE10MFP_EMAC_RMII_TXD0 |
+ SYS_GPE_MFPH_PE11MFP_EMAC_RMII_TXD1 |
+ SYS_GPE_MFPH_PE12MFP_EMAC_RMII_TXEN;
+
+ // Enable high slew rate on all RMII TX output pins
+ PE->SLEWCTL = (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN10_Pos) |
+ (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN11_Pos) |
+ (GPIO_SLEWCTL_HIGH << GPIO_SLEWCTL_HSREN12_Pos);
+
+
+ /* Lock protected registers */
+ SYS_LockReg();
+
+
+}
+
+int numaker_eth_init(uint8_t *mac_addr)
+{
+ int ret = 0;
+ // init CLK & pins
+ __eth_clk_pin_init();
+
+ // Reset MAC
+ EMAC->CTL = EMAC_CTL_RST_Msk;
+ while(EMAC->CTL & EMAC_CTL_RST_Msk) {}
+
+ init_tx_desc();
+ init_rx_desc();
+
+ numaker_set_mac_addr(mac_addr); // need to reconfigure hardware address 'cos we just RESET emc...
+
+
+ /* Configure the MAC interrupt enable register. */
+ EMAC->INTEN = EMAC_INTEN_RXIEN_Msk |
+ EMAC_INTEN_TXIEN_Msk |
+ EMAC_INTEN_RXGDIEN_Msk |
+ EMAC_INTEN_TXCPIEN_Msk |
+ EMAC_INTEN_RXBEIEN_Msk |
+ EMAC_INTEN_TXBEIEN_Msk |
+ EMAC_INTEN_RDUIEN_Msk |
+ EMAC_INTEN_TSALMIEN_Msk |
+ EMAC_INTEN_WOLIEN_Msk;
+
+ /* Configure the MAC control register. */
+ EMAC->CTL = EMAC_CTL_STRIPCRC_Msk | EMAC_CTL_RMIIEN_Msk;
+
+ /* Accept packets for us and all broadcast and multicast packets */
+ EMAC->CAMCTL = EMAC_CAMCTL_CMPEN_Msk |
+ EMAC_CAMCTL_AMP_Msk |
+ EMAC_CAMCTL_ABP_Msk;
+ EMAC->CAMEN = 1; // Enable CAM entry 0
+
+ ret= reset_phy();
+
+ EMAC_ENABLE_RX();
+ EMAC_ENABLE_TX();
+ return ret;
+}
+
+
+
+void ETH_halt(void)
+{
+
+ EMAC->CTL &= ~(EMAC_CTL_RXON_Msk | EMAC_CTL_TXON_Msk);
+}
+
+unsigned int m_status;
+
+void EMAC_RX_IRQHandler(void)
+{
+// NU_DEBUGF(("%s ... \r\n", __FUNCTION__));
+ m_status = EMAC->INTSTS & 0xFFFF;
+ EMAC->INTSTS = m_status;
+ if (m_status & EMAC_INTSTS_RXBEIF_Msk) {
+ // Shouldn't goes here, unless descriptor corrupted
+ NU_DEBUGF(("RX descriptor corrupted \r\n"));
+ //return;
+ }
+ // FIX ME: for rx-event, to ack rx_isr into event queue
+ xNetworkCallback('R');
+}
+
+
+void numaker_eth_trigger_rx(void)
+{
+ ETH_TRIGGER_RX();
+}
+
+int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf)
+{
+ unsigned int cur_entry, status;
+
+ cur_entry = EMAC->CRXDSA;
+ if ((cur_entry == (uint32_t)cur_rx_desc_ptr) && (!(m_status & EMAC_INTSTS_RDUIF_Msk))) // cur_entry may equal to cur_rx_desc_ptr if RDU occures
+ return -1;
+ status = cur_rx_desc_ptr->status1;
+
+ if(status & OWNERSHIP_EMAC)
+ return -1;
+
+ if (status & RXFD_RXGD) {
+ *buf = cur_rx_desc_ptr->buf;
+ *len = status & 0xFFFF;
+ }
+ return 0;
+}
+
+void numaker_eth_rx_next(void)
+{
+ cur_rx_desc_ptr->status1 = OWNERSHIP_EMAC;
+ cur_rx_desc_ptr = cur_rx_desc_ptr->next;
+}
+
+void EMAC_TX_IRQHandler(void)
+{
+ unsigned int cur_entry, status;
+
+ status = EMAC->INTSTS & 0xFFFF0000;
+ EMAC->INTSTS = status;
+ if(status & EMAC_INTSTS_TXBEIF_Msk) {
+ // Shouldn't goes here, unless descriptor corrupted
+ return;
+ }
+
+ cur_entry = EMAC->CTXDSA;
+
+ while (cur_entry != (uint32_t)fin_tx_desc_ptr) {
+
+ fin_tx_desc_ptr = fin_tx_desc_ptr->next;
+ }
+ // FIX ME: for tx-event, no-op at this stage
+ xNetworkCallback('T');
+}
+
+uint8_t *numaker_eth_get_tx_buf(void)
+{
+ if(cur_tx_desc_ptr->status1 & OWNERSHIP_EMAC)
+ return(NULL);
+ else
+ return(cur_tx_desc_ptr->buf);
+}
+
+void numaker_eth_trigger_tx(uint16_t length, void *p)
+{
+ struct eth_descriptor volatile *desc;
+ cur_tx_desc_ptr->status2 = (unsigned int)length;
+ desc = cur_tx_desc_ptr->next; // in case TX is transmitting and overwrite next pointer before we can update cur_tx_desc_ptr
+ cur_tx_desc_ptr->status1 |= OWNERSHIP_EMAC;
+ cur_tx_desc_ptr = desc;
+
+ ETH_TRIGGER_TX();
+
+}
+
+int numaker_eth_link_ok(void)
+{
+ /* first, a dummy read to latch */
+ mdio_read(CONFIG_PHY_ADDR, MII_BMSR);
+ if(mdio_read(CONFIG_PHY_ADDR, MII_BMSR) & BMSR_LSTATUS)
+ return 1;
+ return 0;
+}
+
+//void numaker_eth_set_cb(eth_callback_t eth_cb, void *userData)
+//{
+// nu_eth_txrx_cb = eth_cb;
+// nu_userData = userData;
+//}
+
+// Provide ethernet devices with a semi-unique MAC address
+void numaker_mac_address(uint8_t *mac)
+{
+ uint32_t uID1;
+ // Fetch word 0
+ uint32_t word0 = *(uint32_t *)0x7F804; // 2KB Data Flash at 0x7F800
+ // Fetch word 1
+ // we only want bottom 16 bits of word1 (MAC bits 32-47)
+ // and bit 9 forced to 1, bit 8 forced to 0
+ // Locally administered MAC, reduced conflicts
+ // http://en.wikipedia.org/wiki/MAC_address
+ uint32_t word1 = *(uint32_t *)0x7F800; // 2KB Data Flash at 0x7F800
+
+ if( word0 == 0xFFFFFFFF ) // Not burn any mac address at 1st 2 words of Data Flash
+ {
+ // with a semi-unique MAC address from the UUID
+ /* Enable FMC ISP function */
+ SYS_UnlockReg();
+ FMC_Open();
+ // = FMC_ReadUID(0);
+ uID1 = FMC_ReadUID(1);
+ word1 = (uID1 & 0x003FFFFF) | ((uID1 & 0x030000) << 6) >> 8;
+ word0 = ((FMC_ReadUID(0) >> 4) << 20) | ((uID1 & 0xFF)<<12) | (FMC_ReadUID(2) & 0xFFF);
+ /* Disable FMC ISP function */
+ FMC_Close();
+ /* Lock protected registers */
+ SYS_LockReg();
+ }
+
+ word1 |= 0x00000200;
+ word1 &= 0x0000FEFF;
+
+ mac[0] = (word1 & 0x0000ff00) >> 8;
+ mac[1] = (word1 & 0x000000ff);
+ mac[2] = (word0 & 0xff000000) >> 24;
+ mac[3] = (word0 & 0x00ff0000) >> 16;
+ mac[4] = (word0 & 0x0000ff00) >> 8;
+ mac[5] = (word0 & 0x000000ff);
+
+ NU_DEBUGF(("mac address %02x-%02x-%02x-%02x-%02x-%02x \r\n", mac[0], mac[1],mac[2],mac[3],mac[4],mac[5]));
+}
+
+void numaker_eth_enable_interrupts(void) {
+ EMAC->INTEN |= EMAC_INTEN_RXIEN_Msk |
+ EMAC_INTEN_TXIEN_Msk ;
+ NVIC_EnableIRQ(EMAC_RX_IRQn);
+ NVIC_EnableIRQ(EMAC_TX_IRQn);
+}
+
+void numaker_eth_disable_interrupts(void) {
+ NVIC_DisableIRQ(EMAC_RX_IRQn);
+ NVIC_DisableIRQ(EMAC_TX_IRQn);
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h
index 4e4d98d6d..3d370bca7 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/M487/m480_eth.h
@@ -1,164 +1,164 @@
-/**************************************************************************//**
- * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of Nuvoton Technology Corp. 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
-*****************************************************************************/
-#include "M480.h"
-#ifndef _M480_ETH_
-#define _M480_ETH_
-
-/* Generic MII registers. */
-
-#define MII_BMCR 0x00 /* Basic mode control register */
-#define MII_BMSR 0x01 /* Basic mode status register */
-#define MII_PHYSID1 0x02 /* PHYS ID 1 */
-#define MII_PHYSID2 0x03 /* PHYS ID 2 */
-#define MII_ADVERTISE 0x04 /* Advertisement control reg */
-#define MII_LPA 0x05 /* Link partner ability reg */
-#define MII_EXPANSION 0x06 /* Expansion register */
-#define MII_DCOUNTER 0x12 /* Disconnect counter */
-#define MII_FCSCOUNTER 0x13 /* False carrier counter */
-#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
-#define MII_RERRCOUNTER 0x15 /* Receive error counter */
-#define MII_SREVISION 0x16 /* Silicon revision */
-#define MII_RESV1 0x17 /* Reserved... */
-#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
-#define MII_PHYADDR 0x19 /* PHY address */
-#define MII_RESV2 0x1a /* Reserved... */
-#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
-#define MII_NCONFIG 0x1c /* Network interface config */
-
-/* Basic mode control register. */
-#define BMCR_RESV 0x007f /* Unused... */
-#define BMCR_CTST 0x0080 /* Collision test */
-#define BMCR_FULLDPLX 0x0100 /* Full duplex */
-#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
-#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
-#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
-#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
-#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
-#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
-#define BMCR_RESET 0x8000 /* Reset the DP83840 */
-
-/* Basic mode status register. */
-#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
-#define BMSR_JCD 0x0002 /* Jabber detected */
-#define BMSR_LSTATUS 0x0004 /* Link status */
-#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
-#define BMSR_RFAULT 0x0010 /* Remote fault detected */
-#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
-#define BMSR_RESV 0x07c0 /* Unused... */
-#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
-#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
-#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
-#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
-#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
-
-/* Advertisement control register. */
-#define ADVERTISE_SLCT 0x001f /* Selector bits */
-#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
-#define ADVERTISE_RESV 0x1c00 /* Unused... */
-#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
-#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
-#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
-
-#define RX_DESCRIPTOR_NUM 4 //8 // Max Number of Rx Frame Descriptors
-#define TX_DESCRIPTOR_NUM 2 //4 // Max number of Tx Frame Descriptors
-
-#define PACKET_BUFFER_SIZE 1520
-
-#define CONFIG_PHY_ADDR 1
-
-
-// Frame Descriptor's Owner bit
-#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC
-//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU
-
-
-
-// Rx Frame Descriptor Status
-#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received
-#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available
-
-
-// Tx Frame Descriptor's Control bits
-#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable
-#define TXFD_INTEN 0x04 // Interrupt Enable
-#define TXFD_CRCAPP 0x02 // Append CRC
-#define TXFD_PADEN 0x01 // Padding Enable
-
-// Tx Frame Descriptor Status
-#define TXFD_TXCP 0x00080000 // Transmission Completion
-#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available
-
-// Tx/Rx buffer descriptor structure
-struct eth_descriptor;
-struct eth_descriptor {
- uint32_t status1;
- uint8_t *buf;
- uint32_t status2;
- struct eth_descriptor *next;
-#ifdef TIME_STAMPING
- uint32_t backup1;
- uint32_t backup2;
- uint32_t reserved1;
- uint32_t reserved2;
-#endif
-};
-
-#ifdef TIME_STAMPING
-
-#define ETH_TS_ENABLE() do{EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;}while(0)
-#define ETH_TS_START() do{EMAC->TSCTL |= (EMAC_TSCTL_TSMODE_Msk | EMAC_TSCTL_TSIEN_Msk);}while(0)
-s32_t ETH_settime(u32_t sec, u32_t nsec);
-s32_t ETH_gettime(u32_t *sec, u32_t *nsec);
-s32_t ETH_updatetime(u32_t neg, u32_t sec, u32_t nsec);
-s32_t ETH_adjtimex(int ppm);
-void ETH_setinc(void);
-
-#endif
-
-#ifdef NU_TRACE
-#define NU_DEBUGF(x) { printf x; }
-#else
-#define NU_DEBUGF(x)
-#endif
-
-void numaker_set_mac_addr(uint8_t *addr);
-int numaker_eth_init(uint8_t *mac_addr);
-uint8_t *numaker_eth_get_tx_buf(void);
-void numaker_eth_trigger_tx(uint16_t length, void *p);
-int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf);
-void numaker_eth_rx_next(void);
-void numaker_eth_trigger_rx(void);
-int numaker_eth_link_ok(void);
-void numaker_mac_address(uint8_t *mac);
-void numaker_eth_enable_interrupts(void);
-void numaker_eth_disable_interrupts(void);
-
-#endif /* _M480_ETH_ */
+/**************************************************************************//**
+ * @copyright (C) 2019 Nuvoton Technology Corp. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without modification,
+ * are permitted provided that the following conditions are met:
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of Nuvoton Technology Corp. 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
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
+*****************************************************************************/
+#include "M480.h"
+#ifndef _M480_ETH_
+#define _M480_ETH_
+
+/* Generic MII registers. */
+
+#define MII_BMCR 0x00 /* Basic mode control register */
+#define MII_BMSR 0x01 /* Basic mode status register */
+#define MII_PHYSID1 0x02 /* PHYS ID 1 */
+#define MII_PHYSID2 0x03 /* PHYS ID 2 */
+#define MII_ADVERTISE 0x04 /* Advertisement control reg */
+#define MII_LPA 0x05 /* Link partner ability reg */
+#define MII_EXPANSION 0x06 /* Expansion register */
+#define MII_DCOUNTER 0x12 /* Disconnect counter */
+#define MII_FCSCOUNTER 0x13 /* False carrier counter */
+#define MII_NWAYTEST 0x14 /* N-way auto-neg test reg */
+#define MII_RERRCOUNTER 0x15 /* Receive error counter */
+#define MII_SREVISION 0x16 /* Silicon revision */
+#define MII_RESV1 0x17 /* Reserved... */
+#define MII_LBRERROR 0x18 /* Lpback, rx, bypass error */
+#define MII_PHYADDR 0x19 /* PHY address */
+#define MII_RESV2 0x1a /* Reserved... */
+#define MII_TPISTATUS 0x1b /* TPI status for 10mbps */
+#define MII_NCONFIG 0x1c /* Network interface config */
+
+/* Basic mode control register. */
+#define BMCR_RESV 0x007f /* Unused... */
+#define BMCR_CTST 0x0080 /* Collision test */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart */
+#define BMCR_ISOLATE 0x0400 /* Disconnect DP83840 from MII */
+#define BMCR_PDOWN 0x0800 /* Powerdown the DP83840 */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps */
+#define BMCR_LOOPBACK 0x4000 /* TXD loopback bits */
+#define BMCR_RESET 0x8000 /* Reset the DP83840 */
+
+/* Basic mode status register. */
+#define BMSR_ERCAP 0x0001 /* Ext-reg capability */
+#define BMSR_JCD 0x0002 /* Jabber detected */
+#define BMSR_LSTATUS 0x0004 /* Link status */
+#define BMSR_ANEGCAPABLE 0x0008 /* Able to do auto-negotiation */
+#define BMSR_RFAULT 0x0010 /* Remote fault detected */
+#define BMSR_ANEGCOMPLETE 0x0020 /* Auto-negotiation complete */
+#define BMSR_RESV 0x07c0 /* Unused... */
+#define BMSR_10HALF 0x0800 /* Can do 10mbps, half-duplex */
+#define BMSR_10FULL 0x1000 /* Can do 10mbps, full-duplex */
+#define BMSR_100HALF 0x2000 /* Can do 100mbps, half-duplex */
+#define BMSR_100FULL 0x4000 /* Can do 100mbps, full-duplex */
+#define BMSR_100BASE4 0x8000 /* Can do 100mbps, 4k packets */
+
+/* Advertisement control register. */
+#define ADVERTISE_SLCT 0x001f /* Selector bits */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+#define ADVERTISE_100BASE4 0x0200 /* Try for 100mbps 4k packets */
+#define ADVERTISE_RESV 0x1c00 /* Unused... */
+#define ADVERTISE_RFAULT 0x2000 /* Say we can detect faults */
+#define ADVERTISE_LPACK 0x4000 /* Ack link partners response */
+#define ADVERTISE_NPAGE 0x8000 /* Next page bit */
+
+#define RX_DESCRIPTOR_NUM 4 //8 // Max Number of Rx Frame Descriptors
+#define TX_DESCRIPTOR_NUM 2 //4 // Max number of Tx Frame Descriptors
+
+#define PACKET_BUFFER_SIZE 1520
+
+#define CONFIG_PHY_ADDR 1
+
+
+// Frame Descriptor's Owner bit
+#define OWNERSHIP_EMAC 0x80000000 // 1 = EMAC
+//#define OWNERSHIP_CPU 0x7fffffff // 0 = CPU
+
+
+
+// Rx Frame Descriptor Status
+#define RXFD_RXGD 0x00100000 // Receiving Good Packet Received
+#define RXFD_RTSAS 0x00800000 // RX Time Stamp Available
+
+
+// Tx Frame Descriptor's Control bits
+#define TXFD_TTSEN 0x08 // Tx Time Stamp Enable
+#define TXFD_INTEN 0x04 // Interrupt Enable
+#define TXFD_CRCAPP 0x02 // Append CRC
+#define TXFD_PADEN 0x01 // Padding Enable
+
+// Tx Frame Descriptor Status
+#define TXFD_TXCP 0x00080000 // Transmission Completion
+#define TXFD_TTSAS 0x08000000 // TX Time Stamp Available
+
+// Tx/Rx buffer descriptor structure
+struct eth_descriptor;
+struct eth_descriptor {
+ uint32_t status1;
+ uint8_t *buf;
+ uint32_t status2;
+ struct eth_descriptor *next;
+#ifdef TIME_STAMPING
+ uint32_t backup1;
+ uint32_t backup2;
+ uint32_t reserved1;
+ uint32_t reserved2;
+#endif
+};
+
+#ifdef TIME_STAMPING
+
+#define ETH_TS_ENABLE() do{EMAC->TSCTL = EMAC_TSCTL_TSEN_Msk;}while(0)
+#define ETH_TS_START() do{EMAC->TSCTL |= (EMAC_TSCTL_TSMODE_Msk | EMAC_TSCTL_TSIEN_Msk);}while(0)
+s32_t ETH_settime(u32_t sec, u32_t nsec);
+s32_t ETH_gettime(u32_t *sec, u32_t *nsec);
+s32_t ETH_updatetime(u32_t neg, u32_t sec, u32_t nsec);
+s32_t ETH_adjtimex(int ppm);
+void ETH_setinc(void);
+
+#endif
+
+#ifdef NU_TRACE
+#define NU_DEBUGF(x) { printf x; }
+#else
+#define NU_DEBUGF(x)
+#endif
+
+void numaker_set_mac_addr(uint8_t *addr);
+int numaker_eth_init(uint8_t *mac_addr);
+uint8_t *numaker_eth_get_tx_buf(void);
+void numaker_eth_trigger_tx(uint16_t length, void *p);
+int numaker_eth_get_rx_buf(uint16_t *len, uint8_t **buf);
+void numaker_eth_rx_next(void);
+void numaker_eth_trigger_rx(void);
+int numaker_eth_link_ok(void);
+void numaker_mac_address(uint8_t *mac);
+void numaker_eth_enable_interrupts(void);
+void numaker_eth_disable_interrupts(void);
+
+#endif /* _M480_ETH_ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/README_DRIVER_DISCLAIMER.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/README_DRIVER_DISCLAIMER.txt
index 347bb113e..d4dc8687c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/README_DRIVER_DISCLAIMER.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/README_DRIVER_DISCLAIMER.txt
@@ -1,10 +1,10 @@
-Network drivers are provided as examples only, and do not form part of the
-FreeRTOS+TCP stack itself. They:
-
- + May be based on driver code provided by the chip vendors,
- + May not have been tested in all possible configurations,
- + Will not necessarily be optimised.
- + May have a dependency on a particular PHY part number.
- + May not necessarily comply with any particular coding standard.
- + May have dependencies on chip company libraries.
- + May include other hardware board dependencies.
+Network drivers are provided as examples only, and do not form part of the
+FreeRTOS+TCP stack itself. They:
+
+ + May be based on driver code provided by the chip vendors,
+ + May not have been tested in all possible configurations,
+ + Will not necessarily be optimised.
+ + May have a dependency on a particular PHY part number.
+ + May not necessarily comply with any particular coding standard.
+ + May have dependencies on chip company libraries.
+ + May include other hardware board dependencies.
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
index 5a605af9b..139979cce 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/NetworkInterface.c
@@ -1,629 +1,622 @@
-/***********************************************************************************************************************
-* DISCLAIMER
-* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
-* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
-* applicable laws, including copyright laws.
-* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
-* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
-* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
-* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
-* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
-* this software. By using this software, you agree to the additional terms and conditions found by accessing the
-* following link:
-* http://www.renesas.com/disclaimer
-*
-* Copyright (C) 2018 Renesas Electronics Corporation. All rights reserved.
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-* File Name : NetworkInterface.c
-* Device(s) : RX
-* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-* History : DD.MM.YYYY Version Description
-* : 07.03.2018 0.1 Development
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-* Includes <System Includes> , "Project Includes"
-***********************************************************************************************************************/
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-/*#include "FreeRTOS_DNS.h" */
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "r_ether_rx_if.h"
-#include "r_pinset.h"
-
-/***********************************************************************************************************************
- * Macro definitions
- **********************************************************************************************************************/
-#define ETHER_BUFSIZE_MIN 60
-
-#if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M )
- #if ETHER_CFG_MODE_SEL == 0
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_MII()
- #elif ETHER_CFG_MODE_SEL == 1
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_RMII()
- #endif
-#elif defined( BSP_MCU_RX63N )
- #if ETHER_CFG_MODE_SEL == 0
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_MII()
- #elif ETHER_CFG_MODE_SEL == 1
- #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_RMII()
- #endif
-#endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
-
-/* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
- * receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 2000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/***********************************************************************************************************************
- * Private global variables and functions
- **********************************************************************************************************************/
-typedef enum
-{
- eMACInit, /* Must initialise MAC. */
- eMACPass, /* Initialisation was successful. */
- eMACFailed, /* Initialisation failed. */
-} eMAC_INIT_STATUS_TYPE;
-
-static TaskHandle_t ether_receive_check_task_handle = 0;
-static TaskHandle_t ether_link_check_task_handle = 0;
-static TaskHandle_t xTaskToNotify = NULL;
-static BaseType_t xPHYLinkStatus;
-static BaseType_t xReportedStatus;
-static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
-
-static int16_t SendData( uint8_t * pucBuffer,
- size_t length );
-static int InitializeNetwork( void );
-static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
-static void clear_all_ether_rx_discriptors( uint32_t event );
-
-int32_t callback_ether_regist( void );
-void EINT_Trig_isr( void * );
-void get_random_number( uint8_t * data,
- uint32_t len );
-
-void prvLinkStatusChange( BaseType_t xStatus );
-#if ( ipconfigHAS_PRINTF != 0 )
- static void prvMonitorResources( void );
-#endif
-
-/***********************************************************************************************************************
- * Function Name: xNetworkInterfaceInitialise ()
- * Description : Initialization of Ethernet driver.
- * Arguments : none
- * Return Value : pdPASS, pdFAIL
- **********************************************************************************************************************/
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- BaseType_t xReturn;
-
- if( xMacInitStatus == eMACInit )
- {
- /*
- * Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
- * Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
- *
- * InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
- */
- if( InitializeNetwork() == pdFALSE )
- {
- xMacInitStatus = eMACFailed;
- }
- else
- {
- /* Indicate that the MAC initialisation succeeded. */
- xMacInitStatus = eMACPass;
- }
-
- FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
- }
-
- if( xMacInitStatus == eMACPass )
- {
- xReturn = xPHYLinkStatus;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
-
- return xReturn;
-} /* End of function xNetworkInterfaceInitialise() */
-
-
-/***********************************************************************************************************************
- * Function Name: xNetworkInterfaceOutput ()
- * Description : Simple network output interface.
- * Arguments : pxDescriptor, xReleaseAfterSend
- * Return Value : pdTRUE, pdFALSE
- **********************************************************************************************************************/
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
- BaseType_t xReleaseAfterSend )
-{
- BaseType_t xReturn = pdFALSE;
-
- /* Simple network interfaces (as opposed to more efficient zero copy network
- * interfaces) just use Ethernet peripheral driver library functions to copy
- * data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
- * This example assumes SendData() is a peripheral driver library function that
- * takes a pointer to the start of the data to be sent and the length of the
- * data to be sent as two separate parameters. The start of the data is located
- * by pxDescriptor->pucEthernetBuffer. The length of the data is located
- * by pxDescriptor->xDataLength. */
- if( xPHYLinkStatus != 0 )
- {
- if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
- {
- xReturn = pdTRUE;
- /* Call the standard trace macro to log the send event. */
- iptraceNETWORK_INTERFACE_TRANSMIT();
- }
- }
- else
- {
- /* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
- }
-
- if( xReleaseAfterSend != pdFALSE )
- {
- /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
- * buffer. The Ethernet buffer is therefore no longer needed, and must be
- * freed for re-use. */
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- return xReturn;
-} /* End of function xNetworkInterfaceOutput() */
-
-
-#if ( ipconfigHAS_PRINTF != 0 )
- static void prvMonitorResources()
- {
- static UBaseType_t uxLastMinBufferCount = 0u;
- static UBaseType_t uxCurrentBufferCount = 0u;
- static size_t uxMinLastSize = 0uL;
- static size_t uxCurLastSize = 0uL;
- size_t uxMinSize;
- size_t uxCurSize;
-
- uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
-
- if( uxLastMinBufferCount != uxCurrentBufferCount )
- {
- /* The logging produced below may be helpful
- * while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentBufferCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
- }
-
- uxMinSize = xPortGetMinimumEverFreeHeapSize();
- uxCurSize = xPortGetFreeHeapSize();
-
- if( uxMinLastSize != uxMinSize )
- {
- uxCurLastSize = uxCurSize;
- uxMinLastSize = uxMinSize;
- FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", uxCurSize, uxMinSize ) );
- }
-
- #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
- UBaseType_t uxCurrentCount = 0u;
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
-
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- * while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
- }
-#endif /* ( ipconfigHAS_PRINTF != 0 ) */
-
-/***********************************************************************************************************************
- * Function Name: prvEMACDeferredInterruptHandlerTask ()
- * Description : The deferred interrupt handler is a standard RTOS task.
- * Arguments : pvParameters
- * Return Value : none
- **********************************************************************************************************************/
-static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
-{
- NetworkBufferDescriptor_t * pxBufferDescriptor;
- int32_t xBytesReceived = 0;
-
- /* Avoid compiler warning about unreferenced parameter. */
- ( void ) pvParameters;
-
- /* Used to indicate that xSendEventStructToIPTask() is being called because
- * of an Ethernet receive event. */
- IPStackEvent_t xRxEvent;
-
- uint8_t * buffer_pointer;
-
- /* Some variables related to monitoring the PHY. */
- TimeOut_t xPhyTime;
- TickType_t xPhyRemTime;
- const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
- xTaskToNotify = ether_receive_check_task_handle;
-
- for( ; ; )
- {
- #if ( ipconfigHAS_PRINTF != 0 )
- {
- prvMonitorResources();
- }
- #endif /* ipconfigHAS_PRINTF != 0 ) */
-
- /* Wait for the Ethernet MAC interrupt to indicate that another packet
- * has been received. */
- if( xBytesReceived <= 0 )
- {
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- /* See how much data was received. */
- xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
-
- if( xBytesReceived < 0 )
- {
- /* This is an error. Logged. */
- if( xBytesReceived == ETHER_ERR_LINK )
- {
- /* Auto-negotiation is not completed, and transmission/
- reception is not enabled. Will be logged elsewhere. */
- }
- else
- {
- FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d not %d\n", xBytesReceived, ETHER_ERR_LINK ) );
- }
- }
- else if( xBytesReceived > 0 )
- {
- /* Allocate a network buffer descriptor that points to a buffer
- * large enough to hold the received frame. As this is the simple
- * rather than efficient example the received data will just be copied
- * into this buffer. */
- pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
-
- if( pxBufferDescriptor != NULL )
- {
- /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
- * buffer large enough to hold the received data. Copy the
- * received data into pcNetworkBuffer->pucEthernetBuffer. Here it
- * is assumed ReceiveData() is a peripheral driver function that
- * copies the received data into a buffer passed in as the function's
- * parameter. Remember! While is is a simple robust technique -
- * it is not efficient. An example that uses a zero copy technique
- * is provided further down this page. */
- memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
- /*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
-
- /* Set the actual packet length, in case a larger buffer was returned. */
- pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
-
- R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
-
- /* See if the data contained in the received Ethernet frame needs
- * to be processed. NOTE! It is preferable to do this in
- * the interrupt service routine itself, which would remove the need
- * to unblock this task for packets that don't need processing. */
- if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
- {
- /* The event about to be sent to the TCP/IP is an Rx event. */
- xRxEvent.eEventType = eNetworkRxEvent;
-
- /* pvData is used to point to the network buffer descriptor that
- * now references the received data. */
- xRxEvent.pvData = ( void * ) pxBufferDescriptor;
-
- /* Send the data to the TCP/IP stack. */
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- {
- /* The buffer could not be sent to the IP task so the buffer must be released. */
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
-
- /* Make a call to the standard trace macro to log the occurrence. */
- iptraceETHERNET_RX_EVENT_LOST();
- clear_all_ether_rx_discriptors( 0 );
- }
- else
- {
- /* The message was successfully sent to the TCP/IP stack.
- * Call the standard trace macro to log the occurrence. */
- iptraceNETWORK_INTERFACE_RECEIVE();
- R_NOP();
- }
- }
- else
- {
- /* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
- }
- }
- else
- {
- /* The event was lost because a network buffer was not available.
- * Call the standard trace macro to log the occurrence. */
- iptraceETHERNET_RX_EVENT_LOST();
- clear_all_ether_rx_discriptors( 1 );
- FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
- }
- }
-
- if( xBytesReceived > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- * but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
-
- /* Indicate that the Link Status is high, so that
- * xNetworkInterfaceOutput() can send packets. */
- if( xPHYLinkStatus == 0 )
- {
- xPHYLinkStatus = 1;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
- }
- }
- else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
- {
- R_ETHER_LinkProcess( 0 );
-
- if( xPHYLinkStatus != xReportedStatus )
- {
- xPHYLinkStatus = xReportedStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
-
- if( xPHYLinkStatus != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-} /* End of function prvEMACDeferredInterruptHandlerTask() */
-
-
-/***********************************************************************************************************************
- * Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
- * Description : .
- * Arguments : pxNetworkBuffers
- * Return Value : none
- **********************************************************************************************************************/
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
- uint32_t ul;
- uint8_t * buffer_address;
-
- R_EXTERN_SEC( B_ETHERNET_BUFFERS_1 )
-
- buffer_address = R_SECTOP( B_ETHERNET_BUFFERS_1 );
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
- }
-} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
-
-
-/***********************************************************************************************************************
- * Function Name: prvLinkStatusChange ()
- * Description : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
- * Arguments : xStatus : true when statyus has become high
- * Return Value : void
- **********************************************************************************************************************/
-void prvLinkStatusChange( BaseType_t xStatus )
-{
- if( xReportedStatus != xStatus )
- {
- xReportedStatus = xStatus;
- }
-}
-
-/***********************************************************************************************************************
- * Function Name: InitializeNetwork ()
- * Description :
- * Arguments : none
- * Return Value : pdTRUE, pdFALSE
- **********************************************************************************************************************/
-static int InitializeNetwork( void )
-{
- ether_return_t eth_ret;
- BaseType_t return_code = pdFALSE;
- ether_param_t param;
- uint8_t myethaddr[ 6 ] =
- {
- configMAC_ADDR0,
- configMAC_ADDR1,
- configMAC_ADDR2,
- configMAC_ADDR3,
- configMAC_ADDR4,
- configMAC_ADDR5
- }; /*XXX Fix me */
-
- R_ETHER_PinSet_CHANNEL_0();
- R_ETHER_Initial();
- callback_ether_regist();
-
- param.channel = ETHER_CHANNEL_0;
- eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
-
- if( ETHER_SUCCESS != eth_ret )
- {
- return pdFALSE;
- }
-
- eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
-
- if( ETHER_SUCCESS != eth_ret )
- {
- return pdFALSE;
- }
-
- return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
- "ETHER_RECEIVE_CHECK_TASK",
- 512u,
- 0,
- configMAX_PRIORITIES - 1,
- &ether_receive_check_task_handle );
-
- if( pdFALSE == return_code )
- {
- return pdFALSE;
- }
-
- return pdTRUE;
-} /* End of function InitializeNetwork() */
-
-
-/***********************************************************************************************************************
- * Function Name: SendData ()
- * Description :
- * Arguments : pucBuffer, length
- * Return Value : 0 success, negative fail
- **********************************************************************************************************************/
-static int16_t SendData( uint8_t * pucBuffer,
- size_t length ) /*TODO complete stub function */
-{
- ether_return_t ret;
- uint8_t * pwrite_buffer;
- uint16_t write_buf_size;
-
- /* (1) Retrieve the transmit buffer location controlled by the descriptor. */
- ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
-
- if( ETHER_SUCCESS == ret )
- {
- if( write_buf_size >= length )
- {
- memcpy( pwrite_buffer, pucBuffer, length );
- }
-
- if( length < ETHER_BUFSIZE_MIN ) /*under minimum*/
- {
- memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
- length = ETHER_BUFSIZE_MIN; /*resize*/
- }
-
- ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
- ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
- }
-
- if( ETHER_SUCCESS != ret )
- {
- return -5; /* XXX return meaningful value */
- }
- else
- {
- return 0;
- }
-} /* End of function SendData() */
-
-
-/***********************************************************************************************************************
-* Function Name: EINT_Trig_isr
-* Description : Standard frame received interrupt handler
-* Arguments : ectrl - EDMAC and ETHERC control structure
-* Return Value : None
-* Note : This callback function is executed when EINT0 interrupt occurred.
-***********************************************************************************************************************/
-void EINT_Trig_isr( void * ectrl )
-{
- ether_cb_arg_t * pdecode;
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- pdecode = ( ether_cb_arg_t * ) ectrl;
-
- if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
- {
- if( xTaskToNotify != NULL )
- {
- vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
- }
-
- /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
- * should be performed to ensure the interrupt returns directly to the highest
- * priority task. The macro used for this purpose is dependent on the port in
- * use and may be called portEND_SWITCHING_ISR(). */
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- /*TODO complete interrupt handler for other events. */
- }
-} /* End of function EINT_Trig_isr() */
-
-
-static void clear_all_ether_rx_discriptors( uint32_t event )
-{
- int32_t xBytesReceived;
- uint8_t * buffer_pointer;
-
- /* Avoid compiler warning about unreferenced parameter. */
- ( void ) event;
-
- while( 1 )
- {
- /* See how much data was received. */
- xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
-
- if( 0 > xBytesReceived )
- {
- /* This is an error. Ignored. */
- }
- else if( 0 < xBytesReceived )
- {
- R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- else
- {
- break;
- }
- }
-}
-
-/***********************************************************************************************************************
- * End of file "NetworkInterface.c"
- **********************************************************************************************************************/
+/***********************************************************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
+* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
+* applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
+* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
+* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
+* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
+* this software. By using this software, you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer
+*
+* Copyright (C) 2018 Renesas Electronics Corporation. All rights reserved.
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* File Name : NetworkInterface.c
+* Device(s) : RX
+* Description : Interfaces FreeRTOS TCP/IP stack to RX Ethernet driver.
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* History : DD.MM.YYYY Version Description
+* : 07.03.2018 0.1 Development
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+* Includes <System Includes> , "Project Includes"
+***********************************************************************************************************************/
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+/*#include "FreeRTOS_DNS.h" */
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "r_ether_rx_if.h"
+#include "r_pinset.h"
+
+/***********************************************************************************************************************
+ * Macro definitions
+ **********************************************************************************************************************/
+#define ETHER_BUFSIZE_MIN 60
+
+#if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M )
+ #if ETHER_CFG_MODE_SEL == 0
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_MII()
+ #elif ETHER_CFG_MODE_SEL == 1
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC0_RMII()
+ #endif
+#elif defined( BSP_MCU_RX63N )
+ #if ETHER_CFG_MODE_SEL == 0
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_MII()
+ #elif ETHER_CFG_MODE_SEL == 1
+ #define R_ETHER_PinSet_CHANNEL_0() R_ETHER_PinSet_ETHERC_RMII()
+ #endif
+#endif /* if defined( BSP_MCU_RX65N ) || defined( BSP_MCU_RX64M ) || defined( BSP_MCU_RX71M ) */
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+
+/* Check if the LinkSStatus in the PHY is still high after 2 seconds of not
+ * receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 2000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/***********************************************************************************************************************
+ * Private global variables and functions
+ **********************************************************************************************************************/
+typedef enum
+{
+ eMACInit, /* Must initialise MAC. */
+ eMACPass, /* Initialisation was successful. */
+ eMACFailed, /* Initialisation failed. */
+} eMAC_INIT_STATUS_TYPE;
+
+static TaskHandle_t ether_receive_check_task_handle = 0;
+static TaskHandle_t ether_link_check_task_handle = 0;
+static TaskHandle_t xTaskToNotify = NULL;
+static BaseType_t xPHYLinkStatus;
+static BaseType_t xReportedStatus;
+static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
+
+static int16_t SendData( uint8_t * pucBuffer,
+ size_t length );
+static int InitializeNetwork( void );
+static void prvEMACDeferredInterruptHandlerTask( void * pvParameters );
+static void clear_all_ether_rx_discriptors( uint32_t event );
+
+int32_t callback_ether_regist( void );
+void EINT_Trig_isr( void * );
+void get_random_number( uint8_t * data,
+ uint32_t len );
+
+void prvLinkStatusChange( BaseType_t xStatus );
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources( void );
+#endif
+
+/***********************************************************************************************************************
+ * Function Name: xNetworkInterfaceInitialise ()
+ * Description : Initialization of Ethernet driver.
+ * Arguments : none
+ * Return Value : pdPASS, pdFAIL
+ **********************************************************************************************************************/
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ BaseType_t xReturn;
+
+ if( xMacInitStatus == eMACInit )
+ {
+ /*
+ * Perform the hardware specific network initialization here using the Ethernet driver library to initialize the
+ * Ethernet hardware, initialize DMA descriptors, and perform a PHY auto-negotiation to obtain a network link.
+ *
+ * InitialiseNetwork() uses Ethernet peripheral driver library function, and returns 0 if the initialization fails.
+ */
+ if( InitializeNetwork() == pdFALSE )
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ else
+ {
+ /* Indicate that the MAC initialisation succeeded. */
+ xMacInitStatus = eMACPass;
+ }
+
+ FreeRTOS_printf( ( "InitializeNetwork returns %s\n", ( xMacInitStatus == eMACPass ) ? "OK" : " Fail" ) );
+ }
+
+ if( xMacInitStatus == eMACPass )
+ {
+ xReturn = xPHYLinkStatus;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ FreeRTOS_printf( ( "xNetworkInterfaceInitialise returns %d\n", xReturn ) );
+
+ return xReturn;
+} /* End of function xNetworkInterfaceInitialise() */
+
+
+/***********************************************************************************************************************
+ * Function Name: xNetworkInterfaceOutput ()
+ * Description : Simple network output interface.
+ * Arguments : pxDescriptor, xReleaseAfterSend
+ * Return Value : pdTRUE, pdFALSE
+ **********************************************************************************************************************/
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
+ BaseType_t xReleaseAfterSend )
+{
+ BaseType_t xReturn = pdFALSE;
+
+ /* Simple network interfaces (as opposed to more efficient zero copy network
+ * interfaces) just use Ethernet peripheral driver library functions to copy
+ * data from the FreeRTOS+TCP buffer into the peripheral driver's own buffer.
+ * This example assumes SendData() is a peripheral driver library function that
+ * takes a pointer to the start of the data to be sent and the length of the
+ * data to be sent as two separate parameters. The start of the data is located
+ * by pxDescriptor->pucEthernetBuffer. The length of the data is located
+ * by pxDescriptor->xDataLength. */
+ if( xPHYLinkStatus != 0 )
+ {
+ if( SendData( pxDescriptor->pucEthernetBuffer, pxDescriptor->xDataLength ) >= 0 )
+ {
+ xReturn = pdTRUE;
+ /* Call the standard trace macro to log the send event. */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ }
+ }
+ else
+ {
+ /* As the PHY Link Status is low, it makes no sense trying to deliver a packet. */
+ }
+
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ /* It is assumed SendData() copies the data out of the FreeRTOS+TCP Ethernet
+ * buffer. The Ethernet buffer is therefore no longer needed, and must be
+ * freed for re-use. */
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ return xReturn;
+} /* End of function xNetworkInterfaceOutput() */
+
+
+#if ( ipconfigHAS_PRINTF != 0 )
+ static void prvMonitorResources()
+ {
+ static UBaseType_t uxLastMinBufferCount = 0u;
+ static UBaseType_t uxCurrentBufferCount = 0u;
+ static size_t uxMinLastSize = 0uL;
+ static size_t uxCurLastSize = 0uL;
+ size_t uxMinSize;
+ size_t uxCurSize;
+
+ uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
+
+ if( uxLastMinBufferCount != uxCurrentBufferCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentBufferCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
+ }
+
+ uxMinSize = xPortGetMinimumEverFreeHeapSize();
+ uxCurSize = xPortGetFreeHeapSize();
+
+ if( uxMinLastSize != uxMinSize )
+ {
+ uxCurLastSize = uxCurSize;
+ uxMinLastSize = uxMinSize;
+ FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", uxCurSize, uxMinSize ) );
+ }
+
+ #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+ UBaseType_t uxCurrentCount = 0u;
+
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ * while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+ }
+#endif /* ( ipconfigHAS_PRINTF != 0 ) */
+
+/***********************************************************************************************************************
+ * Function Name: prvEMACDeferredInterruptHandlerTask ()
+ * Description : The deferred interrupt handler is a standard RTOS task.
+ * Arguments : pvParameters
+ * Return Value : none
+ **********************************************************************************************************************/
+static void prvEMACDeferredInterruptHandlerTask( void * pvParameters )
+{
+ NetworkBufferDescriptor_t * pxBufferDescriptor;
+ int32_t xBytesReceived = 0;
+
+ /* Avoid compiler warning about unreferenced parameter. */
+ ( void ) pvParameters;
+
+ /* Used to indicate that xSendEventStructToIPTask() is being called because
+ * of an Ethernet receive event. */
+ IPStackEvent_t xRxEvent;
+
+ uint8_t * buffer_pointer;
+
+ /* Some variables related to monitoring the PHY. */
+ TimeOut_t xPhyTime;
+ TickType_t xPhyRemTime;
+ const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ FreeRTOS_printf( ( "Deferred Interrupt Handler Task started\n" ) );
+ xTaskToNotify = ether_receive_check_task_handle;
+
+ for( ; ; )
+ {
+ #if ( ipconfigHAS_PRINTF != 0 )
+ {
+ prvMonitorResources();
+ }
+ #endif /* ipconfigHAS_PRINTF != 0 ) */
+
+ /* Wait for the Ethernet MAC interrupt to indicate that another packet
+ * has been received. */
+ if( xBytesReceived <= 0 )
+ {
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ /* See how much data was received. */
+ xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
+
+ if( xBytesReceived < 0 )
+ {
+ /* This is an error. Logged. */
+ FreeRTOS_printf( ( "R_ETHER_Read_ZC2: rc = %d\n", xBytesReceived ) );
+ }
+ else if( xBytesReceived > 0 )
+ {
+ /* Allocate a network buffer descriptor that points to a buffer
+ * large enough to hold the received frame. As this is the simple
+ * rather than efficient example the received data will just be copied
+ * into this buffer. */
+ pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( ( size_t ) xBytesReceived, 0 );
+
+ if( pxBufferDescriptor != NULL )
+ {
+ /* pxBufferDescriptor->pucEthernetBuffer now points to an Ethernet
+ * buffer large enough to hold the received data. Copy the
+ * received data into pcNetworkBuffer->pucEthernetBuffer. Here it
+ * is assumed ReceiveData() is a peripheral driver function that
+ * copies the received data into a buffer passed in as the function's
+ * parameter. Remember! While is is a simple robust technique -
+ * it is not efficient. An example that uses a zero copy technique
+ * is provided further down this page. */
+ memcpy( pxBufferDescriptor->pucEthernetBuffer, buffer_pointer, ( size_t ) xBytesReceived );
+ /*ReceiveData( pxBufferDescriptor->pucEthernetBuffer ); */
+
+ /* Set the actual packet length, in case a larger buffer was returned. */
+ pxBufferDescriptor->xDataLength = ( size_t ) xBytesReceived;
+
+ R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
+
+ /* See if the data contained in the received Ethernet frame needs
+ * to be processed. NOTE! It is preferable to do this in
+ * the interrupt service routine itself, which would remove the need
+ * to unblock this task for packets that don't need processing. */
+ if( eConsiderFrameForProcessing( pxBufferDescriptor->pucEthernetBuffer ) == eProcessBuffer )
+ {
+ /* The event about to be sent to the TCP/IP is an Rx event. */
+ xRxEvent.eEventType = eNetworkRxEvent;
+
+ /* pvData is used to point to the network buffer descriptor that
+ * now references the received data. */
+ xRxEvent.pvData = ( void * ) pxBufferDescriptor;
+
+ /* Send the data to the TCP/IP stack. */
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ {
+ /* The buffer could not be sent to the IP task so the buffer must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+
+ /* Make a call to the standard trace macro to log the occurrence. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ clear_all_ether_rx_discriptors( 0 );
+ }
+ else
+ {
+ /* The message was successfully sent to the TCP/IP stack.
+ * Call the standard trace macro to log the occurrence. */
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ R_NOP();
+ }
+ }
+ else
+ {
+ /* The Ethernet frame can be dropped, but the Ethernet buffer must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+ }
+ }
+ else
+ {
+ /* The event was lost because a network buffer was not available.
+ * Call the standard trace macro to log the occurrence. */
+ iptraceETHERNET_RX_EVENT_LOST();
+ clear_all_ether_rx_discriptors( 1 );
+ FreeRTOS_printf( ( "R_ETHER_Read_ZC2: Cleared descriptors\n" ) );
+ }
+ }
+
+ if( xBytesReceived > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ * but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+
+ /* Indicate that the Link Status is high, so that
+ * xNetworkInterfaceOutput() can send packets. */
+ if( xPHYLinkStatus == 0 )
+ {
+ xPHYLinkStatus = 1;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS assume %d\n", xPHYLinkStatus ) );
+ }
+ }
+ else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) || ( FreeRTOS_IsNetworkUp() == pdFALSE ) )
+ {
+ R_ETHER_LinkProcess( 0 );
+
+ if( xPHYLinkStatus != xReportedStatus )
+ {
+ xPHYLinkStatus = xReportedStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", xPHYLinkStatus ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+
+ if( xPHYLinkStatus != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+} /* End of function prvEMACDeferredInterruptHandlerTask() */
+
+
+/***********************************************************************************************************************
+ * Function Name: vNetworkInterfaceAllocateRAMToBuffers ()
+ * Description : .
+ * Arguments : pxNetworkBuffers
+ * Return Value : none
+ **********************************************************************************************************************/
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+ uint32_t ul;
+ uint8_t * buffer_address;
+
+ R_EXTERN_SEC( B_ETHERNET_BUFFERS_1 )
+
+ buffer_address = R_SECTOP( B_ETHERNET_BUFFERS_1 );
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ( buffer_address + ( ETHER_CFG_BUFSIZE * ul ) );
+ }
+} /* End of function vNetworkInterfaceAllocateRAMToBuffers() */
+
+
+/***********************************************************************************************************************
+ * Function Name: prvLinkStatusChange ()
+ * Description : Function will be called when the Link Status of the phy has changed ( see ether_callback.c )
+ * Arguments : xStatus : true when statyus has become high
+ * Return Value : void
+ **********************************************************************************************************************/
+void prvLinkStatusChange( BaseType_t xStatus )
+{
+ if( xReportedStatus != xStatus )
+ {
+ FreeRTOS_printf( ( "prvLinkStatusChange( %d )\n", xStatus ) );
+ xReportedStatus = xStatus;
+ }
+}
+
+/***********************************************************************************************************************
+ * Function Name: InitializeNetwork ()
+ * Description :
+ * Arguments : none
+ * Return Value : pdTRUE, pdFALSE
+ **********************************************************************************************************************/
+static int InitializeNetwork( void )
+{
+ ether_return_t eth_ret;
+ BaseType_t return_code = pdFALSE;
+ ether_param_t param;
+ uint8_t myethaddr[ 6 ] =
+ {
+ configMAC_ADDR0,
+ configMAC_ADDR1,
+ configMAC_ADDR2,
+ configMAC_ADDR3,
+ configMAC_ADDR4,
+ configMAC_ADDR5
+ }; /*XXX Fix me */
+
+ R_ETHER_PinSet_CHANNEL_0();
+ R_ETHER_Initial();
+ callback_ether_regist();
+
+ param.channel = ETHER_CHANNEL_0;
+ eth_ret = R_ETHER_Control( CONTROL_POWER_ON, param ); /* PHY mode settings, module stop cancellation */
+
+ if( ETHER_SUCCESS != eth_ret )
+ {
+ return pdFALSE;
+ }
+
+ eth_ret = R_ETHER_Open_ZC2( ETHER_CHANNEL_0, myethaddr, ETHER_FLAG_OFF );
+
+ if( ETHER_SUCCESS != eth_ret )
+ {
+ return pdFALSE;
+ }
+
+ return_code = xTaskCreate( prvEMACDeferredInterruptHandlerTask,
+ "ETHER_RECEIVE_CHECK_TASK",
+ 512u,
+ 0,
+ configMAX_PRIORITIES - 1,
+ &ether_receive_check_task_handle );
+
+ if( pdFALSE == return_code )
+ {
+ return pdFALSE;
+ }
+
+ return pdTRUE;
+} /* End of function InitializeNetwork() */
+
+
+/***********************************************************************************************************************
+ * Function Name: SendData ()
+ * Description :
+ * Arguments : pucBuffer, length
+ * Return Value : 0 success, negative fail
+ **********************************************************************************************************************/
+static int16_t SendData( uint8_t * pucBuffer,
+ size_t length ) /*TODO complete stub function */
+{
+ ether_return_t ret;
+ uint8_t * pwrite_buffer;
+ uint16_t write_buf_size;
+
+ /* (1) Retrieve the transmit buffer location controlled by the descriptor. */
+ ret = R_ETHER_Write_ZC2_GetBuf( ETHER_CHANNEL_0, ( void ** ) &pwrite_buffer, &write_buf_size );
+
+ if( ETHER_SUCCESS == ret )
+ {
+ if( write_buf_size >= length )
+ {
+ memcpy( pwrite_buffer, pucBuffer, length );
+ }
+
+ if( length < ETHER_BUFSIZE_MIN ) /*under minimum*/
+ {
+ memset( ( pwrite_buffer + length ), 0, ( ETHER_BUFSIZE_MIN - length ) ); /*padding*/
+ length = ETHER_BUFSIZE_MIN; /*resize*/
+ }
+
+ ret = R_ETHER_Write_ZC2_SetBuf( ETHER_CHANNEL_0, ( uint16_t ) length );
+ ret = R_ETHER_CheckWrite( ETHER_CHANNEL_0 );
+ }
+
+ if( ETHER_SUCCESS != ret )
+ {
+ return -5; /* XXX return meaningful value */
+ }
+ else
+ {
+ return 0;
+ }
+} /* End of function SendData() */
+
+
+/***********************************************************************************************************************
+* Function Name: EINT_Trig_isr
+* Description : Standard frame received interrupt handler
+* Arguments : ectrl - EDMAC and ETHERC control structure
+* Return Value : None
+* Note : This callback function is executed when EINT0 interrupt occurred.
+***********************************************************************************************************************/
+void EINT_Trig_isr( void * ectrl )
+{
+ ether_cb_arg_t * pdecode;
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ pdecode = ( ether_cb_arg_t * ) ectrl;
+
+ if( pdecode->status_eesr & 0x00040000 ) /* EDMAC FR (Frame Receive Event) interrupt */
+ {
+ if( xTaskToNotify != NULL )
+ {
+ vTaskNotifyGiveFromISR( ether_receive_check_task_handle, &xHigherPriorityTaskWoken );
+ }
+
+ /* If xHigherPriorityTaskWoken is now set to pdTRUE then a context switch
+ * should be performed to ensure the interrupt returns directly to the highest
+ * priority task. The macro used for this purpose is dependent on the port in
+ * use and may be called portEND_SWITCHING_ISR(). */
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ /*TODO complete interrupt handler for other events. */
+ }
+} /* End of function EINT_Trig_isr() */
+
+
+static void clear_all_ether_rx_discriptors( uint32_t event )
+{
+ int32_t xBytesReceived;
+ uint8_t * buffer_pointer;
+
+ /* Avoid compiler warning about unreferenced parameter. */
+ ( void ) event;
+
+ while( 1 )
+ {
+ /* See how much data was received. */
+ xBytesReceived = R_ETHER_Read_ZC2( ETHER_CHANNEL_0, ( void ** ) &buffer_pointer );
+
+ if( 0 > xBytesReceived )
+ {
+ /* This is an error. Ignored. */
+ }
+ else if( 0 < xBytesReceived )
+ {
+ R_ETHER_Read_ZC2_BufRelease( ETHER_CHANNEL_0 );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ else
+ {
+ break;
+ }
+ }
+}
+
+/***********************************************************************************************************************
+ * End of file "NetworkInterface.c"
+ **********************************************************************************************************************/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c
index c42d8a20b..8cb38ce30 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/RX/ether_callback.c
@@ -1,177 +1,177 @@
-/***********************************************************************************************************************
-* DISCLAIMER
-* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
-* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
-* applicable laws, including copyright laws.
-* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
-* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
-* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
-* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
-* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
-* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
-* this software. By using this software, you agree to the additional terms and conditions found by accessing the
-* following link:
-* http://www.renesas.com/disclaimer
-*
-* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
-***********************************************************************************************************************/
-/***********************************************************************************************************************
-* File Name : ether_callback.c
-* Version : ----
-* Description : This module solves all the world's problems
-***********************************************************************************************************************/
-/**********************************************************************************************************************
-* History : DD.MM.YYYY Version Description
-* : 05.01.2015 ---- Clean up source code.
-***********************************************************************************************************************/
-
-/***********************************************************************************************************************
-Includes <System Includes> , "Project Includes"
-***********************************************************************************************************************/
-#include "r_ether_rx_if.h"
-
-/***********************************************************************************************************************
-Private global variables and functions
-***********************************************************************************************************************/
-int32_t callback_ether_regist(void);
-void callback_ether(void * pparam);
-static void callback_wakeon_lan(uint32_t channel);
-static void callback_link_on(uint32_t channel);
-static void callback_link_off(uint32_t channel);
-
-volatile uint8_t pause_enable = ETHER_FLAG_OFF;
-volatile uint8_t magic_packet_detect[ETHER_CHANNEL_MAX];
-volatile uint8_t link_detect[ETHER_CHANNEL_MAX];
-
-void EINT_Trig_isr(void *);
-
-/*
- * When that Link Status changes, the following function will be called:
- */
-void prvLinkStatusChange( BaseType_t xStatus );
-
-/***********************************************************************************************************************
-* Function Name: callback_ether
-* Description : Regist of callback function
-* Arguments : -
-* Return Value : 0: success, -1:failed
-***********************************************************************************************************************/
-int32_t callback_ether_regist(void)
-{
- ether_param_t param;
- ether_cb_t cb_func;
-
- int32_t ret;
-
- /* Set the callback function (LAN cable connect/disconnect event) */
- cb_func.pcb_func = &callback_ether;
- param.ether_callback = cb_func;
- ret = R_ETHER_Control(CONTROL_SET_CALLBACK, param);
- if (ETHER_SUCCESS != ret)
- {
- return -1;
- }
-
- /* Set the callback function (Ether interrupt event) */
- cb_func.pcb_int_hnd = &EINT_Trig_isr;
- param.ether_callback = cb_func;
- ret = R_ETHER_Control(CONTROL_SET_INT_HANDLER, param);
- if (ETHER_SUCCESS != ret)
- {
- return -1;
- }
- return 0;
-} /* End of function callback_ether_regist() */
-
-/***********************************************************************************************************************
-* Function Name: callback_ether
-* Description : Sample of the callback function
-* Arguments : pparam -
-*
-* Return Value : none
-***********************************************************************************************************************/
-void callback_ether(void * pparam)
-{
- ether_cb_arg_t * pdecode;
- uint32_t channel;
-
- pdecode = (ether_cb_arg_t *)pparam;
- channel = pdecode->channel; /* Get Ethernet channel number */
-
- switch (pdecode->event_id)
- {
- /* Callback function that notifies user to have detected magic packet. */
- case ETHER_CB_EVENT_ID_WAKEON_LAN:
- callback_wakeon_lan(channel);
- break;
-
- /* Callback function that notifies user to have become Link up. */
- case ETHER_CB_EVENT_ID_LINK_ON:
- callback_link_on(channel);
- break;
-
- /* Callback function that notifies user to have become Link down. */
- case ETHER_CB_EVENT_ID_LINK_OFF:
- callback_link_off(channel);
- break;
-
- default:
- break;
- }
-} /* End of function callback_ether() */
-
-/***********************************************************************************************************************
-* Function Name: callback_wakeon_lan
-* Description :
-* Arguments : channel -
-* Ethernet channel number
-* Return Value : none
-***********************************************************************************************************************/
-static void callback_wakeon_lan(uint32_t channel)
-{
- if (ETHER_CHANNEL_MAX > channel)
- {
- magic_packet_detect[channel] = 1;
-
- /* Please add necessary processing when magic packet is detected. */
- }
-} /* End of function callback_wakeon_lan() */
-
-/***********************************************************************************************************************
-* Function Name: callback_link_on
-* Description :
-* Arguments : channel -
-* Ethernet channel number
-* Return Value : none
-***********************************************************************************************************************/
-static void callback_link_on(uint32_t channel)
-{
- if (ETHER_CHANNEL_MAX > channel)
- {
- link_detect[channel] = ETHER_FLAG_ON_LINK_ON;
-
- /* Please add necessary processing when becoming Link up. */
- prvLinkStatusChange( 1 );
- }
-} /* End of function callback_link_on() */
-
-/***********************************************************************************************************************
-* Function Name: callback_link_off
-* Description :
-* Arguments : channel -
-* Ethernet channel number
-* Return Value : none
-***********************************************************************************************************************/
-static void callback_link_off(uint32_t channel)
-{
- if (ETHER_CHANNEL_MAX > channel)
- {
- link_detect[channel] = ETHER_FLAG_ON_LINK_OFF;
-
- /* Please add necessary processing when becoming Link down. */
- prvLinkStatusChange( 0 );
- }
-} /* End of function ether_cb_link_off() */
-
-/* End of File */
+/***********************************************************************************************************************
+* DISCLAIMER
+* This software is supplied by Renesas Electronics Corporation and is only intended for use with Renesas products. No
+* other uses are authorized. This software is owned by Renesas Electronics Corporation and is protected under all
+* applicable laws, including copyright laws.
+* THIS SOFTWARE IS PROVIDED "AS IS" AND RENESAS MAKES NO WARRANTIES REGARDING
+* THIS SOFTWARE, WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING BUT NOT LIMITED TO WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. ALL SUCH WARRANTIES ARE EXPRESSLY DISCLAIMED. TO THE MAXIMUM
+* EXTENT PERMITTED NOT PROHIBITED BY LAW, NEITHER RENESAS ELECTRONICS CORPORATION NOR ANY OF ITS AFFILIATED COMPANIES
+* SHALL BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES FOR ANY REASON RELATED TO THIS
+* SOFTWARE, EVEN IF RENESAS OR ITS AFFILIATES HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
+* Renesas reserves the right, without notice, to make changes to this software and to discontinue the availability of
+* this software. By using this software, you agree to the additional terms and conditions found by accessing the
+* following link:
+* http://www.renesas.com/disclaimer
+*
+* Copyright (C) 2015 Renesas Electronics Corporation. All rights reserved.
+***********************************************************************************************************************/
+/***********************************************************************************************************************
+* File Name : ether_callback.c
+* Version : ----
+* Description : This module solves all the world's problems
+***********************************************************************************************************************/
+/**********************************************************************************************************************
+* History : DD.MM.YYYY Version Description
+* : 05.01.2015 ---- Clean up source code.
+***********************************************************************************************************************/
+
+/***********************************************************************************************************************
+Includes <System Includes> , "Project Includes"
+***********************************************************************************************************************/
+#include "r_ether_rx_if.h"
+
+/***********************************************************************************************************************
+Private global variables and functions
+***********************************************************************************************************************/
+int32_t callback_ether_regist(void);
+void callback_ether(void * pparam);
+static void callback_wakeon_lan(uint32_t channel);
+static void callback_link_on(uint32_t channel);
+static void callback_link_off(uint32_t channel);
+
+volatile uint8_t pause_enable = ETHER_FLAG_OFF;
+volatile uint8_t magic_packet_detect[ETHER_CHANNEL_MAX];
+volatile uint8_t link_detect[ETHER_CHANNEL_MAX];
+
+void EINT_Trig_isr(void *);
+
+/*
+ * When that Link Status changes, the following function will be called:
+ */
+void prvLinkStatusChange( BaseType_t xStatus );
+
+/***********************************************************************************************************************
+* Function Name: callback_ether
+* Description : Regist of callback function
+* Arguments : -
+* Return Value : 0: success, -1:failed
+***********************************************************************************************************************/
+int32_t callback_ether_regist(void)
+{
+ ether_param_t param;
+ ether_cb_t cb_func;
+
+ int32_t ret;
+
+ /* Set the callback function (LAN cable connect/disconnect event) */
+ cb_func.pcb_func = &callback_ether;
+ param.ether_callback = cb_func;
+ ret = R_ETHER_Control(CONTROL_SET_CALLBACK, param);
+ if (ETHER_SUCCESS != ret)
+ {
+ return -1;
+ }
+
+ /* Set the callback function (Ether interrupt event) */
+ cb_func.pcb_int_hnd = &EINT_Trig_isr;
+ param.ether_callback = cb_func;
+ ret = R_ETHER_Control(CONTROL_SET_INT_HANDLER, param);
+ if (ETHER_SUCCESS != ret)
+ {
+ return -1;
+ }
+ return 0;
+} /* End of function callback_ether_regist() */
+
+/***********************************************************************************************************************
+* Function Name: callback_ether
+* Description : Sample of the callback function
+* Arguments : pparam -
+*
+* Return Value : none
+***********************************************************************************************************************/
+void callback_ether(void * pparam)
+{
+ ether_cb_arg_t * pdecode;
+ uint32_t channel;
+
+ pdecode = (ether_cb_arg_t *)pparam;
+ channel = pdecode->channel; /* Get Ethernet channel number */
+
+ switch (pdecode->event_id)
+ {
+ /* Callback function that notifies user to have detected magic packet. */
+ case ETHER_CB_EVENT_ID_WAKEON_LAN:
+ callback_wakeon_lan(channel);
+ break;
+
+ /* Callback function that notifies user to have become Link up. */
+ case ETHER_CB_EVENT_ID_LINK_ON:
+ callback_link_on(channel);
+ break;
+
+ /* Callback function that notifies user to have become Link down. */
+ case ETHER_CB_EVENT_ID_LINK_OFF:
+ callback_link_off(channel);
+ break;
+
+ default:
+ break;
+ }
+} /* End of function callback_ether() */
+
+/***********************************************************************************************************************
+* Function Name: callback_wakeon_lan
+* Description :
+* Arguments : channel -
+* Ethernet channel number
+* Return Value : none
+***********************************************************************************************************************/
+static void callback_wakeon_lan(uint32_t channel)
+{
+ if (ETHER_CHANNEL_MAX > channel)
+ {
+ magic_packet_detect[channel] = 1;
+
+ /* Please add necessary processing when magic packet is detected. */
+ }
+} /* End of function callback_wakeon_lan() */
+
+/***********************************************************************************************************************
+* Function Name: callback_link_on
+* Description :
+* Arguments : channel -
+* Ethernet channel number
+* Return Value : none
+***********************************************************************************************************************/
+static void callback_link_on(uint32_t channel)
+{
+ if (ETHER_CHANNEL_MAX > channel)
+ {
+ link_detect[channel] = ETHER_FLAG_ON_LINK_ON;
+
+ /* Please add necessary processing when becoming Link up. */
+ prvLinkStatusChange( 1 );
+ }
+} /* End of function callback_link_on() */
+
+/***********************************************************************************************************************
+* Function Name: callback_link_off
+* Description :
+* Arguments : channel -
+* Ethernet channel number
+* Return Value : none
+***********************************************************************************************************************/
+static void callback_link_off(uint32_t channel)
+{
+ if (ETHER_CHANNEL_MAX > channel)
+ {
+ link_detect[channel] = ETHER_FLAG_ON_LINK_OFF;
+
+ /* Please add necessary processing when becoming Link down. */
+ prvLinkStatusChange( 0 );
+ }
+} /* End of function ether_cb_link_off() */
+
+/* End of File */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c
index 44d19f3a9..adc603c52 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/SH2A/NetworkInterface.c
@@ -1,118 +1,118 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "NetworkBufferManagement.h"
-
-/* Hardware includes. */
-#include "hwEthernet.h"
-
-/* Demo includes. */
-#include "NetworkInterface.h"
-
-#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* When a packet is ready to be sent, if it cannot be sent immediately then the
-task performing the transmit will block for niTX_BUFFER_FREE_WAIT
-milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
-up. */
-#define niTX_BUFFER_FREE_WAIT ( ( TickType_t ) 2UL / portTICK_PERIOD_MS )
-#define niMAX_TX_ATTEMPTS ( 5 )
-
-/* The length of the queue used to send interrupt status words from the
-interrupt handler to the deferred handler task. */
-#define niINTERRUPT_QUEUE_LENGTH ( 10 )
-
-/*-----------------------------------------------------------*/
-
-/*
- * A deferred interrupt handler task that processes
- */
-extern void vEMACHandlerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* The queue used to communicate Ethernet events with the IP task. */
-extern QueueHandle_t xNetworkEventQueue;
-
-/* The semaphore used to wake the deferred interrupt handler task when an Rx
-interrupt is received. */
-SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-BaseType_t xStatus, xReturn;
-extern uint8_t ucMACAddress[ 6 ];
-
- /* Initialise the MAC. */
- vInitEmac();
-
- while( lEMACWaitForLink() != pdPASS )
- {
- vTaskDelay( 20 );
- }
-
- vSemaphoreCreateBinary( xEMACRxEventSemaphore );
- configASSERT( xEMACRxEventSemaphore );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( vEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
- xReturn = pdPASS;
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
-extern void vEMACCopyWrite( uint8_t * pucBuffer, uint16_t usLength );
-
- vEMACCopyWrite( pxNetworkBuffer->pucBuffer, pxNetworkBuffer->xDataLength );
-
- /* Finished with the network buffer. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "NetworkBufferManagement.h"
+
+/* Hardware includes. */
+#include "hwEthernet.h"
+
+/* Demo includes. */
+#include "NetworkInterface.h"
+
+#if ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES != 1
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* When a packet is ready to be sent, if it cannot be sent immediately then the
+task performing the transmit will block for niTX_BUFFER_FREE_WAIT
+milliseconds. It will do this a maximum of niMAX_TX_ATTEMPTS before giving
+up. */
+#define niTX_BUFFER_FREE_WAIT ( ( TickType_t ) 2UL / portTICK_PERIOD_MS )
+#define niMAX_TX_ATTEMPTS ( 5 )
+
+/* The length of the queue used to send interrupt status words from the
+interrupt handler to the deferred handler task. */
+#define niINTERRUPT_QUEUE_LENGTH ( 10 )
+
+/*-----------------------------------------------------------*/
+
+/*
+ * A deferred interrupt handler task that processes
+ */
+extern void vEMACHandlerTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* The queue used to communicate Ethernet events with the IP task. */
+extern QueueHandle_t xNetworkEventQueue;
+
+/* The semaphore used to wake the deferred interrupt handler task when an Rx
+interrupt is received. */
+SemaphoreHandle_t xEMACRxEventSemaphore = NULL;
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+BaseType_t xStatus, xReturn;
+extern uint8_t ucMACAddress[ 6 ];
+
+ /* Initialise the MAC. */
+ vInitEmac();
+
+ while( lEMACWaitForLink() != pdPASS )
+ {
+ vTaskDelay( 20 );
+ }
+
+ vSemaphoreCreateBinary( xEMACRxEventSemaphore );
+ configASSERT( xEMACRxEventSemaphore );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( vEMACHandlerTask, "EMAC", configMINIMAL_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, NULL );
+ xReturn = pdPASS;
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+extern void vEMACCopyWrite( uint8_t * pucBuffer, uint16_t usLength );
+
+ vEMACCopyWrite( pxNetworkBuffer->pucBuffer, pxNetworkBuffer->xDataLength );
+
+ /* Finished with the network buffer. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/NetworkInterface.c
deleted file mode 100644
index 7de2902f8..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/NetworkInterface.c
+++ /dev/null
@@ -1,1193 +0,0 @@
-/*
- * Some constants, hardware definitions and comments taken from ST's HAL driver
- * library, COPYRIGHT(c) 2015 STMicroelectronics.
- */
-
-/*
- * FreeRTOS+TCP V2.0.11
- * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy of
- * this software and associated documentation files (the "Software"), to deal in
- * the Software without restriction, including without limitation the rights to
- * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
- * the Software, and to permit persons to whom the Software is furnished to do so,
- * subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in all
- * copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
- * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
- * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * http://www.FreeRTOS.org
- * http://aws.amazon.com/freertos
- *
- * 1 tab == 4 spaces!
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_DNS.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "phyHandling.h"
-
-/* ST includes. */
-#ifdef STM32F7xx
- #include "stm32f7xx_hal.h"
-#else
- #include "stm32f4xx_hal.h"
-#endif
-
-/* Interrupt events to process. Currently only the Rx event is processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-#define ETH_DMA_ALL_INTS \
- ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_ER | \
- ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
- ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-
-
-
-#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
-
-/*
- * Most users will want a PHY that negotiates about
- * the connection properties: speed, dmix and duplex.
- * On some rare cases, you want to select what is being
- * advertised, properties like MDIX and duplex.
- */
-
-#if !defined( ipconfigETHERNET_AN_ENABLE )
- /* Enable auto-negotiation */
- #define ipconfigETHERNET_AN_ENABLE 1
-#endif
-
-#if !defined( ipconfigETHERNET_AUTO_CROSS_ENABLE )
- #define ipconfigETHERNET_AUTO_CROSS_ENABLE 1
-#endif
-
-#if( ipconfigETHERNET_AN_ENABLE == 0 )
- /*
- * The following three defines are only used in case there
- * is no auto-negotiation.
- */
- #if !defined( ipconfigETHERNET_CROSSED_LINK )
- #define ipconfigETHERNET_CROSSED_LINK 1
- #endif
-
- #if !defined( ipconfigETHERNET_USE_100MB )
- #define ipconfigETHERNET_USE_100MB 1
- #endif
-
- #if !defined( ipconfigETHERNET_USE_FULL_DUPLEX )
- #define ipconfigETHERNET_USE_FULL_DUPLEX 1
- #endif
-#endif /* ipconfigETHERNET_AN_ENABLE == 0 */
-
-/* Default the size of the stack used by the EMAC deferred handler task to twice
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-#endif
-
-/* Two choices must be made: RMII versus MII,
-and the index of the PHY in use ( between 0 and 31 ). */
-#ifndef ipconfigUSE_RMII
- #ifdef STM32F7xx
- #define ipconfigUSE_RMII 1
- #else
- #define ipconfigUSE_RMII 0
- #endif /* STM32F7xx */
-#endif /* ipconfigUSE_RMII */
-
-#ifndef ipconfigPHY_INDEX
- #ifdef STM32F7xx
- #define ipconfigPHY_INDEX 0
- #else
- #define ipconfigPHY_INDEX 1
- #endif /* STM32F7xx */
-#endif /* ipconfigPHY_INDEX */
-
-
-/*-----------------------------------------------------------*/
-
-/*
- * A deferred interrupt handler task that processes
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Force a negotiation with the Switch or Router and wait for LS.
- */
-static void prvEthernetUpdateConfig( BaseType_t xForce );
-
-/*
- * See if there is a new packet and forward it to the IP-task.
- */
-static BaseType_t prvNetworkInterfaceInput( void );
-
-#if( ipconfigUSE_LLMNR != 0 )
- /*
- * For LLMNR, an extra MAC-address must be configured to
- * be able to receive the multicast messages.
- */
- static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr);
-#endif
-
-/*
- * Check if a given packet should be accepted.
- */
-static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer );
-
-/*
- * Initialise the TX descriptors.
- */
-static void prvDMATxDescListInit( void );
-
-/*
- * Initialise the RX descriptors.
- */
-static void prvDMARxDescListInit( void );
-
-/* After packets have been sent, the network
-buffers will be released. */
-static void vClearTXBuffers( void );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx interrupt is handled, although code is included for other events to
-enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-#if( ipconfigUSE_LLMNR == 1 )
- static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
-#endif
-
-static EthernetPhy_t xPhyObject;
-
-/* Ethernet handle. */
-static ETH_HandleTypeDef xETH;
-
-/* xTXDescriptorSemaphore is a counting semaphore with
-a maximum count of ETH_TXBUFNB, which is the number of
-DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*
- * Note: it is adviced to define both
- *
- * #define ipconfigZERO_COPY_RX_DRIVER 1
- * #define ipconfigZERO_COPY_TX_DRIVER 1
- *
- * The method using memcpy is slower and probaly uses more RAM memory.
- * The possibility is left in the code just for comparison.
- *
- * It is adviced to define ETH_TXBUFNB at least 4. Note that no
- * TX buffers are allocated in a zero-copy driver.
- */
-/* MAC buffers: ---------------------------------------------------------*/
-
-/* Put the DMA descriptors in '.first_data'.
-This is important for STM32F7, which has an L1 data cache.
-The first 64KB of the SRAM is not cached. */
-
-/* Ethernet Rx MA Descriptor */
-__attribute__ ((aligned (32)))
-__attribute__ ((section(".first_data")))
- ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ];
-
-#if( ipconfigZERO_COPY_RX_DRIVER == 0 )
- /* Ethernet Receive Buffer */
- __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;
-#endif
-
-/* Ethernet Tx DMA Descriptor */
-__attribute__ ((aligned (32)))
-__attribute__ ((section(".first_data")))
- ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ];
-
-#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- /* Ethernet Transmit Buffer */
- __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;
-#endif
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* DMATxDescToClear points to the next TX DMA descriptor
- that must be cleared by vClearTXBuffers(). */
- static __IO ETH_DMADescTypeDef *DMATxDescToClear;
-#endif
-
-/* ucMACAddress as it appears in main.c */
-extern const uint8_t ucMACAddress[ 6 ];
-
-/* Holds the handle of the task used as a deferred interrupt processor. The
-handle is used so direct notifications can be sent to the task for all EMAC/DMA
-related interrupts. */
-static TaskHandle_t xEMACTaskHandle = NULL;
-
-/* For local use only: describe the PHY's properties: */
-const PhyProperties_t xPHYProperties =
-{
- #if( ipconfigETHERNET_AN_ENABLE != 0 )
- .ucSpeed = PHY_SPEED_AUTO,
- .ucDuplex = PHY_DUPLEX_AUTO,
- #else
- #if( ipconfigETHERNET_USE_100MB != 0 )
- .ucSpeed = PHY_SPEED_100,
- #else
- .ucSpeed = PHY_SPEED_10,
- #endif
-
- #if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
- .duplex = PHY_DUPLEX_FULL,
- #else
- .duplex = PHY_DUPLEX_HALF,
- #endif
- #endif
-
- #if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )
- .ucMDI_X = PHY_MDIX_AUTO,
- #elif( ipconfigETHERNET_CROSSED_LINK != 0 )
- .ucMDI_X = PHY_MDIX_CROSSED,
- #else
- .ucMDI_X = PHY_MDIX_DIRECT,
- #endif
-};
-
-/*-----------------------------------------------------------*/
-
-void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- /* Ethernet RX-Complete callback function, elsewhere declared as weak. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- /* Wakeup the prvEMACHandlerTask. */
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
-}
-/*-----------------------------------------------------------*/
-
-void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- /* This call-back is only useful in case packets are being sent
- zero-copy. Once they're sent, the buffers will be released
- by the function vClearTXBuffers(). */
- ulISREvents |= EMAC_IF_TX_EVENT;
- /* Wakeup the prvEMACHandlerTask. */
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
-
-}
-/*-----------------------------------------------------------*/
-
-static void vClearTXBuffers()
-{
-__IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
-size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- uint8_t *ucPayLoad;
-#endif
-
- /* This function is called after a TX-completion interrupt.
- It will release each Network Buffer used in xNetworkInterfaceOutput().
- 'uxCount' represents the number of descriptors given to DMA for transmission.
- After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
- while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
- {
- if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
- {
- break;
- }
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
-
- if( ucPayLoad != NULL )
- {
- pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
- if( pxNetworkBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
- }
- DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;
- }
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
-
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-HAL_StatusTypeDef hal_eth_init_status;
-BaseType_t xResult;
-
- if( xEMACTaskHandle == NULL )
- {
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
- configASSERT( xTXDescriptorSemaphore );
- }
-
- /* Initialise ETH */
-
- xETH.Instance = ETH;
-//#warning Enable auto-nego again
- xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
-// xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_DISABLE;
- xETH.Init.Speed = ETH_SPEED_100M;
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- xETH.Init.PhyAddress = ipconfigPHY_INDEX;
-
- xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;
- xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
-
- /* using the ETH_CHECKSUM_BY_HARDWARE option:
- both the IP and the protocol checksums will be calculated
- by the peripheral. */
- xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
-
- #if( ipconfigUSE_RMII != 0 )
- {
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
- }
- #else
- {
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
- }
- #endif /* ipconfigUSE_RMII */
-
- hal_eth_init_status = HAL_ETH_Init( &xETH );
-
- /* Only for inspection by debugger. */
- ( void ) hal_eth_init_status;
-
- /* Set the TxDesc and RxDesc pointers. */
- xETH.TxDesc = DMATxDscrTab;
- xETH.RxDesc = DMARxDscrTab;
-
- /* Make sure that all unused fields are cleared. */
- memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
- memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
-
- /* Initialize Tx Descriptors list: Chain Mode */
- DMATxDescToClear = DMATxDscrTab;
-
- /* Initialise TX-descriptors. */
- prvDMATxDescListInit();
-
- /* Initialise RX-descriptors. */
- prvDMARxDescListInit();
-
- #if( ipconfigUSE_LLMNR != 0 )
- {
- /* Program the LLMNR address at index 1. */
- prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
- }
- #endif
-
- /* Force a negotiation with the Switch or Router and wait for LS. */
- prvEthernetUpdateConfig( pdTRUE );
-
- /* The deferred interrupt handler task is created at the highest
- possible priority to ensure the interrupt handler can return directly
- to it. The task's handle is stored in xEMACTaskHandle so interrupts can
- notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- } /* if( xEMACTaskHandle == NULL ) */
-
- if( xPhyObject.ulLinkStatusMask != 0 )
- {
- xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
- xResult = pdPASS;
- FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
- }
- else
- {
- /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
- and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
- xResult = pdFAIL;
- FreeRTOS_printf( ( "Link Status still low\n" ) ) ;
- }
- /* When returning non-zero, the stack will become active and
- start DHCP (in configured) */
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-static void prvDMATxDescListInit()
-{
-ETH_DMADescTypeDef *pxDMADescriptor;
-BaseType_t xIndex;
-
- /* Get the pointer on the first member of the descriptor list */
- pxDMADescriptor = DMATxDscrTab;
-
- /* Fill each DMA descriptor with the right values */
- for( xIndex = 0; xIndex < ETH_TXBUFNB; xIndex++, pxDMADescriptor++ )
- {
- /* Set Second Address Chained bit */
- pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- {
- /* Set Buffer1 address pointer */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( Tx_Buff[ xIndex ] );
- }
- #endif
-
- if( xETH.Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE )
- {
- /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
- pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if( xIndex < ETH_TXBUFNB - 1 )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMADescriptor + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMATxDscrTab;
- }
- }
-
- /* Set Transmit Descriptor List Address Register */
- xETH.Instance->DMATDLAR = ( uint32_t ) DMATxDscrTab;
-}
-/*-----------------------------------------------------------*/
-
-static void prvDMARxDescListInit()
-{
-ETH_DMADescTypeDef *pxDMADescriptor;
-BaseType_t xIndex;
- /*
- * RX-descriptors.
- */
-
- /* Get the pointer on the first member of the descriptor list */
- pxDMADescriptor = DMARxDscrTab;
-
- /* Fill each DMA descriptor with the right values */
- for( xIndex = 0; xIndex < ETH_RXBUFNB; xIndex++, pxDMADescriptor++ )
- {
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Set Buffer1 address pointer */
- NetworkBufferDescriptor_t *pxBuffer;
-
- pxBuffer = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, 100ul );
- /* If the assert below fails, make sure that there are at least 'ETH_RXBUFNB'
- Network Buffers available during start-up ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) */
- configASSERT( pxBuffer != NULL );
- if( pxBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = (uint32_t)pxBuffer->pucEthernetBuffer;
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
- }
- }
- #else
- {
- /* Set Buffer1 address pointer */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( Rx_Buff[ xIndex ] );
- /* Set Own bit of the Rx descriptor Status */
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
- }
- #endif
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if( xIndex < ETH_RXBUFNB - 1 )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t )( pxDMADescriptor + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMARxDscrTab;
- }
-
- }
- /* Set Receive Descriptor List Address Register */
- xETH.Instance->DMARDLAR = ( uint32_t ) DMARxDscrTab;
-}
-/*-----------------------------------------------------------*/
-
-static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr)
-{
-uint32_t ulTempReg;
-
- /* Calculate the selected MAC address high register. */
- ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
-
- /* Load the selected MAC address high register. */
- ( *(__IO uint32_t *)( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + ulIndex ) ) ) = ulTempReg;
-
- /* Calculate the selected MAC address low register. */
- ulTempReg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ];
-
- /* Load the selected MAC address low register */
- ( *(__IO uint32_t *) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + ulIndex ) ) ) = ulTempReg;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
-{
-BaseType_t xReturn = pdFAIL;
-uint32_t ulTransmitSize = 0;
-__IO ETH_DMADescTypeDef *pxDmaTxDesc;
-/* Do not wait too long for a free TX DMA buffer. */
-const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
-
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
- {
- ProtocolPacket_t *pxPacket;
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- configASSERT( bReleaseAfterSend != 0 );
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- /* If the peripheral must calculate the checksum, it wants
- the protocol checksum to have a value of zero. */
- pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
-
- if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
- {
- pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
- }
- }
- #endif
-
- /* Open a do {} while ( 0 ) loop to be able to call break. */
- do
- {
- if( xPhyObject.ulLinkStatusMask != 0 )
- {
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- break;
- }
-
- /* This function does the actual transmission of the packet. The packet is
- contained in 'pxDescriptor' that is passed to the function. */
- pxDmaTxDesc = xETH.TxDesc;
-
- /* Is this buffer available? */
- configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );
-
- {
- /* Is this buffer available? */
- /* Get bytes in current buffer. */
- ulTransmitSize = pxDescriptor->xDataLength;
-
- if( ulTransmitSize > ETH_TX_BUF_SIZE )
- {
- ulTransmitSize = ETH_TX_BUF_SIZE;
- }
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- {
- /* Copy the bytes. */
- memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );
- }
- #else
- {
- /* Move the buffer. */
- pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
- /* The Network Buffer has been passed to DMA, no need to release it. */
- bReleaseAfterSend = pdFALSE_UNSIGNED;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- /* Ask to set the IPv4 checksum.
- Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
-
- /* Prepare transmit descriptors to give to DMA. */
-
- /* Set LAST and FIRST segment */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
- /* Set frame size */
- pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
-
- /* Point to next descriptor */
- xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );
- /* Ensure completion of memory access */
- __DSB();
- /* Resume DMA transmission*/
- xETH.Instance->DMATPDR = 0;
- iptraceNETWORK_INTERFACE_TRANSMIT();
- xReturn = pdPASS;
- }
- }
- else
- {
- /* The PHY has no Link Status, packet shall be dropped. */
- }
- } while( 0 );
- /* The buffer has been sent so can be released. */
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer )
-{
-const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
-
- switch( pxProtPacket->xTCPPacket.xEthernetHeader.usFrameType )
- {
- case ipARP_FRAME_TYPE:
- /* Check it later. */
- return pdTRUE;
- case ipIPv4_FRAME_TYPE:
- /* Check it here. */
- break;
- default:
- /* Refuse the packet. */
- return pdFALSE;
- }
-
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
- {
- const IPHeader_t *pxIPHeader = &(pxProtPacket->xTCPPacket.xIPHeader);
- uint32_t ulDestinationIPAddress;
-
- /* Ensure that the incoming packet is not fragmented (only outgoing packets
- * can be fragmented) as these are the only handled IP frames currently. */
- if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U )
- {
- return pdFALSE;
- }
- /* HT: Might want to make the following configurable because
- * most IP messages have a standard length of 20 bytes */
-
- /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
- * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
- if( pxIPHeader->ucVersionHeaderLength < 0x45 || pxIPHeader->ucVersionHeaderLength > 0x4F )
- {
- return pdFALSE;
- }
-
- ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
- /* Is the packet for this node? */
- if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
- /* Is it a broadcast address x.x.x.255 ? */
- ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xff ) != 0xff ) &&
- #if( ipconfigUSE_LLMNR == 1 )
- ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
- #endif
- ( *ipLOCAL_IP_ADDRESS_POINTER != 0 ) ) {
- FreeRTOS_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) );
- return pdFALSE;
- }
-
- if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
- {
- uint16_t port = pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort;
-
- if( ( xPortHasUDPSocket( port ) == pdFALSE )
- #if ipconfigUSE_LLMNR == 1
- && ( port != FreeRTOS_ntohs( ipLLMNR_PORT ) )
- #endif
- #if ipconfigUSE_NBNS == 1
- && ( port != FreeRTOS_ntohs( ipNBNS_PORT ) )
- #endif
- #if ipconfigUSE_DNS == 1
- && ( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort != FreeRTOS_ntohs( ipDNS_PORT ) )
- #endif
- ) {
- /* Drop this packet, not for this device. */
- return pdFALSE;
- }
- }
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvNetworkInterfaceInput( void )
-{
-NetworkBufferDescriptor_t *pxCurDescriptor;
-NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
-BaseType_t xReceivedLength, xAccepted;
-__IO ETH_DMADescTypeDef *pxDMARxDescriptor;
-xIPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-uint8_t *pucBuffer;
-
- pxDMARxDescriptor = xETH.RxDesc;
-
- if( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN) == 0 )
- {
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
-
- pucBuffer = (uint8_t *) pxDMARxDescriptor->Buffer1Addr;
-
- /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
- /* Chained Mode */
- /* Selects the next DMA Rx descriptor list for next buffer to read */
- xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
- }
- else
- {
- xReceivedLength = 0;
- }
-
- /* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
-
- /* get received frame */
- if( xReceivedLength > 0ul )
- {
- /* In order to make the code easier and faster, only packets in a single buffer
- will be accepted. This can be done by making the buffers large enough to
- hold a complete Ethernet packet (1536 bytes).
- Therefore, two sanity checks: */
- configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
-
- if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
- {
- /* Not an Ethernet frame-type or a checmsum error. */
- xAccepted = pdFALSE;
- }
- else
- {
- /* See if this packet must be handled. */
- xAccepted = xMayAcceptPacket( pucBuffer );
- }
-
- if( xAccepted != pdFALSE )
- {
- /* The packet wil be accepted, but check first if a new Network Buffer can
- be obtained. If not, the packet will still be dropped. */
- pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, xDescriptorWaitTime );
-
- if( pxNewDescriptor == NULL )
- {
- /* A new descriptor can not be allocated now. This packet will be dropped. */
- xAccepted = pdFALSE;
- }
- }
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Find out which Network Buffer was originally passed to the descriptor. */
- pxCurDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
- configASSERT( pxCurDescriptor != NULL );
- }
- #else
- {
- /* In this mode, the two descriptors are the same. */
- pxCurDescriptor = pxNewDescriptor;
- if( pxNewDescriptor != NULL )
- {
- /* The packet is acepted and a new Network Buffer was created,
- copy data to the Network Bufffer. */
- memcpy( pxNewDescriptor->pucEthernetBuffer, pucBuffer, xReceivedLength );
- }
- }
- #endif
-
- if( xAccepted != pdFALSE )
- {
- pxCurDescriptor->xDataLength = xReceivedLength;
- xRxEvent.pvData = ( void * ) pxCurDescriptor;
-
- /* Pass the data to the TCP/IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
- {
- /* Could not send the descriptor into the TCP/IP stack, it
- must be released. */
- vReleaseNetworkBufferAndDescriptor( pxCurDescriptor );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- else
- {
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
- }
-
- /* Release descriptors to DMA */
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Set Buffer1 address pointer */
- if( pxNewDescriptor != NULL )
- {
- pxDMARxDescriptor->Buffer1Addr = (uint32_t)pxNewDescriptor->pucEthernetBuffer;
- }
- else
- {
- /* The packet was dropped and the same Network
- Buffer will be used to receive a new packet. */
- }
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
- pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;
-
- /* Ensure completion of memory access */
- __DSB();
- /* When Rx Buffer unavailable flag is set clear it and resume
- reception. */
- if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )
- {
- /* Clear RBUS ETHERNET DMA flag. */
- xETH.Instance->DMASR = ETH_DMASR_RBUS;
-
- /* Resume DMA reception. */
- xETH.Instance->DMARPDR = 0;
- }
- }
-
- return ( xReceivedLength > 0 );
-}
-/*-----------------------------------------------------------*/
-
-
-BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )
-{
-uint16_t usPrevAddress = xETH.Init.PhyAddress;
-BaseType_t xResult;
-HAL_StatusTypeDef xHALResult;
-
- xETH.Init.PhyAddress = xAddress;
- xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );
- xETH.Init.PhyAddress = usPrevAddress;
-
- if( xHALResult == HAL_OK )
- {
- xResult = 0;
- }
- else
- {
- xResult = -1;
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )
-{
-uint16_t usPrevAddress = xETH.Init.PhyAddress;
-BaseType_t xResult;
-HAL_StatusTypeDef xHALResult;
-
- xETH.Init.PhyAddress = xAddress;
- xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );
- xETH.Init.PhyAddress = usPrevAddress;
-
- if( xHALResult == HAL_OK )
- {
- xResult = 0;
- }
- else
- {
- xResult = -1;
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-void phy_test()
-{
-BaseType_t xPhyCount;
-BaseType_t xPhyIndex;
-
- vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
- xPhyCount = xPhyDiscover( &xPhyObject );
- FreeRTOS_printf( ( "PHY count %ld\n", xPhyCount ) );
- for( xPhyIndex = 0; xPhyIndex < xPhyCount; xPhyIndex++ )
- {
- FreeRTOS_printf( ( "PHY[%d] at address %d ( 0x%08X )\n",
- xPhyIndex,
- xPhyObject.ucPhyIndexes[ xPhyIndex ],
- xPhyObject.ulPhyIDs[ xPhyIndex ] ) );
-
- }
-
-}
-
-void vMACBProbePhy( void )
-{
- vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
- xPhyDiscover( &xPhyObject );
- xPhyConfigure( &xPhyObject, &xPHYProperties );
-}
-/*-----------------------------------------------------------*/
-
-static void prvEthernetUpdateConfig( BaseType_t xForce )
-{
- FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02X Force %d\n",
- xPhyObject.ulLinkStatusMask,
- ( int )xForce ) );
-
- if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )
- {
- /* Restart the auto-negotiation. */
- if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )
- {
- xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );
-
- /* Configure the MAC with the Duplex Mode fixed by the
- auto-negotiation process. */
- if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )
- {
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- }
- else
- {
- xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
- }
-
- /* Configure the MAC with the speed fixed by the
- auto-negotiation process. */
- if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )
- {
- xETH.Init.Speed = ETH_SPEED_10M;
- }
- else
- {
- xETH.Init.Speed = ETH_SPEED_100M;
- }
- }
- else /* AutoNegotiation Disable */
- {
- /* Check parameters */
- assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );
- assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );
-
- if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )
- {
- xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;
- }
- else
- {
- xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;
- }
-
- if( xETH.Init.Speed == ETH_SPEED_10M )
- {
- xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;
- }
- else
- {
- xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;
- }
-
- xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;
-
- /* Use predefined (fixed) configuration. */
- xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );
- }
-
- /* ETHERNET MAC Re-Configuration */
- HAL_ETH_ConfigMAC( &xETH, (ETH_MACInitTypeDef *) NULL);
-
- /* Restart MAC interface */
- HAL_ETH_Start( &xETH);
- }
- else
- {
- /* Stop MAC interface */
- HAL_ETH_Stop( &xETH );
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xReturn;
-
- if( xPhyObject.ulLinkStatusMask != 0 )
- {
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-#define niBUFFER_1_PACKET_SIZE 1536
-
-static __attribute__ ((section(".first_data"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-
-uint8_t *ucRAMBuffer = ucNetworkPackets;
-uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-UBaseType_t uxLastMinBufferCount = 0;
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
-UBaseType_t uxLastMinQueueSpace = 0;
-#endif
-UBaseType_t uxCurrentCount;
-BaseType_t xResult;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- xResult = 0;
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- if( xTXDescriptorSemaphore != NULL )
- {
- static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
-
- uxCurrentCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );
- if( uxLowestSemCount > uxCurrentCount )
- {
- uxLowestSemCount = uxCurrentCount;
- FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
- }
-
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- xResult = prvNetworkInterfaceInput();
- if( xResult > 0 )
- {
- while( prvNetworkInterfaceInput() > 0 )
- {
- }
- }
- }
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- /* Check if DMA packets have been delivered. */
- vClearTXBuffers();
- }
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
- {
- /* Future extension: logging about errors that occurred. */
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
- }
- if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )
- {
- /* Something has changed to a Link Status, need re-check. */
- prvEthernetUpdateConfig( pdFALSE );
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-void ETH_IRQHandler( void )
-{
- HAL_ETH_IRQHandler( &xETH );
-}
-
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.c
deleted file mode 100644
index 6f335c512..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.c
+++ /dev/null
@@ -1,1835 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f7xx_hal_eth.c
- * @author MCD Application Team
- * @version V1.3.2
- * @date 26-June-2015
- * @brief ETH HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Ethernet (ETH) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#)Declare a ETH_HandleTypeDef handle structure, for example:
- ETH_HandleTypeDef heth;
-
- (#)Fill parameters of Init structure in heth handle
-
- (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
-
- (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
- (##) Enable the Ethernet interface clock using
- (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
-
- (##) Initialize the related GPIO clocks
- (##) Configure Ethernet pin-out
- (##) Configure Ethernet NVIC interrupt (IT mode)
-
- (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
- (##) HAL_ETH_DMATxDescListInit(); for Transmission process
- (##) HAL_ETH_DMARxDescListInit(); for Reception process
-
- (#)Enable MAC and DMA transmission and reception:
- (##) HAL_ETH_Start();
-
- (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
- the frame to MAC TX FIFO:
- (##) HAL_ETH_TransmitFrame();
-
- (#)Poll for a received frame in ETH RX DMA Descriptors and get received
- frame parameters
- (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
-
- (#) Get a received frame when an ETH RX interrupt occurs:
- (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
-
- (#) Communicate with external PHY device:
- (##) Read a specific register from the PHY
- HAL_ETH_ReadPHYRegister();
- (##) Write data to a specific RHY register:
- HAL_ETH_WritePHYRegister();
-
- (#) Configure the Ethernet MAC after ETH peripheral initialization
- HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
-
- (#) Configure the Ethernet DMA after ETH peripheral initialization
- HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
-
- -@- The PTP protocol and the DMA descriptors ring mode are not supported
- in this driver
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f7xx_hal.h"
-
-
-int lUDPLoggingPrintf( const char *pcFormatString, ... );
-
-/** @addtogroup STM32F4xx_HAL_Driver
- * @{
- */
-
-/** @defgroup ETH ETH
- * @brief ETH HAL module driver
- * @{
- */
-
-#if !defined( ARRAY_SIZE )
- #define ARRAY_SIZE( x ) ( sizeof ( x ) / sizeof ( x )[ 0 ] )
-#endif
-
-#ifdef HAL_ETH_MODULE_ENABLED
-
-#if defined(STM32F7xx)
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup ETH_Private_Constants ETH Private Constants
- * @{
- */
-#define LINKED_STATE_TIMEOUT_VALUE ((uint32_t)2000) /* 2000 ms */
-#define AUTONEGO_COMPLETED_TIMEOUT_VALUE ((uint32_t)1000) /* 1000 ms */
-
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup ETH_Private_Functions ETH Private Functions
- * @{
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
-
-/**
- * @}
- */
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup ETH_Exported_Functions ETH Exported Functions
- * @{
- */
-
-/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize and configure the Ethernet peripheral
- (+) De-initialize the Ethernet peripheral
-
- @endverbatim
- * @{
- */
-extern void vMACBProbePhy ( void );
-
-/**
- * @brief Initializes the Ethernet MAC and DMA according to default
- * parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = 0;
- uint32_t hclk = 60000000;
- uint32_t err = ETH_SUCCESS;
-
- /* Check the ETH peripheral state */
- if( heth == NULL )
- {
- return HAL_ERROR;
- }
-
- /* Check parameters */
- assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
- assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
- assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
- assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
-
- if( heth->State == HAL_ETH_STATE_RESET )
- {
- /* Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspInit( heth );
- }
-
- /* Enable SYSCFG Clock */
- __HAL_RCC_SYSCFG_CLK_ENABLE();
-
- /* Select MII or RMII Mode*/
- SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
- SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface;
-
- /* Ethernet Software reset */
- /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
- /* After reset all the registers holds their respective reset values */
- /* Also enable EDFE: Enhanced descriptor format enable. */
-// heth->Instance->DMABMR |= ETH_DMABMR_SR | ETH_DMABMR_EDE;
- heth->Instance->DMABMR |= ETH_DMABMR_SR;
-
- /* Wait for software reset */
- while ((heth->Instance->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
- {
- }
-
- /*-------------------------------- MAC Initialization ----------------------*/
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
- /* Clear CSR Clock Range CR[2:0] bits */
- tmpreg &= ETH_MACMIIAR_CR_MASK;
-
- /* Get hclk frequency value (168,000,000) */
- hclk = HAL_RCC_GetHCLKFreq();
-
- /* Set CR bits depending on hclk value */
- if( ( hclk >= 20000000 ) && ( hclk < 35000000 ) )
- {
- /* CSR Clock Range between 20-35 MHz */
- tmpreg |= (uint32_t) ETH_MACMIIAR_CR_Div16;
- }
- else if( ( hclk >= 35000000 ) && ( hclk < 60000000 ) )
- {
- /* CSR Clock Range between 35-60 MHz */
- tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26;
- }
- else if((hclk >= 60000000 ) && ( hclk < 100000000 ) )
- {
- /* CSR Clock Range between 60-100 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
- }
- else if((hclk >= 100000000 ) && ( hclk < 150000000))
- {
- /* CSR Clock Range between 100-150 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
- }
- else /* ((hclk >= 150000000 ) && ( hclk <= 168000000)) */
- {
- /* CSR Clock Range between 150-168 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
- }
-
- /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
- heth->Instance->MACMIIAR = (uint32_t)tmpreg;
-
- /* Initialise the MACB and set all PHY properties */
- vMACBProbePhy();
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief De-Initializes the ETH peripheral.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
-{
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspDeInit( heth );
-
- /* Set ETH HAL state to Disabled */
- heth->State= HAL_ETH_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Tx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMATxDescTab: Pointer to the first Tx desc list
- * @param TxBuff: Pointer to the first TxBuffer list
- * @param TxBuffCount: Number of the used Tx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *pxDMATable, uint8_t *ucDataBuffer, uint32_t ulBufferCount)
-{
- uint32_t i = 0;
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the TxDesc pointer with the first one of the pxDMATable list */
- heth->TxDesc = pxDMATable;
-
- /* Fill each DMA descriptor with the right values */
- for( i=0; i < ulBufferCount; i++ )
- {
- /* Get the pointer on the ith member of the descriptor list */
- pxDMADescriptor = pxDMATable + i;
-
- /* Set Second Address Chained bit */
- pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
-
- pxDMADescriptor->ControlBufferSize = 0;
-
- /* Set Buffer1 address pointer */
- if( ucDataBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( &ucDataBuffer[ i * ETH_TX_BUF_SIZE ] );
- }
- else
- {
- /* Buffer space is not provided because it uses zero-copy transmissions. */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )0u;
- }
-
- if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
- pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if(i < ( ulBufferCount - 1 ) )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMATable + i + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) pxDMATable;
- }
- }
-
- /* Set Transmit Descriptor List Address Register */
- heth->Instance->DMATDLAR = ( uint32_t ) pxDMATable;
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Rx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMARxDescTab: Pointer to the first Rx desc list
- * @param RxBuff: Pointer to the first RxBuffer list
- * @param RxBuffCount: Number of the used Rx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *pxDMATable, uint8_t *ucDataBuffer, uint32_t ulBufferCount)
-{
- uint32_t i = 0;
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the RxDesc pointer with the first one of the pxDMATable list */
- heth->RxDesc = pxDMATable;
-
- /* Fill each DMA descriptor with the right values */
- for(i=0; i < ulBufferCount; i++)
- {
- /* Get the pointer on the ith member of the descriptor list */
- pxDMADescriptor = pxDMATable+i;
-
- /* Set Own bit of the Rx descriptor Status */
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
-
- /* Set Buffer1 address pointer */
- if( ucDataBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( &ucDataBuffer[ i * ETH_RX_BUF_SIZE ] );
- }
- else
- {
- /* Buffer space is not provided because it uses zero-copy reception. */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )0u;
- }
-
- if( heth->Init.RxMode == ETH_RXINTERRUPT_MODE )
- {
- /* Enable Ethernet DMA Rx Descriptor interrupt */
- pxDMADescriptor->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if(i < (ulBufferCount-1))
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = (uint32_t)(pxDMATable+i+1);
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) pxDMATable;
- }
- }
-
- /* Set Receive Descriptor List Address Register */
- heth->Instance->DMARDLAR = ( uint32_t ) pxDMATable;
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
- @verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Transmit a frame
- HAL_ETH_TransmitFrame();
- (+) Receive a frame
- HAL_ETH_GetReceivedFrame();
- HAL_ETH_GetReceivedFrame_IT();
- (+) Read from an External PHY register
- HAL_ETH_ReadPHYRegister();
- (+) Write to an External PHY register
- HAL_ETH_WritePHYRegister();
-
- @endverbatim
-
- * @{
- */
-
-/**
- * @brief Sends an Ethernet frame.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param FrameLength: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
-{
- uint32_t bufcount = 0, size = 0, i = 0;
- __IO ETH_DMADescTypeDef *pxDmaTxDesc = heth->TxDesc;
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- if( FrameLength == 0 )
- {
- /* Set ETH HAL state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- return HAL_ERROR;
- }
-
- /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
- if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) != ( uint32_t ) RESET )
- {
- /* OWN bit set */
- heth->State = HAL_ETH_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- return HAL_ERROR;
- }
-
- /* Get the number of needed Tx buffers for the current frame, rounding up. */
- bufcount = ( FrameLength + ETH_TX_BUF_SIZE - 1 ) / ETH_TX_BUF_SIZE;
-
- if (bufcount == 1)
- {
- /* Set LAST and FIRST segment */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
- /* Set frame size */
- pxDmaTxDesc->ControlBufferSize = ( FrameLength & ETH_DMATXDESC_TBS1 );
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
- /* Point to next descriptor */
- heth->TxDesc = ( ETH_DMADescTypeDef * ) ( heth->TxDesc->Buffer2NextDescAddr );
- }
- else
- {
- for( i = 0; i < bufcount; i++ )
- {
- /* Clear FIRST and LAST segment bits */
- uint32_t ulStatus = heth->TxDesc->Status & ~( ETH_DMATXDESC_FS | ETH_DMATXDESC_LS );
-
- if( i == 0 )
- {
- /* Setting the first segment bit */
- heth->TxDesc->Status = ulStatus | ETH_DMATXDESC_FS;
- }
-
- /* Program size */
- if (i < (bufcount-1))
- {
- heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
- }
- else
- {
- /* Setting the last segment bit */
- heth->TxDesc->Status = ulStatus | ETH_DMATXDESC_LS;
- size = FrameLength - (bufcount-1)*ETH_TX_BUF_SIZE;
- heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
- }
-
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
- /* point to next descriptor */
- heth->TxDesc = (ETH_DMADescTypeDef *)( heth->TxDesc->Buffer2NextDescAddr );
- }
- }
-
- __DSB();
-
- /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
- if( ( heth->Instance->DMASR & ETH_DMASR_TBUS ) != ( uint32_t )RESET )
- {
- heth->Instance->DMACHTDR = ( uint32_t )pxDmaTxDesc;
-
- /* Clear TBUS ETHERNET DMA flag */
- heth->Instance->DMASR = ETH_DMASR_TBUS;
- /* Resume DMA transmission*/
- heth->Instance->DMATPDR = 0;
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Checks for received frames.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT( ETH_HandleTypeDef *heth )
-{
- return HAL_ETH_GetReceivedFrame( heth );
-}
-
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame( ETH_HandleTypeDef *heth )
-{
-uint32_t ulCounter = 0;
-ETH_DMADescTypeDef *pxDescriptor = heth->RxDesc;
-HAL_StatusTypeDef xResult = HAL_ERROR;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Check the ETH state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Scan descriptors owned by CPU */
- while( ( ( pxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0ul ) && ( ulCounter < ETH_RXBUFNB ) )
- {
- uint32_t ulStatus = pxDescriptor->Status;
-
- /* Just for security. */
- ulCounter++;
-
- if( ( ulStatus & ( ETH_DMARXDESC_FS | ETH_DMARXDESC_LS ) ) == ( uint32_t )ETH_DMARXDESC_FS )
- {
- /* First segment in frame, but not the last. */
- heth->RxFrameInfos.FSRxDesc = pxDescriptor;
- heth->RxFrameInfos.LSRxDesc = ( ETH_DMADescTypeDef *)NULL;
- heth->RxFrameInfos.SegCount = 1;
- /* Point to next descriptor. */
- pxDescriptor = (ETH_DMADescTypeDef*) (pxDescriptor->Buffer2NextDescAddr);
- heth->RxDesc = pxDescriptor;
- }
- else if( ( ulStatus & ( ETH_DMARXDESC_LS | ETH_DMARXDESC_FS ) ) == 0ul )
- {
- /* This is an intermediate segment, not first, not last. */
- /* Increment segment count. */
- heth->RxFrameInfos.SegCount++;
- /* Move to the next descriptor. */
- pxDescriptor = ( ETH_DMADescTypeDef * ) ( pxDescriptor->Buffer2NextDescAddr );
- heth->RxDesc = pxDescriptor;
- }
- /* Must be a last segment */
- else
- {
- /* This is the last segment. */
- /* Check if last segment is first segment: one segment contains the frame */
- if( heth->RxFrameInfos.SegCount == 0 )
- {
- /* Remember the first segment. */
- heth->RxFrameInfos.FSRxDesc = pxDescriptor;
- }
-
- /* Increment segment count */
- heth->RxFrameInfos.SegCount++;
-
- /* Remember the last segment. */
- heth->RxFrameInfos.LSRxDesc = pxDescriptor;
-
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- heth->RxFrameInfos.length =
- ( ( ulStatus & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
-
- /* Get the address of the buffer start address */
- heth->RxFrameInfos.buffer = heth->RxFrameInfos.FSRxDesc->Buffer1Addr;
-
- /* Point to next descriptor */
- heth->RxDesc = ( ETH_DMADescTypeDef * ) pxDescriptor->Buffer2NextDescAddr;
-
- /* Return OK status: a packet was received. */
- xResult = HAL_OK;
- break;
- }
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return xResult;
-}
-
-#if( STM32_ETHERNET_STATS != 0 )
-
- volatile int rx_count, tx_count, int_count;
- /**
- * @brief This function handles ETH interrupt request.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
- volatile int int_counts[32];
- volatile int tx_status[8];
- volatile unsigned sr_history[32];
- volatile int sr_head;
- #define STM32_STAT_INC( x ) do { ( x )++; } while( 0 )
-
-#else
- #define STM32_STAT_INC( x ) do { } while( 0 )
-#endif /* STM32_ETHERNET_STATS */
-
-#define ETH_DMA_ALL_INTS \
- ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_AIS | ETH_DMA_IT_ER | \
- ETH_DMA_IT_FBE | ETH_DMA_IT_ET | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
- ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-
-//#define ETH_DMA_ALL_INTS ETH_DMA_IT_RBU | ETH_DMA_FLAG_T | ETH_DMA_FLAG_AIS
-
-#define INT_MASK ( ( uint32_t ) ~ ( ETH_DMA_IT_TBU ) )
-void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
-{
- uint32_t dmasr;
-
- STM32_STAT_INC( int_count );
-
- dmasr = heth->Instance->DMASR & ETH_DMA_ALL_INTS;
- heth->Instance->DMASR = dmasr;
-
-#if( STM32_ETHERNET_STATS != 0 )
- if( sr_head < ARRAY_SIZE( sr_history ) )
- {
- sr_history[ sr_head++ ] = dmasr;
- }
-
- {
- int i;
- for (i = 0; i < 32; i++) {
- if (dmasr & (1u << i)) {
- int_counts[i]++;
- }
- }
- tx_status[ ( dmasr >> 20 ) & 0x07 ]++;
- }
-#endif
-
- /* Frame received */
- if( ( dmasr & ( ETH_DMA_FLAG_R | ETH_DMA_IT_RBU ) ) != 0 )
- {
- /* Receive complete callback */
- HAL_ETH_RxCpltCallback( heth );
- STM32_STAT_INC( rx_count );
- }
- /* Frame transmitted */
- if( ( dmasr & ( ETH_DMA_FLAG_T ) ) != 0 )
- {
- /* Transfer complete callback */
- HAL_ETH_TxCpltCallback( heth );
- STM32_STAT_INC( tx_count );
- }
-
- /* ETH DMA Error */
- if( ( dmasr & ( ETH_DMA_FLAG_AIS ) ) != 0 )
- {
- /* Ethernet Error callback */
- HAL_ETH_ErrorCallback( heth );
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Ethernet transfer error callbacks
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Reads a PHY register
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Basic Control Register,
- * PHY_BSR: Transceiver Basic Status Register.
- * More PHY register could be read depending on the used PHY
- * @param RegValue: PHY register value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
-{
-uint32_t tmpreg = 0;
-uint32_t tickstart = 0;
-HAL_StatusTypeDef xResult;
-
- /* Check parameters */
- assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
-
- /* Check the ETH peripheral state */
- if( heth->State == HAL_ETH_STATE_BUSY_RD )
- {
- xResult = HAL_BUSY;
- }
- else
- {
- __HAL_LOCK( heth );
-
- /* Set ETH HAL State to BUSY_RD */
- heth->State = HAL_ETH_STATE_BUSY_RD;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII address register value */
- tmpreg |= ( ( ( uint32_t )heth->Init.PhyAddress << 11) & ETH_MACMIIAR_PA ); /* Set the PHY device address */
- tmpreg |= ( ( ( uint32_t )PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */
- tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while( 1 )
- {
- tmpreg = heth->Instance->MACMIIAR;
-
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul )
- {
- /* Get MACMIIDR value */
- *RegValue = ( uint32_t ) heth->Instance->MACMIIDR;
- xResult = HAL_OK;
- break;
- }
- /* Check for the Timeout */
- if( ( HAL_GetTick( ) - tickstart ) > PHY_READ_TO )
- {
- xResult = HAL_TIMEOUT;
- break;
- }
-
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
- }
-
- if( xResult != HAL_OK )
- {
- lUDPLoggingPrintf( "ReadPHY: %d\n", xResult );
- }
- /* Return function status */
- return xResult;
-}
-
-/**
- * @brief Writes to a PHY register.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Control Register.
- * More PHY register could be written depending on the used PHY
- * @param RegValue: the value to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
-{
-uint32_t tmpreg = 0;
-uint32_t tickstart = 0;
-HAL_StatusTypeDef xResult;
-
- /* Check parameters */
- assert_param( IS_ETH_PHY_ADDRESS( heth->Init.PhyAddress ) );
-
- /* Check the ETH peripheral state */
- if( heth->State == HAL_ETH_STATE_BUSY_WR )
- {
- xResult = HAL_BUSY;
- }
- else
- {
- __HAL_LOCK( heth );
-
- /* Set ETH HAL State to BUSY_WR */
- heth->State = HAL_ETH_STATE_BUSY_WR;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII register address value */
- tmpreg |= ( ( ( uint32_t ) heth->Init.PhyAddress << 11 ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */
- tmpreg |= ( ( ( uint32_t ) PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */
- tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Give the value to the MII data register */
- heth->Instance->MACMIIDR = ( uint16_t ) RegValue;
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while( 1 )
- {
- tmpreg = heth->Instance->MACMIIAR;
-
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul )
- {
- xResult = HAL_OK;
- break;
- }
- /* Check for the Timeout */
- if( ( HAL_GetTick( ) - tickstart ) > PHY_WRITE_TO )
- {
- xResult = HAL_TIMEOUT;
- break;
- }
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
- }
-
- if( xResult != HAL_OK )
- {
- lUDPLoggingPrintf( "WritePHY: %d\n", xResult );
- }
- /* Return function status */
- return xResult;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Enable MAC and DMA transmission and reception.
- HAL_ETH_Start();
- (+) Disable MAC and DMA transmission and reception.
- HAL_ETH_Stop();
- (+) Set the MAC configuration in runtime mode
- HAL_ETH_ConfigMAC();
- (+) Set the DMA configuration in runtime mode
- HAL_ETH_ConfigDMA();
-
-@endverbatim
- * @{
- */
-
- /**
- * @brief Enables Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef *heth )
-{
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Enable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionEnable( heth );
-
- /* Enable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionEnable( heth );
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO( heth );
-
- /* Start DMA transmission */
- ETH_DMATransmissionEnable( heth );
-
- /* Start DMA reception */
- ETH_DMAReceptionEnable( heth );
-
- /* Set the ETH state to READY*/
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stop Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
-{
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Stop DMA transmission */
- ETH_DMATransmissionDisable( heth );
-
- /* Stop DMA reception */
- ETH_DMAReceptionDisable( heth );
-
- /* Disable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionDisable( heth );
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO( heth );
-
- /* Disable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionDisable( heth );
-
- /* Set the ETH state*/
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-static void prvWriteMACFCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->MACFCR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->MACFCR;
-
- HAL_Delay( ETH_REG_WRITE_DELAY );
-
- heth->Instance->MACFCR = ulValue;
-}
-
-static void prvWriteDMAOMR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->DMAOMR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->DMAOMR;
-
- HAL_Delay( ETH_REG_WRITE_DELAY );
-
- heth->Instance->DMAOMR = ulValue;
-}
-
-static void prvWriteMACCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->MACCR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->MACCR;
-
- HAL_Delay( ETH_REG_WRITE_DELAY );
-
- heth->Instance->MACCR = ulValue;
-}
-
-/**
- * @brief Set ETH MAC Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param macconf: MAC Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
-{
- uint32_t tmpreg = 0;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State= HAL_ETH_STATE_BUSY;
-
- assert_param(IS_ETH_SPEED(heth->Init.Speed));
- assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
-
- if (macconf != NULL)
- {
- /* Check the parameters */
- assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
- assert_param(IS_ETH_JABBER(macconf->Jabber));
- assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
- assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
- assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
- assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
- assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
- assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
- assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
- assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
- assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
- assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
- assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
- assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
- assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
- assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
- assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
- assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
- assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
- assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
- assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
- assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
- assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
- assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
- assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
- assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
- assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg &= ETH_MACCR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)(
- macconf->Watchdog |
- macconf->Jabber |
- macconf->InterFrameGap |
- macconf->CarrierSense |
- heth->Init.Speed |
- macconf->ReceiveOwn |
- macconf->LoopbackMode |
- heth->Init.DuplexMode |
- macconf->ChecksumOffload |
- macconf->RetryTransmission |
- macconf->AutomaticPadCRCStrip |
- macconf->BackOffLimit |
- macconf->DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Write to ETHERNET MACFFR */
- heth->Instance->MACFFR = (uint32_t)(
- macconf->ReceiveAll |
- macconf->SourceAddrFilter |
- macconf->PassControlFrames |
- macconf->BroadcastFramesReception |
- macconf->DestinationAddrFilter |
- macconf->PromiscuousMode |
- macconf->MulticastFramesFilter |
- macconf->UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACFFR = tmpreg;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
- /* Write to ETHERNET MACHTHR */
- heth->Instance->MACHTHR = (uint32_t)macconf->HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- heth->Instance->MACHTLR = (uint32_t)macconf->HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration --------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg = heth->Instance->MACFCR;
- /* Clear xx bits */
- tmpreg &= ETH_MACFCR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)((
- macconf->PauseTime << 16) |
- macconf->ZeroQuantaPause |
- macconf->PauseLowThreshold |
- macconf->UnicastPauseFrameDetect |
- macconf->ReceiveFlowControl |
- macconf->TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- prvWriteMACFCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
- heth->Instance->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
- macconf->VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACVLANTR = tmpreg;
- }
- else /* macconf == NULL : here we just configure Speed and Duplex mode */
- {
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
-
- /* Clear FES and DM bits */
- tmpreg &= ~((uint32_t)0x00004800);
-
- tmpreg |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
- }
-
- /* Set the ETH state to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Sets ETH DMA Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param dmaconf: DMA Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
-{
- uint32_t tmpreg = 0;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State= HAL_ETH_STATE_BUSY;
-
- /* Check parameters */
- assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
- assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
- assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
- assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
- assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
- assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
- assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
- assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
- assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
- assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
- assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
- assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
- assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
- assert_param(IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(dmaconf->EnhancedDescriptorFormat));
- assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
- assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
-
- /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
- /* Get the ETHERNET DMAOMR value */
- tmpreg = heth->Instance->DMAOMR;
- /* Clear xx bits */
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)(
- dmaconf->DropTCPIPChecksumErrorFrame |
- dmaconf->ReceiveStoreForward |
- dmaconf->FlushReceivedFrame |
- dmaconf->TransmitStoreForward |
- dmaconf->TransmitThresholdControl |
- dmaconf->ForwardErrorFrames |
- dmaconf->ForwardUndersizedGoodFrames |
- dmaconf->ReceiveThresholdControl |
- dmaconf->SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- prvWriteDMAOMR( heth, tmpreg );
-
- /*----------------------- ETHERNET DMABMR Configuration --------------------*/
- heth->Instance->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
- dmaconf->FixedBurst |
- dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmaconf->TxDMABurstLength |
- dmaconf->EnhancedDescriptorFormat |
- (dmaconf->DescriptorSkipLength << 2) |
- dmaconf->DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->DMABMR = tmpreg;
-
- /* Set the ETH state to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
- (+) Get the ETH handle state:
- HAL_ETH_GetState();
-
-
- @endverbatim
- * @{
- */
-
-/**
- * @brief Return the ETH HAL state
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL state
- */
-HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
-{
- /* Return ETH state */
- return heth->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup ETH_Private_Functions
- * @{
- */
-
-/**
- * @brief Configures Ethernet MAC and DMA with default parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param err: Ethernet Init error
- * @retval HAL status
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
-{
- ETH_MACInitTypeDef macinit;
- ETH_DMAInitTypeDef dmainit;
- uint32_t tmpreg = 0;
-
- if (err != ETH_SUCCESS) /* Auto-negotiation failed */
- {
- /* Set Ethernet duplex mode to Full-duplex */
- heth->Init.DuplexMode = ETH_MODE_FULLDUPLEX;
-
- /* Set Ethernet speed to 100M */
- heth->Init.Speed = ETH_SPEED_100M;
- }
-
- /* Ethernet MAC default initialization **************************************/
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;
- macinit.Jabber = ETH_JABBER_ENABLE;
- macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
- macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
- macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
- if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
- }
- else
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
- }
- macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
- macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
- macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
- macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
- macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
- macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
- macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
- macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
- macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
- macinit.HashTableHigh = 0x0;
- macinit.HashTableLow = 0x0;
- macinit.PauseTime = 0x0;
- macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
- macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
- macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
- macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
- macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
- macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
- macinit.VLANTagIdentifier = 0x0;
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg &= ETH_MACCR_CLEAR_MASK;
- /* Set the WD bit according to ETH Watchdog value */
- /* Set the JD: bit according to ETH Jabber value */
- /* Set the IFG bit according to ETH InterFrameGap value */
- /* Set the DCRS bit according to ETH CarrierSense value */
- /* Set the FES bit according to ETH Speed value */
- /* Set the DO bit according to ETH ReceiveOwn value */
- /* Set the LM bit according to ETH LoopbackMode value */
- /* Set the DM bit according to ETH Mode value */
- /* Set the IPCO bit according to ETH ChecksumOffload value */
- /* Set the DR bit according to ETH RetryTransmission value */
- /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
- /* Set the BL bit according to ETH BackOffLimit value */
- /* Set the DC bit according to ETH DeferralCheck value */
- tmpreg |= (uint32_t)(macinit.Watchdog |
- macinit.Jabber |
- macinit.InterFrameGap |
- macinit.CarrierSense |
- heth->Init.Speed |
- macinit.ReceiveOwn |
- macinit.LoopbackMode |
- heth->Init.DuplexMode |
- macinit.ChecksumOffload |
- macinit.RetryTransmission |
- macinit.AutomaticPadCRCStrip |
- macinit.BackOffLimit |
- macinit.DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Set the RA bit according to ETH ReceiveAll value */
- /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
- /* Set the PCF bit according to ETH PassControlFrames value */
- /* Set the DBF bit according to ETH BroadcastFramesReception value */
- /* Set the DAIF bit according to ETH DestinationAddrFilter value */
- /* Set the PR bit according to ETH PromiscuousMode value */
- /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
- /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
- /* Write to ETHERNET MACFFR */
- heth->Instance->MACFFR = (uint32_t)(macinit.ReceiveAll |
- macinit.SourceAddrFilter |
- macinit.PassControlFrames |
- macinit.BroadcastFramesReception |
- macinit.DestinationAddrFilter |
- macinit.PromiscuousMode |
- macinit.MulticastFramesFilter |
- macinit.UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACFFR = tmpreg;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
- /* Write to ETHERNET MACHTHR */
- heth->Instance->MACHTHR = (uint32_t)macinit.HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- heth->Instance->MACHTLR = (uint32_t)macinit.HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration -------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg = heth->Instance->MACFCR;
- /* Clear xx bits */
- tmpreg &= ETH_MACFCR_CLEAR_MASK;
-
- /* Set the PT bit according to ETH PauseTime value */
- /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
- /* Set the PLT bit according to ETH PauseLowThreshold value */
- /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
- /* Set the RFE bit according to ETH ReceiveFlowControl value */
- /* Set the TFE bit according to ETH TransmitFlowControl value */
- tmpreg |= (uint32_t)((macinit.PauseTime << 16) |
- macinit.ZeroQuantaPause |
- macinit.PauseLowThreshold |
- macinit.UnicastPauseFrameDetect |
- macinit.ReceiveFlowControl |
- macinit.TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- prvWriteMACFCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
- /* Set the ETV bit according to ETH VLANTagComparison value */
- /* Set the VL bit according to ETH VLANTagIdentifier value */
- heth->Instance->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
- macinit.VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACVLANTR = tmpreg;
-
- /* Ethernet DMA default initialization ************************************/
- dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
- dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
- dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
- dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
- dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
- dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
- dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
- dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
- dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
- dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
- dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
- dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
- dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
- dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
- dmainit.DescriptorSkipLength = 0x0;
- dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
-
- /* Get the ETHERNET DMAOMR value */
- tmpreg = heth->Instance->DMAOMR;
- /* Clear xx bits */
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;
-
- /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
- /* Set the RSF bit according to ETH ReceiveStoreForward value */
- /* Set the DFF bit according to ETH FlushReceivedFrame value */
- /* Set the TSF bit according to ETH TransmitStoreForward value */
- /* Set the TTC bit according to ETH TransmitThresholdControl value */
- /* Set the FEF bit according to ETH ForwardErrorFrames value */
- /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
- /* Set the RTC bit according to ETH ReceiveThresholdControl value */
- /* Set the OSF bit according to ETH SecondFrameOperate value */
- tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
- dmainit.ReceiveStoreForward |
- dmainit.FlushReceivedFrame |
- dmainit.TransmitStoreForward |
- dmainit.TransmitThresholdControl |
- dmainit.ForwardErrorFrames |
- dmainit.ForwardUndersizedGoodFrames |
- dmainit.ReceiveThresholdControl |
- dmainit.SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- prvWriteDMAOMR( heth, tmpreg );
-
- /*----------------------- ETHERNET DMABMR Configuration ------------------*/
- /* Set the AAL bit according to ETH AddressAlignedBeats value */
- /* Set the FB bit according to ETH FixedBurst value */
- /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
- /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
- /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
- /* Set the DSL bit according to ETH DesciptorSkipLength value */
- /* Set the PR and DA bits according to ETH DMAArbitration value */
- heth->Instance->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
- dmainit.FixedBurst |
- dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmainit.TxDMABurstLength |
- dmainit.EnhancedDescriptorFormat |
- (dmainit.DescriptorSkipLength << 2) |
- dmainit.DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->DMABMR = tmpreg;
-
- if(heth->Init.RxMode == ETH_RXINTERRUPT_MODE)
- {
- /* Enable the Ethernet Rx Interrupt */
- __HAL_ETH_DMA_ENABLE_IT(( heth ), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
- }
-
- /* Initialize MAC address in ethernet MAC */
- ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
-}
-
-/**
- * @brief Configures the selected MAC address.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param MacAddr: The MAC address to configure
- * This parameter can be one of the following values:
- * @arg ETH_MAC_Address0: MAC Address0
- * @arg ETH_MAC_Address1: MAC Address1
- * @arg ETH_MAC_Address2: MAC Address2
- * @arg ETH_MAC_Address3: MAC Address3
- * @param Addr: Pointer to MAC address buffer data (6 bytes)
- * @retval HAL status
- */
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
-{
- uint32_t tmpreg;
-
- /* Check the parameters */
- assert_param( IS_ETH_MAC_ADDRESS0123( MacAddr ) );
-
- /* Calculate the selected MAC address high register */
- tmpreg = 0x80000000ul | ( ( uint32_t )Addr[ 5 ] << 8) | (uint32_t)Addr[ 4 ];
- /* Load the selected MAC address high register */
- ( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg;
- /* Calculate the selected MAC address low register */
- tmpreg = ( ( uint32_t )Addr[ 3 ] << 24 ) | ( ( uint32_t )Addr[ 2 ] << 16 ) | ( ( uint32_t )Addr[ 1 ] << 8 ) | Addr[ 0 ];
-
- /* Load the selected MAC address low register */
- ( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + MacAddr ) ) ) = tmpreg;
-}
-
-/**
- * @brief Enables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_TE;
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_TE );
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_RE;
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_RE );
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA transmission */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_ST;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA transmission */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_ST );
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA reception */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_SR;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA reception */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_SR );
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Clears the ETHERNET transmit FIFO.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
-{
- /* Set the Flush Transmit FIFO bit */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_FTF;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @}
- */
-
-#endif /* STM32F7xx */
-#endif /* HAL_ETH_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.h
deleted file mode 100644
index 0c401936b..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32F7xx/stm32f7xx_hal_eth.h
+++ /dev/null
@@ -1,2214 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f7xx_hal_eth.h
- * @author MCD Application Team
- * @version V1.2.2
- * @date 14-April-2017
- * @brief Header file of ETH HAL module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32F7xx_HAL_ETH_H
-#define __STM32F7xx_HAL_ETH_H
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f7xx_hal_def.h"
-
-/** @addtogroup STM32F7xx_HAL_Driver
- * @{
- */
-
-/** @addtogroup ETH
- * @{
- */
-
-/** @addtogroup ETH_Private_Macros
- * @{
- */
-#define IS_ETH_PHY_ADDRESS(ADDRESS) ((ADDRESS) <= 0x20)
-#define IS_ETH_AUTONEGOTIATION(CMD) (((CMD) == ETH_AUTONEGOTIATION_ENABLE) || \
- ((CMD) == ETH_AUTONEGOTIATION_DISABLE))
-#define IS_ETH_SPEED(SPEED) (((SPEED) == ETH_SPEED_10M) || \
- ((SPEED) == ETH_SPEED_100M))
-#define IS_ETH_DUPLEX_MODE(MODE) (((MODE) == ETH_MODE_FULLDUPLEX) || \
- ((MODE) == ETH_MODE_HALFDUPLEX))
-#define IS_ETH_RX_MODE(MODE) (((MODE) == ETH_RXPOLLING_MODE) || \
- ((MODE) == ETH_RXINTERRUPT_MODE))
-#define IS_ETH_CHECKSUM_MODE(MODE) (((MODE) == ETH_CHECKSUM_BY_HARDWARE) || \
- ((MODE) == ETH_CHECKSUM_BY_SOFTWARE))
-#define IS_ETH_MEDIA_INTERFACE(MODE) (((MODE) == ETH_MEDIA_INTERFACE_MII) || \
- ((MODE) == ETH_MEDIA_INTERFACE_RMII))
-#define IS_ETH_WATCHDOG(CMD) (((CMD) == ETH_WATCHDOG_ENABLE) || \
- ((CMD) == ETH_WATCHDOG_DISABLE))
-#define IS_ETH_JABBER(CMD) (((CMD) == ETH_JABBER_ENABLE) || \
- ((CMD) == ETH_JABBER_DISABLE))
-#define IS_ETH_INTER_FRAME_GAP(GAP) (((GAP) == ETH_INTERFRAMEGAP_96BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_88BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_80BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_72BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_64BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_56BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_48BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_40BIT))
-#define IS_ETH_CARRIER_SENSE(CMD) (((CMD) == ETH_CARRIERSENCE_ENABLE) || \
- ((CMD) == ETH_CARRIERSENCE_DISABLE))
-#define IS_ETH_RECEIVE_OWN(CMD) (((CMD) == ETH_RECEIVEOWN_ENABLE) || \
- ((CMD) == ETH_RECEIVEOWN_DISABLE))
-#define IS_ETH_LOOPBACK_MODE(CMD) (((CMD) == ETH_LOOPBACKMODE_ENABLE) || \
- ((CMD) == ETH_LOOPBACKMODE_DISABLE))
-#define IS_ETH_CHECKSUM_OFFLOAD(CMD) (((CMD) == ETH_CHECKSUMOFFLAOD_ENABLE) || \
- ((CMD) == ETH_CHECKSUMOFFLAOD_DISABLE))
-#define IS_ETH_RETRY_TRANSMISSION(CMD) (((CMD) == ETH_RETRYTRANSMISSION_ENABLE) || \
- ((CMD) == ETH_RETRYTRANSMISSION_DISABLE))
-#define IS_ETH_AUTOMATIC_PADCRC_STRIP(CMD) (((CMD) == ETH_AUTOMATICPADCRCSTRIP_ENABLE) || \
- ((CMD) == ETH_AUTOMATICPADCRCSTRIP_DISABLE))
-#define IS_ETH_BACKOFF_LIMIT(LIMIT) (((LIMIT) == ETH_BACKOFFLIMIT_10) || \
- ((LIMIT) == ETH_BACKOFFLIMIT_8) || \
- ((LIMIT) == ETH_BACKOFFLIMIT_4) || \
- ((LIMIT) == ETH_BACKOFFLIMIT_1))
-#define IS_ETH_DEFERRAL_CHECK(CMD) (((CMD) == ETH_DEFFERRALCHECK_ENABLE) || \
- ((CMD) == ETH_DEFFERRALCHECK_DISABLE))
-#define IS_ETH_RECEIVE_ALL(CMD) (((CMD) == ETH_RECEIVEALL_ENABLE) || \
- ((CMD) == ETH_RECEIVEAll_DISABLE))
-#define IS_ETH_SOURCE_ADDR_FILTER(CMD) (((CMD) == ETH_SOURCEADDRFILTER_NORMAL_ENABLE) || \
- ((CMD) == ETH_SOURCEADDRFILTER_INVERSE_ENABLE) || \
- ((CMD) == ETH_SOURCEADDRFILTER_DISABLE))
-#define IS_ETH_CONTROL_FRAMES(PASS) (((PASS) == ETH_PASSCONTROLFRAMES_BLOCKALL) || \
- ((PASS) == ETH_PASSCONTROLFRAMES_FORWARDALL) || \
- ((PASS) == ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER))
-#define IS_ETH_BROADCAST_FRAMES_RECEPTION(CMD) (((CMD) == ETH_BROADCASTFRAMESRECEPTION_ENABLE) || \
- ((CMD) == ETH_BROADCASTFRAMESRECEPTION_DISABLE))
-#define IS_ETH_DESTINATION_ADDR_FILTER(FILTER) (((FILTER) == ETH_DESTINATIONADDRFILTER_NORMAL) || \
- ((FILTER) == ETH_DESTINATIONADDRFILTER_INVERSE))
-#define IS_ETH_PROMISCUOUS_MODE(CMD) (((CMD) == ETH_PROMISCUOUS_MODE_ENABLE) || \
- ((CMD) == ETH_PROMISCUOUS_MODE_DISABLE))
-#define IS_ETH_MULTICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE) || \
- ((FILTER) == ETH_MULTICASTFRAMESFILTER_HASHTABLE) || \
- ((FILTER) == ETH_MULTICASTFRAMESFILTER_PERFECT) || \
- ((FILTER) == ETH_MULTICASTFRAMESFILTER_NONE))
-#define IS_ETH_UNICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE) || \
- ((FILTER) == ETH_UNICASTFRAMESFILTER_HASHTABLE) || \
- ((FILTER) == ETH_UNICASTFRAMESFILTER_PERFECT))
-#define IS_ETH_PAUSE_TIME(TIME) ((TIME) <= 0xFFFF)
-#define IS_ETH_ZEROQUANTA_PAUSE(CMD) (((CMD) == ETH_ZEROQUANTAPAUSE_ENABLE) || \
- ((CMD) == ETH_ZEROQUANTAPAUSE_DISABLE))
-#define IS_ETH_PAUSE_LOW_THRESHOLD(THRESHOLD) (((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS4) || \
- ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS28) || \
- ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS144) || \
- ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS256))
-#define IS_ETH_UNICAST_PAUSE_FRAME_DETECT(CMD) (((CMD) == ETH_UNICASTPAUSEFRAMEDETECT_ENABLE) || \
- ((CMD) == ETH_UNICASTPAUSEFRAMEDETECT_DISABLE))
-#define IS_ETH_RECEIVE_FLOWCONTROL(CMD) (((CMD) == ETH_RECEIVEFLOWCONTROL_ENABLE) || \
- ((CMD) == ETH_RECEIVEFLOWCONTROL_DISABLE))
-#define IS_ETH_TRANSMIT_FLOWCONTROL(CMD) (((CMD) == ETH_TRANSMITFLOWCONTROL_ENABLE) || \
- ((CMD) == ETH_TRANSMITFLOWCONTROL_DISABLE))
-#define IS_ETH_VLAN_TAG_COMPARISON(COMPARISON) (((COMPARISON) == ETH_VLANTAGCOMPARISON_12BIT) || \
- ((COMPARISON) == ETH_VLANTAGCOMPARISON_16BIT))
-#define IS_ETH_VLAN_TAG_IDENTIFIER(IDENTIFIER) ((IDENTIFIER) <= 0xFFFF)
-#define IS_ETH_MAC_ADDRESS0123(ADDRESS) (((ADDRESS) == ETH_MAC_ADDRESS0) || \
- ((ADDRESS) == ETH_MAC_ADDRESS1) || \
- ((ADDRESS) == ETH_MAC_ADDRESS2) || \
- ((ADDRESS) == ETH_MAC_ADDRESS3))
-#define IS_ETH_MAC_ADDRESS123(ADDRESS) (((ADDRESS) == ETH_MAC_ADDRESS1) || \
- ((ADDRESS) == ETH_MAC_ADDRESS2) || \
- ((ADDRESS) == ETH_MAC_ADDRESS3))
-#define IS_ETH_MAC_ADDRESS_FILTER(FILTER) (((FILTER) == ETH_MAC_ADDRESSFILTER_SA) || \
- ((FILTER) == ETH_MAC_ADDRESSFILTER_DA))
-#define IS_ETH_MAC_ADDRESS_MASK(MASK) (((MASK) == ETH_MAC_ADDRESSMASK_BYTE6) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE5) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE4) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE3) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE2) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE1))
-#define IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(CMD) (((CMD) == ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE) || \
- ((CMD) == ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE))
-#define IS_ETH_RECEIVE_STORE_FORWARD(CMD) (((CMD) == ETH_RECEIVESTOREFORWARD_ENABLE) || \
- ((CMD) == ETH_RECEIVESTOREFORWARD_DISABLE))
-#define IS_ETH_FLUSH_RECEIVE_FRAME(CMD) (((CMD) == ETH_FLUSHRECEIVEDFRAME_ENABLE) || \
- ((CMD) == ETH_FLUSHRECEIVEDFRAME_DISABLE))
-#define IS_ETH_TRANSMIT_STORE_FORWARD(CMD) (((CMD) == ETH_TRANSMITSTOREFORWARD_ENABLE) || \
- ((CMD) == ETH_TRANSMITSTOREFORWARD_DISABLE))
-#define IS_ETH_TRANSMIT_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_64BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_128BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_192BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_256BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_40BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_32BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_24BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_16BYTES))
-#define IS_ETH_FORWARD_ERROR_FRAMES(CMD) (((CMD) == ETH_FORWARDERRORFRAMES_ENABLE) || \
- ((CMD) == ETH_FORWARDERRORFRAMES_DISABLE))
-#define IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(CMD) (((CMD) == ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE) || \
- ((CMD) == ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE))
-#define IS_ETH_RECEIVE_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES) || \
- ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES) || \
- ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES) || \
- ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES))
-#define IS_ETH_SECOND_FRAME_OPERATE(CMD) (((CMD) == ETH_SECONDFRAMEOPERARTE_ENABLE) || \
- ((CMD) == ETH_SECONDFRAMEOPERARTE_DISABLE))
-#define IS_ETH_ADDRESS_ALIGNED_BEATS(CMD) (((CMD) == ETH_ADDRESSALIGNEDBEATS_ENABLE) || \
- ((CMD) == ETH_ADDRESSALIGNEDBEATS_DISABLE))
-#define IS_ETH_FIXED_BURST(CMD) (((CMD) == ETH_FIXEDBURST_ENABLE) || \
- ((CMD) == ETH_FIXEDBURST_DISABLE))
-#define IS_ETH_RXDMA_BURST_LENGTH(LENGTH) (((LENGTH) == ETH_RXDMABURSTLENGTH_1BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_2BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_8BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_16BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_32BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_4BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_8BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_16BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_32BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_64BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_128BEAT))
-#define IS_ETH_TXDMA_BURST_LENGTH(LENGTH) (((LENGTH) == ETH_TXDMABURSTLENGTH_1BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_2BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_8BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_16BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_32BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_4BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_8BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_16BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_32BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_64BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_128BEAT))
-#define IS_ETH_DMA_DESC_SKIP_LENGTH(LENGTH) ((LENGTH) <= 0x1F)
-#define IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(RATIO) (((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1) || \
- ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1) || \
- ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1) || \
- ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1) || \
- ((RATIO) == ETH_DMAARBITRATION_RXPRIORTX))
-#define IS_ETH_DMATXDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMATXDESC_OWN) || \
- ((FLAG) == ETH_DMATXDESC_IC) || \
- ((FLAG) == ETH_DMATXDESC_LS) || \
- ((FLAG) == ETH_DMATXDESC_FS) || \
- ((FLAG) == ETH_DMATXDESC_DC) || \
- ((FLAG) == ETH_DMATXDESC_DP) || \
- ((FLAG) == ETH_DMATXDESC_TTSE) || \
- ((FLAG) == ETH_DMATXDESC_TER) || \
- ((FLAG) == ETH_DMATXDESC_TCH) || \
- ((FLAG) == ETH_DMATXDESC_TTSS) || \
- ((FLAG) == ETH_DMATXDESC_IHE) || \
- ((FLAG) == ETH_DMATXDESC_ES) || \
- ((FLAG) == ETH_DMATXDESC_JT) || \
- ((FLAG) == ETH_DMATXDESC_FF) || \
- ((FLAG) == ETH_DMATXDESC_PCE) || \
- ((FLAG) == ETH_DMATXDESC_LCA) || \
- ((FLAG) == ETH_DMATXDESC_NC) || \
- ((FLAG) == ETH_DMATXDESC_LCO) || \
- ((FLAG) == ETH_DMATXDESC_EC) || \
- ((FLAG) == ETH_DMATXDESC_VF) || \
- ((FLAG) == ETH_DMATXDESC_CC) || \
- ((FLAG) == ETH_DMATXDESC_ED) || \
- ((FLAG) == ETH_DMATXDESC_UF) || \
- ((FLAG) == ETH_DMATXDESC_DB))
-#define IS_ETH_DMA_TXDESC_SEGMENT(SEGMENT) (((SEGMENT) == ETH_DMATXDESC_LASTSEGMENTS) || \
- ((SEGMENT) == ETH_DMATXDESC_FIRSTSEGMENT))
-#define IS_ETH_DMA_TXDESC_CHECKSUM(CHECKSUM) (((CHECKSUM) == ETH_DMATXDESC_CHECKSUMBYPASS) || \
- ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMIPV4HEADER) || \
- ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT) || \
- ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL))
-#define IS_ETH_DMATXDESC_BUFFER_SIZE(SIZE) ((SIZE) <= 0x1FFF)
-#define IS_ETH_DMARXDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMARXDESC_OWN) || \
- ((FLAG) == ETH_DMARXDESC_AFM) || \
- ((FLAG) == ETH_DMARXDESC_ES) || \
- ((FLAG) == ETH_DMARXDESC_DE) || \
- ((FLAG) == ETH_DMARXDESC_SAF) || \
- ((FLAG) == ETH_DMARXDESC_LE) || \
- ((FLAG) == ETH_DMARXDESC_OE) || \
- ((FLAG) == ETH_DMARXDESC_VLAN) || \
- ((FLAG) == ETH_DMARXDESC_FS) || \
- ((FLAG) == ETH_DMARXDESC_LS) || \
- ((FLAG) == ETH_DMARXDESC_IPV4HCE) || \
- ((FLAG) == ETH_DMARXDESC_LC) || \
- ((FLAG) == ETH_DMARXDESC_FT) || \
- ((FLAG) == ETH_DMARXDESC_RWT) || \
- ((FLAG) == ETH_DMARXDESC_RE) || \
- ((FLAG) == ETH_DMARXDESC_DBE) || \
- ((FLAG) == ETH_DMARXDESC_CE) || \
- ((FLAG) == ETH_DMARXDESC_MAMPCE))
-#define IS_ETH_DMA_RXDESC_BUFFER(BUFFER) (((BUFFER) == ETH_DMARXDESC_BUFFER1) || \
- ((BUFFER) == ETH_DMARXDESC_BUFFER2))
-#define IS_ETH_PMT_GET_FLAG(FLAG) (((FLAG) == ETH_PMT_FLAG_WUFR) || \
- ((FLAG) == ETH_PMT_FLAG_MPR))
-#define IS_ETH_DMA_FLAG(FLAG) ((((FLAG) & (uint32_t)0xC7FE1800) == 0x00) && ((FLAG) != 0x00))
-#define IS_ETH_DMA_GET_FLAG(FLAG) (((FLAG) == ETH_DMA_FLAG_TST) || ((FLAG) == ETH_DMA_FLAG_PMT) || \
- ((FLAG) == ETH_DMA_FLAG_MMC) || ((FLAG) == ETH_DMA_FLAG_DATATRANSFERERROR) || \
- ((FLAG) == ETH_DMA_FLAG_READWRITEERROR) || ((FLAG) == ETH_DMA_FLAG_ACCESSERROR) || \
- ((FLAG) == ETH_DMA_FLAG_NIS) || ((FLAG) == ETH_DMA_FLAG_AIS) || \
- ((FLAG) == ETH_DMA_FLAG_ER) || ((FLAG) == ETH_DMA_FLAG_FBE) || \
- ((FLAG) == ETH_DMA_FLAG_ET) || ((FLAG) == ETH_DMA_FLAG_RWT) || \
- ((FLAG) == ETH_DMA_FLAG_RPS) || ((FLAG) == ETH_DMA_FLAG_RBU) || \
- ((FLAG) == ETH_DMA_FLAG_R) || ((FLAG) == ETH_DMA_FLAG_TU) || \
- ((FLAG) == ETH_DMA_FLAG_RO) || ((FLAG) == ETH_DMA_FLAG_TJT) || \
- ((FLAG) == ETH_DMA_FLAG_TBU) || ((FLAG) == ETH_DMA_FLAG_TPS) || \
- ((FLAG) == ETH_DMA_FLAG_T))
-#define IS_ETH_MAC_IT(IT) ((((IT) & (uint32_t)0xFFFFFDF1) == 0x00) && ((IT) != 0x00))
-#define IS_ETH_MAC_GET_IT(IT) (((IT) == ETH_MAC_IT_TST) || ((IT) == ETH_MAC_IT_MMCT) || \
- ((IT) == ETH_MAC_IT_MMCR) || ((IT) == ETH_MAC_IT_MMC) || \
- ((IT) == ETH_MAC_IT_PMT))
-#define IS_ETH_MAC_GET_FLAG(FLAG) (((FLAG) == ETH_MAC_FLAG_TST) || ((FLAG) == ETH_MAC_FLAG_MMCT) || \
- ((FLAG) == ETH_MAC_FLAG_MMCR) || ((FLAG) == ETH_MAC_FLAG_MMC) || \
- ((FLAG) == ETH_MAC_FLAG_PMT))
-#define IS_ETH_DMA_IT(IT) ((((IT) & (uint32_t)0xC7FE1800) == 0x00) && ((IT) != 0x00))
-#define IS_ETH_DMA_GET_IT(IT) (((IT) == ETH_DMA_IT_TST) || ((IT) == ETH_DMA_IT_PMT) || \
- ((IT) == ETH_DMA_IT_MMC) || ((IT) == ETH_DMA_IT_NIS) || \
- ((IT) == ETH_DMA_IT_AIS) || ((IT) == ETH_DMA_IT_ER) || \
- ((IT) == ETH_DMA_IT_FBE) || ((IT) == ETH_DMA_IT_ET) || \
- ((IT) == ETH_DMA_IT_RWT) || ((IT) == ETH_DMA_IT_RPS) || \
- ((IT) == ETH_DMA_IT_RBU) || ((IT) == ETH_DMA_IT_R) || \
- ((IT) == ETH_DMA_IT_TU) || ((IT) == ETH_DMA_IT_RO) || \
- ((IT) == ETH_DMA_IT_TJT) || ((IT) == ETH_DMA_IT_TBU) || \
- ((IT) == ETH_DMA_IT_TPS) || ((IT) == ETH_DMA_IT_T))
-#define IS_ETH_DMA_GET_OVERFLOW(OVERFLOW) (((OVERFLOW) == ETH_DMA_OVERFLOW_RXFIFOCOUNTER) || \
- ((OVERFLOW) == ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER))
-#define IS_ETH_MMC_IT(IT) (((((IT) & (uint32_t)0xFFDF3FFF) == 0x00) || (((IT) & (uint32_t)0xEFFDFF9F) == 0x00)) && \
- ((IT) != 0x00))
-#define IS_ETH_MMC_GET_IT(IT) (((IT) == ETH_MMC_IT_TGF) || ((IT) == ETH_MMC_IT_TGFMSC) || \
- ((IT) == ETH_MMC_IT_TGFSC) || ((IT) == ETH_MMC_IT_RGUF) || \
- ((IT) == ETH_MMC_IT_RFAE) || ((IT) == ETH_MMC_IT_RFCE))
-#define IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(CMD) (((CMD) == ETH_DMAENHANCEDDESCRIPTOR_ENABLE) || \
- ((CMD) == ETH_DMAENHANCEDDESCRIPTOR_DISABLE))
-
-
-/**
- * @}
- */
-
-/** @addtogroup ETH_Private_Defines
- * @{
- */
-/* Delay to wait when writing to some Ethernet registers */
-#define ETH_REG_WRITE_DELAY ((uint32_t)0x00000001U)
-
-/* Ethernet Errors */
-#define ETH_SUCCESS ((uint32_t)0U)
-#define ETH_ERROR ((uint32_t)1U)
-
-/* Ethernet DMA Tx descriptors Collision Count Shift */
-#define ETH_DMATXDESC_COLLISION_COUNTSHIFT ((uint32_t)3U)
-
-/* Ethernet DMA Tx descriptors Buffer2 Size Shift */
-#define ETH_DMATXDESC_BUFFER2_SIZESHIFT ((uint32_t)16U)
-
-/* Ethernet DMA Rx descriptors Frame Length Shift */
-#define ETH_DMARXDESC_FRAME_LENGTHSHIFT ((uint32_t)16U)
-
-/* Ethernet DMA Rx descriptors Buffer2 Size Shift */
-#define ETH_DMARXDESC_BUFFER2_SIZESHIFT ((uint32_t)16U)
-
-/* Ethernet DMA Rx descriptors Frame length Shift */
-#define ETH_DMARXDESC_FRAMELENGTHSHIFT ((uint32_t)16)
-
-/* Ethernet MAC address offsets */
-#define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + (uint32_t)0x40U) /* Ethernet MAC address high offset */
-#define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + (uint32_t)0x44U) /* Ethernet MAC address low offset */
-
-/* Ethernet MACMIIAR register Mask */
-#define ETH_MACMIIAR_CR_MASK ((uint32_t)0xFFFFFFE3U)
-
-/* Ethernet MACCR register Mask */
-#define ETH_MACCR_CLEAR_MASK ((uint32_t)0xFF20810FU)
-
-/* Ethernet MACFCR register Mask */
-#define ETH_MACFCR_CLEAR_MASK ((uint32_t)0x0000FF41U)
-
-/* Ethernet DMAOMR register Mask */
-#define ETH_DMAOMR_CLEAR_MASK ((uint32_t)0xF8DE3F23U)
-
-/* Ethernet Remote Wake-up frame register length */
-#define ETH_WAKEUP_REGISTER_LENGTH 8U
-
-/* Ethernet Missed frames counter Shift */
-#define ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT 17U
- /**
- * @}
- */
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup ETH_Exported_Types ETH Exported Types
- * @{
- */
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_ETH_STATE_RESET = 0x00U, /*!< Peripheral not yet Initialized or disabled */
- HAL_ETH_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
- HAL_ETH_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
- HAL_ETH_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */
- HAL_ETH_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
- HAL_ETH_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission and Reception process is ongoing */
- HAL_ETH_STATE_BUSY_WR = 0x42U, /*!< Write process is ongoing */
- HAL_ETH_STATE_BUSY_RD = 0x82U, /*!< Read process is ongoing */
- HAL_ETH_STATE_TIMEOUT = 0x03U, /*!< Timeout state */
- HAL_ETH_STATE_ERROR = 0x04U /*!< Reception process is ongoing */
-}HAL_ETH_StateTypeDef;
-
-/**
- * @brief ETH Init Structure definition
- */
-
-typedef struct
-{
- uint32_t AutoNegotiation; /*!< Selects or not the AutoNegotiation mode for the external PHY
- The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps)
- and the mode (half/full-duplex).
- This parameter can be a value of @ref ETH_AutoNegotiation */
-
- uint32_t Speed; /*!< Sets the Ethernet speed: 10/100 Mbps.
- This parameter can be a value of @ref ETH_Speed */
-
- uint32_t DuplexMode; /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode
- This parameter can be a value of @ref ETH_Duplex_Mode */
-
- uint16_t PhyAddress; /*!< Ethernet PHY address.
- This parameter must be a number between Min_Data = 0 and Max_Data = 32 */
-
- uint8_t *MACAddr; /*!< MAC Address of used Hardware: must be pointer on an array of 6 bytes */
-
- uint32_t RxMode; /*!< Selects the Ethernet Rx mode: Polling mode, Interrupt mode.
- This parameter can be a value of @ref ETH_Rx_Mode */
-
- uint32_t ChecksumMode; /*!< Selects if the checksum is check by hardware or by software.
- This parameter can be a value of @ref ETH_Checksum_Mode */
-
- uint32_t MediaInterface ; /*!< Selects the media-independent interface or the reduced media-independent interface.
- This parameter can be a value of @ref ETH_Media_Interface */
-
-} ETH_InitTypeDef;
-
-
- /**
- * @brief ETH MAC Configuration Structure definition
- */
-
-typedef struct
-{
- uint32_t Watchdog; /*!< Selects or not the Watchdog timer
- When enabled, the MAC allows no more then 2048 bytes to be received.
- When disabled, the MAC can receive up to 16384 bytes.
- This parameter can be a value of @ref ETH_Watchdog */
-
- uint32_t Jabber; /*!< Selects or not Jabber timer
- When enabled, the MAC allows no more then 2048 bytes to be sent.
- When disabled, the MAC can send up to 16384 bytes.
- This parameter can be a value of @ref ETH_Jabber */
-
- uint32_t InterFrameGap; /*!< Selects the minimum IFG between frames during transmission.
- This parameter can be a value of @ref ETH_Inter_Frame_Gap */
-
- uint32_t CarrierSense; /*!< Selects or not the Carrier Sense.
- This parameter can be a value of @ref ETH_Carrier_Sense */
-
- uint32_t ReceiveOwn; /*!< Selects or not the ReceiveOwn,
- ReceiveOwn allows the reception of frames when the TX_EN signal is asserted
- in Half-Duplex mode.
- This parameter can be a value of @ref ETH_Receive_Own */
-
- uint32_t LoopbackMode; /*!< Selects or not the internal MAC MII Loopback mode.
- This parameter can be a value of @ref ETH_Loop_Back_Mode */
-
- uint32_t ChecksumOffload; /*!< Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers.
- This parameter can be a value of @ref ETH_Checksum_Offload */
-
- uint32_t RetryTransmission; /*!< Selects or not the MAC attempt retries transmission, based on the settings of BL,
- when a collision occurs (Half-Duplex mode).
- This parameter can be a value of @ref ETH_Retry_Transmission */
-
- uint32_t AutomaticPadCRCStrip; /*!< Selects or not the Automatic MAC Pad/CRC Stripping.
- This parameter can be a value of @ref ETH_Automatic_Pad_CRC_Strip */
-
- uint32_t BackOffLimit; /*!< Selects the BackOff limit value.
- This parameter can be a value of @ref ETH_Back_Off_Limit */
-
- uint32_t DeferralCheck; /*!< Selects or not the deferral check function (Half-Duplex mode).
- This parameter can be a value of @ref ETH_Deferral_Check */
-
- uint32_t ReceiveAll; /*!< Selects or not all frames reception by the MAC (No filtering).
- This parameter can be a value of @ref ETH_Receive_All */
-
- uint32_t SourceAddrFilter; /*!< Selects the Source Address Filter mode.
- This parameter can be a value of @ref ETH_Source_Addr_Filter */
-
- uint32_t PassControlFrames; /*!< Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames)
- This parameter can be a value of @ref ETH_Pass_Control_Frames */
-
- uint32_t BroadcastFramesReception; /*!< Selects or not the reception of Broadcast Frames.
- This parameter can be a value of @ref ETH_Broadcast_Frames_Reception */
-
- uint32_t DestinationAddrFilter; /*!< Sets the destination filter mode for both unicast and multicast frames.
- This parameter can be a value of @ref ETH_Destination_Addr_Filter */
-
- uint32_t PromiscuousMode; /*!< Selects or not the Promiscuous Mode
- This parameter can be a value of @ref ETH_Promiscuous_Mode */
-
- uint32_t MulticastFramesFilter; /*!< Selects the Multicast Frames filter mode: None/HashTableFilter/PerfectFilter/PerfectHashTableFilter.
- This parameter can be a value of @ref ETH_Multicast_Frames_Filter */
-
- uint32_t UnicastFramesFilter; /*!< Selects the Unicast Frames filter mode: HashTableFilter/PerfectFilter/PerfectHashTableFilter.
- This parameter can be a value of @ref ETH_Unicast_Frames_Filter */
-
- uint32_t HashTableHigh; /*!< This field holds the higher 32 bits of Hash table.
- This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFF */
-
- uint32_t HashTableLow; /*!< This field holds the lower 32 bits of Hash table.
- This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFF */
-
- uint32_t PauseTime; /*!< This field holds the value to be used in the Pause Time field in the transmit control frame.
- This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFF */
-
- uint32_t ZeroQuantaPause; /*!< Selects or not the automatic generation of Zero-Quanta Pause Control frames.
- This parameter can be a value of @ref ETH_Zero_Quanta_Pause */
-
- uint32_t PauseLowThreshold; /*!< This field configures the threshold of the PAUSE to be checked for
- automatic retransmission of PAUSE Frame.
- This parameter can be a value of @ref ETH_Pause_Low_Threshold */
-
- uint32_t UnicastPauseFrameDetect; /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0
- unicast address and unique multicast address).
- This parameter can be a value of @ref ETH_Unicast_Pause_Frame_Detect */
-
- uint32_t ReceiveFlowControl; /*!< Enables or disables the MAC to decode the received Pause frame and
- disable its transmitter for a specified time (Pause Time)
- This parameter can be a value of @ref ETH_Receive_Flow_Control */
-
- uint32_t TransmitFlowControl; /*!< Enables or disables the MAC to transmit Pause frames (Full-Duplex mode)
- or the MAC back-pressure operation (Half-Duplex mode)
- This parameter can be a value of @ref ETH_Transmit_Flow_Control */
-
- uint32_t VLANTagComparison; /*!< Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for
- comparison and filtering.
- This parameter can be a value of @ref ETH_VLAN_Tag_Comparison */
-
- uint32_t VLANTagIdentifier; /*!< Holds the VLAN tag identifier for receive frames */
-
-} ETH_MACInitTypeDef;
-
-
-/**
- * @brief ETH DMA Configuration Structure definition
- */
-
-typedef struct
-{
- uint32_t DropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames.
- This parameter can be a value of @ref ETH_Drop_TCP_IP_Checksum_Error_Frame */
-
- uint32_t ReceiveStoreForward; /*!< Enables or disables the Receive store and forward mode.
- This parameter can be a value of @ref ETH_Receive_Store_Forward */
-
- uint32_t FlushReceivedFrame; /*!< Enables or disables the flushing of received frames.
- This parameter can be a value of @ref ETH_Flush_Received_Frame */
-
- uint32_t TransmitStoreForward; /*!< Enables or disables Transmit store and forward mode.
- This parameter can be a value of @ref ETH_Transmit_Store_Forward */
-
- uint32_t TransmitThresholdControl; /*!< Selects or not the Transmit Threshold Control.
- This parameter can be a value of @ref ETH_Transmit_Threshold_Control */
-
- uint32_t ForwardErrorFrames; /*!< Selects or not the forward to the DMA of erroneous frames.
- This parameter can be a value of @ref ETH_Forward_Error_Frames */
-
- uint32_t ForwardUndersizedGoodFrames; /*!< Enables or disables the Rx FIFO to forward Undersized frames (frames with no Error
- and length less than 64 bytes) including pad-bytes and CRC)
- This parameter can be a value of @ref ETH_Forward_Undersized_Good_Frames */
-
- uint32_t ReceiveThresholdControl; /*!< Selects the threshold level of the Receive FIFO.
- This parameter can be a value of @ref ETH_Receive_Threshold_Control */
-
- uint32_t SecondFrameOperate; /*!< Selects or not the Operate on second frame mode, which allows the DMA to process a second
- frame of Transmit data even before obtaining the status for the first frame.
- This parameter can be a value of @ref ETH_Second_Frame_Operate */
-
- uint32_t AddressAlignedBeats; /*!< Enables or disables the Address Aligned Beats.
- This parameter can be a value of @ref ETH_Address_Aligned_Beats */
-
- uint32_t FixedBurst; /*!< Enables or disables the AHB Master interface fixed burst transfers.
- This parameter can be a value of @ref ETH_Fixed_Burst */
-
- uint32_t RxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction.
- This parameter can be a value of @ref ETH_Rx_DMA_Burst_Length */
-
- uint32_t TxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Tx DMA transaction.
- This parameter can be a value of @ref ETH_Tx_DMA_Burst_Length */
-
- uint32_t EnhancedDescriptorFormat; /*!< Enables the enhanced descriptor format.
- This parameter can be a value of @ref ETH_DMA_Enhanced_descriptor_format */
-
- uint32_t DescriptorSkipLength; /*!< Specifies the number of word to skip between two unchained descriptors (Ring mode)
- This parameter must be a number between Min_Data = 0 and Max_Data = 32 */
-
- uint32_t DMAArbitration; /*!< Selects the DMA Tx/Rx arbitration.
- This parameter can be a value of @ref ETH_DMA_Arbitration */
-} ETH_DMAInitTypeDef;
-
-
-/**
- * @brief ETH DMA Descriptors data structure definition
- */
-
-typedef struct
-{
- __IO uint32_t Status; /*!< Status */
-
- uint32_t ControlBufferSize; /*!< Control and Buffer1, Buffer2 lengths */
-
- uint32_t Buffer1Addr; /*!< Buffer1 address pointer */
-
- uint32_t Buffer2NextDescAddr; /*!< Buffer2 or next descriptor address pointer */
-
- /*!< Enhanced Ethernet DMA PTP Descriptors */
- uint32_t ExtendedStatus; /*!< Extended status for PTP receive descriptor */
-
- uint32_t Reserved1; /*!< Reserved */
-
- uint32_t TimeStampLow; /*!< Time Stamp Low value for transmit and receive */
-
- uint32_t TimeStampHigh; /*!< Time Stamp High value for transmit and receive */
-
-} ETH_DMADescTypeDef;
-
-
-/**
- * @brief Received Frame Informations structure definition
- */
-typedef struct
-{
- ETH_DMADescTypeDef *FSRxDesc; /*!< First Segment Rx Desc */
-
- ETH_DMADescTypeDef *LSRxDesc; /*!< Last Segment Rx Desc */
-
- uint32_t SegCount; /*!< Segment count */
-
- uint32_t length; /*!< Frame length */
-
- uint32_t buffer; /*!< Frame buffer */
-
-} ETH_DMARxFrameInfos;
-
-
-/**
- * @brief ETH Handle Structure definition
- */
-
-typedef struct
-{
- ETH_TypeDef *Instance; /*!< Register base address */
-
- ETH_InitTypeDef Init; /*!< Ethernet Init Configuration */
-
- uint32_t LinkStatus; /*!< Ethernet link status */
-
- ETH_DMADescTypeDef *RxDesc; /*!< Rx descriptor to Get */
-
- ETH_DMADescTypeDef *TxDesc; /*!< Tx descriptor to Set */
-
- ETH_DMARxFrameInfos RxFrameInfos; /*!< last Rx frame infos */
-
- __IO HAL_ETH_StateTypeDef State; /*!< ETH communication state */
-
- HAL_LockTypeDef Lock; /*!< ETH Lock */
-
-} ETH_HandleTypeDef;
-
- /**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup ETH_Exported_Constants ETH Exported Constants
- * @{
- */
-
-/** @defgroup ETH_Buffers_setting ETH Buffers setting
- * @{
- */
-#define ETH_MAX_PACKET_SIZE ((uint32_t)1524U) /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */
-#define ETH_HEADER ((uint32_t)14U) /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */
-#define ETH_CRC ((uint32_t)4U) /*!< Ethernet CRC */
-#define ETH_EXTRA ((uint32_t)2U) /*!< Extra bytes in some cases */
-#define ETH_VLAN_TAG ((uint32_t)4U) /*!< optional 802.1q VLAN Tag */
-#define ETH_MIN_ETH_PAYLOAD ((uint32_t)46U) /*!< Minimum Ethernet payload size */
-#define ETH_MAX_ETH_PAYLOAD ((uint32_t)1500U) /*!< Maximum Ethernet payload size */
-#define ETH_JUMBO_FRAME_PAYLOAD ((uint32_t)9000U) /*!< Jumbo frame payload size */
-
- /* Ethernet driver receive buffers are organized in a chained linked-list, when
- an Ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO
- to the driver receive buffers memory.
-
- Depending on the size of the received Ethernet packet and the size of
- each Ethernet driver receive buffer, the received packet can take one or more
- Ethernet driver receive buffer.
-
- In below are defined the size of one Ethernet driver receive buffer ETH_RX_BUF_SIZE
- and the total count of the driver receive buffers ETH_RXBUFNB.
-
- The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as
- example, they can be reconfigured in the application layer to fit the application
- needs */
-
-/* Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet
- packet */
-#ifndef ETH_RX_BUF_SIZE
- #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE
-#endif
-
-/* 5 Ethernet driver receive buffers are used (in a chained linked list)*/
-#ifndef ETH_RXBUFNB
- #define ETH_RXBUFNB ((uint32_t)5U) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */
-#endif
-
-
- /* Ethernet driver transmit buffers are organized in a chained linked-list, when
- an Ethernet packet is transmitted, Tx-DMA will transfer the packet from the
- driver transmit buffers memory to the TxFIFO.
-
- Depending on the size of the Ethernet packet to be transmitted and the size of
- each Ethernet driver transmit buffer, the packet to be transmitted can take
- one or more Ethernet driver transmit buffer.
-
- In below are defined the size of one Ethernet driver transmit buffer ETH_TX_BUF_SIZE
- and the total count of the driver transmit buffers ETH_TXBUFNB.
-
- The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as
- example, they can be reconfigured in the application layer to fit the application
- needs */
-
-/* Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet
- packet */
-#ifndef ETH_TX_BUF_SIZE
- #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE
-#endif
-
-/* 5 Ethernet driver transmit buffers are used (in a chained linked list)*/
-#ifndef ETH_TXBUFNB
- #define ETH_TXBUFNB ((uint32_t)5U) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */
-#endif
-
- /**
- * @}
- */
-
-/** @defgroup ETH_DMA_TX_Descriptor ETH DMA TX Descriptor
- * @{
- */
-
-/*
- DMA Tx Descriptor
- -----------------------------------------------------------------------------------------------
- TDES0 | OWN(31) | CTRL[30:26] | Reserved[25:24] | CTRL[23:20] | Reserved[19:17] | Status[16:0] |
- -----------------------------------------------------------------------------------------------
- TDES1 | Reserved[31:29] | Buffer2 ByteCount[28:16] | Reserved[15:13] | Buffer1 ByteCount[12:0] |
- -----------------------------------------------------------------------------------------------
- TDES2 | Buffer1 Address [31:0] |
- -----------------------------------------------------------------------------------------------
- TDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] |
- -----------------------------------------------------------------------------------------------
-*/
-
-/**
- * @brief Bit definition of TDES0 register: DMA Tx descriptor status register
- */
-#define ETH_DMATXDESC_OWN ((uint32_t)0x80000000U) /*!< OWN bit: descriptor is owned by DMA engine */
-#define ETH_DMATXDESC_IC ((uint32_t)0x40000000U) /*!< Interrupt on Completion */
-#define ETH_DMATXDESC_LS ((uint32_t)0x20000000U) /*!< Last Segment */
-#define ETH_DMATXDESC_FS ((uint32_t)0x10000000U) /*!< First Segment */
-#define ETH_DMATXDESC_DC ((uint32_t)0x08000000U) /*!< Disable CRC */
-#define ETH_DMATXDESC_DP ((uint32_t)0x04000000U) /*!< Disable Padding */
-#define ETH_DMATXDESC_TTSE ((uint32_t)0x02000000U) /*!< Transmit Time Stamp Enable */
-#define ETH_DMATXDESC_CIC ((uint32_t)0x00C00000U) /*!< Checksum Insertion Control: 4 cases */
-#define ETH_DMATXDESC_CIC_BYPASS ((uint32_t)0x00000000U) /*!< Do Nothing: Checksum Engine is bypassed */
-#define ETH_DMATXDESC_CIC_IPV4HEADER ((uint32_t)0x00400000U) /*!< IPV4 header Checksum Insertion */
-#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT ((uint32_t)0x00800000U) /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */
-#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL ((uint32_t)0x00C00000U) /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */
-#define ETH_DMATXDESC_TER ((uint32_t)0x00200000U) /*!< Transmit End of Ring */
-#define ETH_DMATXDESC_TCH ((uint32_t)0x00100000U) /*!< Second Address Chained */
-#define ETH_DMATXDESC_TTSS ((uint32_t)0x00020000U) /*!< Tx Time Stamp Status */
-#define ETH_DMATXDESC_IHE ((uint32_t)0x00010000U) /*!< IP Header Error */
-#define ETH_DMATXDESC_ES ((uint32_t)0x00008000U) /*!< Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */
-#define ETH_DMATXDESC_JT ((uint32_t)0x00004000U) /*!< Jabber Timeout */
-#define ETH_DMATXDESC_FF ((uint32_t)0x00002000U) /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
-#define ETH_DMATXDESC_PCE ((uint32_t)0x00001000U) /*!< Payload Checksum Error */
-#define ETH_DMATXDESC_LCA ((uint32_t)0x00000800U) /*!< Loss of Carrier: carrier lost during transmission */
-#define ETH_DMATXDESC_NC ((uint32_t)0x00000400U) /*!< No Carrier: no carrier signal from the transceiver */
-#define ETH_DMATXDESC_LCO ((uint32_t)0x00000200U) /*!< Late Collision: transmission aborted due to collision */
-#define ETH_DMATXDESC_EC ((uint32_t)0x00000100U) /*!< Excessive Collision: transmission aborted after 16 collisions */
-#define ETH_DMATXDESC_VF ((uint32_t)0x00000080U) /*!< VLAN Frame */
-#define ETH_DMATXDESC_CC ((uint32_t)0x00000078U) /*!< Collision Count */
-#define ETH_DMATXDESC_ED ((uint32_t)0x00000004U) /*!< Excessive Deferral */
-#define ETH_DMATXDESC_UF ((uint32_t)0x00000002U) /*!< Underflow Error: late data arrival from the memory */
-#define ETH_DMATXDESC_DB ((uint32_t)0x00000001U) /*!< Deferred Bit */
-
-/**
- * @brief Bit definition of TDES1 register
- */
-#define ETH_DMATXDESC_TBS2 ((uint32_t)0x1FFF0000U) /*!< Transmit Buffer2 Size */
-#define ETH_DMATXDESC_TBS1 ((uint32_t)0x00001FFFU) /*!< Transmit Buffer1 Size */
-
-/**
- * @brief Bit definition of TDES2 register
- */
-#define ETH_DMATXDESC_B1AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer1 Address Pointer */
-
-/**
- * @brief Bit definition of TDES3 register
- */
-#define ETH_DMATXDESC_B2AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer2 Address Pointer */
-
- /*---------------------------------------------------------------------------------------------
- TDES6 | Transmit Time Stamp Low [31:0] |
- -----------------------------------------------------------------------------------------------
- TDES7 | Transmit Time Stamp High [31:0] |
- ----------------------------------------------------------------------------------------------*/
-
-/* Bit definition of TDES6 register */
- #define ETH_DMAPTPTXDESC_TTSL ((uint32_t)0xFFFFFFFFU) /* Transmit Time Stamp Low */
-
-/* Bit definition of TDES7 register */
- #define ETH_DMAPTPTXDESC_TTSH ((uint32_t)0xFFFFFFFFU) /* Transmit Time Stamp High */
-
-/**
- * @}
- */
-/** @defgroup ETH_DMA_RX_Descriptor ETH DMA RX Descriptor
- * @{
- */
-
-/*
- DMA Rx Descriptor
- --------------------------------------------------------------------------------------------------------------------
- RDES0 | OWN(31) | Status [30:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES1 | CTRL(31) | Reserved[30:29] | Buffer2 ByteCount[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 ByteCount[12:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES2 | Buffer1 Address [31:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] |
- ---------------------------------------------------------------------------------------------------------------------
-*/
-
-/**
- * @brief Bit definition of RDES0 register: DMA Rx descriptor status register
- */
-#define ETH_DMARXDESC_OWN ((uint32_t)0x80000000U) /*!< OWN bit: descriptor is owned by DMA engine */
-#define ETH_DMARXDESC_AFM ((uint32_t)0x40000000U) /*!< DA Filter Fail for the rx frame */
-#define ETH_DMARXDESC_FL ((uint32_t)0x3FFF0000U) /*!< Receive descriptor frame length */
-#define ETH_DMARXDESC_ES ((uint32_t)0x00008000U) /*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */
-#define ETH_DMARXDESC_DE ((uint32_t)0x00004000U) /*!< Descriptor error: no more descriptors for receive frame */
-#define ETH_DMARXDESC_SAF ((uint32_t)0x00002000U) /*!< SA Filter Fail for the received frame */
-#define ETH_DMARXDESC_LE ((uint32_t)0x00001000U) /*!< Frame size not matching with length field */
-#define ETH_DMARXDESC_OE ((uint32_t)0x00000800U) /*!< Overflow Error: Frame was damaged due to buffer overflow */
-#define ETH_DMARXDESC_VLAN ((uint32_t)0x00000400U) /*!< VLAN Tag: received frame is a VLAN frame */
-#define ETH_DMARXDESC_FS ((uint32_t)0x00000200U) /*!< First descriptor of the frame */
-#define ETH_DMARXDESC_LS ((uint32_t)0x00000100U) /*!< Last descriptor of the frame */
-#define ETH_DMARXDESC_IPV4HCE ((uint32_t)0x00000080U) /*!< IPC Checksum Error: Rx Ipv4 header checksum error */
-#define ETH_DMARXDESC_LC ((uint32_t)0x00000040U) /*!< Late collision occurred during reception */
-#define ETH_DMARXDESC_FT ((uint32_t)0x00000020U) /*!< Frame type - Ethernet, otherwise 802.3 */
-#define ETH_DMARXDESC_RWT ((uint32_t)0x00000010U) /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
-#define ETH_DMARXDESC_RE ((uint32_t)0x00000008U) /*!< Receive error: error reported by MII interface */
-#define ETH_DMARXDESC_DBE ((uint32_t)0x00000004U) /*!< Dribble bit error: frame contains non int multiple of 8 bits */
-#define ETH_DMARXDESC_CE ((uint32_t)0x00000002U) /*!< CRC error */
-#define ETH_DMARXDESC_MAMPCE ((uint32_t)0x00000001U) /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
-
-/**
- * @brief Bit definition of RDES1 register
- */
-#define ETH_DMARXDESC_DIC ((uint32_t)0x80000000U) /*!< Disable Interrupt on Completion */
-#define ETH_DMARXDESC_RBS2 ((uint32_t)0x1FFF0000U) /*!< Receive Buffer2 Size */
-#define ETH_DMARXDESC_RER ((uint32_t)0x00008000U) /*!< Receive End of Ring */
-#define ETH_DMARXDESC_RCH ((uint32_t)0x00004000U) /*!< Second Address Chained */
-#define ETH_DMARXDESC_RBS1 ((uint32_t)0x00001FFFU) /*!< Receive Buffer1 Size */
-
-/**
- * @brief Bit definition of RDES2 register
- */
-#define ETH_DMARXDESC_B1AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer1 Address Pointer */
-
-/**
- * @brief Bit definition of RDES3 register
- */
-#define ETH_DMARXDESC_B2AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer2 Address Pointer */
-
-/*---------------------------------------------------------------------------------------------------------------------
- RDES4 | Reserved[31:15] | Extended Status [14:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES5 | Reserved[31:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES6 | Receive Time Stamp Low [31:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES7 | Receive Time Stamp High [31:0] |
- --------------------------------------------------------------------------------------------------------------------*/
-
-/* Bit definition of RDES4 register */
-#define ETH_DMAPTPRXDESC_PTPV ((uint32_t)0x00002000U) /* PTP Version */
-#define ETH_DMAPTPRXDESC_PTPFT ((uint32_t)0x00001000U) /* PTP Frame Type */
-#define ETH_DMAPTPRXDESC_PTPMT ((uint32_t)0x00000F00U) /* PTP Message Type */
-#define ETH_DMAPTPRXDESC_PTPMT_SYNC ((uint32_t)0x00000100U) /* SYNC message (all clock types) */
-#define ETH_DMAPTPRXDESC_PTPMT_FOLLOWUP ((uint32_t)0x00000200U) /* FollowUp message (all clock types) */
-#define ETH_DMAPTPRXDESC_PTPMT_DELAYREQ ((uint32_t)0x00000300U) /* DelayReq message (all clock types) */
-#define ETH_DMAPTPRXDESC_PTPMT_DELAYRESP ((uint32_t)0x00000400U) /* DelayResp message (all clock types) */
-#define ETH_DMAPTPRXDESC_PTPMT_PDELAYREQ_ANNOUNCE ((uint32_t)0x00000500U) /* PdelayReq message (peer-to-peer transparent clock) or Announce message (Ordinary or Boundary clock) */
-#define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESP_MANAG ((uint32_t)0x00000600U) /* PdelayResp message (peer-to-peer transparent clock) or Management message (Ordinary or Boundary clock) */
-#define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESPFOLLOWUP_SIGNAL ((uint32_t)0x00000700U) /* PdelayRespFollowUp message (peer-to-peer transparent clock) or Signaling message (Ordinary or Boundary clock) */
-#define ETH_DMAPTPRXDESC_IPV6PR ((uint32_t)0x00000080U) /* IPv6 Packet Received */
-#define ETH_DMAPTPRXDESC_IPV4PR ((uint32_t)0x00000040U) /* IPv4 Packet Received */
-#define ETH_DMAPTPRXDESC_IPCB ((uint32_t)0x00000020U) /* IP Checksum Bypassed */
-#define ETH_DMAPTPRXDESC_IPPE ((uint32_t)0x00000010U) /* IP Payload Error */
-#define ETH_DMAPTPRXDESC_IPHE ((uint32_t)0x00000008U) /* IP Header Error */
-#define ETH_DMAPTPRXDESC_IPPT ((uint32_t)0x00000007U) /* IP Payload Type */
-#define ETH_DMAPTPRXDESC_IPPT_UDP ((uint32_t)0x00000001U) /* UDP payload encapsulated in the IP datagram */
-#define ETH_DMAPTPRXDESC_IPPT_TCP ((uint32_t)0x00000002U) /* TCP payload encapsulated in the IP datagram */
-#define ETH_DMAPTPRXDESC_IPPT_ICMP ((uint32_t)0x00000003U) /* ICMP payload encapsulated in the IP datagram */
-
-/* Bit definition of RDES6 register */
-#define ETH_DMAPTPRXDESC_RTSL ((uint32_t)0xFFFFFFFFU) /* Receive Time Stamp Low */
-
-/* Bit definition of RDES7 register */
-#define ETH_DMAPTPRXDESC_RTSH ((uint32_t)0xFFFFFFFFU) /* Receive Time Stamp High */
-/**
- * @}
- */
- /** @defgroup ETH_AutoNegotiation ETH AutoNegotiation
- * @{
- */
-#define ETH_AUTONEGOTIATION_ENABLE ((uint32_t)0x00000001U)
-#define ETH_AUTONEGOTIATION_DISABLE ((uint32_t)0x00000000U)
-
-/**
- * @}
- */
-/** @defgroup ETH_Speed ETH Speed
- * @{
- */
-#define ETH_SPEED_10M ((uint32_t)0x00000000U)
-#define ETH_SPEED_100M ((uint32_t)0x00004000U)
-
-/**
- * @}
- */
-/** @defgroup ETH_Duplex_Mode ETH Duplex Mode
- * @{
- */
-#define ETH_MODE_FULLDUPLEX ((uint32_t)0x00000800U)
-#define ETH_MODE_HALFDUPLEX ((uint32_t)0x00000000U)
-/**
- * @}
- */
-/** @defgroup ETH_Rx_Mode ETH Rx Mode
- * @{
- */
-#define ETH_RXPOLLING_MODE ((uint32_t)0x00000000U)
-#define ETH_RXINTERRUPT_MODE ((uint32_t)0x00000001U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Checksum_Mode ETH Checksum Mode
- * @{
- */
-#define ETH_CHECKSUM_BY_HARDWARE ((uint32_t)0x00000000U)
-#define ETH_CHECKSUM_BY_SOFTWARE ((uint32_t)0x00000001U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Media_Interface ETH Media Interface
- * @{
- */
-#define ETH_MEDIA_INTERFACE_MII ((uint32_t)0x00000000U)
-#define ETH_MEDIA_INTERFACE_RMII ((uint32_t)SYSCFG_PMC_MII_RMII_SEL)
-/**
- * @}
- */
-
-/** @defgroup ETH_Watchdog ETH Watchdog
- * @{
- */
-#define ETH_WATCHDOG_ENABLE ((uint32_t)0x00000000U)
-#define ETH_WATCHDOG_DISABLE ((uint32_t)0x00800000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Jabber ETH Jabber
- * @{
- */
-#define ETH_JABBER_ENABLE ((uint32_t)0x00000000U)
-#define ETH_JABBER_DISABLE ((uint32_t)0x00400000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Inter_Frame_Gap ETH Inter Frame Gap
- * @{
- */
-#define ETH_INTERFRAMEGAP_96BIT ((uint32_t)0x00000000U) /*!< minimum IFG between frames during transmission is 96Bit */
-#define ETH_INTERFRAMEGAP_88BIT ((uint32_t)0x00020000U) /*!< minimum IFG between frames during transmission is 88Bit */
-#define ETH_INTERFRAMEGAP_80BIT ((uint32_t)0x00040000U) /*!< minimum IFG between frames during transmission is 80Bit */
-#define ETH_INTERFRAMEGAP_72BIT ((uint32_t)0x00060000U) /*!< minimum IFG between frames during transmission is 72Bit */
-#define ETH_INTERFRAMEGAP_64BIT ((uint32_t)0x00080000U) /*!< minimum IFG between frames during transmission is 64Bit */
-#define ETH_INTERFRAMEGAP_56BIT ((uint32_t)0x000A0000U) /*!< minimum IFG between frames during transmission is 56Bit */
-#define ETH_INTERFRAMEGAP_48BIT ((uint32_t)0x000C0000U) /*!< minimum IFG between frames during transmission is 48Bit */
-#define ETH_INTERFRAMEGAP_40BIT ((uint32_t)0x000E0000U) /*!< minimum IFG between frames during transmission is 40Bit */
-/**
- * @}
- */
-
-/** @defgroup ETH_Carrier_Sense ETH Carrier Sense
- * @{
- */
-#define ETH_CARRIERSENCE_ENABLE ((uint32_t)0x00000000U)
-#define ETH_CARRIERSENCE_DISABLE ((uint32_t)0x00010000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Own ETH Receive Own
- * @{
- */
-#define ETH_RECEIVEOWN_ENABLE ((uint32_t)0x00000000U)
-#define ETH_RECEIVEOWN_DISABLE ((uint32_t)0x00002000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Loop_Back_Mode ETH Loop Back Mode
- * @{
- */
-#define ETH_LOOPBACKMODE_ENABLE ((uint32_t)0x00001000U)
-#define ETH_LOOPBACKMODE_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Checksum_Offload ETH Checksum Offload
- * @{
- */
-#define ETH_CHECKSUMOFFLAOD_ENABLE ((uint32_t)0x00000400U)
-#define ETH_CHECKSUMOFFLAOD_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Retry_Transmission ETH Retry Transmission
- * @{
- */
-#define ETH_RETRYTRANSMISSION_ENABLE ((uint32_t)0x00000000U)
-#define ETH_RETRYTRANSMISSION_DISABLE ((uint32_t)0x00000200U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Automatic_Pad_CRC_Strip ETH Automatic Pad CRC Strip
- * @{
- */
-#define ETH_AUTOMATICPADCRCSTRIP_ENABLE ((uint32_t)0x00000080U)
-#define ETH_AUTOMATICPADCRCSTRIP_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Back_Off_Limit ETH Back Off Limit
- * @{
- */
-#define ETH_BACKOFFLIMIT_10 ((uint32_t)0x00000000U)
-#define ETH_BACKOFFLIMIT_8 ((uint32_t)0x00000020U)
-#define ETH_BACKOFFLIMIT_4 ((uint32_t)0x00000040U)
-#define ETH_BACKOFFLIMIT_1 ((uint32_t)0x00000060U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Deferral_Check ETH Deferral Check
- * @{
- */
-#define ETH_DEFFERRALCHECK_ENABLE ((uint32_t)0x00000010U)
-#define ETH_DEFFERRALCHECK_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_All ETH Receive All
- * @{
- */
-#define ETH_RECEIVEALL_ENABLE ((uint32_t)0x80000000U)
-#define ETH_RECEIVEAll_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Source_Addr_Filter ETH Source Addr Filter
- * @{
- */
-#define ETH_SOURCEADDRFILTER_NORMAL_ENABLE ((uint32_t)0x00000200U)
-#define ETH_SOURCEADDRFILTER_INVERSE_ENABLE ((uint32_t)0x00000300U)
-#define ETH_SOURCEADDRFILTER_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Pass_Control_Frames ETH Pass Control Frames
- * @{
- */
-#define ETH_PASSCONTROLFRAMES_BLOCKALL ((uint32_t)0x00000040U) /*!< MAC filters all control frames from reaching the application */
-#define ETH_PASSCONTROLFRAMES_FORWARDALL ((uint32_t)0x00000080U) /*!< MAC forwards all control frames to application even if they fail the Address Filter */
-#define ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER ((uint32_t)0x000000C0U) /*!< MAC forwards control frames that pass the Address Filter. */
-/**
- * @}
- */
-
-/** @defgroup ETH_Broadcast_Frames_Reception ETH Broadcast Frames Reception
- * @{
- */
-#define ETH_BROADCASTFRAMESRECEPTION_ENABLE ((uint32_t)0x00000000U)
-#define ETH_BROADCASTFRAMESRECEPTION_DISABLE ((uint32_t)0x00000020U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Destination_Addr_Filter ETH Destination Addr Filter
- * @{
- */
-#define ETH_DESTINATIONADDRFILTER_NORMAL ((uint32_t)0x00000000U)
-#define ETH_DESTINATIONADDRFILTER_INVERSE ((uint32_t)0x00000008U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Promiscuous_Mode ETH Promiscuous Mode
- * @{
- */
-#define ETH_PROMISCUOUS_MODE_ENABLE ((uint32_t)0x00000001U)
-#define ETH_PROMISCUOUS_MODE_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Multicast_Frames_Filter ETH Multicast Frames Filter
- * @{
- */
-#define ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE ((uint32_t)0x00000404U)
-#define ETH_MULTICASTFRAMESFILTER_HASHTABLE ((uint32_t)0x00000004U)
-#define ETH_MULTICASTFRAMESFILTER_PERFECT ((uint32_t)0x00000000U)
-#define ETH_MULTICASTFRAMESFILTER_NONE ((uint32_t)0x00000010U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Unicast_Frames_Filter ETH Unicast Frames Filter
- * @{
- */
-#define ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE ((uint32_t)0x00000402U)
-#define ETH_UNICASTFRAMESFILTER_HASHTABLE ((uint32_t)0x00000002U)
-#define ETH_UNICASTFRAMESFILTER_PERFECT ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Zero_Quanta_Pause ETH Zero Quanta Pause
- * @{
- */
-#define ETH_ZEROQUANTAPAUSE_ENABLE ((uint32_t)0x00000000U)
-#define ETH_ZEROQUANTAPAUSE_DISABLE ((uint32_t)0x00000080U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Pause_Low_Threshold ETH Pause Low Threshold
- * @{
- */
-#define ETH_PAUSELOWTHRESHOLD_MINUS4 ((uint32_t)0x00000000U) /*!< Pause time minus 4 slot times */
-#define ETH_PAUSELOWTHRESHOLD_MINUS28 ((uint32_t)0x00000010U) /*!< Pause time minus 28 slot times */
-#define ETH_PAUSELOWTHRESHOLD_MINUS144 ((uint32_t)0x00000020U) /*!< Pause time minus 144 slot times */
-#define ETH_PAUSELOWTHRESHOLD_MINUS256 ((uint32_t)0x00000030U) /*!< Pause time minus 256 slot times */
-/**
- * @}
- */
-
-/** @defgroup ETH_Unicast_Pause_Frame_Detect ETH Unicast Pause Frame Detect
- * @{
- */
-#define ETH_UNICASTPAUSEFRAMEDETECT_ENABLE ((uint32_t)0x00000008U)
-#define ETH_UNICASTPAUSEFRAMEDETECT_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Flow_Control ETH Receive Flow Control
- * @{
- */
-#define ETH_RECEIVEFLOWCONTROL_ENABLE ((uint32_t)0x00000004U)
-#define ETH_RECEIVEFLOWCONTROL_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Transmit_Flow_Control ETH Transmit Flow Control
- * @{
- */
-#define ETH_TRANSMITFLOWCONTROL_ENABLE ((uint32_t)0x00000002U)
-#define ETH_TRANSMITFLOWCONTROL_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_VLAN_Tag_Comparison ETH VLAN Tag Comparison
- * @{
- */
-#define ETH_VLANTAGCOMPARISON_12BIT ((uint32_t)0x00010000U)
-#define ETH_VLANTAGCOMPARISON_16BIT ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_addresses ETH MAC addresses
- * @{
- */
-#define ETH_MAC_ADDRESS0 ((uint32_t)0x00000000U)
-#define ETH_MAC_ADDRESS1 ((uint32_t)0x00000008U)
-#define ETH_MAC_ADDRESS2 ((uint32_t)0x00000010U)
-#define ETH_MAC_ADDRESS3 ((uint32_t)0x00000018U)
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_addresses_filter_SA_DA ETH MAC addresses filter SA DA
- * @{
- */
-#define ETH_MAC_ADDRESSFILTER_SA ((uint32_t)0x00000000U)
-#define ETH_MAC_ADDRESSFILTER_DA ((uint32_t)0x00000008U)
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_addresses_filter_Mask_bytes ETH MAC addresses filter Mask bytes
- * @{
- */
-#define ETH_MAC_ADDRESSMASK_BYTE6 ((uint32_t)0x20000000U) /*!< Mask MAC Address high reg bits [15:8] */
-#define ETH_MAC_ADDRESSMASK_BYTE5 ((uint32_t)0x10000000U) /*!< Mask MAC Address high reg bits [7:0] */
-#define ETH_MAC_ADDRESSMASK_BYTE4 ((uint32_t)0x08000000U) /*!< Mask MAC Address low reg bits [31:24] */
-#define ETH_MAC_ADDRESSMASK_BYTE3 ((uint32_t)0x04000000U) /*!< Mask MAC Address low reg bits [23:16] */
-#define ETH_MAC_ADDRESSMASK_BYTE2 ((uint32_t)0x02000000U) /*!< Mask MAC Address low reg bits [15:8] */
-#define ETH_MAC_ADDRESSMASK_BYTE1 ((uint32_t)0x01000000U) /*!< Mask MAC Address low reg bits [70] */
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_Debug_flags ETH MAC Debug flags
- * @{
- */
-#define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */
-#define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */
-#define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */
-#define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */
-#define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */
-#define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */
-#define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */
-#define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */
-#define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */
-#define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */
-#define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */
-#define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */
-#define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */
-#define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */
-#define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000060) /* Rx FIFO read controller IDLE state */
-#define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame data */
-#define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame status (or time-stamp) */
-#define ETH_MAC_READCONTROLLER_ FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */
-#define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */
-#define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */
-#define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */
-#define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */
-#define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */
-#define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */
-/**
- * @}
- */
-
-/** @defgroup ETH_Drop_TCP_IP_Checksum_Error_Frame ETH Drop TCP IP Checksum Error Frame
- * @{
- */
-#define ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE ((uint32_t)0x00000000U)
-#define ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE ((uint32_t)0x04000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Store_Forward ETH Receive Store Forward
- * @{
- */
-#define ETH_RECEIVESTOREFORWARD_ENABLE ((uint32_t)0x02000000U)
-#define ETH_RECEIVESTOREFORWARD_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Flush_Received_Frame ETH Flush Received Frame
- * @{
- */
-#define ETH_FLUSHRECEIVEDFRAME_ENABLE ((uint32_t)0x00000000U)
-#define ETH_FLUSHRECEIVEDFRAME_DISABLE ((uint32_t)0x01000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Transmit_Store_Forward ETH Transmit Store Forward
- * @{
- */
-#define ETH_TRANSMITSTOREFORWARD_ENABLE ((uint32_t)0x00200000U)
-#define ETH_TRANSMITSTOREFORWARD_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Transmit_Threshold_Control ETH Transmit Threshold Control
- * @{
- */
-#define ETH_TRANSMITTHRESHOLDCONTROL_64BYTES ((uint32_t)0x00000000U) /*!< threshold level of the MTL Transmit FIFO is 64 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_128BYTES ((uint32_t)0x00004000U) /*!< threshold level of the MTL Transmit FIFO is 128 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_192BYTES ((uint32_t)0x00008000U) /*!< threshold level of the MTL Transmit FIFO is 192 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_256BYTES ((uint32_t)0x0000C000U) /*!< threshold level of the MTL Transmit FIFO is 256 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_40BYTES ((uint32_t)0x00010000U) /*!< threshold level of the MTL Transmit FIFO is 40 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_32BYTES ((uint32_t)0x00014000U) /*!< threshold level of the MTL Transmit FIFO is 32 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_24BYTES ((uint32_t)0x00018000U) /*!< threshold level of the MTL Transmit FIFO is 24 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_16BYTES ((uint32_t)0x0001C000U) /*!< threshold level of the MTL Transmit FIFO is 16 Bytes */
-/**
- * @}
- */
-
-/** @defgroup ETH_Forward_Error_Frames ETH Forward Error Frames
- * @{
- */
-#define ETH_FORWARDERRORFRAMES_ENABLE ((uint32_t)0x00000080U)
-#define ETH_FORWARDERRORFRAMES_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Forward_Undersized_Good_Frames ETH Forward Undersized Good Frames
- * @{
- */
-#define ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE ((uint32_t)0x00000040U)
-#define ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Threshold_Control ETH Receive Threshold Control
- * @{
- */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES ((uint32_t)0x00000000U) /*!< threshold level of the MTL Receive FIFO is 64 Bytes */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES ((uint32_t)0x00000008U) /*!< threshold level of the MTL Receive FIFO is 32 Bytes */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES ((uint32_t)0x00000010U) /*!< threshold level of the MTL Receive FIFO is 96 Bytes */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES ((uint32_t)0x00000018U) /*!< threshold level of the MTL Receive FIFO is 128 Bytes */
-/**
- * @}
- */
-
-/** @defgroup ETH_Second_Frame_Operate ETH Second Frame Operate
- * @{
- */
-#define ETH_SECONDFRAMEOPERARTE_ENABLE ((uint32_t)0x00000004U)
-#define ETH_SECONDFRAMEOPERARTE_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Address_Aligned_Beats ETH Address Aligned Beats
- * @{
- */
-#define ETH_ADDRESSALIGNEDBEATS_ENABLE ((uint32_t)0x02000000U)
-#define ETH_ADDRESSALIGNEDBEATS_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Fixed_Burst ETH Fixed Burst
- * @{
- */
-#define ETH_FIXEDBURST_ENABLE ((uint32_t)0x00010000U)
-#define ETH_FIXEDBURST_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Rx_DMA_Burst_Length ETH Rx DMA Burst Length
- * @{
- */
-#define ETH_RXDMABURSTLENGTH_1BEAT ((uint32_t)0x00020000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 1 */
-#define ETH_RXDMABURSTLENGTH_2BEAT ((uint32_t)0x00040000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 2 */
-#define ETH_RXDMABURSTLENGTH_4BEAT ((uint32_t)0x00080000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */
-#define ETH_RXDMABURSTLENGTH_8BEAT ((uint32_t)0x00100000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */
-#define ETH_RXDMABURSTLENGTH_16BEAT ((uint32_t)0x00200000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */
-#define ETH_RXDMABURSTLENGTH_32BEAT ((uint32_t)0x00400000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_4BEAT ((uint32_t)0x01020000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_8BEAT ((uint32_t)0x01040000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_16BEAT ((uint32_t)0x01080000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_32BEAT ((uint32_t)0x01100000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_64BEAT ((uint32_t)0x01200000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 64 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_128BEAT ((uint32_t)0x01400000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 128 */
-/**
- * @}
- */
-
-/** @defgroup ETH_Tx_DMA_Burst_Length ETH Tx DMA Burst Length
- * @{
- */
-#define ETH_TXDMABURSTLENGTH_1BEAT ((uint32_t)0x00000100U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
-#define ETH_TXDMABURSTLENGTH_2BEAT ((uint32_t)0x00000200U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
-#define ETH_TXDMABURSTLENGTH_4BEAT ((uint32_t)0x00000400U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
-#define ETH_TXDMABURSTLENGTH_8BEAT ((uint32_t)0x00000800U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
-#define ETH_TXDMABURSTLENGTH_16BEAT ((uint32_t)0x00001000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
-#define ETH_TXDMABURSTLENGTH_32BEAT ((uint32_t)0x00002000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_4BEAT ((uint32_t)0x01000100U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_8BEAT ((uint32_t)0x01000200U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_16BEAT ((uint32_t)0x01000400U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_32BEAT ((uint32_t)0x01000800U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_64BEAT ((uint32_t)0x01001000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_128BEAT ((uint32_t)0x01002000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Enhanced_descriptor_format ETH DMA Enhanced descriptor format
- * @{
- */
-#define ETH_DMAENHANCEDDESCRIPTOR_ENABLE ((uint32_t)0x00000080U)
-#define ETH_DMAENHANCEDDESCRIPTOR_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Arbitration ETH DMA Arbitration
- * @{
- */
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1 ((uint32_t)0x00000000U)
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1 ((uint32_t)0x00004000U)
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1 ((uint32_t)0x00008000U)
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 ((uint32_t)0x0000C000U)
-#define ETH_DMAARBITRATION_RXPRIORTX ((uint32_t)0x00000002U)
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Tx_descriptor_segment ETH DMA Tx descriptor segment
- * @{
- */
-#define ETH_DMATXDESC_LASTSEGMENTS ((uint32_t)0x40000000U) /*!< Last Segment */
-#define ETH_DMATXDESC_FIRSTSEGMENT ((uint32_t)0x20000000U) /*!< First Segment */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Tx_descriptor_Checksum_Insertion_Control ETH DMA Tx descriptor Checksum Insertion Control
- * @{
- */
-#define ETH_DMATXDESC_CHECKSUMBYPASS ((uint32_t)0x00000000U) /*!< Checksum engine bypass */
-#define ETH_DMATXDESC_CHECKSUMIPV4HEADER ((uint32_t)0x00400000U) /*!< IPv4 header checksum insertion */
-#define ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT ((uint32_t)0x00800000U) /*!< TCP/UDP/ICMP checksum insertion. Pseudo header checksum is assumed to be present */
-#define ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL ((uint32_t)0x00C00000U) /*!< TCP/UDP/ICMP checksum fully in hardware including pseudo header */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Rx_descriptor_buffers ETH DMA Rx descriptor buffers
- * @{
- */
-#define ETH_DMARXDESC_BUFFER1 ((uint32_t)0x00000000U) /*!< DMA Rx Desc Buffer1 */
-#define ETH_DMARXDESC_BUFFER2 ((uint32_t)0x00000001U) /*!< DMA Rx Desc Buffer2 */
-/**
- * @}
- */
-
-/** @defgroup ETH_PMT_Flags ETH PMT Flags
- * @{
- */
-#define ETH_PMT_FLAG_WUFFRPR ((uint32_t)0x80000000U) /*!< Wake-Up Frame Filter Register Pointer Reset */
-#define ETH_PMT_FLAG_WUFR ((uint32_t)0x00000040U) /*!< Wake-Up Frame Received */
-#define ETH_PMT_FLAG_MPR ((uint32_t)0x00000020U) /*!< Magic Packet Received */
-/**
- * @}
- */
-
-/** @defgroup ETH_MMC_Tx_Interrupts ETH MMC Tx Interrupts
- * @{
- */
-#define ETH_MMC_IT_TGF ((uint32_t)0x00200000U) /*!< When Tx good frame counter reaches half the maximum value */
-#define ETH_MMC_IT_TGFMSC ((uint32_t)0x00008000U) /*!< When Tx good multi col counter reaches half the maximum value */
-#define ETH_MMC_IT_TGFSC ((uint32_t)0x00004000U) /*!< When Tx good single col counter reaches half the maximum value */
-/**
- * @}
- */
-
-/** @defgroup ETH_MMC_Rx_Interrupts ETH MMC Rx Interrupts
- * @{
- */
-#define ETH_MMC_IT_RGUF ((uint32_t)0x10020000U) /*!< When Rx good unicast frames counter reaches half the maximum value */
-#define ETH_MMC_IT_RFAE ((uint32_t)0x10000040U) /*!< When Rx alignment error counter reaches half the maximum value */
-#define ETH_MMC_IT_RFCE ((uint32_t)0x10000020U) /*!< When Rx crc error counter reaches half the maximum value */
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_Flags ETH MAC Flags
- * @{
- */
-#define ETH_MAC_FLAG_TST ((uint32_t)0x00000200U) /*!< Time stamp trigger flag (on MAC) */
-#define ETH_MAC_FLAG_MMCT ((uint32_t)0x00000040U) /*!< MMC transmit flag */
-#define ETH_MAC_FLAG_MMCR ((uint32_t)0x00000020U) /*!< MMC receive flag */
-#define ETH_MAC_FLAG_MMC ((uint32_t)0x00000010U) /*!< MMC flag (on MAC) */
-#define ETH_MAC_FLAG_PMT ((uint32_t)0x00000008U) /*!< PMT flag (on MAC) */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Flags ETH DMA Flags
- * @{
- */
-#define ETH_DMA_FLAG_TST ((uint32_t)0x20000000U) /*!< Time-stamp trigger interrupt (on DMA) */
-#define ETH_DMA_FLAG_PMT ((uint32_t)0x10000000U) /*!< PMT interrupt (on DMA) */
-#define ETH_DMA_FLAG_MMC ((uint32_t)0x08000000U) /*!< MMC interrupt (on DMA) */
-#define ETH_DMA_FLAG_DATATRANSFERERROR ((uint32_t)0x00800000U) /*!< Error bits 0-Rx DMA, 1-Tx DMA */
-#define ETH_DMA_FLAG_READWRITEERROR ((uint32_t)0x01000000U) /*!< Error bits 0-write transfer, 1-read transfer */
-#define ETH_DMA_FLAG_ACCESSERROR ((uint32_t)0x02000000U) /*!< Error bits 0-data buffer, 1-desc. access */
-#define ETH_DMA_FLAG_NIS ((uint32_t)0x00010000U) /*!< Normal interrupt summary flag */
-#define ETH_DMA_FLAG_AIS ((uint32_t)0x00008000U) /*!< Abnormal interrupt summary flag */
-#define ETH_DMA_FLAG_ER ((uint32_t)0x00004000U) /*!< Early receive flag */
-#define ETH_DMA_FLAG_FBE ((uint32_t)0x00002000U) /*!< Fatal bus error flag */
-#define ETH_DMA_FLAG_ET ((uint32_t)0x00000400U) /*!< Early transmit flag */
-#define ETH_DMA_FLAG_RWT ((uint32_t)0x00000200U) /*!< Receive watchdog timeout flag */
-#define ETH_DMA_FLAG_RPS ((uint32_t)0x00000100U) /*!< Receive process stopped flag */
-#define ETH_DMA_FLAG_RBU ((uint32_t)0x00000080U) /*!< Receive buffer unavailable flag */
-#define ETH_DMA_FLAG_R ((uint32_t)0x00000040U) /*!< Receive flag */
-#define ETH_DMA_FLAG_TU ((uint32_t)0x00000020U) /*!< Underflow flag */
-#define ETH_DMA_FLAG_RO ((uint32_t)0x00000010U) /*!< Overflow flag */
-#define ETH_DMA_FLAG_TJT ((uint32_t)0x00000008U) /*!< Transmit jabber timeout flag */
-#define ETH_DMA_FLAG_TBU ((uint32_t)0x00000004U) /*!< Transmit buffer unavailable flag */
-#define ETH_DMA_FLAG_TPS ((uint32_t)0x00000002U) /*!< Transmit process stopped flag */
-#define ETH_DMA_FLAG_T ((uint32_t)0x00000001U) /*!< Transmit flag */
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_Interrupts ETH MAC Interrupts
- * @{
- */
-#define ETH_MAC_IT_TST ((uint32_t)0x00000200U) /*!< Time stamp trigger interrupt (on MAC) */
-#define ETH_MAC_IT_MMCT ((uint32_t)0x00000040U) /*!< MMC transmit interrupt */
-#define ETH_MAC_IT_MMCR ((uint32_t)0x00000020U) /*!< MMC receive interrupt */
-#define ETH_MAC_IT_MMC ((uint32_t)0x00000010U) /*!< MMC interrupt (on MAC) */
-#define ETH_MAC_IT_PMT ((uint32_t)0x00000008U) /*!< PMT interrupt (on MAC) */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Interrupts ETH DMA Interrupts
- * @{
- */
-#define ETH_DMA_IT_TST ((uint32_t)0x20000000U) /*!< Time-stamp trigger interrupt (on DMA) */
-#define ETH_DMA_IT_PMT ((uint32_t)0x10000000U) /*!< PMT interrupt (on DMA) */
-#define ETH_DMA_IT_MMC ((uint32_t)0x08000000U) /*!< MMC interrupt (on DMA) */
-#define ETH_DMA_IT_NIS ((uint32_t)0x00010000U) /*!< Normal interrupt summary */
-#define ETH_DMA_IT_AIS ((uint32_t)0x00008000U) /*!< Abnormal interrupt summary */
-#define ETH_DMA_IT_ER ((uint32_t)0x00004000U) /*!< Early receive interrupt */
-#define ETH_DMA_IT_FBE ((uint32_t)0x00002000U) /*!< Fatal bus error interrupt */
-#define ETH_DMA_IT_ET ((uint32_t)0x00000400U) /*!< Early transmit interrupt */
-#define ETH_DMA_IT_RWT ((uint32_t)0x00000200U) /*!< Receive watchdog timeout interrupt */
-#define ETH_DMA_IT_RPS ((uint32_t)0x00000100U) /*!< Receive process stopped interrupt */
-#define ETH_DMA_IT_RBU ((uint32_t)0x00000080U) /*!< Receive buffer unavailable interrupt */
-#define ETH_DMA_IT_R ((uint32_t)0x00000040U) /*!< Receive interrupt */
-#define ETH_DMA_IT_TU ((uint32_t)0x00000020U) /*!< Underflow interrupt */
-#define ETH_DMA_IT_RO ((uint32_t)0x00000010U) /*!< Overflow interrupt */
-#define ETH_DMA_IT_TJT ((uint32_t)0x00000008U) /*!< Transmit jabber timeout interrupt */
-#define ETH_DMA_IT_TBU ((uint32_t)0x00000004U) /*!< Transmit buffer unavailable interrupt */
-#define ETH_DMA_IT_TPS ((uint32_t)0x00000002U) /*!< Transmit process stopped interrupt */
-#define ETH_DMA_IT_T ((uint32_t)0x00000001U) /*!< Transmit interrupt */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_transmit_process_state ETH DMA transmit process state
- * @{
- */
-#define ETH_DMA_TRANSMITPROCESS_STOPPED ((uint32_t)0x00000000U) /*!< Stopped - Reset or Stop Tx Command issued */
-#define ETH_DMA_TRANSMITPROCESS_FETCHING ((uint32_t)0x00100000U) /*!< Running - fetching the Tx descriptor */
-#define ETH_DMA_TRANSMITPROCESS_WAITING ((uint32_t)0x00200000U) /*!< Running - waiting for status */
-#define ETH_DMA_TRANSMITPROCESS_READING ((uint32_t)0x00300000U) /*!< Running - reading the data from host memory */
-#define ETH_DMA_TRANSMITPROCESS_SUSPENDED ((uint32_t)0x00600000U) /*!< Suspended - Tx Descriptor unavailable */
-#define ETH_DMA_TRANSMITPROCESS_CLOSING ((uint32_t)0x00700000U) /*!< Running - closing Rx descriptor */
-
-/**
- * @}
- */
-
-
-/** @defgroup ETH_DMA_receive_process_state ETH DMA receive process state
- * @{
- */
-#define ETH_DMA_RECEIVEPROCESS_STOPPED ((uint32_t)0x00000000U) /*!< Stopped - Reset or Stop Rx Command issued */
-#define ETH_DMA_RECEIVEPROCESS_FETCHING ((uint32_t)0x00020000U) /*!< Running - fetching the Rx descriptor */
-#define ETH_DMA_RECEIVEPROCESS_WAITING ((uint32_t)0x00060000U) /*!< Running - waiting for packet */
-#define ETH_DMA_RECEIVEPROCESS_SUSPENDED ((uint32_t)0x00080000U) /*!< Suspended - Rx Descriptor unavailable */
-#define ETH_DMA_RECEIVEPROCESS_CLOSING ((uint32_t)0x000A0000U) /*!< Running - closing descriptor */
-#define ETH_DMA_RECEIVEPROCESS_QUEUING ((uint32_t)0x000E0000U) /*!< Running - queuing the receive frame into host memory */
-
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_overflow ETH DMA overflow
- * @{
- */
-#define ETH_DMA_OVERFLOW_RXFIFOCOUNTER ((uint32_t)0x10000000U) /*!< Overflow bit for FIFO overflow counter */
-#define ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER ((uint32_t)0x00010000U) /*!< Overflow bit for missed frame counter */
-/**
- * @}
- */
-
-/** @defgroup ETH_EXTI_LINE_WAKEUP ETH EXTI LINE WAKEUP
- * @{
- */
-#define ETH_EXTI_LINE_WAKEUP ((uint32_t)0x00080000U) /*!< External interrupt line 19 Connected to the ETH EXTI Line */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup ETH_Exported_Macros ETH Exported Macros
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-
-/** @brief Reset ETH handle state
- * @param __HANDLE__: specifies the ETH handle.
- * @retval None
- */
-#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_ETH_STATE_RESET)
-
-/**
- * @brief Checks whether the specified Ethernet DMA Tx Desc flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag of TDES0 to check.
- * @retval the ETH_DMATxDescFlag (SET or RESET).
- */
-#define __HAL_ETH_DMATXDESC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->TxDesc->Status & (__FLAG__) == (__FLAG__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA Rx Desc flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag of RDES0 to check.
- * @retval the ETH_DMATxDescFlag (SET or RESET).
- */
-#define __HAL_ETH_DMARXDESC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->RxDesc->Status & (__FLAG__) == (__FLAG__))
-
-/**
- * @brief Enables the specified DMA Rx Desc receive interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMARXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->RxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARXDESC_DIC))
-
-/**
- * @brief Disables the specified DMA Rx Desc receive interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMARXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->RxDesc->ControlBufferSize |= ETH_DMARXDESC_DIC)
-
-/**
- * @brief Set the specified DMA Rx Desc Own bit.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMARXDESC_SET_OWN_BIT(__HANDLE__) ((__HANDLE__)->RxDesc->Status |= ETH_DMARXDESC_OWN)
-
-/**
- * @brief Returns the specified Ethernet DMA Tx Desc collision count.
- * @param __HANDLE__: ETH Handle
- * @retval The Transmit descriptor collision counter value.
- */
-#define __HAL_ETH_DMATXDESC_GET_COLLISION_COUNT(__HANDLE__) (((__HANDLE__)->TxDesc->Status & ETH_DMATXDESC_CC) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT)
-
-/**
- * @brief Set the specified DMA Tx Desc Own bit.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_SET_OWN_BIT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_OWN)
-
-/**
- * @brief Enables the specified DMA Tx Desc Transmit interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_IC)
-
-/**
- * @brief Disables the specified DMA Tx Desc Transmit interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_IC)
-
-/**
- * @brief Selects the specified Ethernet DMA Tx Desc Checksum Insertion.
- * @param __HANDLE__: ETH Handle
- * @param __CHECKSUM__: specifies is the DMA Tx desc checksum insertion.
- * This parameter can be one of the following values:
- * @arg ETH_DMATXDESC_CHECKSUMBYPASS : Checksum bypass
- * @arg ETH_DMATXDESC_CHECKSUMIPV4HEADER : IPv4 header checksum
- * @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
- * @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL : TCP/UDP/ICMP checksum fully in hardware including pseudo header
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_CHECKSUM_INSERTION(__HANDLE__, __CHECKSUM__) ((__HANDLE__)->TxDesc->Status |= (__CHECKSUM__))
-
-/**
- * @brief Enables the DMA Tx Desc CRC.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_CRC_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DC)
-
-/**
- * @brief Disables the DMA Tx Desc CRC.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_CRC_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DC)
-
-/**
- * @brief Enables the DMA Tx Desc padding for frame shorter than 64 bytes.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DP)
-
-/**
- * @brief Disables the DMA Tx Desc padding for frame shorter than 64 bytes.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DP)
-
-/**
- * @brief Enables the specified Ethernet MAC interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet MAC interrupt sources to be
- * enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
- * @arg ETH_MAC_IT_PMT : PMT interrupt
- * @retval None
- */
-#define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR |= (__INTERRUPT__))
-
-/**
- * @brief Disables the specified Ethernet MAC interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet MAC interrupt sources to be
- * enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
- * @arg ETH_MAC_IT_PMT : PMT interrupt
- * @retval None
- */
-#define __HAL_ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR &= ~(__INTERRUPT__))
-
-/**
- * @brief Initiate a Pause Control Frame (Full-duplex only).
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_INITIATE_PAUSE_CONTROL_FRAME(__HANDLE__) ((__HANDLE__)->Instance->MACFCR |= ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Checks whether the Ethernet flow control busy bit is set or not.
- * @param __HANDLE__: ETH Handle
- * @retval The new state of flow control busy status bit (SET or RESET).
- */
-#define __HAL_ETH_GET_FLOW_CONTROL_BUSY_STATUS(__HANDLE__) (((__HANDLE__)->Instance->MACFCR & ETH_MACFCR_FCBBPA) == ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Enables the MAC Back Pressure operation activation (Half-duplex only).
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_BACK_PRESSURE_ACTIVATION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACFCR |= ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Disables the MAC BackPressure operation activation (Half-duplex only).
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_BACK_PRESSURE_ACTIVATION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACFCR &= ~ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Checks whether the specified Ethernet MAC flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg ETH_MAC_FLAG_TST : Time stamp trigger flag
- * @arg ETH_MAC_FLAG_MMCT : MMC transmit flag
- * @arg ETH_MAC_FLAG_MMCR : MMC receive flag
- * @arg ETH_MAC_FLAG_MMC : MMC flag
- * @arg ETH_MAC_FLAG_PMT : PMT flag
- * @retval The state of Ethernet MAC flag.
- */
-#define __HAL_ETH_MAC_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACSR &( __FLAG__)) == ( __FLAG__))
-
-/**
- * @brief Enables the specified Ethernet DMA interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet DMA interrupt sources to be
- * enabled @ref ETH_DMA_Interrupts
- * @retval None
- */
-#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER |= (__INTERRUPT__))
-
-/**
- * @brief Disables the specified Ethernet DMA interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet DMA interrupt sources to be
- * disabled. @ref ETH_DMA_Interrupts
- * @retval None
- */
-#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER &= ~(__INTERRUPT__))
-
-/**
- * @brief Clears the Ethernet DMA IT pending bit.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts
- * @retval None
- */
-#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMASR =(__INTERRUPT__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA flag is set or not.
-* @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Flags
- * @retval The new state of ETH_DMA_FLAG (SET or RESET).
- */
-#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMASR &( __FLAG__)) == ( __FLAG__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag to clear. @ref ETH_DMA_Flags
- * @retval The new state of ETH_DMA_FLAG (SET or RESET).
- */
-#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMASR = (__FLAG__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA overflow flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __OVERFLOW__: specifies the DMA overflow flag to check.
- * This parameter can be one of the following values:
- * @arg ETH_DMA_OVERFLOW_RXFIFOCOUNTER : Overflow for FIFO Overflows Counter
- * @arg ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER : Overflow for Buffer Unavailable Missed Frame Counter
- * @retval The state of Ethernet DMA overflow Flag (SET or RESET).
- */
-#define __HAL_ETH_GET_DMA_OVERFLOW_STATUS(__HANDLE__, __OVERFLOW__) (((__HANDLE__)->Instance->DMAMFBOCR & (__OVERFLOW__)) == (__OVERFLOW__))
-
-/**
- * @brief Set the DMA Receive status watchdog timer register value
- * @param __HANDLE__: ETH Handle
- * @param __VALUE__: DMA Receive status watchdog timer register value
- * @retval None
- */
-#define __HAL_ETH_SET_RECEIVE_WATCHDOG_TIMER(__HANDLE__, __VALUE__) ((__HANDLE__)->Instance->DMARSWTR = (__VALUE__))
-
-/**
- * @brief Enables any unicast packet filtered by the MAC address
- * recognition to be a wake-up frame.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_GLOBAL_UNICAST_WAKEUP_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_GU)
-
-/**
- * @brief Disables any unicast packet filtered by the MAC address
- * recognition to be a wake-up frame.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_GLOBAL_UNICAST_WAKEUP_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_GU)
-
-/**
- * @brief Enables the MAC Wake-Up Frame Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_FRAME_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_WFE)
-
-/**
- * @brief Disables the MAC Wake-Up Frame Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_FRAME_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_WFE)
-
-/**
- * @brief Enables the MAC Magic Packet Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MAGIC_PACKET_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_MPE)
-
-/**
- * @brief Disables the MAC Magic Packet Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MAGIC_PACKET_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_WFE)
-
-/**
- * @brief Enables the MAC Power Down.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_POWER_DOWN_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_PD)
-
-/**
- * @brief Disables the MAC Power Down.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_POWER_DOWN_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_PD)
-
-/**
- * @brief Checks whether the specified Ethernet PMT flag is set or not.
- * @param __HANDLE__: ETH Handle.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset
- * @arg ETH_PMT_FLAG_WUFR : Wake-Up Frame Received
- * @arg ETH_PMT_FLAG_MPR : Magic Packet Received
- * @retval The new state of Ethernet PMT Flag (SET or RESET).
- */
-#define __HAL_ETH_GET_PMT_FLAG_STATUS(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACPMTCSR &( __FLAG__)) == ( __FLAG__))
-
-/**
- * @brief Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16)
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_FULL_PRESET(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= (ETH_MMCCR_MCFHP | ETH_MMCCR_MCP))
-
-/**
- * @brief Preset and Initialize the MMC counters to almost-half value: 0x7FFF_FFF0 (half - 16)
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_HALF_PRESET(__HANDLE__) do{(__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_MCFHP;\
- (__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_MCP;} while (0)
-
-/**
- * @brief Enables the MMC Counter Freeze.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_FREEZE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_MCF)
-
-/**
- * @brief Disables the MMC Counter Freeze.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_FREEZE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_MCF)
-
-/**
- * @brief Enables the MMC Reset On Read.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_RESET_ONREAD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_ROR)
-
-/**
- * @brief Disables the MMC Reset On Read.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_RESET_ONREAD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_ROR)
-
-/**
- * @brief Enables the MMC Counter Stop Rollover.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_COUNTER_ROLLOVER_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_CSR)
-
-/**
- * @brief Disables the MMC Counter Stop Rollover.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_COUNTER_ROLLOVER_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_CSR)
-
-/**
- * @brief Resets the MMC Counters.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTERS_RESET(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_CR)
-
-/**
- * @brief Enables the specified Ethernet MMC Rx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_RX_IT_ENABLE(__HANDLE__, __INTERRUPT__) (__HANDLE__)->Instance->MMCRIMR &= ~((__INTERRUPT__) & 0xEFFFFFFF)
-/**
- * @brief Disables the specified Ethernet MMC Rx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_RX_IT_DISABLE(__HANDLE__, __INTERRUPT__) (__HANDLE__)->Instance->MMCRIMR |= ((__INTERRUPT__) & 0xEFFFFFFF)
-/**
- * @brief Enables the specified Ethernet MMC Tx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_TX_IT_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR &= ~ (__INTERRUPT__))
-
-/**
- * @brief Disables the specified Ethernet MMC Tx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_TX_IT_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR |= (__INTERRUPT__))
-
-/**
- * @brief Enables the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Disables the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enable event on ETH External event line.
- * @retval None.
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_EVENT() EXTI->EMR |= (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Disable event on ETH External event line
- * @retval None.
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_EVENT() EXTI->EMR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Get flag of the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Clear flag of the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enables rising edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER() EXTI->RTSR |= ETH_EXTI_LINE_WAKEUP
-
-/**
- * @brief Disables the rising edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_RISING_EDGE_TRIGGER() EXTI->RTSR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enables falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER() EXTI->FTSR |= (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Disables falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_FALLING_EDGE_TRIGGER() EXTI->FTSR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enables rising/falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER() EXTI->RTSR |= ETH_EXTI_LINE_WAKEUP;\
- EXTI->FTSR |= ETH_EXTI_LINE_WAKEUP
-
-/**
- * @brief Disables rising/falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_FALLINGRISING_TRIGGER() EXTI->RTSR &= ~(ETH_EXTI_LINE_WAKEUP);\
- EXTI->FTSR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Generate a Software interrupt on selected EXTI line.
- * @retval None.
- */
-#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT() EXTI->SWIER|= ETH_EXTI_LINE_WAKEUP
-
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup ETH_Exported_Functions
- * @{
- */
-
-/* Initialization and de-initialization functions ****************************/
-
-/** @addtogroup ETH_Exported_Functions_Group1
- * @{
- */
-HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth);
-void HAL_ETH_MspInit(ETH_HandleTypeDef *heth);
-void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount);
-HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount);
-
-/**
- * @}
- */
-/* IO operation functions ****************************************************/
-
-/** @addtogroup ETH_Exported_Functions_Group2
- * @{
- */
-HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength);
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth);
-/* Communication with PHY functions*/
-HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue);
-HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth);
-void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth);
-/* Callback in non blocking modes (Interrupt) */
-void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth);
-void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth);
-void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth);
-/**
- * @}
- */
-
-/* Peripheral Control functions **********************************************/
-
-/** @addtogroup ETH_Exported_Functions_Group3
- * @{
- */
-
-HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf);
-HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf);
-/**
- * @}
- */
-
-/* Peripheral State functions ************************************************/
-
-/** @addtogroup ETH_Exported_Functions_Group4
- * @{
- */
-HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32F7xx_HAL_ETH_H */
-
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
index 6fad9216e..b9278c042 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/NetworkInterface.c
@@ -1,1287 +1,1421 @@
-/*
- * Some constants, hardware definitions and comments taken from ST's HAL driver
- * library, COPYRIGHT(c) 2015 STMicroelectronics.
- */
-
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_DNS.h"
-#include "FreeRTOS_ARP.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-#include "phyHandling.h"
-
-/* ST includes. */
-#if defined( STM32F7xx )
- #include "stm32f7xx_hal.h"
-#elif defined( STM32F4xx )
- #include "stm32f4xx_hal.h"
-#elif defined( STM32F2xx )
- #include "stm32f2xx_hal.h"
-#elif !defined( _lint ) /* Lint does not like an #error */
- #error What part?
-#endif
-
-#include "stm32fxx_hal_eth.h"
-
-/* Interrupt events to process. Currently only the Rx event is processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-#define ETH_DMA_ALL_INTS \
- ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_ER | \
- ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
- ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-
-#ifndef niEMAC_HANDLER_TASK_PRIORITY
- #define niEMAC_HANDLER_TASK_PRIORITY configMAX_PRIORITIES - 1
-#endif
-
-#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
-
-#if( ( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM == 0 ) || ( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM == 0 ) )
- #warning Consider enabling checksum offloading
-#endif
-
-#ifndef niDESCRIPTOR_WAIT_TIME_MS
- #define niDESCRIPTOR_WAIT_TIME_MS 250uL
-#endif
-
-/*
- * Most users will want a PHY that negotiates about
- * the connection properties: speed, dmix and duplex.
- * On some rare cases, you want to select what is being
- * advertised, properties like MDIX and duplex.
- */
-
-#if !defined( ipconfigETHERNET_AN_ENABLE )
- /* Enable auto-negotiation */
- #define ipconfigETHERNET_AN_ENABLE 1
-#endif
-
-#if !defined( ipconfigETHERNET_AUTO_CROSS_ENABLE )
- #define ipconfigETHERNET_AUTO_CROSS_ENABLE 1
-#endif
-
-#if( ipconfigETHERNET_AN_ENABLE == 0 )
- /*
- * The following three defines are only used in case there
- * is no auto-negotiation.
- */
- #if !defined( ipconfigETHERNET_CROSSED_LINK )
- #define ipconfigETHERNET_CROSSED_LINK 1
- #endif
-
- #if !defined( ipconfigETHERNET_USE_100MB )
- #define ipconfigETHERNET_USE_100MB 1
- #endif
-
- #if !defined( ipconfigETHERNET_USE_FULL_DUPLEX )
- #define ipconfigETHERNET_USE_FULL_DUPLEX 1
- #endif
-#endif /* ipconfigETHERNET_AN_ENABLE == 0 */
-
-/* Default the size of the stack used by the EMAC deferred handler task to twice
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-#endif
-
-/* Two choices must be made: RMII versus MII,
-and the index of the PHY in use ( between 0 and 31 ). */
-#ifndef ipconfigUSE_RMII
- #ifdef STM32F7xx
- #define ipconfigUSE_RMII 1
- #else
- #define ipconfigUSE_RMII 0
- #endif /* STM32F7xx */
-#endif /* ipconfigUSE_RMII */
-
-#if( ipconfigUSE_RMII != 0 )
- #warning Using RMII, make sure if this is correct
-#else
- #warning Using MII, make sure if this is correct
-#endif
-
-typedef enum
-{
- eMACInit, /* Must initialise MAC. */
- eMACPass, /* Initialisation was successful. */
- eMACFailed, /* Initialisation failed. */
-} eMAC_INIT_STATUS_TYPE;
-
-static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
-
-/*-----------------------------------------------------------*/
-
-/*
- * A deferred interrupt handler task that processes
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Force a negotiation with the Switch or Router and wait for LS.
- */
-static void prvEthernetUpdateConfig( BaseType_t xForce );
-
-/*
- * See if there is a new packet and forward it to the IP-task.
- */
-static BaseType_t prvNetworkInterfaceInput( void );
-
-#if( ipconfigUSE_LLMNR != 0 )
- /*
- * For LLMNR, an extra MAC-address must be configured to
- * be able to receive the multicast messages.
- */
- static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr);
-#endif
-
-/*
- * Check if a given packet should be accepted.
- */
-static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer );
-
-/*
- * Initialise the TX descriptors.
- */
-static void prvDMATxDescListInit( void );
-
-/*
- * Initialise the RX descriptors.
- */
-static void prvDMARxDescListInit( void );
-
-/* After packets have been sent, the network
-buffers will be released. */
-static void vClearTXBuffers( void );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx interrupt is handled, although code is included for other events to
-enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-#if( ipconfigUSE_LLMNR == 1 )
- static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
-#endif
-
-static EthernetPhy_t xPhyObject;
-
-/* Ethernet handle. */
-static ETH_HandleTypeDef xETH;
-
-/* xTXDescriptorSemaphore is a counting semaphore with
-a maximum count of ETH_TXBUFNB, which is the number of
-DMA TX descriptors. */
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*
- * Note: it is adviced to define both
- *
- * #define ipconfigZERO_COPY_RX_DRIVER 1
- * #define ipconfigZERO_COPY_TX_DRIVER 1
- *
- * The method using memcpy is slower and probaly uses more RAM memory.
- * The possibility is left in the code just for comparison.
- *
- * It is adviced to define ETH_TXBUFNB at least 4. Note that no
- * TX buffers are allocated in a zero-copy driver.
- */
-/* MAC buffers: ---------------------------------------------------------*/
-
-/* Put the DMA descriptors in '.first_data'.
-This is important for STM32F7, which has an L1 data cache.
-The first 64KB of the SRAM is not cached. */
-
-/* Ethernet Rx MA Descriptor */
-__attribute__ ((aligned (32)))
-__attribute__ ((section(".first_data")))
- ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ];
-
-#if( ipconfigZERO_COPY_RX_DRIVER == 0 )
- /* Ethernet Receive Buffer */
- __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END;
-#endif
-
-/* Ethernet Tx DMA Descriptor */
-__attribute__ ((aligned (32)))
-__attribute__ ((section(".first_data")))
- ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ];
-
-#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- /* Ethernet Transmit Buffer */
- __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END;
-#endif
-
-/* DMATxDescToClear points to the next TX DMA descriptor
-that must be cleared by vClearTXBuffers(). */
-static __IO ETH_DMADescTypeDef *DMATxDescToClear;
-
-/* Holds the handle of the task used as a deferred interrupt processor. The
-handle is used so direct notifications can be sent to the task for all EMAC/DMA
-related interrupts. */
-static TaskHandle_t xEMACTaskHandle = NULL;
-
-/* For local use only: describe the PHY's properties: */
-const PhyProperties_t xPHYProperties =
-{
- #if( ipconfigETHERNET_AN_ENABLE != 0 )
- .ucSpeed = PHY_SPEED_AUTO,
- .ucDuplex = PHY_DUPLEX_AUTO,
- #else
- #if( ipconfigETHERNET_USE_100MB != 0 )
- .ucSpeed = PHY_SPEED_100,
- #else
- .ucSpeed = PHY_SPEED_10,
- #endif
-
- #if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
- .ucDuplex = PHY_DUPLEX_FULL,
- #else
- .ucDuplex = PHY_DUPLEX_HALF,
- #endif
- #endif
-
- #if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )
- .ucMDI_X = PHY_MDIX_AUTO,
- #elif( ipconfigETHERNET_CROSSED_LINK != 0 )
- .ucMDI_X = PHY_MDIX_CROSSED,
- #else
- .ucMDI_X = PHY_MDIX_DIRECT,
- #endif
-};
-
-/*-----------------------------------------------------------*/
-
-void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- ( void ) heth;
-
- /* Ethernet RX-Complete callback function, elsewhere declared as weak. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- /* Wakeup the prvEMACHandlerTask. */
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
-}
-/*-----------------------------------------------------------*/
-
-void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
-{
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- ( void ) heth;
-
- /* This call-back is only useful in case packets are being sent
- zero-copy. Once they're sent, the buffers will be released
- by the function vClearTXBuffers(). */
- ulISREvents |= EMAC_IF_TX_EVENT;
- /* Wakeup the prvEMACHandlerTask. */
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
- }
-}
-/*-----------------------------------------------------------*/
-
-static void vClearTXBuffers()
-{
-__IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
-size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- uint8_t *ucPayLoad;
-#endif
-
- /* This function is called after a TX-completion interrupt.
- It will release each Network Buffer used in xNetworkInterfaceOutput().
- 'uxCount' represents the number of descriptors given to DMA for transmission.
- After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
- while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
- {
- if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
- {
- break;
- }
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
-
- if( ucPayLoad != NULL )
- {
- pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
- if( pxNetworkBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
- }
- DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;
- }
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
-
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-HAL_StatusTypeDef hal_eth_init_status;
-BaseType_t xResult;
-
- if( xMacInitStatus == eMACInit )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
- if( xTXDescriptorSemaphore == NULL )
- {
- xMacInitStatus = eMACFailed;
- }
- else
- {
- /* Initialise ETH */
-
- xETH.Instance = ETH;
- xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
- xETH.Init.Speed = ETH_SPEED_100M;
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- /* Value of PhyAddress doesn't matter, will be probed for. */
- xETH.Init.PhyAddress = 0;
-
- xETH.Init.MACAddr = ( uint8_t * ) FreeRTOS_GetMACAddress();
- xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
-
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
- {
- /* using the ETH_CHECKSUM_BY_HARDWARE option:
- both the IP and the protocol checksums will be calculated
- by the peripheral. */
- xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
- }
- #else
- {
- xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_SOFTWARE;
- }
- #endif
-
- #if( ipconfigUSE_RMII != 0 )
- {
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_RMII;
- }
- #else
- {
- xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
- }
- #endif /* ipconfigUSE_RMII */
-
- hal_eth_init_status = HAL_ETH_Init( &xETH );
-
- /* Only for inspection by debugger. */
- ( void ) hal_eth_init_status;
-
- /* Set the TxDesc and RxDesc pointers. */
- xETH.TxDesc = DMATxDscrTab;
- xETH.RxDesc = DMARxDscrTab;
-
- /* Make sure that all unused fields are cleared. */
- memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
- memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
-
- /* Initialize Tx Descriptors list: Chain Mode */
- DMATxDescToClear = DMATxDscrTab;
-
- /* Initialise TX-descriptors. */
- prvDMATxDescListInit();
-
- /* Initialise RX-descriptors. */
- prvDMARxDescListInit();
-
- #if( ipconfigUSE_LLMNR != 0 )
- {
- /* Program the LLMNR address at index 1. */
- prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
- }
- #endif
-
- /* Force a negotiation with the Switch or Router and wait for LS. */
- prvEthernetUpdateConfig( pdTRUE );
-
- /* The deferred interrupt handler task is created at the highest
- possible priority to ensure the interrupt handler can return directly
- to it. The task's handle is stored in xEMACTaskHandle so interrupts can
- notify the task when there is something to process. */
- if( xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, niEMAC_HANDLER_TASK_PRIORITY, &xEMACTaskHandle ) == pdPASS )
- {
- /* The xTXDescriptorSemaphore and the task are created successfully. */
- xMacInitStatus = eMACPass;
- }
- else
- {
- xMacInitStatus = eMACFailed;
- }
- }
- } /* if( xEMACTaskHandle == NULL ) */
-
- if( xMacInitStatus != eMACPass )
- {
- /* EMAC initialisation failed, return pdFAIL. */
- xResult = pdFAIL;
- }
- else
- {
- if( xPhyObject.ulLinkStatusMask != 0uL )
- {
- xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
- xResult = pdPASS;
- FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
- }
- else
- {
- /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
- and it will keep on checking the PHY and set 'ulLinkStatusMask' when necessary. */
- xResult = pdFAIL;
- }
- }
- /* When returning non-zero, the stack will become active and
- start DHCP (in configured) */
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-static void prvDMATxDescListInit()
-{
-ETH_DMADescTypeDef *pxDMADescriptor;
-BaseType_t xIndex;
-
- /* Get the pointer on the first member of the descriptor list */
- pxDMADescriptor = DMATxDscrTab;
-
- /* Fill each DMA descriptor with the right values */
- for( xIndex = 0; xIndex < ETH_TXBUFNB; xIndex++, pxDMADescriptor++ )
- {
- /* Set Second Address Chained bit */
- pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- {
- /* Set Buffer1 address pointer */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( Tx_Buff[ xIndex ] );
- }
- #endif
-
- if( xETH.Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE )
- {
- /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
- pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
- }
- else
- {
- pxDMADescriptor->Status &= ~( ( uint32_t ) ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL );
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if( xIndex < ETH_TXBUFNB - 1 )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMADescriptor + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMATxDscrTab;
- }
- }
-
- /* Set Transmit Descriptor List Address Register */
- xETH.Instance->DMATDLAR = ( uint32_t ) DMATxDscrTab;
-}
-/*-----------------------------------------------------------*/
-
-static void prvDMARxDescListInit()
-{
-ETH_DMADescTypeDef *pxDMADescriptor;
-BaseType_t xIndex;
- /*
- * RX-descriptors.
- */
-
- /* Get the pointer on the first member of the descriptor list */
- pxDMADescriptor = DMARxDscrTab;
-
- /* Fill each DMA descriptor with the right values */
- for( xIndex = 0; xIndex < ETH_RXBUFNB; xIndex++, pxDMADescriptor++ )
- {
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
-
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Set Buffer1 address pointer */
- NetworkBufferDescriptor_t *pxBuffer;
-
- pxBuffer = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, 100ul );
- /* If the assert below fails, make sure that there are at least 'ETH_RXBUFNB'
- Network Buffers available during start-up ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) */
- configASSERT( pxBuffer != NULL );
- if( pxBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = (uint32_t)pxBuffer->pucEthernetBuffer;
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
- }
- }
- #else
- {
- /* Set Buffer1 address pointer */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( Rx_Buff[ xIndex ] );
- /* Set Own bit of the Rx descriptor Status */
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
- }
- #endif
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if( xIndex < ETH_RXBUFNB - 1 )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t )( pxDMADescriptor + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMARxDscrTab;
- }
-
- }
- /* Set Receive Descriptor List Address Register */
- xETH.Instance->DMARDLAR = ( uint32_t ) DMARxDscrTab;
-}
-/*-----------------------------------------------------------*/
-
-static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr)
-{
-uint32_t ulTempReg;
-
- ( void ) heth;
-
- /* Calculate the selected MAC address high register. */
- ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
-
- /* Load the selected MAC address high register. */
- ( *(__IO uint32_t *)( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + ulIndex ) ) ) = ulTempReg;
-
- /* Calculate the selected MAC address low register. */
- ulTempReg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ];
-
- /* Load the selected MAC address low register */
- ( *(__IO uint32_t *) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + ulIndex ) ) ) = ulTempReg;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
-{
-BaseType_t xReturn = pdFAIL;
-uint32_t ulTransmitSize = 0;
-__IO ETH_DMADescTypeDef *pxDmaTxDesc;
-/* Do not wait too long for a free TX DMA buffer. */
-const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
-
- /* Open a do {} while ( 0 ) loop to be able to call break. */
- do
- {
- if( xCheckLoopback( pxDescriptor, bReleaseAfterSend ) != 0 )
- {
- /* The packet has been sent back to the IP-task.
- The IP-task will further handle it.
- Do not release the descriptor. */
- bReleaseAfterSend = pdFALSE;
- break;
- }
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
- {
- ProtocolPacket_t *pxPacket;
-
- /* If the peripheral must calculate the checksum, it wants
- the protocol checksum to have a value of zero. */
- pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
-
- if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ( uint8_t ) ipPROTOCOL_ICMP )
- {
- pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
- }
- }
- #endif /* ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM */
- if( xPhyObject.ulLinkStatusMask != 0 )
- {
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- /* Time-out waiting for a free TX descriptor. */
- break;
- }
-
- /* This function does the actual transmission of the packet. The packet is
- contained in 'pxDescriptor' that is passed to the function. */
- pxDmaTxDesc = xETH.TxDesc;
-
- /* Is this buffer available? */
- configASSERT ( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 );
-
- {
- /* Is this buffer available? */
- /* Get bytes in current buffer. */
- ulTransmitSize = pxDescriptor->xDataLength;
-
- if( ulTransmitSize > ETH_TX_BUF_SIZE )
- {
- ulTransmitSize = ETH_TX_BUF_SIZE;
- }
-
- #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
- {
- /* Copy the bytes. */
- memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );
- }
- #else
- {
- configASSERT( bReleaseAfterSend != 0 );
-
- /* Move the buffer. */
- pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
- /* The Network Buffer has been passed to DMA, no need to release it. */
- bReleaseAfterSend = pdFALSE_UNSIGNED;
- }
- #endif /* ipconfigZERO_COPY_TX_DRIVER */
-
- /* Ask to set the IPv4 checksum.
- Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
- #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
- {
- pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
- }
- #else
- {
- pxDmaTxDesc->Status &= ~( ( uint32_t ) ETH_DMATXDESC_CIC );
- pxDmaTxDesc->Status |= ETH_DMATXDESC_IC;
- }
- #endif
-
-
- /* Prepare transmit descriptors to give to DMA. */
-
- /* Set LAST and FIRST segment */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
- /* Set frame size */
- pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
-
- #if( NETWORK_BUFFERS_CACHED != 0 )
- {
- BaseType_t xlength = CACHE_LINE_SIZE * ( ( ulTransmitSize + NETWORK_BUFFER_HEADER_SIZE + CACHE_LINE_SIZE - 1 ) / CACHE_LINE_SIZE );
- uint32_t *pulBuffer = ( uint32_t )( pxDescriptor->pucEthernetBuffer - NETWORK_BUFFER_HEADER_SIZE );
- cache_clean_invalidate_by_addr( pulBuffer, xlength );
- }
- #endif
-
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
-
- /* Point to next descriptor */
- xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );
- /* Ensure completion of memory access */
- __DSB();
- /* Resume DMA transmission*/
- xETH.Instance->DMATPDR = 0;
- iptraceNETWORK_INTERFACE_TRANSMIT();
- xReturn = pdPASS;
- }
- }
- else
- {
- /* The PHY has no Link Status, packet shall be dropped. */
- }
- } while( 0 );
- /* The buffer has been sent so can be released. */
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer )
-{
-const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
-
- switch( pxProtPacket->xTCPPacket.xEthernetHeader.usFrameType )
- {
- case ipARP_FRAME_TYPE:
- /* Check it later. */
- return pdTRUE;
- case ipIPv4_FRAME_TYPE:
- /* Check it here. */
- break;
- default:
- /* Refuse the packet. */
- return pdFALSE;
- }
-
- #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
- {
- const IPHeader_t *pxIPHeader = &(pxProtPacket->xTCPPacket.xIPHeader);
- uint32_t ulDestinationIPAddress;
-
- /* Ensure that the incoming packet is not fragmented (only outgoing packets
- * can be fragmented) as these are the only handled IP frames currently. */
- if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U )
- {
- return pdFALSE;
- }
- /* HT: Might want to make the following configurable because
- * most IP messages have a standard length of 20 bytes */
-
- /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
- * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
- if( pxIPHeader->ucVersionHeaderLength < 0x45 || pxIPHeader->ucVersionHeaderLength > 0x4F )
- {
- return pdFALSE;
- }
-
- ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
- /* Is the packet for this node? */
- if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
- /* Is it a broadcast address x.x.x.255 ? */
- ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xff ) != 0xff ) &&
- #if( ipconfigUSE_LLMNR == 1 )
- ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
- #endif
- ( *ipLOCAL_IP_ADDRESS_POINTER != 0 ) ) {
- FreeRTOS_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) );
- return pdFALSE;
- }
-
- if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
- {
- uint16_t usSourcePort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort );
- uint16_t usDestinationPort = FreeRTOS_ntohs( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort );
-
- if( ( xPortHasUDPSocket( pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort ) == pdFALSE )
- #if ipconfigUSE_LLMNR == 1
- && ( usDestinationPort != ipLLMNR_PORT )
- && ( usSourcePort != ipLLMNR_PORT )
- #endif
- #if ipconfigUSE_NBNS == 1
- && ( usDestinationPort != ipNBNS_PORT )
- && ( usSourcePort != ipNBNS_PORT )
- #endif
- #if ipconfigUSE_DNS == 1
- && ( usSourcePort != ipDNS_PORT )
- #endif
- ) {
- /* Drop this packet, not for this device. */
- /* FreeRTOS_printf( ( "Drop: UDP port %d -> %d\n", usSourcePort, usDestinationPort ) ); */
- return pdFALSE;
- }
- }
- }
- #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static void prvPassEthMessages( NetworkBufferDescriptor_t *pxDescriptor )
-{
-IPStackEvent_t xRxEvent;
-
- xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) pxDescriptor;
-
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
- {
- /* The buffer could not be sent to the stack so must be released again.
- This is a deferred handler taskr, not a real interrupt, so it is ok to
- use the task level function here. */
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- do
- {
- NetworkBufferDescriptor_t *pxNext = pxDescriptor->pxNextBuffer;
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- pxDescriptor = pxNext;
- } while( pxDescriptor != NULL );
- }
- #else
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "prvPassEthMessages: Can not queue return packet!\n" ) );
- }
- else
- {
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-}
-
-static BaseType_t prvNetworkInterfaceInput( void )
-{
-NetworkBufferDescriptor_t *pxCurDescriptor;
-NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
-#if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- NetworkBufferDescriptor_t *pxFirstDescriptor = NULL;
- NetworkBufferDescriptor_t *pxLastDescriptor = NULL;
-#endif
-BaseType_t xReceivedLength = 0;
-__IO ETH_DMADescTypeDef *pxDMARxDescriptor;
-const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( niDESCRIPTOR_WAIT_TIME_MS );
-uint8_t *pucBuffer;
-
- pxDMARxDescriptor = xETH.RxDesc;
-
- while( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0u )
- {
- BaseType_t xAccepted = pdTRUE;
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
-
- pucBuffer = (uint8_t *) pxDMARxDescriptor->Buffer1Addr;
-
- /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
- /* Chained Mode */
- /* Selects the next DMA Rx descriptor list for next buffer to read */
- xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
-
- /* In order to make the code easier and faster, only packets in a single buffer
- will be accepted. This can be done by making the buffers large enough to
- hold a complete Ethernet packet (1536 bytes).
- Therefore, two sanity checks: */
- configASSERT( xReceivedLength <= ETH_RX_BUF_SIZE );
-
- if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
- {
- /* Not an Ethernet frame-type or a checmsum error. */
- xAccepted = pdFALSE;
- }
- else
- {
- /* See if this packet must be handled. */
- xAccepted = xMayAcceptPacket( pucBuffer );
- }
-
- if( xAccepted != pdFALSE )
- {
- /* The packet wil be accepted, but check first if a new Network Buffer can
- be obtained. If not, the packet will still be dropped. */
- pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, xDescriptorWaitTime );
-
- if( pxNewDescriptor == NULL )
- {
- /* A new descriptor can not be allocated now. This packet will be dropped. */
- xAccepted = pdFALSE;
- }
- }
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Find out which Network Buffer was originally passed to the descriptor. */
- pxCurDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
- configASSERT( pxCurDescriptor != NULL );
- }
- #else
- {
- /* In this mode, the two descriptors are the same. */
- pxCurDescriptor = pxNewDescriptor;
- if( pxNewDescriptor != NULL )
- {
- /* The packet is acepted and a new Network Buffer was created,
- copy data to the Network Bufffer. */
- memcpy( pxNewDescriptor->pucEthernetBuffer, pucBuffer, xReceivedLength );
- }
- }
- #endif
-
- if( xAccepted != pdFALSE )
- {
- pxCurDescriptor->xDataLength = xReceivedLength;
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- pxCurDescriptor->pxNextBuffer = NULL;
-
- if( pxFirstDescriptor == NULL )
- {
- // Becomes the first message
- pxFirstDescriptor = pxCurDescriptor;
- }
- else if( pxLastDescriptor != NULL )
- {
- // Add to the tail
- pxLastDescriptor->pxNextBuffer = pxCurDescriptor;
- }
-
- pxLastDescriptor = pxCurDescriptor;
- }
- #else
- {
- prvPassEthMessages( pxCurDescriptor );
- }
- #endif
- }
-
- /* Release descriptors to DMA */
- #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
- {
- /* Set Buffer1 address pointer */
- if( pxNewDescriptor != NULL )
- {
- pxDMARxDescriptor->Buffer1Addr = (uint32_t)pxNewDescriptor->pucEthernetBuffer;
- }
- else
- {
- /* The packet was dropped and the same Network
- Buffer will be used to receive a new packet. */
- }
- }
- #endif /* ipconfigZERO_COPY_RX_DRIVER */
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
- pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;
-
- /* Ensure completion of memory access */
- __DSB();
- /* When Rx Buffer unavailable flag is set clear it and resume
- reception. */
- if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )
- {
- /* Clear RBUS ETHERNET DMA flag. */
- xETH.Instance->DMASR = ETH_DMASR_RBUS;
-
- /* Resume DMA reception. */
- xETH.Instance->DMARPDR = 0;
- }
- pxDMARxDescriptor = xETH.RxDesc;
- }
-
- #if( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- if( pxFirstDescriptor != NULL )
- {
- prvPassEthMessages( pxFirstDescriptor );
- }
- }
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
-
- return ( xReceivedLength > 0 );
-}
-/*-----------------------------------------------------------*/
-
-
-BaseType_t xSTM32_PhyRead( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue )
-{
-uint16_t usPrevAddress = xETH.Init.PhyAddress;
-BaseType_t xResult;
-HAL_StatusTypeDef xHALResult;
-
- xETH.Init.PhyAddress = xAddress;
- xHALResult = HAL_ETH_ReadPHYRegister( &xETH, ( uint16_t )xRegister, pulValue );
- xETH.Init.PhyAddress = usPrevAddress;
-
- if( xHALResult == HAL_OK )
- {
- xResult = 0;
- }
- else
- {
- xResult = -1;
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xSTM32_PhyWrite( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue )
-{
-uint16_t usPrevAddress = xETH.Init.PhyAddress;
-BaseType_t xResult;
-HAL_StatusTypeDef xHALResult;
-
- xETH.Init.PhyAddress = xAddress;
- xHALResult = HAL_ETH_WritePHYRegister( &xETH, ( uint16_t )xRegister, ulValue );
- xETH.Init.PhyAddress = usPrevAddress;
-
- if( xHALResult == HAL_OK )
- {
- xResult = 0;
- }
- else
- {
- xResult = -1;
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-void vMACBProbePhy( void )
-{
- vPhyInitialise( &xPhyObject, xSTM32_PhyRead, xSTM32_PhyWrite );
- xPhyDiscover( &xPhyObject );
- xPhyConfigure( &xPhyObject, &xPHYProperties );
-}
-/*-----------------------------------------------------------*/
-
-static void prvEthernetUpdateConfig( BaseType_t xForce )
-{
- FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS mask %02lX Force %d\n",
- xPhyObject.ulLinkStatusMask,
- ( int )xForce ) );
-
- if( ( xForce != pdFALSE ) || ( xPhyObject.ulLinkStatusMask != 0 ) )
- {
- /* Restart the auto-negotiation. */
- if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )
- {
- xPhyStartAutoNegotiation( &xPhyObject, xPhyGetMask( &xPhyObject ) );
-
- /* Configure the MAC with the Duplex Mode fixed by the
- auto-negotiation process. */
- if( xPhyObject.xPhyProperties.ucDuplex == PHY_DUPLEX_FULL )
- {
- xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
- }
- else
- {
- xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
- }
-
- /* Configure the MAC with the speed fixed by the
- auto-negotiation process. */
- if( xPhyObject.xPhyProperties.ucSpeed == PHY_SPEED_10 )
- {
- xETH.Init.Speed = ETH_SPEED_10M;
- }
- else
- {
- xETH.Init.Speed = ETH_SPEED_100M;
- }
- }
- else /* AutoNegotiation Disable */
- {
- /* Check parameters */
- assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );
- assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );
-
- if( xETH.Init.DuplexMode == ETH_MODE_FULLDUPLEX )
- {
- xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_HALF;
- }
- else
- {
- xPhyObject.xPhyPreferences.ucDuplex = PHY_DUPLEX_FULL;
- }
-
- if( xETH.Init.Speed == ETH_SPEED_10M )
- {
- xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_10;
- }
- else
- {
- xPhyObject.xPhyPreferences.ucSpeed = PHY_SPEED_100;
- }
-
- xPhyObject.xPhyPreferences.ucMDI_X = PHY_MDIX_AUTO;
-
- /* Use predefined (fixed) configuration. */
- xPhyFixedValue( &xPhyObject, xPhyGetMask( &xPhyObject ) );
- }
-
- /* ETHERNET MAC Re-Configuration */
- HAL_ETH_ConfigMAC( &xETH, (ETH_MACInitTypeDef *) NULL);
-
- /* Restart MAC interface */
- HAL_ETH_Start( &xETH);
- }
- else
- {
- /* Stop MAC interface */
- HAL_ETH_Stop( &xETH );
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xReturn;
-
- if( xPhyObject.ulLinkStatusMask != 0 )
- {
- xReturn = pdPASS;
- }
- else
- {
- xReturn = pdFAIL;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-/* Uncomment this in case BufferAllocation_1.c is used. */
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-static __attribute__ ((section(".first_data"))) uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * ETH_MAX_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
-uint8_t *ucRAMBuffer = ucNetworkPackets;
-uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += ETH_MAX_PACKET_SIZE;
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-UBaseType_t uxLastMinBufferCount = 0;
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
-UBaseType_t uxLastMinQueueSpace = 0;
-#endif
-UBaseType_t uxCurrentCount;
-BaseType_t xResult;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- xResult = 0;
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- if( xTXDescriptorSemaphore != NULL )
- {
- static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
-
- uxCurrentCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );
- if( uxLowestSemCount > uxCurrentCount )
- {
- uxLowestSemCount = uxCurrentCount;
- FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
- }
-
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- xResult = prvNetworkInterfaceInput();
- }
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- /* Check if DMA packets have been delivered. */
- vClearTXBuffers();
- }
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
- {
- /* Future extension: logging about errors that occurred. */
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
- }
- if( xPhyCheckLinkStatus( &xPhyObject, xResult ) != 0 )
- {
- /* Something has changed to a Link Status, need re-check. */
- prvEthernetUpdateConfig( pdFALSE );
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-void ETH_IRQHandler( void )
-{
- HAL_ETH_IRQHandler( &xETH );
-}
-
+/*
+ * Some constants, hardware definitions and comments taken from ST's HAL driver
+ * library, COPYRIGHT(c) 2015 STMicroelectronics.
+ */
+
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_DNS.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* ST includes. */
+#include "stm32f4xx_hal.h"
+
+#ifndef BMSR_LINK_STATUS
+ #define BMSR_LINK_STATUS 0x0004UL
+#endif
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* Interrupt events to process. Currently only the Rx event is processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+#define ETH_DMA_ALL_INTS \
+ ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_ER | \
+ ETH_DMA_IT_FBE | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
+ ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
+
+/* Naming and numbering of PHY registers. */
+#define PHY_REG_00_BMCR 0x00 /* Basic Mode Control Register */
+#define PHY_REG_01_BMSR 0x01 /* Basic Mode Status Register */
+#define PHY_REG_02_PHYSID1 0x02 /* PHYS ID 1 */
+#define PHY_REG_03_PHYSID2 0x03 /* PHYS ID 2 */
+#define PHY_REG_04_ADVERTISE 0x04 /* Advertisement control reg */
+
+#define PHY_ID_LAN8720 0x0007c0f0
+#define PHY_ID_DP83848I 0x20005C90
+
+#ifndef USE_STM324xG_EVAL
+ #define USE_STM324xG_EVAL 1
+#endif
+
+#if( USE_STM324xG_EVAL == 0 )
+ #define EXPECTED_PHY_ID PHY_ID_LAN8720
+ #define PHY_REG_1F_PHYSPCS 0x1F /* 31 RW PHY Special Control Status */
+ /* Use 3 bits in register 31 */
+ #define PHYSPCS_SPEED_MASK 0x0C
+ #define PHYSPCS_SPEED_10 0x04
+ #define PHYSPCS_SPEED_100 0x08
+ #define PHYSPCS_FULL_DUPLEX 0x10
+#else
+ #define EXPECTED_PHY_ID PHY_ID_DP83848I
+
+ #define PHY_REG_10_PHY_SR 0x10 /* PHY status register Offset */
+ #define PHY_REG_19_PHYCR 0x19 /* 25 RW PHY Control Register */
+#endif
+
+/* Some defines used internally here to indicate preferences about speed, MDIX
+(wired direct or crossed), and duplex (half or full). */
+#define PHY_SPEED_10 1
+#define PHY_SPEED_100 2
+#define PHY_SPEED_AUTO (PHY_SPEED_10|PHY_SPEED_100)
+
+#define PHY_MDIX_DIRECT 1
+#define PHY_MDIX_CROSSED 2
+#define PHY_MDIX_AUTO (PHY_MDIX_CROSSED|PHY_MDIX_DIRECT)
+
+#define PHY_DUPLEX_HALF 1
+#define PHY_DUPLEX_FULL 2
+#define PHY_DUPLEX_AUTO (PHY_DUPLEX_FULL|PHY_DUPLEX_HALF)
+
+#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020) /*!< Auto-Negotiation process completed */
+
+/*
+ * Description of all capabilities that can be advertised to
+ * the peer (usually a switch or router).
+ */
+#define ADVERTISE_CSMA 0x0001 /* Only selector supported. */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex. */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex. */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex. */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex. */
+
+#define ADVERTISE_ALL ( ADVERTISE_10HALF | ADVERTISE_10FULL | \
+ ADVERTISE_100HALF | ADVERTISE_100FULL)
+
+/*
+ * Value for the 'PHY_REG_00_BMCR', the PHY's Basic Mode Control Register
+ */
+#define BMCR_FULLDPLX 0x0100 /* Full duplex. */
+#define BMCR_ANRESTART 0x0200 /* Auto negotiation restart. */
+#define BMCR_ANENABLE 0x1000 /* Enable auto negotiation. */
+#define BMCR_SPEED100 0x2000 /* Select 100Mbps. */
+#define BMCR_RESET 0x8000 /* Reset the PHY. */
+
+#define PHYCR_MDIX_EN 0x8000 /* Enable Auto MDIX. */
+#define PHYCR_MDIX_FORCE 0x4000 /* Force MDIX crossed. */
+
+#define ipFRAGMENT_OFFSET_BIT_MASK ( ( uint16_t ) 0x0fff ) /* The bits in the two byte IP header field that make up the fragment offset value. */
+
+/*
+ * Most users will want a PHY that negotiates about
+ * the connection properties: speed, dmix and duplex.
+ * On some rare cases, you want to select what is being
+ * advertised, properties like MDIX and duplex.
+ */
+
+#if !defined( ipconfigETHERNET_AN_ENABLE )
+ /* Enable auto-negotiation */
+ #define ipconfigETHERNET_AN_ENABLE 1
+#endif
+
+#if !defined( ipconfigETHERNET_AUTO_CROSS_ENABLE )
+ #define ipconfigETHERNET_AUTO_CROSS_ENABLE 1
+#endif
+
+#if( ipconfigETHERNET_AN_ENABLE == 0 )
+ /*
+ * The following three defines are only used in case there
+ * is no auto-negotiation.
+ */
+ #if !defined( ipconfigETHERNET_CROSSED_LINK )
+ #define ipconfigETHERNET_CROSSED_LINK 1
+ #endif
+
+ #if !defined( ipconfigETHERNET_USE_100MB )
+ #define ipconfigETHERNET_USE_100MB 1
+ #endif
+
+ #if !defined( ipconfigETHERNET_USE_FULL_DUPLEX )
+ #define ipconfigETHERNET_USE_FULL_DUPLEX 1
+ #endif
+#endif /* ipconfigETHERNET_AN_ENABLE == 0 */
+
+/* Default the size of the stack used by the EMAC deferred handler task to twice
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * A deferred interrupt handler task that processes
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Force a negotiation with the Switch or Router and wait for LS.
+ */
+static void prvEthernetUpdateConfig( BaseType_t xForce );
+
+/*
+ * See if there is a new packet and forward it to the IP-task.
+ */
+static BaseType_t prvNetworkInterfaceInput( void );
+
+#if( ipconfigUSE_LLMNR != 0 )
+ /*
+ * For LLMNR, an extra MAC-address must be configured to
+ * be able to receive the multicast messages.
+ */
+ static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr);
+#endif
+
+/*
+ * Check if a given packet should be accepted.
+ */
+static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer );
+
+/*
+ * Initialise the TX descriptors.
+ */
+static void prvDMATxDescListInit( void );
+
+/*
+ * Initialise the RX descriptors.
+ */
+static void prvDMARxDescListInit( void );
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ /* After packets have been sent, the network
+ buffers will be released. */
+ static void vClearTXBuffers( void );
+#endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+/*-----------------------------------------------------------*/
+
+typedef struct _PhyProperties_t
+{
+ uint8_t speed;
+ uint8_t mdix;
+ uint8_t duplex;
+ uint8_t spare;
+} PhyProperties_t;
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx interrupt is handled, although code is included for other events to
+enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
+#endif
+
+/* Ethernet handle. */
+static ETH_HandleTypeDef xETH;
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ /* xTXDescriptorSemaphore is a counting semaphore with
+ a maximum count of ETH_TXBUFNB, which is the number of
+ DMA TX descriptors. */
+ static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+#endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+/*
+ * Note: it is adviced to define both
+ *
+ * #define ipconfigZERO_COPY_RX_DRIVER 1
+ * #define ipconfigZERO_COPY_TX_DRIVER 1
+ *
+ * The method using memcpy is slower and probaly uses more RAM memory.
+ * The possibility is left in the code just for comparison.
+ *
+ * It is adviced to define ETH_TXBUFNB at least 4. Note that no
+ * TX buffers are allocated in a zero-copy driver.
+ */
+/* MAC buffers: ---------------------------------------------------------*/
+__ALIGN_BEGIN ETH_DMADescTypeDef DMARxDscrTab[ ETH_RXBUFNB ] __ALIGN_END;/* Ethernet Rx MA Descriptor */
+#if( ipconfigZERO_COPY_RX_DRIVER == 0 )
+ __ALIGN_BEGIN uint8_t Rx_Buff[ ETH_RXBUFNB ][ ETH_RX_BUF_SIZE ] __ALIGN_END; /* Ethernet Receive Buffer */
+#endif
+
+__ALIGN_BEGIN ETH_DMADescTypeDef DMATxDscrTab[ ETH_TXBUFNB ] __ALIGN_END;/* Ethernet Tx DMA Descriptor */
+#if( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ __ALIGN_BEGIN uint8_t Tx_Buff[ ETH_TXBUFNB ][ ETH_TX_BUF_SIZE ] __ALIGN_END; /* Ethernet Transmit Buffer */
+#endif
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ /* DMATxDescToClear points to the next TX DMA descriptor
+ that must be cleared by vClearTXBuffers(). */
+ static __IO ETH_DMADescTypeDef *DMATxDescToClear;
+#endif
+
+/* Value to be written into the 'Basic mode Control Register'. */
+static uint32_t ulBCRvalue;
+
+/* Value to be written into the 'Advertisement Control Register'. */
+static uint32_t ulACRValue;
+
+/* ucMACAddress as it appears in main.c */
+extern const uint8_t ucMACAddress[ 6 ];
+
+/* Holds the handle of the task used as a deferred interrupt processor. The
+handle is used so direct notifications can be sent to the task for all EMAC/DMA
+related interrupts. */
+static TaskHandle_t xEMACTaskHandle = NULL;
+
+/* For local use only: describe the PHY's properties: */
+const PhyProperties_t xPHYProperties =
+{
+ #if( ipconfigETHERNET_AN_ENABLE != 0 )
+ .speed = PHY_SPEED_AUTO,
+ .duplex = PHY_DUPLEX_AUTO,
+ #else
+ #if( ipconfigETHERNET_USE_100MB != 0 )
+ .speed = PHY_SPEED_100,
+ #else
+ .speed = PHY_SPEED_10,
+ #endif
+
+ #if( ipconfigETHERNET_USE_FULL_DUPLEX != 0 )
+ .duplex = PHY_DUPLEX_FULL,
+ #else
+ .duplex = PHY_DUPLEX_HALF,
+ #endif
+ #endif
+
+ #if( ipconfigETHERNET_AN_ENABLE != 0 ) && ( ipconfigETHERNET_AUTO_CROSS_ENABLE != 0 )
+ .mdix = PHY_MDIX_AUTO,
+ #elif( ipconfigETHERNET_CROSSED_LINK != 0 )
+ .mdix = PHY_MDIX_CROSSED,
+ #else
+ .mdix = PHY_MDIX_DIRECT,
+ #endif
+};
+
+/*-----------------------------------------------------------*/
+
+void HAL_ETH_RxCpltCallback( ETH_HandleTypeDef *heth )
+{
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ /* Ethernet RX-Complete callback function, elsewhere declared as weak. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ /* Wakeup the prvEMACHandlerTask. */
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ }
+}
+/*-----------------------------------------------------------*/
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ void HAL_ETH_TxCpltCallback( ETH_HandleTypeDef *heth )
+ {
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ /* This call-back is only useful in case packets are being sent
+ zero-copy. Once they're sent, the buffers will be released
+ by the function vClearTXBuffers(). */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ /* Wakeup the prvEMACHandlerTask. */
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+ }
+
+ }
+#endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+/*-----------------------------------------------------------*/
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ static void vClearTXBuffers()
+ {
+ __IO ETH_DMADescTypeDef *txLastDescriptor = xETH.TxDesc;
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ uint8_t *ucPayLoad;
+ size_t uxCount = ( ( UBaseType_t ) ETH_TXBUFNB ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+
+ /* This function is called after a TX-completion interrupt.
+ It will release each Network Buffer used in xNetworkInterfaceOutput().
+ 'uxCount' represents the number of descriptors given to DMA for transmission.
+ After sending a packet, the DMA will clear the 'ETH_DMATXDESC_OWN' bit. */
+ while( ( uxCount > 0 ) && ( ( DMATxDescToClear->Status & ETH_DMATXDESC_OWN ) == 0 ) )
+ {
+ if( ( DMATxDescToClear == txLastDescriptor ) && ( uxCount != ETH_TXBUFNB ) )
+ {
+ break;
+ }
+
+ ucPayLoad = ( uint8_t * )DMATxDescToClear->Buffer1Addr;
+
+ if( ucPayLoad != NULL )
+ {
+ pxNetworkBuffer = pxPacketBuffer_to_NetworkBuffer( ucPayLoad );
+ if( pxNetworkBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer ) ;
+ }
+ DMATxDescToClear->Buffer1Addr = ( uint32_t )0u;
+ }
+
+ DMATxDescToClear = ( ETH_DMADescTypeDef * )( DMATxDescToClear->Buffer2NextDescAddr );
+
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ }
+ }
+#endif /* ipconfigZERO_COPY_TX_DRIVER */
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+HAL_StatusTypeDef hal_eth_init_status;
+BaseType_t xResult;
+
+ if( xEMACTaskHandle == NULL )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ETH_TXBUFNB, ( UBaseType_t ) ETH_TXBUFNB );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ /* Initialise ETH */
+
+ xETH.Instance = ETH;
+ xETH.Init.AutoNegotiation = ETH_AUTONEGOTIATION_ENABLE;
+ xETH.Init.Speed = ETH_SPEED_100M;
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
+ xETH.Init.PhyAddress = 1;
+
+ xETH.Init.MACAddr = ( uint8_t *) ucMACAddress;
+ xETH.Init.RxMode = ETH_RXINTERRUPT_MODE;
+
+ /* using the ETH_CHECKSUM_BY_HARDWARE option:
+ both the IP and the protocol checksums will be calculated
+ by the peripheral. */
+ xETH.Init.ChecksumMode = ETH_CHECKSUM_BY_HARDWARE;
+
+ xETH.Init.MediaInterface = ETH_MEDIA_INTERFACE_MII;
+ hal_eth_init_status = HAL_ETH_Init( &xETH );
+
+ /* Only for inspection by debugger. */
+ ( void ) hal_eth_init_status;
+
+ /* Set the TxDesc and RxDesc pointers. */
+ xETH.TxDesc = DMATxDscrTab;
+ xETH.RxDesc = DMARxDscrTab;
+
+ /* Make sure that all unused fields are cleared. */
+ memset( &DMATxDscrTab, '\0', sizeof( DMATxDscrTab ) );
+ memset( &DMARxDscrTab, '\0', sizeof( DMARxDscrTab ) );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Initialize Tx Descriptors list: Chain Mode */
+ DMATxDescToClear = DMATxDscrTab;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ /* Initialise TX-descriptors. */
+ prvDMATxDescListInit();
+
+ /* Initialise RX-descriptors. */
+ prvDMARxDescListInit();
+
+ #if( ipconfigUSE_LLMNR != 0 )
+ {
+ /* Program the LLMNR address at index 1. */
+ prvMACAddressConfig( &xETH, ETH_MAC_ADDRESS1, ( uint8_t *) xLLMNR_MACAddress );
+ }
+ #endif
+
+ /* Force a negotiation with the Switch or Router and wait for LS. */
+ prvEthernetUpdateConfig( pdTRUE );
+
+ /* The deferred interrupt handler task is created at the highest
+ possible priority to ensure the interrupt handler can return directly
+ to it. The task's handle is stored in xEMACTaskHandle so interrupts can
+ notify the task when there is something to process. */
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ } /* if( xEMACTaskHandle == NULL ) */
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xETH.Instance->DMAIER |= ETH_DMA_ALL_INTS;
+ xResult = pdPASS;
+ FreeRTOS_printf( ( "Link Status is high\n" ) ) ;
+ }
+ else
+ {
+ /* For now pdFAIL will be returned. But prvEMACHandlerTask() is running
+ and it will keep on checking the PHY and set ulPHYLinkStatus when necessary. */
+ xResult = pdFAIL;
+ FreeRTOS_printf( ( "Link Status still low\n" ) ) ;
+ }
+ /* When returning non-zero, the stack will become active and
+ start DHCP (in configured) */
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+static void prvDMATxDescListInit()
+{
+ETH_DMADescTypeDef *pxDMADescriptor;
+BaseType_t xIndex;
+
+ /* Get the pointer on the first member of the descriptor list */
+ pxDMADescriptor = DMATxDscrTab;
+
+ /* Fill each DMA descriptor with the right values */
+ for( xIndex = 0; xIndex < ETH_TXBUFNB; xIndex++, pxDMADescriptor++ )
+ {
+ /* Set Second Address Chained bit */
+ pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
+
+ #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ {
+ /* Set Buffer1 address pointer */
+ pxDMADescriptor->Buffer1Addr = ( uint32_t )( Tx_Buff[ xIndex ] );
+ }
+ #endif
+
+ if( xETH.Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE )
+ {
+ /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
+ pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
+ }
+
+ /* Initialize the next descriptor with the Next Descriptor Polling Enable */
+ if( xIndex < ETH_TXBUFNB - 1 )
+ {
+ /* Set next descriptor address register with next descriptor base address */
+ pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMADescriptor + 1 );
+ }
+ else
+ {
+ /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
+ pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMATxDscrTab;
+ }
+ }
+
+ /* Set Transmit Descriptor List Address Register */
+ xETH.Instance->DMATDLAR = ( uint32_t ) DMATxDscrTab;
+}
+/*-----------------------------------------------------------*/
+
+static void prvDMARxDescListInit()
+{
+ETH_DMADescTypeDef *pxDMADescriptor;
+BaseType_t xIndex;
+ /*
+ * RX-descriptors.
+ */
+
+ /* Get the pointer on the first member of the descriptor list */
+ pxDMADescriptor = DMARxDscrTab;
+
+ /* Fill each DMA descriptor with the right values */
+ for( xIndex = 0; xIndex < ETH_RXBUFNB; xIndex++, pxDMADescriptor++ )
+ {
+
+ /* Set Buffer1 size and Second Address Chained bit */
+ pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
+
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ /* Set Buffer1 address pointer */
+ NetworkBufferDescriptor_t *pxBuffer;
+
+ pxBuffer = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, 100ul );
+ /* If the assert below fails, make sure that there are at least 'ETH_RXBUFNB'
+ Network Buffers available during start-up ( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ) */
+ configASSERT( pxBuffer != NULL );
+ if( pxBuffer != NULL )
+ {
+ pxDMADescriptor->Buffer1Addr = (uint32_t)pxBuffer->pucEthernetBuffer;
+ pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
+ }
+ }
+ #else
+ {
+ /* Set Buffer1 address pointer */
+ pxDMADescriptor->Buffer1Addr = ( uint32_t )( Rx_Buff[ xIndex ] );
+ /* Set Own bit of the Rx descriptor Status */
+ pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
+ }
+ #endif
+
+ /* Initialize the next descriptor with the Next Descriptor Polling Enable */
+ if( xIndex < ETH_RXBUFNB - 1 )
+ {
+ /* Set next descriptor address register with next descriptor base address */
+ pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t )( pxDMADescriptor + 1 );
+ }
+ else
+ {
+ /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
+ pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) DMARxDscrTab;
+ }
+
+ }
+ /* Set Receive Descriptor List Address Register */
+ xETH.Instance->DMARDLAR = ( uint32_t ) DMARxDscrTab;
+}
+/*-----------------------------------------------------------*/
+
+static void prvMACAddressConfig(ETH_HandleTypeDef *heth, uint32_t ulIndex, uint8_t *Addr)
+{
+uint32_t ulTempReg;
+
+ /* Calculate the selected MAC address high register. */
+ ulTempReg = 0x80000000ul | ( ( uint32_t ) Addr[ 5 ] << 8 ) | ( uint32_t ) Addr[ 4 ];
+
+ /* Load the selected MAC address high register. */
+ ( *(__IO uint32_t *)( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + ulIndex ) ) ) = ulTempReg;
+
+ /* Calculate the selected MAC address low register. */
+ ulTempReg = ( ( uint32_t ) Addr[ 3 ] << 24 ) | ( ( uint32_t ) Addr[ 2 ] << 16 ) | ( ( uint32_t ) Addr[ 1 ] << 8 ) | Addr[ 0 ];
+
+ /* Load the selected MAC address low register */
+ ( *(__IO uint32_t *) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + ulIndex ) ) ) = ulTempReg;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor, BaseType_t bReleaseAfterSend )
+{
+BaseType_t xReturn = pdFAIL;
+uint32_t ulTransmitSize = 0;
+__IO ETH_DMADescTypeDef *pxDmaTxDesc;
+/* Do not wait too long for a free TX DMA buffer. */
+const TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 50u );
+
+ #if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ {
+ ProtocolPacket_t *pxPacket;
+
+ /* If the peripheral must calculate the checksum, it wants
+ the protocol checksum to have a value of zero. */
+ pxPacket = ( ProtocolPacket_t * ) ( pxDescriptor->pucEthernetBuffer );
+
+ if( pxPacket->xICMPPacket.xIPHeader.ucProtocol == ipPROTOCOL_ICMP )
+ {
+ pxPacket->xICMPPacket.xICMPHeader.usChecksum = ( uint16_t )0u;
+ }
+ }
+ #endif
+
+ /* Open a do {} while ( 0 ) loop to be able to call break. */
+ do
+ {
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ break;
+ }
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ /* Time-out waiting for a free TX descriptor. */
+ break;
+ }
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ /* This function does the actual transmission of the packet. The packet is
+ contained in 'pxDescriptor' that is passed to the function. */
+ pxDmaTxDesc = xETH.TxDesc;
+
+ /* Is this buffer available? */
+ if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) == 0 )
+ {
+ /* Is this buffer available? */
+ /* Get bytes in current buffer. */
+ ulTransmitSize = pxDescriptor->xDataLength;
+
+ if( ulTransmitSize > ETH_TX_BUF_SIZE )
+ {
+ ulTransmitSize = ETH_TX_BUF_SIZE;
+ }
+
+ #if( ipconfigZERO_COPY_TX_DRIVER == 0 )
+ {
+ /* Copy the bytes. */
+ memcpy( ( void * ) pxDmaTxDesc->Buffer1Addr, pxDescriptor->pucEthernetBuffer, ulTransmitSize );
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL;
+ }
+ #else
+ {
+ /* Move the buffer. */
+ pxDmaTxDesc->Buffer1Addr = ( uint32_t )pxDescriptor->pucEthernetBuffer;
+ /* Ask to set the IPv4 checksum.
+ Also need an Interrupt on Completion so that 'vClearTXBuffers()' will be called.. */
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_CIC_TCPUDPICMP_FULL | ETH_DMATXDESC_IC;
+ /* The Network Buffer has been passed to DMA, no need to release it. */
+ bReleaseAfterSend = pdFALSE_UNSIGNED;
+ }
+ #endif /* ipconfigZERO_COPY_TX_DRIVER */
+
+ /* Prepare transmit descriptors to give to DMA. */
+
+ /* Set LAST and FIRST segment */
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
+ /* Set frame size */
+ pxDmaTxDesc->ControlBufferSize = ( ulTransmitSize & ETH_DMATXDESC_TBS1 );
+ /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
+ pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
+
+ /* Point to next descriptor */
+ xETH.TxDesc = ( ETH_DMADescTypeDef * ) ( xETH.TxDesc->Buffer2NextDescAddr );
+
+ /* Resume DMA transmission*/
+ xETH.Instance->DMATPDR = 0;
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ xReturn = pdPASS;
+ }
+ }
+ else
+ {
+ /* The PHY has no Link Status, packet shall be dropped. */
+ }
+ } while( 0 );
+ /* The buffer has been sent so can be released. */
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t xMayAcceptPacket( uint8_t *pcBuffer )
+{
+const ProtocolPacket_t *pxProtPacket = ( const ProtocolPacket_t * )pcBuffer;
+
+ switch( pxProtPacket->xTCPPacket.xEthernetHeader.usFrameType )
+ {
+ case ipARP_FRAME_TYPE:
+ /* Check it later. */
+ return pdTRUE;
+ case ipIPv4_FRAME_TYPE:
+ /* Check it here. */
+ break;
+ default:
+ /* Refuse the packet. */
+ return pdFALSE;
+ }
+
+ #if( ipconfigETHERNET_DRIVER_FILTERS_PACKETS == 1 )
+ {
+ const IPHeader_t *pxIPHeader = &(pxProtPacket->xTCPPacket.xIPHeader);
+ uint32_t ulDestinationIPAddress;
+
+ /* Ensure that the incoming packet is not fragmented (only outgoing packets
+ * can be fragmented) as these are the only handled IP frames currently. */
+ if( ( pxIPHeader->usFragmentOffset & FreeRTOS_ntohs( ipFRAGMENT_OFFSET_BIT_MASK ) ) != 0U )
+ {
+ return pdFALSE;
+ }
+ /* HT: Might want to make the following configurable because
+ * most IP messages have a standard length of 20 bytes */
+
+ /* 0x45 means: IPv4 with an IP header of 5 x 4 = 20 bytes
+ * 0x47 means: IPv4 with an IP header of 7 x 4 = 28 bytes */
+ if( pxIPHeader->ucVersionHeaderLength < 0x45 || pxIPHeader->ucVersionHeaderLength > 0x4F )
+ {
+ return pdFALSE;
+ }
+
+ ulDestinationIPAddress = pxIPHeader->ulDestinationIPAddress;
+ /* Is the packet for this node? */
+ if( ( ulDestinationIPAddress != *ipLOCAL_IP_ADDRESS_POINTER ) &&
+ /* Is it a broadcast address x.x.x.255 ? */
+ ( ( FreeRTOS_ntohl( ulDestinationIPAddress ) & 0xff ) != 0xff ) &&
+ #if( ipconfigUSE_LLMNR == 1 )
+ ( ulDestinationIPAddress != ipLLMNR_IP_ADDR ) &&
+ #endif
+ ( *ipLOCAL_IP_ADDRESS_POINTER != 0 ) ) {
+ FreeRTOS_printf( ( "Drop IP %lxip\n", FreeRTOS_ntohl( ulDestinationIPAddress ) ) );
+ return pdFALSE;
+ }
+
+ if( pxIPHeader->ucProtocol == ipPROTOCOL_UDP )
+ {
+ uint16_t port = pxProtPacket->xUDPPacket.xUDPHeader.usDestinationPort;
+
+ if( ( xPortHasUDPSocket( port ) == pdFALSE )
+ #if ipconfigUSE_LLMNR == 1
+ && ( port != FreeRTOS_ntohs( ipLLMNR_PORT ) )
+ #endif
+ #if ipconfigUSE_NBNS == 1
+ && ( port != FreeRTOS_ntohs( ipNBNS_PORT ) )
+ #endif
+ #if ipconfigUSE_DNS == 1
+ && ( pxProtPacket->xUDPPacket.xUDPHeader.usSourcePort != FreeRTOS_ntohs( ipDNS_PORT ) )
+ #endif
+ ) {
+ /* Drop this packet, not for this device. */
+ return pdFALSE;
+ }
+ }
+ }
+ #endif /* ipconfigETHERNET_DRIVER_FILTERS_PACKETS */
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvNetworkInterfaceInput( void )
+{
+NetworkBufferDescriptor_t *pxCurDescriptor;
+NetworkBufferDescriptor_t *pxNewDescriptor = NULL;
+BaseType_t xReceivedLength, xAccepted;
+__IO ETH_DMADescTypeDef *pxDMARxDescriptor;
+xIPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+uint8_t *pucBuffer;
+
+ pxDMARxDescriptor = xETH.RxDesc;
+
+ if( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_OWN) == 0 )
+ {
+ /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
+ xReceivedLength = ( ( pxDMARxDescriptor->Status & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
+
+ pucBuffer = (uint8_t *) pxDMARxDescriptor->Buffer1Addr;
+
+ /* Update the ETHERNET DMA global Rx descriptor with next Rx descriptor */
+ /* Chained Mode */
+ /* Selects the next DMA Rx descriptor list for next buffer to read */
+ xETH.RxDesc = ( ETH_DMADescTypeDef* )pxDMARxDescriptor->Buffer2NextDescAddr;
+ }
+ else
+ {
+ xReceivedLength = 0;
+ }
+
+ /* Obtain the size of the packet and put it into the "usReceivedLength" variable. */
+ /* In order to make the code easier and faster, only packets in a single buffer
+ will be accepted. This can be done by making the buffers large enough to
+ hold a complete Ethernet packet (1536 bytes). */
+ if( xReceivedLength > 0ul && xReceivedLength < ETH_RX_BUF_SIZE )
+ {
+ if( ( pxDMARxDescriptor->Status & ( ETH_DMARXDESC_CE | ETH_DMARXDESC_IPV4HCE | ETH_DMARXDESC_FT ) ) != ETH_DMARXDESC_FT )
+ {
+ /* Not an Ethernet frame-type or a checmsum error. */
+ xAccepted = pdFALSE;
+ }
+ else
+ {
+ /* See if this packet must be handled. */
+ xAccepted = xMayAcceptPacket( pucBuffer );
+ }
+
+ if( xAccepted != pdFALSE )
+ {
+ /* The packet wil be accepted, but check first if a new Network Buffer can
+ be obtained. If not, the packet will still be dropped. */
+ pxNewDescriptor = pxGetNetworkBufferWithDescriptor( ETH_RX_BUF_SIZE, xDescriptorWaitTime );
+
+ if( pxNewDescriptor == NULL )
+ {
+ /* A new descriptor can not be allocated now. This packet will be dropped. */
+ xAccepted = pdFALSE;
+ }
+ }
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ /* Find out which Network Buffer was originally passed to the descriptor. */
+ pxCurDescriptor = pxPacketBuffer_to_NetworkBuffer( pucBuffer );
+ configASSERT( pxCurDescriptor != NULL );
+ }
+ #else
+ {
+ /* In this mode, the two descriptors are the same. */
+ pxCurDescriptor = pxNewDescriptor;
+ if( pxNewDescriptor != NULL )
+ {
+ /* The packet is acepted and a new Network Buffer was created,
+ copy data to the Network Bufffer. */
+ memcpy( pxNewDescriptor->pucEthernetBuffer, pucBuffer, xReceivedLength );
+ }
+ }
+ #endif
+
+ if( xAccepted != pdFALSE )
+ {
+ pxCurDescriptor->xDataLength = xReceivedLength;
+ xRxEvent.pvData = ( void * ) pxCurDescriptor;
+
+ /* Pass the data to the TCP/IP task for processing. */
+ if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFALSE )
+ {
+ /* Could not send the descriptor into the TCP/IP stack, it
+ must be released. */
+ vReleaseNetworkBufferAndDescriptor( pxCurDescriptor );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ else
+ {
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+ }
+
+ /* Release descriptors to DMA */
+ #if( ipconfigZERO_COPY_RX_DRIVER != 0 )
+ {
+ /* Set Buffer1 address pointer */
+ if( pxNewDescriptor != NULL )
+ {
+ pxDMARxDescriptor->Buffer1Addr = (uint32_t)pxNewDescriptor->pucEthernetBuffer;
+ }
+ else
+ {
+ /* The packet was dropped and the same Network
+ Buffer will be used to receive a new packet. */
+ }
+ }
+ #endif /* ipconfigZERO_COPY_RX_DRIVER */
+
+ /* Set Buffer1 size and Second Address Chained bit */
+ pxDMARxDescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | (uint32_t)ETH_RX_BUF_SIZE;
+ pxDMARxDescriptor->Status = ETH_DMARXDESC_OWN;
+
+ /* When Rx Buffer unavailable flag is set clear it and resume
+ reception. */
+ if( ( xETH.Instance->DMASR & ETH_DMASR_RBUS ) != 0 )
+ {
+ /* Clear RBUS ETHERNET DMA flag. */
+ xETH.Instance->DMASR = ETH_DMASR_RBUS;
+
+ /* Resume DMA reception. */
+ xETH.Instance->DMARPDR = 0;
+ }
+ }
+
+ return ( xReceivedLength > 0 );
+}
+/*-----------------------------------------------------------*/
+
+void vMACBProbePhy( void )
+{
+uint32_t ulConfig, ulAdvertise, ulLower, ulUpper, ulMACPhyID, ulValue;
+TimeOut_t xPhyTime;
+TickType_t xRemTime = 0;
+#if( EXPECTED_PHY_ID == PHY_ID_DP83848I )
+ uint32_t ulPhyControl;
+#endif
+
+ HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_03_PHYSID2, &ulLower);
+ HAL_ETH_ReadPHYRegister(&xETH, PHY_REG_02_PHYSID1, &ulUpper);
+
+ ulMACPhyID = ( ( ulUpper << 16 ) & 0xFFFF0000 ) | ( ulLower & 0xFFF0 );
+
+ /* The expected ID for the 'LAN8720' is 0x0007c0f0. */
+ /* The expected ID for the 'DP83848I' is 0x20005C90. */
+
+ FreeRTOS_printf( ( "PHY ID %lX (%s)\n", ulMACPhyID,
+ ( ulMACPhyID == EXPECTED_PHY_ID ) ? "OK" : "Unknown" ) );
+
+ /* Remove compiler warning if FreeRTOS_printf() is not defined. */
+ ( void ) ulMACPhyID;
+
+ /* Set advertise register. */
+ if( ( xPHYProperties.speed == PHY_SPEED_AUTO ) && ( xPHYProperties.duplex == PHY_DUPLEX_AUTO ) )
+ {
+ ulAdvertise = ADVERTISE_CSMA | ADVERTISE_ALL;
+ /* Reset auto-negotiation capability. */
+ }
+ else
+ {
+ ulAdvertise = ADVERTISE_CSMA;
+
+ if( xPHYProperties.speed == PHY_SPEED_AUTO )
+ {
+ if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
+ {
+ ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_100FULL;
+ }
+ else
+ {
+ ulAdvertise |= ADVERTISE_10HALF | ADVERTISE_100HALF;
+ }
+ }
+ else if( xPHYProperties.duplex == PHY_DUPLEX_AUTO )
+ {
+ if( xPHYProperties.speed == PHY_SPEED_10 )
+ {
+ ulAdvertise |= ADVERTISE_10FULL | ADVERTISE_10HALF;
+ }
+ else
+ {
+ ulAdvertise |= ADVERTISE_100FULL | ADVERTISE_100HALF;
+ }
+ }
+ else if( xPHYProperties.speed == PHY_SPEED_100 )
+ {
+ if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
+ {
+ ulAdvertise |= ADVERTISE_100FULL;
+ }
+ else
+ {
+ ulAdvertise |= ADVERTISE_100HALF;
+ }
+ }
+ else
+ {
+ if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
+ {
+ ulAdvertise |= ADVERTISE_10FULL;
+ }
+ else
+ {
+ ulAdvertise |= ADVERTISE_10HALF;
+ }
+ }
+ }
+
+ /* Read Control register. */
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );
+
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig | BMCR_RESET );
+ xRemTime = ( TickType_t ) pdMS_TO_TICKS( 1000UL );
+ vTaskSetTimeOutState( &xPhyTime );
+
+ for( ; ; )
+ {
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulValue );
+ if( ( ulValue & BMCR_RESET ) == 0 )
+ {
+ FreeRTOS_printf( ( "BMCR_RESET ready\n" ) );
+ break;
+ }
+ if( xTaskCheckForTimeOut( &xPhyTime, &xRemTime ) != pdFALSE )
+ {
+ FreeRTOS_printf( ( "BMCR_RESET timed out\n" ) );
+ break;
+ }
+ }
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulConfig & ~BMCR_RESET );
+
+ vTaskDelay( pdMS_TO_TICKS( 50ul ) );
+
+ /* Write advertise register. */
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulAdvertise );
+
+ /*
+ AN_EN AN1 AN0 Forced Mode
+ 0 0 0 10BASE-T, Half-Duplex
+ 0 0 1 10BASE-T, Full-Duplex
+ 0 1 0 100BASE-TX, Half-Duplex
+ 0 1 1 100BASE-TX, Full-Duplex
+ AN_EN AN1 AN0 Advertised Mode
+ 1 0 0 10BASE-T, Half/Full-Duplex
+ 1 0 1 100BASE-TX, Half/Full-Duplex
+ 1 1 0 10BASE-T Half-Duplex
+ 100BASE-TX, Half-Duplex
+ 1 1 1 10BASE-T, Half/Full-Duplex
+ 100BASE-TX, Half/Full-Duplex
+ */
+
+ /* Read Control register. */
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_00_BMCR, &ulConfig );
+
+ ulConfig &= ~( BMCR_ANRESTART | BMCR_ANENABLE | BMCR_SPEED100 | BMCR_FULLDPLX );
+
+ /* HT 12/9/14: always set AN-restart and AN-enable, even though the choices
+ are limited. */
+ ulConfig |= (BMCR_ANRESTART | BMCR_ANENABLE);
+
+ if( xPHYProperties.speed == PHY_SPEED_100 )
+ {
+ ulConfig |= BMCR_SPEED100;
+ }
+ else if( xPHYProperties.speed == PHY_SPEED_10 )
+ {
+ ulConfig &= ~BMCR_SPEED100;
+ }
+
+ if( xPHYProperties.duplex == PHY_DUPLEX_FULL )
+ {
+ ulConfig |= BMCR_FULLDPLX;
+ }
+ else if( xPHYProperties.duplex == PHY_DUPLEX_HALF )
+ {
+ ulConfig &= ~BMCR_FULLDPLX;
+ }
+
+ #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )
+ {
+ }
+ #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )
+ {
+ /* Read PHY Control register. */
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_19_PHYCR, &ulPhyControl );
+
+ /* Clear bits which might get set: */
+ ulPhyControl &= ~( PHYCR_MDIX_EN|PHYCR_MDIX_FORCE );
+
+ if( xPHYProperties.mdix == PHY_MDIX_AUTO )
+ {
+ ulPhyControl |= PHYCR_MDIX_EN;
+ }
+ else if( xPHYProperties.mdix == PHY_MDIX_CROSSED )
+ {
+ /* Force direct link = Use crossed RJ45 cable. */
+ ulPhyControl &= ~PHYCR_MDIX_FORCE;
+ }
+ else
+ {
+ /* Force crossed link = Use direct RJ45 cable. */
+ ulPhyControl |= PHYCR_MDIX_FORCE;
+ }
+ /* update PHY Control Register. */
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_19_PHYCR, ulPhyControl );
+ }
+ #endif
+ FreeRTOS_printf( ( "+TCP: advertise: %lX config %lX\n", ulAdvertise, ulConfig ) );
+
+ /* Now the two values to global values for later use. */
+ ulBCRvalue = ulConfig;
+ ulACRValue = ulAdvertise;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEthernetUpdateConfig( BaseType_t xForce )
+{
+__IO uint32_t ulTimeout = 0;
+uint32_t ulRegValue = 0;
+
+ FreeRTOS_printf( ( "prvEthernetUpdateConfig: LS %d Force %d\n",
+ ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ,
+ xForce ) );
+
+ if( ( xForce != pdFALSE ) || ( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) )
+ {
+ /* Restart the auto-negotiation. */
+ if( xETH.Init.AutoNegotiation != ETH_AUTONEGOTIATION_DISABLE )
+ {
+ /* Enable Auto-Negotiation. */
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue | BMCR_ANRESTART );
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_04_ADVERTISE, ulACRValue);
+
+ /* Wait until the auto-negotiation will be completed */
+ do
+ {
+ ulTimeout++;
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue );
+ } while( ( ( ulRegValue & PHY_AUTONEGO_COMPLETE) == 0 ) && ( ulTimeout < PHY_READ_TO ) );
+
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, ulBCRvalue & ~BMCR_ANRESTART );
+
+ if( ulTimeout < PHY_READ_TO )
+ {
+ /* Reset Timeout counter. */
+ ulTimeout = 0;
+
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &ulRegValue);
+ if( ( ulRegValue & BMSR_LINK_STATUS ) != 0 )
+ {
+ ulPHYLinkStatus |= BMSR_LINK_STATUS;
+ }
+ else
+ {
+ ulPHYLinkStatus &= ~( BMSR_LINK_STATUS );
+ }
+
+ #if( EXPECTED_PHY_ID == PHY_ID_LAN8720 )
+ {
+ /* 31 RW PHY Special Control Status */
+ uint32_t ulControlStatus;
+
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_1F_PHYSPCS, &ulControlStatus);
+ ulRegValue = 0;
+ if( ( ulControlStatus & PHYSPCS_FULL_DUPLEX ) != 0 )
+ {
+ ulRegValue |= PHY_DUPLEX_STATUS;
+ }
+ if( ( ulControlStatus & PHYSPCS_SPEED_MASK ) == PHYSPCS_SPEED_10 )
+ {
+ ulRegValue |= PHY_SPEED_STATUS;
+ }
+
+ }
+ #elif( EXPECTED_PHY_ID == PHY_ID_DP83848I )
+ {
+ /* Read the result of the auto-negotiation. */
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_10_PHY_SR, &ulRegValue);
+ }
+ #endif
+ FreeRTOS_printf( ( ">> Autonego ready: %08lx: %s duplex %u mbit %s status\n",
+ ulRegValue,
+ (ulRegValue & PHY_DUPLEX_STATUS) ? "full" : "half",
+ (ulRegValue & PHY_SPEED_STATUS) ? 10 : 100,
+ ((ulPHYLinkStatus |= BMSR_LINK_STATUS) != 0) ? "high" : "low" ) );
+
+ /* Configure the MAC with the Duplex Mode fixed by the
+ auto-negotiation process. */
+ if( ( ulRegValue & PHY_DUPLEX_STATUS ) != ( uint32_t ) RESET )
+ {
+ /* Set Ethernet duplex mode to Full-duplex following the
+ auto-negotiation. */
+ xETH.Init.DuplexMode = ETH_MODE_FULLDUPLEX;
+ }
+ else
+ {
+ /* Set Ethernet duplex mode to Half-duplex following the
+ auto-negotiation. */
+ xETH.Init.DuplexMode = ETH_MODE_HALFDUPLEX;
+ }
+
+ /* Configure the MAC with the speed fixed by the
+ auto-negotiation process. */
+ if( ( ulRegValue & PHY_SPEED_STATUS) != 0 )
+ {
+ /* Set Ethernet speed to 10M following the
+ auto-negotiation. */
+ xETH.Init.Speed = ETH_SPEED_10M;
+ }
+ else
+ {
+ /* Set Ethernet speed to 100M following the
+ auto-negotiation. */
+ xETH.Init.Speed = ETH_SPEED_100M;
+ }
+ } /* if( ulTimeout < PHY_READ_TO ) */
+ }
+ else /* AutoNegotiation Disable */
+ {
+ uint16_t usValue;
+
+ /* Check parameters */
+ assert_param( IS_ETH_SPEED( xETH.Init.Speed ) );
+ assert_param( IS_ETH_DUPLEX_MODE( xETH.Init.DuplexMode ) );
+
+ /* Set MAC Speed and Duplex Mode to PHY */
+ usValue = ( uint16_t ) ( xETH.Init.DuplexMode >> 3 ) | ( uint16_t ) ( xETH.Init.Speed >> 1 );
+ HAL_ETH_WritePHYRegister( &xETH, PHY_REG_00_BMCR, usValue );
+ }
+
+ /* ETHERNET MAC Re-Configuration */
+ HAL_ETH_ConfigMAC( &xETH, (ETH_MACInitTypeDef *) NULL);
+
+ /* Restart MAC interface */
+ HAL_ETH_Start( &xETH);
+ }
+ else
+ {
+ /* Stop MAC interface */
+ HAL_ETH_Stop( &xETH );
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xReturn;
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xReturn = pdPASS;
+ }
+ else
+ {
+ xReturn = pdFAIL;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0;
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+UBaseType_t uxLastMinQueueSpace = 0;
+#endif
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
+ if( uxLastMinBufferCount != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
+ }
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ if( xTXDescriptorSemaphore != NULL )
+ {
+ static UBaseType_t uxLowestSemCount = ( UBaseType_t ) ETH_TXBUFNB - 1;
+
+ uxCurrentCount = uxSemaphoreGetCount( xTXDescriptorSemaphore );
+ if( uxLowestSemCount > uxCurrentCount )
+ {
+ uxLowestSemCount = uxCurrentCount;
+ FreeRTOS_printf( ( "TX DMA buffers: lowest %lu\n", uxLowestSemCount ) );
+ }
+
+ }
+ #endif
+ #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+
+ if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ xResult = prvNetworkInterfaceInput();
+ if( xResult > 0 )
+ {
+ while( prvNetworkInterfaceInput() > 0 )
+ {
+ }
+ }
+ }
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* Check if DMA packets have been delivered. */
+ vClearTXBuffers();
+ }
+ #endif
+ }
+
+ if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
+ {
+ /* Future extension: logging about errors that occurred. */
+ ulISREvents &= ~EMAC_IF_ERR_EVENT;
+ }
+
+ if( xResult > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ HAL_ETH_ReadPHYRegister( &xETH, PHY_REG_01_BMSR, &xStatus );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ prvEthernetUpdateConfig( pdFALSE );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+void ETH_IRQHandler( void )
+{
+ HAL_ETH_IRQHandler( &xETH );
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
deleted file mode 100644
index 51170c041..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/readme.txt
+++ /dev/null
@@ -1,60 +0,0 @@
-This is a FreeeRTOS+TCP driver that works for both STM32F4xx and STM32F7xx parts.
-
-The code of stm32fxx_hal_eth.c is based on both drivers as provided by ST.
-
-These modules should be included:
-
- NetworkInterface.c
- stm32fxx_hal_eth.c
-
-It is assumed that one of these words are defined:
-
- STM32F7xx
- STM32F407xx
- STM32F417xx
- STM32F427xx
- STM32F437xx
- STM32F429xx
- STM32F439xx
-
-The driver has been tested on both Eval and Discovery boards with both STM32F4 and STM32F7.
-
-Recommened settings for STM32Fxx Network Interface:
-
-// Defined in FreeRTOSIPConfig.h
-
-#define ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES 1
-#define ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM 1
-#define ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM 1
-#define ipconfigZERO_COPY_RX_DRIVER 1
-#define ipconfigZERO_COPY_TX_DRIVER 1
-#define ipconfigUSE_LINKED_RX_MESSAGES 1
-
-// Defined in stm32f4xx_hal_conf.h
-#define ETH_RXBUFNB 3 or 4
-#define ETH_TXBUFNB 2 or 3
-#define ETH_RX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
-#define ETH_TX_BUF_SIZE ( ipconfigNETWORK_MTU + 36 )
-
-The best size for 'ETH_RXBUFNB' and 'ETH_TXBUFNB' depends on the speed of the CPU. These macro's define the number of DMA buffers for reception and for transmission.
-In general, if the CPU is very fast, you will need less buffers. You can obtain an estimate empirically.
-
-The optimal value of 'ETH_RX_BUF_SIZE' and 'ETH_TX_BUF_SIZE' depends on the actual value of 'ipconfigNETWORK_MTU'.
-When MTU is 1500, MTU+36 becomes a well-aligned buffer of 1536 bytes ( 0x600 ).
-When MTU is 1200, MTU+48 will make 1248 ( 0x4E0 ), which is also well aligned.
-
-Having well aligned buffers is important for CPU with memory cache. Often the caching system divides memory in blocks of 32 bytes. When two buffers share the same cache buffer, you are bound to see data errors.
-
-Without memory caching, let the size be at least a multiple of 8 ( for DMA ), and make it at least "ipconfigNETWORK_MTU + 14".
-
-The driver contains these files:
-
- stm32fxx_hal_eth.c
- stm32f2xx_hal_eth.h
- stm32f4xx_hal_eth.h
- stm32f7xx_hal_eth.h
- stm32fxx_hal_eth.h
-
-These files are copied from ST's HAL library. These work both for STM32F4 and STM32F7.
-Please remove or rename these files from the HAL distribution that you are using.
-
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f2xx_hal_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f2xx_hal_eth.h
deleted file mode 100644
index 93b9caff0..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f2xx_hal_eth.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
- * a single module that works for both parts: "stm32fxx_hal_eth"
- */
-
-#include "stm32fxx_hal_eth.h"
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.c
deleted file mode 100644
index 4388d1277..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.c
+++ /dev/null
@@ -1,1833 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32f4xx_hal_eth.c
- * @author MCD Application Team
- * @version V1.3.2
- * @date 26-June-2015
- * @brief ETH HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Ethernet (ETH) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#)Declare a ETH_HandleTypeDef handle structure, for example:
- ETH_HandleTypeDef heth;
-
- (#)Fill parameters of Init structure in heth handle
-
- (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
-
- (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
- (##) Enable the Ethernet interface clock using
- (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
-
- (##) Initialize the related GPIO clocks
- (##) Configure Ethernet pin-out
- (##) Configure Ethernet NVIC interrupt (IT mode)
-
- (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
- (##) HAL_ETH_DMATxDescListInit(); for Transmission process
- (##) HAL_ETH_DMARxDescListInit(); for Reception process
-
- (#)Enable MAC and DMA transmission and reception:
- (##) HAL_ETH_Start();
-
- (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
- the frame to MAC TX FIFO:
- (##) HAL_ETH_TransmitFrame();
-
- (#)Poll for a received frame in ETH RX DMA Descriptors and get received
- frame parameters
- (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
-
- (#) Get a received frame when an ETH RX interrupt occurs:
- (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
-
- (#) Communicate with external PHY device:
- (##) Read a specific register from the PHY
- HAL_ETH_ReadPHYRegister();
- (##) Write data to a specific RHY register:
- HAL_ETH_WritePHYRegister();
-
- (#) Configure the Ethernet MAC after ETH peripheral initialization
- HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
-
- (#) Configure the Ethernet DMA after ETH peripheral initialization
- HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
-
- -@- The PTP protocol and the DMA descriptors ring mode are not supported
- in this driver
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-#include "stm32f4xx_hal.h"
-
-int lUDPLoggingPrintf( const char *pcFormatString, ... );
-
-/** @addtogroup STM32F4xx_HAL_Driver
- * @{
- */
-
-/** @defgroup ETH ETH
- * @brief ETH HAL module driver
- * @{
- */
-
-#if !defined( ARRAY_SIZE )
- #define ARRAY_SIZE( x ) ( sizeof ( x ) / sizeof ( x )[ 0 ] )
-#endif
-
-#ifdef HAL_ETH_MODULE_ENABLED
-
-#if defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup ETH_Private_Constants ETH Private Constants
- * @{
- */
-#define LINKED_STATE_TIMEOUT_VALUE ((uint32_t)2000) /* 2000 ms */
-#define AUTONEGO_COMPLETED_TIMEOUT_VALUE ((uint32_t)1000) /* 1000 ms */
-
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup ETH_Private_Functions ETH Private Functions
- * @{
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
-
-/**
- * @}
- */
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup ETH_Exported_Functions ETH Exported Functions
- * @{
- */
-
-/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize and configure the Ethernet peripheral
- (+) De-initialize the Ethernet peripheral
-
- @endverbatim
- * @{
- */
-extern void vMACBProbePhy ( void );
-
-/**
- * @brief Initializes the Ethernet MAC and DMA according to default
- * parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = 0;
- uint32_t hclk = 60000000;
- uint32_t err = ETH_SUCCESS;
-
- /* Check the ETH peripheral state */
- if( heth == NULL )
- {
- return HAL_ERROR;
- }
-
- /* Check parameters */
- assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
- assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
- assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
- assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
-
- if( heth->State == HAL_ETH_STATE_RESET )
- {
- /* Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspInit( heth );
- }
-
- /* Enable SYSCFG Clock */
- __HAL_RCC_SYSCFG_CLK_ENABLE();
-
- /* Select MII or RMII Mode*/
- SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
- SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface;
-
- /* Ethernet Software reset */
- /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
- /* After reset all the registers holds their respective reset values */
- /* Also enable EDFE: Enhanced descriptor format enable. */
- heth->Instance->DMABMR |= ETH_DMABMR_SR | ETH_DMABMR_EDE;
-
- /* Wait for software reset */
- while ((heth->Instance->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
- {
- }
-
- /*-------------------------------- MAC Initialization ----------------------*/
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
- /* Clear CSR Clock Range CR[2:0] bits */
- tmpreg &= ETH_MACMIIAR_CR_MASK;
-
- /* Get hclk frequency value (168,000,000) */
- hclk = HAL_RCC_GetHCLKFreq();
-
- /* Set CR bits depending on hclk value */
- if( ( hclk >= 20000000 ) && ( hclk < 35000000 ) )
- {
- /* CSR Clock Range between 20-35 MHz */
- tmpreg |= (uint32_t) ETH_MACMIIAR_CR_Div16;
- }
- else if( ( hclk >= 35000000 ) && ( hclk < 60000000 ) )
- {
- /* CSR Clock Range between 35-60 MHz */
- tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26;
- }
- else if((hclk >= 60000000 ) && ( hclk < 100000000 ) )
- {
- /* CSR Clock Range between 60-100 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
- }
- else if((hclk >= 100000000 ) && ( hclk < 150000000))
- {
- /* CSR Clock Range between 100-150 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
- }
- else /* ((hclk >= 150000000 ) && ( hclk <= 168000000)) */
- {
- /* CSR Clock Range between 150-168 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
- }
-
- /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
- heth->Instance->MACMIIAR = (uint32_t)tmpreg;
-
- /* Initialise the MACB and set all PHY properties */
- vMACBProbePhy();
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief De-Initializes the ETH peripheral.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
-{
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspDeInit( heth );
-
- /* Set ETH HAL state to Disabled */
- heth->State= HAL_ETH_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Tx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMATxDescTab: Pointer to the first Tx desc list
- * @param TxBuff: Pointer to the first TxBuffer list
- * @param TxBuffCount: Number of the used Tx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *pxDMATable, uint8_t *ucDataBuffer, uint32_t ulBufferCount)
-{
- uint32_t i = 0;
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the TxDesc pointer with the first one of the pxDMATable list */
- heth->TxDesc = pxDMATable;
-
- /* Fill each DMA descriptor with the right values */
- for( i=0; i < ulBufferCount; i++ )
- {
- /* Get the pointer on the ith member of the descriptor list */
- pxDMADescriptor = pxDMATable + i;
-
- /* Set Second Address Chained bit */
- pxDMADescriptor->Status = ETH_DMATXDESC_TCH;
-
- pxDMADescriptor->ControlBufferSize = 0;
-
- /* Set Buffer1 address pointer */
- if( ucDataBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( &ucDataBuffer[ i * ETH_TX_BUF_SIZE ] );
- }
- else
- {
- /* Buffer space is not provided because it uses zero-copy transmissions. */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )0u;
- }
-
- if (heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- /* Set the DMA Tx descriptors checksum insertion for TCP, UDP, and ICMP */
- pxDMADescriptor->Status |= ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if(i < ( ulBufferCount - 1 ) )
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) ( pxDMATable + i + 1 );
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) pxDMATable;
- }
- }
-
- /* Set Transmit Descriptor List Address Register */
- heth->Instance->DMATDLAR = ( uint32_t ) pxDMATable;
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the DMA Rx descriptors in chain mode.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param DMARxDescTab: Pointer to the first Rx desc list
- * @param RxBuff: Pointer to the first RxBuffer list
- * @param RxBuffCount: Number of the used Rx desc in the list
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *pxDMATable, uint8_t *ucDataBuffer, uint32_t ulBufferCount)
-{
- uint32_t i = 0;
- ETH_DMADescTypeDef *pxDMADescriptor;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Set the RxDesc pointer with the first one of the pxDMATable list */
- heth->RxDesc = pxDMATable;
-
- /* Fill each DMA descriptor with the right values */
- for(i=0; i < ulBufferCount; i++)
- {
- /* Get the pointer on the ith member of the descriptor list */
- pxDMADescriptor = pxDMATable+i;
-
- /* Set Own bit of the Rx descriptor Status */
- pxDMADescriptor->Status = ETH_DMARXDESC_OWN;
-
- /* Set Buffer1 size and Second Address Chained bit */
- pxDMADescriptor->ControlBufferSize = ETH_DMARXDESC_RCH | ETH_RX_BUF_SIZE;
-
- /* Set Buffer1 address pointer */
- if( ucDataBuffer != NULL )
- {
- pxDMADescriptor->Buffer1Addr = ( uint32_t )( &ucDataBuffer[ i * ETH_RX_BUF_SIZE ] );
- }
- else
- {
- /* Buffer space is not provided because it uses zero-copy reception. */
- pxDMADescriptor->Buffer1Addr = ( uint32_t )0u;
- }
-
- if( heth->Init.RxMode == ETH_RXINTERRUPT_MODE )
- {
- /* Enable Ethernet DMA Rx Descriptor interrupt */
- pxDMADescriptor->ControlBufferSize &= ~ETH_DMARXDESC_DIC;
- }
-
- /* Initialize the next descriptor with the Next Descriptor Polling Enable */
- if(i < (ulBufferCount-1))
- {
- /* Set next descriptor address register with next descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = (uint32_t)(pxDMATable+i+1);
- }
- else
- {
- /* For last descriptor, set next descriptor address register equal to the first descriptor base address */
- pxDMADescriptor->Buffer2NextDescAddr = ( uint32_t ) pxDMATable;
- }
- }
-
- /* Set Receive Descriptor List Address Register */
- heth->Instance->DMARDLAR = ( uint32_t ) pxDMATable;
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspInit could be implemented in the user file
- */
-}
-
-/**
- * @brief DeInitializes ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspDeInit could be implemented in the user file
- */
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
- @verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Transmit a frame
- HAL_ETH_TransmitFrame();
- (+) Receive a frame
- HAL_ETH_GetReceivedFrame();
- HAL_ETH_GetReceivedFrame_IT();
- (+) Read from an External PHY register
- HAL_ETH_ReadPHYRegister();
- (+) Write to an External PHY register
- HAL_ETH_WritePHYRegister();
-
- @endverbatim
-
- * @{
- */
-
-/**
- * @brief Sends an Ethernet frame.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param FrameLength: Amount of data to be sent
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength)
-{
- uint32_t bufcount = 0, size = 0, i = 0;
- __IO ETH_DMADescTypeDef *pxDmaTxDesc = heth->TxDesc;
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- if( FrameLength == 0 )
- {
- /* Set ETH HAL state to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- return HAL_ERROR;
- }
-
- /* Check if the descriptor is owned by the ETHERNET DMA (when set) or CPU (when reset) */
- if( ( pxDmaTxDesc->Status & ETH_DMATXDESC_OWN ) != ( uint32_t ) RESET )
- {
- /* OWN bit set */
- heth->State = HAL_ETH_STATE_BUSY_TX;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- return HAL_ERROR;
- }
-
- /* Get the number of needed Tx buffers for the current frame, rounding up. */
- bufcount = ( FrameLength + ETH_TX_BUF_SIZE - 1 ) / ETH_TX_BUF_SIZE;
-
- if (bufcount == 1)
- {
- /* Set LAST and FIRST segment */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_FS | ETH_DMATXDESC_LS;
- /* Set frame size */
- pxDmaTxDesc->ControlBufferSize = ( FrameLength & ETH_DMATXDESC_TBS1 );
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- pxDmaTxDesc->Status |= ETH_DMATXDESC_OWN;
- /* Point to next descriptor */
- heth->TxDesc = ( ETH_DMADescTypeDef * ) ( heth->TxDesc->Buffer2NextDescAddr );
- }
- else
- {
- for( i = 0; i < bufcount; i++ )
- {
- /* Clear FIRST and LAST segment bits */
- uint32_t ulStatus = heth->TxDesc->Status & ~( ETH_DMATXDESC_FS | ETH_DMATXDESC_LS );
-
- if( i == 0 )
- {
- /* Setting the first segment bit */
- heth->TxDesc->Status = ulStatus | ETH_DMATXDESC_FS;
- }
-
- /* Program size */
- if (i < (bufcount-1))
- {
- heth->TxDesc->ControlBufferSize = (ETH_TX_BUF_SIZE & ETH_DMATXDESC_TBS1);
- }
- else
- {
- /* Setting the last segment bit */
- heth->TxDesc->Status = ulStatus | ETH_DMATXDESC_LS;
- size = FrameLength - (bufcount-1)*ETH_TX_BUF_SIZE;
- heth->TxDesc->ControlBufferSize = (size & ETH_DMATXDESC_TBS1);
- }
-
- /* Set Own bit of the Tx descriptor Status: gives the buffer back to ETHERNET DMA */
- heth->TxDesc->Status |= ETH_DMATXDESC_OWN;
- /* point to next descriptor */
- heth->TxDesc = (ETH_DMADescTypeDef *)( heth->TxDesc->Buffer2NextDescAddr );
- }
- }
-
- __DSB();
-
- /* When Tx Buffer unavailable flag is set: clear it and resume transmission */
- if( ( heth->Instance->DMASR & ETH_DMASR_TBUS ) != ( uint32_t )RESET )
- {
- heth->Instance->DMACHTDR = ( uint32_t )pxDmaTxDesc;
-
- /* Clear TBUS ETHERNET DMA flag */
- heth->Instance->DMASR = ETH_DMASR_TBUS;
- /* Resume DMA transmission*/
- heth->Instance->DMATPDR = 0;
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Checks for received frames.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT( ETH_HandleTypeDef *heth )
-{
- return HAL_ETH_GetReceivedFrame( heth );
-}
-
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame( ETH_HandleTypeDef *heth )
-{
-uint32_t ulCounter = 0;
-ETH_DMADescTypeDef *pxDescriptor = heth->RxDesc;
-HAL_StatusTypeDef xResult = HAL_ERROR;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Check the ETH state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Scan descriptors owned by CPU */
- while( ( ( pxDescriptor->Status & ETH_DMARXDESC_OWN ) == 0ul ) && ( ulCounter < ETH_RXBUFNB ) )
- {
- uint32_t ulStatus = pxDescriptor->Status;
-
- /* Just for security. */
- ulCounter++;
-
- if( ( ulStatus & ( ETH_DMARXDESC_FS | ETH_DMARXDESC_LS ) ) == ( uint32_t )ETH_DMARXDESC_FS )
- {
- /* First segment in frame, but not the last. */
- heth->RxFrameInfos.FSRxDesc = pxDescriptor;
- heth->RxFrameInfos.LSRxDesc = ( ETH_DMADescTypeDef *)NULL;
- heth->RxFrameInfos.SegCount = 1;
- /* Point to next descriptor. */
- pxDescriptor = (ETH_DMADescTypeDef*) (pxDescriptor->Buffer2NextDescAddr);
- heth->RxDesc = pxDescriptor;
- }
- else if( ( ulStatus & ( ETH_DMARXDESC_LS | ETH_DMARXDESC_FS ) ) == 0ul )
- {
- /* This is an intermediate segment, not first, not last. */
- /* Increment segment count. */
- heth->RxFrameInfos.SegCount++;
- /* Move to the next descriptor. */
- pxDescriptor = ( ETH_DMADescTypeDef * ) ( pxDescriptor->Buffer2NextDescAddr );
- heth->RxDesc = pxDescriptor;
- }
- /* Must be a last segment */
- else
- {
- /* This is the last segment. */
- /* Check if last segment is first segment: one segment contains the frame */
- if( heth->RxFrameInfos.SegCount == 0 )
- {
- /* Remember the first segment. */
- heth->RxFrameInfos.FSRxDesc = pxDescriptor;
- }
-
- /* Increment segment count */
- heth->RxFrameInfos.SegCount++;
-
- /* Remember the last segment. */
- heth->RxFrameInfos.LSRxDesc = pxDescriptor;
-
- /* Get the Frame Length of the received packet: substruct 4 bytes of the CRC */
- heth->RxFrameInfos.length =
- ( ( ulStatus & ETH_DMARXDESC_FL ) >> ETH_DMARXDESC_FRAMELENGTHSHIFT ) - 4;
-
- /* Get the address of the buffer start address */
- heth->RxFrameInfos.buffer = heth->RxFrameInfos.FSRxDesc->Buffer1Addr;
-
- /* Point to next descriptor */
- heth->RxDesc = ( ETH_DMADescTypeDef * ) pxDescriptor->Buffer2NextDescAddr;
-
- /* Return OK status: a packet was received. */
- xResult = HAL_OK;
- break;
- }
- }
-
- /* Set ETH HAL State to Ready */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return xResult;
-}
-
-#if( STM32_ETHERNET_STATS != 0 )
-
- volatile int rx_count, tx_count, int_count;
- /**
- * @brief This function handles ETH interrupt request.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
- volatile int int_counts[32];
- volatile int tx_status[8];
- volatile unsigned sr_history[32];
- volatile int sr_head;
- #define STM32_STAT_INC( x ) do { ( x )++; } while( 0 )
-
-#else
- #define STM32_STAT_INC( x ) do { } while( 0 )
-#endif /* STM32_ETHERNET_STATS */
-
-#define ETH_DMA_ALL_INTS \
- ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_AIS | ETH_DMA_IT_ER | \
- ETH_DMA_IT_FBE | ETH_DMA_IT_ET | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
- ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-
-//#define ETH_DMA_ALL_INTS ETH_DMA_IT_RBU | ETH_DMA_FLAG_T | ETH_DMA_FLAG_AIS
-
-#define INT_MASK ( ( uint32_t ) ~ ( ETH_DMA_IT_TBU ) )
-void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
-{
- uint32_t dmasr;
-
- STM32_STAT_INC( int_count );
-
- dmasr = heth->Instance->DMASR & ETH_DMA_ALL_INTS;
- heth->Instance->DMASR = dmasr;
-
-#if( STM32_ETHERNET_STATS != 0 )
- if( sr_head < ARRAY_SIZE( sr_history ) )
- {
- sr_history[ sr_head++ ] = dmasr;
- }
-
- {
- int i;
- for (i = 0; i < 32; i++) {
- if (dmasr & (1u << i)) {
- int_counts[i]++;
- }
- }
- tx_status[ ( dmasr >> 20 ) & 0x07 ]++;
- }
-#endif
-
- /* Frame received */
- if( ( dmasr & ( ETH_DMA_FLAG_R | ETH_DMA_IT_RBU ) ) != 0 )
- {
- /* Receive complete callback */
- HAL_ETH_RxCpltCallback( heth );
- STM32_STAT_INC( rx_count );
- }
- /* Frame transmitted */
- if( ( dmasr & ( ETH_DMA_FLAG_T ) ) != 0 )
- {
- /* Transfer complete callback */
- HAL_ETH_TxCpltCallback( heth );
- STM32_STAT_INC( tx_count );
- }
-
- /* ETH DMA Error */
- if( ( dmasr & ( ETH_DMA_FLAG_AIS ) ) != 0 )
- {
- /* Ethernet Error callback */
- HAL_ETH_ErrorCallback( heth );
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Rx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Ethernet transfer error callbacks
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
-}
-
-/**
- * @brief Reads a PHY register
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Basic Control Register,
- * PHY_BSR: Transceiver Basic Status Register.
- * More PHY register could be read depending on the used PHY
- * @param RegValue: PHY register value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
-{
-uint32_t tmpreg = 0;
-uint32_t tickstart = 0;
-HAL_StatusTypeDef xResult;
-
- /* Check parameters */
- assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
-
- /* Check the ETH peripheral state */
- if( heth->State == HAL_ETH_STATE_BUSY_RD )
- {
- xResult = HAL_BUSY;
- }
- else
- {
- __HAL_LOCK( heth );
-
- /* Set ETH HAL State to BUSY_RD */
- heth->State = HAL_ETH_STATE_BUSY_RD;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII address register value */
- tmpreg |= ( ( ( uint32_t )heth->Init.PhyAddress << 11) & ETH_MACMIIAR_PA ); /* Set the PHY device address */
- tmpreg |= ( ( ( uint32_t )PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */
- tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while( 1 )
- {
- tmpreg = heth->Instance->MACMIIAR;
-
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul )
- {
- /* Get MACMIIDR value */
- *RegValue = ( uint32_t ) heth->Instance->MACMIIDR;
- xResult = HAL_OK;
- break;
- }
- /* Check for the Timeout */
- if( ( HAL_GetTick( ) - tickstart ) > PHY_READ_TO )
- {
- xResult = HAL_TIMEOUT;
- break;
- }
-
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
- }
-
- if( xResult != HAL_OK )
- {
- lUDPLoggingPrintf( "ReadPHY: %d\n", xResult );
- }
- /* Return function status */
- return xResult;
-}
-
-/**
- * @brief Writes to a PHY register.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Control Register.
- * More PHY register could be written depending on the used PHY
- * @param RegValue: the value to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
-{
-uint32_t tmpreg = 0;
-uint32_t tickstart = 0;
-HAL_StatusTypeDef xResult;
-
- /* Check parameters */
- assert_param( IS_ETH_PHY_ADDRESS( heth->Init.PhyAddress ) );
-
- /* Check the ETH peripheral state */
- if( heth->State == HAL_ETH_STATE_BUSY_WR )
- {
- xResult = HAL_BUSY;
- }
- else
- {
- __HAL_LOCK( heth );
-
- /* Set ETH HAL State to BUSY_WR */
- heth->State = HAL_ETH_STATE_BUSY_WR;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII register address value */
- tmpreg |= ( ( ( uint32_t ) heth->Init.PhyAddress << 11 ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */
- tmpreg |= ( ( ( uint32_t ) PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */
- tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Give the value to the MII data register */
- heth->Instance->MACMIIDR = ( uint16_t ) RegValue;
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while( 1 )
- {
- tmpreg = heth->Instance->MACMIIAR;
-
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul )
- {
- xResult = HAL_OK;
- break;
- }
- /* Check for the Timeout */
- if( ( HAL_GetTick( ) - tickstart ) > PHY_WRITE_TO )
- {
- xResult = HAL_TIMEOUT;
- break;
- }
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
- }
-
- if( xResult != HAL_OK )
- {
- lUDPLoggingPrintf( "WritePHY: %d\n", xResult );
- }
- /* Return function status */
- return xResult;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Enable MAC and DMA transmission and reception.
- HAL_ETH_Start();
- (+) Disable MAC and DMA transmission and reception.
- HAL_ETH_Stop();
- (+) Set the MAC configuration in runtime mode
- HAL_ETH_ConfigMAC();
- (+) Set the DMA configuration in runtime mode
- HAL_ETH_ConfigDMA();
-
-@endverbatim
- * @{
- */
-
- /**
- * @brief Enables Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef *heth )
-{
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Enable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionEnable( heth );
-
- /* Enable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionEnable( heth );
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO( heth );
-
- /* Start DMA transmission */
- ETH_DMATransmissionEnable( heth );
-
- /* Start DMA reception */
- ETH_DMAReceptionEnable( heth );
-
- /* Set the ETH state to READY*/
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stop Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
-{
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Stop DMA transmission */
- ETH_DMATransmissionDisable( heth );
-
- /* Stop DMA reception */
- ETH_DMAReceptionDisable( heth );
-
- /* Disable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionDisable( heth );
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO( heth );
-
- /* Disable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionDisable( heth );
-
- /* Set the ETH state*/
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-static void prvWriteMACFCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->MACFCR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->MACFCR;
-
- HAL_Delay( ETH_REG_WRITE_DELAY );
-
- heth->Instance->MACFCR = ulValue;
-}
-
-static void prvWriteDMAOMR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->DMAOMR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->DMAOMR;
-
- HAL_Delay( ETH_REG_WRITE_DELAY );
-
- heth->Instance->DMAOMR = ulValue;
-}
-
-static void prvWriteMACCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->MACCR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->MACCR;
-
- HAL_Delay( ETH_REG_WRITE_DELAY );
-
- heth->Instance->MACCR = ulValue;
-}
-
-/**
- * @brief Set ETH MAC Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param macconf: MAC Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
-{
- uint32_t tmpreg = 0;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State= HAL_ETH_STATE_BUSY;
-
- assert_param(IS_ETH_SPEED(heth->Init.Speed));
- assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
-
- if (macconf != NULL)
- {
- /* Check the parameters */
- assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
- assert_param(IS_ETH_JABBER(macconf->Jabber));
- assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
- assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
- assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
- assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
- assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
- assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
- assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
- assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
- assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
- assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
- assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
- assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
- assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
- assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
- assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
- assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
- assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
- assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
- assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
- assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
- assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
- assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
- assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
- assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
- assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg &= ETH_MACCR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)(
- macconf->Watchdog |
- macconf->Jabber |
- macconf->InterFrameGap |
- macconf->CarrierSense |
- heth->Init.Speed |
- macconf->ReceiveOwn |
- macconf->LoopbackMode |
- heth->Init.DuplexMode |
- macconf->ChecksumOffload |
- macconf->RetryTransmission |
- macconf->AutomaticPadCRCStrip |
- macconf->BackOffLimit |
- macconf->DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Write to ETHERNET MACFFR */
- heth->Instance->MACFFR = (uint32_t)(
- macconf->ReceiveAll |
- macconf->SourceAddrFilter |
- macconf->PassControlFrames |
- macconf->BroadcastFramesReception |
- macconf->DestinationAddrFilter |
- macconf->PromiscuousMode |
- macconf->MulticastFramesFilter |
- macconf->UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACFFR = tmpreg;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
- /* Write to ETHERNET MACHTHR */
- heth->Instance->MACHTHR = (uint32_t)macconf->HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- heth->Instance->MACHTLR = (uint32_t)macconf->HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration --------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg = heth->Instance->MACFCR;
- /* Clear xx bits */
- tmpreg &= ETH_MACFCR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)((
- macconf->PauseTime << 16) |
- macconf->ZeroQuantaPause |
- macconf->PauseLowThreshold |
- macconf->UnicastPauseFrameDetect |
- macconf->ReceiveFlowControl |
- macconf->TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- prvWriteMACFCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
- heth->Instance->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
- macconf->VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACVLANTR = tmpreg;
- }
- else /* macconf == NULL : here we just configure Speed and Duplex mode */
- {
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
-
- /* Clear FES and DM bits */
- tmpreg &= ~((uint32_t)0x00004800);
-
- tmpreg |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
- }
-
- /* Set the ETH state to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Sets ETH DMA Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param dmaconf: DMA Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
-{
- uint32_t tmpreg = 0;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State= HAL_ETH_STATE_BUSY;
-
- /* Check parameters */
- assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
- assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
- assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
- assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
- assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
- assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
- assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
- assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
- assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
- assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
- assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
- assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
- assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
- assert_param(IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(dmaconf->EnhancedDescriptorFormat));
- assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
- assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
-
- /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
- /* Get the ETHERNET DMAOMR value */
- tmpreg = heth->Instance->DMAOMR;
- /* Clear xx bits */
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)(
- dmaconf->DropTCPIPChecksumErrorFrame |
- dmaconf->ReceiveStoreForward |
- dmaconf->FlushReceivedFrame |
- dmaconf->TransmitStoreForward |
- dmaconf->TransmitThresholdControl |
- dmaconf->ForwardErrorFrames |
- dmaconf->ForwardUndersizedGoodFrames |
- dmaconf->ReceiveThresholdControl |
- dmaconf->SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- prvWriteDMAOMR( heth, tmpreg );
-
- /*----------------------- ETHERNET DMABMR Configuration --------------------*/
- heth->Instance->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
- dmaconf->FixedBurst |
- dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmaconf->TxDMABurstLength |
- dmaconf->EnhancedDescriptorFormat |
- (dmaconf->DescriptorSkipLength << 2) |
- dmaconf->DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->DMABMR = tmpreg;
-
- /* Set the ETH state to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
- (+) Get the ETH handle state:
- HAL_ETH_GetState();
-
-
- @endverbatim
- * @{
- */
-
-/**
- * @brief Return the ETH HAL state
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL state
- */
-HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
-{
- /* Return ETH state */
- return heth->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup ETH_Private_Functions
- * @{
- */
-
-/**
- * @brief Configures Ethernet MAC and DMA with default parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param err: Ethernet Init error
- * @retval HAL status
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
-{
- ETH_MACInitTypeDef macinit;
- ETH_DMAInitTypeDef dmainit;
- uint32_t tmpreg = 0;
-
- if (err != ETH_SUCCESS) /* Auto-negotiation failed */
- {
- /* Set Ethernet duplex mode to Full-duplex */
- heth->Init.DuplexMode = ETH_MODE_FULLDUPLEX;
-
- /* Set Ethernet speed to 100M */
- heth->Init.Speed = ETH_SPEED_100M;
- }
-
- /* Ethernet MAC default initialization **************************************/
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;
- macinit.Jabber = ETH_JABBER_ENABLE;
- macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
- macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
- macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
- if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
- }
- else
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
- }
- macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
- macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
- macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
- macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
- macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
- macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
- macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
- macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
- macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
- macinit.HashTableHigh = 0x0;
- macinit.HashTableLow = 0x0;
- macinit.PauseTime = 0x0;
- macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
- macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
- macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
- macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
- macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
- macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
- macinit.VLANTagIdentifier = 0x0;
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg &= ETH_MACCR_CLEAR_MASK;
- /* Set the WD bit according to ETH Watchdog value */
- /* Set the JD: bit according to ETH Jabber value */
- /* Set the IFG bit according to ETH InterFrameGap value */
- /* Set the DCRS bit according to ETH CarrierSense value */
- /* Set the FES bit according to ETH Speed value */
- /* Set the DO bit according to ETH ReceiveOwn value */
- /* Set the LM bit according to ETH LoopbackMode value */
- /* Set the DM bit according to ETH Mode value */
- /* Set the IPCO bit according to ETH ChecksumOffload value */
- /* Set the DR bit according to ETH RetryTransmission value */
- /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
- /* Set the BL bit according to ETH BackOffLimit value */
- /* Set the DC bit according to ETH DeferralCheck value */
- tmpreg |= (uint32_t)(macinit.Watchdog |
- macinit.Jabber |
- macinit.InterFrameGap |
- macinit.CarrierSense |
- heth->Init.Speed |
- macinit.ReceiveOwn |
- macinit.LoopbackMode |
- heth->Init.DuplexMode |
- macinit.ChecksumOffload |
- macinit.RetryTransmission |
- macinit.AutomaticPadCRCStrip |
- macinit.BackOffLimit |
- macinit.DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Set the RA bit according to ETH ReceiveAll value */
- /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
- /* Set the PCF bit according to ETH PassControlFrames value */
- /* Set the DBF bit according to ETH BroadcastFramesReception value */
- /* Set the DAIF bit according to ETH DestinationAddrFilter value */
- /* Set the PR bit according to ETH PromiscuousMode value */
- /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
- /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
- /* Write to ETHERNET MACFFR */
- heth->Instance->MACFFR = (uint32_t)(macinit.ReceiveAll |
- macinit.SourceAddrFilter |
- macinit.PassControlFrames |
- macinit.BroadcastFramesReception |
- macinit.DestinationAddrFilter |
- macinit.PromiscuousMode |
- macinit.MulticastFramesFilter |
- macinit.UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACFFR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACFFR = tmpreg;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
- /* Write to ETHERNET MACHTHR */
- heth->Instance->MACHTHR = (uint32_t)macinit.HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- heth->Instance->MACHTLR = (uint32_t)macinit.HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration -------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg = heth->Instance->MACFCR;
- /* Clear xx bits */
- tmpreg &= ETH_MACFCR_CLEAR_MASK;
-
- /* Set the PT bit according to ETH PauseTime value */
- /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
- /* Set the PLT bit according to ETH PauseLowThreshold value */
- /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
- /* Set the RFE bit according to ETH ReceiveFlowControl value */
- /* Set the TFE bit according to ETH TransmitFlowControl value */
- tmpreg |= (uint32_t)((macinit.PauseTime << 16) |
- macinit.ZeroQuantaPause |
- macinit.PauseLowThreshold |
- macinit.UnicastPauseFrameDetect |
- macinit.ReceiveFlowControl |
- macinit.TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- prvWriteMACFCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
- /* Set the ETV bit according to ETH VLANTagComparison value */
- /* Set the VL bit according to ETH VLANTagIdentifier value */
- heth->Instance->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
- macinit.VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACVLANTR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->MACVLANTR = tmpreg;
-
- /* Ethernet DMA default initialization ************************************/
- dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
- dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
- dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
- dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
- dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
- dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
- dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
- dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
- dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
- dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
- dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
- dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
- dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
- dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
- dmainit.DescriptorSkipLength = 0x0;
- dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
-
- /* Get the ETHERNET DMAOMR value */
- tmpreg = heth->Instance->DMAOMR;
- /* Clear xx bits */
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;
-
- /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
- /* Set the RSF bit according to ETH ReceiveStoreForward value */
- /* Set the DFF bit according to ETH FlushReceivedFrame value */
- /* Set the TSF bit according to ETH TransmitStoreForward value */
- /* Set the TTC bit according to ETH TransmitThresholdControl value */
- /* Set the FEF bit according to ETH ForwardErrorFrames value */
- /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
- /* Set the RTC bit according to ETH ReceiveThresholdControl value */
- /* Set the OSF bit according to ETH SecondFrameOperate value */
- tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
- dmainit.ReceiveStoreForward |
- dmainit.FlushReceivedFrame |
- dmainit.TransmitStoreForward |
- dmainit.TransmitThresholdControl |
- dmainit.ForwardErrorFrames |
- dmainit.ForwardUndersizedGoodFrames |
- dmainit.ReceiveThresholdControl |
- dmainit.SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- prvWriteDMAOMR( heth, tmpreg );
-
- /*----------------------- ETHERNET DMABMR Configuration ------------------*/
- /* Set the AAL bit according to ETH AddressAlignedBeats value */
- /* Set the FB bit according to ETH FixedBurst value */
- /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
- /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
- /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
- /* Set the DSL bit according to ETH DesciptorSkipLength value */
- /* Set the PR and DA bits according to ETH DMAArbitration value */
- heth->Instance->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
- dmainit.FixedBurst |
- dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmainit.TxDMABurstLength |
- dmainit.EnhancedDescriptorFormat |
- (dmainit.DescriptorSkipLength << 2) |
- dmainit.DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->DMABMR;
- HAL_Delay(ETH_REG_WRITE_DELAY);
- heth->Instance->DMABMR = tmpreg;
-
- if(heth->Init.RxMode == ETH_RXINTERRUPT_MODE)
- {
- /* Enable the Ethernet Rx Interrupt */
- __HAL_ETH_DMA_ENABLE_IT(( heth ), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
- }
-
- /* Initialize MAC address in ethernet MAC */
- ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
-}
-
-/**
- * @brief Configures the selected MAC address.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param MacAddr: The MAC address to configure
- * This parameter can be one of the following values:
- * @arg ETH_MAC_Address0: MAC Address0
- * @arg ETH_MAC_Address1: MAC Address1
- * @arg ETH_MAC_Address2: MAC Address2
- * @arg ETH_MAC_Address3: MAC Address3
- * @param Addr: Pointer to MAC address buffer data (6 bytes)
- * @retval HAL status
- */
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
-{
- uint32_t tmpreg;
-
- /* Check the parameters */
- assert_param( IS_ETH_MAC_ADDRESS0123( MacAddr ) );
-
- /* Calculate the selected MAC address high register */
- tmpreg = 0x80000000ul | ( ( uint32_t )Addr[ 5 ] << 8) | (uint32_t)Addr[ 4 ];
- /* Load the selected MAC address high register */
- ( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg;
- /* Calculate the selected MAC address low register */
- tmpreg = ( ( uint32_t )Addr[ 3 ] << 24 ) | ( ( uint32_t )Addr[ 2 ] << 16 ) | ( ( uint32_t )Addr[ 1 ] << 8 ) | Addr[ 0 ];
-
- /* Load the selected MAC address low register */
- ( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + MacAddr ) ) ) = tmpreg;
-}
-
-/**
- * @brief Enables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_TE;
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_TE );
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_RE;
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_RE );
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA transmission */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_ST;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA transmission */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_ST );
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA reception */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_SR;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA reception */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_SR );
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Clears the ETHERNET transmit FIFO.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
-{
- /* Set the Flush Transmit FIFO bit */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_FTF;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @}
- */
-
-#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
-#endif /* HAL_ETH_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.h
deleted file mode 100644
index 93b9caff0..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f4xx_hal_eth.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
- * a single module that works for both parts: "stm32fxx_hal_eth"
- */
-
-#include "stm32fxx_hal_eth.h"
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f7xx_hal_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f7xx_hal_eth.h
deleted file mode 100644
index 93b9caff0..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32f7xx_hal_eth.h
+++ /dev/null
@@ -1,6 +0,0 @@
-/*
- * The Ethernet header files for STM32F2, STM32F4 and STM32F7 have been merged to
- * a single module that works for both parts: "stm32fxx_hal_eth"
- */
-
-#include "stm32fxx_hal_eth.h"
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c
deleted file mode 100644
index dad16aaf8..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.c
+++ /dev/null
@@ -1,1468 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32fxx_hal_eth.c
- * @author MCD Application Team
- * @version V1.3.2
- * @date 26-June-2015
- * @brief ETH HAL module driver.
- * This file provides firmware functions to manage the following
- * functionalities of the Ethernet (ETH) peripheral:
- * + Initialization and de-initialization functions
- * + IO operation functions
- * + Peripheral Control functions
- * + Peripheral State and Errors functions
- *
- @verbatim
- ==============================================================================
- ##### How to use this driver #####
- ==============================================================================
- [..]
- (#)Declare a ETH_HandleTypeDef handle structure, for example:
- ETH_HandleTypeDef heth;
-
- (#)Fill parameters of Init structure in heth handle
-
- (#)Call HAL_ETH_Init() API to initialize the Ethernet peripheral (MAC, DMA, ...)
-
- (#)Initialize the ETH low level resources through the HAL_ETH_MspInit() API:
- (##) Enable the Ethernet interface clock using
- (+++) __HAL_RCC_ETHMAC_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACTX_CLK_ENABLE();
- (+++) __HAL_RCC_ETHMACRX_CLK_ENABLE();
-
- (##) Initialize the related GPIO clocks
- (##) Configure Ethernet pin-out
- (##) Configure Ethernet NVIC interrupt (IT mode)
-
- (#)Initialize Ethernet DMA Descriptors in chain mode and point to allocated buffers:
- (##) HAL_ETH_DMATxDescListInit(); for Transmission process
- (##) HAL_ETH_DMARxDescListInit(); for Reception process
-
- (#)Enable MAC and DMA transmission and reception:
- (##) HAL_ETH_Start();
-
- (#)Prepare ETH DMA TX Descriptors and give the hand to ETH DMA to transfer
- the frame to MAC TX FIFO:
- (##) HAL_ETH_TransmitFrame();
-
- (#)Poll for a received frame in ETH RX DMA Descriptors and get received
- frame parameters
- (##) HAL_ETH_GetReceivedFrame(); (should be called into an infinite loop)
-
- (#) Get a received frame when an ETH RX interrupt occurs:
- (##) HAL_ETH_GetReceivedFrame_IT(); (called in IT mode only)
-
- (#) Communicate with external PHY device:
- (##) Read a specific register from the PHY
- HAL_ETH_ReadPHYRegister();
- (##) Write data to a specific RHY register:
- HAL_ETH_WritePHYRegister();
-
- (#) Configure the Ethernet MAC after ETH peripheral initialization
- HAL_ETH_ConfigMAC(); all MAC parameters should be filled.
-
- (#) Configure the Ethernet DMA after ETH peripheral initialization
- HAL_ETH_ConfigDMA(); all DMA parameters should be filled.
-
- -@- The PTP protocol and the DMA descriptors ring mode are not supported
- in this driver
-
- @endverbatim
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2015 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Includes ------------------------------------------------------------------*/
-
-#if defined(STM32F7xx)
- #include "stm32f7xx_hal.h"
- #define stm_is_F7 1
-#elif defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
- #include "stm32f4xx_hal.h"
- #define stm_is_F4 1
-#elif defined(STM32F2xx)
- #include "stm32f2xx_hal.h"
- #define stm_is_F2 1
-#else
- #error For what part should this be compiled?
-#endif
-
-#include "stm32fxx_hal_eth.h"
-
-/** @addtogroup STM32F4xx_HAL_Driver
- * @{
- */
-
-/** @defgroup ETH ETH
- * @brief ETH HAL module driver
- * @{
- */
-
-#if !defined( ARRAY_SIZE )
- #define ARRAY_SIZE( x ) ( sizeof ( x ) / sizeof ( x )[ 0 ] )
-#endif
-
-#ifdef HAL_ETH_MODULE_ENABLED
-
-#if( stm_is_F2 != 0 || stm_is_F4 != 0 || stm_is_F7 )
-
-/* Private typedef -----------------------------------------------------------*/
-/* Private define ------------------------------------------------------------*/
-/** @defgroup ETH_Private_Constants ETH Private Constants
- * @{
- */
-
-/**
- * @}
- */
-/* Private macro -------------------------------------------------------------*/
-/* Private variables ---------------------------------------------------------*/
-/* Private function prototypes -----------------------------------------------*/
-/** @defgroup ETH_Private_Functions ETH Private Functions
- * @{
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err);
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr);
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth);
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth);
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth);
-
-/**
- * @}
- */
-/* Private functions ---------------------------------------------------------*/
-
-/** @defgroup ETH_Exported_Functions ETH Exported Functions
- * @{
- */
-
-/** @defgroup ETH_Exported_Functions_Group1 Initialization and de-initialization functions
- * @brief Initialization and Configuration functions
- *
- @verbatim
- ===============================================================================
- ##### Initialization and de-initialization functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Initialize and configure the Ethernet peripheral
- (+) De-initialize the Ethernet peripheral
-
- @endverbatim
- * @{
- */
-extern void vMACBProbePhy ( void );
-
-/**
- * @brief Initializes the Ethernet MAC and DMA according to default
- * parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = 0uL;
- uint32_t hclk = 60000000uL;
- uint32_t err = ETH_SUCCESS;
-
- /* Check the ETH peripheral state */
- if( heth == NULL )
- {
- return HAL_ERROR;
- }
-
- /* Check parameters */
- assert_param(IS_ETH_AUTONEGOTIATION(heth->Init.AutoNegotiation));
- assert_param(IS_ETH_RX_MODE(heth->Init.RxMode));
- assert_param(IS_ETH_CHECKSUM_MODE(heth->Init.ChecksumMode));
- assert_param(IS_ETH_MEDIA_INTERFACE(heth->Init.MediaInterface));
-
- if( heth->State == HAL_ETH_STATE_RESET )
- {
- /* Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspInit( heth );
- }
-
- /* Enable SYSCFG Clock */
- __HAL_RCC_SYSCFG_CLK_ENABLE();
-
- /* Select MII or RMII Mode*/
- SYSCFG->PMC &= ~(SYSCFG_PMC_MII_RMII_SEL);
- SYSCFG->PMC |= (uint32_t)heth->Init.MediaInterface;
-
- /* Ethernet Software reset */
- /* Set the SWR bit: resets all MAC subsystem internal registers and logic */
- /* After reset all the registers holds their respective reset values */
- /* Also enable EDFE: Enhanced descriptor format enable. */
- heth->Instance->DMABMR |= ETH_DMABMR_SR | ETH_DMABMR_EDE;
-
- /* Wait for software reset */
- while ((heth->Instance->DMABMR & ETH_DMABMR_SR) != (uint32_t)RESET)
- {
- /* If your program hangs here, please check the value of 'ipconfigUSE_RMII'. */
- }
-
- /*-------------------------------- MAC Initialization ----------------------*/
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
- /* Clear CSR Clock Range CR[2:0] bits */
- tmpreg &= ETH_MACMIIAR_CR_MASK;
-
- /* Get hclk frequency value (e.g. 168,000,000) */
- hclk = HAL_RCC_GetHCLKFreq();
-
- /* Set CR bits depending on hclk value */
- if(( hclk >= 20000000uL ) && ( hclk < 35000000uL ) )
- {
- /* CSR Clock Range between 20-35 MHz */
- tmpreg |= ( uint32_t) ETH_MACMIIAR_CR_Div16;
- }
- else if( ( hclk >= 35000000uL ) && ( hclk < 60000000uL ) )
- {
- /* CSR Clock Range between 35-60 MHz */
- tmpreg |= ( uint32_t ) ETH_MACMIIAR_CR_Div26;
- }
- else if( ( hclk >= 60000000uL ) && ( hclk < 100000000uL ) )
- {
- /* CSR Clock Range between 60-100 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div42;
- }
- else if( ( hclk >= 100000000uL ) && ( hclk < 150000000uL ) )
- {
- /* CSR Clock Range between 100-150 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div62;
- }
- else /* ( ( hclk >= 150000000uL ) && ( hclk <= 183000000uL ) ) */
- {
- /* CSR Clock Range between 150-183 MHz */
- tmpreg |= (uint32_t)ETH_MACMIIAR_CR_Div102;
- }
-
- /* Write to ETHERNET MAC MIIAR: Configure the ETHERNET CSR Clock Range */
- heth->Instance->MACMIIAR = (uint32_t)tmpreg;
-
- /* Initialise the MACB and set all PHY properties */
- vMACBProbePhy();
-
- /* Config MAC and DMA */
- ETH_MACDMAConfig(heth, err);
-
- /* Set ETH HAL State to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief De-Initializes the ETH peripheral.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth)
-{
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* De-Init the low level hardware : GPIO, CLOCK, NVIC. */
- HAL_ETH_MspDeInit( heth );
-
- /* Set ETH HAL state to Disabled */
- heth->State= HAL_ETH_STATE_RESET;
-
- /* Release Lock */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Initializes the ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspInit(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspInit could be implemented in the user file
- */
- ( void ) heth;
-}
-
-/**
- * @brief DeInitializes ETH MSP.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_MspDeInit could be implemented in the user file
- */
- ( void ) heth;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group2 IO operation functions
- * @brief Data transfers functions
- *
- @verbatim
- ==============================================================================
- ##### IO operation functions #####
- ==============================================================================
- [..] This section provides functions allowing to:
- (+) Transmit a frame
- HAL_ETH_TransmitFrame();
- (+) Receive a frame
- HAL_ETH_GetReceivedFrame();
- HAL_ETH_GetReceivedFrame_IT();
- (+) Read from an External PHY register
- HAL_ETH_ReadPHYRegister();
- (+) Write to an External PHY register
- HAL_ETH_WritePHYRegister();
-
- @endverbatim
-
- * @{
- */
-
-#define ETH_DMA_ALL_INTS \
- ( ETH_DMA_IT_TST | ETH_DMA_IT_PMT | ETH_DMA_IT_MMC | ETH_DMA_IT_NIS | ETH_DMA_IT_AIS | ETH_DMA_IT_ER | \
- ETH_DMA_IT_FBE | ETH_DMA_IT_ET | ETH_DMA_IT_RWT | ETH_DMA_IT_RPS | ETH_DMA_IT_RBU | ETH_DMA_IT_R | \
- ETH_DMA_IT_TU | ETH_DMA_IT_RO | ETH_DMA_IT_TJT | ETH_DMA_IT_TPS | ETH_DMA_IT_T )
-
-//#define ETH_DMA_ALL_INTS ETH_DMA_IT_RBU | ETH_DMA_FLAG_T | ETH_DMA_FLAG_AIS
-
-#define INT_MASK ( ( uint32_t ) ~ ( ETH_DMA_IT_TBU ) )
-void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth)
-{
- uint32_t dmasr;
-
- dmasr = heth->Instance->DMASR & ETH_DMA_ALL_INTS;
- heth->Instance->DMASR = dmasr;
-
- /* Frame received */
- if( ( dmasr & ( ETH_DMA_FLAG_R | ETH_DMA_IT_RBU ) ) != 0 )
- {
- /* Receive complete callback */
- HAL_ETH_RxCpltCallback( heth );
- }
- /* Frame transmitted */
- if( ( dmasr & ( ETH_DMA_FLAG_T ) ) != 0 )
- {
- /* Transfer complete callback */
- HAL_ETH_TxCpltCallback( heth );
- }
-
- /* ETH DMA Error */
- if( ( dmasr & ( ETH_DMA_FLAG_AIS ) ) != 0 )
- {
- /* Ethernet Error callback */
- HAL_ETH_ErrorCallback( heth );
- }
-}
-
-/**
- * @brief Tx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
- ( void ) heth;
-}
-
-/**
- * @brief Rx Transfer completed callbacks.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
- ( void ) heth;
-}
-
-/**
- * @brief Ethernet transfer error callbacks
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-__weak void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth)
-{
- /* NOTE : This function Should not be modified, when the callback is needed,
- the HAL_ETH_TxCpltCallback could be implemented in the user file
- */
- ( void ) heth;
-}
-
-/**
- * @brief Reads a PHY register
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Basic Control Register,
- * PHY_BSR: Transceiver Basic Status Register.
- * More PHY register could be read depending on the used PHY
- * @param RegValue: PHY register value
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue)
-{
-uint32_t tmpreg = 0uL;
-uint32_t tickstart = 0uL;
-HAL_StatusTypeDef xResult;
-
- /* Check parameters */
- assert_param(IS_ETH_PHY_ADDRESS(heth->Init.PhyAddress));
-
- /* Check the ETH peripheral state */
- if( heth->State == HAL_ETH_STATE_BUSY_RD )
- {
- xResult = HAL_BUSY;
- }
- else
- {
- __HAL_LOCK( heth );
-
- /* Set ETH HAL State to BUSY_RD */
- heth->State = HAL_ETH_STATE_BUSY_RD;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII address register value */
- tmpreg |= ( ( ( uint32_t )heth->Init.PhyAddress << 11) & ETH_MACMIIAR_PA ); /* Set the PHY device address */
- tmpreg |= ( ( ( uint32_t )PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */
- tmpreg &= ~ETH_MACMIIAR_MW; /* Set the read mode */
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while( 1 )
- {
- tmpreg = heth->Instance->MACMIIAR;
-
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0uL )
- {
- /* Get MACMIIDR value */
- *RegValue = ( uint32_t ) heth->Instance->MACMIIDR;
- xResult = HAL_OK;
- break;
- }
- /* Check for the Timeout */
- if( ( HAL_GetTick( ) - tickstart ) > PHY_READ_TO )
- {
- xResult = HAL_TIMEOUT;
- break;
- }
-
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
- }
-
- /* Return function status */
- return xResult;
-}
-
-/**
- * @brief Writes to a PHY register.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param PHYReg: PHY register address, is the index of one of the 32 PHY register.
- * This parameter can be one of the following values:
- * PHY_BCR: Transceiver Control Register.
- * More PHY register could be written depending on the used PHY
- * @param RegValue: the value to write
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue)
-{
-uint32_t tmpreg = 0;
-uint32_t tickstart = 0;
-HAL_StatusTypeDef xResult;
-
- /* Check parameters */
- assert_param( IS_ETH_PHY_ADDRESS( heth->Init.PhyAddress ) );
-
- /* Check the ETH peripheral state */
- if( heth->State == HAL_ETH_STATE_BUSY_WR )
- {
- xResult = HAL_BUSY;
- }
- else
- {
- __HAL_LOCK( heth );
-
- /* Set ETH HAL State to BUSY_WR */
- heth->State = HAL_ETH_STATE_BUSY_WR;
-
- /* Get the ETHERNET MACMIIAR value */
- tmpreg = heth->Instance->MACMIIAR;
-
- /* Keep only the CSR Clock Range CR[2:0] bits value */
- tmpreg &= ~ETH_MACMIIAR_CR_MASK;
-
- /* Prepare the MII register address value */
- tmpreg |= ( ( ( uint32_t ) heth->Init.PhyAddress << 11 ) & ETH_MACMIIAR_PA ); /* Set the PHY device address */
- tmpreg |= ( ( ( uint32_t ) PHYReg << 6 ) & ETH_MACMIIAR_MR ); /* Set the PHY register address */
- tmpreg |= ETH_MACMIIAR_MW; /* Set the write mode */
- tmpreg |= ETH_MACMIIAR_MB; /* Set the MII Busy bit */
-
- /* Give the value to the MII data register */
- heth->Instance->MACMIIDR = ( uint16_t ) RegValue;
-
- /* Write the result value into the MII Address register */
- heth->Instance->MACMIIAR = tmpreg;
-
- /* Get tick */
- tickstart = HAL_GetTick();
-
- /* Check for the Busy flag */
- while( 1 )
- {
- tmpreg = heth->Instance->MACMIIAR;
-
- if( ( tmpreg & ETH_MACMIIAR_MB ) == 0ul )
- {
- xResult = HAL_OK;
- break;
- }
- /* Check for the Timeout */
- if( ( HAL_GetTick( ) - tickstart ) > PHY_WRITE_TO )
- {
- xResult = HAL_TIMEOUT;
- break;
- }
- }
-
- /* Set ETH HAL State to READY */
- heth->State = HAL_ETH_STATE_READY;
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
- }
-
- /* Return function status */
- return xResult;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group3 Peripheral Control functions
- * @brief Peripheral Control functions
- *
-@verbatim
- ===============================================================================
- ##### Peripheral Control functions #####
- ===============================================================================
- [..] This section provides functions allowing to:
- (+) Enable MAC and DMA transmission and reception.
- HAL_ETH_Start();
- (+) Disable MAC and DMA transmission and reception.
- HAL_ETH_Stop();
- (+) Set the MAC configuration in runtime mode
- HAL_ETH_ConfigMAC();
- (+) Set the DMA configuration in runtime mode
- HAL_ETH_ConfigDMA();
-
-@endverbatim
- * @{
- */
-
- /**
- * @brief Enables Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Start( ETH_HandleTypeDef *heth )
-{
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Enable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionEnable( heth );
-
- /* Enable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionEnable( heth );
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO( heth );
-
- /* Start DMA transmission */
- ETH_DMATransmissionEnable( heth );
-
- /* Start DMA reception */
- ETH_DMAReceptionEnable( heth );
-
- /* Set the ETH state to READY*/
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Stop Ethernet MAC and DMA reception/transmission
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth)
-{
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State = HAL_ETH_STATE_BUSY;
-
- /* Stop DMA transmission */
- ETH_DMATransmissionDisable( heth );
-
- /* Stop DMA reception */
- ETH_DMAReceptionDisable( heth );
-
- /* Disable receive state machine of the MAC for reception from the MII */
- ETH_MACReceptionDisable( heth );
-
- /* Flush Transmit FIFO */
- ETH_FlushTransmitFIFO( heth );
-
- /* Disable transmit state machine of the MAC for transmission on the MII */
- ETH_MACTransmissionDisable( heth );
-
- /* Set the ETH state*/
- heth->State = HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-static void vRegisterDelay()
-{
-uint32_t uxCount;
- /*
- * Regarding the HAL delay functions, I noticed that HAL delay is being used to workaround the
- * "Successive write operations to the same register might not be fully taken into account" errata.
- * The workaround requires a delay of four TX_CLK/RX_CLK clock cycles. For a 10 Mbit connection,
- * these clocks are running at 2.5 MHz, so this delay would be at most 1.6 microseconds.
- * 180 Mhz = 288 loops
- * 168 Mhz = 269 loops
- * 100 Mhz = 160 loops
- * 84 Mhz = 134 loops
- */
- #define WAIT_TIME_NS 1600uL /* 1.6 microseconds */
- #define CPU_MAX_FREQ SystemCoreClock /* 84, 100, 168 or 180 MHz */
- uint32_t NOP_COUNT = ( WAIT_TIME_NS * ( CPU_MAX_FREQ / 1000uL ) ) / 1000000uL;
- for( uxCount = NOP_COUNT; uxCount > 0uL; uxCount-- )
- {
- __NOP();
- }
-}
-
-static void prvWriteMACFCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->MACFCR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->MACFCR;
-
- vRegisterDelay();
-
- heth->Instance->MACFCR = ulValue;
-}
-
-static void prvWriteDMAOMR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->DMAOMR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->DMAOMR;
-
- vRegisterDelay();
-
- heth->Instance->DMAOMR = ulValue;
-}
-
-static void prvWriteMACCR( ETH_HandleTypeDef *heth, uint32_t ulValue)
-{
- /* Enable the MAC transmission */
- heth->Instance->MACCR = ulValue;
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles.
- Read it back, wait a ms and */
- ( void ) heth->Instance->MACCR;
-
- vRegisterDelay();
-
- heth->Instance->MACCR = ulValue;
-}
-
-/**
- * @brief Set ETH MAC Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param macconf: MAC Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf)
-{
- uint32_t tmpreg = 0uL;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State= HAL_ETH_STATE_BUSY;
-
- assert_param(IS_ETH_SPEED(heth->Init.Speed));
- assert_param(IS_ETH_DUPLEX_MODE(heth->Init.DuplexMode));
-
- if (macconf != NULL)
- {
- /* Check the parameters */
- assert_param(IS_ETH_WATCHDOG(macconf->Watchdog));
- assert_param(IS_ETH_JABBER(macconf->Jabber));
- assert_param(IS_ETH_INTER_FRAME_GAP(macconf->InterFrameGap));
- assert_param(IS_ETH_CARRIER_SENSE(macconf->CarrierSense));
- assert_param(IS_ETH_RECEIVE_OWN(macconf->ReceiveOwn));
- assert_param(IS_ETH_LOOPBACK_MODE(macconf->LoopbackMode));
- assert_param(IS_ETH_CHECKSUM_OFFLOAD(macconf->ChecksumOffload));
- assert_param(IS_ETH_RETRY_TRANSMISSION(macconf->RetryTransmission));
- assert_param(IS_ETH_AUTOMATIC_PADCRC_STRIP(macconf->AutomaticPadCRCStrip));
- assert_param(IS_ETH_BACKOFF_LIMIT(macconf->BackOffLimit));
- assert_param(IS_ETH_DEFERRAL_CHECK(macconf->DeferralCheck));
- assert_param(IS_ETH_RECEIVE_ALL(macconf->ReceiveAll));
- assert_param(IS_ETH_SOURCE_ADDR_FILTER(macconf->SourceAddrFilter));
- assert_param(IS_ETH_CONTROL_FRAMES(macconf->PassControlFrames));
- assert_param(IS_ETH_BROADCAST_FRAMES_RECEPTION(macconf->BroadcastFramesReception));
- assert_param(IS_ETH_DESTINATION_ADDR_FILTER(macconf->DestinationAddrFilter));
- assert_param(IS_ETH_PROMISCUOUS_MODE(macconf->PromiscuousMode));
- assert_param(IS_ETH_MULTICAST_FRAMES_FILTER(macconf->MulticastFramesFilter));
- assert_param(IS_ETH_UNICAST_FRAMES_FILTER(macconf->UnicastFramesFilter));
- assert_param(IS_ETH_PAUSE_TIME(macconf->PauseTime));
- assert_param(IS_ETH_ZEROQUANTA_PAUSE(macconf->ZeroQuantaPause));
- assert_param(IS_ETH_PAUSE_LOW_THRESHOLD(macconf->PauseLowThreshold));
- assert_param(IS_ETH_UNICAST_PAUSE_FRAME_DETECT(macconf->UnicastPauseFrameDetect));
- assert_param(IS_ETH_RECEIVE_FLOWCONTROL(macconf->ReceiveFlowControl));
- assert_param(IS_ETH_TRANSMIT_FLOWCONTROL(macconf->TransmitFlowControl));
- assert_param(IS_ETH_VLAN_TAG_COMPARISON(macconf->VLANTagComparison));
- assert_param(IS_ETH_VLAN_TAG_IDENTIFIER(macconf->VLANTagIdentifier));
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg &= ETH_MACCR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)(
- macconf->Watchdog |
- macconf->Jabber |
- macconf->InterFrameGap |
- macconf->CarrierSense |
- heth->Init.Speed |
- macconf->ReceiveOwn |
- macconf->LoopbackMode |
- heth->Init.DuplexMode |
- macconf->ChecksumOffload |
- macconf->RetryTransmission |
- macconf->AutomaticPadCRCStrip |
- macconf->BackOffLimit |
- macconf->DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Write to ETHERNET MACFFR */
- heth->Instance->MACFFR = (uint32_t)(
- macconf->ReceiveAll |
- macconf->SourceAddrFilter |
- macconf->PassControlFrames |
- macconf->BroadcastFramesReception |
- macconf->DestinationAddrFilter |
- macconf->PromiscuousMode |
- macconf->MulticastFramesFilter |
- macconf->UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACFFR;
- vRegisterDelay();
- heth->Instance->MACFFR = tmpreg;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration ---------------*/
- /* Write to ETHERNET MACHTHR */
- heth->Instance->MACHTHR = (uint32_t)macconf->HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- heth->Instance->MACHTLR = (uint32_t)macconf->HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration --------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg = heth->Instance->MACFCR;
- /* Clear xx bits */
- tmpreg &= ETH_MACFCR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)((
- macconf->PauseTime << 16) |
- macconf->ZeroQuantaPause |
- macconf->PauseLowThreshold |
- macconf->UnicastPauseFrameDetect |
- macconf->ReceiveFlowControl |
- macconf->TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- prvWriteMACFCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACVLANTR Configuration -----------------*/
- heth->Instance->MACVLANTR = (uint32_t)(macconf->VLANTagComparison |
- macconf->VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account :
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACVLANTR;
- vRegisterDelay();
- heth->Instance->MACVLANTR = tmpreg;
- }
- else /* macconf == NULL : here we just configure Speed and Duplex mode */
- {
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
-
- /* Clear FES and DM bits */
- tmpreg &= ~( ( uint32_t ) 0x00004800uL );
-
- tmpreg |= (uint32_t)(heth->Init.Speed | heth->Init.DuplexMode);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
- }
-
- /* Set the ETH state to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @brief Sets ETH DMA Configuration.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param dmaconf: DMA Configuration structure
- * @retval HAL status
- */
-HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf)
-{
- uint32_t tmpreg = 0uL;
-
- /* Process Locked */
- __HAL_LOCK( heth );
-
- /* Set the ETH peripheral state to BUSY */
- heth->State= HAL_ETH_STATE_BUSY;
-
- /* Check parameters */
- assert_param(IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(dmaconf->DropTCPIPChecksumErrorFrame));
- assert_param(IS_ETH_RECEIVE_STORE_FORWARD(dmaconf->ReceiveStoreForward));
- assert_param(IS_ETH_FLUSH_RECEIVE_FRAME(dmaconf->FlushReceivedFrame));
- assert_param(IS_ETH_TRANSMIT_STORE_FORWARD(dmaconf->TransmitStoreForward));
- assert_param(IS_ETH_TRANSMIT_THRESHOLD_CONTROL(dmaconf->TransmitThresholdControl));
- assert_param(IS_ETH_FORWARD_ERROR_FRAMES(dmaconf->ForwardErrorFrames));
- assert_param(IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(dmaconf->ForwardUndersizedGoodFrames));
- assert_param(IS_ETH_RECEIVE_THRESHOLD_CONTROL(dmaconf->ReceiveThresholdControl));
- assert_param(IS_ETH_SECOND_FRAME_OPERATE(dmaconf->SecondFrameOperate));
- assert_param(IS_ETH_ADDRESS_ALIGNED_BEATS(dmaconf->AddressAlignedBeats));
- assert_param(IS_ETH_FIXED_BURST(dmaconf->FixedBurst));
- assert_param(IS_ETH_RXDMA_BURST_LENGTH(dmaconf->RxDMABurstLength));
- assert_param(IS_ETH_TXDMA_BURST_LENGTH(dmaconf->TxDMABurstLength));
- assert_param(IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(dmaconf->EnhancedDescriptorFormat));
- assert_param(IS_ETH_DMA_DESC_SKIP_LENGTH(dmaconf->DescriptorSkipLength));
- assert_param(IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(dmaconf->DMAArbitration));
-
- /*----------------------- ETHERNET DMAOMR Configuration --------------------*/
- /* Get the ETHERNET DMAOMR value */
- tmpreg = heth->Instance->DMAOMR;
- /* Clear xx bits */
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;
-
- tmpreg |= (uint32_t)(
- dmaconf->DropTCPIPChecksumErrorFrame |
- dmaconf->ReceiveStoreForward |
- dmaconf->FlushReceivedFrame |
- dmaconf->TransmitStoreForward |
- dmaconf->TransmitThresholdControl |
- dmaconf->ForwardErrorFrames |
- dmaconf->ForwardUndersizedGoodFrames |
- dmaconf->ReceiveThresholdControl |
- dmaconf->SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- prvWriteDMAOMR( heth, tmpreg );
-
- /*----------------------- ETHERNET DMABMR Configuration --------------------*/
- heth->Instance->DMABMR = (uint32_t)(dmaconf->AddressAlignedBeats |
- dmaconf->FixedBurst |
- dmaconf->RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmaconf->TxDMABurstLength |
- dmaconf->EnhancedDescriptorFormat |
- (dmaconf->DescriptorSkipLength << 2) |
- dmaconf->DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->DMABMR;
- vRegisterDelay();
- heth->Instance->DMABMR = tmpreg;
-
- /* Set the ETH state to Ready */
- heth->State= HAL_ETH_STATE_READY;
-
- /* Process Unlocked */
- __HAL_UNLOCK( heth );
-
- /* Return function status */
- return HAL_OK;
-}
-
-/**
- * @}
- */
-
-/** @defgroup ETH_Exported_Functions_Group4 Peripheral State functions
- * @brief Peripheral State functions
- *
- @verbatim
- ===============================================================================
- ##### Peripheral State functions #####
- ===============================================================================
- [..]
- This subsection permits to get in run-time the status of the peripheral
- and the data flow.
- (+) Get the ETH handle state:
- HAL_ETH_GetState();
-
-
- @endverbatim
- * @{
- */
-
-/**
- * @brief Return the ETH HAL state
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval HAL state
- */
-HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth)
-{
- /* Return ETH state */
- return heth->State;
-}
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/** @addtogroup ETH_Private_Functions
- * @{
- */
-
-/**
- * @brief Configures Ethernet MAC and DMA with default parameters.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param err: Ethernet Init error
- * @retval HAL status
- */
-static void ETH_MACDMAConfig(ETH_HandleTypeDef *heth, uint32_t err)
-{
- ETH_MACInitTypeDef macinit;
- ETH_DMAInitTypeDef dmainit;
- uint32_t tmpreg = 0uL;
-
- if (err != ETH_SUCCESS) /* Auto-negotiation failed */
- {
- /* Set Ethernet duplex mode to Full-duplex */
- heth->Init.DuplexMode = ETH_MODE_FULLDUPLEX;
-
- /* Set Ethernet speed to 100M */
- heth->Init.Speed = ETH_SPEED_100M;
- }
-
- /* Ethernet MAC default initialization **************************************/
- macinit.Watchdog = ETH_WATCHDOG_ENABLE;
- macinit.Jabber = ETH_JABBER_ENABLE;
- macinit.InterFrameGap = ETH_INTERFRAMEGAP_96BIT;
- macinit.CarrierSense = ETH_CARRIERSENCE_ENABLE;
- macinit.ReceiveOwn = ETH_RECEIVEOWN_ENABLE;
- macinit.LoopbackMode = ETH_LOOPBACKMODE_DISABLE;
- if(heth->Init.ChecksumMode == ETH_CHECKSUM_BY_HARDWARE)
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_ENABLE;
- }
- else
- {
- macinit.ChecksumOffload = ETH_CHECKSUMOFFLAOD_DISABLE;
- }
- macinit.RetryTransmission = ETH_RETRYTRANSMISSION_DISABLE;
- macinit.AutomaticPadCRCStrip = ETH_AUTOMATICPADCRCSTRIP_DISABLE;
- macinit.BackOffLimit = ETH_BACKOFFLIMIT_10;
- macinit.DeferralCheck = ETH_DEFFERRALCHECK_DISABLE;
- macinit.ReceiveAll = ETH_RECEIVEAll_DISABLE;
- macinit.SourceAddrFilter = ETH_SOURCEADDRFILTER_DISABLE;
- macinit.PassControlFrames = ETH_PASSCONTROLFRAMES_BLOCKALL;
- macinit.BroadcastFramesReception = ETH_BROADCASTFRAMESRECEPTION_ENABLE;
- macinit.DestinationAddrFilter = ETH_DESTINATIONADDRFILTER_NORMAL;
- macinit.PromiscuousMode = ETH_PROMISCUOUS_MODE_DISABLE;
- macinit.MulticastFramesFilter = ETH_MULTICASTFRAMESFILTER_PERFECT;
- macinit.UnicastFramesFilter = ETH_UNICASTFRAMESFILTER_PERFECT;
- macinit.HashTableHigh = 0x0uL;
- macinit.HashTableLow = 0x0uL;
- macinit.PauseTime = 0x0uL;
- macinit.ZeroQuantaPause = ETH_ZEROQUANTAPAUSE_DISABLE;
- macinit.PauseLowThreshold = ETH_PAUSELOWTHRESHOLD_MINUS4;
- macinit.UnicastPauseFrameDetect = ETH_UNICASTPAUSEFRAMEDETECT_DISABLE;
- macinit.ReceiveFlowControl = ETH_RECEIVEFLOWCONTROL_DISABLE;
- macinit.TransmitFlowControl = ETH_TRANSMITFLOWCONTROL_DISABLE;
- macinit.VLANTagComparison = ETH_VLANTAGCOMPARISON_16BIT;
- macinit.VLANTagIdentifier = 0x0uL;
-
- /*------------------------ ETHERNET MACCR Configuration --------------------*/
- /* Get the ETHERNET MACCR value */
- tmpreg = heth->Instance->MACCR;
- /* Clear WD, PCE, PS, TE and RE bits */
- tmpreg &= ETH_MACCR_CLEAR_MASK;
- /* Set the WD bit according to ETH Watchdog value */
- /* Set the JD: bit according to ETH Jabber value */
- /* Set the IFG bit according to ETH InterFrameGap value */
- /* Set the DCRS bit according to ETH CarrierSense value */
- /* Set the FES bit according to ETH Speed value */
- /* Set the DO bit according to ETH ReceiveOwn value */
- /* Set the LM bit according to ETH LoopbackMode value */
- /* Set the DM bit according to ETH Mode value */
- /* Set the IPCO bit according to ETH ChecksumOffload value */
- /* Set the DR bit according to ETH RetryTransmission value */
- /* Set the ACS bit according to ETH AutomaticPadCRCStrip value */
- /* Set the BL bit according to ETH BackOffLimit value */
- /* Set the DC bit according to ETH DeferralCheck value */
- tmpreg |= (uint32_t)(macinit.Watchdog |
- macinit.Jabber |
- macinit.InterFrameGap |
- macinit.CarrierSense |
- heth->Init.Speed |
- macinit.ReceiveOwn |
- macinit.LoopbackMode |
- heth->Init.DuplexMode |
- macinit.ChecksumOffload |
- macinit.RetryTransmission |
- macinit.AutomaticPadCRCStrip |
- macinit.BackOffLimit |
- macinit.DeferralCheck);
-
- /* Write to ETHERNET MACCR */
- prvWriteMACCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACFFR Configuration --------------------*/
- /* Set the RA bit according to ETH ReceiveAll value */
- /* Set the SAF and SAIF bits according to ETH SourceAddrFilter value */
- /* Set the PCF bit according to ETH PassControlFrames value */
- /* Set the DBF bit according to ETH BroadcastFramesReception value */
- /* Set the DAIF bit according to ETH DestinationAddrFilter value */
- /* Set the PR bit according to ETH PromiscuousMode value */
- /* Set the PM, HMC and HPF bits according to ETH MulticastFramesFilter value */
- /* Set the HUC and HPF bits according to ETH UnicastFramesFilter value */
- /* Write to ETHERNET MACFFR */
- heth->Instance->MACFFR = (uint32_t)(macinit.ReceiveAll |
- macinit.SourceAddrFilter |
- macinit.PassControlFrames |
- macinit.BroadcastFramesReception |
- macinit.DestinationAddrFilter |
- macinit.PromiscuousMode |
- macinit.MulticastFramesFilter |
- macinit.UnicastFramesFilter);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACFFR;
- vRegisterDelay();
- heth->Instance->MACFFR = tmpreg;
-
- /*--------------- ETHERNET MACHTHR and MACHTLR Configuration --------------*/
- /* Write to ETHERNET MACHTHR */
- heth->Instance->MACHTHR = (uint32_t)macinit.HashTableHigh;
-
- /* Write to ETHERNET MACHTLR */
- heth->Instance->MACHTLR = (uint32_t)macinit.HashTableLow;
- /*----------------------- ETHERNET MACFCR Configuration -------------------*/
-
- /* Get the ETHERNET MACFCR value */
- tmpreg = heth->Instance->MACFCR;
- /* Clear xx bits */
- tmpreg &= ETH_MACFCR_CLEAR_MASK;
-
- /* Set the PT bit according to ETH PauseTime value */
- /* Set the DZPQ bit according to ETH ZeroQuantaPause value */
- /* Set the PLT bit according to ETH PauseLowThreshold value */
- /* Set the UP bit according to ETH UnicastPauseFrameDetect value */
- /* Set the RFE bit according to ETH ReceiveFlowControl value */
- /* Set the TFE bit according to ETH TransmitFlowControl value */
- tmpreg |= (uint32_t)((macinit.PauseTime << 16) |
- macinit.ZeroQuantaPause |
- macinit.PauseLowThreshold |
- macinit.UnicastPauseFrameDetect |
- macinit.ReceiveFlowControl |
- macinit.TransmitFlowControl);
-
- /* Write to ETHERNET MACFCR */
- prvWriteMACFCR( heth, tmpreg );
-
- /*----------------------- ETHERNET MACVLANTR Configuration ----------------*/
- /* Set the ETV bit according to ETH VLANTagComparison value */
- /* Set the VL bit according to ETH VLANTagIdentifier value */
- heth->Instance->MACVLANTR = (uint32_t)(macinit.VLANTagComparison |
- macinit.VLANTagIdentifier);
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->MACVLANTR;
- vRegisterDelay();
- heth->Instance->MACVLANTR = tmpreg;
-
- /* Ethernet DMA default initialization ************************************/
- dmainit.DropTCPIPChecksumErrorFrame = ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE;
- dmainit.ReceiveStoreForward = ETH_RECEIVESTOREFORWARD_ENABLE;
- dmainit.FlushReceivedFrame = ETH_FLUSHRECEIVEDFRAME_ENABLE;
- dmainit.TransmitStoreForward = ETH_TRANSMITSTOREFORWARD_ENABLE;
- dmainit.TransmitThresholdControl = ETH_TRANSMITTHRESHOLDCONTROL_64BYTES;
- dmainit.ForwardErrorFrames = ETH_FORWARDERRORFRAMES_DISABLE;
- dmainit.ForwardUndersizedGoodFrames = ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE;
- dmainit.ReceiveThresholdControl = ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES;
- dmainit.SecondFrameOperate = ETH_SECONDFRAMEOPERARTE_ENABLE;
- dmainit.AddressAlignedBeats = ETH_ADDRESSALIGNEDBEATS_ENABLE;
- dmainit.FixedBurst = ETH_FIXEDBURST_ENABLE;
- dmainit.RxDMABurstLength = ETH_RXDMABURSTLENGTH_32BEAT;
- dmainit.TxDMABurstLength = ETH_TXDMABURSTLENGTH_32BEAT;
- dmainit.EnhancedDescriptorFormat = ETH_DMAENHANCEDDESCRIPTOR_ENABLE;
- dmainit.DescriptorSkipLength = 0x0uL;
- dmainit.DMAArbitration = ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1;
-
- /* Get the ETHERNET DMAOMR value */
- tmpreg = heth->Instance->DMAOMR;
- /* Clear xx bits */
- tmpreg &= ETH_DMAOMR_CLEAR_MASK;
-
- /* Set the DT bit according to ETH DropTCPIPChecksumErrorFrame value */
- /* Set the RSF bit according to ETH ReceiveStoreForward value */
- /* Set the DFF bit according to ETH FlushReceivedFrame value */
- /* Set the TSF bit according to ETH TransmitStoreForward value */
- /* Set the TTC bit according to ETH TransmitThresholdControl value */
- /* Set the FEF bit according to ETH ForwardErrorFrames value */
- /* Set the FUF bit according to ETH ForwardUndersizedGoodFrames value */
- /* Set the RTC bit according to ETH ReceiveThresholdControl value */
- /* Set the OSF bit according to ETH SecondFrameOperate value */
- tmpreg |= (uint32_t)(dmainit.DropTCPIPChecksumErrorFrame |
- dmainit.ReceiveStoreForward |
- dmainit.FlushReceivedFrame |
- dmainit.TransmitStoreForward |
- dmainit.TransmitThresholdControl |
- dmainit.ForwardErrorFrames |
- dmainit.ForwardUndersizedGoodFrames |
- dmainit.ReceiveThresholdControl |
- dmainit.SecondFrameOperate);
-
- /* Write to ETHERNET DMAOMR */
- prvWriteDMAOMR( heth, tmpreg );
-
- /*----------------------- ETHERNET DMABMR Configuration ------------------*/
- /* Set the AAL bit according to ETH AddressAlignedBeats value */
- /* Set the FB bit according to ETH FixedBurst value */
- /* Set the RPBL and 4*PBL bits according to ETH RxDMABurstLength value */
- /* Set the PBL and 4*PBL bits according to ETH TxDMABurstLength value */
- /* Set the Enhanced DMA descriptors bit according to ETH EnhancedDescriptorFormat value*/
- /* Set the DSL bit according to ETH DesciptorSkipLength value */
- /* Set the PR and DA bits according to ETH DMAArbitration value */
- heth->Instance->DMABMR = (uint32_t)(dmainit.AddressAlignedBeats |
- dmainit.FixedBurst |
- dmainit.RxDMABurstLength | /* !! if 4xPBL is selected for Tx or Rx it is applied for the other */
- dmainit.TxDMABurstLength |
- dmainit.EnhancedDescriptorFormat |
- (dmainit.DescriptorSkipLength << 2) |
- dmainit.DMAArbitration |
- ETH_DMABMR_USP); /* Enable use of separate PBL for Rx and Tx */
-
- /* Wait until the write operation will be taken into account:
- at least four TX_CLK/RX_CLK clock cycles */
- tmpreg = heth->Instance->DMABMR;
- vRegisterDelay();
- heth->Instance->DMABMR = tmpreg;
-
- if(heth->Init.RxMode == ETH_RXINTERRUPT_MODE)
- {
- /* Enable the Ethernet Rx Interrupt */
- __HAL_ETH_DMA_ENABLE_IT(( heth ), ETH_DMA_IT_NIS | ETH_DMA_IT_R);
- }
-
- /* Initialize MAC address in ethernet MAC */
- ETH_MACAddressConfig(heth, ETH_MAC_ADDRESS0, heth->Init.MACAddr);
-}
-
-/**
- * @brief Configures the selected MAC address.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @param MacAddr: The MAC address to configure
- * This parameter can be one of the following values:
- * @arg ETH_MAC_Address0: MAC Address0
- * @arg ETH_MAC_Address1: MAC Address1
- * @arg ETH_MAC_Address2: MAC Address2
- * @arg ETH_MAC_Address3: MAC Address3
- * @param Addr: Pointer to MAC address buffer data (6 bytes)
- * @retval HAL status
- */
-static void ETH_MACAddressConfig(ETH_HandleTypeDef *heth, uint32_t MacAddr, uint8_t *Addr)
-{
- uint32_t tmpreg;
-
- ( void ) heth;
-
- /* Check the parameters */
- assert_param( IS_ETH_MAC_ADDRESS0123( MacAddr ) );
-
- /* Calculate the selected MAC address high register */
- /* Register ETH_MACA0HR: Bit 31 MO: Always 1. */
- tmpreg = 0x80000000uL | ( ( uint32_t )Addr[ 5 ] << 8) | (uint32_t)Addr[ 4 ];
- /* Load the selected MAC address high register */
- ( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_HBASE + MacAddr ) ) ) = tmpreg;
- /* Calculate the selected MAC address low register */
- tmpreg = ( ( uint32_t )Addr[ 3 ] << 24 ) | ( ( uint32_t )Addr[ 2 ] << 16 ) | ( ( uint32_t )Addr[ 1 ] << 8 ) | Addr[ 0 ];
-
- /* Load the selected MAC address low register */
- ( * ( __IO uint32_t * ) ( ( uint32_t ) ( ETH_MAC_ADDR_LBASE + MacAddr ) ) ) = tmpreg;
-}
-
-/**
- * @brief Enables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionEnable(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_TE;
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the MAC transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACTransmissionDisable(ETH_HandleTypeDef *heth)
-{
- uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_TE );
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionEnable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg = heth->Instance->MACCR | ETH_MACCR_RE;
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the MAC reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_MACReceptionDisable(ETH_HandleTypeDef *heth)
-{
- __IO uint32_t tmpreg = heth->Instance->MACCR & ~( ETH_MACCR_RE );
-
- prvWriteMACCR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA transmission */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_ST;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the DMA transmission.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMATransmissionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA transmission */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_ST );
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Enables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionEnable(ETH_HandleTypeDef *heth)
-{
- /* Enable the DMA reception */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_SR;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Disables the DMA reception.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_DMAReceptionDisable(ETH_HandleTypeDef *heth)
-{
- /* Disable the DMA reception */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR & ~( ETH_DMAOMR_SR );
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @brief Clears the ETHERNET transmit FIFO.
- * @param heth: pointer to a ETH_HandleTypeDef structure that contains
- * the configuration information for ETHERNET module
- * @retval None
- */
-static void ETH_FlushTransmitFIFO(ETH_HandleTypeDef *heth)
-{
- /* Set the Flush Transmit FIFO bit */
- __IO uint32_t tmpreg = heth->Instance->DMAOMR | ETH_DMAOMR_FTF;
-
- prvWriteDMAOMR( heth, tmpreg );
-}
-
-/**
- * @}
- */
-#endif /* stm_is_F2 != 0 || stm_is_F4 != 0 || stm_is_F7 */
-
-#endif /* HAL_ETH_MODULE_ENABLED */
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h
deleted file mode 100644
index f91122594..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/STM32Fxx/stm32fxx_hal_eth.h
+++ /dev/null
@@ -1,2262 +0,0 @@
-/**
- ******************************************************************************
- * @file stm32fxx_hal_eth.h
- * @author MCD Application Team
- * @version V1.2.2
- * @date 14-April-2017
- * @brief Header file of ETH HAL module.
- ******************************************************************************
- * @attention
- *
- * <h2><center>&copy; COPYRIGHT(c) 2017 STMicroelectronics</center></h2>
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- * 3. Neither the name of STMicroelectronics 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
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER 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 THE POSSIBILITY OF SUCH DAMAGE.
- *
- ******************************************************************************
- */
-
-/* Define to prevent recursive inclusion -------------------------------------*/
-#ifndef __STM32Fxx_HAL_ETH_H
-#define __STM32Fxx_HAL_ETH_H
-
-/* make sure that the original ETH headers files won't be included after this. */
-#define __STM32F2xx_HAL_ETH_H
-#define __STM32F4xx_HAL_ETH_H
-#define __STM32F7xx_HAL_ETH_H
-
-#if defined(STM32F7xx)
- #include "stm32f7xx_hal_def.h"
-#elif defined(STM32F407xx) || defined(STM32F417xx) || defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
- #include "stm32f4xx_hal_def.h"
-#elif defined(STM32F2xx)
- #include "stm32f2xx_hal_def.h"
-#endif
-
-#ifdef __cplusplus
- extern "C" {
-#endif
-
-/** @addtogroup STM32Fxx_HAL_Driver
- * @{
- */
-
-/** @addtogroup ETH
- * @{
- */
-
-/** @addtogroup ETH_Private_Macros
- * @{
- */
-#define IS_ETH_PHY_ADDRESS(ADDRESS) ((ADDRESS) <= 0x20)
-#define IS_ETH_AUTONEGOTIATION(CMD) (((CMD) == ETH_AUTONEGOTIATION_ENABLE) || \
- ((CMD) == ETH_AUTONEGOTIATION_DISABLE))
-#define IS_ETH_SPEED(SPEED) (((SPEED) == ETH_SPEED_10M) || \
- ((SPEED) == ETH_SPEED_100M))
-#define IS_ETH_DUPLEX_MODE(MODE) (((MODE) == ETH_MODE_FULLDUPLEX) || \
- ((MODE) == ETH_MODE_HALFDUPLEX))
-#define IS_ETH_DUPLEX_MODE(MODE) (((MODE) == ETH_MODE_FULLDUPLEX) || \
- ((MODE) == ETH_MODE_HALFDUPLEX))
-#define IS_ETH_RX_MODE(MODE) (((MODE) == ETH_RXPOLLING_MODE) || \
- ((MODE) == ETH_RXINTERRUPT_MODE))
-#define IS_ETH_RX_MODE(MODE) (((MODE) == ETH_RXPOLLING_MODE) || \
- ((MODE) == ETH_RXINTERRUPT_MODE))
-#define IS_ETH_RX_MODE(MODE) (((MODE) == ETH_RXPOLLING_MODE) || \
- ((MODE) == ETH_RXINTERRUPT_MODE))
-#define IS_ETH_CHECKSUM_MODE(MODE) (((MODE) == ETH_CHECKSUM_BY_HARDWARE) || \
- ((MODE) == ETH_CHECKSUM_BY_SOFTWARE))
-#define IS_ETH_MEDIA_INTERFACE(MODE) (((MODE) == ETH_MEDIA_INTERFACE_MII) || \
- ((MODE) == ETH_MEDIA_INTERFACE_RMII))
-#define IS_ETH_WATCHDOG(CMD) (((CMD) == ETH_WATCHDOG_ENABLE) || \
- ((CMD) == ETH_WATCHDOG_DISABLE))
-#define IS_ETH_JABBER(CMD) (((CMD) == ETH_JABBER_ENABLE) || \
- ((CMD) == ETH_JABBER_DISABLE))
-#define IS_ETH_INTER_FRAME_GAP(GAP) (((GAP) == ETH_INTERFRAMEGAP_96BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_88BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_80BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_72BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_64BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_56BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_48BIT) || \
- ((GAP) == ETH_INTERFRAMEGAP_40BIT))
-#define IS_ETH_CARRIER_SENSE(CMD) (((CMD) == ETH_CARRIERSENCE_ENABLE) || \
- ((CMD) == ETH_CARRIERSENCE_DISABLE))
-#define IS_ETH_RECEIVE_OWN(CMD) (((CMD) == ETH_RECEIVEOWN_ENABLE) || \
- ((CMD) == ETH_RECEIVEOWN_DISABLE))
-#define IS_ETH_LOOPBACK_MODE(CMD) (((CMD) == ETH_LOOPBACKMODE_ENABLE) || \
- ((CMD) == ETH_LOOPBACKMODE_DISABLE))
-#define IS_ETH_CHECKSUM_OFFLOAD(CMD) (((CMD) == ETH_CHECKSUMOFFLAOD_ENABLE) || \
- ((CMD) == ETH_CHECKSUMOFFLAOD_DISABLE))
-#define IS_ETH_RETRY_TRANSMISSION(CMD) (((CMD) == ETH_RETRYTRANSMISSION_ENABLE) || \
- ((CMD) == ETH_RETRYTRANSMISSION_DISABLE))
-#define IS_ETH_AUTOMATIC_PADCRC_STRIP(CMD) (((CMD) == ETH_AUTOMATICPADCRCSTRIP_ENABLE) || \
- ((CMD) == ETH_AUTOMATICPADCRCSTRIP_DISABLE))
-#define IS_ETH_BACKOFF_LIMIT(LIMIT) (((LIMIT) == ETH_BACKOFFLIMIT_10) || \
- ((LIMIT) == ETH_BACKOFFLIMIT_8) || \
- ((LIMIT) == ETH_BACKOFFLIMIT_4) || \
- ((LIMIT) == ETH_BACKOFFLIMIT_1))
-#define IS_ETH_DEFERRAL_CHECK(CMD) (((CMD) == ETH_DEFFERRALCHECK_ENABLE) || \
- ((CMD) == ETH_DEFFERRALCHECK_DISABLE))
-#define IS_ETH_RECEIVE_ALL(CMD) (((CMD) == ETH_RECEIVEALL_ENABLE) || \
- ((CMD) == ETH_RECEIVEAll_DISABLE))
-#define IS_ETH_SOURCE_ADDR_FILTER(CMD) (((CMD) == ETH_SOURCEADDRFILTER_NORMAL_ENABLE) || \
- ((CMD) == ETH_SOURCEADDRFILTER_INVERSE_ENABLE) || \
- ((CMD) == ETH_SOURCEADDRFILTER_DISABLE))
-#define IS_ETH_CONTROL_FRAMES(PASS) (((PASS) == ETH_PASSCONTROLFRAMES_BLOCKALL) || \
- ((PASS) == ETH_PASSCONTROLFRAMES_FORWARDALL) || \
- ((PASS) == ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER))
-#define IS_ETH_BROADCAST_FRAMES_RECEPTION(CMD) (((CMD) == ETH_BROADCASTFRAMESRECEPTION_ENABLE) || \
- ((CMD) == ETH_BROADCASTFRAMESRECEPTION_DISABLE))
-#define IS_ETH_DESTINATION_ADDR_FILTER(FILTER) (((FILTER) == ETH_DESTINATIONADDRFILTER_NORMAL) || \
- ((FILTER) == ETH_DESTINATIONADDRFILTER_INVERSE))
-#define IS_ETH_PROMISCUOUS_MODE(CMD) (((CMD) == ETH_PROMISCUOUS_MODE_ENABLE) || \
- ((CMD) == ETH_PROMISCUOUS_MODE_DISABLE))
-#define IS_ETH_MULTICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE) || \
- ((FILTER) == ETH_MULTICASTFRAMESFILTER_HASHTABLE) || \
- ((FILTER) == ETH_MULTICASTFRAMESFILTER_PERFECT) || \
- ((FILTER) == ETH_MULTICASTFRAMESFILTER_NONE))
-#define IS_ETH_UNICAST_FRAMES_FILTER(FILTER) (((FILTER) == ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE) || \
- ((FILTER) == ETH_UNICASTFRAMESFILTER_HASHTABLE) || \
- ((FILTER) == ETH_UNICASTFRAMESFILTER_PERFECT))
-#define IS_ETH_PAUSE_TIME(TIME) ((TIME) <= 0xFFFF)
-#define IS_ETH_ZEROQUANTA_PAUSE(CMD) (((CMD) == ETH_ZEROQUANTAPAUSE_ENABLE) || \
- ((CMD) == ETH_ZEROQUANTAPAUSE_DISABLE))
-#define IS_ETH_PAUSE_LOW_THRESHOLD(THRESHOLD) (((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS4) || \
- ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS28) || \
- ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS144) || \
- ((THRESHOLD) == ETH_PAUSELOWTHRESHOLD_MINUS256))
-#define IS_ETH_UNICAST_PAUSE_FRAME_DETECT(CMD) (((CMD) == ETH_UNICASTPAUSEFRAMEDETECT_ENABLE) || \
- ((CMD) == ETH_UNICASTPAUSEFRAMEDETECT_DISABLE))
-#define IS_ETH_RECEIVE_FLOWCONTROL(CMD) (((CMD) == ETH_RECEIVEFLOWCONTROL_ENABLE) || \
- ((CMD) == ETH_RECEIVEFLOWCONTROL_DISABLE))
-#define IS_ETH_TRANSMIT_FLOWCONTROL(CMD) (((CMD) == ETH_TRANSMITFLOWCONTROL_ENABLE) || \
- ((CMD) == ETH_TRANSMITFLOWCONTROL_DISABLE))
-#define IS_ETH_VLAN_TAG_COMPARISON(COMPARISON) (((COMPARISON) == ETH_VLANTAGCOMPARISON_12BIT) || \
- ((COMPARISON) == ETH_VLANTAGCOMPARISON_16BIT))
-#define IS_ETH_VLAN_TAG_IDENTIFIER(IDENTIFIER) ((IDENTIFIER) <= 0xFFFF)
-#define IS_ETH_MAC_ADDRESS0123(ADDRESS) (((ADDRESS) == ETH_MAC_ADDRESS0) || \
- ((ADDRESS) == ETH_MAC_ADDRESS1) || \
- ((ADDRESS) == ETH_MAC_ADDRESS2) || \
- ((ADDRESS) == ETH_MAC_ADDRESS3))
-#define IS_ETH_MAC_ADDRESS123(ADDRESS) (((ADDRESS) == ETH_MAC_ADDRESS1) || \
- ((ADDRESS) == ETH_MAC_ADDRESS2) || \
- ((ADDRESS) == ETH_MAC_ADDRESS3))
-#define IS_ETH_MAC_ADDRESS_FILTER(FILTER) (((FILTER) == ETH_MAC_ADDRESSFILTER_SA) || \
- ((FILTER) == ETH_MAC_ADDRESSFILTER_DA))
-#define IS_ETH_MAC_ADDRESS_MASK(MASK) (((MASK) == ETH_MAC_ADDRESSMASK_BYTE6) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE5) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE4) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE3) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE2) || \
- ((MASK) == ETH_MAC_ADDRESSMASK_BYTE1))
-#define IS_ETH_DROP_TCPIP_CHECKSUM_FRAME(CMD) (((CMD) == ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE) || \
- ((CMD) == ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE))
-#define IS_ETH_RECEIVE_STORE_FORWARD(CMD) (((CMD) == ETH_RECEIVESTOREFORWARD_ENABLE) || \
- ((CMD) == ETH_RECEIVESTOREFORWARD_DISABLE))
-#define IS_ETH_FLUSH_RECEIVE_FRAME(CMD) (((CMD) == ETH_FLUSHRECEIVEDFRAME_ENABLE) || \
- ((CMD) == ETH_FLUSHRECEIVEDFRAME_DISABLE))
-#define IS_ETH_TRANSMIT_STORE_FORWARD(CMD) (((CMD) == ETH_TRANSMITSTOREFORWARD_ENABLE) || \
- ((CMD) == ETH_TRANSMITSTOREFORWARD_DISABLE))
-#define IS_ETH_TRANSMIT_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_64BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_128BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_192BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_256BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_40BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_32BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_24BYTES) || \
- ((THRESHOLD) == ETH_TRANSMITTHRESHOLDCONTROL_16BYTES))
-#define IS_ETH_FORWARD_ERROR_FRAMES(CMD) (((CMD) == ETH_FORWARDERRORFRAMES_ENABLE) || \
- ((CMD) == ETH_FORWARDERRORFRAMES_DISABLE))
-#define IS_ETH_FORWARD_UNDERSIZED_GOOD_FRAMES(CMD) (((CMD) == ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE) || \
- ((CMD) == ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE))
-#define IS_ETH_RECEIVE_THRESHOLD_CONTROL(THRESHOLD) (((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES) || \
- ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES) || \
- ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES) || \
- ((THRESHOLD) == ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES))
-#define IS_ETH_SECOND_FRAME_OPERATE(CMD) (((CMD) == ETH_SECONDFRAMEOPERARTE_ENABLE) || \
- ((CMD) == ETH_SECONDFRAMEOPERARTE_DISABLE))
-#define IS_ETH_ADDRESS_ALIGNED_BEATS(CMD) (((CMD) == ETH_ADDRESSALIGNEDBEATS_ENABLE) || \
- ((CMD) == ETH_ADDRESSALIGNEDBEATS_DISABLE))
-#define IS_ETH_FIXED_BURST(CMD) (((CMD) == ETH_FIXEDBURST_ENABLE) || \
- ((CMD) == ETH_FIXEDBURST_DISABLE))
-#define IS_ETH_RXDMA_BURST_LENGTH(LENGTH) (((LENGTH) == ETH_RXDMABURSTLENGTH_1BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_2BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_8BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_16BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_32BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_4BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_8BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_16BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_32BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_64BEAT) || \
- ((LENGTH) == ETH_RXDMABURSTLENGTH_4XPBL_128BEAT))
-#define IS_ETH_TXDMA_BURST_LENGTH(LENGTH) (((LENGTH) == ETH_TXDMABURSTLENGTH_1BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_2BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_8BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_16BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_32BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_4BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_8BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_16BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_32BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_64BEAT) || \
- ((LENGTH) == ETH_TXDMABURSTLENGTH_4XPBL_128BEAT))
-#define IS_ETH_DMA_DESC_SKIP_LENGTH(LENGTH) ((LENGTH) <= 0x1F)
-#define IS_ETH_DMA_ARBITRATION_ROUNDROBIN_RXTX(RATIO) (((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1) || \
- ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1) || \
- ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1) || \
- ((RATIO) == ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1) || \
- ((RATIO) == ETH_DMAARBITRATION_RXPRIORTX))
-#define IS_ETH_DMATXDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMATXDESC_OWN) || \
- ((FLAG) == ETH_DMATXDESC_IC) || \
- ((FLAG) == ETH_DMATXDESC_LS) || \
- ((FLAG) == ETH_DMATXDESC_FS) || \
- ((FLAG) == ETH_DMATXDESC_DC) || \
- ((FLAG) == ETH_DMATXDESC_DP) || \
- ((FLAG) == ETH_DMATXDESC_TTSE) || \
- ((FLAG) == ETH_DMATXDESC_TER) || \
- ((FLAG) == ETH_DMATXDESC_TCH) || \
- ((FLAG) == ETH_DMATXDESC_TTSS) || \
- ((FLAG) == ETH_DMATXDESC_IHE) || \
- ((FLAG) == ETH_DMATXDESC_ES) || \
- ((FLAG) == ETH_DMATXDESC_JT) || \
- ((FLAG) == ETH_DMATXDESC_FF) || \
- ((FLAG) == ETH_DMATXDESC_PCE) || \
- ((FLAG) == ETH_DMATXDESC_LCA) || \
- ((FLAG) == ETH_DMATXDESC_NC) || \
- ((FLAG) == ETH_DMATXDESC_LCO) || \
- ((FLAG) == ETH_DMATXDESC_EC) || \
- ((FLAG) == ETH_DMATXDESC_VF) || \
- ((FLAG) == ETH_DMATXDESC_CC) || \
- ((FLAG) == ETH_DMATXDESC_ED) || \
- ((FLAG) == ETH_DMATXDESC_UF) || \
- ((FLAG) == ETH_DMATXDESC_DB))
-#define IS_ETH_DMA_TXDESC_SEGMENT(SEGMENT) (((SEGMENT) == ETH_DMATXDESC_LASTSEGMENTS) || \
- ((SEGMENT) == ETH_DMATXDESC_FIRSTSEGMENT))
-#define IS_ETH_DMA_TXDESC_CHECKSUM(CHECKSUM) (((CHECKSUM) == ETH_DMATXDESC_CHECKSUMBYPASS) || \
- ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMIPV4HEADER) || \
- ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT) || \
- ((CHECKSUM) == ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL))
-#define IS_ETH_DMATXDESC_BUFFER_SIZE(SIZE) ((SIZE) <= 0x1FFF)
-#define IS_ETH_DMARXDESC_GET_FLAG(FLAG) (((FLAG) == ETH_DMARXDESC_OWN) || \
- ((FLAG) == ETH_DMARXDESC_AFM) || \
- ((FLAG) == ETH_DMARXDESC_ES) || \
- ((FLAG) == ETH_DMARXDESC_DE) || \
- ((FLAG) == ETH_DMARXDESC_SAF) || \
- ((FLAG) == ETH_DMARXDESC_LE) || \
- ((FLAG) == ETH_DMARXDESC_OE) || \
- ((FLAG) == ETH_DMARXDESC_VLAN) || \
- ((FLAG) == ETH_DMARXDESC_FS) || \
- ((FLAG) == ETH_DMARXDESC_LS) || \
- ((FLAG) == ETH_DMARXDESC_IPV4HCE) || \
- ((FLAG) == ETH_DMARXDESC_LC) || \
- ((FLAG) == ETH_DMARXDESC_FT) || \
- ((FLAG) == ETH_DMARXDESC_RWT) || \
- ((FLAG) == ETH_DMARXDESC_RE) || \
- ((FLAG) == ETH_DMARXDESC_DBE) || \
- ((FLAG) == ETH_DMARXDESC_CE) || \
- ((FLAG) == ETH_DMARXDESC_MAMPCE))
-#define IS_ETH_DMA_RXDESC_BUFFER(BUFFER) (((BUFFER) == ETH_DMARXDESC_BUFFER1) || \
- ((BUFFER) == ETH_DMARXDESC_BUFFER2))
-#define IS_ETH_PMT_GET_FLAG(FLAG) (((FLAG) == ETH_PMT_FLAG_WUFR) || \
- ((FLAG) == ETH_PMT_FLAG_MPR))
-#define IS_ETH_DMA_FLAG(FLAG) ((((FLAG) & (uint32_t)0xC7FE1800) == 0x00) && ((FLAG) != 0x00))
-#define IS_ETH_DMA_GET_FLAG(FLAG) (((FLAG) == ETH_DMA_FLAG_TST) || ((FLAG) == ETH_DMA_FLAG_PMT) || \
- ((FLAG) == ETH_DMA_FLAG_MMC) || ((FLAG) == ETH_DMA_FLAG_DATATRANSFERERROR) || \
- ((FLAG) == ETH_DMA_FLAG_READWRITEERROR) || ((FLAG) == ETH_DMA_FLAG_ACCESSERROR) || \
- ((FLAG) == ETH_DMA_FLAG_NIS) || ((FLAG) == ETH_DMA_FLAG_AIS) || \
- ((FLAG) == ETH_DMA_FLAG_ER) || ((FLAG) == ETH_DMA_FLAG_FBE) || \
- ((FLAG) == ETH_DMA_FLAG_ET) || ((FLAG) == ETH_DMA_FLAG_RWT) || \
- ((FLAG) == ETH_DMA_FLAG_RPS) || ((FLAG) == ETH_DMA_FLAG_RBU) || \
- ((FLAG) == ETH_DMA_FLAG_R) || ((FLAG) == ETH_DMA_FLAG_TU) || \
- ((FLAG) == ETH_DMA_FLAG_RO) || ((FLAG) == ETH_DMA_FLAG_TJT) || \
- ((FLAG) == ETH_DMA_FLAG_TBU) || ((FLAG) == ETH_DMA_FLAG_TPS) || \
- ((FLAG) == ETH_DMA_FLAG_T))
-#define IS_ETH_MAC_IT(IT) ((((IT) & (uint32_t)0xFFFFFDF1) == 0x00) && ((IT) != 0x00))
-#define IS_ETH_MAC_GET_IT(IT) (((IT) == ETH_MAC_IT_TST) || ((IT) == ETH_MAC_IT_MMCT) || \
- ((IT) == ETH_MAC_IT_MMCR) || ((IT) == ETH_MAC_IT_MMC) || \
- ((IT) == ETH_MAC_IT_PMT))
-#define IS_ETH_MAC_GET_FLAG(FLAG) (((FLAG) == ETH_MAC_FLAG_TST) || ((FLAG) == ETH_MAC_FLAG_MMCT) || \
- ((FLAG) == ETH_MAC_FLAG_MMCR) || ((FLAG) == ETH_MAC_FLAG_MMC) || \
- ((FLAG) == ETH_MAC_FLAG_PMT))
-#define IS_ETH_DMA_IT(IT) ((((IT) & (uint32_t)0xC7FE1800) == 0x00) && ((IT) != 0x00))
-#define IS_ETH_DMA_GET_IT(IT) (((IT) == ETH_DMA_IT_TST) || ((IT) == ETH_DMA_IT_PMT) || \
- ((IT) == ETH_DMA_IT_MMC) || ((IT) == ETH_DMA_IT_NIS) || \
- ((IT) == ETH_DMA_IT_AIS) || ((IT) == ETH_DMA_IT_ER) || \
- ((IT) == ETH_DMA_IT_FBE) || ((IT) == ETH_DMA_IT_ET) || \
- ((IT) == ETH_DMA_IT_RWT) || ((IT) == ETH_DMA_IT_RPS) || \
- ((IT) == ETH_DMA_IT_RBU) || ((IT) == ETH_DMA_IT_R) || \
- ((IT) == ETH_DMA_IT_TU) || ((IT) == ETH_DMA_IT_RO) || \
- ((IT) == ETH_DMA_IT_TJT) || ((IT) == ETH_DMA_IT_TBU) || \
- ((IT) == ETH_DMA_IT_TPS) || ((IT) == ETH_DMA_IT_T))
-#define IS_ETH_DMA_GET_OVERFLOW(OVERFLOW) (((OVERFLOW) == ETH_DMA_OVERFLOW_RXFIFOCOUNTER) || \
- ((OVERFLOW) == ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER))
-#define IS_ETH_MMC_IT(IT) (((((IT) & (uint32_t)0xFFDF3FFF) == 0x00) || (((IT) & (uint32_t)0xEFFDFF9F) == 0x00)) && \
- ((IT) != 0x00))
-#define IS_ETH_MMC_GET_IT(IT) (((IT) == ETH_MMC_IT_TGF) || ((IT) == ETH_MMC_IT_TGFMSC) || \
- ((IT) == ETH_MMC_IT_TGFSC) || ((IT) == ETH_MMC_IT_RGUF) || \
- ((IT) == ETH_MMC_IT_RFAE) || ((IT) == ETH_MMC_IT_RFCE))
-#define IS_ETH_ENHANCED_DESCRIPTOR_FORMAT(CMD) (((CMD) == ETH_DMAENHANCEDDESCRIPTOR_ENABLE) || \
- ((CMD) == ETH_DMAENHANCEDDESCRIPTOR_DISABLE))
-
-
-/**
- * @}
- */
-
-/** @addtogroup ETH_Private_Defines
- * @{
- */
-/* Delay to wait when writing to some Ethernet registers */
-#define ETH_REG_WRITE_DELAY ((uint32_t)0x00000001U)
-
-/* Ethernet Errors */
-#define ETH_SUCCESS ((uint32_t)0U)
-#define ETH_ERROR ((uint32_t)1U)
-
-/* Ethernet DMA Tx descriptors Collision Count Shift */
-#define ETH_DMATXDESC_COLLISION_COUNTSHIFT ((uint32_t)3U)
-
-/* Ethernet DMA Tx descriptors Buffer2 Size Shift */
-#define ETH_DMATXDESC_BUFFER2_SIZESHIFT ((uint32_t)16U)
-
-/* Ethernet DMA Rx descriptors Frame Length Shift */
-#define ETH_DMARXDESC_FRAME_LENGTHSHIFT ((uint32_t)16U)
-
-/* Ethernet DMA Rx descriptors Buffer2 Size Shift */
-#define ETH_DMARXDESC_BUFFER2_SIZESHIFT ((uint32_t)16U)
-
-/* Ethernet DMA Rx descriptors Frame length Shift */
-#define ETH_DMARXDESC_FRAMELENGTHSHIFT ((uint32_t)16U)
-
-/* Ethernet MAC address offsets */
-#define ETH_MAC_ADDR_HBASE (uint32_t)(ETH_MAC_BASE + (uint32_t)0x40U) /* Ethernet MAC address high offset */
-#define ETH_MAC_ADDR_LBASE (uint32_t)(ETH_MAC_BASE + (uint32_t)0x44U) /* Ethernet MAC address low offset */
-
-/* Ethernet MACMIIAR register Mask */
-#define ETH_MACMIIAR_CR_MASK ((uint32_t)0xFFFFFFE3U)
-
-/* Ethernet MACCR register Mask */
-#define ETH_MACCR_CLEAR_MASK ((uint32_t)0xFF20810FU)
-
-/* Ethernet MACFCR register Mask */
-#define ETH_MACFCR_CLEAR_MASK ((uint32_t)0x0000FF41U)
-
-/* Ethernet DMAOMR register Mask */
-#define ETH_DMAOMR_CLEAR_MASK ((uint32_t)0xF8DE3F23U)
-
-/* Ethernet Remote Wake-up frame register length */
-#define ETH_WAKEUP_REGISTER_LENGTH 8U
-
-/* Ethernet Missed frames counter Shift */
-#define ETH_DMA_RX_OVERFLOW_MISSEDFRAMES_COUNTERSHIFT 17U
- /**
- * @}
- */
-
-#ifdef _lint
- #ifdef __IO
- #undef __IO
- #endif
- #define __IO
-
- #ifdef ETH_TypeDef
- #undef ETH_TypeDef
- #endif
- #define ETH_TypeDef void
-
- #ifdef HAL_LockTypeDef
- #undef HAL_LockTypeDef
- #endif
- #define HAL_LockTypeDef unsigned
-
- #ifdef ETH_RX_BUF_SIZE
- #undef ETH_RX_BUF_SIZE
- #endif
- #define ETH_RX_BUF_SIZE 1536
-
- #ifdef ETH_TX_BUF_SIZE
- #undef ETH_TX_BUF_SIZE
- #endif
- #define ETH_TX_BUF_SIZE 1536
-#endif
-
-/* Exported types ------------------------------------------------------------*/
-/** @defgroup ETH_Exported_Types ETH Exported Types
- * @{
- */
-
-/**
- * @brief HAL State structures definition
- */
-typedef enum
-{
- HAL_ETH_STATE_RESET = 0x00U, /*!< Peripheral not yet Initialized or disabled */
- HAL_ETH_STATE_READY = 0x01U, /*!< Peripheral Initialized and ready for use */
- HAL_ETH_STATE_BUSY = 0x02U, /*!< an internal process is ongoing */
- HAL_ETH_STATE_BUSY_TX = 0x12U, /*!< Data Transmission process is ongoing */
- HAL_ETH_STATE_BUSY_RX = 0x22U, /*!< Data Reception process is ongoing */
- HAL_ETH_STATE_BUSY_TX_RX = 0x32U, /*!< Data Transmission and Reception process is ongoing */
- HAL_ETH_STATE_BUSY_WR = 0x42U, /*!< Write process is ongoing */
- HAL_ETH_STATE_BUSY_RD = 0x82U, /*!< Read process is ongoing */
- HAL_ETH_STATE_TIMEOUT = 0x03U, /*!< Timeout state */
- HAL_ETH_STATE_ERROR = 0x04U /*!< Reception process is ongoing */
-}HAL_ETH_StateTypeDef;
-
-/**
- * @brief ETH Init Structure definition
- */
-
-typedef struct
-{
- uint32_t AutoNegotiation; /*!< Selects or not the AutoNegotiation mode for the external PHY
- The AutoNegotiation allows an automatic setting of the Speed (10/100Mbps)
- and the mode (half/full-duplex).
- This parameter can be a value of @ref ETH_AutoNegotiation */
-
- uint32_t Speed; /*!< Sets the Ethernet speed: 10/100 Mbps.
- This parameter can be a value of @ref ETH_Speed */
-
- uint32_t DuplexMode; /*!< Selects the MAC duplex mode: Half-Duplex or Full-Duplex mode
- This parameter can be a value of @ref ETH_Duplex_Mode */
-
- uint16_t PhyAddress; /*!< Ethernet PHY address.
- This parameter must be a number between Min_Data = 0 and Max_Data = 32 */
-
- uint8_t *MACAddr; /*!< MAC Address of used Hardware: must be pointer on an array of 6 bytes */
-
- uint32_t RxMode; /*!< Selects the Ethernet Rx mode: Polling mode, Interrupt mode.
- This parameter can be a value of @ref ETH_Rx_Mode */
-
- uint32_t ChecksumMode; /*!< Selects if the checksum is check by hardware or by software.
- This parameter can be a value of @ref ETH_Checksum_Mode */
-
- uint32_t MediaInterface ; /*!< Selects the media-independent interface or the reduced media-independent interface.
- This parameter can be a value of @ref ETH_Media_Interface */
-
-} ETH_InitTypeDef;
-
-
- /**
- * @brief ETH MAC Configuration Structure definition
- */
-
-typedef struct
-{
- uint32_t Watchdog; /*!< Selects or not the Watchdog timer
- When enabled, the MAC allows no more then 2048 bytes to be received.
- When disabled, the MAC can receive up to 16384 bytes.
- This parameter can be a value of @ref ETH_Watchdog */
-
- uint32_t Jabber; /*!< Selects or not Jabber timer
- When enabled, the MAC allows no more then 2048 bytes to be sent.
- When disabled, the MAC can send up to 16384 bytes.
- This parameter can be a value of @ref ETH_Jabber */
-
- uint32_t InterFrameGap; /*!< Selects the minimum IFG between frames during transmission.
- This parameter can be a value of @ref ETH_Inter_Frame_Gap */
-
- uint32_t CarrierSense; /*!< Selects or not the Carrier Sense.
- This parameter can be a value of @ref ETH_Carrier_Sense */
-
- uint32_t ReceiveOwn; /*!< Selects or not the ReceiveOwn,
- ReceiveOwn allows the reception of frames when the TX_EN signal is asserted
- in Half-Duplex mode.
- This parameter can be a value of @ref ETH_Receive_Own */
-
- uint32_t LoopbackMode; /*!< Selects or not the internal MAC MII Loopback mode.
- This parameter can be a value of @ref ETH_Loop_Back_Mode */
-
- uint32_t ChecksumOffload; /*!< Selects or not the IPv4 checksum checking for received frame payloads' TCP/UDP/ICMP headers.
- This parameter can be a value of @ref ETH_Checksum_Offload */
-
- uint32_t RetryTransmission; /*!< Selects or not the MAC attempt retries transmission, based on the settings of BL,
- when a collision occurs (Half-Duplex mode).
- This parameter can be a value of @ref ETH_Retry_Transmission */
-
- uint32_t AutomaticPadCRCStrip; /*!< Selects or not the Automatic MAC Pad/CRC Stripping.
- This parameter can be a value of @ref ETH_Automatic_Pad_CRC_Strip */
-
- uint32_t BackOffLimit; /*!< Selects the BackOff limit value.
- This parameter can be a value of @ref ETH_Back_Off_Limit */
-
- uint32_t DeferralCheck; /*!< Selects or not the deferral check function (Half-Duplex mode).
- This parameter can be a value of @ref ETH_Deferral_Check */
-
- uint32_t ReceiveAll; /*!< Selects or not all frames reception by the MAC (No filtering).
- This parameter can be a value of @ref ETH_Receive_All */
-
- uint32_t SourceAddrFilter; /*!< Selects the Source Address Filter mode.
- This parameter can be a value of @ref ETH_Source_Addr_Filter */
-
- uint32_t PassControlFrames; /*!< Sets the forwarding mode of the control frames (including unicast and multicast PAUSE frames)
- This parameter can be a value of @ref ETH_Pass_Control_Frames */
-
- uint32_t BroadcastFramesReception; /*!< Selects or not the reception of Broadcast Frames.
- This parameter can be a value of @ref ETH_Broadcast_Frames_Reception */
-
- uint32_t DestinationAddrFilter; /*!< Sets the destination filter mode for both unicast and multicast frames.
- This parameter can be a value of @ref ETH_Destination_Addr_Filter */
-
- uint32_t PromiscuousMode; /*!< Selects or not the Promiscuous Mode
- This parameter can be a value of @ref ETH_Promiscuous_Mode */
-
- uint32_t MulticastFramesFilter; /*!< Selects the Multicast Frames filter mode: None/HashTableFilter/PerfectFilter/PerfectHashTableFilter.
- This parameter can be a value of @ref ETH_Multicast_Frames_Filter */
-
- uint32_t UnicastFramesFilter; /*!< Selects the Unicast Frames filter mode: HashTableFilter/PerfectFilter/PerfectHashTableFilter.
- This parameter can be a value of @ref ETH_Unicast_Frames_Filter */
-
- uint32_t HashTableHigh; /*!< This field holds the higher 32 bits of Hash table.
- This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFF */
-
- uint32_t HashTableLow; /*!< This field holds the lower 32 bits of Hash table.
- This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFFFFFF */
-
- uint32_t PauseTime; /*!< This field holds the value to be used in the Pause Time field in the transmit control frame.
- This parameter must be a number between Min_Data = 0x0 and Max_Data = 0xFFFF */
-
- uint32_t ZeroQuantaPause; /*!< Selects or not the automatic generation of Zero-Quanta Pause Control frames.
- This parameter can be a value of @ref ETH_Zero_Quanta_Pause */
-
- uint32_t PauseLowThreshold; /*!< This field configures the threshold of the PAUSE to be checked for
- automatic retransmission of PAUSE Frame.
- This parameter can be a value of @ref ETH_Pause_Low_Threshold */
-
- uint32_t UnicastPauseFrameDetect; /*!< Selects or not the MAC detection of the Pause frames (with MAC Address0
- unicast address and unique multicast address).
- This parameter can be a value of @ref ETH_Unicast_Pause_Frame_Detect */
-
- uint32_t ReceiveFlowControl; /*!< Enables or disables the MAC to decode the received Pause frame and
- disable its transmitter for a specified time (Pause Time)
- This parameter can be a value of @ref ETH_Receive_Flow_Control */
-
- uint32_t TransmitFlowControl; /*!< Enables or disables the MAC to transmit Pause frames (Full-Duplex mode)
- or the MAC back-pressure operation (Half-Duplex mode)
- This parameter can be a value of @ref ETH_Transmit_Flow_Control */
-
- uint32_t VLANTagComparison; /*!< Selects the 12-bit VLAN identifier or the complete 16-bit VLAN tag for
- comparison and filtering.
- This parameter can be a value of @ref ETH_VLAN_Tag_Comparison */
-
- uint32_t VLANTagIdentifier; /*!< Holds the VLAN tag identifier for receive frames */
-
-} ETH_MACInitTypeDef;
-
-
-/**
- * @brief ETH DMA Configuration Structure definition
- */
-
-typedef struct
-{
- uint32_t DropTCPIPChecksumErrorFrame; /*!< Selects or not the Dropping of TCP/IP Checksum Error Frames.
- This parameter can be a value of @ref ETH_Drop_TCP_IP_Checksum_Error_Frame */
-
- uint32_t ReceiveStoreForward; /*!< Enables or disables the Receive store and forward mode.
- This parameter can be a value of @ref ETH_Receive_Store_Forward */
-
- uint32_t FlushReceivedFrame; /*!< Enables or disables the flushing of received frames.
- This parameter can be a value of @ref ETH_Flush_Received_Frame */
-
- uint32_t TransmitStoreForward; /*!< Enables or disables Transmit store and forward mode.
- This parameter can be a value of @ref ETH_Transmit_Store_Forward */
-
- uint32_t TransmitThresholdControl; /*!< Selects or not the Transmit Threshold Control.
- This parameter can be a value of @ref ETH_Transmit_Threshold_Control */
-
- uint32_t ForwardErrorFrames; /*!< Selects or not the forward to the DMA of erroneous frames.
- This parameter can be a value of @ref ETH_Forward_Error_Frames */
-
- uint32_t ForwardUndersizedGoodFrames; /*!< Enables or disables the Rx FIFO to forward Undersized frames (frames with no Error
- and length less than 64 bytes) including pad-bytes and CRC)
- This parameter can be a value of @ref ETH_Forward_Undersized_Good_Frames */
-
- uint32_t ReceiveThresholdControl; /*!< Selects the threshold level of the Receive FIFO.
- This parameter can be a value of @ref ETH_Receive_Threshold_Control */
-
- uint32_t SecondFrameOperate; /*!< Selects or not the Operate on second frame mode, which allows the DMA to process a second
- frame of Transmit data even before obtaining the status for the first frame.
- This parameter can be a value of @ref ETH_Second_Frame_Operate */
-
- uint32_t AddressAlignedBeats; /*!< Enables or disables the Address Aligned Beats.
- This parameter can be a value of @ref ETH_Address_Aligned_Beats */
-
- uint32_t FixedBurst; /*!< Enables or disables the AHB Master interface fixed burst transfers.
- This parameter can be a value of @ref ETH_Fixed_Burst */
-
- uint32_t RxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Rx DMA transaction.
- This parameter can be a value of @ref ETH_Rx_DMA_Burst_Length */
-
- uint32_t TxDMABurstLength; /*!< Indicates the maximum number of beats to be transferred in one Tx DMA transaction.
- This parameter can be a value of @ref ETH_Tx_DMA_Burst_Length */
-
- uint32_t EnhancedDescriptorFormat; /*!< Enables the enhanced descriptor format.
- This parameter can be a value of @ref ETH_DMA_Enhanced_descriptor_format */
-
- uint32_t DescriptorSkipLength; /*!< Specifies the number of word to skip between two unchained descriptors (Ring mode)
- This parameter must be a number between Min_Data = 0 and Max_Data = 32 */
-
- uint32_t DMAArbitration; /*!< Selects the DMA Tx/Rx arbitration.
- This parameter can be a value of @ref ETH_DMA_Arbitration */
-} ETH_DMAInitTypeDef;
-
-
-/**
- * @brief ETH DMA Descriptors data structure definition
- */
-
-typedef struct
-{
- __IO uint32_t Status; /*!< Status */
-
- uint32_t ControlBufferSize; /*!< Control and Buffer1, Buffer2 lengths */
-
- uint32_t Buffer1Addr; /*!< Buffer1 address pointer */
-
- uint32_t Buffer2NextDescAddr; /*!< Buffer2 or next descriptor address pointer */
-
- /*!< Enhanced Ethernet DMA PTP Descriptors */
- uint32_t ExtendedStatus; /*!< Extended status for PTP receive descriptor */
-
- uint32_t Reserved1; /*!< Reserved */
-
- uint32_t TimeStampLow; /*!< Time Stamp Low value for transmit and receive */
-
- uint32_t TimeStampHigh; /*!< Time Stamp High value for transmit and receive */
-
-} ETH_DMADescTypeDef;
-
-
-/**
- * @brief Received Frame Informations structure definition
- */
-typedef struct
-{
- ETH_DMADescTypeDef *FSRxDesc; /*!< First Segment Rx Desc */
-
- ETH_DMADescTypeDef *LSRxDesc; /*!< Last Segment Rx Desc */
-
- uint32_t SegCount; /*!< Segment count */
-
- uint32_t length; /*!< Frame length */
-
- uint32_t buffer; /*!< Frame buffer */
-
-} ETH_DMARxFrameInfos;
-
-
-/**
- * @brief ETH Handle Structure definition
- */
-
-typedef struct
-{
- ETH_TypeDef *Instance; /*!< Register base address */
-
- ETH_InitTypeDef Init; /*!< Ethernet Init Configuration */
-
- uint32_t LinkStatus; /*!< Ethernet link status */
-
- ETH_DMADescTypeDef *RxDesc; /*!< Rx descriptor to Get */
-
- ETH_DMADescTypeDef *TxDesc; /*!< Tx descriptor to Set */
-
- ETH_DMARxFrameInfos RxFrameInfos; /*!< last Rx frame infos */
-
- __IO HAL_ETH_StateTypeDef State; /*!< ETH communication state */
-
- HAL_LockTypeDef Lock; /*!< ETH Lock */
-
-} ETH_HandleTypeDef;
-
- /**
- * @}
- */
-
-/* Exported constants --------------------------------------------------------*/
-/** @defgroup ETH_Exported_Constants ETH Exported Constants
- * @{
- */
-
-/** @defgroup ETH_Buffers_setting ETH Buffers setting
- * @{
- */
-#define ETH_MAX_PACKET_SIZE ((uint32_t)1536U) /*!< ETH_HEADER + ETH_EXTRA + ETH_VLAN_TAG + ETH_MAX_ETH_PAYLOAD + ETH_CRC */
-#define ETH_HEADER ((uint32_t)14U) /*!< 6 byte Dest addr, 6 byte Src addr, 2 byte length/type */
-#define ETH_CRC ((uint32_t)4U) /*!< Ethernet CRC */
-#define ETH_EXTRA ((uint32_t)2U) /*!< Extra bytes in some cases */
-#define ETH_VLAN_TAG ((uint32_t)4U) /*!< optional 802.1q VLAN Tag */
-#define ETH_MIN_ETH_PAYLOAD ((uint32_t)46U) /*!< Minimum Ethernet payload size */
-#define ETH_MAX_ETH_PAYLOAD ((uint32_t)1500U) /*!< Maximum Ethernet payload size */
-#define ETH_JUMBO_FRAME_PAYLOAD ((uint32_t)9000U) /*!< Jumbo frame payload size */
-
- /* Ethernet driver receive buffers are organized in a chained linked-list, when
- an Ethernet packet is received, the Rx-DMA will transfer the packet from RxFIFO
- to the driver receive buffers memory.
-
- Depending on the size of the received Ethernet packet and the size of
- each Ethernet driver receive buffer, the received packet can take one or more
- Ethernet driver receive buffer.
-
- In below are defined the size of one Ethernet driver receive buffer ETH_RX_BUF_SIZE
- and the total count of the driver receive buffers ETH_RXBUFNB.
-
- The configured value for ETH_RX_BUF_SIZE and ETH_RXBUFNB are only provided as
- example, they can be reconfigured in the application layer to fit the application
- needs */
-
-/* Here we configure each Ethernet driver receive buffer to fit the Max size Ethernet
- packet */
-#ifndef ETH_RX_BUF_SIZE
- #error please define ETH_RX_BUF_SIZE
- #define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE
-#endif
-
-/* 5 Ethernet driver receive buffers are used (in a chained linked list)*/
-#ifndef ETH_RXBUFNB
- #define ETH_RXBUFNB ((uint32_t)5U) /* 5 Rx buffers of size ETH_RX_BUF_SIZE */
-#endif
-
-
- /* Ethernet driver transmit buffers are organized in a chained linked-list, when
- an Ethernet packet is transmitted, Tx-DMA will transfer the packet from the
- driver transmit buffers memory to the TxFIFO.
-
- Depending on the size of the Ethernet packet to be transmitted and the size of
- each Ethernet driver transmit buffer, the packet to be transmitted can take
- one or more Ethernet driver transmit buffer.
-
- In below are defined the size of one Ethernet driver transmit buffer ETH_TX_BUF_SIZE
- and the total count of the driver transmit buffers ETH_TXBUFNB.
-
- The configured value for ETH_TX_BUF_SIZE and ETH_TXBUFNB are only provided as
- example, they can be reconfigured in the application layer to fit the application
- needs */
-
-/* Here we configure each Ethernet driver transmit buffer to fit the Max size Ethernet
- packet */
-#ifndef ETH_TX_BUF_SIZE
- #error please define ETH_TX_BUF_SIZE
- #define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE
-#endif
-
-/* 5 Ethernet driver transmit buffers are used (in a chained linked list)*/
-#ifndef ETH_TXBUFNB
- #define ETH_TXBUFNB ((uint32_t)5U) /* 5 Tx buffers of size ETH_TX_BUF_SIZE */
-#endif
-
- /**
- * @}
- */
-
-/** @defgroup ETH_DMA_TX_Descriptor ETH DMA TX Descriptor
- * @{
- */
-
-/*
- DMA Tx Descriptor
- -----------------------------------------------------------------------------------------------
- TDES0 | OWN(31) | CTRL[30:26] | Reserved[25:24] | CTRL[23:20] | Reserved[19:17] | Status[16:0] |
- -----------------------------------------------------------------------------------------------
- TDES1 | Reserved[31:29] | Buffer2 ByteCount[28:16] | Reserved[15:13] | Buffer1 ByteCount[12:0] |
- -----------------------------------------------------------------------------------------------
- TDES2 | Buffer1 Address [31:0] |
- -----------------------------------------------------------------------------------------------
- TDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] |
- -----------------------------------------------------------------------------------------------
-*/
-
-/**
- * @brief Bit definition of TDES0 register: DMA Tx descriptor status register
- */
-#define ETH_DMATXDESC_OWN ((uint32_t)0x80000000U) /*!< OWN bit: descriptor is owned by DMA engine */
-#define ETH_DMATXDESC_IC ((uint32_t)0x40000000U) /*!< Interrupt on Completion */
-#define ETH_DMATXDESC_LS ((uint32_t)0x20000000U) /*!< Last Segment */
-#define ETH_DMATXDESC_FS ((uint32_t)0x10000000U) /*!< First Segment */
-#define ETH_DMATXDESC_DC ((uint32_t)0x08000000U) /*!< Disable CRC */
-#define ETH_DMATXDESC_DP ((uint32_t)0x04000000U) /*!< Disable Padding */
-#define ETH_DMATXDESC_TTSE ((uint32_t)0x02000000U) /*!< Transmit Time Stamp Enable */
-#define ETH_DMATXDESC_CIC ((uint32_t)0x00C00000U) /*!< Checksum Insertion Control: 4 cases */
-#define ETH_DMATXDESC_CIC_BYPASS ((uint32_t)0x00000000U) /*!< Do Nothing: Checksum Engine is bypassed */
-#define ETH_DMATXDESC_CIC_IPV4HEADER ((uint32_t)0x00400000U) /*!< IPV4 header Checksum Insertion */
-#define ETH_DMATXDESC_CIC_TCPUDPICMP_SEGMENT ((uint32_t)0x00800000U) /*!< TCP/UDP/ICMP Checksum Insertion calculated over segment only */
-#define ETH_DMATXDESC_CIC_TCPUDPICMP_FULL ((uint32_t)0x00C00000U) /*!< TCP/UDP/ICMP Checksum Insertion fully calculated */
-#define ETH_DMATXDESC_TER ((uint32_t)0x00200000U) /*!< Transmit End of Ring */
-#define ETH_DMATXDESC_TCH ((uint32_t)0x00100000U) /*!< Second Address Chained */
-#define ETH_DMATXDESC_TTSS ((uint32_t)0x00020000U) /*!< Tx Time Stamp Status */
-#define ETH_DMATXDESC_IHE ((uint32_t)0x00010000U) /*!< IP Header Error */
-#define ETH_DMATXDESC_ES ((uint32_t)0x00008000U) /*!< Error summary: OR of the following bits: UE || ED || EC || LCO || NC || LCA || FF || JT */
-#define ETH_DMATXDESC_JT ((uint32_t)0x00004000U) /*!< Jabber Timeout */
-#define ETH_DMATXDESC_FF ((uint32_t)0x00002000U) /*!< Frame Flushed: DMA/MTL flushed the frame due to SW flush */
-#define ETH_DMATXDESC_PCE ((uint32_t)0x00001000U) /*!< Payload Checksum Error */
-#define ETH_DMATXDESC_LCA ((uint32_t)0x00000800U) /*!< Loss of Carrier: carrier lost during transmission */
-#define ETH_DMATXDESC_NC ((uint32_t)0x00000400U) /*!< No Carrier: no carrier signal from the transceiver */
-#define ETH_DMATXDESC_LCO ((uint32_t)0x00000200U) /*!< Late Collision: transmission aborted due to collision */
-#define ETH_DMATXDESC_EC ((uint32_t)0x00000100U) /*!< Excessive Collision: transmission aborted after 16 collisions */
-#define ETH_DMATXDESC_VF ((uint32_t)0x00000080U) /*!< VLAN Frame */
-#define ETH_DMATXDESC_CC ((uint32_t)0x00000078U) /*!< Collision Count */
-#define ETH_DMATXDESC_ED ((uint32_t)0x00000004U) /*!< Excessive Deferral */
-#define ETH_DMATXDESC_UF ((uint32_t)0x00000002U) /*!< Underflow Error: late data arrival from the memory */
-#define ETH_DMATXDESC_DB ((uint32_t)0x00000001U) /*!< Deferred Bit */
-
-/**
- * @brief Bit definition of TDES1 register
- */
-#define ETH_DMATXDESC_TBS2 ((uint32_t)0x1FFF0000U) /*!< Transmit Buffer2 Size */
-#define ETH_DMATXDESC_TBS1 ((uint32_t)0x00001FFFU) /*!< Transmit Buffer1 Size */
-
-/**
- * @brief Bit definition of TDES2 register
- */
-#define ETH_DMATXDESC_B1AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer1 Address Pointer */
-
-/**
- * @brief Bit definition of TDES3 register
- */
-#define ETH_DMATXDESC_B2AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer2 Address Pointer */
-
- /*---------------------------------------------------------------------------------------------
- TDES6 | Transmit Time Stamp Low [31:0] |
- -----------------------------------------------------------------------------------------------
- TDES7 | Transmit Time Stamp High [31:0] |
- ----------------------------------------------------------------------------------------------*/
-
-/* Bit definition of TDES6 register */
- #define ETH_DMAPTPTXDESC_TTSL ((uint32_t)0xFFFFFFFFU) /* Transmit Time Stamp Low */
-
-/* Bit definition of TDES7 register */
- #define ETH_DMAPTPTXDESC_TTSH ((uint32_t)0xFFFFFFFFU) /* Transmit Time Stamp High */
-
-/**
- * @}
- */
-/** @defgroup ETH_DMA_RX_Descriptor ETH DMA RX Descriptor
- * @{
- */
-
-/*
- DMA Rx Descriptor
- --------------------------------------------------------------------------------------------------------------------
- RDES0 | OWN(31) | Status [30:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES1 | CTRL(31) | Reserved[30:29] | Buffer2 ByteCount[28:16] | CTRL[15:14] | Reserved(13) | Buffer1 ByteCount[12:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES2 | Buffer1 Address [31:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES3 | Buffer2 Address [31:0] / Next Descriptor Address [31:0] |
- ---------------------------------------------------------------------------------------------------------------------
-*/
-
-/**
- * @brief Bit definition of RDES0 register: DMA Rx descriptor status register
- */
-#define ETH_DMARXDESC_OWN ((uint32_t)0x80000000U) /*!< OWN bit: descriptor is owned by DMA engine */
-#define ETH_DMARXDESC_AFM ((uint32_t)0x40000000U) /*!< DA Filter Fail for the rx frame */
-#define ETH_DMARXDESC_FL ((uint32_t)0x3FFF0000U) /*!< Receive descriptor frame length */
-#define ETH_DMARXDESC_ES ((uint32_t)0x00008000U) /*!< Error summary: OR of the following bits: DE || OE || IPC || LC || RWT || RE || CE */
-#define ETH_DMARXDESC_DE ((uint32_t)0x00004000U) /*!< Descriptor error: no more descriptors for receive frame */
-#define ETH_DMARXDESC_SAF ((uint32_t)0x00002000U) /*!< SA Filter Fail for the received frame */
-#define ETH_DMARXDESC_LE ((uint32_t)0x00001000U) /*!< Frame size not matching with length field */
-#define ETH_DMARXDESC_OE ((uint32_t)0x00000800U) /*!< Overflow Error: Frame was damaged due to buffer overflow */
-#define ETH_DMARXDESC_VLAN ((uint32_t)0x00000400U) /*!< VLAN Tag: received frame is a VLAN frame */
-#define ETH_DMARXDESC_FS ((uint32_t)0x00000200U) /*!< First descriptor of the frame */
-#define ETH_DMARXDESC_LS ((uint32_t)0x00000100U) /*!< Last descriptor of the frame */
-#define ETH_DMARXDESC_IPV4HCE ((uint32_t)0x00000080U) /*!< IPC Checksum Error: Rx Ipv4 header checksum error */
-#define ETH_DMARXDESC_LC ((uint32_t)0x00000040U) /*!< Late collision occurred during reception */
-#define ETH_DMARXDESC_FT ((uint32_t)0x00000020U) /*!< Frame type - Ethernet, otherwise 802.3 */
-#define ETH_DMARXDESC_RWT ((uint32_t)0x00000010U) /*!< Receive Watchdog Timeout: watchdog timer expired during reception */
-#define ETH_DMARXDESC_RE ((uint32_t)0x00000008U) /*!< Receive error: error reported by MII interface */
-#define ETH_DMARXDESC_DBE ((uint32_t)0x00000004U) /*!< Dribble bit error: frame contains non int multiple of 8 bits */
-#define ETH_DMARXDESC_CE ((uint32_t)0x00000002U) /*!< CRC error */
-#define ETH_DMARXDESC_MAMPCE ((uint32_t)0x00000001U) /*!< Rx MAC Address/Payload Checksum Error: Rx MAC address matched/ Rx Payload Checksum Error */
-
-/**
- * @brief Bit definition of RDES1 register
- */
-#define ETH_DMARXDESC_DIC ((uint32_t)0x80000000U) /*!< Disable Interrupt on Completion */
-#define ETH_DMARXDESC_RBS2 ((uint32_t)0x1FFF0000U) /*!< Receive Buffer2 Size */
-#define ETH_DMARXDESC_RER ((uint32_t)0x00008000U) /*!< Receive End of Ring */
-#define ETH_DMARXDESC_RCH ((uint32_t)0x00004000U) /*!< Second Address Chained */
-#define ETH_DMARXDESC_RBS1 ((uint32_t)0x00001FFFU) /*!< Receive Buffer1 Size */
-
-/**
- * @brief Bit definition of RDES2 register
- */
-#define ETH_DMARXDESC_B1AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer1 Address Pointer */
-
-/**
- * @brief Bit definition of RDES3 register
- */
-#define ETH_DMARXDESC_B2AP ((uint32_t)0xFFFFFFFFU) /*!< Buffer2 Address Pointer */
-
-/*---------------------------------------------------------------------------------------------------------------------
- RDES4 | Reserved[31:15] | Extended Status [14:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES5 | Reserved[31:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES6 | Receive Time Stamp Low [31:0] |
- ---------------------------------------------------------------------------------------------------------------------
- RDES7 | Receive Time Stamp High [31:0] |
- --------------------------------------------------------------------------------------------------------------------*/
-
-/* Bit definition of RDES4 register */
-#define ETH_DMAPTPRXDESC_PTPV ((uint32_t)0x00002000U) /* PTP Version */
-#define ETH_DMAPTPRXDESC_PTPFT ((uint32_t)0x00001000U) /* PTP Frame Type */
-#define ETH_DMAPTPRXDESC_PTPMT ((uint32_t)0x00000F00U) /* PTP Message Type */
- #define ETH_DMAPTPRXDESC_PTPMT_SYNC ((uint32_t)0x00000100U) /* SYNC message (all clock types) */
- #define ETH_DMAPTPRXDESC_PTPMT_FOLLOWUP ((uint32_t)0x00000200U) /* FollowUp message (all clock types) */
- #define ETH_DMAPTPRXDESC_PTPMT_DELAYREQ ((uint32_t)0x00000300U) /* DelayReq message (all clock types) */
- #define ETH_DMAPTPRXDESC_PTPMT_DELAYRESP ((uint32_t)0x00000400U) /* DelayResp message (all clock types) */
- #define ETH_DMAPTPRXDESC_PTPMT_PDELAYREQ_ANNOUNCE ((uint32_t)0x00000500U) /* PdelayReq message (peer-to-peer transparent clock) or Announce message (Ordinary or Boundary clock) */
- #define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESP_MANAG ((uint32_t)0x00000600U) /* PdelayResp message (peer-to-peer transparent clock) or Management message (Ordinary or Boundary clock) */
- #define ETH_DMAPTPRXDESC_PTPMT_PDELAYRESPFOLLOWUP_SIGNAL ((uint32_t)0x00000700U) /* PdelayRespFollowUp message (peer-to-peer transparent clock) or Signaling message (Ordinary or Boundary clock) */
-#define ETH_DMAPTPRXDESC_IPV6PR ((uint32_t)0x00000080U) /* IPv6 Packet Received */
-#define ETH_DMAPTPRXDESC_IPV4PR ((uint32_t)0x00000040U) /* IPv4 Packet Received */
-#define ETH_DMAPTPRXDESC_IPCB ((uint32_t)0x00000020U) /* IP Checksum Bypassed */
-#define ETH_DMAPTPRXDESC_IPPE ((uint32_t)0x00000010U) /* IP Payload Error */
-#define ETH_DMAPTPRXDESC_IPHE ((uint32_t)0x00000008U) /* IP Header Error */
-#define ETH_DMAPTPRXDESC_IPPT ((uint32_t)0x00000007U) /* IP Payload Type */
- #define ETH_DMAPTPRXDESC_IPPT_UDP ((uint32_t)0x00000001U) /* UDP payload encapsulated in the IP datagram */
- #define ETH_DMAPTPRXDESC_IPPT_TCP ((uint32_t)0x00000002U) /* TCP payload encapsulated in the IP datagram */
- #define ETH_DMAPTPRXDESC_IPPT_ICMP ((uint32_t)0x00000003U) /* ICMP payload encapsulated in the IP datagram */
-
-/* Bit definition of RDES6 register */
-#define ETH_DMAPTPRXDESC_RTSL ((uint32_t)0xFFFFFFFFU) /* Receive Time Stamp Low */
-
-/* Bit definition of RDES7 register */
-#define ETH_DMAPTPRXDESC_RTSH ((uint32_t)0xFFFFFFFFU) /* Receive Time Stamp High */
-/**
- * @}
- */
- /** @defgroup ETH_AutoNegotiation ETH AutoNegotiation
- * @{
- */
-#define ETH_AUTONEGOTIATION_ENABLE ((uint32_t)0x00000001U)
-#define ETH_AUTONEGOTIATION_DISABLE ((uint32_t)0x00000000U)
-
-/**
- * @}
- */
-/** @defgroup ETH_Speed ETH Speed
- * @{
- */
-#define ETH_SPEED_10M ((uint32_t)0x00000000U)
-#define ETH_SPEED_100M ((uint32_t)0x00004000U)
-
-/**
- * @}
- */
-/** @defgroup ETH_Duplex_Mode ETH Duplex Mode
- * @{
- */
-#define ETH_MODE_FULLDUPLEX ((uint32_t)0x00000800U)
-#define ETH_MODE_HALFDUPLEX ((uint32_t)0x00000000U)
-/**
- * @}
- */
-/** @defgroup ETH_Rx_Mode ETH Rx Mode
- * @{
- */
-#define ETH_RXPOLLING_MODE ((uint32_t)0x00000000U)
-#define ETH_RXINTERRUPT_MODE ((uint32_t)0x00000001U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Checksum_Mode ETH Checksum Mode
- * @{
- */
-#define ETH_CHECKSUM_BY_HARDWARE ((uint32_t)0x00000000U)
-#define ETH_CHECKSUM_BY_SOFTWARE ((uint32_t)0x00000001U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Media_Interface ETH Media Interface
- * @{
- */
-#define ETH_MEDIA_INTERFACE_MII ((uint32_t)0x00000000U)
-#define ETH_MEDIA_INTERFACE_RMII ((uint32_t)SYSCFG_PMC_MII_RMII_SEL)
-/**
- * @}
- */
-
-/** @defgroup ETH_Watchdog ETH Watchdog
- * @{
- */
-#define ETH_WATCHDOG_ENABLE ((uint32_t)0x00000000U)
-#define ETH_WATCHDOG_DISABLE ((uint32_t)0x00800000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Jabber ETH Jabber
- * @{
- */
-#define ETH_JABBER_ENABLE ((uint32_t)0x00000000U)
-#define ETH_JABBER_DISABLE ((uint32_t)0x00400000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Inter_Frame_Gap ETH Inter Frame Gap
- * @{
- */
-#define ETH_INTERFRAMEGAP_96BIT ((uint32_t)0x00000000U) /*!< minimum IFG between frames during transmission is 96Bit */
-#define ETH_INTERFRAMEGAP_88BIT ((uint32_t)0x00020000U) /*!< minimum IFG between frames during transmission is 88Bit */
-#define ETH_INTERFRAMEGAP_80BIT ((uint32_t)0x00040000U) /*!< minimum IFG between frames during transmission is 80Bit */
-#define ETH_INTERFRAMEGAP_72BIT ((uint32_t)0x00060000U) /*!< minimum IFG between frames during transmission is 72Bit */
-#define ETH_INTERFRAMEGAP_64BIT ((uint32_t)0x00080000U) /*!< minimum IFG between frames during transmission is 64Bit */
-#define ETH_INTERFRAMEGAP_56BIT ((uint32_t)0x000A0000U) /*!< minimum IFG between frames during transmission is 56Bit */
-#define ETH_INTERFRAMEGAP_48BIT ((uint32_t)0x000C0000U) /*!< minimum IFG between frames during transmission is 48Bit */
-#define ETH_INTERFRAMEGAP_40BIT ((uint32_t)0x000E0000U) /*!< minimum IFG between frames during transmission is 40Bit */
-/**
- * @}
- */
-
-/** @defgroup ETH_Carrier_Sense ETH Carrier Sense
- * @{
- */
-#define ETH_CARRIERSENCE_ENABLE ((uint32_t)0x00000000U)
-#define ETH_CARRIERSENCE_DISABLE ((uint32_t)0x00010000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Own ETH Receive Own
- * @{
- */
-#define ETH_RECEIVEOWN_ENABLE ((uint32_t)0x00000000U)
-#define ETH_RECEIVEOWN_DISABLE ((uint32_t)0x00002000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Loop_Back_Mode ETH Loop Back Mode
- * @{
- */
-#define ETH_LOOPBACKMODE_ENABLE ((uint32_t)0x00001000U)
-#define ETH_LOOPBACKMODE_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Checksum_Offload ETH Checksum Offload
- * @{
- */
-#define ETH_CHECKSUMOFFLAOD_ENABLE ((uint32_t)0x00000400U)
-#define ETH_CHECKSUMOFFLAOD_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Retry_Transmission ETH Retry Transmission
- * @{
- */
-#define ETH_RETRYTRANSMISSION_ENABLE ((uint32_t)0x00000000U)
-#define ETH_RETRYTRANSMISSION_DISABLE ((uint32_t)0x00000200U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Automatic_Pad_CRC_Strip ETH Automatic Pad CRC Strip
- * @{
- */
-#define ETH_AUTOMATICPADCRCSTRIP_ENABLE ((uint32_t)0x00000080U)
-#define ETH_AUTOMATICPADCRCSTRIP_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Back_Off_Limit ETH Back Off Limit
- * @{
- */
-#define ETH_BACKOFFLIMIT_10 ((uint32_t)0x00000000U)
-#define ETH_BACKOFFLIMIT_8 ((uint32_t)0x00000020U)
-#define ETH_BACKOFFLIMIT_4 ((uint32_t)0x00000040U)
-#define ETH_BACKOFFLIMIT_1 ((uint32_t)0x00000060U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Deferral_Check ETH Deferral Check
- * @{
- */
-#define ETH_DEFFERRALCHECK_ENABLE ((uint32_t)0x00000010U)
-#define ETH_DEFFERRALCHECK_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_All ETH Receive All
- * @{
- */
-#define ETH_RECEIVEALL_ENABLE ((uint32_t)0x80000000U)
-#define ETH_RECEIVEAll_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Source_Addr_Filter ETH Source Addr Filter
- * @{
- */
-#define ETH_SOURCEADDRFILTER_NORMAL_ENABLE ((uint32_t)0x00000200U)
-#define ETH_SOURCEADDRFILTER_INVERSE_ENABLE ((uint32_t)0x00000300U)
-#define ETH_SOURCEADDRFILTER_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Pass_Control_Frames ETH Pass Control Frames
- * @{
- */
-#define ETH_PASSCONTROLFRAMES_BLOCKALL ((uint32_t)0x00000040U) /*!< MAC filters all control frames from reaching the application */
-#define ETH_PASSCONTROLFRAMES_FORWARDALL ((uint32_t)0x00000080U) /*!< MAC forwards all control frames to application even if they fail the Address Filter */
-#define ETH_PASSCONTROLFRAMES_FORWARDPASSEDADDRFILTER ((uint32_t)0x000000C0U) /*!< MAC forwards control frames that pass the Address Filter. */
-/**
- * @}
- */
-
-/** @defgroup ETH_Broadcast_Frames_Reception ETH Broadcast Frames Reception
- * @{
- */
-#define ETH_BROADCASTFRAMESRECEPTION_ENABLE ((uint32_t)0x00000000U)
-#define ETH_BROADCASTFRAMESRECEPTION_DISABLE ((uint32_t)0x00000020U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Destination_Addr_Filter ETH Destination Addr Filter
- * @{
- */
-#define ETH_DESTINATIONADDRFILTER_NORMAL ((uint32_t)0x00000000U)
-#define ETH_DESTINATIONADDRFILTER_INVERSE ((uint32_t)0x00000008U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Promiscuous_Mode ETH Promiscuous Mode
- * @{
- */
-#define ETH_PROMISCUOUS_MODE_ENABLE ((uint32_t)0x00000001U)
-#define ETH_PROMISCUOUS_MODE_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Multicast_Frames_Filter ETH Multicast Frames Filter
- * @{
- */
-#define ETH_MULTICASTFRAMESFILTER_PERFECTHASHTABLE ((uint32_t)0x00000404U)
-#define ETH_MULTICASTFRAMESFILTER_HASHTABLE ((uint32_t)0x00000004U)
-#define ETH_MULTICASTFRAMESFILTER_PERFECT ((uint32_t)0x00000000U)
-#define ETH_MULTICASTFRAMESFILTER_NONE ((uint32_t)0x00000010U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Unicast_Frames_Filter ETH Unicast Frames Filter
- * @{
- */
-#define ETH_UNICASTFRAMESFILTER_PERFECTHASHTABLE ((uint32_t)0x00000402U)
-#define ETH_UNICASTFRAMESFILTER_HASHTABLE ((uint32_t)0x00000002U)
-#define ETH_UNICASTFRAMESFILTER_PERFECT ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Zero_Quanta_Pause ETH Zero Quanta Pause
- * @{
- */
-#define ETH_ZEROQUANTAPAUSE_ENABLE ((uint32_t)0x00000000U)
-#define ETH_ZEROQUANTAPAUSE_DISABLE ((uint32_t)0x00000080U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Pause_Low_Threshold ETH Pause Low Threshold
- * @{
- */
-#define ETH_PAUSELOWTHRESHOLD_MINUS4 ((uint32_t)0x00000000U) /*!< Pause time minus 4 slot times */
-#define ETH_PAUSELOWTHRESHOLD_MINUS28 ((uint32_t)0x00000010U) /*!< Pause time minus 28 slot times */
-#define ETH_PAUSELOWTHRESHOLD_MINUS144 ((uint32_t)0x00000020U) /*!< Pause time minus 144 slot times */
-#define ETH_PAUSELOWTHRESHOLD_MINUS256 ((uint32_t)0x00000030U) /*!< Pause time minus 256 slot times */
-/**
- * @}
- */
-
-/** @defgroup ETH_Unicast_Pause_Frame_Detect ETH Unicast Pause Frame Detect
- * @{
- */
-#define ETH_UNICASTPAUSEFRAMEDETECT_ENABLE ((uint32_t)0x00000008U)
-#define ETH_UNICASTPAUSEFRAMEDETECT_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Flow_Control ETH Receive Flow Control
- * @{
- */
-#define ETH_RECEIVEFLOWCONTROL_ENABLE ((uint32_t)0x00000004U)
-#define ETH_RECEIVEFLOWCONTROL_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Transmit_Flow_Control ETH Transmit Flow Control
- * @{
- */
-#define ETH_TRANSMITFLOWCONTROL_ENABLE ((uint32_t)0x00000002U)
-#define ETH_TRANSMITFLOWCONTROL_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_VLAN_Tag_Comparison ETH VLAN Tag Comparison
- * @{
- */
-#define ETH_VLANTAGCOMPARISON_12BIT ((uint32_t)0x00010000U)
-#define ETH_VLANTAGCOMPARISON_16BIT ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_addresses ETH MAC addresses
- * @{
- */
-#define ETH_MAC_ADDRESS0 ((uint32_t)0x00000000U)
-#define ETH_MAC_ADDRESS1 ((uint32_t)0x00000008U)
-#define ETH_MAC_ADDRESS2 ((uint32_t)0x00000010U)
-#define ETH_MAC_ADDRESS3 ((uint32_t)0x00000018U)
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_addresses_filter_SA_DA ETH MAC addresses filter SA DA
- * @{
- */
-#define ETH_MAC_ADDRESSFILTER_SA ((uint32_t)0x00000000U)
-#define ETH_MAC_ADDRESSFILTER_DA ((uint32_t)0x00000008U)
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_addresses_filter_Mask_bytes ETH MAC addresses filter Mask bytes
- * @{
- */
-#define ETH_MAC_ADDRESSMASK_BYTE6 ((uint32_t)0x20000000U) /*!< Mask MAC Address high reg bits [15:8] */
-#define ETH_MAC_ADDRESSMASK_BYTE5 ((uint32_t)0x10000000U) /*!< Mask MAC Address high reg bits [7:0] */
-#define ETH_MAC_ADDRESSMASK_BYTE4 ((uint32_t)0x08000000U) /*!< Mask MAC Address low reg bits [31:24] */
-#define ETH_MAC_ADDRESSMASK_BYTE3 ((uint32_t)0x04000000U) /*!< Mask MAC Address low reg bits [23:16] */
-#define ETH_MAC_ADDRESSMASK_BYTE2 ((uint32_t)0x02000000U) /*!< Mask MAC Address low reg bits [15:8] */
-#define ETH_MAC_ADDRESSMASK_BYTE1 ((uint32_t)0x01000000U) /*!< Mask MAC Address low reg bits [70] */
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_Debug_flags ETH MAC Debug flags
- * @{
- */
-#ifndef ETH_MAC_TXFIFO_FULL
- #define ETH_MAC_TXFIFO_FULL ((uint32_t)0x02000000) /* Tx FIFO full */
- #define ETH_MAC_TXFIFONOT_EMPTY ((uint32_t)0x01000000) /* Tx FIFO not empty */
- #define ETH_MAC_TXFIFO_WRITE_ACTIVE ((uint32_t)0x00400000) /* Tx FIFO write active */
- #define ETH_MAC_TXFIFO_IDLE ((uint32_t)0x00000000) /* Tx FIFO read status: Idle */
- #define ETH_MAC_TXFIFO_READ ((uint32_t)0x00100000) /* Tx FIFO read status: Read (transferring data to the MAC transmitter) */
- #define ETH_MAC_TXFIFO_WAITING ((uint32_t)0x00200000) /* Tx FIFO read status: Waiting for TxStatus from MAC transmitter */
- #define ETH_MAC_TXFIFO_WRITING ((uint32_t)0x00300000) /* Tx FIFO read status: Writing the received TxStatus or flushing the TxFIFO */
- #define ETH_MAC_TRANSMISSION_PAUSE ((uint32_t)0x00080000) /* MAC transmitter in pause */
- #define ETH_MAC_TRANSMITFRAMECONTROLLER_IDLE ((uint32_t)0x00000000) /* MAC transmit frame controller: Idle */
- #define ETH_MAC_TRANSMITFRAMECONTROLLER_WAITING ((uint32_t)0x00020000) /* MAC transmit frame controller: Waiting for Status of previous frame or IFG/backoff period to be over */
- #define ETH_MAC_TRANSMITFRAMECONTROLLER_GENRATING_PCF ((uint32_t)0x00040000) /* MAC transmit frame controller: Generating and transmitting a Pause control frame (in full duplex mode) */
- #define ETH_MAC_TRANSMITFRAMECONTROLLER_TRANSFERRING ((uint32_t)0x00060000) /* MAC transmit frame controller: Transferring input frame for transmission */
- #define ETH_MAC_MII_TRANSMIT_ACTIVE ((uint32_t)0x00010000) /* MAC MII transmit engine active */
- #define ETH_MAC_RXFIFO_EMPTY ((uint32_t)0x00000000) /* Rx FIFO fill level: empty */
- #define ETH_MAC_RXFIFO_BELOW_THRESHOLD ((uint32_t)0x00000100) /* Rx FIFO fill level: fill-level below flow-control de-activate threshold */
- #define ETH_MAC_RXFIFO_ABOVE_THRESHOLD ((uint32_t)0x00000200) /* Rx FIFO fill level: fill-level above flow-control activate threshold */
- #define ETH_MAC_RXFIFO_FULL ((uint32_t)0x00000300) /* Rx FIFO fill level: full */
- #define ETH_MAC_READCONTROLLER_IDLE ((uint32_t)0x00000060) /* Rx FIFO read controller IDLE state */
- #define ETH_MAC_READCONTROLLER_READING_DATA ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame data */
- #define ETH_MAC_READCONTROLLER_READING_STATUS ((uint32_t)0x00000060) /* Rx FIFO read controller Reading frame status (or time-stamp) */
- #define ETH_MAC_READCONTROLLER_ FLUSHING ((uint32_t)0x00000060) /* Rx FIFO read controller Flushing the frame data and status */
- #define ETH_MAC_RXFIFO_WRITE_ACTIVE ((uint32_t)0x00000010) /* Rx FIFO write controller active */
- #define ETH_MAC_SMALL_FIFO_NOTACTIVE ((uint32_t)0x00000000) /* MAC small FIFO read / write controllers not active */
- #define ETH_MAC_SMALL_FIFO_READ_ACTIVE ((uint32_t)0x00000002) /* MAC small FIFO read controller active */
- #define ETH_MAC_SMALL_FIFO_WRITE_ACTIVE ((uint32_t)0x00000004) /* MAC small FIFO write controller active */
- #define ETH_MAC_SMALL_FIFO_RW_ACTIVE ((uint32_t)0x00000006) /* MAC small FIFO read / write controllers active */
- #define ETH_MAC_MII_RECEIVE_PROTOCOL_ACTIVE ((uint32_t)0x00000001) /* MAC MII receive protocol engine active */
-#else
- /* stm32_hal_legacy.h has probably been included. That file defines 'ETH_MAC_TXFIFO_FULL' and all macro's here below. */
-#endif
-/**
- * @}
- */
-
-/** @defgroup ETH_Drop_TCP_IP_Checksum_Error_Frame ETH Drop TCP IP Checksum Error Frame
- * @{
- */
-#define ETH_DROPTCPIPCHECKSUMERRORFRAME_ENABLE ((uint32_t)0x00000000U)
-#define ETH_DROPTCPIPCHECKSUMERRORFRAME_DISABLE ((uint32_t)0x04000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Store_Forward ETH Receive Store Forward
- * @{
- */
-#define ETH_RECEIVESTOREFORWARD_ENABLE ((uint32_t)0x02000000U)
-#define ETH_RECEIVESTOREFORWARD_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Flush_Received_Frame ETH Flush Received Frame
- * @{
- */
-#define ETH_FLUSHRECEIVEDFRAME_ENABLE ((uint32_t)0x00000000U)
-#define ETH_FLUSHRECEIVEDFRAME_DISABLE ((uint32_t)0x01000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Transmit_Store_Forward ETH Transmit Store Forward
- * @{
- */
-#define ETH_TRANSMITSTOREFORWARD_ENABLE ((uint32_t)0x00200000U)
-#define ETH_TRANSMITSTOREFORWARD_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Transmit_Threshold_Control ETH Transmit Threshold Control
- * @{
- */
-#define ETH_TRANSMITTHRESHOLDCONTROL_64BYTES ((uint32_t)0x00000000U) /*!< threshold level of the MTL Transmit FIFO is 64 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_128BYTES ((uint32_t)0x00004000U) /*!< threshold level of the MTL Transmit FIFO is 128 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_192BYTES ((uint32_t)0x00008000U) /*!< threshold level of the MTL Transmit FIFO is 192 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_256BYTES ((uint32_t)0x0000C000U) /*!< threshold level of the MTL Transmit FIFO is 256 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_40BYTES ((uint32_t)0x00010000U) /*!< threshold level of the MTL Transmit FIFO is 40 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_32BYTES ((uint32_t)0x00014000U) /*!< threshold level of the MTL Transmit FIFO is 32 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_24BYTES ((uint32_t)0x00018000U) /*!< threshold level of the MTL Transmit FIFO is 24 Bytes */
-#define ETH_TRANSMITTHRESHOLDCONTROL_16BYTES ((uint32_t)0x0001C000U) /*!< threshold level of the MTL Transmit FIFO is 16 Bytes */
-/**
- * @}
- */
-
-/** @defgroup ETH_Forward_Error_Frames ETH Forward Error Frames
- * @{
- */
-#define ETH_FORWARDERRORFRAMES_ENABLE ((uint32_t)0x00000080U)
-#define ETH_FORWARDERRORFRAMES_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Forward_Undersized_Good_Frames ETH Forward Undersized Good Frames
- * @{
- */
-#define ETH_FORWARDUNDERSIZEDGOODFRAMES_ENABLE ((uint32_t)0x00000040U)
-#define ETH_FORWARDUNDERSIZEDGOODFRAMES_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Receive_Threshold_Control ETH Receive Threshold Control
- * @{
- */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_64BYTES ((uint32_t)0x00000000U) /*!< threshold level of the MTL Receive FIFO is 64 Bytes */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_32BYTES ((uint32_t)0x00000008U) /*!< threshold level of the MTL Receive FIFO is 32 Bytes */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_96BYTES ((uint32_t)0x00000010U) /*!< threshold level of the MTL Receive FIFO is 96 Bytes */
-#define ETH_RECEIVEDTHRESHOLDCONTROL_128BYTES ((uint32_t)0x00000018U) /*!< threshold level of the MTL Receive FIFO is 128 Bytes */
-/**
- * @}
- */
-
-/** @defgroup ETH_Second_Frame_Operate ETH Second Frame Operate
- * @{
- */
-#define ETH_SECONDFRAMEOPERARTE_ENABLE ((uint32_t)0x00000004U)
-#define ETH_SECONDFRAMEOPERARTE_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Address_Aligned_Beats ETH Address Aligned Beats
- * @{
- */
-#define ETH_ADDRESSALIGNEDBEATS_ENABLE ((uint32_t)0x02000000U)
-#define ETH_ADDRESSALIGNEDBEATS_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Fixed_Burst ETH Fixed Burst
- * @{
- */
-#define ETH_FIXEDBURST_ENABLE ((uint32_t)0x00010000U)
-#define ETH_FIXEDBURST_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_Rx_DMA_Burst_Length ETH Rx DMA Burst Length
- * @{
- */
-#define ETH_RXDMABURSTLENGTH_1BEAT ((uint32_t)0x00020000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 1 */
-#define ETH_RXDMABURSTLENGTH_2BEAT ((uint32_t)0x00040000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 2 */
-#define ETH_RXDMABURSTLENGTH_4BEAT ((uint32_t)0x00080000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */
-#define ETH_RXDMABURSTLENGTH_8BEAT ((uint32_t)0x00100000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */
-#define ETH_RXDMABURSTLENGTH_16BEAT ((uint32_t)0x00200000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */
-#define ETH_RXDMABURSTLENGTH_32BEAT ((uint32_t)0x00400000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_4BEAT ((uint32_t)0x01020000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 4 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_8BEAT ((uint32_t)0x01040000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 8 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_16BEAT ((uint32_t)0x01080000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 16 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_32BEAT ((uint32_t)0x01100000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 32 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_64BEAT ((uint32_t)0x01200000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 64 */
-#define ETH_RXDMABURSTLENGTH_4XPBL_128BEAT ((uint32_t)0x01400000U) /*!< maximum number of beats to be transferred in one RxDMA transaction is 128 */
-/**
- * @}
- */
-
-/** @defgroup ETH_Tx_DMA_Burst_Length ETH Tx DMA Burst Length
- * @{
- */
-#define ETH_TXDMABURSTLENGTH_1BEAT ((uint32_t)0x00000100U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 1 */
-#define ETH_TXDMABURSTLENGTH_2BEAT ((uint32_t)0x00000200U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 2 */
-#define ETH_TXDMABURSTLENGTH_4BEAT ((uint32_t)0x00000400U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
-#define ETH_TXDMABURSTLENGTH_8BEAT ((uint32_t)0x00000800U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
-#define ETH_TXDMABURSTLENGTH_16BEAT ((uint32_t)0x00001000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
-#define ETH_TXDMABURSTLENGTH_32BEAT ((uint32_t)0x00002000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_4BEAT ((uint32_t)0x01000100U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 4 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_8BEAT ((uint32_t)0x01000200U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 8 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_16BEAT ((uint32_t)0x01000400U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 16 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_32BEAT ((uint32_t)0x01000800U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 32 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_64BEAT ((uint32_t)0x01001000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 64 */
-#define ETH_TXDMABURSTLENGTH_4XPBL_128BEAT ((uint32_t)0x01002000U) /*!< maximum number of beats to be transferred in one TxDMA (or both) transaction is 128 */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Enhanced_descriptor_format ETH DMA Enhanced descriptor format
- * @{
- */
-#define ETH_DMAENHANCEDDESCRIPTOR_ENABLE ((uint32_t)0x00000080U)
-#define ETH_DMAENHANCEDDESCRIPTOR_DISABLE ((uint32_t)0x00000000U)
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Arbitration ETH DMA Arbitration
- * @{
- */
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_1_1 ((uint32_t)0x00000000U)
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_2_1 ((uint32_t)0x00004000U)
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_3_1 ((uint32_t)0x00008000U)
-#define ETH_DMAARBITRATION_ROUNDROBIN_RXTX_4_1 ((uint32_t)0x0000C000U)
-#define ETH_DMAARBITRATION_RXPRIORTX ((uint32_t)0x00000002U)
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Tx_descriptor_segment ETH DMA Tx descriptor segment
- * @{
- */
-#define ETH_DMATXDESC_LASTSEGMENTS ((uint32_t)0x40000000U) /*!< Last Segment */
-#define ETH_DMATXDESC_FIRSTSEGMENT ((uint32_t)0x20000000U) /*!< First Segment */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Tx_descriptor_Checksum_Insertion_Control ETH DMA Tx descriptor Checksum Insertion Control
- * @{
- */
-#define ETH_DMATXDESC_CHECKSUMBYPASS ((uint32_t)0x00000000U) /*!< Checksum engine bypass */
-#define ETH_DMATXDESC_CHECKSUMIPV4HEADER ((uint32_t)0x00400000U) /*!< IPv4 header checksum insertion */
-#define ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT ((uint32_t)0x00800000U) /*!< TCP/UDP/ICMP checksum insertion. Pseudo header checksum is assumed to be present */
-#define ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL ((uint32_t)0x00C00000U) /*!< TCP/UDP/ICMP checksum fully in hardware including pseudo header */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Rx_descriptor_buffers ETH DMA Rx descriptor buffers
- * @{
- */
-#define ETH_DMARXDESC_BUFFER1 ((uint32_t)0x00000000U) /*!< DMA Rx Desc Buffer1 */
-#define ETH_DMARXDESC_BUFFER2 ((uint32_t)0x00000001U) /*!< DMA Rx Desc Buffer2 */
-/**
- * @}
- */
-
-/** @defgroup ETH_PMT_Flags ETH PMT Flags
- * @{
- */
-#define ETH_PMT_FLAG_WUFFRPR ((uint32_t)0x80000000U) /*!< Wake-Up Frame Filter Register Pointer Reset */
-#define ETH_PMT_FLAG_WUFR ((uint32_t)0x00000040U) /*!< Wake-Up Frame Received */
-#define ETH_PMT_FLAG_MPR ((uint32_t)0x00000020U) /*!< Magic Packet Received */
-/**
- * @}
- */
-
-/** @defgroup ETH_MMC_Tx_Interrupts ETH MMC Tx Interrupts
- * @{
- */
-#define ETH_MMC_IT_TGF ((uint32_t)0x00200000U) /*!< When Tx good frame counter reaches half the maximum value */
-#define ETH_MMC_IT_TGFMSC ((uint32_t)0x00008000U) /*!< When Tx good multi col counter reaches half the maximum value */
-#define ETH_MMC_IT_TGFSC ((uint32_t)0x00004000U) /*!< When Tx good single col counter reaches half the maximum value */
-/**
- * @}
- */
-
-/** @defgroup ETH_MMC_Rx_Interrupts ETH MMC Rx Interrupts
- * @{
- */
-#define ETH_MMC_IT_RGUF ((uint32_t)0x10020000U) /*!< When Rx good unicast frames counter reaches half the maximum value */
-#define ETH_MMC_IT_RFAE ((uint32_t)0x10000040U) /*!< When Rx alignment error counter reaches half the maximum value */
-#define ETH_MMC_IT_RFCE ((uint32_t)0x10000020U) /*!< When Rx crc error counter reaches half the maximum value */
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_Flags ETH MAC Flags
- * @{
- */
-#define ETH_MAC_FLAG_TST ((uint32_t)0x00000200U) /*!< Time stamp trigger flag (on MAC) */
-#define ETH_MAC_FLAG_MMCT ((uint32_t)0x00000040U) /*!< MMC transmit flag */
-#define ETH_MAC_FLAG_MMCR ((uint32_t)0x00000020U) /*!< MMC receive flag */
-#define ETH_MAC_FLAG_MMC ((uint32_t)0x00000010U) /*!< MMC flag (on MAC) */
-#define ETH_MAC_FLAG_PMT ((uint32_t)0x00000008U) /*!< PMT flag (on MAC) */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Flags ETH DMA Flags
- * @{
- */
-#define ETH_DMA_FLAG_TST ((uint32_t)0x20000000U) /*!< Time-stamp trigger interrupt (on DMA) */
-#define ETH_DMA_FLAG_PMT ((uint32_t)0x10000000U) /*!< PMT interrupt (on DMA) */
-#define ETH_DMA_FLAG_MMC ((uint32_t)0x08000000U) /*!< MMC interrupt (on DMA) */
-#define ETH_DMA_FLAG_DATATRANSFERERROR ((uint32_t)0x00800000U) /*!< Error bits 0-Rx DMA, 1-Tx DMA */
-#define ETH_DMA_FLAG_READWRITEERROR ((uint32_t)0x01000000U) /*!< Error bits 0-write transfer, 1-read transfer */
-#define ETH_DMA_FLAG_ACCESSERROR ((uint32_t)0x02000000U) /*!< Error bits 0-data buffer, 1-desc. access */
-#define ETH_DMA_FLAG_NIS ((uint32_t)0x00010000U) /*!< Normal interrupt summary flag */
-#define ETH_DMA_FLAG_AIS ((uint32_t)0x00008000U) /*!< Abnormal interrupt summary flag */
-#define ETH_DMA_FLAG_ER ((uint32_t)0x00004000U) /*!< Early receive flag */
-#define ETH_DMA_FLAG_FBE ((uint32_t)0x00002000U) /*!< Fatal bus error flag */
-#define ETH_DMA_FLAG_ET ((uint32_t)0x00000400U) /*!< Early transmit flag */
-#define ETH_DMA_FLAG_RWT ((uint32_t)0x00000200U) /*!< Receive watchdog timeout flag */
-#define ETH_DMA_FLAG_RPS ((uint32_t)0x00000100U) /*!< Receive process stopped flag */
-#define ETH_DMA_FLAG_RBU ((uint32_t)0x00000080U) /*!< Receive buffer unavailable flag */
-#define ETH_DMA_FLAG_R ((uint32_t)0x00000040U) /*!< Receive flag */
-#define ETH_DMA_FLAG_TU ((uint32_t)0x00000020U) /*!< Underflow flag */
-#define ETH_DMA_FLAG_RO ((uint32_t)0x00000010U) /*!< Overflow flag */
-#define ETH_DMA_FLAG_TJT ((uint32_t)0x00000008U) /*!< Transmit jabber timeout flag */
-#define ETH_DMA_FLAG_TBU ((uint32_t)0x00000004U) /*!< Transmit buffer unavailable flag */
-#define ETH_DMA_FLAG_TPS ((uint32_t)0x00000002U) /*!< Transmit process stopped flag */
-#define ETH_DMA_FLAG_T ((uint32_t)0x00000001U) /*!< Transmit flag */
-/**
- * @}
- */
-
-/** @defgroup ETH_MAC_Interrupts ETH MAC Interrupts
- * @{
- */
-#define ETH_MAC_IT_TST ((uint32_t)0x00000200U) /*!< Time stamp trigger interrupt (on MAC) */
-#define ETH_MAC_IT_MMCT ((uint32_t)0x00000040U) /*!< MMC transmit interrupt */
-#define ETH_MAC_IT_MMCR ((uint32_t)0x00000020U) /*!< MMC receive interrupt */
-#define ETH_MAC_IT_MMC ((uint32_t)0x00000010U) /*!< MMC interrupt (on MAC) */
-#define ETH_MAC_IT_PMT ((uint32_t)0x00000008U) /*!< PMT interrupt (on MAC) */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_Interrupts ETH DMA Interrupts
- * @{
- */
-#define ETH_DMA_IT_TST ((uint32_t)0x20000000U) /*!< Time-stamp trigger interrupt (on DMA) */
-#define ETH_DMA_IT_PMT ((uint32_t)0x10000000U) /*!< PMT interrupt (on DMA) */
-#define ETH_DMA_IT_MMC ((uint32_t)0x08000000U) /*!< MMC interrupt (on DMA) */
-#define ETH_DMA_IT_NIS ((uint32_t)0x00010000U) /*!< Normal interrupt summary */
-#define ETH_DMA_IT_AIS ((uint32_t)0x00008000U) /*!< Abnormal interrupt summary */
-#define ETH_DMA_IT_ER ((uint32_t)0x00004000U) /*!< Early receive interrupt */
-#define ETH_DMA_IT_FBE ((uint32_t)0x00002000U) /*!< Fatal bus error interrupt */
-#define ETH_DMA_IT_ET ((uint32_t)0x00000400U) /*!< Early transmit interrupt */
-#define ETH_DMA_IT_RWT ((uint32_t)0x00000200U) /*!< Receive watchdog timeout interrupt */
-#define ETH_DMA_IT_RPS ((uint32_t)0x00000100U) /*!< Receive process stopped interrupt */
-#define ETH_DMA_IT_RBU ((uint32_t)0x00000080U) /*!< Receive buffer unavailable interrupt */
-#define ETH_DMA_IT_R ((uint32_t)0x00000040U) /*!< Receive interrupt */
-#define ETH_DMA_IT_TU ((uint32_t)0x00000020U) /*!< Underflow interrupt */
-#define ETH_DMA_IT_RO ((uint32_t)0x00000010U) /*!< Overflow interrupt */
-#define ETH_DMA_IT_TJT ((uint32_t)0x00000008U) /*!< Transmit jabber timeout interrupt */
-#define ETH_DMA_IT_TBU ((uint32_t)0x00000004U) /*!< Transmit buffer unavailable interrupt */
-#define ETH_DMA_IT_TPS ((uint32_t)0x00000002U) /*!< Transmit process stopped interrupt */
-#define ETH_DMA_IT_T ((uint32_t)0x00000001U) /*!< Transmit interrupt */
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_transmit_process_state ETH DMA transmit process state
- * @{
- */
-#define ETH_DMA_TRANSMITPROCESS_STOPPED ((uint32_t)0x00000000U) /*!< Stopped - Reset or Stop Tx Command issued */
-#define ETH_DMA_TRANSMITPROCESS_FETCHING ((uint32_t)0x00100000U) /*!< Running - fetching the Tx descriptor */
-#define ETH_DMA_TRANSMITPROCESS_WAITING ((uint32_t)0x00200000U) /*!< Running - waiting for status */
-#define ETH_DMA_TRANSMITPROCESS_READING ((uint32_t)0x00300000U) /*!< Running - reading the data from host memory */
-#define ETH_DMA_TRANSMITPROCESS_SUSPENDED ((uint32_t)0x00600000U) /*!< Suspended - Tx Descriptor unavailable */
-#define ETH_DMA_TRANSMITPROCESS_CLOSING ((uint32_t)0x00700000U) /*!< Running - closing Rx descriptor */
-
-/**
- * @}
- */
-
-
-/** @defgroup ETH_DMA_receive_process_state ETH DMA receive process state
- * @{
- */
-#define ETH_DMA_RECEIVEPROCESS_STOPPED ((uint32_t)0x00000000U) /*!< Stopped - Reset or Stop Rx Command issued */
-#define ETH_DMA_RECEIVEPROCESS_FETCHING ((uint32_t)0x00020000U) /*!< Running - fetching the Rx descriptor */
-#define ETH_DMA_RECEIVEPROCESS_WAITING ((uint32_t)0x00060000U) /*!< Running - waiting for packet */
-#define ETH_DMA_RECEIVEPROCESS_SUSPENDED ((uint32_t)0x00080000U) /*!< Suspended - Rx Descriptor unavailable */
-#define ETH_DMA_RECEIVEPROCESS_CLOSING ((uint32_t)0x000A0000U) /*!< Running - closing descriptor */
-#define ETH_DMA_RECEIVEPROCESS_QUEUING ((uint32_t)0x000E0000U) /*!< Running - queuing the receive frame into host memory */
-
-/**
- * @}
- */
-
-/** @defgroup ETH_DMA_overflow ETH DMA overflow
- * @{
- */
-#define ETH_DMA_OVERFLOW_RXFIFOCOUNTER ((uint32_t)0x10000000U) /*!< Overflow bit for FIFO overflow counter */
-#define ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER ((uint32_t)0x00010000U) /*!< Overflow bit for missed frame counter */
-/**
- * @}
- */
-
-/** @defgroup ETH_EXTI_LINE_WAKEUP ETH EXTI LINE WAKEUP
- * @{
- */
-#define ETH_EXTI_LINE_WAKEUP ((uint32_t)0x00080000U) /*!< External interrupt line 19 Connected to the ETH EXTI Line */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/* Exported macro ------------------------------------------------------------*/
-/** @defgroup ETH_Exported_Macros ETH Exported Macros
- * @brief macros to handle interrupts and specific clock configurations
- * @{
- */
-
-/** @brief Reset ETH handle state
- * @param __HANDLE__: specifies the ETH handle.
- * @retval None
- */
-#define __HAL_ETH_RESET_HANDLE_STATE(__HANDLE__) ((__HANDLE__)->State = HAL_ETH_STATE_RESET)
-
-/**
- * @brief Checks whether the specified Ethernet DMA Tx Desc flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag of TDES0 to check.
- * @retval the ETH_DMATxDescFlag (SET or RESET).
- */
-#define __HAL_ETH_DMATXDESC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->TxDesc->Status & (__FLAG__) == (__FLAG__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA Rx Desc flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag of RDES0 to check.
- * @retval the ETH_DMATxDescFlag (SET or RESET).
- */
-#define __HAL_ETH_DMARXDESC_GET_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->RxDesc->Status & (__FLAG__) == (__FLAG__))
-
-/**
- * @brief Enables the specified DMA Rx Desc receive interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMARXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->RxDesc->ControlBufferSize &=(~(uint32_t)ETH_DMARXDESC_DIC))
-
-/**
- * @brief Disables the specified DMA Rx Desc receive interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMARXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->RxDesc->ControlBufferSize |= ETH_DMARXDESC_DIC)
-
-/**
- * @brief Set the specified DMA Rx Desc Own bit.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMARXDESC_SET_OWN_BIT(__HANDLE__) ((__HANDLE__)->RxDesc->Status |= ETH_DMARXDESC_OWN)
-
-/**
- * @brief Returns the specified Ethernet DMA Tx Desc collision count.
- * @param __HANDLE__: ETH Handle
- * @retval The Transmit descriptor collision counter value.
- */
-#define __HAL_ETH_DMATXDESC_GET_COLLISION_COUNT(__HANDLE__) (((__HANDLE__)->TxDesc->Status & ETH_DMATXDESC_CC) >> ETH_DMATXDESC_COLLISION_COUNTSHIFT)
-
-/**
- * @brief Set the specified DMA Tx Desc Own bit.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_SET_OWN_BIT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_OWN)
-
-/**
- * @brief Enables the specified DMA Tx Desc Transmit interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_ENABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_IC)
-
-/**
- * @brief Disables the specified DMA Tx Desc Transmit interrupt.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_DISABLE_IT(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_IC)
-
-/**
- * @brief Selects the specified Ethernet DMA Tx Desc Checksum Insertion.
- * @param __HANDLE__: ETH Handle
- * @param __CHECKSUM__: specifies is the DMA Tx desc checksum insertion.
- * This parameter can be one of the following values:
- * @arg ETH_DMATXDESC_CHECKSUMBYPASS : Checksum bypass
- * @arg ETH_DMATXDESC_CHECKSUMIPV4HEADER : IPv4 header checksum
- * @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPSEGMENT : TCP/UDP/ICMP checksum. Pseudo header checksum is assumed to be present
- * @arg ETH_DMATXDESC_CHECKSUMTCPUDPICMPFULL : TCP/UDP/ICMP checksum fully in hardware including pseudo header
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_CHECKSUM_INSERTION(__HANDLE__, __CHECKSUM__) ((__HANDLE__)->TxDesc->Status |= (__CHECKSUM__))
-
-/**
- * @brief Enables the DMA Tx Desc CRC.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_CRC_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DC)
-
-/**
- * @brief Disables the DMA Tx Desc CRC.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_CRC_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DC)
-
-/**
- * @brief Enables the DMA Tx Desc padding for frame shorter than 64 bytes.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_ENABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status &= ~ETH_DMATXDESC_DP)
-
-/**
- * @brief Disables the DMA Tx Desc padding for frame shorter than 64 bytes.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_DMATXDESC_SHORT_FRAME_PADDING_DISABLE(__HANDLE__) ((__HANDLE__)->TxDesc->Status |= ETH_DMATXDESC_DP)
-
-/**
- * @brief Enables the specified Ethernet MAC interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet MAC interrupt sources to be
- * enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
- * @arg ETH_MAC_IT_PMT : PMT interrupt
- * @retval None
- */
-#define __HAL_ETH_MAC_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR |= (__INTERRUPT__))
-
-/**
- * @brief Disables the specified Ethernet MAC interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet MAC interrupt sources to be
- * enabled or disabled.
- * This parameter can be any combination of the following values:
- * @arg ETH_MAC_IT_TST : Time stamp trigger interrupt
- * @arg ETH_MAC_IT_PMT : PMT interrupt
- * @retval None
- */
-#define __HAL_ETH_MAC_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MACIMR &= ~(__INTERRUPT__))
-
-/**
- * @brief Initiate a Pause Control Frame (Full-duplex only).
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_INITIATE_PAUSE_CONTROL_FRAME(__HANDLE__) ((__HANDLE__)->Instance->MACFCR |= ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Checks whether the Ethernet flow control busy bit is set or not.
- * @param __HANDLE__: ETH Handle
- * @retval The new state of flow control busy status bit (SET or RESET).
- */
-#define __HAL_ETH_GET_FLOW_CONTROL_BUSY_STATUS(__HANDLE__) (((__HANDLE__)->Instance->MACFCR & ETH_MACFCR_FCBBPA) == ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Enables the MAC Back Pressure operation activation (Half-duplex only).
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_BACK_PRESSURE_ACTIVATION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACFCR |= ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Disables the MAC BackPressure operation activation (Half-duplex only).
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_BACK_PRESSURE_ACTIVATION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACFCR &= ~ETH_MACFCR_FCBBPA)
-
-/**
- * @brief Checks whether the specified Ethernet MAC flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg ETH_MAC_FLAG_TST : Time stamp trigger flag
- * @arg ETH_MAC_FLAG_MMCT : MMC transmit flag
- * @arg ETH_MAC_FLAG_MMCR : MMC receive flag
- * @arg ETH_MAC_FLAG_MMC : MMC flag
- * @arg ETH_MAC_FLAG_PMT : PMT flag
- * @retval The state of Ethernet MAC flag.
- */
-#define __HAL_ETH_MAC_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACSR &( __FLAG__)) == ( __FLAG__))
-
-/**
- * @brief Enables the specified Ethernet DMA interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet DMA interrupt sources to be
- * enabled @ref ETH_DMA_Interrupts
- * @retval None
- */
-#define __HAL_ETH_DMA_ENABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER |= (__INTERRUPT__))
-
-/**
- * @brief Disables the specified Ethernet DMA interrupts.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the Ethernet DMA interrupt sources to be
- * disabled. @ref ETH_DMA_Interrupts
- * @retval None
- */
-#define __HAL_ETH_DMA_DISABLE_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMAIER &= ~(__INTERRUPT__))
-
-/**
- * @brief Clears the Ethernet DMA IT pending bit.
- * @param __HANDLE__ : ETH Handle
- * @param __INTERRUPT__: specifies the interrupt pending bit to clear. @ref ETH_DMA_Interrupts
- * @retval None
- */
-#define __HAL_ETH_DMA_CLEAR_IT(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->DMASR =(__INTERRUPT__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA flag is set or not.
-* @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag to check. @ref ETH_DMA_Flags
- * @retval The new state of ETH_DMA_FLAG (SET or RESET).
- */
-#define __HAL_ETH_DMA_GET_FLAG(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->DMASR &( __FLAG__)) == ( __FLAG__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __FLAG__: specifies the flag to clear. @ref ETH_DMA_Flags
- * @retval The new state of ETH_DMA_FLAG (SET or RESET).
- */
-#define __HAL_ETH_DMA_CLEAR_FLAG(__HANDLE__, __FLAG__) ((__HANDLE__)->Instance->DMASR = (__FLAG__))
-
-/**
- * @brief Checks whether the specified Ethernet DMA overflow flag is set or not.
- * @param __HANDLE__: ETH Handle
- * @param __OVERFLOW__: specifies the DMA overflow flag to check.
- * This parameter can be one of the following values:
- * @arg ETH_DMA_OVERFLOW_RXFIFOCOUNTER : Overflow for FIFO Overflows Counter
- * @arg ETH_DMA_OVERFLOW_MISSEDFRAMECOUNTER : Overflow for Buffer Unavailable Missed Frame Counter
- * @retval The state of Ethernet DMA overflow Flag (SET or RESET).
- */
-#define __HAL_ETH_GET_DMA_OVERFLOW_STATUS(__HANDLE__, __OVERFLOW__) (((__HANDLE__)->Instance->DMAMFBOCR & (__OVERFLOW__)) == (__OVERFLOW__))
-
-/**
- * @brief Set the DMA Receive status watchdog timer register value
- * @param __HANDLE__: ETH Handle
- * @param __VALUE__: DMA Receive status watchdog timer register value
- * @retval None
- */
-#define __HAL_ETH_SET_RECEIVE_WATCHDOG_TIMER(__HANDLE__, __VALUE__) ((__HANDLE__)->Instance->DMARSWTR = (__VALUE__))
-
-/**
- * @brief Enables any unicast packet filtered by the MAC address
- * recognition to be a wake-up frame.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_GLOBAL_UNICAST_WAKEUP_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_GU)
-
-/**
- * @brief Disables any unicast packet filtered by the MAC address
- * recognition to be a wake-up frame.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_GLOBAL_UNICAST_WAKEUP_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_GU)
-
-/**
- * @brief Enables the MAC Wake-Up Frame Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_FRAME_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_WFE)
-
-/**
- * @brief Disables the MAC Wake-Up Frame Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_FRAME_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_WFE)
-
-/**
- * @brief Enables the MAC Magic Packet Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MAGIC_PACKET_DETECTION_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_MPE)
-
-/**
- * @brief Disables the MAC Magic Packet Detection.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MAGIC_PACKET_DETECTION_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_WFE)
-
-/**
- * @brief Enables the MAC Power Down.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_POWER_DOWN_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR |= ETH_MACPMTCSR_PD)
-
-/**
- * @brief Disables the MAC Power Down.
- * @param __HANDLE__: ETH Handle
- * @retval None
- */
-#define __HAL_ETH_POWER_DOWN_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MACPMTCSR &= ~ETH_MACPMTCSR_PD)
-
-/**
- * @brief Checks whether the specified Ethernet PMT flag is set or not.
- * @param __HANDLE__: ETH Handle.
- * @param __FLAG__: specifies the flag to check.
- * This parameter can be one of the following values:
- * @arg ETH_PMT_FLAG_WUFFRPR : Wake-Up Frame Filter Register Pointer Reset
- * @arg ETH_PMT_FLAG_WUFR : Wake-Up Frame Received
- * @arg ETH_PMT_FLAG_MPR : Magic Packet Received
- * @retval The new state of Ethernet PMT Flag (SET or RESET).
- */
-#define __HAL_ETH_GET_PMT_FLAG_STATUS(__HANDLE__, __FLAG__) (((__HANDLE__)->Instance->MACPMTCSR &( __FLAG__)) == ( __FLAG__))
-
-/**
- * @brief Preset and Initialize the MMC counters to almost-full value: 0xFFFF_FFF0 (full - 16)
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_FULL_PRESET(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= (ETH_MMCCR_MCFHP | ETH_MMCCR_MCP))
-
-/**
- * @brief Preset and Initialize the MMC counters to almost-half value: 0x7FFF_FFF0 (half - 16)
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_HALF_PRESET(__HANDLE__) do{(__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_MCFHP;\
- (__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_MCP;} while (0)
-
-/**
- * @brief Enables the MMC Counter Freeze.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_FREEZE_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_MCF)
-
-/**
- * @brief Disables the MMC Counter Freeze.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTER_FREEZE_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_MCF)
-
-/**
- * @brief Enables the MMC Reset On Read.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_RESET_ONREAD_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_ROR)
-
-/**
- * @brief Disables the MMC Reset On Read.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_RESET_ONREAD_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_ROR)
-
-/**
- * @brief Enables the MMC Counter Stop Rollover.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_COUNTER_ROLLOVER_ENABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR &= ~ETH_MMCCR_CSR)
-
-/**
- * @brief Disables the MMC Counter Stop Rollover.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_ETH_MMC_COUNTER_ROLLOVER_DISABLE(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_CSR)
-
-/**
- * @brief Resets the MMC Counters.
- * @param __HANDLE__: ETH Handle.
- * @retval None
- */
-#define __HAL_ETH_MMC_COUNTERS_RESET(__HANDLE__) ((__HANDLE__)->Instance->MMCCR |= ETH_MMCCR_CR)
-
-/**
- * @brief Enables the specified Ethernet MMC Rx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_RX_IT_ENABLE(__HANDLE__, __INTERRUPT__) (__HANDLE__)->Instance->MMCRIMR &= ~((__INTERRUPT__) & 0xEFFFFFFF)
-/**
- * @brief Disables the specified Ethernet MMC Rx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_RGUF : When Rx good unicast frames counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFAE : When Rx alignment error counter reaches half the maximum value
- * @arg ETH_MMC_IT_RFCE : When Rx crc error counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_RX_IT_DISABLE(__HANDLE__, __INTERRUPT__) (__HANDLE__)->Instance->MMCRIMR |= ((__INTERRUPT__) & 0xEFFFFFFF)
-/**
- * @brief Enables the specified Ethernet MMC Tx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_TX_IT_ENABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR &= ~ (__INTERRUPT__))
-
-/**
- * @brief Disables the specified Ethernet MMC Tx interrupts.
- * @param __HANDLE__: ETH Handle.
- * @param __INTERRUPT__: specifies the Ethernet MMC interrupt sources to be enabled or disabled.
- * This parameter can be one of the following values:
- * @arg ETH_MMC_IT_TGF : When Tx good frame counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFMSC: When Tx good multi col counter reaches half the maximum value
- * @arg ETH_MMC_IT_TGFSC : When Tx good single col counter reaches half the maximum value
- * @retval None
- */
-#define __HAL_ETH_MMC_TX_IT_DISABLE(__HANDLE__, __INTERRUPT__) ((__HANDLE__)->Instance->MMCRIMR |= (__INTERRUPT__))
-
-/**
- * @brief Enables the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_IT() EXTI->IMR |= (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Disables the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_IT() EXTI->IMR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enable event on ETH External event line.
- * @retval None.
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_EVENT() EXTI->EMR |= (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Disable event on ETH External event line
- * @retval None.
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_EVENT() EXTI->EMR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Get flag of the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_GET_FLAG() EXTI->PR & (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Clear flag of the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_CLEAR_FLAG() EXTI->PR = (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enables rising edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_RISING_EDGE_TRIGGER() EXTI->RTSR |= ETH_EXTI_LINE_WAKEUP
-
-/**
- * @brief Disables the rising edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_RISING_EDGE_TRIGGER() EXTI->RTSR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enables falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLING_EDGE_TRIGGER() EXTI->FTSR |= (ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Disables falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_FALLING_EDGE_TRIGGER() EXTI->FTSR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Enables rising/falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_ENABLE_FALLINGRISING_TRIGGER() EXTI->RTSR |= ETH_EXTI_LINE_WAKEUP;\
- EXTI->FTSR |= ETH_EXTI_LINE_WAKEUP
-
-/**
- * @brief Disables rising/falling edge trigger to the ETH External interrupt line.
- * @retval None
- */
-#define __HAL_ETH_WAKEUP_EXTI_DISABLE_FALLINGRISING_TRIGGER() EXTI->RTSR &= ~(ETH_EXTI_LINE_WAKEUP);\
- EXTI->FTSR &= ~(ETH_EXTI_LINE_WAKEUP)
-
-/**
- * @brief Generate a Software interrupt on selected EXTI line.
- * @retval None.
- */
-#define __HAL_ETH_WAKEUP_EXTI_GENERATE_SWIT() EXTI->SWIER|= ETH_EXTI_LINE_WAKEUP
-
-/**
- * @}
- */
-/* Exported functions --------------------------------------------------------*/
-
-/** @addtogroup ETH_Exported_Functions
- * @{
- */
-
-/* Initialization and de-initialization functions ****************************/
-
-/** @addtogroup ETH_Exported_Functions_Group1
- * @{
- */
-HAL_StatusTypeDef HAL_ETH_Init(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_DeInit(ETH_HandleTypeDef *heth);
-void HAL_ETH_MspInit(ETH_HandleTypeDef *heth);
-void HAL_ETH_MspDeInit(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_DMATxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMATxDescTab, uint8_t* TxBuff, uint32_t TxBuffCount);
-HAL_StatusTypeDef HAL_ETH_DMARxDescListInit(ETH_HandleTypeDef *heth, ETH_DMADescTypeDef *DMARxDescTab, uint8_t *RxBuff, uint32_t RxBuffCount);
-
-/**
- * @}
- */
-/* IO operation functions ****************************************************/
-
-/** @addtogroup ETH_Exported_Functions_Group2
- * @{
- */
-HAL_StatusTypeDef HAL_ETH_TransmitFrame(ETH_HandleTypeDef *heth, uint32_t FrameLength);
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame(ETH_HandleTypeDef *heth);
-/* Communication with PHY functions*/
-HAL_StatusTypeDef HAL_ETH_ReadPHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t *RegValue);
-HAL_StatusTypeDef HAL_ETH_WritePHYRegister(ETH_HandleTypeDef *heth, uint16_t PHYReg, uint32_t RegValue);
-/* Non-Blocking mode: Interrupt */
-HAL_StatusTypeDef HAL_ETH_GetReceivedFrame_IT(ETH_HandleTypeDef *heth);
-void HAL_ETH_IRQHandler(ETH_HandleTypeDef *heth);
-/* Callback in non blocking modes (Interrupt) */
-void HAL_ETH_TxCpltCallback(ETH_HandleTypeDef *heth);
-void HAL_ETH_RxCpltCallback(ETH_HandleTypeDef *heth);
-void HAL_ETH_ErrorCallback(ETH_HandleTypeDef *heth);
-/**
- * @}
- */
-
-/* Peripheral Control functions **********************************************/
-
-/** @addtogroup ETH_Exported_Functions_Group3
- * @{
- */
-
-HAL_StatusTypeDef HAL_ETH_Start(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_Stop(ETH_HandleTypeDef *heth);
-HAL_StatusTypeDef HAL_ETH_ConfigMAC(ETH_HandleTypeDef *heth, ETH_MACInitTypeDef *macconf);
-HAL_StatusTypeDef HAL_ETH_ConfigDMA(ETH_HandleTypeDef *heth, ETH_DMAInitTypeDef *dmaconf);
-/**
- * @}
- */
-
-/* Peripheral State functions ************************************************/
-
-/** @addtogroup ETH_Exported_Functions_Group4
- * @{
- */
-HAL_ETH_StateTypeDef HAL_ETH_GetState(ETH_HandleTypeDef *heth);
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-
-/**
- * @}
- */
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __STM32Fxx_HAL_ETH_H */
-
-
-/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
index 502fbd661..8e64a40cc 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/FaultInjection.c
@@ -1,175 +1,175 @@
-#define xBUFFER_CACHE_SIZE 10
-#define xMAX_FAULT_INJECTION_RATE 15
-#define xMIN_FAULT_INJECTION_RATE 3
-#define xNUM_FAULT_TYPES 1
-
-static NetworkBufferDescriptor_t *xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
-
-#define xFAULT_LOG_SIZE 2048
-uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
-uint32_t ulFaultLogIndex = 0;
-
-static BaseType_t prvCachePacket( NetworkBufferDescriptor_t *pxNetworkBufferIn )
-{
-BaseType_t x, xReturn = pdFALSE;
-
- for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
- {
- if( xNetworkBufferCache[ x ] == NULL )
- {
- xNetworkBufferCache[ x ] = pxNetworkBufferIn;
- xReturn = pdTRUE;
- break;
- }
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvGetCachedPacket( void )
-{
-BaseType_t x;
-NetworkBufferDescriptor_t *pxReturn = NULL;
-
- for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
- {
- if( xNetworkBufferCache[ x ] != NULL )
- {
- pxReturn = xNetworkBufferCache[ x ];
- xNetworkBufferCache[ x ] = NULL;
- break;
- }
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket, const uint8_t *pucPacketData )
-{
-NetworkBufferDescriptor_t *pxReturn;
-
- /* Obtain a new descriptor. */
- pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
-
- if( pxReturn != NULL )
- {
- /* Copy in the packet data. */
- pxReturn->xDataLength = pxOriginalPacket->xDataLength;
- memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-static NetworkBufferDescriptor_t *prvRxFaultInjection( NetworkBufferDescriptor_t *pxNetworkBufferIn, const uint8_t *pucPacketData )
-{
-static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
-NetworkBufferDescriptor_t *pxReturn = pxNetworkBufferIn;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-uint32_t ulFault;
-
-return pxNetworkBufferIn;
-
- ulCallCount++;
-
- if( ulCallCount > ulNextFaultCallCount )
- {
- xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
- ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
- if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
- {
- ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
- }
-
- ulCallCount = 0;
-
- xApplicationGetRandomNumber( &( ulFault ) );
- ulFault = ulFault % xNUM_FAULT_TYPES;
-
- if( ulFaultLogIndex < xFAULT_LOG_SIZE )
- {
- ulInjectedFault[ ulFaultLogIndex ] = ulFault;
- ulFaultLogIndex++;
- }
-
- switch( ulFault )
- {
- case 0:
- /* Just drop the packet. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- pxReturn = NULL;
- break;
-
- case 1:
- /* Store the packet in the cache for later. */
- if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
- {
- /* The packet may get sent later, it is not being sent
- now. */
- pxReturn = NULL;
- }
- break;
-
- case 2:
- /* Send a cached packet. */
- pxReturn = prvGetCachedPacket();
- if( pxReturn != NULL )
- {
- /* A cached packet was obtained so drop the original
- packet. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- }
- else
- {
- /* Could not obtain a packet from the cache so just return
- the packet that was passed in. */
- pxReturn = pxNetworkBufferIn;
- }
- break;
-
- case 4:
-
- /* Send a duplicate of the packet right away. */
- pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
-
- /* Send the original packet to the stack. */
- xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- }
- break;
-
- case 5:
-
- /* Send both a cached packet and the current packet. */
- xRxEvent.pvData = ( void * ) prvGetCachedPacket();
- if( xRxEvent.pvData != NULL )
- {
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
- }
- }
- break;
-
- case 6:
- case 7:
- case 8:
- /* Store the packet in the cache for later. */
- if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
- {
- /* The packet may get sent later, it is not being sent
- now. */
- pxReturn = NULL;
- }
- break;
- }
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
+#define xBUFFER_CACHE_SIZE 10
+#define xMAX_FAULT_INJECTION_RATE 15
+#define xMIN_FAULT_INJECTION_RATE 3
+#define xNUM_FAULT_TYPES 1
+
+static NetworkBufferDescriptor_t *xNetworkBufferCache[ xBUFFER_CACHE_SIZE ] = { 0 };
+
+#define xFAULT_LOG_SIZE 2048
+uint32_t ulInjectedFault[ xFAULT_LOG_SIZE ];
+uint32_t ulFaultLogIndex = 0;
+
+static BaseType_t prvCachePacket( NetworkBufferDescriptor_t *pxNetworkBufferIn )
+{
+BaseType_t x, xReturn = pdFALSE;
+
+ for( x = 0; x < xBUFFER_CACHE_SIZE; x++ )
+ {
+ if( xNetworkBufferCache[ x ] == NULL )
+ {
+ xNetworkBufferCache[ x ] = pxNetworkBufferIn;
+ xReturn = pdTRUE;
+ break;
+ }
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvGetCachedPacket( void )
+{
+BaseType_t x;
+NetworkBufferDescriptor_t *pxReturn = NULL;
+
+ for( x = ( xBUFFER_CACHE_SIZE - 1 ); x >= 0; x-- )
+ {
+ if( xNetworkBufferCache[ x ] != NULL )
+ {
+ pxReturn = xNetworkBufferCache[ x ];
+ xNetworkBufferCache[ x ] = NULL;
+ break;
+ }
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvDuplicatePacket( NetworkBufferDescriptor_t * pxOriginalPacket, const uint8_t *pucPacketData )
+{
+NetworkBufferDescriptor_t *pxReturn;
+
+ /* Obtain a new descriptor. */
+ pxReturn = pxGetNetworkBufferWithDescriptor( pxOriginalPacket->xDataLength, 0 );
+
+ if( pxReturn != NULL )
+ {
+ /* Copy in the packet data. */
+ pxReturn->xDataLength = pxOriginalPacket->xDataLength;
+ memcpy( pxReturn->pucEthernetBuffer, pucPacketData, pxOriginalPacket->xDataLength );
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+static NetworkBufferDescriptor_t *prvRxFaultInjection( NetworkBufferDescriptor_t *pxNetworkBufferIn, const uint8_t *pucPacketData )
+{
+static uint32_t ulCallCount = 0, ulNextFaultCallCount = 0;
+NetworkBufferDescriptor_t *pxReturn = pxNetworkBufferIn;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+uint32_t ulFault;
+
+return pxNetworkBufferIn;
+
+ ulCallCount++;
+
+ if( ulCallCount > ulNextFaultCallCount )
+ {
+ xApplicationGetRandomNumber( &( ulNextFaultCallCount ) );
+ ulNextFaultCallCount = ulNextFaultCallCount % xMAX_FAULT_INJECTION_RATE;
+ if( ulNextFaultCallCount < xMIN_FAULT_INJECTION_RATE )
+ {
+ ulNextFaultCallCount = xMIN_FAULT_INJECTION_RATE;
+ }
+
+ ulCallCount = 0;
+
+ xApplicationGetRandomNumber( &( ulFault ) );
+ ulFault = ulFault % xNUM_FAULT_TYPES;
+
+ if( ulFaultLogIndex < xFAULT_LOG_SIZE )
+ {
+ ulInjectedFault[ ulFaultLogIndex ] = ulFault;
+ ulFaultLogIndex++;
+ }
+
+ switch( ulFault )
+ {
+ case 0:
+ /* Just drop the packet. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ pxReturn = NULL;
+ break;
+
+ case 1:
+ /* Store the packet in the cache for later. */
+ if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
+ {
+ /* The packet may get sent later, it is not being sent
+ now. */
+ pxReturn = NULL;
+ }
+ break;
+
+ case 2:
+ /* Send a cached packet. */
+ pxReturn = prvGetCachedPacket();
+ if( pxReturn != NULL )
+ {
+ /* A cached packet was obtained so drop the original
+ packet. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ }
+ else
+ {
+ /* Could not obtain a packet from the cache so just return
+ the packet that was passed in. */
+ pxReturn = pxNetworkBufferIn;
+ }
+ break;
+
+ case 4:
+
+ /* Send a duplicate of the packet right away. */
+ pxReturn = prvDuplicatePacket( pxNetworkBufferIn, pucPacketData );
+
+ /* Send the original packet to the stack. */
+ xRxEvent.pvData = ( void * ) pxNetworkBufferIn;
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ }
+ break;
+
+ case 5:
+
+ /* Send both a cached packet and the current packet. */
+ xRxEvent.pvData = ( void * ) prvGetCachedPacket();
+ if( xRxEvent.pvData != NULL )
+ {
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBufferIn );
+ }
+ }
+ break;
+
+ case 6:
+ case 7:
+ case 8:
+ /* Store the packet in the cache for later. */
+ if( prvCachePacket( pxNetworkBufferIn ) == pdTRUE )
+ {
+ /* The packet may get sent later, it is not being sent
+ now. */
+ pxReturn = NULL;
+ }
+ break;
+ }
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c
index 474629e46..c4a12515b 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/WinPCap/NetworkInterface.c
@@ -1,634 +1,634 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* WinPCap includes. */
-#define HAVE_REMOTE
-#include "pcap.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-/* Thread-safe circular buffers are being used to pass data to and from the PCAP
-access functions. */
-#include "Win32-Extensions.h"
-#include "FreeRTOS_Stream_Buffer.h"
-
-/* Sizes of the thread safe circular buffers used to pass data to and from the
-WinPCAP Windows threads. */
-#define xSEND_BUFFER_SIZE 32768
-#define xRECV_BUFFER_SIZE 32768
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
- #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-/* Used to insert test code only. */
-#define niDISRUPT_PACKETS 0
-
-/*-----------------------------------------------------------*/
-
-/*
- * Windows threads that are outside of the control of the FreeRTOS simulator are
- * used to interface with the WinPCAP libraries.
- */
-DWORD WINAPI prvWinPcapRecvThread( void *pvParam );
-DWORD WINAPI prvWinPcapSendThread( void *pvParam );
-
-/*
- * Print out a numbered list of network interfaces that are available on the
- * host computer.
- */
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
-
-/*
- * Open the network interface. The number of the interface to be opened is set
- * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- */
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
-static int prvOpenInterface( const char *pucName );
-
-/*
- * Configure the capture filter to allow blocking reads, and to filter out
- * packets that are not of interest to this demo.
- */
-static void prvConfigureCaptureBehaviour( void );
-
-/*
- * A function that simulates Ethernet interrupts by periodically polling the
- * WinPCap interface for new data.
- */
-static void prvInterruptSimulatorTask( void *pvParameters );
-
-/*
- * Create the buffers that are used to pass data between the FreeRTOS simulator
- * and the Win32 threads that manage WinPCAP.
- */
-static void prvCreateThreadSafeBuffers( void );
-
-/*
- * Utility function used to format print messages only.
- */
-static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage );
-
-/*-----------------------------------------------------------*/
-
-/* Required by the WinPCap library. */
-static char cErrorBuffer[ PCAP_ERRBUF_SIZE ];
-
-/* An event used to wake up the Win32 thread that sends data through the WinPCAP
-library. */
-static void *pvSendEvent = NULL;
-
-/* _HT_ made the PCAP interface number configurable through the program's
-parameters in order to test in different machines. */
-static BaseType_t xConfigNetworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
-
-/* Handles to the Windows threads that handle the PCAP IO. */
-static HANDLE vWinPcapRecvThreadHandle = NULL;
-static HANDLE vWinPcapSendThreadHandle = NULL;;
-
-/* The interface being used by WinPCap. */
-static pcap_t *pxOpenedInterfaceHandle = NULL;
-
-/* Circular buffers used by the PCAP Win32 threads. */
-static StreamBuffer_t *xSendBuffer = NULL;
-static StreamBuffer_t *xRecvBuffer = NULL;
-
-/* The MAC address initially set to the constants defined in FreeRTOSConfig.h. */
-extern uint8_t ucMACAddress[ 6 ];
-
-/* Logs the number of WinPCAP send failures, for viewing in the debugger only. */
-static volatile uint32_t ulWinPCAPSendFailures = 0;
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-BaseType_t xReturn = pdFALSE;
-pcap_if_t *pxAllNetworkInterfaces;
-
- /* Query the computer the simulation is being executed on to find the
- network interfaces it has installed. */
- pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
-
- /* Open the network interface. The number of the interface to be opened is
- set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
- Calling this function will set the pxOpenedInterfaceHandle variable. If,
- after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
- the interface could not be opened. */
- if( pxAllNetworkInterfaces != NULL )
- {
- prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
- }
-
- if( pxOpenedInterfaceHandle != NULL )
- {
- xReturn = pdPASS;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvCreateThreadSafeBuffers( void )
-{
- /* The buffer used to pass data to be transmitted from a FreeRTOS task to
- the Win32 thread that sends via the WinPCAP library. */
- if( xSendBuffer == NULL)
- {
- xSendBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) + xSEND_BUFFER_SIZE + 1 );
- configASSERT( xSendBuffer );
- memset( xSendBuffer, '\0', sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) );
- xSendBuffer->LENGTH = xSEND_BUFFER_SIZE + 1;
- }
-
- /* The buffer used to pass received data from the Win32 thread that receives
- via the WinPCAP library to the FreeRTOS task. */
- if( xRecvBuffer == NULL)
- {
- xRecvBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) + xRECV_BUFFER_SIZE + 1 );
- configASSERT( xRecvBuffer );
- memset( xRecvBuffer, '\0', sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) );
- xRecvBuffer->LENGTH = xRECV_BUFFER_SIZE + 1;
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
-{
-size_t xSpace;
-
- iptraceNETWORK_INTERFACE_TRANSMIT();
- configASSERT( xIsCallingFromIPTask() == pdTRUE );
-
- /* Both the length of the data being sent and the actual data being sent
- are placed in the thread safe buffer used to pass data between the FreeRTOS
- tasks and the Win32 thread that sends data via the WinPCAP library. Drop
- the packet if there is insufficient space in the buffer to hold both. */
- xSpace = uxStreamBufferGetSpace( xSendBuffer );
-
- if( ( pxNetworkBuffer->xDataLength <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
- ( xSpace >= ( pxNetworkBuffer->xDataLength + sizeof( pxNetworkBuffer->xDataLength ) ) ) )
- {
- /* First write in the length of the data, then write in the data
- itself. */
- uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) &( pxNetworkBuffer->xDataLength ), sizeof( pxNetworkBuffer->xDataLength ) );
- uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
- }
- else
- {
- FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: send buffers full to store %lu\n", pxNetworkBuffer->xDataLength ) );
- }
-
- /* Kick the Tx task in either case in case it doesn't know the buffer is
- full. */
- SetEvent( pvSendEvent );
-
- /* The buffer has been sent so can be released. */
- if( bReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
-
- return pdPASS;
-}
-/*-----------------------------------------------------------*/
-
-static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
-{
-pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
-int32_t lInterfaceNumber = 1;
-char cBuffer[ 512 ];
-static BaseType_t xInvalidInterfaceDetected = pdFALSE;
-
- if( xInvalidInterfaceDetected == pdFALSE )
- {
- if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
- {
- printf( "Could not obtain a list of network interfaces\n%s\n", cErrorBuffer );
- pxAllNetworkInterfaces = NULL;
- }
- else
- {
- printf( "\r\n\r\nThe following network interfaces are available:\r\n\r\n" );
- }
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Print out the list of network interfaces. The first in the list
- is interface '1', not interface '0'. */
- for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
- {
- /* The descriptions of the devices can be full of spaces, clean them
- a little. printf() can only be used here because the network is not
- up yet - so no other network tasks will be running. */
- printf( "Interface %d - %s\n", lInterfaceNumber, prvRemoveSpaces( cBuffer, sizeof( cBuffer ), xInterface->name ) );
- printf( " (%s)\n", prvRemoveSpaces(cBuffer, sizeof( cBuffer ), xInterface->description ? xInterface->description : "No description" ) );
- printf( "\n" );
- lInterfaceNumber++;
- }
- }
-
- if( lInterfaceNumber == 1 )
- {
- /* The interface number was never incremented, so the above for() loop
- did not execute meaning no interfaces were found. */
- printf( " \nNo network interfaces were found.\n" );
- pxAllNetworkInterfaces = NULL;
- }
-
- printf( "\r\nThe interface that will be opened is set by " );
- printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
-
- if( ( xConfigNetworkInterfaceToUse < 1L ) || ( xConfigNetworkInterfaceToUse >= lInterfaceNumber ) )
- {
- printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNetworkInterfaceToUse );
- printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
- printf( "then re-compile and re-start the application. Only Ethernet (as opposed to WiFi)\r\n" );
- printf( "interfaces are supported.\r\n\r\nHALTING\r\n\r\n\r\n" );
- xInvalidInterfaceDetected = pdTRUE;
-
- if( pxAllNetworkInterfaces != NULL )
- {
- /* Free the device list, as no devices are going to be opened. */
- pcap_freealldevs( pxAllNetworkInterfaces );
- pxAllNetworkInterfaces = NULL;
- }
- }
- else
- {
- printf( "Attempting to open interface number %d.\n", xConfigNetworkInterfaceToUse );
- }
- }
-
- return pxAllNetworkInterfaces;
-}
-/*-----------------------------------------------------------*/
-
-static int prvOpenInterface( const char *pucName )
-{
-static char pucInterfaceName[ 256 ];
-
- if( pucName != NULL )
- {
- strncpy( pucInterfaceName, pucName, sizeof( pucInterfaceName ) );
- }
-
- pxOpenedInterfaceHandle = pcap_open( pucInterfaceName, /* The name of the selected interface. */
- ipTOTAL_ETHERNET_FRAME_SIZE, /* The size of the packet to capture. */
- PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and
- IP address is going to be "simulated", and
- not be the real MAC and IP address. This allows
- traffic to the simulated IP address to be routed
- to uIP, and traffic to the real IP address to be
- routed to the Windows TCP/IP stack. */
- 100,
- NULL, /* No authentication is required as this is
- not a remote capture session. */
- cErrorBuffer
- );
-
- if ( pxOpenedInterfaceHandle == NULL )
- {
- printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
- return 1;
- }
- else
- {
- /* Configure the capture filter to allow blocking reads, and to filter
- out packets that are not of interest to this demo. */
- prvConfigureCaptureBehaviour();
- }
- return 0;
-}
-/*-----------------------------------------------------------*/
-
-static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
-{
-pcap_if_t *pxInterface;
-int32_t x;
-
- /* Walk the list of devices until the selected device is located. */
- pxInterface = pxAllNetworkInterfaces;
- for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
- {
- pxInterface = pxInterface->next;
- }
-
- /* Open the selected interface. */
- if( prvOpenInterface( pxInterface->name ) == 0 )
- {
- printf( "Successfully opened interface number %d.\n", x + 1 );
- }
- else
- {
- printf( "Failed to open interface number %d.\n", x + 1 );
- }
-
- /* The device list is no longer required. */
- pcap_freealldevs( pxAllNetworkInterfaces );
-}
-/*-----------------------------------------------------------*/
-
-static void prvConfigureCaptureBehaviour( void )
-{
-struct bpf_program xFilterCode;
-uint32_t ulNetMask;
-
- /* Set up a filter so only the packets of interest are passed to the IP
- stack. cErrorBuffer is used for convenience to create the string. Don't
- confuse this with an error message. */
- sprintf( cErrorBuffer, "broadcast or multicast or ether host %x:%x:%x:%x:%x:%x",
- ucMACAddress[0], ucMACAddress[1], ucMACAddress[2], ucMACAddress[3], ucMACAddress[4], ucMACAddress[5] );
-
- ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
-
- if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
- {
- printf( "\nThe packet filter string is invalid\n" );
- }
- else
- {
- if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
- {
- printf( "\nAn error occurred setting the packet filter.\n" );
- }
- /* When pcap_compile() succeeds, it allocates memory for the memory pointed to by the bpf_program struct
- parameter.pcap_freecode() will free that memory. */
- pcap_freecode( &xFilterCode );
- }
-
- /* Create the buffers used to pass packets between the FreeRTOS simulator
- and the Win32 threads that are handling WinPCAP. */
- prvCreateThreadSafeBuffers();
-
- if( pvSendEvent == NULL )
- {
- /* Create event used to signal the Win32 WinPCAP Tx thread. */
- pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
-
- /* Create the Win32 thread that handles WinPCAP Rx. */
- vWinPcapRecvThreadHandle = CreateThread(
- NULL, /* Pointer to thread security attributes. */
- 0, /* Initial thread stack size, in bytes. */
- prvWinPcapRecvThread, /* Pointer to thread function. */
- NULL, /* Argument for new thread. */
- 0, /* Creation flags. */
- NULL );
-
- /* Use the cores that are not used by the FreeRTOS tasks. */
- SetThreadAffinityMask( vWinPcapRecvThreadHandle, ~0x01u );
-
- /* Create the Win32 thread that handlers WinPCAP Tx. */
- vWinPcapSendThreadHandle = CreateThread(
- NULL, /* Pointer to thread security attributes. */
- 0, /* initial thread stack size, in bytes. */
- prvWinPcapSendThread, /* Pointer to thread function. */
- NULL, /* Argument for new thread. */
- 0, /* Creation flags. */
- NULL );
-
- /* Use the cores that are not used by the FreeRTOS tasks. */
- SetThreadAffinityMask( vWinPcapSendThreadHandle, ~0x01u );
-
- /* Create a task that simulates an interrupt in a real system. This will
- block waiting for packets, then send a message to the IP task when data
- is available. */
- xTaskCreate( prvInterruptSimulatorTask, "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
- }
-}
-/*-----------------------------------------------------------*/
-
-/* WinPCAP function. */
-void pcap_callback( u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data )
-{
- (void)user;
-
- /* THIS IS CALLED FROM A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS
- OR TO PRINT OUT MESSAGES HERE. */
-
- /* Pass data to the FreeRTOS simulator on a thread safe circular buffer. */
- if( ( pkt_header->caplen <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
- ( uxStreamBufferGetSpace( xRecvBuffer ) >= ( ( ( size_t ) pkt_header->caplen ) + sizeof( *pkt_header ) ) ) )
- {
- uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_header, sizeof( *pkt_header ) );
- uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_data, ( size_t ) pkt_header->caplen );
- }
-}
-/*-----------------------------------------------------------*/
-
-DWORD WINAPI prvWinPcapRecvThread ( void *pvParam )
-{
- ( void ) pvParam;
-
- /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
- OUT MESSAGES HERE. */
-
- for( ;; )
- {
- pcap_dispatch( pxOpenedInterfaceHandle, 1, pcap_callback, ( u_char * ) "mydata" );
- }
-}
-/*-----------------------------------------------------------*/
-
-DWORD WINAPI prvWinPcapSendThread( void *pvParam )
-{
-size_t xLength;
-uint8_t ucBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
-static char cErrorMessage[ 1024 ];
-const DWORD xMaxMSToWait = 1000;
-
- /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
- OUT MESSAGES HERE. */
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParam;
-
- for( ;; )
- {
- /* Wait until notified of something to send. */
- WaitForSingleObject( pvSendEvent, xMaxMSToWait );
-
- /* Is there more than the length value stored in the circular buffer
- used to pass data from the FreeRTOS simulator into this Win32 thread? */
- while( uxStreamBufferGetSize( xSendBuffer ) > sizeof( xLength ) )
- {
- uxStreamBufferGet( xSendBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
- uxStreamBufferGet( xSendBuffer, 0, ( uint8_t* ) ucBuffer, xLength, pdFALSE );
- if( pcap_sendpacket( pxOpenedInterfaceHandle, ucBuffer, xLength ) != 0 )
- {
- ulWinPCAPSendFailures++;
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static void prvInterruptSimulatorTask( void *pvParameters )
-{
-struct pcap_pkthdr xHeader;
-static struct pcap_pkthdr *pxHeader;
-const uint8_t *pucPacketData;
-uint8_t ucRecvBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-eFrameProcessingResult_t eResult;
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- for( ;; )
- {
- /* Does the circular buffer used to pass data from the Win32 thread that
- handles WinPCAP Rx into the FreeRTOS simulator contain another packet? */
- if( uxStreamBufferGetSize( xRecvBuffer ) > sizeof( xHeader ) )
- {
- /* Get the next packet. */
- uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)&xHeader, sizeof( xHeader ), pdFALSE );
- uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)ucRecvBuffer, ( size_t ) xHeader.len, pdFALSE );
- pucPacketData = ucRecvBuffer;
- pxHeader = &xHeader;
-
- iptraceNETWORK_INTERFACE_RECEIVE();
-
- /* Check for minimal size. */
- if( pxHeader->len >= sizeof( EthernetHeader_t ) )
- {
- eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
- }
- else
- {
- eResult = eReleaseBuffer;
- }
-
- if( eResult == eProcessBuffer )
- {
- /* Will the data fit into the frame buffer? */
- if( pxHeader->len <= ipTOTAL_ETHERNET_FRAME_SIZE )
- {
- /* Obtain a buffer into which the data can be placed. This
- is only an interrupt simulator, not a real interrupt, so it
- is ok to call the task level function here, but note that
- some buffer implementations cannot be called from a real
- interrupt. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( pxHeader->len, 0 );
-
- if( pxNetworkBuffer != NULL )
- {
- memcpy( pxNetworkBuffer->pucEthernetBuffer, pucPacketData, pxHeader->len );
- pxNetworkBuffer->xDataLength = ( size_t ) pxHeader->len;
-
- #if( niDISRUPT_PACKETS == 1 )
- {
- pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData );
- }
- #endif /* niDISRUPT_PACKETS */
-
- if( pxNetworkBuffer != NULL )
- {
- xRxEvent.pvData = ( void * ) pxNetworkBuffer;
-
- /* Data was received and stored. Send a message to
- the IP task to let it know. */
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
- {
- /* The buffer could not be sent to the stack so
- must be released again. This is only an
- interrupt simulator, not a real interrupt, so it
- is ok to use the task level function here, but
- note no all buffer implementations will allow
- this function to be executed from a real
- interrupt. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- else
- {
- /* The packet was already released or stored inside
- vRxFaultInjection(). Don't release it here. */
- }
- }
- else
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- else
- {
- /* Log that a packet was dropped because it would have
- overflowed the buffer, but there may be more buffers to
- process. */
- }
- }
- }
- else
- {
- /* There is no real way of simulating an interrupt. Make sure
- other tasks can run. */
- vTaskDelay( configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY );
- }
- }
-}
-/*-----------------------------------------------------------*/
-
-static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage )
-{
- char *pcTarget = pcBuffer;
-
- /* Utility function used to formap messages being printed only. */
- while( ( *pcMessage != 0 ) && ( pcTarget < ( pcBuffer + aBuflen - 1 ) ) )
- {
- *( pcTarget++ ) = *pcMessage;
-
- if( isspace( *pcMessage ) != pdFALSE )
- {
- while( isspace( *pcMessage ) != pdFALSE )
- {
- pcMessage++;
- }
- }
- else
- {
- pcMessage++;
- }
- }
-
- *pcTarget = '\0';
-
- return pcBuffer;
-}
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* WinPCap includes. */
+#define HAVE_REMOTE
+#include "pcap.h"
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+/* Thread-safe circular buffers are being used to pass data to and from the PCAP
+access functions. */
+#include "Win32-Extensions.h"
+#include "FreeRTOS_Stream_Buffer.h"
+
+/* Sizes of the thread safe circular buffers used to pass data to and from the
+WinPCAP Windows threads. */
+#define xSEND_BUFFER_SIZE 32768
+#define xRECV_BUFFER_SIZE 32768
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+ #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+/* Used to insert test code only. */
+#define niDISRUPT_PACKETS 0
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Windows threads that are outside of the control of the FreeRTOS simulator are
+ * used to interface with the WinPCAP libraries.
+ */
+DWORD WINAPI prvWinPcapRecvThread( void *pvParam );
+DWORD WINAPI prvWinPcapSendThread( void *pvParam );
+
+/*
+ * Print out a numbered list of network interfaces that are available on the
+ * host computer.
+ */
+static pcap_if_t * prvPrintAvailableNetworkInterfaces( void );
+
+/*
+ * Open the network interface. The number of the interface to be opened is set
+ * by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
+ */
+static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces );
+static int prvOpenInterface( const char *pucName );
+
+/*
+ * Configure the capture filter to allow blocking reads, and to filter out
+ * packets that are not of interest to this demo.
+ */
+static void prvConfigureCaptureBehaviour( void );
+
+/*
+ * A function that simulates Ethernet interrupts by periodically polling the
+ * WinPCap interface for new data.
+ */
+static void prvInterruptSimulatorTask( void *pvParameters );
+
+/*
+ * Create the buffers that are used to pass data between the FreeRTOS simulator
+ * and the Win32 threads that manage WinPCAP.
+ */
+static void prvCreateThreadSafeBuffers( void );
+
+/*
+ * Utility function used to format print messages only.
+ */
+static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage );
+
+/*-----------------------------------------------------------*/
+
+/* Required by the WinPCap library. */
+static char cErrorBuffer[ PCAP_ERRBUF_SIZE ];
+
+/* An event used to wake up the Win32 thread that sends data through the WinPCAP
+library. */
+static void *pvSendEvent = NULL;
+
+/* _HT_ made the PCAP interface number configurable through the program's
+parameters in order to test in different machines. */
+static BaseType_t xConfigNetworkInterfaceToUse = configNETWORK_INTERFACE_TO_USE;
+
+/* Handles to the Windows threads that handle the PCAP IO. */
+static HANDLE vWinPcapRecvThreadHandle = NULL;
+static HANDLE vWinPcapSendThreadHandle = NULL;;
+
+/* The interface being used by WinPCap. */
+static pcap_t *pxOpenedInterfaceHandle = NULL;
+
+/* Circular buffers used by the PCAP Win32 threads. */
+static StreamBuffer_t *xSendBuffer = NULL;
+static StreamBuffer_t *xRecvBuffer = NULL;
+
+/* The MAC address initially set to the constants defined in FreeRTOSConfig.h. */
+extern uint8_t ucMACAddress[ 6 ];
+
+/* Logs the number of WinPCAP send failures, for viewing in the debugger only. */
+static volatile uint32_t ulWinPCAPSendFailures = 0;
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+BaseType_t xReturn = pdFALSE;
+pcap_if_t *pxAllNetworkInterfaces;
+
+ /* Query the computer the simulation is being executed on to find the
+ network interfaces it has installed. */
+ pxAllNetworkInterfaces = prvPrintAvailableNetworkInterfaces();
+
+ /* Open the network interface. The number of the interface to be opened is
+ set by the configNETWORK_INTERFACE_TO_USE constant in FreeRTOSConfig.h.
+ Calling this function will set the pxOpenedInterfaceHandle variable. If,
+ after calling this function, pxOpenedInterfaceHandle is equal to NULL, then
+ the interface could not be opened. */
+ if( pxAllNetworkInterfaces != NULL )
+ {
+ prvOpenSelectedNetworkInterface( pxAllNetworkInterfaces );
+ }
+
+ if( pxOpenedInterfaceHandle != NULL )
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvCreateThreadSafeBuffers( void )
+{
+ /* The buffer used to pass data to be transmitted from a FreeRTOS task to
+ the Win32 thread that sends via the WinPCAP library. */
+ if( xSendBuffer == NULL)
+ {
+ xSendBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) + xSEND_BUFFER_SIZE + 1 );
+ configASSERT( xSendBuffer );
+ memset( xSendBuffer, '\0', sizeof( *xSendBuffer ) - sizeof( xSendBuffer->ucArray ) );
+ xSendBuffer->LENGTH = xSEND_BUFFER_SIZE + 1;
+ }
+
+ /* The buffer used to pass received data from the Win32 thread that receives
+ via the WinPCAP library to the FreeRTOS task. */
+ if( xRecvBuffer == NULL)
+ {
+ xRecvBuffer = ( StreamBuffer_t * ) malloc( sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) + xRECV_BUFFER_SIZE + 1 );
+ configASSERT( xRecvBuffer );
+ memset( xRecvBuffer, '\0', sizeof( *xRecvBuffer ) - sizeof( xRecvBuffer->ucArray ) );
+ xRecvBuffer->LENGTH = xRECV_BUFFER_SIZE + 1;
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
+{
+size_t xSpace;
+
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ configASSERT( xIsCallingFromIPTask() == pdTRUE );
+
+ /* Both the length of the data being sent and the actual data being sent
+ are placed in the thread safe buffer used to pass data between the FreeRTOS
+ tasks and the Win32 thread that sends data via the WinPCAP library. Drop
+ the packet if there is insufficient space in the buffer to hold both. */
+ xSpace = uxStreamBufferGetSpace( xSendBuffer );
+
+ if( ( pxNetworkBuffer->xDataLength <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
+ ( xSpace >= ( pxNetworkBuffer->xDataLength + sizeof( pxNetworkBuffer->xDataLength ) ) ) )
+ {
+ /* First write in the length of the data, then write in the data
+ itself. */
+ uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) &( pxNetworkBuffer->xDataLength ), sizeof( pxNetworkBuffer->xDataLength ) );
+ uxStreamBufferAdd( xSendBuffer, 0, ( const uint8_t * ) pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength );
+ }
+ else
+ {
+ FreeRTOS_debug_printf( ( "xNetworkInterfaceOutput: send buffers full to store %lu\n", pxNetworkBuffer->xDataLength ) );
+ }
+
+ /* Kick the Tx task in either case in case it doesn't know the buffer is
+ full. */
+ SetEvent( pvSendEvent );
+
+ /* The buffer has been sent so can be released. */
+ if( bReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+
+ return pdPASS;
+}
+/*-----------------------------------------------------------*/
+
+static pcap_if_t * prvPrintAvailableNetworkInterfaces( void )
+{
+pcap_if_t * pxAllNetworkInterfaces = NULL, *xInterface;
+int32_t lInterfaceNumber = 1;
+char cBuffer[ 512 ];
+static BaseType_t xInvalidInterfaceDetected = pdFALSE;
+
+ if( xInvalidInterfaceDetected == pdFALSE )
+ {
+ if( pcap_findalldevs_ex( PCAP_SRC_IF_STRING, NULL, &pxAllNetworkInterfaces, cErrorBuffer ) == -1 )
+ {
+ printf( "Could not obtain a list of network interfaces\n%s\n", cErrorBuffer );
+ pxAllNetworkInterfaces = NULL;
+ }
+ else
+ {
+ printf( "\r\n\r\nThe following network interfaces are available:\r\n\r\n" );
+ }
+
+ if( pxAllNetworkInterfaces != NULL )
+ {
+ /* Print out the list of network interfaces. The first in the list
+ is interface '1', not interface '0'. */
+ for( xInterface = pxAllNetworkInterfaces; xInterface != NULL; xInterface = xInterface->next )
+ {
+ /* The descriptions of the devices can be full of spaces, clean them
+ a little. printf() can only be used here because the network is not
+ up yet - so no other network tasks will be running. */
+ printf( "Interface %d - %s\n", lInterfaceNumber, prvRemoveSpaces( cBuffer, sizeof( cBuffer ), xInterface->name ) );
+ printf( " (%s)\n", prvRemoveSpaces(cBuffer, sizeof( cBuffer ), xInterface->description ? xInterface->description : "No description" ) );
+ printf( "\n" );
+ lInterfaceNumber++;
+ }
+ }
+
+ if( lInterfaceNumber == 1 )
+ {
+ /* The interface number was never incremented, so the above for() loop
+ did not execute meaning no interfaces were found. */
+ printf( " \nNo network interfaces were found.\n" );
+ pxAllNetworkInterfaces = NULL;
+ }
+
+ printf( "\r\nThe interface that will be opened is set by " );
+ printf( "\"configNETWORK_INTERFACE_TO_USE\", which\r\nshould be defined in FreeRTOSConfig.h\r\n" );
+
+ if( ( xConfigNetworkInterfaceToUse < 1L ) || ( xConfigNetworkInterfaceToUse >= lInterfaceNumber ) )
+ {
+ printf( "\r\nERROR: configNETWORK_INTERFACE_TO_USE is set to %d, which is an invalid value.\r\n", xConfigNetworkInterfaceToUse );
+ printf( "Please set configNETWORK_INTERFACE_TO_USE to one of the interface numbers listed above,\r\n" );
+ printf( "then re-compile and re-start the application. Only Ethernet (as opposed to WiFi)\r\n" );
+ printf( "interfaces are supported.\r\n\r\nHALTING\r\n\r\n\r\n" );
+ xInvalidInterfaceDetected = pdTRUE;
+
+ if( pxAllNetworkInterfaces != NULL )
+ {
+ /* Free the device list, as no devices are going to be opened. */
+ pcap_freealldevs( pxAllNetworkInterfaces );
+ pxAllNetworkInterfaces = NULL;
+ }
+ }
+ else
+ {
+ printf( "Attempting to open interface number %d.\n", xConfigNetworkInterfaceToUse );
+ }
+ }
+
+ return pxAllNetworkInterfaces;
+}
+/*-----------------------------------------------------------*/
+
+static int prvOpenInterface( const char *pucName )
+{
+static char pucInterfaceName[ 256 ];
+
+ if( pucName != NULL )
+ {
+ strncpy( pucInterfaceName, pucName, sizeof( pucInterfaceName ) );
+ }
+
+ pxOpenedInterfaceHandle = pcap_open( pucInterfaceName, /* The name of the selected interface. */
+ ipTOTAL_ETHERNET_FRAME_SIZE, /* The size of the packet to capture. */
+ PCAP_OPENFLAG_PROMISCUOUS, /* Open in promiscuous mode as the MAC and
+ IP address is going to be "simulated", and
+ not be the real MAC and IP address. This allows
+ traffic to the simulated IP address to be routed
+ to uIP, and traffic to the real IP address to be
+ routed to the Windows TCP/IP stack. */
+ 100,
+ NULL, /* No authentication is required as this is
+ not a remote capture session. */
+ cErrorBuffer
+ );
+
+ if ( pxOpenedInterfaceHandle == NULL )
+ {
+ printf( "\n%s is not supported by WinPcap and cannot be opened\n", pucInterfaceName );
+ return 1;
+ }
+ else
+ {
+ /* Configure the capture filter to allow blocking reads, and to filter
+ out packets that are not of interest to this demo. */
+ prvConfigureCaptureBehaviour();
+ }
+ return 0;
+}
+/*-----------------------------------------------------------*/
+
+static void prvOpenSelectedNetworkInterface( pcap_if_t *pxAllNetworkInterfaces )
+{
+pcap_if_t *pxInterface;
+int32_t x;
+
+ /* Walk the list of devices until the selected device is located. */
+ pxInterface = pxAllNetworkInterfaces;
+ for( x = 0L; x < ( xConfigNetworkInterfaceToUse - 1L ); x++ )
+ {
+ pxInterface = pxInterface->next;
+ }
+
+ /* Open the selected interface. */
+ if( prvOpenInterface( pxInterface->name ) == 0 )
+ {
+ printf( "Successfully opened interface number %d.\n", x + 1 );
+ }
+ else
+ {
+ printf( "Failed to open interface number %d.\n", x + 1 );
+ }
+
+ /* The device list is no longer required. */
+ pcap_freealldevs( pxAllNetworkInterfaces );
+}
+/*-----------------------------------------------------------*/
+
+static void prvConfigureCaptureBehaviour( void )
+{
+struct bpf_program xFilterCode;
+uint32_t ulNetMask;
+
+ /* Set up a filter so only the packets of interest are passed to the IP
+ stack. cErrorBuffer is used for convenience to create the string. Don't
+ confuse this with an error message. */
+ sprintf( cErrorBuffer, "broadcast or multicast or ether host %x:%x:%x:%x:%x:%x",
+ ucMACAddress[0], ucMACAddress[1], ucMACAddress[2], ucMACAddress[3], ucMACAddress[4], ucMACAddress[5] );
+
+ ulNetMask = ( configNET_MASK3 << 24UL ) | ( configNET_MASK2 << 16UL ) | ( configNET_MASK1 << 8L ) | configNET_MASK0;
+
+ if( pcap_compile( pxOpenedInterfaceHandle, &xFilterCode, cErrorBuffer, 1, ulNetMask ) < 0 )
+ {
+ printf( "\nThe packet filter string is invalid\n" );
+ }
+ else
+ {
+ if( pcap_setfilter( pxOpenedInterfaceHandle, &xFilterCode ) < 0 )
+ {
+ printf( "\nAn error occurred setting the packet filter.\n" );
+ }
+ /* When pcap_compile() succeeds, it allocates memory for the memory pointed to by the bpf_program struct
+ parameter.pcap_freecode() will free that memory. */
+ pcap_freecode( &xFilterCode );
+ }
+
+ /* Create the buffers used to pass packets between the FreeRTOS simulator
+ and the Win32 threads that are handling WinPCAP. */
+ prvCreateThreadSafeBuffers();
+
+ if( pvSendEvent == NULL )
+ {
+ /* Create event used to signal the Win32 WinPCAP Tx thread. */
+ pvSendEvent = CreateEvent( NULL, FALSE, TRUE, NULL );
+
+ /* Create the Win32 thread that handles WinPCAP Rx. */
+ vWinPcapRecvThreadHandle = CreateThread(
+ NULL, /* Pointer to thread security attributes. */
+ 0, /* Initial thread stack size, in bytes. */
+ prvWinPcapRecvThread, /* Pointer to thread function. */
+ NULL, /* Argument for new thread. */
+ 0, /* Creation flags. */
+ NULL );
+
+ /* Use the cores that are not used by the FreeRTOS tasks. */
+ SetThreadAffinityMask( vWinPcapRecvThreadHandle, ~0x01u );
+
+ /* Create the Win32 thread that handlers WinPCAP Tx. */
+ vWinPcapSendThreadHandle = CreateThread(
+ NULL, /* Pointer to thread security attributes. */
+ 0, /* initial thread stack size, in bytes. */
+ prvWinPcapSendThread, /* Pointer to thread function. */
+ NULL, /* Argument for new thread. */
+ 0, /* Creation flags. */
+ NULL );
+
+ /* Use the cores that are not used by the FreeRTOS tasks. */
+ SetThreadAffinityMask( vWinPcapSendThreadHandle, ~0x01u );
+
+ /* Create a task that simulates an interrupt in a real system. This will
+ block waiting for packets, then send a message to the IP task when data
+ is available. */
+ xTaskCreate( prvInterruptSimulatorTask, "MAC_ISR", configMINIMAL_STACK_SIZE, NULL, configMAC_ISR_SIMULATOR_PRIORITY, NULL );
+ }
+}
+/*-----------------------------------------------------------*/
+
+/* WinPCAP function. */
+void pcap_callback( u_char *user, const struct pcap_pkthdr *pkt_header, const u_char *pkt_data )
+{
+ (void)user;
+
+ /* THIS IS CALLED FROM A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS
+ OR TO PRINT OUT MESSAGES HERE. */
+
+ /* Pass data to the FreeRTOS simulator on a thread safe circular buffer. */
+ if( ( pkt_header->caplen <= ( ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ) ) &&
+ ( uxStreamBufferGetSpace( xRecvBuffer ) >= ( ( ( size_t ) pkt_header->caplen ) + sizeof( *pkt_header ) ) ) )
+ {
+ uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_header, sizeof( *pkt_header ) );
+ uxStreamBufferAdd( xRecvBuffer, 0, ( const uint8_t* ) pkt_data, ( size_t ) pkt_header->caplen );
+ }
+}
+/*-----------------------------------------------------------*/
+
+DWORD WINAPI prvWinPcapRecvThread ( void *pvParam )
+{
+ ( void ) pvParam;
+
+ /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
+ OUT MESSAGES HERE. */
+
+ for( ;; )
+ {
+ pcap_dispatch( pxOpenedInterfaceHandle, 1, pcap_callback, ( u_char * ) "mydata" );
+ }
+}
+/*-----------------------------------------------------------*/
+
+DWORD WINAPI prvWinPcapSendThread( void *pvParam )
+{
+size_t xLength;
+uint8_t ucBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
+static char cErrorMessage[ 1024 ];
+const DWORD xMaxMSToWait = 1000;
+
+ /* THIS IS A WINDOWS THREAD - DO NOT ATTEMPT ANY FREERTOS CALLS OR TO PRINT
+ OUT MESSAGES HERE. */
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParam;
+
+ for( ;; )
+ {
+ /* Wait until notified of something to send. */
+ WaitForSingleObject( pvSendEvent, xMaxMSToWait );
+
+ /* Is there more than the length value stored in the circular buffer
+ used to pass data from the FreeRTOS simulator into this Win32 thread? */
+ while( uxStreamBufferGetSize( xSendBuffer ) > sizeof( xLength ) )
+ {
+ uxStreamBufferGet( xSendBuffer, 0, ( uint8_t * ) &xLength, sizeof( xLength ), pdFALSE );
+ uxStreamBufferGet( xSendBuffer, 0, ( uint8_t* ) ucBuffer, xLength, pdFALSE );
+ if( pcap_sendpacket( pxOpenedInterfaceHandle, ucBuffer, xLength ) != 0 )
+ {
+ ulWinPCAPSendFailures++;
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static void prvInterruptSimulatorTask( void *pvParameters )
+{
+struct pcap_pkthdr xHeader;
+static struct pcap_pkthdr *pxHeader;
+const uint8_t *pucPacketData;
+uint8_t ucRecvBuffer[ ipconfigNETWORK_MTU + ipSIZE_OF_ETH_HEADER ];
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+eFrameProcessingResult_t eResult;
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ for( ;; )
+ {
+ /* Does the circular buffer used to pass data from the Win32 thread that
+ handles WinPCAP Rx into the FreeRTOS simulator contain another packet? */
+ if( uxStreamBufferGetSize( xRecvBuffer ) > sizeof( xHeader ) )
+ {
+ /* Get the next packet. */
+ uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)&xHeader, sizeof( xHeader ), pdFALSE );
+ uxStreamBufferGet( xRecvBuffer, 0, (uint8_t*)ucRecvBuffer, ( size_t ) xHeader.len, pdFALSE );
+ pucPacketData = ucRecvBuffer;
+ pxHeader = &xHeader;
+
+ iptraceNETWORK_INTERFACE_RECEIVE();
+
+ /* Check for minimal size. */
+ if( pxHeader->len >= sizeof( EthernetHeader_t ) )
+ {
+ eResult = ipCONSIDER_FRAME_FOR_PROCESSING( pucPacketData );
+ }
+ else
+ {
+ eResult = eReleaseBuffer;
+ }
+
+ if( eResult == eProcessBuffer )
+ {
+ /* Will the data fit into the frame buffer? */
+ if( pxHeader->len <= ipTOTAL_ETHERNET_FRAME_SIZE )
+ {
+ /* Obtain a buffer into which the data can be placed. This
+ is only an interrupt simulator, not a real interrupt, so it
+ is ok to call the task level function here, but note that
+ some buffer implementations cannot be called from a real
+ interrupt. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( pxHeader->len, 0 );
+
+ if( pxNetworkBuffer != NULL )
+ {
+ memcpy( pxNetworkBuffer->pucEthernetBuffer, pucPacketData, pxHeader->len );
+ pxNetworkBuffer->xDataLength = ( size_t ) pxHeader->len;
+
+ #if( niDISRUPT_PACKETS == 1 )
+ {
+ pxNetworkBuffer = vRxFaultInjection( pxNetworkBuffer, pucPacketData );
+ }
+ #endif /* niDISRUPT_PACKETS */
+
+ if( pxNetworkBuffer != NULL )
+ {
+ xRxEvent.pvData = ( void * ) pxNetworkBuffer;
+
+ /* Data was received and stored. Send a message to
+ the IP task to let it know. */
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 0 ) == pdFAIL )
+ {
+ /* The buffer could not be sent to the stack so
+ must be released again. This is only an
+ interrupt simulator, not a real interrupt, so it
+ is ok to use the task level function here, but
+ note no all buffer implementations will allow
+ this function to be executed from a real
+ interrupt. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ else
+ {
+ /* The packet was already released or stored inside
+ vRxFaultInjection(). Don't release it here. */
+ }
+ }
+ else
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ else
+ {
+ /* Log that a packet was dropped because it would have
+ overflowed the buffer, but there may be more buffers to
+ process. */
+ }
+ }
+ }
+ else
+ {
+ /* There is no real way of simulating an interrupt. Make sure
+ other tasks can run. */
+ vTaskDelay( configWINDOWS_MAC_INTERRUPT_SIMULATOR_DELAY );
+ }
+ }
+}
+/*-----------------------------------------------------------*/
+
+static const char *prvRemoveSpaces( char *pcBuffer, int aBuflen, const char *pcMessage )
+{
+ char *pcTarget = pcBuffer;
+
+ /* Utility function used to formap messages being printed only. */
+ while( ( *pcMessage != 0 ) && ( pcTarget < ( pcBuffer + aBuflen - 1 ) ) )
+ {
+ *( pcTarget++ ) = *pcMessage;
+
+ if( isspace( *pcMessage ) != pdFALSE )
+ {
+ while( isspace( *pcMessage ) != pdFALSE )
+ {
+ pcMessage++;
+ }
+ }
+ else
+ {
+ pcMessage++;
+ }
+ }
+
+ *pcTarget = '\0';
+
+ return pcBuffer;
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
index 1c11976cb..c8f965395 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/NetworkInterface.c
@@ -1,398 +1,398 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-/* Xilinx library files. */
-#include <xemacps.h>
-#include "Zynq/x_topology.h"
-#include "Zynq/x_emacpsif.h"
-#include "Zynq/x_emacpsif_hw.h"
-
-/* Provided memory configured as uncached. */
-#include "uncached_memory.h"
-
-#ifndef BMSR_LINK_STATUS
- #define BMSR_LINK_STATUS 0x0004UL
-#endif
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/* The size of each buffer when BufferAllocation_1 is used:
-http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
-#define niBUFFER_1_PACKET_SIZE 1536
-
-/* Naming and numbering of PHY registers. */
-#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
-
-#ifndef iptraceEMAC_TASK_STARTING
- #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to twice
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
-#endif
-
-/*-----------------------------------------------------------*/
-
-/*
- * Look for the link to be up every few milliseconds until either xMaxTime time
- * has passed or a link is found.
- */
-static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
-
-/*
- * A deferred interrupt handler for all MAC/DMA interrupt sources.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*-----------------------------------------------------------*/
-
-/* EMAC data/descriptions. */
-static xemacpsif_s xEMACpsif;
-struct xtopology_t xXTopology =
-{
- .emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
- .emac_type = xemac_type_emacps,
- .intc_baseaddr = 0x0,
- .intc_emac_intr = 0x0,
- .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
- .scugic_emac_intr = 0x36,
-};
-
-XEmacPs_Config mac_config =
-{
- .DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
- .BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
-};
-
-extern int phy_detected;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-
-#if( ipconfigUSE_LLMNR == 1 )
- static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
-#endif
-
-/* ucMACAddress as it appears in main.c */
-extern const uint8_t ucMACAddress[ 6 ];
-
-/* Holds the handle of the task used as a deferred interrupt processor. The
-handle is used so direct notifications can be sent to the task for all EMAC/DMA
-related interrupts. */
-TaskHandle_t xEMACTaskHandle = NULL;
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-uint32_t ulLinkSpeed, ulDMAReg;
-BaseType_t xStatus, xLinkStatus;
-XEmacPs *pxEMAC_PS;
-const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
-
- /* Guard against the init function being called more than once. */
- if( xEMACTaskHandle == NULL )
- {
- pxEMAC_PS = &( xEMACpsif.emacps );
- memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
-
- xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
- if( xStatus != XST_SUCCESS )
- {
- FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
- }
-
- /* Initialize the mac and set the MAC address. */
- XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
-
- #if( ipconfigUSE_LLMNR == 1 )
- {
- /* Also add LLMNR multicast MAC address. */
- XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
- }
- #endif /* ipconfigUSE_LLMNR == 1 */
-
- XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
- ulLinkSpeed = Phy_Setup( pxEMAC_PS );
- XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
-
- /* Setting the operating speed of the MAC needs a delay. */
- vTaskDelay( pdMS_TO_TICKS( 25UL ) );
-
- ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
-
- /* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
- packets from the receiver packet buffer memory when no AHB resource is available. */
- XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
- ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
-
- setup_isr( &xEMACpsif );
- init_dma( &xEMACpsif );
- start_emacps( &xEMACpsif );
-
- prvGMACWaitLS( xWaitLinkDelay );
-
- /* The deferred interrupt handler task is created at the highest
- possible priority to ensure the interrupt handler can return directly
- to it. The task's handle is stored in xEMACTaskHandle so interrupts can
- notify the task when there is something to process. */
- xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- }
- else
- {
- /* Initialisation was already performed, just wait for the link. */
- prvGMACWaitLS( xWaitRelinkDelay );
- }
-
- /* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
- DHCP process and all other communication will fail. */
- xLinkStatus = xGetPhyLinkStatus();
-
- return ( xLinkStatus != pdFALSE );
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
-{
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- iptraceNETWORK_INTERFACE_TRANSMIT();
- emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
- }
- else if( bReleaseAfterSend != pdFALSE )
- {
- /* No link. */
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- }
-
- return pdTRUE;
-}
-/*-----------------------------------------------------------*/
-
-static inline unsigned long ulReadMDIO( unsigned ulRegister )
-{
-uint16_t usValue;
-
- XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
- return usValue;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
-{
-TickType_t xStartTime, xEndTime;
-const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
-BaseType_t xReturn;
-
- xStartTime = xTaskGetTickCount();
-
- for( ;; )
- {
- xEndTime = xTaskGetTickCount();
-
- if( xEndTime - xStartTime > xMaxTime )
- {
- xReturn = pdFALSE;
- break;
- }
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xReturn = pdTRUE;
- break;
- }
-
- vTaskDelay( xShortDelay );
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
-static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
-uint8_t *ucRAMBuffer = ucNetworkPackets;
-uint32_t ul;
-
- for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
- {
- pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
- *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
- ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
- }
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xReturn;
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
- {
- xReturn = pdFALSE;
- }
- else
- {
- xReturn = pdTRUE;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t xStatus;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- /* A possibility to set some additional task properties like calling
- portTASK_USES_FLOATING_POINT() */
- iptraceEMAC_TASK_STARTING();
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
-
- for( ;; )
- {
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
- }
-
- if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
- {
- xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
- xResult = emacps_check_rx( &xEMACpsif );
- }
-
- if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
- {
- xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
- emacps_check_tx( &xEMACpsif );
- }
-
- if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 0 )
- {
- xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
- emacps_check_errors( &xEMACpsif );
- }
-
- if( xResult > 0 )
- {
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
- {
- xStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+/* Xilinx library files. */
+#include <xemacps.h>
+#include "Zynq/x_topology.h"
+#include "Zynq/x_emacpsif.h"
+#include "Zynq/x_emacpsif_hw.h"
+
+/* Provided memory configured as uncached. */
+#include "uncached_memory.h"
+
+#ifndef BMSR_LINK_STATUS
+ #define BMSR_LINK_STATUS 0x0004UL
+#endif
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* The size of each buffer when BufferAllocation_1 is used:
+http://www.freertos.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html */
+#define niBUFFER_1_PACKET_SIZE 1536
+
+/* Naming and numbering of PHY registers. */
+#define PHY_REG_01_BMSR 0x01 /* Basic mode status register */
+
+#ifndef iptraceEMAC_TASK_STARTING
+ #define iptraceEMAC_TASK_STARTING() do { } while( 0 )
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to twice
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 2 * configMINIMAL_STACK_SIZE )
+#endif
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Look for the link to be up every few milliseconds until either xMaxTime time
+ * has passed or a link is found.
+ */
+static BaseType_t prvGMACWaitLS( TickType_t xMaxTime );
+
+/*
+ * A deferred interrupt handler for all MAC/DMA interrupt sources.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*-----------------------------------------------------------*/
+
+/* EMAC data/descriptions. */
+static xemacpsif_s xEMACpsif;
+struct xtopology_t xXTopology =
+{
+ .emac_baseaddr = XPAR_PS7_ETHERNET_0_BASEADDR,
+ .emac_type = xemac_type_emacps,
+ .intc_baseaddr = 0x0,
+ .intc_emac_intr = 0x0,
+ .scugic_baseaddr = XPAR_PS7_SCUGIC_0_BASEADDR,
+ .scugic_emac_intr = 0x36,
+};
+
+XEmacPs_Config mac_config =
+{
+ .DeviceId = XPAR_PS7_ETHERNET_0_DEVICE_ID, /**< Unique ID of device */
+ .BaseAddress = XPAR_PS7_ETHERNET_0_BASEADDR /**< Physical base address of IPIF registers */
+};
+
+extern int phy_detected;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+
+#if( ipconfigUSE_LLMNR == 1 )
+ static const uint8_t xLLMNR_MACAddress[] = { 0x01, 0x00, 0x5E, 0x00, 0x00, 0xFC };
+#endif
+
+/* ucMACAddress as it appears in main.c */
+extern const uint8_t ucMACAddress[ 6 ];
+
+/* Holds the handle of the task used as a deferred interrupt processor. The
+handle is used so direct notifications can be sent to the task for all EMAC/DMA
+related interrupts. */
+TaskHandle_t xEMACTaskHandle = NULL;
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+uint32_t ulLinkSpeed, ulDMAReg;
+BaseType_t xStatus, xLinkStatus;
+XEmacPs *pxEMAC_PS;
+const TickType_t xWaitLinkDelay = pdMS_TO_TICKS( 7000UL ), xWaitRelinkDelay = pdMS_TO_TICKS( 1000UL );
+
+ /* Guard against the init function being called more than once. */
+ if( xEMACTaskHandle == NULL )
+ {
+ pxEMAC_PS = &( xEMACpsif.emacps );
+ memset( &xEMACpsif, '\0', sizeof( xEMACpsif ) );
+
+ xStatus = XEmacPs_CfgInitialize( pxEMAC_PS, &mac_config, mac_config.BaseAddress);
+ if( xStatus != XST_SUCCESS )
+ {
+ FreeRTOS_printf( ( "xEMACInit: EmacPs Configuration Failed....\n" ) );
+ }
+
+ /* Initialize the mac and set the MAC address. */
+ XEmacPs_SetMacAddress( pxEMAC_PS, ( void * ) ucMACAddress, 1 );
+
+ #if( ipconfigUSE_LLMNR == 1 )
+ {
+ /* Also add LLMNR multicast MAC address. */
+ XEmacPs_SetMacAddress( pxEMAC_PS, ( void * )xLLMNR_MACAddress, 2 );
+ }
+ #endif /* ipconfigUSE_LLMNR == 1 */
+
+ XEmacPs_SetMdioDivisor( pxEMAC_PS, MDC_DIV_224 );
+ ulLinkSpeed = Phy_Setup( pxEMAC_PS );
+ XEmacPs_SetOperatingSpeed( pxEMAC_PS, ulLinkSpeed);
+
+ /* Setting the operating speed of the MAC needs a delay. */
+ vTaskDelay( pdMS_TO_TICKS( 25UL ) );
+
+ ulDMAReg = XEmacPs_ReadReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET);
+
+ /* DISC_WHEN_NO_AHB: when set, the GEM DMA will automatically discard receive
+ packets from the receiver packet buffer memory when no AHB resource is available. */
+ XEmacPs_WriteReg( pxEMAC_PS->Config.BaseAddress, XEMACPS_DMACR_OFFSET,
+ ulDMAReg | XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK);
+
+ setup_isr( &xEMACpsif );
+ init_dma( &xEMACpsif );
+ start_emacps( &xEMACpsif );
+
+ prvGMACWaitLS( xWaitLinkDelay );
+
+ /* The deferred interrupt handler task is created at the highest
+ possible priority to ensure the interrupt handler can return directly
+ to it. The task's handle is stored in xEMACTaskHandle so interrupts can
+ notify the task when there is something to process. */
+ xTaskCreate( prvEMACHandlerTask, "EMAC", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ }
+ else
+ {
+ /* Initialisation was already performed, just wait for the link. */
+ prvGMACWaitLS( xWaitRelinkDelay );
+ }
+
+ /* Only return pdTRUE when the Link Status of the PHY is high, otherwise the
+ DHCP process and all other communication will fail. */
+ xLinkStatus = xGetPhyLinkStatus();
+
+ return ( xLinkStatus != pdFALSE );
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxBuffer, BaseType_t bReleaseAfterSend )
+{
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ emacps_send_message( &xEMACpsif, pxBuffer, bReleaseAfterSend );
+ }
+ else if( bReleaseAfterSend != pdFALSE )
+ {
+ /* No link. */
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ }
+
+ return pdTRUE;
+}
+/*-----------------------------------------------------------*/
+
+static inline unsigned long ulReadMDIO( unsigned ulRegister )
+{
+uint16_t usValue;
+
+ XEmacPs_PhyRead( &( xEMACpsif.emacps ), phy_detected, ulRegister, &usValue );
+ return usValue;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t prvGMACWaitLS( TickType_t xMaxTime )
+{
+TickType_t xStartTime, xEndTime;
+const TickType_t xShortDelay = pdMS_TO_TICKS( 20UL );
+BaseType_t xReturn;
+
+ xStartTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ xEndTime = xTaskGetTickCount();
+
+ if( xEndTime - xStartTime > xMaxTime )
+ {
+ xReturn = pdFALSE;
+ break;
+ }
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xReturn = pdTRUE;
+ break;
+ }
+
+ vTaskDelay( xShortDelay );
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+static uint8_t ucNetworkPackets[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS * niBUFFER_1_PACKET_SIZE ] __attribute__ ( ( aligned( 32 ) ) );
+uint8_t *ucRAMBuffer = ucNetworkPackets;
+uint32_t ul;
+
+ for( ul = 0; ul < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; ul++ )
+ {
+ pxNetworkBuffers[ ul ].pucEthernetBuffer = ucRAMBuffer + ipBUFFER_PADDING;
+ *( ( unsigned * ) ucRAMBuffer ) = ( unsigned ) ( &( pxNetworkBuffers[ ul ] ) );
+ ucRAMBuffer += niBUFFER_1_PACKET_SIZE;
+ }
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xReturn;
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ {
+ xReturn = pdFALSE;
+ }
+ else
+ {
+ xReturn = pdTRUE;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+UBaseType_t uxLastMinBufferCount = 0;
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( 100UL );
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ /* A possibility to set some additional task properties like calling
+ portTASK_USES_FLOATING_POINT() */
+ iptraceEMAC_TASK_STARTING();
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+
+ for( ;; )
+ {
+ uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
+ if( uxLastMinBufferCount != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
+ }
+
+ #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ static UBaseType_t uxLastMinQueueSpace = 0;
+
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdFALSE, ulMaxBlockTime );
+ }
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ xEMACpsif.isr_events &= ~EMAC_IF_RX_EVENT;
+ xResult = emacps_check_rx( &xEMACpsif );
+ }
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ xEMACpsif.isr_events &= ~EMAC_IF_TX_EVENT;
+ emacps_check_tx( &xEMACpsif );
+ }
+
+ if( ( xEMACpsif.isr_events & EMAC_IF_ERR_EVENT ) != 0 )
+ {
+ xEMACpsif.isr_events &= ~EMAC_IF_ERR_EVENT;
+ emacps_check_errors( &xEMACpsif );
+ }
+
+ if( xResult > 0 )
+ {
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE )
+ {
+ xStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
index 74b241dcf..f9e54bb2f 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/README.txt
@@ -1,25 +1,25 @@
-
-
-NetworkInterface for Xilinx' Zynq
-
-Please include the following source files:
-
- $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/NetworkInterface.c
- $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
- $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
- $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
-
-And include the following source files from the Xilinx library:
-
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps.c
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_control.c
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_g.c
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_intr.c
-
- E.g. ps7_cortexa9_0/libsrc/emacps_v2_0/src/xemacps_intr.c
-
-The following source files are NOT used for the FreeRTOS+TCP interface:
-
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_bdring.c
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_hw.c
- $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_sinit.c
+
+
+NetworkInterface for Xilinx' Zynq
+
+Please include the following source files:
+
+ $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/NetworkInterface.c
+ $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
+ $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
+ $(PLUS_TCP_PATH)/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
+
+And include the following source files from the Xilinx library:
+
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps.c
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_control.c
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_g.c
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_intr.c
+
+ E.g. ps7_cortexa9_0/libsrc/emacps_v2_0/src/xemacps_intr.c
+
+The following source files are NOT used for the FreeRTOS+TCP interface:
+
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_bdring.c
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_hw.c
+ $(CPU_PATH)/$(PROCESSOR)/libsrc/emacps_v2_0/src/xemacps_sinit.c
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
deleted file mode 100644
index b43e50ec2..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * uncached_memory.c
- *
- * This module will declare 1 MB of memory and switch off the caching for it.
- *
- * pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
- * rounded up to a multiple of 4 KB
- *
- * ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT
- * within the range of the 1 MB non-cached memory.
- *
- */
-
-/*
- * After "_end", 1 MB of uncached memory will be allocated for DMA transfers.
- * Both the DMA descriptors as well as all EMAC TX-buffers will be allocated in
- * uncached memory.
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-
-#include "Zynq/x_emacpsif.h"
-#include "Zynq/x_topology.h"
-#include "xstatus.h"
-
-#include "xparameters.h"
-#include "xparameters_ps.h"
-#include "xil_exception.h"
-#include "xil_mmu.h"
-
-#include "uncached_memory.h"
-
-#define UNCACHED_MEMORY_SIZE 0x100000ul
-
-#define DDR_MEMORY_END (XPAR_PS7_DDR_0_S_AXI_HIGHADDR+1)
-
-static void vInitialiseUncachedMemory( void );
-
-static uint8_t *pucHeadOfMemory;
-static uint32_t ulMemorySize;
-static uint8_t *pucStartOfMemory = NULL;
-
-uint8_t ucIsCachedMemory( const uint8_t *pucBuffer )
-{
-uint8_t ucReturn;
-
- if( ( pucStartOfMemory != NULL ) &&
- ( pucBuffer >= pucStartOfMemory ) &&
- ( pucBuffer < ( pucStartOfMemory + UNCACHED_MEMORY_SIZE ) ) )
- {
- ucReturn = pdFALSE;
- }
- else
- {
- ucReturn = pdTRUE;
- }
-
- return ucReturn;
-}
-
-uint8_t *pucGetUncachedMemory( uint32_t ulSize )
-{
-uint8_t *pucReturn;
-
- if( pucStartOfMemory == NULL )
- {
- vInitialiseUncachedMemory( );
- }
- if( ( pucStartOfMemory == NULL ) || ( ulSize > ulMemorySize ) )
- {
- pucReturn = NULL;
- }
- else
- {
- uint32_t ulSkipSize;
-
- pucReturn = pucHeadOfMemory;
- ulSkipSize = ( ulSize + 0x1000ul ) & ~0xffful;
- pucHeadOfMemory += ulSkipSize;
- ulMemorySize -= ulSkipSize;
- }
-
- return pucReturn;
-}
-
-extern u8 _end;
-
-static void vInitialiseUncachedMemory( )
-{
- /* At the end of program's space... */
- pucStartOfMemory = (uint8_t *) &_end;
- /*
- * Align the start address to 1 MB boundary.
- */
- pucStartOfMemory = (uint8_t *)( ( ( uint32_t )pucStartOfMemory + UNCACHED_MEMORY_SIZE ) & ( ~( UNCACHED_MEMORY_SIZE - 1 ) ) );
-
- if( ( ( u32 )pucStartOfMemory ) + UNCACHED_MEMORY_SIZE > DDR_MEMORY_END )
- {
-// vLoggingPrintf("vInitialiseUncachedMemory: Can not allocate uncached memory\n" );
- }
- else
- {
- /*
- * Some objects want to be stored in uncached memory. Hence the 1 MB
- * address range that starts after "_end" is made uncached
- * by setting appropriate attributes in the translation table.
- */
- /* FIXME claudio rossi. Modified to prevent data abort exception (misaligned access)
- * when application is compiled with -O1 or more optimization flag.
- */
-/* Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0xc02 ); // addr, attr */
- Xil_SetTlbAttributes( ( uint32_t )pucStartOfMemory, 0x1c02 ); // addr, attr
-
- /* For experiments in the SDIO driver, make the remaining uncached memory public */
- pucHeadOfMemory = pucStartOfMemory;
- ulMemorySize = UNCACHED_MEMORY_SIZE;
- memset( pucStartOfMemory, '\0', UNCACHED_MEMORY_SIZE );
- }
-}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.h
deleted file mode 100644
index 5a8e5f37f..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/uncached_memory.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * uncached_memory.h
- *
- * This module will declare 1 MB of memory and switch off the caching for it.
- *
- * pucGetUncachedMemory( ulSize ) returns a trunc of this memory with a length
- * rounded up to a multiple of 4 KB
- *
- * ucIsCachedMemory( pucBuffer ) returns non-zero if a given pointer is NOT
- * within the range of the 1 MB non-cached memory.
- *
- */
-
-#ifndef UNCACHEMEMORY_H
-
-#define UNCACHEMEMORY_H
-
-uint8_t *pucGetUncachedMemory( uint32_t ulSize );
-
-uint8_t ucIsCachedMemory( const uint8_t *pucBuffer );
-
-#endif /* UNCACHEMEMORY_H */
-
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
index 823dee0d3..2f1b0df20 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif.h
@@ -1,144 +1,144 @@
-/*
- * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __NETIF_XEMACPSIF_H__
-#define __NETIF_XEMACPSIF_H__
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <stdint.h>
-
-#include "xstatus.h"
-#include "sleep.h"
-#include "xparameters.h"
-#include "xparameters_ps.h" /* defines XPAR values */
-#include "xil_types.h"
-#include "xil_assert.h"
-#include "xil_io.h"
-#include "xil_exception.h"
-#include "xpseudo_asm.h"
-#include "xil_cache.h"
-#include "xil_printf.h"
-#include "xuartps.h"
-#include "xscugic.h"
-#include "xemacps.h" /* defines XEmacPs API */
-
-//#include "netif/xpqueue.h"
-//#include "xlwipconfig.h"
-
-void xemacpsif_setmac(uint32_t index, uint8_t *addr);
-uint8_t* xemacpsif_getmac(uint32_t index);
-//int xemacpsif_init(struct netif *netif);
-//int xemacpsif_input(struct netif *netif);
-#ifdef NOTNOW_BHILL
-unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
-#endif
-
-/* xaxiemacif_hw.c */
-void xemacps_error_handler(XEmacPs * Temac);
-
-struct xBD_TYPE {
- uint32_t address;
- uint32_t flags;
-};
-
-/*
- * Missing declaration in 'src/xemacps_hw.h' :
- * When set, the GEM DMA will automatically
- * discard receive packets from the receiver packet
- * buffer memory when no AHB resource is
- * available.
- * When low, then received packets will remain to be
- * stored in the SRAM based packet buffer until
- * AHB buffer resource next becomes available.
- */
-#define XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK 0x01000000
-
-#define EMAC_IF_RX_EVENT 1
-#define EMAC_IF_TX_EVENT 2
-#define EMAC_IF_ERR_EVENT 4
-#define EMAC_IF_ALL_EVENT 7
-
-/* structure within each netif, encapsulating all information required for
- * using a particular temac instance
- */
-typedef struct {
- XEmacPs emacps;
-
- /* pointers to memory holding buffer descriptors (used only with SDMA) */
- struct xBD_TYPE *rxSegments;
- struct xBD_TYPE *txSegments;
-
- unsigned char *tx_space;
- unsigned uTxUnitSize;
-
- char *remain_mem;
- unsigned remain_siz;
-
- volatile int rxHead, rxTail;
- volatile int txHead, txTail;
-
- volatile int txBusy;
-
- volatile uint32_t isr_events;
-
- unsigned int last_rx_frms_cntr;
-
-} xemacpsif_s;
-
-//extern xemacpsif_s xemacpsif;
-
-int is_tx_space_available(xemacpsif_s *emac);
-
-/* xaxiemacif_dma.c */
-
-struct xNETWORK_BUFFER;
-
-int emacps_check_rx( xemacpsif_s *xemacpsif );
-void emacps_check_tx( xemacpsif_s *xemacpsif );
-int emacps_check_errors( xemacpsif_s *xemacps );
-void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount );
-
-extern XStatus emacps_send_message(xemacpsif_s *xemacpsif, struct xNETWORK_BUFFER *pxBuffer, int iReleaseAfterSend );
-extern unsigned Phy_Setup( XEmacPs *xemacpsp );
-extern void setup_isr( xemacpsif_s *xemacpsif );
-extern XStatus init_dma( xemacpsif_s *xemacpsif );
-extern void start_emacps( xemacpsif_s *xemacpsif );
-
-void EmacEnableIntr(void);
-void EmacDisableIntr(void);
-
-XStatus init_axi_dma(xemacpsif_s *xemacpsif);
-void process_sent_bds( xemacpsif_s *xemacpsif );
-
-void emacps_send_handler(void *arg);
-void emacps_recv_handler(void *arg);
-void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
-void HandleTxErrors(xemacpsif_s *xemacpsif);
-XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
-
-void clean_dma_txdescs(xemacpsif_s *xemacpsif);
-void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* __NETIF_XAXIEMACIF_H__ */
+/*
+ * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __NETIF_XEMACPSIF_H__
+#define __NETIF_XEMACPSIF_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdint.h>
+
+#include "xstatus.h"
+#include "sleep.h"
+#include "xparameters.h"
+#include "xparameters_ps.h" /* defines XPAR values */
+#include "xil_types.h"
+#include "xil_assert.h"
+#include "xil_io.h"
+#include "xil_exception.h"
+#include "xpseudo_asm.h"
+#include "xil_cache.h"
+#include "xil_printf.h"
+#include "xuartps.h"
+#include "xscugic.h"
+#include "xemacps.h" /* defines XEmacPs API */
+
+//#include "netif/xpqueue.h"
+//#include "xlwipconfig.h"
+
+void xemacpsif_setmac(uint32_t index, uint8_t *addr);
+uint8_t* xemacpsif_getmac(uint32_t index);
+//int xemacpsif_init(struct netif *netif);
+//int xemacpsif_input(struct netif *netif);
+#ifdef NOTNOW_BHILL
+unsigned get_IEEE_phy_speed(XLlTemac *xlltemacp);
+#endif
+
+/* xaxiemacif_hw.c */
+void xemacps_error_handler(XEmacPs * Temac);
+
+struct xBD_TYPE {
+ uint32_t address;
+ uint32_t flags;
+};
+
+/*
+ * Missing declaration in 'src/xemacps_hw.h' :
+ * When set, the GEM DMA will automatically
+ * discard receive packets from the receiver packet
+ * buffer memory when no AHB resource is
+ * available.
+ * When low, then received packets will remain to be
+ * stored in the SRAM based packet buffer until
+ * AHB buffer resource next becomes available.
+ */
+#define XEMACPS_DMACR_DISC_WHEN_NO_AHB_MASK 0x01000000
+
+#define EMAC_IF_RX_EVENT 1
+#define EMAC_IF_TX_EVENT 2
+#define EMAC_IF_ERR_EVENT 4
+#define EMAC_IF_ALL_EVENT 7
+
+/* structure within each netif, encapsulating all information required for
+ * using a particular temac instance
+ */
+typedef struct {
+ XEmacPs emacps;
+
+ /* pointers to memory holding buffer descriptors (used only with SDMA) */
+ struct xBD_TYPE *rxSegments;
+ struct xBD_TYPE *txSegments;
+
+ unsigned char *tx_space;
+ unsigned uTxUnitSize;
+
+ char *remain_mem;
+ unsigned remain_siz;
+
+ volatile int rxHead, rxTail;
+ volatile int txHead, txTail;
+
+ volatile int txBusy;
+
+ volatile uint32_t isr_events;
+
+ unsigned int last_rx_frms_cntr;
+
+} xemacpsif_s;
+
+//extern xemacpsif_s xemacpsif;
+
+int is_tx_space_available(xemacpsif_s *emac);
+
+/* xaxiemacif_dma.c */
+
+struct xNETWORK_BUFFER;
+
+int emacps_check_rx( xemacpsif_s *xemacpsif );
+void emacps_check_tx( xemacpsif_s *xemacpsif );
+int emacps_check_errors( xemacpsif_s *xemacps );
+void emacps_set_rx_buffers( xemacpsif_s *xemacpsif, u32 ulCount );
+
+extern XStatus emacps_send_message(xemacpsif_s *xemacpsif, struct xNETWORK_BUFFER *pxBuffer, int iReleaseAfterSend );
+extern unsigned Phy_Setup( XEmacPs *xemacpsp );
+extern void setup_isr( xemacpsif_s *xemacpsif );
+extern XStatus init_dma( xemacpsif_s *xemacpsif );
+extern void start_emacps( xemacpsif_s *xemacpsif );
+
+void EmacEnableIntr(void);
+void EmacDisableIntr(void);
+
+XStatus init_axi_dma(xemacpsif_s *xemacpsif);
+void process_sent_bds( xemacpsif_s *xemacpsif );
+
+void emacps_send_handler(void *arg);
+void emacps_recv_handler(void *arg);
+void emacps_error_handler(void *arg,u8 Direction, u32 ErrorWord);
+void HandleTxErrors(xemacpsif_s *xemacpsif);
+XEmacPs_Config *xemacps_lookup_config(unsigned mac_base);
+
+void clean_dma_txdescs(xemacpsif_s *xemacpsif);
+void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __NETIF_XAXIEMACIF_H__ */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
index fc09d2183..13a62852d 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_dma.c
@@ -1,626 +1,626 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-#include "Zynq/x_emacpsif.h"
-#include "Zynq/x_topology.h"
-#include "xstatus.h"
-
-#include "xparameters.h"
-#include "xparameters_ps.h"
-#include "xil_exception.h"
-#include "xil_mmu.h"
-
-#include "FreeRTOS.h"
-#include "task.h"
-#include "timers.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-#include "uncached_memory.h"
-
-/* Two defines used to set or clear the EMAC interrupt */
-#define INTC_BASE_ADDR XPAR_SCUGIC_CPU_BASEADDR
-#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_DIST_BASEADDR
-
-
-
-#if( ipconfigPACKET_FILLER_SIZE != 2 )
- #error Please define ipconfigPACKET_FILLER_SIZE as the value '2'
-#endif
-#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
-
-#define RX_BUFFER_ALIGNMENT 14
-
-/* Defined in NetworkInterface.c */
-extern TaskHandle_t xEMACTaskHandle;
-
-/*
- pxDMA_tx_buffers: these are character arrays, each one is big enough to hold 1 MTU.
- The actual TX buffers are located in uncached RAM.
-*/
-static unsigned char *pxDMA_tx_buffers[ ipconfigNIC_N_TX_DESC ] = { NULL };
-
-/*
- pxDMA_rx_buffers: these are pointers to 'NetworkBufferDescriptor_t'.
- Once a message has been received by the EMAC, the descriptor can be passed
- immediately to the IP-task.
-*/
-static NetworkBufferDescriptor_t *pxDMA_rx_buffers[ ipconfigNIC_N_RX_DESC ] = { NULL };
-
-/*
- The FreeRTOS+TCP port is using a fixed 'topology', which is declared in
- ./portable/NetworkInterface/Zynq/NetworkInterface.c
-*/
-extern struct xtopology_t xXTopology;
-
-static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
-
-/*
- The FreeRTOS+TCP port does not make use of "src/xemacps_bdring.c".
- In stead 'struct xemacpsif_s' has a "head" and a "tail" index.
- "head" is the next index to be written, used.
- "tail" is the next index to be read, freed.
-*/
-
-int is_tx_space_available( xemacpsif_s *xemacpsif )
-{
-size_t uxCount;
-
- if( xTXDescriptorSemaphore != NULL )
- {
- uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
- }
- else
- {
- uxCount = ( UBaseType_t ) 0u;
- }
-
- return uxCount;
-}
-
-void emacps_check_tx( xemacpsif_s *xemacpsif )
-{
-int tail = xemacpsif->txTail;
-int head = xemacpsif->txHead;
-size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
-
- /* uxCount is the number of TX descriptors that are in use by the DMA. */
- /* When done, "TXBUF_USED" will be set. */
-
- while( ( uxCount > 0 ) && ( ( xemacpsif->txSegments[ tail ].flags & XEMACPS_TXBUF_USED_MASK ) != 0 ) )
- {
- if( ( tail == head ) && ( uxCount != ipconfigNIC_N_TX_DESC ) )
- {
- break;
- }
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
-#warning ipconfigZERO_COPY_TX_DRIVER is defined
- {
- void *pvBuffer = pxDMA_tx_buffers[ tail ];
- NetworkBufferDescriptor_t *pxBuffer;
-
- if( pvBuffer != NULL )
- {
- pxDMA_tx_buffers[ tail ] = NULL;
- pxBuffer = pxPacketBuffer_to_NetworkBuffer( pvBuffer );
- if( pxBuffer != NULL )
- {
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- }
- else
- {
- FreeRTOS_printf( ( "emacps_check_tx: Can not find network buffer\n" ) );
- }
- }
- }
-#endif
- /* Clear all but the "used" and "wrap" bits. */
- if( tail < ipconfigNIC_N_TX_DESC - 1 )
- {
- xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK;
- }
- else
- {
- xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
- }
- uxCount--;
- /* Tell the counting semaphore that one more TX descriptor is available. */
- xSemaphoreGive( xTXDescriptorSemaphore );
- if( ++tail == ipconfigNIC_N_TX_DESC )
- {
- tail = 0;
- }
- xemacpsif->txTail = tail;
- }
-
- return;
-}
-
-void emacps_send_handler(void *arg)
-{
-xemacpsif_s *xemacpsif;
-BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- xemacpsif = (xemacpsif_s *)(arg);
-
- /* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
- "isr_events". The task in NetworkInterface will wake-up and do the necessary work.
- */
- xemacpsif->isr_events |= EMAC_IF_TX_EVENT;
- xemacpsif->txBusy = pdFALSE;
-
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- }
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-
-static BaseType_t xValidLength( BaseType_t xLength )
-{
-BaseType_t xReturn;
-
- if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
- {
- xReturn = pdTRUE;
- }
- else
- {
- xReturn = pdFALSE;
- }
-
- return xReturn;
-}
-
-XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
-{
-int head = xemacpsif->txHead;
-int iHasSent = 0;
-uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
-TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- {
- /* This driver wants to own all network buffers which are to be transmitted. */
- configASSERT( iReleaseAfterSend != pdFALSE );
- }
- #endif
-
- /* Open a do {} while ( 0 ) loop to be able to call break. */
- do
- {
- uint32_t ulFlags = 0;
-
- if( xValidLength( pxBuffer->xDataLength ) != pdTRUE )
- {
- break;
- }
-
- if( xTXDescriptorSemaphore == NULL )
- {
- break;
- }
-
- if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
- {
- FreeRTOS_printf( ( "emacps_send_message: Time-out waiting for TX buffer\n" ) );
- break;
- }
-
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- /* Pass the pointer (and its ownership) directly to DMA. */
- pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
- if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheFlushRange( ( unsigned )pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
- }
- /* Buffer has been transferred, do not release it. */
- iReleaseAfterSend = pdFALSE;
-#else
- if( pxDMA_tx_buffers[ head ] == NULL )
- {
- FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
- break;
- }
- /* Copy the message to unbuffered space in RAM. */
- memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
-#endif
- /* Packets will be sent one-by-one, so for each packet
- the TXBUF_LAST bit will be set. */
- ulFlags |= XEMACPS_TXBUF_LAST_MASK;
- ulFlags |= ( pxBuffer->xDataLength & XEMACPS_TXBUF_LEN_MASK );
- if( head == ( ipconfigNIC_N_TX_DESC - 1 ) )
- {
- ulFlags |= XEMACPS_TXBUF_WRAP_MASK;
- }
-
- /* Copy the address of the buffer and set the flags. */
- xemacpsif->txSegments[ head ].address = ( uint32_t )pxDMA_tx_buffers[ head ];
- xemacpsif->txSegments[ head ].flags = ulFlags;
-
- iHasSent = pdTRUE;
- if( ++head == ipconfigNIC_N_TX_DESC )
- {
- head = 0;
- }
- /* Update the TX-head index. These variable are declared volatile so they will be
- accessed as little as possible. */
- xemacpsif->txHead = head;
- } while( pdFALSE );
-
- if( iReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxBuffer );
- pxBuffer = NULL;
- }
-
- /* Data Synchronization Barrier */
- dsb();
-
- if( iHasSent != pdFALSE )
- {
- /* Make STARTTX high */
- uint32_t ulValue = XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET);
- /* Start transmit */
- xemacpsif->txBusy = pdTRUE;
- XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
- }
- dsb();
-
- return 0;
-}
-
-void emacps_recv_handler(void *arg)
-{
- xemacpsif_s *xemacpsif;
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
-
- xemacpsif = (xemacpsif_s *)(arg);
- xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
-
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- }
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-
-static NetworkBufferDescriptor_t *ethMsg = NULL;
-static NetworkBufferDescriptor_t *ethLast = NULL;
-
-static void passEthMessages( void )
-{
-IPStackEvent_t xRxEvent;
-
- xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) ethMsg;
-
- if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
- {
- /* The buffer could not be sent to the stack so must be released again.
- This is a deferred handler taskr, not a real interrupt, so it is ok to
- use the task level function here. */
- do
- {
- NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
- vReleaseNetworkBufferAndDescriptor( ethMsg );
- ethMsg = xNext;
- } while( ethMsg != NULL );
-
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
- }
-
- ethMsg = ethLast = NULL;
-}
-
-int emacps_check_rx( xemacpsif_s *xemacpsif )
-{
-NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
-int rx_bytes;
-volatile int msgCount = 0;
-int head = xemacpsif->rxHead;
-
- /* There seems to be an issue (SI# 692601), see comments below. */
- resetrx_on_no_rxdata(xemacpsif);
-
- /* This FreeRTOS+TCP driver shall be compiled with the option
- "ipconfigUSE_LINKED_RX_MESSAGES" enabled. It allows the driver to send a
- chain of RX messages within one message to the IP-task. */
- for( ;; )
- {
- if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) ||
- ( pxDMA_rx_buffers[ head ] == NULL ) )
- {
- break;
- }
-
- pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
- if( pxNewBuffer == NULL )
- {
- /* A packet has been received, but there is no replacement for this Network Buffer.
- The packet will be dropped, and it Network Buffer will stay in place. */
- FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
- pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
- }
- else
- {
- pxBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
-
- /* Just avoiding to use or refer to the same buffer again */
- pxDMA_rx_buffers[ head ] = pxNewBuffer;
-
- /*
- * Adjust the buffer size to the actual number of bytes received.
- */
- rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
-
- pxBuffer->xDataLength = rx_bytes;
-
- if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
- }
-
- /* store it in the receive queue, where it'll be processed by a
- different handler. */
- iptraceNETWORK_INTERFACE_RECEIVE();
- pxBuffer->pxNextBuffer = NULL;
-
- if( ethMsg == NULL )
- {
- // Becomes the first message
- ethMsg = pxBuffer;
- }
- else if( ethLast != NULL )
- {
- // Add to the tail
- ethLast->pxNextBuffer = pxBuffer;
- }
-
- ethLast = pxBuffer;
- msgCount++;
- }
- {
- if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
- }
- {
- uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
- if( head == ( ipconfigNIC_N_RX_DESC - 1 ) )
- {
- addr |= XEMACPS_RXBUF_WRAP_MASK;
- }
- /* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
- xemacpsif->rxSegments[ head ].address = addr;
- xemacpsif->rxSegments[ head ].flags = 0;
- }
- }
-
- if( ++head == ipconfigNIC_N_RX_DESC )
- {
- head = 0;
- }
- xemacpsif->rxHead = head;
- }
-
- if( ethMsg != NULL )
- {
- passEthMessages( );
- }
-
- return msgCount;
-}
-
-void clean_dma_txdescs(xemacpsif_s *xemacpsif)
-{
-int index;
-unsigned char *ucTxBuffer;
-
- /* Clear all TX descriptors and assign uncached memory to each descriptor.
- "tx_space" points to the first available TX buffer. */
- ucTxBuffer = xemacpsif->tx_space;
-
- for( index = 0; index < ipconfigNIC_N_TX_DESC; index++ )
- {
- xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
- xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
-#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
- pxDMA_tx_buffers[ index ] = ( void* )NULL;
-#else
- pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
-#endif
- ucTxBuffer += xemacpsif->uTxUnitSize;
- }
- xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
- XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
-}
-
-XStatus init_dma(xemacpsif_s *xemacpsif)
-{
- NetworkBufferDescriptor_t *pxBuffer;
-
- int iIndex;
- UBaseType_t xRxSize;
- UBaseType_t xTxSize;
- struct xtopology_t *xtopologyp = &xXTopology;
-
- xRxSize = ipconfigNIC_N_RX_DESC * sizeof( xemacpsif->rxSegments[ 0 ] );
-
- xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
-
- /* Also round-up to 4KB */
- xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
- /*
- * We allocate 65536 bytes for RX BDs which can accommodate a
- * maximum of 8192 BDs which is much more than any application
- * will ever need.
- */
- xemacpsif->rxSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xRxSize ) );
- xemacpsif->txSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xTxSize ) );
- xemacpsif->tx_space = ( unsigned char * )( pucGetUncachedMemory ( ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize ) );
-
- /* These variables will be used in XEmacPs_Start (see src/xemacps.c). */
- xemacpsif->emacps.RxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->rxSegments;
- xemacpsif->emacps.TxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->txSegments;
-
- if( xTXDescriptorSemaphore == NULL )
- {
- xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNIC_N_TX_DESC, ( UBaseType_t ) ipconfigNIC_N_TX_DESC );
- configASSERT( xTXDescriptorSemaphore );
- }
- /*
- * Allocate RX descriptors, 1 RxBD at a time.
- */
- for( iIndex = 0; iIndex < ipconfigNIC_N_RX_DESC; iIndex++ )
- {
- pxBuffer = pxDMA_rx_buffers[ iIndex ];
- if( pxBuffer == NULL )
- {
- pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
- if( pxBuffer == NULL )
- {
- FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
- return -1;
- }
- }
-
- xemacpsif->rxSegments[ iIndex ].flags = 0;
- xemacpsif->rxSegments[ iIndex ].address = ( ( uint32_t )pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
-
- pxDMA_rx_buffers[ iIndex ] = pxBuffer;
- /* Make sure this memory is not in cache for now. */
- if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
- {
- Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
- (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
- }
- }
-
- xemacpsif->rxSegments[ ipconfigNIC_N_RX_DESC - 1 ].address |= XEMACPS_RXBUF_WRAP_MASK;
-
- memset( xemacpsif->tx_space, '\0', ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize );
-
- clean_dma_txdescs( xemacpsif );
-
- {
- uint32_t value;
- value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET );
-
- // 1xxxx: Attempt to use INCR16 AHB bursts
- value = ( value & ~( XEMACPS_DMACR_BLENGTH_MASK ) ) | XEMACPS_DMACR_INCR16_AHB_BURST;
-#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
- value |= XEMACPS_DMACR_TCPCKSUM_MASK;
-#else
-#warning Are you sure the EMAC should not calculate outgoing checksums?
- value &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
-#endif
- XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET, value );
- }
- {
- uint32_t value;
- value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET );
-
- /* Network buffers are 32-bit aligned + 2 bytes (because ipconfigPACKET_FILLER_SIZE = 2 ).
- Now tell the EMAC that received messages should be stored at "address + 2". */
- value = ( value & ~XEMACPS_NWCFG_RXOFFS_MASK ) | 0x8000;
-
-#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM != 0 )
- value |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
-#else
-#warning Are you sure the EMAC should not calculate incoming checksums?
- value &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
-#endif
- XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET, value );
- }
-
- /*
- * Connect the device driver handler that will be called when an
- * interrupt for the device occurs, the handler defined above performs
- * the specific interrupt processing for the device.
- */
- XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
- (Xil_ExceptionHandler)XEmacPs_IntrHandler,
- (void *)&xemacpsif->emacps);
- /*
- * Enable the interrupt for emacps.
- */
- EmacEnableIntr( );
-
- return 0;
-}
-
-/*
- * resetrx_on_no_rxdata():
- *
- * It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
- * called by the user.
- * The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
- * Under heavy Rx traffic because of the HW bug there are times when the Rx path
- * becomes unresponsive. The workaround for it is to check for the Rx path for
- * traffic (by reading the stats registers regularly). If the stats register
- * does not increment for sometime (proving no Rx traffic), the function resets
- * the Rx data path.
- *
- */
-
-void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
-{
- unsigned long regctrl;
- unsigned long tempcntr;
-
- tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
- if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
- {
- regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, regctrl);
- regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
- regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
- }
- xemacpsif->last_rx_frms_cntr = tempcntr;
-}
-
-void EmacDisableIntr(void)
-{
- XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
-}
-
-void EmacEnableIntr(void)
-{
- XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
-}
-
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+#include "Zynq/x_emacpsif.h"
+#include "Zynq/x_topology.h"
+#include "xstatus.h"
+
+#include "xparameters.h"
+#include "xparameters_ps.h"
+#include "xil_exception.h"
+#include "xil_mmu.h"
+
+#include "FreeRTOS.h"
+#include "task.h"
+#include "timers.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+#include "uncached_memory.h"
+
+/* Two defines used to set or clear the EMAC interrupt */
+#define INTC_BASE_ADDR XPAR_SCUGIC_CPU_BASEADDR
+#define INTC_DIST_BASE_ADDR XPAR_SCUGIC_DIST_BASEADDR
+
+
+
+#if( ipconfigPACKET_FILLER_SIZE != 2 )
+ #error Please define ipconfigPACKET_FILLER_SIZE as the value '2'
+#endif
+#define TX_OFFSET ipconfigPACKET_FILLER_SIZE
+
+#define RX_BUFFER_ALIGNMENT 14
+
+/* Defined in NetworkInterface.c */
+extern TaskHandle_t xEMACTaskHandle;
+
+/*
+ pxDMA_tx_buffers: these are character arrays, each one is big enough to hold 1 MTU.
+ The actual TX buffers are located in uncached RAM.
+*/
+static unsigned char *pxDMA_tx_buffers[ ipconfigNIC_N_TX_DESC ] = { NULL };
+
+/*
+ pxDMA_rx_buffers: these are pointers to 'NetworkBufferDescriptor_t'.
+ Once a message has been received by the EMAC, the descriptor can be passed
+ immediately to the IP-task.
+*/
+static NetworkBufferDescriptor_t *pxDMA_rx_buffers[ ipconfigNIC_N_RX_DESC ] = { NULL };
+
+/*
+ The FreeRTOS+TCP port is using a fixed 'topology', which is declared in
+ ./portable/NetworkInterface/Zynq/NetworkInterface.c
+*/
+extern struct xtopology_t xXTopology;
+
+static SemaphoreHandle_t xTXDescriptorSemaphore = NULL;
+
+/*
+ The FreeRTOS+TCP port does not make use of "src/xemacps_bdring.c".
+ In stead 'struct xemacpsif_s' has a "head" and a "tail" index.
+ "head" is the next index to be written, used.
+ "tail" is the next index to be read, freed.
+*/
+
+int is_tx_space_available( xemacpsif_s *xemacpsif )
+{
+size_t uxCount;
+
+ if( xTXDescriptorSemaphore != NULL )
+ {
+ uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+ }
+ else
+ {
+ uxCount = ( UBaseType_t ) 0u;
+ }
+
+ return uxCount;
+}
+
+void emacps_check_tx( xemacpsif_s *xemacpsif )
+{
+int tail = xemacpsif->txTail;
+int head = xemacpsif->txHead;
+size_t uxCount = ( ( UBaseType_t ) ipconfigNIC_N_TX_DESC ) - uxSemaphoreGetCount( xTXDescriptorSemaphore );
+
+ /* uxCount is the number of TX descriptors that are in use by the DMA. */
+ /* When done, "TXBUF_USED" will be set. */
+
+ while( ( uxCount > 0 ) && ( ( xemacpsif->txSegments[ tail ].flags & XEMACPS_TXBUF_USED_MASK ) != 0 ) )
+ {
+ if( ( tail == head ) && ( uxCount != ipconfigNIC_N_TX_DESC ) )
+ {
+ break;
+ }
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+#warning ipconfigZERO_COPY_TX_DRIVER is defined
+ {
+ void *pvBuffer = pxDMA_tx_buffers[ tail ];
+ NetworkBufferDescriptor_t *pxBuffer;
+
+ if( pvBuffer != NULL )
+ {
+ pxDMA_tx_buffers[ tail ] = NULL;
+ pxBuffer = pxPacketBuffer_to_NetworkBuffer( pvBuffer );
+ if( pxBuffer != NULL )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ }
+ else
+ {
+ FreeRTOS_printf( ( "emacps_check_tx: Can not find network buffer\n" ) );
+ }
+ }
+ }
+#endif
+ /* Clear all but the "used" and "wrap" bits. */
+ if( tail < ipconfigNIC_N_TX_DESC - 1 )
+ {
+ xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK;
+ }
+ else
+ {
+ xemacpsif->txSegments[ tail ].flags = XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
+ }
+ uxCount--;
+ /* Tell the counting semaphore that one more TX descriptor is available. */
+ xSemaphoreGive( xTXDescriptorSemaphore );
+ if( ++tail == ipconfigNIC_N_TX_DESC )
+ {
+ tail = 0;
+ }
+ xemacpsif->txTail = tail;
+ }
+
+ return;
+}
+
+void emacps_send_handler(void *arg)
+{
+xemacpsif_s *xemacpsif;
+BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+
+ /* In this port for FreeRTOS+TCP, the EMAC interrupts will only set a bit in
+ "isr_events". The task in NetworkInterface will wake-up and do the necessary work.
+ */
+ xemacpsif->isr_events |= EMAC_IF_TX_EVENT;
+ xemacpsif->txBusy = pdFALSE;
+
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ }
+
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+static BaseType_t xValidLength( BaseType_t xLength )
+{
+BaseType_t xReturn;
+
+ if( ( xLength >= ( BaseType_t ) sizeof( struct xARP_PACKET ) ) && ( ( ( uint32_t ) xLength ) <= ipTOTAL_ETHERNET_FRAME_SIZE ) )
+ {
+ xReturn = pdTRUE;
+ }
+ else
+ {
+ xReturn = pdFALSE;
+ }
+
+ return xReturn;
+}
+
+XStatus emacps_send_message(xemacpsif_s *xemacpsif, NetworkBufferDescriptor_t *pxBuffer, int iReleaseAfterSend )
+{
+int head = xemacpsif->txHead;
+int iHasSent = 0;
+uint32_t ulBaseAddress = xemacpsif->emacps.Config.BaseAddress;
+TickType_t xBlockTimeTicks = pdMS_TO_TICKS( 5000u );
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ {
+ /* This driver wants to own all network buffers which are to be transmitted. */
+ configASSERT( iReleaseAfterSend != pdFALSE );
+ }
+ #endif
+
+ /* Open a do {} while ( 0 ) loop to be able to call break. */
+ do
+ {
+ uint32_t ulFlags = 0;
+
+ if( xValidLength( pxBuffer->xDataLength ) != pdTRUE )
+ {
+ break;
+ }
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ break;
+ }
+
+ if( xSemaphoreTake( xTXDescriptorSemaphore, xBlockTimeTicks ) != pdPASS )
+ {
+ FreeRTOS_printf( ( "emacps_send_message: Time-out waiting for TX buffer\n" ) );
+ break;
+ }
+
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ /* Pass the pointer (and its ownership) directly to DMA. */
+ pxDMA_tx_buffers[ head ] = pxBuffer->pucEthernetBuffer;
+ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheFlushRange( ( unsigned )pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
+ }
+ /* Buffer has been transferred, do not release it. */
+ iReleaseAfterSend = pdFALSE;
+#else
+ if( pxDMA_tx_buffers[ head ] == NULL )
+ {
+ FreeRTOS_printf( ( "emacps_send_message: pxDMA_tx_buffers[ %d ] == NULL\n", head ) );
+ break;
+ }
+ /* Copy the message to unbuffered space in RAM. */
+ memcpy( pxDMA_tx_buffers[ head ], pxBuffer->pucEthernetBuffer, pxBuffer->xDataLength );
+#endif
+ /* Packets will be sent one-by-one, so for each packet
+ the TXBUF_LAST bit will be set. */
+ ulFlags |= XEMACPS_TXBUF_LAST_MASK;
+ ulFlags |= ( pxBuffer->xDataLength & XEMACPS_TXBUF_LEN_MASK );
+ if( head == ( ipconfigNIC_N_TX_DESC - 1 ) )
+ {
+ ulFlags |= XEMACPS_TXBUF_WRAP_MASK;
+ }
+
+ /* Copy the address of the buffer and set the flags. */
+ xemacpsif->txSegments[ head ].address = ( uint32_t )pxDMA_tx_buffers[ head ];
+ xemacpsif->txSegments[ head ].flags = ulFlags;
+
+ iHasSent = pdTRUE;
+ if( ++head == ipconfigNIC_N_TX_DESC )
+ {
+ head = 0;
+ }
+ /* Update the TX-head index. These variable are declared volatile so they will be
+ accessed as little as possible. */
+ xemacpsif->txHead = head;
+ } while( pdFALSE );
+
+ if( iReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxBuffer );
+ pxBuffer = NULL;
+ }
+
+ /* Data Synchronization Barrier */
+ dsb();
+
+ if( iHasSent != pdFALSE )
+ {
+ /* Make STARTTX high */
+ uint32_t ulValue = XEmacPs_ReadReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET);
+ /* Start transmit */
+ xemacpsif->txBusy = pdTRUE;
+ XEmacPs_WriteReg( ulBaseAddress, XEMACPS_NWCTRL_OFFSET, ( ulValue | XEMACPS_NWCTRL_STARTTX_MASK ) );
+ }
+ dsb();
+
+ return 0;
+}
+
+void emacps_recv_handler(void *arg)
+{
+ xemacpsif_s *xemacpsif;
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+ xemacpsif->isr_events |= EMAC_IF_RX_EVENT;
+
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ }
+
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+static NetworkBufferDescriptor_t *ethMsg = NULL;
+static NetworkBufferDescriptor_t *ethLast = NULL;
+
+static void passEthMessages( void )
+{
+IPStackEvent_t xRxEvent;
+
+ xRxEvent.eEventType = eNetworkRxEvent;
+ xRxEvent.pvData = ( void * ) ethMsg;
+
+ if( xSendEventStructToIPTask( &xRxEvent, ( TickType_t ) 1000 ) != pdPASS )
+ {
+ /* The buffer could not be sent to the stack so must be released again.
+ This is a deferred handler taskr, not a real interrupt, so it is ok to
+ use the task level function here. */
+ do
+ {
+ NetworkBufferDescriptor_t *xNext = ethMsg->pxNextBuffer;
+ vReleaseNetworkBufferAndDescriptor( ethMsg );
+ ethMsg = xNext;
+ } while( ethMsg != NULL );
+
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "passEthMessages: Can not queue return packet!\n" ) );
+ }
+
+ ethMsg = ethLast = NULL;
+}
+
+int emacps_check_rx( xemacpsif_s *xemacpsif )
+{
+NetworkBufferDescriptor_t *pxBuffer, *pxNewBuffer;
+int rx_bytes;
+volatile int msgCount = 0;
+int head = xemacpsif->rxHead;
+
+ /* There seems to be an issue (SI# 692601), see comments below. */
+ resetrx_on_no_rxdata(xemacpsif);
+
+ /* This FreeRTOS+TCP driver shall be compiled with the option
+ "ipconfigUSE_LINKED_RX_MESSAGES" enabled. It allows the driver to send a
+ chain of RX messages within one message to the IP-task. */
+ for( ;; )
+ {
+ if( ( ( xemacpsif->rxSegments[ head ].address & XEMACPS_RXBUF_NEW_MASK ) == 0 ) ||
+ ( pxDMA_rx_buffers[ head ] == NULL ) )
+ {
+ break;
+ }
+
+ pxNewBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ if( pxNewBuffer == NULL )
+ {
+ /* A packet has been received, but there is no replacement for this Network Buffer.
+ The packet will be dropped, and it Network Buffer will stay in place. */
+ FreeRTOS_printf( ("emacps_check_rx: unable to allocate a Netwrok Buffer\n" ) );
+ pxNewBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
+ }
+ else
+ {
+ pxBuffer = ( NetworkBufferDescriptor_t * )pxDMA_rx_buffers[ head ];
+
+ /* Just avoiding to use or refer to the same buffer again */
+ pxDMA_rx_buffers[ head ] = pxNewBuffer;
+
+ /*
+ * Adjust the buffer size to the actual number of bytes received.
+ */
+ rx_bytes = xemacpsif->rxSegments[ head ].flags & XEMACPS_RXBUF_LEN_MASK;
+
+ pxBuffer->xDataLength = rx_bytes;
+
+ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)rx_bytes );
+ }
+
+ /* store it in the receive queue, where it'll be processed by a
+ different handler. */
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ pxBuffer->pxNextBuffer = NULL;
+
+ if( ethMsg == NULL )
+ {
+ // Becomes the first message
+ ethMsg = pxBuffer;
+ }
+ else if( ethLast != NULL )
+ {
+ // Add to the tail
+ ethLast->pxNextBuffer = pxBuffer;
+ }
+
+ ethLast = pxBuffer;
+ msgCount++;
+ }
+ {
+ if( ucIsCachedMemory( pxNewBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE, (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ }
+ {
+ uint32_t addr = ( ( uint32_t )pxNewBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
+ if( head == ( ipconfigNIC_N_RX_DESC - 1 ) )
+ {
+ addr |= XEMACPS_RXBUF_WRAP_MASK;
+ }
+ /* Clearing 'XEMACPS_RXBUF_NEW_MASK' 0x00000001 *< Used bit.. */
+ xemacpsif->rxSegments[ head ].address = addr;
+ xemacpsif->rxSegments[ head ].flags = 0;
+ }
+ }
+
+ if( ++head == ipconfigNIC_N_RX_DESC )
+ {
+ head = 0;
+ }
+ xemacpsif->rxHead = head;
+ }
+
+ if( ethMsg != NULL )
+ {
+ passEthMessages( );
+ }
+
+ return msgCount;
+}
+
+void clean_dma_txdescs(xemacpsif_s *xemacpsif)
+{
+int index;
+unsigned char *ucTxBuffer;
+
+ /* Clear all TX descriptors and assign uncached memory to each descriptor.
+ "tx_space" points to the first available TX buffer. */
+ ucTxBuffer = xemacpsif->tx_space;
+
+ for( index = 0; index < ipconfigNIC_N_TX_DESC; index++ )
+ {
+ xemacpsif->txSegments[ index ].address = ( uint32_t )ucTxBuffer;
+ xemacpsif->txSegments[ index ].flags = XEMACPS_TXBUF_USED_MASK;
+#if( ipconfigZERO_COPY_TX_DRIVER != 0 )
+ pxDMA_tx_buffers[ index ] = ( void* )NULL;
+#else
+ pxDMA_tx_buffers[ index ] = ( void* )( ucTxBuffer + TX_OFFSET );
+#endif
+ ucTxBuffer += xemacpsif->uTxUnitSize;
+ }
+ xemacpsif->txSegments[ ipconfigNIC_N_TX_DESC - 1 ].flags =
+ XEMACPS_TXBUF_USED_MASK | XEMACPS_TXBUF_WRAP_MASK;
+}
+
+XStatus init_dma(xemacpsif_s *xemacpsif)
+{
+ NetworkBufferDescriptor_t *pxBuffer;
+
+ int iIndex;
+ UBaseType_t xRxSize;
+ UBaseType_t xTxSize;
+ struct xtopology_t *xtopologyp = &xXTopology;
+
+ xRxSize = ipconfigNIC_N_RX_DESC * sizeof( xemacpsif->rxSegments[ 0 ] );
+
+ xTxSize = ipconfigNIC_N_TX_DESC * sizeof( xemacpsif->txSegments[ 0 ] );
+
+ /* Also round-up to 4KB */
+ xemacpsif->uTxUnitSize = ( ipTOTAL_ETHERNET_FRAME_SIZE + 0x1000ul ) & ~0xffful;
+ /*
+ * We allocate 65536 bytes for RX BDs which can accommodate a
+ * maximum of 8192 BDs which is much more than any application
+ * will ever need.
+ */
+ xemacpsif->rxSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xRxSize ) );
+ xemacpsif->txSegments = ( struct xBD_TYPE * )( pucGetUncachedMemory ( xTxSize ) );
+ xemacpsif->tx_space = ( unsigned char * )( pucGetUncachedMemory ( ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize ) );
+
+ /* These variables will be used in XEmacPs_Start (see src/xemacps.c). */
+ xemacpsif->emacps.RxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->rxSegments;
+ xemacpsif->emacps.TxBdRing.BaseBdAddr = ( uint32_t ) xemacpsif->txSegments;
+
+ if( xTXDescriptorSemaphore == NULL )
+ {
+ xTXDescriptorSemaphore = xSemaphoreCreateCounting( ( UBaseType_t ) ipconfigNIC_N_TX_DESC, ( UBaseType_t ) ipconfigNIC_N_TX_DESC );
+ configASSERT( xTXDescriptorSemaphore );
+ }
+ /*
+ * Allocate RX descriptors, 1 RxBD at a time.
+ */
+ for( iIndex = 0; iIndex < ipconfigNIC_N_RX_DESC; iIndex++ )
+ {
+ pxBuffer = pxDMA_rx_buffers[ iIndex ];
+ if( pxBuffer == NULL )
+ {
+ pxBuffer = pxGetNetworkBufferWithDescriptor( ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT, ( TickType_t ) 0 );
+ if( pxBuffer == NULL )
+ {
+ FreeRTOS_printf( ("Unable to allocate a network buffer in recv_handler\n" ) );
+ return -1;
+ }
+ }
+
+ xemacpsif->rxSegments[ iIndex ].flags = 0;
+ xemacpsif->rxSegments[ iIndex ].address = ( ( uint32_t )pxBuffer->pucEthernetBuffer ) & XEMACPS_RXBUF_ADD_MASK;
+
+ pxDMA_rx_buffers[ iIndex ] = pxBuffer;
+ /* Make sure this memory is not in cache for now. */
+ if( ucIsCachedMemory( pxBuffer->pucEthernetBuffer ) != 0 )
+ {
+ Xil_DCacheInvalidateRange( ( ( uint32_t )pxBuffer->pucEthernetBuffer ) - ipconfigPACKET_FILLER_SIZE,
+ (unsigned)ipTOTAL_ETHERNET_FRAME_SIZE + RX_BUFFER_ALIGNMENT);
+ }
+ }
+
+ xemacpsif->rxSegments[ ipconfigNIC_N_RX_DESC - 1 ].address |= XEMACPS_RXBUF_WRAP_MASK;
+
+ memset( xemacpsif->tx_space, '\0', ipconfigNIC_N_TX_DESC * xemacpsif->uTxUnitSize );
+
+ clean_dma_txdescs( xemacpsif );
+
+ {
+ uint32_t value;
+ value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET );
+
+ // 1xxxx: Attempt to use INCR16 AHB bursts
+ value = ( value & ~( XEMACPS_DMACR_BLENGTH_MASK ) ) | XEMACPS_DMACR_INCR16_AHB_BURST;
+#if( ipconfigDRIVER_INCLUDED_TX_IP_CHECKSUM != 0 )
+ value |= XEMACPS_DMACR_TCPCKSUM_MASK;
+#else
+#warning Are you sure the EMAC should not calculate outgoing checksums?
+ value &= ~XEMACPS_DMACR_TCPCKSUM_MASK;
+#endif
+ XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_DMACR_OFFSET, value );
+ }
+ {
+ uint32_t value;
+ value = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET );
+
+ /* Network buffers are 32-bit aligned + 2 bytes (because ipconfigPACKET_FILLER_SIZE = 2 ).
+ Now tell the EMAC that received messages should be stored at "address + 2". */
+ value = ( value & ~XEMACPS_NWCFG_RXOFFS_MASK ) | 0x8000;
+
+#if( ipconfigDRIVER_INCLUDED_RX_IP_CHECKSUM != 0 )
+ value |= XEMACPS_NWCFG_RXCHKSUMEN_MASK;
+#else
+#warning Are you sure the EMAC should not calculate incoming checksums?
+ value &= ~XEMACPS_NWCFG_RXCHKSUMEN_MASK;
+#endif
+ XEmacPs_WriteReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCFG_OFFSET, value );
+ }
+
+ /*
+ * Connect the device driver handler that will be called when an
+ * interrupt for the device occurs, the handler defined above performs
+ * the specific interrupt processing for the device.
+ */
+ XScuGic_RegisterHandler(INTC_BASE_ADDR, xtopologyp->scugic_emac_intr,
+ (Xil_ExceptionHandler)XEmacPs_IntrHandler,
+ (void *)&xemacpsif->emacps);
+ /*
+ * Enable the interrupt for emacps.
+ */
+ EmacEnableIntr( );
+
+ return 0;
+}
+
+/*
+ * resetrx_on_no_rxdata():
+ *
+ * It is called at regular intervals through the API xemacpsif_resetrx_on_no_rxdata
+ * called by the user.
+ * The EmacPs has a HW bug (SI# 692601) on the Rx path for heavy Rx traffic.
+ * Under heavy Rx traffic because of the HW bug there are times when the Rx path
+ * becomes unresponsive. The workaround for it is to check for the Rx path for
+ * traffic (by reading the stats registers regularly). If the stats register
+ * does not increment for sometime (proving no Rx traffic), the function resets
+ * the Rx data path.
+ *
+ */
+
+void resetrx_on_no_rxdata(xemacpsif_s *xemacpsif)
+{
+ unsigned long regctrl;
+ unsigned long tempcntr;
+
+ tempcntr = XEmacPs_ReadReg( xemacpsif->emacps.Config.BaseAddress, XEMACPS_RXCNT_OFFSET );
+ if ( ( tempcntr == 0 ) && ( xemacpsif->last_rx_frms_cntr == 0 ) )
+ {
+ regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET);
+ regctrl &= (~XEMACPS_NWCTRL_RXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET, regctrl);
+ regctrl = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET);
+ regctrl |= (XEMACPS_NWCTRL_RXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress, XEMACPS_NWCTRL_OFFSET, regctrl);
+ }
+ xemacpsif->last_rx_frms_cntr = tempcntr;
+}
+
+void EmacDisableIntr(void)
+{
+ XScuGic_DisableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
+}
+
+void EmacEnableIntr(void)
+{
+ XScuGic_EnableIntr(INTC_DIST_BASE_ADDR, xXTopology.scugic_emac_intr);
+}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
index e9443cda8..be00f4f9c 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.c
@@ -1,243 +1,243 @@
-/*
- * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "Zynq/x_emacpsif.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-
-///* FreeRTOS+TCP includes. */
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-extern TaskHandle_t xEMACTaskHandle;
-
-/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
- *** to run it on a PEEP board
- ***/
-
-unsigned int link_speed = 100;
-
-void setup_isr( xemacpsif_s *xemacpsif )
-{
- /*
- * Setup callbacks
- */
- XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
- (void *) emacps_send_handler,
- (void *) xemacpsif);
-
- XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
- (void *) emacps_recv_handler,
- (void *) xemacpsif);
-
- XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
- (void *) emacps_error_handler,
- (void *) xemacpsif);
-}
-
-void start_emacps (xemacpsif_s *xemacps)
-{
- /* start the temac */
- XEmacPs_Start(&xemacps->emacps);
-}
-
-extern struct xtopology_t xXTopology;
-
-volatile int error_msg_count = 0;
-volatile const char *last_err_msg = "";
-
-struct xERROR_MSG {
- void *arg;
- u8 Direction;
- u32 ErrorWord;
-};
-
-static struct xERROR_MSG xErrorList[ 8 ];
-static BaseType_t xErrorHead, xErrorTail;
-
-void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
-{
- BaseType_t xHigherPriorityTaskWoken = pdFALSE;
- xemacpsif_s *xemacpsif;
- BaseType_t xNextHead = xErrorHead;
-
- xemacpsif = (xemacpsif_s *)(arg);
-
- if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
- {
- if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
- xNextHead = 0;
- if( xNextHead != xErrorTail )
- {
-
- xErrorList[ xErrorHead ].arg = arg;
- xErrorList[ xErrorHead ].Direction = Direction;
- xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
-
- xErrorHead = xNextHead;
-
- xemacpsif = (xemacpsif_s *)(arg);
- xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
- }
-
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
- }
-
- }
-
- portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
-}
-
-static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
-
-int emacps_check_errors( xemacpsif_s *xemacps )
-{
-int xResult;
-
- ( void ) xemacps;
-
- if( xErrorHead == xErrorTail )
- {
- xResult = 0;
- }
- else
- {
- xResult = 1;
- emacps_handle_error(
- xErrorList[ xErrorTail ].arg,
- xErrorList[ xErrorTail ].Direction,
- xErrorList[ xErrorTail ].ErrorWord );
- }
-
- return xResult;
-}
-
-BaseType_t xNetworkInterfaceInitialise( void );
-
-static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
-{
- xemacpsif_s *xemacpsif;
- struct xtopology_t *xtopologyp;
- XEmacPs *xemacps;
-
- xemacpsif = (xemacpsif_s *)(arg);
-
- xtopologyp = &xXTopology;
-
- xemacps = &xemacpsif->emacps;
-
- /* Do not appear to be used. */
- ( void ) xemacps;
- ( void ) xtopologyp;
-
- last_err_msg = NULL;
-
- if( ErrorWord != 0 )
- {
- switch (Direction) {
- case XEMACPS_RECV:
- if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
- {
- last_err_msg = "Receive DMA error";
- xNetworkInterfaceInitialise( );
- }
- if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
- {
- last_err_msg = "Receive over run";
- emacps_recv_handler(arg);
- }
- if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
- {
- last_err_msg = "Receive buffer not available";
- emacps_recv_handler(arg);
- }
- break;
- case XEMACPS_SEND:
- if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
- {
- last_err_msg = "Transmit DMA error";
- xNetworkInterfaceInitialise( );
- }
- if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
- {
- last_err_msg = "Transmit under run";
- HandleTxErrors( xemacpsif );
- }
- if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
- {
- last_err_msg = "Transmit buffer exhausted";
- HandleTxErrors( xemacpsif );
- }
- if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
- {
- last_err_msg = "Transmit retry excessed limits";
- HandleTxErrors( xemacpsif );
- }
- if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
- {
- last_err_msg = "Transmit collision";
- emacps_check_tx( xemacpsif );
- }
- break;
- }
- }
- // Break on this statement and inspect error_msg if you like
- if( last_err_msg != NULL )
- {
- error_msg_count++;
- FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
- }
-}
-
-extern XEmacPs_Config mac_config;
-
-void HandleTxErrors(xemacpsif_s *xemacpsif)
-{
- u32 netctrlreg;
-
- //taskENTER_CRITICAL()
- {
- netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, netctrlreg);
-
- clean_dma_txdescs( xemacpsif );
- netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET);
- netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
- XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
- XEMACPS_NWCTRL_OFFSET, netctrlreg);
- }
- //taskEXIT_CRITICAL( );
-}
+/*
+ * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Zynq/x_emacpsif.h"
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+
+///* FreeRTOS+TCP includes. */
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+extern TaskHandle_t xEMACTaskHandle;
+
+/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
+ *** to run it on a PEEP board
+ ***/
+
+unsigned int link_speed = 100;
+
+void setup_isr( xemacpsif_s *xemacpsif )
+{
+ /*
+ * Setup callbacks
+ */
+ XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMASEND,
+ (void *) emacps_send_handler,
+ (void *) xemacpsif);
+
+ XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_DMARECV,
+ (void *) emacps_recv_handler,
+ (void *) xemacpsif);
+
+ XEmacPs_SetHandler(&xemacpsif->emacps, XEMACPS_HANDLER_ERROR,
+ (void *) emacps_error_handler,
+ (void *) xemacpsif);
+}
+
+void start_emacps (xemacpsif_s *xemacps)
+{
+ /* start the temac */
+ XEmacPs_Start(&xemacps->emacps);
+}
+
+extern struct xtopology_t xXTopology;
+
+volatile int error_msg_count = 0;
+volatile const char *last_err_msg = "";
+
+struct xERROR_MSG {
+ void *arg;
+ u8 Direction;
+ u32 ErrorWord;
+};
+
+static struct xERROR_MSG xErrorList[ 8 ];
+static BaseType_t xErrorHead, xErrorTail;
+
+void emacps_error_handler(void *arg, u8 Direction, u32 ErrorWord)
+{
+ BaseType_t xHigherPriorityTaskWoken = pdFALSE;
+ xemacpsif_s *xemacpsif;
+ BaseType_t xNextHead = xErrorHead;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+
+ if( ( Direction != XEMACPS_SEND ) || (ErrorWord != XEMACPS_TXSR_USEDREAD_MASK ) )
+ {
+ if( ++xNextHead == ( sizeof( xErrorList ) / sizeof( xErrorList[ 0 ] ) ) )
+ xNextHead = 0;
+ if( xNextHead != xErrorTail )
+ {
+
+ xErrorList[ xErrorHead ].arg = arg;
+ xErrorList[ xErrorHead ].Direction = Direction;
+ xErrorList[ xErrorHead ].ErrorWord = ErrorWord;
+
+ xErrorHead = xNextHead;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+ xemacpsif->isr_events |= EMAC_IF_ERR_EVENT;
+ }
+
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &xHigherPriorityTaskWoken );
+ }
+
+ }
+
+ portYIELD_FROM_ISR( xHigherPriorityTaskWoken );
+}
+
+static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord);
+
+int emacps_check_errors( xemacpsif_s *xemacps )
+{
+int xResult;
+
+ ( void ) xemacps;
+
+ if( xErrorHead == xErrorTail )
+ {
+ xResult = 0;
+ }
+ else
+ {
+ xResult = 1;
+ emacps_handle_error(
+ xErrorList[ xErrorTail ].arg,
+ xErrorList[ xErrorTail ].Direction,
+ xErrorList[ xErrorTail ].ErrorWord );
+ }
+
+ return xResult;
+}
+
+BaseType_t xNetworkInterfaceInitialise( void );
+
+static void emacps_handle_error(void *arg, u8 Direction, u32 ErrorWord)
+{
+ xemacpsif_s *xemacpsif;
+ struct xtopology_t *xtopologyp;
+ XEmacPs *xemacps;
+
+ xemacpsif = (xemacpsif_s *)(arg);
+
+ xtopologyp = &xXTopology;
+
+ xemacps = &xemacpsif->emacps;
+
+ /* Do not appear to be used. */
+ ( void ) xemacps;
+ ( void ) xtopologyp;
+
+ last_err_msg = NULL;
+
+ if( ErrorWord != 0 )
+ {
+ switch (Direction) {
+ case XEMACPS_RECV:
+ if( ( ErrorWord & XEMACPS_RXSR_HRESPNOK_MASK ) != 0 )
+ {
+ last_err_msg = "Receive DMA error";
+ xNetworkInterfaceInitialise( );
+ }
+ if( ( ErrorWord & XEMACPS_RXSR_RXOVR_MASK ) != 0 )
+ {
+ last_err_msg = "Receive over run";
+ emacps_recv_handler(arg);
+ }
+ if( ( ErrorWord & XEMACPS_RXSR_BUFFNA_MASK ) != 0 )
+ {
+ last_err_msg = "Receive buffer not available";
+ emacps_recv_handler(arg);
+ }
+ break;
+ case XEMACPS_SEND:
+ if( ( ErrorWord & XEMACPS_TXSR_HRESPNOK_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit DMA error";
+ xNetworkInterfaceInitialise( );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_URUN_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit under run";
+ HandleTxErrors( xemacpsif );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_BUFEXH_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit buffer exhausted";
+ HandleTxErrors( xemacpsif );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_RXOVR_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit retry excessed limits";
+ HandleTxErrors( xemacpsif );
+ }
+ if( ( ErrorWord & XEMACPS_TXSR_FRAMERX_MASK ) != 0 )
+ {
+ last_err_msg = "Transmit collision";
+ emacps_check_tx( xemacpsif );
+ }
+ break;
+ }
+ }
+ // Break on this statement and inspect error_msg if you like
+ if( last_err_msg != NULL )
+ {
+ error_msg_count++;
+ FreeRTOS_printf( ( "emacps_handle_error: %s\n", last_err_msg ) );
+ }
+}
+
+extern XEmacPs_Config mac_config;
+
+void HandleTxErrors(xemacpsif_s *xemacpsif)
+{
+ u32 netctrlreg;
+
+ //taskENTER_CRITICAL()
+ {
+ netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET);
+ netctrlreg = netctrlreg & (~XEMACPS_NWCTRL_TXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET, netctrlreg);
+
+ clean_dma_txdescs( xemacpsif );
+ netctrlreg = XEmacPs_ReadReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET);
+ netctrlreg = netctrlreg | (XEMACPS_NWCTRL_TXEN_MASK);
+ XEmacPs_WriteReg(xemacpsif->emacps.Config.BaseAddress,
+ XEMACPS_NWCTRL_OFFSET, netctrlreg);
+ }
+ //taskEXIT_CRITICAL( );
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h
index f3c424a4b..7b0e4fd36 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_hw.h
@@ -1,39 +1,39 @@
-/*
- * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __XEMACPSIF_HW_H_
-#define __XEMACPSIF_HW_H_
-
-#include "Zynq/x_emacpsif.h"
-//#include "lwip/netif.h"
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-XEmacPs_Config * lookup_config(unsigned mac_base);
-
-//void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
-
-int emacps_check_errors( xemacpsif_s *xemacps );
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * Copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __XEMACPSIF_HW_H_
+#define __XEMACPSIF_HW_H_
+
+#include "Zynq/x_emacpsif.h"
+//#include "lwip/netif.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+XEmacPs_Config * lookup_config(unsigned mac_base);
+
+//void init_emacps(xemacpsif_s *xemacpsif, struct netif *netif);
+
+int emacps_check_errors( xemacpsif_s *xemacps );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
index 12b8c60c8..742ff8b96 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_emacpsif_physpeed.c
@@ -1,585 +1,585 @@
-/*
- * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
- * 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.
- * * 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 Advanced Micro Devices, Inc. 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-/*
- * Some portions copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#include "Zynq/x_emacpsif.h"
-//#include "lwipopts.h"
-#include "xparameters_ps.h"
-#include "xparameters.h"
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-///* FreeRTOS+TCP includes. */
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-
-int phy_detected = 0;
-
-/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
- *** to run it on a PEEP board
- ***/
-
-/* Advertisement control register. */
-#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
-#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
-#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
-#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
-
-#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
- ADVERTISE_10HALF | ADVERTISE_100HALF)
-#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
-#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
-
-#define ADVERTISE_1000 0x0300
-
-
-//#define PHY_REG_00_BMCR 0x00 // Basic mode control register
-//#define PHY_REG_01_BMSR 0x01 // Basic mode status register
-//#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
-//#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
-//#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
-
-#define IEEE_CONTROL_REG_OFFSET 0
-#define IEEE_STATUS_REG_OFFSET 1
-#define IEEE_AUTONEGO_ADVERTISE_REG 4
-#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
-#define IEEE_1000_ADVERTISE_REG_OFFSET 9
-#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
-#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
-#define IEEE_SPECIFIC_STATUS_REG 17
-#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
-#define IEEE_CONTROL_REG_MAC 21
-#define IEEE_PAGE_ADDRESS_REGISTER 22
-
-
-#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
-#define IEEE_CTRL_LINKSPEED_MASK 0x0040
-#define IEEE_CTRL_LINKSPEED_1000M 0x0040
-#define IEEE_CTRL_LINKSPEED_100M 0x2000
-#define IEEE_CTRL_LINKSPEED_10M 0x0000
-#define IEEE_CTRL_RESET_MASK 0x8000
-#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#define IEEE_CTRL_RESET 0x9140
-#define IEEE_CTRL_ISOLATE_DISABLE 0xFBFF
-#endif
-#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
-#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
-#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
-#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
-#define IEEE_AN1_ABILITY_MASK 0x1FE0
-#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
-#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
-#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
-#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
-
-#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
-#define IEEE_PAUSE_MASK 0x0400
-#define IEEE_AUTONEG_ERROR_MASK 0x8000
-
-#define PHY_DETECT_REG 1
-#define PHY_DETECT_MASK 0x1808
-
-#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
-#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
-#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
-#define XEMACPS_GMII2RGMII_REG_NUM 0x10
-
-/* Frequency setting */
-#define SLCR_LOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x4)
-#define SLCR_UNLOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x8)
-#define SLCR_GEM0_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x140)
-#define SLCR_GEM1_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x144)
-#ifdef PEEP
-#define SLCR_GEM_10M_CLK_CTRL_VALUE 0x00103031
-#define SLCR_GEM_100M_CLK_CTRL_VALUE 0x00103001
-#define SLCR_GEM_1G_CLK_CTRL_VALUE 0x00103011
-#endif
-#define SLCR_LOCK_KEY_VALUE 0x767B
-#define SLCR_UNLOCK_KEY_VALUE 0xDF0D
-#define SLCR_ADDR_GEM_RST_CTRL (XPS_SYS_CTRL_BASEADDR + 0x214)
-#define EMACPS_SLCR_DIV_MASK 0xFC0FC0FF
-
-#define EMAC0_BASE_ADDRESS 0xE000B000
-#define EMAC1_BASE_ADDRESS 0xE000C000
-
-static int detect_phy(XEmacPs *xemacpsp)
-{
- u16 phy_reg;
- u32 phy_addr;
-
- for (phy_addr = 31; phy_addr > 0; phy_addr--) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
- &phy_reg);
-
- if ((phy_reg != 0xFFFF) &&
- ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
- /* Found a valid PHY address */
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
- phy_addr));
- FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
- phy_detected = phy_addr;
- return phy_addr;
- }
- }
-
- FreeRTOS_printf( ("XEmacPs detect_phy: No PHY detected. Assuming a PHY at address 0\n" ) );
-
- /* default to zero */
- return 0;
-}
-
-#ifdef PEEP
-unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
-{
-
- u16 control;
- u16 status;
- u16 partner_capabilities;
- u16 partner_capabilities_1000;
- u16 phylinkspeed;
- u32 phy_addr = detect_phy(xemacpsp);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- ADVERTISE_1000);
- /* Advertise PHY speed of 100 and 10 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
- ADVERTISE_100_AND_10);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
- &control);
- control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
- IEEE_STAT_AUTONEGOTIATE_RESTART);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
- /* Read PHY control and status registers is successful. */
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
-
- if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
- IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
-
- while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
- &status);
- }
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
- &partner_capabilities);
-
- if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
- &partner_capabilities_1000);
- if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
- return 1000;
- }
-
- if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
- return 100;
- if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
- return 10;
-
- xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__);
- return 10;
-
- } else {
-
- /* Update TEMAC speed accordingly */
- if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
- /* Get commanded link speed */
- phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
-
- switch (phylinkspeed) {
- case (IEEE_CTRL_LINKSPEED_1000M):
- return 1000;
- case (IEEE_CTRL_LINKSPEED_100M):
- return 100;
- case (IEEE_CTRL_LINKSPEED_10M):
- return 10;
- default:
- xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
- __FUNCTION__, phylinkspeed);
- return 10;
- }
-
- } else {
-
- return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
-
- }
- }
-}
-
-#else /* Zynq */
-unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
-{
- u16 temp;
- u16 control;
- u16 status;
- u16 partner_capabilities;
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
-#else
- u32 phy_addr = detect_phy(xemacpsp);
-#endif
- xil_printf("Start PHY autonegotiation \r\n");
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
- control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
- control |= IEEE_ASYMMETRIC_PAUSE_MASK;
- control |= IEEE_PAUSE_MASK;
- control |= ADVERTISE_100;
- control |= ADVERTISE_10;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- &control);
- control |= ADVERTISE_1000;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- control);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
- &control);
- control |= (7 << 12); /* max number of gigabit attempts */
- control |= (1 << 11); /* enable downshift */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
- control);
-#endif
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
- control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- control &= IEEE_CTRL_ISOLATE_DISABLE;
-#endif
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- control |= IEEE_CTRL_RESET_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
-
- while (1) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- if (control & IEEE_CTRL_RESET_MASK)
- continue;
- else
- break;
- }
-#endif
- xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
- while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
- sleep(1);
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
- &temp);
- if (temp & IEEE_AUTONEG_ERROR_MASK) {
- xil_printf("Auto negotiation error \r\n");
- }
-#endif
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
- &status);
- }
-
- xil_printf("autonegotiation complete \r\n");
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
-#else
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
-#endif
-
-#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
- xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
- XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
- while(!(temp & 0x8000)) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
- }
- if((temp & 0x0C00) == 0x0800) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- return 1000;
- }
- else if((temp & 0x0C00) == 0x0400) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- return 100;
- }
- else if((temp & 0x0C00) == 0x0000) {
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- return 10;
- } else {
- xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
- XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
- XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
- return 10;
- }
-#else
- if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
- return 1000;
- else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
- return 100;
- else /* 10Mbps */
- return 10;
-#endif
-}
-#endif
-
-unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
-{
- u16 control;
- u32 phy_addr = detect_phy(xemacpsp);
-
- XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
- control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
- control |= IEEE_ASYMMETRIC_PAUSE_MASK;
- control |= IEEE_PAUSE_MASK;
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
-
- XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
- control &= ~IEEE_CTRL_LINKSPEED_1000M;
- control &= ~IEEE_CTRL_LINKSPEED_100M;
- control &= ~IEEE_CTRL_LINKSPEED_10M;
-
- if (speed == 1000) {
- control |= IEEE_CTRL_LINKSPEED_1000M;
- }
-
- else if (speed == 100) {
- control |= IEEE_CTRL_LINKSPEED_100M;
- /* Dont advertise PHY speed of 1000 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
- /* Dont advertise PHY speed of 10 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
- ADVERTISE_100);
- }
-
- else if (speed == 10) {
- control |= IEEE_CTRL_LINKSPEED_10M;
- /* Dont advertise PHY speed of 1000 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
- 0);
- /* Dont advertise PHY speed of 100 Mbps */
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
- ADVERTISE_10);
- }
-
- XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
- control | IEEE_CTRL_RESET_MASK);
- {
- volatile int wait;
- for (wait=0; wait < 100000; wait++);
- }
- return 0;
-}
-
-static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
-{
- volatile u32 slcrBaseAddress;
-#ifndef PEEP
- u32 SlcrDiv0;
- u32 SlcrDiv1=0;
- u32 SlcrTxClkCntrl;
-#endif
-
- *(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;
-
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
- slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
- } else {
- slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
- }
-#ifdef PEEP
- if (speed == 1000) {
- *(volatile unsigned int *)(slcrBaseAddress) =
- SLCR_GEM_1G_CLK_CTRL_VALUE;
- } else if (speed == 100) {
- *(volatile unsigned int *)(slcrBaseAddress) =
- SLCR_GEM_100M_CLK_CTRL_VALUE;
- } else {
- *(volatile unsigned int *)(slcrBaseAddress) =
- SLCR_GEM_10M_CLK_CTRL_VALUE;
- }
-#else
- if (speed == 1000) {
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
-#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
-#endif
- } else {
-#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
-#endif
- }
- } else if (speed == 100) {
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
-#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
-#endif
- } else {
-#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
-#endif
- }
- } else {
- if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
-#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
-#endif
- } else {
-#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
- SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
- SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
-#endif
- }
- }
- SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
- SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
- SlcrTxClkCntrl |= (SlcrDiv1 << 20);
- SlcrTxClkCntrl |= (SlcrDiv0 << 8);
- *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
-#endif
- *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
- return;
-}
-
-
-unsigned link_speed;
-unsigned Phy_Setup (XEmacPs *xemacpsp)
-{
- unsigned long conv_present = 0;
- unsigned long convspeeddupsetting = 0;
- unsigned long convphyaddr = 0;
-
-#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
- convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
- conv_present = 1;
-#else
-#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
- convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
- conv_present = 1;
-#endif
-#endif
-
-#ifdef ipconfigNIC_LINKSPEED_AUTODETECT
- link_speed = get_IEEE_phy_speed(xemacpsp);
- if (link_speed == 1000) {
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
- } else if (link_speed == 100) {
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
- } else {
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
- }
-#elif defined(ipconfigNIC_LINKSPEED1000)
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
- link_speed = 1000;
- configure_IEEE_phy_speed(xemacpsp, link_speed);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
- sleep(1);
-#elif defined(ipconfigNIC_LINKSPEED100)
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
- link_speed = 100;
- configure_IEEE_phy_speed(xemacpsp, link_speed);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
- sleep(1);
-#elif defined(ipconfigNIC_LINKSPEED10)
- SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
- link_speed = 10;
- configure_IEEE_phy_speed(xemacpsp, link_speed);
- convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
- sleep(1);
-#endif
- if (conv_present) {
- XEmacPs_PhyWrite(xemacpsp, convphyaddr,
- XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
- }
-
- xil_printf("link speed: %d\r\n", link_speed);
- return link_speed;
-}
-
+/*
+ * Copyright (c) 2007-2008, Advanced Micro Devices, Inc.
+ * 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.
+ * * 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 Advanced Micro Devices, Inc. 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 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 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Some portions copyright (c) 2010-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "Zynq/x_emacpsif.h"
+//#include "lwipopts.h"
+#include "xparameters_ps.h"
+#include "xparameters.h"
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+///* FreeRTOS+TCP includes. */
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+
+int phy_detected = 0;
+
+/*** IMPORTANT: Define PEEP in xemacpsif.h and sys_arch_raw.c
+ *** to run it on a PEEP board
+ ***/
+
+/* Advertisement control register. */
+#define ADVERTISE_10HALF 0x0020 /* Try for 10mbps half-duplex */
+#define ADVERTISE_10FULL 0x0040 /* Try for 10mbps full-duplex */
+#define ADVERTISE_100HALF 0x0080 /* Try for 100mbps half-duplex */
+#define ADVERTISE_100FULL 0x0100 /* Try for 100mbps full-duplex */
+
+#define ADVERTISE_100_AND_10 (ADVERTISE_10FULL | ADVERTISE_100FULL | \
+ ADVERTISE_10HALF | ADVERTISE_100HALF)
+#define ADVERTISE_100 (ADVERTISE_100FULL | ADVERTISE_100HALF)
+#define ADVERTISE_10 (ADVERTISE_10FULL | ADVERTISE_10HALF)
+
+#define ADVERTISE_1000 0x0300
+
+
+//#define PHY_REG_00_BMCR 0x00 // Basic mode control register
+//#define PHY_REG_01_BMSR 0x01 // Basic mode status register
+//#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
+//#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
+//#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
+
+#define IEEE_CONTROL_REG_OFFSET 0
+#define IEEE_STATUS_REG_OFFSET 1
+#define IEEE_AUTONEGO_ADVERTISE_REG 4
+#define IEEE_PARTNER_ABILITIES_1_REG_OFFSET 5
+#define IEEE_1000_ADVERTISE_REG_OFFSET 9
+#define IEEE_PARTNER_ABILITIES_3_REG_OFFSET 10
+#define IEEE_COPPER_SPECIFIC_CONTROL_REG 16
+#define IEEE_SPECIFIC_STATUS_REG 17
+#define IEEE_COPPER_SPECIFIC_STATUS_REG_2 19
+#define IEEE_CONTROL_REG_MAC 21
+#define IEEE_PAGE_ADDRESS_REGISTER 22
+
+
+#define IEEE_CTRL_1GBPS_LINKSPEED_MASK 0x2040
+#define IEEE_CTRL_LINKSPEED_MASK 0x0040
+#define IEEE_CTRL_LINKSPEED_1000M 0x0040
+#define IEEE_CTRL_LINKSPEED_100M 0x2000
+#define IEEE_CTRL_LINKSPEED_10M 0x0000
+#define IEEE_CTRL_RESET_MASK 0x8000
+#define IEEE_CTRL_AUTONEGOTIATE_ENABLE 0x1000
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#define IEEE_CTRL_RESET 0x9140
+#define IEEE_CTRL_ISOLATE_DISABLE 0xFBFF
+#endif
+#define IEEE_STAT_AUTONEGOTIATE_CAPABLE 0x0008
+#define IEEE_STAT_AUTONEGOTIATE_COMPLETE 0x0020
+#define IEEE_STAT_AUTONEGOTIATE_RESTART 0x0200
+#define IEEE_STAT_1GBPS_EXTENSIONS 0x0100
+#define IEEE_AN1_ABILITY_MASK 0x1FE0
+#define IEEE_AN3_ABILITY_MASK_1GBPS 0x0C00
+#define IEEE_AN1_ABILITY_MASK_100MBPS 0x0380
+#define IEEE_AN1_ABILITY_MASK_10MBPS 0x0060
+#define IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK 0x0030
+
+#define IEEE_ASYMMETRIC_PAUSE_MASK 0x0800
+#define IEEE_PAUSE_MASK 0x0400
+#define IEEE_AUTONEG_ERROR_MASK 0x8000
+
+#define PHY_DETECT_REG 1
+#define PHY_DETECT_MASK 0x1808
+
+#define XEMACPS_GMII2RGMII_SPEED1000_FD 0x140
+#define XEMACPS_GMII2RGMII_SPEED100_FD 0x2100
+#define XEMACPS_GMII2RGMII_SPEED10_FD 0x100
+#define XEMACPS_GMII2RGMII_REG_NUM 0x10
+
+/* Frequency setting */
+#define SLCR_LOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x4)
+#define SLCR_UNLOCK_ADDR (XPS_SYS_CTRL_BASEADDR + 0x8)
+#define SLCR_GEM0_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x140)
+#define SLCR_GEM1_CLK_CTRL_ADDR (XPS_SYS_CTRL_BASEADDR + 0x144)
+#ifdef PEEP
+#define SLCR_GEM_10M_CLK_CTRL_VALUE 0x00103031
+#define SLCR_GEM_100M_CLK_CTRL_VALUE 0x00103001
+#define SLCR_GEM_1G_CLK_CTRL_VALUE 0x00103011
+#endif
+#define SLCR_LOCK_KEY_VALUE 0x767B
+#define SLCR_UNLOCK_KEY_VALUE 0xDF0D
+#define SLCR_ADDR_GEM_RST_CTRL (XPS_SYS_CTRL_BASEADDR + 0x214)
+#define EMACPS_SLCR_DIV_MASK 0xFC0FC0FF
+
+#define EMAC0_BASE_ADDRESS 0xE000B000
+#define EMAC1_BASE_ADDRESS 0xE000C000
+
+static int detect_phy(XEmacPs *xemacpsp)
+{
+ u16 phy_reg;
+ u32 phy_addr;
+
+ for (phy_addr = 31; phy_addr > 0; phy_addr--) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, PHY_DETECT_REG,
+ &phy_reg);
+
+ if ((phy_reg != 0xFFFF) &&
+ ((phy_reg & PHY_DETECT_MASK) == PHY_DETECT_MASK)) {
+ /* Found a valid PHY address */
+ FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected at address %d.\r\n",
+ phy_addr));
+ FreeRTOS_printf( ("XEmacPs detect_phy: PHY detected.\n" ) );
+ phy_detected = phy_addr;
+ return phy_addr;
+ }
+ }
+
+ FreeRTOS_printf( ("XEmacPs detect_phy: No PHY detected. Assuming a PHY at address 0\n" ) );
+
+ /* default to zero */
+ return 0;
+}
+
+#ifdef PEEP
+unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
+{
+
+ u16 control;
+ u16 status;
+ u16 partner_capabilities;
+ u16 partner_capabilities_1000;
+ u16 phylinkspeed;
+ u32 phy_addr = detect_phy(xemacpsp);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ ADVERTISE_1000);
+ /* Advertise PHY speed of 100 and 10 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
+ ADVERTISE_100_AND_10);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
+ &control);
+ control |= (IEEE_CTRL_AUTONEGOTIATE_ENABLE |
+ IEEE_STAT_AUTONEGOTIATE_RESTART);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
+
+ /* Read PHY control and status registers is successful. */
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
+
+ if ((control & IEEE_CTRL_AUTONEGOTIATE_ENABLE) && (status &
+ IEEE_STAT_AUTONEGOTIATE_CAPABLE)) {
+
+ while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
+ &status);
+ }
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_1_REG_OFFSET,
+ &partner_capabilities);
+
+ if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_PARTNER_ABILITIES_3_REG_OFFSET,
+ &partner_capabilities_1000);
+ if (partner_capabilities_1000 & IEEE_AN3_ABILITY_MASK_1GBPS)
+ return 1000;
+ }
+
+ if (partner_capabilities & IEEE_AN1_ABILITY_MASK_100MBPS)
+ return 100;
+ if (partner_capabilities & IEEE_AN1_ABILITY_MASK_10MBPS)
+ return 10;
+
+ xil_printf("%s: unknown PHY link speed, setting TEMAC speed to be 10 Mbps\r\n",
+ __FUNCTION__);
+ return 10;
+
+ } else {
+
+ /* Update TEMAC speed accordingly */
+ if (status & IEEE_STAT_1GBPS_EXTENSIONS) {
+ /* Get commanded link speed */
+ phylinkspeed = control & IEEE_CTRL_1GBPS_LINKSPEED_MASK;
+
+ switch (phylinkspeed) {
+ case (IEEE_CTRL_LINKSPEED_1000M):
+ return 1000;
+ case (IEEE_CTRL_LINKSPEED_100M):
+ return 100;
+ case (IEEE_CTRL_LINKSPEED_10M):
+ return 10;
+ default:
+ xil_printf("%s: unknown PHY link speed (%d), setting TEMAC speed to be 10 Mbps\r\n",
+ __FUNCTION__, phylinkspeed);
+ return 10;
+ }
+
+ } else {
+
+ return (control & IEEE_CTRL_LINKSPEED_MASK) ? 100 : 10;
+
+ }
+ }
+}
+
+#else /* Zynq */
+unsigned get_IEEE_phy_speed(XEmacPs *xemacpsp)
+{
+ u16 temp;
+ u16 control;
+ u16 status;
+ u16 partner_capabilities;
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+ u32 phy_addr = XPAR_PCSPMA_SGMII_PHYADDR;
+#else
+ u32 phy_addr = detect_phy(xemacpsp);
+#endif
+ xil_printf("Start PHY autonegotiation \r\n");
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
+ control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
+ control |= IEEE_ASYMMETRIC_PAUSE_MASK;
+ control |= IEEE_PAUSE_MASK;
+ control |= ADVERTISE_100;
+ control |= ADVERTISE_10;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ &control);
+ control |= ADVERTISE_1000;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ control);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
+ &control);
+ control |= (7 << 12); /* max number of gigabit attempts */
+ control |= (1 << 11); /* enable downshift */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_CONTROL_REG,
+ control);
+#endif
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ control |= IEEE_CTRL_AUTONEGOTIATE_ENABLE;
+ control |= IEEE_STAT_AUTONEGOTIATE_RESTART;
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+ control &= IEEE_CTRL_ISOLATE_DISABLE;
+#endif
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
+
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ control |= IEEE_CTRL_RESET_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, control);
+
+ while (1) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ if (control & IEEE_CTRL_RESET_MASK)
+ continue;
+ else
+ break;
+ }
+#endif
+ xil_printf("Waiting for PHY to complete autonegotiation.\r\n");
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET, &status);
+ while ( !(status & IEEE_STAT_AUTONEGOTIATE_COMPLETE) ) {
+ sleep(1);
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_COPPER_SPECIFIC_STATUS_REG_2,
+ &temp);
+ if (temp & IEEE_AUTONEG_ERROR_MASK) {
+ xil_printf("Auto negotiation error \r\n");
+ }
+#endif
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_STATUS_REG_OFFSET,
+ &status);
+ }
+
+ xil_printf("autonegotiation complete \r\n");
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+#else
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_SPECIFIC_STATUS_REG, &partner_capabilities);
+#endif
+
+#if XPAR_GIGE_PCS_PMA_CORE_PRESENT == 1
+ xil_printf("Waiting for Link to be up; Polling for SGMII core Reg \r\n");
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
+ while(!(temp & 0x8000)) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 5, &temp);
+ }
+ if((temp & 0x0C00) == 0x0800) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ return 1000;
+ }
+ else if((temp & 0x0C00) == 0x0400) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ return 100;
+ }
+ else if((temp & 0x0C00) == 0x0000) {
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ return 10;
+ } else {
+ xil_printf("get_IEEE_phy_speed(): Invalid speed bit value, Deafulting to Speed = 10 Mbps\r\n");
+ XEmacPs_PhyRead(xemacpsp, phy_addr, 0, &temp);
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, 0, 0x0100);
+ return 10;
+ }
+#else
+ if ( ((partner_capabilities >> 14) & 3) == 2)/* 1000Mbps */
+ return 1000;
+ else if ( ((partner_capabilities >> 14) & 3) == 1)/* 100Mbps */
+ return 100;
+ else /* 10Mbps */
+ return 10;
+#endif
+}
+#endif
+
+unsigned configure_IEEE_phy_speed(XEmacPs *xemacpsp, unsigned speed)
+{
+ u16 control;
+ u32 phy_addr = detect_phy(xemacpsp);
+
+ XEmacPs_PhyWrite(xemacpsp,phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 2);
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, &control);
+ control |= IEEE_RGMII_TXRX_CLOCK_DELAYED_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_MAC, control);
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_PAGE_ADDRESS_REGISTER, 0);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, &control);
+ control |= IEEE_ASYMMETRIC_PAUSE_MASK;
+ control |= IEEE_PAUSE_MASK;
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG, control);
+
+ XEmacPs_PhyRead(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET, &control);
+ control &= ~IEEE_CTRL_LINKSPEED_1000M;
+ control &= ~IEEE_CTRL_LINKSPEED_100M;
+ control &= ~IEEE_CTRL_LINKSPEED_10M;
+
+ if (speed == 1000) {
+ control |= IEEE_CTRL_LINKSPEED_1000M;
+ }
+
+ else if (speed == 100) {
+ control |= IEEE_CTRL_LINKSPEED_100M;
+ /* Dont advertise PHY speed of 1000 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET, 0);
+ /* Dont advertise PHY speed of 10 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
+ ADVERTISE_100);
+ }
+
+ else if (speed == 10) {
+ control |= IEEE_CTRL_LINKSPEED_10M;
+ /* Dont advertise PHY speed of 1000 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_1000_ADVERTISE_REG_OFFSET,
+ 0);
+ /* Dont advertise PHY speed of 100 Mbps */
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_AUTONEGO_ADVERTISE_REG,
+ ADVERTISE_10);
+ }
+
+ XEmacPs_PhyWrite(xemacpsp, phy_addr, IEEE_CONTROL_REG_OFFSET,
+ control | IEEE_CTRL_RESET_MASK);
+ {
+ volatile int wait;
+ for (wait=0; wait < 100000; wait++);
+ }
+ return 0;
+}
+
+static void SetUpSLCRDivisors(int mac_baseaddr, int speed)
+{
+ volatile u32 slcrBaseAddress;
+#ifndef PEEP
+ u32 SlcrDiv0;
+ u32 SlcrDiv1=0;
+ u32 SlcrTxClkCntrl;
+#endif
+
+ *(volatile unsigned int *)(SLCR_UNLOCK_ADDR) = SLCR_UNLOCK_KEY_VALUE;
+
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+ slcrBaseAddress = SLCR_GEM0_CLK_CTRL_ADDR;
+ } else {
+ slcrBaseAddress = SLCR_GEM1_CLK_CTRL_ADDR;
+ }
+#ifdef PEEP
+ if (speed == 1000) {
+ *(volatile unsigned int *)(slcrBaseAddress) =
+ SLCR_GEM_1G_CLK_CTRL_VALUE;
+ } else if (speed == 100) {
+ *(volatile unsigned int *)(slcrBaseAddress) =
+ SLCR_GEM_100M_CLK_CTRL_VALUE;
+ } else {
+ *(volatile unsigned int *)(slcrBaseAddress) =
+ SLCR_GEM_10M_CLK_CTRL_VALUE;
+ }
+#else
+ if (speed == 1000) {
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_1000MBPS_DIV1;
+#endif
+ } else {
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_1000MBPS_DIV1;
+#endif
+ }
+ } else if (speed == 100) {
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_100MBPS_DIV1;
+#endif
+ } else {
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_100MBPS_DIV1;
+#endif
+ }
+ } else {
+ if ((unsigned long)mac_baseaddr == EMAC0_BASE_ADDRESS) {
+#ifdef XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_0_ENET_SLCR_10MBPS_DIV1;
+#endif
+ } else {
+#ifdef XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0
+ SlcrDiv0 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV0;
+ SlcrDiv1 = XPAR_PS7_ETHERNET_1_ENET_SLCR_10MBPS_DIV1;
+#endif
+ }
+ }
+ SlcrTxClkCntrl = *(volatile unsigned int *)(slcrBaseAddress);
+ SlcrTxClkCntrl &= EMACPS_SLCR_DIV_MASK;
+ SlcrTxClkCntrl |= (SlcrDiv1 << 20);
+ SlcrTxClkCntrl |= (SlcrDiv0 << 8);
+ *(volatile unsigned int *)(slcrBaseAddress) = SlcrTxClkCntrl;
+#endif
+ *(volatile unsigned int *)(SLCR_LOCK_ADDR) = SLCR_LOCK_KEY_VALUE;
+ return;
+}
+
+
+unsigned link_speed;
+unsigned Phy_Setup (XEmacPs *xemacpsp)
+{
+ unsigned long conv_present = 0;
+ unsigned long convspeeddupsetting = 0;
+ unsigned long convphyaddr = 0;
+
+#ifdef XPAR_GMII2RGMIICON_0N_ETH0_ADDR
+ convphyaddr = XPAR_GMII2RGMIICON_0N_ETH0_ADDR;
+ conv_present = 1;
+#else
+#ifdef XPAR_GMII2RGMIICON_0N_ETH1_ADDR
+ convphyaddr = XPAR_GMII2RGMIICON_0N_ETH1_ADDR;
+ conv_present = 1;
+#endif
+#endif
+
+#ifdef ipconfigNIC_LINKSPEED_AUTODETECT
+ link_speed = get_IEEE_phy_speed(xemacpsp);
+ if (link_speed == 1000) {
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
+ } else if (link_speed == 100) {
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
+ } else {
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
+ }
+#elif defined(ipconfigNIC_LINKSPEED1000)
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,1000);
+ link_speed = 1000;
+ configure_IEEE_phy_speed(xemacpsp, link_speed);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED1000_FD;
+ sleep(1);
+#elif defined(ipconfigNIC_LINKSPEED100)
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,100);
+ link_speed = 100;
+ configure_IEEE_phy_speed(xemacpsp, link_speed);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED100_FD;
+ sleep(1);
+#elif defined(ipconfigNIC_LINKSPEED10)
+ SetUpSLCRDivisors(xemacpsp->Config.BaseAddress,10);
+ link_speed = 10;
+ configure_IEEE_phy_speed(xemacpsp, link_speed);
+ convspeeddupsetting = XEMACPS_GMII2RGMII_SPEED10_FD;
+ sleep(1);
+#endif
+ if (conv_present) {
+ XEmacPs_PhyWrite(xemacpsp, convphyaddr,
+ XEMACPS_GMII2RGMII_REG_NUM, convspeeddupsetting);
+ }
+
+ xil_printf("link speed: %d\r\n", link_speed);
+ return link_speed;
+}
+
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h
index bb5178346..1d8fede15 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/Zynq/x_topology.h
@@ -1,46 +1,46 @@
-/*
- * Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
- *
- * Xilinx, Inc.
- * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
- * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
- * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
- * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
- * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
- * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
- * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
- * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
- * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
- * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
- * AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- */
-
-#ifndef __XTOPOLOGY_H_
-#define __XTOPOLOGY_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
-
-struct xtopology_t {
- unsigned emac_baseaddr;
- enum xemac_types emac_type;
- unsigned intc_baseaddr;
- unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
- unsigned scugic_baseaddr; /* valid only for Zynq */
- unsigned scugic_emac_intr; /* valid only for GEM */
-};
-
-extern int x_topology_n_emacs;
-extern struct xtopology_t x_topology[];
-
-int x_topology_find_index(unsigned base);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
+/*
+ * Copyright (c) 2007-2013 Xilinx, Inc. All rights reserved.
+ *
+ * Xilinx, Inc.
+ * XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
+ * COURTESY TO YOU. BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
+ * ONE POSSIBLE IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
+ * STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
+ * IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
+ * FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
+ * XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
+ * THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
+ * ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
+ * FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
+ * AND FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ */
+
+#ifndef __XTOPOLOGY_H_
+#define __XTOPOLOGY_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum xemac_types { xemac_type_unknown = -1, xemac_type_xps_emaclite, xemac_type_xps_ll_temac, xemac_type_axi_ethernet, xemac_type_emacps };
+
+struct xtopology_t {
+ unsigned emac_baseaddr;
+ enum xemac_types emac_type;
+ unsigned intc_baseaddr;
+ unsigned intc_emac_intr; /* valid only for xemac_type_xps_emaclite */
+ unsigned scugic_baseaddr; /* valid only for Zynq */
+ unsigned scugic_emac_intr; /* valid only for GEM */
+};
+
+extern int x_topology_n_emacs;
+extern struct xtopology_t x_topology[];
+
+int x_topology_find_index(unsigned base);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c
index aa0a646b4..4692c12c4 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/board_family/NetworkInterface.c
@@ -1,63 +1,63 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "list.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- /* FIX ME. */
- return pdFALSE;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
-{
- /* FIX ME. */
- return pdFALSE;
-}
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
- /* FIX ME. */
-}
-
-BaseType_t xGetPhyLinkStatus( void )
-{
- /* FIX ME. */
- return pdFALSE;
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ /* FIX ME. */
+ return pdFALSE;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
+{
+ /* FIX ME. */
+ return pdFALSE;
+}
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+ /* FIX ME. */
+}
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+ /* FIX ME. */
+ return pdFALSE;
} \ No newline at end of file
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
index 0b34edf7b..96503f457 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/esp32/NetworkInterface.c
@@ -1,193 +1,135 @@
-// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_DNS.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "esp_log.h"
-#include "esp_wifi.h"
-#include "esp_wifi_internal.h"
-#include "tcpip_adapter.h"
-
-enum if_state_t {
- INTERFACE_DOWN = 0,
- INTERFACE_UP,
-};
-
-static const char *TAG = "NetInterface";
-volatile static uint32_t xInterfaceState = INTERFACE_DOWN;
-
-#if ( ipconfigHAS_PRINTF != 0 )
- static void prvMonitorResources();
-#endif
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- static BaseType_t xMACAdrInitialized = pdFALSE;
- uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ];
-
- if (xInterfaceState == INTERFACE_UP) {
- if (xMACAdrInitialized == pdFALSE) {
- esp_wifi_get_mac(ESP_IF_WIFI_STA, ucMACAddress);
- FreeRTOS_UpdateMACAddress(ucMACAddress);
- xMACAdrInitialized = pdTRUE;
- }
- return pdTRUE;
- }
- return pdFALSE;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
-{
- if (pxNetworkBuffer == NULL || pxNetworkBuffer->pucEthernetBuffer == NULL || pxNetworkBuffer->xDataLength == 0) {
- ESP_LOGE(TAG, "Invalid params");
- return pdFALSE;
- }
-
- esp_err_t ret;
- if (xInterfaceState == INTERFACE_DOWN) {
- ESP_LOGD(TAG, "Interface down");
- ret = ESP_FAIL;
- } else {
- ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
- if (ret != ESP_OK) {
- ESP_LOGE(TAG, "Failed to tx buffer %p, len %d, err %d", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
- }
- }
-
-#if ( ipconfigHAS_PRINTF != 0 )
- prvMonitorResources();
-#endif
- if (xReleaseAfterSend == pdTRUE) {
- vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
- }
-
- return ret == ESP_OK ? pdTRUE : pdFALSE;
-}
-
-void vNetworkNotifyIFDown()
-{
- IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
- if (xInterfaceState != INTERFACE_DOWN) {
- xInterfaceState = INTERFACE_DOWN;
- xSendEventStructToIPTask( &xRxEvent, 0 );
- }
-}
-
-void vNetworkNotifyIFUp()
-{
- xInterfaceState = INTERFACE_UP;
-}
-
-esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
-{
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
- const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-
-#if ( ipconfigHAS_PRINTF != 0 )
- prvMonitorResources();
-#endif
-
- if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
- ESP_LOGD(TAG, "Dropping packet");
- esp_wifi_internal_free_rx_buffer(eb);
- return ESP_OK;
- }
-
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
- if (pxNetworkBuffer != NULL) {
-
- /* Set the packet size, in case a larger buffer was returned. */
- pxNetworkBuffer->xDataLength = len;
-
- /* Copy the packet data. */
- memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
- xRxEvent.pvData = (void *) pxNetworkBuffer;
-
- if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
- ESP_LOGE(TAG, "Failed to enqueue packet to network stack %p, len %d", buffer, len);
- vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
- return ESP_FAIL;
- }
- esp_wifi_internal_free_rx_buffer(eb);
- return ESP_OK;
- } else {
- ESP_LOGE(TAG, "Failed to get buffer descriptor");
- return ESP_FAIL;
- }
-}
-
-#if ( ipconfigHAS_PRINTF != 0 )
- static void prvMonitorResources()
- {
- static UBaseType_t uxLastMinBufferCount = 0u;
- static UBaseType_t uxCurrentBufferCount = 0u;
- static size_t uxMinLastSize = 0uL;
- size_t uxMinSize;
-
- uxCurrentBufferCount = uxGetMinimumFreeNetworkBuffers();
-
- if( uxLastMinBufferCount != uxCurrentBufferCount )
- {
- /* The logging produced below may be helpful
- * while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentBufferCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentBufferCount ) );
- }
-
- uxMinSize = xPortGetMinimumEverFreeHeapSize();
-
- if( uxMinLastSize != uxMinSize )
- {
- uxMinLastSize = uxMinSize;
- FreeRTOS_printf( ( "Heap: current %lu lowest %lu\n", xPortGetFreeHeapSize(), uxMinSize ) );
- }
-
- #if ( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- static UBaseType_t uxLastMinQueueSpace = 0;
- UBaseType_t uxCurrentCount = 0u;
-
- uxCurrentCount = uxGetMinimumIPQueueSpace();
-
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- * while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
- }
-#endif /* ( ipconfigHAS_PRINTF != 0 ) */
-/*-----------------------------------------------------------*/
+// Copyright 2018 Espressif Systems (Shanghai) PTE LTD
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_DNS.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "esp_log.h"
+#include "esp_wifi.h"
+#include "esp_wifi_internal.h"
+#include "tcpip_adapter.h"
+
+enum if_state_t {
+ INTERFACE_DOWN = 0,
+ INTERFACE_UP,
+};
+
+static const char *TAG = "NetInterface";
+volatile static uint32_t xInterfaceState = INTERFACE_DOWN;
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ static BaseType_t xMACAdrInitialized = pdFALSE;
+ uint8_t ucMACAddress[ ipMAC_ADDRESS_LENGTH_BYTES ];
+
+ if (xInterfaceState == INTERFACE_UP) {
+ if (xMACAdrInitialized == pdFALSE) {
+ esp_wifi_get_mac(ESP_IF_WIFI_STA, ucMACAddress);
+ FreeRTOS_UpdateMACAddress(ucMACAddress);
+ xMACAdrInitialized = pdTRUE;
+ }
+ return pdTRUE;
+ }
+ return pdFALSE;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
+{
+ if (pxNetworkBuffer == NULL || pxNetworkBuffer->pucEthernetBuffer == NULL || pxNetworkBuffer->xDataLength == 0) {
+ ESP_LOGE(TAG, "Invalid params");
+ return pdFALSE;
+ }
+
+ esp_err_t ret;
+ if (xInterfaceState == INTERFACE_DOWN) {
+ ESP_LOGD(TAG, "Interface down");
+ ret = ESP_FAIL;
+ } else {
+ ret = esp_wifi_internal_tx(ESP_IF_WIFI_STA, pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength);
+ if (ret != ESP_OK) {
+ ESP_LOGE(TAG, "Failed to tx buffer %p, len %d, err %d", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
+ }
+ }
+
+ if (xReleaseAfterSend == pdTRUE) {
+ vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
+ }
+
+ return ret == ESP_OK ? pdTRUE : pdFALSE;
+}
+
+void vNetworkNotifyIFDown()
+{
+ IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
+ if (xInterfaceState != INTERFACE_DOWN) {
+ xInterfaceState = INTERFACE_DOWN;
+ xSendEventStructToIPTask( &xRxEvent, 0 );
+ }
+}
+
+void vNetworkNotifyIFUp()
+{
+ xInterfaceState = INTERFACE_UP;
+}
+
+esp_err_t wlanif_input(void *netif, void *buffer, uint16_t len, void *eb)
+{
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+ const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+
+ if( eConsiderFrameForProcessing( buffer ) != eProcessBuffer ) {
+ ESP_LOGD(TAG, "Dropping packet");
+ esp_wifi_internal_free_rx_buffer(eb);
+ return ESP_OK;
+ }
+
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(len, xDescriptorWaitTime);
+ if (pxNetworkBuffer != NULL) {
+
+ /* Set the packet size, in case a larger buffer was returned. */
+ pxNetworkBuffer->xDataLength = len;
+
+ /* Copy the packet data. */
+ memcpy(pxNetworkBuffer->pucEthernetBuffer, buffer, len);
+ xRxEvent.pvData = (void *) pxNetworkBuffer;
+
+ if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
+ ESP_LOGE(TAG, "Failed to enqueue packet to network stack %p, len %d", buffer, len);
+ vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
+ return ESP_FAIL;
+ }
+ esp_wifi_internal_free_rx_buffer(eb);
+ return ESP_OK;
+ } else {
+ ESP_LOGE(TAG, "Failed to get buffer descriptor");
+ return ESP_FAIL;
+ }
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/include/phyHandling.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/include/phyHandling.h
deleted file mode 100644
index 9e8a11387..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/include/phyHandling.h
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Handling of Ethernet PHY's
- * PHY's communicate with an EMAC either through
- * a Media-Independent Interface (MII), or a Reduced Media-Independent Interface (RMII).
- * The EMAC can poll for PHY ports on 32 different addresses. Each of the PHY ports
- * shall be treated independently.
- *
- */
-
-#ifndef PHYHANDLING_H
-
-#define PHYHANDLING_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-
-#ifndef ipconfigPHY_MAX_PORTS
- /* There can be at most 32 PHY ports, but in most cases there are 4 or less. */
- #define ipconfigPHY_MAX_PORTS 4
-#endif
-
-/* A generic user-provided function that reads from the PHY-port at 'xAddress'( 0-based ). A 16-bit value shall be stored in
- '*pulValue'. xRegister is the register number ( 0 .. 31 ). In fact all PHY registers are 16-bit.
- Return non-zero in case the action failed. */
-typedef BaseType_t ( *xApplicationPhyReadHook_t )( BaseType_t xAddress, BaseType_t xRegister, uint32_t *pulValue );
-
-/* A generic user-provided function that writes 'ulValue' to the
- PHY-port at 'xAddress' ( 0-based ). xRegister is the register number ( 0 .. 31 ).
- Return non-zero in case the action failed. */
-typedef BaseType_t ( *xApplicationPhyWriteHook_t )( BaseType_t xAddress, BaseType_t xRegister, uint32_t ulValue );
-
-typedef struct xPhyProperties
-{
- uint8_t ucSpeed;
- uint8_t ucMDI_X; /* MDI-X : Medium Dependent Interface - Crossover */
- uint8_t ucDuplex;
- uint8_t ucSpare;
-} PhyProperties_t;
-
-typedef struct xEthernetPhy
-{
- xApplicationPhyReadHook_t fnPhyRead;
- xApplicationPhyWriteHook_t fnPhyWrite;
- uint32_t ulPhyIDs[ ipconfigPHY_MAX_PORTS ];
- uint8_t ucPhyIndexes[ ipconfigPHY_MAX_PORTS ];
- TimeOut_t xLinkStatusTimer;
- TickType_t xLinkStatusRemaining;
- BaseType_t xPortCount;
- uint32_t ulBCRValue;
- uint32_t ulACRValue;
- uint32_t ulLinkStatusMask;
- PhyProperties_t xPhyPreferences;
- PhyProperties_t xPhyProperties;
-} EthernetPhy_t;
-
-/* Some defines used internally here to indicate preferences about speed, MDIX
-(wired direct or crossed), and duplex (half or full). */
-
-/* Values for PhyProperties_t::ucSpeed : */
-#define PHY_SPEED_10 1
-#define PHY_SPEED_100 2
-#define PHY_SPEED_AUTO 3
-
-/* Values for PhyProperties_t::ucMDI_X : */
-#define PHY_MDIX_DIRECT 1
-#define PHY_MDIX_CROSSED 2
-#define PHY_MDIX_AUTO 3
-
-/* Values for PhyProperties_t::ucDuplex : */
-#define PHY_DUPLEX_HALF 1
-#define PHY_DUPLEX_FULL 2
-#define PHY_DUPLEX_AUTO 3
-
-/* ID's of supported PHY's : */
-#define PHY_ID_LAN8742A 0x0007c130
-#define PHY_ID_LAN8720 0x0007c0f0
-
-#define PHY_ID_KSZ8041 0x000010A1
-#define PHY_ID_KSZ8051 0x000010A1
-#define PHY_ID_KSZ8081 0x000010A1
-
-#define PHY_ID_KSZ8863 0x00221430
-#define PHY_ID_KSZ8081MNXIA 0x00221560
-
-#define PHY_ID_DP83848I 0x20005C90
-
-
-/* Initialise the struct and assign a PHY-read and -write function. */
-void vPhyInitialise( EthernetPhy_t *pxPhyObject, xApplicationPhyReadHook_t fnPhyRead, xApplicationPhyWriteHook_t fnPhyWrite );
-
-/* Discover all PHY's connected by polling 32 indexes ( zero-based ) */
-BaseType_t xPhyDiscover( EthernetPhy_t *pxPhyObject );
-
-/* Send a reset command to the connected PHY ports and send configuration. */
-BaseType_t xPhyConfigure( EthernetPhy_t *pxPhyObject, const PhyProperties_t *pxPhyProperties );
-
-/* Give a command to start auto negotiation on a set of PHY port's. */
-BaseType_t xPhyStartAutoNegotiation( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask );
-
-/* Do not use auto negotiation but use predefined values from 'pxPhyObject->xPhyPreferences'. */
-BaseType_t xPhyFixedValue( EthernetPhy_t *pxPhyObject, uint32_t ulPhyMask );
-
-/* Check the current Link Status.
-'xHadReception' : make this true if a packet has been received since the
-last call to this function. */
-BaseType_t xPhyCheckLinkStatus( EthernetPhy_t *pxPhyObject, BaseType_t xHadReception );
-
-/* Get the bitmask of a given 'EthernetPhy_t'. */
-#define xPhyGetMask( pxPhyObject ) \
- ( ( ( ( uint32_t ) 1u ) << ( pxPhyObject )->xPortCount ) - 1u )
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c
index 544e5ba09..e4ae1168f 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/NetworkInterface.c
@@ -1,1272 +1,1272 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* Standard includes. */
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdarg.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "queue.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "sam4e_xplained_pro.h"
-#include "hr_gettime.h"
-#include "conf_eth.h"
-#include "ksz8851snl.h"
-#include "ksz8851snl_reg.h"
-
-/* Some files from the Atmel Software Framework */
-#include <sysclk.h>
-#include <pdc/pdc.h>
-#include <spi/spi.h>
-
-/*
- Sending a packet:
-
- 1) Called by UP-task, add buffer to the TX-list:
- xNetworkInterfaceOutput()
- tx_buffers[ us_tx_head ] = pxNetworkBuffer;
- tx_busy[ us_tx_head ] = pdTRUE;
- us_tx_head++;
-
- 2) Called by EMAC-Task: start SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_IDLE )
- {
- if( ( tx_busy[ us_tx_tail ] != pdFALSE ) &&
- ( us_pending_frame == 0 ) &&
- ( ul_had_intn_interrupt == 0 ) )
- {
- // disable all interrupts.
- ksz8851_reg_write( REG_INT_MASK, 0 );
- Bring KSZ8851SNL_CSN_GPIO low
- ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
- ul_spi_pdc_status = SPI_PDC_TX_START;
- tx_cur_buffer = pxNetworkBuffer;
- }
- }
- 3) Wait for SPI RXBUFF interrupt
- SPI_Handler()
- if( ul_spi_pdc_status == SPI_PDC_TX_START )
- {
- if( SPI_Status & SPI_SR_RXBUFF )
- {
- ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
- }
- }
-
- 4) Called by EMAC-Task: finish SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_TX_COMPLETE )
- {
- ul_spi_pdc_status = SPI_PDC_IDLE;
- Bring KSZ8851SNL_CSN_GPIO high
- // TX step12: disable TXQ write access.
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
- // TX step12.1: enqueue frame in TXQ.
- ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
-
- // RX step13: enable INT_RX flag.
- ksz8851_reg_write( REG_INT_MASK, INT_RX );
-
- // Buffer sent, free the corresponding buffer and mark descriptor as owned by software.
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- tx_buffers[ us_tx_tail ] = NULL;
- tx_busy[ us_tx_tail ] = pdFALSE;
- us_tx_tail++
- }
-
- Receiving a packet:
-
- 1) Wait for a INTN interrupt
- INTN_Handler()
- ul_had_intn_interrupt = 1
- vTaskNotifyGiveFromISR(); // Wake up the EMAC task
-
- 2) Called by EMAC-Task: check for new fragments and start SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_IDLE )
- {
- if( ( ul_had_intn_interrupt != 0 ) || ( us_pending_frame > 0 ) )
- {
- if( us_pending_frame == 0 )
- {
- us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
- if( us_pending_frame == 0 )
- {
- break;
- }
- }
- // RX step2: disable all interrupts.
- ksz8851_reg_write( REG_INT_MASK, 0 );
- Check if there is a valid packet: REG_RX_FHR_STATUS
- Read the length of the next fragment: REG_RX_FHR_BYTE_CNT
- ul_spi_pdc_status = SPI_PDC_RX_START;
- gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);
- // Start SPI data transfer
- ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer, xReadLength );
- }
- }
-
- 3) Wait for SPI RXBUFF interrupt
- SPI_Handler()
- if( ul_spi_pdc_status == SPI_PDC_RX_START:
- {
- if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
- {
- // Transfer complete, disable SPI RXBUFF interrupt.
- spi_disable_interrupt( KSZ8851SNL_SPI, SPI_IDR_RXBUFF );
-
- ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
- }
- }
- }
-
- 4) Finish SPI transfer
- ksz8851snl_update()
- if( ul_spi_pdc_status == SPI_PDC_RX_COMPLETE )
- {
- ul_spi_pdc_status = SPI_PDC_IDLE;
- Bring KSZ8851SNL_CSN_GPIO high
- // RX step21: end RXQ read access.
- ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
- // RX step22-23: update frame count to be read.
- us_pending_frame--
- // RX step24: enable INT_RX flag if transfer complete.
- if( us_pending_frame == 0 )
- {
- // Allow more RX interrupts.
- ksz8851_reg_write( REG_INT_MASK, INT_RX );
- }
-
- // Mark descriptor ready to be read.
- rx_ready[ rxHead ] = pdTRUE;
- rxHead++
- }
-*/
-
-#define PHY_REG_00_BMCR 0x00 // Basic mode control register
-#define PHY_REG_01_BMSR 0x01 // Basic mode status register
-#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
-#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
-#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
-#define PHY_REG_05_LPA 0x05 // Link partner ability reg
-#define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
-#define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
-#define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
-
-#define BMSR_LINK_STATUS 0x0004 //!< Link status
-
-#ifndef PHY_LS_HIGH_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
- receiving packets. */
- #define PHY_LS_HIGH_CHECK_TIME_MS 15000
-#endif
-
-#ifndef PHY_LS_LOW_CHECK_TIME_MS
- /* Check if the LinkSStatus in the PHY is still low every second. */
- #define PHY_LS_LOW_CHECK_TIME_MS 1000
-#endif
-
-/* Interrupt events to process. Currently only the Rx event is processed
-although code for other events is included to allow for possible future
-expansion. */
-#define EMAC_IF_RX_EVENT 1UL
-#define EMAC_IF_TX_EVENT 2UL
-#define EMAC_IF_ERR_EVENT 4UL
-#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
-
-#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
-
-#ifdef ipconfigHAS_TX_CRC_OFFLOADING
- #undef ipconfigHAS_TX_CRC_OFFLOADING
-#endif
-/* Override this define because the KSZ8851 is programmed to set all outgoing CRC's */
-#define ipconfigHAS_TX_CRC_OFFLOADING 1
-
-#ifndef EMAC_MAX_BLOCK_TIME_MS
- #define EMAC_MAX_BLOCK_TIME_MS 100ul
-#endif
-
-/* Default the size of the stack used by the EMAC deferred handler task to 4x
-the size of the stack used by the idle task - but allow this to be overridden in
-FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
-#ifndef configEMAC_TASK_STACK_SIZE
- #define configEMAC_TASK_STACK_SIZE ( 6 * configMINIMAL_STACK_SIZE )
-#endif
-
-#define SPI_PDC_IDLE 0
-#define SPI_PDC_RX_START 1
-#define SPI_PDC_TX_ERROR 2
-#define SPI_PDC_RX_COMPLETE 3
-#define SPI_PDC_TX_START 4
-#define SPI_PDC_RX_ERROR 5
-#define SPI_PDC_TX_COMPLETE 6
-
-/**
- * ksz8851snl driver structure.
- */
-typedef struct {
- /** Set to 1 when owner is software (ready to read), 0 for Micrel. */
- uint32_t rx_ready[MICREL_RX_BUFFERS];
- /** Set to 1 when owner is Micrel, 0 for software. */
- uint32_t tx_busy[MICREL_TX_BUFFERS];
- /** RX NetworkBufferDescriptor_t pointer list */
- NetworkBufferDescriptor_t *rx_buffers[MICREL_RX_BUFFERS];
- /** TX NetworkBufferDescriptor_t pointer list */
- NetworkBufferDescriptor_t *tx_buffers[MICREL_TX_BUFFERS];
- NetworkBufferDescriptor_t *tx_cur_buffer;
-
- /** Circular buffer head pointer for packet received. */
- uint32_t us_rx_head;
- /** Circular buffer tail pointer for packet to be read. */
- uint32_t us_rx_tail;
- /** Circular buffer head pointer by upper layer (buffer to be sent). */
- uint32_t us_tx_head;
- /** Circular buffer tail pointer incremented by handlers (buffer sent). */
- uint32_t us_tx_tail;
-
- uint32_t ul_total_tx;
- uint32_t ul_total_rx;
- uint32_t tx_space;
-
- /** Still experimental: hash table to allow certain multicast addresses. */
- uint16_t pusHashTable[ 4 ];
-
- /* ul_spi_pdc_status has "SPI_PDC_xxx" values. */
- volatile uint32_t ul_spi_pdc_status;
-
- /* ul_had_intn_interrupt becomes true within the INTN interrupt. */
- volatile uint32_t ul_had_intn_interrupt;
-
- uint16_t us_pending_frame;
-} xKSZ8851_Device_t;
-
-/* SPI PDC register base.
-Declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
-extern Pdc *g_p_spi_pdc;
-
-/* Temporary buffer for PDC reception.
-declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
-extern uint8_t tmpbuf[1536];
-
-COMPILER_ALIGNED(8)
-static xKSZ8851_Device_t xMicrelDevice;
-
-static TaskHandle_t xTransmitHandle;
-
-/*-----------------------------------------------------------*/
-
-/*
- * Wait a fixed time for the link status to indicate the network is up.
- */
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
-
-/*
- * A deferred interrupt handler task that processes GMAC interrupts.
- */
-static void prvEMACHandlerTask( void *pvParameters );
-
-/*
- * Try to obtain an Rx packet from the hardware.
- */
-static uint32_t prvEMACRxPoll( void );
-
-static inline unsigned long ulReadMDIO( unsigned uAddress );
-
-static void ksz8851snl_low_level_init( void );
-
-static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void );
-
-/*-----------------------------------------------------------*/
-
-/* Bit map of outstanding ETH interrupt events for processing. Currently only
-the Rx interrupt is handled, although code is included for other events to
-enable future expansion. */
-static volatile uint32_t ulISREvents;
-
-/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
-static uint32_t ulPHYLinkStatus = 0;
-static volatile BaseType_t xGMACSwitchRequired;
-
-static void ksz8851snl_update( void );
-
-static void ksz8851snl_rx_init( void );
-
-static void ksz8851snl_tx_init( void );
-
-/* Holds the handle of the task used as a deferred interrupt processor. The
-handle is used so direct notifications can be sent to the task for all EMAC/DMA
-related interrupts. */
-TaskHandle_t xEMACTaskHandle = NULL;
-
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
-const TickType_t x5_Seconds = 5000UL;
-
- if( xEMACTaskHandle == NULL )
- {
- ksz8851snl_low_level_init();
-
- /* Wait at most 5 seconds for a Link Status in the PHY. */
- xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
-
- /* The handler task is created at the highest possible priority to
- ensure the interrupt handler can return directly to it. */
- xTaskCreate( prvEMACHandlerTask, "KSZ8851", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
- configASSERT( xEMACTaskHandle );
- }
-
- /* When returning non-zero, the stack will become active and
- start DHCP (in configured) */
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xGetPhyLinkStatus( void )
-{
-BaseType_t xResult;
-
- /* This function returns true if the Link Status in the PHY is high. */
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xResult = pdTRUE;
- }
- else
- {
- xResult = pdFALSE;
- }
-
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
-{
-BaseType_t xResult = pdFALSE;
-int txHead = xMicrelDevice.us_tx_head;
-
- /* Make sure the next descriptor is free. */
- if( xMicrelDevice.tx_busy[ txHead ] != pdFALSE )
- {
- /* All TX buffers busy. */
- }
- else if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
- {
- /* Output: LS low. */
- }
- else
- {
- /* Pass the packet. */
- xMicrelDevice.tx_buffers[ txHead ] = pxNetworkBuffer;
- /* The descriptor is now owned by Micrel. */
- xMicrelDevice.tx_busy[ txHead ] = pdTRUE;
-
- /* Move the head pointer. */
- if( ++txHead == MICREL_TX_BUFFERS )
- {
- txHead = 0;
- }
- xMicrelDevice.us_tx_head = txHead;
- if( xEMACTaskHandle != NULL )
- {
- xTaskNotifyGive( xEMACTaskHandle );
- }
-
- #if( ipconfigZERO_COPY_TX_DRIVER != 1 )
- #warning Please ipconfigZERO_COPY_TX_DRIVER as 1
- #endif
- configASSERT( bReleaseAfterSend != pdFALSE );
- xResult = pdTRUE;
- }
- if( ( xResult == pdFALSE ) && ( bReleaseAfterSend != pdFALSE ) )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
- return xResult;
-}
-/*-----------------------------------------------------------*/
-
-/* This Micrel has numbered it's PHY registers in a different way.
-Translate the register index. */
-static int ks8851_phy_reg( int reg )
-{
- switch (reg) {
- case PHY_REG_00_BMCR:
- return REG_PHY_CNTL; // P1MBCR;
- case PHY_REG_01_BMSR:
- return REG_PHY_STATUS;
- case PHY_REG_02_PHYSID1:
- return REG_PHY_ID_LOW;
- case PHY_REG_03_PHYSID2:
- return REG_PHY_ID_HIGH;
- case PHY_REG_04_ADVERTISE:
- return REG_PHY_AUTO_NEGOTIATION;
- case PHY_REG_05_LPA:
- return REG_PHY_REMOTE_CAPABILITY;
- }
-
- return 0x0;
-}
-/*-----------------------------------------------------------*/
-
-static inline unsigned long ulReadMDIO( unsigned uAddress )
-{
-uint16_t usPHYStatus;
-int ks8851_reg = ks8851_phy_reg( uAddress );
-
- if( ks8851_reg != 0 )
- {
- usPHYStatus = ksz8851_reg_read( ks8851_reg );
- }
- else
- {
- /* Other addresses not yet implemented. */
- usPHYStatus = 0;
- }
- return usPHYStatus;
-}
-/*-----------------------------------------------------------*/
-
-static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
-{
-TickType_t xStartTime = xTaskGetTickCount();
-TickType_t xEndTime;
-BaseType_t xReturn;
-const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
-const uint32_t ulHz_Per_MHz = 1000000UL;
-
- for( ;; )
- {
- xEndTime = xTaskGetTickCount();
-
- if( ( xEndTime - xStartTime ) > xMaxTime )
- {
- /* Wated more than xMaxTime, return. */
- xReturn = pdFALSE;
- break;
- }
-
- /* Check the link status again. */
- ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- /* Link is up - return. */
- xReturn = pdTRUE;
- break;
- }
-
- /* Link is down - wait in the Blocked state for a short while (to allow
- other tasks to execute) before checking again. */
- vTaskDelay( xShortTime );
- }
-
- FreeRTOS_printf( ( "xGMACWaitLS: %ld freq %lu Mz\n",
- xReturn,
- sysclk_get_cpu_hz() / ulHz_Per_MHz ) );
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-static void vPioSetPinHigh(uint32_t ul_pin)
-{
- Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
- // Value to be driven on the I/O line: 1.
- p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
-}
-
-/**
- * \brief Handler for SPI interrupt.
- */
-void SPI_Handler(void)
-{
-BaseType_t xDoWakeup = pdFALSE;
-BaseType_t xKSZTaskWoken = pdFALSE;
-uint32_t ulCurrentSPIStatus;
-uint32_t ulEnabledSPIStatus;
-
- ulCurrentSPIStatus = spi_read_status( KSZ8851SNL_SPI );
- ulEnabledSPIStatus = spi_read_interrupt_mask( KSZ8851SNL_SPI );
- ulCurrentSPIStatus &= ulEnabledSPIStatus;
- spi_disable_interrupt( KSZ8851SNL_SPI, ulCurrentSPIStatus );
-
-
- switch( xMicrelDevice.ul_spi_pdc_status )
- {
- case SPI_PDC_RX_START:
- {
- if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
- {
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_ERROR;
- xDoWakeup = pdTRUE;
- }
- else
- {
- if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
- {
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
- xDoWakeup = pdTRUE;
- }
- }
- }
- break;
-
- case SPI_PDC_TX_START:
- {
- /* Middle of TX. */
- if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
- {
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_ERROR;
- xDoWakeup = pdTRUE;
- }
- else
- {
- if( ( ulCurrentSPIStatus & SPI_SR_ENDRX ) != 0 )
- {
- /* Enable RX complete interrupt. */
- spi_enable_interrupt( KSZ8851SNL_SPI, SPI_IER_RXBUFF );
- }
- /* End of TX. */
- if( ( ulCurrentSPIStatus & SPI_END_OF_TX ) != 0 )
- {
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
- xDoWakeup = pdTRUE;
- }
- }
- }
- break;
- } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
-
- if( xDoWakeup != pdFALSE )
- {
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xKSZTaskWoken );
- }
- }
- else
- {
- }
- portEND_SWITCHING_ISR( xKSZTaskWoken );
-}
-/*-----------------------------------------------------------*/
-
-static void INTN_Handler(uint32_t id, uint32_t mask)
-{
-BaseType_t xKSZTaskWoken = pdFALSE;
-
- if( ( id == INTN_ID ) &&
- ( mask == INTN_PIN_MSK ) )
- {
- /* Clear the PIO interrupt flags. */
- pio_get_interrupt_status( INTN_PIO );
-
- /* Set the INTN flag. */
- xMicrelDevice.ul_had_intn_interrupt++;
- if( xEMACTaskHandle != NULL )
- {
- vTaskNotifyGiveFromISR( xEMACTaskHandle, &( xKSZTaskWoken ) );
- }
- }
- portEND_SWITCHING_ISR( xKSZTaskWoken );
-}
-/*-----------------------------------------------------------*/
-
-/**
- * \brief Populate the RX descriptor ring buffers with pbufs.
- *
- * \param p_ksz8851snl_dev Pointer to driver data structure.
- */
-static void ksz8851snl_rx_populate_queue( void )
-{
- uint32_t ul_index = 0;
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-
- /* Set up the RX descriptors */
- for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
- if( xMicrelDevice.rx_buffers[ ul_index ] == NULL )
- {
- /* Allocate a new NetworkBufferDescriptor_t with the maximum size. */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipconfigNETWORK_MTU + 36, 100 );
- if( pxNetworkBuffer == NULL )
- {
- FreeRTOS_printf( ( "ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t allocation failure\n" ) );
- configASSERT( 1 == 2 );
- }
-
- /* Make sure lwIP is well configured so one NetworkBufferDescriptor_t can contain the maximum packet size. */
- //LWIP_ASSERT("ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t size too small!", pbuf_clen(pxNetworkBuffer) <= 1);
-
- /* Save NetworkBufferDescriptor_t pointer to be sent to lwIP upper layer. */
- xMicrelDevice.rx_buffers[ ul_index ] = pxNetworkBuffer;
- /* Pass it to Micrel for reception. */
- xMicrelDevice.rx_ready[ ul_index ] = pdFALSE;
- }
- }
-}
-
-unsigned tx_space, wait_tx_space, tx_status, fhr_status;
-unsigned rx_debug = 0;
-/**
- * \brief Update Micrel state machine and perform required actions.
- *
- * \param netif the lwIP network interface structure for this ethernetif.
- */
-static void ksz8851snl_update()
-{
- uint16_t txmir = 0;
-
-/* Check for free PDC. */
- switch( xMicrelDevice.ul_spi_pdc_status )
- {
- case SPI_PDC_TX_ERROR:
- {
- uint32_t ulValue;
- // /* TX step11: end TX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* TX step12: disable TXQ write access. */
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
-
- ulValue = ksz8851snl_reset_tx();
-
- xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
-
- FreeRTOS_printf( ("SPI_PDC_TX_ERROR %02X\n", ulValue ) );
- }
- break;
-
- case SPI_PDC_RX_ERROR:
- {
- uint32_t ulValue;
- /* TX step11: end TX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
- vTaskDelay( 1 );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* TX step12: disable TXQ write access. */
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
-
- //ulValue = ksz8851snl_reset_rx();
- ulValue = ksz8851snl_reinit();
-
- xGMACWaitLS( pdMS_TO_TICKS( 5000UL ) );
-
- FreeRTOS_printf( ("SPI_PDC_RX_ERROR %02X\n", ulValue ) );
- }
- break;
- }
- switch( xMicrelDevice.ul_spi_pdc_status )
- {
- case SPI_PDC_IDLE:
- {
- int txTail = xMicrelDevice.us_tx_tail;
-
- /*
- * ========================== Handle RX ==========================
- */
- if( ( xMicrelDevice.ul_had_intn_interrupt != 0 ) || ( xMicrelDevice.us_pending_frame > 0 ) )
- {
- int rxHead = xMicrelDevice.us_rx_head;
- NetworkBufferDescriptor_t *pxNetworkBuffer;
-#warning try
- xMicrelDevice.ul_had_intn_interrupt = 0;
-
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- uint16_t int_status;
- /* RX step1: read interrupt status for INT_RX flag. */
- int_status = ksz8851_reg_read( REG_INT_STATUS );
-
-
- /* RX step2: disable all interrupts. */
- ksz8851_reg_write( REG_INT_MASK, 0 );
-
- /* RX step3: clear INT_RX flag. */
- ksz8851_reg_setbits( REG_INT_STATUS, INT_RX );
-
- /* RX step4-5: check for received frames. */
- xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- /* RX step24: enable INT_RX flag. */
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
- return;
- }
- }
-#warning try
- xMicrelDevice.ul_had_intn_interrupt = 0;
-
- /* Now xMicrelDevice.us_pending_frame != 0 */
-
- /* Don't break Micrel state machine, wait for a free descriptor first! */
- if( xMicrelDevice.rx_ready[ rxHead ] != pdFALSE )
- {
- FreeRTOS_printf( ( "ksz8851snl_update: out of free descriptor! [tail=%u head=%u]\n",
- xMicrelDevice.us_rx_tail, rxHead ) );
- return;
- }
- pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxHead ];
-
- if( pxNetworkBuffer == NULL )
- {
- ksz8851snl_rx_populate_queue();
- FreeRTOS_printf( ( "ksz8851snl_update: no buffer set [head=%u]\n", rxHead ) );
- return;
- }
-
- /* RX step6: get RX packet status. */
- fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
- if( ( ( fhr_status & RX_VALID ) == 0 ) || ( ( fhr_status & RX_ERRORS ) != 0 ) )
- {
- ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_CMD_FREE_PACKET);
- FreeRTOS_printf( ( "ksz8851snl_update: RX packet error!\n" ) );
-
- /* RX step4-5: check for received frames. */
- xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- /* RX step24: enable INT_RX flag. */
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
- }
- ulISREvents |= EMAC_IF_ERR_EVENT;
- }
- else
- {
- size_t xLength;
- /* RX step7: read frame length. */
- xLength = ksz8851_reg_read(REG_RX_FHR_BYTE_CNT) & RX_BYTE_CNT_MASK;
-
- /* RX step8: Drop packet if len is invalid or no descriptor available. */
- if( xLength == 0 )
- {
- ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_CMD_FREE_PACKET );
- FreeRTOS_printf( ( "ksz8851snl_update: RX bad len!\n" ) );
- ulISREvents |= EMAC_IF_ERR_EVENT;
- }
- else
- {
- size_t xReadLength = xLength;
-
- xMicrelDevice.ul_total_rx++;
- /* RX step9: reset RX frame pointer. */
- ksz8851_reg_clrbits(REG_RX_ADDR_PTR, ADDR_PTR_MASK);
-
- /* RX step10: start RXQ read access. */
- ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_START);
- /* RX step11-17: start asynchronous FIFO read operation. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_START;
- gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- if( ( xReadLength & ( sizeof( size_t ) - 1 ) ) != 0 )
- {
- xReadLength = ( xReadLength | ( sizeof( size_t ) - 1 ) ) + 1;
- }
-
- /* Pass the buffer minus 2 bytes, see ksz8851snl.c: RXQ_TWOBYTE_OFFSET. */
- ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer - 2, xReadLength );
- /* Remove CRC and update buffer length. */
- xLength -= 4;
- pxNetworkBuffer->xDataLength = xLength;
- /* Wait for SPI interrupt to set status 'SPI_PDC_RX_COMPLETE'. */
- }
- }
- break;
- } /* ul_had_intn_interrupt || us_pending_frame */
- /*
- * ========================== Handle TX ==========================
- */
-
- /* Fetch next packet to be sent. */
- if( ( xMicrelDevice.tx_busy[ txTail ] != pdFALSE ) &&
- ( xMicrelDevice.us_pending_frame == 0 ) &&
- ( xMicrelDevice.ul_had_intn_interrupt == 0 ) )
- {
- NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
- size_t xLength = pxNetworkBuffer->xDataLength;
- int iIndex = xLength;
-
- xLength = 4 * ( ( xLength + 3 ) / 4 );
- while( iIndex < ( int ) xLength )
- {
- pxNetworkBuffer->pucEthernetBuffer[ iIndex ] = '\0';
- iIndex++;
- }
- pxNetworkBuffer->xDataLength = xLength;
-
- /* TX step1: check if TXQ memory size is available for transmit. */
- txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
- txmir = txmir & TX_MEM_AVAILABLE_MASK;
-
- if( txmir < ( xLength + 8 ) )
- {
- if( wait_tx_space == pdFALSE )
- {
- tx_status = ksz8851_reg_read( REG_TX_STATUS );
- fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
- wait_tx_space = pdTRUE;
- }
- //return;
- rx_debug = 1;
- tx_space = txmir;
- }
- else
- {
- tx_space = txmir;
-
- /* TX step2: disable all interrupts. */
- ksz8851_reg_write( REG_INT_MASK, 0 );
-
- xMicrelDevice.tx_space -= xLength;
-
- /* TX step3: enable TXQ write access. */
- ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_START );
- /* TX step4-8: perform FIFO write operation. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_START;
- xMicrelDevice.tx_cur_buffer = pxNetworkBuffer;
- /* Bring SPI SS low. */
- gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
- xMicrelDevice.ul_total_tx++;
-
- ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
- }
- }
- }
- break; /* SPI_PDC_IDLE */
-
- case SPI_PDC_RX_COMPLETE:
- {
- int rxHead = xMicrelDevice.us_rx_head;
- /* RX step18-19: pad with dummy data to keep dword alignment. */
- /* Packet lengths will be rounded up to a multiple of "sizeof size_t". */
-// xLength = xMicrelDevice.rx_buffers[ rxHead ]->xDataLength & 3;
-// if( xLength != 0 )
-// {
-// ksz8851_fifo_dummy( 4 - xLength );
-// }
-
- /* RX step20: end RX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* RX step21: end RXQ read access. */
- ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
-
- /* RX step22-23: update frame count to be read. */
- xMicrelDevice.us_pending_frame -= 1;
-
- /* RX step24: enable INT_RX flag if transfer complete. */
- if( xMicrelDevice.us_pending_frame == 0 )
- {
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
- }
-
- /* Mark descriptor ready to be read. */
- xMicrelDevice.rx_ready[ rxHead ] = pdTRUE;
- if( ++rxHead == MICREL_RX_BUFFERS )
- {
- rxHead = 0;
- }
- xMicrelDevice.us_rx_head = rxHead;
- if( rx_debug != 0 )
- {
- uint32_t txmir;
- rx_debug = 0;
- txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
- txmir = txmir & TX_MEM_AVAILABLE_MASK;
- }
- /* Tell prvEMACHandlerTask that RX packets are available. */
- ulISREvents |= EMAC_IF_RX_EVENT;
- } /* case SPI_PDC_RX_COMPLETE */
- break;
-
- case SPI_PDC_TX_COMPLETE:
- {
- int txTail = xMicrelDevice.us_tx_tail;
- NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
-
- size_t xLength;
- /* TX step9-10: pad with dummy data to keep dword alignment. */
- /* Not necessary: length is already a multiple of 4. */
- xLength = pxNetworkBuffer->xDataLength & 3;
- if( xLength != 0 )
- {
-// ksz8851_fifo_dummy( 4 - xLength );
- }
-
-// /* TX step11: end TX transfer. */
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
-
- /* Disable asynchronous transfer mode. */
- xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
-
- /* TX step12: disable TXQ write access. */
- ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
-
- xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
-
- /* TX step12.1: enqueue frame in TXQ. */
- ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
-
- /* RX step13: enable INT_RX flag. */
-// ksz8851_reg_write( REG_INT_MASK, INT_RX );
- /* Buffer sent, free the corresponding buffer and mark descriptor as owned by software. */
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
-
- xMicrelDevice.tx_buffers[ txTail ] = NULL;
- xMicrelDevice.tx_busy[ txTail ] = pdFALSE;
- if( ++txTail == MICREL_TX_BUFFERS )
- {
- txTail = 0;
- }
-
- xMicrelDevice.us_tx_tail = txTail;
- /* Experiment. */
- //xMicrelDevice.ul_had_intn_interrupt = 1;
- if( xTransmitHandle != NULL )
- {
- xTaskNotifyGive( xTransmitHandle );
- }
-#warning moved downward
- /* RX step13: enable INT_RX flag. */
- ksz8851_reg_write( REG_INT_MASK, INT_RX );
- /* Prevent the EMAC task from sleeping a single time. */
- ulISREvents |= EMAC_IF_TX_EVENT;
- } /* case SPI_PDC_TX_COMPLETE */
- break;
- } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
-}
-
-/**
- * \brief Set up the RX descriptor ring buffers.
- *
- * This function sets up the descriptor list used for RX packets.
- *
- */
-static void ksz8851snl_rx_init()
-{
- uint32_t ul_index = 0;
-
- /* Init pointer index. */
- xMicrelDevice.us_rx_head = 0;
- xMicrelDevice.us_rx_tail = 0;
-
- /* Set up the RX descriptors. */
- for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
- xMicrelDevice.rx_buffers[ul_index] = NULL;
- xMicrelDevice.rx_ready[ul_index] = pdFALSE;
- }
-
- /* Build RX buffer and descriptors. */
- ksz8851snl_rx_populate_queue();
-}
-
-/**
- * \brief Set up the TX descriptor ring buffers.
- *
- * This function sets up the descriptor list used for TX packets.
- *
- */
-static void ksz8851snl_tx_init()
-{
- uint32_t ul_index = 0;
-
- /* Init TX index pointer. */
- xMicrelDevice.us_tx_head = 0;
- xMicrelDevice.us_tx_tail = 0;
-
- /* Set up the TX descriptors */
- for( ul_index = 0; ul_index < MICREL_TX_BUFFERS; ul_index++ )
- {
- xMicrelDevice.tx_busy[ul_index] = pdFALSE;
- }
- xMicrelDevice.tx_space = 6144;
-}
-
-/**
- * \brief Initialize ksz8851snl ethernet controller.
- *
- * \note Called from ethernetif_init().
- *
- * \param netif the lwIP network interface structure for this ethernetif.
- */
-static void ksz8851snl_low_level_init( void )
-{
- ksz8851snl_rx_init();
- ksz8851snl_tx_init();
-
- /* Enable NVIC interrupts. */
- NVIC_SetPriority(SPI_IRQn, INT_PRIORITY_SPI);
- NVIC_EnableIRQ(SPI_IRQn);
-
- /* Initialize SPI link. */
- if( ksz8851snl_init() < 0 )
- {
- FreeRTOS_printf( ( "ksz8851snl_low_level_init: failed to initialize the Micrel driver!\n" ) );
- configASSERT(0 == 1);
- }
- memset( xMicrelDevice.pusHashTable, 255, sizeof( xMicrelDevice.pusHashTable ) );
- ksz8851_reg_write( REG_MAC_HASH_0, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 0 ] ) );
- ksz8851_reg_write( REG_MAC_HASH_2, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 1 ] ) );
- ksz8851_reg_write( REG_MAC_HASH_4, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 2 ] ) );
- ksz8851_reg_write( REG_MAC_HASH_6, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 3 ] ) );
-
- /* Initialize interrupt line INTN. */
- configure_intn( INTN_Handler );
-}
-
-/**
- * \brief Use pre-allocated pbuf as DMA source and return the incoming packet.
- *
- * \param netif the lwIP network interface structure for this ethernetif.
- *
- * \return a pbuf filled with the received packet (including MAC header).
- * 0 on memory error.
- */
-static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer = NULL;
-int rxTail = xMicrelDevice.us_rx_tail;
-
- /* Check that descriptor is owned by software (ie packet received). */
- if( xMicrelDevice.rx_ready[ rxTail ] != pdFALSE )
- {
-
- /* Fetch pre-allocated buffer */
- pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxTail ];
-
- /* Remove this pbuf from its descriptor. */
- xMicrelDevice.rx_buffers[ rxTail ] = NULL;
-
- /* Clears rx_ready and sets rx_buffers. */
- ksz8851snl_rx_populate_queue();
-
- if( ++rxTail == MICREL_RX_BUFFERS )
- {
- rxTail = 0;
- }
- xMicrelDevice.us_rx_tail = rxTail;
- }
-
- return pxNetworkBuffer;
-}
-/*-----------------------------------------------------------*/
-
-static uint32_t prvEMACRxPoll( void )
-{
-NetworkBufferDescriptor_t *pxNetworkBuffer;
-IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-uint32_t ulReturnValue = 0;
-
- for( ;; )
- {
- /* Only for logging. */
- int rxTail = xMicrelDevice.us_rx_tail;
- EthernetHeader_t *pxEthernetHeader;
-
- pxNetworkBuffer = ksz8851snl_low_level_input();
-
- if( pxNetworkBuffer == NULL )
- {
- break;
- }
- pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
-
- if( ( pxEthernetHeader->usFrameType != ipIPv4_FRAME_TYPE ) &&
- ( pxEthernetHeader->usFrameType != ipARP_FRAME_TYPE ) )
- {
- FreeRTOS_printf( ( "Frame type %02X received\n", pxEthernetHeader->usFrameType ) );
- }
- ulReturnValue++;
-
- xRxEvent.pvData = ( void * )pxNetworkBuffer;
- /* Send the descriptor to the IP task for processing. */
- if( xSendEventStructToIPTask( &xRxEvent, 100UL ) != pdTRUE )
- {
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- iptraceETHERNET_RX_EVENT_LOST();
- FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
- }
- }
-
- return ulReturnValue;
-}
-/*-----------------------------------------------------------*/
-
-static void prvEMACHandlerTask( void *pvParameters )
-{
-TimeOut_t xPhyTime;
-TickType_t xPhyRemTime;
-TickType_t xLoggingTime;
-UBaseType_t uxLastMinBufferCount = 0;
-UBaseType_t uxCurrentCount;
-BaseType_t xResult = 0;
-uint32_t xStatus;
-const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
-#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- UBaseType_t uxLastMinQueueSpace = 0;
-#endif
-
- /* Remove compiler warnings about unused parameters. */
- ( void ) pvParameters;
-
- configASSERT( xEMACTaskHandle );
-
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- xLoggingTime = xTaskGetTickCount();
-
- for( ;; )
- {
- uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
- if( uxLastMinBufferCount != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinBufferCount = uxCurrentCount;
- FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
- uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
- }
-
- #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
- {
- uxCurrentCount = uxGetMinimumIPQueueSpace();
- if( uxLastMinQueueSpace != uxCurrentCount )
- {
- /* The logging produced below may be helpful
- while tuning +TCP: see how many buffers are in use. */
- uxLastMinQueueSpace = uxCurrentCount;
- FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
- }
- }
- #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
-
- /* Run the state-machine of the ksz8851 driver. */
- ksz8851snl_update();
-
- if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
- {
- /* No events to process now, wait for the next. */
- ulTaskNotifyTake( pdTRUE, ulMaxBlockTime );
- }
-
- if( ( xTaskGetTickCount() - xLoggingTime ) > 10000 )
- {
- xLoggingTime += 10000;
- FreeRTOS_printf( ( "Now Tx/Rx %7d /%7d\n",
- xMicrelDevice.ul_total_tx, xMicrelDevice.ul_total_rx ) );
- }
-
- if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
- {
- ulISREvents &= ~EMAC_IF_RX_EVENT;
-
- /* Wait for the EMAC interrupt to indicate that another packet has been
- received. */
- xResult = prvEMACRxPoll();
- }
-
- if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
- {
- /* Future extension: code to release TX buffers if zero-copy is used. */
- ulISREvents &= ~EMAC_IF_TX_EVENT;
- }
-
- if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
- {
- /* Future extension: logging about errors that occurred. */
- ulISREvents &= ~EMAC_IF_ERR_EVENT;
- }
-
- if( xResult > 0 )
- {
- /* As long as packets are being received, assume that
- the Link Status is high. */
- ulPHYLinkStatus |= BMSR_LINK_STATUS;
- /* A packet was received. No need to check for the PHY status now,
- but set a timer to check it later on. */
- vTaskSetTimeOutState( &xPhyTime );
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- xResult = 0;
- }
- else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) &&
- ( xMicrelDevice.ul_spi_pdc_status == SPI_PDC_IDLE ) )
- {
- /* Check the link status again. */
- xStatus = ulReadMDIO( PHY_REG_01_BMSR );
-
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
- {
- ulPHYLinkStatus = xStatus;
- FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
- }
-
- vTaskSetTimeOutState( &xPhyTime );
- if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
- }
- else
- {
- xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
- }
- }
- }
-}
-/*-----------------------------------------------------------*/
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* Standard includes. */
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "queue.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "sam4e_xplained_pro.h"
+#include "hr_gettime.h"
+#include "conf_eth.h"
+#include "ksz8851snl.h"
+#include "ksz8851snl_reg.h"
+
+/* Some files from the Atmel Software Framework */
+#include <sysclk.h>
+#include <pdc/pdc.h>
+#include <spi/spi.h>
+
+/*
+ Sending a packet:
+
+ 1) Called by UP-task, add buffer to the TX-list:
+ xNetworkInterfaceOutput()
+ tx_buffers[ us_tx_head ] = pxNetworkBuffer;
+ tx_busy[ us_tx_head ] = pdTRUE;
+ us_tx_head++;
+
+ 2) Called by EMAC-Task: start SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_IDLE )
+ {
+ if( ( tx_busy[ us_tx_tail ] != pdFALSE ) &&
+ ( us_pending_frame == 0 ) &&
+ ( ul_had_intn_interrupt == 0 ) )
+ {
+ // disable all interrupts.
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+ Bring KSZ8851SNL_CSN_GPIO low
+ ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
+ ul_spi_pdc_status = SPI_PDC_TX_START;
+ tx_cur_buffer = pxNetworkBuffer;
+ }
+ }
+ 3) Wait for SPI RXBUFF interrupt
+ SPI_Handler()
+ if( ul_spi_pdc_status == SPI_PDC_TX_START )
+ {
+ if( SPI_Status & SPI_SR_RXBUFF )
+ {
+ ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
+ }
+ }
+
+ 4) Called by EMAC-Task: finish SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_TX_COMPLETE )
+ {
+ ul_spi_pdc_status = SPI_PDC_IDLE;
+ Bring KSZ8851SNL_CSN_GPIO high
+ // TX step12: disable TXQ write access.
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+ // TX step12.1: enqueue frame in TXQ.
+ ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
+
+ // RX step13: enable INT_RX flag.
+ ksz8851_reg_write( REG_INT_MASK, INT_RX );
+
+ // Buffer sent, free the corresponding buffer and mark descriptor as owned by software.
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ tx_buffers[ us_tx_tail ] = NULL;
+ tx_busy[ us_tx_tail ] = pdFALSE;
+ us_tx_tail++
+ }
+
+ Receiving a packet:
+
+ 1) Wait for a INTN interrupt
+ INTN_Handler()
+ ul_had_intn_interrupt = 1
+ vTaskNotifyGiveFromISR(); // Wake up the EMAC task
+
+ 2) Called by EMAC-Task: check for new fragments and start SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_IDLE )
+ {
+ if( ( ul_had_intn_interrupt != 0 ) || ( us_pending_frame > 0 ) )
+ {
+ if( us_pending_frame == 0 )
+ {
+ us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
+ if( us_pending_frame == 0 )
+ {
+ break;
+ }
+ }
+ // RX step2: disable all interrupts.
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+ Check if there is a valid packet: REG_RX_FHR_STATUS
+ Read the length of the next fragment: REG_RX_FHR_BYTE_CNT
+ ul_spi_pdc_status = SPI_PDC_RX_START;
+ gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);
+ // Start SPI data transfer
+ ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer, xReadLength );
+ }
+ }
+
+ 3) Wait for SPI RXBUFF interrupt
+ SPI_Handler()
+ if( ul_spi_pdc_status == SPI_PDC_RX_START:
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
+ {
+ // Transfer complete, disable SPI RXBUFF interrupt.
+ spi_disable_interrupt( KSZ8851SNL_SPI, SPI_IDR_RXBUFF );
+
+ ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
+ }
+ }
+ }
+
+ 4) Finish SPI transfer
+ ksz8851snl_update()
+ if( ul_spi_pdc_status == SPI_PDC_RX_COMPLETE )
+ {
+ ul_spi_pdc_status = SPI_PDC_IDLE;
+ Bring KSZ8851SNL_CSN_GPIO high
+ // RX step21: end RXQ read access.
+ ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
+ // RX step22-23: update frame count to be read.
+ us_pending_frame--
+ // RX step24: enable INT_RX flag if transfer complete.
+ if( us_pending_frame == 0 )
+ {
+ // Allow more RX interrupts.
+ ksz8851_reg_write( REG_INT_MASK, INT_RX );
+ }
+
+ // Mark descriptor ready to be read.
+ rx_ready[ rxHead ] = pdTRUE;
+ rxHead++
+ }
+*/
+
+#define PHY_REG_00_BMCR 0x00 // Basic mode control register
+#define PHY_REG_01_BMSR 0x01 // Basic mode status register
+#define PHY_REG_02_PHYSID1 0x02 // PHYS ID 1
+#define PHY_REG_03_PHYSID2 0x03 // PHYS ID 2
+#define PHY_REG_04_ADVERTISE 0x04 // Advertisement control reg
+#define PHY_REG_05_LPA 0x05 // Link partner ability reg
+#define PHY_REG_06_ANER 0x06 // 6 RW Auto-Negotiation Expansion Register
+#define PHY_REG_07_ANNPTR 0x07 // 7 RW Auto-Negotiation Next Page TX
+#define PHY_REG_08_RESERVED0 0x08 // 0x08..0x0Fh 8-15 RW RESERVED
+
+#define BMSR_LINK_STATUS 0x0004 //!< Link status
+
+#ifndef PHY_LS_HIGH_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still high after 15 seconds of not
+ receiving packets. */
+ #define PHY_LS_HIGH_CHECK_TIME_MS 15000
+#endif
+
+#ifndef PHY_LS_LOW_CHECK_TIME_MS
+ /* Check if the LinkSStatus in the PHY is still low every second. */
+ #define PHY_LS_LOW_CHECK_TIME_MS 1000
+#endif
+
+/* Interrupt events to process. Currently only the Rx event is processed
+although code for other events is included to allow for possible future
+expansion. */
+#define EMAC_IF_RX_EVENT 1UL
+#define EMAC_IF_TX_EVENT 2UL
+#define EMAC_IF_ERR_EVENT 4UL
+#define EMAC_IF_ALL_EVENT ( EMAC_IF_RX_EVENT | EMAC_IF_TX_EVENT | EMAC_IF_ERR_EVENT )
+
+#define ETHERNET_CONF_PHY_ADDR BOARD_GMAC_PHY_ADDR
+
+#ifdef ipconfigHAS_TX_CRC_OFFLOADING
+ #undef ipconfigHAS_TX_CRC_OFFLOADING
+#endif
+/* Override this define because the KSZ8851 is programmed to set all outgoing CRC's */
+#define ipconfigHAS_TX_CRC_OFFLOADING 1
+
+#ifndef EMAC_MAX_BLOCK_TIME_MS
+ #define EMAC_MAX_BLOCK_TIME_MS 100ul
+#endif
+
+/* Default the size of the stack used by the EMAC deferred handler task to 4x
+the size of the stack used by the idle task - but allow this to be overridden in
+FreeRTOSConfig.h as configMINIMAL_STACK_SIZE is a user definable constant. */
+#ifndef configEMAC_TASK_STACK_SIZE
+ #define configEMAC_TASK_STACK_SIZE ( 6 * configMINIMAL_STACK_SIZE )
+#endif
+
+#define SPI_PDC_IDLE 0
+#define SPI_PDC_RX_START 1
+#define SPI_PDC_TX_ERROR 2
+#define SPI_PDC_RX_COMPLETE 3
+#define SPI_PDC_TX_START 4
+#define SPI_PDC_RX_ERROR 5
+#define SPI_PDC_TX_COMPLETE 6
+
+/**
+ * ksz8851snl driver structure.
+ */
+typedef struct {
+ /** Set to 1 when owner is software (ready to read), 0 for Micrel. */
+ uint32_t rx_ready[MICREL_RX_BUFFERS];
+ /** Set to 1 when owner is Micrel, 0 for software. */
+ uint32_t tx_busy[MICREL_TX_BUFFERS];
+ /** RX NetworkBufferDescriptor_t pointer list */
+ NetworkBufferDescriptor_t *rx_buffers[MICREL_RX_BUFFERS];
+ /** TX NetworkBufferDescriptor_t pointer list */
+ NetworkBufferDescriptor_t *tx_buffers[MICREL_TX_BUFFERS];
+ NetworkBufferDescriptor_t *tx_cur_buffer;
+
+ /** Circular buffer head pointer for packet received. */
+ uint32_t us_rx_head;
+ /** Circular buffer tail pointer for packet to be read. */
+ uint32_t us_rx_tail;
+ /** Circular buffer head pointer by upper layer (buffer to be sent). */
+ uint32_t us_tx_head;
+ /** Circular buffer tail pointer incremented by handlers (buffer sent). */
+ uint32_t us_tx_tail;
+
+ uint32_t ul_total_tx;
+ uint32_t ul_total_rx;
+ uint32_t tx_space;
+
+ /** Still experimental: hash table to allow certain multicast addresses. */
+ uint16_t pusHashTable[ 4 ];
+
+ /* ul_spi_pdc_status has "SPI_PDC_xxx" values. */
+ volatile uint32_t ul_spi_pdc_status;
+
+ /* ul_had_intn_interrupt becomes true within the INTN interrupt. */
+ volatile uint32_t ul_had_intn_interrupt;
+
+ uint16_t us_pending_frame;
+} xKSZ8851_Device_t;
+
+/* SPI PDC register base.
+Declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
+extern Pdc *g_p_spi_pdc;
+
+/* Temporary buffer for PDC reception.
+declared in ASF\sam\components\ksz8851snl\ksz8851snl.c */
+extern uint8_t tmpbuf[1536];
+
+COMPILER_ALIGNED(8)
+static xKSZ8851_Device_t xMicrelDevice;
+
+static TaskHandle_t xTransmitHandle;
+
+/*-----------------------------------------------------------*/
+
+/*
+ * Wait a fixed time for the link status to indicate the network is up.
+ */
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime );
+
+/*
+ * A deferred interrupt handler task that processes GMAC interrupts.
+ */
+static void prvEMACHandlerTask( void *pvParameters );
+
+/*
+ * Try to obtain an Rx packet from the hardware.
+ */
+static uint32_t prvEMACRxPoll( void );
+
+static inline unsigned long ulReadMDIO( unsigned uAddress );
+
+static void ksz8851snl_low_level_init( void );
+
+static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void );
+
+/*-----------------------------------------------------------*/
+
+/* Bit map of outstanding ETH interrupt events for processing. Currently only
+the Rx interrupt is handled, although code is included for other events to
+enable future expansion. */
+static volatile uint32_t ulISREvents;
+
+/* A copy of PHY register 1: 'PHY_REG_01_BMSR' */
+static uint32_t ulPHYLinkStatus = 0;
+static volatile BaseType_t xGMACSwitchRequired;
+
+static void ksz8851snl_update( void );
+
+static void ksz8851snl_rx_init( void );
+
+static void ksz8851snl_tx_init( void );
+
+/* Holds the handle of the task used as a deferred interrupt processor. The
+handle is used so direct notifications can be sent to the task for all EMAC/DMA
+related interrupts. */
+TaskHandle_t xEMACTaskHandle = NULL;
+
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+const TickType_t x5_Seconds = 5000UL;
+
+ if( xEMACTaskHandle == NULL )
+ {
+ ksz8851snl_low_level_init();
+
+ /* Wait at most 5 seconds for a Link Status in the PHY. */
+ xGMACWaitLS( pdMS_TO_TICKS( x5_Seconds ) );
+
+ /* The handler task is created at the highest possible priority to
+ ensure the interrupt handler can return directly to it. */
+ xTaskCreate( prvEMACHandlerTask, "KSZ8851", configEMAC_TASK_STACK_SIZE, NULL, configMAX_PRIORITIES - 1, &xEMACTaskHandle );
+ configASSERT( xEMACTaskHandle );
+ }
+
+ /* When returning non-zero, the stack will become active and
+ start DHCP (in configured) */
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ return ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+BaseType_t xResult;
+
+ /* This function returns true if the Link Status in the PHY is high. */
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xResult = pdTRUE;
+ }
+ else
+ {
+ xResult = pdFALSE;
+ }
+
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer, BaseType_t bReleaseAfterSend )
+{
+BaseType_t xResult = pdFALSE;
+int txHead = xMicrelDevice.us_tx_head;
+
+ /* Make sure the next descriptor is free. */
+ if( xMicrelDevice.tx_busy[ txHead ] != pdFALSE )
+ {
+ /* All TX buffers busy. */
+ }
+ else if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) == 0 )
+ {
+ /* Output: LS low. */
+ }
+ else
+ {
+ /* Pass the packet. */
+ xMicrelDevice.tx_buffers[ txHead ] = pxNetworkBuffer;
+ /* The descriptor is now owned by Micrel. */
+ xMicrelDevice.tx_busy[ txHead ] = pdTRUE;
+
+ /* Move the head pointer. */
+ if( ++txHead == MICREL_TX_BUFFERS )
+ {
+ txHead = 0;
+ }
+ xMicrelDevice.us_tx_head = txHead;
+ if( xEMACTaskHandle != NULL )
+ {
+ xTaskNotifyGive( xEMACTaskHandle );
+ }
+
+ #if( ipconfigZERO_COPY_TX_DRIVER != 1 )
+ #warning Please ipconfigZERO_COPY_TX_DRIVER as 1
+ #endif
+ configASSERT( bReleaseAfterSend != pdFALSE );
+ xResult = pdTRUE;
+ }
+ if( ( xResult == pdFALSE ) && ( bReleaseAfterSend != pdFALSE ) )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+ return xResult;
+}
+/*-----------------------------------------------------------*/
+
+/* This Micrel has numbered it's PHY registers in a different way.
+Translate the register index. */
+static int ks8851_phy_reg( int reg )
+{
+ switch (reg) {
+ case PHY_REG_00_BMCR:
+ return REG_PHY_CNTL; // P1MBCR;
+ case PHY_REG_01_BMSR:
+ return REG_PHY_STATUS;
+ case PHY_REG_02_PHYSID1:
+ return REG_PHY_ID_LOW;
+ case PHY_REG_03_PHYSID2:
+ return REG_PHY_ID_HIGH;
+ case PHY_REG_04_ADVERTISE:
+ return REG_PHY_AUTO_NEGOTIATION;
+ case PHY_REG_05_LPA:
+ return REG_PHY_REMOTE_CAPABILITY;
+ }
+
+ return 0x0;
+}
+/*-----------------------------------------------------------*/
+
+static inline unsigned long ulReadMDIO( unsigned uAddress )
+{
+uint16_t usPHYStatus;
+int ks8851_reg = ks8851_phy_reg( uAddress );
+
+ if( ks8851_reg != 0 )
+ {
+ usPHYStatus = ksz8851_reg_read( ks8851_reg );
+ }
+ else
+ {
+ /* Other addresses not yet implemented. */
+ usPHYStatus = 0;
+ }
+ return usPHYStatus;
+}
+/*-----------------------------------------------------------*/
+
+static BaseType_t xGMACWaitLS( TickType_t xMaxTime )
+{
+TickType_t xStartTime = xTaskGetTickCount();
+TickType_t xEndTime;
+BaseType_t xReturn;
+const TickType_t xShortTime = pdMS_TO_TICKS( 100UL );
+const uint32_t ulHz_Per_MHz = 1000000UL;
+
+ for( ;; )
+ {
+ xEndTime = xTaskGetTickCount();
+
+ if( ( xEndTime - xStartTime ) > xMaxTime )
+ {
+ /* Wated more than xMaxTime, return. */
+ xReturn = pdFALSE;
+ break;
+ }
+
+ /* Check the link status again. */
+ ulPHYLinkStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ /* Link is up - return. */
+ xReturn = pdTRUE;
+ break;
+ }
+
+ /* Link is down - wait in the Blocked state for a short while (to allow
+ other tasks to execute) before checking again. */
+ vTaskDelay( xShortTime );
+ }
+
+ FreeRTOS_printf( ( "xGMACWaitLS: %ld freq %lu Mz\n",
+ xReturn,
+ sysclk_get_cpu_hz() / ulHz_Per_MHz ) );
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+static void vPioSetPinHigh(uint32_t ul_pin)
+{
+ Pio *p_pio = (Pio *)((uint32_t)PIOA + (PIO_DELTA * (ul_pin >> 5)));
+ // Value to be driven on the I/O line: 1.
+ p_pio->PIO_SODR = 1 << (ul_pin & 0x1F);
+}
+
+/**
+ * \brief Handler for SPI interrupt.
+ */
+void SPI_Handler(void)
+{
+BaseType_t xDoWakeup = pdFALSE;
+BaseType_t xKSZTaskWoken = pdFALSE;
+uint32_t ulCurrentSPIStatus;
+uint32_t ulEnabledSPIStatus;
+
+ ulCurrentSPIStatus = spi_read_status( KSZ8851SNL_SPI );
+ ulEnabledSPIStatus = spi_read_interrupt_mask( KSZ8851SNL_SPI );
+ ulCurrentSPIStatus &= ulEnabledSPIStatus;
+ spi_disable_interrupt( KSZ8851SNL_SPI, ulCurrentSPIStatus );
+
+
+ switch( xMicrelDevice.ul_spi_pdc_status )
+ {
+ case SPI_PDC_RX_START:
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
+ {
+ pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_ERROR;
+ xDoWakeup = pdTRUE;
+ }
+ else
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_RXBUFF ) != 0 )
+ {
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_COMPLETE;
+ xDoWakeup = pdTRUE;
+ }
+ }
+ }
+ break;
+
+ case SPI_PDC_TX_START:
+ {
+ /* Middle of TX. */
+ if( ( ulCurrentSPIStatus & SPI_SR_OVRES ) != 0 )
+ {
+ pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_ERROR;
+ xDoWakeup = pdTRUE;
+ }
+ else
+ {
+ if( ( ulCurrentSPIStatus & SPI_SR_ENDRX ) != 0 )
+ {
+ /* Enable RX complete interrupt. */
+ spi_enable_interrupt( KSZ8851SNL_SPI, SPI_IER_RXBUFF );
+ }
+ /* End of TX. */
+ if( ( ulCurrentSPIStatus & SPI_END_OF_TX ) != 0 )
+ {
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_COMPLETE;
+ xDoWakeup = pdTRUE;
+ }
+ }
+ }
+ break;
+ } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
+
+ if( xDoWakeup != pdFALSE )
+ {
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, ( BaseType_t * ) &xKSZTaskWoken );
+ }
+ }
+ else
+ {
+ }
+ portEND_SWITCHING_ISR( xKSZTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+static void INTN_Handler(uint32_t id, uint32_t mask)
+{
+BaseType_t xKSZTaskWoken = pdFALSE;
+
+ if( ( id == INTN_ID ) &&
+ ( mask == INTN_PIN_MSK ) )
+ {
+ /* Clear the PIO interrupt flags. */
+ pio_get_interrupt_status( INTN_PIO );
+
+ /* Set the INTN flag. */
+ xMicrelDevice.ul_had_intn_interrupt++;
+ if( xEMACTaskHandle != NULL )
+ {
+ vTaskNotifyGiveFromISR( xEMACTaskHandle, &( xKSZTaskWoken ) );
+ }
+ }
+ portEND_SWITCHING_ISR( xKSZTaskWoken );
+}
+/*-----------------------------------------------------------*/
+
+/**
+ * \brief Populate the RX descriptor ring buffers with pbufs.
+ *
+ * \param p_ksz8851snl_dev Pointer to driver data structure.
+ */
+static void ksz8851snl_rx_populate_queue( void )
+{
+ uint32_t ul_index = 0;
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+
+ /* Set up the RX descriptors */
+ for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
+ if( xMicrelDevice.rx_buffers[ ul_index ] == NULL )
+ {
+ /* Allocate a new NetworkBufferDescriptor_t with the maximum size. */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( ipconfigNETWORK_MTU + 36, 100 );
+ if( pxNetworkBuffer == NULL )
+ {
+ FreeRTOS_printf( ( "ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t allocation failure\n" ) );
+ configASSERT( 1 == 2 );
+ }
+
+ /* Make sure lwIP is well configured so one NetworkBufferDescriptor_t can contain the maximum packet size. */
+ //LWIP_ASSERT("ksz8851snl_rx_populate_queue: NetworkBufferDescriptor_t size too small!", pbuf_clen(pxNetworkBuffer) <= 1);
+
+ /* Save NetworkBufferDescriptor_t pointer to be sent to lwIP upper layer. */
+ xMicrelDevice.rx_buffers[ ul_index ] = pxNetworkBuffer;
+ /* Pass it to Micrel for reception. */
+ xMicrelDevice.rx_ready[ ul_index ] = pdFALSE;
+ }
+ }
+}
+
+unsigned tx_space, wait_tx_space, tx_status, fhr_status;
+unsigned rx_debug = 0;
+/**
+ * \brief Update Micrel state machine and perform required actions.
+ *
+ * \param netif the lwIP network interface structure for this ethernetif.
+ */
+static void ksz8851snl_update()
+{
+ uint16_t txmir = 0;
+
+/* Check for free PDC. */
+ switch( xMicrelDevice.ul_spi_pdc_status )
+ {
+ case SPI_PDC_TX_ERROR:
+ {
+ uint32_t ulValue;
+ // /* TX step11: end TX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* TX step12: disable TXQ write access. */
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+
+ ulValue = ksz8851snl_reset_tx();
+
+ xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
+
+ FreeRTOS_printf( ("SPI_PDC_TX_ERROR %02X\n", ulValue ) );
+ }
+ break;
+
+ case SPI_PDC_RX_ERROR:
+ {
+ uint32_t ulValue;
+ /* TX step11: end TX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ vTaskDelay( 2 ); gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 ); gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+ vTaskDelay( 1 );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* TX step12: disable TXQ write access. */
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+
+ //ulValue = ksz8851snl_reset_rx();
+ ulValue = ksz8851snl_reinit();
+
+ xGMACWaitLS( pdMS_TO_TICKS( 5000UL ) );
+
+ FreeRTOS_printf( ("SPI_PDC_RX_ERROR %02X\n", ulValue ) );
+ }
+ break;
+ }
+ switch( xMicrelDevice.ul_spi_pdc_status )
+ {
+ case SPI_PDC_IDLE:
+ {
+ int txTail = xMicrelDevice.us_tx_tail;
+
+ /*
+ * ========================== Handle RX ==========================
+ */
+ if( ( xMicrelDevice.ul_had_intn_interrupt != 0 ) || ( xMicrelDevice.us_pending_frame > 0 ) )
+ {
+ int rxHead = xMicrelDevice.us_rx_head;
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+#warning try
+ xMicrelDevice.ul_had_intn_interrupt = 0;
+
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ uint16_t int_status;
+ /* RX step1: read interrupt status for INT_RX flag. */
+ int_status = ksz8851_reg_read( REG_INT_STATUS );
+
+
+ /* RX step2: disable all interrupts. */
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+
+ /* RX step3: clear INT_RX flag. */
+ ksz8851_reg_setbits( REG_INT_STATUS, INT_RX );
+
+ /* RX step4-5: check for received frames. */
+ xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ /* RX step24: enable INT_RX flag. */
+ ksz8851_reg_write(REG_INT_MASK, INT_RX);
+ return;
+ }
+ }
+#warning try
+ xMicrelDevice.ul_had_intn_interrupt = 0;
+
+ /* Now xMicrelDevice.us_pending_frame != 0 */
+
+ /* Don't break Micrel state machine, wait for a free descriptor first! */
+ if( xMicrelDevice.rx_ready[ rxHead ] != pdFALSE )
+ {
+ FreeRTOS_printf( ( "ksz8851snl_update: out of free descriptor! [tail=%u head=%u]\n",
+ xMicrelDevice.us_rx_tail, rxHead ) );
+ return;
+ }
+ pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxHead ];
+
+ if( pxNetworkBuffer == NULL )
+ {
+ ksz8851snl_rx_populate_queue();
+ FreeRTOS_printf( ( "ksz8851snl_update: no buffer set [head=%u]\n", rxHead ) );
+ return;
+ }
+
+ /* RX step6: get RX packet status. */
+ fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
+ if( ( ( fhr_status & RX_VALID ) == 0 ) || ( ( fhr_status & RX_ERRORS ) != 0 ) )
+ {
+ ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_CMD_FREE_PACKET);
+ FreeRTOS_printf( ( "ksz8851snl_update: RX packet error!\n" ) );
+
+ /* RX step4-5: check for received frames. */
+ xMicrelDevice.us_pending_frame = ksz8851_reg_read(REG_RX_FRAME_CNT_THRES) >> 8;
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ /* RX step24: enable INT_RX flag. */
+ ksz8851_reg_write(REG_INT_MASK, INT_RX);
+ }
+ ulISREvents |= EMAC_IF_ERR_EVENT;
+ }
+ else
+ {
+ size_t xLength;
+ /* RX step7: read frame length. */
+ xLength = ksz8851_reg_read(REG_RX_FHR_BYTE_CNT) & RX_BYTE_CNT_MASK;
+
+ /* RX step8: Drop packet if len is invalid or no descriptor available. */
+ if( xLength == 0 )
+ {
+ ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_CMD_FREE_PACKET );
+ FreeRTOS_printf( ( "ksz8851snl_update: RX bad len!\n" ) );
+ ulISREvents |= EMAC_IF_ERR_EVENT;
+ }
+ else
+ {
+ size_t xReadLength = xLength;
+
+ xMicrelDevice.ul_total_rx++;
+ /* RX step9: reset RX frame pointer. */
+ ksz8851_reg_clrbits(REG_RX_ADDR_PTR, ADDR_PTR_MASK);
+
+ /* RX step10: start RXQ read access. */
+ ksz8851_reg_setbits(REG_RXQ_CMD, RXQ_START);
+ /* RX step11-17: start asynchronous FIFO read operation. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_RX_START;
+ gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ if( ( xReadLength & ( sizeof( size_t ) - 1 ) ) != 0 )
+ {
+ xReadLength = ( xReadLength | ( sizeof( size_t ) - 1 ) ) + 1;
+ }
+
+ /* Pass the buffer minus 2 bytes, see ksz8851snl.c: RXQ_TWOBYTE_OFFSET. */
+ ksz8851_fifo_read( pxNetworkBuffer->pucEthernetBuffer - 2, xReadLength );
+ /* Remove CRC and update buffer length. */
+ xLength -= 4;
+ pxNetworkBuffer->xDataLength = xLength;
+ /* Wait for SPI interrupt to set status 'SPI_PDC_RX_COMPLETE'. */
+ }
+ }
+ break;
+ } /* ul_had_intn_interrupt || us_pending_frame */
+ /*
+ * ========================== Handle TX ==========================
+ */
+
+ /* Fetch next packet to be sent. */
+ if( ( xMicrelDevice.tx_busy[ txTail ] != pdFALSE ) &&
+ ( xMicrelDevice.us_pending_frame == 0 ) &&
+ ( xMicrelDevice.ul_had_intn_interrupt == 0 ) )
+ {
+ NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
+ size_t xLength = pxNetworkBuffer->xDataLength;
+ int iIndex = xLength;
+
+ xLength = 4 * ( ( xLength + 3 ) / 4 );
+ while( iIndex < ( int ) xLength )
+ {
+ pxNetworkBuffer->pucEthernetBuffer[ iIndex ] = '\0';
+ iIndex++;
+ }
+ pxNetworkBuffer->xDataLength = xLength;
+
+ /* TX step1: check if TXQ memory size is available for transmit. */
+ txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
+ txmir = txmir & TX_MEM_AVAILABLE_MASK;
+
+ if( txmir < ( xLength + 8 ) )
+ {
+ if( wait_tx_space == pdFALSE )
+ {
+ tx_status = ksz8851_reg_read( REG_TX_STATUS );
+ fhr_status = ksz8851_reg_read( REG_RX_FHR_STATUS );
+ wait_tx_space = pdTRUE;
+ }
+ //return;
+ rx_debug = 1;
+ tx_space = txmir;
+ }
+ else
+ {
+ tx_space = txmir;
+
+ /* TX step2: disable all interrupts. */
+ ksz8851_reg_write( REG_INT_MASK, 0 );
+
+ xMicrelDevice.tx_space -= xLength;
+
+ /* TX step3: enable TXQ write access. */
+ ksz8851_reg_setbits( REG_RXQ_CMD, RXQ_START );
+ /* TX step4-8: perform FIFO write operation. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_TX_START;
+ xMicrelDevice.tx_cur_buffer = pxNetworkBuffer;
+ /* Bring SPI SS low. */
+ gpio_set_pin_low( KSZ8851SNL_CSN_GPIO );
+ xMicrelDevice.ul_total_tx++;
+
+ ksz8851_fifo_write( pxNetworkBuffer->pucEthernetBuffer, xLength, xLength );
+ }
+ }
+ }
+ break; /* SPI_PDC_IDLE */
+
+ case SPI_PDC_RX_COMPLETE:
+ {
+ int rxHead = xMicrelDevice.us_rx_head;
+ /* RX step18-19: pad with dummy data to keep dword alignment. */
+ /* Packet lengths will be rounded up to a multiple of "sizeof size_t". */
+// xLength = xMicrelDevice.rx_buffers[ rxHead ]->xDataLength & 3;
+// if( xLength != 0 )
+// {
+// ksz8851_fifo_dummy( 4 - xLength );
+// }
+
+ /* RX step20: end RX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* RX step21: end RXQ read access. */
+ ksz8851_reg_clrbits(REG_RXQ_CMD, RXQ_START);
+
+ /* RX step22-23: update frame count to be read. */
+ xMicrelDevice.us_pending_frame -= 1;
+
+ /* RX step24: enable INT_RX flag if transfer complete. */
+ if( xMicrelDevice.us_pending_frame == 0 )
+ {
+ ksz8851_reg_write(REG_INT_MASK, INT_RX);
+ }
+
+ /* Mark descriptor ready to be read. */
+ xMicrelDevice.rx_ready[ rxHead ] = pdTRUE;
+ if( ++rxHead == MICREL_RX_BUFFERS )
+ {
+ rxHead = 0;
+ }
+ xMicrelDevice.us_rx_head = rxHead;
+ if( rx_debug != 0 )
+ {
+ uint32_t txmir;
+ rx_debug = 0;
+ txmir = ksz8851_reg_read( REG_TX_MEM_INFO );
+ txmir = txmir & TX_MEM_AVAILABLE_MASK;
+ }
+ /* Tell prvEMACHandlerTask that RX packets are available. */
+ ulISREvents |= EMAC_IF_RX_EVENT;
+ } /* case SPI_PDC_RX_COMPLETE */
+ break;
+
+ case SPI_PDC_TX_COMPLETE:
+ {
+ int txTail = xMicrelDevice.us_tx_tail;
+ NetworkBufferDescriptor_t *pxNetworkBuffer = xMicrelDevice.tx_buffers[ txTail ];
+
+ size_t xLength;
+ /* TX step9-10: pad with dummy data to keep dword alignment. */
+ /* Not necessary: length is already a multiple of 4. */
+ xLength = pxNetworkBuffer->xDataLength & 3;
+ if( xLength != 0 )
+ {
+// ksz8851_fifo_dummy( 4 - xLength );
+ }
+
+// /* TX step11: end TX transfer. */
+ gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
+
+ /* Disable asynchronous transfer mode. */
+ xMicrelDevice.ul_spi_pdc_status = SPI_PDC_IDLE;
+
+ /* TX step12: disable TXQ write access. */
+ ksz8851_reg_clrbits( REG_RXQ_CMD, RXQ_START );
+
+ xMicrelDevice.tx_space = ksz8851_reg_read( REG_TX_MEM_INFO ) & TX_MEM_AVAILABLE_MASK;
+
+ /* TX step12.1: enqueue frame in TXQ. */
+ ksz8851_reg_setbits( REG_TXQ_CMD, TXQ_ENQUEUE );
+
+ /* RX step13: enable INT_RX flag. */
+// ksz8851_reg_write( REG_INT_MASK, INT_RX );
+ /* Buffer sent, free the corresponding buffer and mark descriptor as owned by software. */
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+
+ xMicrelDevice.tx_buffers[ txTail ] = NULL;
+ xMicrelDevice.tx_busy[ txTail ] = pdFALSE;
+ if( ++txTail == MICREL_TX_BUFFERS )
+ {
+ txTail = 0;
+ }
+
+ xMicrelDevice.us_tx_tail = txTail;
+ /* Experiment. */
+ //xMicrelDevice.ul_had_intn_interrupt = 1;
+ if( xTransmitHandle != NULL )
+ {
+ xTaskNotifyGive( xTransmitHandle );
+ }
+#warning moved downward
+ /* RX step13: enable INT_RX flag. */
+ ksz8851_reg_write( REG_INT_MASK, INT_RX );
+ /* Prevent the EMAC task from sleeping a single time. */
+ ulISREvents |= EMAC_IF_TX_EVENT;
+ } /* case SPI_PDC_TX_COMPLETE */
+ break;
+ } /* switch( xMicrelDevice.ul_spi_pdc_status ) */
+}
+
+/**
+ * \brief Set up the RX descriptor ring buffers.
+ *
+ * This function sets up the descriptor list used for RX packets.
+ *
+ */
+static void ksz8851snl_rx_init()
+{
+ uint32_t ul_index = 0;
+
+ /* Init pointer index. */
+ xMicrelDevice.us_rx_head = 0;
+ xMicrelDevice.us_rx_tail = 0;
+
+ /* Set up the RX descriptors. */
+ for (ul_index = 0; ul_index < MICREL_RX_BUFFERS; ul_index++) {
+ xMicrelDevice.rx_buffers[ul_index] = NULL;
+ xMicrelDevice.rx_ready[ul_index] = pdFALSE;
+ }
+
+ /* Build RX buffer and descriptors. */
+ ksz8851snl_rx_populate_queue();
+}
+
+/**
+ * \brief Set up the TX descriptor ring buffers.
+ *
+ * This function sets up the descriptor list used for TX packets.
+ *
+ */
+static void ksz8851snl_tx_init()
+{
+ uint32_t ul_index = 0;
+
+ /* Init TX index pointer. */
+ xMicrelDevice.us_tx_head = 0;
+ xMicrelDevice.us_tx_tail = 0;
+
+ /* Set up the TX descriptors */
+ for( ul_index = 0; ul_index < MICREL_TX_BUFFERS; ul_index++ )
+ {
+ xMicrelDevice.tx_busy[ul_index] = pdFALSE;
+ }
+ xMicrelDevice.tx_space = 6144;
+}
+
+/**
+ * \brief Initialize ksz8851snl ethernet controller.
+ *
+ * \note Called from ethernetif_init().
+ *
+ * \param netif the lwIP network interface structure for this ethernetif.
+ */
+static void ksz8851snl_low_level_init( void )
+{
+ ksz8851snl_rx_init();
+ ksz8851snl_tx_init();
+
+ /* Enable NVIC interrupts. */
+ NVIC_SetPriority(SPI_IRQn, INT_PRIORITY_SPI);
+ NVIC_EnableIRQ(SPI_IRQn);
+
+ /* Initialize SPI link. */
+ if( ksz8851snl_init() < 0 )
+ {
+ FreeRTOS_printf( ( "ksz8851snl_low_level_init: failed to initialize the Micrel driver!\n" ) );
+ configASSERT(0 == 1);
+ }
+ memset( xMicrelDevice.pusHashTable, 255, sizeof( xMicrelDevice.pusHashTable ) );
+ ksz8851_reg_write( REG_MAC_HASH_0, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 0 ] ) );
+ ksz8851_reg_write( REG_MAC_HASH_2, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 1 ] ) );
+ ksz8851_reg_write( REG_MAC_HASH_4, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 2 ] ) );
+ ksz8851_reg_write( REG_MAC_HASH_6, FreeRTOS_htons( xMicrelDevice.pusHashTable[ 3 ] ) );
+
+ /* Initialize interrupt line INTN. */
+ configure_intn( INTN_Handler );
+}
+
+/**
+ * \brief Use pre-allocated pbuf as DMA source and return the incoming packet.
+ *
+ * \param netif the lwIP network interface structure for this ethernetif.
+ *
+ * \return a pbuf filled with the received packet (including MAC header).
+ * 0 on memory error.
+ */
+static NetworkBufferDescriptor_t *ksz8851snl_low_level_input( void )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer = NULL;
+int rxTail = xMicrelDevice.us_rx_tail;
+
+ /* Check that descriptor is owned by software (ie packet received). */
+ if( xMicrelDevice.rx_ready[ rxTail ] != pdFALSE )
+ {
+
+ /* Fetch pre-allocated buffer */
+ pxNetworkBuffer = xMicrelDevice.rx_buffers[ rxTail ];
+
+ /* Remove this pbuf from its descriptor. */
+ xMicrelDevice.rx_buffers[ rxTail ] = NULL;
+
+ /* Clears rx_ready and sets rx_buffers. */
+ ksz8851snl_rx_populate_queue();
+
+ if( ++rxTail == MICREL_RX_BUFFERS )
+ {
+ rxTail = 0;
+ }
+ xMicrelDevice.us_rx_tail = rxTail;
+ }
+
+ return pxNetworkBuffer;
+}
+/*-----------------------------------------------------------*/
+
+static uint32_t prvEMACRxPoll( void )
+{
+NetworkBufferDescriptor_t *pxNetworkBuffer;
+IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+uint32_t ulReturnValue = 0;
+
+ for( ;; )
+ {
+ /* Only for logging. */
+ int rxTail = xMicrelDevice.us_rx_tail;
+ EthernetHeader_t *pxEthernetHeader;
+
+ pxNetworkBuffer = ksz8851snl_low_level_input();
+
+ if( pxNetworkBuffer == NULL )
+ {
+ break;
+ }
+ pxEthernetHeader = ( EthernetHeader_t * ) ( pxNetworkBuffer->pucEthernetBuffer );
+
+ if( ( pxEthernetHeader->usFrameType != ipIPv4_FRAME_TYPE ) &&
+ ( pxEthernetHeader->usFrameType != ipARP_FRAME_TYPE ) )
+ {
+ FreeRTOS_printf( ( "Frame type %02X received\n", pxEthernetHeader->usFrameType ) );
+ }
+ ulReturnValue++;
+
+ xRxEvent.pvData = ( void * )pxNetworkBuffer;
+ /* Send the descriptor to the IP task for processing. */
+ if( xSendEventStructToIPTask( &xRxEvent, 100UL ) != pdTRUE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ iptraceETHERNET_RX_EVENT_LOST();
+ FreeRTOS_printf( ( "prvEMACRxPoll: Can not queue return packet!\n" ) );
+ }
+ }
+
+ return ulReturnValue;
+}
+/*-----------------------------------------------------------*/
+
+static void prvEMACHandlerTask( void *pvParameters )
+{
+TimeOut_t xPhyTime;
+TickType_t xPhyRemTime;
+TickType_t xLoggingTime;
+UBaseType_t uxLastMinBufferCount = 0;
+UBaseType_t uxCurrentCount;
+BaseType_t xResult = 0;
+uint32_t xStatus;
+const TickType_t ulMaxBlockTime = pdMS_TO_TICKS( EMAC_MAX_BLOCK_TIME_MS );
+#if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ UBaseType_t uxLastMinQueueSpace = 0;
+#endif
+
+ /* Remove compiler warnings about unused parameters. */
+ ( void ) pvParameters;
+
+ configASSERT( xEMACTaskHandle );
+
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ xLoggingTime = xTaskGetTickCount();
+
+ for( ;; )
+ {
+ uxCurrentCount = uxGetMinimumFreeNetworkBuffers();
+ if( uxLastMinBufferCount != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinBufferCount = uxCurrentCount;
+ FreeRTOS_printf( ( "Network buffers: %lu lowest %lu\n",
+ uxGetNumberOfFreeNetworkBuffers(), uxCurrentCount ) );
+ }
+
+ #if( ipconfigCHECK_IP_QUEUE_SPACE != 0 )
+ {
+ uxCurrentCount = uxGetMinimumIPQueueSpace();
+ if( uxLastMinQueueSpace != uxCurrentCount )
+ {
+ /* The logging produced below may be helpful
+ while tuning +TCP: see how many buffers are in use. */
+ uxLastMinQueueSpace = uxCurrentCount;
+ FreeRTOS_printf( ( "Queue space: lowest %lu\n", uxCurrentCount ) );
+ }
+ }
+ #endif /* ipconfigCHECK_IP_QUEUE_SPACE */
+
+ /* Run the state-machine of the ksz8851 driver. */
+ ksz8851snl_update();
+
+ if( ( ulISREvents & EMAC_IF_ALL_EVENT ) == 0 )
+ {
+ /* No events to process now, wait for the next. */
+ ulTaskNotifyTake( pdTRUE, ulMaxBlockTime );
+ }
+
+ if( ( xTaskGetTickCount() - xLoggingTime ) > 10000 )
+ {
+ xLoggingTime += 10000;
+ FreeRTOS_printf( ( "Now Tx/Rx %7d /%7d\n",
+ xMicrelDevice.ul_total_tx, xMicrelDevice.ul_total_rx ) );
+ }
+
+ if( ( ulISREvents & EMAC_IF_RX_EVENT ) != 0 )
+ {
+ ulISREvents &= ~EMAC_IF_RX_EVENT;
+
+ /* Wait for the EMAC interrupt to indicate that another packet has been
+ received. */
+ xResult = prvEMACRxPoll();
+ }
+
+ if( ( ulISREvents & EMAC_IF_TX_EVENT ) != 0 )
+ {
+ /* Future extension: code to release TX buffers if zero-copy is used. */
+ ulISREvents &= ~EMAC_IF_TX_EVENT;
+ }
+
+ if( ( ulISREvents & EMAC_IF_ERR_EVENT ) != 0 )
+ {
+ /* Future extension: logging about errors that occurred. */
+ ulISREvents &= ~EMAC_IF_ERR_EVENT;
+ }
+
+ if( xResult > 0 )
+ {
+ /* As long as packets are being received, assume that
+ the Link Status is high. */
+ ulPHYLinkStatus |= BMSR_LINK_STATUS;
+ /* A packet was received. No need to check for the PHY status now,
+ but set a timer to check it later on. */
+ vTaskSetTimeOutState( &xPhyTime );
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ xResult = 0;
+ }
+ else if( ( xTaskCheckForTimeOut( &xPhyTime, &xPhyRemTime ) != pdFALSE ) &&
+ ( xMicrelDevice.ul_spi_pdc_status == SPI_PDC_IDLE ) )
+ {
+ /* Check the link status again. */
+ xStatus = ulReadMDIO( PHY_REG_01_BMSR );
+
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != ( xStatus & BMSR_LINK_STATUS ) )
+ {
+ ulPHYLinkStatus = xStatus;
+ FreeRTOS_printf( ( "prvEMACHandlerTask: PHY LS now %d\n", ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 ) );
+ }
+
+ vTaskSetTimeOutState( &xPhyTime );
+ if( ( ulPHYLinkStatus & BMSR_LINK_STATUS ) != 0 )
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_HIGH_CHECK_TIME_MS );
+ }
+ else
+ {
+ xPhyRemTime = pdMS_TO_TICKS( PHY_LS_LOW_CHECK_TIME_MS );
+ }
+ }
+ }
+}
+/*-----------------------------------------------------------*/
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.c
deleted file mode 100644
index 1579863fe..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.c
+++ /dev/null
@@ -1,610 +0,0 @@
-/**
- *
- * \file
- *
- * \brief KS8851SNL driver for SAM.
- *
- * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
- */
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-
-#include "spi_master.h"
-#include "ksz8851snl.h"
-#include "ksz8851snl_reg.h"
-#include "delay.h"
-#include "pio.h"
-#include "pio_handler.h"
-#include "pdc.h"
-#include "conf_eth.h"
-
-/* Clock polarity. */
-#define SPI_CLK_POLARITY 0
-
-/* Clock phase. */
-#define SPI_CLK_PHASE 1
-
-/* SPI PDC register base. */
-Pdc *g_p_spi_pdc = 0;
-
-int lUDPLoggingPrintf( const char *pcFormatString, ... );
-
-/* Temporary buffer for PDC reception. */
-uint8_t tmpbuf[1536] __attribute__ ((aligned (16)));
-
-union {
- uint64_t ul[2];
- uint8_t uc[16];
-} cmdBuf, respBuf;
-
-void dbg_add_line( const char *pcFormat, ... );
-
-static void spi_clear_ovres( void );
-
-/**
- * \brief Read register content, set bitmask and write back to register.
- *
- * \param reg the register address to modify.
- * \param bits_to_set bitmask to apply.
- */
-void ksz8851_reg_setbits(uint16_t reg, uint16_t bits_to_set)
-{
- uint16_t temp;
-
- temp = ksz8851_reg_read(reg);
- temp |= bits_to_set;
- ksz8851_reg_write(reg, temp);
-}
-
-/**
- * \brief Read register content, clear bitmask and write back to register.
- *
- * \param reg the register address to modify.
- * \param bits_to_set bitmask to apply.
- */
-void ksz8851_reg_clrbits(uint16_t reg, uint16_t bits_to_clr)
-{
- uint16_t temp;
-
- temp = ksz8851_reg_read(reg);
- temp &= ~(uint32_t) bits_to_clr;
- ksz8851_reg_write(reg, temp);
-}
-
-/**
- * \brief Configure the INTN interrupt.
- */
-void configure_intn(void (*p_handler) (uint32_t, uint32_t))
-{
-// gpio_configure_pin(KSZ8851SNL_INTN_GPIO, PIO_INPUT);
-// pio_set_input(PIOA, PIO_PA11_IDX, PIO_PULLUP);
-
- /* Configure PIO clock. */
- pmc_enable_periph_clk(INTN_ID);
-
- /* Adjust PIO debounce filter parameters, uses 10 Hz filter. */
- pio_set_debounce_filter(INTN_PIO, INTN_PIN_MSK, 10);
-
- /* Initialize PIO interrupt handlers, see PIO definition in board.h. */
- pio_handler_set(INTN_PIO, INTN_ID, INTN_PIN_MSK,
- INTN_ATTR, p_handler);
-
- /* Enable NVIC interrupts. */
- NVIC_SetPriority(INTN_IRQn, INT_PRIORITY_PIO);
- NVIC_EnableIRQ((IRQn_Type)INTN_ID);
-
- /* Enable PIO interrupts. */
- pio_enable_interrupt(INTN_PIO, INTN_PIN_MSK);
-}
-
-/**
- * \brief Read a register value.
- *
- * \param reg the register address to modify.
- *
- * \return the register value.
- */
-uint16_t ksz8851_reg_read(uint16_t reg)
-{
-pdc_packet_t g_pdc_spi_tx_packet;
-pdc_packet_t g_pdc_spi_rx_packet;
-uint16_t cmd = 0;
-uint16_t res = 0;
-int iTryCount = 3;
-
- while( iTryCount-- > 0 )
- {
- uint32_t ulStatus;
-
- spi_clear_ovres();
- /* Move register address to cmd bits 9-2, make 32-bit address. */
- cmd = (reg << 2) & REG_ADDR_MASK;
-
- /* Last 2 bits still under "don't care bits" handled with byte enable. */
- /* Select byte enable for command. */
- if (reg & 2) {
- /* Odd word address writes bytes 2 and 3 */
- cmd |= (0xc << 10);
- } else {
- /* Even word address write bytes 0 and 1 */
- cmd |= (0x3 << 10);
- }
-
- /* Add command read code. */
- cmd |= CMD_READ;
- cmdBuf.uc[0] = cmd >> 8;
- cmdBuf.uc[1] = cmd & 0xff;
- cmdBuf.uc[2] = CONFIG_SPI_MASTER_DUMMY;
- cmdBuf.uc[3] = CONFIG_SPI_MASTER_DUMMY;
-
- /* Prepare PDC transfer. */
- g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
- g_pdc_spi_tx_packet.ul_size = 4;
- g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
- g_pdc_spi_rx_packet.ul_size = 4;
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, NULL);
- pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, NULL);
- gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);
-
- spi_disable_interrupt( KSZ8851SNL_SPI, ~0ul );
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
- for( ;; )
- {
- ulStatus = spi_read_status( KSZ8851SNL_SPI );
- if( ( ulStatus & ( SPI_SR_OVRES | SPI_SR_ENDRX ) ) != 0 )
- {
- break;
- }
- }
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
- if( ( ulStatus & SPI_SR_OVRES ) == 0 )
- {
- break;
- }
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- lUDPLoggingPrintf( "ksz8851_reg_read: SPI_SR_OVRES\n" );
- }
-
- res = (tmpbuf[3] << 8) | tmpbuf[2];
- return res;
-}
-
-/**
- * \brief Write a register value.
- *
- * \param reg the register address to modify.
- * \param wrdata the new register value.
- */
-void ksz8851_reg_write(uint16_t reg, uint16_t wrdata)
-{
-pdc_packet_t g_pdc_spi_tx_packet;
-pdc_packet_t g_pdc_spi_rx_packet;
-uint16_t cmd = 0;
-int iTryCount = 3;
-
- while( iTryCount-- > 0 )
- {
- uint32_t ulStatus;
-
-
- spi_clear_ovres();
- /* Move register address to cmd bits 9-2, make 32-bit address. */
- cmd = (reg << 2) & REG_ADDR_MASK;
-
- /* Last 2 bits still under "don't care bits" handled with byte enable. */
- /* Select byte enable for command. */
- if (reg & 2) {
- /* Odd word address writes bytes 2 and 3 */
- cmd |= (0xc << 10);
- } else {
- /* Even word address write bytes 0 and 1 */
- cmd |= (0x3 << 10);
- }
-
- /* Add command write code. */
- cmd |= CMD_WRITE;
- cmdBuf.uc[0] = cmd >> 8;
- cmdBuf.uc[1] = cmd & 0xff;
- cmdBuf.uc[2] = wrdata & 0xff;
- cmdBuf.uc[3] = wrdata >> 8;
-
- /* Prepare PDC transfer. */
- g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
- g_pdc_spi_tx_packet.ul_size = 4;
- g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
- g_pdc_spi_rx_packet.ul_size = 4;
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, NULL);
- pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, NULL);
- gpio_set_pin_low(KSZ8851SNL_CSN_GPIO);
-
- spi_disable_interrupt( KSZ8851SNL_SPI, ~0ul );
-
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
- for( ;; )
- {
- ulStatus = spi_read_status( KSZ8851SNL_SPI );
- if( ( ulStatus & ( SPI_SR_OVRES | SPI_SR_ENDRX ) ) != 0 )
- {
- break;
- }
- }
- gpio_set_pin_high( KSZ8851SNL_CSN_GPIO );
- if( ( ulStatus & SPI_SR_OVRES ) == 0 )
- {
- break;
- }
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- lUDPLoggingPrintf( "ksz8851_reg_write: SPI_SR_OVRES\n" );
- }
-}
-
-static void spi_clear_ovres( void )
-{
-volatile uint32_t rc;
- rc = KSZ8851SNL_SPI->SPI_RDR;
-
- spi_read_status( KSZ8851SNL_SPI );
-}
-
-/**
- * \brief Read internal fifo buffer.
- *
- * \param buf the buffer to store the data from the fifo buffer.
- * \param len the amount of data to read.
- */
-void ksz8851_fifo_read(uint8_t *buf, uint32_t len)
-{
- pdc_packet_t g_pdc_spi_tx_packet;
- pdc_packet_t g_pdc_spi_rx_packet;
- pdc_packet_t g_pdc_spi_tx_npacket;
- pdc_packet_t g_pdc_spi_rx_npacket;
-
- memset( cmdBuf.uc, '\0', sizeof cmdBuf );
- cmdBuf.uc[0] = FIFO_READ;
- spi_clear_ovres();
-
- /* Prepare PDC transfer. */
- g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
- g_pdc_spi_tx_packet.ul_size = 9;
- g_pdc_spi_rx_packet.ul_addr = (uint32_t) respBuf.uc;
- g_pdc_spi_rx_packet.ul_size = 9;
-
- g_pdc_spi_tx_npacket.ul_addr = (uint32_t) buf;
- g_pdc_spi_tx_npacket.ul_size = len;
- g_pdc_spi_rx_npacket.ul_addr = (uint32_t) buf;
- g_pdc_spi_rx_npacket.ul_size = len;
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, &g_pdc_spi_tx_npacket);
- pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, &g_pdc_spi_rx_npacket);
-
-spi_enable_interrupt(KSZ8851SNL_SPI, SPI_IER_RXBUFF | SPI_IER_OVRES);
-
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
-}
-
-/**
- * \brief Write internal fifo buffer.
- *
- * \param buf the buffer to send to the fifo buffer.
- * \param ulActualLength the total amount of data to write.
- * \param ulFIFOLength the size of the first pbuf to write from the pbuf chain.
- */
-void ksz8851_fifo_write(uint8_t *buf, uint32_t ulActualLength, uint32_t ulFIFOLength)
-{
- static uint8_t frameID = 0;
-
- pdc_packet_t g_pdc_spi_tx_packet;
- pdc_packet_t g_pdc_spi_rx_packet;
- pdc_packet_t g_pdc_spi_tx_npacket;
- pdc_packet_t g_pdc_spi_rx_npacket;
-
- /* Prepare control word and byte count. */
- cmdBuf.uc[0] = FIFO_WRITE;
- cmdBuf.uc[1] = frameID++ & 0x3f;
- cmdBuf.uc[2] = 0;
- cmdBuf.uc[3] = ulActualLength & 0xff;
- cmdBuf.uc[4] = ulActualLength >> 8;
-
- spi_clear_ovres();
-
- /* Prepare PDC transfer. */
- g_pdc_spi_tx_packet.ul_addr = (uint32_t) cmdBuf.uc;
- g_pdc_spi_tx_packet.ul_size = 5;
-
- g_pdc_spi_rx_packet.ul_addr = (uint32_t) respBuf.uc;
- g_pdc_spi_rx_packet.ul_size = 5;
-
- g_pdc_spi_tx_npacket.ul_addr = (uint32_t) buf;
- g_pdc_spi_tx_npacket.ul_size = ulFIFOLength;
-
- g_pdc_spi_rx_npacket.ul_addr = (uint32_t) tmpbuf;
- g_pdc_spi_rx_npacket.ul_size = ulFIFOLength;
-
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, &g_pdc_spi_tx_npacket);
- #if( TX_USES_RECV == 1 )
- pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, &g_pdc_spi_rx_npacket);
- spi_enable_interrupt(KSZ8851SNL_SPI, SPI_IER_ENDRX | SPI_IER_OVRES);
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
- #else
- spi_enable_interrupt(KSZ8851SNL_SPI, SPI_SR_TXBUFE | SPI_IER_OVRES);
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_TXTEN);
- #endif
-}
-
-/**
- * \brief Write dummy data to the internal fifo buffer.
- *
- * \param len the amount of dummy data to write.
- */
-void ksz8851_fifo_dummy(uint32_t len)
-{
- pdc_packet_t g_pdc_spi_tx_packet;
- pdc_packet_t g_pdc_spi_rx_packet;
-
- /* Prepare PDC transfer. */
- g_pdc_spi_tx_packet.ul_addr = (uint32_t) tmpbuf;
- g_pdc_spi_tx_packet.ul_size = len;
- g_pdc_spi_rx_packet.ul_addr = (uint32_t) tmpbuf;
- g_pdc_spi_rx_packet.ul_size = len;
- pdc_disable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS);
- pdc_tx_init(g_p_spi_pdc, &g_pdc_spi_tx_packet, NULL);
- pdc_rx_init(g_p_spi_pdc, &g_pdc_spi_rx_packet, NULL);
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
-
- while (!(spi_read_status(KSZ8851SNL_SPI) & SPI_SR_ENDRX))
- ;
-}
-
-void ksz8851snl_set_registers(void)
-{
- /* Init step2-4: write QMU MAC address (low, middle then high). */
- ksz8851_reg_write(REG_MAC_ADDR_0, (ETHERNET_CONF_ETHADDR4 << 8) | ETHERNET_CONF_ETHADDR5);
- ksz8851_reg_write(REG_MAC_ADDR_2, (ETHERNET_CONF_ETHADDR2 << 8) | ETHERNET_CONF_ETHADDR3);
- ksz8851_reg_write(REG_MAC_ADDR_4, (ETHERNET_CONF_ETHADDR0 << 8) | ETHERNET_CONF_ETHADDR1);
-
- /* Init step5: enable QMU Transmit Frame Data Pointer Auto Increment. */
- ksz8851_reg_write(REG_TX_ADDR_PTR, ADDR_PTR_AUTO_INC);
-
- /* Init step6: configure QMU transmit control register. */
- ksz8851_reg_write(REG_TX_CTRL,
- TX_CTRL_ICMP_CHECKSUM |
- TX_CTRL_UDP_CHECKSUM |
- TX_CTRL_TCP_CHECKSUM |
- TX_CTRL_IP_CHECKSUM |
- TX_CTRL_FLOW_ENABLE |
- TX_CTRL_PAD_ENABLE |
- TX_CTRL_CRC_ENABLE
- );
-
- /* Init step7: enable QMU Receive Frame Data Pointer Auto Increment. */
- ksz8851_reg_write(REG_RX_ADDR_PTR, ADDR_PTR_AUTO_INC);
-
- /* Init step8: configure QMU Receive Frame Threshold for one frame. */
- ksz8851_reg_write(REG_RX_FRAME_CNT_THRES, 1);
-
- /* Init step9: configure QMU receive control register1. */
- ksz8851_reg_write(REG_RX_CTRL1,
- RX_CTRL_UDP_CHECKSUM |
- RX_CTRL_TCP_CHECKSUM |
- RX_CTRL_IP_CHECKSUM |
- RX_CTRL_MAC_FILTER |
- RX_CTRL_FLOW_ENABLE |
- RX_CTRL_BROADCAST |
- RX_CTRL_ALL_MULTICAST|
- RX_CTRL_UNICAST);
-// ksz8851_reg_write(REG_RX_CTRL1,
-// RX_CTRL_UDP_CHECKSUM |
-// RX_CTRL_TCP_CHECKSUM |
-// RX_CTRL_IP_CHECKSUM |
-// RX_CTRL_FLOW_ENABLE |
-// RX_CTRL_PROMISCUOUS);
-
- ksz8851_reg_write(REG_RX_CTRL2,
- RX_CTRL_IPV6_UDP_NOCHECKSUM |
- RX_CTRL_UDP_LITE_CHECKSUM |
- RX_CTRL_ICMP_CHECKSUM |
- RX_CTRL_BURST_LEN_FRAME);
-
-
-//#define RXQ_TWOBYTE_OFFSET (0x0200) /* Enable adding 2-byte before frame header for IP aligned with DWORD */
-#warning Remember to try the above option to get a 2-byte offset
-
- /* Init step11: configure QMU receive queue: trigger INT and auto-dequeue frame. */
- ksz8851_reg_write( REG_RXQ_CMD, RXQ_CMD_CNTL | RXQ_TWOBYTE_OFFSET );
-
- /* Init step12: adjust SPI data output delay. */
- ksz8851_reg_write(REG_BUS_CLOCK_CTRL, BUS_CLOCK_166 | BUS_CLOCK_DIVIDEDBY_1);
-
- /* Init step13: restart auto-negotiation. */
- ksz8851_reg_setbits(REG_PORT_CTRL, PORT_AUTO_NEG_RESTART);
-
- /* Init step13.1: force link in half duplex if auto-negotiation failed. */
- if ((ksz8851_reg_read(REG_PORT_CTRL) & PORT_AUTO_NEG_RESTART) != PORT_AUTO_NEG_RESTART)
- {
- ksz8851_reg_clrbits(REG_PORT_CTRL, PORT_FORCE_FULL_DUPLEX);
- }
-
- /* Init step14: clear interrupt status. */
- ksz8851_reg_write(REG_INT_STATUS, 0xFFFF);
-
- /* Init step15: set interrupt mask. */
- ksz8851_reg_write(REG_INT_MASK, INT_RX);
-
- /* Init step16: enable QMU Transmit. */
- ksz8851_reg_setbits(REG_TX_CTRL, TX_CTRL_ENABLE);
-
- /* Init step17: enable QMU Receive. */
- ksz8851_reg_setbits(REG_RX_CTRL1, RX_CTRL_ENABLE);
-}
-/**
- * \brief KSZ8851SNL initialization function.
- *
- * \return 0 on success, 1 on communication error.
- */
-uint32_t ksz8851snl_init(void)
-{
-uint32_t count = 10;
-uint16_t dev_id = 0;
-uint8_t id_ok = 0;
-
- /* Configure the SPI peripheral. */
- spi_enable_clock(KSZ8851SNL_SPI);
- spi_disable(KSZ8851SNL_SPI);
- spi_reset(KSZ8851SNL_SPI);
- spi_set_master_mode(KSZ8851SNL_SPI);
- spi_disable_mode_fault_detect(KSZ8851SNL_SPI);
- spi_set_peripheral_chip_select_value(KSZ8851SNL_SPI, ~(uint32_t)(1UL << KSZ8851SNL_CS_PIN));
-spi_set_fixed_peripheral_select(KSZ8851SNL_SPI);
-//spi_disable_peripheral_select_decode(KSZ8851SNL_SPI);
-
- spi_set_clock_polarity(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_POLARITY);
- spi_set_clock_phase(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, SPI_CLK_PHASE);
- spi_set_bits_per_transfer(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN,
- SPI_CSR_BITS_8_BIT);
- spi_set_baudrate_div(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, (sysclk_get_cpu_hz() / KSZ8851SNL_CLOCK_SPEED));
-// spi_set_transfer_delay(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, CONFIG_SPI_MASTER_DELAY_BS,
-// CONFIG_SPI_MASTER_DELAY_BCT);
-
-
- spi_set_transfer_delay(KSZ8851SNL_SPI, KSZ8851SNL_CS_PIN, 0, 0);
-
- spi_enable(KSZ8851SNL_SPI);
-
- /* Get pointer to UART PDC register base. */
- g_p_spi_pdc = spi_get_pdc_base(KSZ8851SNL_SPI);
- pdc_enable_transfer(g_p_spi_pdc, PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN);
-
- /* Control RSTN and CSN pin from the driver. */
- gpio_configure_pin(KSZ8851SNL_CSN_GPIO, KSZ8851SNL_CSN_FLAGS);
- gpio_set_pin_high(KSZ8851SNL_CSN_GPIO);
- gpio_configure_pin(KSZ8851SNL_RSTN_GPIO, KSZ8851SNL_RSTN_FLAGS);
-
- /* Reset the Micrel in a proper state. */
- while( count-- )
- {
- /* Perform hardware reset with respect to the reset timing from the datasheet. */
- gpio_set_pin_low(KSZ8851SNL_RSTN_GPIO);
- vTaskDelay(2);
- gpio_set_pin_high(KSZ8851SNL_RSTN_GPIO);
- vTaskDelay(2);
-
- /* Init step1: read chip ID. */
- dev_id = ksz8851_reg_read(REG_CHIP_ID);
- if( ( dev_id & 0xFFF0 ) == CHIP_ID_8851_16 )
- {
- id_ok = 1;
- break;
- }
- }
- if( id_ok != 0 )
- {
- ksz8851snl_set_registers();
- }
-
- return id_ok ? 1 : -1;
-}
-
-uint32_t ksz8851snl_reinit(void)
-{
-uint32_t count = 10;
-uint16_t dev_id = 0;
-uint8_t id_ok = 0;
- /* Reset the Micrel in a proper state. */
- while( count-- )
- {
- /* Perform hardware reset with respect to the reset timing from the datasheet. */
- gpio_set_pin_low(KSZ8851SNL_RSTN_GPIO);
- vTaskDelay(2);
- gpio_set_pin_high(KSZ8851SNL_RSTN_GPIO);
- vTaskDelay(2);
-
- /* Init step1: read chip ID. */
- dev_id = ksz8851_reg_read(REG_CHIP_ID);
- if( ( dev_id & 0xFFF0 ) == CHIP_ID_8851_16 )
- {
- id_ok = 1;
- break;
- }
- }
- if( id_ok != 0 )
- {
- ksz8851snl_set_registers();
- }
-
- return id_ok ? 1 : -1;
-}
-
-uint32_t ksz8851snl_reset_rx( void )
-{
-uint16_t usValue;
-
- usValue = ksz8851_reg_read(REG_RX_CTRL1);
-
- usValue &= ~( ( uint16_t ) RX_CTRL_ENABLE | RX_CTRL_FLUSH_QUEUE );
-
- ksz8851_reg_write( REG_RX_CTRL1, usValue ); vTaskDelay( 2 );
- ksz8851_reg_write( REG_RX_CTRL1, usValue | RX_CTRL_FLUSH_QUEUE ); vTaskDelay( 1 );
- ksz8851_reg_write( REG_RX_CTRL1, usValue ); vTaskDelay( 1 );
- ksz8851_reg_write( REG_RX_CTRL1, usValue | RX_CTRL_ENABLE ); vTaskDelay( 1 );
-
- return ( uint32_t )usValue;
-}
-
-uint32_t ksz8851snl_reset_tx( void )
-{
-uint16_t usValue;
-
- usValue = ksz8851_reg_read( REG_TX_CTRL );
-
- usValue &= ~( ( uint16_t ) TX_CTRL_ENABLE | TX_CTRL_FLUSH_QUEUE );
-
- ksz8851_reg_write( REG_TX_CTRL, usValue ); vTaskDelay( 2 );
- ksz8851_reg_write( REG_TX_CTRL, usValue | TX_CTRL_FLUSH_QUEUE ); vTaskDelay( 1 );
- ksz8851_reg_write( REG_TX_CTRL, usValue ); vTaskDelay( 1 );
- ksz8851_reg_write( REG_TX_CTRL, usValue | TX_CTRL_ENABLE ); vTaskDelay( 1 );
-
- return ( uint32_t )usValue;
-}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.h
deleted file mode 100644
index 7952dc241..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/**
- *
- * \file
- *
- * \brief KS8851SNL driver for SAM.
- *
- * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
- */
-
-#ifndef KSZ8851SNL_H_INCLUDED
-#define KSZ8851SNL_H_INCLUDED
-
-#include "gpio.h"
-
-void configure_intn(void (*p_handler) (uint32_t, uint32_t));
-void ksz8851_reg_setbits(uint16_t reg, uint16_t bits_to_set);
-void ksz8851_reg_clrbits(uint16_t reg, uint16_t bits_to_clr);
-void ksz8851_fifo_read(uint8_t *buf, uint32_t len);
-void ksz8851_fifo_write(uint8_t *buf, uint32_t ulActualLength, uint32_t ulFIFOLength);
-void ksz8851_fifo_dummy(uint32_t len);
-void ksz8851_reg_write(uint16_t reg, uint16_t wrdata);
-uint16_t ksz8851_reg_read(uint16_t reg);
-uint32_t ksz8851snl_init(void);
-uint32_t ksz8851snl_reinit(void);
-
-uint32_t ksz8851snl_reset_rx( void );
-uint32_t ksz8851snl_reset_tx( void );
-
-#endif /* KSZ8851SNL_H_INCLUDED */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl_reg.h b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl_reg.h
deleted file mode 100644
index 3102fcc42..000000000
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/ksz8851snl/ksz8851snl_reg.h
+++ /dev/null
@@ -1,473 +0,0 @@
-/**
- *
- * \file
- *
- * \brief KS8851SNL registers definitions.
- *
- * Copyright (c) 2013-2015 Atmel Corporation. All rights reserved.
- *
- * \asf_license_start
- *
- * \page License
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- * this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- * this list of conditions and the following disclaimer in the documentation
- * and/or other materials provided with the distribution.
- *
- * 3. The name of Atmel may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- *
- * 4. This software may only be redistributed and used in connection with an
- * Atmel microcontroller product.
- *
- * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE
- * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- * POSSIBILITY OF SUCH DAMAGE.
- *
- * \asf_license_stop
- *
- */
-/*
- * Support and FAQ: visit <a href="http://www.atmel.com/design-support/">Atmel Support</a>
- */
-
-#ifndef KSZ8851SNL_REG_H_INCLUDED
-#define KSZ8851SNL_REG_H_INCLUDED
-
-#define REG_ADDR_MASK (0x3F0) /* Register address mask */
-#define OPCODE_MASK (3 << 14)
-#define CMD_READ (0 << 14)
-#define CMD_WRITE (1 << 14)
-#define FIFO_READ (0x80)
-#define FIFO_WRITE (0xC0)
-
-/*
- * MAC Registers
- * (Offset 0x00 - 0x25)
- */
-#define REG_BUS_ERROR_STATUS (0x06) /* BESR */
-#define BUS_ERROR_IBEC (0x8000)
-#define BUS_ERROR_IBECV_MASK (0x7800) /* Default IPSec clock at 166Mhz */
-
-#define REG_CHIP_CFG_STATUS (0x08) /* CCFG */
-#define LITTLE_ENDIAN_BUS_MODE (0x0400) /* Bus in little endian mode */
-#define EEPROM_PRESENCE (0x0200) /* External EEPROM is used */
-#define SPI_BUS_MODE (0x0100) /* In SPI bus mode */
-#define DATA_BUS_8BIT (0x0080) /* In 8-bit bus mode operation */
-#define DATA_BUS_16BIT (0x0040) /* In 16-bit bus mode operation */
-#define DATA_BUS_32BIT (0x0020) /* In 32-bit bus mode operation */
-#define MULTIPLEX_MODE (0x0010) /* Data and address bus are shared */
-#define CHIP_PACKAGE_128PIN (0x0008) /* 128-pin package */
-#define CHIP_PACKAGE_80PIN (0x0004) /* 80-pin package */
-#define CHIP_PACKAGE_48PIN (0x0002) /* 48-pin package */
-#define CHIP_PACKAGE_32PIN (0x0001) /* 32-pin package for SPI host interface only */
-
-#define REG_MAC_ADDR_0 (0x10) /* MARL */
-#define REG_MAC_ADDR_1 (0x11) /* MARL */
-#define REG_MAC_ADDR_2 (0x12) /* MARM */
-#define REG_MAC_ADDR_3 (0x13) /* MARM */
-#define REG_MAC_ADDR_4 (0x14) /* MARH */
-#define REG_MAC_ADDR_5 (0x15) /* MARH */
-
-#define REG_BUS_CLOCK_CTRL (0x20) /* OBCR */
-#define BUS_CLOCK_166 (0x0004) /* 166 MHz on-chip bus clock (defaul is 125MHz) */
-#define BUS_CLOCK_DIVIDEDBY_5 (0x0003) /* Bus clock devided by 5 */
-#define BUS_CLOCK_DIVIDEDBY_3 (0x0002) /* Bus clock devided by 3 */
-#define BUS_CLOCK_DIVIDEDBY_2 (0x0001) /* Bus clock devided by 2 */
-#define BUS_CLOCK_DIVIDEDBY_1 (0x0000) /* Bus clock devided by 1 */
-#define BUS_CLOCK_DIVIDED_MASK (0x0003) /* Bus clock devider mask */
-
-#define BUS_SPEED_166_MHZ (0x0004) /* Set bus speed to 166 MHz */
-#define BUS_SPEED_125_MHZ (0x0000) /* Set bus speed to 125 MHz */
-#define BUS_SPEED_83_MHZ (0x0005) /* Set bus speed to 83 MHz (166/2)*/
-#define BUS_SPEED_62_5_MHZ (0x0001) /* Set bus speed to 62.5 MHz (125/2) */
-#define BUS_SPEED_53_3_MHZ (0x0006) /* Set bus speed to 53.3 MHz (166/3) */
-#define BUS_SPEED_41_7_MHZ (0x0002) /* Set bus speed to 41.67 MHz (125/3) */
-#define BUS_SPEED_33_2_MHZ (0x0007) /* Set bus speed to 33.2 MHz (166/5) */
-#define BUS_SPEED_25_MHZ (0x0003) /* Set bus speed to 25 MHz (125/5) */
-
-#define REG_EEPROM_CTRL (0x22) /* EEPCR */
-#define EEPROM_ACCESS_ENABLE (0x0010) /* Enable software to access EEPROM through bit 3 to bit 0 */
-#define EEPROM_DATA_IN (0x0008) /* Data receive from EEPROM (EEDI pin) */
-#define EEPROM_DATA_OUT (0x0004) /* Data transmit to EEPROM (EEDO pin) */
-#define EEPROM_SERIAL_CLOCK (0x0002) /* Serial clock (EESK pin) */
-#define EEPROM_CHIP_SELECT (0x0001) /* EEPROM chip select (EECS pin) */
-
-#define REG_MEM_BIST_INFO (0x24) /* MBIR */
-#define TX_MEM_TEST_FINISHED (0x1000) /* TX memeory BIST test finish */
-#define TX_MEM_TEST_FAILED (0x0800) /* TX memory BIST test fail */
-#define TX_MEM_TEST_FAILED_COUNT (0x0700) /* TX memory BIST test fail count */
-#define RX_MEM_TEST_FINISHED (0x0010) /* RX memory BIST test finish */
-#define RX_MEM_TEST_FAILED (0x0008) /* RX memory BIST test fail */
-#define RX_MEM_TEST_FAILED_COUNT (0x0003) /* RX memory BIST test fail count */
-
-#define REG_RESET_CTRL (0x26) /* GRR */
-#define QMU_SOFTWARE_RESET (0x0002) /* QMU soft reset (clear TxQ, RxQ) */
-#define GLOBAL_SOFTWARE_RESET (0x0001) /* Global soft reset (PHY, MAC, QMU) */
-
-/*
- * Wake On Lan Control Registers
- * (Offset 0x2A - 0x6B)
- */
-#define REG_WOL_CTRL (0x2A) /* WFCR */
-#define WOL_MAGIC_ENABLE (0x0080) /* Enable the magic packet pattern detection */
-#define WOL_FRAME3_ENABLE (0x0008) /* Enable the wake up frame 3 pattern detection */
-#define WOL_FRAME2_ENABLE (0x0004) /* Enable the wake up frame 2 pattern detection */
-#define WOL_FRAME1_ENABLE (0x0002) /* Enable the wake up frame 1 pattern detection */
-#define WOL_FRAME0_ENABLE (0x0001) /* Enable the wake up frame 0 pattern detection */
-
-#define REG_WOL_FRAME0_CRC0 (0x30) /* WF0CRC0 */
-#define REG_WOL_FRAME0_CRC1 (0x32) /* WF0CRC1 */
-#define REG_WOL_FRAME0_BYTE_MASK0 (0x34) /* WF0BM0 */
-#define REG_WOL_FRAME0_BYTE_MASK1 (0x36) /* WF0BM1 */
-#define REG_WOL_FRAME0_BYTE_MASK2 (0x38) /* WF0BM2 */
-#define REG_WOL_FRAME0_BYTE_MASK3 (0x3A) /* WF0BM3 */
-
-#define REG_WOL_FRAME1_CRC0 (0x40) /* WF1CRC0 */
-#define REG_WOL_FRAME1_CRC1 (0x42) /* WF1CRC1 */
-#define REG_WOL_FRAME1_BYTE_MASK0 (0x44) /* WF1BM0 */
-#define REG_WOL_FRAME1_BYTE_MASK1 (0x46) /* WF1BM1 */
-#define REG_WOL_FRAME1_BYTE_MASK2 (0x48) /* WF1BM2 */
-#define REG_WOL_FRAME1_BYTE_MASK3 (0x4A) /* WF1BM3 */
-
-#define REG_WOL_FRAME2_CRC0 (0x50) /* WF2CRC0 */
-#define REG_WOL_FRAME2_CRC1 (0x52) /* WF2CRC1 */
-#define REG_WOL_FRAME2_BYTE_MASK0 (0x54) /* WF2BM0 */
-#define REG_WOL_FRAME2_BYTE_MASK1 (0x56) /* WF2BM1 */
-#define REG_WOL_FRAME2_BYTE_MASK2 (0x58) /* WF2BM2 */
-#define REG_WOL_FRAME2_BYTE_MASK3 (0x5A) /* WF2BM3 */
-
-#define REG_WOL_FRAME3_CRC0 (0x60) /* WF3CRC0 */
-#define REG_WOL_FRAME3_CRC1 (0x62) /* WF3CRC1 */
-#define REG_WOL_FRAME3_BYTE_MASK0 (0x64) /* WF3BM0 */
-#define REG_WOL_FRAME3_BYTE_MASK1 (0x66) /* WF3BM1 */
-#define REG_WOL_FRAME3_BYTE_MASK2 (0x68) /* WF3BM2 */
-#define REG_WOL_FRAME3_BYTE_MASK3 (0x6A) /* WF3BM3 */
-
-/*
- * Transmit/Receive Control Registers
- * (Offset 0x70 - 0x9F)
- */
-
-/* Transmit Frame Header */
-#define REG_QDR_DUMMY (0x00) /* Dummy address to access QMU RxQ, TxQ */
-#define TX_CTRL_INTERRUPT_ON (0x8000) /* Transmit Interrupt on Completion */
-
-#define REG_TX_CTRL (0x70) /* TXCR */
-#define TX_CTRL_ICMP_CHECKSUM (0x0100) /* Enable ICMP frame checksum generation */
-#define TX_CTRL_UDP_CHECKSUM (0x0080) /* Enable UDP frame checksum generation */
-#define TX_CTRL_TCP_CHECKSUM (0x0040) /* Enable TCP frame checksum generation */
-#define TX_CTRL_IP_CHECKSUM (0x0020) /* Enable IP frame checksum generation */
-#define TX_CTRL_FLUSH_QUEUE (0x0010) /* Clear transmit queue, reset tx frame pointer */
-#define TX_CTRL_FLOW_ENABLE (0x0008) /* Enable transmit flow control */
-#define TX_CTRL_PAD_ENABLE (0x0004) /* Eanble adding a padding to a packet shorter than 64 bytes */
-#define TX_CTRL_CRC_ENABLE (0x0002) /* Enable adding a CRC to the end of transmit frame */
-#define TX_CTRL_ENABLE (0x0001) /* Enable tranmsit */
-
-#define REG_TX_STATUS (0x72) /* TXSR */
-#define TX_STAT_LATE_COL (0x2000) /* Tranmsit late collision occurs */
-#define TX_STAT_MAX_COL (0x1000) /* Tranmsit maximum collision is reached */
-#define TX_FRAME_ID_MASK (0x003F) /* Transmit frame ID mask */
-#define TX_STAT_ERRORS ( TX_STAT_MAX_COL | TX_STAT_LATE_COL )
-
-#define REG_RX_CTRL1 (0x74) /* RXCR1 */
-#define RX_CTRL_FLUSH_QUEUE (0x8000) /* Clear receive queue, reset rx frame pointer */
-#define RX_CTRL_UDP_CHECKSUM (0x4000) /* Enable UDP frame checksum verification */
-#define RX_CTRL_TCP_CHECKSUM (0x2000) /* Enable TCP frame checksum verification */
-#define RX_CTRL_IP_CHECKSUM (0x1000) /* Enable IP frame checksum verification */
-#define RX_CTRL_MAC_FILTER (0x0800) /* Receive with address that pass MAC address filtering */
-#define RX_CTRL_FLOW_ENABLE (0x0400) /* Enable receive flow control */
-#define RX_CTRL_BAD_PACKET (0x0200) /* Eanble receive CRC error frames */
-#define RX_CTRL_MULTICAST (0x0100) /* Receive multicast frames that pass the CRC hash filtering */
-#define RX_CTRL_BROADCAST (0x0080) /* Receive all the broadcast frames */
-#define RX_CTRL_ALL_MULTICAST (0x0040) /* Receive all the multicast frames (including broadcast frames) */
-#define RX_CTRL_UNICAST (0x0020) /* Receive unicast frames that match the device MAC address */
-#define RX_CTRL_PROMISCUOUS (0x0010) /* Receive all incoming frames, regardless of frame's DA */
-#define RX_CTRL_STRIP_CRC (0x0008) /* Enable strip CRC on the received frames */
-#define RX_CTRL_INVERSE_FILTER (0x0002) /* Receive with address check in inverse filtering mode */
-#define RX_CTRL_ENABLE (0x0001) /* Enable receive */
-
-/* Address filtering scheme mask */
-#define RX_CTRL_FILTER_MASK ( RX_CTRL_INVERSE_FILTER | RX_CTRL_PROMISCUOUS | RX_CTRL_MULTICAST | RX_CTRL_MAC_FILTER )
-
-#define REG_RX_CTRL2 (0x76) /* RXCR2 */
-#define RX_CTRL_IPV6_UDP_NOCHECKSUM (0x0010) /* No checksum generation and verification if IPv6 UDP is fragment */
-#define RX_CTRL_IPV6_UDP_CHECKSUM (0x0008) /* Receive pass IPv6 UDP frame with UDP checksum is zero */
-#define RX_CTRL_UDP_LITE_CHECKSUM (0x0004) /* Enable UDP Lite frame checksum generation and verification */
-#define RX_CTRL_ICMP_CHECKSUM (0x0002) /* Enable ICMP frame checksum verification */
-#define RX_CTRL_BLOCK_MAC (0x0001) /* Receive drop frame if the SA is same as device MAC address */
-#define RX_CTRL_BURST_LEN_MASK (0x00e0) /* SRDBL SPI Receive Data Burst Length */
-#define RX_CTRL_BURST_LEN_4 (0x0000)
-#define RX_CTRL_BURST_LEN_8 (0x0020)
-#define RX_CTRL_BURST_LEN_16 (0x0040)
-#define RX_CTRL_BURST_LEN_32 (0x0060)
-#define RX_CTRL_BURST_LEN_FRAME (0x0080)
-
-#define REG_TX_MEM_INFO (0x78) /* TXMIR */
-#define TX_MEM_AVAILABLE_MASK (0x1FFF) /* The amount of memory available in TXQ */
-
-#define REG_RX_FHR_STATUS (0x7C) /* RXFHSR */
-#define RX_VALID (0x8000) /* Frame in the receive packet memory is valid */
-#define RX_ICMP_ERROR (0x2000) /* ICMP checksum field doesn't match */
-#define RX_IP_ERROR (0x1000) /* IP checksum field doesn't match */
-#define RX_TCP_ERROR (0x0800) /* TCP checksum field doesn't match */
-#define RX_UDP_ERROR (0x0400) /* UDP checksum field doesn't match */
-#define RX_BROADCAST (0x0080) /* Received frame is a broadcast frame */
-#define RX_MULTICAST (0x0040) /* Received frame is a multicast frame */
-#define RX_UNICAST (0x0020) /* Received frame is a unicast frame */
-#define RX_PHY_ERROR (0x0010) /* Received frame has runt error */
-#define RX_FRAME_ETHER (0x0008) /* Received frame is an Ethernet-type frame */
-#define RX_TOO_LONG (0x0004) /* Received frame length exceeds max size 0f 2048 bytes */
-#define RX_RUNT_ERROR (0x0002) /* Received frame was demaged by a collision */
-#define RX_BAD_CRC (0x0001) /* Received frame has a CRC error */
-#define RX_ERRORS ( RX_BAD_CRC | RX_TOO_LONG | RX_RUNT_ERROR | RX_PHY_ERROR | \
- RX_ICMP_ERROR | RX_IP_ERROR | RX_TCP_ERROR | RX_UDP_ERROR )
-
-#define REG_RX_FHR_BYTE_CNT (0x7E) /* RXFHBCR */
-#define RX_BYTE_CNT_MASK (0x0FFF) /* Received frame byte size mask */
-
-#define REG_TXQ_CMD (0x80) /* TXQCR */
-#define TXQ_AUTO_ENQUEUE (0x0004) /* Enable enqueue tx frames from tx buffer automatically */
-#define TXQ_MEM_AVAILABLE_INT (0x0002) /* Enable generate interrupt when tx memory is available */
-#define TXQ_ENQUEUE (0x0001) /* Enable enqueue tx frames one frame at a time */
-
-#define REG_RXQ_CMD (0x82) /* RXQCR */
-#define RXQ_STAT_TIME_INT (0x1000) /* RX interrupt is occured by timer duration */
-#define RXQ_STAT_BYTE_CNT_INT (0x0800) /* RX interrupt is occured by byte count threshold */
-#define RXQ_STAT_FRAME_CNT_INT (0x0400) /* RX interrupt is occured by frame count threshold */
-#define RXQ_TWOBYTE_OFFSET (0x0200) /* Enable adding 2-byte before frame header for IP aligned with DWORD */
-#define RXQ_TIME_INT (0x0080) /* Enable RX interrupt by timer duration */
-#define RXQ_BYTE_CNT_INT (0x0040) /* Enable RX interrupt by byte count threshold */
-#define RXQ_FRAME_CNT_INT (0x0020) /* Enable RX interrupt by frame count threshold */
-#define RXQ_AUTO_DEQUEUE (0x0010) /* Enable release rx frames from rx buffer automatically */
-#define RXQ_START (0x0008) /* Start QMU transfer operation */
-#define RXQ_CMD_FREE_PACKET (0x0001) /* Manual dequeue (release the current frame from RxQ) */
-
-#define RXQ_CMD_CNTL (RXQ_FRAME_CNT_INT|RXQ_AUTO_DEQUEUE)
-
-#define REG_TX_ADDR_PTR (0x84) /* TXFDPR */
-#define REG_RX_ADDR_PTR (0x86) /* RXFDPR */
-#define ADDR_PTR_AUTO_INC (0x4000) /* Enable Frame data pointer increments automatically */
-#define ADDR_PTR_MASK (0x03ff) /* Address pointer mask */
-
-#define REG_RX_TIME_THRES (0x8C) /* RXDTTR */
-#define RX_TIME_THRESHOLD_MASK (0xFFFF) /* Set receive timer duration threshold */
-
-#define REG_RX_BYTE_CNT_THRES (0x8E) /* RXDBCTR */
-#define RX_BYTE_THRESHOLD_MASK (0xFFFF) /* Set receive byte count threshold */
-
-#define REG_INT_MASK (0x90) /* IER */
-#define INT_PHY (0x8000) /* Enable link change interrupt */
-#define INT_TX (0x4000) /* Enable transmit done interrupt */
-#define INT_RX (0x2000) /* Enable receive interrupt */
-#define INT_RX_OVERRUN (0x0800) /* Enable receive overrun interrupt */
-#define INT_TX_STOPPED (0x0200) /* Enable transmit process stopped interrupt */
-#define INT_RX_STOPPED (0x0100) /* Enable receive process stopped interrupt */
-#define INT_TX_SPACE (0x0040) /* Enable transmit space available interrupt */
-#define INT_RX_WOL_FRAME (0x0020) /* Enable WOL on receive wake-up frame detect interrupt */
-#define INT_RX_WOL_MAGIC (0x0010) /* Enable WOL on receive magic packet detect interrupt */
-#define INT_RX_WOL_LINKUP (0x0008) /* Enable WOL on link up detect interrupt */
-#define INT_RX_WOL_ENERGY (0x0004) /* Enable WOL on energy detect interrupt */
-#define INT_RX_SPI_ERROR (0x0002) /* Enable receive SPI bus error interrupt */
-#define INT_RX_WOL_DELAY_ENERGY (0x0001) /* Enable WOL on delay energy detect interrupt */
-#define INT_MASK ( INT_RX | INT_TX | INT_PHY )
-
-#define REG_INT_STATUS (0x92) /* ISR */
-
-#define REG_RX_FRAME_CNT_THRES (0x9C) /* RXFCTFC */
-#define RX_FRAME_CNT_MASK (0xFF00) /* Received frame count mask */
-#define RX_FRAME_THRESHOLD_MASK (0x00FF) /* Set receive frame count threshold mask */
-
-#define REG_TX_TOTAL_FRAME_SIZE (0x9E) /* TXNTFSR */
-#define TX_TOTAL_FRAME_SIZE_MASK (0xFFFF) /* Set next total tx frame size mask */
-
-/*
- * MAC Address Hash Table Control Registers
- * (Offset 0xA0 - 0xA7)
- */
-#define REG_MAC_HASH_0 (0xA0) /* MAHTR0 */
-#define REG_MAC_HASH_1 (0xA1)
-
-#define REG_MAC_HASH_2 (0xA2) /* MAHTR1 */
-#define REG_MAC_HASH_3 (0xA3)
-
-#define REG_MAC_HASH_4 (0xA4) /* MAHTR2 */
-#define REG_MAC_HASH_5 (0xA5)
-
-#define REG_MAC_HASH_6 (0xA6) /* MAHTR3 */
-#define REG_MAC_HASH_7 (0xA7)
-
-/*
- * QMU Receive Queue Watermark Control Registers
- * (Offset 0xB0 - 0xB5)
- */
-#define REG_RX_LOW_WATERMARK (0xB0) /* FCLWR */
-#define RX_LOW_WATERMARK_MASK (0x0FFF) /* Set QMU RxQ low watermark mask */
-
-#define REG_RX_HIGH_WATERMARK (0xB2) /* FCHWR */
-#define RX_HIGH_WATERMARK_MASK (0x0FFF) /* Set QMU RxQ high watermark mask */
-
-#define REG_RX_OVERRUN_WATERMARK (0xB4) /* FCOWR */
-#define RX_OVERRUN_WATERMARK_MASK (0x0FFF) /* Set QMU RxQ overrun watermark mask */
-
-/*
- * Global Control Registers
- * (Offset 0xC0 - 0xD3)
- */
-#define REG_CHIP_ID (0xC0) /* CIDER */
-#define CHIP_ID_MASK (0xFFF0) /* Family ID and chip ID mask */
-#define REVISION_MASK (0x000E) /* Chip revision mask */
-#define CHIP_ID_SHIFT (4)
-#define REVISION_SHIFT (1)
-#define CHIP_ID_8851_16 (0x8870) /* KS8851-16/32MQL chip ID */
-
-#define REG_LED_CTRL (0xC6) /* CGCR */
-#define LED_CTRL_SEL1 (0x8000) /* Select LED3/LED2/LED1/LED0 indication */
-#define LED_CTRL_SEL0 (0x0200) /* Select LED3/LED2/LED1/LED0 indication */
-
-#define REG_IND_IACR (0xC8) /* IACR */
-#define TABLE_READ (0x1000) /* Indirect read */
-#define TABLE_MIB (0x0C00) /* Select MIB counter table */
-#define TABLE_ENTRY_MASK (0x001F) /* Set table entry to access */
-
-#define REG_IND_DATA_LOW (0xD0) /* IADLR */
-#define REG_IND_DATA_HIGH (0xD2) /* IADHR */
-
-/*
- * Power Management Control Registers
- * (Offset 0xD4 - 0xD7)
- */
-#define REG_POWER_CNTL (0xD4) /* PMECR */
-#define PME_DELAY_ENABLE (0x4000) /* Enable the PME output pin assertion delay */
-#define PME_ACTIVE_HIGHT (0x1000) /* PME output pin is active high */
-#define PME_FROM_WKFRAME (0x0800) /* PME asserted when wake-up frame is detected */
-#define PME_FROM_MAGIC (0x0400) /* PME asserted when magic packet is detected */
-#define PME_FROM_LINKUP (0x0200) /* PME asserted when link up is detected */
-#define PME_FROM_ENERGY (0x0100) /* PME asserted when energy is detected */
-#define PME_EVENT_MASK (0x0F00) /* PME asserted event mask */
-#define WAKEUP_AUTO_ENABLE (0x0080) /* Enable auto wake-up in energy mode */
-#define WAKEUP_NORMAL_AUTO_ENABLE (0x0040) /* Enable auto goto normal mode from energy detecion mode */
-#define WAKEUP_FROM_WKFRAME (0x0020) /* Wake-up from wake-up frame event detected */
-#define WAKEUP_FROM_MAGIC (0x0010) /* Wake-up from magic packet event detected */
-#define WAKEUP_FROM_LINKUP (0x0008) /* Wake-up from link up event detected */
-#define WAKEUP_FROM_ENERGY (0x0004) /* Wake-up from energy event detected */
-#define WAKEUP_EVENT_MASK (0x003C) /* Wake-up event mask */
-#define POWER_STATE_D1 (0x0003) /* Power saving mode */
-#define POWER_STATE_D3 (0x0002) /* Power down mode */
-#define POWER_STATE_D2 (0x0001) /* Power detection mode */
-#define POWER_STATE_D0 (0x0000) /* Normal operation mode (default) */
-#define POWER_STATE_MASK (0x0003) /* Power management mode mask */
-
-#define REG_WAKEUP_TIME (0xD6) /* GSWUTR */
-#define WAKEUP_TIME (0xFF00) /* Min time (sec) wake-uo after detected energy */
-#define GOSLEEP_TIME (0x00FF) /* Min time (sec) before goto sleep when in energy mode */
-
-/*
- * PHY Control Registers
- * (Offset 0xD8 - 0xF9)
- */
-#define REG_PHY_RESET (0xD8) /* PHYRR */
-#define PHY_RESET (0x0001) /* Reset PHY */
-
-#define REG_PHY_CNTL (0xE4) /* P1MBCR */
-#define PHY_SPEED_100MBIT (0x2000) /* Force PHY 100Mbps */
-#define PHY_AUTO_NEG_ENABLE (0x1000) /* Enable PHY auto-negotiation */
-#define PHY_POWER_DOWN (0x0800) /* Set PHY power-down */
-#define PHY_AUTO_NEG_RESTART (0x0200) /* Restart PHY auto-negotiation */
-#define PHY_FULL_DUPLEX (0x0100) /* Force PHY in full duplex mode */
-#define PHY_HP_MDIX (0x0020) /* Set PHY in HP auto MDI-X mode */
-#define PHY_FORCE_MDIX (0x0010) /* Force MDI-X */
-#define PHY_AUTO_MDIX_DISABLE (0x0008) /* Disable auto MDI-X */
-#define PHY_TRANSMIT_DISABLE (0x0002) /* Disable PHY transmit */
-#define PHY_LED_DISABLE (0x0001) /* Disable PHY LED */
-
-#define REG_PHY_STATUS (0xE6) /* P1MBSR */
-#define PHY_100BT4_CAPABLE (0x8000) /* 100 BASE-T4 capable */
-#define PHY_100BTX_FD_CAPABLE (0x4000) /* 100BASE-TX full duplex capable */
-#define PHY_100BTX_CAPABLE (0x2000) /* 100BASE-TX half duplex capable */
-#define PHY_10BT_FD_CAPABLE (0x1000) /* 10BASE-TX full duplex capable */
-#define PHY_10BT_CAPABLE (0x0800) /* 10BASE-TX half duplex capable */
-#define PHY_AUTO_NEG_ACKNOWLEDGE (0x0020) /* Auto-negotiation complete */
-#define PHY_AUTO_NEG_CAPABLE (0x0008) /* Auto-negotiation capable */
-#define PHY_LINK_UP (0x0004) /* PHY link is up */
-#define PHY_EXTENDED_CAPABILITY (0x0001) /* PHY extended register capable */
-
-#define REG_PHY_ID_LOW (0xE8) /* PHY1ILR */
-#define REG_PHY_ID_HIGH (0xEA) /* PHY1IHR */
-
-#define REG_PHY_AUTO_NEGOTIATION (0xEC) /* P1ANAR */
-#define PHY_AUTO_NEG_SYM_PAUSE (0x0400) /* Advertise pause capability */
-#define PHY_AUTO_NEG_100BTX_FD (0x0100) /* Advertise 100 full-duplex capability */
-#define PHY_AUTO_NEG_100BTX (0x0080) /* Advertise 100 half-duplex capability */
-#define PHY_AUTO_NEG_10BT_FD (0x0040) /* Advertise 10 full-duplex capability */
-#define PHY_AUTO_NEG_10BT (0x0020) /* Advertise 10 half-duplex capability */
-#define PHY_AUTO_NEG_SELECTOR (0x001F) /* Selector field mask */
-#define PHY_AUTO_NEG_802_3 (0x0001) /* 802.3 */
-
-#define REG_PHY_REMOTE_CAPABILITY (0xEE) /* P1ANLPR */
-#define PHY_REMOTE_SYM_PAUSE (0x0400) /* Link partner pause capability */
-#define PHY_REMOTE_100BTX_FD (0x0100) /* Link partner 100 full-duplex capability */
-#define PHY_REMOTE_100BTX (0x0080) /* Link partner 100 half-duplex capability */
-#define PHY_REMOTE_10BT_FD (0x0040) /* Link partner 10 full-duplex capability */
-#define PHY_REMOTE_10BT (0x0020) /* Link partner 10 half-duplex capability */
-
-#define REG_PORT_LINK_MD (0xF4) /* P1SCLMD */
-#define PORT_CABLE_10M_SHORT (0x8000) /* Cable length is less than 10m short */
-#define PORT_CABLE_STAT_FAILED (0x6000) /* Cable diagnostic test fail */
-#define PORT_CABLE_STAT_SHORT (0x4000) /* Short condition detected in the cable */
-#define PORT_CABLE_STAT_OPEN (0x2000) /* Open condition detected in the cable */
-#define PORT_CABLE_STAT_NORMAL (0x0000) /* Normal condition */
-#define PORT_CABLE_DIAG_RESULT (0x6000) /* Cable diagnostic test result mask */
-#define PORT_START_CABLE_DIAG (0x1000) /* Enable cable diagnostic test */
-#define PORT_FORCE_LINK (0x0800) /* Enable force link pass */
-#define PORT_POWER_SAVING (0x0400) /* Disable power saving */
-#define PORT_REMOTE_LOOPBACK (0x0200) /* Enable remote loopback at PHY */
-#define PORT_CABLE_FAULT_COUNTER (0x01FF) /* Cable length distance to the fault */
-
-#define REG_PORT_CTRL (0xF6) /* P1CR */
-#define PORT_LED_OFF (0x8000) /* Turn off all the port LEDs (LED3/LED2/LED1/LED0) */
-#define PORT_TX_DISABLE (0x4000) /* Disable port transmit */
-#define PORT_AUTO_NEG_RESTART (0x2000) /* Restart auto-negotiation */
-#define PORT_POWER_DOWN (0x0800) /* Set port power-down */
-#define PORT_AUTO_MDIX_DISABLE (0x0400) /* Disable auto MDI-X */
-#define PORT_FORCE_MDIX (0x0200) /* Force MDI-X */
-#define PORT_AUTO_NEG_ENABLE (0x0080) /* Enable auto-negotiation */
-#define PORT_FORCE_100_MBIT (0x0040) /* Force PHY 100Mbps */
-#define PORT_FORCE_FULL_DUPLEX (0x0020) /* Force PHY in full duplex mode */
-#define PORT_AUTO_NEG_SYM_PAUSE (0x0010) /* Advertise pause capability */
-#define PORT_AUTO_NEG_100BTX_FD (0x0008) /* Advertise 100 full-duplex capability */
-#define PORT_AUTO_NEG_100BTX (0x0004) /* Advertise 100 half-duplex capability */
-#define PORT_AUTO_NEG_10BT_FD (0x0002) /* Advertise 10 full-duplex capability */
-#define PORT_AUTO_NEG_10BT (0x0001) /* Advertise 10 half-duplex capability */
-
-#define REG_PORT_STATUS (0xF8) /* P1SR */
-#define PORT_HP_MDIX (0x8000) /* Set PHY in HP auto MDI-X mode */
-#define PORT_REVERSED_POLARITY (0x2000) /* Polarity is reversed */
-#define PORT_RX_FLOW_CTRL (0x1000) /* Reeive flow control feature is active */
-#define PORT_TX_FLOW_CTRL (0x0800) /* Transmit flow control feature is active */
-#define PORT_STAT_SPEED_100MBIT (0x0400) /* Link is 100Mbps */
-#define PORT_STAT_FULL_DUPLEX (0x0200) /* Link is full duplex mode */
-#define PORT_MDIX_STATUS (0x0080) /* Is MDI */
-#define PORT_AUTO_NEG_COMPLETE (0x0040) /* Auto-negotiation complete */
-#define PORT_STATUS_LINK_GOOD (0x0020) /* PHY link is up */
-#define PORT_REMOTE_SYM_PAUSE (0x0010) /* Link partner pause capability */
-#define PORT_REMOTE_100BTX_FD (0x0008) /* Link partner 100 full-duplex capability */
-#define PORT_REMOTE_100BTX (0x0004) /* Link partner 100 half-duplex capability */
-#define PORT_REMOTE_10BT_FD (0x0002) /* Link partner 10 full-duplex capability */
-#define PORT_REMOTE_10BT (0x0001) /* Link partner 10 half-duplex capability */
-
-#endif /* KSZ8851SNL_REG_H_INCLUDED */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c
index 87161fd39..df5bd7cfe 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/mw300_rd/NetworkInterface.c
@@ -1,217 +1,217 @@
-/*
-FreeRTOS+TCP V2.0.11
-Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
- http://aws.amazon.com/freertos
- http://www.FreeRTOS.org
-*/
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "list.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_Sockets.h"
-#include "FreeRTOS_IP_Private.h"
-#include "FreeRTOS_DNS.h"
-#include "NetworkBufferManagement.h"
-#include "NetworkInterface.h"
-
-#include "wifi-decl.h"
-#include "wmerrno.h"
-#include "wifi.h"
-
-#include <wmlog.h>
-
-#define net_e(...) \
- wmlog_e("freertos_tcp", ##__VA_ARGS__)
-#define net_w(...) \
- wmlog_w("freertos_tcp", ##__VA_ARGS__)
-#define net_d(...) \
- wmlog("freertos_tcp", ##__VA_ARGS__)
-
-#if 0 //this is lwip structure.
-#define MAX_INTERFACES_SUPPORTED 3
-static struct netif *netif_arr[MAX_INTERFACES_SUPPORTED];
-#endif
-
-/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
-driver will filter incoming packets and only pass the stack those packets it
-considers need processing. */
-#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
-#else
-#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
-#endif
-
-#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any)
-#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast)
-
-/** 255.255.255.255 */
-#define IPADDR_NONE ((u32_t)0xffffffffUL)
-/** 127.0.0.1 */
-#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
-/** 0.0.0.0 */
-#define IPADDR_ANY ((u32_t)0x00000000UL)
-/** 255.255.255.255 */
-#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
-
-/** 255.255.255.255 */
-#define INADDR_NONE IPADDR_NONE
-/** 127.0.0.1 */
-#define INADDR_LOOPBACK IPADDR_LOOPBACK
-/** 0.0.0.0 */
-#define INADDR_ANY IPADDR_ANY
-/** 255.255.255.255 */
-#define INADDR_BROADCAST IPADDR_BROADCAST
-
-enum if_state_t {
- INTERFACE_DOWN = 0,
- INTERFACE_UP,
-};
-struct ip_addr {
- u32_t addr;
-};
-
-#define MLAN_BSS_TYPE_STA 0
-
-extern uint8_t outbuf[2048];
-extern bool mlan_is_amsdu(const t_u8 *rcvdata);
-extern t_u8 *mlan_get_payload(const t_u8 *rcvdata, t_u16 *payload_len, int *interface);
-extern int wrapper_wlan_handle_amsdu_rx_packet(const t_u8 *rcvdata, const t_u16 datalen);
-extern int wrapper_wlan_handle_rx_packet(const t_u16 datalen, const t_u8 *rcvdata, NetworkBufferDescriptor_t *pxNetworkBuffer);
-static volatile uint32_t xInterfaceState = INTERFACE_DOWN;
-
-static int process_data_packet(const t_u8 *databuf, const t_u16 datalen)
-{
- int interface = BSS_TYPE_STA;
- t_u8 *payload = NULL;
- t_u16 payload_len = 0;
- const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
-
- NetworkBufferDescriptor_t *pxNetworkBuffer;
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- payload = (t_u8 *)mlan_get_payload(databuf, &payload_len, &interface);
-
- if( eConsiderFrameForProcessing( payload ) != eProcessBuffer ) {
- net_d("Dropping packet\r\n");
- return WM_SUCCESS;
- }
-
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(/*payload_len*/datalen, xDescriptorWaitTime);
-
- if (pxNetworkBuffer != NULL) {
- /* Set the packet size, in case a larger buffer was returned. */
- pxNetworkBuffer->xDataLength = payload_len;
-
- /* Copy the packet data. */
- memcpy(pxNetworkBuffer->pucEthernetBuffer, payload, payload_len);
-
- xRxEvent.pvData = (void *) pxNetworkBuffer;
- if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
- wmprintf("Failed to enqueue packet to network stack %p, len %d", payload, payload_len);
- vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
- return WM_FAIL;
- }
- }
- return WM_SUCCESS;
-}
-
-/* Callback function called from the wifi module */
-void handle_data_packet(const t_u8 interface, const t_u8 *rcvdata,
- const t_u16 datalen)
-{
- if (interface == BSS_TYPE_STA)
- process_data_packet(rcvdata, datalen);
-}
-
-BaseType_t xNetworkInterfaceInitialise( void )
-{
- uint8_t ret;
- mac_addr_t mac_addr;
-
- ret = wifi_get_device_mac_addr(&mac_addr);
- if (ret != WM_SUCCESS) {
- net_d("Failed to get mac address");
- }
-
- FreeRTOS_UpdateMACAddress(mac_addr.mac);
-
- return ( xInterfaceState == INTERFACE_UP && ret == WM_SUCCESS ) ? pdTRUE : pdFALSE;
-}
-
-void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
-{
- /* FIX ME. */
-}
-
-BaseType_t xGetPhyLinkStatus( void )
-{
- /* FIX ME. */
- return pdFALSE;
-}
-void vNetworkNotifyIFDown()
-{
- IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
- xInterfaceState = INTERFACE_DOWN;
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) != pdPASS ) {
- /* Could not send the message, so it is still pending. */
- net_e("Could not send network down event");
- }
- else {
- /* Message was sent so it is not pending. */
- net_d("Sent network down event");
- }
-}
-
-void vNetworkNotifyIFUp()
-{
- xInterfaceState = INTERFACE_UP;
-}
-
-BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
-{
- uint8_t pkt_len;
-
- if (pxNetworkBuffer == NULL ||
- pxNetworkBuffer->pucEthernetBuffer == NULL ||
- pxNetworkBuffer->xDataLength == 0) {
- net_d("Incorrect params");
- return pdFALSE;
- }
- memset(outbuf, 0x00, sizeof(outbuf));
- pkt_len = 22 + 4; /* sizeof(TxPD) + INTF_HEADER_LEN */
- memcpy((u8_t *) outbuf + pkt_len, (u8_t *) pxNetworkBuffer->pucEthernetBuffer,
- pxNetworkBuffer->xDataLength);
- int ret = wifi_low_level_output(BSS_TYPE_STA, outbuf + pkt_len, pxNetworkBuffer->xDataLength);
- if (ret != WM_SUCCESS) {
- net_e("Failed output %p, length %d, error %d \r\n", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
- }
-
- if (xReleaseAfterSend != pdFALSE) {
- vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
- }
-
- return ret == WM_SUCCESS ? pdTRUE : pdFALSE;
-}
+/*
+FreeRTOS+TCP V2.0.11
+Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software is furnished to do so,
+subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
+FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
+COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+ http://aws.amazon.com/freertos
+ http://www.FreeRTOS.org
+*/
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "list.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_Sockets.h"
+#include "FreeRTOS_IP_Private.h"
+#include "FreeRTOS_DNS.h"
+#include "NetworkBufferManagement.h"
+#include "NetworkInterface.h"
+
+#include "wifi-decl.h"
+#include "wmerrno.h"
+#include "wifi.h"
+
+#include <wmlog.h>
+
+#define net_e(...) \
+ wmlog_e("freertos_tcp", ##__VA_ARGS__)
+#define net_w(...) \
+ wmlog_w("freertos_tcp", ##__VA_ARGS__)
+#define net_d(...) \
+ wmlog("freertos_tcp", ##__VA_ARGS__)
+
+#if 0 //this is lwip structure.
+#define MAX_INTERFACES_SUPPORTED 3
+static struct netif *netif_arr[MAX_INTERFACES_SUPPORTED];
+#endif
+
+/* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
+driver will filter incoming packets and only pass the stack those packets it
+considers need processing. */
+#if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
+#else
+#define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
+#endif
+
+#define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any)
+#define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast)
+
+/** 255.255.255.255 */
+#define IPADDR_NONE ((u32_t)0xffffffffUL)
+/** 127.0.0.1 */
+#define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
+/** 0.0.0.0 */
+#define IPADDR_ANY ((u32_t)0x00000000UL)
+/** 255.255.255.255 */
+#define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
+
+/** 255.255.255.255 */
+#define INADDR_NONE IPADDR_NONE
+/** 127.0.0.1 */
+#define INADDR_LOOPBACK IPADDR_LOOPBACK
+/** 0.0.0.0 */
+#define INADDR_ANY IPADDR_ANY
+/** 255.255.255.255 */
+#define INADDR_BROADCAST IPADDR_BROADCAST
+
+enum if_state_t {
+ INTERFACE_DOWN = 0,
+ INTERFACE_UP,
+};
+struct ip_addr {
+ u32_t addr;
+};
+
+#define MLAN_BSS_TYPE_STA 0
+
+extern uint8_t outbuf[2048];
+extern bool mlan_is_amsdu(const t_u8 *rcvdata);
+extern t_u8 *mlan_get_payload(const t_u8 *rcvdata, t_u16 *payload_len, int *interface);
+extern int wrapper_wlan_handle_amsdu_rx_packet(const t_u8 *rcvdata, const t_u16 datalen);
+extern int wrapper_wlan_handle_rx_packet(const t_u16 datalen, const t_u8 *rcvdata, NetworkBufferDescriptor_t *pxNetworkBuffer);
+static volatile uint32_t xInterfaceState = INTERFACE_DOWN;
+
+static int process_data_packet(const t_u8 *databuf, const t_u16 datalen)
+{
+ int interface = BSS_TYPE_STA;
+ t_u8 *payload = NULL;
+ t_u16 payload_len = 0;
+ const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
+
+ NetworkBufferDescriptor_t *pxNetworkBuffer;
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+ payload = (t_u8 *)mlan_get_payload(databuf, &payload_len, &interface);
+
+ if( eConsiderFrameForProcessing( payload ) != eProcessBuffer ) {
+ net_d("Dropping packet\r\n");
+ return WM_SUCCESS;
+ }
+
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(/*payload_len*/datalen, xDescriptorWaitTime);
+
+ if (pxNetworkBuffer != NULL) {
+ /* Set the packet size, in case a larger buffer was returned. */
+ pxNetworkBuffer->xDataLength = payload_len;
+
+ /* Copy the packet data. */
+ memcpy(pxNetworkBuffer->pucEthernetBuffer, payload, payload_len);
+
+ xRxEvent.pvData = (void *) pxNetworkBuffer;
+ if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
+ wmprintf("Failed to enqueue packet to network stack %p, len %d", payload, payload_len);
+ vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
+ return WM_FAIL;
+ }
+ }
+ return WM_SUCCESS;
+}
+
+/* Callback function called from the wifi module */
+void handle_data_packet(const t_u8 interface, const t_u8 *rcvdata,
+ const t_u16 datalen)
+{
+ if (interface == BSS_TYPE_STA)
+ process_data_packet(rcvdata, datalen);
+}
+
+BaseType_t xNetworkInterfaceInitialise( void )
+{
+ uint8_t ret;
+ mac_addr_t mac_addr;
+
+ ret = wifi_get_device_mac_addr(&mac_addr);
+ if (ret != WM_SUCCESS) {
+ net_d("Failed to get mac address");
+ }
+
+ FreeRTOS_UpdateMACAddress(mac_addr.mac);
+
+ return ( xInterfaceState == INTERFACE_UP && ret == WM_SUCCESS ) ? pdTRUE : pdFALSE;
+}
+
+void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
+{
+ /* FIX ME. */
+}
+
+BaseType_t xGetPhyLinkStatus( void )
+{
+ /* FIX ME. */
+ return pdFALSE;
+}
+void vNetworkNotifyIFDown()
+{
+ IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
+ xInterfaceState = INTERFACE_DOWN;
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) != pdPASS ) {
+ /* Could not send the message, so it is still pending. */
+ net_e("Could not send network down event");
+ }
+ else {
+ /* Message was sent so it is not pending. */
+ net_d("Sent network down event");
+ }
+}
+
+void vNetworkNotifyIFUp()
+{
+ xInterfaceState = INTERFACE_UP;
+}
+
+BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
+{
+ uint8_t pkt_len;
+
+ if (pxNetworkBuffer == NULL ||
+ pxNetworkBuffer->pucEthernetBuffer == NULL ||
+ pxNetworkBuffer->xDataLength == 0) {
+ net_d("Incorrect params");
+ return pdFALSE;
+ }
+ memset(outbuf, 0x00, sizeof(outbuf));
+ pkt_len = 22 + 4; /* sizeof(TxPD) + INTF_HEADER_LEN */
+ memcpy((u8_t *) outbuf + pkt_len, (u8_t *) pxNetworkBuffer->pucEthernetBuffer,
+ pxNetworkBuffer->xDataLength);
+ int ret = wifi_low_level_output(BSS_TYPE_STA, outbuf + pkt_len, pxNetworkBuffer->xDataLength);
+ if (ret != WM_SUCCESS) {
+ net_e("Failed output %p, length %d, error %d \r\n", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
+ }
+
+ if (xReleaseAfterSend != pdFALSE) {
+ vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
+ }
+
+ return ret == WM_SUCCESS ? pdTRUE : pdFALSE;
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c
index 531e878ea..f00ae1fe8 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/BufferAllocation_2.c
@@ -1,620 +1,620 @@
-/*
- * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd.
- * Authors include Hein Tibosch and Richard Barry
- *
- *******************************************************************************
- ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
- *** ***
- *** ***
- *** FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP ***
- *** demos have a dependency on FreeRTOS+FAT, which is only in the Labs ***
- *** download): ***
- *** ***
- *** FreeRTOS+TCP is functional and has been used in commercial products ***
- *** for some time. Be aware however that we are still refining its ***
- *** design, the source code does not yet quite conform to the strict ***
- *** coding and style standards mandated by Real Time Engineers ltd., and ***
- *** the documentation and testing is not necessarily complete. ***
- *** ***
- *** PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE ***
- *** URL: http://www.FreeRTOS.org/contact Active early adopters may, at ***
- *** the sole discretion of Real Time Engineers Ltd., be offered versions ***
- *** under a license other than that described below. ***
- *** ***
- *** ***
- ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
- *******************************************************************************
- *
- * FreeRTOS+TCP can be used under two different free open source licenses. The
- * license that applies is dependent on the processor on which FreeRTOS+TCP is
- * executed, as follows:
- *
- * If FreeRTOS+TCP is executed on one of the processors listed under the Special
- * License Arrangements heading of the FreeRTOS+TCP license information web
- * page, then it can be used under the terms of the FreeRTOS Open Source
- * License. If FreeRTOS+TCP is used on any other processor, then it can be used
- * under the terms of the GNU General Public License V2. Links to the relevant
- * licenses follow:
- *
- * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license
- * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license
- * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt
- *
- * FreeRTOS+TCP is distributed in the hope that it will be useful. You cannot
- * use FreeRTOS+TCP unless you agree that you use the software 'as is'.
- * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied
- * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they
- * implied, expressed, or statutory.
- *
- * 1 tab == 4 spaces!
- *
- * http://www.FreeRTOS.org
- * http://www.FreeRTOS.org/plus
- * http://www.FreeRTOS.org/labs
- *
- */
-
-/******************************************************************************
-*
-* See the following web page for essential buffer allocation scheme usage and
-* configuration details:
-* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
-*
-******************************************************************************/
-
-/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
- * THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
- * heap_4 can be used. */
-
-/* Standard includes. */
-#include <stdint.h>
-
-/* FreeRTOS includes. */
-#include "FreeRTOS.h"
-#include "task.h"
-#include "semphr.h"
-
-/* FreeRTOS+TCP includes. */
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_UDP_IP.h"
-#include "FreeRTOS_IP_Private.h"
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-#include "tcpip/tcpip.h"
-#include "tcpip/src/tcpip_private.h"
-
-#include "NetworkConfig.h"
-
-/* The obtained network buffer must be large enough to hold a packet that might
- * replace the packet that was requested to be sent. */
-#if ipconfigUSE_TCP == 1
- #define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
-#else
- #define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
-#endif /* ipconfigUSE_TCP == 1 */
-
-/*_RB_ This is too complex not to have an explanation. */
-#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
- #define ASSERT_CONCAT_( a, b ) a ## b
- #define ASSERT_CONCAT( a, b ) ASSERT_CONCAT_( a, b )
- #define STATIC_ASSERT( e ) \
- ; enum { ASSERT_CONCAT( assert_line_, __LINE__ ) = 1 / ( !!( e ) ) }
-
- STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
-#endif
-
-/* A list of free (available) NetworkBufferDescriptor_t structures. */
-static List_t xFreeBuffersList;
-
-/* Some statistics about the use of buffers. */
-static size_t uxMinimumFreeNetworkBuffers;
-
-/* Declares the pool of NetworkBufferDescriptor_t structures that are available
- * to the system. All the network buffers referenced from xFreeBuffersList exist
- * in this array. The array is not accessed directly except during initialisation,
- * when the xFreeBuffersList is filled (as all the buffers are free when the system
- * is booted). */
-static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
-
-/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
- * network buffers have a variable size: resizing may be necessary */
-const BaseType_t xBufferAllocFixedSize = pdFALSE;
-
-/* The semaphore used to obtain network buffers. */
-static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
-
-/*-----------------------------------------------------------*/
-
-#ifdef PIC32_USE_ETHERNET
-
- /* PIC32 specific stuff */
- /* */
-
- /* MAC packet acknowledgment, once MAC is done with it */
- static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
- const void * param );
-
- /* allocates a MAC packet that holds a data buffer that can be used by both: */
- /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
- /* - the Harmony MAC driver: TCPIP_MAC_PACKET->pDSeg->segLoad */
- /* from the beginning of the buffer: */
- /* - 4 bytes pointer to the network descriptor (FreeRTOS) */
- /* - 4 bytes pointer to the MAC packet (pic32_NetworkInterface.c) */
- /* - 2 bytes offset from the MAC packet (Harmony MAC driver: segLoadOffset) */
- /* */
- /* NOTE: segLoadLen should NOT include: */
- /* - the TCPIP_MAC_FRAME_OFFSET (== ipBUFFER_PADDING which should be == 10!) */
- /* - the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
- /* These are added by the MAC packet allocation! */
- /* */
- static uint8_t * PIC32_PktAlloc( uint16_t pktLen,
- uint16_t segLoadLen,
- TCPIP_MAC_PACKET_ACK_FUNC ackF,
- TCPIP_MAC_PACKET ** pPtrPkt )
- {
- uint8_t * pBuff = 0;
-
- /* allocate standard packet */
- TCPIP_MAC_PACKET * pPkt = TCPIP_PKT_PacketAlloc( pktLen, segLoadLen, 0 );
-
- /* set the MAC packet pointer in the packet */
- if( pPkt != 0 )
- {
- pBuff = pPkt->pDSeg->segLoad;
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pBuff - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- *ppkt = pPkt; /* store the packet it comes from */
- pPkt->ackFunc = ackF;
- pPkt->ackParam = 0;
- }
-
- if( pPtrPkt != 0 )
- {
- *pPtrPkt = pPkt;
- }
-
- return pBuff;
- }
-
-
-
- /* standard PIC32 MAC allocation function for a MAC packet */
- /* this packet saves room for the FreeRTOS network descriptor */
- /* at the beginning of the data buffer */
- /* see NetworkBufferAllocate */
- /* Note: flags parameter is ignored since that's used in the Harmony stack only */
- TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
- uint16_t segLoadLen,
- TCPIP_MAC_PACKET_FLAGS flags )
- {
- TCPIP_MAC_PACKET * pPkt;
-
- PIC32_PktAlloc( pktLen, segLoadLen, 0, &pPkt );
-
- return pPkt;
- }
-
- /* standard PIC32 MAC packet acknowledgment */
- /* function called once MAC is done with it */
- static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
- const void * param )
- {
- configASSERT( ( pPkt != 0 ) );
-
- TCPIP_PKT_PacketFree( pPkt );
-
- return false;
- }
-
- /* associates the current MAC packet with a network descriptor */
- /* mainly for RX packet */
- void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
- NetworkBufferDescriptor_t * pxBufferDescriptor,
- size_t pktLength )
- {
- uint8_t * pPktBuff = pRxPkt->pDSeg->segLoad;
-
- pxBufferDescriptor->pucEthernetBuffer = pPktBuff;
- pxBufferDescriptor->xDataLength = pktLength;
-
- /* make sure this is a properly allocated packet */
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pPktBuff - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
-
- if( *ppkt != pRxPkt )
- {
- configASSERT( false );
- }
-
- /* set the proper descriptor info */
- NetworkBufferDescriptor_t ** ppDcpt = ( NetworkBufferDescriptor_t ** ) ( pPktBuff - ipBUFFER_PADDING );
- configASSERT( ( ( uint32_t ) ppDcpt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- *ppDcpt = pxBufferDescriptor;
- }
-
- /* debug functionality */
- void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt )
- {
- TCPIP_PKT_PacketFree( pPkt );
- configASSERT( false );
- }
-
- /* FreeRTOS allocation functions */
-
- /* allocates a buffer that can be used by both: */
- /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
- /* - the Harmony MAC driver: TCPIP_MAC_PACKET */
- /* See PIC32_PktAlloc for details */
- /* */
- /* NOTE: reqLength should NOT include the ipBUFFER_PADDING (which should be == 10!) */
- /* or the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
- /* These are added by the MAC packet allocation! */
- /* */
- uint8_t * NetworkBufferAllocate( size_t reqLength )
- {
- return PIC32_PktAlloc( sizeof( TCPIP_MAC_PACKET ), reqLength, PIC32_MacPacketAcknowledge, 0 );
- }
-
- /* deallocates a network buffer previously allocated */
- /* with NetworkBufferAllocate */
- void NetworkBufferFree( uint8_t * pNetworkBuffer )
- {
- if( pNetworkBuffer != 0 )
- {
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pNetworkBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- TCPIP_MAC_PACKET * pPkt = *ppkt;
- configASSERT( ( pPkt != 0 ) );
-
- if( pPkt->ackFunc != 0 )
- {
- ( *pPkt->ackFunc )( pPkt, pPkt->ackParam );
- }
- else
- { /* ??? */
- PIC32_MacPacketOrphan( pPkt );
- }
- }
- }
-
-#endif /* #ifdef PIC32_USE_ETHERNET */
-
-/*-----------------------------------------------------------*/
-
-BaseType_t xNetworkBuffersInitialise( void )
-{
- BaseType_t xReturn, x;
-
- /* Only initialise the buffers and their associated kernel objects if they
- * have not been initialised before. */
- if( xNetworkBufferSemaphore == NULL )
- {
- xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
- configASSERT( xNetworkBufferSemaphore );
-
- if( xNetworkBufferSemaphore != NULL )
- {
- #if ( configQUEUE_REGISTRY_SIZE > 0 )
- {
- vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
- }
- #endif /* configQUEUE_REGISTRY_SIZE */
-
- /* If the trace recorder code is included name the semaphore for viewing
- * in FreeRTOS+Trace. */
- #if ( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
- {
- extern QueueHandle_t xNetworkEventQueue;
- vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
- vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
- }
- #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
-
- vListInitialise( &xFreeBuffersList );
-
- /* Initialise all the network buffers. No storage is allocated to
- * the buffers yet. */
- for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
- {
- /* Initialise and set the owner of the buffer list items. */
- xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
- vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
- listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
-
- /* Currently, all buffers are available for use. */
- vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
- }
-
- uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
- }
- }
-
- if( xNetworkBufferSemaphore == NULL )
- {
- xReturn = pdFAIL;
- }
- else
- {
- xReturn = pdPASS;
- }
-
- return xReturn;
-}
-/*-----------------------------------------------------------*/
-
-uint8_t * pucGetNetworkBuffer( size_t * pxRequestedSizeBytes )
-{
- uint8_t * pucEthernetBuffer;
- size_t xSize = *pxRequestedSizeBytes;
-
- if( xSize < baMINIMAL_BUFFER_SIZE )
- {
- /* Buffers must be at least large enough to hold a TCP-packet with
- * headers, or an ARP packet, in case TCP is not included. */
- xSize = baMINIMAL_BUFFER_SIZE;
- }
-
- /* Round up xSize to the nearest multiple of N bytes,
- * where N equals 'sizeof( size_t )'. */
- if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
- {
- xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
- }
-
- *pxRequestedSizeBytes = xSize;
-
- /* Allocate a buffer large enough to store the requested Ethernet frame size
- * and a pointer to a network buffer structure (hence the addition of
- * ipBUFFER_PADDING bytes). */
-
- #ifdef PIC32_USE_ETHERNET
- pucEthernetBuffer = NetworkBufferAllocate( xSize - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
- #else
- pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- configASSERT( pucEthernetBuffer );
-
- if( pucEthernetBuffer != NULL )
- {
- /* Enough space is left at the start of the buffer to place a pointer to
- * the network buffer structure that references this Ethernet buffer.
- * Return a pointer to the start of the Ethernet buffer itself. */
- #ifndef PIC32_USE_ETHERNET
- pucEthernetBuffer += ipBUFFER_PADDING;
- #endif /* #ifndef PIC32_USE_ETHERNET */
- }
-
- return pucEthernetBuffer;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBuffer( uint8_t * pucEthernetBuffer )
-{
- /* There is space before the Ethernet buffer in which a pointer to the
- * network buffer that references this Ethernet buffer is stored. Remove the
- * space before freeing the buffer. */
- #ifdef PIC32_USE_ETHERNET
- NetworkBufferFree( pucEthernetBuffer );
- #else
- if( pucEthernetBuffer != NULL )
- {
- pucEthernetBuffer -= ipBUFFER_PADDING;
- vPortFree( ( void * ) pucEthernetBuffer );
- }
- #endif /* #ifdef PIC32_USE_ETHERNET */
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
- TickType_t xBlockTimeTicks )
-{
- NetworkBufferDescriptor_t * pxReturn = NULL;
- size_t uxCount;
-
- if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
- {
- /* ARP packets can replace application packets, so the storage must be
- * at least large enough to hold an ARP. */
- xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
- }
-
- #ifdef PIC32_USE_ETHERNET
- if( xRequestedSizeBytes != 0u )
- {
- #endif /* #ifdef PIC32_USE_ETHERNET */
- xRequestedSizeBytes += 2u;
-
- if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
- {
- xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
- }
- #ifdef PIC32_USE_ETHERNET
- }
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- /* If there is a semaphore available, there is a network buffer available. */
- if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
- {
- /* Protect the structure as it is accessed from tasks and interrupts. */
- taskENTER_CRITICAL();
- {
- pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
- uxListRemove( &( pxReturn->xBufferListItem ) );
- }
- taskEXIT_CRITICAL();
-
- /* Reading UBaseType_t, no critical section needed. */
- uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-
- if( uxMinimumFreeNetworkBuffers > uxCount )
- {
- uxMinimumFreeNetworkBuffers = uxCount;
- }
-
- /* Allocate storage of exactly the requested size to the buffer. */
- configASSERT( pxReturn->pucEthernetBuffer == NULL );
-
- if( xRequestedSizeBytes > 0 )
- {
- /* Extra space is obtained so a pointer to the network buffer can
- * be stored at the beginning of the buffer. */
-
- #ifdef PIC32_USE_ETHERNET
- pxReturn->pucEthernetBuffer = NetworkBufferAllocate( xRequestedSizeBytes - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
- #else
- pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- if( pxReturn->pucEthernetBuffer == NULL )
- {
- /* The attempt to allocate storage for the buffer payload failed,
- * so the network buffer structure cannot be used and must be
- * released. */
- vReleaseNetworkBufferAndDescriptor( pxReturn );
- pxReturn = NULL;
- }
- else
- {
- /* Store a pointer to the network buffer structure in the
- * buffer storage area, then move the buffer pointer on past the
- * stored pointer so the pointer value is not overwritten by the
- * application when the buffer is used. */
- #ifdef PIC32_USE_ETHERNET
- *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer - ipBUFFER_PADDING ) ) = pxReturn;
- #else
- *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
- pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- /* Store the actual size of the allocated buffer, which may be
- * greater than the original requested size. */
- pxReturn->xDataLength = xRequestedSizeBytes;
-
- #if ( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
- {
- /* make sure the buffer is not linked */
- pxReturn->pxNextBuffer = NULL;
- }
- #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
- }
- }
- else
- {
- /* A descriptor is being returned without an associated buffer being
- * allocated. */
- }
- }
-
- if( pxReturn == NULL )
- {
- iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
- }
- else
- {
- iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
- }
-
- return pxReturn;
-}
-/*-----------------------------------------------------------*/
-
-void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
-{
- BaseType_t xListItemAlreadyInFreeList;
-
- /* Ensure the buffer is returned to the list of free buffers before the
- * counting semaphore is 'given' to say a buffer is available. Release the
- * storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
- * IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
- * MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
- vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
- pxNetworkBuffer->pucEthernetBuffer = NULL;
-
- taskENTER_CRITICAL();
- {
- xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
-
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
- }
- }
- taskEXIT_CRITICAL();
-
- /*
- * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
- * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
- */
- if( xListItemAlreadyInFreeList == pdFALSE )
- {
- if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
- {
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
- }
- }
- else
- {
- iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
- }
-}
-/*-----------------------------------------------------------*/
-
-/*
- * Returns the number of free network buffers
- */
-UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
-{
- return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
-}
-/*-----------------------------------------------------------*/
-
-UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
-{
- return uxMinimumFreeNetworkBuffers;
-}
-/*-----------------------------------------------------------*/
-
-NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
- size_t xNewSizeBytes )
-{
- size_t xOriginalLength;
- uint8_t * pucBuffer;
-
- #ifdef PIC32_USE_ETHERNET
- xOriginalLength = pxNetworkBuffer->xDataLength;
- #else
- xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
- xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
-
- if( pucBuffer == NULL )
- {
- /* In case the allocation fails, return NULL. */
- pxNetworkBuffer = NULL;
- }
- else
- {
- pxNetworkBuffer->xDataLength = xNewSizeBytes;
- if( xNewSizeBytes > xOriginalLength )
- {
- xNewSizeBytes = xOriginalLength;
- }
-
- #ifdef PIC32_USE_ETHERNET
- memcpy( pucBuffer, pxNetworkBuffer->pucEthernetBuffer, xNewSizeBytes );
- *( ( NetworkBufferDescriptor_t ** ) ( pucBuffer - ipBUFFER_PADDING ) ) = pxNetworkBuffer;
- #else
- memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
- #endif /* #ifdef PIC32_USE_ETHERNET */
-
- vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
- pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
- }
-
- return pxNetworkBuffer;
-}
+/*
+ * FreeRTOS+TCP Labs Build 160919 (C) 2016 Real Time Engineers ltd.
+ * Authors include Hein Tibosch and Richard Barry
+ *
+ *******************************************************************************
+ ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
+ *** ***
+ *** ***
+ *** FREERTOS+TCP IS STILL IN THE LAB (mainly because the FTP and HTTP ***
+ *** demos have a dependency on FreeRTOS+FAT, which is only in the Labs ***
+ *** download): ***
+ *** ***
+ *** FreeRTOS+TCP is functional and has been used in commercial products ***
+ *** for some time. Be aware however that we are still refining its ***
+ *** design, the source code does not yet quite conform to the strict ***
+ *** coding and style standards mandated by Real Time Engineers ltd., and ***
+ *** the documentation and testing is not necessarily complete. ***
+ *** ***
+ *** PLEASE REPORT EXPERIENCES USING THE SUPPORT RESOURCES FOUND ON THE ***
+ *** URL: http://www.FreeRTOS.org/contact Active early adopters may, at ***
+ *** the sole discretion of Real Time Engineers Ltd., be offered versions ***
+ *** under a license other than that described below. ***
+ *** ***
+ *** ***
+ ***** NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ******* NOTE ***
+ *******************************************************************************
+ *
+ * FreeRTOS+TCP can be used under two different free open source licenses. The
+ * license that applies is dependent on the processor on which FreeRTOS+TCP is
+ * executed, as follows:
+ *
+ * If FreeRTOS+TCP is executed on one of the processors listed under the Special
+ * License Arrangements heading of the FreeRTOS+TCP license information web
+ * page, then it can be used under the terms of the FreeRTOS Open Source
+ * License. If FreeRTOS+TCP is used on any other processor, then it can be used
+ * under the terms of the GNU General Public License V2. Links to the relevant
+ * licenses follow:
+ *
+ * The FreeRTOS+TCP License Information Page: http://www.FreeRTOS.org/tcp_license
+ * The FreeRTOS Open Source License: http://www.FreeRTOS.org/license
+ * The GNU General Public License Version 2: http://www.FreeRTOS.org/gpl-2.0.txt
+ *
+ * FreeRTOS+TCP is distributed in the hope that it will be useful. You cannot
+ * use FreeRTOS+TCP unless you agree that you use the software 'as is'.
+ * FreeRTOS+TCP is provided WITHOUT ANY WARRANTY; without even the implied
+ * warranties of NON-INFRINGEMENT, MERCHANTABILITY or FITNESS FOR A PARTICULAR
+ * PURPOSE. Real Time Engineers Ltd. disclaims all conditions and terms, be they
+ * implied, expressed, or statutory.
+ *
+ * 1 tab == 4 spaces!
+ *
+ * http://www.FreeRTOS.org
+ * http://www.FreeRTOS.org/plus
+ * http://www.FreeRTOS.org/labs
+ *
+ */
+
+/******************************************************************************
+*
+* See the following web page for essential buffer allocation scheme usage and
+* configuration details:
+* http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/Embedded_Ethernet_Buffer_Management.html
+*
+******************************************************************************/
+
+/* THIS FILE SHOULD NOT BE USED IF THE PROJECT INCLUDES A MEMORY ALLOCATOR
+ * THAT WILL FRAGMENT THE HEAP MEMORY. For example, heap_2 must not be used,
+ * heap_4 can be used. */
+
+/* Standard includes. */
+#include <stdint.h>
+
+/* FreeRTOS includes. */
+#include "FreeRTOS.h"
+#include "task.h"
+#include "semphr.h"
+
+/* FreeRTOS+TCP includes. */
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_UDP_IP.h"
+#include "FreeRTOS_IP_Private.h"
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+#include "tcpip/tcpip.h"
+#include "tcpip/src/tcpip_private.h"
+
+#include "NetworkConfig.h"
+
+/* The obtained network buffer must be large enough to hold a packet that might
+ * replace the packet that was requested to be sent. */
+#if ipconfigUSE_TCP == 1
+ #define baMINIMAL_BUFFER_SIZE sizeof( TCPPacket_t )
+#else
+ #define baMINIMAL_BUFFER_SIZE sizeof( ARPPacket_t )
+#endif /* ipconfigUSE_TCP == 1 */
+
+/*_RB_ This is too complex not to have an explanation. */
+#if defined( ipconfigETHERNET_MINIMUM_PACKET_BYTES )
+ #define ASSERT_CONCAT_( a, b ) a ## b
+ #define ASSERT_CONCAT( a, b ) ASSERT_CONCAT_( a, b )
+ #define STATIC_ASSERT( e ) \
+ ; enum { ASSERT_CONCAT( assert_line_, __LINE__ ) = 1 / ( !!( e ) ) }
+
+ STATIC_ASSERT( ipconfigETHERNET_MINIMUM_PACKET_BYTES <= baMINIMAL_BUFFER_SIZE );
+#endif
+
+/* A list of free (available) NetworkBufferDescriptor_t structures. */
+static List_t xFreeBuffersList;
+
+/* Some statistics about the use of buffers. */
+static size_t uxMinimumFreeNetworkBuffers;
+
+/* Declares the pool of NetworkBufferDescriptor_t structures that are available
+ * to the system. All the network buffers referenced from xFreeBuffersList exist
+ * in this array. The array is not accessed directly except during initialisation,
+ * when the xFreeBuffersList is filled (as all the buffers are free when the system
+ * is booted). */
+static NetworkBufferDescriptor_t xNetworkBufferDescriptors[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ];
+
+/* This constant is defined as false to let FreeRTOS_TCP_IP.c know that the
+ * network buffers have a variable size: resizing may be necessary */
+const BaseType_t xBufferAllocFixedSize = pdFALSE;
+
+/* The semaphore used to obtain network buffers. */
+static SemaphoreHandle_t xNetworkBufferSemaphore = NULL;
+
+/*-----------------------------------------------------------*/
+
+#ifdef PIC32_USE_ETHERNET
+
+ /* PIC32 specific stuff */
+ /* */
+
+ /* MAC packet acknowledgment, once MAC is done with it */
+ static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
+ const void * param );
+
+ /* allocates a MAC packet that holds a data buffer that can be used by both: */
+ /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
+ /* - the Harmony MAC driver: TCPIP_MAC_PACKET->pDSeg->segLoad */
+ /* from the beginning of the buffer: */
+ /* - 4 bytes pointer to the network descriptor (FreeRTOS) */
+ /* - 4 bytes pointer to the MAC packet (pic32_NetworkInterface.c) */
+ /* - 2 bytes offset from the MAC packet (Harmony MAC driver: segLoadOffset) */
+ /* */
+ /* NOTE: segLoadLen should NOT include: */
+ /* - the TCPIP_MAC_FRAME_OFFSET (== ipBUFFER_PADDING which should be == 10!) */
+ /* - the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
+ /* These are added by the MAC packet allocation! */
+ /* */
+ static uint8_t * PIC32_PktAlloc( uint16_t pktLen,
+ uint16_t segLoadLen,
+ TCPIP_MAC_PACKET_ACK_FUNC ackF,
+ TCPIP_MAC_PACKET ** pPtrPkt )
+ {
+ uint8_t * pBuff = 0;
+
+ /* allocate standard packet */
+ TCPIP_MAC_PACKET * pPkt = TCPIP_PKT_PacketAlloc( pktLen, segLoadLen, 0 );
+
+ /* set the MAC packet pointer in the packet */
+ if( pPkt != 0 )
+ {
+ pBuff = pPkt->pDSeg->segLoad;
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pBuff - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ *ppkt = pPkt; /* store the packet it comes from */
+ pPkt->ackFunc = ackF;
+ pPkt->ackParam = 0;
+ }
+
+ if( pPtrPkt != 0 )
+ {
+ *pPtrPkt = pPkt;
+ }
+
+ return pBuff;
+ }
+
+
+
+ /* standard PIC32 MAC allocation function for a MAC packet */
+ /* this packet saves room for the FreeRTOS network descriptor */
+ /* at the beginning of the data buffer */
+ /* see NetworkBufferAllocate */
+ /* Note: flags parameter is ignored since that's used in the Harmony stack only */
+ TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
+ uint16_t segLoadLen,
+ TCPIP_MAC_PACKET_FLAGS flags )
+ {
+ TCPIP_MAC_PACKET * pPkt;
+
+ PIC32_PktAlloc( pktLen, segLoadLen, 0, &pPkt );
+
+ return pPkt;
+ }
+
+ /* standard PIC32 MAC packet acknowledgment */
+ /* function called once MAC is done with it */
+ static bool PIC32_MacPacketAcknowledge( TCPIP_MAC_PACKET * pPkt,
+ const void * param )
+ {
+ configASSERT( ( pPkt != 0 ) );
+
+ TCPIP_PKT_PacketFree( pPkt );
+
+ return false;
+ }
+
+ /* associates the current MAC packet with a network descriptor */
+ /* mainly for RX packet */
+ void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
+ NetworkBufferDescriptor_t * pxBufferDescriptor,
+ size_t pktLength )
+ {
+ uint8_t * pPktBuff = pRxPkt->pDSeg->segLoad;
+
+ pxBufferDescriptor->pucEthernetBuffer = pPktBuff;
+ pxBufferDescriptor->xDataLength = pktLength;
+
+ /* make sure this is a properly allocated packet */
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pPktBuff - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+
+ if( *ppkt != pRxPkt )
+ {
+ configASSERT( false );
+ }
+
+ /* set the proper descriptor info */
+ NetworkBufferDescriptor_t ** ppDcpt = ( NetworkBufferDescriptor_t ** ) ( pPktBuff - ipBUFFER_PADDING );
+ configASSERT( ( ( uint32_t ) ppDcpt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ *ppDcpt = pxBufferDescriptor;
+ }
+
+ /* debug functionality */
+ void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt )
+ {
+ TCPIP_PKT_PacketFree( pPkt );
+ configASSERT( false );
+ }
+
+ /* FreeRTOS allocation functions */
+
+ /* allocates a buffer that can be used by both: */
+ /* - the FreeRTOSIP (NetworkBufferDescriptor_t->pucEthernetBuffer) */
+ /* - the Harmony MAC driver: TCPIP_MAC_PACKET */
+ /* See PIC32_PktAlloc for details */
+ /* */
+ /* NOTE: reqLength should NOT include the ipBUFFER_PADDING (which should be == 10!) */
+ /* or the sizeof(TCPIP_MAC_ETHERNET_HEADER) */
+ /* These are added by the MAC packet allocation! */
+ /* */
+ uint8_t * NetworkBufferAllocate( size_t reqLength )
+ {
+ return PIC32_PktAlloc( sizeof( TCPIP_MAC_PACKET ), reqLength, PIC32_MacPacketAcknowledge, 0 );
+ }
+
+ /* deallocates a network buffer previously allocated */
+ /* with NetworkBufferAllocate */
+ void NetworkBufferFree( uint8_t * pNetworkBuffer )
+ {
+ if( pNetworkBuffer != 0 )
+ {
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pNetworkBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ TCPIP_MAC_PACKET * pPkt = *ppkt;
+ configASSERT( ( pPkt != 0 ) );
+
+ if( pPkt->ackFunc != 0 )
+ {
+ ( *pPkt->ackFunc )( pPkt, pPkt->ackParam );
+ }
+ else
+ { /* ??? */
+ PIC32_MacPacketOrphan( pPkt );
+ }
+ }
+ }
+
+#endif /* #ifdef PIC32_USE_ETHERNET */
+
+/*-----------------------------------------------------------*/
+
+BaseType_t xNetworkBuffersInitialise( void )
+{
+ BaseType_t xReturn, x;
+
+ /* Only initialise the buffers and their associated kernel objects if they
+ * have not been initialised before. */
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xNetworkBufferSemaphore = xSemaphoreCreateCounting( ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS, ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS );
+ configASSERT( xNetworkBufferSemaphore );
+
+ if( xNetworkBufferSemaphore != NULL )
+ {
+ #if ( configQUEUE_REGISTRY_SIZE > 0 )
+ {
+ vQueueAddToRegistry( xNetworkBufferSemaphore, "NetBufSem" );
+ }
+ #endif /* configQUEUE_REGISTRY_SIZE */
+
+ /* If the trace recorder code is included name the semaphore for viewing
+ * in FreeRTOS+Trace. */
+ #if ( ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 )
+ {
+ extern QueueHandle_t xNetworkEventQueue;
+ vTraceSetQueueName( xNetworkEventQueue, "IPStackEvent" );
+ vTraceSetQueueName( xNetworkBufferSemaphore, "NetworkBufferCount" );
+ }
+ #endif /* ipconfigINCLUDE_EXAMPLE_FREERTOS_PLUS_TRACE_CALLS == 1 */
+
+ vListInitialise( &xFreeBuffersList );
+
+ /* Initialise all the network buffers. No storage is allocated to
+ * the buffers yet. */
+ for( x = 0; x < ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS; x++ )
+ {
+ /* Initialise and set the owner of the buffer list items. */
+ xNetworkBufferDescriptors[ x ].pucEthernetBuffer = NULL;
+ vListInitialiseItem( &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
+ listSET_LIST_ITEM_OWNER( &( xNetworkBufferDescriptors[ x ].xBufferListItem ), &xNetworkBufferDescriptors[ x ] );
+
+ /* Currently, all buffers are available for use. */
+ vListInsert( &xFreeBuffersList, &( xNetworkBufferDescriptors[ x ].xBufferListItem ) );
+ }
+
+ uxMinimumFreeNetworkBuffers = ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS;
+ }
+ }
+
+ if( xNetworkBufferSemaphore == NULL )
+ {
+ xReturn = pdFAIL;
+ }
+ else
+ {
+ xReturn = pdPASS;
+ }
+
+ return xReturn;
+}
+/*-----------------------------------------------------------*/
+
+uint8_t * pucGetNetworkBuffer( size_t * pxRequestedSizeBytes )
+{
+ uint8_t * pucEthernetBuffer;
+ size_t xSize = *pxRequestedSizeBytes;
+
+ if( xSize < baMINIMAL_BUFFER_SIZE )
+ {
+ /* Buffers must be at least large enough to hold a TCP-packet with
+ * headers, or an ARP packet, in case TCP is not included. */
+ xSize = baMINIMAL_BUFFER_SIZE;
+ }
+
+ /* Round up xSize to the nearest multiple of N bytes,
+ * where N equals 'sizeof( size_t )'. */
+ if( ( xSize & ( sizeof( size_t ) - 1u ) ) != 0u )
+ {
+ xSize = ( xSize | ( sizeof( size_t ) - 1u ) ) + 1u;
+ }
+
+ *pxRequestedSizeBytes = xSize;
+
+ /* Allocate a buffer large enough to store the requested Ethernet frame size
+ * and a pointer to a network buffer structure (hence the addition of
+ * ipBUFFER_PADDING bytes). */
+
+ #ifdef PIC32_USE_ETHERNET
+ pucEthernetBuffer = NetworkBufferAllocate( xSize - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
+ #else
+ pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xSize + ipBUFFER_PADDING );
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ configASSERT( pucEthernetBuffer );
+
+ if( pucEthernetBuffer != NULL )
+ {
+ /* Enough space is left at the start of the buffer to place a pointer to
+ * the network buffer structure that references this Ethernet buffer.
+ * Return a pointer to the start of the Ethernet buffer itself. */
+ #ifndef PIC32_USE_ETHERNET
+ pucEthernetBuffer += ipBUFFER_PADDING;
+ #endif /* #ifndef PIC32_USE_ETHERNET */
+ }
+
+ return pucEthernetBuffer;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBuffer( uint8_t * pucEthernetBuffer )
+{
+ /* There is space before the Ethernet buffer in which a pointer to the
+ * network buffer that references this Ethernet buffer is stored. Remove the
+ * space before freeing the buffer. */
+ #ifdef PIC32_USE_ETHERNET
+ NetworkBufferFree( pucEthernetBuffer );
+ #else
+ if( pucEthernetBuffer != NULL )
+ {
+ pucEthernetBuffer -= ipBUFFER_PADDING;
+ vPortFree( ( void * ) pucEthernetBuffer );
+ }
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t * pxGetNetworkBufferWithDescriptor( size_t xRequestedSizeBytes,
+ TickType_t xBlockTimeTicks )
+{
+ NetworkBufferDescriptor_t * pxReturn = NULL;
+ size_t uxCount;
+
+ if( ( xRequestedSizeBytes != 0u ) && ( xRequestedSizeBytes < ( size_t ) baMINIMAL_BUFFER_SIZE ) )
+ {
+ /* ARP packets can replace application packets, so the storage must be
+ * at least large enough to hold an ARP. */
+ xRequestedSizeBytes = baMINIMAL_BUFFER_SIZE;
+ }
+
+ #ifdef PIC32_USE_ETHERNET
+ if( xRequestedSizeBytes != 0u )
+ {
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+ xRequestedSizeBytes += 2u;
+
+ if( ( xRequestedSizeBytes & ( sizeof( size_t ) - 1u ) ) != 0u )
+ {
+ xRequestedSizeBytes = ( xRequestedSizeBytes | ( sizeof( size_t ) - 1u ) ) + 1u;
+ }
+ #ifdef PIC32_USE_ETHERNET
+ }
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ /* If there is a semaphore available, there is a network buffer available. */
+ if( xSemaphoreTake( xNetworkBufferSemaphore, xBlockTimeTicks ) == pdPASS )
+ {
+ /* Protect the structure as it is accessed from tasks and interrupts. */
+ taskENTER_CRITICAL();
+ {
+ pxReturn = ( NetworkBufferDescriptor_t * ) listGET_OWNER_OF_HEAD_ENTRY( &xFreeBuffersList );
+ uxListRemove( &( pxReturn->xBufferListItem ) );
+ }
+ taskEXIT_CRITICAL();
+
+ /* Reading UBaseType_t, no critical section needed. */
+ uxCount = listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+
+ if( uxMinimumFreeNetworkBuffers > uxCount )
+ {
+ uxMinimumFreeNetworkBuffers = uxCount;
+ }
+
+ /* Allocate storage of exactly the requested size to the buffer. */
+ configASSERT( pxReturn->pucEthernetBuffer == NULL );
+
+ if( xRequestedSizeBytes > 0 )
+ {
+ /* Extra space is obtained so a pointer to the network buffer can
+ * be stored at the beginning of the buffer. */
+
+ #ifdef PIC32_USE_ETHERNET
+ pxReturn->pucEthernetBuffer = NetworkBufferAllocate( xRequestedSizeBytes - sizeof( TCPIP_MAC_ETHERNET_HEADER ) );
+ #else
+ pxReturn->pucEthernetBuffer = ( uint8_t * ) pvPortMalloc( xRequestedSizeBytes + ipBUFFER_PADDING );
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ if( pxReturn->pucEthernetBuffer == NULL )
+ {
+ /* The attempt to allocate storage for the buffer payload failed,
+ * so the network buffer structure cannot be used and must be
+ * released. */
+ vReleaseNetworkBufferAndDescriptor( pxReturn );
+ pxReturn = NULL;
+ }
+ else
+ {
+ /* Store a pointer to the network buffer structure in the
+ * buffer storage area, then move the buffer pointer on past the
+ * stored pointer so the pointer value is not overwritten by the
+ * application when the buffer is used. */
+ #ifdef PIC32_USE_ETHERNET
+ *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer - ipBUFFER_PADDING ) ) = pxReturn;
+ #else
+ *( ( NetworkBufferDescriptor_t ** ) ( pxReturn->pucEthernetBuffer ) ) = pxReturn;
+ pxReturn->pucEthernetBuffer += ipBUFFER_PADDING;
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ /* Store the actual size of the allocated buffer, which may be
+ * greater than the original requested size. */
+ pxReturn->xDataLength = xRequestedSizeBytes;
+
+ #if ( ipconfigUSE_LINKED_RX_MESSAGES != 0 )
+ {
+ /* make sure the buffer is not linked */
+ pxReturn->pxNextBuffer = NULL;
+ }
+ #endif /* ipconfigUSE_LINKED_RX_MESSAGES */
+ }
+ }
+ else
+ {
+ /* A descriptor is being returned without an associated buffer being
+ * allocated. */
+ }
+ }
+
+ if( pxReturn == NULL )
+ {
+ iptraceFAILED_TO_OBTAIN_NETWORK_BUFFER();
+ }
+ else
+ {
+ iptraceNETWORK_BUFFER_OBTAINED( pxReturn );
+ }
+
+ return pxReturn;
+}
+/*-----------------------------------------------------------*/
+
+void vReleaseNetworkBufferAndDescriptor( NetworkBufferDescriptor_t * const pxNetworkBuffer )
+{
+ BaseType_t xListItemAlreadyInFreeList;
+
+ /* Ensure the buffer is returned to the list of free buffers before the
+ * counting semaphore is 'given' to say a buffer is available. Release the
+ * storage allocated to the buffer payload. THIS FILE SHOULD NOT BE USED
+ * IF THE PROJECT INCLUDES A MEMORY ALLOCATOR THAT WILL FRAGMENT THE HEAP
+ * MEMORY. For example, heap_2 must not be used, heap_4 can be used. */
+ vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
+ pxNetworkBuffer->pucEthernetBuffer = NULL;
+
+ taskENTER_CRITICAL();
+ {
+ xListItemAlreadyInFreeList = listIS_CONTAINED_WITHIN( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ vListInsertEnd( &xFreeBuffersList, &( pxNetworkBuffer->xBufferListItem ) );
+ }
+ }
+ taskEXIT_CRITICAL();
+
+ /*
+ * Update the network state machine, unless the program fails to release its 'xNetworkBufferSemaphore'.
+ * The program should only try to release its semaphore if 'xListItemAlreadyInFreeList' is false.
+ */
+ if( xListItemAlreadyInFreeList == pdFALSE )
+ {
+ if ( xSemaphoreGive( xNetworkBufferSemaphore ) == pdTRUE )
+ {
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+ }
+ }
+ else
+ {
+ iptraceNETWORK_BUFFER_RELEASED( pxNetworkBuffer );
+ }
+}
+/*-----------------------------------------------------------*/
+
+/*
+ * Returns the number of free network buffers
+ */
+UBaseType_t uxGetNumberOfFreeNetworkBuffers( void )
+{
+ return listCURRENT_LIST_LENGTH( &xFreeBuffersList );
+}
+/*-----------------------------------------------------------*/
+
+UBaseType_t uxGetMinimumFreeNetworkBuffers( void )
+{
+ return uxMinimumFreeNetworkBuffers;
+}
+/*-----------------------------------------------------------*/
+
+NetworkBufferDescriptor_t * pxResizeNetworkBufferWithDescriptor( NetworkBufferDescriptor_t * pxNetworkBuffer,
+ size_t xNewSizeBytes )
+{
+ size_t xOriginalLength;
+ uint8_t * pucBuffer;
+
+ #ifdef PIC32_USE_ETHERNET
+ xOriginalLength = pxNetworkBuffer->xDataLength;
+ #else
+ xOriginalLength = pxNetworkBuffer->xDataLength + ipBUFFER_PADDING;
+ xNewSizeBytes = xNewSizeBytes + ipBUFFER_PADDING;
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ pucBuffer = pucGetNetworkBuffer( &( xNewSizeBytes ) );
+
+ if( pucBuffer == NULL )
+ {
+ /* In case the allocation fails, return NULL. */
+ pxNetworkBuffer = NULL;
+ }
+ else
+ {
+ pxNetworkBuffer->xDataLength = xNewSizeBytes;
+ if( xNewSizeBytes > xOriginalLength )
+ {
+ xNewSizeBytes = xOriginalLength;
+ }
+
+ #ifdef PIC32_USE_ETHERNET
+ memcpy( pucBuffer, pxNetworkBuffer->pucEthernetBuffer, xNewSizeBytes );
+ *( ( NetworkBufferDescriptor_t ** ) ( pucBuffer - ipBUFFER_PADDING ) ) = pxNetworkBuffer;
+ #else
+ memcpy( pucBuffer - ipBUFFER_PADDING, pxNetworkBuffer->pucEthernetBuffer - ipBUFFER_PADDING, xNewSizeBytes );
+ #endif /* #ifdef PIC32_USE_ETHERNET */
+
+ vReleaseNetworkBuffer( pxNetworkBuffer->pucEthernetBuffer );
+ pxNetworkBuffer->pucEthernetBuffer = pucBuffer;
+ }
+
+ return pxNetworkBuffer;
+}
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c
index 1b7584c44..5fe4438bd 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_eth.c
@@ -1,889 +1,889 @@
-/*******************************************************************************
-* Network Interface file
-*
-* Summary:
-* Network Interface file for FreeRTOS-Plus-TCP stack
-*
-* Description:
-* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
-*******************************************************************************/
-
-/*******************************************************************************
-* File Name: pic32_NetworkInterface.c
-* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy of
-* this software and associated documentation files (the "Software"), to deal in
-* the Software without restriction, including without limitation the rights to
-* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-* of the Software, and to permit persons to whom the Software is furnished to do
-* so, subject to the following conditions:
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE
-*******************************************************************************/
-#include <sys/kmem.h>
-
-#include "FreeRTOS.h"
-#include "semphr.h"
-#include "event_groups.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-
-
-#include "NetworkInterface.h"
-#include "NetworkConfig.h"
-
-#include "peripheral/eth/plib_eth.h"
-
-#include "system_config.h"
-#include "system/console/sys_console.h"
-#include "system/debug/sys_debug.h"
-#include "system/command/sys_command.h"
-
-#include "driver/ethmac/drv_ethmac.h"
-#include "driver/miim/drv_miim.h"
-
-#include "tcpip/tcpip.h"
-#include "tcpip/src/tcpip_private.h"
-#include "tcpip/src/link_list.h"
-
-#ifdef PIC32_USE_ETHERNET
-
- /* local definitions and data */
-
- /* debug messages */
- #if ( PIC32_MAC_DEBUG_MESSAGES != 0 )
- #define PIC32_MAC_DbgPrint( format, ... ) SYS_CONSOLE_PRINT( format, ## __VA_ARGS__ )
- #else
- #define PIC32_MAC_DbgPrint( format, ... )
- #endif /* (PIC32_MAC_DEBUG_MESSAGES != 0) */
-
- typedef enum
- {
- PIC32_MAC_EVENT_INIT_NONE = 0x000, /* no event/invalid */
-
- PIC32_MAC_EVENT_INIT_DONE = 0x001, /* initialization done event */
- PIC32_MAC_EVENT_TIMEOUT = 0x002, /* periodic timeout event */
- PIC32_MAC_EVENT_IF_PENDING = 0x004, /* an interface event signal: RX, TX, errors. etc. */
- } PIC32_MAC_EVENT_TYPE;
-
- typedef enum
- {
- eMACInit, /* Must initialise MAC. */
- eMACPass, /* Initialisation was successful. */
- eMACFailed, /* Initialisation failed. */
- } eMAC_INIT_STATUS_TYPE;
-
- static TCPIP_STACK_HEAP_HANDLE macHeapHandle;
-
- static const TCPIP_MAC_OBJECT * macObject; /* the one and only MAC object; */
-
- static SYS_MODULE_OBJ macObjHandle; /* the MAC object instance, obtained at initialization */
- static TCPIP_MAC_HANDLE macCliHandle; /* client handle */
- static volatile SYS_STATUS macObjStatus; /* current MAC status */
-
- static TaskHandle_t macTaskHandle;
-
- static TimerHandle_t macTmrHandle;
-
- static bool macLinkStatus; /* true if link is ON */
-
- static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
-
- /* local prototypes */
- static bool StartInitMac( void );
- static void StartInitCleanup( void );
-
- static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl );
-
- static bool MacSyncFunction( void * synchHandle,
- TCPIP_MAC_SYNCH_REQUEST req );
-
- /* the PIC32 MAC task function */
- static void MacHandlerTask( void * params );
-
- /* MAC interrupt event function */
- static void MAC_EventFunction( TCPIP_MAC_EVENT event,
- const void * eventParam );
-
- /* timer callback for link maintenance, etc; */
- static void MacTmrCallback( TimerHandle_t xTimer );
-
- /* MAC RX packets functions */
- static void MacRxPackets( void );
- static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt );
-
-
- /* memory allocation mapping to FreeRTOS */
- static void * _malloc( size_t nBytes )
- {
- return pvPortMalloc( nBytes );
- }
-
- /*-----------------------------------------------------------*/
-
- static void * _calloc( size_t nElems,
- size_t elemSize )
- {
- size_t nBytes = nElems * elemSize;
-
- void * ptr = pvPortMalloc( nBytes );
-
- if( ptr != 0 )
- {
- memset( ptr, 0, nBytes );
- }
-
- return ptr;
- }
-
- /*-----------------------------------------------------------*/
-
- static void _free( void * pBuff )
- {
- vPortFree( pBuff );
- }
-
- /* extern references */
- /* */
- /* use the configuration data from the system_init.c */
- extern const TCPIP_NETWORK_CONFIG TCPIP_HOSTS_CONFIGURATION[];
-
- /* BufferAllocation_2.c:: packet allocation function */
- extern TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
- uint16_t segLoadLen,
- TCPIP_MAC_PACKET_FLAGS flags );
-
- extern void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
- NetworkBufferDescriptor_t * pxBufferDescriptor,
- size_t pktLength );
- extern void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt );
-
- /* cannot use the system_init.c::tcpipHeapConfig because FreeRTOS does not have a calloc function! */
- /* we build it here! */
-
- /* make sure we're running with external heap! Redirect to FreeRTOS. */
- #if !defined( TCPIP_STACK_USE_EXTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP_POOL )
- #error "TCPIP_STACK_USE_EXTERNAL_HEAP should be defined for this project!"
- #endif
-
- static const TCPIP_STACK_HEAP_EXTERNAL_CONFIG tcpipHeapConfig =
- {
- .heapType = TCPIP_STACK_HEAP_TYPE_EXTERNAL_HEAP,
- .heapFlags = TCPIP_STACK_HEAP_FLAG_ALLOC_UNCACHED | TCPIP_STACK_HEAP_FLAG_NO_MTHREAD_SYNC,
- .heapUsage = TCPIP_STACK_HEAP_USE_DEFAULT,
- .malloc_fnc = _malloc,
- .calloc_fnc = _calloc,
- .free_fnc = _free,
- };
-
- #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
- static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv );
- static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv );
- static int _Command_Version( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv );
-
- static const SYS_CMD_DESCRIPTOR macCmdTbl[] =
- {
- { "macinfo", _Command_MacInfo, ": Check MAC statistics" },
- { "netinfo", _Command_NetInfo, ": Net info" },
- { "version", _Command_Version, ": Version info" },
- };
- #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
-
-
- /* FreeRTOS implementation functions */
- BaseType_t xNetworkInterfaceInitialise( void )
- {
- BaseType_t xResult;
-
- if( xMacInitStatus == eMACInit )
- {
- /* This is the first time this function is called. */
- if( StartInitMac() != false )
- {
- /* Indicate that the MAC initialisation succeeded. */
- xMacInitStatus = eMACPass;
- }
- else
- {
- xMacInitStatus = eMACFailed;
- }
- }
-
- if( xMacInitStatus == eMACPass )
- {
- xResult = xGetPhyLinkStatus();
- }
- else
- {
- xResult = pdFAIL;
- }
-
- PIC32_MAC_DbgPrint( "xNetworkInterfaceInitialise: %d %d\r\n", ( int ) xMacInitStatus, ( int ) xResult );
-
- return xResult;
- }
-
-
- /*-----------------------------------------------------------*/
-
- BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
- BaseType_t xReleaseAfterSend )
- {
- TCPIP_MAC_RES macRes;
- TCPIP_MAC_PACKET * pTxPkt;
-
- BaseType_t retRes = pdFALSE;
-
-
- if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
- {
- TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pxDescriptor->pucEthernetBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
- configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
- pTxPkt = *ppkt;
- configASSERT( pTxPkt != 0 );
-
- /* prepare the packet for transmission */
- /* set the correct data length: */
- configASSERT( pTxPkt->pDSeg->segSize >= pTxPkt->pDSeg->segLen );
- pTxPkt->pDSeg->segLen = pxDescriptor->xDataLength;
- pTxPkt->next = 0; /* unlink it */
- macRes = ( macObject->TCPIP_MAC_PacketTx )( macCliHandle, pTxPkt );
-
- if( macRes >= 0 )
- {
- retRes = pdTRUE;
- pxDescriptor->pucEthernetBuffer = 0; /* it will be released by the MAC driver once it's transmitted */
- iptraceNETWORK_INTERFACE_TRANSMIT();
- }
-
- /* else same error occurred; this normally should not happen! But the buffer is left in there so it shold be freed! */
-
- /* The buffer has been sent so can be released. */
- if( xReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- }
-
- return retRes;
- }
-
-
- /************************************* Section: helper functions ************************************************** */
- /* */
-
- void PIC32_GetMACAddress( uint8_t macAdd[ 6 ] )
- {
- #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
- PLIB_ETH_MACGetAddress( ETH_ID_0, macAdd );
- #else
- #error "MAC Address: not supported architecture!"
- #endif
- }
-
-
- /*-----------------------------------------------------------*/
-
- const void * const PIC32_GetMacConfigData( void )
- {
- #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
- extern const TCPIP_MODULE_MAC_PIC32INT_CONFIG tcpipMACPIC32INTInitData;
-
- return &tcpipMACPIC32INTInitData;
- #else
- #error "MAC Address: not supported architecture!"
- #endif
- }
-
- /************************************* Section: worker code ************************************************** */
- /* */
-
-
- static bool StartInitMac( void )
- {
- TCPIP_MAC_MODULE_CTRL macCtrl;
- SYS_MODULE_INIT moduleInit;
- EventBits_t evBits;
-
-
- /* perform some initialization of all variables so that we can cleanup what failed */
- /* if something failed, the routine will be called again and again by FreeRTOS! */
- macHeapHandle = 0;
- macObjHandle = 0;
- macCliHandle = 0;
- macTmrHandle = 0;
- macTaskHandle = 0;
- macObject = TCPIP_HOSTS_CONFIGURATION[ 0 ].pMacObject; /* the MAC object we use */
- macObjStatus = SYS_STATUS_UNINITIALIZED;
- macLinkStatus = false;
-
- int netUpFail = 0;
-
- while( true )
- {
- /* start the allocator */
- macHeapHandle = TCPIP_HEAP_Create( ( const TCPIP_STACK_HEAP_CONFIG * ) &tcpipHeapConfig, 0 );
-
- if( macHeapHandle == 0 )
- {
- netUpFail = 1;
- break;
- }
-
- if( TCPIP_PKT_Initialize( macHeapHandle, 0, 0 ) == false )
- {
- netUpFail = 2;
- break;
- }
-
- moduleInit.sys.powerState = SYS_MODULE_POWER_RUN_FULL;
-
- /* Initialize the MAC. MAC address is defined to 0x000000000000 in
- * FreeRTOSConfig.h and therefore it will be initialized to the
- * factory programmed MAC address. */
- SetMacCtrl( &macCtrl );
- /* Set the mac address in the FreeRTOS+TCP stack. */
- FreeRTOS_UpdateMACAddress( macCtrl.ifPhyAddress.v );
-
- TCPIP_MAC_INIT macInit =
- {
- .moduleInit = { moduleInit.value },
- .macControl = &macCtrl,
- .moduleData = PIC32_GetMacConfigData(),
- };
-
- macObjHandle = ( macObject->TCPIP_MAC_Initialize )( TCPIP_MODULE_MAC_PIC32INT, &macInit.moduleInit );
-
- if( macObjHandle == SYS_MODULE_OBJ_INVALID )
- {
- macObjHandle = 0;
- netUpFail = 4;
- break;
- }
-
- /* open the MAC */
- macCliHandle = ( macObject->TCPIP_MAC_Open )( TCPIP_MODULE_MAC_PIC32INT, DRV_IO_INTENT_READWRITE );
-
- if( macCliHandle == DRV_HANDLE_INVALID )
- {
- macCliHandle = 0;
- netUpFail = 5;
- break;
- }
-
- if( !( macObject->TCPIP_MAC_EventMaskSet )( macCliHandle, ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ), true ) )
- {
- netUpFail = 6;
- break;
- }
-
- /* completed the MAC initialization */
- /* continue the initialization */
- macTmrHandle = xTimerCreate( PIC32_MAC_TIMER_NAME, PIC32_MAC_TIMER_PERIOD, pdTRUE, 0, MacTmrCallback );
-
- if( ( macTmrHandle == 0 ) || ( xTimerStart( macTmrHandle, 0 ) != pdPASS ) )
- {
- netUpFail = 8;
- break;
- }
-
- /* spawn the PIC32 MAC task function */
- /* and wait for its event signal */
- macObjStatus = SYS_STATUS_BUSY;
-
- if( xTaskCreate( MacHandlerTask, PIC32_MAC_TASK_NAME, PIC32_MAC_TASK_STACK_SIZE, xTaskGetCurrentTaskHandle(), PIC32_MAC_TASK_PRI, &macTaskHandle ) != pdPASS )
- { /* failed */
- netUpFail = 9;
- break;
- }
-
- xTaskNotifyWait( PIC32_MAC_EVENT_INIT_DONE, PIC32_MAC_EVENT_INIT_DONE, &evBits, PIC32_MAC_INIT_TIMEOUT );
-
- if( ( evBits & PIC32_MAC_EVENT_INIT_DONE ) == 0 )
- { /* timed out */
- netUpFail = 10;
- break;
- }
-
- if( macObjStatus != SYS_STATUS_READY )
- { /* failed somehow ??? */
- netUpFail = 11;
- break;
- }
-
- netUpFail = 0;
- break;
- }
-
- if( netUpFail == 0 )
- {
- PIC32_MAC_DbgPrint( " MAC Init success!\r\n" );
-
- #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
- /* create command group */
- if( !SYS_CMD_ADDGRP( macCmdTbl, sizeof( macCmdTbl ) / sizeof( *macCmdTbl ), "mac", ": mac commands" ) )
- {
- PIC32_MAC_DbgPrint( "Failed to create MAC Commands\r\n" );
- }
- #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
-
- return true;
- }
- else
- {
- StartInitCleanup();
- PIC32_MAC_DbgPrint( "MAC Init failed: %d!\r\n", netUpFail );
-
- return false;
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void StartInitCleanup( void )
- {
- if( macHeapHandle != 0 )
- {
- TCPIP_HEAP_Delete( macHeapHandle );
- macHeapHandle = 0;
- }
-
- if( macObjHandle != 0 )
- {
- ( macObject->TCPIP_MAC_Deinitialize )( macObjHandle );
- macObjHandle = 0;
- }
-
- if( macTmrHandle != 0 )
- {
- xTimerDelete( macTmrHandle, portMAX_DELAY );
- macTmrHandle = 0;
- }
-
- if( macTaskHandle != 0 )
- {
- vTaskDelete( macTaskHandle );
- macTaskHandle = 0;
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl )
- {
- TCPIP_MAC_ADDR macAdd;
- uint8_t unsetMACAddr[ 6 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* not set MAC address */
-
- pMacCtrl->nIfs = 1;
-
- pMacCtrl->mallocF = TCPIP_HEAP_MallocOutline;
- pMacCtrl->callocF = TCPIP_HEAP_CallocOutline;
- pMacCtrl->freeF = TCPIP_HEAP_FreeOutline;
- pMacCtrl->memH = macHeapHandle;
-
-
- pMacCtrl->pktAllocF = PIC32_MacPacketAllocate;
- pMacCtrl->pktFreeF = ( TCPIP_MAC_PKT_FreeF ) _TCPIP_PKT_FREE_FNC;
- pMacCtrl->pktAckF = ( TCPIP_MAC_PKT_AckF ) _TCPIP_PKT_ACK_FNC;
-
- pMacCtrl->synchF = MacSyncFunction;
-
- pMacCtrl->eventF = MAC_EventFunction;
- pMacCtrl->eventParam = 0;
-
- pMacCtrl->moduleId = TCPIP_MODULE_MAC_PIC32INT;
- pMacCtrl->netIx = 0;
- pMacCtrl->macAction = TCPIP_MAC_ACTION_INIT;
- pMacCtrl->powerMode = TCPIP_MAC_POWER_FULL;
-
- macAdd.v[ 0 ] = configMAC_ADDR0;
- macAdd.v[ 1 ] = configMAC_ADDR1;
- macAdd.v[ 2 ] = configMAC_ADDR2;
- macAdd.v[ 3 ] = configMAC_ADDR3;
- macAdd.v[ 4 ] = configMAC_ADDR4;
- macAdd.v[ 5 ] = configMAC_ADDR5;
-
- if( memcmp( macAdd.v, unsetMACAddr, sizeof( unsetMACAddr ) ) == 0 )
- { /* if unspecified we use the factory pre-programmed address */
- PIC32_GetMACAddress( pMacCtrl->ifPhyAddress.v );
- }
- else
- { /* use the config suggested one */
- memcpy( pMacCtrl->ifPhyAddress.v, macAdd.v, sizeof( macAdd ) );
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static bool MacSyncFunction( void * synchHandle,
- TCPIP_MAC_SYNCH_REQUEST req )
- {
- switch( req )
- {
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_CREATE:
- vSemaphoreCreateBinary( *( SemaphoreHandle_t * ) synchHandle );
-
- return ( *( SemaphoreHandle_t * ) synchHandle == NULL ) ? false : true;
-
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_DELETE:
- vSemaphoreDelete( *( SemaphoreHandle_t * ) synchHandle );
- *( SemaphoreHandle_t * ) synchHandle = NULL;
-
- return true;
-
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_LOCK:
-
- return ( xSemaphoreTake( *( SemaphoreHandle_t * ) synchHandle, portMAX_DELAY ) == pdTRUE ) ? true : false;
-
- case TCPIP_MAC_SYNCH_REQUEST_OBJ_UNLOCK:
-
- return ( xSemaphoreGive( *( SemaphoreHandle_t * ) synchHandle ) == pdTRUE ) ? true : false;
-
- case TCPIP_MAC_SYNCH_REQUEST_CRIT_ENTER:
- vTaskSuspendAll();
-
- return true;
-
- case TCPIP_MAC_SYNCH_REQUEST_CRIT_LEAVE:
- xTaskResumeAll();
-
- return true;
-
- default:
-
- return false;
- }
- }
-
-
- /*-----------------------------------------------------------*/
-
- static void MacHandlerTask( void * params )
- {
- EventBits_t evBits;
-
- /* perform the MAC initialization */
- while( macObjStatus == SYS_STATUS_BUSY )
- {
- /* process the underlying MAC module tasks */
- ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
-
- SYS_STATUS macStatus = ( macObject->TCPIP_MAC_Status )( macObjHandle );
-
- if( macStatus == SYS_STATUS_BUSY )
- { /* still pending */
- vTaskDelay( PIC32_MAC_TASK_INIT_PENDING_DELAY );
- }
- else
- { /* completed ...somehow */
- macObjStatus = macStatus;
-
- xTaskNotify( ( TaskHandle_t ) params, PIC32_MAC_EVENT_INIT_DONE, eSetBits );
-
- if( macStatus != SYS_STATUS_READY )
- { /* failed miserably */
- vTaskDelete( 0 );
- }
-
- /* done, up and running */
- }
- }
-
- while( true )
- {
- xTaskNotifyWait( PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, &evBits, portMAX_DELAY );
-
- if( ( evBits & PIC32_MAC_EVENT_TIMEOUT ) != 0 )
- { /* timeout occurred... */
- ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
- bool linkCurr = ( macObject->TCPIP_MAC_LinkCheck )( macCliHandle ); /* check link status */
-
- if( macLinkStatus != linkCurr )
- { /* link status changed; some event could ve fired here if needed */
- PIC32_MAC_DbgPrint( " MAC link: %s!\r\n", linkCurr ? "ON" : "OFF" );
- macLinkStatus = linkCurr;
- }
- }
-
- if( ( evBits & PIC32_MAC_EVENT_IF_PENDING ) != 0 )
- { /* IF events signal */
- TCPIP_MAC_EVENT activeEvents = ( macObject->TCPIP_MAC_EventPendingGet )( macCliHandle );
-
- if( activeEvents != TCPIP_MAC_EV_NONE )
- {
- /* acknowledge the events */
- ( macObject->TCPIP_MAC_EventAcknowledge )( macCliHandle, activeEvents );
-
- /* check for RX */
- if( ( activeEvents & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_RX_OVFLOW | TCPIP_MAC_EV_RX_BUFNA ) ) != 0 )
- { /* RX packets available */
- MacRxPackets();
- }
-
- /* call the driver process function; */
- /* PIC32 driver requests it through TCPIP_MAC_ParametersGet() which is bypassed here! */
- ( macObject->TCPIP_MAC_Process )( macCliHandle );
- }
- }
-
- /* do what you have to do and then wait for another event... */
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void MacTmrCallback( TimerHandle_t xTimer )
- {
- xTaskNotify( macTaskHandle, PIC32_MAC_EVENT_TIMEOUT, eSetBits );
- }
-
- /* MAC interrupt event function */
- /* MAC signals an event, probably from within ISR */
- /* we care just for RX related events */
- static void MAC_EventFunction( TCPIP_MAC_EVENT event,
- const void * eventParam )
- {
- BaseType_t xHigherPriorityTaskWoken;
-
- if( ( event & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ) ) != 0 )
- {
- xHigherPriorityTaskWoken = pdFALSE;
- xTaskNotifyFromISR( macTaskHandle, PIC32_MAC_EVENT_IF_PENDING, eSetBits, &xHigherPriorityTaskWoken );
-
- if( xHigherPriorityTaskWoken )
- {
- portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
- }
- }
- }
-
- /*-----------------------------------------------------------*/
-
- BaseType_t xGetPhyLinkStatus( void )
- {
- return macLinkStatus == true ? pdPASS : pdFAIL;
- }
-
-
- /* receive packets from the MAC driver */
- static void MacRxPackets( void )
- {
- TCPIP_MAC_PACKET * pRxPkt;
-
- /* get all the new MAC packets */
- while( ( pRxPkt = ( macObject->TCPIP_MAC_PacketRx )( macCliHandle, 0, 0 ) ) != 0 )
- {
- MacProcessRxPacket( pRxPkt );
- }
- }
-
- /*-----------------------------------------------------------*/
-
- static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt )
- {
- bool pktSuccess, pktLost;
- size_t pktLength;
- TCPIP_MAC_DATA_SEGMENT * pSeg;
- uint8_t * pPktBuff;
- NetworkBufferDescriptor_t * pxBufferDescriptor;
- IPStackEvent_t xRxEvent;
-
- pxBufferDescriptor = 0;
- pktSuccess = pktLost = false;
-
- while( true )
- {
- pktLength = 0;
- int nSegs = 0;
- pSeg = pRxPkt->pDSeg;
- pPktBuff = pSeg->segLoad;
-
- /* calculate the packet size */
- do
- {
- pktLength += pSeg->segLen;
- pSeg = pSeg->next;
- nSegs++;
- } while( pSeg != 0 );
-
- if( nSegs > 1 )
- { /* no support in FreeRTOS for multi segment packets! */
- break;
- }
-
- /* sizeof(TCPIP_MAC_ETHERNET_HEADER) is subtracted by the driver */
- /* but FreeRTOS needs the whole frame! */
- pktLength += sizeof( TCPIP_MAC_ETHERNET_HEADER );
-
- if( eConsiderFrameForProcessing( pPktBuff ) != eProcessBuffer )
- {
- break;
- }
-
- /* get the network descriptor (no data buffer) to hold this packet */
- pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( 0, 0 );
-
- if( pxBufferDescriptor == 0 )
- {
- pktLost = true;
- break;
- }
-
- PIC32_MacAssociate( pRxPkt, pxBufferDescriptor, pktLength );
-
- xRxEvent.eEventType = eNetworkRxEvent;
- xRxEvent.pvData = ( void * ) pxBufferDescriptor;
-
- /* Send the data to the TCP/IP stack */
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- { /* failed */
- pktLost = true;
- }
- else
- { /* success */
- pktSuccess = true;
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-
- break;
- }
-
- if( !pktSuccess )
- { /* smth went wrong; nothing sent to the */
- if( pxBufferDescriptor != 0 )
- {
- pxBufferDescriptor->pucEthernetBuffer = 0;
- vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
- }
-
- if( pktLost )
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
-
- /* acknowledge the packet to the MAC driver */
- if( pRxPkt->ackFunc )
- {
- ( *pRxPkt->ackFunc )( pRxPkt, pRxPkt->ackParam );
- }
- else
- {
- PIC32_MacPacketOrphan( pRxPkt );
- }
- }
- }
-
- #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
- /* */
- static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv )
- {
- TCPIP_MAC_RES macRes;
- TCPIP_MAC_RX_STATISTICS rxStatistics;
- TCPIP_MAC_TX_STATISTICS txStatistics;
- TCPIP_MAC_STATISTICS_REG_ENTRY regEntries[ 8 ];
- TCPIP_MAC_STATISTICS_REG_ENTRY * pRegEntry;
- int jx, hwEntries;
- char entryName[ sizeof( pRegEntry->registerName ) + 1 ];
-
- const void * cmdIoParam = pCmdIO->cmdIoParam;
-
- if( argc != 1 )
- {
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Usage: macinfo \r\n" );
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Ex: macinfo \r\n" );
-
- return false;
- }
-
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s driver statistics\r\n", macObject->macName );
- macRes = ( macObject->TCPIP_MAC_StatisticsGet )( macCliHandle, &rxStatistics, &txStatistics );
-
- if( macRes == TCPIP_MAC_RES_OK )
- {
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnRxOkPackets: %d, nRxPendBuffers: %d, nRxSchedBuffers: %d, ",
- rxStatistics.nRxOkPackets, rxStatistics.nRxPendBuffers, rxStatistics.nRxSchedBuffers );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "nRxErrorPackets: %d, nRxFragmentErrors: %d\r\n", rxStatistics.nRxErrorPackets, rxStatistics.nRxFragmentErrors );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnTxOkPackets: %d, nTxPendBuffers: %d, nTxErrorPackets: %d, nTxQueueFull: %d\r\n",
- txStatistics.nTxOkPackets, txStatistics.nTxPendBuffers, txStatistics.nTxErrorPackets, txStatistics.nTxQueueFull );
- }
- else
- {
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
- }
-
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s hardware statistics\r\n", macObject->macName );
- macRes = ( macObject->TCPIP_MAC_RegisterStatisticsGet )( macCliHandle, regEntries, sizeof( regEntries ) / sizeof( *regEntries ), &hwEntries );
-
- if( macRes == TCPIP_MAC_RES_OK )
- {
- entryName[ sizeof( entryName ) - 1 ] = 0;
-
- for( jx = 0, pRegEntry = regEntries; jx < hwEntries && jx < sizeof( regEntries ) / sizeof( *regEntries ); jx++, pRegEntry++ )
- {
- strncpy( entryName, pRegEntry->registerName, sizeof( entryName ) - 1 );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\t%s: 0x%8x\r\n", entryName, pRegEntry->registerValue );
- }
- }
- else
- {
- ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
- }
-
- return true;
- }
-
- /*-----------------------------------------------------------*/
-
- static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
- int argc,
- char ** argv )
- {
- const void * cmdIoParam = pCmdIO->cmdIoParam;
-
- union
- {
- uint32_t ul;
- uint8_t b[ 4 ];
- }
- sUl;
-
- sUl.ul = FreeRTOS_GetIPAddress();
-
- bool linkUp = FreeRTOS_IsNetworkUp() == pdTRUE;
-
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "IP address: %d.%d.%d.%d\r\n", sUl.b[ 0 ], sUl.b[ 1 ], sUl.b[ 2 ], sUl.b[ 3 ] );
- ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Link is: %s\r\n", linkUp ? "Up" : "Down" );
-
- return true;
- }
-
-#include "aws_application_version.h"
-
-static int _Command_Version(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv)
-{
- configPRINTF( ( "App version - maj: %d, min: %d, build: %d\r\n", xAppFirmwareVersion.u.x.ucMajor, xAppFirmwareVersion.u.x.ucMinor, xAppFirmwareVersion.u.x.usBuild) );
- return 0;
-}
-
- #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
-#endif /* #ifdef PIC32_USE_ETHERNET */
+/*******************************************************************************
+* Network Interface file
+*
+* Summary:
+* Network Interface file for FreeRTOS-Plus-TCP stack
+*
+* Description:
+* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
+*******************************************************************************/
+
+/*******************************************************************************
+* File Name: pic32_NetworkInterface.c
+* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to
+* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+* of the Software, and to permit persons to whom the Software is furnished to do
+* so, subject to the following conditions:
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE
+*******************************************************************************/
+#include <sys/kmem.h>
+
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "event_groups.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+
+
+#include "NetworkInterface.h"
+#include "NetworkConfig.h"
+
+#include "peripheral/eth/plib_eth.h"
+
+#include "system_config.h"
+#include "system/console/sys_console.h"
+#include "system/debug/sys_debug.h"
+#include "system/command/sys_command.h"
+
+#include "driver/ethmac/drv_ethmac.h"
+#include "driver/miim/drv_miim.h"
+
+#include "tcpip/tcpip.h"
+#include "tcpip/src/tcpip_private.h"
+#include "tcpip/src/link_list.h"
+
+#ifdef PIC32_USE_ETHERNET
+
+ /* local definitions and data */
+
+ /* debug messages */
+ #if ( PIC32_MAC_DEBUG_MESSAGES != 0 )
+ #define PIC32_MAC_DbgPrint( format, ... ) SYS_CONSOLE_PRINT( format, ## __VA_ARGS__ )
+ #else
+ #define PIC32_MAC_DbgPrint( format, ... )
+ #endif /* (PIC32_MAC_DEBUG_MESSAGES != 0) */
+
+ typedef enum
+ {
+ PIC32_MAC_EVENT_INIT_NONE = 0x000, /* no event/invalid */
+
+ PIC32_MAC_EVENT_INIT_DONE = 0x001, /* initialization done event */
+ PIC32_MAC_EVENT_TIMEOUT = 0x002, /* periodic timeout event */
+ PIC32_MAC_EVENT_IF_PENDING = 0x004, /* an interface event signal: RX, TX, errors. etc. */
+ } PIC32_MAC_EVENT_TYPE;
+
+ typedef enum
+ {
+ eMACInit, /* Must initialise MAC. */
+ eMACPass, /* Initialisation was successful. */
+ eMACFailed, /* Initialisation failed. */
+ } eMAC_INIT_STATUS_TYPE;
+
+ static TCPIP_STACK_HEAP_HANDLE macHeapHandle;
+
+ static const TCPIP_MAC_OBJECT * macObject; /* the one and only MAC object; */
+
+ static SYS_MODULE_OBJ macObjHandle; /* the MAC object instance, obtained at initialization */
+ static TCPIP_MAC_HANDLE macCliHandle; /* client handle */
+ static volatile SYS_STATUS macObjStatus; /* current MAC status */
+
+ static TaskHandle_t macTaskHandle;
+
+ static TimerHandle_t macTmrHandle;
+
+ static bool macLinkStatus; /* true if link is ON */
+
+ static eMAC_INIT_STATUS_TYPE xMacInitStatus = eMACInit;
+
+ /* local prototypes */
+ static bool StartInitMac( void );
+ static void StartInitCleanup( void );
+
+ static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl );
+
+ static bool MacSyncFunction( void * synchHandle,
+ TCPIP_MAC_SYNCH_REQUEST req );
+
+ /* the PIC32 MAC task function */
+ static void MacHandlerTask( void * params );
+
+ /* MAC interrupt event function */
+ static void MAC_EventFunction( TCPIP_MAC_EVENT event,
+ const void * eventParam );
+
+ /* timer callback for link maintenance, etc; */
+ static void MacTmrCallback( TimerHandle_t xTimer );
+
+ /* MAC RX packets functions */
+ static void MacRxPackets( void );
+ static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt );
+
+
+ /* memory allocation mapping to FreeRTOS */
+ static void * _malloc( size_t nBytes )
+ {
+ return pvPortMalloc( nBytes );
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void * _calloc( size_t nElems,
+ size_t elemSize )
+ {
+ size_t nBytes = nElems * elemSize;
+
+ void * ptr = pvPortMalloc( nBytes );
+
+ if( ptr != 0 )
+ {
+ memset( ptr, 0, nBytes );
+ }
+
+ return ptr;
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void _free( void * pBuff )
+ {
+ vPortFree( pBuff );
+ }
+
+ /* extern references */
+ /* */
+ /* use the configuration data from the system_init.c */
+ extern const TCPIP_NETWORK_CONFIG TCPIP_HOSTS_CONFIGURATION[];
+
+ /* BufferAllocation_2.c:: packet allocation function */
+ extern TCPIP_MAC_PACKET * PIC32_MacPacketAllocate( uint16_t pktLen,
+ uint16_t segLoadLen,
+ TCPIP_MAC_PACKET_FLAGS flags );
+
+ extern void PIC32_MacAssociate( TCPIP_MAC_PACKET * pRxPkt,
+ NetworkBufferDescriptor_t * pxBufferDescriptor,
+ size_t pktLength );
+ extern void PIC32_MacPacketOrphan( TCPIP_MAC_PACKET * pPkt );
+
+ /* cannot use the system_init.c::tcpipHeapConfig because FreeRTOS does not have a calloc function! */
+ /* we build it here! */
+
+ /* make sure we're running with external heap! Redirect to FreeRTOS. */
+ #if !defined( TCPIP_STACK_USE_EXTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP ) || defined( TCPIP_STACK_USE_INTERNAL_HEAP_POOL )
+ #error "TCPIP_STACK_USE_EXTERNAL_HEAP should be defined for this project!"
+ #endif
+
+ static const TCPIP_STACK_HEAP_EXTERNAL_CONFIG tcpipHeapConfig =
+ {
+ .heapType = TCPIP_STACK_HEAP_TYPE_EXTERNAL_HEAP,
+ .heapFlags = TCPIP_STACK_HEAP_FLAG_ALLOC_UNCACHED | TCPIP_STACK_HEAP_FLAG_NO_MTHREAD_SYNC,
+ .heapUsage = TCPIP_STACK_HEAP_USE_DEFAULT,
+ .malloc_fnc = _malloc,
+ .calloc_fnc = _calloc,
+ .free_fnc = _free,
+ };
+
+ #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
+ static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv );
+ static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv );
+ static int _Command_Version( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv );
+
+ static const SYS_CMD_DESCRIPTOR macCmdTbl[] =
+ {
+ { "macinfo", _Command_MacInfo, ": Check MAC statistics" },
+ { "netinfo", _Command_NetInfo, ": Net info" },
+ { "version", _Command_Version, ": Version info" },
+ };
+ #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
+
+
+ /* FreeRTOS implementation functions */
+ BaseType_t xNetworkInterfaceInitialise( void )
+ {
+ BaseType_t xResult;
+
+ if( xMacInitStatus == eMACInit )
+ {
+ /* This is the first time this function is called. */
+ if( StartInitMac() != false )
+ {
+ /* Indicate that the MAC initialisation succeeded. */
+ xMacInitStatus = eMACPass;
+ }
+ else
+ {
+ xMacInitStatus = eMACFailed;
+ }
+ }
+
+ if( xMacInitStatus == eMACPass )
+ {
+ xResult = xGetPhyLinkStatus();
+ }
+ else
+ {
+ xResult = pdFAIL;
+ }
+
+ PIC32_MAC_DbgPrint( "xNetworkInterfaceInitialise: %d %d\r\n", ( int ) xMacInitStatus, ( int ) xResult );
+
+ return xResult;
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
+ BaseType_t xReleaseAfterSend )
+ {
+ TCPIP_MAC_RES macRes;
+ TCPIP_MAC_PACKET * pTxPkt;
+
+ BaseType_t retRes = pdFALSE;
+
+
+ if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
+ {
+ TCPIP_MAC_PACKET ** ppkt = ( TCPIP_MAC_PACKET ** ) ( pxDescriptor->pucEthernetBuffer - PIC32_BUFFER_PKT_PTR_OSSET );
+ configASSERT( ( ( uint32_t ) ppkt & ( sizeof( uint32_t ) - 1 ) ) == 0 );
+ pTxPkt = *ppkt;
+ configASSERT( pTxPkt != 0 );
+
+ /* prepare the packet for transmission */
+ /* set the correct data length: */
+ configASSERT( pTxPkt->pDSeg->segSize >= pTxPkt->pDSeg->segLen );
+ pTxPkt->pDSeg->segLen = pxDescriptor->xDataLength;
+ pTxPkt->next = 0; /* unlink it */
+ macRes = ( macObject->TCPIP_MAC_PacketTx )( macCliHandle, pTxPkt );
+
+ if( macRes >= 0 )
+ {
+ retRes = pdTRUE;
+ pxDescriptor->pucEthernetBuffer = 0; /* it will be released by the MAC driver once it's transmitted */
+ iptraceNETWORK_INTERFACE_TRANSMIT();
+ }
+
+ /* else same error occurred; this normally should not happen! But the buffer is left in there so it shold be freed! */
+
+ /* The buffer has been sent so can be released. */
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ }
+
+ return retRes;
+ }
+
+
+ /************************************* Section: helper functions ************************************************** */
+ /* */
+
+ void PIC32_GetMACAddress( uint8_t macAdd[ 6 ] )
+ {
+ #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
+ PLIB_ETH_MACGetAddress( ETH_ID_0, macAdd );
+ #else
+ #error "MAC Address: not supported architecture!"
+ #endif
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ const void * const PIC32_GetMacConfigData( void )
+ {
+ #if defined( __PIC32MZ__ ) || defined( __PIC32MX__ )
+ extern const TCPIP_MODULE_MAC_PIC32INT_CONFIG tcpipMACPIC32INTInitData;
+
+ return &tcpipMACPIC32INTInitData;
+ #else
+ #error "MAC Address: not supported architecture!"
+ #endif
+ }
+
+ /************************************* Section: worker code ************************************************** */
+ /* */
+
+
+ static bool StartInitMac( void )
+ {
+ TCPIP_MAC_MODULE_CTRL macCtrl;
+ SYS_MODULE_INIT moduleInit;
+ EventBits_t evBits;
+
+
+ /* perform some initialization of all variables so that we can cleanup what failed */
+ /* if something failed, the routine will be called again and again by FreeRTOS! */
+ macHeapHandle = 0;
+ macObjHandle = 0;
+ macCliHandle = 0;
+ macTmrHandle = 0;
+ macTaskHandle = 0;
+ macObject = TCPIP_HOSTS_CONFIGURATION[ 0 ].pMacObject; /* the MAC object we use */
+ macObjStatus = SYS_STATUS_UNINITIALIZED;
+ macLinkStatus = false;
+
+ int netUpFail = 0;
+
+ while( true )
+ {
+ /* start the allocator */
+ macHeapHandle = TCPIP_HEAP_Create( ( const TCPIP_STACK_HEAP_CONFIG * ) &tcpipHeapConfig, 0 );
+
+ if( macHeapHandle == 0 )
+ {
+ netUpFail = 1;
+ break;
+ }
+
+ if( TCPIP_PKT_Initialize( macHeapHandle, 0, 0 ) == false )
+ {
+ netUpFail = 2;
+ break;
+ }
+
+ moduleInit.sys.powerState = SYS_MODULE_POWER_RUN_FULL;
+
+ /* Initialize the MAC. MAC address is defined to 0x000000000000 in
+ * FreeRTOSConfig.h and therefore it will be initialized to the
+ * factory programmed MAC address. */
+ SetMacCtrl( &macCtrl );
+ /* Set the mac address in the FreeRTOS+TCP stack. */
+ FreeRTOS_UpdateMACAddress( macCtrl.ifPhyAddress.v );
+
+ TCPIP_MAC_INIT macInit =
+ {
+ .moduleInit = { moduleInit.value },
+ .macControl = &macCtrl,
+ .moduleData = PIC32_GetMacConfigData(),
+ };
+
+ macObjHandle = ( macObject->TCPIP_MAC_Initialize )( TCPIP_MODULE_MAC_PIC32INT, &macInit.moduleInit );
+
+ if( macObjHandle == SYS_MODULE_OBJ_INVALID )
+ {
+ macObjHandle = 0;
+ netUpFail = 4;
+ break;
+ }
+
+ /* open the MAC */
+ macCliHandle = ( macObject->TCPIP_MAC_Open )( TCPIP_MODULE_MAC_PIC32INT, DRV_IO_INTENT_READWRITE );
+
+ if( macCliHandle == DRV_HANDLE_INVALID )
+ {
+ macCliHandle = 0;
+ netUpFail = 5;
+ break;
+ }
+
+ if( !( macObject->TCPIP_MAC_EventMaskSet )( macCliHandle, ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ), true ) )
+ {
+ netUpFail = 6;
+ break;
+ }
+
+ /* completed the MAC initialization */
+ /* continue the initialization */
+ macTmrHandle = xTimerCreate( PIC32_MAC_TIMER_NAME, PIC32_MAC_TIMER_PERIOD, pdTRUE, 0, MacTmrCallback );
+
+ if( ( macTmrHandle == 0 ) || ( xTimerStart( macTmrHandle, 0 ) != pdPASS ) )
+ {
+ netUpFail = 8;
+ break;
+ }
+
+ /* spawn the PIC32 MAC task function */
+ /* and wait for its event signal */
+ macObjStatus = SYS_STATUS_BUSY;
+
+ if( xTaskCreate( MacHandlerTask, PIC32_MAC_TASK_NAME, PIC32_MAC_TASK_STACK_SIZE, xTaskGetCurrentTaskHandle(), PIC32_MAC_TASK_PRI, &macTaskHandle ) != pdPASS )
+ { /* failed */
+ netUpFail = 9;
+ break;
+ }
+
+ xTaskNotifyWait( PIC32_MAC_EVENT_INIT_DONE, PIC32_MAC_EVENT_INIT_DONE, &evBits, PIC32_MAC_INIT_TIMEOUT );
+
+ if( ( evBits & PIC32_MAC_EVENT_INIT_DONE ) == 0 )
+ { /* timed out */
+ netUpFail = 10;
+ break;
+ }
+
+ if( macObjStatus != SYS_STATUS_READY )
+ { /* failed somehow ??? */
+ netUpFail = 11;
+ break;
+ }
+
+ netUpFail = 0;
+ break;
+ }
+
+ if( netUpFail == 0 )
+ {
+ PIC32_MAC_DbgPrint( " MAC Init success!\r\n" );
+
+ #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
+ /* create command group */
+ if( !SYS_CMD_ADDGRP( macCmdTbl, sizeof( macCmdTbl ) / sizeof( *macCmdTbl ), "mac", ": mac commands" ) )
+ {
+ PIC32_MAC_DbgPrint( "Failed to create MAC Commands\r\n" );
+ }
+ #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
+
+ return true;
+ }
+ else
+ {
+ StartInitCleanup();
+ PIC32_MAC_DbgPrint( "MAC Init failed: %d!\r\n", netUpFail );
+
+ return false;
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void StartInitCleanup( void )
+ {
+ if( macHeapHandle != 0 )
+ {
+ TCPIP_HEAP_Delete( macHeapHandle );
+ macHeapHandle = 0;
+ }
+
+ if( macObjHandle != 0 )
+ {
+ ( macObject->TCPIP_MAC_Deinitialize )( macObjHandle );
+ macObjHandle = 0;
+ }
+
+ if( macTmrHandle != 0 )
+ {
+ xTimerDelete( macTmrHandle, portMAX_DELAY );
+ macTmrHandle = 0;
+ }
+
+ if( macTaskHandle != 0 )
+ {
+ vTaskDelete( macTaskHandle );
+ macTaskHandle = 0;
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void SetMacCtrl( TCPIP_MAC_MODULE_CTRL * pMacCtrl )
+ {
+ TCPIP_MAC_ADDR macAdd;
+ uint8_t unsetMACAddr[ 6 ] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; /* not set MAC address */
+
+ pMacCtrl->nIfs = 1;
+
+ pMacCtrl->mallocF = TCPIP_HEAP_MallocOutline;
+ pMacCtrl->callocF = TCPIP_HEAP_CallocOutline;
+ pMacCtrl->freeF = TCPIP_HEAP_FreeOutline;
+ pMacCtrl->memH = macHeapHandle;
+
+
+ pMacCtrl->pktAllocF = PIC32_MacPacketAllocate;
+ pMacCtrl->pktFreeF = ( TCPIP_MAC_PKT_FreeF ) _TCPIP_PKT_FREE_FNC;
+ pMacCtrl->pktAckF = ( TCPIP_MAC_PKT_AckF ) _TCPIP_PKT_ACK_FNC;
+
+ pMacCtrl->synchF = MacSyncFunction;
+
+ pMacCtrl->eventF = MAC_EventFunction;
+ pMacCtrl->eventParam = 0;
+
+ pMacCtrl->moduleId = TCPIP_MODULE_MAC_PIC32INT;
+ pMacCtrl->netIx = 0;
+ pMacCtrl->macAction = TCPIP_MAC_ACTION_INIT;
+ pMacCtrl->powerMode = TCPIP_MAC_POWER_FULL;
+
+ macAdd.v[ 0 ] = configMAC_ADDR0;
+ macAdd.v[ 1 ] = configMAC_ADDR1;
+ macAdd.v[ 2 ] = configMAC_ADDR2;
+ macAdd.v[ 3 ] = configMAC_ADDR3;
+ macAdd.v[ 4 ] = configMAC_ADDR4;
+ macAdd.v[ 5 ] = configMAC_ADDR5;
+
+ if( memcmp( macAdd.v, unsetMACAddr, sizeof( unsetMACAddr ) ) == 0 )
+ { /* if unspecified we use the factory pre-programmed address */
+ PIC32_GetMACAddress( pMacCtrl->ifPhyAddress.v );
+ }
+ else
+ { /* use the config suggested one */
+ memcpy( pMacCtrl->ifPhyAddress.v, macAdd.v, sizeof( macAdd ) );
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static bool MacSyncFunction( void * synchHandle,
+ TCPIP_MAC_SYNCH_REQUEST req )
+ {
+ switch( req )
+ {
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_CREATE:
+ vSemaphoreCreateBinary( *( SemaphoreHandle_t * ) synchHandle );
+
+ return ( *( SemaphoreHandle_t * ) synchHandle == NULL ) ? false : true;
+
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_DELETE:
+ vSemaphoreDelete( *( SemaphoreHandle_t * ) synchHandle );
+ *( SemaphoreHandle_t * ) synchHandle = NULL;
+
+ return true;
+
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_LOCK:
+
+ return ( xSemaphoreTake( *( SemaphoreHandle_t * ) synchHandle, portMAX_DELAY ) == pdTRUE ) ? true : false;
+
+ case TCPIP_MAC_SYNCH_REQUEST_OBJ_UNLOCK:
+
+ return ( xSemaphoreGive( *( SemaphoreHandle_t * ) synchHandle ) == pdTRUE ) ? true : false;
+
+ case TCPIP_MAC_SYNCH_REQUEST_CRIT_ENTER:
+ vTaskSuspendAll();
+
+ return true;
+
+ case TCPIP_MAC_SYNCH_REQUEST_CRIT_LEAVE:
+ xTaskResumeAll();
+
+ return true;
+
+ default:
+
+ return false;
+ }
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ static void MacHandlerTask( void * params )
+ {
+ EventBits_t evBits;
+
+ /* perform the MAC initialization */
+ while( macObjStatus == SYS_STATUS_BUSY )
+ {
+ /* process the underlying MAC module tasks */
+ ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
+
+ SYS_STATUS macStatus = ( macObject->TCPIP_MAC_Status )( macObjHandle );
+
+ if( macStatus == SYS_STATUS_BUSY )
+ { /* still pending */
+ vTaskDelay( PIC32_MAC_TASK_INIT_PENDING_DELAY );
+ }
+ else
+ { /* completed ...somehow */
+ macObjStatus = macStatus;
+
+ xTaskNotify( ( TaskHandle_t ) params, PIC32_MAC_EVENT_INIT_DONE, eSetBits );
+
+ if( macStatus != SYS_STATUS_READY )
+ { /* failed miserably */
+ vTaskDelete( 0 );
+ }
+
+ /* done, up and running */
+ }
+ }
+
+ while( true )
+ {
+ xTaskNotifyWait( PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, PIC32_MAC_EVENT_TIMEOUT | PIC32_MAC_EVENT_IF_PENDING, &evBits, portMAX_DELAY );
+
+ if( ( evBits & PIC32_MAC_EVENT_TIMEOUT ) != 0 )
+ { /* timeout occurred... */
+ ( macObject->TCPIP_MAC_Tasks )( macObjHandle );
+ bool linkCurr = ( macObject->TCPIP_MAC_LinkCheck )( macCliHandle ); /* check link status */
+
+ if( macLinkStatus != linkCurr )
+ { /* link status changed; some event could ve fired here if needed */
+ PIC32_MAC_DbgPrint( " MAC link: %s!\r\n", linkCurr ? "ON" : "OFF" );
+ macLinkStatus = linkCurr;
+ }
+ }
+
+ if( ( evBits & PIC32_MAC_EVENT_IF_PENDING ) != 0 )
+ { /* IF events signal */
+ TCPIP_MAC_EVENT activeEvents = ( macObject->TCPIP_MAC_EventPendingGet )( macCliHandle );
+
+ if( activeEvents != TCPIP_MAC_EV_NONE )
+ {
+ /* acknowledge the events */
+ ( macObject->TCPIP_MAC_EventAcknowledge )( macCliHandle, activeEvents );
+
+ /* check for RX */
+ if( ( activeEvents & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_RX_OVFLOW | TCPIP_MAC_EV_RX_BUFNA ) ) != 0 )
+ { /* RX packets available */
+ MacRxPackets();
+ }
+
+ /* call the driver process function; */
+ /* PIC32 driver requests it through TCPIP_MAC_ParametersGet() which is bypassed here! */
+ ( macObject->TCPIP_MAC_Process )( macCliHandle );
+ }
+ }
+
+ /* do what you have to do and then wait for another event... */
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void MacTmrCallback( TimerHandle_t xTimer )
+ {
+ xTaskNotify( macTaskHandle, PIC32_MAC_EVENT_TIMEOUT, eSetBits );
+ }
+
+ /* MAC interrupt event function */
+ /* MAC signals an event, probably from within ISR */
+ /* we care just for RX related events */
+ static void MAC_EventFunction( TCPIP_MAC_EVENT event,
+ const void * eventParam )
+ {
+ BaseType_t xHigherPriorityTaskWoken;
+
+ if( ( event & ( TCPIP_MAC_EV_RX_DONE | TCPIP_MAC_EV_TX_DONE | TCPIP_MAC_EV_RXTX_ERRORS ) ) != 0 )
+ {
+ xHigherPriorityTaskWoken = pdFALSE;
+ xTaskNotifyFromISR( macTaskHandle, PIC32_MAC_EVENT_IF_PENDING, eSetBits, &xHigherPriorityTaskWoken );
+
+ if( xHigherPriorityTaskWoken )
+ {
+ portEND_SWITCHING_ISR( xHigherPriorityTaskWoken );
+ }
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ BaseType_t xGetPhyLinkStatus( void )
+ {
+ return macLinkStatus == true ? pdPASS : pdFAIL;
+ }
+
+
+ /* receive packets from the MAC driver */
+ static void MacRxPackets( void )
+ {
+ TCPIP_MAC_PACKET * pRxPkt;
+
+ /* get all the new MAC packets */
+ while( ( pRxPkt = ( macObject->TCPIP_MAC_PacketRx )( macCliHandle, 0, 0 ) ) != 0 )
+ {
+ MacProcessRxPacket( pRxPkt );
+ }
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static void MacProcessRxPacket( TCPIP_MAC_PACKET * pRxPkt )
+ {
+ bool pktSuccess, pktLost;
+ size_t pktLength;
+ TCPIP_MAC_DATA_SEGMENT * pSeg;
+ uint8_t * pPktBuff;
+ NetworkBufferDescriptor_t * pxBufferDescriptor;
+ IPStackEvent_t xRxEvent;
+
+ pxBufferDescriptor = 0;
+ pktSuccess = pktLost = false;
+
+ while( true )
+ {
+ pktLength = 0;
+ int nSegs = 0;
+ pSeg = pRxPkt->pDSeg;
+ pPktBuff = pSeg->segLoad;
+
+ /* calculate the packet size */
+ do
+ {
+ pktLength += pSeg->segLen;
+ pSeg = pSeg->next;
+ nSegs++;
+ } while( pSeg != 0 );
+
+ if( nSegs > 1 )
+ { /* no support in FreeRTOS for multi segment packets! */
+ break;
+ }
+
+ /* sizeof(TCPIP_MAC_ETHERNET_HEADER) is subtracted by the driver */
+ /* but FreeRTOS needs the whole frame! */
+ pktLength += sizeof( TCPIP_MAC_ETHERNET_HEADER );
+
+ if( eConsiderFrameForProcessing( pPktBuff ) != eProcessBuffer )
+ {
+ break;
+ }
+
+ /* get the network descriptor (no data buffer) to hold this packet */
+ pxBufferDescriptor = pxGetNetworkBufferWithDescriptor( 0, 0 );
+
+ if( pxBufferDescriptor == 0 )
+ {
+ pktLost = true;
+ break;
+ }
+
+ PIC32_MacAssociate( pRxPkt, pxBufferDescriptor, pktLength );
+
+ xRxEvent.eEventType = eNetworkRxEvent;
+ xRxEvent.pvData = ( void * ) pxBufferDescriptor;
+
+ /* Send the data to the TCP/IP stack */
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ { /* failed */
+ pktLost = true;
+ }
+ else
+ { /* success */
+ pktSuccess = true;
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+
+ break;
+ }
+
+ if( !pktSuccess )
+ { /* smth went wrong; nothing sent to the */
+ if( pxBufferDescriptor != 0 )
+ {
+ pxBufferDescriptor->pucEthernetBuffer = 0;
+ vReleaseNetworkBufferAndDescriptor( pxBufferDescriptor );
+ }
+
+ if( pktLost )
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+
+ /* acknowledge the packet to the MAC driver */
+ if( pRxPkt->ackFunc )
+ {
+ ( *pRxPkt->ackFunc )( pRxPkt, pRxPkt->ackParam );
+ }
+ else
+ {
+ PIC32_MacPacketOrphan( pRxPkt );
+ }
+ }
+ }
+
+ #if ( PIC32_MAC_DEBUG_COMMANDS != 0 )
+ /* */
+ static int _Command_MacInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv )
+ {
+ TCPIP_MAC_RES macRes;
+ TCPIP_MAC_RX_STATISTICS rxStatistics;
+ TCPIP_MAC_TX_STATISTICS txStatistics;
+ TCPIP_MAC_STATISTICS_REG_ENTRY regEntries[ 8 ];
+ TCPIP_MAC_STATISTICS_REG_ENTRY * pRegEntry;
+ int jx, hwEntries;
+ char entryName[ sizeof( pRegEntry->registerName ) + 1 ];
+
+ const void * cmdIoParam = pCmdIO->cmdIoParam;
+
+ if( argc != 1 )
+ {
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Usage: macinfo \r\n" );
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "Ex: macinfo \r\n" );
+
+ return false;
+ }
+
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s driver statistics\r\n", macObject->macName );
+ macRes = ( macObject->TCPIP_MAC_StatisticsGet )( macCliHandle, &rxStatistics, &txStatistics );
+
+ if( macRes == TCPIP_MAC_RES_OK )
+ {
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnRxOkPackets: %d, nRxPendBuffers: %d, nRxSchedBuffers: %d, ",
+ rxStatistics.nRxOkPackets, rxStatistics.nRxPendBuffers, rxStatistics.nRxSchedBuffers );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "nRxErrorPackets: %d, nRxFragmentErrors: %d\r\n", rxStatistics.nRxErrorPackets, rxStatistics.nRxFragmentErrors );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\tnTxOkPackets: %d, nTxPendBuffers: %d, nTxErrorPackets: %d, nTxQueueFull: %d\r\n",
+ txStatistics.nTxOkPackets, txStatistics.nTxPendBuffers, txStatistics.nTxErrorPackets, txStatistics.nTxQueueFull );
+ }
+ else
+ {
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
+ }
+
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Interface: %s hardware statistics\r\n", macObject->macName );
+ macRes = ( macObject->TCPIP_MAC_RegisterStatisticsGet )( macCliHandle, regEntries, sizeof( regEntries ) / sizeof( *regEntries ), &hwEntries );
+
+ if( macRes == TCPIP_MAC_RES_OK )
+ {
+ entryName[ sizeof( entryName ) - 1 ] = 0;
+
+ for( jx = 0, pRegEntry = regEntries; jx < hwEntries && jx < sizeof( regEntries ) / sizeof( *regEntries ); jx++, pRegEntry++ )
+ {
+ strncpy( entryName, pRegEntry->registerName, sizeof( entryName ) - 1 );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "\t%s: 0x%8x\r\n", entryName, pRegEntry->registerValue );
+ }
+ }
+ else
+ {
+ ( *pCmdIO->pCmdApi->msg )( cmdIoParam, "\tnot supported\r\n" );
+ }
+
+ return true;
+ }
+
+ /*-----------------------------------------------------------*/
+
+ static int _Command_NetInfo( SYS_CMD_DEVICE_NODE * pCmdIO,
+ int argc,
+ char ** argv )
+ {
+ const void * cmdIoParam = pCmdIO->cmdIoParam;
+
+ union
+ {
+ uint32_t ul;
+ uint8_t b[ 4 ];
+ }
+ sUl;
+
+ sUl.ul = FreeRTOS_GetIPAddress();
+
+ bool linkUp = FreeRTOS_IsNetworkUp() == pdTRUE;
+
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "IP address: %d.%d.%d.%d\r\n", sUl.b[ 0 ], sUl.b[ 1 ], sUl.b[ 2 ], sUl.b[ 3 ] );
+ ( *pCmdIO->pCmdApi->print )( cmdIoParam, "Link is: %s\r\n", linkUp ? "Up" : "Down" );
+
+ return true;
+ }
+
+#include "aws_application_version.h"
+
+static int _Command_Version(SYS_CMD_DEVICE_NODE* pCmdIO, int argc, char** argv)
+{
+ configPRINTF( ( "App version - maj: %d, min: %d, build: %d\r\n", xAppFirmwareVersion.u.x.ucMajor, xAppFirmwareVersion.u.x.ucMinor, xAppFirmwareVersion.u.x.usBuild) );
+ return 0;
+}
+
+ #endif /* (PIC32_MAC_DEBUG_COMMANDS != 0) */
+#endif /* #ifdef PIC32_USE_ETHERNET */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c
index a24cfe8ad..fc8335ebe 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/portable/NetworkInterface/pic32mzef/NetworkInterface_wifi.c
@@ -1,192 +1,192 @@
-/*******************************************************************************
-* Network Interface file
-*
-* Summary:
-* Network Interface file for FreeRTOS-Plus-TCP stack
-*
-* Description:
-* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
-*******************************************************************************/
-
-/*******************************************************************************
-* File Name: pic32_NetworkInterface.c
-* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
-*
-* Permission is hereby granted, free of charge, to any person obtaining a copy of
-* this software and associated documentation files (the "Software"), to deal in
-* the Software without restriction, including without limitation the rights to
-* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-* of the Software, and to permit persons to whom the Software is furnished to do
-* so, subject to the following conditions:
-* The above copyright notice and this permission notice shall be included in all
-* copies or substantial portions of the Software.
-*
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-* SOFTWARE
-*******************************************************************************/
-#ifndef PIC32_USE_ETHERNET
-#include <sys/kmem.h>
-
-#include "FreeRTOS.h"
-#include "semphr.h"
-#include "event_groups.h"
-#include "FreeRTOS_IP.h"
-#include "FreeRTOS_IP_Private.h"
-
-#include "NetworkInterface.h"
-#include "NetworkBufferManagement.h"
-#include "peripheral/eth/plib_eth.h"
-
-#include "system_config.h"
-#include "system/console/sys_console.h"
-#include "system/debug/sys_debug.h"
-#include "system/command/sys_command.h"
-
-#include "driver/ethmac/drv_ethmac.h"
-#include "driver/miim/drv_miim.h"
-#include "m2m_types.h"
-
-#include "tcpip/tcpip.h"
-#include "tcpip/src/tcpip_private.h"
-#include "tcpip/src/link_list.h"
-#include "wilc1000_task.h"
-
-#include "NetworkConfig.h"
-
-
- #include "iot_wifi.h"
-
- /* local definitions and data */
-
-
- /* FreeRTOS implementation functions */
- BaseType_t xNetworkInterfaceInitialise( void )
- {
- WIFINetworkParams_t xNetworkParams;
-
- xNetworkParams.pcSSID = clientcredentialWIFI_SSID;
- xNetworkParams.ucSSIDLength = sizeof( clientcredentialWIFI_SSID );
- xNetworkParams.pcPassword = clientcredentialWIFI_PASSWORD;
- xNetworkParams.ucPasswordLength = sizeof( clientcredentialWIFI_PASSWORD );
- xNetworkParams.xSecurity = clientcredentialWIFI_SECURITY;
- xNetworkParams.cChannel = M2M_WIFI_CH_ALL; /* Scan all channels (255) */
-
- /*Turn WiFi ON */
- if( WIFI_On() != eWiFiSuccess )
- {
- return pdFAIL;
- }
-
- /* Connect to the AP */
- if( WIFI_ConnectAP( &xNetworkParams ) != eWiFiSuccess )
- {
- return pdFAIL;
- }
-
- return pdPASS;
- }
-
-
- /*-----------------------------------------------------------*/
-
- BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
- BaseType_t xReleaseAfterSend )
- {
- BaseType_t retRes = pdFALSE;
-
- if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
- {
- /* There you go */
- if( WDRV_EXT_DataSend( pxDescriptor->xDataLength, pxDescriptor->pucEthernetBuffer ) == 0 )
- {
- retRes = pdTRUE;
- }
-
- /* The buffer has been sent so can be released. */
- if( xReleaseAfterSend != pdFALSE )
- {
- vReleaseNetworkBufferAndDescriptor( pxDescriptor );
- }
- }
-
- return retRes;
- }
-
-
- /************************************* Section: helper functions ************************************************** */
- /* */
-
-
-
- /************************************* Section: worker code ************************************************** */
- /* */
-
- void xNetworkFrameReceived( uint32_t len,
- uint8_t const * const frame )
- {
- bool pktSuccess, pktLost;
- NetworkBufferDescriptor_t * pxNetworkBuffer = NULL;
- IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
-
- pktSuccess = pktLost = false;
-
- while( true )
- {
- if( eConsiderFrameForProcessing( frame ) != eProcessBuffer )
- {
- break;
- }
-
- /* get the network descriptor (no data buffer) to hold this packet */
- pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( len, 0 );
-
- if( pxNetworkBuffer == NULL )
- {
- pktLost = true;
- break;
- }
-
- /* Set the actual packet length, in case a larger buffer was
- returned. */
- pxNetworkBuffer->xDataLength = len;
-
- /* Copy the packet. */
- memcpy( pxNetworkBuffer->pucEthernetBuffer, frame, len );
-
- /* Send the data to the TCP/IP stack. */
- xRxEvent.pvData = ( void * ) pxNetworkBuffer;
-
- if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
- { /* failed */
- pktLost = true;
- }
- else
- { /* success */
- pktSuccess = true;
- iptraceNETWORK_INTERFACE_RECEIVE();
- }
-
- break;
- }
-
- if( !pktSuccess )
- { /* smth went wrong; nothing sent to the */
- if( pxNetworkBuffer != NULL )
- {
- pxNetworkBuffer->pucEthernetBuffer = 0;
- vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
- }
-
- if( pktLost )
- {
- iptraceETHERNET_RX_EVENT_LOST();
- }
- }
- }
-
-#endif /* #ifndef PIC32_USE_ETHERNET */
+/*******************************************************************************
+* Network Interface file
+*
+* Summary:
+* Network Interface file for FreeRTOS-Plus-TCP stack
+*
+* Description:
+* - Interfaces PIC32 to the FreeRTOS TCP/IP stack
+*******************************************************************************/
+
+/*******************************************************************************
+* File Name: pic32_NetworkInterface.c
+* Copyright 2017 Microchip Technology Incorporated and its subsidiaries.
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy of
+* this software and associated documentation files (the "Software"), to deal in
+* the Software without restriction, including without limitation the rights to
+* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+* of the Software, and to permit persons to whom the Software is furnished to do
+* so, subject to the following conditions:
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE
+*******************************************************************************/
+#ifndef PIC32_USE_ETHERNET
+#include <sys/kmem.h>
+
+#include "FreeRTOS.h"
+#include "semphr.h"
+#include "event_groups.h"
+#include "FreeRTOS_IP.h"
+#include "FreeRTOS_IP_Private.h"
+
+#include "NetworkInterface.h"
+#include "NetworkBufferManagement.h"
+#include "peripheral/eth/plib_eth.h"
+
+#include "system_config.h"
+#include "system/console/sys_console.h"
+#include "system/debug/sys_debug.h"
+#include "system/command/sys_command.h"
+
+#include "driver/ethmac/drv_ethmac.h"
+#include "driver/miim/drv_miim.h"
+#include "m2m_types.h"
+
+#include "tcpip/tcpip.h"
+#include "tcpip/src/tcpip_private.h"
+#include "tcpip/src/link_list.h"
+#include "wilc1000_task.h"
+
+#include "NetworkConfig.h"
+
+
+ #include "iot_wifi.h"
+
+ /* local definitions and data */
+
+
+ /* FreeRTOS implementation functions */
+ BaseType_t xNetworkInterfaceInitialise( void )
+ {
+ WIFINetworkParams_t xNetworkParams;
+
+ xNetworkParams.pcSSID = clientcredentialWIFI_SSID;
+ xNetworkParams.ucSSIDLength = sizeof( clientcredentialWIFI_SSID );
+ xNetworkParams.pcPassword = clientcredentialWIFI_PASSWORD;
+ xNetworkParams.ucPasswordLength = sizeof( clientcredentialWIFI_PASSWORD );
+ xNetworkParams.xSecurity = clientcredentialWIFI_SECURITY;
+ xNetworkParams.cChannel = M2M_WIFI_CH_ALL; /* Scan all channels (255) */
+
+ /*Turn WiFi ON */
+ if( WIFI_On() != eWiFiSuccess )
+ {
+ return pdFAIL;
+ }
+
+ /* Connect to the AP */
+ if( WIFI_ConnectAP( &xNetworkParams ) != eWiFiSuccess )
+ {
+ return pdFAIL;
+ }
+
+ return pdPASS;
+ }
+
+
+ /*-----------------------------------------------------------*/
+
+ BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxDescriptor,
+ BaseType_t xReleaseAfterSend )
+ {
+ BaseType_t retRes = pdFALSE;
+
+ if( ( pxDescriptor != 0 ) && ( pxDescriptor->pucEthernetBuffer != 0 ) && ( pxDescriptor->xDataLength != 0 ) )
+ {
+ /* There you go */
+ if( WDRV_EXT_DataSend( pxDescriptor->xDataLength, pxDescriptor->pucEthernetBuffer ) == 0 )
+ {
+ retRes = pdTRUE;
+ }
+
+ /* The buffer has been sent so can be released. */
+ if( xReleaseAfterSend != pdFALSE )
+ {
+ vReleaseNetworkBufferAndDescriptor( pxDescriptor );
+ }
+ }
+
+ return retRes;
+ }
+
+
+ /************************************* Section: helper functions ************************************************** */
+ /* */
+
+
+
+ /************************************* Section: worker code ************************************************** */
+ /* */
+
+ void xNetworkFrameReceived( uint32_t len,
+ uint8_t const * const frame )
+ {
+ bool pktSuccess, pktLost;
+ NetworkBufferDescriptor_t * pxNetworkBuffer = NULL;
+ IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
+
+ pktSuccess = pktLost = false;
+
+ while( true )
+ {
+ if( eConsiderFrameForProcessing( frame ) != eProcessBuffer )
+ {
+ break;
+ }
+
+ /* get the network descriptor (no data buffer) to hold this packet */
+ pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( len, 0 );
+
+ if( pxNetworkBuffer == NULL )
+ {
+ pktLost = true;
+ break;
+ }
+
+ /* Set the actual packet length, in case a larger buffer was
+ returned. */
+ pxNetworkBuffer->xDataLength = len;
+
+ /* Copy the packet. */
+ memcpy( pxNetworkBuffer->pucEthernetBuffer, frame, len );
+
+ /* Send the data to the TCP/IP stack. */
+ xRxEvent.pvData = ( void * ) pxNetworkBuffer;
+
+ if( xSendEventStructToIPTask( &xRxEvent, 0 ) == pdFALSE )
+ { /* failed */
+ pktLost = true;
+ }
+ else
+ { /* success */
+ pktSuccess = true;
+ iptraceNETWORK_INTERFACE_RECEIVE();
+ }
+
+ break;
+ }
+
+ if( !pktSuccess )
+ { /* smth went wrong; nothing sent to the */
+ if( pxNetworkBuffer != NULL )
+ {
+ pxNetworkBuffer->pucEthernetBuffer = 0;
+ vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
+ }
+
+ if( pktLost )
+ {
+ iptraceETHERNET_RX_EVENT_LOST();
+ }
+ }
+ }
+
+#endif /* #ifndef PIC32_USE_ETHERNET */
diff --git a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/readme.txt b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/readme.txt
index a90fb9e17..65e5e2b19 100644
--- a/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/readme.txt
+++ b/FreeRTOS-Plus/Source/FreeRTOS-Plus-TCP/readme.txt
@@ -1,18 +1,18 @@
-Contains the files that implement FreeRTOS+TCP.
-
-User documentation, including an API reference is available on:
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/
-
-A description of the source code organisation is available on:
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html
-
-The porting guide is available on:
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_Porting.html
-
-License information is available on:
-http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_Plus_TCP_License.html
-
-At this time it is recommended to use BufferAllocation_2.c in which case it is
-essential to use the heap_4.c memory allocation scheme:
-http://www.FreeRTOS.org/a00111.html
-
+Contains the files that implement FreeRTOS+TCP.
+
+User documentation, including an API reference is available on:
+http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/
+
+A description of the source code organisation is available on:
+http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/TCP_Networking_Tutorial.html
+
+The porting guide is available on:
+http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_TCP_Porting.html
+
+License information is available on:
+http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_TCP/FreeRTOS_Plus_TCP_License.html
+
+At this time it is recommended to use BufferAllocation_2.c in which case it is
+essential to use the heap_4.c memory allocation scheme:
+http://www.FreeRTOS.org/a00111.html
+