/* ********************************************************************************************************* * ScratchUnmount() * * Description : Unmounts Scratch from the specified RAW window. * * Argument(s) : rawId -- RAW window ID that scratch had been mounted to. * * Return(s) : None * * Caller(s) : WF Driver * * Notes: : None * ********************************************************************************************************* */ void ScratchUnmount(UINT8 rawId) { RawMove(rawId, RAW_SCRATCH_POOL, FALSE, 0); if (rawId == RAW_RX_ID) { SetRawWindowState(RAW_RX_ID, WF_RAW_UNMOUNTED); } else { SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); } }
/* ********************************************************************************************************* * ScratchUnmount() * * Description : Unmounts Scratch from the specified RAW window. * * Argument(s) : rawId -- RAW window ID that scratch had been mounted to. * * Return(s) : None * * Caller(s) : WF Driver * * Notes: : None * ********************************************************************************************************* */ void ScratchUnmount(uint8_t rawId) { RawMove(rawId, RAW_SCRATCH_POOL, false, 0); if (rawId == RAW_RX_ID) { SetRawWindowState(RAW_RX_ID, WF_RAW_UNMOUNTED); } else { SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); } }
BOOL AllocateMgmtTxBuffer(UINT16 bytesNeeded) { UINT16 bufAvail; UINT16 byteCount; /* get total bytes available for MGMT tx memory pool */ bufAvail = Read16BitWFRegister(WF_HOST_WFIFO_BCNT1_REG) & 0x0fff; /* LS 12 bits contain length */ /* if enough bytes available to allocate */ if ( bufAvail >= bytesNeeded ) { /* allocate and create the new Tx buffer (mgmt or data) */ byteCount = RawMove(RAW_TX_ID, RAW_MGMT_POOL, TRUE, bytesNeeded); WF_ASSERT(byteCount != 0); } /* else not enough bytes available at this time to satisfy request */ else { return FALSE; } RawWindowReady[RAW_TX_ID] = TRUE; SetRawWindowState(RAW_TX_ID, WF_RAW_MGMT_MOUNTED); return TRUE; }
bool AllocateDataTxBuffer(uint16_t bytesNeeded) { uint16_t bufAvail; uint16_t byteCount; /* Ensure the MRF24W is awake (only applies if PS-Poll was enabled) */ EnsureWFisAwake(); /* get total bytes available for DATA tx memory pool */ bufAvail = Read16BitWFRegister(WF_HOST_WFIFO_BCNT0_REG) & 0x0fff; /* LS 12 bits contain length */ /* if enough bytes available to allocate */ if ( bufAvail >= bytesNeeded ) { /* allocate and create the new Tx buffer (mgmt or data) */ byteCount = RawMove(RAW_TX_ID, RAW_DATA_POOL, true, bytesNeeded); SYS_ASSERT(byteCount != 0, ""); } /* else not enough bytes available at this time to satisfy request */ else { return false; } RawWindowReady[RAW_TX_ID] = true; SetRawWindowState(RAW_TX_ID, WF_RAW_DATA_MOUNTED); return true; }
/***************************************************************************** * FUNCTION: WaitForMgmtRespAndReadData * * RETURNS: None * * PARAMS: expectedSubtype -- management message subtype that we are expecting * p_data -- pointer where any desired management data bytes * will be written * numDataBytes -- Number of data bytes from mgmt response to write to * p_data. Data always starts at index 4 of mgmt response. * skipDataRead -- if TRUE, then no data will be read and the mgmt buffer will not * be freed. If FALSE, the data will be read and the mgmt buffer * will be freed. * * NOTES: Waits for the mgmt response message and validates it by: * 1) checking the result field * 2) verifying that the received subtype matches the execpted subtype * * In addition, this function reads the desired number of data bytes from * the mgmt response, copies them to p_data, and then frees the mgmt buffer. *****************************************************************************/ void WaitForMgmtResponseAndReadData(UINT8 expectedSubtype, UINT8 numDataBytes, UINT8 startIndex, UINT8 *p_data) { tMgmtMsgRxHdr hdr; /* management msg header struct */ WaitForMgmtResponse(expectedSubtype, DO_NOT_FREE_MGMT_BUFFER); /* if made it here then received a management message */ RawRead(RAW_RX_ID, 0, (UINT16)(sizeof(tMgmtMsgRxHdr)), (UINT8 *)&hdr); /* check header result and subtype fields */ WF_ASSERT(hdr.result == WF_SUCCESS || hdr.result == WF_ERROR_NO_STORED_BSS_DESCRIPTOR); WF_ASSERT(hdr.subtype == expectedSubtype); /* if caller wants to read data from this mgmt response */ if (numDataBytes > 0) { RawRead(RAW_RX_ID, startIndex, numDataBytes, p_data); } /* free the mgmt buffer */ DeallocateMgmtRxBuffer(); /* if there was a mounted data packet prior to the mgmt tx/rx transaction, then restore it */ if (RestoreRxData == TRUE) { RestoreRxData = FALSE; PopRawWindow(RAW_RX_ID); SetRawWindowState(RAW_RX_ID, WF_RAW_DATA_MOUNTED); } }
/* If a data message mounted in RAW window then will be transmitted to 802.11 network */ void RawSendTxBuffer(UINT16 len) { RawMove(RAW_TX_ID, RAW_MAC, FALSE, len); RawWindowReady[RAW_TX_ID] = FALSE; SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); }
bool AllocateMgmtTxBuffer(uint16_t bytesNeeded) { uint16_t bufAvail; uint16_t byteCount; /* get total bytes available for MGMT tx memory pool */ bufAvail = Read16BitWFRegister(WF_HOST_WFIFO_BCNT1_REG) & 0x0fff; /* LS 12 bits contain length */ /* if enough bytes available to allocate */ if ( bufAvail >= bytesNeeded ) { /* allocate and create the new Tx buffer (mgmt or data) */ byteCount = RawMove(RAW_TX_ID, RAW_MGMT_POOL, true, bytesNeeded); if (byteCount == 0) return false; // just return and let host retry again } /* else not enough bytes available at this time to satisfy request */ else { return false; } RawWindowReady[RAW_TX_ID] = true; SetRawWindowState(RAW_TX_ID, WF_RAW_MGMT_MOUNTED); return true; }
/***************************************************************************** Function: BOOL AllocateDataTxBuffer(UINT16 bytesNeeded) Summary: Allocates a Data Tx buffer for use by the TCP/IP stack. Description: Determines if WiFi chip has enough memory to allocate a tx data buffer, and, if so, allocates it. Precondition: None Parameters: bytesNeeded -- number of bytes needed for the data tx message Returns: True if data tx buffer successfully allocated, else False Remarks: None *****************************************************************************/ BOOL AllocateDataTxBuffer(UINT16 bytesNeeded) { UINT16 bufAvail; UINT16 byteCount; WF_ASSERT(GetRawWindowState(RAW_DATA_TX_ID) != WF_RAW_DATA_MOUNTED); /* Ensure the MRF24W is awake (only applies if PS-Poll was enabled) */ EnsureWFisAwake(); /* get total bytes available for DATA tx memory pool */ bufAvail = Read16BitWFRegister(WF_HOST_WFIFO_BCNT0_REG) & 0x0fff; /* LS 12 bits contain length */ /* if enough bytes available to allocate */ if ( bufAvail >= bytesNeeded ) { /* allocate and create the new Tx buffer (mgmt or data) */ byteCount = RawMove(RAW_DATA_TX_ID, RAW_DATA_POOL, TRUE, bytesNeeded); WF_ASSERT(byteCount != 0); /* flag this raw window as mounted (in use) */ SetRawWindowState(RAW_DATA_TX_ID, WF_RAW_DATA_MOUNTED); return TRUE; } /* else not enough bytes available at this time to satisfy request */ else { return FALSE; } }
/* If a data message mounted in RAW window then will be transmitted to 802.11 network */ void RawSendTxBuffer(uint16_t len) { RawMove(RAW_TX_ID, RAW_MAC, false, len); RawWindowReady[RAW_TX_ID] = false; SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); }
/***************************************************************************** * 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); }
/* mounts the most recent Rx message. Could be a management or data message. */ uint16_t RawMountRxBuffer(void) { uint16_t length; length = RawMove(RAW_RX_ID, RAW_MAC, true, 0); RawWindowReady[RAW_RX_ID] = true; SetRawWindowState(RAW_RX_ID, WF_RAW_DATA_MOUNTED); return length; }
/* mounts the most recent Rx message. Could be a management or data message. */ UINT16 RawMountRxBuffer(void) { UINT16 length; length = RawMove(RAW_RX_ID, RAW_MAC, TRUE, 0); RawWindowReady[RAW_RX_ID] = TRUE; SetRawWindowState(RAW_RX_ID, WF_RAW_DATA_MOUNTED); return length; }
/***************************************************************************** * FUNCTION: WaitForMgmtResponse * * RETURNS: None * * PARAMS: expectedSubtype -- The expected subtype of the mgmt response * freeAction -- FREE_MGMT_BUFFER or DO_NOT_FREE_MGMT_BUFFER * * NOTES: Called after sending a mgmt request. This function waits for a mgmt * response. The caller can optionally request the the management * response be freed immediately (by this function) or not freed. If not * freed the caller is responsible to free the response buffer. *****************************************************************************/ void WaitForMgmtResponse(UINT8 expectedSubtype, UINT8 freeAction) { tMgmtMsgRxHdr hdr; /* Wait until mgmt response is received */ while (gMgmtConfirmMsgReceived == FALSE) { WFProcess(); /* if received a data packet while waiting for mgmt packet */ if (g_HostRAWDataPacketReceived) { /* loop until stack has processed the received data message */ while (g_HostRAWDataPacketReceived) { StackTask(); } /* ensure interrupts enabled */ WF_EintEnable(); } } /* set this back to FALSE so the next mgmt send won't think he has a response before one is received */ gMgmtConfirmMsgReceived = FALSE; /* if the caller wants to delete the response immediately (doesn't need any data from it */ if (freeAction == FREE_MGMT_BUFFER) { /* read and verify result before freeing up buffer to ensure our message send was successful */ RawRead(RAW_RX_ID, 0, (UINT16)(sizeof(tMgmtMsgRxHdr)), (UINT8 *)&hdr); /* Mgmt response 'result' field should always indicate success. If this assert is hit the error codes are located */ /* WFApi.h. Search for WF_SUCCESS for the list of error codes. */ WF_ASSERT(hdr.result == WF_SUCCESS); /* mgmt response subtype had better match subtype we were expecting */ WF_ASSERT(hdr.subtype == expectedSubtype); /* free mgmt buffer */ DeallocateMgmtRxBuffer(); /* if there was a mounted data packet prior to the mgmt tx/rx transaction, then restore it */ if (RestoreRxData == TRUE) { RestoreRxData = FALSE; PopRawWindow(RAW_RX_ID); SetRawWindowState(RAW_RX_ID, WF_RAW_DATA_MOUNTED); } } }
/***************************************************************************** Function: void DeallocateDataRxBuffer(void) Summary: Deallocates a Data Rx buffer Description: Typically called by MACGetHeader(), the assumption being that when the stack is checking for a newly received data message it is finished with the previously received data message. Also called by MACGetHeader() if the SNAP header is invalid and the packet is thrown away. Precondition: None Parameters: None Returns: None Remarks: None *****************************************************************************/ void DeallocateDataRxBuffer(void) { WF_ASSERT(GetRawWindowState(RAW_DATA_RX_ID) == WF_RAW_DATA_MOUNTED); /* perform deallocation of raw rx buffer */ RawMove(RAW_DATA_RX_ID, RAW_DATA_POOL, FALSE, 0); /* set state flag */ SetRawWindowState(RAW_DATA_RX_ID, WF_RAW_UNMOUNTED); /* the current length of the Rx data packet is now 0 (used by MAC) */ SetRxDataPacketLength(0); }
/* ********************************************************************************************************* * ScratchMount() * * Description : Mounts Scratch using the specified RAW window. * * Argument(s) : rawId -- desired RAW window to mount Scratch to. * * Return(s) : None * * Caller(s) : WF Driver * * Notes: : None * ********************************************************************************************************* */ uint16_t ScratchMount(uint8_t rawId) { uint16_t byteCount; byteCount = RawMove(rawId, RAW_SCRATCH_POOL, true, 0); if (byteCount == 0) { /* work-around, somehow the scratch was already mounted to the other raw window */ rawId = !rawId; // WF_ASSERT(byteCount > 0); /* scratch mount should always return value > 0 */ } SetRawWindowState(rawId, WF_SCRATCH_MOUNTED); return byteCount; }
/***************************************************************************** Function: UINT16 RawMountRxBuffer(UINT8 rawId) Summary: Mounts most recent Rx message. Description: This function mounts the most recent Rx message from the WiFi chip, which could be either a management or a data message. Precondition: None Parameters: rawId -- RAW ID specifying which raw window to mount the rx packet in. Returns: length -- number of bytes in the received message. Remarks: None *****************************************************************************/ UINT16 RawMountRxBuffer(UINT8 rawId) { UINT16 length; length = RawMove(rawId, RAW_MAC, TRUE, 0); WF_ASSERT(length > 0); /* if mounting a Raw Rx data frame */ if (rawId == RAW_DATA_RX_ID) { /* notify WiFi driver that an Rx data frame is mounted */ SetRawWindowState(RAW_DATA_RX_ID, WF_RAW_DATA_MOUNTED); } return length; }
/***************************************************************************** Function: void SendRAWDataFrame(UINT16 bufLen) Summary: Sends a data frame to the WiFi chip for transmission to the 802.11 network. Description: After the TCP/IP stack has created a data frame and called MACFlush() this function is called to notify the WiFi chip to transmit the data frame to the 802.11 network. The actual data frame starts at index 4 in the allocated buffer. The first 4 bytes (indexes 0 - 3) were reserved, and this function fills them in with an internal preamble which notifies the WiFi chip that this is a data frame to send (as opposed to a management frame). Precondition: None Parameters: bufLen -- number of data bytes that comprise the data frame. Returns: None Remarks: None *****************************************************************************/ void SendRAWDataFrame(UINT16 bufLen) { /* create internal preamble */ UINT8 txDataPreamble[4] = { WF_DATA_REQUEST_TYPE, WF_STD_DATA_MSG_SUBTYPE, 1, 0}; /* write out internal preamble, starting at index 0 in the raw window */ RawWrite(RAW_DATA_TX_ID, 0, sizeof(txDataPreamble), txDataPreamble); /* Notify WiFi device that there is a transmit frame to send . The frame will */ /* be automatically deallocated after RF transmission is completed. */ RawMove(RAW_DATA_TX_ID, RAW_MAC, FALSE, bufLen); /* this raw window is logically no longer mounted. The WiFi chip will */ /* automatically deallocate after RF transmission. */ SetRawWindowState(RAW_DATA_TX_ID, WF_RAW_UNMOUNTED); }
/* ********************************************************************************************************* * ScratchUnmount() * * Description : Unmounts Scratch from the specified RAW window. * * Argument(s) : rawId -- RAW window ID that scratch had been mounted to. * * Return(s) : None * * Caller(s) : WF Driver * * Notes: : None * ********************************************************************************************************* */ void ScratchUnmount(uint8_t rawId) { RawMove(rawId, RAW_SCRATCH_POOL, false, 0); SetRawWindowState(rawId, WF_RAW_UNMOUNTED); // if (rawId == RAW_RX_ID) // { // SetRawWindowState(RAW_RX_ID, WF_RAW_UNMOUNTED); // } // else // { // SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); // } }
/* transmits raw Tx data frame to 802.11 network */ void RawSendTxBuffer(UINT16 len) { RawMove(RAW_DATA_TX_ID, RAW_MAC, FALSE, len); SetRawWindowState(RAW_DATA_TX_ID, WF_RAW_UNMOUNTED); }
void DeallocateDataTxBuffer(void) { RawMove(RAW_DATA_TX_ID, RAW_DATA_POOL, FALSE, 0); SetRawWindowState(RAW_DATA_TX_ID, WF_RAW_UNMOUNTED); }
/***************************************************************************** * FUNCTION: WaitForMgmtResponse * * RETURNS: None * * PARAMS: expectedSubtype -- The expected subtype of the mgmt response * freeAction -- FREE_MGMT_BUFFER or DO_NOT_FREE_MGMT_BUFFER * * NOTES: Called after sending a mgmt request. This function waits for a mgmt * response. The caller can optionally request the the management * response be freed immediately (by this function) or not freed. If not * freed the caller is responsible to free the response buffer. *****************************************************************************/ void WaitForMgmtResponse(UINT8 expectedSubtype, UINT8 freeAction) { #if defined(__18CXX) static tMgmtMsgRxHdr hdr; #else tMgmtMsgRxHdr hdr; #endif g_WaitingForMgmtResponse = TRUE; /* Wait until mgmt response is received */ while (gMgmtConfirmMsgReceived == FALSE) { WFProcess(); /* if received a data packet while waiting for mgmt packet */ if (g_HostRAWDataPacketReceived) { // We can't let the StackTask processs data messages that come in while waiting for mgmt // response because the application might send another mgmt message, which is illegal until the response // is received for the first mgmt msg. And, we can't prevent the race condition where a data message // comes in before a mgmt response is received. Thus, the only solution is to throw away a data message // that comes in while waiting for a mgmt response. This should happen very infrequently. If using TCP then the // stack takes care of retries. If using UDP, the application has to deal with occasional data messages not being // received. Also, applications typically do not send a lot of management messages after connected. // throw away the data rx RawMountRxBuffer(); DeallocateDataRxBuffer(); g_HostRAWDataPacketReceived = FALSE; /* ensure interrupts enabled */ WF_EintEnable(); } } /* set this back to FALSE so the next mgmt send won't think he has a response before one is received */ gMgmtConfirmMsgReceived = FALSE; /* if the caller wants to delete the response immediately (doesn't need any data from it */ if (freeAction == FREE_MGMT_BUFFER) { /* read and verify result before freeing up buffer to ensure our message send was successful */ RawRead(RAW_RX_ID, 0, (UINT16)(sizeof(tMgmtMsgRxHdr)), (UINT8 *)&hdr); /* mgmt response subtype had better match subtype we were expecting */ WF_ASSERT(hdr.subtype == expectedSubtype); if (hdr.result == WF_ERROR_DISCONNECT_FAILED || hdr.result == WF_ERROR_NOT_CONNECTED) { #if defined(STACK_USE_UART) putrsUART("Disconnect failed. Disconnect is allowed only when module is in connected state\r\n"); #endif } else if (hdr.result == WF_ERROR_NO_STORED_BSS_DESCRIPTOR) { #if defined(STACK_USE_UART) putrsUART("No stored scan results\r\n"); #endif } else { WF_ASSERT(hdr.result == WF_SUCCESS); } /* free mgmt buffer */ DeallocateMgmtRxBuffer(); /* if there was a mounted data packet prior to the mgmt tx/rx transaction, then restore it */ if (RestoreRxData == TRUE) { RestoreRxData = FALSE; PopRawWindow(RAW_RX_ID); SetRawWindowState(RAW_RX_ID, WF_RAW_DATA_MOUNTED); } } }
void DeallocateDataTxBuffer(void) { RawMove(RAW_TX_ID, RAW_DATA_POOL, false, 0); RawWindowReady[RAW_TX_ID] = false; SetRawWindowState(RAW_TX_ID, WF_RAW_UNMOUNTED); }