long accept(long sd, sockaddr *addr, socklen_t *addrlen) { long ret; unsigned char *ptr, *args; tBsdReturnParams tAcceptReturnArguments; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); // Initiate a HCI command hci_command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); // need specify return parameters!!! memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); *addrlen = ASIC_ADDR_LEN; errno = tAcceptReturnArguments.iStatus; ret = errno; // if succeeded, iStatus = new socket descriptor. otherwise - error number if(M_IS_VALID_SD(ret)) { set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); } else { set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); } return(ret); }
int32_t cc3000_wlan::set_event_mask(uint32_t mask) { int32_t ret; uint8_t *ptr; uint8_t *args; if ((mask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) { _simple_link.set_tx_complete_signal(0); // Since an event is a virtual event - i.e. it is not coming from CC3000 // there is no need to send anything to the device if it was an only event if (mask == HCI_EVNT_WLAN_TX_COMPLETE) { return 0; } mask &= ~HCI_EVNT_WLAN_TX_COMPLETE; mask |= HCI_EVNT_WLAN_UNSOL_BASE; } else { _simple_link.set_tx_complete_signal(1); } ret = EFAIL; ptr = _simple_link.get_transmit_buffer(); args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, mask); // Initiate a HCI command _hci.command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN); // Wait for command complete event _event.simplelink_wait_event(HCI_CMND_EVENT_MASK, &ret); return(ret); }
INT32 wlan_ioctl_del_profile(UINT32 ulIndex) { INT32 ret; UINT8 *ptr; UINT8 *args; ptr = tSLInformation.pucTxCommandBuffer; args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulIndex); ret = EFAIL; // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); return(ret); }
long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, unsigned char *ucResults) { unsigned char *ptr; unsigned char *args; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, ulScanTimeout); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults); return(0); }
BOOLEAN btsnd_hcic_user_passkey_reply (BD_ADDR bd_addr, UINT32 value) { BT_HDR *p; UINT8 *pp; if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_U_PKEY_REPLY)) == NULL) return (FALSE); pp = (UINT8 *)(p + 1); p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_U_PKEY_REPLY; p->offset = 0; UINT16_TO_STREAM (pp, HCI_USER_PASSKEY_REQ_REPLY); UINT8_TO_STREAM (pp, HCIC_PARAM_SIZE_U_PKEY_REPLY); BDADDR_TO_STREAM (pp, bd_addr); UINT32_TO_STREAM (pp, value); btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID, p); return (TRUE); }
INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag) { INT32 ret; UINT8 *ptr; UINT8 *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (UINT8 *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, algoEncryptedFlag); ret = EFAIL; hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret); return(ret); }
/* init io callback */ tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin; tSLInformation.WlanInterruptEnable = sWlanInterruptEnable; tSLInformation.WlanInterruptDisable = sWlanInterruptDisable; tSLInformation.WriteWlanPin = sWriteWlanPin; //init asynchronous events callback tSLInformation.sWlanCB= sWlanCB; // By default TX Complete events are routed to host too tSLInformation.InformHostOnTxComplete = 1; } //***************************************************************************** // //! SpiReceiveHandler //! //! @param pvBuffer - pointer to the received data buffer //! The function triggers Received event/data processing //! //! @param Pointer to the received data //! @return none //! //! @brief The function triggers Received event/data processing. It is //! called from the SPI library to receive the data // //***************************************************************************** void SpiReceiveHandler(void *pvBuffer) { tSLInformation.usEventOrDataReceived = 1; tSLInformation.pucReceivedData = (unsigned char *)pvBuffer; hci_unsolicited_event_handler(); } //***************************************************************************** // //! wlan_start //! //! @param usPatchesAvailableAtHost - flag to indicate if patches available //! from host or from EEPROM. Due to the //! fact the patches are burn to the EEPROM //! using the patch programmer utility, the //! patches will be available from the EEPROM //! and not from the host. //! //! @return none //! //! @brief Start WLAN device. This function asserts the enable pin of //! the device (WLAN_EN), starting the HW initialization process. //! The function blocked until device Initialization is completed. //! Function also configure patches (FW, driver or bootloader) //! and calls appropriate device callbacks. //! //! @Note Prior calling the function wlan_init shall be called. //! @Warning This function must be called after wlan_init and before any //! other wlan API //! @sa wlan_init , wlan_stop //! // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ void c_wlan_start(unsigned short usPatchesAvailableAtHost) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ void wlan_start(unsigned short usPatchesAvailableAtHost) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { unsigned long ulSpiIRQState; tSLInformation.NumberOfSentPackets = 0; tSLInformation.NumberOfReleasedPackets = 0; tSLInformation.usRxEventOpcode = 0; tSLInformation.usNumberOfFreeBuffers = 0; tSLInformation.usSlBufferLength = 0; tSLInformation.usBufferSize = 0; tSLInformation.usRxDataPending = 0; tSLInformation.slTransmitDataError = 0; tSLInformation.usEventOrDataReceived = 0; tSLInformation.pucReceivedData = 0; // Allocate the memory for the RX/TX data transactions tSLInformation.pucTxCommandBuffer = (unsigned char *)wlan_tx_buffer; // init spi SpiOpen(SpiReceiveHandler); // Check the IRQ line ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); // ASIC 1273 chip enable: toggle WLAN EN line tSLInformation.WriteWlanPin( WLAN_ENABLE ); if (ulSpiIRQState) { // wait till the IRQ line goes low while(tSLInformation.ReadWlanInterruptPin() != 0) { } } else { // Wait till the IRQ line goes high and then low. while(tSLInformation.ReadWlanInterruptPin() == 0) { } while(tSLInformation.ReadWlanInterruptPin() != 0) { } } SimpleLink_Init_Start(usPatchesAvailableAtHost); // Read Buffer's size and finish hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); } //***************************************************************************** // //! wlan_stop //! //! @param none //! //! @return none //! //! @brief Stop WLAN device by putting it into reset state. //! //! @sa wlan_start // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ void c_wlan_stop(void) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ void wlan_stop(void) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { // ASIC 1273 chip disable tSLInformation.WriteWlanPin( WLAN_DISABLE ); // Wait till IRQ line goes high... while(tSLInformation.ReadWlanInterruptPin() == 0) { } // Free the used by WLAN Driver memory if (tSLInformation.pucTxCommandBuffer) { tSLInformation.pucTxCommandBuffer = 0; } SpiClose(); } //***************************************************************************** // //! wlan_connect //! //! @param sec_type security options: //! WLAN_SEC_UNSEC, //! WLAN_SEC_WEP (ASCII support only), //! WLAN_SEC_WPA or WLAN_SEC_WPA2 //! @param ssid up to 32 bytes and is ASCII SSID of the AP //! @param ssid_len length of the SSID //! @param bssid 6 bytes specified the AP bssid //! @param key up to 16 bytes specified the AP security key //! @param key_len key length //! //! @return On success, zero is returned. On error, negative is returned. //! Note that even though a zero is returned on success to trigger //! connection operation, it does not mean that CCC3000 is already //! connected. An asynchronous "Connected" event is generated when //! actual association process finishes and CC3000 is connected to //! the AP. If DHCP is set, An asynchronous "DHCP" event is //! generated when DHCP process is finish. //! //! //! @brief Connect to AP //! @warning Please Note that when connection to AP configured with security //! type WEP, please confirm that the key is set as ASCII and not //! as HEX. //! @sa wlan_disconnect // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, unsigned char *bssid, unsigned char *key, long key_len) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, unsigned char *bssid, unsigned char *key, long key_len) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in command buffer args = UINT32_TO_STREAM(args, 0x0000001c); args = UINT32_TO_STREAM(args, ssid_len); args = UINT32_TO_STREAM(args, ulSecType); args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); args = UINT32_TO_STREAM(args, key_len); args = UINT16_TO_STREAM(args, 0); // padding shall be zeroed if(bssid) { ARRAY_TO_STREAM(args, bssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } ARRAY_TO_STREAM(args, ssid, ssid_len); if(key_len && key) { ARRAY_TO_STREAM(args, key, key_len); } // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len + key_len - 1); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); errno = ret; return(ret); } #else #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_connect(char *ssid, long ssid_len) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_connect(char *ssid, long ssid_len) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in command buffer args = UINT32_TO_STREAM(args, 0x0000001c); args = UINT32_TO_STREAM(args, ssid_len); args = UINT32_TO_STREAM(args, 0); args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); args = UINT32_TO_STREAM(args, 0); args = UINT16_TO_STREAM(args, 0); // padding shall be zeroed ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); ARRAY_TO_STREAM(args, ssid, ssid_len); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len - 1); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); errno = ret; return(ret); } #endif //***************************************************************************** // //! wlan_disconnect //! //! @return 0 disconnected done, other CC3000 already disconnected //! //! @brief Disconnect connection from AP. //! //! @sa wlan_connect // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_disconnect(void) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_disconnect(void) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret); errno = ret; return(ret); } //***************************************************************************** // //! wlan_ioctl_set_connection_policy //! //! @param should_connect_to_open_ap enable(1), disable(0) connect to any //! available AP. This parameter corresponds to the configuration of //! item # 3 in the brief description. //! @param should_use_fast_connect enable(1), disable(0). if enabled, tries //! to connect to the last connected AP. This parameter corresponds //! to the configuration of item # 1 in the brief description. //! @param auto_start enable(1), disable(0) auto connect //! after reset and periodically reconnect if needed. This //! configuration configures option 2 in the above description. //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief When auto is enabled, the device tries to connect according //! the following policy: //! 1) If fast connect is enabled and last connection is valid, //! the device will try to connect to it without the scanning //! procedure (fast). The last connection will be marked as //! invalid, due to adding/removing profile. //! 2) If profile exists, the device will try to connect it //! (Up to seven profiles). //! 3) If fast and profiles are not found, and open mode is //! enabled, the device will try to connect to any AP. //! * Note that the policy settings are stored in the CC3000 NVMEM. //! //! @sa wlan_add_profile , wlan_ioctl_del_profile // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, unsigned long ulShouldUseFastConnect, unsigned long ulUseProfiles) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, unsigned long ulShouldUseFastConnect, unsigned long ulUseProfiles) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, should_connect_to_open_ap); args = UINT32_TO_STREAM(args, ulShouldUseFastConnect); args = UINT32_TO_STREAM(args, ulUseProfiles); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret); return(ret); } //***************************************************************************** // //! wlan_add_profile //! //! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 //! @param ucSsid ssid SSID up to 32 bytes //! @param ulSsidLen ssid length //! @param ucBssid bssid 6 bytes //! @param ulPriority ulPriority profile priority. Lowest priority:0. //! Important Note: Smartconfig process (in unencrypted mode) //! stores the profile internally with priority 1, so changing //! priorities when adding new profiles should be done with extra care //! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security //! @param ulGroupCipher_TxKeyIndex key index //! @param ulKeyMgmt KEY management //! @param ucPf_OrKey security key //! @param ulPassPhraseLen security key length for WPA\WPA2 //! //! @return On success, index (1-7) of the stored profile is returned. //! On error, -1 is returned. //! //! @brief When auto start is enabled, the device connects to //! station from the profiles table. Up to 7 profiles are supported. //! If several profiles configured the device choose the highest //! priority profile, within each priority group, device will choose //! profile based on security policy, signal strength, etc //! parameters. All the profiles are stored in CC3000 NVMEM. //! //! @sa wlan_ioctl_del_profile // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { unsigned short arg_len; long ret; unsigned char *ptr; long i = 0; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); args = UINT32_TO_STREAM(args, ulSecType); // Setup arguments in accordance with the security type switch (ulSecType) { //OPEN case WLAN_SEC_UNSEC: { args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; } break; //WEP case WLAN_SEC_WEP: { args = UINT32_TO_STREAM(args, 0x00000020); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); for(i = 0; i < 4; i++) { unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); } arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + ulPairwiseCipher_Or_TxKeyLen * 4; } break; //WPA //WPA2 case WLAN_SEC_WPA: case WLAN_SEC_WPA2: { args = UINT32_TO_STREAM(args, 0x00000028); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); args = UINT32_TO_STREAM(args, ulKeyMgmt); args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); args = UINT32_TO_STREAM(args, ulPassPhraseLen); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; } break; // // An unrecognized security type was detected. Return an error. // default: { return(-1); } } // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); return(ret); } #else #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { return -1; } #endif //***************************************************************************** // //! wlan_ioctl_del_profile //! //! @param index number of profile to delete //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief Delete WLAN profile //! //! @Note In order to delete all stored profile, set index to 255. //! //! @sa wlan_add_profile // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_del_profile(unsigned long ulIndex) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_del_profile(unsigned long ulIndex) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulIndex); ret = EFAIL; // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); return(ret); } //***************************************************************************** // //! wlan_ioctl_get_scan_results //! //! @param[in] scan_timeout parameter not supported //! @param[out] ucResults scan results (_wlan_full_scan_results_args_t) //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief Gets entry from scan result table. //! The scan results are returned one by one, and each entry //! represents a single AP found in the area. The following is a //! format of the scan result: //! - 4 Bytes: number of networks found //! - 4 Bytes: The status of the scan: 0 - aged results, //! 1 - results valid, 2 - no results //! - 42 bytes: Result entry, where the bytes are arranged as follows: //! //! - 1 bit isValid - is result valid or not //! - 7 bits rssi - RSSI value; //! - 2 bits: securityMode - security mode of the AP: //! 0 - Open, 1 - WEP, 2 WPA, 3 WPA2 //! - 6 bits: SSID name length //! - 2 bytes: the time at which the entry has entered into //! scans result table //! - 32 bytes: SSID name //! - 6 bytes: BSSID //! //! @Note scan_timeout, is not supported on this version. //! //! @sa wlan_ioctl_set_scan_params // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, unsigned char *ucResults) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, unsigned char *ucResults) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { unsigned char *ptr; unsigned char *args; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, ulScanTimeout); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults); return(0); } #endif //***************************************************************************** // //! wlan_ioctl_set_scan_params //! //! @param uiEnable - start/stop application scan: //! 1 = start scan with default interval value of 10 min. //! in order to set a different scan interval value apply the value //! in milliseconds. minimum 1 second. 0=stop). Wlan reset //! (wlan_stop() wlan_start()) is needed when changing scan interval //! value. Saved: No //! @param uiMinDwellTime minimum dwell time value to be used for each //! channel, in milliseconds. Saved: yes //! Recommended Value: 100 (Default: 20) //! @param uiMaxDwellTime maximum dwell time value to be used for each //! channel, in milliseconds. Saved: yes //! Recommended Value: 100 (Default: 30) //! @param uiNumOfProbeRequests max probe request between dwell time. //! Saved: yes. Recommended Value: 5 (Default:2) //! @param uiChannelMask bitwise, up to 13 channels (0x1fff). //! Saved: yes. Default: 0x7ff //! @param uiRSSIThreshold RSSI threshold. Saved: yes (Default: -80) //! @param uiSNRThreshold NSR threshold. Saved: yes (Default: 0) //! @param uiDefaultTxPower probe Tx power. Saved: yes (Default: 205) //! @param aiIntervalList pointer to array with 16 entries (16 channels) //! each entry (unsigned long) holds timeout between periodic scan //! (connection scan) - in millisecond. Saved: yes. Default 2000ms. //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief start and stop scan procedure. Set scan parameters. //! //! @Note uiDefaultTxPower, is not supported on this version. //! //! @sa wlan_ioctl_get_scan_results // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime, unsigned long uiMaxDwellTime, unsigned long uiNumOfProbeRequests, unsigned long uiChannelMask, long iRSSIThreshold, unsigned long uiSNRThreshold, unsigned long uiDefaultTxPower, unsigned long *aiIntervalList) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime, unsigned long uiMaxDwellTime, unsigned long uiNumOfProbeRequests, unsigned long uiChannelMask, long iRSSIThreshold, unsigned long uiSNRThreshold, unsigned long uiDefaultTxPower, unsigned long *aiIntervalList) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { unsigned long uiRes; unsigned char *ptr; unsigned char *args; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, 36); args = UINT32_TO_STREAM(args, uiEnable); args = UINT32_TO_STREAM(args, uiMinDwellTime); args = UINT32_TO_STREAM(args, uiMaxDwellTime); args = UINT32_TO_STREAM(args, uiNumOfProbeRequests); args = UINT32_TO_STREAM(args, uiChannelMask); args = UINT32_TO_STREAM(args, iRSSIThreshold); args = UINT32_TO_STREAM(args, uiSNRThreshold); args = UINT32_TO_STREAM(args, uiDefaultTxPower); ARRAY_TO_STREAM(args, aiIntervalList, sizeof(unsigned long) * SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, ptr, WLAN_SET_SCAN_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes); return(uiRes); } #endif //***************************************************************************** // //! wlan_set_event_mask //! //! @param mask mask option: //! HCI_EVNT_WLAN_UNSOL_CONNECT connect event //! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event //! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE smart config done //! HCI_EVNT_WLAN_UNSOL_INIT init done //! HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report //! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report //! HCI_EVNT_WLAN_KEEPALIVE keepalive //! HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission //! Saved: no. //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief Mask event according to bit mask. In case that event is //! masked (1), the device will not send the masked event to host. // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_set_event_mask(unsigned long ulMask) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_set_event_mask(unsigned long ulMask) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) { tSLInformation.InformHostOnTxComplete = 0; // Since an event is a virtual event - i.e. it is not coming from CC3000 // there is no need to send anything to the device if it was an only event if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE) { return 0; } ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE; ulMask |= HCI_EVNT_WLAN_UNSOL_BASE; } else { tSLInformation.InformHostOnTxComplete = 1; } ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulMask); // Initiate a HCI command hci_command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret); return(ret); } //***************************************************************************** // //! wlan_ioctl_statusget //! //! @param none //! //! @return WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, //! STATUS_CONNECTING or WLAN_STATUS_CONNECTED //! //! @brief get wlan status: disconnected, scanning, connecting or connected // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_statusget(void) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_statusget(void) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET, ptr, 0); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret); return(ret); } #endif //***************************************************************************** // //! wlan_smart_config_start //! //! @param algoEncryptedFlag indicates whether the information is encrypted //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief Start to acquire device profile. The device acquire its own //! profile, if profile message is found. The acquired AP information //! is stored in CC3000 EEPROM only in case AES128 encryption is used. //! In case AES128 encryption is not used, a profile is created by //! CC3000 internally. //! //! @Note An asynchronous event - Smart Config Done will be generated as soon //! as the process finishes successfully. //! //! @sa wlan_smart_config_set_prefix , wlan_smart_config_stop // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_smart_config_start(unsigned long algoEncryptedFlag) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_smart_config_start(unsigned long algoEncryptedFlag) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, algoEncryptedFlag); ret = EFAIL; hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret); return(ret); }
/* init io callback */ tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin; tSLInformation.WlanInterruptEnable = sWlanInterruptEnable; tSLInformation.WlanInterruptDisable = sWlanInterruptDisable; tSLInformation.WriteWlanPin = sWriteWlanPin; //init asynchronous events callback tSLInformation.sWlanCB= sWlanCB; // By default TX Complete events are routed to host too tSLInformation.InformHostOnTxComplete = 1; } //***************************************************************************** // //! SpiReceiveHandler //! //! @param pvBuffer - pointer to the received data buffer //! The function triggers Received event/data processing //! //! @param Pointer to the received data //! @return none //! //! @brief The function triggers Received event/data processing. It is //! called from the SPI library to receive the data // //***************************************************************************** void SpiReceiveHandler(void *pvBuffer) { tSLInformation.usEventOrDataReceived = 1; tSLInformation.pucReceivedData = (unsigned char *)pvBuffer; hci_unsolicited_event_handler(); } //***************************************************************************** // //! wlan_start //! //! @param usPatchesAvailableAtHost - flag to indicate if patches available //! from host or from EEPROM. Due to the //! fact the patches are burn to the EEPROM //! using the patch programmer utility, the //! patches will be available from the EEPROM //! and not from the host. //! //! @return none //! //! @brief Start WLAN device. This function asserts the enable pin of //! the device (WLAN_EN), starting the HW initialization process. //! The function blocked until device Initialization is completed. //! Function also configure patches (FW, driver or bootloader) //! and calls appropriate device callbacks. //! //! @Note Prior calling the function wlan_init shall be called. //! @Warning This function must be called after wlan_init and before any //! other wlan API //! @sa wlan_init , wlan_stop //! // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ void c_wlan_start(unsigned short usPatchesAvailableAtHost) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ void wlan_start(unsigned short usPatchesAvailableAtHost) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { unsigned long ulSpiIRQState; tSLInformation.NumberOfSentPackets = 0; tSLInformation.NumberOfReleasedPackets = 0; tSLInformation.usRxEventOpcode = 0; tSLInformation.usNumberOfFreeBuffers = 0; tSLInformation.usSlBufferLength = 0; tSLInformation.usBufferSize = 0; tSLInformation.usRxDataPending = 0; tSLInformation.slTransmitDataError = 0; tSLInformation.usEventOrDataReceived = 0; tSLInformation.pucReceivedData = 0; // Allocate the memory for the RX/TX data transactions tSLInformation.pucTxCommandBuffer = (unsigned char *)wlan_tx_buffer; // init spi SpiOpen(SpiReceiveHandler); // Check the IRQ line ulSpiIRQState = tSLInformation.ReadWlanInterruptPin(); // ASIC 1273 chip enable: toggle WLAN EN line tSLInformation.WriteWlanPin( WLAN_ENABLE ); if (ulSpiIRQState) { // wait till the IRQ line goes low while(tSLInformation.ReadWlanInterruptPin() != 0) { } } else { // Wait till the IRQ line goes high and then low. while(tSLInformation.ReadWlanInterruptPin() == 0) { } while(tSLInformation.ReadWlanInterruptPin() != 0) { } } SimpleLink_Init_Start(usPatchesAvailableAtHost); // Read Buffer's size and finish hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0); SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0); } //***************************************************************************** // //! wlan_stop //! //! @param none //! //! @return none //! //! @brief Stop WLAN device by putting it into reset state. //! //! @sa wlan_start // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ void c_wlan_stop(void) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ void wlan_stop(void) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { // ASIC 1273 chip disable tSLInformation.WriteWlanPin( WLAN_DISABLE ); // Wait till IRQ line goes high... while(tSLInformation.ReadWlanInterruptPin() == 0) { } // Free the used by WLAN Driver memory if (tSLInformation.pucTxCommandBuffer) { tSLInformation.pucTxCommandBuffer = 0; } SpiClose(); } //***************************************************************************** // //! wlan_connect //! //! @param sec_type security options: //! WLAN_SEC_UNSEC, //! WLAN_SEC_WEP (ASCII support only), //! WLAN_SEC_WPA or WLAN_SEC_WPA2 //! @param ssid up to 32 bytes and is ASCII SSID of the AP //! @param ssid_len length of the SSID //! @param bssid 6 bytes specified the AP bssid //! @param key up to 16 bytes specified the AP security key //! @param key_len key length //! //! @return On success, zero is returned. On error, negative is returned. //! Note that even though a zero is returned on success to trigger //! connection operation, it does not mean that CCC3000 is already //! connected. An asynchronous "Connected" event is generated when //! actual association process finishes and CC3000 is connected to //! the AP. If DHCP is set, An asynchronous "DHCP" event is //! generated when DHCP process is finish. //! //! //! @brief Connect to AP //! @warning Please Note that when connection to AP configured with security //! type WEP, please confirm that the key is set as ASCII and not //! as HEX. //! @sa wlan_disconnect // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, unsigned char *bssid, unsigned char *key, long key_len) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, unsigned char *bssid, unsigned char *key, long key_len) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in command buffer args = UINT32_TO_STREAM(args, 0x0000001c); args = UINT32_TO_STREAM(args, ssid_len); args = UINT32_TO_STREAM(args, ulSecType); args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); args = UINT32_TO_STREAM(args, key_len); args = UINT16_TO_STREAM(args, 0); // padding shall be zeroed if(bssid) { ARRAY_TO_STREAM(args, bssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } ARRAY_TO_STREAM(args, ssid, ssid_len); if(key_len && key) { ARRAY_TO_STREAM(args, key, key_len); } // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len + key_len - 1); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); errno = ret; return(ret); } #else #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_connect(char *ssid, long ssid_len) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_connect(char *ssid, long ssid_len) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in command buffer args = UINT32_TO_STREAM(args, 0x0000001c); args = UINT32_TO_STREAM(args, ssid_len); args = UINT32_TO_STREAM(args, 0); args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len); args = UINT32_TO_STREAM(args, 0); args = UINT16_TO_STREAM(args, 0); // padding shall be zeroed ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); ARRAY_TO_STREAM(args, ssid, ssid_len); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len - 1); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret); errno = ret; return(ret); } #endif //***************************************************************************** // //! wlan_disconnect //! //! @return 0 disconnected done, other CC3000 already disconnected //! //! @brief Disconnect connection from AP. //! //! @sa wlan_connect // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_disconnect(void) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_disconnect(void) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret); errno = ret; return(ret); } //***************************************************************************** // //! wlan_ioctl_set_connection_policy //! //! @param should_connect_to_open_ap enable(1), disable(0) connect to any //! available AP. This parameter corresponds to the configuration of //! item # 3 in the brief description. //! @param should_use_fast_connect enable(1), disable(0). if enabled, tries //! to connect to the last connected AP. This parameter corresponds //! to the configuration of item # 1 in the brief description. //! @param auto_start enable(1), disable(0) auto connect //! after reset and periodically reconnect if needed. This //! configuration configures option 2 in the above description. //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief When auto is enabled, the device tries to connect according //! the following policy: //! 1) If fast connect is enabled and last connection is valid, //! the device will try to connect to it without the scanning //! procedure (fast). The last connection will be marked as //! invalid, due to adding/removing profile. //! 2) If profile exists, the device will try to connect it //! (Up to seven profiles). //! 3) If fast and profiles are not found, and open mode is //! enabled, the device will try to connect to any AP. //! * Note that the policy settings are stored in the CC3000 NVMEM. //! //! @sa wlan_add_profile , wlan_ioctl_del_profile // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, unsigned long ulShouldUseFastConnect, unsigned long ulUseProfiles) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, unsigned long ulShouldUseFastConnect, unsigned long ulUseProfiles) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, should_connect_to_open_ap); args = UINT32_TO_STREAM(args, ulShouldUseFastConnect); args = UINT32_TO_STREAM(args, ulUseProfiles); // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret); return(ret); } //***************************************************************************** // //! wlan_add_profile //! //! @param ulSecType WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 //! @param ucSsid ssid SSID up to 32 bytes //! @param ulSsidLen ssid length //! @param ucBssid bssid 6 bytes //! @param ulPriority ulPriority profile priority. Lowest priority:0. //! Important Note: Smartconfig process (in unencrypted mode) //! stores the profile internally with priority 1, so changing //! priorities when adding new profiles should be done with extra care //! @param ulPairwiseCipher_Or_TxKeyLen key length for WEP security //! @param ulGroupCipher_TxKeyIndex key index //! @param ulKeyMgmt KEY management //! @param ucPf_OrKey security key //! @param ulPassPhraseLen security key length for WPA\WPA2 //! //! @return On success, index (1-7) of the stored profile is returned. //! On error, -1 is returned. //! //! @brief When auto start is enabled, the device connects to //! station from the profiles table. Up to 7 profiles are supported. //! If several profiles configured the device choose the highest //! priority profile, within each priority group, device will choose //! profile based on security policy, signal strength, etc //! parameters. All the profiles are stored in CC3000 NVMEM. //! //! @sa wlan_ioctl_del_profile // //***************************************************************************** #ifndef CC3000_TINY_DRIVER #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { unsigned short arg_len; long ret; unsigned char *ptr; long i = 0; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); args = UINT32_TO_STREAM(args, ulSecType); // Setup arguments in accordance with the security type switch (ulSecType) { //OPEN case WLAN_SEC_UNSEC: { args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; } break; //WEP case WLAN_SEC_WEP: { args = UINT32_TO_STREAM(args, 0x00000020); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); for(i = 0; i < 4; i++) { unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); } arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + ulPairwiseCipher_Or_TxKeyLen * 4; } break; //WPA //WPA2 case WLAN_SEC_WPA: case WLAN_SEC_WPA2: { args = UINT32_TO_STREAM(args, 0x00000028); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); args = UINT32_TO_STREAM(args, ulKeyMgmt); args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); args = UINT32_TO_STREAM(args, ulPassPhraseLen); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; } break; // // An unrecognized security type was detected. Return an error. // default: { return(-1); } } // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); return(ret); } #else #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { return -1; } #endif //***************************************************************************** // //! wlan_ioctl_del_profile //! //! @param index number of profile to delete //! //! @return On success, zero is returned. On error, -1 is returned //! //! @brief Delete WLAN profile //! //! @Note In order to delete all stored profile, set index to 255. //! //! @sa wlan_add_profile // //***************************************************************************** #ifdef __ENABLE_MULTITHREADED_SUPPORT__ long c_wlan_ioctl_del_profile(unsigned long ulIndex) #else /* __ENABLE_MULTITHREADED_SUPPORT__ */ long wlan_ioctl_del_profile(unsigned long ulIndex) #endif /* __ENABLE_MULTITHREADED_SUPPORT__ */ { long ret; unsigned char *ptr; unsigned char *args; ptr = tSLInformation.pucTxCommandBuffer; args = (unsigned char *)(ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, ulIndex); ret = EFAIL; // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret); return(ret); }
//***************************************************************************** // //! accept //! //! @param[in] sd socket descriptor (handle) //! @param[out] addr the argument addr is a pointer to a sockaddr structure //! This structure is filled in with the address of the //! peer socket, as known to the communications layer. //! determined. The exact format of the address returned //! addr is by the socket's address sockaddr. //! On this version only AF_INET is supported. //! This argument returns in network order. //! @param[out] addrlen the addrlen argument is a value-result argument: //! it should initially contain the size of the structure //! pointed to by addr. //! //! @return For socket in blocking mode: //! On success, socket handle. on failure negative //! For socket in non-blocking mode: //! - On connection establishment, socket handle //! - On connection pending, SOC_IN_PROGRESS (-2) //! - On failure, SOC_ERROR (-1) //! //! @brief accept a connection on a socket: //! This function is used with connection-based socket types //! (SOCK_STREAM). It extracts the first connection request on the //! queue of pending connections, creates a new connected socket, and //! returns a new file descriptor referring to that socket. //! The newly created socket is not in the listening state. //! The original socket sd is unaffected by this call. //! The argument sd is a socket that has been created with socket(), //! bound to a local address with bind(), and is listening for //! connections after a listen(). The argument addr is a pointer //! to a sockaddr structure. This structure is filled in with the //! address of the peer socket, as known to the communications layer. //! The exact format of the address returned addr is determined by the //! socket's address family. The addrlen argument is a value-result //! argument: it should initially contain the size of the structure //! pointed to by addr, on return it will contain the actual //! length (in bytes) of the address returned. //! //! @sa socket ; bind ; listen // //***************************************************************************** long c_accept(long sd, sockaddr *addr, socklen_t *addrlen) { long ret; uint8_t *args; tBsdReturnParams tAcceptReturnArguments; ret = EFAIL; args = hci_get_cmd_buffer(); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); // Initiate a HCI command hci_command_send(HCI_CMND_ACCEPT, SOCKET_ACCEPT_PARAMS_LEN, HCI_CMND_ACCEPT, &tAcceptReturnArguments); // need specify return parameters!!! memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); *addrlen = ASIC_ADDR_LEN; errno = tAcceptReturnArguments.iStatus; ret = errno; return(ret); }
int select(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, TICC3000fd_set *exceptsds, struct timeval *timeout) { unsigned char *ptr, *args; tBsdSelectRecvParams tParams; unsigned long is_blocking; if( timeout == NULL) { is_blocking = 1; /* blocking , infinity timeout */ } else { is_blocking = 0; /* no blocking, timeout */ } // Fill in HCI packet structure ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, nfds); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, is_blocking); args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); if (timeout) { if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) { timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; } args = UINT32_TO_STREAM(args, timeout->tv_sec); args = UINT32_TO_STREAM(args, timeout->tv_usec); } // Initiate a HCI command hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); // Update actually read FD if (tParams.iStatus >= 0) { if (readsds) { memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); } if (writesds) { memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); } if (exceptsds) { memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); } return(tParams.iStatus); } else { errno = tParams.iStatus; return(-1); } }
//***************************************************************************** // //! simple_link_send //! //! @param sd socket handle //! @param buf write buffer //! @param len buffer length //! @param flags On this version, this parameter is not supported //! @param to pointer to an address structure indicating destination //! address //! @param tolen destination address structure size //! //! @return Return the number of bytes transmitted, or -1 if an error //! occurred, or -2 in case there are no free buffers available //! (only when SEND_NON_BLOCKING is enabled) //! //! @brief This function is used to transmit a message to another //! socket // //***************************************************************************** int simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode) { unsigned char uArgSize, addrlen; unsigned char *ptr, *pDataPtr, *args; unsigned long addr_offset; int res; tBsdReadReturnParams tSocketSendEvent; // Check the bsd_arguments if (0 != (res = HostFlowControlConsumeBuff(sd))) { return res; } //Update the number of sent packets tSLInformation.NumberOfSentPackets++; // Allocate a buffer and construct a packet and send it over spi ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_DATA); // Update the offset of data and parameters according to the command switch(opcode) { case HCI_CMND_SENDTO: { addr_offset = len + sizeof(len) + sizeof(len); addrlen = 8; uArgSize = SOCKET_SENDTO_PARAMS_LEN; pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; break; } case HCI_CMND_SEND: { tolen = 0; to = NULL; uArgSize = HCI_CMND_SEND_ARG_LENGTH; pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; break; } default: { break; } } // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); args = UINT32_TO_STREAM(args, len); args = UINT32_TO_STREAM(args, flags); if (opcode == HCI_CMND_SENDTO) { args = UINT32_TO_STREAM(args, addr_offset); args = UINT32_TO_STREAM(args, addrlen); } // Copy the data received from user into the TX Buffer ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len); // In case we are using SendTo, copy the to parameters if (opcode == HCI_CMND_SENDTO) { ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen); } // Initiate a HCI command hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen); if (opcode == HCI_CMND_SENDTO) SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); else SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); return (len); }
unsigned char * hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) { unsigned char *pucReceivedData, ucArgsize; unsigned short usLength; unsigned char *pucReceivedParams; unsigned short usReceivedEventOpcode = 0; unsigned long retValue32; unsigned char * RecvParams; unsigned char *RetParams; JsSysTime timeout = jshGetSystemTime() + jshGetTimeFromMilliseconds(10000); // blocking for 10 seconds (!!!) cc3000_irq_disable(); while (!jspIsInterrupted()) { if (tSLInformation.usEventOrDataReceived != 0) { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = pRetParams; // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams,0 ,*(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams ,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams ,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; } } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } if (pRetParams) // GW: just in case. It'll probably still crash though :( memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, usLength - ucArgsize); tSLInformation.usRxDataPending = 0; } tSLInformation.usEventOrDataReceived = 0; cc3000_spi_resume(); // Since we are going to TX - we need to handle this event after the // ResumeSPi since we need interrupts if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { cc3000_irq_enable(); return NULL; } } else cc3000_check_irq_pin(); if (jshGetSystemTime() > timeout) { jspSetInterrupted(true); jsError("Timeout in CC3000 driver (%d)", tSLInformation.usRxEventOpcode); break; } } cc3000_irq_enable(); return NULL; }
uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) { uint8_t *received_data, argument_size; uint16_t length; uint8_t *pucReceivedParams; uint16_t received_op_code = 0; uint32_t return_value; uint8_t * RecvParams; uint8_t *RetParams; while (1) { if (_simple_link.get_data_received_flag() != 0) { received_data = _simple_link.get_received_data(); if (*received_data == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code); pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = (uint8_t *)ret_param; // unsolicited event received - finish handling if (hci_unsol_event_handler((uint8_t *)received_data) == 0) { STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length); hci_event_debug_print( received_op_code ); switch(received_op_code) { case HCI_CMND_READ_BUFFER_SIZE: { uint16_t temp = _simple_link.get_number_free_buffers(); STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp); _simple_link.set_number_free_buffers(temp); temp = _simple_link.get_buffer_length(); STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp); _simple_link.set_buffer_length(temp); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 1; STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value); UINT32_TO_STREAM((uint8_t *)ret_param, return_value); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; //This argument returns in network order memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param); if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus); //This argument returns in network order memcpy((uint8_t *)ret_param, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 2; STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 2; memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); break; default : DBG_HCI("UNKNOWN Event Received : 0x%04X ", received_op_code); break; } } if (received_op_code == _simple_link.get_op_code()) { _simple_link.set_op_code(0); } } else { pucReceivedParams = received_data; STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size); STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen); memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size); _simple_link.set_pending_data(0); } _simple_link.set_data_received_flag(0); _spi.wlan_irq_enable(); // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((uint8_t *)received_data); } if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0)) { return NULL; } } } }
uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) { uint8_t *pucReceivedData, ucArgsize; uint16_t usLength; uint8_t *pucReceivedParams; uint16_t usReceivedEventOpcode = 0; unsigned long retValue32; uint8_t * RecvParams; uint8_t *RetParams; while (1) { if (tSLInformation.usEventOrDataReceived != 0) { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { /* Event Received */ STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = (uint8_t *)pRetParams; /* In case unsolicited event received - here the handling finished */ if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams, 0, *(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((uint8_t *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams, GET_HOST_BY_NAME_RETVAL_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, GET_HOST_BY_NAME_ADDR_OFFSET, *(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams, ACCEPT_SD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, ACCEPT_RETURN_STATUS_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; /* This argument returns in network order */ memcpy((uint8_t *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(struct sockaddr)); } break; case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_SD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_NUM_BYTES_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE__FLAGS__OFFSET, *(unsigned long *)pRetParams); if (((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status (((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor, SOCKET_STATUS_INACTIVE); } } break; case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_SD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_NUM_BYTES_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; } break; case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_STATUS_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_READFD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_WRITEFD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_EXFD_OFFSET, *(unsigned long *)pRetParams); } break; case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, ((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); /* This argument returns in network order */ memcpy((uint8_t *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams, GET_SCAN_RESULTS_TABlE_COUNT_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams, GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams, GET_SCAN_RESULTS_FRAME_TIME_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((uint8_t *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: /* Read IP address */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read subnet */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read default GW */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read DHCP server */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read DNS server */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read Mac address */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; /* Read SSID */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); break; default: PANIC(); break; } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; } } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); /* Data received: note that the only case where from and from length * are not null is in recv from, so fill the args accordingly */ if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET), *fromlen); } memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, usLength - ucArgsize); tSLInformation.usRxDataPending = 0; } tSLInformation.usEventOrDataReceived = 0; cc3000_resume(); /* Since we are going to TX - we need to handle this event after the * ResumeSPi since we need interrupts */ if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { break; } } } return NULL; }
unsigned char * hci_event_handler(void *pRetParams, unsigned char *from, long *fromlen) { unsigned char *pucReceivedData, ucArgsize; unsigned short usLength; unsigned char *pucReceivedParams; unsigned short usReceivedEventOpcode = 0; unsigned long retValue32; unsigned char * RecvParams; unsigned char *RetParams; volatile system_tick_t start = GetSystem1MsTick(); while (1) { if (tSLInformation.usEventOrDataReceived == 0) { volatile system_tick_t now = GetSystem1MsTick(); volatile system_tick_t elapsed = now - start; if (elapsed < 0) { // Did we wrap elapsed = start + now; // yes now } if (cc3000__event_timeout_ms && (elapsed >= cc3000__event_timeout_ms)) { ERROR("Timeout now %ld start %ld elapsed %ld cc3000__event_timeout_ms %ld",now,start,elapsed,cc3000__event_timeout_ms); ERROR("Timeout waiting on tSLInformation.usRxEventOpcode 0x%04x",tSLInformation.usRxEventOpcode); // Timeout Return Error for requested Opcode // This sucks because callers should have initialized pucReceivedParams switch(tSLInformation.usRxEventOpcode) { default: INVALID_CASE(tSLInformation.usRxEventOpcode); break; case HCI_CMND_SIMPLE_LINK_START: case HCI_CMND_READ_BUFFER_SIZE: break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: case HCI_EVNT_READ_SP_VERSION: case HCI_EVNT_SELECT: *(unsigned char *)pRetParams = -1; break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: case HCI_EVNT_BSD_GETHOSTBYNAME: *(int32_t *)pRetParams = -1; break; case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: case HCI_EVNT_ACCEPT: case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: case HCI_CMND_GETSOCKOPT: *(int32_t *)pRetParams = -1; pRetParams += sizeof(int32_t ); *(int32_t *)pRetParams = -1; break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: *(int32_t *)pRetParams = 0; break; case HCI_NETAPP_IPCONFIG: memset(pRetParams,0,sizeof(tNetappIpconfigRetArgs)); break; } break; // Exit Loop } } else { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = pRetParams; // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,*(unsigned char *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams, 0, *(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(unsigned char *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; tSLInformation.solicitedResponse = 0; } } else { if (tSLInformation.usRxDataPending == 0) { ERROR("type != HCI_TYPE_EVNT is (%d) usRxDataPending=%d usRxEventOpcode=%u usReceivedEventOpcode=%u", *pucReceivedData, tSLInformation.usRxDataPending, tSLInformation.usRxEventOpcode, usReceivedEventOpcode); } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } // Let's vet length long length = usLength - ucArgsize; if (length <= 0 || length > arraySize(wlan_rx_buffer)) { // Not sane length = -1; } else { memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, length); } // fixes the Nvram read not returning length if (fromlen) { *fromlen = length; } tSLInformation.usRxDataPending = 0; } } tSLInformation.usEventOrDataReceived = 0; SpiResumeSpi(); // Since we are going to TX - we need to handle this event after the // ResumeSPi since we need interrupts if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { break; } } } return NULL; }
long wlan_add_profile(unsigned long ulSecType, unsigned char* ucSsid, unsigned long ulSsidLen, unsigned char *ucBssid, unsigned long ulPriority, unsigned long ulPairwiseCipher_Or_TxKeyLen, unsigned long ulGroupCipher_TxKeyIndex, unsigned long ulKeyMgmt, unsigned char* ucPf_OrKey, unsigned long ulPassPhraseLen) { unsigned short arg_len; long ret; unsigned char *ptr; long i = 0; unsigned char *args; unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0}; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); args = UINT32_TO_STREAM(args, ulSecType); // Setup arguments in accordance with the security type switch (ulSecType) { //OPEN case WLAN_SEC_UNSEC: { args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen; } break; //WEP case WLAN_SEC_WEP: { args = UINT32_TO_STREAM(args, 0x00000020); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen); args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); for(i = 0; i < 4; i++) { unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen]; ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen); } arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen + ulPairwiseCipher_Or_TxKeyLen * 4; } break; //WPA //WPA2 case WLAN_SEC_WPA: case WLAN_SEC_WPA2: { args = UINT32_TO_STREAM(args, 0x00000028); args = UINT32_TO_STREAM(args, ulSsidLen); args = UINT16_TO_STREAM(args, 0); if(ucBssid) { ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, ulPriority); args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen); args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex); args = UINT32_TO_STREAM(args, ulKeyMgmt); args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen); args = UINT32_TO_STREAM(args, ulPassPhraseLen); ARRAY_TO_STREAM(args, ucSsid, ulSsidLen); ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen); arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen; } break; } // Initiate a HCI command hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len); // Wait for command complete event SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); return(ret); }
/******************************************************************************* ** ** Function hw_config_cback ** ** Description Callback function for controller configuration ** ** Returns None ** *******************************************************************************/ void hw_config_cback(void *p_mem) { HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem; char *p_name, *p_tmp; uint8_t *p, status; uint16_t opcode; HC_BT_HDR *p_buf=NULL; uint8_t is_proceeding = FALSE; int i; #if (USE_CONTROLLER_BDADDR == TRUE) const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0}; #endif status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE); p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE; STREAM_TO_UINT16(opcode,p); /* Ask a new buffer big enough to hold any HCI commands sent in here */ if ((status == 0) && bt_vendor_cbacks) p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \ HCI_CMD_MAX_LEN); ALOGI("[Atmel %s] rcvd cb with state: %d!!,status:%d,op_code:%x",__func__, hw_cfg_cb.state,status,opcode); if (p_buf != NULL) { p_buf->event = MSG_STACK_TO_HC_HCI_CMD; p_buf->offset = 0; p_buf->len = 0; p_buf->layer_specific = 0; p = (uint8_t *) (p_buf + 1); switch (hw_cfg_cb.state) { case HW_CFG_SET_UART_BAUD_1: /* update baud rate of host's UART port */ ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); userial_vendor_set_baud( \ line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ ); /* read local name */ UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME); *p = 0; /* parameter length */ p_buf->len = HCI_CMD_PREAMBLE_SIZE; hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME; is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \ p_buf, hw_config_cback); break; case HW_CFG_READ_LOCAL_NAME: p_tmp = p_name = (char *) (p_evt_buf + 1) + \ HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING; for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++) *(p_name+i) = toupper(*(p_name+i)); if ((p_name = strstr(p_name, "BCM")) != NULL) { strncpy(hw_cfg_cb.local_chip_name, p_name, \ LOCAL_NAME_BUFFER_LEN-1); } else { strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \ LOCAL_NAME_BUFFER_LEN-1); p_name = p_tmp; } hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0; BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name); if ((status = hw_config_findpatch(p_name)) == TRUE) { if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1) { ALOGE("vendor lib preload failed to open [%s]", p_name); } else { #if 0 /* vsc_download_minidriver */ UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV); *p = 0; /* parameter length */ p_buf->len = HCI_CMD_PREAMBLE_SIZE; hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER; is_proceeding = bt_vendor_cbacks->xmit_cb( \ HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \ hw_config_cback); #endif } } else { ALOGE( \ "vendor lib preload failed to locate firmware patch file" \ ); } if (is_proceeding == FALSE) { //is_proceeding = hw_config_set_bdaddr(p_buf); } break; case HW_CFG_DL_MINIDRIVER: /* give time for placing firmware in download mode */ ms_delay(50); hw_cfg_cb.state = HW_CFG_DL_FW_PATCH; /* fall through intentionally */ case HW_CFG_DL_FW_PATCH: p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE); if (p_buf->len > 0) { #if 0 if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \ (opcode == HCI_VSC_LAUNCH_RAM)) { ALOGW("firmware patch file might be altered!"); } else { p_buf->len += read(hw_cfg_cb.fw_fd, \ p+HCI_CMD_PREAMBLE_SIZE,\ *(p+HCD_REC_PAYLOAD_LEN_BYTE)); STREAM_TO_UINT16(opcode,p); is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \ p_buf, hw_config_cback); break; } #endif } close(hw_cfg_cb.fw_fd); hw_cfg_cb.fw_fd = -1; /* Normally the firmware patch configuration file * sets the new starting baud rate at 115200. * So, we need update host's baud rate accordingly. */ ALOGI("bt vendor lib: set UART baud 115200"); userial_vendor_set_baud(USERIAL_BAUD_115200); /* Next, we would like to boost baud rate up again * to desired working speed. */ hw_cfg_cb.f_set_baud_2 = TRUE; /* Check if we need to pause a few hundred milliseconds * before sending down any HCI command. */ ms_delay(look_up_fw_settlement_delay()); /* fall through intentionally */ case HW_CFG_START: if (UART_TARGET_BAUD_RATE > 3000000) { #if 1 /* set UART clock to 48MHz */ UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING); *p++ = 1; /* parameter length */ *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */ p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1; hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK; is_proceeding = bt_vendor_cbacks->xmit_cb( \ HCI_VSC_WRITE_UART_CLOCK_SETTING, \ p_buf, hw_config_cback); break; #endif } /* fall through intentionally */ case HW_CFG_SET_UART_CLOCK: /* set controller's UART baud rate to 3M */ UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE); *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */ *p++ = 0; /* encoded baud rate */ *p++ = 0; /* use encoded form */ UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE); p_buf->len = HCI_CMD_PREAMBLE_SIZE + \ UPDATE_BAUDRATE_CMD_PARAM_SIZE; hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \ HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1; is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \ p_buf, hw_config_cback); break; case HW_CFG_SET_UART_BAUD_2: /* update baud rate of host's UART port */ ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE); userial_vendor_set_baud( \ line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \ ); #if (USE_CONTROLLER_BDADDR == TRUE) if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE) break; #else // if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) // break; #endif /* fall through intentionally */ case HW_CFG_SET_BD_ADDR: ALOGI("vendor lib fwcfg completed"); bt_vendor_cbacks->dealloc(p_buf); bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); hw_cfg_cb.state = 0; if (hw_cfg_cb.fw_fd != -1) { close(hw_cfg_cb.fw_fd); hw_cfg_cb.fw_fd = -1; } is_proceeding = TRUE; break; #if (USE_CONTROLLER_BDADDR == TRUE) case HW_CFG_READ_BD_ADDR: p_tmp = (char *) (p_evt_buf + 1) + \ HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY; if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0) { // Controller does not have a valid OTP BDADDR! // Set the BTIF initial BDADDR instead. // if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE) // break; } else { ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X", *(p_tmp+5), *(p_tmp+4), *(p_tmp+3), *(p_tmp+2), *(p_tmp+1), *p_tmp); } ALOGI("vendor lib fwcfg completed"); bt_vendor_cbacks->dealloc(p_buf); bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS); hw_cfg_cb.state = 0; if (hw_cfg_cb.fw_fd != -1) { close(hw_cfg_cb.fw_fd); hw_cfg_cb.fw_fd = -1; } is_proceeding = TRUE; break; #endif // (USE_CONTROLLER_BDADDR == TRUE) } // switch(hw_cfg_cb.state) } // if (p_buf != NULL) /* Free the RX event buffer */ if (bt_vendor_cbacks) bt_vendor_cbacks->dealloc(p_evt_buf); if (is_proceeding == FALSE) { ALOGE("vendor lib fwcfg aborted!!!"); if (bt_vendor_cbacks) { if (p_buf != NULL) bt_vendor_cbacks->dealloc(p_buf); bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL); } if (hw_cfg_cb.fw_fd != -1) { close(hw_cfg_cb.fw_fd); hw_cfg_cb.fw_fd = -1; } hw_cfg_cb.state = 0; } }
//***************************************************************************** // //! select //! //! @param[in] nfds the highest-numbered file descriptor in any of the //! three sets, plus 1. //! @param[out] writesds socket descriptors list for write monitoring //! @param[out] readsds socket descriptors list for read monitoring //! @param[out] exceptsds socket descriptors list for exception monitoring //! @param[in] timeout is an upper bound on the amount of time elapsed //! before select() returns. Null means infinity //! timeout. The minimum timeout is 5 milliseconds, //! less than 5 milliseconds will be set //! automatically to 5 milliseconds. //! @return On success, select() returns the number of file descriptors //! contained in the three returned descriptor sets (that is, the //! total number of bits that are set in readfds, writefds, //! exceptfds) which may be zero if the timeout expires before //! anything interesting happens. //! On error, -1 is returned. //! *readsds - return the sockets on which Read request will //! return without delay with valid data. //! *writesds - return the sockets on which Write request //! will return without delay. //! *exceptsds - return the sockets which closed recently. //! //! @brief Monitor socket activity //! Select allow a program to monitor multiple file descriptors, //! waiting until one or more of the file descriptors become //! "ready" for some class of I/O operation //! //! @Note If the timeout value set to less than 5ms it will automatically set //! to 5ms to prevent overload of the system //! //! @sa socket // //***************************************************************************** int c_select(long nfds, wfd_set *readsds, wfd_set *writesds, wfd_set *exceptsds, struct timeval *timeout) { uint8_t *args; tBsdSelectRecvParams tParams; uint32_t is_blocking; if( timeout == NULL) { is_blocking = 1; /* blocking , infinity timeout */ } else { is_blocking = 0; /* no blocking, timeout */ } // Fill in HCI packet structure args = hci_get_cmd_buffer(); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, nfds); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, is_blocking); args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0)); args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0)); args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0)); if (timeout) { if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) { timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; } args = UINT32_TO_STREAM(args, timeout->tv_sec); args = UINT32_TO_STREAM(args, timeout->tv_usec); } // Initiate a HCI command hci_command_send(HCI_CMND_BSD_SELECT, SOCKET_SELECT_PARAMS_LEN, HCI_EVNT_SELECT, &tParams); // Update actually read FD if (tParams.iStatus >= 0) { if (readsds) memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); if (writesds) memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); if (exceptsds) memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); return(tParams.iStatus); } else { errno = tParams.iStatus; return(-1); } }
//***************************************************************************** // //! simple_link_send //! //! @param sd socket handle //! @param buf write buffer //! @param len buffer length //! @param flags On this version, this parameter is not supported //! @param to pointer to an address structure indicating destination //! address //! @param tolen destination address structure size //! //! @return Return the number of bytes transmitted, or -1 if an error //! occurred, or -2 in case there are no free buffers available //! //! @brief This function is used to transmit a message to another //! socket // //***************************************************************************** static int simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode) { uint8_t uArgSize, addrlen; uint8_t *pDataPtr, *args; uint32_t addr_offset = 0; int res; tBsdReadReturnParams tSocketSendEvent; uint16_t rx_opcode; // Check the bsd_arguments if ((res = consume_buf(sd)) != 0) return res; // Allocate a buffer and construct a packet and send it over spi args = hci_get_data_buffer(); // Update the offset of data and parameters according to the command switch(opcode) { case HCI_CMND_SENDTO: addr_offset = len + sizeof(len) + sizeof(len); addrlen = 8; uArgSize = SOCKET_SENDTO_PARAMS_LEN; pDataPtr = args + SOCKET_SENDTO_PARAMS_LEN; break; case HCI_CMND_SEND: tolen = 0; to = NULL; uArgSize = HCI_CMND_SEND_ARG_LENGTH; pDataPtr = args + HCI_CMND_SEND_ARG_LENGTH; break; default: return -1; } // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); args = UINT32_TO_STREAM(args, len); args = UINT32_TO_STREAM(args, flags); if (opcode == HCI_CMND_SENDTO) { args = UINT32_TO_STREAM(args, addr_offset); args = UINT32_TO_STREAM(args, addrlen); } // Copy the data received from user into the TX Buffer ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); // In case we are using SendTo, copy the to parameters if (opcode == HCI_CMND_SENDTO) { ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); } if (opcode == HCI_CMND_SENDTO) rx_opcode = HCI_EVNT_SENDTO; else rx_opcode = HCI_EVNT_SEND; // Initiate a HCI command hci_data_send(opcode, uArgSize, len, (uint8_t*)to, tolen, rx_opcode, &tSocketSendEvent); return (len); }
UINT8 *hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen) { UINT8 *pucReceivedData, ucArgsize; UINT16 usLength; UINT8 *pucReceivedParams; UINT16 usReceivedEventOpcode = 0; UINT32 retValue32; UINT8 *RecvParams; UINT8 *RetParams; while (1) { // Adafruit CC3k Host Driver Difference // Call cc3k_int_poll to try to keep from missing interrupts. // Noted 12-12-2014 by tdicola cc3k_int_poll(); if (tSLInformation.usEventOrDataReceived != 0) { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((CHAR *) pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; // Adafruit CC3k Host Driver Difference // Explicit cast of pRetParams to UINT8* to fix compiler warning. // Noted 12-12-2014 by tdicola RetParams = (UINT8 *) pRetParams; // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((CHAR *) pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch (usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((CHAR *) pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((CHAR *) pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(UINT8 *) pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((CHAR *) pucReceivedParams, 0, *(UINT32 *) pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(UINT8 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 1; STREAM_TO_UINT32((CHAR *) pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((UINT8 *) pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((CHAR *) pucReceivedParams, GET_HOST_BY_NAME_RETVAL_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, GET_HOST_BY_NAME_ADDR_OFFSET, *(UINT32 *) pRetParams); break; case HCI_EVNT_GETMSSVALUE: STREAM_TO_UINT16((CHAR *) pucReceivedParams, GET_MSS_VAL_RETVAL_OFFSET, *(UINT16 *) pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((CHAR *) pucReceivedParams, ACCEPT_SD_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, ACCEPT_RETURN_STATUS_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; // This argument returns in network order memcpy((UINT8 *) pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE_SD_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE_NUM_BYTES_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE__FLAGS__OFFSET, *(UINT32 *) pRetParams); if (((tBsdReadReturnParams *) pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status( ((tBsdReadReturnParams *) pRetParams)->iSocketDescriptor, SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE_SD_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE_NUM_BYTES_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_STATUS_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_READFD_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_WRITEFD_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_EXFD_OFFSET, *(UINT32 *) pRetParams); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8( pucReceivedData, HCI_EVENT_STATUS_OFFSET, ((tBsdGetSockOptReturnParams *) pRetParams)->iStatus); // This argument returns in network order memcpy((UINT8 *) pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((CHAR *) pucReceivedParams, GET_SCAN_RESULTS_TABlE_COUNT_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT32((CHAR *) pucReceivedParams, GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 4; STREAM_TO_UINT16((CHAR *) pucReceivedParams, GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 2; STREAM_TO_UINT16((CHAR *) pucReceivedParams, GET_SCAN_RESULTS_FRAME_TIME_OFFSET, *(UINT32 *) pRetParams); pRetParams = ((CHAR *) pRetParams) + 2; memcpy((UINT8 *) pRetParams, (CHAR *) (pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: // Read IP address STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; // Read subnet STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; // Read default GW STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; // Read DHCP server STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; // Read DNS server STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; // Read Mac address STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; // Read SSID STREAM_TO_STREAM(RecvParams, RetParams, NETAPP_IPCONFIG_SSID_LENGTH); } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; } } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((CHAR *) pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((CHAR *) pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((CHAR *) (pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(UINT32 *) fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET), *fromlen); } memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, usLength - ucArgsize); tSLInformation.usRxDataPending = 0; } tSLInformation.usEventOrDataReceived = 0; SpiResumeSpi(); // Since we are going to TX - we need to handle this event after the // ResumeSPi since we need interrupts if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((CHAR *) pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { return NULL; } } } }
unsigned char * hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen) { renableIRQ(); // TM_DEBUG("hci event handler"); // TM_DEBUG("event or data recieved y/n? %ul", tSLInformation.usEventOrDataReceived); // TM_DEBUG("the actual event/data %ul", (unsigned char *)tSLInformation.pucReceivedData[0]); volatile unsigned char *pucReceivedData, ucArgsize; unsigned short usLength; unsigned char *pucReceivedParams; unsigned short usReceivedEventOpcode = 0; unsigned long retValue32; unsigned char * RecvParams; unsigned char *RetParams; #ifdef CC3K_TIMEOUT uint32_t ccStartTime = tm_uptime_micro(); #endif while (1) { CC_BLOCKS(); if (tSLInformation.usEventOrDataReceived != 0) { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = (unsigned char*) (pucReceivedData + HCI_EVENT_HEADER_SIZE); RecvParams = pucReceivedParams; RetParams = pRetParams; // TM_DEBUG("PUC RECIEVED DATA pre %ul", (char *)pucReceivedData[0]); // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); // TM_DEBUG("PUC RECIEVED DATA %ul",(char *) pucReceivedData[0]); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams,0 ,*(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET ,*(unsigned char *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams ,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams ,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; } } else { pucReceivedParams = (unsigned char*) pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (void*) (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, usLength - ucArgsize); tSLInformation.usRxDataPending = 0; } tSLInformation.usEventOrDataReceived = 0; SpiResumeSpi(); // Since we are going to TX - we need to handle this event after the // ResumeSPi since we need interrupts if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { return NULL; } } #ifdef CC3K_TIMEOUT else { // check the system timer // compare it to maximum allowed wait if (tm_uptime_micro() - ccStartTime >= CC3000_MAX_WAIT) { // set pRetParams to some default values switch(tSLInformation.usRxEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: // tSLInformation values are defaulted to 0 tSLInformation.usNumberOfFreeBuffers = 0; tSLInformation.usSlBufferLength = 0; break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: // return CC3K_TIMEOUT_ERR for errored out on timeout *(signed char *)pRetParams = CC3K_TIMEOUT_ERR; break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: // return CC3K_TIMEOUT_ERR for errored out on timeout *(long *)pRetParams = CC3K_TIMEOUT_ERR; break; case HCI_EVNT_BSD_GETHOSTBYNAME: // expects a tBsdGethostbynameParams, set error on retVal and default outputAddress ((tBsdGethostbynameParams *)pRetParams)->retVal = CC3K_TIMEOUT_ERR; ((tBsdGethostbynameParams *)pRetParams)->outputAddress = 0; break; case HCI_EVNT_READ_SP_VERSION: case HCI_CMND_SIMPLE_LINK_START: case HCI_EVNT_ACCEPT: case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { // these don't do anything, we're not in a blocking loop for this break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: // expects a tBsdReadReturnParams, set the iNumberOfBytes to zero ((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes = 0; break; case HCI_EVNT_SELECT: // expects a tBsdSelectRecvParams, set the isStatus ((tBsdSelectRecvParams *)pRetParams)->iStatus = CC3K_TIMEOUT_ERR; break; case HCI_CMND_GETSOCKOPT: // HCI_CMND_GETSOCKOPT expects a tBsdGetSockOptReturnParams, set the error code ((tBsdGetSockOptReturnParams *)pRetParams)->iStatus = CC3K_TIMEOUT_ERR; break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: // no results on error *(unsigned char *)pRetParams = 0; break; case HCI_NETAPP_IPCONFIG: // set all values to zero memset(pRetParams,0,sizeof(tNetappIpconfigRetArgs)); break; } TM_DEBUG("HCI Event error on command: %x", tSLInformation.usRxEventOpcode); // past maximum wait, get out of here return NULL; } } #endif } }
int32_t cc3000_wlan::add_profile(uint32_t sec_type, uint8_t* ssid, uint32_t ssid_length, uint8_t *b_ssid, uint32_t priority, uint32_t pairwise_cipher_or_tx_key_len, uint32_t group_cipher_tx_key_index, uint32_t key_mgmt, uint8_t* pf_or_key, uint32_t pass_phrase_len) { uint16_t arg_len = 0x00; int32_t ret; uint8_t *ptr; int32_t i = 0; uint8_t *args; uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0}; ptr = _simple_link.get_transmit_buffer(); args = (ptr + HEADERS_SIZE_CMD); args = UINT32_TO_STREAM(args, sec_type); // Setup arguments in accordance with the security type switch (sec_type) { //OPEN case WLAN_SEC_UNSEC: { args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, ssid_length); args = UINT16_TO_STREAM(args, 0); if(b_ssid) { ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, priority); ARRAY_TO_STREAM(args, ssid, ssid_length); arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length; } break; //WEP case WLAN_SEC_WEP: { args = UINT32_TO_STREAM(args, 0x00000020); args = UINT32_TO_STREAM(args, ssid_length); args = UINT16_TO_STREAM(args, 0); if(b_ssid) { ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, priority); args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length); args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len); args = UINT32_TO_STREAM(args, group_cipher_tx_key_index); ARRAY_TO_STREAM(args, ssid, ssid_length); for(i = 0; i < 4; i++) { uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len]; ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len); } arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length + pairwise_cipher_or_tx_key_len * 4; } break; //WPA //WPA2 case WLAN_SEC_WPA: case WLAN_SEC_WPA2: { args = UINT32_TO_STREAM(args, 0x00000028); args = UINT32_TO_STREAM(args, ssid_length); args = UINT16_TO_STREAM(args, 0); if(b_ssid) { ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN); } else { ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN); } args = UINT32_TO_STREAM(args, priority); args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len); args = UINT32_TO_STREAM(args, group_cipher_tx_key_index); args = UINT32_TO_STREAM(args, key_mgmt); args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length); args = UINT32_TO_STREAM(args, pass_phrase_len); ARRAY_TO_STREAM(args, ssid, ssid_length); ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len); arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len; } break; } // Initiate a HCI command _hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len); // Wait for command complete event _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret); return(ret); }