Update version number in readiness for V10.3.0 release. Sync SVN with reviewed release candidate.
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/DemoTasks/SimpleHTTPSExamples.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/DemoTasks/SimpleHTTPSExamples.c index a543fae..c2c236d 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/DemoTasks/SimpleHTTPSExamples.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/DemoTasks/SimpleHTTPSExamples.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/arch.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/arch.c index 02bf82b..1f62658 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/arch.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/arch.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/netif.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/netif.h index 2d51478..1a25c30 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/netif.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/WinPCap/netif.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.c index 2dc08cf..8eef94a 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.h index 197b216..ae31ae8 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/demo_logging.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/main.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/main.c index a1b0fa5..7af543b 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/main.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/common/main.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSConfig.h index d58a0b8..5b50d81 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSIPConfig.h index 92b7773..b165942 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/demo_config.h index e81cc2c..b6e7b4e 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/http_plain_text/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSConfig.h index d58a0b8..5b50d81 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSIPConfig.h index 92b7773..b165942 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/demo_config.h index 73f3318..14751df 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_basic_tls_server_auth/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSConfig.h index d58a0b8..5b50d81 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSIPConfig.h index f698510..1b09c3e 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/demo_config.h index 1e28638..2b1f43f 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/https/https_tls_mutual_auth/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_demo_profile.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_demo_profile.h index c4a3e1a..d1263f2 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_demo_profile.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_demo_profile.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_setup_check.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_setup_check.h index 0fefe03..85ee695 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_setup_check.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/aws_iot_setup_check.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/https_demo_profile.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/https_demo_profile.h index 8ef81df..eab9021 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/https_demo_profile.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/https_demo_profile.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/mqtt_demo_profile.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/mqtt_demo_profile.h index 40b5a97..51cb52e 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/mqtt_demo_profile.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/include/mqtt_demo_profile.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/DemoTasks/JobsNotifyNextExamples.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/DemoTasks/JobsNotifyNextExamples.c index 89d36a4..37a9ae8 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/DemoTasks/JobsNotifyNextExamples.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/DemoTasks/JobsNotifyNextExamples.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSConfig.h index d58a0b8..5b50d81 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSIPConfig.h index 6f86009..a2084f0 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/arch.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/arch.c index 02bf82b..1f62658 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/arch.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/arch.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/netif.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/netif.h index 2d51478..1a25c30 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/netif.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/WinPCap/netif.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_config.h index 971405c..407cd76 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.c index e22e910..8388bab 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.h index 197b216..ae31ae8 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/demo_logging.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/main.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/main.c index f06d37c..924ecee 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/main.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/jobs/jobs_notify_next/main.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/LightWeightMQTTExample.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/LightWeightMQTTExample.c index aabb3a6..94b5241 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/LightWeightMQTTExample.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/LightWeightMQTTExample.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/SimpleMQTTExamples.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/SimpleMQTTExamples.c index feb872c..7288238 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/SimpleMQTTExamples.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/DemoTasks/SimpleMQTTExamples.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/Run-time-stats-utils.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/Run-time-stats-utils.c index d9b7a59..bda52a9 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/Run-time-stats-utils.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/Run-time-stats-utils.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/arch.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/arch.c index 02bf82b..1f62658 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/arch.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/arch.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/netif.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/netif.h index 2d51478..1a25c30 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/netif.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/WinPCap/netif.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.c index e22e910..8388bab 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.h index 197b216..ae31ae8 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/demo_logging.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/main.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/main.c index 0c11b0c..d8403fd 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/main.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/common/main.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSConfig.h index d58a0b8..5b50d81 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSIPConfig.h index b4f55e1..b28a449 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/demo_config.h index 20a783d..a289ae5 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_basic_tls_server_auth/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSConfig.h index 841ebd1..9f4f4e6 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSIPConfig.h index 92b7773..b165942 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/demo_config.h index 6ea3703..14382ad 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_plain_text/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSConfig.h index d58a0b8..5b50d81 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSIPConfig.h index 6f86009..a2084f0 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/demo_config.h index 6639d24..5adfd95 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/mqtt/mqtt_tls_mutual_auth/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/DemoTasks/ShadowDeviceOperationsExamples.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/DemoTasks/ShadowDeviceOperationsExamples.c index 614e261..25b7d77 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/DemoTasks/ShadowDeviceOperationsExamples.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/DemoTasks/ShadowDeviceOperationsExamples.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSConfig.h index e407f43..7279980 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSIPConfig.h index 6f86009..a2084f0 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/arch.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/arch.c index 02bf82b..1f62658 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/arch.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/arch.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/netif.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/netif.h index 2d51478..1a25c30 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/netif.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/WinPCap/netif.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_config.h index b96fc0b..f0d8362 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.c index e22e910..8388bab 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.h index 197b216..ae31ae8 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/demo_logging.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/main.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/main.c index 357a2c2..131daa6 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/main.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/shadow/shadow_device_operations/main.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_offline/js/aws_iot_demo_profile_template.js b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_offline/js/aws_iot_demo_profile_template.js index d30abd5..a89619b 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_offline/js/aws_iot_demo_profile_template.js +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_offline/js/aws_iot_demo_profile_template.js
@@ -1,7 +1,7 @@ var awsIotProfileTemplate = `/* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile.templ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile.templ index 817f706..c9a54ab 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile.templ +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile.templ
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile_empty.templ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile_empty.templ index c4a3e1a..d1263f2 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile_empty.templ +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/tools/aws_config_quick_start/aws_iot_demo_profile_empty.templ
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/DemoTasks/SimpleTaskPoolExamples.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/DemoTasks/SimpleTaskPoolExamples.c index 3c8fa06..e0667d7 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/DemoTasks/SimpleTaskPoolExamples.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/DemoTasks/SimpleTaskPoolExamples.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSConfig.h index 8ec7ee0..1a46df0 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSIPConfig.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSIPConfig.h index 11f8f00..e788d28 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSIPConfig.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/FreeRTOSIPConfig.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/arch.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/arch.c index 02bf82b..1f62658 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/arch.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/arch.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/netif.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/netif.h index 2d51478..1a25c30 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/netif.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/WinPCap/netif.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_config.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_config.h index 971405c..407cd76 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_config.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_config.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.c index e22e910..8388bab 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.h b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.h index 197b216..ae31ae8 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.h +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/demo_logging.h
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
diff --git a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/main.c b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/main.c index 22f9590..fa9f5aa 100644 --- a/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/main.c +++ b/FreeRTOS-Labs/Demo/FreeRTOS_IoT_Libraries/utilities/task_pool/main.c
@@ -1,6 +1,6 @@ /* - * FreeRTOS Kernel V10.2.1 - * Copyright (C) 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * FreeRTOS Kernel V10.3.0 + * Copyright (C) 2020 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
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 e973cef..20fbe61 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 fd54884..0ee1b62 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 ba3a43e..d61e017 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 bac9b7a..27a948e 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 1574635..b47c4de 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 a432648..3df1c44 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 69dda29..69698c6 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 eb0d078..f8ea22e 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 cc18728..e0f89d2 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 3f1f6ef..e3c32fc 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 b241fd3..b159373 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 1a73f1c..939bff2 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 80a0416..0000000 --- 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 29b4aac..0000000 --- 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 563f0cb..0000000 --- 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 8a5a861..0000000 --- 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 b922783..0000000 --- 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 98cdff0..0000000 --- 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 1e0eacd..0000000 --- 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 8124db6..0000000 --- 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 be71c85..0000000 --- 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 d704da8..0000000 --- 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 f55fcec..0000000 --- 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 562fa61..0000000 --- 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 8fe5393..0000000 --- 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 5fe129d..0000000 --- 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 80a2f00..0000000 --- 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 cbd62d1..0000000 --- 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 935f949..0000000 --- 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 7bf65df..0000000 --- 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 9f4ca33..0000000 --- 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 9002c75..0000000 --- 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 ad8fc40..0000000 --- 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 e9d5452..0000000 --- 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 adcd19c..0000000 --- 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 b0cb794..0000000 --- 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 9f54d69..0000000 --- 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 f832e04..0000000 --- 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 d44593d..0000000 --- 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 d6a1d25..0000000 --- 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 62ae46a..0000000 --- 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 8a06baa..0000000 --- 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 8d39bac..0000000 --- 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 6442e8d..0000000 --- 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 f2f8eb5..0000000 --- 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 b362f36..0000000 --- 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 5505535..0000000 --- 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 fb2eaca..0000000 --- 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 54143c3..0000000 --- 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 3b63eb0..0000000 --- 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 7092fca..0000000 --- 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 c00147b..0000000 --- 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 7f9596a..0000000 --- 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 3653a6c..0000000 --- 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 1e0eacd..0000000 --- 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 8124db6..0000000 --- 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 be71c85..0000000 --- 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 d704da8..0000000 --- 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 f55fcec..0000000 --- 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 562fa61..0000000 --- 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 8fe5393..0000000 --- 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 5fe129d..0000000 --- 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 80a2f00..0000000 --- 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 cbd62d1..0000000 --- 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 935f949..0000000 --- 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 7bf65df..0000000 --- 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 9f4ca33..0000000 --- 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 9002c75..0000000 --- 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 ad8fc40..0000000 --- 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 e9d5452..0000000 --- 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 adcd19c..0000000 --- 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 b0cb794..0000000 --- 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 9f54d69..0000000 --- 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 f832e04..0000000 --- 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 d6a1d25..0000000 --- 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 62ae46a..0000000 --- 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 6851788..0000000 --- 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 8b97610..0000000 --- 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 2cf6b38..0000000 --- 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 5505535..0000000 --- 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 b362f36..0000000 --- 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 5f4fa3d..0a0774b 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 f73e0f3..c0670fe 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 37204d1..ea34041 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 d155d87..6cd2403 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 a8e293d..d02c44a 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 347140a..2ff605a 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 523fc8b..a270209 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 04a8a65..420a39f 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 72ed5a4..b87d8c7 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 42e7cc4..f36a93f 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 5659823..bd70799 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 f5bf167..182afea 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 54143c3..3bd55b3 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 e89d369..c4f8eb1 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 342ab12..d178d2c 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 0f4676f..864a3a1 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 7fdff10..2ea5354 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 4aa549e..9adb448 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 d704da8..ea1c431 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 8fe5393..6a93bea 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 d6a1d25..61d6f20 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 62ae46a..ad6886b 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 fae30bd..9641e06 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 e031afb..c089851 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 ad8d22c..727a805 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 ba678b9..8667ac2 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 0558704..08616dc 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 c98a7e8..7d8ed18 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 8871d65..9307680 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 43b246d..d4f167a 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 c94f55d..48e632a 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 e158348..87099ec 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 53a5c69..0bda993 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 d267565..8497965 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 cda8acd..8040880 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 e7d2a6c..14ae96e 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 52565cc..0bbfaa5 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 8a8017f..4174076 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 20cdf73..d23410f 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 166bf3a..363fca4 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 6a6d372..a49909e 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 449fa51..0458d76 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 6bfb4ad..46a2157 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 8604abe..0d8c038 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 88d3bba..926cceb 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 95bbbdf..9698227 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 76738c4..e26edf6 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 9532fd1..1cb7eeb 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 a7463fc..cb3dd35 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 534f526..0253a20 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 316e18f..0af7189 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 0fcde34..d57e607 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 c3d3fb4..8f1fb32 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 fa3f433..e70eb80 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 e008da0..51f5410 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 0000000..17aca57 --- /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 0000000..cdbad17 --- /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 0000000..7fe533a --- /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 d61b8d0..73455f9 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 5a88f78..658cc4a 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 85e6708..f0a7388 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 15e6eb6..95cc089 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 816b0b3..48a8ef9 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 29ea9ae..32c98e8 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 19a0f39..e486c1c 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 54a3e68..52b9080 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 2e6d2f9..49e2769 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 7c8750c..88c4c1f 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 83c96a0..3528269 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 6eb069f..ae40ac9 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 fe9e296..fc72c6a 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 8ea5fa0..6729df0 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 948f9a6..e4a3ba9 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 fca3ece..d741a2a 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 24d806d..dd29dfe 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 fa76959..0000000 --- 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 e0d04e4..7cee711 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 ac01d41..0b1f74d 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; + } + } +}<