cc3000 hostdriver with the mbed socket interface
Dependents: cc3000_hello_world_demo cc3000_simple_socket_demo cc3000_ntp_demo cc3000_ping_demo ... more
Revision 23:fed7f64dd520, committed 2013-10-03
- Comitter:
- SolderSplashLabs
- Date:
- Thu Oct 03 21:00:00 2013 +0000
- Parent:
- 21:fb34ac8d9af5
- Child:
- 24:ba3fa29197ac
- Commit message:
- Added separate debug messages and VT100 formatting
Changed in this revision
--- a/cc3000.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,447 +1,447 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_event.h" - -namespace mbed_cc3000 { - -/* TODO this prefix remove? verify */ -static uint8_t cc3000_prefix[] = {'T', 'T', 'T'}; -cc3000 *cc3000::_inst; - -cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port) - : _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event), _spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, irq_port, _event, _simple_link), _hci(_spi), - _nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event), _wlan(_simple_link, _event, _spi, _hci) { - /* TODO - pIRQ riorities ?? */ - - _simple_link.set_tx_complete_signal(1); - _status.dhcp = 0; - _status.connected = 0; - _status.socket = 0; - _status.dhcp_configured = 0; - _status.smart_config_complete = 0; - _status.stop_smart_config = 0; - _status.ok_to_shut_down = 0; - - _inst = this; -} - -cc3000::~cc3000() { - -} - -void cc3000::usync_callback(int32_t event_type, uint8_t * data, uint8_t length) { - if (event_type == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE) - { - _status.smart_config_complete = 1; - _status.stop_smart_config = 1; - } - - if (event_type == HCI_EVNT_WLAN_UNSOL_CONNECT) - { - _status.connected = 1; - } - - if (event_type == HCI_EVNT_WLAN_UNSOL_DISCONNECT) - { - _status.connected = 0; - _status.dhcp = 0; - _status.dhcp_configured = 0; - } - - if (event_type == HCI_EVNT_WLAN_UNSOL_DHCP) - { - if ( *(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) { - _status.dhcp = 1; - } else { - _status.dhcp = 0; - } - } - - if (event_type == HCI_EVENT_CC3000_CAN_SHUT_DOWN) - { - _status.ok_to_shut_down = 1; - } - - if (event_type == HCI_EVNT_WLAN_ASYNC_PING_REPORT) - { - memcpy(&_ping_report, data, length); - } - - if (event_type == HCI_EVNT_BSD_TCP_CLOSE_WAIT) { - uint8_t socketnum; - socketnum = data[0]; - if (socketnum < MAX_SOCKETS) { - _closed_sockets[socketnum] = true; /* clients socket is closed */ - } - } -} - -void cc3000::start_smart_config(const uint8_t *smart_config_key) { - // Reset all the previous configuration - _wlan.ioctl_set_connection_policy(0, 0, 0); - _wlan.ioctl_del_profile(255); - - //Wait until CC3000 is disconected - while (_status.connected == 1) - { - wait_us(5); - _event.hci_unsolicited_event_handler(); - } - - // Trigger the Smart Config process - - _wlan.smart_config_set_prefix(cc3000_prefix); - // Start the Smart Config process with AES disabled - _wlan.smart_config_start(0); - - DBG_CC("Waiting for smartconfig to be completed"); - - // Wait for Smart config finished - while (_status.smart_config_complete == 0) - { - wait_ms(100); - - } - - DBG_CC("Smartconfig finished"); - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - // create new entry for AES encryption key - _nvmem.create_entry(NVMEM_AES128_KEY_FILEID, 16); - // write AES key to NVMEM - _security.aes_write_key((uint8_t *)(&smart_config_key[0])); - // Decrypt configuration information and add profile - _wlan.smart_config_process(); -#endif - - // Configure to connect automatically to the AP retrieved in the - // Smart config process - _wlan.ioctl_set_connection_policy(0, 1, 1); - - // reset the CC3000 - _wlan.stop(); - wait(2); - _wlan.start(0); - wait(2); - - // Mask out all non-required events - _wlan.set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT); -} - -bool cc3000::connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) { - uint32_t ret; - - _wlan.disconnect(); - wait_ms(3); - ret = _wlan.connect(security_mode, ssid, strlen((const char *)ssid), 0, (uint8_t *)key, strlen((const char *)key)); - if (ret == 0) { /* TODO static internal cc3000 state 0 to TRUE */ - ret = true; - } else { - ret = false; - } - return ret; -} - -bool cc3000::connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) { - Timer t; /* TODO static? */ - bool ret = true; - - t.start(); - while (is_connected() == false) { - if (key == 0) { - if (connect_open(ssid)) { - break; - } - } else { -#ifndef CC3000_TINY_DRIVER - if (connect_secure(ssid,key,security_mode)) { - break; - } -#else - return false; /* secure connection not supported with TINY_DRIVER */ -#endif - } - - /* timeout 10 seconds */ - if (t.read_ms() > 10000){ - ret = false; - - DBG_CC("Connection to AP failed"); - - break; - } - } - - return ret; -} - -void cc3000::start(uint8_t patch) { - _wlan.start(patch); - _wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE); -} - -void cc3000::stop(void) { - _wlan.stop(); -} - -void cc3000::restart(uint8_t patch) { - _wlan.stop(); - wait_ms(500); - _wlan.start(patch); -} - -bool cc3000::connect_open(const uint8_t *ssid) { - uint32_t ret; - - _wlan.disconnect(); - wait_ms(3); -#ifndef CC3000_TINY_DRIVER - ret = _wlan.connect(0,ssid, strlen((const char *)ssid), 0, 0, 0); -#else - ret = _wlan.connect(ssid, strlen((const char *)ssid)); -#endif - if (ret == 0) { - ret = true; - } else { - ret = false; - } - return ret; -} - -bool cc3000::is_connected() { - return _status.connected; -} - -bool cc3000::is_dhcp_configured() { - return _status.dhcp; -} - -bool cc3000::is_smart_confing_completed() { - return _status.smart_config_complete; -} - -void cc3000::get_mac_address(uint8_t address[6]) { - _nvmem.get_mac_address(address); -} - -void cc3000::set_mac_address(uint8_t address[6]) { - _nvmem.set_mac_address(address); -} - -void cc3000::get_user_file_info(uint8_t *info_file, size_t size) { - _nvmem.read( NVMEM_USER_FILE_1_FILEID, size, 0, info_file); -} - -#ifndef CC3000_TINY_DRIVER -bool cc3000::get_ip_config(tNetappIpconfigRetArgs *ip_config) { - if ((_status.dhcp == false) || (_status.connected == false)) { - return false; - } - - _netapp.ipconfig(ip_config); - return true; -} -#endif - -cc3000_client cc3000::create_tcp_client(uint32_t ip_address, uint16_t port) { - sockaddr socket_address = {0}; - int32_t tcp_socket; - - tcp_socket = _socket.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (tcp_socket == -1) { - DBG_CC("Failed to create new socket (tcp)"); - return cc3000_client(*this); - } - - socket_address.family = AF_INET; - socket_address.data[0] = (port & 0xFF00) >> 8; - socket_address.data[1] = (port & 0x00FF); - socket_address.data[2] = ip_address >> 24; - socket_address.data[3] = ip_address >> 16; - socket_address.data[4] = ip_address >> 8; - socket_address.data[5] = ip_address; - - if (_socket.connect(tcp_socket, &socket_address, sizeof(socket_address)) == -1) { - DBG_CC("Failed to connect (tcp)"); - _socket.closesocket(tcp_socket); - return cc3000_client(*this); - } - - return cc3000_client(*this, tcp_socket); -} -cc3000_client cc3000::create_udp_client(uint32_t ip_address, uint16_t port) { - sockaddr socket_address = {0}; - int32_t udp_socket; - - udp_socket = _socket.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (udp_socket == -1) { - DBG_CC("Failed to create new socket (udp)"); - return cc3000_client(*this); - } - - socket_address.family = AF_INET; - socket_address.data[0] = (port & 0xFF00) >> 8; - socket_address.data[1] = (port & 0x00FF); - socket_address.data[2] = ip_address >> 24; - socket_address.data[3] = ip_address >> 16; - socket_address.data[4] = ip_address >> 8; - socket_address.data[5] = ip_address; - - if (_socket.connect(udp_socket, &socket_address, sizeof(socket_address)) == -1) { - DBG_CC("Failed to connect (udp)"); - _socket.closesocket(udp_socket); - return cc3000_client(*this); - } - - return cc3000_client(*this, udp_socket); -} - -cc3000_server cc3000::create_tcp_server(uint32_t ip_address, uint16_t port) { - sockaddr socket_address = {0}; - int32_t tcp_socket; - - tcp_socket = _socket.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (tcp_socket == -1) { - DBG_CC("Failed to create new socket."); - return cc3000_server(*this, socket_address); - } - - socket_address.family = AF_INET; - socket_address.data[0] = (port & 0xFF00) >> 8; - socket_address.data[1] = (port & 0x00FF); - socket_address.data[2] = ip_address >> 24; - socket_address.data[3] = ip_address >> 16; - socket_address.data[4] = ip_address >> 8; - socket_address.data[5] = ip_address; - - if (_socket.bind(tcp_socket, &socket_address, sizeof(socket_address)) != 0) { - DBG_CC("Failed to bind the new socket"); - return cc3000_server(*this, socket_address); - } - if (_socket.listen(tcp_socket, 1) != 0) { /* 1 client */ - DBG_CC("Failed to listen on the new socket"); - return cc3000_server(*this, socket_address); - } - - return cc3000_server(*this, socket_address, tcp_socket); -} - -void cc3000::delete_profiles(void) { - tUserFS user_info; - - _wlan.ioctl_set_connection_policy(0, 0, 0); - _wlan.ioctl_del_profile(255); - - get_user_file_info((uint8_t *)&user_info, sizeof(user_info)); - user_info.FTC = 0; - set_user_file_info((uint8_t *)&user_info, sizeof(user_info)); -} - -void cc3000::set_user_file_info(uint8_t *info_file, size_t size) { - _nvmem.write( NVMEM_USER_FILE_1_FILEID, size, 0, info_file); -} - -bool cc3000::disconnect(void){ - if (_wlan.disconnect()) { - return false; - } else { - return true; - } -} - -uint32_t cc3000::ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size) { - uint32_t reversed_ip = (ip >> 24) | (ip >> 8) & 0xFF00 | (ip << 8) & 0xFF0000 | (ip << 24); - - _ping_report.packets_received = 0; - if (_netapp.ping_send(&reversed_ip, attempts, size, timeout) == -1) { - DBG_CC("Failed to send ping"); - return 0; - } - wait_ms(timeout*attempts*2); - - /* known issue of cc3000 - sent number is send + received */ - // TODO : Remove the Sent/recv'd counts until ti fix the firmware issue? - DBG_CC("Sent: %d",_ping_report.packets_sent); - DBG_CC("Received: %d",_ping_report.packets_received); - DBG_CC("Min time: %d",_ping_report.min_round_time); - DBG_CC("Max time: %d",_ping_report.max_round_time); - DBG_CC("Avg time: %d",_ping_report.avg_round_time); - - return _ping_report.packets_received; -} - -/* Conversion between uint types and C strings */ -uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32) -{ - *(p)++ = (uint8_t)(u32); - *(p)++ = (uint8_t)((u32) >> 8); - *(p)++ = (uint8_t)((u32) >> 16); - *(p)++ = (uint8_t)((u32) >> 24); - return p; -} - - -uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16) -{ - *(p)++ = (uint8_t)(u16); - *(p)++ = (uint8_t)((u16) >> 8); - return p; -} - - -uint16_t STREAM_TO_UINT16_f(uint8_t *p, uint16_t offset) -{ - return (uint16_t)((uint16_t)((uint16_t) - (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset))); -} - - -uint32_t STREAM_TO_UINT32_f(uint8_t *p, uint16_t offset) -{ - return (uint32_t)((uint32_t)((uint32_t) - (*(p + offset + 3)) << 24) + (uint32_t)((uint32_t) - (*(p + offset + 2)) << 16) + (uint32_t)((uint32_t) - (*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset))); -} - -} /* end of mbed_cc3000 namespace */ - +/***************************************************************************** +* +* 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" +#include "cc3000_event.h" + +namespace mbed_cc3000 { + +/* TODO this prefix remove? verify */ +static uint8_t cc3000_prefix[] = {'T', 'T', 'T'}; +cc3000 *cc3000::_inst; + +cc3000::cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port) + : _event(_simple_link, _hci, _spi, *this), _socket(_simple_link, _hci, _event), _spi(cc3000_irq, cc3000_en, cc3000_cs, cc3000_spi, irq_port, _event, _simple_link), _hci(_spi), + _nvmem(_hci, _event, _simple_link), _netapp(_simple_link, _nvmem, _hci, _event), _wlan(_simple_link, _event, _spi, _hci) { + /* TODO - pIRQ riorities ?? */ + + _simple_link.set_tx_complete_signal(1); + _status.dhcp = 0; + _status.connected = 0; + _status.socket = 0; + _status.dhcp_configured = 0; + _status.smart_config_complete = 0; + _status.stop_smart_config = 0; + _status.ok_to_shut_down = 0; + + _inst = this; +} + +cc3000::~cc3000() { + +} + +void cc3000::usync_callback(int32_t event_type, uint8_t * data, uint8_t length) { + if (event_type == HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE) + { + _status.smart_config_complete = 1; + _status.stop_smart_config = 1; + } + + if (event_type == HCI_EVNT_WLAN_UNSOL_CONNECT) + { + _status.connected = 1; + } + + if (event_type == HCI_EVNT_WLAN_UNSOL_DISCONNECT) + { + _status.connected = 0; + _status.dhcp = 0; + _status.dhcp_configured = 0; + } + + if (event_type == HCI_EVNT_WLAN_UNSOL_DHCP) + { + if ( *(data + NETAPP_IPCONFIG_MAC_OFFSET) == 0) { + _status.dhcp = 1; + } else { + _status.dhcp = 0; + } + } + + if (event_type == HCI_EVENT_CC3000_CAN_SHUT_DOWN) + { + _status.ok_to_shut_down = 1; + } + + if (event_type == HCI_EVNT_WLAN_ASYNC_PING_REPORT) + { + memcpy(&_ping_report, data, length); + } + + if (event_type == HCI_EVNT_BSD_TCP_CLOSE_WAIT) { + uint8_t socketnum; + socketnum = data[0]; + if (socketnum < MAX_SOCKETS) { + _closed_sockets[socketnum] = true; /* clients socket is closed */ + } + } +} + +void cc3000::start_smart_config(const uint8_t *smart_config_key) { + // Reset all the previous configuration + _wlan.ioctl_set_connection_policy(0, 0, 0); + _wlan.ioctl_del_profile(255); + + //Wait until CC3000 is disconected + while (_status.connected == 1) + { + wait_us(5); + _event.hci_unsolicited_event_handler(); + } + + // Trigger the Smart Config process + + _wlan.smart_config_set_prefix(cc3000_prefix); + // Start the Smart Config process with AES disabled + _wlan.smart_config_start(0); + + DBG_CC("Waiting for smartconfig to be completed"); + + // Wait for Smart config finished + while (_status.smart_config_complete == 0) + { + wait_ms(100); + + } + + DBG_CC("Smartconfig finished"); + +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG + // create new entry for AES encryption key + _nvmem.create_entry(NVMEM_AES128_KEY_FILEID, 16); + // write AES key to NVMEM + _security.aes_write_key((uint8_t *)(&smart_config_key[0])); + // Decrypt configuration information and add profile + _wlan.smart_config_process(); +#endif + + // Configure to connect automatically to the AP retrieved in the + // Smart config process + _wlan.ioctl_set_connection_policy(0, 1, 1); + + // reset the CC3000 + _wlan.stop(); + wait(2); + _wlan.start(0); + wait(2); + + // Mask out all non-required events + _wlan.set_event_mask(HCI_EVNT_WLAN_KEEPALIVE|HCI_EVNT_WLAN_UNSOL_INIT|HCI_EVNT_WLAN_ASYNC_PING_REPORT); +} + +bool cc3000::connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) { + uint32_t ret; + + _wlan.disconnect(); + wait_ms(3); + ret = _wlan.connect(security_mode, ssid, strlen((const char *)ssid), 0, (uint8_t *)key, strlen((const char *)key)); + if (ret == 0) { /* TODO static internal cc3000 state 0 to TRUE */ + ret = true; + } else { + ret = false; + } + return ret; +} + +bool cc3000::connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode) { + Timer t; /* TODO static? */ + bool ret = true; + + t.start(); + while (is_connected() == false) { + if (key == 0) { + if (connect_open(ssid)) { + break; + } + } else { +#ifndef CC3000_TINY_DRIVER + if (connect_secure(ssid,key,security_mode)) { + break; + } +#else + return false; /* secure connection not supported with TINY_DRIVER */ +#endif + } + + /* timeout 10 seconds */ + if (t.read_ms() > 10000){ + ret = false; + + DBG_CC("Connection to AP failed"); + + break; + } + } + + return ret; +} + +void cc3000::start(uint8_t patch) { + _wlan.start(patch); + _wlan.set_event_mask(HCI_EVNT_WLAN_UNSOL_INIT | HCI_EVNT_WLAN_KEEPALIVE); +} + +void cc3000::stop(void) { + _wlan.stop(); +} + +void cc3000::restart(uint8_t patch) { + _wlan.stop(); + wait_ms(500); + _wlan.start(patch); +} + +bool cc3000::connect_open(const uint8_t *ssid) { + uint32_t ret; + + _wlan.disconnect(); + wait_ms(3); +#ifndef CC3000_TINY_DRIVER + ret = _wlan.connect(0,ssid, strlen((const char *)ssid), 0, 0, 0); +#else + ret = _wlan.connect(ssid, strlen((const char *)ssid)); +#endif + if (ret == 0) { + ret = true; + } else { + ret = false; + } + return ret; +} + +bool cc3000::is_connected() { + return _status.connected; +} + +bool cc3000::is_dhcp_configured() { + return _status.dhcp; +} + +bool cc3000::is_smart_confing_completed() { + return _status.smart_config_complete; +} + +uint8_t cc3000::get_mac_address(uint8_t address[6]) { + return _nvmem.get_mac_address(address); +} + +uint8_t cc3000::set_mac_address(uint8_t address[6]) { + return _nvmem.set_mac_address(address); +} + +void cc3000::get_user_file_info(uint8_t *info_file, size_t size) { + _nvmem.read( NVMEM_USER_FILE_1_FILEID, size, 0, info_file); +} + +#ifndef CC3000_TINY_DRIVER +bool cc3000::get_ip_config(tNetappIpconfigRetArgs *ip_config) { + if ((_status.dhcp == false) || (_status.connected == false)) { + return false; + } + + _netapp.ipconfig(ip_config); + return true; +} +#endif + +cc3000_client cc3000::create_tcp_client(uint32_t ip_address, uint16_t port) { + sockaddr socket_address = {0}; + int32_t tcp_socket; + + tcp_socket = _socket.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tcp_socket == -1) { + DBG_CC("Failed to create new socket (tcp)"); + return cc3000_client(*this); + } + + socket_address.family = AF_INET; + socket_address.data[0] = (port & 0xFF00) >> 8; + socket_address.data[1] = (port & 0x00FF); + socket_address.data[2] = ip_address >> 24; + socket_address.data[3] = ip_address >> 16; + socket_address.data[4] = ip_address >> 8; + socket_address.data[5] = ip_address; + + if (_socket.connect(tcp_socket, &socket_address, sizeof(socket_address)) == -1) { + DBG_CC("Failed to connect (tcp)"); + _socket.closesocket(tcp_socket); + return cc3000_client(*this); + } + + return cc3000_client(*this, tcp_socket); +} +cc3000_client cc3000::create_udp_client(uint32_t ip_address, uint16_t port) { + sockaddr socket_address = {0}; + int32_t udp_socket; + + udp_socket = _socket.socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (udp_socket == -1) { + DBG_CC("Failed to create new socket (udp)"); + return cc3000_client(*this); + } + + socket_address.family = AF_INET; + socket_address.data[0] = (port & 0xFF00) >> 8; + socket_address.data[1] = (port & 0x00FF); + socket_address.data[2] = ip_address >> 24; + socket_address.data[3] = ip_address >> 16; + socket_address.data[4] = ip_address >> 8; + socket_address.data[5] = ip_address; + + if (_socket.connect(udp_socket, &socket_address, sizeof(socket_address)) == -1) { + DBG_CC("Failed to connect (udp)"); + _socket.closesocket(udp_socket); + return cc3000_client(*this); + } + + return cc3000_client(*this, udp_socket); +} + +cc3000_server cc3000::create_tcp_server(uint32_t ip_address, uint16_t port) { + sockaddr socket_address = {0}; + int32_t tcp_socket; + + tcp_socket = _socket.socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (tcp_socket == -1) { + DBG_CC("Failed to create new socket."); + return cc3000_server(*this, socket_address); + } + + socket_address.family = AF_INET; + socket_address.data[0] = (port & 0xFF00) >> 8; + socket_address.data[1] = (port & 0x00FF); + socket_address.data[2] = ip_address >> 24; + socket_address.data[3] = ip_address >> 16; + socket_address.data[4] = ip_address >> 8; + socket_address.data[5] = ip_address; + + if (_socket.bind(tcp_socket, &socket_address, sizeof(socket_address)) != 0) { + DBG_CC("Failed to bind the new socket"); + return cc3000_server(*this, socket_address); + } + if (_socket.listen(tcp_socket, 1) != 0) { /* 1 client */ + DBG_CC("Failed to listen on the new socket"); + return cc3000_server(*this, socket_address); + } + + return cc3000_server(*this, socket_address, tcp_socket); +} + +void cc3000::delete_profiles(void) { + tUserFS user_info; + + _wlan.ioctl_set_connection_policy(0, 0, 0); + _wlan.ioctl_del_profile(255); + + get_user_file_info((uint8_t *)&user_info, sizeof(user_info)); + user_info.FTC = 0; + set_user_file_info((uint8_t *)&user_info, sizeof(user_info)); +} + +void cc3000::set_user_file_info(uint8_t *info_file, size_t size) { + _nvmem.write( NVMEM_USER_FILE_1_FILEID, size, 0, info_file); +} + +bool cc3000::disconnect(void){ + if (_wlan.disconnect()) { + return false; + } else { + return true; + } +} + +uint32_t cc3000::ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size) { + uint32_t reversed_ip = (ip >> 24) | (ip >> 8) & 0xFF00 | (ip << 8) & 0xFF0000 | (ip << 24); + + _ping_report.packets_received = 0; + if (_netapp.ping_send(&reversed_ip, attempts, size, timeout) == -1) { + DBG_CC("Failed to send ping"); + return 0; + } + wait_ms(timeout*attempts*2); + + /* known issue of cc3000 - sent number is send + received */ + // TODO : Remove the Sent/recv'd counts until ti fix the firmware issue? + DBG_CC("Sent: %d",_ping_report.packets_sent); + DBG_CC("Received: %d",_ping_report.packets_received); + DBG_CC("Min time: %d",_ping_report.min_round_time); + DBG_CC("Max time: %d",_ping_report.max_round_time); + DBG_CC("Avg time: %d",_ping_report.avg_round_time); + + return _ping_report.packets_received; +} + +/* Conversion between uint types and C strings */ +uint8_t* UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32) +{ + *(p)++ = (uint8_t)(u32); + *(p)++ = (uint8_t)((u32) >> 8); + *(p)++ = (uint8_t)((u32) >> 16); + *(p)++ = (uint8_t)((u32) >> 24); + return p; +} + + +uint8_t* UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16) +{ + *(p)++ = (uint8_t)(u16); + *(p)++ = (uint8_t)((u16) >> 8); + return p; +} + + +uint16_t STREAM_TO_UINT16_f(uint8_t *p, uint16_t offset) +{ + return (uint16_t)((uint16_t)((uint16_t) + (*(p + offset + 1)) << 8) + (uint16_t)(*(p + offset))); +} + + +uint32_t STREAM_TO_UINT32_f(uint8_t *p, uint16_t offset) +{ + return (uint32_t)((uint32_t)((uint32_t) + (*(p + offset + 3)) << 24) + (uint32_t)((uint32_t) + (*(p + offset + 2)) << 16) + (uint32_t)((uint32_t) + (*(p + offset + 1)) << 8) + (uint32_t)(*(p + offset))); +} + +} /* end of mbed_cc3000 namespace */ +
--- a/cc3000.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,719 +1,754 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_H -#define CC3000_H - -#include "mbed.h" -#include "cc3000_common.h" -#include "cc3000_spi.h" -#include "cc3000_simplelink.h" -#include "cc3000_netapp.h" -#include "cc3000_nvmem.h" -#include "cc3000_socket.h" - -#define MAX_SOCKETS 4 - -/** Enable debug messages - */ -#define CC3000_DEBUG 1 - -#if CC3000_DEBUG == 1 - - // DBG_SOCKET, mbed socket specific debug messages - #define DBG_SOCKET(x, ...) std::printf("[CC3000 : SOCKET] "x"\r\n", ##__VA_ARGS__); - - // DBG_HCI, prints a message for every recieved HCI event, quite a lot of debug - #define DBG_HCI(x, ...) std::printf("[CC3000 : HCI RX] "x"\r\n", ##__VA_ARGS__); - - // DBG_HCI_CMD, Prints commands that are sent - #define DBG_HCI_CMD(x, ...) std::printf("[CC3000 : HCI TX] "x"\r\n", ##__VA_ARGS__); - - // DBG_CC, General cc3000 debug messages - #define DBG_CC(x, ...) std::printf("[CC3000] "x"\r\n", ##__VA_ARGS__); -#else - #define DBG_SOCKET(x, ...) - #define DBG_HCI(x, ...) - #define DBG_HCI_CMD(x, ...) - #define DBG_CC(x, ...) -#endif - -namespace mbed_cc3000 { - -/** User info structure - */ -typedef struct { - uint8_t FTC; // First time config performed - uint8_t PP_version[2]; // Patch Programmer version - uint8_t SERV_PACK[2]; // Service Pack Version - uint8_t DRV_VER[3]; // Driver Version - uint8_t FW_VER[3]; // Firmware Version - uint8_t validCIK; // CIK[] is valid (Client Interface Key) - uint8_t CIK[40]; -} tUserFS; - -/** Function pointers which are not yet implemented - */ -enum FunctionNumber { - FW_PATCHES = 0, - DRIVER_PATCHES = 1, - BOOTLOADER_PATCHES = 2, -}; - -/** CC3000 Simple Link class which contains status of cc3000. - */ -class cc3000_simple_link { -public: - /** ctor - sets magic number in the buffers (overflow mark). - */ - cc3000_simple_link(); - /** dtor - */ - ~cc3000_simple_link(); - /** Returns data received flag. - * \return - * if data have been received. - */ - uint8_t get_data_received_flag(); - /** Set data received flag. - * \param value The value to be set. - */ - void set_data_received_flag(uint8_t value); - /** Returns if tx was completed. - * \return - * true if tx was completed, - * false otherwise. - */ - bool get_tx_complete_signal(); - /** - */ - void set_tx_complete_signal(bool value); - /** - */ - uint8_t *get_received_buffer(); - /** - */ - void set_received_buffer(uint8_t value); - /** - */ - uint8_t *get_transmit_buffer(); - /** - */ - void set_transmit_buffer(uint8_t value); - /** - */ - uint16_t get_number_free_buffers(); - /** - */ - void set_number_free_buffers(uint16_t value); - /** - */ - uint16_t get_buffer_length(); - /** - */ - void set_buffer_length(uint16_t value); - /** - */ - uint16_t get_pending_data(); - /** - */ - void set_pending_data(uint16_t value); - /** - */ - uint16_t get_op_code(); - /** - */ - void set_op_code(uint16_t code); - /** - */ - uint16_t get_released_packets(); - /** - */ - void set_number_of_released_packets(uint16_t value); - /** - */ - uint16_t get_sent_packets(); - /** - */ - void set_sent_packets(uint16_t value); - - int32_t get_transmit_error(); - void set_transmit_error(int32_t value); - - uint16_t get_buffer_size(void); - void set_buffer_size(uint16_t value); - - void *get_func_pointer(FunctionNumber function); - - uint8_t *get_received_data(void); - void set_received_data(uint8_t *pointer); - -private: - uint8_t _data_received_flag; - bool _tx_complete_signal; - uint16_t _rx_event_opcode; - uint16_t _free_buffers; - uint16_t _buffer_length; - uint16_t _buffer_size; - uint16_t _rx_data_pending; - uint16_t _sent_packets; - uint16_t _released_packets; - int32_t _transmit_data_error; - uint8_t *_received_data; - uint8_t _rx_buffer[CC3000_RX_BUFFER_SIZE]; - uint8_t _tx_buffer[CC3000_TX_BUFFER_SIZE]; -private: - int8_t *(* _fFWPatches)(uint32_t *length); - int8_t *(* _fDriverPatches)(uint32_t *length); - int8_t *(* _fBootLoaderPatches)(uint32_t *length); -}; - -/** Forward declaration classes - */ -class cc3000_hci; -class cc3000_nvmem; -class cc3000_spi; -class cc3000; - -/** - */ -class cc3000_event { -public: - cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000); - ~cc3000_event(); - - void hci_unsol_handle_patch_request(uint8_t *event_hdr); - uint8_t *hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen); - int32_t hci_unsol_event_handler(uint8_t *event_hdr); - int32_t hci_unsolicited_event_handler(void); - int32_t get_socket_active_status(int32_t sd); - void set_socket_active_status(int32_t sd, int32_t status); - int32_t hci_event_unsol_flowcontrol_handler(uint8_t *event); - void update_socket_active_status(uint8_t *resp_params); - void simplelink_wait_event(uint16_t op_code, void *ret_param); - void simplelink_wait_data(uint8_t *buffer, uint8_t *from, uint8_t *fromlen); - - void received_handler(uint8_t *buffer); - private: - uint32_t socket_active_status; - cc3000_simple_link &_simple_link; - cc3000_hci &_hci; - cc3000_spi &_spi; - cc3000 &_cc3000; -}; - -class cc3000_netapp { -public: - cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci, cc3000_event &event); - ~cc3000_netapp(); - int32_t config_mac_adrress(uint8_t *mac); - int32_t dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server); -#ifndef CC3000_TINY_DRIVER - void ipconfig(tNetappIpconfigRetArgs *ipconfig); - int32_t timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity); - int32_t ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout); - void ping_report(); - int32_t ping_stop(); - int32_t arp_flush(); -#endif -private: - cc3000_simple_link &_simple_link; - cc3000_nvmem &_nvmem; - cc3000_hci &_hci; - cc3000_event &_event; -}; - -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG -class cc3000_security { -public: - void expandKey(uint8_t *expanded_key, uint8_t *key); - uint8_t galois_mul2(uint8_t value); - void aes_encr(uint8_t *state, uint8_t *expanded_key); - void aes_decr(uint8_t *state, uint8_t *expanded_key); - void aes_encrypt(uint8_t *state, uint8_t *key); - void aes_decrypt(uint8_t *state, uint8_t *key); - int32_t aes_read_key(uint8_t *key); - int32_t aes_write_key(uint8_t *key); -private: - uint8_t _expanded_key[176]; -}; -#endif - -class cc3000_socket { -public: - cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event); - ~cc3000_socket(); - int32_t socket(int32_t domain, int32_t type, int32_t protocol); - int32_t accept(int32_t sd, sockaddr *addr, socklen_t *addrlen); - int32_t bind(int32_t sd, const sockaddr *addr, int32_t addrlen); - int32_t HostFlowControlConsumeBuff(int32_t sd); - int32_t closesocket(int32_t sd); - int32_t listen(int32_t sd, int32_t backlog); - int32_t connect(int32_t sd, const sockaddr *addr, int32_t addrlen); - int32_t select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout); - int32_t getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen); - int32_t simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode); - int32_t simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode); - int32_t recv(int32_t sd, void *buf, int32_t len, int32_t flags); - int32_t recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen); - int32_t send(int32_t sd, const void *buf, int32_t len, int32_t flags); - int32_t sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen); - int32_t mdns_advertiser(uint16_t mdns_enabled, uint8_t * device_service_name, uint16_t device_service_name_length); -#ifndef CC3000_TINY_DRIVER - int32_t gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr); - int32_t setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen); -#endif -private: - cc3000_simple_link &_simple_link; - cc3000_hci &_hci; - cc3000_event &_event; -}; - -/** SPI communication class - */ -class cc3000_spi { -public: - /** ctor - */ - cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link); - /** dtor - */ - ~cc3000_spi(); - /** Close SPI - disables IRQ and set received buffer to 0 - * \param none - * \return none - */ - void close(); - /** - * \param none - * \return none - */ - void open(); - /** - * \param buffer - * \param length - * \return none - */ - uint32_t first_write(uint8_t *buffer, uint16_t length); - /** - */ - uint32_t write(uint8_t *buffer, uint16_t length); - /** - */ - void write_synchronous(uint8_t *data, uint16_t size); - /** - */ - void read_synchronous(uint8_t *data, uint16_t size); - /** - */ - uint32_t read_data_cont(); - /** - */ - void wlan_irq_enable(); - /** - */ - void wlan_irq_disable(); - /** - */ - void wlan_irq_set(uint8_t value); - /** - */ - uint32_t wlan_irq_read(); - /** - */ - void WLAN_IRQHandler(); - /** - */ - void write_wlan_en(uint8_t value); -private: - tSpiInfo _spi_info; - InterruptIn _wlan_irq; - DigitalOut _wlan_en; - DigitalOut _wlan_cs; - SPI _wlan_spi; - IRQn_Type _irq_port; - pFunctionPointer_t _function_pointer; - cc3000_event &_event; - cc3000_simple_link &_simple_link; -}; - -class cc3000_hci { -public: - cc3000_hci(cc3000_spi &spi); - ~cc3000_hci(); - uint16_t command_send(uint16_t op_code, uint8_t *buffer, uint8_t length); - uint32_t data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length, - uint16_t data_length, const uint8_t *tail, uint16_t tail_length); - void data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, - uint16_t data_length); - void patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length); -private: - cc3000_spi &_spi; -}; - -class cc3000_nvmem { -public: - cc3000_nvmem(cc3000_hci &hci, cc3000_event &_event,cc3000_simple_link &simple_link); - ~cc3000_nvmem(); - int32_t read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff); - int32_t write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff); - uint8_t set_mac_address(uint8_t *mac); - uint8_t get_mac_address(uint8_t *mac); - uint8_t write_patch(uint32_t file_id, uint32_t length, const uint8_t *data); - int32_t create_entry(uint32_t file_id, uint32_t new_len); -#ifndef CC3000_TINY_DRIVER - uint8_t read_sp_version(uint8_t* patch_ver); -#endif -private: - cc3000_hci &_hci; - cc3000_event &_event; - cc3000_simple_link &_simple_link; -}; - -class cc3000_wlan { -public: - cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci); - ~cc3000_wlan(); - /** Send SIMPLE LINK START to cc3000 - * \param patches_available_host Flag to indicate if patches are available - * \return none - */ - void simpleLink_init_start(uint16_t patches_available_host); - /** Start wlan device. Blocking call until init is completed - * \param patches_available_host Flag to indicate if patches are available - * \return none - */ - void start(uint16_t patches_available_host); - /** Stop wlan device - * \param none - * \return none - */ - void stop(void); -#ifndef CC3000_TINY_DRIVER - int32_t connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_length, uint8_t *b_ssid, uint8_t *key, int32_t key_len); - int32_t 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); - int32_t ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results); - int32_t 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); - int32_t ioctl_statusget(void); -#else - int32_t connect(const uint8_t *ssid, int32_t ssid_length); - int32_t 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); -#endif -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - int32_t smart_config_process(void); -#endif - int32_t disconnect(); - int32_t ioctl_set_connection_policy(uint32_t should_connect_to_open_ap, uint32_t use_fast_connect, uint32_t use_profiles); - int32_t ioctl_del_profile(uint32_t index); - int32_t set_event_mask(uint32_t mask); - int32_t smart_config_start(uint32_t encrypted_flag); - int32_t smart_config_stop(void); - int32_t smart_config_set_prefix(uint8_t *new_prefix); -private: - cc3000_simple_link &_simple_link; - cc3000_event &_event; - cc3000_spi &_spi; - cc3000_hci &_hci; -}; - -/** Client TCP/UDP class - TODO - not complete client - */ -class cc3000_client { -public: - /** - */ - cc3000_client(cc3000 &cc3000_ref); - /** - */ - cc3000_client(cc3000 &cc3000_ref, int16_t socket); - /** - */ - bool connected(void); - /** - */ - int16_t write(const void *buffer, uint16_t length, uint32_t flags); - /** - */ - int16_t read(void *buffer, uint16_t length, uint32_t flags); - /** - */ - void close(void); - -private: - int16_t _current_socket; - cc3000 &_cc3000; -}; - -/** Server TCP/UDP - */ -class cc3000_server { -public: - /** ctor (server was not created successfully) - */ - cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add); - /** ctor - */ - cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add, int16_t socket); - /** Blocking accept - */ - int32_t accept(void); - /** - */ - int32_t receive(void *buffer, uint16_t length, uint32_t flags); - /** - */ - int32_t send(void *buffer, uint16_t length, uint32_t flags); - /** - */ - void bind(void); - /** - */ - void listen(uint32_t backlog); - /** - */ - void close(void); -private: - int16_t _current_socket; - sockaddr _socket_address; - cc3000 &_cc3000; -}; - -/** The main class of entire cc3000 implementation - */ -class cc3000 { -public: - typedef struct { - bool dhcp; - bool connected; - uint8_t socket; - bool smart_config_complete; - bool stop_smart_config; - bool dhcp_configured; - bool ok_to_shut_down; - } tStatus; - /** ctor for cc3000 class. - * \param cc3000_irq IRQ pin - * \param cc3000_en Enable pin - * \param cc3000_cs Chip select pin - * \param cc3000_spi SPI interface - * \param irq_port IRQ pin's port - */ - cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port); - /** dtor - */ - ~cc3000(); - /** Initiate cc3000. It starts the wlan communication and deletes profiles. - * \param patch Patch - */ - void start(uint8_t patch); - /** Stops the wlan communication. - */ - void stop(); - /** Restarts the wlan communication. - */ - void restart(uint8_t patch); - /** Disconnect wlan device - * - */ - bool disconnect(void); - /** Callback which is called from the event class. This updates status of cc3000. - * \param event_type Type of the event - * \param data Pointer to data - * \param length Length of data - * \return none - */ - void usync_callback(int32_t event_type, uint8_t *data, uint8_t length); - /** Connect to SSID (open/secured) with timeout (10ms). - * \param ssid SSID name - * \param key Security key (if key = 0, open connection) - * \param security_mode Security mode - * \return true if connection was established, false otherwise. - */ - bool connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode); - /** Connect to SSID which is secured - * \param ssid SSID name - * \param key Security key - * \param security_mode Security mode - * \return true if connection was established, false otherwise. - */ - bool connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode); - /** Connect to SSID which is open (no security) - * \param ssid SSID name - * \return true if connection was established, false otherwise. - */ - bool connect_open(const uint8_t *ssid); - /** Status of the cc3000 connection. - * \return true if it's connected, false otherwise. - */ - bool is_connected(); - /** Status of DHCP. - * \param none - * \return true if DCHP is configured, false otherwise. - */ - bool is_dhcp_configured(); - /** Status of smart confing completation. - * \param none - * \return smart config was set, false otherwise. - */ - bool is_smart_confing_completed(); - /** Return the cc3000's mac address. - * \param address Retreived mac address. - * \return none - */ - void get_mac_address(uint8_t address[6]); - /** Set the cc3000's mac address - * \param address Mac address to be set - * \return none - */ - void set_mac_address(uint8_t address[6]); - /** Get user file info - * \param info_file Pointer where info will be stored - * \param size Available size - * \return none - */ - void get_user_file_info(uint8_t *info_file, size_t size); - /** Set user filo info - * \param info_file Pointer to user's info - * \return none - */ - void set_user_file_info(uint8_t *info_file, size_t size); - /** Start smart config - * \param smart_config_key Pointer to smart config key - * \return none - */ - void start_smart_config(const uint8_t *smart_config_key); /* TODO enable AES ? */ -#ifndef CC3000_TINY_DRIVER - /** Return ip configuration - * \param ip_config Pointer to ipconfig data - * \return true if it's connected and info was retrieved, false otherwise. - */ - bool get_ip_config(tNetappIpconfigRetArgs *ip_config); -#endif - /** Creates tcp client - * \param ip_address Client's IP address - * \param port Client's PORT - * \return client with socket != -1 - */ - cc3000_client create_tcp_client(uint32_t ip_address, uint16_t port); - /** Creates tcp server - * \param ip_address Server's IP address - * \param port Server's PORT - * \return server with socket != -1 - */ - cc3000_server create_tcp_server(uint32_t ip_address, uint16_t port); - /** Creates udp client - * \param ip_address Server's IP address - * \param port Server's PORT - * \return client with socket != -1 - */ - cc3000_client create_udp_client(uint32_t ip_address, uint16_t port); - /** Delete all stored profiles - * \param none - * \return none - */ - void delete_profiles(void); - /** - * - */ - uint32_t ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size); - - static cc3000 *get_instance() { - return _inst; - } -public: - cc3000_simple_link _simple_link; - cc3000_event _event; -#ifndef CC3000_UNENCRYPTED_SMART_CONFIG - cc3000_security _security; -#endif - cc3000_socket _socket; - cc3000_spi _spi; - cc3000_hci _hci; - cc3000_nvmem _nvmem; - cc3000_netapp _netapp; - cc3000_wlan _wlan; -protected: - static cc3000 *_inst; -private: - tStatus _status; - netapp_pingreport_args_t _ping_report; - bool _closed_sockets[MAX_SOCKETS]; -}; - -/** -* Copy 32 bit to stream while converting to little endian format. -* @param p pointer to the new stream -* @param u32 pointer to the 32 bit -* @return pointer to the new stream -*/ -uint8_t *UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32); - -/** -* Copy 16 bit to stream while converting to little endian format. -* @param p pointer to the new stream -* @param u32 pointer to the 16 bit -* @return pointer to the new stream -*/ -uint8_t *UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16); - -/** -* Copy received stream to 16 bit in little endian format. -* @param p pointer to the stream -* @param offset offset in the stream -* @return pointer to the new 16 bit -*/ -uint16_t STREAM_TO_UINT16_f(uint8_t* p, uint16_t offset); - -/** -* Copy received stream to 32 bit in little endian format. -* @param p pointer to the stream -* @param offset offset in the stream -* @return pointer to the new 32 bit -*/ -uint32_t STREAM_TO_UINT32_f(uint8_t* p, uint16_t offset); - -} /* end of mbed_cc3000 namespace */ - - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_H +#define CC3000_H + +#include "mbed.h" +#include "cc3000_common.h" +#include "cc3000_spi.h" +#include "cc3000_simplelink.h" +#include "cc3000_netapp.h" +#include "cc3000_nvmem.h" +#include "cc3000_socket.h" + +#define MAX_SOCKETS 4 + +/** Enable debug messages, comment out the ones you don't want + */ +#define CC3000_DEBUG_SOCKET +#define CC3000_DEBUG_HCI_TX +#define CC3000_DEBUG_HCI_RX +#define CC3000_DEBUG + +// Add color too the debug messages, requires a VT100 terminal like putty, comment out to remove +#define VT100_COLOUR + +#ifdef CC3000_DEBUG_SOCKET + + #ifdef VT100_COLOUR + #define DBG_SOCKET(x, ...) std::printf("\x1b[2;32;40m[CC3000 : SOCKET] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__); + #else + #define DBG_SOCKET(x, ...) std::printf("[CC3000 : SOCKET] "x"\r\n", ##__VA_ARGS__); + #endif + +#else + #define DBG_SOCKET(x, ...) +#endif + +#ifdef CC3000_DEBUG_HCI_TX + + #ifdef VT100_COLOUR + #define DBG_HCI(x, ...) std::printf("\x1b[2;35;40m[CC3000 : HCI RX] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__); + #else + #define DBG_HCI(x, ...) std::printf("[CC3000 : HCI RX] "x"\r\n", ##__VA_ARGS__); + #endif + +#else + #define DBG_HCI(x, ...) +#endif + +#ifdef CC3000_DEBUG_HCI_RX + + #ifdef VT100_COLOUR + #define DBG_HCI_CMD(x, ...) std::printf("\x1b[2;36;40m[CC3000 : HCI TX] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__); + #else + #define DBG_HCI_CMD(x, ...) std::printf("[CC3000 : HCI TX] "x"\r\n", ##__VA_ARGS__); + #endif + +#else + #define DBG_HCI_CMD(x, ...) +#endif + + +#ifdef CC3000_DEBUG + + #ifdef VT100_COLOUR + #define DBG_CC(x, ...) std::printf("\x1b[2;32;40m[CC3000] "x"\x1b[0;37;40m\r\n", ##__VA_ARGS__); + #else + #define DBG_CC(x, ...) std::printf("[CC3000] "x"\r\n", ##__VA_ARGS__); + #endif + +#else + #define DBG_HCI_CMD(x, ...) +#endif + +namespace mbed_cc3000 { + +/** User info structure + */ +typedef struct { + uint8_t FTC; // First time config performed + uint8_t PP_version[2]; // Patch Programmer version + uint8_t SERV_PACK[2]; // Service Pack Version + uint8_t DRV_VER[3]; // Driver Version + uint8_t FW_VER[3]; // Firmware Version + uint8_t validCIK; // CIK[] is valid (Client Interface Key) + uint8_t CIK[40]; +} tUserFS; + +/** Function pointers which are not yet implemented + */ +enum FunctionNumber { + FW_PATCHES = 0, + DRIVER_PATCHES = 1, + BOOTLOADER_PATCHES = 2, +}; + +/** CC3000 Simple Link class which contains status of cc3000. + */ +class cc3000_simple_link { +public: + /** ctor - sets magic number in the buffers (overflow mark). + */ + cc3000_simple_link(); + /** dtor + */ + ~cc3000_simple_link(); + /** Returns data received flag. + * \return + * if data have been received. + */ + uint8_t get_data_received_flag(); + /** Set data received flag. + * \param value The value to be set. + */ + void set_data_received_flag(uint8_t value); + /** Returns if tx was completed. + * \return + * true if tx was completed, + * false otherwise. + */ + bool get_tx_complete_signal(); + /** + */ + void set_tx_complete_signal(bool value); + /** + */ + uint8_t *get_received_buffer(); + /** + */ + void set_received_buffer(uint8_t value); + /** + */ + uint8_t *get_transmit_buffer(); + /** + */ + void set_transmit_buffer(uint8_t value); + /** + */ + uint16_t get_number_free_buffers(); + /** + */ + void set_number_free_buffers(uint16_t value); + /** + */ + uint16_t get_buffer_length(); + /** + */ + void set_buffer_length(uint16_t value); + /** + */ + uint16_t get_pending_data(); + /** + */ + void set_pending_data(uint16_t value); + /** + */ + uint16_t get_op_code(); + /** + */ + void set_op_code(uint16_t code); + /** + */ + uint16_t get_released_packets(); + /** + */ + void set_number_of_released_packets(uint16_t value); + /** + */ + uint16_t get_sent_packets(); + /** + */ + void set_sent_packets(uint16_t value); + + int32_t get_transmit_error(); + void set_transmit_error(int32_t value); + + uint16_t get_buffer_size(void); + void set_buffer_size(uint16_t value); + + void *get_func_pointer(FunctionNumber function); + + uint8_t *get_received_data(void); + void set_received_data(uint8_t *pointer); + +private: + uint8_t _data_received_flag; + bool _tx_complete_signal; + uint16_t _rx_event_opcode; + uint16_t _free_buffers; + uint16_t _buffer_length; + uint16_t _buffer_size; + uint16_t _rx_data_pending; + uint16_t _sent_packets; + uint16_t _released_packets; + int32_t _transmit_data_error; + uint8_t *_received_data; + uint8_t _rx_buffer[CC3000_RX_BUFFER_SIZE]; + uint8_t _tx_buffer[CC3000_TX_BUFFER_SIZE]; +private: + int8_t *(* _fFWPatches)(uint32_t *length); + int8_t *(* _fDriverPatches)(uint32_t *length); + int8_t *(* _fBootLoaderPatches)(uint32_t *length); +}; + +/** Forward declaration classes + */ +class cc3000_hci; +class cc3000_nvmem; +class cc3000_spi; +class cc3000; + +/** + */ +class cc3000_event { +public: + cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000); + ~cc3000_event(); + + void hci_unsol_handle_patch_request(uint8_t *event_hdr); + uint8_t *hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen); + int32_t hci_unsol_event_handler(uint8_t *event_hdr); + int32_t hci_unsolicited_event_handler(void); + int32_t get_socket_active_status(int32_t sd); + void set_socket_active_status(int32_t sd, int32_t status); + int32_t hci_event_unsol_flowcontrol_handler(uint8_t *event); + void update_socket_active_status(uint8_t *resp_params); + void simplelink_wait_event(uint16_t op_code, void *ret_param); + void simplelink_wait_data(uint8_t *buffer, uint8_t *from, uint8_t *fromlen); + + void received_handler(uint8_t *buffer); + private: + uint32_t socket_active_status; + cc3000_simple_link &_simple_link; + cc3000_hci &_hci; + cc3000_spi &_spi; + cc3000 &_cc3000; +}; + +class cc3000_netapp { +public: + cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci, cc3000_event &event); + ~cc3000_netapp(); + int32_t config_mac_adrress(uint8_t *mac); + int32_t dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server); +#ifndef CC3000_TINY_DRIVER + void ipconfig(tNetappIpconfigRetArgs *ipconfig); + int32_t timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity); + int32_t ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout); + void ping_report(); + int32_t ping_stop(); + int32_t arp_flush(); +#endif +private: + cc3000_simple_link &_simple_link; + cc3000_nvmem &_nvmem; + cc3000_hci &_hci; + cc3000_event &_event; +}; + +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG +class cc3000_security { +public: + void expandKey(uint8_t *expanded_key, uint8_t *key); + uint8_t galois_mul2(uint8_t value); + void aes_encr(uint8_t *state, uint8_t *expanded_key); + void aes_decr(uint8_t *state, uint8_t *expanded_key); + void aes_encrypt(uint8_t *state, uint8_t *key); + void aes_decrypt(uint8_t *state, uint8_t *key); + int32_t aes_read_key(uint8_t *key); + int32_t aes_write_key(uint8_t *key); +private: + uint8_t _expanded_key[176]; +}; +#endif + +class cc3000_socket { +public: + cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event); + ~cc3000_socket(); + int32_t socket(int32_t domain, int32_t type, int32_t protocol); + int32_t accept(int32_t sd, sockaddr *addr, socklen_t *addrlen); + int32_t bind(int32_t sd, const sockaddr *addr, int32_t addrlen); + int32_t HostFlowControlConsumeBuff(int32_t sd); + int32_t closesocket(int32_t sd); + int32_t listen(int32_t sd, int32_t backlog); + int32_t connect(int32_t sd, const sockaddr *addr, int32_t addrlen); + int32_t select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout); + int32_t getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen); + int32_t simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode); + int32_t simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode); + int32_t recv(int32_t sd, void *buf, int32_t len, int32_t flags); + int32_t recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen); + int32_t send(int32_t sd, const void *buf, int32_t len, int32_t flags); + int32_t sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen); + int32_t mdns_advertiser(uint16_t mdns_enabled, uint8_t * device_service_name, uint16_t device_service_name_length); +#ifndef CC3000_TINY_DRIVER + int32_t gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr); + int32_t setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen); +#endif +private: + cc3000_simple_link &_simple_link; + cc3000_hci &_hci; + cc3000_event &_event; +}; + +/** SPI communication class + */ +class cc3000_spi { +public: + /** ctor + */ + cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link); + /** dtor + */ + ~cc3000_spi(); + /** Close SPI - disables IRQ and set received buffer to 0 + * \param none + * \return none + */ + void close(); + /** + * \param none + * \return none + */ + void open(); + /** + * \param buffer + * \param length + * \return none + */ + uint32_t first_write(uint8_t *buffer, uint16_t length); + /** + */ + uint32_t write(uint8_t *buffer, uint16_t length); + /** + */ + void write_synchronous(uint8_t *data, uint16_t size); + /** + */ + void read_synchronous(uint8_t *data, uint16_t size); + /** + */ + uint32_t read_data_cont(); + /** + */ + void wlan_irq_enable(); + /** + */ + void wlan_irq_disable(); + /** + */ + void wlan_irq_set(uint8_t value); + /** + */ + uint32_t wlan_irq_read(); + /** + */ + void WLAN_IRQHandler(); + /** + */ + void write_wlan_en(uint8_t value); +private: + tSpiInfo _spi_info; + InterruptIn _wlan_irq; + DigitalOut _wlan_en; + DigitalOut _wlan_cs; + SPI _wlan_spi; + IRQn_Type _irq_port; + pFunctionPointer_t _function_pointer; + cc3000_event &_event; + cc3000_simple_link &_simple_link; +}; + +class cc3000_hci { +public: + cc3000_hci(cc3000_spi &spi); + ~cc3000_hci(); + uint16_t command_send(uint16_t op_code, uint8_t *buffer, uint8_t length); + uint32_t data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length, + uint16_t data_length, const uint8_t *tail, uint16_t tail_length); + void data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, + uint16_t data_length); + void patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length); +private: + cc3000_spi &_spi; +}; + +class cc3000_nvmem { +public: + cc3000_nvmem(cc3000_hci &hci, cc3000_event &_event,cc3000_simple_link &simple_link); + ~cc3000_nvmem(); + int32_t read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff); + int32_t write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff); + uint8_t set_mac_address(uint8_t *mac); + uint8_t get_mac_address(uint8_t *mac); + uint8_t write_patch(uint32_t file_id, uint32_t length, const uint8_t *data); + int32_t create_entry(uint32_t file_id, uint32_t new_len); +#ifndef CC3000_TINY_DRIVER + uint8_t read_sp_version(uint8_t* patch_ver); +#endif +private: + cc3000_hci &_hci; + cc3000_event &_event; + cc3000_simple_link &_simple_link; +}; + +class cc3000_wlan { +public: + cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci); + ~cc3000_wlan(); + /** Send SIMPLE LINK START to cc3000 + * \param patches_available_host Flag to indicate if patches are available + * \return none + */ + void simpleLink_init_start(uint16_t patches_available_host); + /** Start wlan device. Blocking call until init is completed + * \param patches_available_host Flag to indicate if patches are available + * \return none + */ + void start(uint16_t patches_available_host); + /** Stop wlan device + * \param none + * \return none + */ + void stop(void); +#ifndef CC3000_TINY_DRIVER + int32_t connect(uint32_t sec_type, const uint8_t *ssid, int32_t ssid_length, uint8_t *b_ssid, uint8_t *key, int32_t key_len); + int32_t 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); + int32_t ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results); + int32_t 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); + int32_t ioctl_statusget(void); +#else + int32_t connect(const uint8_t *ssid, int32_t ssid_length); + int32_t 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); +#endif +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG + int32_t smart_config_process(void); +#endif + int32_t disconnect(); + int32_t ioctl_set_connection_policy(uint32_t should_connect_to_open_ap, uint32_t use_fast_connect, uint32_t use_profiles); + int32_t ioctl_del_profile(uint32_t index); + int32_t set_event_mask(uint32_t mask); + int32_t smart_config_start(uint32_t encrypted_flag); + int32_t smart_config_stop(void); + int32_t smart_config_set_prefix(uint8_t *new_prefix); +private: + cc3000_simple_link &_simple_link; + cc3000_event &_event; + cc3000_spi &_spi; + cc3000_hci &_hci; +}; + +/** Client TCP/UDP class - TODO - not complete client + */ +class cc3000_client { +public: + /** + */ + cc3000_client(cc3000 &cc3000_ref); + /** + */ + cc3000_client(cc3000 &cc3000_ref, int16_t socket); + /** + */ + bool connected(void); + /** + */ + int16_t write(const void *buffer, uint16_t length, uint32_t flags); + /** + */ + int16_t read(void *buffer, uint16_t length, uint32_t flags); + /** + */ + void close(void); + +private: + int16_t _current_socket; + cc3000 &_cc3000; +}; + +/** Server TCP/UDP + */ +class cc3000_server { +public: + /** ctor (server was not created successfully) + */ + cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add); + /** ctor + */ + cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add, int16_t socket); + /** Blocking accept + */ + int32_t accept(void); + /** + */ + int32_t receive(void *buffer, uint16_t length, uint32_t flags); + /** + */ + int32_t send(void *buffer, uint16_t length, uint32_t flags); + /** + */ + void bind(void); + /** + */ + void listen(uint32_t backlog); + /** + */ + void close(void); +private: + int16_t _current_socket; + sockaddr _socket_address; + cc3000 &_cc3000; +}; + +/** The main class of entire cc3000 implementation + */ +class cc3000 { +public: + typedef struct { + bool dhcp; + bool connected; + uint8_t socket; + bool smart_config_complete; + bool stop_smart_config; + bool dhcp_configured; + bool ok_to_shut_down; + } tStatus; + /** ctor for cc3000 class. + * \param cc3000_irq IRQ pin + * \param cc3000_en Enable pin + * \param cc3000_cs Chip select pin + * \param cc3000_spi SPI interface + * \param irq_port IRQ pin's port + */ + cc3000(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port); + /** dtor + */ + ~cc3000(); + /** Initiate cc3000. It starts the wlan communication and deletes profiles. + * \param patch Patch + */ + void start(uint8_t patch); + /** Stops the wlan communication. + */ + void stop(); + /** Restarts the wlan communication. + */ + void restart(uint8_t patch); + /** Disconnect wlan device + * + */ + bool disconnect(void); + /** Callback which is called from the event class. This updates status of cc3000. + * \param event_type Type of the event + * \param data Pointer to data + * \param length Length of data + * \return none + */ + void usync_callback(int32_t event_type, uint8_t *data, uint8_t length); + /** Connect to SSID (open/secured) with timeout (10ms). + * \param ssid SSID name + * \param key Security key (if key = 0, open connection) + * \param security_mode Security mode + * \return true if connection was established, false otherwise. + */ + bool connect_to_AP(const uint8_t *ssid, const uint8_t *key, int32_t security_mode); + /** Connect to SSID which is secured + * \param ssid SSID name + * \param key Security key + * \param security_mode Security mode + * \return true if connection was established, false otherwise. + */ + bool connect_secure(const uint8_t *ssid, const uint8_t *key, int32_t security_mode); + /** Connect to SSID which is open (no security) + * \param ssid SSID name + * \return true if connection was established, false otherwise. + */ + bool connect_open(const uint8_t *ssid); + /** Status of the cc3000 connection. + * \return true if it's connected, false otherwise. + */ + bool is_connected(); + /** Status of DHCP. + * \param none + * \return true if DCHP is configured, false otherwise. + */ + bool is_dhcp_configured(); + /** Status of smart confing completation. + * \param none + * \return smart config was set, false otherwise. + */ + bool is_smart_confing_completed(); + /** Return the cc3000's mac address. + * \param address Retreived mac address. + * \return + */ + uint8_t get_mac_address(uint8_t address[6]); + /** Set the cc3000's mac address + * \param address Mac address to be set + * \return + */ + uint8_t set_mac_address(uint8_t address[6]); + /** Get user file info + * \param info_file Pointer where info will be stored + * \param size Available size + * \return none + */ + void get_user_file_info(uint8_t *info_file, size_t size); + /** Set user filo info + * \param info_file Pointer to user's info + * \return none + */ + void set_user_file_info(uint8_t *info_file, size_t size); + /** Start smart config + * \param smart_config_key Pointer to smart config key + * \return none + */ + void start_smart_config(const uint8_t *smart_config_key); /* TODO enable AES ? */ +#ifndef CC3000_TINY_DRIVER + /** Return ip configuration + * \param ip_config Pointer to ipconfig data + * \return true if it's connected and info was retrieved, false otherwise. + */ + bool get_ip_config(tNetappIpconfigRetArgs *ip_config); +#endif + /** Creates tcp client + * \param ip_address Client's IP address + * \param port Client's PORT + * \return client with socket != -1 + */ + cc3000_client create_tcp_client(uint32_t ip_address, uint16_t port); + /** Creates tcp server + * \param ip_address Server's IP address + * \param port Server's PORT + * \return server with socket != -1 + */ + cc3000_server create_tcp_server(uint32_t ip_address, uint16_t port); + /** Creates udp client + * \param ip_address Server's IP address + * \param port Server's PORT + * \return client with socket != -1 + */ + cc3000_client create_udp_client(uint32_t ip_address, uint16_t port); + /** Delete all stored profiles + * \param none + * \return none + */ + void delete_profiles(void); + /** + * + */ + uint32_t ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size); + + static cc3000 *get_instance() { + return _inst; + } +public: + cc3000_simple_link _simple_link; + cc3000_event _event; +#ifndef CC3000_UNENCRYPTED_SMART_CONFIG + cc3000_security _security; +#endif + cc3000_socket _socket; + cc3000_spi _spi; + cc3000_hci _hci; + cc3000_nvmem _nvmem; + cc3000_netapp _netapp; + cc3000_wlan _wlan; +protected: + static cc3000 *_inst; +private: + tStatus _status; + netapp_pingreport_args_t _ping_report; + bool _closed_sockets[MAX_SOCKETS]; +}; + +/** +* Copy 32 bit to stream while converting to little endian format. +* @param p pointer to the new stream +* @param u32 pointer to the 32 bit +* @return pointer to the new stream +*/ +uint8_t *UINT32_TO_STREAM_f (uint8_t *p, uint32_t u32); + +/** +* Copy 16 bit to stream while converting to little endian format. +* @param p pointer to the new stream +* @param u32 pointer to the 16 bit +* @return pointer to the new stream +*/ +uint8_t *UINT16_TO_STREAM_f (uint8_t *p, uint16_t u16); + +/** +* Copy received stream to 16 bit in little endian format. +* @param p pointer to the stream +* @param offset offset in the stream +* @return pointer to the new 16 bit +*/ +uint16_t STREAM_TO_UINT16_f(uint8_t* p, uint16_t offset); + +/** +* Copy received stream to 32 bit in little endian format. +* @param p pointer to the stream +* @param offset offset in the stream +* @return pointer to the new 32 bit +*/ +uint32_t STREAM_TO_UINT32_f(uint8_t* p, uint16_t offset); + +} /* end of mbed_cc3000 namespace */ + + +#endif
--- a/cc3000_client.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_client.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,72 +1,72 @@ -/***************************************************************************** -* -* 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_client::cc3000_client(cc3000 &cc3000_ref) : _cc3000(cc3000_ref) { - _current_socket = -1; -} - -cc3000_client::cc3000_client(cc3000 &cc3000_ref, int16_t socket) : _cc3000(cc3000_ref) { - _current_socket = socket; -} - -bool cc3000_client::connected(void) { - if (_current_socket < 0) { - return false; - } - - return true; -} - -int16_t cc3000_client::write(const void *buffer, uint16_t length, uint32_t flags = 0) { - return _cc3000._socket.send(_current_socket, buffer, length, flags); -} - -int16_t cc3000_client::read(void *buffer, uint16_t length, uint32_t flags) -{ - return _cc3000._socket.recv(_current_socket, buffer, length, flags); - -} - -} /* end of mbed_cc3000 namespace */ +/***************************************************************************** +* +* 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_client::cc3000_client(cc3000 &cc3000_ref) : _cc3000(cc3000_ref) { + _current_socket = -1; +} + +cc3000_client::cc3000_client(cc3000 &cc3000_ref, int16_t socket) : _cc3000(cc3000_ref) { + _current_socket = socket; +} + +bool cc3000_client::connected(void) { + if (_current_socket < 0) { + return false; + } + + return true; +} + +int16_t cc3000_client::write(const void *buffer, uint16_t length, uint32_t flags = 0) { + return _cc3000._socket.send(_current_socket, buffer, length, flags); +} + +int16_t cc3000_client::read(void *buffer, uint16_t length, uint32_t flags) +{ + return _cc3000._socket.recv(_current_socket, buffer, length, flags); + +} + +} /* end of mbed_cc3000 namespace */
--- a/cc3000_common.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_common.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,198 +1,198 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_COMMON_H -#define CC3000_COMMON_H - -#include <errno.h> - -//#define CC3000_TINY_DRIVER // Driver for small memory model CPUs - -#define ESUCCESS 0 -#define EFAIL -1 -#define EERROR EFAIL - -#define CC3000_UNENCRYPTED_SMART_CONFIG // No encryption - -#define ERROR_SOCKET_INACTIVE -57 - -#define HCI_CC_PAYLOAD_LEN 5 - -#define WLAN_ENABLE (1) -#define WLAN_DISABLE (0) - -#define MAC_ADDR_LEN (6) - - -/*Defines for minimal and maximal RX buffer size. This size includes the spi - header and hci header. - maximal buffer size: MTU + HCI header + SPI header + sendto() args size - minimum buffer size: HCI header + SPI header + max args size - - This buffer is used for receiving events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for reception of the data - and events from CC3000. That is why the minimum is defined. - The calculation for the actual size of buffer for reception is: - Given the maximal data size MAX_DATA that is expected to be received by - application, the required buffer Using recv() or recvfrom(): - - max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen + ucArgsize + 1) - - Using gethostbyname() with minimal buffer size will limit the host name returned to 99 bytes. - The 1 is used for the overrun detection -*/ - -#define CC3000_MINIMAL_RX_SIZE (118 + 1) -#define CC3000_MAXIMAL_RX_SIZE (511 + 1) - -/*Defines for minimal and maximal TX buffer size. - This buffer is used for sending events and data. - The packet can not be longer than MTU size and CC3000 does not support - fragmentation. Note that the same buffer is used for transmission of the data - and commands. That is why the minimum is defined. - The calculation for the actual size of buffer for transmission is: - Given the maximal data size MAX_DATA, the required buffer is: - Using Sendto(): - - max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE - + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - Using Send(): - - max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE - + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) - - The 1 is used for the overrun detection */ - -#define CC3000_MINIMAL_TX_SIZE (118 + 1) -#define CC3000_MAXIMAL_TX_SIZE (1519 + 1) - -//TX and RX buffer size - allow to receive and transmit maximum data at lengh 8. -#ifdef CC3000_TINY_DRIVER -#define TINY_CC3000_MAXIMAL_RX_SIZE 44 -#define TINY_CC3000_MAXIMAL_TX_SIZE 59 -#endif - -/*In order to determine your preferred buffer size, - change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between - the minimal and maximal specified above. - Note that the buffers are allocated by SPI. -*/ - -#ifndef CC3000_TINY_DRIVER - - #define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE) - #define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE) - #define SP_PORTION_SIZE 512 - -//TINY DRIVER: We use smaller rx and tx buffers in order to minimize RAM consumption -#else - #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE) - #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE) - #define SP_PORTION_SIZE 32 -#endif - - -//Copy 8 bit to stream while converting to little endian format. -#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);} -//Copy 16 bit to stream while converting to little endian format. -#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16)) -//Copy 32 bit to stream while converting to little endian format. -#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32)) -//Copy a specified value length bits (l) to stream while converting to little endian format. -#define ARRAY_TO_STREAM(p, a, l) {uint32_t _i; for (_i = 0; _i < l; _i++) *(p)++ = ((uint8_t *) a)[_i];} -//Copy received stream to 8 bit in little endian format. -#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (uint8_t)(*(_p + _offset));} -//Copy received stream to 16 bit in little endian format. -#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);} -//Copy received stream to 32 bit in little endian format. -#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);} -#define STREAM_TO_STREAM(p, a, l) {uint32_t _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];} - -typedef struct _sockaddr_t -{ - uint16_t family; - uint8_t data[14]; -} sockaddr; - -struct timeval -{ - int32_t tv_sec; /* seconds */ - int32_t tv_usec; /* microseconds */ -}; - -#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length) - -/* 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) - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_COMMON_H +#define CC3000_COMMON_H + +#include <errno.h> + +//#define CC3000_TINY_DRIVER // Driver for small memory model CPUs + +#define ESUCCESS 0 +#define EFAIL -1 +#define EERROR EFAIL + +#define CC3000_UNENCRYPTED_SMART_CONFIG // No encryption + +#define ERROR_SOCKET_INACTIVE -57 + +#define HCI_CC_PAYLOAD_LEN 5 + +#define WLAN_ENABLE (1) +#define WLAN_DISABLE (0) + +#define MAC_ADDR_LEN (6) + + +/*Defines for minimal and maximal RX buffer size. This size includes the spi + header and hci header. + maximal buffer size: MTU + HCI header + SPI header + sendto() args size + minimum buffer size: HCI header + SPI header + max args size + + This buffer is used for receiving events and data. + The packet can not be longer than MTU size and CC3000 does not support + fragmentation. Note that the same buffer is used for reception of the data + and events from CC3000. That is why the minimum is defined. + The calculation for the actual size of buffer for reception is: + Given the maximal data size MAX_DATA that is expected to be received by + application, the required buffer Using recv() or recvfrom(): + + max(CC3000_MINIMAL_RX_SIZE, MAX_DATA + HEADERS_SIZE_DATA + fromlen + ucArgsize + 1) + + Using gethostbyname() with minimal buffer size will limit the host name returned to 99 bytes. + The 1 is used for the overrun detection +*/ + +#define CC3000_MINIMAL_RX_SIZE (118 + 1) +#define CC3000_MAXIMAL_RX_SIZE (511 + 1) + +/*Defines for minimal and maximal TX buffer size. + This buffer is used for sending events and data. + The packet can not be longer than MTU size and CC3000 does not support + fragmentation. Note that the same buffer is used for transmission of the data + and commands. That is why the minimum is defined. + The calculation for the actual size of buffer for transmission is: + Given the maximal data size MAX_DATA, the required buffer is: + Using Sendto(): + + max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE + + SOCKET_SENDTO_PARAMS_LEN + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) + + Using Send(): + + max(CC3000_MINIMAL_TX_SIZE, MAX_DATA + SPI_HEADER_SIZE + + HCI_CMND_SEND_ARG_LENGTH + SIMPLE_LINK_HCI_DATA_HEADER_SIZE + 1) + + The 1 is used for the overrun detection */ + +#define CC3000_MINIMAL_TX_SIZE (118 + 1) +#define CC3000_MAXIMAL_TX_SIZE (1519 + 1) + +//TX and RX buffer size - allow to receive and transmit maximum data at lengh 8. +#ifdef CC3000_TINY_DRIVER +#define TINY_CC3000_MAXIMAL_RX_SIZE 44 +#define TINY_CC3000_MAXIMAL_TX_SIZE 59 +#endif + +/*In order to determine your preferred buffer size, + change CC3000_MAXIMAL_RX_SIZE and CC3000_MAXIMAL_TX_SIZE to a value between + the minimal and maximal specified above. + Note that the buffers are allocated by SPI. +*/ + +#ifndef CC3000_TINY_DRIVER + + #define CC3000_RX_BUFFER_SIZE (CC3000_MAXIMAL_RX_SIZE) + #define CC3000_TX_BUFFER_SIZE (CC3000_MAXIMAL_TX_SIZE) + #define SP_PORTION_SIZE 512 + +//TINY DRIVER: We use smaller rx and tx buffers in order to minimize RAM consumption +#else + #define CC3000_RX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_RX_SIZE) + #define CC3000_TX_BUFFER_SIZE (TINY_CC3000_MAXIMAL_TX_SIZE) + #define SP_PORTION_SIZE 32 +#endif + + +//Copy 8 bit to stream while converting to little endian format. +#define UINT8_TO_STREAM(_p, _val) {*(_p)++ = (_val);} +//Copy 16 bit to stream while converting to little endian format. +#define UINT16_TO_STREAM(_p, _u16) (UINT16_TO_STREAM_f(_p, _u16)) +//Copy 32 bit to stream while converting to little endian format. +#define UINT32_TO_STREAM(_p, _u32) (UINT32_TO_STREAM_f(_p, _u32)) +//Copy a specified value length bits (l) to stream while converting to little endian format. +#define ARRAY_TO_STREAM(p, a, l) {uint32_t _i; for (_i = 0; _i < l; _i++) *(p)++ = ((uint8_t *) a)[_i];} +//Copy received stream to 8 bit in little endian format. +#define STREAM_TO_UINT8(_p, _offset, _u8) {_u8 = (uint8_t)(*(_p + _offset));} +//Copy received stream to 16 bit in little endian format. +#define STREAM_TO_UINT16(_p, _offset, _u16) {_u16 = STREAM_TO_UINT16_f(_p, _offset);} +//Copy received stream to 32 bit in little endian format. +#define STREAM_TO_UINT32(_p, _offset, _u32) {_u32 = STREAM_TO_UINT32_f(_p, _offset);} +#define STREAM_TO_STREAM(p, a, l) {uint32_t _i; for (_i = 0; _i < l; _i++) *(a)++= ((uint8_t *) p)[_i];} + +typedef struct _sockaddr_t +{ + uint16_t family; + uint8_t data[14]; +} sockaddr; + +struct timeval +{ + int32_t tv_sec; /* seconds */ + int32_t tv_usec; /* microseconds */ +}; + +#define SMART_CONFIG_PROFILE_SIZE 67 // 67 = 32 (max ssid) + 32 (max key) + 1 (SSID length) + 1 (security type) + 1 (key length) + +/* 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) + +#endif
--- a/cc3000_event.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_event.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,664 +1,664 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_event.h" -#include "cc3000_netapp.h" - -namespace mbed_cc3000 { - -#if CC3000_DEBUG == 1 -const char *HCI_EVENT_STR[] = -{ - "Socket", - "Bind", - "Send", - "Recv", - "Accept", - "Listen", - "Connect", - "BSD Select", - "Set Socket Options", - "Get Socket Options", - "Close Socket", - "Unknown", - "Recv From", - "Write", - "Send To", - "Get Hostname", - "mDNS Advertise" -}; - -const char *HCI_NETAPP_STR[] = -{ - "DHCP", - "Ping Sent", - "Ping Report", - "Ping Stop", - "IP Config", - "ARP Flush", - "Unknown", - "Set Debug level", - "Set Timers" -}; - -// from 0-7 -const char *HCI_MISC_STR[] = -{ - "BASE - Error?", - "Connecting", - "Disconnect", - "Scan Param", - "Connect Policy", - "Add Profile", - "Del Profile", - "Get Scan Res", - "Event Mask", - "Status Req", - "Config Start", - "Config Stop", - "Config Set Prefix", - "Config Patch", -}; -#endif - -cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000) - : socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) { - -} - -cc3000_event::~cc3000_event() { - -} - -/* TODO removed buffer, set it in init */ -void cc3000_event::received_handler(uint8_t *buffer) { - _simple_link.set_data_received_flag(1); - _simple_link.set_received_data(buffer); - - hci_unsolicited_event_handler(); -} - -void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) { - uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - uint32_t length = 0; - uint8_t *patch; - - switch (*params) - { - case HCI_EVENT_PATCHES_DRV_REQ: - { - tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES); - if (func_pointer) - { - patch = func_pointer(&length); - if (patch) - { - _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length); - return; - } - } - - // Send 0 length Patches response event - _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0); - break; - } - case HCI_EVENT_PATCHES_FW_REQ: - { - tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES); - if (func_pointer) - { - patch = func_pointer(&length); - // Build and send a patch - if (patch) - { - _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length); - return; - } - } - // Send 0 length Patches response event - _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0); - break; - } - case HCI_EVENT_PATCHES_BOOTLOAD_REQ: - { - tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES); - if (func_pointer) - { - patch = func_pointer(&length); - if (patch) - { - _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length); - return; - } - } - // Send 0 length Patches response event - _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0); - break; - } - } -} - -static void hci_event_debug_print(uint16_t hciEventNo) -{ -#if CC3000_DEBUG == 1 - if ((hciEventNo > HCI_CMND_SOCKET_BASE) && ( hciEventNo <= HCI_CMND_MDNS_ADVERTISE)) - { - DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_EVENT_STR[hciEventNo-HCI_CMND_SOCKET]); - } - else if ((hciEventNo > HCI_CMND_NETAPP_BASE) && ( hciEventNo <= HCI_NETAPP_SET_TIMERS)) - { - DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_NETAPP_STR[hciEventNo-HCI_NETAPP_DHCP]); - } - else if (hciEventNo < HCI_CMND_WLAN_CONFIGURE_PATCH+1) - { - DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_MISC_STR[hciEventNo]); - } - else - { - DBG_HCI("Event Received : 0x%04X", hciEventNo); - } -#endif -} - -uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) { - uint8_t *received_data, argument_size; - uint16_t length; - uint8_t *pucReceivedParams; - uint16_t received_op_code = 0; - uint32_t return_value; - uint8_t * RecvParams; - uint8_t *RetParams; - - while (1) - { - if (_simple_link.get_data_received_flag() != 0) - { - received_data = _simple_link.get_received_data(); - if (*received_data == HCI_TYPE_EVNT) - { - // Event Received - STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code); - pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE; - RecvParams = pucReceivedParams; - RetParams = (uint8_t *)ret_param; - - // unsolicited event received - finish handling - if (hci_unsol_event_handler((uint8_t *)received_data) == 0) - { - STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length); - - hci_event_debug_print( received_op_code ); - - switch(received_op_code) - { - case HCI_CMND_READ_BUFFER_SIZE: - { - uint16_t temp = _simple_link.get_number_free_buffers(); - STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp); - _simple_link.set_number_free_buffers(temp); - - temp = _simple_link.get_buffer_length(); - STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp); - _simple_link.set_buffer_length(temp); - } - break; - - case HCI_CMND_WLAN_CONFIGURE_PATCH: - case HCI_NETAPP_DHCP: - case HCI_NETAPP_PING_SEND: - case HCI_NETAPP_PING_STOP: - case HCI_NETAPP_ARP_FLUSH: - case HCI_NETAPP_SET_DEBUG_LEVEL: - case HCI_NETAPP_SET_TIMERS: - case HCI_EVNT_NVMEM_READ: - case HCI_EVNT_NVMEM_CREATE_ENTRY: - case HCI_CMND_NVMEM_WRITE_PATCH: - case HCI_NETAPP_PING_REPORT: - case HCI_EVNT_MDNS_ADVERTISE: - - STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); - break; - - case HCI_CMND_SETSOCKOPT: - case HCI_CMND_WLAN_CONNECT: - case HCI_CMND_WLAN_IOCTL_STATUSGET: - case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: - case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: - case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: - case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: - case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: - case HCI_CMND_EVENT_MASK: - case HCI_EVNT_WLAN_DISCONNECT: - case HCI_EVNT_SOCKET: - case HCI_EVNT_BIND: - case HCI_CMND_LISTEN: - case HCI_EVNT_CLOSE_SOCKET: - case HCI_EVNT_CONNECT: - case HCI_EVNT_NVMEM_WRITE: - - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param); - break; - - case HCI_EVNT_READ_SP_VERSION: - - STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 1; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value); - UINT32_TO_STREAM((uint8_t *)ret_param, return_value); - break; - - case HCI_EVNT_BSD_GETHOSTBYNAME: - - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param); - break; - - case HCI_EVNT_ACCEPT: - { - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - - //This argument returns in network order - memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); - break; - } - - case HCI_EVNT_RECV: - case HCI_EVNT_RECVFROM: - { - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param); - - if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) - { - set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); - } - break; - } - - case HCI_EVNT_SEND: - case HCI_EVNT_SENDTO: - { - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - - break; - } - - case HCI_EVNT_SELECT: - { - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param); - break; - } - - case HCI_CMND_GETSOCKOPT: - - STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus); - //This argument returns in network order - memcpy((uint8_t *)ret_param, pucReceivedParams, 4); - break; - - case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: - - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 4; - STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 2; - STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param); - ret_param = ((uint8_t *)ret_param) + 2; - memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); - break; - - case HCI_CMND_SIMPLE_LINK_START: - break; - - case HCI_NETAPP_IPCONFIG: - - //Read IP address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read subnet - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read default GW - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DHCP server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read DNS server - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); - RecvParams += 4; - - //Read Mac address - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); - RecvParams += 6; - - //Read SSID - STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); - - } - } - if (received_op_code == _simple_link.get_op_code()) - { - _simple_link.set_op_code(0); - } - } - else - { - pucReceivedParams = received_data; - STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size); - - STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length); - - // Data received: note that the only case where from and from length - // are not null is in recv from, so fill the args accordingly - if (from) - { - STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen); - memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); - } - - memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size); - - _simple_link.set_pending_data(0); - } - - _simple_link.set_data_received_flag(0); - - //tWlanInterruptEnable func_pointer = (tWlanInterruptEnable)_simple_link.get_func_pointer(WLAN_INTERRUPT_ENABLE); - //func_pointer(); - _spi.wlan_irq_enable(); - - // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts - if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ)) - { - hci_unsol_handle_patch_request((uint8_t *)received_data); - } - if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0)) - { - return NULL; - } - } - } -} - -int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) { - uint8_t *data = NULL; - int32_t event_type; - uint32_t number_of_released_packets; - uint32_t number_of_sent_packets; - - STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); - - if (event_type & HCI_EVNT_UNSOL_BASE) { - switch(event_type) { - case HCI_EVNT_DATA_UNSOL_FREE_BUFF: - { - hci_event_unsol_flowcontrol_handler(event_hdr); - - number_of_released_packets = _simple_link.get_released_packets(); - number_of_sent_packets = _simple_link.get_sent_packets(); - - if (number_of_released_packets == number_of_sent_packets) - { - if (_simple_link.get_tx_complete_signal()) - { - //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); - _cc3000.usync_callback(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0); - } - } - return 1; - } - } - } - - if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) { - switch(event_type) { - case HCI_EVNT_WLAN_KEEPALIVE: - case HCI_EVNT_WLAN_UNSOL_CONNECT: - case HCI_EVNT_WLAN_UNSOL_DISCONNECT: - case HCI_EVNT_WLAN_UNSOL_INIT: - case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: - // { - // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); - // if( func_pointer ) - // { - // func_pointer(event_type, 0, 0); - // } - _cc3000.usync_callback(event_type, 0, 0); - break; - // } - case HCI_EVNT_WLAN_UNSOL_DHCP: - { - uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status - uint8_t *recParams = params; - data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - - //Read IP address - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read subnet - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read default GW - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DHCP server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - data += 4; - //Read DNS server - STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); - // read the status - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams); - - // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); - // if( func_pointer ) - // { - _cc3000.usync_callback(event_type, (uint8_t *)params, sizeof(params)); - // } - break; - } - case HCI_EVNT_WLAN_ASYNC_PING_REPORT: - { - netapp_pingreport_args_t params; - data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE; - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); - STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); - STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time); - STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time); - - // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); - // if (func_pointer) - // { - _cc3000.usync_callback(event_type, (uint8_t *)¶ms, sizeof(params)); - // } - break; - } - case HCI_EVNT_BSD_TCP_CLOSE_WAIT: - { - // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); - // if (func_pointer) - // { - _cc3000.usync_callback(event_type, NULL, 0); - // } - break; - } - - //'default' case which means "event not supported" - default: - return (0); - } - return(1); - } - - if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) { - uint8_t *pArg; - int32_t status; - pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); - STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); - if (ERROR_SOCKET_INACTIVE == status) { - // The only synchronous event that can come from SL device in form of - // command complete is "Command Complete" on data sent, in case SL device - // was unable to transmit - int32_t transmit_error = _simple_link.get_transmit_error(); - STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error); - _simple_link.set_transmit_error(transmit_error); - update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); - return (1); - } - else { - return (0); - } - } - return(0); -} - -int32_t cc3000_event::hci_unsolicited_event_handler(void) { - uint32_t res = 0; - uint8_t *received_data; - - if (_simple_link.get_data_received_flag() != 0) { - received_data = (_simple_link.get_received_data()); - - if (*received_data == HCI_TYPE_EVNT) { - // unsolicited event received - finish handling - if (hci_unsol_event_handler((uint8_t *)received_data) == 1) { - // An unsolicited event was received: - // release the buffer and clean the event received - _simple_link.set_data_received_flag(0); - - res = 1; - _spi.wlan_irq_enable(); - } - } - } - return res; -} - -void cc3000_event::set_socket_active_status(int32_t sd, int32_t status) { - if (M_IS_VALID_SD(sd) && M_IS_VALID_STATUS(status)) - { - socket_active_status &= ~(1 << sd); /* clean socket's mask */ - socket_active_status |= (status << sd); /* set new socket's mask */ - } -} - -int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) { - int32_t temp, value; - uint16_t i; - uint16_t pusNumberOfHandles=0; - uint8_t *pReadPayload; - - STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); - pReadPayload = ((uint8_t *)event + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); - temp = 0; - - for(i = 0; i < pusNumberOfHandles; i++) { - STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value); - temp += value; - pReadPayload += FLOW_CONTROL_EVENT_SIZE; - } - - _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp); - _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp); - - return(ESUCCESS); -} - -int32_t cc3000_event::get_socket_active_status(int32_t sd) { - if(M_IS_VALID_SD(sd)) { - return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE; - } else { - return SOCKET_STATUS_INACTIVE; - } -} - -void cc3000_event::update_socket_active_status(uint8_t *resp_params) { - int32_t status, sd; - - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); - STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); - - if(ERROR_SOCKET_INACTIVE == status) { - set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } -} - -void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) { - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction - _simple_link.set_op_code(op_code); - hci_event_handler(ret_param, 0, 0); -} - -void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) { - // In the blocking implementation the control to caller will be returned only - // after the end of current transaction, i.e. only after data will be received - _simple_link.set_pending_data(1); - hci_event_handler(pBuf, from, fromlen); -} - - -} /* end of cc3000 namespace */ +/***************************************************************************** +* +* 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" +#include "cc3000_event.h" +#include "cc3000_netapp.h" + +namespace mbed_cc3000 { + +#ifdef CC3000_DEBUG_HCI_RX +const char *HCI_EVENT_STR[] = +{ + "Socket", + "Bind", + "Send", + "Recv", + "Accept", + "Listen", + "Connect", + "BSD Select", + "Set Socket Options", + "Get Socket Options", + "Close Socket", + "Unknown", + "Recv From", + "Write", + "Send To", + "Get Hostname", + "mDNS Advertise" +}; + +const char *HCI_NETAPP_STR[] = +{ + "DHCP", + "Ping Sent", + "Ping Report", + "Ping Stop", + "IP Config", + "ARP Flush", + "Unknown", + "Set Debug level", + "Set Timers" +}; + +// from 0-7 +const char *HCI_MISC_STR[] = +{ + "BASE - Error?", + "Connecting", + "Disconnect", + "Scan Param", + "Connect Policy", + "Add Profile", + "Del Profile", + "Get Scan Res", + "Event Mask", + "Status Req", + "Config Start", + "Config Stop", + "Config Set Prefix", + "Config Patch", +}; +#endif + +cc3000_event::cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000) + : socket_active_status(SOCKET_STATUS_INIT_VAL), _simple_link(simplelink), _hci(hci), _spi(spi), _cc3000(cc3000) { + +} + +cc3000_event::~cc3000_event() { + +} + +/* TODO removed buffer, set it in init */ +void cc3000_event::received_handler(uint8_t *buffer) { + _simple_link.set_data_received_flag(1); + _simple_link.set_received_data(buffer); + + hci_unsolicited_event_handler(); +} + +void cc3000_event::hci_unsol_handle_patch_request(uint8_t *event_hdr) { + uint8_t *params = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE; + uint32_t length = 0; + uint8_t *patch; + + switch (*params) + { + case HCI_EVENT_PATCHES_DRV_REQ: + { + tDriverPatches func_pointer = (tDriverPatches)_simple_link.get_func_pointer(DRIVER_PATCHES); + if (func_pointer) + { + patch = func_pointer(&length); + if (patch) + { + _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), patch, length); + return; + } + } + + // Send 0 length Patches response event + _hci.patch_send(HCI_EVENT_PATCHES_DRV_REQ, _simple_link.get_transmit_buffer(), 0, 0); + break; + } + case HCI_EVENT_PATCHES_FW_REQ: + { + tFWPatches func_pointer = (tFWPatches)_simple_link.get_func_pointer(FW_PATCHES); + if (func_pointer) + { + patch = func_pointer(&length); + // Build and send a patch + if (patch) + { + _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), patch, length); + return; + } + } + // Send 0 length Patches response event + _hci.patch_send(HCI_EVENT_PATCHES_FW_REQ, _simple_link.get_transmit_buffer(), 0, 0); + break; + } + case HCI_EVENT_PATCHES_BOOTLOAD_REQ: + { + tBootLoaderPatches func_pointer = (tBootLoaderPatches)_simple_link.get_func_pointer(BOOTLOADER_PATCHES); + if (func_pointer) + { + patch = func_pointer(&length); + if (patch) + { + _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), patch, length); + return; + } + } + // Send 0 length Patches response event + _hci.patch_send(HCI_EVENT_PATCHES_BOOTLOAD_REQ, _simple_link.get_transmit_buffer(), 0, 0); + break; + } + } +} + +static void hci_event_debug_print(uint16_t hciEventNo) +{ +#ifdef CC3000_DEBUG_HCI_RX + if ((hciEventNo > HCI_CMND_SOCKET_BASE) && ( hciEventNo <= HCI_CMND_MDNS_ADVERTISE)) + { + DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_EVENT_STR[hciEventNo-HCI_CMND_SOCKET]); + } + else if ((hciEventNo > HCI_CMND_NETAPP_BASE) && ( hciEventNo <= HCI_NETAPP_SET_TIMERS)) + { + DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_NETAPP_STR[hciEventNo-HCI_NETAPP_DHCP]); + } + else if (hciEventNo < HCI_CMND_WLAN_CONFIGURE_PATCH+1) + { + DBG_HCI("Event Received : 0x%04X - %s", hciEventNo, HCI_MISC_STR[hciEventNo]); + } + else + { + DBG_HCI("Event Received : 0x%04X", hciEventNo); + } +#endif +} + +uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) { + uint8_t *received_data, argument_size; + uint16_t length; + uint8_t *pucReceivedParams; + uint16_t received_op_code = 0; + uint32_t return_value; + uint8_t * RecvParams; + uint8_t *RetParams; + + while (1) + { + if (_simple_link.get_data_received_flag() != 0) + { + received_data = _simple_link.get_received_data(); + if (*received_data == HCI_TYPE_EVNT) + { + // Event Received + STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code); + pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE; + RecvParams = pucReceivedParams; + RetParams = (uint8_t *)ret_param; + + // unsolicited event received - finish handling + if (hci_unsol_event_handler((uint8_t *)received_data) == 0) + { + STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length); + + hci_event_debug_print( received_op_code ); + + switch(received_op_code) + { + case HCI_CMND_READ_BUFFER_SIZE: + { + uint16_t temp = _simple_link.get_number_free_buffers(); + STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp); + _simple_link.set_number_free_buffers(temp); + + temp = _simple_link.get_buffer_length(); + STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp); + _simple_link.set_buffer_length(temp); + } + break; + + case HCI_CMND_WLAN_CONFIGURE_PATCH: + case HCI_NETAPP_DHCP: + case HCI_NETAPP_PING_SEND: + case HCI_NETAPP_PING_STOP: + case HCI_NETAPP_ARP_FLUSH: + case HCI_NETAPP_SET_DEBUG_LEVEL: + case HCI_NETAPP_SET_TIMERS: + case HCI_EVNT_NVMEM_READ: + case HCI_EVNT_NVMEM_CREATE_ENTRY: + case HCI_CMND_NVMEM_WRITE_PATCH: + case HCI_NETAPP_PING_REPORT: + case HCI_EVNT_MDNS_ADVERTISE: + + STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); + break; + + case HCI_CMND_SETSOCKOPT: + case HCI_CMND_WLAN_CONNECT: + case HCI_CMND_WLAN_IOCTL_STATUSGET: + case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: + case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: + case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: + case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: + case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: + case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: + case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: + case HCI_CMND_EVENT_MASK: + case HCI_EVNT_WLAN_DISCONNECT: + case HCI_EVNT_SOCKET: + case HCI_EVNT_BIND: + case HCI_CMND_LISTEN: + case HCI_EVNT_CLOSE_SOCKET: + case HCI_EVNT_CONNECT: + case HCI_EVNT_NVMEM_WRITE: + + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param); + break; + + case HCI_EVNT_READ_SP_VERSION: + + STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 1; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value); + UINT32_TO_STREAM((uint8_t *)ret_param, return_value); + break; + + case HCI_EVNT_BSD_GETHOSTBYNAME: + + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param); + break; + + case HCI_EVNT_ACCEPT: + { + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + + //This argument returns in network order + memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); + break; + } + + case HCI_EVNT_RECV: + case HCI_EVNT_RECVFROM: + { + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param); + + if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) + { + set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); + } + break; + } + + case HCI_EVNT_SEND: + case HCI_EVNT_SENDTO: + { + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + + break; + } + + case HCI_EVNT_SELECT: + { + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param); + break; + } + + case HCI_CMND_GETSOCKOPT: + + STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus); + //This argument returns in network order + memcpy((uint8_t *)ret_param, pucReceivedParams, 4); + break; + + case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: + + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 4; + STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 2; + STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param); + ret_param = ((uint8_t *)ret_param) + 2; + memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); + break; + + case HCI_CMND_SIMPLE_LINK_START: + break; + + case HCI_NETAPP_IPCONFIG: + + //Read IP address + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + //Read subnet + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + //Read default GW + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + //Read DHCP server + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + //Read DNS server + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); + RecvParams += 4; + + //Read Mac address + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); + RecvParams += 6; + + //Read SSID + STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); + + } + } + if (received_op_code == _simple_link.get_op_code()) + { + _simple_link.set_op_code(0); + } + } + else + { + pucReceivedParams = received_data; + STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size); + + STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length); + + // Data received: note that the only case where from and from length + // are not null is in recv from, so fill the args accordingly + if (from) + { + STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen); + memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); + } + + memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size); + + _simple_link.set_pending_data(0); + } + + _simple_link.set_data_received_flag(0); + + //tWlanInterruptEnable func_pointer = (tWlanInterruptEnable)_simple_link.get_func_pointer(WLAN_INTERRUPT_ENABLE); + //func_pointer(); + _spi.wlan_irq_enable(); + + // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts + if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ)) + { + hci_unsol_handle_patch_request((uint8_t *)received_data); + } + if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0)) + { + return NULL; + } + } + } +} + +int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) { + uint8_t *data = NULL; + int32_t event_type; + uint32_t number_of_released_packets; + uint32_t number_of_sent_packets; + + STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); + + if (event_type & HCI_EVNT_UNSOL_BASE) { + switch(event_type) { + case HCI_EVNT_DATA_UNSOL_FREE_BUFF: + { + hci_event_unsol_flowcontrol_handler(event_hdr); + + number_of_released_packets = _simple_link.get_released_packets(); + number_of_sent_packets = _simple_link.get_sent_packets(); + + if (number_of_released_packets == number_of_sent_packets) + { + if (_simple_link.get_tx_complete_signal()) + { + //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); + _cc3000.usync_callback(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0); + } + } + return 1; + } + } + } + + if (event_type & HCI_EVNT_WLAN_UNSOL_BASE) { + switch(event_type) { + case HCI_EVNT_WLAN_KEEPALIVE: + case HCI_EVNT_WLAN_UNSOL_CONNECT: + case HCI_EVNT_WLAN_UNSOL_DISCONNECT: + case HCI_EVNT_WLAN_UNSOL_INIT: + case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE: + // { + // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); + // if( func_pointer ) + // { + // func_pointer(event_type, 0, 0); + // } + _cc3000.usync_callback(event_type, 0, 0); + break; + // } + case HCI_EVNT_WLAN_UNSOL_DHCP: + { + uint8_t params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status + uint8_t *recParams = params; + data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE; + + //Read IP address + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + //Read subnet + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + //Read default GW + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + //Read DHCP server + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + data += 4; + //Read DNS server + STREAM_TO_STREAM(data,recParams,NETAPP_IPCONFIG_IP_LENGTH); + // read the status + STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams); + + // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); + // if( func_pointer ) + // { + _cc3000.usync_callback(event_type, (uint8_t *)params, sizeof(params)); + // } + break; + } + case HCI_EVNT_WLAN_ASYNC_PING_REPORT: + { + netapp_pingreport_args_t params; + data = (uint8_t *)(event_hdr) + HCI_EVENT_HEADER_SIZE; + STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent); + STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received); + STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time); + STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time); + STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time); + + // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); + // if (func_pointer) + // { + _cc3000.usync_callback(event_type, (uint8_t *)¶ms, sizeof(params)); + // } + break; + } + case HCI_EVNT_BSD_TCP_CLOSE_WAIT: + { + // tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); + // if (func_pointer) + // { + _cc3000.usync_callback(event_type, NULL, 0); + // } + break; + } + + //'default' case which means "event not supported" + default: + return (0); + } + return(1); + } + + if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) || (event_type == HCI_EVNT_WRITE)) { + uint8_t *pArg; + int32_t status; + pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr); + STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET,status); + if (ERROR_SOCKET_INACTIVE == status) { + // The only synchronous event that can come from SL device in form of + // command complete is "Command Complete" on data sent, in case SL device + // was unable to transmit + int32_t transmit_error = _simple_link.get_transmit_error(); + STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error); + _simple_link.set_transmit_error(transmit_error); + update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); + return (1); + } + else { + return (0); + } + } + return(0); +} + +int32_t cc3000_event::hci_unsolicited_event_handler(void) { + uint32_t res = 0; + uint8_t *received_data; + + if (_simple_link.get_data_received_flag() != 0) { + received_data = (_simple_link.get_received_data()); + + if (*received_data == HCI_TYPE_EVNT) { + // unsolicited event received - finish handling + if (hci_unsol_event_handler((uint8_t *)received_data) == 1) { + // An unsolicited event was received: + // release the buffer and clean the event received + _simple_link.set_data_received_flag(0); + + res = 1; + _spi.wlan_irq_enable(); + } + } + } + return res; +} + +void cc3000_event::set_socket_active_status(int32_t sd, int32_t status) { + if (M_IS_VALID_SD(sd) && M_IS_VALID_STATUS(status)) + { + socket_active_status &= ~(1 << sd); /* clean socket's mask */ + socket_active_status |= (status << sd); /* set new socket's mask */ + } +} + +int32_t cc3000_event::hci_event_unsol_flowcontrol_handler(uint8_t *event) { + int32_t temp, value; + uint16_t i; + uint16_t pusNumberOfHandles=0; + uint8_t *pReadPayload; + + STREAM_TO_UINT16((uint8_t *)event,HCI_EVENT_HEADER_SIZE,pusNumberOfHandles); + pReadPayload = ((uint8_t *)event + HCI_EVENT_HEADER_SIZE + sizeof(pusNumberOfHandles)); + temp = 0; + + for(i = 0; i < pusNumberOfHandles; i++) { + STREAM_TO_UINT16(pReadPayload, FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET, value); + temp += value; + pReadPayload += FLOW_CONTROL_EVENT_SIZE; + } + + _simple_link.set_number_free_buffers(_simple_link.get_number_free_buffers() + temp); + _simple_link.set_number_of_released_packets(_simple_link.get_released_packets() + temp); + + return(ESUCCESS); +} + +int32_t cc3000_event::get_socket_active_status(int32_t sd) { + if(M_IS_VALID_SD(sd)) { + return (socket_active_status & (1 << sd)) ? SOCKET_STATUS_INACTIVE : SOCKET_STATUS_ACTIVE; + } else { + return SOCKET_STATUS_INACTIVE; + } +} + +void cc3000_event::update_socket_active_status(uint8_t *resp_params) { + int32_t status, sd; + + STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); + STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); + + if(ERROR_SOCKET_INACTIVE == status) { + set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); + } +} + +void cc3000_event::simplelink_wait_event(uint16_t op_code, void *ret_param) { + // In the blocking implementation the control to caller will be returned only + // after the end of current transaction + _simple_link.set_op_code(op_code); + hci_event_handler(ret_param, 0, 0); +} + +void cc3000_event::simplelink_wait_data(uint8_t *pBuf, uint8_t *from, uint8_t *fromlen) { + // In the blocking implementation the control to caller will be returned only + // after the end of current transaction, i.e. only after data will be received + _simple_link.set_pending_data(1); + hci_event_handler(pBuf, from, fromlen); +} + + +} /* end of cc3000 namespace */
--- a/cc3000_event.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_event.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,143 +1,143 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_EVENT_H -#define CC3000_EVENT_H - -typedef struct _bsd_read_return_t -{ - int32_t iSocketDescriptor; - int32_t iNumberOfBytes; - uint32_t uiFlags; -} tBsdReadReturnParams; - -typedef struct _bsd_getsockopt_return_t -{ - uint8_t ucOptValue[4]; - uint8_t iStatus; -} tBsdGetSockOptReturnParams; - -typedef struct _bsd_accept_return_t -{ - int32_t iSocketDescriptor; - int32_t iStatus; - sockaddr tSocketAddress; - -} tBsdReturnParams; - -typedef struct _bsd_select_return_t -{ - int32_t iStatus; - uint32_t uiRdfd; - uint32_t uiWrfd; - uint32_t uiExfd; -} tBsdSelectRecvParams; - -typedef struct _bsd_gethostbyname_return_t -{ - int32_t retVal; - int32_t outputAddress; -} tBsdGethostbynameParams; - -#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) -#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) -#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) -#define FLOW_CONTROL_EVENT_SIZE (4) - -#define BSD_RSP_PARAMS_SOCKET_OFFSET (0) -#define BSD_RSP_PARAMS_STATUS_OFFSET (4) - -#define GET_HOST_BY_NAME_RETVAL_OFFSET (0) -#define GET_HOST_BY_NAME_ADDR_OFFSET (4) - -#define ACCEPT_SD_OFFSET (0) -#define ACCEPT_RETURN_STATUS_OFFSET (4) -#define ACCEPT_ADDRESS__OFFSET (8) - -#define SL_RECEIVE_SD_OFFSET (0) -#define SL_RECEIVE_NUM_BYTES_OFFSET (4) -#define SL_RECEIVE__FLAGS__OFFSET (8) - - -#define SELECT_STATUS_OFFSET (0) -#define SELECT_READFD_OFFSET (4) -#define SELECT_WRITEFD_OFFSET (8) -#define SELECT_EXFD_OFFSET (12) - - -#define NETAPP_IPCONFIG_IP_OFFSET (0) -#define NETAPP_IPCONFIG_SUBNET_OFFSET (4) -#define NETAPP_IPCONFIG_GW_OFFSET (8) -#define NETAPP_IPCONFIG_DHCP_OFFSET (12) -#define NETAPP_IPCONFIG_DNS_OFFSET (16) -#define NETAPP_IPCONFIG_MAC_OFFSET (20) -#define NETAPP_IPCONFIG_SSID_OFFSET (26) - -#define NETAPP_IPCONFIG_IP_LENGTH (4) -#define NETAPP_IPCONFIG_MAC_LENGTH (6) -#define NETAPP_IPCONFIG_SSID_LENGTH (32) - - -#define NETAPP_PING_PACKETS_SENT_OFFSET (0) -#define NETAPP_PING_PACKETS_RCVD_OFFSET (4) -#define NETAPP_PING_MIN_RTT_OFFSET (8) -#define NETAPP_PING_MAX_RTT_OFFSET (12) -#define NETAPP_PING_AVG_RTT_OFFSET (16) - -#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) -#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) -#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) -#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) -#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) - -#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((uint8_t *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE) - -#define SOCKET_STATUS_ACTIVE 0 -#define SOCKET_STATUS_INACTIVE 1 -/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE. - Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */ -#define SOCKET_STATUS_INIT_VAL 0xFFFF -#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) -#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) - -#define BSD_RECV_FROM_FROMLEN_OFFSET (4) -#define BSD_RECV_FROM_FROM_OFFSET (16) - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_EVENT_H +#define CC3000_EVENT_H + +typedef struct _bsd_read_return_t +{ + int32_t iSocketDescriptor; + int32_t iNumberOfBytes; + uint32_t uiFlags; +} tBsdReadReturnParams; + +typedef struct _bsd_getsockopt_return_t +{ + uint8_t ucOptValue[4]; + uint8_t iStatus; +} tBsdGetSockOptReturnParams; + +typedef struct _bsd_accept_return_t +{ + int32_t iSocketDescriptor; + int32_t iStatus; + sockaddr tSocketAddress; + +} tBsdReturnParams; + +typedef struct _bsd_select_return_t +{ + int32_t iStatus; + uint32_t uiRdfd; + uint32_t uiWrfd; + uint32_t uiExfd; +} tBsdSelectRecvParams; + +typedef struct _bsd_gethostbyname_return_t +{ + int32_t retVal; + int32_t outputAddress; +} tBsdGethostbynameParams; + +#define FLOW_CONTROL_EVENT_HANDLE_OFFSET (0) +#define FLOW_CONTROL_EVENT_BLOCK_MODE_OFFSET (1) +#define FLOW_CONTROL_EVENT_FREE_BUFFS_OFFSET (2) +#define FLOW_CONTROL_EVENT_SIZE (4) + +#define BSD_RSP_PARAMS_SOCKET_OFFSET (0) +#define BSD_RSP_PARAMS_STATUS_OFFSET (4) + +#define GET_HOST_BY_NAME_RETVAL_OFFSET (0) +#define GET_HOST_BY_NAME_ADDR_OFFSET (4) + +#define ACCEPT_SD_OFFSET (0) +#define ACCEPT_RETURN_STATUS_OFFSET (4) +#define ACCEPT_ADDRESS__OFFSET (8) + +#define SL_RECEIVE_SD_OFFSET (0) +#define SL_RECEIVE_NUM_BYTES_OFFSET (4) +#define SL_RECEIVE__FLAGS__OFFSET (8) + + +#define SELECT_STATUS_OFFSET (0) +#define SELECT_READFD_OFFSET (4) +#define SELECT_WRITEFD_OFFSET (8) +#define SELECT_EXFD_OFFSET (12) + + +#define NETAPP_IPCONFIG_IP_OFFSET (0) +#define NETAPP_IPCONFIG_SUBNET_OFFSET (4) +#define NETAPP_IPCONFIG_GW_OFFSET (8) +#define NETAPP_IPCONFIG_DHCP_OFFSET (12) +#define NETAPP_IPCONFIG_DNS_OFFSET (16) +#define NETAPP_IPCONFIG_MAC_OFFSET (20) +#define NETAPP_IPCONFIG_SSID_OFFSET (26) + +#define NETAPP_IPCONFIG_IP_LENGTH (4) +#define NETAPP_IPCONFIG_MAC_LENGTH (6) +#define NETAPP_IPCONFIG_SSID_LENGTH (32) + + +#define NETAPP_PING_PACKETS_SENT_OFFSET (0) +#define NETAPP_PING_PACKETS_RCVD_OFFSET (4) +#define NETAPP_PING_MIN_RTT_OFFSET (8) +#define NETAPP_PING_MAX_RTT_OFFSET (12) +#define NETAPP_PING_AVG_RTT_OFFSET (16) + +#define GET_SCAN_RESULTS_TABlE_COUNT_OFFSET (0) +#define GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET (4) +#define GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET (8) +#define GET_SCAN_RESULTS_FRAME_TIME_OFFSET (10) +#define GET_SCAN_RESULTS_SSID_MAC_LENGTH (38) + +#define M_BSD_RESP_PARAMS_OFFSET(hci_event_hdr)((uint8_t *)(hci_event_hdr) + HCI_EVENT_HEADER_SIZE) + +#define SOCKET_STATUS_ACTIVE 0 +#define SOCKET_STATUS_INACTIVE 1 +/* Init socket_active_status = 'all ones': init all sockets with SOCKET_STATUS_INACTIVE. + Will be changed by 'set_socket_active_status' upon 'connect' and 'accept' calls */ +#define SOCKET_STATUS_INIT_VAL 0xFFFF +#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) +#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) + +#define BSD_RECV_FROM_FROMLEN_OFFSET (4) +#define BSD_RECV_FROM_FROM_OFFSET (16) + +#endif
--- a/cc3000_hci.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_hci.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,151 +1,151 @@ -/***************************************************************************** -* -* 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_hci::cc3000_hci(cc3000_spi &spi) : _spi(spi) { - -} - -cc3000_hci::~cc3000_hci() { - -} - -uint16_t cc3000_hci::command_send(uint16_t op_code, uint8_t *buffer, uint8_t length) { - unsigned char *stream; - - DBG_HCI_CMD("Command Sent : 0x%04X", op_code); - - stream = (buffer + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_CMND); - stream = UINT16_TO_STREAM(stream, op_code); - UINT8_TO_STREAM(stream, length); - //Update the opcode of the event we will be waiting for - _spi.write(buffer, length + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); - return(0); -} - -uint32_t cc3000_hci::data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length, - uint16_t data_length, const uint8_t *tail, uint16_t tail_length) { - unsigned char *stream; - - stream = ((args) + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, op_code); - UINT8_TO_STREAM(stream, arg_length); - stream = UINT16_TO_STREAM(stream, arg_length + data_length + tail_length); - - // Send the packet - _spi.write(args, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + arg_length + data_length + tail_length); - - return 0; -} - -void cc3000_hci::data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, uint16_t data_length) { - unsigned char *stream = (buffer + SPI_HEADER_SIZE); - - UINT8_TO_STREAM(stream, HCI_TYPE_DATA); - UINT8_TO_STREAM(stream, op_code); - UINT8_TO_STREAM(stream, arg_length); - stream = UINT16_TO_STREAM(stream, arg_length + data_length); - - // Send the command - _spi.write(buffer, arg_length + data_length + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); - - return; -} - -void cc3000_hci::patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length) { - unsigned short usTransLength; - unsigned char *stream = (buffer + SPI_HEADER_SIZE); - UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); - UINT8_TO_STREAM(stream, op_code); - stream = UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - if (data_length <= SL_PATCH_PORTION_SIZE) - { - UINT16_TO_STREAM(stream, data_length); - stream = UINT16_TO_STREAM(stream, data_length); - memcpy((buffer + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, data_length); - // Update the opcode of the event we will be waiting for - _spi.write(buffer, data_length + HCI_PATCH_HEADER_SIZE); - } - else - { - - usTransLength = (data_length/SL_PATCH_PORTION_SIZE); - UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); - stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); - memcpy(buffer + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); - data_length -= SL_PATCH_PORTION_SIZE; - patch += SL_PATCH_PORTION_SIZE; - - // Update the opcode of the event we will be waiting for - _spi.write(buffer, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); - - stream = (buffer + SPI_HEADER_SIZE); - while (data_length) - { - if (data_length <= SL_PATCH_PORTION_SIZE) - { - usTransLength = data_length; - data_length = 0; - - } - else - { - usTransLength = SL_PATCH_PORTION_SIZE; - data_length -= usTransLength; - } - - *(unsigned short *)stream = usTransLength; - memcpy(stream + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); - patch += usTransLength; - - // Update the opcode of the event we will be waiting for - _spi.write((unsigned char *)stream, usTransLength + sizeof(usTransLength)); - } - } -} - -} +/***************************************************************************** +* +* 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_hci::cc3000_hci(cc3000_spi &spi) : _spi(spi) { + +} + +cc3000_hci::~cc3000_hci() { + +} + +uint16_t cc3000_hci::command_send(uint16_t op_code, uint8_t *buffer, uint8_t length) { + unsigned char *stream; + + DBG_HCI_CMD("Command Sent : 0x%04X", op_code); + + stream = (buffer + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_CMND); + stream = UINT16_TO_STREAM(stream, op_code); + UINT8_TO_STREAM(stream, length); + //Update the opcode of the event we will be waiting for + _spi.write(buffer, length + SIMPLE_LINK_HCI_CMND_HEADER_SIZE); + return(0); +} + +uint32_t cc3000_hci::data_send(uint8_t op_code, uint8_t *args, uint16_t arg_length, + uint16_t data_length, const uint8_t *tail, uint16_t tail_length) { + unsigned char *stream; + + stream = ((args) + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_DATA); + UINT8_TO_STREAM(stream, op_code); + UINT8_TO_STREAM(stream, arg_length); + stream = UINT16_TO_STREAM(stream, arg_length + data_length + tail_length); + + // Send the packet + _spi.write(args, SIMPLE_LINK_HCI_DATA_HEADER_SIZE + arg_length + data_length + tail_length); + + return 0; +} + +void cc3000_hci::data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, uint16_t data_length) { + unsigned char *stream = (buffer + SPI_HEADER_SIZE); + + UINT8_TO_STREAM(stream, HCI_TYPE_DATA); + UINT8_TO_STREAM(stream, op_code); + UINT8_TO_STREAM(stream, arg_length); + stream = UINT16_TO_STREAM(stream, arg_length + data_length); + + // Send the command + _spi.write(buffer, arg_length + data_length + SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE); + + return; +} + +void cc3000_hci::patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length) { + unsigned short usTransLength; + unsigned char *stream = (buffer + SPI_HEADER_SIZE); + UINT8_TO_STREAM(stream, HCI_TYPE_PATCH); + UINT8_TO_STREAM(stream, op_code); + stream = UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); + if (data_length <= SL_PATCH_PORTION_SIZE) + { + UINT16_TO_STREAM(stream, data_length); + stream = UINT16_TO_STREAM(stream, data_length); + memcpy((buffer + SPI_HEADER_SIZE) + HCI_PATCH_HEADER_SIZE, patch, data_length); + // Update the opcode of the event we will be waiting for + _spi.write(buffer, data_length + HCI_PATCH_HEADER_SIZE); + } + else + { + + usTransLength = (data_length/SL_PATCH_PORTION_SIZE); + UINT16_TO_STREAM(stream, data_length + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE + usTransLength*SIMPLE_LINK_HCI_PATCH_HEADER_SIZE); + stream = UINT16_TO_STREAM(stream, SL_PATCH_PORTION_SIZE); + memcpy(buffer + SPI_HEADER_SIZE + HCI_PATCH_HEADER_SIZE, patch, SL_PATCH_PORTION_SIZE); + data_length -= SL_PATCH_PORTION_SIZE; + patch += SL_PATCH_PORTION_SIZE; + + // Update the opcode of the event we will be waiting for + _spi.write(buffer, SL_PATCH_PORTION_SIZE + HCI_PATCH_HEADER_SIZE); + + stream = (buffer + SPI_HEADER_SIZE); + while (data_length) + { + if (data_length <= SL_PATCH_PORTION_SIZE) + { + usTransLength = data_length; + data_length = 0; + + } + else + { + usTransLength = SL_PATCH_PORTION_SIZE; + data_length -= usTransLength; + } + + *(unsigned short *)stream = usTransLength; + memcpy(stream + SIMPLE_LINK_HCI_PATCH_HEADER_SIZE, patch, usTransLength); + patch += usTransLength; + + // Update the opcode of the event we will be waiting for + _spi.write((unsigned char *)stream, usTransLength + sizeof(usTransLength)); + } + } +} + +}
--- a/cc3000_netapp.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_netapp.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,199 +1,199 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_netapp.h" - -namespace mbed_cc3000 { - -cc3000_netapp::cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci , cc3000_event &event) : - _simple_link(simple_link), _nvmem(nvmem), _hci(hci), _event(event) { - -} - -cc3000_netapp::~cc3000_netapp() { - -} - -int32_t cc3000_netapp::config_mac_adrress(uint8_t * mac) { - return _nvmem.set_mac_address(mac); -} - -int32_t cc3000_netapp::dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server) { - int8_t scRet; - uint8_t *ptr; - uint8_t *args; - - scRet = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - ARRAY_TO_STREAM(args,ip,4); - ARRAY_TO_STREAM(args,subnet_mask,4); - ARRAY_TO_STREAM(args,default_gateway,4); - args = UINT32_TO_STREAM(args, 0); - ARRAY_TO_STREAM(args,dns_server,4); - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_DHCP, &scRet); - - return(scRet); -} - -#ifndef CC3000_TINY_DRIVER -void cc3000_netapp::ipconfig( tNetappIpconfigRetArgs * ipconfig ) { - uint8_t *ptr; - - ptr = _simple_link.get_transmit_buffer(); - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_IPCONFIG, ptr, 0); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_IPCONFIG, ipconfig ); -} - - -int32_t cc3000_netapp::timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity) { - int8_t scRet; - uint8_t *ptr; - uint8_t *args; - - scRet = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Set minimal values of timers - MIN_TIMER_SET(*dhcp) - MIN_TIMER_SET(*arp) - MIN_TIMER_SET(*keep_alive) - MIN_TIMER_SET(*inactivity) - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *dhcp); - args = UINT32_TO_STREAM(args, *arp); - args = UINT32_TO_STREAM(args, *keep_alive); - args = UINT32_TO_STREAM(args, *inactivity); - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_SET_TIMERS, &scRet); - - return(scRet); -} - -int32_t cc3000_netapp::ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout) { - int8_t scRet; - uint8_t *ptr, *args; - - scRet = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, *ip); - args = UINT32_TO_STREAM(args, ping_attempts); - args = UINT32_TO_STREAM(args, ping_size); - args = UINT32_TO_STREAM(args, ping_timeout); - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_PING_SEND, &scRet); - - return(scRet); -} - -void cc3000_netapp::ping_report() { - uint8_t *ptr; - int8_t scRet; - ptr = _simple_link.get_transmit_buffer(); - - - scRet = EFAIL; - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_PING_REPORT, ptr, 0); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_PING_REPORT, &scRet); -} - -int32_t cc3000_netapp::ping_stop() { - int8_t scRet; - uint8_t *ptr; - - scRet = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_PING_STOP, ptr, 0); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_PING_STOP, &scRet); - - return(scRet); -} - -int32_t cc3000_netapp::arp_flush() { - int8_t scRet; - uint8_t *ptr; - - scRet = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - - // Initiate a HCI command - _hci.command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); - - // Wait for command complete event - _event.simplelink_wait_event(HCI_NETAPP_ARP_FLUSH, &scRet); - - return(scRet); -} -#endif - -} /* end of cc3000 namespace */ +/***************************************************************************** +* +* 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" +#include "cc3000_netapp.h" + +namespace mbed_cc3000 { + +cc3000_netapp::cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci , cc3000_event &event) : + _simple_link(simple_link), _nvmem(nvmem), _hci(hci), _event(event) { + +} + +cc3000_netapp::~cc3000_netapp() { + +} + +int32_t cc3000_netapp::config_mac_adrress(uint8_t * mac) { + return _nvmem.set_mac_address(mac); +} + +int32_t cc3000_netapp::dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server) { + int8_t scRet; + uint8_t *ptr; + uint8_t *args; + + scRet = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + ARRAY_TO_STREAM(args,ip,4); + ARRAY_TO_STREAM(args,subnet_mask,4); + ARRAY_TO_STREAM(args,default_gateway,4); + args = UINT32_TO_STREAM(args, 0); + ARRAY_TO_STREAM(args,dns_server,4); + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_DHCP, ptr, NETAPP_DHCP_PARAMS_LEN); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_DHCP, &scRet); + + return(scRet); +} + +#ifndef CC3000_TINY_DRIVER +void cc3000_netapp::ipconfig( tNetappIpconfigRetArgs * ipconfig ) { + uint8_t *ptr; + + ptr = _simple_link.get_transmit_buffer(); + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_IPCONFIG, ptr, 0); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_IPCONFIG, ipconfig ); +} + + +int32_t cc3000_netapp::timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity) { + int8_t scRet; + uint8_t *ptr; + uint8_t *args; + + scRet = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Set minimal values of timers + MIN_TIMER_SET(*dhcp) + MIN_TIMER_SET(*arp) + MIN_TIMER_SET(*keep_alive) + MIN_TIMER_SET(*inactivity) + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, *dhcp); + args = UINT32_TO_STREAM(args, *arp); + args = UINT32_TO_STREAM(args, *keep_alive); + args = UINT32_TO_STREAM(args, *inactivity); + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_SET_TIMERS, ptr, NETAPP_SET_TIMER_PARAMS_LEN); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_SET_TIMERS, &scRet); + + return(scRet); +} + +int32_t cc3000_netapp::ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout) { + int8_t scRet; + uint8_t *ptr, *args; + + scRet = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, *ip); + args = UINT32_TO_STREAM(args, ping_attempts); + args = UINT32_TO_STREAM(args, ping_size); + args = UINT32_TO_STREAM(args, ping_timeout); + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_PING_SEND, ptr, NETAPP_PING_SEND_PARAMS_LEN); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_PING_SEND, &scRet); + + return(scRet); +} + +void cc3000_netapp::ping_report() { + uint8_t *ptr; + int8_t scRet; + ptr = _simple_link.get_transmit_buffer(); + + + scRet = EFAIL; + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_PING_REPORT, ptr, 0); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_PING_REPORT, &scRet); +} + +int32_t cc3000_netapp::ping_stop() { + int8_t scRet; + uint8_t *ptr; + + scRet = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_PING_STOP, ptr, 0); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_PING_STOP, &scRet); + + return(scRet); +} + +int32_t cc3000_netapp::arp_flush() { + int8_t scRet; + uint8_t *ptr; + + scRet = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + + // Initiate a HCI command + _hci.command_send(HCI_NETAPP_ARP_FLUSH, ptr, 0); + + // Wait for command complete event + _event.simplelink_wait_event(HCI_NETAPP_ARP_FLUSH, &scRet); + + return(scRet); +} +#endif + +} /* end of cc3000 namespace */
--- a/cc3000_netapp.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_netapp.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,88 +1,88 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_NETAPP_H -#define CC3000_NETAPP_H - -#define MIN_TIMER_VAL_SECONDS 20 -#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ - { \ - t = MIN_TIMER_VAL_SECONDS; \ - } - - -#define NETAPP_DHCP_PARAMS_LEN (20) -#define NETAPP_SET_TIMER_PARAMS_LEN (20) -#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) -#define NETAPP_PING_SEND_PARAMS_LEN (16) - - -typedef struct _netapp_dhcp_ret_args_t -{ - uint8_t aucIP[4]; - uint8_t aucSubnetMask[4]; - uint8_t aucDefaultGateway[4]; - uint8_t aucDHCPServer[4]; - uint8_t aucDNSServer[4]; -}tNetappDhcpParams; - -typedef struct _netapp_ipconfig_ret_args_t -{ - uint8_t aucIP[4]; - uint8_t aucSubnetMask[4]; - uint8_t aucDefaultGateway[4]; - uint8_t aucDHCPServer[4]; - uint8_t aucDNSServer[4]; - uint8_t uaMacAddr[6]; - uint8_t uaSSID[32]; -}tNetappIpconfigRetArgs; - - -/*Ping send report parameters*/ -typedef struct _netapp_pingreport_args -{ - uint32_t packets_sent; - uint32_t packets_received; - uint32_t min_round_time; - uint32_t max_round_time; - uint32_t avg_round_time; -} netapp_pingreport_args_t; - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_NETAPP_H +#define CC3000_NETAPP_H + +#define MIN_TIMER_VAL_SECONDS 20 +#define MIN_TIMER_SET(t) if ((0 != t) && (t < MIN_TIMER_VAL_SECONDS)) \ + { \ + t = MIN_TIMER_VAL_SECONDS; \ + } + + +#define NETAPP_DHCP_PARAMS_LEN (20) +#define NETAPP_SET_TIMER_PARAMS_LEN (20) +#define NETAPP_SET_DEBUG_LEVEL_PARAMS_LEN (4) +#define NETAPP_PING_SEND_PARAMS_LEN (16) + + +typedef struct _netapp_dhcp_ret_args_t +{ + uint8_t aucIP[4]; + uint8_t aucSubnetMask[4]; + uint8_t aucDefaultGateway[4]; + uint8_t aucDHCPServer[4]; + uint8_t aucDNSServer[4]; +}tNetappDhcpParams; + +typedef struct _netapp_ipconfig_ret_args_t +{ + uint8_t aucIP[4]; + uint8_t aucSubnetMask[4]; + uint8_t aucDefaultGateway[4]; + uint8_t aucDHCPServer[4]; + uint8_t aucDNSServer[4]; + uint8_t uaMacAddr[6]; + uint8_t uaSSID[32]; +}tNetappIpconfigRetArgs; + + +/*Ping send report parameters*/ +typedef struct _netapp_pingreport_args +{ + uint32_t packets_sent; + uint32_t packets_received; + uint32_t min_round_time; + uint32_t max_round_time; + uint32_t avg_round_time; +} netapp_pingreport_args_t; + +#endif
--- a/cc3000_nvmem.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_nvmem.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,186 +1,186 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_nvmem.h" -#include "cc3000_common.h" - -namespace mbed_cc3000 { - -cc3000_nvmem::cc3000_nvmem(cc3000_hci &hci, cc3000_event &event, cc3000_simple_link &simple_link) - : _hci(hci), _event(event), _simple_link(simple_link) { - -} - -cc3000_nvmem::~cc3000_nvmem() { - -} - -int32_t cc3000_nvmem::read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff) { - uint8_t ucStatus = 0xFF; - uint8_t *ptr; - uint8_t *args; - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, file_id); - args = UINT32_TO_STREAM(args, length); - args = UINT32_TO_STREAM(args, offset); - - // Initiate HCI command - _hci.command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); - _event.simplelink_wait_event(HCI_CMND_NVMEM_READ, &ucStatus); - - // If data is present, read it even when an error is returned. - // Note: It is the users responsibility to ignore the data when an error is returned. - // Wait for the data in a synchronous way. - // We assume the buffer is large enough to also store nvmem parameters. - _event.simplelink_wait_data(buff, 0, 0); - - return(ucStatus); -} - -int32_t cc3000_nvmem::write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff) { - int32_t iRes; - uint8_t *ptr; - uint8_t *args; - - iRes = EFAIL; - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, file_id); - args = UINT32_TO_STREAM(args, 12); - args = UINT32_TO_STREAM(args, length); - args = UINT32_TO_STREAM(args, entry_offset); - - memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + - NVMEM_WRITE_PARAMS_LEN),buff,length); - - // Initiate a HCI command on the data channel - _hci.data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, length); - - _event.simplelink_wait_event(HCI_EVNT_NVMEM_WRITE, &iRes); - - return(iRes); -} - -uint8_t cc3000_nvmem::set_mac_address(uint8_t *mac) { - return write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); -} - -uint8_t cc3000_nvmem::get_mac_address(uint8_t *mac) { - return read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); -} - -uint8_t cc3000_nvmem::write_patch(uint32_t file_id, uint32_t length, const uint8_t *data) { - uint8_t status = 0; - uint16_t offset = 0; - uint8_t* spDataPtr = (uint8_t*)data; - - while ((status == 0) && (length >= SP_PORTION_SIZE)) - { - status = write(file_id, SP_PORTION_SIZE, offset, spDataPtr); - offset += SP_PORTION_SIZE; - length -= SP_PORTION_SIZE; - spDataPtr += SP_PORTION_SIZE; - } - - if (status !=0) - { - // NVMEM error occurred - return status; - } - - if (length != 0) - { - // If length MOD 512 is nonzero, write the remaining bytes. - status = write(file_id, length, offset, spDataPtr); - } - - return status; -} - -int32_t cc3000_nvmem::create_entry(uint32_t file_id, uint32_t new_len) { - uint8_t *ptr; - uint8_t *args; - uint16_t retval; - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, file_id); - args = UINT32_TO_STREAM(args, new_len); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); - - _event.simplelink_wait_event(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); - - return(retval); -} - -#ifndef CC3000_TINY_DRIVER -uint8_t cc3000_nvmem::read_sp_version(uint8_t* patch_ver) { - uint8_t *ptr; - // 1st byte is the status and the rest is the SP version - uint8_t retBuf[5]; - - ptr = _simple_link.get_transmit_buffer(); - - // Initiate a HCI command, no args are required - _hci.command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); - _event.simplelink_wait_event(HCI_CMND_READ_SP_VERSION, retBuf); - - // package ID - *patch_ver = retBuf[3]; - // package build number - *(patch_ver+1) = retBuf[4]; - - return(retBuf[0]); -} - -#endif - -} +/***************************************************************************** +* +* 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" +#include "cc3000_nvmem.h" +#include "cc3000_common.h" + +namespace mbed_cc3000 { + +cc3000_nvmem::cc3000_nvmem(cc3000_hci &hci, cc3000_event &event, cc3000_simple_link &simple_link) + : _hci(hci), _event(event), _simple_link(simple_link) { + +} + +cc3000_nvmem::~cc3000_nvmem() { + +} + +int32_t cc3000_nvmem::read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff) { + uint8_t ucStatus = 0xFF; + uint8_t *ptr; + uint8_t *args; + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, file_id); + args = UINT32_TO_STREAM(args, length); + args = UINT32_TO_STREAM(args, offset); + + // Initiate HCI command + _hci.command_send(HCI_CMND_NVMEM_READ, ptr, NVMEM_READ_PARAMS_LEN); + _event.simplelink_wait_event(HCI_CMND_NVMEM_READ, &ucStatus); + + // If data is present, read it even when an error is returned. + // Note: It is the users responsibility to ignore the data when an error is returned. + // Wait for the data in a synchronous way. + // We assume the buffer is large enough to also store nvmem parameters. + _event.simplelink_wait_data(buff, 0, 0); + + return(ucStatus); +} + +int32_t cc3000_nvmem::write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff) { + int32_t iRes; + uint8_t *ptr; + uint8_t *args; + + iRes = EFAIL; + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE); + + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, file_id); + args = UINT32_TO_STREAM(args, 12); + args = UINT32_TO_STREAM(args, length); + args = UINT32_TO_STREAM(args, entry_offset); + + memcpy((ptr + SPI_HEADER_SIZE + HCI_DATA_CMD_HEADER_SIZE + + NVMEM_WRITE_PARAMS_LEN),buff,length); + + // Initiate a HCI command on the data channel + _hci.data_command_send(HCI_CMND_NVMEM_WRITE, ptr, NVMEM_WRITE_PARAMS_LEN, length); + + _event.simplelink_wait_event(HCI_EVNT_NVMEM_WRITE, &iRes); + + return(iRes); +} + +uint8_t cc3000_nvmem::set_mac_address(uint8_t *mac) { + return write(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); +} + +uint8_t cc3000_nvmem::get_mac_address(uint8_t *mac) { + return read(NVMEM_MAC_FILEID, MAC_ADDR_LEN, 0, mac); +} + +uint8_t cc3000_nvmem::write_patch(uint32_t file_id, uint32_t length, const uint8_t *data) { + uint8_t status = 0; + uint16_t offset = 0; + uint8_t* spDataPtr = (uint8_t*)data; + + while ((status == 0) && (length >= SP_PORTION_SIZE)) + { + status = write(file_id, SP_PORTION_SIZE, offset, spDataPtr); + offset += SP_PORTION_SIZE; + length -= SP_PORTION_SIZE; + spDataPtr += SP_PORTION_SIZE; + } + + if (status !=0) + { + // NVMEM error occurred + return status; + } + + if (length != 0) + { + // If length MOD 512 is nonzero, write the remaining bytes. + status = write(file_id, length, offset, spDataPtr); + } + + return status; +} + +int32_t cc3000_nvmem::create_entry(uint32_t file_id, uint32_t new_len) { + uint8_t *ptr; + uint8_t *args; + uint16_t retval; + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, file_id); + args = UINT32_TO_STREAM(args, new_len); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_NVMEM_CREATE_ENTRY,ptr, NVMEM_CREATE_PARAMS_LEN); + + _event.simplelink_wait_event(HCI_CMND_NVMEM_CREATE_ENTRY, &retval); + + return(retval); +} + +#ifndef CC3000_TINY_DRIVER +uint8_t cc3000_nvmem::read_sp_version(uint8_t* patch_ver) { + uint8_t *ptr; + // 1st byte is the status and the rest is the SP version + uint8_t retBuf[5]; + + ptr = _simple_link.get_transmit_buffer(); + + // Initiate a HCI command, no args are required + _hci.command_send(HCI_CMND_READ_SP_VERSION, ptr, 0); + _event.simplelink_wait_event(HCI_CMND_READ_SP_VERSION, retBuf); + + // package ID + *patch_ver = retBuf[3]; + // package build number + *(patch_ver+1) = retBuf[4]; + + return(retBuf[0]); +} + +#endif + +}
--- a/cc3000_nvmem.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_nvmem.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,100 +1,100 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_NVMEM_H -#define CC3000_NVMEM_H - -#define NVMEM_READ_PARAMS_LEN (12) -#define NVMEM_CREATE_PARAMS_LEN (8) -#define NVMEM_WRITE_PARAMS_LEN (16) - - -/**************************************************************************** -** -** Definitions for File IDs -** -****************************************************************************/ -/* --------------------------------------------------------- EEPROM FAT table --------------------------------------------------------- - - File ID Offset File Size Used Size Parameter - # ID address (bytes) (bytes) - -------------------------------------------------------------------------------------------------------------------------------------- - 0 NVMEM_NVS_FILEID 0x50 0x1A0 0x1A RF Calibration results table(generated automatically by TX Bip) - 1 NVMEM_NVS_SHADOW_FILEID 0x1F0 0x1A0 0x1A NVS Shadow - 2 NVMEM_WLAN_CONFIG_FILEID 0x390 0x1000 0x64 WLAN configuration - 3 NVMEM_WLAN_CONFIG_SHADOW_FILEID 0x1390 0x1000 0x64 WLAN configuration shadow - 4 NVMEM_WLAN_DRIVER_SP_FILEID 0x2390 0x2000 variable WLAN Driver ROM Patches - 5 NVMEM_WLAN_FW_SP_FILEID 0x4390 0x2000 variable WLAN FW Patches - 6 NVMEM_MAC_FILEID 0x6390 0x10 0x10 6 bytes of MAC address - 7 NVMEM_FRONTEND_VARS_FILEID 0x63A0 0x10 0x10 Frontend Vars - 8 NVMEM_IP_CONFIG_FILEID 0x63B0 0x40 0x40 IP configuration - 9 NVMEM_IP_CONFIG_SHADOW_FILEID 0x63F0 0x40 0x40 IP configuration shadow -10 NVMEM_BOOTLOADER_SP_FILEID 0x6430 0x400 variable Bootloader Patches -11 NVMEM_RM_FILEID 0x6830 0x200 0x7F Radio parameters -12 NVMEM_AES128_KEY_FILEID 0x6A30 0x10 0x10 AES128 key file -13 NVMEM_SHARED_MEM_FILEID 0x6A40 0x50 0x44 Host-CC3000 shared memory file -14 NVMEM_USER_FILE_1_FILEID 0x6A90 variable variable 1st user file -15 NVMEM_USER_FILE_2_FILEID variable variable variable 2nd user file -*/ -/* NVMEM file ID - system files*/ -#define NVMEM_NVS_FILEID (0) -#define NVMEM_NVS_SHADOW_FILEID (1) -#define NVMEM_WLAN_CONFIG_FILEID (2) -#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) -#define NVMEM_WLAN_DRIVER_SP_FILEID (4) -#define NVMEM_WLAN_FW_SP_FILEID (5) -#define NVMEM_MAC_FILEID (6) -#define NVMEM_FRONTEND_VARS_FILEID (7) -#define NVMEM_IP_CONFIG_FILEID (8) -#define NVMEM_IP_CONFIG_SHADOW_FILEID (9) -#define NVMEM_BOOTLOADER_SP_FILEID (10) -#define NVMEM_RM_FILEID (11) - -/* NVMEM file ID - user files*/ -#define NVMEM_AES128_KEY_FILEID (12) -#define NVMEM_SHARED_MEM_FILEID (13) -#define NVMEM_USER_FILE_1_FILEID (14) -#define NVMEM_USER_FILE_2_FILEID (15) - -/* max entry in order to invalid nvmem */ -#define NVMEM_MAX_ENTRY (16) - - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_NVMEM_H +#define CC3000_NVMEM_H + +#define NVMEM_READ_PARAMS_LEN (12) +#define NVMEM_CREATE_PARAMS_LEN (8) +#define NVMEM_WRITE_PARAMS_LEN (16) + + +/**************************************************************************** +** +** Definitions for File IDs +** +****************************************************************************/ +/* --------------------------------------------------------- EEPROM FAT table --------------------------------------------------------- + + File ID Offset File Size Used Size Parameter + # ID address (bytes) (bytes) + -------------------------------------------------------------------------------------------------------------------------------------- + 0 NVMEM_NVS_FILEID 0x50 0x1A0 0x1A RF Calibration results table(generated automatically by TX Bip) + 1 NVMEM_NVS_SHADOW_FILEID 0x1F0 0x1A0 0x1A NVS Shadow + 2 NVMEM_WLAN_CONFIG_FILEID 0x390 0x1000 0x64 WLAN configuration + 3 NVMEM_WLAN_CONFIG_SHADOW_FILEID 0x1390 0x1000 0x64 WLAN configuration shadow + 4 NVMEM_WLAN_DRIVER_SP_FILEID 0x2390 0x2000 variable WLAN Driver ROM Patches + 5 NVMEM_WLAN_FW_SP_FILEID 0x4390 0x2000 variable WLAN FW Patches + 6 NVMEM_MAC_FILEID 0x6390 0x10 0x10 6 bytes of MAC address + 7 NVMEM_FRONTEND_VARS_FILEID 0x63A0 0x10 0x10 Frontend Vars + 8 NVMEM_IP_CONFIG_FILEID 0x63B0 0x40 0x40 IP configuration + 9 NVMEM_IP_CONFIG_SHADOW_FILEID 0x63F0 0x40 0x40 IP configuration shadow +10 NVMEM_BOOTLOADER_SP_FILEID 0x6430 0x400 variable Bootloader Patches +11 NVMEM_RM_FILEID 0x6830 0x200 0x7F Radio parameters +12 NVMEM_AES128_KEY_FILEID 0x6A30 0x10 0x10 AES128 key file +13 NVMEM_SHARED_MEM_FILEID 0x6A40 0x50 0x44 Host-CC3000 shared memory file +14 NVMEM_USER_FILE_1_FILEID 0x6A90 variable variable 1st user file +15 NVMEM_USER_FILE_2_FILEID variable variable variable 2nd user file +*/ +/* NVMEM file ID - system files*/ +#define NVMEM_NVS_FILEID (0) +#define NVMEM_NVS_SHADOW_FILEID (1) +#define NVMEM_WLAN_CONFIG_FILEID (2) +#define NVMEM_WLAN_CONFIG_SHADOW_FILEID (3) +#define NVMEM_WLAN_DRIVER_SP_FILEID (4) +#define NVMEM_WLAN_FW_SP_FILEID (5) +#define NVMEM_MAC_FILEID (6) +#define NVMEM_FRONTEND_VARS_FILEID (7) +#define NVMEM_IP_CONFIG_FILEID (8) +#define NVMEM_IP_CONFIG_SHADOW_FILEID (9) +#define NVMEM_BOOTLOADER_SP_FILEID (10) +#define NVMEM_RM_FILEID (11) + +/* NVMEM file ID - user files*/ +#define NVMEM_AES128_KEY_FILEID (12) +#define NVMEM_SHARED_MEM_FILEID (13) +#define NVMEM_USER_FILE_1_FILEID (14) +#define NVMEM_USER_FILE_2_FILEID (15) + +/* max entry in order to invalid nvmem */ +#define NVMEM_MAX_ENTRY (16) + + +#endif
--- a/cc3000_server.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_server.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,93 +1,93 @@ -/***************************************************************************** -* -* 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_server::cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add) : _socket_address(socket_add), _cc3000(cc3000_ref) { - _current_socket = -1; -} - -cc3000_server::cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add, int16_t socket) : _socket_address(socket_add), _cc3000(cc3000_ref) { - _current_socket = socket; -} - -int32_t cc3000_server::accept(void) { - int32_t client_descriptor = -2; - sockaddr dest_address; - - socklen_t address_length = sizeof(dest_address); - _current_socket = 0; - - DBG_HCI("Waiting for receiving a connection"); - - while((client_descriptor == -1) || (client_descriptor == -2)) - { - client_descriptor = _cc3000._socket.accept(_current_socket,&dest_address, &address_length); - } - - DBG_HCI("Received"); - - _current_socket = client_descriptor; - - return _current_socket; -} - -int32_t cc3000_server::receive(void *buffer, uint16_t length, uint32_t flags) { - return _cc3000._socket.recv(_current_socket, buffer, length, flags); -} - -int32_t cc3000_server::send(void *buffer, uint16_t length, uint32_t flags) { - return _cc3000._socket.send(_current_socket, buffer, length, flags); -} - -void cc3000_server::bind(void) { - _cc3000._socket.bind(_current_socket, &_socket_address, sizeof(sockaddr)); -} - -void cc3000_server::listen(uint32_t backlog) { - _cc3000._socket.listen(_current_socket, backlog); -} - -void cc3000_server::close(void) { - _cc3000._socket.closesocket(_current_socket); -} - -} +/***************************************************************************** +* +* 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_server::cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add) : _socket_address(socket_add), _cc3000(cc3000_ref) { + _current_socket = -1; +} + +cc3000_server::cc3000_server(cc3000 &cc3000_ref, sockaddr socket_add, int16_t socket) : _socket_address(socket_add), _cc3000(cc3000_ref) { + _current_socket = socket; +} + +int32_t cc3000_server::accept(void) { + int32_t client_descriptor = -2; + sockaddr dest_address; + + socklen_t address_length = sizeof(dest_address); + _current_socket = 0; + + DBG_HCI("Waiting for receiving a connection"); + + while((client_descriptor == -1) || (client_descriptor == -2)) + { + client_descriptor = _cc3000._socket.accept(_current_socket,&dest_address, &address_length); + } + + DBG_HCI("Received"); + + _current_socket = client_descriptor; + + return _current_socket; +} + +int32_t cc3000_server::receive(void *buffer, uint16_t length, uint32_t flags) { + return _cc3000._socket.recv(_current_socket, buffer, length, flags); +} + +int32_t cc3000_server::send(void *buffer, uint16_t length, uint32_t flags) { + return _cc3000._socket.send(_current_socket, buffer, length, flags); +} + +void cc3000_server::bind(void) { + _cc3000._socket.bind(_current_socket, &_socket_address, sizeof(sockaddr)); +} + +void cc3000_server::listen(uint32_t backlog) { + _cc3000._socket.listen(_current_socket, backlog); +} + +void cc3000_server::close(void) { + _cc3000._socket.closesocket(_current_socket); +} + +}
--- a/cc3000_simplelink.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_simplelink.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,185 +1,185 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_common.h" - -namespace mbed_cc3000 { - -cc3000_simple_link::cc3000_simple_link() { - _rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - _tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; -} - -cc3000_simple_link::~cc3000_simple_link() { -} - -uint8_t cc3000_simple_link::get_data_received_flag() { - return _data_received_flag; -} - -void *cc3000_simple_link::get_func_pointer(FunctionNumber function){ - void *result; - /* casting to void *, will be casted back once used */ - switch(function) { - case FW_PATCHES: - result = (void *)_fFWPatches; - break; - case DRIVER_PATCHES: - result = (void *)_fDriverPatches; - break; - case BOOTLOADER_PATCHES: - result = (void *)_fBootLoaderPatches; - break; - // case WLAN_CB: - // result = (void *)_fWlanCB; - // break; - default: - result = 0; - } - return result; -} - -uint8_t *cc3000_simple_link::get_transmit_buffer() { - return _tx_buffer; -} - -uint8_t *cc3000_simple_link::get_received_buffer() { - return _rx_buffer; -} - -void cc3000_simple_link::set_received_buffer(uint8_t value) { - *_rx_buffer = value; -} - -void cc3000_simple_link::set_transmit_buffer(uint8_t value) { - *_tx_buffer = value; -} - -void cc3000_simple_link::set_op_code(uint16_t code) { - _rx_event_opcode = code; -} - -void cc3000_simple_link::set_pending_data(uint16_t value) { - _rx_data_pending = value; -} - -uint16_t cc3000_simple_link::get_pending_data() { - return _rx_data_pending; -} - -void cc3000_simple_link::set_number_free_buffers(uint16_t value) { - _free_buffers = value; -} - -void cc3000_simple_link::set_number_of_released_packets(uint16_t value) { - _released_packets = value; -} - - -void cc3000_simple_link::set_tx_complete_signal(bool value) { - _tx_complete_signal = value; -} - -bool cc3000_simple_link::get_tx_complete_signal() { - return _tx_complete_signal; -} - -void cc3000_simple_link::set_data_received_flag(uint8_t value) { - _data_received_flag = value; -} - -uint16_t cc3000_simple_link::get_number_free_buffers() { - return _free_buffers; -} - -uint16_t cc3000_simple_link::get_buffer_length() { - return _buffer_length; -} - -void cc3000_simple_link::set_buffer_length(uint16_t value) { - _buffer_length = value; -} - -uint16_t cc3000_simple_link::get_op_code() { - return _rx_event_opcode; -} - -uint16_t cc3000_simple_link::get_released_packets() { - return _released_packets; -} - -uint16_t cc3000_simple_link::get_sent_packets() { - return _sent_packets; -} - -void cc3000_simple_link::set_sent_packets(uint16_t value) { - _sent_packets = value; -} - -void cc3000_simple_link::set_transmit_error(int32_t value){ - _transmit_data_error = value; -} - -int32_t cc3000_simple_link::get_transmit_error(){ - return _transmit_data_error; -} - -void cc3000_simple_link::set_buffer_size(uint16_t value) { - _buffer_size = value; -} - -uint16_t cc3000_simple_link::get_buffer_size(void) { - return _buffer_size; -} - -uint8_t *cc3000_simple_link::get_received_data(void) { - return _received_data; -} - -void cc3000_simple_link::set_received_data(uint8_t *pointer) { - _received_data = pointer; -} - -//void cc3000_simple_link::set_wlan_cb(tWlanCB fpointer) { -// _fWlanCB = fpointer; -//} - -} +/***************************************************************************** +* +* 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" +#include "cc3000_common.h" + +namespace mbed_cc3000 { + +cc3000_simple_link::cc3000_simple_link() { + _rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; + _tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; +} + +cc3000_simple_link::~cc3000_simple_link() { +} + +uint8_t cc3000_simple_link::get_data_received_flag() { + return _data_received_flag; +} + +void *cc3000_simple_link::get_func_pointer(FunctionNumber function){ + void *result; + /* casting to void *, will be casted back once used */ + switch(function) { + case FW_PATCHES: + result = (void *)_fFWPatches; + break; + case DRIVER_PATCHES: + result = (void *)_fDriverPatches; + break; + case BOOTLOADER_PATCHES: + result = (void *)_fBootLoaderPatches; + break; + // case WLAN_CB: + // result = (void *)_fWlanCB; + // break; + default: + result = 0; + } + return result; +} + +uint8_t *cc3000_simple_link::get_transmit_buffer() { + return _tx_buffer; +} + +uint8_t *cc3000_simple_link::get_received_buffer() { + return _rx_buffer; +} + +void cc3000_simple_link::set_received_buffer(uint8_t value) { + *_rx_buffer = value; +} + +void cc3000_simple_link::set_transmit_buffer(uint8_t value) { + *_tx_buffer = value; +} + +void cc3000_simple_link::set_op_code(uint16_t code) { + _rx_event_opcode = code; +} + +void cc3000_simple_link::set_pending_data(uint16_t value) { + _rx_data_pending = value; +} + +uint16_t cc3000_simple_link::get_pending_data() { + return _rx_data_pending; +} + +void cc3000_simple_link::set_number_free_buffers(uint16_t value) { + _free_buffers = value; +} + +void cc3000_simple_link::set_number_of_released_packets(uint16_t value) { + _released_packets = value; +} + + +void cc3000_simple_link::set_tx_complete_signal(bool value) { + _tx_complete_signal = value; +} + +bool cc3000_simple_link::get_tx_complete_signal() { + return _tx_complete_signal; +} + +void cc3000_simple_link::set_data_received_flag(uint8_t value) { + _data_received_flag = value; +} + +uint16_t cc3000_simple_link::get_number_free_buffers() { + return _free_buffers; +} + +uint16_t cc3000_simple_link::get_buffer_length() { + return _buffer_length; +} + +void cc3000_simple_link::set_buffer_length(uint16_t value) { + _buffer_length = value; +} + +uint16_t cc3000_simple_link::get_op_code() { + return _rx_event_opcode; +} + +uint16_t cc3000_simple_link::get_released_packets() { + return _released_packets; +} + +uint16_t cc3000_simple_link::get_sent_packets() { + return _sent_packets; +} + +void cc3000_simple_link::set_sent_packets(uint16_t value) { + _sent_packets = value; +} + +void cc3000_simple_link::set_transmit_error(int32_t value){ + _transmit_data_error = value; +} + +int32_t cc3000_simple_link::get_transmit_error(){ + return _transmit_data_error; +} + +void cc3000_simple_link::set_buffer_size(uint16_t value) { + _buffer_size = value; +} + +uint16_t cc3000_simple_link::get_buffer_size(void) { + return _buffer_size; +} + +uint8_t *cc3000_simple_link::get_received_data(void) { + return _received_data; +} + +void cc3000_simple_link::set_received_data(uint8_t *pointer) { + _received_data = pointer; +} + +//void cc3000_simple_link::set_wlan_cb(tWlanCB fpointer) { +// _fWlanCB = fpointer; +//} + +}
--- a/cc3000_simplelink.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_simplelink.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,48 +1,48 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_SIMPLELINK_H -#define CC3000_SIMPLELINK_H - -typedef uint8_t *(*tFWPatches)(uint32_t *usLength); -typedef uint8_t *(*tDriverPatches)(uint32_t *usLength); -typedef uint8_t *(*tBootLoaderPatches)(uint32_t *usLength); - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_SIMPLELINK_H +#define CC3000_SIMPLELINK_H + +typedef uint8_t *(*tFWPatches)(uint32_t *usLength); +typedef uint8_t *(*tDriverPatches)(uint32_t *usLength); +typedef uint8_t *(*tBootLoaderPatches)(uint32_t *usLength); + +#endif
--- a/cc3000_socket.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_socket.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,603 +1,603 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_socket.h" -#include "cc3000_event.h" //TODO - remove this -#include "cc3000_common.h" - -namespace mbed_cc3000 { - -cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event) - : _simple_link(simplelink), _hci(hci), _event(event) -{ - -} - -cc3000_socket::~cc3000_socket() -{ - -} - -int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) { -#ifndef SEND_NON_BLOCKING - /* wait in busy loop */ - do - { - // When the last transmission failed, return the last failure reason. - // Note that the buffer will not be allocated in this case - if (_simple_link.get_transmit_error() != 0) - { - errno = _simple_link.get_transmit_error(); - _simple_link.set_transmit_error(0); - return errno; - } - - if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd)) - return -1; - } while(0 == _simple_link.get_number_free_buffers()); - - uint16_t free_buffer = _simple_link.get_number_free_buffers(); - free_buffer--; - _simple_link.set_number_free_buffers(free_buffer); - - return 0; -#else - - // When the last transmission failed, return the last failure reason. - // Note that the buffer will not be allocated in this case - if (_simple_link.get_transmit_error() != 0) - { - errno = _simple_link.get_transmit_error(); - _simple_link.set_transmit_error(0); - return errno; - } - if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd)) - return -1; - - // If there are no available buffers, return -2. It is recommended to use - // select or receive to see if there is any buffer occupied with received data - // If so, call receive() to release the buffer. - if(0 == _simple_link.get_number_free_buffers()) - { - return -2; - } - else - { - uint16_t free_buffer = _simple_link.get_number_free_buffers(); - free_buffer--; - _simple_link.set_number_free_buffers(free_buffer); - return 0; - } -#endif -} - -int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) { - int32_t ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, domain); - args = UINT32_TO_STREAM(args, type); - args = UINT32_TO_STREAM(args, protocol); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_SOCKET, &ret); - - // Process the event - errno = ret; - - _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - - return(ret); -} - -int32_t cc3000_socket::closesocket(int32_t sd) { - int32_t ret; - uint8_t *ptr, *args; - - while(_simple_link.get_number_free_buffers() != SOCKET_MAX_FREE_BUFFERS); - ret = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret); - errno = ret; - - // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid - _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - - return(ret); -} - -int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) { - int32_t ret; - uint8_t *ptr, *args; - tBsdReturnParams tAcceptReturnArguments; - - ret = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments); - - - // need specify return parameters!!! - memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); - *addrlen = ASIC_ADDR_LEN; - errno = tAcceptReturnArguments.iStatus; - ret = errno; - - // if succeeded, iStatus = new socket descriptor. otherwise - error number - if(M_IS_VALID_SD(ret)) - { - _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); - } - else - { - _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); - } - - return(ret); -} - -int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) { - int32_t ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - addrlen = ASIC_ADDR_LEN; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_BIND, &ret); - - errno = ret; - - return(ret); -} - -int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) { - int32_t ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, backlog); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret); - errno = ret; - - return(ret); -} - -int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) { - int32_t ret; - uint8_t *ptr, *args; - - ret = EFAIL; - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - addrlen = 8; - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, addrlen); - ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret); - - errno = ret; - - return((int32_t)ret); -} - -int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) { - uint8_t *ptr, *args; - tBsdSelectRecvParams tParams; - uint32_t is_blocking; - - if( timeout == NULL) - { - is_blocking = 1; /* blocking , infinity timeout */ - } - else - { - is_blocking = 0; /* no blocking, timeout */ - } - - // Fill in HCI packet structure - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, nfds); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, 0x00000014); - args = UINT32_TO_STREAM(args, is_blocking); - args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0)); - args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0)); - args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0)); - - if (timeout) - { - if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) - { - timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; - } - args = UINT32_TO_STREAM(args, timeout->tv_sec); - args = UINT32_TO_STREAM(args, timeout->tv_usec); - } - - // Initiate a HCI command - _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams); - - // Update actually read FD - if (tParams.iStatus >= 0) - { - if (readsds) - { - memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); - } - - if (writesds) - { - memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); - } - - if (exceptsds) - { - memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); - } - - return(tParams.iStatus); - - } - else - { - errno = tParams.iStatus; - return(-1); - } -} - -int32_t cc3000_socket::getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) { - uint8_t *ptr, *args; - tBsdGetSockOptReturnParams tRetParams; - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams); - - if (((int8_t)tRetParams.iStatus) >= 0) - { - *optlen = 4; - memcpy(optval, tRetParams.ucOptValue, 4); - return (0); - } - else - { - errno = tRetParams.iStatus; - return errno; - } -} - -int32_t cc3000_socket::simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode) { - uint8_t *ptr, *args; - tBsdReadReturnParams tSocketReadEvent; - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - // Generate the read command, and wait for the - _hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(opcode, &tSocketReadEvent); - - // In case the number of bytes is more then zero - read data - if (tSocketReadEvent.iNumberOfBytes > 0) - { - // Wait for the data in a synchronous way. Here we assume that the bug is - // big enough to store also parameters of receive from too.... - _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen); - } - - errno = tSocketReadEvent.iNumberOfBytes; - - return(tSocketReadEvent.iNumberOfBytes); -} - -int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) { - return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); -} - -int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) { - return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM)); -} - -int32_t cc3000_socket::simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode) { - uint8_t uArgSize = 0x00, addrlen = 0x00; - uint8_t *ptr, *pDataPtr = NULL, *args; - uint32_t addr_offset = 0x00; - int32_t res; - tBsdReadReturnParams tSocketSendEvent; - - // Check the bsd_arguments - if (0 != (res = HostFlowControlConsumeBuff(sd))) - { - return res; - } - - //Update the number of sent packets - uint16_t sent_packets = _simple_link.get_sent_packets(); - sent_packets++; - _simple_link.set_sent_packets(sent_packets); - - // Allocate a buffer and construct a packet and send it over spi - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_DATA); - - // Update the offset of data and parameters according to the command - switch(opcode) - { - case HCI_CMND_SENDTO: - { - addr_offset = len + sizeof(len) + sizeof(len); - addrlen = 8; - uArgSize = SOCKET_SENDTO_PARAMS_LEN; - pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; - break; - } - - case HCI_CMND_SEND: - { - tolen = 0; - to = NULL; - uArgSize = HCI_CMND_SEND_ARG_LENGTH; - pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; - break; - } - - default: - { - break; - } - } - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); - args = UINT32_TO_STREAM(args, len); - args = UINT32_TO_STREAM(args, flags); - - if (opcode == HCI_CMND_SENDTO) - { - args = UINT32_TO_STREAM(args, addr_offset); - args = UINT32_TO_STREAM(args, addrlen); - } - - // Copy the data received from user into the TX Buffer - ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); - - // In case we are using SendTo, copy the to parameters - if (opcode == HCI_CMND_SENDTO) - { - ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); - } - - // Initiate a HCI command - _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen); - if (opcode == HCI_CMND_SENDTO) - _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent); - else - _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent); - - return (len); -} - -int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) { - return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); -} - -int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) { - return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); -} - -int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) { - int32_t ret; - uint8_t *pTxBuffer, *pArgs; - - if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH) - { - return EFAIL; - } - - pTxBuffer = _simple_link.get_transmit_buffer(); - pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled); - pArgs = UINT32_TO_STREAM(pArgs, 8); - pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length); - ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret); - - return ret; -} - - -#ifndef CC3000_TINY_DRIVER -int32_t cc3000_socket::gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) { - tBsdGethostbynameParams ret; - uint8_t *ptr, *args; - - errno = EFAIL; - - if (name_length > HOSTNAME_MAX_LENGTH) - { - return errno; - } - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); - - // Fill in HCI packet structure - args = UINT32_TO_STREAM(args, 8); - args = UINT32_TO_STREAM(args, name_length); - ARRAY_TO_STREAM(args, hostname, name_length); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); - - errno = ret.retVal; - - (*((int32_t*)out_ip_addr)) = ret.outputAddress; - - return (errno); -} - -int32_t cc3000_socket::setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) { - int32_t ret; - uint8_t *ptr, *args; - - ptr = _simple_link.get_transmit_buffer(); - args = (ptr + HEADERS_SIZE_CMD); - - // Fill in temporary command buffer - args = UINT32_TO_STREAM(args, sd); - args = UINT32_TO_STREAM(args, level); - args = UINT32_TO_STREAM(args, optname); - args = UINT32_TO_STREAM(args, 0x00000008); - args = UINT32_TO_STREAM(args, optlen); - ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen); - - // Initiate a HCI command - _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); - - // Since we are in blocking state - wait for event complete - _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret); - - if (ret >= 0) - { - return (0); - } - else - { - errno = ret; - return ret; - } -} - -#endif - -} /* end of cc3000 namespace */ +/***************************************************************************** +* +* 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" +#include "cc3000_socket.h" +#include "cc3000_event.h" //TODO - remove this +#include "cc3000_common.h" + +namespace mbed_cc3000 { + +cc3000_socket::cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event) + : _simple_link(simplelink), _hci(hci), _event(event) +{ + +} + +cc3000_socket::~cc3000_socket() +{ + +} + +int32_t cc3000_socket::HostFlowControlConsumeBuff(int32_t sd) { +#ifndef SEND_NON_BLOCKING + /* wait in busy loop */ + do + { + // When the last transmission failed, return the last failure reason. + // Note that the buffer will not be allocated in this case + if (_simple_link.get_transmit_error() != 0) + { + errno = _simple_link.get_transmit_error(); + _simple_link.set_transmit_error(0); + return errno; + } + + if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd)) + return -1; + } while(0 == _simple_link.get_number_free_buffers()); + + uint16_t free_buffer = _simple_link.get_number_free_buffers(); + free_buffer--; + _simple_link.set_number_free_buffers(free_buffer); + + return 0; +#else + + // When the last transmission failed, return the last failure reason. + // Note that the buffer will not be allocated in this case + if (_simple_link.get_transmit_error() != 0) + { + errno = _simple_link.get_transmit_error(); + _simple_link.set_transmit_error(0); + return errno; + } + if(SOCKET_STATUS_ACTIVE != _event.get_socket_active_status(sd)) + return -1; + + // If there are no available buffers, return -2. It is recommended to use + // select or receive to see if there is any buffer occupied with received data + // If so, call receive() to release the buffer. + if(0 == _simple_link.get_number_free_buffers()) + { + return -2; + } + else + { + uint16_t free_buffer = _simple_link.get_number_free_buffers(); + free_buffer--; + _simple_link.set_number_free_buffers(free_buffer); + return 0; + } +#endif +} + +int32_t cc3000_socket::socket(int32_t domain, int32_t type, int32_t protocol) { + int32_t ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, domain); + args = UINT32_TO_STREAM(args, type); + args = UINT32_TO_STREAM(args, protocol); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_SOCKET, &ret); + + // Process the event + errno = ret; + + _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); + + return(ret); +} + +int32_t cc3000_socket::closesocket(int32_t sd) { + int32_t ret; + uint8_t *ptr, *args; + + while(_simple_link.get_number_free_buffers() != SOCKET_MAX_FREE_BUFFERS); + ret = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, sd); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_CLOSE_SOCKET, &ret); + errno = ret; + + // since 'close' call may result in either OK (and then it closed) or error, mark this socket as invalid + _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); + + return(ret); +} + +int32_t cc3000_socket::accept(int32_t sd, sockaddr *addr, socklen_t *addrlen) { + int32_t ret; + uint8_t *ptr, *args; + tBsdReturnParams tAcceptReturnArguments; + + ret = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_ACCEPT, &tAcceptReturnArguments); + + + // need specify return parameters!!! + memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); + *addrlen = ASIC_ADDR_LEN; + errno = tAcceptReturnArguments.iStatus; + ret = errno; + + // if succeeded, iStatus = new socket descriptor. otherwise - error number + if(M_IS_VALID_SD(ret)) + { + _event.set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); + } + else + { + _event.set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); + } + + return(ret); +} + +int32_t cc3000_socket::bind(int32_t sd, const sockaddr *addr, int32_t addrlen) { + int32_t ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + addrlen = ASIC_ADDR_LEN; + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, 0x00000008); + args = UINT32_TO_STREAM(args, addrlen); + ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_BIND, &ret); + + errno = ret; + + return(ret); +} + +int32_t cc3000_socket::listen(int32_t sd, int32_t backlog) { + int32_t ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, backlog); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_LISTEN, &ret); + errno = ret; + + return(ret); +} + +int32_t cc3000_socket::connect(int32_t sd, const sockaddr *addr, int32_t addrlen) { + int32_t ret; + uint8_t *ptr, *args; + + ret = EFAIL; + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); + addrlen = 8; + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, 0x00000008); + args = UINT32_TO_STREAM(args, addrlen); + ARRAY_TO_STREAM(args, ((uint8_t *)addr), addrlen); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_CONNECT, &ret); + + errno = ret; + + return((int32_t)ret); +} + +int32_t cc3000_socket::select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) { + uint8_t *ptr, *args; + tBsdSelectRecvParams tParams; + uint32_t is_blocking; + + if( timeout == NULL) + { + is_blocking = 1; /* blocking , infinity timeout */ + } + else + { + is_blocking = 0; /* no blocking, timeout */ + } + + // Fill in HCI packet structure + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, nfds); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, 0x00000014); + args = UINT32_TO_STREAM(args, is_blocking); + args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0)); + args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0)); + args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0)); + + if (timeout) + { + if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) + { + timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; + } + args = UINT32_TO_STREAM(args, timeout->tv_sec); + args = UINT32_TO_STREAM(args, timeout->tv_usec); + } + + // Initiate a HCI command + _hci.command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_EVNT_SELECT, &tParams); + + // Update actually read FD + if (tParams.iStatus >= 0) + { + if (readsds) + { + memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); + } + + if (writesds) + { + memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); + } + + if (exceptsds) + { + memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); + } + + return(tParams.iStatus); + + } + else + { + errno = tParams.iStatus; + return(-1); + } +} + +int32_t cc3000_socket::getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen) { + uint8_t *ptr, *args; + tBsdGetSockOptReturnParams tRetParams; + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, level); + args = UINT32_TO_STREAM(args, optname); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_GETSOCKOPT, &tRetParams); + + if (((int8_t)tRetParams.iStatus) >= 0) + { + *optlen = 4; + memcpy(optval, tRetParams.ucOptValue, 4); + return (0); + } + else + { + errno = tRetParams.iStatus; + return errno; + } +} + +int32_t cc3000_socket::simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode) { + uint8_t *ptr, *args; + tBsdReadReturnParams tSocketReadEvent; + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, len); + args = UINT32_TO_STREAM(args, flags); + + // Generate the read command, and wait for the + _hci.command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(opcode, &tSocketReadEvent); + + // In case the number of bytes is more then zero - read data + if (tSocketReadEvent.iNumberOfBytes > 0) + { + // Wait for the data in a synchronous way. Here we assume that the bug is + // big enough to store also parameters of receive from too.... + _event.simplelink_wait_data((uint8_t *)buf, (uint8_t *)from, (uint8_t *)fromlen); + } + + errno = tSocketReadEvent.iNumberOfBytes; + + return(tSocketReadEvent.iNumberOfBytes); +} + +int32_t cc3000_socket::recv(int32_t sd, void *buf, int32_t len, int32_t flags) { + return(simple_link_recv(sd, buf, len, flags, NULL, NULL, HCI_CMND_RECV)); +} + +int32_t cc3000_socket::recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen) { + return(simple_link_recv(sd, buf, len, flags, from, fromlen, HCI_CMND_RECVFROM)); +} + +int32_t cc3000_socket::simple_link_send(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, int32_t tolen, int32_t opcode) { + uint8_t uArgSize = 0x00, addrlen = 0x00; + uint8_t *ptr, *pDataPtr = NULL, *args; + uint32_t addr_offset = 0x00; + int32_t res; + tBsdReadReturnParams tSocketSendEvent; + + // Check the bsd_arguments + if (0 != (res = HostFlowControlConsumeBuff(sd))) + { + return res; + } + + //Update the number of sent packets + uint16_t sent_packets = _simple_link.get_sent_packets(); + sent_packets++; + _simple_link.set_sent_packets(sent_packets); + + // Allocate a buffer and construct a packet and send it over spi + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_DATA); + + // Update the offset of data and parameters according to the command + switch(opcode) + { + case HCI_CMND_SENDTO: + { + addr_offset = len + sizeof(len) + sizeof(len); + addrlen = 8; + uArgSize = SOCKET_SENDTO_PARAMS_LEN; + pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; + break; + } + + case HCI_CMND_SEND: + { + tolen = 0; + to = NULL; + uArgSize = HCI_CMND_SEND_ARG_LENGTH; + pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; + break; + } + + default: + { + break; + } + } + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); + args = UINT32_TO_STREAM(args, len); + args = UINT32_TO_STREAM(args, flags); + + if (opcode == HCI_CMND_SENDTO) + { + args = UINT32_TO_STREAM(args, addr_offset); + args = UINT32_TO_STREAM(args, addrlen); + } + + // Copy the data received from user into the TX Buffer + ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len); + + // In case we are using SendTo, copy the to parameters + if (opcode == HCI_CMND_SENDTO) + { + ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen); + } + + // Initiate a HCI command + _hci.data_send(opcode, ptr, uArgSize, len,(uint8_t*)to, tolen); + if (opcode == HCI_CMND_SENDTO) + _event.simplelink_wait_event(HCI_EVNT_SENDTO, &tSocketSendEvent); + else + _event.simplelink_wait_event(HCI_EVNT_SEND, &tSocketSendEvent); + + return (len); +} + +int32_t cc3000_socket::send(int32_t sd, const void *buf, int32_t len, int32_t flags) { + return(simple_link_send(sd, buf, len, flags, NULL, 0, HCI_CMND_SEND)); +} + +int32_t cc3000_socket::sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen) { + return(simple_link_send(sd, buf, len, flags, to, tolen, HCI_CMND_SENDTO)); +} + +int32_t cc3000_socket::mdns_advertiser(uint16_t mdns_enabled, uint8_t *device_service_name, uint16_t device_service_name_length) { + int32_t ret; + uint8_t *pTxBuffer, *pArgs; + + if (device_service_name_length > MDNS_DEVICE_SERVICE_MAX_LENGTH) + { + return EFAIL; + } + + pTxBuffer = _simple_link.get_transmit_buffer(); + pArgs = (pTxBuffer + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); + + // Fill in HCI packet structure + pArgs = UINT32_TO_STREAM(pArgs, mdns_enabled); + pArgs = UINT32_TO_STREAM(pArgs, 8); + pArgs = UINT32_TO_STREAM(pArgs, device_service_name_length); + ARRAY_TO_STREAM(pArgs, device_service_name, device_service_name_length); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_MDNS_ADVERTISE, pTxBuffer, SOCKET_MDNS_ADVERTISE_PARAMS_LEN + device_service_name_length); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_EVNT_MDNS_ADVERTISE, &ret); + + return ret; +} + + +#ifndef CC3000_TINY_DRIVER +int32_t cc3000_socket::gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr) { + tBsdGethostbynameParams ret; + uint8_t *ptr, *args; + + errno = EFAIL; + + if (name_length > HOSTNAME_MAX_LENGTH) + { + return errno; + } + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); + + // Fill in HCI packet structure + args = UINT32_TO_STREAM(args, 8); + args = UINT32_TO_STREAM(args, name_length); + ARRAY_TO_STREAM(args, hostname, name_length); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + name_length - 1); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); + + errno = ret.retVal; + + (*((int32_t*)out_ip_addr)) = ret.outputAddress; + + return (errno); +} + +int32_t cc3000_socket::setsockopt(int32_t sd, int32_t level, int32_t optname, const void *optval, socklen_t optlen) { + int32_t ret; + uint8_t *ptr, *args; + + ptr = _simple_link.get_transmit_buffer(); + args = (ptr + HEADERS_SIZE_CMD); + + // Fill in temporary command buffer + args = UINT32_TO_STREAM(args, sd); + args = UINT32_TO_STREAM(args, level); + args = UINT32_TO_STREAM(args, optname); + args = UINT32_TO_STREAM(args, 0x00000008); + args = UINT32_TO_STREAM(args, optlen); + ARRAY_TO_STREAM(args, ((uint8_t *)optval), optlen); + + // Initiate a HCI command + _hci.command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); + + // Since we are in blocking state - wait for event complete + _event.simplelink_wait_event(HCI_CMND_SETSOCKOPT, &ret); + + if (ret >= 0) + { + return (0); + } + else + { + errno = ret; + return ret; + } +} + +#endif + +} /* end of cc3000 namespace */
--- a/cc3000_socket.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_socket.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,225 +1,225 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_SOCKET_H -#define CC3000_SOCKET_H - -#define SOCKET_MAX_FREE_BUFFERS 6 - -#define SOCKET_STATUS_ACTIVE 0 -#define SOCKET_STATUS_INACTIVE 1 - -#define SOCKET_STATUS_INIT_VAL 0xFFFF -#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) -#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) - -#ifdef _API_USE_BSD_CLOSE - #define close(sd) closesocket(sd) -#endif - -//Enable this flag if and only if you must comply with BSD socket read() and -//write() functions -#ifdef _API_USE_BSD_READ_WRITE - #define read(sd, buf, len, flags) recv(sd, buf, len, flags) - #define write(sd, buf, len, flags) send(sd, buf, len, flags) -#endif - -#define SOCKET_OPEN_PARAMS_LEN (12) -#define SOCKET_CLOSE_PARAMS_LEN (4) -#define SOCKET_ACCEPT_PARAMS_LEN (4) -#define SOCKET_BIND_PARAMS_LEN (20) -#define SOCKET_LISTEN_PARAMS_LEN (8) -#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) -#define SOCKET_CONNECT_PARAMS_LEN (20) -#define SOCKET_SELECT_PARAMS_LEN (44) -#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) -#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) -#define SOCKET_RECV_FROM_PARAMS_LEN (12) -#define SOCKET_SENDTO_PARAMS_LEN (24) -#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) - -//#define NULL 0 - -// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, -// while size of each parameter is 32 bit - so the total length is 16 bytes; - -#define HCI_CMND_SEND_ARG_LENGTH (16) -#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 -#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) -#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) -#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) - - -#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value - -//--------- Address Families -------- - -#define AF_INET 2 -#define AF_INET6 23 - -//------------ Socket Types ------------ - -#define SOCK_STREAM 1 -#define SOCK_DGRAM 2 -#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers -#define SOCK_RDM 4 -#define SOCK_SEQPACKET 5 - -//----------- Socket Protocol ---------- - -#define IPPROTO_IP 0 // dummy for IP -#define IPPROTO_ICMP 1 // control message protocol -#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP -#define IPPROTO_TCP 6 // tcp -#define IPPROTO_UDP 17 // user datagram protocol -#define IPPROTO_IPV6 41 // IPv6 in IPv6 -#define IPPROTO_NONE 59 // No next header -#define IPPROTO_RAW 255 // raw IP packet -#define IPPROTO_MAX 256 - -//----------- Socket retunr codes ----------- - -#define SOC_ERROR (-1) // error -#define SOC_IN_PROGRESS (-2) // socket in progress - -//----------- Socket Options ----------- -#define SOL_SOCKET 0xffff // socket level -#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout -#define SOCKOPT_NONBLOCK 2 // accept non block mode set SOCK_ON or SOCK_OFF (default block mode ) -#define SOCK_ON 0 // socket non-blocking mode is enabled -#define SOCK_OFF 1 // socket blocking mode is enabled - -#define TCP_NODELAY 0x0001 -#define TCP_BSDURGENT 0x7000 - -#define MAX_PACKET_SIZE 1500 -#define MAX_LISTEN_QUEUE 4 - -#define IOCTL_SOCKET_EVENTMASK - -#define ENOBUFS 55 // No buffer space available - -#define __FD_SETSIZE 32 - -#define ASIC_ADDR_LEN 8 - -#define NO_QUERY_RECIVED -3 - - -typedef struct _in_addr_t -{ - uint32_t s_addr; // load with inet_aton() -} in_addr; - -/*typedef struct _sockaddr_t -{ - unsigned short int sa_family; - unsigned char sa_data[14]; -} sockaddr;*/ - -typedef struct _sockaddr_in_t -{ - int16_t sin_family; // e.g. AF_INET - uint16_t sin_port; // e.g. htons(3490) - in_addr sin_addr; // see struct in_addr, below - uint8_t sin_zero[8]; // zero this if you want to -} sockaddr_in; - -typedef uint32_t socklen_t; - -// The fd_set member is required to be an array of longs. -typedef int32_t __fd_mask; - -// It's easier to assume 8-bit bytes than to get CHAR_BIT. -#define __NFDBITS (8 * sizeof (__fd_mask)) -#define __FDELT(d) ((d) / __NFDBITS) -#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) - -// fd_set for select and pselect. -typedef struct -{ - __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; -#define __FDS_BITS(set) ((set)->fds_bits) -} fd_set; - -// We don't use `memset' because this would require a prototype and -// the array isn't too big. -#define __FD_ZERO(set) \ - do { \ - uint32_t __i; \ - fd_set *__arr = (set); \ - for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ - __FDS_BITS (__arr)[__i] = 0; \ - } while (0) -#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) -#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d)) -#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d)) - -// Access macros for 'fd_set'. -#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) -#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) -#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) -#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) - -//Use in case of Big Endian only - -#define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \ - (((uint32_t)(A) & 0x00ff0000) >> 8) | \ - (((uint32_t)(A) & 0x0000ff00) << 8) | \ - (((uint32_t)(A) & 0x000000ff) << 24)) - -#define ntohl htonl - -//Use in case of Big Endian only -#define htons(A) ((((uint32_t)(A) & 0xff00) >> 8) | \ - (((uint32_t)(A) & 0x00ff) << 8)) - - -#define ntohs htons - -// mDNS port - 5353 mDNS multicast address - 224.0.0.251 -#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \ - sockaddr.sa_data[1] = 0xe9; \ - sockaddr.sa_data[2] = 0xe0; \ - sockaddr.sa_data[3] = 0x0; \ - sockaddr.sa_data[4] = 0x0; \ - sockaddr.sa_data[5] = 0xfb; - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_SOCKET_H +#define CC3000_SOCKET_H + +#define SOCKET_MAX_FREE_BUFFERS 6 + +#define SOCKET_STATUS_ACTIVE 0 +#define SOCKET_STATUS_INACTIVE 1 + +#define SOCKET_STATUS_INIT_VAL 0xFFFF +#define M_IS_VALID_SD(sd) ((0 <= (sd)) && ((sd) <= 7)) +#define M_IS_VALID_STATUS(status) (((status) == SOCKET_STATUS_ACTIVE)||((status) == SOCKET_STATUS_INACTIVE)) + +#ifdef _API_USE_BSD_CLOSE + #define close(sd) closesocket(sd) +#endif + +//Enable this flag if and only if you must comply with BSD socket read() and +//write() functions +#ifdef _API_USE_BSD_READ_WRITE + #define read(sd, buf, len, flags) recv(sd, buf, len, flags) + #define write(sd, buf, len, flags) send(sd, buf, len, flags) +#endif + +#define SOCKET_OPEN_PARAMS_LEN (12) +#define SOCKET_CLOSE_PARAMS_LEN (4) +#define SOCKET_ACCEPT_PARAMS_LEN (4) +#define SOCKET_BIND_PARAMS_LEN (20) +#define SOCKET_LISTEN_PARAMS_LEN (8) +#define SOCKET_GET_HOST_BY_NAME_PARAMS_LEN (9) +#define SOCKET_CONNECT_PARAMS_LEN (20) +#define SOCKET_SELECT_PARAMS_LEN (44) +#define SOCKET_SET_SOCK_OPT_PARAMS_LEN (20) +#define SOCKET_GET_SOCK_OPT_PARAMS_LEN (12) +#define SOCKET_RECV_FROM_PARAMS_LEN (12) +#define SOCKET_SENDTO_PARAMS_LEN (24) +#define SOCKET_MDNS_ADVERTISE_PARAMS_LEN (12) + +//#define NULL 0 + +// The legnth of arguments for the SEND command: sd + buff_offset + len + flags, +// while size of each parameter is 32 bit - so the total length is 16 bytes; + +#define HCI_CMND_SEND_ARG_LENGTH (16) +#define SELECT_TIMEOUT_MIN_MICRO_SECONDS 5000 +#define HEADERS_SIZE_DATA (SPI_HEADER_SIZE + 5) +#define SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) +#define MDNS_DEVICE_SERVICE_MAX_LENGTH (32) + + +#define HOSTNAME_MAX_LENGTH (230) // 230 bytes + header shouldn't exceed 8 bit value + +//--------- Address Families -------- + +#define AF_INET 2 +#define AF_INET6 23 + +//------------ Socket Types ------------ + +#define SOCK_STREAM 1 +#define SOCK_DGRAM 2 +#define SOCK_RAW 3 // Raw sockets allow new IPv4 protocols to be implemented in user space. A raw socket receives or sends the raw datagram not including link level headers +#define SOCK_RDM 4 +#define SOCK_SEQPACKET 5 + +//----------- Socket Protocol ---------- + +#define IPPROTO_IP 0 // dummy for IP +#define IPPROTO_ICMP 1 // control message protocol +#define IPPROTO_IPV4 IPPROTO_IP // IP inside IP +#define IPPROTO_TCP 6 // tcp +#define IPPROTO_UDP 17 // user datagram protocol +#define IPPROTO_IPV6 41 // IPv6 in IPv6 +#define IPPROTO_NONE 59 // No next header +#define IPPROTO_RAW 255 // raw IP packet +#define IPPROTO_MAX 256 + +//----------- Socket retunr codes ----------- + +#define SOC_ERROR (-1) // error +#define SOC_IN_PROGRESS (-2) // socket in progress + +//----------- Socket Options ----------- +#define SOL_SOCKET 0xffff // socket level +#define SOCKOPT_RECV_TIMEOUT 1 // optname to configure recv and recvfromtimeout +#define SOCKOPT_NONBLOCK 2 // accept non block mode set SOCK_ON or SOCK_OFF (default block mode ) +#define SOCK_ON 0 // socket non-blocking mode is enabled +#define SOCK_OFF 1 // socket blocking mode is enabled + +#define TCP_NODELAY 0x0001 +#define TCP_BSDURGENT 0x7000 + +#define MAX_PACKET_SIZE 1500 +#define MAX_LISTEN_QUEUE 4 + +#define IOCTL_SOCKET_EVENTMASK + +#define ENOBUFS 55 // No buffer space available + +#define __FD_SETSIZE 32 + +#define ASIC_ADDR_LEN 8 + +#define NO_QUERY_RECIVED -3 + + +typedef struct _in_addr_t +{ + uint32_t s_addr; // load with inet_aton() +} in_addr; + +/*typedef struct _sockaddr_t +{ + unsigned short int sa_family; + unsigned char sa_data[14]; +} sockaddr;*/ + +typedef struct _sockaddr_in_t +{ + int16_t sin_family; // e.g. AF_INET + uint16_t sin_port; // e.g. htons(3490) + in_addr sin_addr; // see struct in_addr, below + uint8_t sin_zero[8]; // zero this if you want to +} sockaddr_in; + +typedef uint32_t socklen_t; + +// The fd_set member is required to be an array of longs. +typedef int32_t __fd_mask; + +// It's easier to assume 8-bit bytes than to get CHAR_BIT. +#define __NFDBITS (8 * sizeof (__fd_mask)) +#define __FDELT(d) ((d) / __NFDBITS) +#define __FDMASK(d) ((__fd_mask) 1 << ((d) % __NFDBITS)) + +// fd_set for select and pselect. +typedef struct +{ + __fd_mask fds_bits[__FD_SETSIZE / __NFDBITS]; +#define __FDS_BITS(set) ((set)->fds_bits) +} fd_set; + +// We don't use `memset' because this would require a prototype and +// the array isn't too big. +#define __FD_ZERO(set) \ + do { \ + uint32_t __i; \ + fd_set *__arr = (set); \ + for (__i = 0; __i < sizeof (fd_set) / sizeof (__fd_mask); ++__i) \ + __FDS_BITS (__arr)[__i] = 0; \ + } while (0) +#define __FD_SET(d, set) (__FDS_BITS (set)[__FDELT (d)] |= __FDMASK (d)) +#define __FD_CLR(d, set) (__FDS_BITS (set)[__FDELT (d)] &= ~__FDMASK (d)) +#define __FD_ISSET(d, set) (__FDS_BITS (set)[__FDELT (d)] & __FDMASK (d)) + +// Access macros for 'fd_set'. +#define FD_SET(fd, fdsetp) __FD_SET (fd, fdsetp) +#define FD_CLR(fd, fdsetp) __FD_CLR (fd, fdsetp) +#define FD_ISSET(fd, fdsetp) __FD_ISSET (fd, fdsetp) +#define FD_ZERO(fdsetp) __FD_ZERO (fdsetp) + +//Use in case of Big Endian only + +#define htonl(A) ((((uint32_t)(A) & 0xff000000) >> 24) | \ + (((uint32_t)(A) & 0x00ff0000) >> 8) | \ + (((uint32_t)(A) & 0x0000ff00) << 8) | \ + (((uint32_t)(A) & 0x000000ff) << 24)) + +#define ntohl htonl + +//Use in case of Big Endian only +#define htons(A) ((((uint32_t)(A) & 0xff00) >> 8) | \ + (((uint32_t)(A) & 0x00ff) << 8)) + + +#define ntohs htons + +// mDNS port - 5353 mDNS multicast address - 224.0.0.251 +#define SET_mDNS_ADD(sockaddr) sockaddr.sa_data[0] = 0x14; \ + sockaddr.sa_data[1] = 0xe9; \ + sockaddr.sa_data[2] = 0xe0; \ + sockaddr.sa_data[3] = 0x0; \ + sockaddr.sa_data[4] = 0x0; \ + sockaddr.sa_data[5] = 0xfb; + +#endif
--- a/cc3000_spi.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_spi.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,302 +1,302 @@ -/***************************************************************************** -* -* 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" -#include "cc3000_spi.h" - -namespace mbed_cc3000 { - -cc3000_spi::cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link) - : _wlan_irq(cc3000_irq), _wlan_en(cc3000_en), _wlan_cs(cc3000_cs), _wlan_spi(cc3000_spi), _irq_port(irq_port), - _event(event), _simple_link(simple_link) { - /* TODO = clear pending interrupts for PORTS. This is dependent on the used chip */ - - _wlan_spi.format(8,1); - _wlan_spi.frequency(12000000); - _function_pointer = _wlan_irq.fall(this, &cc3000_spi::WLAN_IRQHandler); - - _wlan_en = 0; - _wlan_cs = 1; -} - -cc3000_spi::~cc3000_spi() { - -} - -void cc3000_spi::wlan_irq_enable() -{ - NVIC_EnableIRQ(_irq_port); -} - -void cc3000_spi::wlan_irq_disable() { - NVIC_DisableIRQ(_irq_port); -} - -void cc3000_spi::wlan_irq_set(uint8_t value) { - if (value) - { - _wlan_en = 1; - } - else - { - _wlan_en = 0; - } -} - -uint32_t cc3000_spi::wlan_irq_read() { - return _wlan_irq.read(); -} - -void cc3000_spi::close() { - if (_simple_link.get_received_buffer() != 0) - { - _simple_link.set_received_buffer(0); - } - wlan_irq_disable(); -} - -// void cc3000_spi::SpiReceiveHandler() { -// _simple_link.usEventOrDataReceived = 1; -// //_simple_link.pucReceivedData = (unsigned char *)pvBuffer; - -// hci_unsolicited_event_handler(); -// } - - -/* TODO - pRxPacket, pTxPacket do we need to hold this pointer ? - SPIRxHandler - remove? -*/ -void cc3000_spi::open() { - _spi_info.spi_state = eSPI_STATE_POWERUP; - //_spi_info.SPIRxHandler = pfRxHandler; - _spi_info.tx_packet_length = 0; - _spi_info.rx_packet_length = 0; - //_rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - //_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; - wlan_irq_enable(); -} - -uint32_t cc3000_spi::first_write(uint8_t *buffer, uint16_t length) { - _wlan_cs = 0; - wait_us(50); - - /* first 4 bytes of the data */ - write_synchronous(buffer, 4); - wait_us(50); - write_synchronous(buffer + 4, length - 4); - _spi_info.spi_state = eSPI_STATE_IDLE; - _wlan_cs = 1; - - return 0; -} - - -uint32_t cc3000_spi::write(uint8_t *buffer, uint16_t length) { - uint8_t pad = 0; - // check the total length of the packet in order to figure out if padding is necessary - if(!(length & 0x0001)) - { - pad++; - } - buffer[0] = WRITE; - buffer[1] = HI(length + pad); - buffer[2] = LO(length + pad); - buffer[3] = 0; - buffer[4] = 0; - - length += (SPI_HEADER_SIZE + pad); - - // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size) - // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever! - uint8_t * transmit_buffer = _simple_link.get_transmit_buffer(); - if (transmit_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) - { - while (1); - } - - if (_spi_info.spi_state == eSPI_STATE_POWERUP) - { - while (_spi_info.spi_state != eSPI_STATE_INITIALIZED); - } - - if (_spi_info.spi_state == eSPI_STATE_INITIALIZED) - { - // TX/RX transaction over SPI after powerup: IRQ is low - send read buffer size command - first_write(buffer, length); - } - else - { - // Prevent occurence of a race condition when 2 back to back packets are sent to the - // device, so the state will move to IDLE and once again to not IDLE due to IRQ - wlan_irq_disable(); - - while (_spi_info.spi_state != eSPI_STATE_IDLE); - - _spi_info.spi_state = eSPI_STATE_WRITE_IRQ; - //_spi_info.pTxPacket = buffer; - _spi_info.tx_packet_length = length; - - // Assert the CS line and wait until the IRQ line is active, then initialize the write operation - _wlan_cs = 0; - - wlan_irq_enable(); - } - - // Wait until the transaction ends - while (_spi_info.spi_state != eSPI_STATE_IDLE); - - return 0; -} - -void cc3000_spi::write_synchronous(uint8_t *data, uint16_t size) { - while(size) - { - _wlan_spi.write(*data++); - size--; - } -} - -void cc3000_spi::read_synchronous(uint8_t *data, uint16_t size) { - for (uint32_t i = 0; i < size; i++) - { - data[i] = _wlan_spi.write(0x03);; - } -} - -uint32_t cc3000_spi::read_data_cont() { - long data_to_recv; - unsigned char *evnt_buff, type; - - //determine the packet type - evnt_buff = _simple_link.get_received_buffer(); - data_to_recv = 0; - STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type); - - switch(type) - { - case HCI_TYPE_DATA: - { - // Read the remaining data.. - STREAM_TO_UINT16((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv); - if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) - { - data_to_recv++; - } - - if (data_to_recv) - { - read_synchronous(evnt_buff + 10, data_to_recv); - } - break; - } - case HCI_TYPE_EVNT: - { - // Calculate the rest length of the data - STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv); - data_to_recv -= 1; - // Add padding byte if needed - if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) - { - data_to_recv++; - } - - if (data_to_recv) - { - read_synchronous(evnt_buff + 10, data_to_recv); - } - - _spi_info.spi_state = eSPI_STATE_READ_EOT; - break; - } - } - return (0); -} - -void cc3000_spi::write_wlan_en(uint8_t value) { - if (value) { - _wlan_en = 1; - } else { - _wlan_en = 0; - } -} - -void cc3000_spi::WLAN_IRQHandler() { - if (_spi_info.spi_state == eSPI_STATE_POWERUP) - { - // Inform HCI Layer that IRQ occured after powerup - _spi_info.spi_state = eSPI_STATE_INITIALIZED; - } - else if (_spi_info.spi_state == eSPI_STATE_IDLE) - { - _spi_info.spi_state = eSPI_STATE_READ_IRQ; - /* IRQ line goes low - acknowledge it */ - _wlan_cs = 0; - read_synchronous(_simple_link.get_received_buffer(), 10); - _spi_info.spi_state = eSPI_STATE_READ_EOT; - - - // The header was read - continue with the payload read - if (!read_data_cont()) - { - // All the data was read - finalize handling by switching to the task - // Trigger Rx processing - wlan_irq_disable(); - _wlan_cs = 1; - // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size) - // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever! - uint8_t *received_buffer = _simple_link.get_received_buffer(); - if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) - { - while (1); - } - _spi_info.spi_state = eSPI_STATE_IDLE; - _event.received_handler(received_buffer + SPI_HEADER_SIZE); - } - } - else if (_spi_info.spi_state == eSPI_STATE_WRITE_IRQ) - { - write_synchronous(_simple_link.get_transmit_buffer(), _spi_info.tx_packet_length); - _spi_info.spi_state = eSPI_STATE_IDLE; - _wlan_cs = 1; - } -} - -} +/***************************************************************************** +* +* 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" +#include "cc3000_spi.h" + +namespace mbed_cc3000 { + +cc3000_spi::cc3000_spi(PinName cc3000_irq, PinName cc3000_en, PinName cc3000_cs, SPI cc3000_spi, IRQn_Type irq_port, cc3000_event &event, cc3000_simple_link &simple_link) + : _wlan_irq(cc3000_irq), _wlan_en(cc3000_en), _wlan_cs(cc3000_cs), _wlan_spi(cc3000_spi), _irq_port(irq_port), + _event(event), _simple_link(simple_link) { + /* TODO = clear pending interrupts for PORTS. This is dependent on the used chip */ + + _wlan_spi.format(8,1); + _wlan_spi.frequency(12000000); + _function_pointer = _wlan_irq.fall(this, &cc3000_spi::WLAN_IRQHandler); + + _wlan_en = 0; + _wlan_cs = 1; +} + +cc3000_spi::~cc3000_spi() { + +} + +void cc3000_spi::wlan_irq_enable() +{ + NVIC_EnableIRQ(_irq_port); +} + +void cc3000_spi::wlan_irq_disable() { + NVIC_DisableIRQ(_irq_port); +} + +void cc3000_spi::wlan_irq_set(uint8_t value) { + if (value) + { + _wlan_en = 1; + } + else + { + _wlan_en = 0; + } +} + +uint32_t cc3000_spi::wlan_irq_read() { + return _wlan_irq.read(); +} + +void cc3000_spi::close() { + if (_simple_link.get_received_buffer() != 0) + { + _simple_link.set_received_buffer(0); + } + wlan_irq_disable(); +} + +// void cc3000_spi::SpiReceiveHandler() { +// _simple_link.usEventOrDataReceived = 1; +// //_simple_link.pucReceivedData = (unsigned char *)pvBuffer; + +// hci_unsolicited_event_handler(); +// } + + +/* TODO + pRxPacket, pTxPacket do we need to hold this pointer ? + SPIRxHandler - remove? +*/ +void cc3000_spi::open() { + _spi_info.spi_state = eSPI_STATE_POWERUP; + //_spi_info.SPIRxHandler = pfRxHandler; + _spi_info.tx_packet_length = 0; + _spi_info.rx_packet_length = 0; + //_rx_buffer[CC3000_RX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; + //_tx_buffer[CC3000_TX_BUFFER_SIZE - 1] = CC3000_BUFFER_MAGIC_NUMBER; + wlan_irq_enable(); +} + +uint32_t cc3000_spi::first_write(uint8_t *buffer, uint16_t length) { + _wlan_cs = 0; + wait_us(50); + + /* first 4 bytes of the data */ + write_synchronous(buffer, 4); + wait_us(50); + write_synchronous(buffer + 4, length - 4); + _spi_info.spi_state = eSPI_STATE_IDLE; + _wlan_cs = 1; + + return 0; +} + + +uint32_t cc3000_spi::write(uint8_t *buffer, uint16_t length) { + uint8_t pad = 0; + // check the total length of the packet in order to figure out if padding is necessary + if(!(length & 0x0001)) + { + pad++; + } + buffer[0] = WRITE; + buffer[1] = HI(length + pad); + buffer[2] = LO(length + pad); + buffer[3] = 0; + buffer[4] = 0; + + length += (SPI_HEADER_SIZE + pad); + + // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size) + // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever! + uint8_t * transmit_buffer = _simple_link.get_transmit_buffer(); + if (transmit_buffer[CC3000_TX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) + { + while (1); + } + + if (_spi_info.spi_state == eSPI_STATE_POWERUP) + { + while (_spi_info.spi_state != eSPI_STATE_INITIALIZED); + } + + if (_spi_info.spi_state == eSPI_STATE_INITIALIZED) + { + // TX/RX transaction over SPI after powerup: IRQ is low - send read buffer size command + first_write(buffer, length); + } + else + { + // Prevent occurence of a race condition when 2 back to back packets are sent to the + // device, so the state will move to IDLE and once again to not IDLE due to IRQ + wlan_irq_disable(); + + while (_spi_info.spi_state != eSPI_STATE_IDLE); + + _spi_info.spi_state = eSPI_STATE_WRITE_IRQ; + //_spi_info.pTxPacket = buffer; + _spi_info.tx_packet_length = length; + + // Assert the CS line and wait until the IRQ line is active, then initialize the write operation + _wlan_cs = 0; + + wlan_irq_enable(); + } + + // Wait until the transaction ends + while (_spi_info.spi_state != eSPI_STATE_IDLE); + + return 0; +} + +void cc3000_spi::write_synchronous(uint8_t *data, uint16_t size) { + while(size) + { + _wlan_spi.write(*data++); + size--; + } +} + +void cc3000_spi::read_synchronous(uint8_t *data, uint16_t size) { + for (uint32_t i = 0; i < size; i++) + { + data[i] = _wlan_spi.write(0x03);; + } +} + +uint32_t cc3000_spi::read_data_cont() { + long data_to_recv; + unsigned char *evnt_buff, type; + + //determine the packet type + evnt_buff = _simple_link.get_received_buffer(); + data_to_recv = 0; + STREAM_TO_UINT8((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_PACKET_TYPE_OFFSET, type); + + switch(type) + { + case HCI_TYPE_DATA: + { + // Read the remaining data.. + STREAM_TO_UINT16((uint8_t *)(evnt_buff + SPI_HEADER_SIZE), HCI_DATA_LENGTH_OFFSET, data_to_recv); + if (!((HEADERS_SIZE_EVNT + data_to_recv) & 1)) + { + data_to_recv++; + } + + if (data_to_recv) + { + read_synchronous(evnt_buff + 10, data_to_recv); + } + break; + } + case HCI_TYPE_EVNT: + { + // Calculate the rest length of the data + STREAM_TO_UINT8((char *)(evnt_buff + SPI_HEADER_SIZE), HCI_EVENT_LENGTH_OFFSET, data_to_recv); + data_to_recv -= 1; + // Add padding byte if needed + if ((HEADERS_SIZE_EVNT + data_to_recv) & 1) + { + data_to_recv++; + } + + if (data_to_recv) + { + read_synchronous(evnt_buff + 10, data_to_recv); + } + + _spi_info.spi_state = eSPI_STATE_READ_EOT; + break; + } + } + return (0); +} + +void cc3000_spi::write_wlan_en(uint8_t value) { + if (value) { + _wlan_en = 1; + } else { + _wlan_en = 0; + } +} + +void cc3000_spi::WLAN_IRQHandler() { + if (_spi_info.spi_state == eSPI_STATE_POWERUP) + { + // Inform HCI Layer that IRQ occured after powerup + _spi_info.spi_state = eSPI_STATE_INITIALIZED; + } + else if (_spi_info.spi_state == eSPI_STATE_IDLE) + { + _spi_info.spi_state = eSPI_STATE_READ_IRQ; + /* IRQ line goes low - acknowledge it */ + _wlan_cs = 0; + read_synchronous(_simple_link.get_received_buffer(), 10); + _spi_info.spi_state = eSPI_STATE_READ_EOT; + + + // The header was read - continue with the payload read + if (!read_data_cont()) + { + // All the data was read - finalize handling by switching to the task + // Trigger Rx processing + wlan_irq_disable(); + _wlan_cs = 1; + // The magic number resides at the end of the TX/RX buffer (1 byte after the allocated size) + // If the magic number is overwitten - buffer overrun occurred - we will be stuck here forever! + uint8_t *received_buffer = _simple_link.get_received_buffer(); + if (received_buffer[CC3000_RX_BUFFER_SIZE - 1] != CC3000_BUFFER_MAGIC_NUMBER) + { + while (1); + } + _spi_info.spi_state = eSPI_STATE_IDLE; + _event.received_handler(received_buffer + SPI_HEADER_SIZE); + } + } + else if (_spi_info.spi_state == eSPI_STATE_WRITE_IRQ) + { + write_synchronous(_simple_link.get_transmit_buffer(), _spi_info.tx_packet_length); + _spi_info.spi_state = eSPI_STATE_IDLE; + _wlan_cs = 1; + } +} + +}
--- a/cc3000_spi.h Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_spi.h Thu Oct 03 21:00:00 2013 +0000 @@ -1,251 +1,251 @@ -/***************************************************************************** -* -* 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. -* -*****************************************************************************/ -#ifndef CC3000_SPI_H -#define CC3000_SPI_H - -typedef struct -{ - uint16_t tx_packet_length; - uint16_t rx_packet_length; - uint32_t spi_state; -} tSpiInfo; - - -/* =========================================================================================== - SPI - =========================================================================================== */ -#define READ 3 -#define WRITE 1 - -#define HI(value) (((value) & 0xFF00) >> 8) -#define LO(value) ((value) & 0x00FF) - -#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5) - -#define SPI_HEADER_SIZE (5) - -#define eSPI_STATE_POWERUP (0) -#define eSPI_STATE_INITIALIZED (1) -#define eSPI_STATE_IDLE (2) -#define eSPI_STATE_WRITE_IRQ (3) -#define eSPI_STATE_WRITE_FIRST_PORTION (4) -#define eSPI_STATE_WRITE_EOT (5) -#define eSPI_STATE_READ_IRQ (6) -#define eSPI_STATE_READ_FIRST_PORTION (7) -#define eSPI_STATE_READ_EOT (8) - -// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) -// for the purpose of detection of the overrun. The location of the memory where the magic number -// resides shall never be written. In case it is written - overrun occured and either recevie function -// or send function will be stuck forever. -#define CC3000_BUFFER_MAGIC_NUMBER (0xDE) - -/* =========================================================================================== - HCI - =========================================================================================== */ - -#define SL_PATCH_PORTION_SIZE (1000) - -#define SPI_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4) -#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) -#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5) -#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2) - -// Values that can be used as HCI Commands and HCI Packet header defines -#define HCI_TYPE_CMND 0x1 -#define HCI_TYPE_DATA 0x2 -#define HCI_TYPE_PATCH 0x3 -#define HCI_TYPE_EVNT 0x4 - - -#define HCI_EVENT_PATCHES_DRV_REQ (1) -#define HCI_EVENT_PATCHES_FW_REQ (2) -#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3) - - -#define HCI_CMND_WLAN_BASE (0x0000) -#define HCI_CMND_WLAN_CONNECT 0x0001 -#define HCI_CMND_WLAN_DISCONNECT 0x0002 -#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003 -#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004 -#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005 -#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006 -#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007 -#define HCI_CMND_EVENT_MASK 0x0008 -#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009 -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B -#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C -#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D - - -#define HCI_CMND_SOCKET_BASE 0x1000 -#define HCI_CMND_SOCKET 0x1001 -#define HCI_CMND_BIND 0x1002 -#define HCI_CMND_RECV 0x1004 -#define HCI_CMND_ACCEPT 0x1005 -#define HCI_CMND_LISTEN 0x1006 -#define HCI_CMND_CONNECT 0x1007 -#define HCI_CMND_BSD_SELECT 0x1008 -#define HCI_CMND_SETSOCKOPT 0x1009 -#define HCI_CMND_GETSOCKOPT 0x100A -#define HCI_CMND_CLOSE_SOCKET 0x100B -#define HCI_CMND_RECVFROM 0x100D -#define HCI_CMND_GETHOSTNAME 0x1010 -#define HCI_CMND_MDNS_ADVERTISE 0x1011 - - -#define HCI_DATA_BASE 0x80 - -#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE) -#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE) -#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE) -#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE) - - -#define HCI_CMND_NVMEM_CBASE (0x0200) - - -#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203) -#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205) -#define HCI_CMND_NVMEM_READ (0x0201) -#define HCI_CMND_NVMEM_WRITE (0x0090) -#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204) -#define HCI_CMND_READ_SP_VERSION (0x0207) - -#define HCI_CMND_READ_BUFFER_SIZE 0x400B -#define HCI_CMND_SIMPLE_LINK_START 0x4000 - -#define HCI_CMND_NETAPP_BASE 0x2000 - -#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE) -#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE) - -// Values that can be used as HCI Events defines -#define HCI_EVNT_WLAN_BASE 0x0000 -#define HCI_EVNT_WLAN_CONNECT 0x0001 -#define HCI_EVNT_WLAN_DISCONNECT \ - 0x0002 -#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \ - 0x0005 - - -#define HCI_EVNT_SOCKET HCI_CMND_SOCKET -#define HCI_EVNT_BIND HCI_CMND_BIND -#define HCI_EVNT_RECV HCI_CMND_RECV -#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT -#define HCI_EVNT_LISTEN HCI_CMND_LISTEN -#define HCI_EVNT_CONNECT HCI_CMND_CONNECT -#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT -#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET -#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM -#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT -#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT -#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME -#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE - -#define HCI_EVNT_SEND 0x1003 -#define HCI_EVNT_WRITE 0x100E -#define HCI_EVNT_SENDTO 0x100F - -#define HCI_EVNT_PATCHES_REQ 0x1000 - -#define HCI_EVNT_UNSOL_BASE 0x4000 - -#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000) - -#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE) -#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE) - -#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \ - 0x4100 - -#define HCI_EVNT_NVMEM_CREATE_ENTRY \ - HCI_CMND_NVMEM_CREATE_ENTRY -#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY - -#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ -#define HCI_EVNT_NVMEM_WRITE (0x0202) - -#define HCI_EVNT_READ_SP_VERSION \ - HCI_CMND_READ_SP_VERSION - -#define HCI_EVNT_INPROGRESS 0xFFFF - - -#define HCI_DATA_RECVFROM 0x84 -#define HCI_DATA_RECV 0x85 -#define HCI_DATA_NVMEM 0x91 - -#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99 - -// Prototypes for the structures for HCI APIs. -#define HCI_DATA_HEADER_SIZE (5) -#define HCI_EVENT_HEADER_SIZE (5) -#define HCI_DATA_CMD_HEADER_SIZE (5) -#define HCI_PATCH_HEADER_SIZE (6) - -#define HCI_PACKET_TYPE_OFFSET (0) -#define HCI_PACKET_ARGSIZE_OFFSET (2) -#define HCI_PACKET_LENGTH_OFFSET (3) - - -#define HCI_EVENT_OPCODE_OFFSET (1) -#define HCI_EVENT_LENGTH_OFFSET (3) -#define HCI_EVENT_STATUS_OFFSET (4) -#define HCI_DATA_LENGTH_OFFSET (3) - -#endif +/***************************************************************************** +* +* 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. +* +*****************************************************************************/ +#ifndef CC3000_SPI_H +#define CC3000_SPI_H + +typedef struct +{ + uint16_t tx_packet_length; + uint16_t rx_packet_length; + uint32_t spi_state; +} tSpiInfo; + + +/* =========================================================================================== + SPI + =========================================================================================== */ +#define READ 3 +#define WRITE 1 + +#define HI(value) (((value) & 0xFF00) >> 8) +#define LO(value) ((value) & 0x00FF) + +#define HEADERS_SIZE_EVNT (SPI_HEADER_SIZE + 5) + +#define SPI_HEADER_SIZE (5) + +#define eSPI_STATE_POWERUP (0) +#define eSPI_STATE_INITIALIZED (1) +#define eSPI_STATE_IDLE (2) +#define eSPI_STATE_WRITE_IRQ (3) +#define eSPI_STATE_WRITE_FIRST_PORTION (4) +#define eSPI_STATE_WRITE_EOT (5) +#define eSPI_STATE_READ_IRQ (6) +#define eSPI_STATE_READ_FIRST_PORTION (7) +#define eSPI_STATE_READ_EOT (8) + +// The magic number that resides at the end of the TX/RX buffer (1 byte after the allocated size) +// for the purpose of detection of the overrun. The location of the memory where the magic number +// resides shall never be written. In case it is written - overrun occured and either recevie function +// or send function will be stuck forever. +#define CC3000_BUFFER_MAGIC_NUMBER (0xDE) + +/* =========================================================================================== + HCI + =========================================================================================== */ + +#define SL_PATCH_PORTION_SIZE (1000) + +#define SPI_HEADER_SIZE (5) +#define SIMPLE_LINK_HCI_CMND_HEADER_SIZE (4) +#define HEADERS_SIZE_CMD (SPI_HEADER_SIZE + SIMPLE_LINK_HCI_CMND_HEADER_SIZE) +#define SIMPLE_LINK_HCI_DATA_CMND_HEADER_SIZE (5) +#define SIMPLE_LINK_HCI_DATA_HEADER_SIZE (5) +#define SIMPLE_LINK_HCI_PATCH_HEADER_SIZE (2) + +// Values that can be used as HCI Commands and HCI Packet header defines +#define HCI_TYPE_CMND 0x1 +#define HCI_TYPE_DATA 0x2 +#define HCI_TYPE_PATCH 0x3 +#define HCI_TYPE_EVNT 0x4 + + +#define HCI_EVENT_PATCHES_DRV_REQ (1) +#define HCI_EVENT_PATCHES_FW_REQ (2) +#define HCI_EVENT_PATCHES_BOOTLOAD_REQ (3) + + +#define HCI_CMND_WLAN_BASE (0x0000) +#define HCI_CMND_WLAN_CONNECT 0x0001 +#define HCI_CMND_WLAN_DISCONNECT 0x0002 +#define HCI_CMND_WLAN_IOCTL_SET_SCANPARAM 0x0003 +#define HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY 0x0004 +#define HCI_CMND_WLAN_IOCTL_ADD_PROFILE 0x0005 +#define HCI_CMND_WLAN_IOCTL_DEL_PROFILE 0x0006 +#define HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS 0x0007 +#define HCI_CMND_EVENT_MASK 0x0008 +#define HCI_CMND_WLAN_IOCTL_STATUSGET 0x0009 +#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START 0x000A +#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP 0x000B +#define HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX 0x000C +#define HCI_CMND_WLAN_CONFIGURE_PATCH 0x000D + + +#define HCI_CMND_SOCKET_BASE 0x1000 +#define HCI_CMND_SOCKET 0x1001 +#define HCI_CMND_BIND 0x1002 +#define HCI_CMND_RECV 0x1004 +#define HCI_CMND_ACCEPT 0x1005 +#define HCI_CMND_LISTEN 0x1006 +#define HCI_CMND_CONNECT 0x1007 +#define HCI_CMND_BSD_SELECT 0x1008 +#define HCI_CMND_SETSOCKOPT 0x1009 +#define HCI_CMND_GETSOCKOPT 0x100A +#define HCI_CMND_CLOSE_SOCKET 0x100B +#define HCI_CMND_RECVFROM 0x100D +#define HCI_CMND_GETHOSTNAME 0x1010 +#define HCI_CMND_MDNS_ADVERTISE 0x1011 + + +#define HCI_DATA_BASE 0x80 + +#define HCI_CMND_SEND (0x01 + HCI_DATA_BASE) +#define HCI_CMND_SENDTO (0x03 + HCI_DATA_BASE) +#define HCI_DATA_BSD_RECVFROM (0x04 + HCI_DATA_BASE) +#define HCI_DATA_BSD_RECV (0x05 + HCI_DATA_BASE) + + +#define HCI_CMND_NVMEM_CBASE (0x0200) + + +#define HCI_CMND_NVMEM_CREATE_ENTRY (0x0203) +#define HCI_CMND_NVMEM_SWAP_ENTRY (0x0205) +#define HCI_CMND_NVMEM_READ (0x0201) +#define HCI_CMND_NVMEM_WRITE (0x0090) +#define HCI_CMND_NVMEM_WRITE_PATCH (0x0204) +#define HCI_CMND_READ_SP_VERSION (0x0207) + +#define HCI_CMND_READ_BUFFER_SIZE 0x400B +#define HCI_CMND_SIMPLE_LINK_START 0x4000 + +#define HCI_CMND_NETAPP_BASE 0x2000 + +#define HCI_NETAPP_DHCP (0x0001 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_PING_SEND (0x0002 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_PING_REPORT (0x0003 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_PING_STOP (0x0004 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_IPCONFIG (0x0005 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_ARP_FLUSH (0x0006 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_SET_DEBUG_LEVEL (0x0008 + HCI_CMND_NETAPP_BASE) +#define HCI_NETAPP_SET_TIMERS (0x0009 + HCI_CMND_NETAPP_BASE) + +// Values that can be used as HCI Events defines +#define HCI_EVNT_WLAN_BASE 0x0000 +#define HCI_EVNT_WLAN_CONNECT 0x0001 +#define HCI_EVNT_WLAN_DISCONNECT \ + 0x0002 +#define HCI_EVNT_WLAN_IOCTL_ADD_PROFILE \ + 0x0005 + + +#define HCI_EVNT_SOCKET HCI_CMND_SOCKET +#define HCI_EVNT_BIND HCI_CMND_BIND +#define HCI_EVNT_RECV HCI_CMND_RECV +#define HCI_EVNT_ACCEPT HCI_CMND_ACCEPT +#define HCI_EVNT_LISTEN HCI_CMND_LISTEN +#define HCI_EVNT_CONNECT HCI_CMND_CONNECT +#define HCI_EVNT_SELECT HCI_CMND_BSD_SELECT +#define HCI_EVNT_CLOSE_SOCKET HCI_CMND_CLOSE_SOCKET +#define HCI_EVNT_RECVFROM HCI_CMND_RECVFROM +#define HCI_EVNT_SETSOCKOPT HCI_CMND_SETSOCKOPT +#define HCI_EVNT_GETSOCKOPT HCI_CMND_GETSOCKOPT +#define HCI_EVNT_BSD_GETHOSTBYNAME HCI_CMND_GETHOSTNAME +#define HCI_EVNT_MDNS_ADVERTISE HCI_CMND_MDNS_ADVERTISE + +#define HCI_EVNT_SEND 0x1003 +#define HCI_EVNT_WRITE 0x100E +#define HCI_EVNT_SENDTO 0x100F + +#define HCI_EVNT_PATCHES_REQ 0x1000 + +#define HCI_EVNT_UNSOL_BASE 0x4000 + +#define HCI_EVNT_WLAN_UNSOL_BASE (0x8000) + +#define HCI_EVNT_WLAN_UNSOL_CONNECT (0x0001 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_UNSOL_DISCONNECT (0x0002 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_UNSOL_INIT (0x0004 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_TX_COMPLETE (0x0008 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_UNSOL_DHCP (0x0010 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_ASYNC_PING_REPORT (0x0040 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE (0x0080 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_WLAN_KEEPALIVE (0x0200 + HCI_EVNT_WLAN_UNSOL_BASE) +#define HCI_EVNT_BSD_TCP_CLOSE_WAIT (0x0800 + HCI_EVNT_WLAN_UNSOL_BASE) + +#define HCI_EVNT_DATA_UNSOL_FREE_BUFF \ + 0x4100 + +#define HCI_EVNT_NVMEM_CREATE_ENTRY \ + HCI_CMND_NVMEM_CREATE_ENTRY +#define HCI_EVNT_NVMEM_SWAP_ENTRY HCI_CMND_NVMEM_SWAP_ENTRY + +#define HCI_EVNT_NVMEM_READ HCI_CMND_NVMEM_READ +#define HCI_EVNT_NVMEM_WRITE (0x0202) + +#define HCI_EVNT_READ_SP_VERSION \ + HCI_CMND_READ_SP_VERSION + +#define HCI_EVNT_INPROGRESS 0xFFFF + + +#define HCI_DATA_RECVFROM 0x84 +#define HCI_DATA_RECV 0x85 +#define HCI_DATA_NVMEM 0x91 + +#define HCI_EVENT_CC3000_CAN_SHUT_DOWN 0x99 + +// Prototypes for the structures for HCI APIs. +#define HCI_DATA_HEADER_SIZE (5) +#define HCI_EVENT_HEADER_SIZE (5) +#define HCI_DATA_CMD_HEADER_SIZE (5) +#define HCI_PATCH_HEADER_SIZE (6) + +#define HCI_PACKET_TYPE_OFFSET (0) +#define HCI_PACKET_ARGSIZE_OFFSET (2) +#define HCI_PACKET_LENGTH_OFFSET (3) + + +#define HCI_EVENT_OPCODE_OFFSET (1) +#define HCI_EVENT_LENGTH_OFFSET (3) +#define HCI_EVENT_STATUS_OFFSET (4) +#define HCI_DATA_LENGTH_OFFSET (3) + +#endif
--- a/cc3000_wlan.cpp Thu Oct 03 20:22:45 2013 +0000 +++ b/cc3000_wlan.cpp Thu Oct 03 21:00:00 2013 +0000 @@ -1,699 +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 - -} +/***************************************************************************** +* +* 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 + +}