/***************************************************************************** * FUNCTION: SendMgmtMsg * * RETURNS: error code * * PARAMS: p_header -- pointer to mgmt message header data * headerLength -- number of bytes in the header * will be written * p_data -- pointer to mgmt message data * dataLength -- number of byte of data * * NOTES: Sends a management message *****************************************************************************/ void SendMgmtMsg(UINT8 *p_header, UINT8 headerLength, UINT8 *p_data, UINT8 dataLength) { #if defined(__18CXX) static UINT32 startTickCount; static UINT32 maxAllowedTicks; #else UINT32 startTickCount; UINT32 maxAllowedTicks; #endif /* cannot send management messages while in WF_ProcessEvent() */ WF_ASSERT(!isInWFProcessEvent()); EnsureWFisAwake(); /* if a Rx Data packet is mounted that has not yet been processed */ if (GetRawWindowState(RAW_RX_ID) == WF_RAW_DATA_MOUNTED) { /* save it, so after mgmt response received it can be restored */ PushRawWindow(RAW_RX_ID); RestoreRxData = TRUE; } /* mounts a tx mgmt buffer on the MRF24W when data tx is done */ maxAllowedTicks = TICKS_PER_SECOND / 200; /* 5 ms timeout */ startTickCount = (UINT32)TickGet(); while (!WFisTxMgmtReady() ) { MACProcess(); /* DEBUG -- REMOVE AFTER FIGURE OUT WHY TIMING OUT (RARELY HAPPENS) */ if (TickGet() - startTickCount >= maxAllowedTicks) { /* force flags so WFisTxMgmtReady will return TRUE */ SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); RawWindowReady[RAW_TX_ID] = FALSE; } } /* write out management header */ RawSetByte(RAW_TX_ID, p_header, headerLength); /* write out data (if any) */ if (dataLength > 0) { RawSetByte(RAW_TX_ID, p_data, dataLength); } /* send mgmt msg to MRF24W */ SendRAWManagementFrame(headerLength + dataLength); }
/********************************************************************* * Function: void StackTask(void) * * PreCondition: StackInit() is already called. * * Input: None * * Output: Stack FSM is executed. * * Side Effects: None * * Note: This FSM checks for new incoming packets, * and routes it to appropriate stack components. * It also performs timed operations. * * This function must be called periodically to * ensure timely responses. * ********************************************************************/ void StackTask(void) { WORD dataCount; IP_ADDR tempLocalIP; BYTE cFrameType; BYTE cIPFrameType; #if defined( WF_CS_TRIS ) // This task performs low-level MAC processing specific to the MRF24WB0M MACProcess(); #if defined( STACK_USE_EZ_CONFIG ) && !defined(__18CXX) WFEasyConfigMgr(); #endif #if defined(STACK_USE_DHCP_CLIENT) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. if(AppConfig.Flags.bIsDHCPEnabled) { if(g_DhcpRenew == TRUE) { g_DhcpRenew = FALSE; AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val; AppConfig.MyMask.Val = AppConfig.DefaultMask.Val; AppConfig.Flags.bInConfigMode = TRUE; DHCPInit(0); } // DHCP must be called all the time even after IP configuration is // discovered. // DHCP has to account lease expiration time and renew the configuration // time. DHCPTask(); if(DHCPIsBound(0)) AppConfig.Flags.bInConfigMode = FALSE; } #endif // STACK_USE_DHCP_CLIENT #endif #if defined(STACK_USE_DHCP_CLIENT) && !defined(WF_CS_TRIS) // Normally, an application would not include DHCP module // if it is not enabled. But in case some one wants to disable // DHCP module at run-time, remember to not clear our IP // address if link is removed. if(AppConfig.Flags.bIsDHCPEnabled) { static BOOL bLastLinkState = FALSE; BOOL bCurrentLinkState; bCurrentLinkState = MACIsLinked(); if(bCurrentLinkState != bLastLinkState) { bLastLinkState = bCurrentLinkState; if(!bCurrentLinkState) { AppConfig.MyIPAddr.Val = AppConfig.DefaultIPAddr.Val; AppConfig.MyMask.Val = AppConfig.DefaultMask.Val; AppConfig.Flags.bInConfigMode = TRUE; DHCPInit(0); } } // DHCP must be called all the time even after IP configuration is // discovered. // DHCP has to account lease expiration time and renew the configuration // time. DHCPTask(); if(DHCPIsBound(0)) AppConfig.Flags.bInConfigMode = FALSE; } #endif #if defined (STACK_USE_AUTO_IP) AutoIPTasks(); #endif #if defined(STACK_USE_TCP) // Perform all TCP time related tasks (retransmit, send acknowledge, close connection, etc) TCPTick(); #endif #if defined(STACK_USE_UDP) UDPTask(); #endif // Process as many incomming packets as we can while(1) { //if using the random module, generate entropy #if defined(STACK_USE_RANDOM) RandomAdd(remoteNode.MACAddr.v[5]); #endif // We are about to fetch a new packet, make sure that the // UDP module knows that any old RX data it has laying // around will now be gone. #if defined(STACK_USE_UDP) UDPDiscard(); #endif // Fetch a packet (throws old one away, if not thrown away // yet) if(!MACGetHeader(&remoteNode.MACAddr, &cFrameType)) break; // When using a WiFi module, filter out all incoming packets that have // the same source MAC address as our own MAC address. This is to // prevent receiving and passing our own broadcast packets up to other // layers and avoid, for example, having our own gratuitous ARPs get // answered by ourself. #if defined(WF_CS_TRIS) if(memcmp((void*)&remoteNode.MACAddr, (void*)&AppConfig.MyMACAddr, 6) == 0u) continue; #endif // Dispatch the packet to the appropriate handler switch(cFrameType) { case MAC_ARP: ARPProcess(); break; case MAC_IP: if(!IPGetHeader(&tempLocalIP, &remoteNode, &cIPFrameType, &dataCount)) break; #if defined(STACK_USE_ICMP_SERVER) || defined(STACK_USE_ICMP_CLIENT) if(cIPFrameType == IP_PROT_ICMP) { #if defined(STACK_USE_IP_GLEANING) if(AppConfig.Flags.bInConfigMode && AppConfig.Flags.bIsDHCPEnabled) { // According to "IP Gleaning" procedure, // when we receive an ICMP packet with a valid // IP address while we are still in configuration // mode, accept that address as ours and conclude // configuration mode. if(tempLocalIP.Val != 0xffffffff) { AppConfig.Flags.bInConfigMode = FALSE; AppConfig.MyIPAddr = tempLocalIP; } } #endif // Process this ICMP packet if it the destination IP address matches our address or one of the broadcast IP addressees if( (tempLocalIP.Val == AppConfig.MyIPAddr.Val) || (tempLocalIP.Val == 0xFFFFFFFF) || #if defined(STACK_USE_ZEROCONF_LINK_LOCAL) || defined(STACK_USE_ZEROCONF_MDNS_SD) (tempLocalIP.Val == 0xFB0000E0) || #endif (tempLocalIP.Val == ((AppConfig.MyIPAddr.Val & AppConfig.MyMask.Val) | ~AppConfig.MyMask.Val))) { ICMPProcess(&remoteNode, dataCount); } break; } #endif #if defined(STACK_USE_TCP) if(cIPFrameType == IP_PROT_TCP) { TCPProcess(&remoteNode, &tempLocalIP, dataCount); break; } #endif #if defined(STACK_USE_UDP) if(cIPFrameType == IP_PROT_UDP) { // Stop processing packets if we came upon a UDP frame with application data in it if(UDPProcess(&remoteNode, &tempLocalIP, dataCount)) return; } #endif break; } } }