3 Copyright (C) 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
\r
5 Permission is hereby granted, free of charge, to any person obtaining a copy of
\r
6 this software and associated documentation files (the "Software"), to deal in
\r
7 the Software without restriction, including without limitation the rights to
\r
8 use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
\r
9 the Software, and to permit persons to whom the Software is furnished to do so,
\r
10 subject to the following conditions:
\r
12 The above copyright notice and this permission notice shall be included in all
\r
13 copies or substantial portions of the Software.
\r
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
\r
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
\r
17 FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
\r
18 COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
\r
19 IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\r
22 http://aws.amazon.com/freertos
\r
23 http://www.FreeRTOS.org
\r
26 /* FreeRTOS includes. */
\r
27 #include "FreeRTOS.h"
\r
30 /* FreeRTOS+TCP includes. */
\r
31 #include "FreeRTOS_IP.h"
\r
32 /* FreeRTOS+TCP includes. */
\r
33 #include "FreeRTOS_IP.h"
\r
34 #include "FreeRTOS_Sockets.h"
\r
35 #include "FreeRTOS_IP_Private.h"
\r
36 #include "FreeRTOS_DNS.h"
\r
37 #include "NetworkBufferManagement.h"
\r
38 #include "NetworkInterface.h"
\r
40 #include "wifi-decl.h"
\r
41 #include "wmerrno.h"
\r
46 #define net_e(...) \
\r
47 wmlog_e("freertos_tcp", ##__VA_ARGS__)
\r
48 #define net_w(...) \
\r
49 wmlog_w("freertos_tcp", ##__VA_ARGS__)
\r
50 #define net_d(...) \
\r
51 wmlog("freertos_tcp", ##__VA_ARGS__)
\r
53 #if 0 //this is lwip structure.
\r
54 #define MAX_INTERFACES_SUPPORTED 3
\r
55 static struct netif *netif_arr[MAX_INTERFACES_SUPPORTED];
\r
58 /* If ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES is set to 1, then the Ethernet
\r
59 driver will filter incoming packets and only pass the stack those packets it
\r
60 considers need processing. */
\r
61 #if( ipconfigETHERNET_DRIVER_FILTERS_FRAME_TYPES == 0 )
\r
62 #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eProcessBuffer
\r
64 #define ipCONSIDER_FRAME_FOR_PROCESSING( pucEthernetBuffer ) eConsiderFrameForProcessing( ( pucEthernetBuffer ) )
\r
67 #define IP_ADDR_ANY ((ip_addr_t *)&ip_addr_any)
\r
68 #define IP_ADDR_BROADCAST ((ip_addr_t *)&ip_addr_broadcast)
\r
70 /** 255.255.255.255 */
\r
71 #define IPADDR_NONE ((u32_t)0xffffffffUL)
\r
73 #define IPADDR_LOOPBACK ((u32_t)0x7f000001UL)
\r
75 #define IPADDR_ANY ((u32_t)0x00000000UL)
\r
76 /** 255.255.255.255 */
\r
77 #define IPADDR_BROADCAST ((u32_t)0xffffffffUL)
\r
79 /** 255.255.255.255 */
\r
80 #define INADDR_NONE IPADDR_NONE
\r
82 #define INADDR_LOOPBACK IPADDR_LOOPBACK
\r
84 #define INADDR_ANY IPADDR_ANY
\r
85 /** 255.255.255.255 */
\r
86 #define INADDR_BROADCAST IPADDR_BROADCAST
\r
96 #define MLAN_BSS_TYPE_STA 0
\r
98 extern uint8_t outbuf[2048];
\r
99 extern bool mlan_is_amsdu(const t_u8 *rcvdata);
\r
100 extern t_u8 *mlan_get_payload(const t_u8 *rcvdata, t_u16 *payload_len, int *interface);
\r
101 extern int wrapper_wlan_handle_amsdu_rx_packet(const t_u8 *rcvdata, const t_u16 datalen);
\r
102 extern int wrapper_wlan_handle_rx_packet(const t_u16 datalen, const t_u8 *rcvdata, NetworkBufferDescriptor_t *pxNetworkBuffer);
\r
103 static volatile uint32_t xInterfaceState = INTERFACE_DOWN;
\r
105 static int process_data_packet(const t_u8 *databuf, const t_u16 datalen)
\r
107 int interface = BSS_TYPE_STA;
\r
108 t_u8 *payload = NULL;
\r
109 t_u16 payload_len = 0;
\r
110 const TickType_t xDescriptorWaitTime = pdMS_TO_TICKS( 250 );
\r
112 NetworkBufferDescriptor_t *pxNetworkBuffer;
\r
113 IPStackEvent_t xRxEvent = { eNetworkRxEvent, NULL };
\r
115 payload = (t_u8 *)mlan_get_payload(databuf, &payload_len, &interface);
\r
117 if( eConsiderFrameForProcessing( payload ) != eProcessBuffer ) {
\r
118 net_d("Dropping packet\r\n");
\r
122 pxNetworkBuffer = pxGetNetworkBufferWithDescriptor(/*payload_len*/datalen, xDescriptorWaitTime);
\r
124 if (pxNetworkBuffer != NULL) {
\r
125 /* Set the packet size, in case a larger buffer was returned. */
\r
126 pxNetworkBuffer->xDataLength = payload_len;
\r
128 /* Copy the packet data. */
\r
129 memcpy(pxNetworkBuffer->pucEthernetBuffer, payload, payload_len);
\r
131 xRxEvent.pvData = (void *) pxNetworkBuffer;
\r
132 if ( xSendEventStructToIPTask( &xRxEvent, xDescriptorWaitTime) == pdFAIL ) {
\r
133 wmprintf("Failed to enqueue packet to network stack %p, len %d", payload, payload_len);
\r
134 vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
\r
141 /* Callback function called from the wifi module */
\r
142 void handle_data_packet(const t_u8 interface, const t_u8 *rcvdata,
\r
143 const t_u16 datalen)
\r
145 if (interface == BSS_TYPE_STA)
\r
146 process_data_packet(rcvdata, datalen);
\r
149 BaseType_t xNetworkInterfaceInitialise( void )
\r
152 mac_addr_t mac_addr;
\r
154 ret = wifi_get_device_mac_addr(&mac_addr);
\r
155 if (ret != WM_SUCCESS) {
\r
156 net_d("Failed to get mac address");
\r
159 FreeRTOS_UpdateMACAddress(mac_addr.mac);
\r
161 return ( xInterfaceState == INTERFACE_UP && ret == WM_SUCCESS ) ? pdTRUE : pdFALSE;
\r
164 void vNetworkInterfaceAllocateRAMToBuffers( NetworkBufferDescriptor_t pxNetworkBuffers[ ipconfigNUM_NETWORK_BUFFER_DESCRIPTORS ] )
\r
169 BaseType_t xGetPhyLinkStatus( void )
\r
174 void vNetworkNotifyIFDown()
\r
176 IPStackEvent_t xRxEvent = { eNetworkDownEvent, NULL };
\r
177 xInterfaceState = INTERFACE_DOWN;
\r
178 if( xSendEventStructToIPTask( &xRxEvent, 0 ) != pdPASS ) {
\r
179 /* Could not send the message, so it is still pending. */
\r
180 net_e("Could not send network down event");
\r
183 /* Message was sent so it is not pending. */
\r
184 net_d("Sent network down event");
\r
188 void vNetworkNotifyIFUp()
\r
190 xInterfaceState = INTERFACE_UP;
\r
193 BaseType_t xNetworkInterfaceOutput( NetworkBufferDescriptor_t *const pxNetworkBuffer, BaseType_t xReleaseAfterSend )
\r
197 if (pxNetworkBuffer == NULL ||
\r
198 pxNetworkBuffer->pucEthernetBuffer == NULL ||
\r
199 pxNetworkBuffer->xDataLength == 0) {
\r
200 net_d("Incorrect params");
\r
203 memset(outbuf, 0x00, sizeof(outbuf));
\r
204 pkt_len = 22 + 4; /* sizeof(TxPD) + INTF_HEADER_LEN */
\r
205 memcpy((u8_t *) outbuf + pkt_len, (u8_t *) pxNetworkBuffer->pucEthernetBuffer,
\r
206 pxNetworkBuffer->xDataLength);
\r
207 int ret = wifi_low_level_output(BSS_TYPE_STA, outbuf + pkt_len, pxNetworkBuffer->xDataLength);
\r
208 if (ret != WM_SUCCESS) {
\r
209 net_e("Failed output %p, length %d, error %d \r\n", pxNetworkBuffer->pucEthernetBuffer, pxNetworkBuffer->xDataLength, ret);
\r
212 if (xReleaseAfterSend != pdFALSE) {
\r
213 vReleaseNetworkBufferAndDescriptor(pxNetworkBuffer);
\r
216 return ret == WM_SUCCESS ? pdTRUE : pdFALSE;
\r