diff options
author | Gregory Nutt <gnutt@nuttx.org> | 2013-09-04 09:45:59 -0600 |
---|---|---|
committer | Gregory Nutt <gnutt@nuttx.org> | 2013-09-04 09:45:59 -0600 |
commit | a2ffe6b068f3975e7574feabff0d20b368bd2f49 (patch) | |
tree | 25e2a3ee86c34dd3953b7f6b8f8feeafa62962bb /nuttx/drivers/wireless/cc3000/wlan.c | |
parent | 87069eb35cb10aa7bea564a12d7bb5075fdd31e3 (diff) | |
download | px4-nuttx-a2ffe6b068f3975e7574feabff0d20b368bd2f49.tar.gz px4-nuttx-a2ffe6b068f3975e7574feabff0d20b368bd2f49.tar.bz2 px4-nuttx-a2ffe6b068f3975e7574feabff0d20b368bd2f49.zip |
CC3000 driver updates from Alan Carvalho de Assis
Diffstat (limited to 'nuttx/drivers/wireless/cc3000/wlan.c')
-rw-r--r-- | nuttx/drivers/wireless/cc3000/wlan.c | 2505 |
1 files changed, 1251 insertions, 1254 deletions
diff --git a/nuttx/drivers/wireless/cc3000/wlan.c b/nuttx/drivers/wireless/cc3000/wlan.c index b30b82c10..48735947b 100644 --- a/nuttx/drivers/wireless/cc3000/wlan.c +++ b/nuttx/drivers/wireless/cc3000/wlan.c @@ -1,1254 +1,1251 @@ -/*****************************************************************************
-*
-* wlan.c - CC3000 Host Driver Implementation.
-* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
-*
-* Redistribution and use in source and binary forms, with or without
-* modification, are permitted provided that the following conditions
-* are met:
-*
-* Redistributions of source code must retain the above copyright
-* notice, this list of conditions and the following disclaimer.
-*
-* Redistributions in binary form must reproduce the above copyright
-* notice, this list of conditions and the following disclaimer in the
-* documentation and/or other materials provided with the
-* distribution.
-*
-* Neither the name of Texas Instruments Incorporated nor the names of
-* its contributors may be used to endorse or promote products derived
-* from this software without specific prior written permission.
-*
-* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*
-*****************************************************************************/
-
-//*****************************************************************************
-//
-//! \addtogroup wlan_api
-//! @{
-//
-//*****************************************************************************
-#include <string.h>
-#include <nuttx/cc3000/wlan.h>
-#include <nuttx/cc3000/hci.h>
-#include <nuttx/cc3000/spi.h>
-#include <nuttx/cc3000/socket.h>
-#include <nuttx/cc3000/nvmem.h>
-#include <nuttx/cc3000/security.h>
-#include <nuttx/cc3000/evnt_handler.h>
-
-
-volatile sSimplLinkInformation tSLInformation;
-
-#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length)
-
-#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
-unsigned char akey[AES128_KEY_SIZE];
-unsigned char profileArray[SMART_CONFIG_PROFILE_SIZE];
-#endif //CC3000_UNENCRYPTED_SMART_CONFIG
-
-/* patches type */
-#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01
-#define PATCHES_HOST_TYPE_WLAN_FW 0x02
-#define PATCHES_HOST_TYPE_BOOTLOADER 0x03
-
-#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16)
-#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3)
-#define ETH_ALEN (6)
-#define MAXIMAL_SSID_LENGTH (32)
-
-#define SL_PATCHES_REQUEST_DEFAULT (0)
-#define SL_PATCHES_REQUEST_FORCE_HOST (1)
-#define SL_PATCHES_REQUEST_FORCE_NONE (2)
-
-
-#define WLAN_SEC_UNSEC (0)
-#define WLAN_SEC_WEP (1)
-#define WLAN_SEC_WPA (2)
-#define WLAN_SEC_WPA2 (3)
-
-
-#define WLAN_SL_INIT_START_PARAMS_LEN (1)
-#define WLAN_PATCH_PARAMS_LENGTH (8)
-#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12)
-#define WLAN_DEL_PROFILE_PARAMS_LEN (4)
-#define WLAN_SET_MASK_PARAMS_LEN (4)
-#define WLAN_SET_SCAN_PARAMS_LEN (100)
-#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4)
-#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24)
-#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36)
-#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44)
-#define WLAN_CONNECT_PARAM_LEN (29)
-#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4)
-
-
-
-
-//*****************************************************************************
-//
-//! SimpleLink_Init_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 Send HCI_CMND_SIMPLE_LINK_START to CC3000
-//
-//*****************************************************************************
-static void SimpleLink_Init_Start(unsigned short usPatchesAvailableAtHost)
-{
- unsigned char *ptr;
- unsigned char *args;
-
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);
-
- UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT));
-
- // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000
- hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN);
-
- printf ("Goind to call SimpleLinkWaitEvent...\n");
- SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0);
-}
-
-
-
-//*****************************************************************************
-//
-//! wlan_init
-//!
-//! @param sWlanCB Asynchronous events callback.
-//! 0 no event call back.
-//! -call back parameters:
-//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event,
-//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event,
-//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done,
-//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report,
-//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR
-//! HCI_EVNT_WLAN_KEEPALIVE keepalive.
-//! 2) data: pointer to extra data that received by the event
-//! (NULL no data).
-//! 3) length: data length.
-//! -Events with extra data:
-//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask,
-//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes
-//! for DNS server.
-//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent,
-//! 4 bytes Packets received, 4 bytes Min round time,
-//! 4 bytes Max round time and 4 bytes for Avg round time.
-//!
-//! @param sFWPatches 0 no patch or pointer to FW patches
-//! @param sDriverPatches 0 no patch or pointer to driver patches
-//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches
-//! @param sReadWlanInterruptPin init callback. the callback read wlan
-//! interrupt status.
-//! @param sWlanInterruptEnable init callback. the callback enable wlan
-//! interrupt.
-//! @param sWlanInterruptDisable init callback. the callback disable wlan
-//! interrupt.
-//! @param sWriteWlanPin init callback. the callback write value
-//! to device pin.
-//!
-//! @return none
-//!
-//! @sa wlan_set_event_mask , wlan_start , wlan_stop
-//!
-//! @brief Initialize wlan driver
-//!
-//! @warning This function must be called before ANY other wlan driver function
-//
-//*****************************************************************************
-
-void wlan_init( tWlanCB sWlanCB,
- tFWPatches sFWPatches,
- tDriverPatches sDriverPatches,
- tBootLoaderPatches sBootLoaderPatches,
- tWlanReadInteruptPin sReadWlanInterruptPin,
- tWlanInterruptEnable sWlanInterruptEnable,
- tWlanInterruptDisable sWlanInterruptDisable,
- tWriteWlanPin sWriteWlanPin)
-{
-
- tSLInformation.sFWPatches = sFWPatches;
- tSLInformation.sDriverPatches = sDriverPatches;
- tSLInformation.sBootLoaderPatches = sBootLoaderPatches;
-
- // 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
-//!
-//
-//*****************************************************************************
-
-void
-wlan_start(unsigned short usPatchesAvailableAtHost)
-{
-
- 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 than low
- while(tSLInformation.ReadWlanInterruptPin() == 0)
- {
- }
-
- while(tSLInformation.ReadWlanInterruptPin() != 0)
- {
- }
- }
-
- printf("Going to call SimpleLink_Init_Start...\n");
- SimpleLink_Init_Start(usPatchesAvailableAtHost);
- printf("Returned from SimpleLink_Init_Start...\n");
-
- // 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
-//
-//*****************************************************************************
-
-void
-wlan_stop(void)
-{
- // 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
-long
-wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
- unsigned char *bssid, unsigned char *key, long key_len)
-{
- 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
-long
-wlan_connect(char *ssid, long ssid_len)
-{
- 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
-//
-//*****************************************************************************
-
-long
-wlan_disconnect()
-{
- 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
-//
-//*****************************************************************************
-
-long
-wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap,
- unsigned long ulShouldUseFastConnect,
- unsigned long ulUseProfiles)
-{
- 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.
-//! @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, zero 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
-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 = 0;
- 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);
-}
-#else
-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)
-{
- 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
-//
-//*****************************************************************************
-
-long
-wlan_ioctl_del_profile(unsigned long ulIndex)
-{
- 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
-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);
-}
-#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
-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)
-{
- 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.
-//
-//*****************************************************************************
-
-long
-wlan_set_event_mask(unsigned long ulMask)
-{
- 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
-long
-wlan_ioctl_statusget(void)
-{
- 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
-//
-//*****************************************************************************
-
-long
-wlan_smart_config_start(unsigned long algoEncryptedFlag)
-{
- 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);
-}
-
-//*****************************************************************************
-//
-//! wlan_smart_config_stop
-//!
-//! @param algoEncryptedFlag indicates whether the information is encrypted
-//!
-//! @return On success, zero is returned. On error, -1 is returned
-//!
-//! @brief Stop the acquire profile procedure
-//!
-//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix
-//
-//*****************************************************************************
-
-long
-wlan_smart_config_stop(void)
-{
- long ret;
- unsigned char *ptr;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
-
- hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
-
- // Wait for command complete event
- SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! wlan_smart_config_set_prefix
-//!
-//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config.
-//!
-//! @return On success, zero is returned. On error, -1 is returned
-//!
-//! @brief Configure station ssid prefix. The prefix is used internally
-//! in CC3000. It should always be TTT.
-//!
-//! @Note The prefix is stored in CC3000 NVMEM
-//!
-//! @sa wlan_smart_config_start , wlan_smart_config_stop
-//
-//*****************************************************************************
-
-long
-wlan_smart_config_set_prefix(char* cNewPrefix)
-{
- long ret;
- unsigned char *ptr;
- unsigned char *args;
-
- ret = EFAIL;
- ptr = tSLInformation.pucTxCommandBuffer;
- args = (ptr + HEADERS_SIZE_CMD);
-
- if (cNewPrefix == NULL)
- return ret;
- else // with the new Smart Config, prefix must be TTT
- {
- *cNewPrefix = 'T';
- *(cNewPrefix + 1) = 'T';
- *(cNewPrefix + 2) = 'T';
- }
-
- ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
-
- hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr,
- SL_SIMPLE_CONFIG_PREFIX_LENGTH);
-
- // Wait for command complete event
- SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
-
- return(ret);
-}
-
-//*****************************************************************************
-//
-//! wlan_smart_config_process
-//!
-//! @param none
-//!
-//! @return On success, zero is returned. On error, -1 is returned
-//!
-//! @brief process the acquired data and store it as a profile. The acquired
-//! AP information is stored in CC3000 EEPROM encrypted.
-//! The encrypted data is decrypted and stored as a profile.
-//! behavior is as defined by connection policy.
-//
-//*****************************************************************************
-
-
-#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
-long
-wlan_smart_config_process()
-{
- signed long returnValue;
- unsigned long ssidLen, keyLen;
- unsigned char *decKeyPtr;
- unsigned char *ssidPtr;
-
- // read the key from EEPROM - fileID 12
- returnValue = aes_read_key(akey);
-
- if (returnValue != 0)
- return returnValue;
-
- // read the received data from fileID #13 and parse it according to the followings:
- // 1) SSID LEN - not encrypted
- // 2) SSID - not encrypted
- // 3) KEY LEN - not encrypted. always 32 bytes long
- // 4) Security type - not encrypted
- // 5) KEY - encrypted together with true key length as the first byte in KEY
- // to elaborate, there are two corner cases:
- // 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
- // 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
- returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray);
-
- if (returnValue != 0)
- return returnValue;
-
- ssidPtr = &profileArray[1];
-
- ssidLen = profileArray[0];
-
- decKeyPtr = &profileArray[profileArray[0] + 3];
-
- aes_decrypt(decKeyPtr, akey);
- if (profileArray[profileArray[0] + 1] > 16)
- aes_decrypt((unsigned char *)(decKeyPtr + 16), akey);
-
- if (*(unsigned char *)(decKeyPtr +31) != 0)
- {
- if (*decKeyPtr == 31)
- {
- keyLen = 31;
- decKeyPtr++;
- }
- else
- {
- keyLen = 32;
- }
- }
- else
- {
- keyLen = *decKeyPtr;
- decKeyPtr++;
- }
-
- // add a profile
- switch (profileArray[profileArray[0] + 2])
- {
- case WLAN_SEC_UNSEC://None
- {
- returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type
- ssidPtr, // SSID
- ssidLen, // SSID length
- NULL, // BSSID
- 1, // Priority
- 0, 0, 0, 0, 0);
-
- break;
- }
-
- case WLAN_SEC_WEP://WEP
- {
- returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type
- ssidPtr, // SSID
- ssidLen, // SSID length
- NULL, // BSSID
- 1, // Priority
- keyLen, // KEY length
- 0, // KEY index
- 0,
- decKeyPtr, // KEY
- 0);
-
- break;
- }
-
- case WLAN_SEC_WPA://WPA
- case WLAN_SEC_WPA2://WPA2
- {
- returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type
- ssidPtr,
- ssidLen,
- NULL, // BSSID
- 1, // Priority
- 0x18, // PairwiseCipher
- 0x1e, // GroupCipher
- 2, // KEY management
- decKeyPtr, // KEY
- keyLen); // KEY length
-
- break;
- }
- }
-
- return returnValue;
-}
-#endif //CC3000_UNENCRYPTED_SMART_CONFIG
-
-//*****************************************************************************
-//
-// Close the Doxygen group.
-//! @}
-//
-//*****************************************************************************
+/***************************************************************************** +* +* wlan.c - CC3000 Host Driver Implementation. +* Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/ +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* +* Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* +* Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the +* distribution. +* +* Neither the name of Texas Instruments Incorporated nor the names of +* its contributors may be used to endorse or promote products derived +* from this software without specific prior written permission. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +* +*****************************************************************************/ + +//***************************************************************************** +// +//! \addtogroup wlan_api +//! @{ +// +//***************************************************************************** +#include <string.h> +#include <nuttx/cc3000/wlan.h> +#include <nuttx/cc3000/hci.h> +#include <nuttx/cc3000/spi.h> +#include <nuttx/cc3000/socket.h> +#include <nuttx/cc3000/nvmem.h> +#include <nuttx/cc3000/security.h> +#include <nuttx/cc3000/evnt_handler.h> + + +volatile sSimplLinkInformation tSLInformation; + +#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length) + +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG +uint8_t akey[AES128_KEY_SIZE]; +uint8_t profileArray[SMART_CONFIG_PROFILE_SIZE]; +#endif //CC3000_UNENCRYPTED_SMART_CONFIG + +/* patches type */ +#define PATCHES_HOST_TYPE_WLAN_DRIVER 0x01 +#define PATCHES_HOST_TYPE_WLAN_FW 0x02 +#define PATCHES_HOST_TYPE_BOOTLOADER 0x03 + +#define SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE (16) +#define SL_SIMPLE_CONFIG_PREFIX_LENGTH (3) +#define ETH_ALEN (6) +#define MAXIMAL_SSID_LENGTH (32) + +#define SL_PATCHES_REQUEST_DEFAULT (0) +#define SL_PATCHES_REQUEST_FORCE_HOST (1) +#define SL_PATCHES_REQUEST_FORCE_NONE (2) + + +#define WLAN_SEC_UNSEC (0) +#define WLAN_SEC_WEP (1) +#define WLAN_SEC_WPA (2) +#define WLAN_SEC_WPA2 (3) + + +#define WLAN_SL_INIT_START_PARAMS_LEN (1) +#define WLAN_PATCH_PARAMS_LENGTH (8) +#define WLAN_SET_CONNECTION_POLICY_PARAMS_LEN (12) +#define WLAN_DEL_PROFILE_PARAMS_LEN (4) +#define WLAN_SET_MASK_PARAMS_LEN (4) +#define WLAN_SET_SCAN_PARAMS_LEN (100) +#define WLAN_GET_SCAN_RESULTS_PARAMS_LEN (4) +#define WLAN_ADD_PROFILE_NOSEC_PARAM_LEN (24) +#define WLAN_ADD_PROFILE_WEP_PARAM_LEN (36) +#define WLAN_ADD_PROFILE_WPA_PARAM_LEN (44) +#define WLAN_CONNECT_PARAM_LEN (29) +#define WLAN_SMART_CONFIG_START_PARAMS_LEN (4) + + + + +//***************************************************************************** +// +//! SimpleLink_Init_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 Send HCI_CMND_SIMPLE_LINK_START to CC3000 +// +//***************************************************************************** +static void SimpleLink_Init_Start(uint16_t usPatchesAvailableAtHost) +{ + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(ptr + HEADERS_SIZE_CMD); + + UINT8_TO_STREAM(args, ((usPatchesAvailableAtHost) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT)); + + // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000 + hci_command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN); + + SimpleLinkWaitEvent(HCI_CMND_SIMPLE_LINK_START, 0); +} + + + +//***************************************************************************** +// +//! wlan_init +//! +//! @param sWlanCB Asynchronous events callback. +//! 0 no event call back. +//! -call back parameters: +//! 1) event_type: HCI_EVNT_WLAN_UNSOL_CONNECT connect event, +//! HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event, +//! HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE config done, +//! HCI_EVNT_WLAN_UNSOL_DHCP dhcp report, +//! HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report OR +//! HCI_EVNT_WLAN_KEEPALIVE keepalive. +//! 2) data: pointer to extra data that received by the event +//! (NULL no data). +//! 3) length: data length. +//! -Events with extra data: +//! HCI_EVNT_WLAN_UNSOL_DHCP: 4 bytes IP, 4 bytes Mask, +//! 4 bytes default gateway, 4 bytes DHCP server and 4 bytes +//! for DNS server. +//! HCI_EVNT_WLAN_ASYNC_PING_REPORT: 4 bytes Packets sent, +//! 4 bytes Packets received, 4 bytes Min round time, +//! 4 bytes Max round time and 4 bytes for Avg round time. +//! +//! @param sFWPatches 0 no patch or pointer to FW patches +//! @param sDriverPatches 0 no patch or pointer to driver patches +//! @param sBootLoaderPatches 0 no patch or pointer to bootloader patches +//! @param sReadWlanInterruptPin init callback. the callback read wlan +//! interrupt status. +//! @param sWlanInterruptEnable init callback. the callback enable wlan +//! interrupt. +//! @param sWlanInterruptDisable init callback. the callback disable wlan +//! interrupt. +//! @param sWriteWlanPin init callback. the callback write value +//! to device pin. +//! +//! @return none +//! +//! @sa wlan_set_event_mask , wlan_start , wlan_stop +//! +//! @brief Initialize wlan driver +//! +//! @warning This function must be called before ANY other wlan driver function +// +//***************************************************************************** + +void wlan_init( tWlanCB sWlanCB, + tFWPatches sFWPatches, + tDriverPatches sDriverPatches, + tBootLoaderPatches sBootLoaderPatches, + tWlanReadInteruptPin sReadWlanInterruptPin, + tWlanInterruptEnable sWlanInterruptEnable, + tWlanInterruptDisable sWlanInterruptDisable, + tWriteWlanPin sWriteWlanPin) +{ + + tSLInformation.sFWPatches = sFWPatches; + tSLInformation.sDriverPatches = sDriverPatches; + tSLInformation.sBootLoaderPatches = sBootLoaderPatches; + + // 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 = (uint8_t *)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 +//! +// +//***************************************************************************** + +void +wlan_start(uint16_t usPatchesAvailableAtHost) +{ + + 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 = (uint8_t *)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 than 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 +// +//***************************************************************************** + +void +wlan_stop(void) +{ + // 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 +long +wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len, + uint8_t *bssid, uint8_t *key, long key_len) +{ + long ret; + uint8_t *ptr; + uint8_t *args; + uint8_t 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 +long +wlan_connect(char *ssid, long ssid_len) +{ + long ret; + uint8_t *ptr; + uint8_t *args; + uint8_t 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 +// +//***************************************************************************** + +long +wlan_disconnect() +{ + long ret; + uint8_t *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 +// +//***************************************************************************** + +long +wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap, + unsigned long ulShouldUseFastConnect, + unsigned long ulUseProfiles) +{ + long ret; + uint8_t *ptr; + uint8_t *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(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. +//! @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, zero 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 +long +wlan_add_profile(unsigned long ulSecType, + uint8_t* ucSsid, + unsigned long ulSsidLen, + uint8_t *ucBssid, + unsigned long ulPriority, + unsigned long ulPairwiseCipher_Or_TxKeyLen, + unsigned long ulGroupCipher_TxKeyIndex, + unsigned long ulKeyMgmt, + uint8_t* ucPf_OrKey, + unsigned long ulPassPhraseLen) +{ + uint16_t arg_len = 0; + long ret; + uint8_t *ptr; + long i = 0; + uint8_t *args; + uint8_t 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++) + { + uint8_t *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); +} +#else +long +wlan_add_profile(unsigned long ulSecType, + uint8_t * ucSsid, + uint8_t ulSsidLen, + uint8_t *ucBssid, + unsigned long ulPriority, + unsigned long ulPairwiseCipher_Or_TxKeyLen, + unsigned long ulGroupCipher_TxKeyIndex, + unsigned long ulKeyMgmt, + uint8_t * ucPf_OrKey, + unsigned long ulPassPhraseLen) +{ + 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 +// +//***************************************************************************** + +long +wlan_ioctl_del_profile(unsigned long ulIndex) +{ + long ret; + uint8_t *ptr; + uint8_t *args; + + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(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 +long +wlan_ioctl_get_scan_results(unsigned long ulScanTimeout, + uint8_t *ucResults) +{ + uint8_t *ptr; + uint8_t *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 +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) +{ + unsigned long uiRes; + uint8_t *ptr; + uint8_t *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. +// +//***************************************************************************** + +long +wlan_set_event_mask(unsigned long ulMask) +{ + long ret; + uint8_t *ptr; + uint8_t *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 = (uint8_t *)(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 +long +wlan_ioctl_statusget(void) +{ + long ret; + uint8_t *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 +// +//***************************************************************************** + +long +wlan_smart_config_start(unsigned long algoEncryptedFlag) +{ + long ret; + uint8_t *ptr; + uint8_t *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (uint8_t *)(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); +} + +//***************************************************************************** +// +//! wlan_smart_config_stop +//! +//! @param algoEncryptedFlag indicates whether the information is encrypted +//! +//! @return On success, zero is returned. On error, -1 is returned +//! +//! @brief Stop the acquire profile procedure +//! +//! @sa wlan_smart_config_start , wlan_smart_config_set_prefix +// +//***************************************************************************** + +long +wlan_smart_config_stop(void) +{ + long ret; + uint8_t *ptr; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + + hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0); + + // Wait for command complete event + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret); + + return(ret); +} + +//***************************************************************************** +// +//! wlan_smart_config_set_prefix +//! +//! @param newPrefix 3 bytes identify the SSID prefix for the Smart Config. +//! +//! @return On success, zero is returned. On error, -1 is returned +//! +//! @brief Configure station ssid prefix. The prefix is used internally +//! in CC3000. It should always be TTT. +//! +//! @Note The prefix is stored in CC3000 NVMEM +//! +//! @sa wlan_smart_config_start , wlan_smart_config_stop +// +//***************************************************************************** + +long +wlan_smart_config_set_prefix(char* cNewPrefix) +{ + long ret; + uint8_t *ptr; + uint8_t *args; + + ret = EFAIL; + ptr = tSLInformation.pucTxCommandBuffer; + args = (ptr + HEADERS_SIZE_CMD); + + if (cNewPrefix == NULL) + return ret; + else // with the new Smart Config, prefix must be TTT + { + *cNewPrefix = 'T'; + *(cNewPrefix + 1) = 'T'; + *(cNewPrefix + 2) = 'T'; + } + + ARRAY_TO_STREAM(args, cNewPrefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH); + + hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, + SL_SIMPLE_CONFIG_PREFIX_LENGTH); + + // Wait for command complete event + SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret); + + return(ret); +} + +//***************************************************************************** +// +//! wlan_smart_config_process +//! +//! @param none +//! +//! @return On success, zero is returned. On error, -1 is returned +//! +//! @brief process the acquired data and store it as a profile. The acquired +//! AP information is stored in CC3000 EEPROM encrypted. +//! The encrypted data is decrypted and stored as a profile. +//! behavior is as defined by connection policy. +// +//***************************************************************************** + + +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG +long +wlan_smart_config_process() +{ + signed long returnValue; + unsigned long ssidLen, keyLen; + uint8_t *decKeyPtr; + uint8_t *ssidPtr; + + // read the key from EEPROM - fileID 12 + returnValue = aes_read_key(akey); + + if (returnValue != 0) + return returnValue; + + // read the received data from fileID #13 and parse it according to the followings: + // 1) SSID LEN - not encrypted + // 2) SSID - not encrypted + // 3) KEY LEN - not encrypted. always 32 bytes long + // 4) Security type - not encrypted + // 5) KEY - encrypted together with true key length as the first byte in KEY + // to elaborate, there are two corner cases: + // 1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length + // 2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31 + returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray); + + if (returnValue != 0) + return returnValue; + + ssidPtr = &profileArray[1]; + + ssidLen = profileArray[0]; + + decKeyPtr = &profileArray[profileArray[0] + 3]; + + aes_decrypt(decKeyPtr, akey); + if (profileArray[profileArray[0] + 1] > 16) + aes_decrypt((uint8_t *)(decKeyPtr + 16), akey); + + if (*(uint8_t *)(decKeyPtr +31) != 0) + { + if (*decKeyPtr == 31) + { + keyLen = 31; + decKeyPtr++; + } + else + { + keyLen = 32; + } + } + else + { + keyLen = *decKeyPtr; + decKeyPtr++; + } + + // add a profile + switch (profileArray[profileArray[0] + 2]) + { + case WLAN_SEC_UNSEC://None + { + returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type + ssidPtr, // SSID + ssidLen, // SSID length + NULL, // BSSID + 1, // Priority + 0, 0, 0, 0, 0); + + break; + } + + case WLAN_SEC_WEP://WEP + { + returnValue = wlan_add_profile(profileArray[profileArray[0] + 2], // security type + ssidPtr, // SSID + ssidLen, // SSID length + NULL, // BSSID + 1, // Priority + keyLen, // KEY length + 0, // KEY index + 0, + decKeyPtr, // KEY + 0); + + break; + } + + case WLAN_SEC_WPA://WPA + case WLAN_SEC_WPA2://WPA2 + { + returnValue = wlan_add_profile(WLAN_SEC_WPA2, // security type + ssidPtr, + ssidLen, + NULL, // BSSID + 1, // Priority + 0x18, // PairwiseCipher + 0x1e, // GroupCipher + 2, // KEY management + decKeyPtr, // KEY + keyLen); // KEY length + + break; + } + } + + return returnValue; +} +#endif //CC3000_UNENCRYPTED_SMART_CONFIG + +//***************************************************************************** +// +// Close the Doxygen group. +//! @} +// +//***************************************************************************** |