Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: cc3000_ping_demo_try_2
Fork of cc3000_hostdriver_mbedsocket by
Diff: cc3000_wlan.cpp
- Revision:
- 0:615c697c33b0
- Child:
- 20:30b6ed7bf8fd
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_wlan.cpp Thu Sep 19 07:55:14 2013 +0000
@@ -0,0 +1,699 @@
+/*****************************************************************************
+*
+* C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
+* Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
+* provided help.
+*
+* This version of "host driver" uses CC3000 Host Driver Implementation. Thus
+* read the following copyright:
+*
+* 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.
+*
+*****************************************************************************/
+#include "cc3000.h"
+
+namespace mbed_cc3000 {
+
+cc3000_wlan::cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci) :
+ _simple_link(simple_link), _event(event), _spi(spi), _hci(hci) {
+
+}
+
+cc3000_wlan::~cc3000_wlan() {
+
+}
+
+void cc3000_wlan::simpleLink_init_start(uint16_t patches_available_host) {
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ UINT8_TO_STREAM(args, ((patches_available_host) ? 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);
+ _event.simplelink_wait_event(HCI_CMND_SIMPLE_LINK_START, 0);
+}
+
+void cc3000_wlan::start(uint16_t patches_available_host) {
+ uint32_t spi_irq_state;
+
+ _simple_link.set_sent_packets(0);
+ _simple_link.set_number_of_released_packets(0);
+ _simple_link.set_op_code(0);
+ _simple_link.set_number_free_buffers(0);
+ _simple_link.set_buffer_length(0);
+ _simple_link.set_buffer_size(0);
+ _simple_link.set_pending_data(0);
+ _simple_link.set_transmit_error(0);
+ _simple_link.set_data_received_flag(0);
+ _simple_link.set_buffer_size(0);
+
+ // init spi
+ _spi.open();
+ // Check the IRQ line
+ spi_irq_state = _spi.wlan_irq_read();
+ // ASIC 1273 chip enable: toggle WLAN EN line
+ _spi.write_wlan_en(WLAN_ENABLE);
+
+ if (spi_irq_state)
+ {
+ // wait till the IRQ line goes low
+ while(_spi.wlan_irq_read() != 0)
+ {
+ }
+ }
+ else
+ {
+ // wait till the IRQ line goes high and then low
+ while(_spi.wlan_irq_read() == 0)
+ {
+ }
+ while(_spi.wlan_irq_read() != 0)
+ {
+ }
+ }
+ simpleLink_init_start(patches_available_host);
+
+ // Read Buffer's size and finish
+ _hci.command_send(HCI_CMND_READ_BUFFER_SIZE, _simple_link.get_transmit_buffer(), 0);
+ _event.simplelink_wait_event(HCI_CMND_READ_BUFFER_SIZE, 0);
+}
+
+
+void cc3000_wlan::stop() {
+ // ASIC 1273 chip disable
+ _spi.write_wlan_en( WLAN_DISABLE );
+
+ // Wait till IRQ line goes high...
+ while(_spi.wlan_irq_read() == 0)
+ {
+ }
+
+ // Free the used by WLAN Driver memory
+ if (_simple_link.get_transmit_buffer())
+ {
+ _simple_link.set_transmit_buffer(0);
+ }
+
+ _spi.close();
+}
+
+
+int32_t cc3000_wlan::disconnect() {
+ int32_t ret;
+ uint8_t *ptr;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ _hci.command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_DISCONNECT, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::ioctl_set_connection_policy(uint32_t should_connect_to_open_ap,
+ uint32_t use_fast_connect,
+ uint32_t use_profiles) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ 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, should_connect_to_open_ap);
+ args = UINT32_TO_STREAM(args, use_fast_connect);
+ args = UINT32_TO_STREAM(args, use_profiles);
+
+ // 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::ioctl_del_profile(uint32_t index) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
+
+ // Fill in HCI packet structure
+ args = UINT32_TO_STREAM(args, index);
+ 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);
+
+ 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_t cc3000_wlan::smart_config_start(uint32_t encrypted_flag) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ 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, encrypted_flag);
+ ret = EFAIL;
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);
+
+ return(ret);
+}
+
+
+int32_t cc3000_wlan::smart_config_stop(void) {
+ int32_t ret;
+ uint8_t *ptr;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
+
+ return(ret);
+}
+
+int32_t cc3000_wlan::smart_config_set_prefix(uint8_t *new_prefix) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ if (new_prefix == NULL)
+ return ret;
+ else // with the new Smart Config, prefix must be TTT
+ {
+ *new_prefix = 'T';
+ *(new_prefix + 1) = 'T';
+ *(new_prefix + 2) = 'T';
+ }
+
+ ARRAY_TO_STREAM(args, new_prefix, 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
+
+ return(ret);
+}
+
+#ifndef CC3000_TINY_DRIVER
+int32_t cc3000_wlan::connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_len, uint8_t *bssid,
+ uint8_t *key, int32_t key_len) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+ uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ 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, sec_type);
+ 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
+ errno = ret;
+
+ return(ret);
+}
+
+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);
+}
+
+int32_t cc3000_wlan::ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results) {
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, scan_timeout);
+
+ // 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, results);
+
+ return(0);
+}
+
+int32_t cc3000_wlan::ioctl_set_scan_params(uint32_t enable,
+ uint32_t min_dwell_time,
+ uint32_t max_dwell_time,
+ uint32_t num_probe_requests,
+ uint32_t channel_mask,
+ int32_t rssi_threshold,
+ uint32_t snr_threshold,
+ uint32_t default_tx_power,
+ uint32_t *interval_list) {
+ uint32_t uiRes;
+ uint8_t *ptr;
+ uint8_t *args;
+
+ ptr = _simple_link.get_transmit_buffer();
+ args = (ptr + HEADERS_SIZE_CMD);
+
+ // Fill in temporary command buffer
+ args = UINT32_TO_STREAM(args, 36);
+ args = UINT32_TO_STREAM(args, enable);
+ args = UINT32_TO_STREAM(args, min_dwell_time);
+ args = UINT32_TO_STREAM(args, max_dwell_time);
+ args = UINT32_TO_STREAM(args, num_probe_requests);
+ args = UINT32_TO_STREAM(args, channel_mask);
+ args = UINT32_TO_STREAM(args, rssi_threshold);
+ args = UINT32_TO_STREAM(args, snr_threshold);
+ args = UINT32_TO_STREAM(args, default_tx_power);
+ ARRAY_TO_STREAM(args, interval_list, sizeof(uint32_t) * 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);
+
+ return(uiRes);
+}
+
+int32_t cc3000_wlan::ioctl_statusget(void) {
+ int32_t ret;
+ uint8_t *ptr;
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+
+ _hci.command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,ptr, 0);
+
+ // Wait for command complete event
+ _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);
+
+ return(ret);
+}
+
+#else
+int32_t cc3000_wlan::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_length)
+{
+ return -1;
+}
+
+int32_t cc3000_wlan::connect(const uint8_t *ssid, int32_t ssid_len) {
+ int32_t ret;
+ uint8_t *ptr;
+ uint8_t *args;
+ uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
+
+ ret = EFAIL;
+ ptr = _simple_link.get_transmit_buffer();
+ 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
+ _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
+ errno = ret;
+
+ return(ret);
+}
+#endif
+
+
+
+#ifndef CC3000_UNENCRYPTED_SMART_CONFIG
+int32_t cc3000_wlan::smart_config_process(void) {
+ int32_t returnValue;
+ uint32_t ssidLen, keyLen;
+ uint8_t *decKeyPtr;
+ uint8_t *ssidPtr;
+
+ // read the key from EEPROM - fileID 12
+ returnValue = aes_read_key(key);
+
+ 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, key);
+ if (profileArray[profileArray[0] + 1] > 16)
+ aes_decrypt((uint8_t *)(decKeyPtr + 16), key);
+
+ 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
+
+}
