1 /*
2 * FreeRTOS+TCP V3.1.0
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 /* FreeRTOS includes. */
29 #include "FreeRTOS.h"
30 #include "list.h"
31
32 /* FreeRTOS+TCP includes. */
33 #include "FreeRTOS_IP.h"
34 /* FreeRTOS+TCP includes. */
35 #include "FreeRTOS_IP.h"
36 #include "FreeRTOS_Sockets.h"
37 #include "FreeRTOS_IP_Private.h"
38 #include "FreeRTOS_DNS.h"
39 #include "NetworkBufferManagement.h"
40 #include "NetworkInterface.h"
41
42 #include "wifi-decl.h"
43 #include "wmerrno.h"
44 #include "wifi.h"
45
46 #include <wmlog.h>
47
48 #define net_e( ... ) \
49 wmlog_e( "freertos_tcp", ## __VA_ARGS__ )
50 #define net_w( ... ) \
51 wmlog_w( "freertos_tcp", ## __VA_ARGS__ )
52 #define net_d( ... ) \
53 wmlog( "freertos_tcp", ## __VA_ARGS__ )
54
55 #if 0 /*this is lwip structure. */
56 #define MAX_INTERFACES_SUPPORTED 3
57 static struct netif * netif_arr[ MAX_INTERFACES_SUPPORTED ];
58 #endif
59
60 /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
61 * driver will filter incoming packets and only pass the stack those packets it
62 * considers need processing. */
63 #if ( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
64 #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
65 #else
66 #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
67 #endif
68
69 #define IP_ADDR_ANY ( ( ip_addr_t * ) &ip_addr_any )
70 #define IP_ADDR_BROADCAST ( ( ip_addr_t * ) &ip_addr_broadcast )
71
72 /** 255.255.255.255 */
73 #define IPADDR_NONE ( ( u32_t ) 0xffffffffUL )
74 /** 127.0.0.1 */
75 #define IPADDR_LOOPBACK ( ( u32_t ) 0x7f000001UL )
76 /** 0.0.0.0 */
77 #define IPADDR_ANY ( ( u32_t ) 0x00000000UL )
78 /** 255.255.255.255 */
79 #define IPADDR_BROADCAST ( ( u32_t ) 0xffffffffUL )
80
81 /** 255.255.255.255 */
82 #define INADDR_NONE IPADDR_NONE
83 /** 127.0.0.1 */
84 #define INADDR_LOOPBACK IPADDR_LOOPBACK
85 /** 0.0.0.0 */
86 #define INADDR_ANY IPADDR_ANY
87 /** 255.255.255.255 */
88 #define INADDR_BROADCAST IPADDR_BROADCAST
89
90 enum if_state_t
91 {
92 INTERFACE_DOWN = 0,
93 INTERFACE_UP,
94 };
95 struct ip_addr
96 {
97 u32_t addr;
98 };
99
100 #define MLAN_BSS_TYPE_STA 0
101
102 extern uint8_t outbuf[ 2048 ];
103 extern bool mlan_is_amsdu( const t_u8 * rcvdata );
104 extern t_u8 * mlan_get_payload( const t_u8 * rcvdata,
105 t_u16 * payload_len,
106 int * interface );
107 extern int wrapper_wlan_handle_amsdu_rx_packet( const t_u8 * rcvdata,
108 const t_u16 datalen );
109 extern int wrapper_wlan_handle_rx_packet( const t_u16 datalen,
110 const t_u8 * rcvdata,
111 NetworkBufferDescriptor_t * pxNetworkBuffer );
112 static volatile uint32_t xInterfaceState = INTERFACE_DOWN;
113
process_data_packet(const t_u8 * databuf,const t_u16 datalen)114 static int process_data_packet( const t_u8 * databuf,
115 const t_u16 datalen )
116 {
117 int interface = BSS_TYPE_STA;
118 t_u8 * payload = NULL;
119 t_u16 payload_len = 0;
120 const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
121
122 NetworkBufferDescriptor_t * pxNetworkBuffer;
123 IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
124
125 payload = ( t_u8 * ) mlan_get_payload( databuf, &payload_len, &interface );
126
127 if( eConsiderFrameForProcessing( payload ) != eProcessBuffer )
128 {
129 net_d( "Dropping packet\r\n" );
130 return WM_SUCCESS;
131 }
132
133 pxNetworkBuffer = pxGetNetworkBufferWithDescriptor( /*payload_len*/ datalen, xDescriptorWaitTime );
134
135 if( pxNetworkBuffer != NULL )
136 {
137 /* Set the packet size, in case a larger buffer was returned. */
138 pxNetworkBuffer->xDataLength = payload_len;
139
140 /* Copy the packet data. */
141 memcpy( pxNetworkBuffer->pucEthernetBuffer, payload, payload_len );
142
143 xRxEvent.pvData = ( void * ) pxNetworkBuffer;
144
145 if( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime ) == pdFAIL )
146 {
147 wmprintf( "Failed to enqueue packet to network stack %p, len %d", payload, payload_len );
148 vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
149 return WM_FAIL;
150 }
151 }
152
153 return WM_SUCCESS;
154 }
155
156 /* Callback function called from the wifi module */
handle_data_packet(const t_u8 interface,const t_u8 * rcvdata,const t_u16 datalen)157 void handle_data_packet( const t_u8 interface,
158 const t_u8 * rcvdata,
159 const t_u16 datalen )
160 {
161 if( interface == BSS_TYPE_STA )
162 {
163 process_data_packet( rcvdata, datalen );
164 }
165 }
166
xNetworkInterfaceInitialise(void)167 BaseType_t xNetworkInterfaceInitialise( void )
168 {
169 uint8_t ret;
170 mac_addr_t mac_addr;
171
172 ret = wifi_get_device_mac_addr( &mac_addr );
173
174 if( ret != WM_SUCCESS )
175 {
176 net_d( "Failed to get mac address" );
177 }
178
179 FreeRTOS_UpdateMACAddress( mac_addr.mac );
180
181 return ( xInterfaceState == INTERFACE_UP && ret == WM_SUCCESS ) ? pdTRUE : pdFALSE;
182 }
183
vNetworkInterfaceAllocateRAMToBuffers(NetworkBufferDescriptor_t pxNetworkBuffers[ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS])184 void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
185 {
186 /* FIX ME. */
187 }
188
xGetPhyLinkStatus(void)189 BaseType_t xGetPhyLinkStatus( void )
190 {
191 /* FIX ME. */
192 return pdFALSE;
193 }
vNetworkNotifyIFDown()194 void vNetworkNotifyIFDown()
195 {
196 IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
197
198 xInterfaceState = INTERFACE_DOWN;
199
200 if( xSendEventStructToIPTask( &xRxEvent, 0 ) != pdPASS )
201 {
202 /* Could not send the message, so it is still pending. */
203 net_e( "Could not send network down event" );
204 }
205 else
206 {
207 /* Message was sent so it is not pending. */
208 net_d( "Sent network down event" );
209 }
210 }
211
vNetworkNotifyIFUp()212 void vNetworkNotifyIFUp()
213 {
214 xInterfaceState = INTERFACE_UP;
215 }
216
xNetworkInterfaceOutput(NetworkBufferDescriptor_t * const pxNetworkBuffer,BaseType_t xReleaseAfterSend)217 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t * const pxNetworkBuffer,
218 BaseType_t xReleaseAfterSend )
219 {
220 uint8_t pkt_len;
221
222 if( ( pxNetworkBuffer == NULL ) ||
223 ( pxNetworkBuffer->pucEthernetBuffer == NULL ) ||
224 ( pxNetworkBuffer->xDataLength == 0 ) )
225 {
226 net_d( "Incorrect params" );
227 return pdFALSE;
228 }
229
230 memset( outbuf, 0x00, sizeof( outbuf ) );
231 pkt_len = 22 + 4; /* sizeof(TxPD) + INTF_HEADER_LEN */
232 memcpy( ( u8_t * ) outbuf + pkt_len, ( u8_t * ) pxNetworkBuffer->pucEthernetBuffer,
233 pxNetworkBuffer->xDataLength );
234 int ret = wifi_low_level_output( BSS_TYPE_STA, outbuf + pkt_len, pxNetworkBuffer->xDataLength );
235
236 if( ret != WM_SUCCESS )
237 {
238 net_e( "Failed output %p, length %d, error %d \r\n", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret );
239 }
240
241 if( xReleaseAfterSend != pdFALSE )
242 {
243 vReleaseNetworkBufferAndDescriptor( pxNetworkBuffer );
244 }
245
246 return ret == WM_SUCCESS ? pdTRUE : pdFALSE;
247 }
248