/******************************************************************************* Function: void WaitForMgmtResponseAndReadData(UINT8 expectedSubtype, UINT8 numDataBytes, UINT8 startIndex, UINT8 *p_data) Summary: Waits for a management response and read data. Description: Waits for the mgmt response message and validates it by: 1) checking the result field 2) verifying that the received subtype matches the expected 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. Precondition: MACInit must be called. Parameters: 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. Returns: None Remarks: *****************************************************************************/ 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_MGMT_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_MGMT_RX_ID, startIndex, numDataBytes, p_data); } /* free the mgmt buffer */ DeallocateMgmtRxBuffer(); }
/***************************************************************************** * 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); } }
/******************************************************************************* Function: void WF_CPGetSsid(UINT8 CpId, UINT8 *p_ssid, UINT8 *p_ssidLength) Summary: Gets the SSID for the specified Connection Profile ID. Description: Gets the SSID and SSID Length elements in the Connection Profile. Precondition: MACInit must be called first. Parameters: CpId - Connection Profile ID p_ssid - Pointer to the SSID string ssidLength - Pumber of bytes in the SSID Returns: None. Remarks: None. *****************************************************************************/ void WF_CPGetSsid(UINT8 CpId, UINT8 *p_ssid, UINT8 *p_ssidLength) { tCPElementResponseHdr mgmtHdr; /* Request SSID, but don't have this function read data or free response buffer. */ LowLevel_CPGetElement(CpId, /* Connection Profile ID */ WF_CP_ELEMENT_SSID, /* Element ID */ NULL, /* ptr to element data (not used here */ 0, /* num data bytes to read (not used here */ FALSE); /* no read, leave response mounted */ /* At this point, management response is mounted and ready to be read. */ /* Set raw index to 0, read normal 4 byte header plus the next 3 bytes, these will be: */ /* profile id [4] */ /* element id [5] */ /* element data length [6] */ RawRead(RAW_MGMT_RX_ID, 0, sizeof(tCPElementResponseHdr), (UINT8 *)&mgmtHdr); /* extract SSID length and write to caller */ *p_ssidLength = mgmtHdr.elementDataLength; /* copy SSID name to callers buffer */ RawRead(RAW_MGMT_RX_ID, sizeof(tCPElementResponseHdr), *p_ssidLength, p_ssid); /* free management buffer */ DeallocateMgmtRxBuffer(); }
/******************************************************************************* Function: void WF_CPGetSecurity(UINT8 CpId, UINT8 securityType, UINT8 wepKeyIndex, UINT8 *p_securityKey, UINT8 securityKeyLength) Summary: Gets the security for the specified Connection Profile. Description: Configures security for a Connection Profile. <table> Security Key Length -------- --- ------ WF_SECURITY_OPEN N/A N/A WF_SECURITY_WEP_40 hex 4, 5 byte keys WF_SECURITY_WEP_104 hex 4, 13 byte keys WF_SECURITY_WPA_WITH_KEY hex 32 bytes WF_SECURITY_WPA_WITH_PASS_PHRASE ascii 8-63 ascii characters WF_SECURITY_WPA2_WITH_KEY hex 32 bytes WF_SECURITY_WPA2_WITH_PASS_PHRASE ascii 8-63 ascii characters WF_SECURITY_WPA_AUTO_WITH_KEY hex 32 bytes WF_SECURITY_WPA_AUTO_WITH_PASS_PHRASE ascii 8-63 ascii characters </table> Precondition: MACInit must be called first. Parameters: CpId - Connection Profile ID securityType - Value corresponding to the security type desired. wepKeyIndex - 0 thru 3 (only used if security type is WF_SECURITY_WEP_40 or WF_SECURITY_WEP_104) p_securityKey - Binary key or passphrase (not used if security is WF_SECURITY_OPEN) securityKeyLength - Number of bytes in p_securityKey (not used if security is WF_SECURITY_OPEN) Returns: None. Remarks: None. *****************************************************************************/ void WF_CPGetSecurity(UINT8 CpId, UINT8 *p_securityType, UINT8 *p_wepKeyIndex, UINT8 *p_securityKey, UINT8 *p_securityKeyLength) { tCPElementResponseHdr mgmtHdr; UINT8 keyLength; /* send request, wait for mgmt response, do not read and do not free up response buffer */ LowLevel_CPGetElement(CpId, WF_CP_ELEMENT_SECURITY, /* Element ID */ NULL, /* do not read */ 0, /* do not read */ FALSE); /* do not read, do not free mgmt buffer */ /* at this point, management response is mounted and ready to be read */ /* At this point, management response is mounted and ready to be read. */ /* Set raw index to 0, read normal 4 byte header plus the next 3 bytes, these will be: */ /* profile id [4] */ /* element id [5] */ /* element data length [6] */ RawRead(RAW_MGMT_RX_ID, 0, sizeof(tCPElementResponseHdr), (UINT8 *)&mgmtHdr); RawRead(RAW_MGMT_RX_ID, /* raw Id */ sizeof(tCPElementResponseHdr) + 0, /* index of security type [7] */ 1, /* read one byte */ p_securityType); /* copy that byte here */ RawRead(RAW_MGMT_RX_ID, /* raw Id */ sizeof(tCPElementResponseHdr) + 1 , /* index of WEP key index [8] */ 1, /* read one byte */ p_wepKeyIndex); /* copy that byte here */ /* determine security key length and read if it is present */ keyLength = mgmtHdr.elementDataLength - 2; if (keyLength > 0) { *p_securityKeyLength = keyLength; RawRead(RAW_MGMT_RX_ID, /* raw Id */ sizeof(tCPElementResponseHdr) + 2, /* index of first key byte */ keyLength, /* number of bytes to read */ p_securityKey); /* copy bytes here */ } /* no security key, so set key length param to 0 */ else { *p_securityKeyLength = 0; } /* free management buffer */ DeallocateMgmtRxBuffer(); }
/***************************************************************************** * 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 WaitForMgmtResponse(UINT8 expectedSubtype, UINT8 freeAction) Summary: Waits for a management response Description: 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. Precondition: MACInit must be called. Parameters: expectedSubtype -- Expected subtype of the mgmt response freeAction -- FREE_MGMT_BUFFER or DO_NOT_FREE_MGMT_BUFFER Returns: None Remarks: *****************************************************************************/ 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(RAW_DATA_RX_ID); DeallocateDataRxBuffer(); g_HostRAWDataPacketReceived = FALSE; /* ensure interrupts enabled */ WF_EintEnable(); } } g_WaitingForMgmtResponse = FALSE; /* 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_MGMT_RX_ID, 0, (UINT16)(sizeof(tMgmtMsgRxHdr)), (UINT8 *)&hdr); /* mgmt response subtype had better match subtype we were expecting */ WF_ASSERT(hdr.subtype == expectedSubtype); /* 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. */ if (hdr.result == WF_ERROR_HOST_SCAN_NOT_ALLOWED) { #if defined(STACK_USE_UART) putrsUART("Host Scan Failed. Host scan is allowed only in idle or connected state\r\n"); #endif } else if (hdr.result == WF_ERROR_INVALID_WPS_PIN) { #if defined(STACK_USE_UART) putrsUART("WPS failed : Invalid WPS PIN data\r\n"); #endif } else if (hdr.result == WF_ERROR_DISCONNECT_FAILED) { #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 if (hdr.result != WF_SUCCESS) { #if defined(STACK_USE_UART) UINT8 buf[8]; putrsUART("WaitForMgmtResponse result error: "); sprintf((char *)buf, "%d",hdr.result); putrsUART((char *)buf); putrsUART("\r\n"); #endif //WF_ASSERT(FALSE); } /* free mgmt buffer */ DeallocateMgmtRxBuffer(); } }
/***************************************************************************** * 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); } } }
/***************************************************************************** * FUNCTION: WFProcessMgmtIndicateMsg * * RETURNS: error code * * PARAMS: None * * NOTES: Processes a management indicate message *****************************************************************************/ void WFProcessMgmtIndicateMsg() { tMgmtIndicateHdr hdr; UINT8 buf[6]; UINT8 event = 0xff; UINT16 eventInfo; tMgmtIndicatePassphraseReady passphraseReady; /* read 2-byte header of management message */ RawRead(RAW_MGMT_RX_ID, 0, sizeof(tMgmtIndicateHdr), (UINT8 *)&hdr); /* Determine which event occurred and handle it */ switch (hdr.subType) { /*-----------------------------------------------------------------*/ case WF_EVENT_CONNECTION_ATTEMPT_STATUS_SUBTYPE: /*-----------------------------------------------------------------*/ #if defined(MRF24WG) /* There is one data byte with this message */ RawRead(RAW_MGMT_RX_ID, sizeof(tMgmtIndicateHdr),2, buf); /* read first 2 bytes after header */ /* if connection attempt successful */ if (buf[0] == CONNECTION_ATTEMPT_SUCCESSFUL) { event = WF_EVENT_CONNECTION_SUCCESSFUL; eventInfo = WF_NO_ADDITIONAL_INFO; SignalWiFiConnectionChanged(TRUE); #if defined (STACK_USE_DHCP_CLIENT) RenewDhcp(); #endif SetLogicalConnectionState(TRUE); } /* else connection attempt failed */ else { event = WF_EVENT_CONNECTION_FAILED; eventInfo = (UINT16)(buf[0] << 8 | buf[1]); /* contains connection failure code */ SetLogicalConnectionState(FALSE); } #else /* !defined(MRF24WG) */ /* There is one data byte with this message */ RawRead(RAW_MGMT_RX_ID, sizeof(tMgmtIndicateHdr), 1, buf); /* read first byte after header */ /* if connection attempt successful */ if (buf[0] == CONNECTION_ATTEMPT_SUCCESSFUL) { event = WF_EVENT_CONNECTION_SUCCESSFUL; eventInfo = WF_NO_ADDITIONAL_INFO; SignalWiFiConnectionChanged(TRUE); #if defined (STACK_USE_DHCP_CLIENT) RenewDhcp(); #endif SetLogicalConnectionState(TRUE); } /* else connection attempt failed */ else { event = WF_EVENT_CONNECTION_FAILED; eventInfo = (UINT16)buf[0]; /* contains connection failure code */ SetLogicalConnectionState(FALSE); } #endif /* defined(MRF24WG) */ break; /*-----------------------------------------------------------------*/ case WF_EVENT_CONNECTION_LOST_SUBTYPE: /*-----------------------------------------------------------------*/ /* read index 2 and 3 from message and store in buf[0] and buf[1] buf[0] -- 1: Connection temporarily lost 2: Connection permanently lost 3: Connection Reestablished buf[1] -- 0: Beacon Timeout 1: Deauth from AP */ RawRead(RAW_MGMT_RX_ID, sizeof(tMgmtIndicateHdr), 2, buf); if (buf[0] == CONNECTION_TEMPORARILY_LOST) { event = WF_EVENT_CONNECTION_TEMPORARILY_LOST; eventInfo = (UINT16)buf[1]; /* lost due to beacon timeout or deauth */ SignalWiFiConnectionChanged(FALSE); } else if (buf[0] == CONNECTION_PERMANENTLY_LOST) { event = WF_EVENT_CONNECTION_PERMANENTLY_LOST; eventInfo = (UINT16)buf[1]; /* lost due to beacon timeout or deauth */ SetLogicalConnectionState(FALSE); SignalWiFiConnectionChanged(FALSE); } else if (buf[0] == CONNECTION_REESTABLISHED) { event = WF_EVENT_CONNECTION_REESTABLISHED; eventInfo = (UINT16)buf[1]; /* originally lost due to beacon timeout or deauth */ #if defined(STACK_USE_DHCP_CLIENT) RenewDhcp(); #endif SignalWiFiConnectionChanged(TRUE); SetLogicalConnectionState(TRUE); } else { /* invalid parameter in message */ WF_ASSERT(FALSE); } break; /*-----------------------------------------------------------------*/ case WF_EVENT_SCAN_RESULTS_READY_SUBTYPE: /*-----------------------------------------------------------------*/ /* read index 2 of mgmt indicate to get the number of scan results */ RawRead(RAW_MGMT_RX_ID, sizeof(tMgmtIndicateHdr), 1, buf); event = WF_EVENT_SCAN_RESULTS_READY; eventInfo = (UINT16)buf[0]; /* number of scan results */ break; /*-----------------------------------------------------------------*/ case WF_EVENT_SCAN_IE_RESULTS_READY_SUBTYPE: /*-----------------------------------------------------------------*/ event = WF_EVENT_IE_RESULTS_READY; /* read indexes 2 and 3 containing the 16-bit value of IE bytes */ RawRead(RAW_MGMT_RX_ID, sizeof(tMgmtIndicateHdr), 2, (UINT8 *)&eventInfo); eventInfo = WFSTOHS(eventInfo); /* fix endianess of 16-bit value */ break; #if defined(MRF24WG) case WF_EVENT_KEY_CALCULATION_REQUEST_SUBTYPE: event = WF_EVENT_KEY_CALCULATION_REQUEST; RawRead(RAW_MGMT_RX_ID, sizeof(tMgmtIndicateHdr), sizeof(tMgmtIndicatePassphraseReady), (UINT8 *)&passphraseReady); break; #endif /*-----------------------------------------------------------------*/ default: /*-----------------------------------------------------------------*/ WF_ASSERT(FALSE); break; } /* free mgmt buffer */ DeallocateMgmtRxBuffer(); /* if the application wants to be notified of the event */ if (isNotifyApp(event)) { // WF_ProcessEvent(event, eventInfo, (UINT8 *)&passphraseReady); } }