1 /*
2  * FreeRTOS V202212.00
3  * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4  *
5  * Permission is hereby granted, free of charge, to any person obtaining a copy of
6  * this software and associated documentation files (the "Software"), to deal in
7  * the Software without restriction, including without limitation the rights to
8  * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9  * the Software, and to permit persons to whom the Software is furnished to do so,
10  * subject to the following conditions:
11  *
12  * The above copyright notice and this permission notice shall be included in all
13  * copies or substantial portions of the Software.
14  *
15  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17  * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18  * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  *
22  * https://www.FreeRTOS.org
23  * https://github.com/FreeRTOS
24  *
25  */
26 
27 /* Standard includes. */
28 #include <string.h>
29 
30 /* FreeRTOS includes. */
31 #include "FreeRTOS.h"
32 
33 /* Transport interface include. */
34 #include "transport_plaintext.h"
35 
36 /*-----------------------------------------------------------*/
37 
38 /**
39  * @brief Each compilation unit that consumes the NetworkContext must define it.
40  * It should contain a single pointer as seen below whenever the header file
41  * of this transport implementation is included to your project.
42  *
43  * @note When using multiple transports in the same compilation unit,
44  *       define this pointer as void *.
45  */
46 struct NetworkContext
47 {
48     PlaintextTransportParams_t * pParams;
49 };
50 
51 /*-----------------------------------------------------------*/
52 
Plaintext_FreeRTOS_Connect(NetworkContext_t * pNetworkContext,const char * pHostName,uint16_t port,uint32_t receiveTimeoutMs,uint32_t sendTimeoutMs)53 PlaintextTransportStatus_t Plaintext_FreeRTOS_Connect( NetworkContext_t * pNetworkContext,
54                                                        const char * pHostName,
55                                                        uint16_t port,
56                                                        uint32_t receiveTimeoutMs,
57                                                        uint32_t sendTimeoutMs )
58 {
59     PlaintextTransportParams_t * pPlaintextTransportParams = NULL;
60     PlaintextTransportStatus_t plaintextStatus = PLAINTEXT_TRANSPORT_SUCCESS;
61     BaseType_t socketStatus = 0;
62 
63     if( ( pNetworkContext == NULL ) || ( pNetworkContext->pParams == NULL ) || ( pHostName == NULL ) )
64     {
65         LogError( ( "Invalid input parameter(s): Arguments cannot be NULL. pNetworkContext=%p, "
66                     "pHostName=%p.",
67                     pNetworkContext,
68                     pHostName ) );
69         plaintextStatus = PLAINTEXT_TRANSPORT_INVALID_PARAMETER;
70     }
71     else
72     {
73         pPlaintextTransportParams = pNetworkContext->pParams;
74 
75         /* Initialize tcpSocket. */
76         pPlaintextTransportParams->tcpSocket = NULL;
77 
78         /* Establish a TCP connection with the server. */
79         socketStatus = TCP_Sockets_Connect( &( pPlaintextTransportParams->tcpSocket ),
80                                             pHostName,
81                                             port,
82                                             receiveTimeoutMs,
83                                             sendTimeoutMs );
84 
85         /* A non zero status is an error. */
86         if( socketStatus != 0 )
87         {
88             LogError( ( "Failed to connect to %s with error %d.",
89                         pHostName,
90                         socketStatus ) );
91             plaintextStatus = PLAINTEXT_TRANSPORT_CONNECT_FAILURE;
92         }
93     }
94 
95     return plaintextStatus;
96 }
97 
Plaintext_FreeRTOS_Disconnect(const NetworkContext_t * pNetworkContext)98 PlaintextTransportStatus_t Plaintext_FreeRTOS_Disconnect( const NetworkContext_t * pNetworkContext )
99 {
100     PlaintextTransportParams_t * pPlaintextTransportParams = NULL;
101     PlaintextTransportStatus_t plaintextStatus = PLAINTEXT_TRANSPORT_SUCCESS;
102 
103     if( ( pNetworkContext == NULL ) || ( pNetworkContext->pParams == NULL ) )
104     {
105         LogError( ( "pNetworkContext cannot be NULL." ) );
106         plaintextStatus = PLAINTEXT_TRANSPORT_INVALID_PARAMETER;
107     }
108     else
109     {
110         pPlaintextTransportParams = pNetworkContext->pParams;
111         /* Call socket disconnect function to close connection. */
112         TCP_Sockets_Disconnect( pPlaintextTransportParams->tcpSocket );
113     }
114 
115     return plaintextStatus;
116 }
117 
Plaintext_FreeRTOS_recv(NetworkContext_t * pNetworkContext,void * pBuffer,size_t bytesToRecv)118 int32_t Plaintext_FreeRTOS_recv( NetworkContext_t * pNetworkContext,
119                                  void * pBuffer,
120                                  size_t bytesToRecv )
121 {
122     PlaintextTransportParams_t * pPlaintextTransportParams = NULL;
123     int32_t socketStatus = 1;
124 
125     if( ( pNetworkContext == NULL ) || ( pNetworkContext->pParams == NULL ) )
126     {
127         LogError( ( "invalid input, pNetworkContext=%p", pNetworkContext ) );
128         socketStatus = -1;
129     }
130     else if( pBuffer == NULL )
131     {
132         LogError( ( "invalid input, pBuffer == NULL" ) );
133         socketStatus = -1;
134     }
135     else if( bytesToRecv == 0 )
136     {
137         LogError( ( "invalid input, bytesToRecv == 0" ) );
138         socketStatus = -1;
139     }
140     else
141     {
142         pPlaintextTransportParams = pNetworkContext->pParams;
143 
144         socketStatus = TCP_Sockets_Recv( pPlaintextTransportParams->tcpSocket,
145                                          pBuffer,
146                                          bytesToRecv );
147     }
148 
149     return socketStatus;
150 }
151 
Plaintext_FreeRTOS_send(NetworkContext_t * pNetworkContext,const void * pBuffer,size_t bytesToSend)152 int32_t Plaintext_FreeRTOS_send( NetworkContext_t * pNetworkContext,
153                                  const void * pBuffer,
154                                  size_t bytesToSend )
155 {
156     PlaintextTransportParams_t * pPlaintextTransportParams = NULL;
157     int32_t socketStatus = 0;
158 
159     if( ( pNetworkContext == NULL ) || ( pNetworkContext->pParams == NULL ) )
160     {
161         LogError( ( "invalid input, pNetworkContext=%p", pNetworkContext ) );
162         socketStatus = -1;
163     }
164     else if( pBuffer == NULL )
165     {
166         LogError( ( "invalid input, pBuffer == NULL" ) );
167         socketStatus = -1;
168     }
169     else if( bytesToSend == 0 )
170     {
171         LogError( ( "invalid input, bytesToSend == 0" ) );
172         socketStatus = -1;
173     }
174     else
175     {
176         pPlaintextTransportParams = pNetworkContext->pParams;
177         socketStatus = TCP_Sockets_Send( pPlaintextTransportParams->tcpSocket,
178                                          pBuffer,
179                                          bytesToSend );
180     }
181 
182     return socketStatus;
183 }
184