erez i / cc3000_hostdriver_mbedsocket

Dependents:   cc3000_ping_demo_try_2

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     DigitalIn input_irq(D3);    //P21 input from button
00071 
00072     printf("CC3000 wlan start 1. \r\n");
00073     _simple_link.set_sent_packets(0);
00074     printf("CC3000 wlan start 2. \r\n");
00075     _simple_link.set_number_of_released_packets(0);
00076     printf("CC3000 wlan start 3. \r\n");
00077     _simple_link.set_op_code(0);
00078     printf("CC3000 wlan start 4. \r\n");
00079     _simple_link.set_number_free_buffers(0);
00080     printf("CC3000 wlan start 5. \r\n");
00081     _simple_link.set_buffer_length(0);
00082     printf("CC3000 wlan start 6. \r\n");
00083     _simple_link.set_buffer_size(0);
00084     printf("CC3000 wlan start 7. \r\n");
00085     _simple_link.set_pending_data(0);
00086     printf("CC3000 wlan start 8. \r\n");
00087     _simple_link.set_transmit_error(0);
00088     printf("CC3000 wlan start 9. \r\n");
00089     _simple_link.set_data_received_flag(0);
00090     printf("CC3000 wlan start 10. \r\n");
00091     _simple_link.set_buffer_size(0);
00092     printf("CC3000 wlan start 11. \r\n");
00093 
00094     // init spi
00095     _spi.open();
00096     printf("CC3000 wlan start 12. \r\n");
00097     // Check the IRQ line
00098     spi_irq_state = _spi.wlan_irq_read();
00099     printf("CC3000 wlan start 13. input_irq = %d \r\n",input_irq.read());
00100     // ASIC 1273 chip enable: toggle WLAN EN line
00101     _spi.set_wlan_en(WLAN_ENABLE);
00102     printf("CC3000 wlan start 14. input_irq = %d \r\n",input_irq.read());
00103 
00104     if (spi_irq_state) {
00105         // wait till the IRQ line goes low
00106         printf("CC3000 wlan start 15 before wait to irq. \r\n");
00107         while(_spi.wlan_irq_read() != 0){
00108             printf("CC3000 wlan start 15 in while. input_irq = %d\r\n",input_irq.read());
00109             wait(0.2);
00110             }
00111         printf("CC3000 wlan start 15. \r\n");
00112     } else {
00113         // wait till the IRQ line goes high and then low
00114         printf("CC3000 wlan start 16 before wait to irq. input_irq = %d\r\n",input_irq.read());
00115         while(_spi.wlan_irq_read() == 0){
00116             printf("CC3000 wlan start 16 in while. input_irq = %d\r\n",input_irq.read());
00117             wait(0.2);
00118             }
00119         printf("CC3000 wlan start 16. \r\n");
00120         while(_spi.wlan_irq_read() != 0);
00121         printf("CC3000 wlan start 17. \r\n");
00122     }
00123     printf("CC3000 wlan start 18. \r\n");
00124     simpleLink_init_start(patches_available_host);
00125     printf("CC3000 wlan start 19. \r\n");
00126 
00127     // Read Buffer's size and finish
00128     _hci.command_send(HCI_CMND_READ_BUFFER_SIZE, _simple_link.get_transmit_buffer(), 0);
00129     printf("CC3000 wlan start 20. \r\n");
00130     _event.simplelink_wait_event(HCI_CMND_READ_BUFFER_SIZE, 0);
00131     printf("CC3000 wlan start 21. \r\n");
00132 }
00133 
00134 
00135 void cc3000_wlan::stop() {
00136     // ASIC 1273 chip disable
00137     _spi.set_wlan_en(WLAN_DISABLE);
00138 
00139     // Wait till IRQ line goes high
00140     while(_spi.wlan_irq_read() == 0);
00141 
00142     _spi.close();
00143 }
00144 
00145 
00146 int32_t cc3000_wlan::disconnect() {
00147     int32_t ret;
00148     uint8_t *ptr;
00149 
00150     ret = EFAIL;
00151     ptr = _simple_link.get_transmit_buffer();
00152 
00153     _hci.command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);
00154 
00155     // Wait for command complete event
00156     _event.simplelink_wait_event(HCI_CMND_WLAN_DISCONNECT, &ret);
00157     errno = ret;
00158 
00159     return ret;
00160 }
00161 
00162 
00163 int32_t cc3000_wlan::ioctl_set_connection_policy(uint32_t should_connect_to_open_ap,
00164                                       uint32_t use_fast_connect,
00165                                       uint32_t use_profiles) {
00166     int32_t ret;
00167     uint8_t *ptr;
00168     uint8_t *args;
00169 
00170     ret = EFAIL;
00171     ptr = _simple_link.get_transmit_buffer();
00172     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00173 
00174     // Fill in HCI packet structure
00175     args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
00176     args = UINT32_TO_STREAM(args, use_fast_connect);
00177     args = UINT32_TO_STREAM(args, use_profiles);
00178 
00179     // Initiate a HCI command
00180     _hci.command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);
00181 
00182     // Wait for command complete event
00183     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);
00184 
00185     return ret;
00186 }
00187 
00188 
00189 int32_t cc3000_wlan::ioctl_del_profile(uint32_t index) {
00190     int32_t ret;
00191     uint8_t *ptr;
00192     uint8_t *args;
00193 
00194     ptr = _simple_link.get_transmit_buffer();
00195     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00196 
00197     // Fill in HCI packet structure
00198     args = UINT32_TO_STREAM(args, index);
00199     ret = EFAIL;
00200 
00201     // Initiate a HCI command
00202     _hci.command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, ptr, WLAN_DEL_PROFILE_PARAMS_LEN);
00203 
00204     // Wait for command complete event
00205     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);
00206 
00207     return ret;
00208 }
00209 
00210 int32_t cc3000_wlan::set_event_mask(uint32_t mask) {
00211     int32_t ret;
00212     uint8_t *ptr;
00213     uint8_t *args;
00214 
00215 
00216     if ((mask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE) {
00217         _simple_link.set_tx_complete_signal(0);
00218 
00219         // Since an event is a virtual event - i.e. it is not coming from CC3000
00220         // there is no need to send anything to the device if it was an only event
00221         if (mask == HCI_EVNT_WLAN_TX_COMPLETE) {
00222             return 0;
00223         }
00224 
00225         mask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
00226         mask |= HCI_EVNT_WLAN_UNSOL_BASE;
00227     } else {
00228         _simple_link.set_tx_complete_signal(1);
00229     }
00230 
00231     ret = EFAIL;
00232     ptr = _simple_link.get_transmit_buffer();
00233     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00234 
00235     // Fill in HCI packet structure
00236     args = UINT32_TO_STREAM(args, mask);
00237 
00238     // Initiate a HCI command
00239     _hci.command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN);
00240 
00241     // Wait for command complete event
00242     _event.simplelink_wait_event(HCI_CMND_EVENT_MASK, &ret);
00243 
00244     return ret;
00245 }
00246 
00247 
00248 int32_t cc3000_wlan::smart_config_start(uint32_t encrypted_flag) {
00249     int32_t ret;
00250     uint8_t *ptr;
00251     uint8_t *args;
00252 
00253     ret = EFAIL;
00254     ptr = _simple_link.get_transmit_buffer();
00255     args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);
00256 
00257     // Fill in HCI packet structure
00258     args = UINT32_TO_STREAM(args, encrypted_flag);
00259     ret = EFAIL;
00260 
00261     _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, WLAN_SMART_CONFIG_START_PARAMS_LEN);
00262 
00263     // Wait for command complete event
00264     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);
00265 
00266     return ret;
00267 }
00268 
00269 
00270 int32_t cc3000_wlan::smart_config_stop(void) {
00271     int32_t ret;
00272     uint8_t *ptr;
00273 
00274     ret = EFAIL;
00275     ptr = _simple_link.get_transmit_buffer();
00276 
00277     _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, ptr, 0);
00278 
00279     // Wait for command complete event
00280     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP, &ret);
00281 
00282     return ret;
00283 }
00284 
00285 int32_t cc3000_wlan::smart_config_set_prefix(uint8_t *new_prefix) {
00286     int32_t ret;
00287     uint8_t *ptr;
00288     uint8_t *args;
00289 
00290     ret = EFAIL;
00291     ptr = _simple_link.get_transmit_buffer();
00292     args = (ptr + HEADERS_SIZE_CMD);
00293 
00294     if (new_prefix == NULL) {
00295         return ret;
00296     } else {
00297         // with the new Smart Config, prefix must be TTT
00298         *new_prefix = 'T';
00299         *(new_prefix + 1) = 'T';
00300         *(new_prefix + 2) = 'T';
00301     }
00302 
00303     ARRAY_TO_STREAM(args, new_prefix, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
00304 
00305     _hci.command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, ptr, SL_SIMPLE_CONFIG_PREFIX_LENGTH);
00306 
00307     // Wait for command complete event
00308     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX, &ret);
00309 
00310     return ret;
00311 }
00312 
00313 #ifndef CC3000_TINY_DRIVER
00314 int32_t cc3000_wlan::connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_len, uint8_t *bssid,
00315               uint8_t *key, int32_t key_len) {
00316     int32_t ret;
00317     uint8_t *ptr;
00318     uint8_t *args;
00319     uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
00320 
00321     ret      = EFAIL;
00322     ptr      = _simple_link.get_transmit_buffer();
00323     args     = (ptr + HEADERS_SIZE_CMD);
00324 
00325     // Fill in command buffer
00326     args = UINT32_TO_STREAM(args, 0x0000001c);
00327     args = UINT32_TO_STREAM(args, ssid_len);
00328     args = UINT32_TO_STREAM(args, sec_type);
00329     args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
00330     args = UINT32_TO_STREAM(args, key_len);
00331     args = UINT16_TO_STREAM(args, 0);
00332 
00333     // padding shall be zeroed
00334     if (bssid) {
00335         ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
00336     } else {
00337         ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00338     }
00339 
00340     ARRAY_TO_STREAM(args, ssid, ssid_len);
00341 
00342     if (key_len && key) {
00343         ARRAY_TO_STREAM(args, key, key_len);
00344     }
00345 
00346     // Initiate a HCI command
00347     _hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len + key_len - 1);
00348 
00349     // Wait for command complete event
00350     _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
00351     errno = ret;
00352 
00353     return ret;
00354 }
00355 
00356 int32_t cc3000_wlan::add_profile(uint32_t sec_type,
00357                       uint8_t* ssid,
00358                       uint32_t ssid_length,
00359                       uint8_t *b_ssid,
00360                       uint32_t priority,
00361                       uint32_t pairwise_cipher_or_tx_key_len,
00362                       uint32_t group_cipher_tx_key_index,
00363                       uint32_t key_mgmt,
00364                       uint8_t* pf_or_key,
00365                       uint32_t pass_phrase_len) {
00366     uint16_t arg_len = 0x00;
00367     int32_t ret;
00368     uint8_t *ptr;
00369     int32_t i = 0;
00370     uint8_t *args;
00371     uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
00372 
00373     ptr = _simple_link.get_transmit_buffer();
00374     args = (ptr + HEADERS_SIZE_CMD);
00375 
00376     args = UINT32_TO_STREAM(args, sec_type);
00377 
00378     // Setup arguments in accordance with the security type
00379     switch (sec_type)
00380     {
00381         //OPEN
00382         case WLAN_SEC_UNSEC:
00383         {
00384             args = UINT32_TO_STREAM(args, 0x00000014);
00385             args = UINT32_TO_STREAM(args, ssid_length);
00386             args = UINT16_TO_STREAM(args, 0);
00387             if(b_ssid) {
00388                 ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
00389             } else {
00390                 ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00391             }
00392             args = UINT32_TO_STREAM(args, priority);
00393             ARRAY_TO_STREAM(args, ssid, ssid_length);
00394 
00395             arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length;
00396         }
00397         break;
00398 
00399         //WEP
00400         case WLAN_SEC_WEP:
00401         {
00402             args = UINT32_TO_STREAM(args, 0x00000020);
00403             args = UINT32_TO_STREAM(args, ssid_length);
00404             args = UINT16_TO_STREAM(args, 0);
00405             if (b_ssid) {
00406                 ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
00407             } else {
00408                 ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00409             }
00410             args = UINT32_TO_STREAM(args, priority);
00411             args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length);
00412             args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
00413             args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
00414             ARRAY_TO_STREAM(args, ssid, ssid_length);
00415 
00416             for(i = 0; i < 4; i++) {
00417                 uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len];
00418 
00419                 ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len);
00420             }
00421 
00422             arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length +
00423                 pairwise_cipher_or_tx_key_len * 4;
00424 
00425         }
00426         break;
00427 
00428         //WPA
00429         //WPA2
00430         case WLAN_SEC_WPA:
00431         case WLAN_SEC_WPA2:
00432         {
00433             args = UINT32_TO_STREAM(args, 0x00000028);
00434             args = UINT32_TO_STREAM(args, ssid_length);
00435             args = UINT16_TO_STREAM(args, 0);
00436             if (b_ssid) {
00437                 ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
00438             } else {
00439                 ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00440             }
00441             args = UINT32_TO_STREAM(args, priority);
00442             args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
00443             args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
00444             args = UINT32_TO_STREAM(args, key_mgmt);
00445             args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length);
00446             args = UINT32_TO_STREAM(args, pass_phrase_len);
00447             ARRAY_TO_STREAM(args, ssid, ssid_length);
00448             ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len);
00449 
00450             arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len;
00451         }
00452 
00453         break;
00454     }
00455 
00456     // Initiate a HCI command
00457     _hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len);
00458 
00459     // Wait for command complete event
00460     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);
00461 
00462     return ret;
00463 }
00464 
00465 int32_t cc3000_wlan::ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results) {
00466     uint8_t *ptr;
00467     uint8_t *args;
00468 
00469     ptr = _simple_link.get_transmit_buffer();
00470     args = (ptr + HEADERS_SIZE_CMD);
00471 
00472     // Fill in temporary command buffer
00473     args = UINT32_TO_STREAM(args, scan_timeout);
00474 
00475     // Initiate a HCI command
00476     _hci.command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);
00477 
00478     // Wait for command complete event
00479     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, results);
00480 
00481     return 0;
00482 }
00483 
00484 int32_t cc3000_wlan::ioctl_set_scan_params(uint32_t enable,
00485                                 uint32_t min_dwell_time,
00486                                 uint32_t max_dwell_time,
00487                                 uint32_t num_probe_requests,
00488                                 uint32_t channel_mask,
00489                                 int32_t rssi_threshold,
00490                                 uint32_t snr_threshold,
00491                                 uint32_t default_tx_power,
00492                                 uint32_t *interval_list) {
00493     uint32_t  uiRes;
00494     uint8_t *ptr;
00495     uint8_t *args;
00496 
00497     ptr = _simple_link.get_transmit_buffer();
00498     args = (ptr + HEADERS_SIZE_CMD);
00499 
00500     // Fill in temporary command buffer
00501     args = UINT32_TO_STREAM(args, 36);
00502     args = UINT32_TO_STREAM(args, enable);
00503     args = UINT32_TO_STREAM(args, min_dwell_time);
00504     args = UINT32_TO_STREAM(args, max_dwell_time);
00505     args = UINT32_TO_STREAM(args, num_probe_requests);
00506     args = UINT32_TO_STREAM(args, channel_mask);
00507     args = UINT32_TO_STREAM(args, rssi_threshold);
00508     args = UINT32_TO_STREAM(args, snr_threshold);
00509     args = UINT32_TO_STREAM(args, default_tx_power);
00510     ARRAY_TO_STREAM(args, interval_list, sizeof(uint32_t) * SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE);
00511 
00512     // Initiate a HCI command
00513     _hci.command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, ptr, WLAN_SET_SCAN_PARAMS_LEN);
00514 
00515     // Wait for command complete event
00516     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);
00517 
00518     return(uiRes);
00519 }
00520 
00521 int32_t cc3000_wlan::ioctl_statusget(void) {
00522     int32_t ret;
00523     uint8_t *ptr;
00524 
00525     ret = EFAIL;
00526     ptr = _simple_link.get_transmit_buffer();
00527 
00528     _hci.command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,ptr, 0);
00529 
00530     // Wait for command complete event
00531     _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);
00532 
00533     return ret;
00534 }
00535 
00536 #else
00537 int32_t cc3000_wlan::add_profile(uint32_t sec_type,
00538                       uint8_t *ssid,
00539                       uint32_t ssid_length,
00540                       uint8_t *b_ssid,
00541                       uint32_t priority,
00542                       uint32_t pairwise_cipher_or_tx_key_len,
00543                       uint32_t group_cipher_tx_key_index,
00544                       uint32_t key_mgmt,
00545                       uint8_t* pf_or_key,
00546                       uint32_t pass_phrase_length)
00547 {
00548     return -1;
00549 }
00550 
00551 int32_t cc3000_wlan::connect(const uint8_t *ssid, int32_t ssid_len) {
00552     int32_t ret;
00553     uint8_t *ptr;
00554     uint8_t *args;
00555     uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};
00556 
00557     ret      = EFAIL;
00558     ptr      = _simple_link.get_transmit_buffer();
00559     args     = (ptr + HEADERS_SIZE_CMD);
00560 
00561     // Fill in command buffer
00562     args = UINT32_TO_STREAM(args, 0x0000001c);
00563     args = UINT32_TO_STREAM(args, ssid_len);
00564     args = UINT32_TO_STREAM(args, 0);
00565     args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
00566     args = UINT32_TO_STREAM(args, 0);
00567     args = UINT16_TO_STREAM(args, 0);
00568 
00569     // padding shall be zeroed
00570     ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
00571     ARRAY_TO_STREAM(args, ssid, ssid_len);
00572 
00573     // Initiate a HCI command
00574     _hci.command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN + ssid_len  - 1);
00575 
00576     // Wait for command complete event
00577     _event.simplelink_wait_event(HCI_CMND_WLAN_CONNECT, &ret);
00578     errno = ret;
00579 
00580     return ret;
00581 }
00582 #endif
00583 
00584 
00585 
00586 #ifndef CC3000_UNENCRYPTED_SMART_CONFIG
00587 int32_t cc3000_wlan::smart_config_process(void) {
00588     int32_t  returnValue;
00589     uint32_t ssidLen, keyLen;
00590     uint8_t *decKeyPtr;
00591     uint8_t *ssidPtr;
00592 
00593     // read the key from EEPROM - fileID 12
00594     returnValue = aes_read_key(key);
00595 
00596     if (returnValue != 0)
00597         return returnValue;
00598 
00599     // read the received data from fileID #13 and parse it according to the followings:
00600     // 1) SSID LEN - not encrypted
00601     // 2) SSID - not encrypted
00602     // 3) KEY LEN - not encrypted. always 32 bytes long
00603     // 4) Security type - not encrypted
00604     // 5) KEY - encrypted together with true key length as the first byte in KEY
00605     //     to elaborate, there are two corner cases:
00606     //        1) the KEY is 32 bytes long. In this case, the first byte does not represent KEY length
00607     //        2) the KEY is 31 bytes long. In this case, the first byte represent KEY length and equals 31
00608     returnValue = nvmem_read(NVMEM_SHARED_MEM_FILEID, SMART_CONFIG_PROFILE_SIZE, 0, profileArray);
00609 
00610     if (returnValue != 0)
00611         return returnValue;
00612 
00613     ssidPtr = &profileArray[1];
00614 
00615     ssidLen = profileArray[0];
00616 
00617     decKeyPtr = &profileArray[profileArray[0] + 3];
00618 
00619     aes_decrypt(decKeyPtr, key);
00620     if (profileArray[profileArray[0] + 1] > 16)
00621         aes_decrypt((uint8_t *)(decKeyPtr + 16), key);
00622 
00623     if (*(uint8_t *)(decKeyPtr +31) != 0) {
00624         if (*decKeyPtr == 31) {
00625             keyLen = 31;
00626             decKeyPtr++;
00627         } else {
00628             keyLen = 32;
00629         }
00630     } else {
00631         keyLen = *decKeyPtr;
00632         decKeyPtr++;
00633     }
00634 
00635     // add a profile
00636     switch (profileArray[profileArray[0] + 2])
00637     {
00638     case WLAN_SEC_UNSEC://None
00639          {
00640             returnValue = wlan_add_profile(profileArray[profileArray[0] + 2],     // security type
00641                                            ssidPtr,                               // SSID
00642                                            ssidLen,                               // SSID length
00643                                            NULL,                                  // BSSID
00644                                            1,                                     // Priority
00645                                            0, 0, 0, 0, 0);
00646 
00647             break;
00648          }
00649 
00650     case WLAN_SEC_WEP://WEP
00651         {
00652             returnValue = wlan_add_profile(profileArray[profileArray[0] + 2],     // security type
00653                                            ssidPtr,                               // SSID
00654                                            ssidLen,                               // SSID length
00655                                            NULL,                                  // BSSID
00656                                            1,                                     // Priority
00657                                            keyLen,                                // KEY length
00658                                            0,                                     // KEY index
00659                                            0,
00660                                            decKeyPtr,                             // KEY
00661                                            0);
00662 
00663             break;
00664         }
00665 
00666     case WLAN_SEC_WPA:  //WPA
00667     case WLAN_SEC_WPA2: //WPA2
00668         {
00669             returnValue = wlan_add_profile(WLAN_SEC_WPA2,     // security type
00670                                            ssidPtr,
00671                                            ssidLen,
00672                                            NULL,              // BSSID
00673                                            1,                 // Priority
00674                                            0x18,              // PairwiseCipher
00675                                            0x1e,              // GroupCipher
00676                                            2,                 // KEY management
00677                                            decKeyPtr,         // KEY
00678                                            keyLen);           // KEY length
00679 
00680             break;
00681         }
00682     }
00683 
00684     return returnValue;
00685 }
00686 #endif
00687 
00688 }