None

Fork of cc3000_hostdriver_mbedsocket by Martin Kojtal

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers cc3000_wlan.cpp Source File

cc3000_wlan.cpp

00001 /*****************************************************************************
00002 *
00003 *  C++ interface/implementation created by Martin Kojtal (0xc0170). Thanks to
00004 *  Jim Carver and Frank Vannieuwkerke for their inital cc3000 mbed port and
00005 *  provided help.
00006 *
00007 *  This version of "host driver" uses CC3000 Host Driver Implementation. Thus
00008 *  read the following copyright:
00009 *
00010 *  Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
00011 *
00012 *  Redistribution and use in source and binary forms, with or without
00013 *  modification, are permitted provided that the following conditions
00014 *  are met:
00015 *
00016 *    Redistributions of source code must retain the above copyright
00017 *    notice, this list of conditions and the following disclaimer.
00018 *
00019 *    Redistributions in binary form must reproduce the above copyright
00020 *    notice, this list of conditions and the following disclaimer in the
00021 *    documentation and/or other materials provided with the
00022 *    distribution.
00023 *
00024 *    Neither the name of Texas Instruments Incorporated nor the names of
00025 *    its contributors may be used to endorse or promote products derived
00026 *    from this software without specific prior written permission.
00027 *
00028 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00029 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00030 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00031 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00032 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00033 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00034 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00035 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00036 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00037 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00038 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00039 *
00040 *****************************************************************************/
00041 #include "cc3000.h"
00042 
00043 namespace mbed_cc3000 {
00044 
00045 cc3000_wlan::cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci) :
00046     _simple_link(simple_link), _event(event), _spi(spi), _hci(hci) {
00047 
00048 }
00049 
00050 cc3000_wlan::~cc3000_wlan() {
00051 
00052 }
00053 
00054 void cc3000_wlan::simpleLink_init_start(uint16_t patches_available_host) {
00055     uint8_t *ptr;
00056     uint8_t *args;
00057 
00058     ptr = _simple_link.get_transmit_buffer();
00059     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00060 
00061     UINT8_TO_STREAM(args, ((patches_available_host) ? SL_PATCHES_REQUEST_FORCE_HOST : SL_PATCHES_REQUEST_DEFAULT));
00062 
00063     // IRQ Line asserted - send HCI_CMND_SIMPLE_LINK_START to CC3000
00064     _hci.command_send(HCI_CMND_SIMPLE_LINK_START, ptr, WLAN_SL_INIT_START_PARAMS_LEN);
00065     _event.simplelink_wait_event(HCI_CMND_SIMPLE_LINK_START, 0);
00066 }
00067 
00068 void cc3000_wlan::start(uint16_t patches_available_host) {
00069     uint32_t spi_irq_state;
00070 
00071     _simple_link.set_sent_packets(0);
00072     _simple_link.set_number_of_released_packets(0);
00073     _simple_link.set_op_code(0);
00074     _simple_link.set_number_free_buffers(0);
00075     _simple_link.set_buffer_length(0);
00076     _simple_link.set_buffer_size(0);
00077     _simple_link.set_pending_data(0);
00078     _simple_link.set_transmit_error(0);
00079     _simple_link.set_data_received_flag(0);
00080     _simple_link.set_buffer_size(0);
00081 
00082     // init spi
00083     _spi.open();
00084     // Check the IRQ line
00085     spi_irq_state = _spi.wlan_irq_read();
00086     // ASIC 1273 chip enable: toggle WLAN EN line
00087     _spi.set_wlan_en(WLAN_ENABLE);
00088 
00089     if (spi_irq_state) {
00090         // wait till the IRQ line goes low
00091         while(_spi.wlan_irq_read() != 0);
00092     } else {
00093         // wait till the IRQ line goes high and then low
00094         while(_spi.wlan_irq_read() == 0);
00095         while(_spi.wlan_irq_read() != 0);
00096     }
00097     simpleLink_init_start(patches_available_host);
00098 
00099     // Read Buffer's size and finish
00100     _hci.command_send(HCI_CMND_READ_BUFFER_SIZE, _simple_link.get_transmit_buffer(), 0);
00101     _event.simplelink_wait_event(HCI_CMND_READ_BUFFER_SIZE, 0);
00102 }
00103 
00104 
00105 void cc3000_wlan::stop() {
00106     // ASIC 1273 chip disable
00107     _spi.set_wlan_en(WLAN_DISABLE);
00108 
00109     // Wait till IRQ line goes high
00110     while(_spi.wlan_irq_read() == 0);
00111 
00112     _spi.close();
00113 }
00114 
00115 
00116 int32_t cc3000_wlan::disconnect() {
00117     int32_t ret;
00118     uint8_t *ptr;
00119 
00120     ret = EFAIL;
00121     ptr = _simple_link.get_transmit_buffer();
00122 
00123     _hci.command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);
00124 
00125     // Wait for command complete event
00126     _event.simplelink_wait_event(HCI_CMND_WLAN_DISCONNECT, &ret);
00127     errno = ret;
00128 
00129     return ret;
00130 }
00131 
00132 
00133 int32_t cc3000_wlan::ioctl_set_connection_policy(uint32_t should_connect_to_open_ap,
00134                                       uint32_t use_fast_connect,
00135                                       uint32_t use_profiles) {
00136     int32_t ret;
00137     uint8_t *ptr;
00138     uint8_t *args;
00139 
00140     ret = EFAIL;
00141     ptr = _simple_link.get_transmit_buffer();
00142     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00143 
00144     // Fill in HCI packet structure
00145     args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
00146     args = UINT32_TO_STREAM(args, use_fast_connect);
00147     args = UINT32_TO_STREAM(args, use_profiles);
00148 
00149     // Initiate a HCI command
00150     _hci.command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);
00151 
00152     // Wait for command complete event
00153     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);
00154 
00155     return ret;
00156 }
00157 
00158 
00159 int32_t cc3000_wlan::ioctl_del_profile(uint32_t index) {
00160     int32_t ret;
00161     uint8_t *ptr;
00162     uint8_t *args;
00163 
00164     ptr = _simple_link.get_transmit_buffer();
00165     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00166 
00167     // Fill in HCI packet structure
00168     args = UINT32_TO_STREAM(args, index);
00169     ret = EFAIL;
00170 
00171     // Initiate a HCI command
00172     _hci.command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN);
00173 
00174     // Wait for command complete event
00175     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);
00176 
00177     return ret;
00178 }
00179 
00180 int32_t cc3000_wlan::set_event_mask(uint32_t mask) {
00181     int32_t ret;
00182     uint8_t *ptr;
00183     uint8_t *args;
00184 
00185 
00186     if ((mask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) {
00187         _simple_link.set_tx_complete_signal(0);
00188 
00189         // Since an event is a virtual event - i.e. it is not coming from CC3000
00190         // there is no need to send anything to the device if it was an only event
00191         if (mask == HCI_EVNT_WLAN_TX_COMPLETE) {
00192             return 0;
00193         }
00194 
00195         mask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
00196         mask |= HCI_EVNT_WLAN_UNSOL_BASE;
00197     } else {
00198         _simple_link.set_tx_complete_signal(1);
00199     }
00200 
00201     ret = EFAIL;
00202     ptr = _simple_link.get_transmit_buffer();
00203     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00204 
00205     // Fill in HCI packet structure
00206     args = UINT32_TO_STREAM(args, mask);
00207 
00208     // Initiate a HCI command
00209     _hci.command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN);
00210 
00211     // Wait for command complete event
00212     _event.simplelink_wait_event(HCI_CMND_EVENT_MASK, &ret);
00213 
00214     return ret;
00215 }
00216 
00217 
00218 int32_t cc3000_wlan::smart_config_start(uint32_t encrypted_flag) {
00219     int32_t ret;
00220     uint8_t *ptr;
00221     uint8_t *args;
00222 
00223     ret = EFAIL;
00224     ptr = _simple_link.get_transmit_buffer();
00225     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00226 
00227     // Fill in HCI packet structure
00228     args = UINT32_TO_STREAM(args, encrypted_flag);
00229     ret = EFAIL;
00230 
00231     _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN);
00232 
00233     // Wait for command complete event
00234     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);
00235 
00236     return ret;
00237 }
00238 
00239 
00240 int32_t cc3000_wlan::smart_config_stop(void) {
00241     int32_t ret;
00242     uint8_t *ptr;
00243 
00244     ret = EFAIL;
00245     ptr = _simple_link.get_transmit_buffer();
00246 
00247     _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
00248 
00249     // Wait for command complete event
00250     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
00251 
00252     return ret;
00253 }
00254 
00255 int32_t cc3000_wlan::smart_config_set_prefix(uint8_t *new_prefix) {
00256     int32_t ret;
00257     uint8_t *ptr;
00258     uint8_t *args;
00259 
00260     ret = EFAIL;
00261     ptr = _simple_link.get_transmit_buffer();
00262     args = (ptr + HEADERS_SIZE_CMD);
00263 
00264     if (new_prefix == NULL) {
00265         return ret;
00266     } else {
00267         // with the new Smart Config, prefix must be TTT
00268         *new_prefix = 'T';
00269         *(new_prefix + 1) = 'T';
00270         *(new_prefix + 2) = 'T';
00271     }
00272 
00273     ARRAY_TO_STREAM(args, new_prefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
00274 
00275     _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
00276 
00277     // Wait for command complete event
00278     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
00279 
00280     return ret;
00281 }
00282 
00283 #ifndef CC3000_TINY_DRIVER
00284 int32_t cc3000_wlan::connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_len, uint8_t *bssid,
00285               uint8_t *key, int32_t key_len) {
00286     int32_t ret;
00287     uint8_t *ptr;
00288     uint8_t *args;
00289     uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
00290 
00291     ret      = EFAIL;
00292     ptr      = _simple_link.get_transmit_buffer();
00293     args     = (ptr + HEADERS_SIZE_CMD);
00294 
00295     // Fill in command buffer
00296     args = UINT32_TO_STREAM(args, 0x0000001c);
00297     args = UINT32_TO_STREAM(args, ssid_len);
00298     args = UINT32_TO_STREAM(args, sec_type);
00299     args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
00300     args = UINT32_TO_STREAM(args, key_len);
00301     args = UINT16_TO_STREAM(args, 0);
00302 
00303     // padding shall be zeroed
00304     if (bssid) {
00305         ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
00306     } else {
00307         ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00308     }
00309 
00310     ARRAY_TO_STREAM(args, ssid, ssid_len);
00311 
00312     if (key_len && key) {
00313         ARRAY_TO_STREAM(args, key, key_len);
00314     }
00315 
00316     // Initiate a HCI command
00317     _hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len + key_len - 1);
00318 
00319     // Wait for command complete event
00320     _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
00321     errno = ret;
00322 
00323     return ret;
00324 }
00325 
00326 int32_t cc3000_wlan::add_profile(uint32_t sec_type,
00327                       uint8_t* ssid,
00328                       uint32_t ssid_length,
00329                       uint8_t *b_ssid,
00330                       uint32_t priority,
00331                       uint32_t pairwise_cipher_or_tx_key_len,
00332                       uint32_t group_cipher_tx_key_index,
00333                       uint32_t key_mgmt,
00334                       uint8_t* pf_or_key,
00335                       uint32_t pass_phrase_len) {
00336     uint16_t arg_len = 0x00;
00337     int32_t ret;
00338     uint8_t *ptr;
00339     int32_t i = 0;
00340     uint8_t *args;
00341     uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
00342 
00343     ptr = _simple_link.get_transmit_buffer();
00344     args = (ptr + HEADERS_SIZE_CMD);
00345 
00346     args = UINT32_TO_STREAM(args, sec_type);
00347 
00348     // Setup arguments in accordance with the security type
00349     switch (sec_type)
00350     {
00351         //OPEN
00352         case WLAN_SEC_UNSEC:
00353         {
00354             args = UINT32_TO_STREAM(args, 0x00000014);
00355             args = UINT32_TO_STREAM(args, ssid_length);
00356             args = UINT16_TO_STREAM(args, 0);
00357             if(b_ssid) {
00358                 ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
00359             } else {
00360                 ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00361             }
00362             args = UINT32_TO_STREAM(args, priority);
00363             ARRAY_TO_STREAM(args, ssid, ssid_length);
00364 
00365             arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length;
00366         }
00367         break;
00368 
00369         //WEP
00370         case WLAN_SEC_WEP:
00371         {
00372             args = UINT32_TO_STREAM(args, 0x00000020);
00373             args = UINT32_TO_STREAM(args, ssid_length);
00374             args = UINT16_TO_STREAM(args, 0);
00375             if (b_ssid) {
00376                 ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
00377             } else {
00378                 ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00379             }
00380             args = UINT32_TO_STREAM(args, priority);
00381             args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length);
00382             args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
00383             args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
00384             ARRAY_TO_STREAM(args, ssid, ssid_length);
00385 
00386             for(i = 0; i < 4; i++) {
00387                 uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len];
00388 
00389                 ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len);
00390             }
00391 
00392             arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length +
00393                 pairwise_cipher_or_tx_key_len * 4;
00394 
00395         }
00396         break;
00397 
00398         //WPA
00399         //WPA2
00400         case WLAN_SEC_WPA:
00401         case WLAN_SEC_WPA2:
00402         {
00403             args = UINT32_TO_STREAM(args, 0x00000028);
00404             args = UINT32_TO_STREAM(args, ssid_length);
00405             args = UINT16_TO_STREAM(args, 0);
00406             if (b_ssid) {
00407                 ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
00408             } else {
00409                 ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00410             }
00411             args = UINT32_TO_STREAM(args, priority);
00412             args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
00413             args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
00414             args = UINT32_TO_STREAM(args, key_mgmt);
00415             args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length);
00416             args = UINT32_TO_STREAM(args, pass_phrase_len);
00417             ARRAY_TO_STREAM(args, ssid, ssid_length);
00418             ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len);
00419 
00420             arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len;
00421         }
00422 
00423         break;
00424     }
00425 
00426     // Initiate a HCI command
00427     _hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len);
00428 
00429     // Wait for command complete event
00430     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);
00431 
00432     return ret;
00433 }
00434 
00435 int32_t cc3000_wlan::ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results) {
00436     uint8_t *ptr;
00437     uint8_t *args;
00438 
00439     ptr = _simple_link.get_transmit_buffer();
00440     args = (ptr + HEADERS_SIZE_CMD);
00441 
00442     // Fill in temporary command buffer
00443     args = UINT32_TO_STREAM(args, scan_timeout);
00444 
00445     // Initiate a HCI command
00446     _hci.command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);
00447 
00448     // Wait for command complete event
00449     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, results);
00450 
00451     return 0;
00452 }
00453 
00454 int32_t cc3000_wlan::ioctl_set_scan_params(uint32_t enable,
00455                                 uint32_t min_dwell_time,
00456                                 uint32_t max_dwell_time,
00457                                 uint32_t num_probe_requests,
00458                                 uint32_t channel_mask,
00459                                 int32_t rssi_threshold,
00460                                 uint32_t snr_threshold,
00461                                 uint32_t default_tx_power,
00462                                 uint32_t *interval_list) {
00463     uint32_t  uiRes;
00464     uint8_t *ptr;
00465     uint8_t *args;
00466 
00467     ptr = _simple_link.get_transmit_buffer();
00468     args = (ptr + HEADERS_SIZE_CMD);
00469 
00470     // Fill in temporary command buffer
00471     args = UINT32_TO_STREAM(args, 36);
00472     args = UINT32_TO_STREAM(args, enable);
00473     args = UINT32_TO_STREAM(args, min_dwell_time);
00474     args = UINT32_TO_STREAM(args, max_dwell_time);
00475     args = UINT32_TO_STREAM(args, num_probe_requests);
00476     args = UINT32_TO_STREAM(args, channel_mask);
00477     args = UINT32_TO_STREAM(args, rssi_threshold);
00478     args = UINT32_TO_STREAM(args, snr_threshold);
00479     args = UINT32_TO_STREAM(args, default_tx_power);
00480     ARRAY_TO_STREAM(args, interval_list, sizeof(uint32_t) * SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE);
00481 
00482     // Initiate a HCI command
00483     _hci.command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, ptr, WLAN_SET_SCAN_PARAMS_LEN);
00484 
00485     // Wait for command complete event
00486     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);
00487 
00488     return(uiRes);
00489 }
00490 
00491 int32_t cc3000_wlan::ioctl_statusget(void) {
00492     int32_t ret;
00493     uint8_t *ptr;
00494 
00495     ret = EFAIL;
00496     ptr = _simple_link.get_transmit_buffer();
00497 
00498     _hci.command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,ptr, 0);
00499 
00500     // Wait for command complete event
00501     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);
00502 
00503     return ret;
00504 }
00505 
00506 #else
00507 int32_t cc3000_wlan::add_profile(uint32_t sec_type,
00508                       uint8_t *ssid,
00509                       uint32_t ssid_length,
00510                       uint8_t *b_ssid,
00511                       uint32_t priority,
00512                       uint32_t pairwise_cipher_or_tx_key_len,
00513                       uint32_t group_cipher_tx_key_index,
00514                       uint32_t key_mgmt,
00515                       uint8_t* pf_or_key,
00516                       uint32_t pass_phrase_length)
00517 {
00518     return -1;
00519 }
00520 
00521 int32_t cc3000_wlan::connect(const uint8_t *ssid, int32_t ssid_len) {
00522     int32_t ret;
00523     uint8_t *ptr;
00524     uint8_t *args;
00525     uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
00526 
00527     ret      = EFAIL;
00528     ptr      = _simple_link.get_transmit_buffer();
00529     args     = (ptr + HEADERS_SIZE_CMD);
00530 
00531     // Fill in command buffer
00532     args = UINT32_TO_STREAM(args, 0x0000001c);
00533     args = UINT32_TO_STREAM(args, ssid_len);
00534     args = UINT32_TO_STREAM(args, 0);
00535     args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
00536     args = UINT32_TO_STREAM(args, 0);
00537     args = UINT16_TO_STREAM(args, 0);
00538 
00539     // padding shall be zeroed
00540     ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00541     ARRAY_TO_STREAM(args, ssid, ssid_len);
00542 
00543     // Initiate a HCI command
00544     _hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len  - 1);
00545 
00546     // Wait for command complete event
00547     _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
00548     errno = ret;
00549 
00550     return ret;
00551 }
00552 #endif
00553 
00554 
00555 
00556 #ifndef CC3000_UNENCRYPTED_SMART_CONFIG
00557 int32_t cc3000_wlan::smart_config_process(void) {
00558     int32_t  returnValue;
00559     uint32_t ssidLen, keyLen;
00560     uint8_t *decKeyPtr;
00561     uint8_t *ssidPtr;
00562 
00563     // read the key from EEPROM - fileID 12
00564     returnValue = aes_read_key(key);
00565 
00566     if (returnValue != 0)
00567         return returnValue;
00568 
00569     // read the received data from fileID #13 and parse it according to the followings:
00570     // 1) SSID LEN - not encrypted
00571     // 2) SSID - not encrypted
00572     // 3) KEY LEN - not encrypted. always 32 bytes long
00573     // 4) Security type - not encrypted
00574     // 5) KEY - encrypted together with true key length as the first byte in KEY
00575     //     to elaborate, there are two corner cases:
00576     //        1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
00577     //        2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
00578     returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray);
00579 
00580     if (returnValue != 0)
00581         return returnValue;
00582 
00583     ssidPtr = &profileArray[1];
00584 
00585     ssidLen = profileArray[0];
00586 
00587     decKeyPtr = &profileArray[profileArray[0] + 3];
00588 
00589     aes_decrypt(decKeyPtr, key);
00590     if (profileArray[profileArray[0] + 1] > 16)
00591         aes_decrypt((uint8_t *)(decKeyPtr + 16), key);
00592 
00593     if (*(uint8_t *)(decKeyPtr +31) != 0) {
00594         if (*decKeyPtr == 31) {
00595             keyLen = 31;
00596             decKeyPtr++;
00597         } else {
00598             keyLen = 32;
00599         }
00600     } else {
00601         keyLen = *decKeyPtr;
00602         decKeyPtr++;
00603     }
00604 
00605     // add a profile
00606     switch (profileArray[profileArray[0] + 2])
00607     {
00608     case WLAN_SEC_UNSEC://None
00609          {
00610             returnValue = wlan_add_profile(profileArray[profileArray[0] + 2],     // security type
00611                                            ssidPtr,                               // SSID
00612                                            ssidLen,                               // SSID length
00613                                            NULL,                                  // BSSID
00614                                            1,                                     // Priority
00615                                            0, 0, 0, 0, 0);
00616 
00617             break;
00618          }
00619 
00620     case WLAN_SEC_WEP://WEP
00621         {
00622             returnValue = wlan_add_profile(profileArray[profileArray[0] + 2],     // security type
00623                                            ssidPtr,                               // SSID
00624                                            ssidLen,                               // SSID length
00625                                            NULL,                                  // BSSID
00626                                            1,                                     // Priority
00627                                            keyLen,                                // KEY length
00628                                            0,                                     // KEY index
00629                                            0,
00630                                            decKeyPtr,                             // KEY
00631                                            0);
00632 
00633             break;
00634         }
00635 
00636     case WLAN_SEC_WPA:  //WPA
00637     case WLAN_SEC_WPA2: //WPA2
00638         {
00639             returnValue = wlan_add_profile(WLAN_SEC_WPA2,     // security type
00640                                            ssidPtr,
00641                                            ssidLen,
00642                                            NULL,              // BSSID
00643                                            1,                 // Priority
00644                                            0x18,              // PairwiseCipher
00645                                            0x1e,              // GroupCipher
00646                                            2,                 // KEY management
00647                                            decKeyPtr,         // KEY
00648                                            keyLen);           // KEY length
00649 
00650             break;
00651         }
00652     }
00653 
00654     return returnValue;
00655 }
00656 #endif
00657 
00658 }