xref: /FreeRTOS-Plus-TCP-v4.0.0/source/portable/NetworkInterface/mw300_rd/NetworkInterface.c (revision 1ab6eb88857cf1011bf1f8349b43a1c34c7ced0f)
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 /* 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