xref: /FreeRTOS-Plus-TCP-v4.0.0/test/unit-test/FreeRTOS_Sockets/FreeRTOS_Sockets_UDP_API_utest.c (revision 2d3f4daa567ffe71aeda2e0f6d0bc02850db0627)
1 /*
2  * FreeRTOS+TCP <DEVELOPMENT BRANCH>
3  * Copyright (C) 2022 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
4  *
5  * SPDX-License-Identifier: MIT
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy of
8  * this software and associated documentation files (the "Software"), to deal in
9  * the Software without restriction, including without limitation the rights to
10  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
11  * the Software, and to permit persons to whom the Software is furnished to do so,
12  * subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in all
15  * copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
19  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
20  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23  *
24  * http://aws.amazon.com/freertos
25  * http://www.FreeRTOS.org
26  */
27 
28 
29 /* Include Unity header */
30 #include "unity.h"
31 
32 /* Include standard libraries */
33 #include <stdlib.h>
34 #include <string.h>
35 #include <stdint.h>
36 
37 #include "mock_task.h"
38 #include "mock_list.h"
39 
40 /* This must come after list.h is included (in this case, indirectly
41  * by mock_list.h). */
42 #include "mock_Sockets_list_macros.h"
43 #include "mock_queue.h"
44 #include "mock_event_groups.h"
45 #include "mock_portable.h"
46 
47 #include "mock_FreeRTOS_IP.h"
48 #include "mock_FreeRTOS_IP_Private.h"
49 #include "mock_NetworkBufferManagement.h"
50 #include "mock_FreeRTOS_Stream_Buffer.h"
51 #include "mock_FreeRTOS_TCP_WIN.h"
52 #include "mock_FreeRTOS_IPv4_Sockets.h"
53 #include "mock_FreeRTOS_IPv6_Sockets.h"
54 
55 #include "FreeRTOS_Sockets.h"
56 
57 #include "FreeRTOS_Sockets_stubs.c"
58 #include "catch_assert.h"
59 
60 #include "FreeRTOSIPConfig.h"
61 
62 /* =========================== EXTERN VARIABLES =========================== */
63 
64 #define TEST_MAX_UDPV4_PAYLOAD_LENGTH    ipconfigNETWORK_MTU - ( ipSIZE_OF_IPv4_HEADER + ipSIZE_OF_UDP_HEADER )
65 #define TEST_MAX_UDPV6_PAYLOAD_LENGTH    ipconfigNETWORK_MTU - ( ipSIZE_OF_IPv6_HEADER + ipSIZE_OF_UDP_HEADER )
66 
67 /* ============================== Test Cases ============================== */
68 
69 /**
70  * @brief NULL socket.
71  */
test_FreeRTOS_recvfrom_NullSocket(void)72 void test_FreeRTOS_recvfrom_NullSocket( void )
73 {
74     int32_t lReturn;
75     Socket_t xSocket = NULL;
76     void * pvBuffer;
77     size_t uxBufferLength;
78     BaseType_t xFlags = 0;
79     struct freertos_sockaddr * pxSourceAddress;
80     socklen_t * pxSourceAddressLength;
81 
82     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
83 
84     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINVAL, lReturn );
85 }
86 
87 /**
88  * @brief Receiving from a TCP socket (while a UDP socket should be called).
89  */
test_FreeRTOS_recvfrom_TCPSocket(void)90 void test_FreeRTOS_recvfrom_TCPSocket( void )
91 {
92     int32_t lReturn;
93     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
94     Socket_t xSocket = ( Socket_t ) ucSocket;
95     void * pvBuffer;
96     size_t uxBufferLength;
97     BaseType_t xFlags = 0;
98     struct freertos_sockaddr * pxSourceAddress = NULL;
99     socklen_t * pxSourceAddressLength = NULL;
100 
101     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
102 
103     xSocket->ucProtocol = FREERTOS_IPPROTO_TCP;
104 
105     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
106 
107     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
108 
109     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINVAL, lReturn );
110 }
111 
112 /**
113  * @brief Call to the function is interrupted.
114  */
test_FreeRTOS_recvfrom_NonBlockingInterrupted(void)115 void test_FreeRTOS_recvfrom_NonBlockingInterrupted( void )
116 {
117     int32_t lReturn;
118     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
119     Socket_t xSocket = ( Socket_t ) ucSocket;
120     void * pvBuffer;
121     size_t uxBufferLength;
122     BaseType_t xFlags = 0;
123     struct freertos_sockaddr * pxSourceAddress;
124     socklen_t * pxSourceAddressLength;
125 
126     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
127 
128     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
129 
130     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
131 
132     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
133 
134     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( EventBits_t ) eSOCKET_INTR, pdTRUE, pdFALSE, 0, eSOCKET_INTR );
135 
136     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
137 
138     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINTR, lReturn );
139 }
140 
141 /**
142  * @brief Non blocking call which will block.
143  */
test_FreeRTOS_recvfrom_NonBlocking(void)144 void test_FreeRTOS_recvfrom_NonBlocking( void )
145 {
146     int32_t lReturn;
147     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
148     Socket_t xSocket = ( Socket_t ) ucSocket;
149     void * pvBuffer;
150     size_t uxBufferLength;
151     BaseType_t xFlags = 0;
152     struct freertos_sockaddr * pxSourceAddress;
153     socklen_t * pxSourceAddressLength;
154 
155     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
156 
157     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
158 
159     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
160 
161     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
162 
163     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( EventBits_t ) eSOCKET_INTR, pdTRUE, pdFALSE, 0, ~eSOCKET_INTR );
164 
165     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
166 
167     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EWOULDBLOCK, lReturn );
168 }
169 
170 /**
171  * @brief Non-blocking flag set but nothing received by the socket yet.
172  */
test_FreeRTOS_recvfrom_NonBlockingFlagSet(void)173 void test_FreeRTOS_recvfrom_NonBlockingFlagSet( void )
174 {
175     int32_t lReturn;
176     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
177     Socket_t xSocket = ( Socket_t ) ucSocket;
178     void * pvBuffer;
179     size_t uxBufferLength;
180     BaseType_t xFlags = FREERTOS_MSG_DONTWAIT;
181     struct freertos_sockaddr * pxSourceAddress;
182     socklen_t * pxSourceAddressLength;
183 
184     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
185 
186     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
187     xSocket->xReceiveBlockTime = 0x123;
188 
189     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
190 
191     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
192 
193     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
194 
195     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EWOULDBLOCK, lReturn );
196 }
197 
198 /**
199  * @brief Blocking read times out.
200  */
test_FreeRTOS_recvfrom_BlockingButTimeout(void)201 void test_FreeRTOS_recvfrom_BlockingButTimeout( void )
202 {
203     int32_t lReturn;
204     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
205     Socket_t xSocket = ( Socket_t ) ucSocket;
206     void * pvBuffer;
207     size_t uxBufferLength;
208     BaseType_t xFlags = 0;
209     struct freertos_sockaddr * pxSourceAddress;
210     socklen_t * pxSourceAddressLength;
211 
212     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
213 
214     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
215     xSocket->xReceiveBlockTime = 0x123;
216 
217     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
218 
219     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
220 
221     vTaskSetTimeOutState_ExpectAnyArgs();
222 
223     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
224 
225     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
226 
227     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdTRUE );
228 
229     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
230 
231     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EWOULDBLOCK, lReturn );
232 }
233 
234 /**
235  * @brief Blocking read - timeout in second iteration.
236  */
test_FreeRTOS_recvfrom_BlockingButTimeoutSecondTime(void)237 void test_FreeRTOS_recvfrom_BlockingButTimeoutSecondTime( void )
238 {
239     int32_t lReturn;
240     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
241     Socket_t xSocket = ( Socket_t ) ucSocket;
242     void * pvBuffer;
243     size_t uxBufferLength;
244     BaseType_t xFlags = 0;
245     struct freertos_sockaddr * pxSourceAddress;
246     socklen_t * pxSourceAddressLength;
247 
248     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
249 
250     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
251     xSocket->xReceiveBlockTime = 0x123;
252 
253     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
254 
255     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
256 
257     vTaskSetTimeOutState_ExpectAnyArgs();
258 
259     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
260 
261     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
262 
263     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdFALSE );
264 
265     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
266 
267     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
268 
269     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdTRUE );
270 
271     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
272 
273     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EWOULDBLOCK, lReturn );
274 }
275 
276 /**
277  * @brief Blocking read interrupted.
278  */
test_FreeRTOS_recvfrom_BlockingButInterrupted(void)279 void test_FreeRTOS_recvfrom_BlockingButInterrupted( void )
280 {
281     int32_t lReturn;
282     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
283     Socket_t xSocket = ( Socket_t ) ucSocket;
284     void * pvBuffer;
285     size_t uxBufferLength;
286     BaseType_t xFlags = 0;
287     struct freertos_sockaddr * pxSourceAddress;
288     socklen_t * pxSourceAddressLength;
289 
290     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
291 
292     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
293     xSocket->xReceiveBlockTime = 0x123;
294 
295     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
296     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
297 
298     vTaskSetTimeOutState_ExpectAnyArgs();
299 
300     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, eSOCKET_INTR );
301 
302     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
303 
304     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINTR, lReturn );
305 }
306 
307 /**
308  * @brief Blocking read interrupted and received.
309  */
test_FreeRTOS_recvfrom_BlockingButInterruptedAndReceived(void)310 void test_FreeRTOS_recvfrom_BlockingButInterruptedAndReceived( void )
311 {
312     int32_t lReturn;
313     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
314     Socket_t xSocket = ( Socket_t ) ucSocket;
315     void * pvBuffer;
316     size_t uxBufferLength;
317     BaseType_t xFlags = 0;
318     struct freertos_sockaddr * pxSourceAddress;
319     socklen_t * pxSourceAddressLength;
320 
321     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
322 
323     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
324     xSocket->xReceiveBlockTime = 0x123;
325 
326     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
327     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
328 
329     vTaskSetTimeOutState_ExpectAnyArgs();
330 
331     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, eSOCKET_INTR | eSOCKET_RECEIVE );
332 
333     xEventGroupSetBits_ExpectAndReturn( xSocket->xEventGroup, ( EventBits_t ) eSOCKET_RECEIVE, pdFALSE );
334 
335     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, pxSourceAddress, pxSourceAddressLength );
336 
337     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINTR, lReturn );
338 }
339 
340 /**
341  * @brief Blocking read socket gets a packet while it is waiting. However, the packet
342  *        is only a UDP header.
343  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_JustUDPHeader(void)344 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_JustUDPHeader( void )
345 {
346     int32_t lReturn;
347     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
348     Socket_t xSocket = ( Socket_t ) ucSocket;
349     char pvBuffer[ ipconfigTCP_MSS ];
350     size_t uxBufferLength = ipconfigTCP_MSS;
351     BaseType_t xFlags = 0;
352     struct freertos_sockaddr xSourceAddress;
353     socklen_t xSourceAddressLength;
354     ListItem_t xListItem;
355     NetworkBufferDescriptor_t xNetworkBuffer;
356     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
357 
358     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
359     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t );
360     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
361     xNetworkBuffer.usPort = 0xABCD;
362 
363     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
364     memset( &xListItem, 0, sizeof( ListItem_t ) );
365     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
366     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
367 
368     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
369     xSocket->xReceiveBlockTime = 0x123;
370     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
371 
372     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
373 
374     xListItem.pvOwner = &xNetworkBuffer;
375     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
376 
377     vTaskSetTimeOutState_ExpectAnyArgs();
378 
379     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
380 
381     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
382 
383     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
384 
385     uxListRemove_ExpectAndReturn( &( xNetworkBuffer.xBufferListItem ), 0 );
386 
387     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
388 
389     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xSourceAddress, ipUDP_PAYLOAD_OFFSET_IPv4 );
390 
391     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
392 
393     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, &xSourceAddress, &xSourceAddressLength );
394 
395     TEST_ASSERT_EQUAL( 0, lReturn );
396     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
397     TEST_ASSERT_EACH_EQUAL_UINT8( 0xAB, pvBuffer, ipconfigTCP_MSS );
398 }
399 
400 /**
401  * @brief Blocking read socket gets a packet while it is waiting. However, the packet
402  *        is UDP header and 100 bytes.
403  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100(void)404 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100( void )
405 {
406     int32_t lReturn;
407     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
408     Socket_t xSocket = ( Socket_t ) ucSocket;
409     char pvBuffer[ ipconfigTCP_MSS ];
410     size_t uxBufferLength = ipconfigTCP_MSS;
411     BaseType_t xFlags = 0;
412     struct freertos_sockaddr xSourceAddress;
413     socklen_t xSourceAddressLength;
414     ListItem_t xListItem;
415     NetworkBufferDescriptor_t xNetworkBuffer;
416     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
417 
418     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
419     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t ) + 100;
420     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
421     xNetworkBuffer.usPort = 0xABCD;
422 
423     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
424     memset( &xListItem, 0, sizeof( ListItem_t ) );
425     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
426     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
427 
428     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
429     xSocket->xReceiveBlockTime = 0x123;
430 
431     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
432 
433     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
434 
435     xListItem.pvOwner = &xNetworkBuffer;
436     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
437 
438     vTaskSetTimeOutState_ExpectAnyArgs();
439 
440     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
441 
442     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
443 
444     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
445 
446     uxListRemove_ExpectAndReturn( &( xNetworkBuffer.xBufferListItem ), 0 );
447 
448     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
449 
450     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xSourceAddress, ipUDP_PAYLOAD_OFFSET_IPv4 );
451 
452     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
453 
454     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, &xSourceAddress, &xSourceAddressLength );
455 
456     TEST_ASSERT_EQUAL( 100, lReturn );
457     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
458     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, 100 );
459     TEST_ASSERT_EACH_EQUAL_UINT8( 0xAB, &pvBuffer[ 100 ], ipconfigTCP_MSS - 100 );
460 }
461 
462 /**
463  * @brief Blocking read socket gets a packet while it is waiting. However, the packet
464  *        is UDP header and 100 bytes.
465  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall(void)466 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall( void )
467 {
468     int32_t lReturn;
469     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
470     Socket_t xSocket = ( Socket_t ) ucSocket;
471     char pvBuffer[ ipconfigTCP_MSS ];
472     size_t uxBufferLength = 50;
473     BaseType_t xFlags = 0;
474     struct freertos_sockaddr xSourceAddress;
475     socklen_t xSourceAddressLength;
476     ListItem_t xListItem;
477     NetworkBufferDescriptor_t xNetworkBuffer;
478     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
479 
480     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
481     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t ) + 100;
482     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
483     xNetworkBuffer.usPort = 0xABCD;
484 
485     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
486     memset( &xListItem, 0, sizeof( ListItem_t ) );
487     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
488     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
489 
490     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
491     xSocket->xReceiveBlockTime = 0x123;
492 
493     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
494 
495     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
496 
497     xListItem.pvOwner = &xNetworkBuffer;
498     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
499 
500     vTaskSetTimeOutState_ExpectAnyArgs();
501 
502     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
503 
504     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
505 
506     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
507 
508     uxListRemove_ExpectAndReturn( &( xNetworkBuffer.xBufferListItem ), 0 );
509 
510     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
511 
512     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xSourceAddress, ipUDP_PAYLOAD_OFFSET_IPv4 );
513 
514     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
515 
516     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, &xSourceAddress, &xSourceAddressLength );
517 
518     TEST_ASSERT_EQUAL( 50, lReturn );
519     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
520     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, uxBufferLength );
521     TEST_ASSERT_EACH_EQUAL_UINT8( 0xAB, &pvBuffer[ uxBufferLength ], ipconfigTCP_MSS - uxBufferLength );
522 }
523 
524 /**
525  * @brief Blocking read socket gets a packet while it is waiting. The packet
526  *        is UDP header and 100 bytes. But the buffer is small and the receive
527  *        call is used to peek in the list.
528  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall_Peek(void)529 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall_Peek( void )
530 {
531     int32_t lReturn;
532     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
533     Socket_t xSocket = ( Socket_t ) ucSocket;
534     char pvBuffer[ ipconfigTCP_MSS ];
535     size_t uxBufferLength = 50;
536     BaseType_t xFlags = FREERTOS_MSG_PEEK;
537     struct freertos_sockaddr xSourceAddress;
538     socklen_t xSourceAddressLength;
539     ListItem_t xListItem;
540     NetworkBufferDescriptor_t xNetworkBuffer;
541     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
542 
543     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
544     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t ) + 100;
545     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
546     xNetworkBuffer.usPort = 0xABCD;
547 
548     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
549     memset( &xListItem, 0, sizeof( ListItem_t ) );
550     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
551     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
552 
553     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
554     xSocket->xReceiveBlockTime = 0x123;
555 
556     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
557 
558     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
559 
560     xListItem.pvOwner = &xNetworkBuffer;
561     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
562 
563     vTaskSetTimeOutState_ExpectAnyArgs();
564 
565     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
566 
567     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
568 
569     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
570 
571     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
572 
573     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xSourceAddress, ipUDP_PAYLOAD_OFFSET_IPv4 );
574 
575     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, &xSourceAddress, &xSourceAddressLength );
576 
577     TEST_ASSERT_EQUAL( 50, lReturn );
578     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
579     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, uxBufferLength );
580     TEST_ASSERT_EACH_EQUAL_UINT8( 0xAB, &pvBuffer[ uxBufferLength ], ipconfigTCP_MSS - uxBufferLength );
581 }
582 
583 /**
584  * @brief Blocking read socket gets a packet while it is waiting. The packet
585  *        is UDP header and 100 bytes. But the buffer is small and the receive
586  *        call is used to peek in the list. The source address param passed is NULL.
587  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall_Peek_SourceAddrNULL(void)588 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall_Peek_SourceAddrNULL( void )
589 {
590     int32_t lReturn;
591     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
592     Socket_t xSocket = ( Socket_t ) ucSocket;
593     char pvBuffer[ ipconfigTCP_MSS ];
594     size_t uxBufferLength = 50;
595     BaseType_t xFlags = FREERTOS_MSG_PEEK;
596     socklen_t xSourceAddressLength;
597     ListItem_t xListItem;
598     NetworkBufferDescriptor_t xNetworkBuffer;
599     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
600 
601     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
602     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t ) + 100;
603     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
604     xNetworkBuffer.usPort = 0xABCD;
605 
606     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
607     memset( &xListItem, 0, sizeof( ListItem_t ) );
608     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
609     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
610 
611     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
612     xSocket->xReceiveBlockTime = 0x123;
613 
614     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
615 
616     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
617 
618     xListItem.pvOwner = &xNetworkBuffer;
619     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
620 
621     vTaskSetTimeOutState_ExpectAnyArgs();
622 
623     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
624 
625     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
626 
627     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
628 
629     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
630 
631     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, NULL, ipUDP_PAYLOAD_OFFSET_IPv4 );
632 
633     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, NULL, &xSourceAddressLength );
634 
635     TEST_ASSERT_EQUAL( 50, lReturn );
636     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
637     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, uxBufferLength );
638     TEST_ASSERT_EACH_EQUAL_UINT8( 0xAB, &pvBuffer[ uxBufferLength ], ipconfigTCP_MSS - uxBufferLength );
639 }
640 
641 /**
642  * @brief Blocking read socket gets a packet while it is waiting. The packet
643  *        is UDP header and 100 bytes. But the buffer is small and the receive
644  *        call is used to peek in the list with zero copy flag.
645  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall_ZeroCopyAndPeek(void)646 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_Packet100SizeSmall_ZeroCopyAndPeek( void )
647 {
648     int32_t lReturn;
649     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
650     Socket_t xSocket = ( Socket_t ) ucSocket;
651     char * pvBuffer;
652     size_t uxBufferLength = 50;
653     BaseType_t xFlags = FREERTOS_ZERO_COPY;
654     socklen_t xSourceAddressLength;
655     ListItem_t xListItem;
656     NetworkBufferDescriptor_t xNetworkBuffer;
657     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
658 
659     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
660     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t ) + 100;
661     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
662     xNetworkBuffer.usPort = 0xABCD;
663 
664     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
665     memset( &xListItem, 0, sizeof( ListItem_t ) );
666     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
667 
668     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
669     xSocket->xReceiveBlockTime = 0x123;
670 
671     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
672 
673     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
674 
675     xListItem.pvOwner = &xNetworkBuffer;
676     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
677 
678     vTaskSetTimeOutState_ExpectAnyArgs();
679 
680     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
681 
682     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
683 
684     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
685 
686     uxListRemove_ExpectAndReturn( &xNetworkBuffer.xBufferListItem, 0U );
687 
688     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
689 
690     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, NULL, ipUDP_PAYLOAD_OFFSET_IPv4 );
691 
692     lReturn = FreeRTOS_recvfrom( xSocket, &pvBuffer, uxBufferLength, xFlags, NULL, &xSourceAddressLength );
693 
694     TEST_ASSERT_EQUAL( 100, lReturn );
695     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
696     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, 100 );
697 }
698 
699 /**
700  * @brief Blocking read socket gets a packet as soon as the function is called. The packet
701  *        is UDP header and 100 bytes. But the buffer is small and the receive
702  *        call is used to peek in the list.
703  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBegining_Packet100SizeSmall_ZeroCopyAndPeek(void)704 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBegining_Packet100SizeSmall_ZeroCopyAndPeek( void )
705 {
706     int32_t lReturn;
707     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
708     Socket_t xSocket = ( Socket_t ) ucSocket;
709     char * pvBuffer;
710     size_t uxBufferLength = 50;
711     BaseType_t xFlags = FREERTOS_MSG_PEEK | FREERTOS_ZERO_COPY;
712     socklen_t xSourceAddressLength;
713     ListItem_t xListItem;
714     NetworkBufferDescriptor_t xNetworkBuffer;
715     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
716 
717     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
718     xNetworkBuffer.xDataLength = sizeof( UDPPacket_t ) + 100;
719     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
720     xNetworkBuffer.usPort = 0xABCD;
721 
722     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
723     memset( &xListItem, 0, sizeof( ListItem_t ) );
724     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
725 
726     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
727     xSocket->xReceiveBlockTime = 0x123;
728 
729     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
730 
731     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
732 
733     xListItem.pvOwner = &xNetworkBuffer;
734     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
735 
736     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
737 
738     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv4_HEADER );
739 
740     xRecv_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, NULL, ipUDP_PAYLOAD_OFFSET_IPv4 );
741 
742     lReturn = FreeRTOS_recvfrom( xSocket, &pvBuffer, uxBufferLength, xFlags, NULL, &xSourceAddressLength );
743 
744     TEST_ASSERT_EQUAL( 100, lReturn );
745     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
746     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, 100 );
747 }
748 
749 /**
750  * @brief Blocking read socket gets a packet while it is waiting. However, the packet
751  *        is UDPv6 header and 100 bytes.
752  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_IPv6Packet100(void)753 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_IPv6Packet100( void )
754 {
755     int32_t lReturn;
756     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
757     Socket_t xSocket = ( Socket_t ) ucSocket;
758     char pvBuffer[ ipconfigTCP_MSS ];
759     size_t uxBufferLength = ipconfigTCP_MSS;
760     BaseType_t xFlags = 0;
761     struct freertos_sockaddr xSourceAddress;
762     ListItem_t xListItem;
763     NetworkBufferDescriptor_t xNetworkBuffer;
764     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
765 
766     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
767     xNetworkBuffer.xDataLength = sizeof( UDPPacket_IPv6_t ) + 100;
768     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
769     xNetworkBuffer.usPort = 0xABCD;
770 
771     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
772     memset( &xListItem, 0, sizeof( ListItem_t ) );
773     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
774     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
775 
776     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
777     xSocket->xReceiveBlockTime = 0x123;
778 
779     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
780 
781     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
782 
783     xListItem.pvOwner = &xNetworkBuffer;
784     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
785 
786     vTaskSetTimeOutState_ExpectAnyArgs();
787 
788     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
789 
790     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
791 
792     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
793 
794     uxListRemove_ExpectAndReturn( &( xNetworkBuffer.xBufferListItem ), 0 );
795 
796     uxIPHeaderSizePacket_IgnoreAndReturn( ipSIZE_OF_IPv6_HEADER );
797 
798     xRecv_Update_IPv6_ExpectAndReturn( &xNetworkBuffer, &xSourceAddress, ipUDP_PAYLOAD_OFFSET_IPv6 );
799 
800     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
801 
802     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, &xSourceAddress, NULL );
803 
804     TEST_ASSERT_EQUAL( 100, lReturn );
805     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pucEthernetBuffer, ipconfigTCP_MSS );
806     TEST_ASSERT_EACH_EQUAL_UINT8( 0x12, pvBuffer, 100 );
807     TEST_ASSERT_EACH_EQUAL_UINT8( 0xAB, &pvBuffer[ 100 ], ipconfigTCP_MSS - 100 );
808 }
809 
810 /**
811  * @brief Blocking read socket gets a packet while it is waiting. However, the packet
812  *        is UDPv6 header and 100 bytes.
813  */
test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_UnknownIPHeaderSize(void)814 void test_FreeRTOS_recvfrom_BlockingGetsPacketInBetween_UnknownIPHeaderSize( void )
815 {
816     int32_t lReturn;
817     uint8_t ucSocket[ sizeof( FreeRTOS_Socket_t ) ];
818     Socket_t xSocket = ( Socket_t ) ucSocket;
819     char pvBuffer[ ipconfigTCP_MSS ];
820     size_t uxBufferLength = ipconfigTCP_MSS;
821     BaseType_t xFlags = FREERTOS_ZERO_COPY;
822     struct freertos_sockaddr xSourceAddress;
823     ListItem_t xListItem;
824     NetworkBufferDescriptor_t xNetworkBuffer;
825     uint8_t pucEthernetBuffer[ ipconfigTCP_MSS ];
826 
827     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
828     xNetworkBuffer.xDataLength = sizeof( UDPPacket_IPv6_t ) + 100;
829     xNetworkBuffer.xIPAddress.ulIP_IPv4 = 0x1234ABCD;
830     xNetworkBuffer.usPort = 0xABCD;
831 
832     memset( xSocket, 0, sizeof( FreeRTOS_Socket_t ) );
833     memset( &xListItem, 0, sizeof( ListItem_t ) );
834     memset( pucEthernetBuffer, 0x12, ipconfigTCP_MSS );
835     memset( pvBuffer, 0xAB, ipconfigTCP_MSS );
836 
837     xSocket->ucProtocol = FREERTOS_IPPROTO_UDP;
838     xSocket->xReceiveBlockTime = 0x123;
839 
840     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket->xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
841 
842     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0 );
843 
844     xListItem.pvOwner = &xNetworkBuffer;
845     xSocket->u.xUDP.xWaitingPacketsList.xListEnd.pxNext = &xListItem;
846 
847     vTaskSetTimeOutState_ExpectAnyArgs();
848 
849     xEventGroupWaitBits_ExpectAndReturn( xSocket->xEventGroup, ( ( EventBits_t ) eSOCKET_RECEIVE ) | ( ( EventBits_t ) eSOCKET_INTR ), pdTRUE, pdFALSE, xSocket->xReceiveBlockTime, 0 );
850 
851     listCURRENT_LIST_LENGTH_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), 0x12 );
852 
853     listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &( xSocket->u.xUDP.xWaitingPacketsList ), &xNetworkBuffer );
854 
855     uxListRemove_ExpectAndReturn( &( xNetworkBuffer.xBufferListItem ), 0 );
856 
857     uxIPHeaderSizePacket_IgnoreAndReturn( 0xFF );
858 
859     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
860 
861     lReturn = FreeRTOS_recvfrom( xSocket, pvBuffer, uxBufferLength, xFlags, &xSourceAddress, NULL );
862 
863     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINVAL, lReturn );
864 }
865 
866 /**
867  * @brief Assert to catch sending buffer is NULL.
868  */
test_FreeRTOS_sendto_CatchAssert(void)869 void test_FreeRTOS_sendto_CatchAssert( void )
870 {
871     int32_t lResult;
872     Socket_t xSocket;
873     char * pvBuffer = NULL;
874     size_t uxTotalDataLength = 0;
875     BaseType_t xFlags = 0;
876     struct freertos_sockaddr xDestinationAddress;
877     socklen_t xDestinationAddressLength;
878 
879     catch_assert( FreeRTOS_sendto( xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength ) );
880 }
881 
882 /**
883  * @brief Assert to catch destination address is NULL.
884  */
test_FreeRTOS_sendto_CatchAssertNullDest(void)885 void test_FreeRTOS_sendto_CatchAssertNullDest( void )
886 {
887     int32_t lResult;
888     Socket_t xSocket;
889     char pvBuffer[ ipconfigTCP_MSS ];
890     size_t uxTotalDataLength = 0;
891     BaseType_t xFlags = 0;
892     socklen_t xDestinationAddressLength;
893 
894     catch_assert( FreeRTOS_sendto( xSocket, pvBuffer, uxTotalDataLength, xFlags, NULL, xDestinationAddressLength ) );
895 }
896 
897 /**
898  * @brief Sending more than maximum allowed data in one go.
899  */
test_FreeRTOS_sendto_MoreDataThanUDPPayload(void)900 void test_FreeRTOS_sendto_MoreDataThanUDPPayload( void )
901 {
902     int32_t lResult;
903     Socket_t xSocket;
904     char pvBuffer[ ipconfigTCP_MSS ];
905     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH + 1;
906     BaseType_t xFlags;
907     struct freertos_sockaddr xDestinationAddress;
908     socklen_t xDestinationAddressLength;
909 
910     xDestinationAddress.sin_family = FREERTOS_AF_INET;
911 
912     lResult = FreeRTOS_sendto( xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
913 
914     TEST_ASSERT_EQUAL( 0, lResult );
915 }
916 
917 /**
918  * @brief Trying to send with a TCP socket.
919  */
test_FreeRTOS_sendto_TCPSocket(void)920 void test_FreeRTOS_sendto_TCPSocket( void )
921 {
922     int32_t lResult;
923     FreeRTOS_Socket_t xSocket;
924     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
925     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
926     BaseType_t xFlags;
927     struct freertos_sockaddr xDestinationAddress;
928     socklen_t xDestinationAddressLength;
929 
930     xDestinationAddress.sin_family = FREERTOS_AF_INET;
931     xSocket.ucProtocol = FREERTOS_IPPROTO_TCP;
932 
933     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
934 
935     TEST_ASSERT_EQUAL( 0, lResult );
936 }
937 
938 /**
939  * @brief Sending from IP task when a buffer cannot be allocated.
940  */
test_FreeRTOS_sendto_IPTaskCalling_NoNetworkBuffer(void)941 void test_FreeRTOS_sendto_IPTaskCalling_NoNetworkBuffer( void )
942 {
943     int32_t lResult;
944     FreeRTOS_Socket_t xSocket;
945     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
946     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
947     BaseType_t xFlags = 0;
948     struct freertos_sockaddr xDestinationAddress;
949     socklen_t xDestinationAddressLength;
950 
951     xDestinationAddress.sin_family = FREERTOS_AF_INET;
952     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
953 
954     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
955 
956     xIsCallingFromIPTask_ExpectAndReturn( pdTRUE );
957 
958     vTaskSetTimeOutState_ExpectAnyArgs();
959 
960     pxGetNetworkBufferWithDescriptor_ExpectAnyArgsAndReturn( NULL );
961 
962     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
963 
964     TEST_ASSERT_EQUAL( 0, lResult );
965 }
966 
967 /**
968  * @brief Sending from IP task without using zero copy.
969  */
test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy(void)970 void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy( void )
971 {
972     int32_t lResult;
973     FreeRTOS_Socket_t xSocket;
974     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
975     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
976     BaseType_t xFlags = 0;
977     struct freertos_sockaddr xDestinationAddress;
978     socklen_t xDestinationAddressLength;
979     NetworkBufferDescriptor_t xNetworkBuffer;
980     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
981 
982     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
983     memset( &xSocket, 0, sizeof( xSocket ) );
984     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
985 
986     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
987 
988     xDestinationAddress.sin_family = FREERTOS_AF_INET;
989     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
990     xSocket.u.xUDP.pxHandleSent = NULL;
991 
992     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
993 
994     xIsCallingFromIPTask_ExpectAndReturn( pdTRUE );
995 
996     vTaskSetTimeOutState_ExpectAnyArgs();
997 
998     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv4, 0, &xNetworkBuffer );
999 
1000     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdTRUE );
1001 
1002     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1003 
1004     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1005 
1006     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1007 
1008     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1009 
1010     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1011     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1012     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1013     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1014 }
1015 
1016 /**
1017  * @brief Sending from IP task without using zero copy.
1018  */
test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy1(void)1019 void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy1( void )
1020 {
1021     int32_t lResult;
1022     FreeRTOS_Socket_t xSocket;
1023     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1024     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1025     BaseType_t xFlags = 0;
1026     struct freertos_sockaddr xDestinationAddress;
1027     socklen_t xDestinationAddressLength;
1028     NetworkBufferDescriptor_t xNetworkBuffer;
1029     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1030 
1031     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1032     memset( &xSocket, 0, sizeof( xSocket ) );
1033     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1034 
1035     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1036 
1037     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1038     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1039     xSocket.u.xUDP.pxHandleSent = NULL;
1040 
1041     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1042 
1043     xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
1044 
1045     vTaskSetTimeOutState_ExpectAnyArgs();
1046 
1047     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv4, 0, &xNetworkBuffer );
1048 
1049     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdTRUE );
1050 
1051     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1052 
1053     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1054 
1055     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1056 
1057     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1058 
1059     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1060     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1061     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1062     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1063 }
1064 
1065 /**
1066  * @brief Sending from IP task without using zero copy.
1067  */
test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy2(void)1068 void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy2( void )
1069 {
1070     int32_t lResult;
1071     FreeRTOS_Socket_t xSocket;
1072     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1073     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1074     BaseType_t xFlags = FREERTOS_MSG_DONTWAIT;
1075     struct freertos_sockaddr xDestinationAddress;
1076     socklen_t xDestinationAddressLength;
1077     NetworkBufferDescriptor_t xNetworkBuffer;
1078     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1079 
1080     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1081     memset( &xSocket, 0, sizeof( xSocket ) );
1082     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1083 
1084     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1085 
1086     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1087     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1088     xSocket.u.xUDP.pxHandleSent = NULL;
1089 
1090     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1091 
1092     vTaskSetTimeOutState_ExpectAnyArgs();
1093 
1094     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv4, 0, &xNetworkBuffer );
1095 
1096     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdTRUE );
1097 
1098     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1099 
1100     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1101 
1102     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1103 
1104     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1105 
1106     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1107     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1108     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1109     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1110 }
1111 
1112 /**
1113  * @brief Sending from IP task without using zero copy. Checks if xIsCallingFromIPTask
1114  * gets called if xFlags's FREERTOS_MSG_DONTWAIT bit is unset.
1115  */
test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy2_xFlagZero(void)1116 void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy2_xFlagZero( void )
1117 {
1118     int32_t lResult;
1119     FreeRTOS_Socket_t xSocket;
1120     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1121     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1122     BaseType_t xFlags = 0;
1123     struct freertos_sockaddr xDestinationAddress;
1124     socklen_t xDestinationAddressLength;
1125     NetworkBufferDescriptor_t xNetworkBuffer;
1126     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1127 
1128     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1129     memset( &xSocket, 0, sizeof( xSocket ) );
1130     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1131 
1132     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1133 
1134     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1135     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1136     xSocket.u.xUDP.pxHandleSent = NULL;
1137 
1138     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1139 
1140     xIsCallingFromIPTask_ExpectAndReturn( pdFALSE );
1141 
1142     vTaskSetTimeOutState_ExpectAnyArgs();
1143 
1144     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv4, 0, &xNetworkBuffer );
1145 
1146     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdTRUE );
1147 
1148     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1149 
1150     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1151 
1152     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1153 
1154     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1155 
1156     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1157     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1158     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1159     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1160 }
1161 
1162 /**
1163  * @brief Sending from IP task without using zero copy.
1164  */
test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy3(void)1165 void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy3( void )
1166 {
1167     int32_t lResult;
1168     FreeRTOS_Socket_t xSocket;
1169     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1170     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1171     BaseType_t xFlags = FREERTOS_MSG_DONTWAIT;
1172     struct freertos_sockaddr xDestinationAddress;
1173     socklen_t xDestinationAddressLength;
1174     NetworkBufferDescriptor_t xNetworkBuffer;
1175     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1176 
1177     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1178     memset( &xSocket, 0, sizeof( xSocket ) );
1179     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1180 
1181     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1182 
1183     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1184     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1185     xSocket.u.xUDP.pxHandleSent = NULL;
1186 
1187     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1188 
1189     vTaskSetTimeOutState_ExpectAnyArgs();
1190 
1191     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv4, 0, &xNetworkBuffer );
1192 
1193     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdFALSE );
1194 
1195     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1196 
1197     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1198 
1199     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1200 
1201     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1202 
1203     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1204     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1205     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1206     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1207 }
1208 
1209 /**
1210  * @brief  Sending from IP task with zero copy.
1211  */
test_FreeRTOS_sendto_IPTaskCalling_ZeroCopy(void)1212 void test_FreeRTOS_sendto_IPTaskCalling_ZeroCopy( void )
1213 {
1214     int32_t lResult;
1215     FreeRTOS_Socket_t xSocket;
1216     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1217     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1218     BaseType_t xFlags = FREERTOS_ZERO_COPY;
1219     struct freertos_sockaddr xDestinationAddress;
1220     socklen_t xDestinationAddressLength;
1221     NetworkBufferDescriptor_t xNetworkBuffer;
1222     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1223 
1224     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1225     memset( &xSocket, 0, sizeof( xSocket ) );
1226     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1227 
1228     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1229 
1230     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1231     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1232     xSocket.u.xUDP.pxHandleSent = NULL;
1233 
1234     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1235 
1236     xIsCallingFromIPTask_ExpectAndReturn( pdTRUE );
1237 
1238     pxUDPPayloadBuffer_to_NetworkBuffer_ExpectAndReturn( pvBuffer, &xNetworkBuffer );
1239 
1240     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1241 
1242     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1243 
1244     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1245 
1246     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1247 
1248     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1249     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1250     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1251     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1252 }
1253 
1254 static uint32_t ulCalled = 0;
xLocalFunctionPointer(Socket_t xSocket,size_t xLength)1255 static void xLocalFunctionPointer( Socket_t xSocket,
1256                                    size_t xLength )
1257 {
1258     ulCalled++;
1259 }
1260 
1261 /**
1262  * @brief Sending from IP task with zero copy. A valid callback function pointer is added.
1263  */
test_FreeRTOS_sendto_IPTaskCalling_ZeroCopy_ValidFunctionPointer(void)1264 void test_FreeRTOS_sendto_IPTaskCalling_ZeroCopy_ValidFunctionPointer( void )
1265 {
1266     int32_t lResult;
1267     FreeRTOS_Socket_t xSocket;
1268     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1269     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1270     BaseType_t xFlags = FREERTOS_ZERO_COPY;
1271     struct freertos_sockaddr xDestinationAddress;
1272     socklen_t xDestinationAddressLength;
1273     NetworkBufferDescriptor_t xNetworkBuffer;
1274     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1275 
1276     ulCalled = 0;
1277 
1278     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1279     memset( &xSocket, 0, sizeof( xSocket ) );
1280     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1281 
1282     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1283 
1284     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1285     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1286     xSocket.u.xUDP.pxHandleSent = xLocalFunctionPointer;
1287 
1288     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1289 
1290     xIsCallingFromIPTask_ExpectAndReturn( pdTRUE );
1291 
1292     pxUDPPayloadBuffer_to_NetworkBuffer_ExpectAndReturn( pvBuffer, &xNetworkBuffer );
1293 
1294     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1295 
1296     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1297 
1298     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1299 
1300     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1301 
1302     TEST_ASSERT_EQUAL( TEST_MAX_UDPV4_PAYLOAD_LENGTH, lResult );
1303     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1304     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1305     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1306     TEST_ASSERT_EQUAL( 1, ulCalled );
1307 }
1308 
1309 /**
1310  * @brief Sending from IP task with zero copy.Sending message to IP task fails.
1311  */
test_FreeRTOS_sendto_IPTaskCalling_ZeroCopy_SendingToIPTaskFails(void)1312 void test_FreeRTOS_sendto_IPTaskCalling_ZeroCopy_SendingToIPTaskFails( void )
1313 {
1314     int32_t lResult;
1315     FreeRTOS_Socket_t xSocket;
1316     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1317     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1318     BaseType_t xFlags = FREERTOS_ZERO_COPY;
1319     struct freertos_sockaddr xDestinationAddress;
1320     socklen_t xDestinationAddressLength;
1321     NetworkBufferDescriptor_t xNetworkBuffer;
1322     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1323 
1324     ulCalled = 0;
1325 
1326     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1327     memset( &xSocket, 0, sizeof( xSocket ) );
1328     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1329 
1330     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1331 
1332     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1333     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1334     xSocket.u.xUDP.pxHandleSent = xLocalFunctionPointer;
1335 
1336     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1337 
1338     xIsCallingFromIPTask_ExpectAndReturn( pdTRUE );
1339 
1340     pxUDPPayloadBuffer_to_NetworkBuffer_ExpectAndReturn( pvBuffer, &xNetworkBuffer );
1341 
1342     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1343 
1344     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1345 
1346     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdFAIL );
1347 
1348     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1349 
1350     TEST_ASSERT_EQUAL( 0, lResult );
1351     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1352     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1353     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1354     TEST_ASSERT_EQUAL( 0, ulCalled );
1355 }
1356 
1357 /**
1358  * @brief Sending from IP task without zero copy. Sending message to IP task fails.
1359  */
test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy_SendingToIPTaskFails(void)1360 void test_FreeRTOS_sendto_IPTaskCalling_NonZeroCopy_SendingToIPTaskFails( void )
1361 {
1362     int32_t lResult;
1363     FreeRTOS_Socket_t xSocket;
1364     char pvBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH ];
1365     size_t uxTotalDataLength = TEST_MAX_UDPV4_PAYLOAD_LENGTH;
1366     BaseType_t xFlags = 0;
1367     struct freertos_sockaddr xDestinationAddress;
1368     socklen_t xDestinationAddressLength;
1369     NetworkBufferDescriptor_t xNetworkBuffer;
1370     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 ];
1371 
1372     ulCalled = 0;
1373 
1374     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV4_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv4 );
1375     memset( &xSocket, 0, sizeof( xSocket ) );
1376     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1377 
1378     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1379 
1380     xDestinationAddress.sin_family = FREERTOS_AF_INET;
1381     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1382     xSocket.u.xUDP.pxHandleSent = xLocalFunctionPointer;
1383 
1384     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1385 
1386     xIsCallingFromIPTask_ExpectAndReturn( pdTRUE );
1387 
1388     vTaskSetTimeOutState_ExpectAnyArgs();
1389 
1390     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv4, 0, &xNetworkBuffer );
1391 
1392     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdFALSE );
1393 
1394     xSend_UDP_Update_IPv4_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1395 
1396     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1397 
1398     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdFAIL );
1399 
1400     vReleaseNetworkBufferAndDescriptor_Expect( &xNetworkBuffer );
1401 
1402     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1403 
1404     TEST_ASSERT_EQUAL( 0, lResult );
1405     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_t ) );
1406     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1407     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1408     TEST_ASSERT_EQUAL( 0, ulCalled );
1409 }
1410 
1411 /**
1412  * @brief Sending an IPv6 packet from IP task without using zero copy.
1413  */
test_FreeRTOS_sendto_IPTaskCalling_IPv6NonZeroCopy(void)1414 void test_FreeRTOS_sendto_IPTaskCalling_IPv6NonZeroCopy( void )
1415 {
1416     int32_t lResult;
1417     FreeRTOS_Socket_t xSocket;
1418     char pvBuffer[ TEST_MAX_UDPV6_PAYLOAD_LENGTH ];
1419     size_t uxTotalDataLength = TEST_MAX_UDPV6_PAYLOAD_LENGTH;
1420     BaseType_t xFlags = FREERTOS_MSG_DONTWAIT;
1421     struct freertos_sockaddr xDestinationAddress;
1422     socklen_t xDestinationAddressLength;
1423     NetworkBufferDescriptor_t xNetworkBuffer;
1424     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV6_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv6 ];
1425 
1426     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV6_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv6 );
1427     memset( &xSocket, 0, sizeof( xSocket ) );
1428     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1429 
1430     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1431 
1432     xDestinationAddress.sin_family = FREERTOS_AF_INET6;
1433     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1434     xSocket.u.xUDP.pxHandleSent = NULL;
1435 
1436     listLIST_ITEM_CONTAINER_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), ( struct xLIST * ) ( uintptr_t ) 0x11223344 );
1437 
1438     vTaskSetTimeOutState_ExpectAnyArgs();
1439 
1440     pxGetNetworkBufferWithDescriptor_ExpectAndReturn( uxTotalDataLength + ipUDP_PAYLOAD_OFFSET_IPv6, 0, &xNetworkBuffer );
1441 
1442     xTaskCheckForTimeOut_ExpectAnyArgsAndReturn( pdFALSE );
1443 
1444     xSend_UDP_Update_IPv6_ExpectAndReturn( &xNetworkBuffer, &xDestinationAddress, NULL );
1445 
1446     listGET_LIST_ITEM_VALUE_ExpectAndReturn( &( xSocket.xBoundSocketListItem ), 0xAADF );
1447 
1448     xSendEventStructToIPTask_ExpectAnyArgsAndReturn( pdPASS );
1449 
1450     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1451 
1452     TEST_ASSERT_EQUAL( TEST_MAX_UDPV6_PAYLOAD_LENGTH, lResult );
1453     TEST_ASSERT_EQUAL( xNetworkBuffer.xDataLength, uxTotalDataLength + sizeof( UDPPacket_IPv6_t ) );
1454     TEST_ASSERT_EQUAL( xNetworkBuffer.usPort, xDestinationAddress.sin_port );
1455     TEST_ASSERT_EQUAL( xNetworkBuffer.usBoundPort, 0xAADF );
1456 }
1457 
1458 /**
1459  * @brief Sending an packet with unknown family.
1460  */
test_FreeRTOS_sendto_UnknownDestinationFamily(void)1461 void test_FreeRTOS_sendto_UnknownDestinationFamily( void )
1462 {
1463     int32_t lResult;
1464     FreeRTOS_Socket_t xSocket;
1465     char pvBuffer[ TEST_MAX_UDPV6_PAYLOAD_LENGTH ];
1466     size_t uxTotalDataLength = TEST_MAX_UDPV6_PAYLOAD_LENGTH;
1467     BaseType_t xFlags = FREERTOS_MSG_DONTWAIT;
1468     struct freertos_sockaddr xDestinationAddress;
1469     socklen_t xDestinationAddressLength;
1470     NetworkBufferDescriptor_t xNetworkBuffer;
1471     uint8_t pucEthernetBuffer[ TEST_MAX_UDPV6_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv6 ];
1472 
1473     memset( pucEthernetBuffer, 0, TEST_MAX_UDPV6_PAYLOAD_LENGTH + ipUDP_PAYLOAD_OFFSET_IPv6 );
1474     memset( &xSocket, 0, sizeof( xSocket ) );
1475     memset( &xNetworkBuffer, 0, sizeof( xNetworkBuffer ) );
1476 
1477     xNetworkBuffer.pucEthernetBuffer = pucEthernetBuffer;
1478 
1479     xDestinationAddress.sin_family = 0xFF;
1480     xSocket.ucProtocol = FREERTOS_IPPROTO_UDP;
1481     xSocket.u.xUDP.pxHandleSent = NULL;
1482 
1483     lResult = FreeRTOS_sendto( &xSocket, pvBuffer, uxTotalDataLength, xFlags, &xDestinationAddress, xDestinationAddressLength );
1484 
1485     TEST_ASSERT_EQUAL( -pdFREERTOS_ERRNO_EINVAL, lResult );
1486 }
1487