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
cc3000.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 #include "cc3000_event.h" 00043 00044 namespace mbed_cc3000 { 00045 00046 /* TODO this prefix remove? verify */ 00047 static uint8_t cc3000_prefix[] = {'T', 'T', 'T'}; 00048 cc3000 *cc3000::_inst; 00049 00050 cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi) 00051 : _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event), 00052 _spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, _event, _simple_link), _hci(_spi), 00053 _nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event), 00054 _wlan(_simple_link, _event, _spi, _hci) { 00055 _simple_link.set_tx_complete_signal(1); 00056 memset(&_status, 0, sizeof(_status)); 00057 _inst = this; 00058 } 00059 00060 cc3000::~cc3000() { 00061 } 00062 00063 #if (CC3000_ETH_COMPAT == 1) 00064 cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, const char *ssid, 00065 const char *phrase, Security sec, bool smart_config) 00066 : _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event), 00067 _spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, _event, _simple_link), _hci(_spi), 00068 _nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event), 00069 _wlan(_simple_link, _event, _spi, _hci), _sec(sec), _smart_config(smart_config) { 00070 _simple_link.set_tx_complete_signal(1); 00071 memset(&_status, 0, sizeof(_status)); 00072 strcpy((char *)_ssid, ssid); 00073 strcpy((char *)_phrase, phrase); 00074 _inst = this; 00075 } 00076 00077 // Ethernet library compatible, functions return strings 00078 // Caches the ipconfig from the usync callback 00079 static char mac_addr[19]= "\0"; 00080 static char ip_addr[17] = "\0"; 00081 static char gateway[17] = "\0"; 00082 static char networkmask[17] = "\0"; 00083 00084 void cc3000::init() { 00085 printf("CC3000 init start. \r\n"); 00086 _wlan.start(0); 00087 printf("CC3000 init 1. \r\n"); 00088 00089 uint32_t subnet[4] = {0}; 00090 uint32_t ip[4] = {0}; 00091 uint32_t getway[4] = {0}; 00092 uint32_t dns[4] = {0}; 00093 00094 _netapp.dhcp(ip, subnet, getway, dns); 00095 printf("CC3000 init 2. \r\n"); 00096 _wlan.stop(); 00097 printf("CC3000 init 3. \r\n"); 00098 wait(1); 00099 printf("CC3000 init 4. \r\n"); 00100 _wlan.start(0); 00101 printf("CC3000 init 5. \r\n"); 00102 00103 _status.enabled = 1; 00104 _wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE); 00105 printf("CC3000 init 6. \r\n"); 00106 printf("CC3000 init done. \r\n"); 00107 } 00108 00109 void cc3000::init(const char *ip, const char *mask, const char *gateway) { 00110 _netapp.dhcp((uint32_t *)ip, (uint32_t *)mask, (uint32_t *)gateway, (uint32_t *)ip); //dns = ip 00111 _wlan.stop(); 00112 wait(1); 00113 _wlan.start(0); 00114 00115 _status.enabled = 1; 00116 _wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE); 00117 } 00118 00119 int cc3000::connect(unsigned int timeout_ms) { 00120 Timer t; 00121 int ret = 0; 00122 00123 if (_smart_config == false) { 00124 _wlan.ioctl_set_connection_policy(0, 0, 0); 00125 } else { 00126 tUserFS user_info; 00127 get_user_file_info((uint8_t *)&user_info, sizeof(user_info)); 00128 if (user_info.FTC == 1) { 00129 _wlan.ioctl_set_connection_policy(0, 1, 1); 00130 } else { 00131 DBG_CC("Smart config is not set. Please run the first time configuration."); 00132 return -1; 00133 } 00134 } 00135 00136 t.start(); 00137 while (is_connected() == false) { 00138 if (strlen((const char *)_phrase) < 8) { 00139 if (connect_open(_ssid)) { 00140 break; 00141 } 00142 } else { 00143 #ifndef CC3000_TINY_DRIVER 00144 if (connect_secure(_ssid,_phrase, _sec)) { 00145 break; 00146 } 00147 #else 00148 return -1; /* secure connection not supported with TINY_DRIVER */ 00149 #endif 00150 } 00151 00152 if (t.read_ms() > timeout_ms) { 00153 ret = -1; 00154 DBG_CC("Connection to AP failed"); 00155 break; 00156 } 00157 } 00158 00159 while (is_dhcp_configured() == false) 00160 { 00161 if (t.read_ms() > timeout_ms) { 00162 ret = -1; 00163 DBG_CC("Connection to AP failed"); 00164 break; 00165 } 00166 } 00167 00168 return ret; 00169 } 00170 00171 char* cc3000::getMACAddress() { 00172 return mac_addr; 00173 } 00174 00175 char* cc3000::getIPAddress() { 00176 return ip_addr; 00177 } 00178 00179 char* cc3000::getGateway() { 00180 return gateway; 00181 } 00182 00183 char* cc3000::getNetworkMask() { 00184 return networkmask; 00185 } 00186 00187 int cc3000::disconnect(void){ 00188 if (_wlan.disconnect()) { 00189 return -1; 00190 } else { 00191 return 0; 00192 } 00193 } 00194 00195 #endif 00196 00197 void cc3000::usync_callback(int32_t event_type, uint8_t *data, uint8_t length) { 00198 if (event_type == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE) { 00199 DBG_CC("Callback : HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE"); 00200 _status.smart_config_complete = 1; 00201 _status.stop_smart_config = 1; 00202 } 00203 00204 if (event_type == HCI_EVNT_WLAN_UNSOL_CONNECT) { 00205 DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_CONNECT"); 00206 _status.connected = 1; 00207 // Connect message is always followed by a DHCP message, connection is not useable until then 00208 _status.dhcp = 0; 00209 } 00210 00211 if (event_type == HCI_EVNT_WLAN_UNSOL_DISCONNECT) { 00212 DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_DISCONNECT"); 00213 _status.connected = 0; 00214 _status.dhcp = 0; 00215 _status.dhcp_configured = 0; 00216 } 00217 00218 if (event_type == HCI_EVNT_WLAN_UNSOL_DHCP) { 00219 #if (CC3000_ETH_COMPAT == 1) 00220 _socket.inet_ntoa_r ( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_IP_OFFSET]))), ip_addr, 17); 00221 _socket.inet_ntoa_r ( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_GW_OFFSET]))), gateway, 17); 00222 _socket.inet_ntoa_r ( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_SUBNET_OFFSET]))), networkmask, 17); 00223 _socket.inet_ntoa_r ( htonl(*((uint32_t *)(&data[NETAPP_IPCONFIG_MAC_OFFSET]))), mac_addr, 19); 00224 #endif 00225 if (*(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) { 00226 _status.dhcp = 1; 00227 DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_DHCP %i.%i.%i.%i", data[3], data[2], data[1], data[0]); 00228 } else { 00229 DBG_CC("Callback : HCI_EVNT_WLAN_UNSOL_DHCP - Disconnecting"); 00230 _status.dhcp = 0; 00231 } 00232 } 00233 00234 if (event_type == HCI_EVENT_CC3000_CAN_SHUT_DOWN) { 00235 // Note this means the modules is idle, so it could be shutdown.. 00236 //DBG_CC("Callback : HCI_EVENT_CC3000_CAN_SHUT_DOWN"); 00237 _status.ok_to_shut_down = 1; 00238 } 00239 00240 if (event_type == HCI_EVNT_WLAN_ASYNC_PING_REPORT) { 00241 DBG_CC("Callback : HCI_EVNT_WLAN_ASYNC_PING_REPORT"); 00242 memcpy(&_ping_report, data, length); 00243 } 00244 00245 if (event_type == HCI_EVNT_BSD_TCP_CLOSE_WAIT) { 00246 uint8_t socketnum = data[0]; 00247 DBG_CC("Callback : HCI_EVNT_BSD_TCP_CLOSE_WAIT - Socket : %d", socketnum); 00248 if (socketnum < MAX_SOCKETS) { 00249 _closed_sockets[socketnum] = true; /* clients socket is closed */ 00250 } 00251 } 00252 } 00253 00254 void cc3000::start_smart_config(const uint8_t *smart_config_key) { 00255 _status.smart_config_complete = 0; 00256 _wlan.ioctl_set_connection_policy(0, 0, 0); 00257 00258 if (_status.connected == 1) { 00259 disconnect(); 00260 } 00261 00262 //Wait until CC3000 is disconected 00263 while (_status.connected == 1) { 00264 wait_us(5); 00265 _event.hci_unsolicited_event_handler(); 00266 } 00267 00268 // Trigger the Smart Config process 00269 _wlan.smart_config_set_prefix(cc3000_prefix); 00270 // Start the Smart Config process with AES disabled 00271 _wlan.smart_config_start(0); 00272 00273 DBG_CC("Waiting for smartconfig to be completed"); 00274 00275 // Wait for Smart config finished 00276 while (_status.smart_config_complete == 0) { 00277 wait_ms(100); 00278 } 00279 00280 DBG_CC("Smartconfig finished"); 00281 00282 #ifndef CC3000_UNENCRYPTED_SMART_CONFIG 00283 // create new entry for AES encryption key 00284 _nvmem.create_entry(NVMEM_AES128_KEY_FILEID, 16); 00285 // write AES key to NVMEM 00286 _security.aes_write_key((uint8_t *)(&smart_config_key[0])); 00287 // Decrypt configuration information and add profile 00288 _wlan.smart_config_process(); 00289 #endif 00290 00291 // Configure to connect automatically to the AP retrieved in the 00292 // Smart config process 00293 _wlan.ioctl_set_connection_policy(0, 0, 1); 00294 00295 // reset the CC3000 00296 _wlan.stop(); 00297 _status.enabled = 0; 00298 wait(5); 00299 _wlan.start(0); 00300 _status.enabled = 1; 00301 00302 // Mask out all non-required events 00303 _wlan.set_event_mask(HCI_EVNT_WLAN_KEEPALIVE | HCI_EVNT_WLAN_UNSOL_INIT); 00304 } 00305 00306 bool cc3000::connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) { 00307 #ifdef CC3000_TINY_DRIVER 00308 return false; /* not supported*/ 00309 #else 00310 uint32_t ret; 00311 00312 //_wlan.disconnect(); 00313 wait_ms(3); 00314 ret = _wlan.connect(security_mode, ssid, strlen((const char *)ssid), 0, (uint8_t *)key, strlen((const char *)key)); 00315 if (ret == 0) { /* TODO static internal cc3000 state 0 to TRUE */ 00316 ret = true; 00317 } else { 00318 ret = false; 00319 } 00320 return ret; 00321 #endif 00322 } 00323 00324 bool cc3000::connect_non_blocking(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) 00325 { 00326 bool ret = false; 00327 00328 if (key == 0) { 00329 if (connect_open(ssid)) { 00330 ret = true; 00331 } 00332 } else { 00333 #ifndef CC3000_TINY_DRIVER 00334 if (connect_secure(ssid,key,security_mode)) { 00335 ret = true; 00336 } 00337 #else 00338 /* secure connection not supported with TINY_DRIVER */ 00339 #endif 00340 } 00341 00342 return ret; 00343 } 00344 00345 bool cc3000::connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) { 00346 Timer t; 00347 bool ret = true; 00348 00349 t.start(); 00350 while (is_connected() == false) { 00351 if (key == 0) { 00352 if (connect_open(ssid)) { 00353 break; 00354 } 00355 } else { 00356 #ifndef CC3000_TINY_DRIVER 00357 if (connect_secure(ssid,key,security_mode)) { 00358 break; 00359 } 00360 #else 00361 return false; /* secure connection not supported with TINY_DRIVER */ 00362 #endif 00363 } 00364 00365 /* timeout 10 seconds */ 00366 if (t.read_ms() > 10000) { 00367 ret = false; 00368 DBG_CC("Connection to AP failed"); 00369 break; 00370 } 00371 } 00372 00373 return ret; 00374 } 00375 00376 void cc3000::start(uint8_t patch) { 00377 printf("CC3000 start 1. \r\n"); 00378 _wlan.start(patch); 00379 printf("CC3000 start 2. \r\n"); 00380 _status.enabled = 1; 00381 _wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE); 00382 printf("CC3000 start 3. \r\n"); 00383 } 00384 00385 void cc3000::stop(void) { 00386 _wlan.stop(); 00387 _status.enabled = 0; 00388 } 00389 00390 void cc3000::restart(uint8_t patch) { 00391 _wlan.stop(); 00392 _status.enabled = 0; 00393 wait_ms(500); 00394 _wlan.start(patch); 00395 _status.enabled = 1; 00396 } 00397 00398 bool cc3000::connect_open(const uint8_t *ssid) { 00399 _wlan.disconnect(); 00400 wait_ms(3); 00401 uint32_t ret; 00402 #ifndef CC3000_TINY_DRIVER 00403 ret = _wlan.connect(0,ssid, strlen((const char *)ssid), 0, 0, 0); 00404 #else 00405 ret = _wlan.connect(ssid, strlen((const char *)ssid)); 00406 #endif 00407 if (ret == 0) { 00408 ret = true; 00409 } else { 00410 ret = false; 00411 } 00412 return ret; 00413 } 00414 00415 bool cc3000::is_enabled() 00416 { 00417 return _status.enabled; 00418 } 00419 00420 bool cc3000::is_connected() { 00421 if (( _status.connected ) && ( _status.dhcp )) { 00422 return 1; 00423 } else { 00424 return 0; 00425 } 00426 } 00427 00428 bool cc3000::is_dhcp_configured() { 00429 return _status.dhcp; 00430 } 00431 00432 bool cc3000::is_smart_confing_completed() { 00433 return _status.smart_config_complete; 00434 } 00435 00436 uint8_t cc3000::get_mac_address(uint8_t address[6]) { 00437 return _nvmem.get_mac_address(address); 00438 } 00439 00440 uint8_t cc3000::set_mac_address(uint8_t address[6]) { 00441 return _nvmem.set_mac_address(address); 00442 } 00443 00444 void cc3000::get_user_file_info(uint8_t *info_file, size_t size) { 00445 _nvmem.read( NVMEM_USER_FILE_1_FILEID, size, 0, info_file); 00446 } 00447 00448 #ifndef CC3000_TINY_DRIVER 00449 bool cc3000::get_ip_config(tNetappIpconfigRetArgs *ip_config) { 00450 if ((_status.dhcp == false) || (_status.connected == false)) { 00451 return false; 00452 } 00453 00454 _netapp.ipconfig(ip_config); 00455 return true; 00456 } 00457 #endif 00458 00459 void cc3000::delete_profiles(void) { 00460 _wlan.ioctl_set_connection_policy(0, 0, 0); 00461 _wlan.ioctl_del_profile(255); 00462 00463 tUserFS user_info; 00464 get_user_file_info((uint8_t *)&user_info, sizeof(user_info)); 00465 user_info.FTC = 0; 00466 set_user_file_info((uint8_t *)&user_info, sizeof(user_info)); 00467 } 00468 00469 void cc3000::set_user_file_info(uint8_t *info_file, size_t size) { 00470 _nvmem.write( NVMEM_USER_FILE_1_FILEID, size, 0, info_file); 00471 } 00472 00473 uint32_t cc3000::ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size) { 00474 #ifndef CC3000_TINY_DRIVER 00475 uint32_t reversed_ip = (ip >> 24) | ((ip >> 8) & 0xFF00) | ((ip << 8) & 0xFF0000) | (ip << 24); 00476 00477 _ping_report.packets_received = 0; 00478 if (_netapp.ping_send(&reversed_ip, attempts, size, timeout) == -1) { 00479 DBG_CC("Failed to send ping"); 00480 return 0; 00481 } 00482 wait_ms(timeout*attempts*2); 00483 00484 /* known issue of cc3000 - sent number is send + received */ 00485 // TODO : Remove the Sent/recv'd counts until ti fix the firmware issue? 00486 DBG_CC("Sent: %d",_ping_report.packets_sent); 00487 DBG_CC("Received: %d",_ping_report.packets_received); 00488 DBG_CC("Min time: %d",_ping_report.min_round_time); 00489 DBG_CC("Max time: %d",_ping_report.max_round_time); 00490 DBG_CC("Avg time: %d",_ping_report.avg_round_time); 00491 00492 return _ping_report.packets_received; 00493 #else 00494 return 0; 00495 #endif 00496 } 00497 00498 /* Conversion between uint types and C strings */ 00499 uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32) 00500 { 00501 *(p)++ = (uint8_t)(u32); 00502 *(p)++ = (uint8_t)((u32) >> 8); 00503 *(p)++ = (uint8_t)((u32) >> 16); 00504 *(p)++ = (uint8_t)((u32) >> 24); 00505 return p; 00506 } 00507 00508 00509 uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16) 00510 { 00511 *(p)++ = (uint8_t)(u16); 00512 *(p)++ = (uint8_t)((u16) >> 8); 00513 return p; 00514 } 00515 00516 00517 uint16_t STREAM_TO_UINT16_f(uint8_t *p, uint16_t offset) 00518 { 00519 return (uint16_t)((uint16_t)((uint16_t) 00520 (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset))); 00521 } 00522 00523 00524 uint32_t STREAM_TO_UINT32_f(uint8_t *p, uint16_t offset) 00525 { 00526 return (uint32_t)((uint32_t)((uint32_t) 00527 (*(p + offset + 3)) << 24) + (uint32_t)((uint32_t) 00528 (*(p + offset + 2)) << 16) + (uint32_t)((uint32_t) 00529 (*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset))); 00530 } 00531 00532 } // mbed_cc3000 namespace 00533
Generated on Tue Jul 12 2022 18:37:32 by
