cc3000 hostdriver with the mbed socket interface
Fork of cc3000_hostdriver_mbedsocket by
cc3000.h
- Committer:
- Kojto
- Date:
- 2013-10-08
- Revision:
- 35:9dd909fb7caf
- Parent:
- 34:1ad18123bf11
- Child:
- 38:1d374a7f0c0d
File content as of revision 35:9dd909fb7caf:
/***************************************************************************** * * 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, remove comment from the ones you want or all. */ // Debug - Socket interface messages //#define CC3000_DEBUG_SOCKET // Debug - HCI TX messages //#define CC3000_DEBUG_HCI_TX // Debug - HCI Rx messages //#define CC3000_DEBUG_HCI_RX // Debug - General Debug //#define CC3000_DEBUG // Add colour to 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_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: /** * \brief ctor - sets magic number in the buffers (overflow mark). * \param none * \return none */ cc3000_simple_link(); /** * \brief dtor * \param none * \return none */ ~cc3000_simple_link(); /** * \brief Returns data received flag. * \return Data received flag. */ uint8_t get_data_received_flag(); /** * \brief 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(); /** * \brief Sets flag that tx was completed. * \param value Value to be set * \return none */ void set_tx_complete_signal(bool value); /** * \brief Get receive buffer. * \param none * \return Pointer to the receive buffer. */ uint8_t *get_received_buffer(); /** * \brief Get transmit buffer. * \param none * \return Pointer to the transmit buffer. */ uint8_t *get_transmit_buffer(); /** * \brief Get number of free buffers. * \param none * \return * Number of free buffers. */ uint16_t get_number_free_buffers(); /** * \brief Set number of free buffers. * \param value Number of free buffers. * \return none */ void set_number_free_buffers(uint16_t value); /** * \brief Retrieve buffer length. * \param none * \return Buffer length */ uint16_t get_buffer_length(); /** * \brief Set buffer length * \param value The length * \return none */ void set_buffer_length(uint16_t value); /** * \brief Retrieve pending data flag. * \param none * \return Pending data flag */ uint16_t get_pending_data(); /** * \brief Set pending data flag. * \param value Pending data value. * \return none */ void set_pending_data(uint16_t value); /** * \brief Retreive op code. * \param none * \return Op code */ uint16_t get_op_code(); /** * \brief Set op code. * \param code op code. * \return none */ void set_op_code(uint16_t code); /** * \brief Get number of released packets. * \param none * \return Number of released packets. */ uint16_t get_released_packets(); /** * \brief Set number of released packets. * \param value Number of released packets. * \return none */ void set_number_of_released_packets(uint16_t value); /** * \brief Get number of sent packats * \param none * \return Number of sent packets. */ uint16_t get_sent_packets(); /** * \brief Set number of sent packets * \param value Number of sent packets. * \return none */ void set_sent_packets(uint16_t value); /** * \brief Retrieve transmit error * \param none * \return Transmit error */ int32_t get_transmit_error(); /** * \brief Set transmit error. * \param value Error to be set. * \return none */ void set_transmit_error(int32_t value); /** * \brief Get buffer size. * \param none * \return Size of buffer. */ uint16_t get_buffer_size(); /** * \brief Set buffer size. * \param value Buffer size. * \return none */ void set_buffer_size(uint16_t value); /** * \brief Not used currently. * \param function Number of desired function. * \return void pointer to the function (need to recast). */ void *get_func_pointer(FunctionNumber function); /** * \brief Retreive pointer to the received data. * \param none * \return Pointer to the received data buffer. */ uint8_t *get_received_data(); /** * \brief Set received data pointer. * \param pointer Pointer to the buffer. * \return none */ 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: /* Not used currently */ 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; /** Event layer */ class cc3000_event { public: /** * \brief * \param simplelink Reference to simple link object. * \param hci Reference to hci object. * \param spi Reference to spi object. * \param cc3000 Reference to cc3000 object. * \return none */ cc3000_event(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_spi &spi, cc3000 &cc3000); /** * \brief Ctor * \param none * \return none */ ~cc3000_event(); /** * \brief Handle unsolicited event from type patch request. * \param event_hdr event header * \return none */ void hci_unsol_handle_patch_request(uint8_t *event_hdr); /** * \brief Parse the incoming event packets and issue corresponding event handler from global array of handlers pointers. * \param ret_param incoming data buffer * \param from from information (in case of data received) * \param fromlen from information length (in case of data received) * \return none */ uint8_t *hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen); /** * \brief Handle unsolicited events. * \param event_hdr Event header * \return 1 if event supported and handled * \return 0 if event is not supported */ int32_t hci_unsol_event_handler(uint8_t *event_hdr); /** * \brief Parse the incoming unsolicited event packets and start corresponding event handler. * \param None * \return ESUCCESS if successful, EFAIL if an error occurred. */ int32_t hci_unsolicited_event_handler(void); /** * \brief Get the socket status. * \param Sd Socket IS * \return Current status of the socket. */ int32_t get_socket_active_status(int32_t sd); /** * \brief Check if the socket ID and status are valid and set the global socket status accordingly. * \param Sd Sock descr * \param Status status to be set * \return none */ void set_socket_active_status(int32_t sd, int32_t status); /** * \brief Keep track on the number of packets transmitted and update the number of free buffer in the SL device. * \brief Called when unsolicited event = HCI_EVNT_DATA_UNSOL_FREE_BUFF has received. * \param event pointer to the string contains parameters for IPERF. * \return ESUCCESS if successful, EFAIL if an error occurred. */ int32_t hci_event_unsol_flowcontrol_handler(uint8_t *event); /** * \brief Update the socket status. * \param resp_params Socket IS * \return Current status of the socket. */ void update_socket_active_status(uint8_t *resp_params); /** * \brief Wait for event, pass it to the hci_event_handler and update the event opcode in a global variable. * \param op_code Command operation code * \param ret_param Command return parameters * \return none */ void simplelink_wait_event(uint16_t op_code, void *ret_param); /** * \brief Wait for data, pass it to the hci_event_handler and set the data available flag. * \param buffer Data buffer * \param from From information * \param fromlen From information length * \return none */ void simplelink_wait_data(uint8_t *buffer, uint8_t *from, uint8_t *fromlen); /** * \brief Trigger Received event/data processing - called from the SPI library to receive the data * \param buffer pointer to the received data buffer\n * The function triggers Received event/data processing\n * \return none */ 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; }; /** Netapp layer */ class cc3000_netapp { public: /** * \brief Ctor * \param simple_link Reference to the simple link object. * \param nvmem Reference to the nvmem object. * \param hci Reference to the hci object. * \param event Reference to the event object. * \return none */ cc3000_netapp(cc3000_simple_link &simple_link, cc3000_nvmem &nvmem, cc3000_hci &hci, cc3000_event &event); /** * \brief Dtor * \param none * \return none */ ~cc3000_netapp(); /** * \brief Configure device MAC address and store it in NVMEM. * The value of the MAC address configured through the API will be\n * stored in CC3000 non volatile memory, thus preserved over resets.\n * \param mac device mac address, 6 bytes. Saved: yes * \return return on success 0, otherwise error. */ int32_t config_mac_adrress(uint8_t *mac); /** * \brief Configure the network interface, static or dynamic (DHCP). * In order to activate DHCP mode, ip, subnet_mask, default_gateway must be 0.\n * The default mode of CC3000 is DHCP mode. The configuration is saved in non volatile memory\n * and thus preserved over resets.\n * \param ip device mac address, 6 bytes. Saved: yes * \param subnet_mask device mac address, 6 bytes. Saved: yes * \param default_gateway device mac address, 6 bytes. Saved: yes * \param dns_server device mac address, 6 bytes. Saved: yes * \return 0 on success, otherwise error. * \note If the mode is altered, a reset of CC3000 device is required to apply the changes.\n * Also note that an asynchronous event of type 'DHCP_EVENT' is generated only when\n * a connection to the AP was established. This event is generated when an IP address\n * is allocated either by the DHCP server or by static allocation.\n */ int32_t dhcp(uint32_t *ip, uint32_t *subnet_mask,uint32_t *default_gateway, uint32_t *dns_server); #ifndef CC3000_TINY_DRIVER /** * \brief Get the CC3000 Network interface information. * This information is only available after establishing a WLAN connection.\n * Undefined values are returned when this function is called before association.\n * \param ipconfig pointer to a tNetappIpconfigRetArgs structure for storing the network interface configuration.\n * tNetappIpconfigRetArgs: aucIP - ip address,\n * aucSubnetMask - mask * aucDefaultGateway - default gateway address\n * aucDHCPServer - dhcp server address\n * aucDNSServer - dns server address\n * uaMacAddr - mac address\n * uaSSID - connected AP ssid\n * \return none * \note This function is useful for figuring out the IP Configuration of\n * the device when DHCP is used and for figuring out the SSID of\n * the Wireless network the device is associated with.\n */ void ipconfig(tNetappIpconfigRetArgs *ipconfig); /** * \brief Set new timeout values for DHCP lease timeout, ARP refresh timeout, keepalive event timeout and socket inactivity timeout * \param dhcp DHCP lease time request, also impact\n * the DHCP renew timeout.\n * Range: [0-0xffffffff] seconds,\n * 0 or 0xffffffff = infinite lease timeout.\n * Resolution: 10 seconds.\n * Influence: only after reconnecting to the AP. \n * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds.\n * The parameter is saved into the CC3000 NVMEM.\n * The default value on CC3000 is 14400 seconds.\n * * \param arp ARP refresh timeout, if ARP entry is not updated by\n * incoming packet, the ARP entry will be deleted by\n * the end of the timeout. \n * Range: [0-0xffffffff] seconds, 0 = infinite ARP timeout\n * Resolution: 10 seconds.\n * Influence: at runtime.\n * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 seconds\n * The parameter is saved into the CC3000 NVMEM.\n * The default value on CC3000 is 3600 seconds.\n * * \param keep_alive Keepalive event sent by the end of keepalive timeout\n * Range: [0-0xffffffff] seconds, 0 == infinite timeout\n * Resolution: 10 seconds.\n * Influence: at runtime.\n * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec\n * The parameter is saved into the CC3000 NVMEM. \n * The default value on CC3000 is 10 seconds.\n * * \param inactivity Socket inactivity timeout, socket timeout is\n * refreshed by incoming or outgoing packet, by the\n * end of the socket timeout the socket will be closed\n * Range: [0-0xffffffff] sec, 0 == infinite timeout.\n * Resolution: 10 seconds.\n * Influence: at runtime.\n * Minimal bound value: MIN_TIMER_VAL_SECONDS - 20 sec\n * The parameter is saved into the CC3000 NVMEM.\n * The default value on CC3000 is 60 seconds.\n * * \return 0 on success,otherwise error. * * \note A parameter set to a non zero value less than 20s automatically changes to 20s. */ int32_t timeout_values(uint32_t *dhcp, uint32_t *arp,uint32_t *keep_alive, uint32_t *inactivity); /** * \brief send ICMP ECHO_REQUEST to network hosts * \param ip destination IP address * \param ping_attempts number of echo requests to send * \param ping_size send buffer size which may be up to 1400 bytes * \param ping_timeout Time to wait for a response,in milliseconds. * \return 0 on success, otherwise error. * * \note A succesful operation will generate an asynchronous ping report event.\n * The report structure is defined by structure netapp_pingreport_args_t.\n * \warning Calling this function while a Ping Request is in progress will kill the ping request in progress. */ int32_t ping_send(uint32_t *ip, uint32_t ping_attempts, uint32_t ping_size, uint32_t ping_timeout); /** * \brief Ping status request. * This API triggers the CC3000 to send asynchronous events: HCI_EVNT_WLAN_ASYNC_PING_REPORT.\n * This event will create the report structure in netapp_pingreport_args_t.\n * This structure is filled with ping results until the API is triggered.\n * netapp_pingreport_args_t: packets_sent - echo sent\n * packets_received - echo reply\n * min_round_time - minimum round time\n * max_round_time - max round time\n * avg_round_time - average round time\n * * \param none * \return none * \note When a ping operation is not active, the returned structure fields are 0. */ void ping_report(); /** * \brief Stop any ping request. * \param none * \return 0 on success * -1 on error */ int32_t ping_stop(); /** * \brief Flush ARP table * \param none * \return none */ 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 /** Security class used only if encrypted smart config is set */ class cc3000_security { public: /** * \brief Expand a 16 bytes key for AES128 implementation. * \param expanded_key expanded AES128 key * \param key AES128 key - 16 bytes * \return none */ void expandKey(uint8_t *expanded_key, uint8_t *key); /** * \brief multiply by 2 in the galois field. * \param value Argument to multiply * \return multiplied argument */ uint8_t galois_mul2(uint8_t value); /** * \brief internal implementation of AES128 encryption. * straight forward aes encryption implementation\n * first the group of operations * - addRoundKey * - subbytes * - shiftrows * - mixcolums\n * * is executed 9 times, after this addroundkey to finish the 9th\n * round, after that the 10th round without mixcolums\n * no further subfunctions to save cycles for function calls\n * no structuring with "for (....)" to save cycles.\n * \param[in] expanded_key expanded AES128 key * \param[in/out] state 16 bytes of plain text and cipher text * \return none */ void aes_encr(uint8_t *state, uint8_t *expanded_key); /** * \brief internal implementation of AES128 decryption. * straightforward aes decryption implementation\n * the order of substeps is the exact reverse of decryption\n * inverse functions: * - addRoundKey is its own inverse * - rsbox is inverse of sbox * - rightshift instead of leftshift * - invMixColumns = barreto + mixColumns\n * * no further subfunctions to save cycles for function calls\n * no structuring with "for (....)" to save cycles\n * \param[in] expanded_key expanded AES128 key * \param[in\out] state 16 bytes of cipher text and plain text * \return none */ void aes_decr(uint8_t *state, uint8_t *expanded_key); /** * \brief AES128 encryption. * Given AES128 key and 16 bytes plain text, cipher text of 16 bytes is computed.\n * The AES implementation is in mode ECB (Electronic Code Book).\n * \param[in] key AES128 key of size 16 bytes * \param[in\out] state 16 bytes of plain text and cipher text * \return none */ void aes_encrypt(uint8_t *state, uint8_t *key); /** * \brief AES128 decryption. * Given AES128 key and 16 bytes cipher text, plain text of 16 bytes is computed.\n * The AES implementation is in mode ECB (Electronic Code Book).\n * \param[in] key AES128 key of size 16 bytes * \param[in\out] state 16 bytes of cipher text and plain text * \return none */ void aes_decrypt(uint8_t *state, uint8_t *key); /** * \brief Read the AES128 key from fileID #12 in EEPROM. * \param[out] key AES128 key of size 16 bytes * \return 0 on success, error otherwise. */ int32_t aes_read_key(uint8_t *key); /** * \brief Write the AES128 key to fileID #12 in EEPROM. * \param[out] key AES128 key of size 16 bytes * \return on success 0, error otherwise. */ int32_t aes_write_key(uint8_t *key); private: uint8_t _expanded_key[176]; }; #endif /** Socket layer */ class cc3000_socket { public: /** * \brief Ctor * \param simplelink Reference to simple link object. * \param hci Reference to hci object. * \param event Reference to event object. * \return none */ cc3000_socket(cc3000_simple_link &simplelink, cc3000_hci &hci, cc3000_event &event); /** * \brief Dtor * \param * \return none */ ~cc3000_socket(); /** * \brief create an endpoint for communication. * The socket function creates a socket that is bound to a specific transport service provider.\n * This function is called by the application layer to obtain a socket handle.\n * * \param domain selects the protocol family which will be used for\n * communication. On this version only AF_INET is supported\n * \param type specifies the communication semantics. On this version\n * only SOCK_STREAM, SOCK_DGRAM, SOCK_RAW are supported\n * \param protocol specifies a particular protocol to be used with the\n * socket IPPROTO_TCP, IPPROTO_UDP or IPPROTO_RAW are supported.\n * \return On success, socket handle that is used for consequent socket operations\n * On error, -1 is returned.\n */ int32_t socket(int32_t domain, int32_t type, int32_t protocol); /** * \brief accept a connection on a socket. * This function is used with connection-based socket types\n * (SOCK_STREAM). It extracts the first connection request on the\n * queue of pending connections, creates a new connected socket, and\n * returns a new file descriptor referring to that socket.\n * The newly created socket is not in the listening state.\n * The original socket sd is unaffected by this call.\n * The argument sd is a socket that has been created with socket(),\n * bound to a local address with bind(), and is listening for \n * connections after a listen(). The argument addr is a pointer \n * to a sockaddr structure. This structure is filled in with the \n * address of the peer socket, as known to the communications layer.\n * The exact format of the address returned addr is determined by the \n * socket's address family. The addrlen argument is a value-result\n * argument: it should initially contain the size of the structure\n * pointed to by addr, on return it will contain the actual\n * length (in bytes) of the address returned.\n * * \param[in] sd socket descriptor (handle)\n * \param[out] addr the argument addr is a pointer to a sockaddr structure\n * This structure is filled in with the address of the \n * peer socket, as known to the communications layer. \n * determined. The exact format of the address returned \n * addr is by the socket's address sockaddr. \n * On this version only AF_INET is supported.\n * This argument returns in network order.\n * \param[out] addrlen the addrlen argument is a value-result argument: \n * it should initially contain the size of the structure\n * pointed to by addr.\n * \return For socket in blocking mode:\n * - On success, socket handle. on failure negative\n * For socket in non-blocking mode:\n * - On connection establishment, socket handle\n * - On connection pending, SOC_IN_PROGRESS (-2)\n * - On failure, SOC_ERROR (-1)\n * \sa socket ; bind ; listen */ int32_t accept(int32_t sd, sockaddr *addr, socklen_t *addrlen); /** * \brief assign a name to a socket. * This function gives the socket the local address addr.\n * addr is addrlen bytes long. Traditionally, this is called when a \n * socket is created with socket, it exists in a name space (address \n * family) but has no name assigned.\n * It is necessary to assign a local address before a SOCK_STREAM\n * socket may receive connections.\n * * \param[in] sd socket descriptor (handle) * \param[out] addr specifies the destination address. On this version\n * only AF_INET is supported.\n * \param[out] addrlen contains the size of the structure pointed to by addr.\n * \return On success, zero is returned.\n * On error, -1 is returned.\n * \sa socket ; accept ; listen */ int32_t bind(int32_t sd, const sockaddr *addr, int32_t addrlen); /** * \brief HostFlowControlConsumeBuff. * if SEND_NON_BLOCKING is not defined - block until a free buffer is available,\n * otherwise return the status of the available buffers.\n * * \param sd socket descriptor * \return 0 in case there are buffers available, \n * -1 in case of bad socket\n * -2 if there are no free buffers present (only when SEND_NON_BLOCKING is enabled)\n */ int32_t HostFlowControlConsumeBuff(int32_t sd); /** * \brief The socket function closes a created socket. * \param sd socket handle. * \return On success, zero is returned. On error, -1 is returned. */ int32_t closesocket(int32_t sd); /** * \brief listen for connections on a socket. * The willingness to accept incoming connections and a queue\n * limit for incoming connections are specified with listen(),\n * and then the connections are accepted with accept.\n * The listen() call applies only to sockets of type SOCK_STREAM\n * The backlog parameter defines the maximum length the queue of\n * pending connections may grow to. \n * * \param[in] sd socket descriptor (handle) * \param[in] backlog specifies the listen queue depth. On this version\n * backlog is not supported.\n * \return On success, zero is returned.\n * On error, -1 is returned.\n * \sa socket ; accept ; bind * \note On this version, backlog is not supported */ int32_t listen(int32_t sd, int32_t backlog); /** * \brief initiate a connection on a socket. * Function connects the socket referred to by the socket descriptor\n * sd, to the address specified by addr. The addrlen argument \n * specifies the size of addr. The format of the address in addr is \n * determined by the address space of the socket. If it is of type \n * SOCK_DGRAM, this call specifies the peer with which the socket is \n * to be associated; this address is that to which datagrams are to be\n * sent, and the only address from which datagrams are to be received. \n * If the socket is of type SOCK_STREAM, this call attempts to make a \n * connection to another socket. The other socket is specified by \n * address, which is an address in the communications space of the\n * socket. Note that the function implements only blocking behavior \n * thus the caller will be waiting either for the connection \n * establishment or for the connection establishment failure.\n * * \param[in] sd socket descriptor (handle) * \param[in] addr specifies the destination addr. On this version\n * only AF_INET is supported.\n * \param[out] addrlen contains the size of the structure pointed to by addr * \return On success, zero is returned.\n On error, -1 is returned\n * \sa socket */ int32_t connect(int32_t sd, const sockaddr *addr, int32_t addrlen); /** * \brief Monitor socket activity. * Select allow a program to monitor multiple file descriptors,\n * waiting until one or more of the file descriptors become \n * "ready" for some class of I/O operation \n * * \param[in] nfds the highest-numbered file descriptor in any of the\n * three sets, plus 1. \n * \param[out] readsds socket descriptors list for read monitoring\n * \param[out] writesds socket descriptors list for write monitoring\n * \param[out] exceptsds socket descriptors list for exception monitoring\n * \param[in] timeout is an upper bound on the amount of time elapsed\n * before select() returns. Null means infinity \n * timeout. The minimum timeout is 5 milliseconds,\n * less than 5 milliseconds will be set\n * automatically to 5 milliseconds.\n * \return On success, select() returns the number of file descriptors\n * contained in the three returned descriptor sets (that is, the\n * total number of bits that are set in readfds, writefds,\n * exceptfds) which may be zero if the timeout expires before\n * anything interesting happens.\n * On error, -1 is returned.\n * *readsds - return the sockets on which Read request will\n * return without delay with valid data.\n * *writesds - return the sockets on which Write request \n * will return without delay.\n * *exceptsds - return the sockets which closed recently.\n * \Note If the timeout value set to less than 5ms it will automatically\n * change to 5ms to prevent overload of the system\n * \sa socket */ int32_t select(int32_t nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout); /** * \brief get socket options. * This function manipulate the options associated with a socket.\n * Options may exist at multiple protocol levels; they are always\n * present at the uppermost socket level.\n * When manipulating socket options the level at which the option \n * resides and the name of the option must be specified. \n * To manipulate options at the socket level, level is specified as \n * SOL_SOCKET. To manipulate options at any other level the protocol \n * number of the appropriate protocol controlling the option is \n * supplied. For example, to indicate that an option is to be \n * interpreted by the TCP protocol, level should be set to the \n * protocol number of TCP; \n * The parameters optval and optlen are used to access optval -\n * use for setsockopt(). For getsockopt() they identify a buffer\n * in which the value for the requested option(s) are to \n * be returned. For getsockopt(), optlen is a value-result \n * parameter, initially containing the size of the buffer \n * pointed to by option_value, and modified on return to \n * indicate the actual size of the value returned. If no option \n * value is to be supplied or returned, option_value may be NULL.\n * * \param[in] sd socket handle * \param[in] level defines the protocol level for this option * \param[in] optname defines the option name to Interrogate * \param[out] optval specifies a value for the option * \param[out] optlen specifies the length of the option value * \return On success, zero is returned. On error, -1 is returned * * \Note On this version the following two socket options are enabled:\n * The only protocol level supported in this version is SOL_SOCKET (level).\n * 1. SOCKOPT_RECV_TIMEOUT (optname)\n * SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout in milliseconds.\n * In that case optval should be pointer to unsigned long.\n * 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on or off.\n * In that case optval should be SOCK_ON or SOCK_OFF (optval).\n * \sa setsockopt */ int32_t getsockopt (int32_t sd, int32_t level, int32_t optname, void *optval, socklen_t *optlen); /** * \brief Read data from socket (simple_link_recv). * Return the length of the message on successful completion.\n * If a message is too long to fit in the supplied buffer, excess bytes may\n * be discarded depending on the type of socket the message is received from.\n * * \param sd socket handle * \param buf read buffer * \param len buffer length * \param flags indicates blocking or non-blocking operation * \param from pointer to an address structure indicating source address * \param fromlen source address structure size * \return Return the number of bytes received, or -1 if an error occurred */ int32_t simple_link_recv(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen, int32_t opcode); /** * \brief Transmit a message to another socket (simple_link_send). * \param sd socket handle * \param buf write buffer * \param len buffer length * \param flags On this version, this parameter is not supported * \param to pointer to an address structure indicating destination address * \param tolen destination address structure size * \return Return the number of bytes transmitted, or -1 if an error\n * occurred, or -2 in case there are no free buffers available\n * (only when SEND_NON_BLOCKING is enabled)\n */ 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); /** * \brief Receive a message from a connection-mode socket. * \param[in] sd socket handle * \param[out] buf Points to the buffer where the message should be stored * \param[in] len Specifies the length in bytes of the buffer pointed to \n * by the buffer argument.\n * \param[in] flags Specifies the type of message reception. \n * On this version, this parameter is not supported.\n * \return Return the number of bytes received, or -1 if an error occurred * \sa recvfrom * \Note On this version, only blocking mode is supported. */ int32_t recv(int32_t sd, void *buf, int32_t len, int32_t flags); /** * \brief read data from socket (recvfrom). * Receives a message from a connection-mode or connectionless-mode socket.\n * Note that raw sockets are not supported.\n * * \param[in] sd socket handle * \param[out] buf Points to the buffer where the message should be stored * \param[in] len Specifies the length in bytes of the buffer pointed to \n * by the buffer argument.\n * \param[in] flags Specifies the type of message reception.\n * On this version, this parameter is not supported.\n * \param[in] from pointer to an address structure indicating the source\n * address: sockaddr. On this version only AF_INET is\n * supported.\n * \param[in] fromlen source address structure size * \return Return the number of bytes received, or -1 if an error occurred * \sa recv * \Note On this version, only blocking mode is supported. */ int32_t recvfrom(int32_t sd, void *buf, int32_t len, int32_t flags, sockaddr *from, socklen_t *fromlen); /** * \brief Transmit a message to another socket (send). * \param sd socket handle * \param buf Points to a buffer containing the message to be sent * \param len message size in bytes * \param flags On this version, this parameter is not supported * \return Return the number of bytes transmitted, or -1 if an\n * error occurred\n * \Note On this version, only blocking mode is supported. * \sa sendto */ int32_t send(int32_t sd, const void *buf, int32_t len, int32_t flags); /** * \brief Transmit a message to another socket (sendto). * \param sd socket handle * \param buf Points to a buffer containing the message to be sent * \param len message size in bytes * \param flags On this version, this parameter is not supported * \param to pointer to an address structure indicating the destination\n * address: sockaddr. On this version only AF_INET is\n * supported.\n * \param tolen destination address structure size * \return Return the number of bytes transmitted, or -1 if an error occurred * \Note On this version, only blocking mode is supported. * \sa send */ int32_t sendto(int32_t sd, const void *buf, int32_t len, int32_t flags, const sockaddr *to, socklen_t tolen); /** * \brief Set CC3000 in mDNS advertiser mode in order to advertise itself. * \param[in] mdns_enabled flag to enable/disable the mDNS feature * \param[in] device_service_name Service name as part of the published\n * canonical domain name\n * \param[in] device_service_name_length Length of the service name * \return On success, zero is returned,\n * return SOC_ERROR if socket was not opened successfully, or if an error occurred.\n */ int32_t mdns_advertiser(uint16_t mdns_enabled, uint8_t * device_service_name, uint16_t device_service_name_length); #ifndef CC3000_TINY_DRIVER /** * \brief Get host IP by name.\n * Obtain the IP Address of machine on network\n * * \param[in] hostname host name * \param[in] name_length name length * \param[out] out_ip_addr This parameter is filled in with host IP address.\n * In case that host name is not resolved, \n * out_ip_addr is zero.\n * \return On success, positive is returned.\n * On error, negative is returned by its name.\n * \note On this version, only blocking mode is supported. Also note that\n * The function requires DNS server to be configured prior to its usage.\n */ int32_t gethostbyname(uint8_t *hostname, uint16_t name_length, uint32_t *out_ip_addr); /** * \brief set socket options. * This function manipulate the options associated with a socket.\n * Options may exist at multiple protocol levels; they are always\n * present at the uppermost socket level.\n * When manipulating socket options the level at which the option \n * resides and the name of the option must be specified.\n * To manipulate options at the socket level, level is specified as\n * SOL_SOCKET. To manipulate options at any other level the protocol \n * number of the appropriate protocol controlling the option is \n * supplied. For example, to indicate that an option is to be \n * interpreted by the TCP protocol, level should be set to the \n * protocol number of TCP; \n * The parameters optval and optlen are used to access optval - \n * use for setsockopt(). For getsockopt() they identify a buffer\n * in which the value for the requested option(s) are to \n * be returned. For getsockopt(), optlen is a value-result \n * parameter, initially containing the size of the buffer \n * pointed to by option_value, and modified on return to \n * indicate the actual size of the value returned. If no option \n * value is to be supplied or returned, option_value may be NULL.\n * * \param[in] sd socket handle * \param[in] level defines the protocol level for this option * \param[in] optname defines the option name to Interrogate * \param[in] optval specifies a value for the option * \param[in] optlen specifies the length of the option value * \return On success, zero is returned.\n * On error, -1 is returned\n * * \Note On this version the following two socket options are enabled:\n * The only protocol level supported in this version is SOL_SOCKET (level).\n * 1. SOCKOPT_RECV_TIMEOUT (optname)\n * SOCKOPT_RECV_TIMEOUT configures recv and recvfrom timeout in milliseconds.\n * In that case optval should be pointer to unsigned long.\n * 2. SOCKOPT_NONBLOCK (optname). sets the socket non-blocking mode on or off.\n * In that case optval should be SOCK_ON or SOCK_OFF (optval).\n * \sa getsockopt */ 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 layer */ class cc3000_spi { public: /** * \brief Ctor * \param irq IRQ pin * \param cc3000_en Enable pin * \param cc3000_cs Chip select pin * \param cc3000_spi SPI object * \param irq_port Port for IRQ pin (needed for enable/disable interrupts) * \param event Reference to the event object. * \param simple_link Reference to the simple link object. * \return none */ 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); /** * \brief Dtor * \param none * \return none */ ~cc3000_spi(); /** * \brief Close SPI - disables IRQ and set received buffer to 0 * \param none * \return none */ void close(); /** * \brief Open the SPI interface * \param none * \return none */ void open(); /** * \brief First SPI write after powerup (delay needed between SPI header and body) * \param buffer pointer to write buffer * \param length buffer length * \return 0 */ uint32_t first_write(uint8_t *buffer, uint16_t length); /** * \brief SPI Write function * \param buffer pointer to write buffer * \param length buffer length * \return 0 */ uint32_t write(uint8_t *buffer, uint16_t length); /** * \brief Low level SPI write * \param data pointer to data buffer * \param size number of bytes * \return none */ void write_synchronous(uint8_t *data, uint16_t size); /** * \brief Low level SPI read * \param data pointer to data buffer * \param size number of bytes * \return none */ void read_synchronous(uint8_t *data, uint16_t size); /** * \brief Process the received SPI Header and in accordance with it - continue reading the packet * \param None * \return 0 */ uint32_t read_data_cont(); /** * \brief Enable WLAN interrutp * \param None * \return None */ void wlan_irq_enable(); /** * \brief Disable WLAN interrutp * \param None * \return None */ void wlan_irq_disable(); /** * \brief Get WLAN interrupt status * \param None * \return 0 : No interrupt occured * 1 : Interrupt occured */ uint32_t wlan_irq_read(); /** * \brief SPI interrupt Handler. * The external WLAN device asserts the IRQ line when data is ready.\n * The host CPU needs to acknowledges the IRQ by asserting CS.\n * * \param none * \return none */ void WLAN_IRQHandler(); /** * \brief Enable/Disable the WLAN module * \param value 1 : Enable * 0 : Disable * \return None */ void set_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; }; /** HCI layer */ class cc3000_hci { public: /** * \brief Ctor * \param spi Reference to the spi object. * \return none */ cc3000_hci(cc3000_spi &spi); /** * \brief Dtor * \param none * \return none */ ~cc3000_hci(); /** * \brief Initiate an HCI command. * \param op_code command operation code * \param buffer pointer to the command's arguments buffer * \param length length of the arguments * \return 0 */ uint16_t command_send(uint16_t op_code, uint8_t *buffer, uint8_t length); /** * \brief Initiate an HCI data write operation * \param op_code command operation code * \param args pointer to the command's arguments buffer * \param arg_length length of the arguments * \param data_length length od data * \param tail pointer to the data buffer * \param tail_length buffer length * \return ESUCCESS */ 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); /** * \brief Prepare HCI header and initiate an HCI data write operation. * \param op_code command operation code * \param buffer pointer to the data buffer * \param arg_length arguments length * \param data_length data length * \return none */ void data_command_send(uint16_t op_code, uint8_t *buffer, uint8_t arg_length, uint16_t data_length); /** * \brief Prepare HCI header and initiate an HCI patch write operation. * \param op_code command operation code * \param buffer pointer to the command's arguments buffer * \param patch pointer to patch content buffer * \param data_length data length * \return none */ void patch_send(uint8_t op_code, uint8_t *buffer, uint8_t *patch, uint16_t data_length); private: cc3000_spi &_spi; }; /** NVMEM layer */ class cc3000_nvmem { public: /** * \brief Ctor * \param hci Reference to the hci object. * \param event Reference to the event object. * \param simple_link Reference to the simple link object. * \return none */ cc3000_nvmem(cc3000_hci &hci, cc3000_event &event, cc3000_simple_link &simple_link); /** * \brief Dtor * \param none * \return none */ ~cc3000_nvmem(); /** * \brief Reads data from the file referred by the file_id parameter. * Reads data from file offset till length. Err if the file can't be used, * is invalid, or if the read is out of bounds. * \param file_id nvmem file id. * \param length number of bytes to read. * \param offset offset in file from where to read. * \param buff output buffer pointer. * \return * Number of bytes read, otherwise error. */ int32_t read(uint32_t file_id, uint32_t length, uint32_t offset, uint8_t *buff); /** * \brief Write data to nvmem. * \param file_id Nvmem file id * \param length number of bytes to write * \param entry_offset offset in file to start write operation from * \param buff data to write * \return * On success 0, error otherwise. */ int32_t write(uint32_t file_id, uint32_t length, uint32_t entry_offset, uint8_t *buff); /** * \brief Write MAC address to EEPROM. * \param mac Mac address to be set * \return * On success 0, error otherwise. */ uint8_t set_mac_address(uint8_t *mac); /** * \brief Read MAC address from EEPROM. * \param mac Mac address * \return * On success 0, error otherwise. */ uint8_t get_mac_address(uint8_t *mac); /** * \brief Program a patch to a specific file ID. The SP data is assumed to be organized in 2-dimensional. * Each line is SP_PORTION_SIZE bytes long. * \param file_id nvmem file id/ * \param length number of bytes to write * \param data SP data to write * \return * On success 0, error otherwise. */ uint8_t write_patch(uint32_t file_id, uint32_t length, const uint8_t *data); /** * \brief Create new file entry and allocate space on the NVMEM. Applies only to user files. * \param file_id nvmem file Id * \param new_len entry ulLength * \return */ int32_t create_entry(uint32_t file_id, uint32_t new_len); #ifndef CC3000_TINY_DRIVER /** * \brief Read patch version. read package version (WiFi FW patch, river-supplicant-NS patch, * bootloader patch) * \param patch_ver First number indicates package ID and the second number indicates * package build number * \return * On success 0, error otherwise. */ uint8_t read_sp_version(uint8_t* patch_ver); #endif private: cc3000_hci &_hci; cc3000_event &_event; cc3000_simple_link &_simple_link; }; /** WLAN layer */ class cc3000_wlan { public: /** * \brief Ctor * \param simple_link Reference to the simple link object. * \param event Reference to the event object. * \param spi Reference to the spi object. * \param hci Reference to the hci object. * \return none */ cc3000_wlan(cc3000_simple_link &simple_link, cc3000_event &event, cc3000_spi &spi, cc3000_hci &hci); /** * \brief Dtor * \param none * \return none */ ~cc3000_wlan(); /** * \brief 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); /** * \brief 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); /** * \brief Stop wlan device * \param none * \return none */ void stop(void); #ifndef CC3000_TINY_DRIVER /** * \brief Connect to AP. * \param sec_type Security option. * \param ssid up to 32 bytes, ASCII SSID * \param ssid_length length of SSID * \param b_ssid 6 bytes specified the AP bssid * \param key up to 16 bytes specified the AP security key * \param key_len key length * \return * On success, zero is returned. On error, negative is returned. */ 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); /** * \brief Add profile. Up to 7 profiles are supported. * \param sec_type Security option. * \param ssid Up to 32 bytes, ASCII SSID * \param ssid_length Length of SSID * \param b_ssid 6 bytes specified the AP bssid * \param priority Up to 16 bytes specified the AP security key * \param pairwise_cipher_or_tx_key_len Key length * \param group_cipher_tx_key_index Key length for WEP security * \param key_mgmt KEY management * \param pf_or_key Security key * \param pass_phrase_length Security key length for WPA\WPA2 * \return * On success, zero is returned. On error, negative is returned. */ 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); /** * \brief Gets entry from scan result table. The scan results are returned * one by one, and each entry represents a single AP found in the area. * \param scan_timeout Not supported yet * \param results Scan result * \return * On success, zero is returned. On error, -1 is returned */ int32_t ioctl_get_scan_results(uint32_t scan_timeout, uint8_t *results); /** * \brief Start and stop scan procedure. Set scan parameters. * \param enable Start/stop application scan * \param min_dwell_time Minimum dwell time value to be used for each channel, in ms. (Default: 20) * \param max_dwell_time Maximum dwell time value to be used for each channel, in ms. (Default: 30) * \param num_probe_requests Max probe request between dwell time. (Default:2) * \param channel_mask Bitwise, up to 13 channels (0x1fff). * \param rssi_threshold RSSI threshold. Saved: yes (Default: -80) * \param snr_threshold NSR threshold. Saved: yes (Default: 0) * \param default_tx_power probe Tx power. Saved: yes (Default: 205) * \param interval_list Pointer to array with 16 entries (16 channels) * \return * On success, zero is returned. On error, -1 is returned. */ 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); /** * \brief Get wlan status: disconnected, scanning, connecting or connected * \param none * \return * WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING, STATUS_CONNECTING or WLAN_STATUS_CONNECTED */ int32_t ioctl_statusget(void); #else /** * \brief Connect to AP * \param ssid Up to 32 bytes and is ASCII SSID of the AP * \param ssid_length Length of the SSID * \return * On success, zero is returned. On error, negative is returned. */ int32_t connect(const uint8_t *ssid, int32_t ssid_length); /** * \brief When auto start is enabled, the device connects to station from the profiles table. * If several profiles configured the device choose the highest priority profile. * \param sec_type WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2 * \param ssid SSID up to 32 bytes * \param ssid_length SSID length * \param b_ssid bssid 6 bytes * \param priority Profile priority. Lowest priority:0. * \param pairwise_cipher_or_tx_key_len Key length for WEP security * \param group_cipher_tx_key_index Key index * \param key_mgmt KEY management * \param pf_or_key Security key * \param pass_phrase_length Security key length for WPA\WPA2 * \return * On success, zero is returned. On error, -1 is returned */ 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 /** * \brief Process the acquired data and store it as a profile. * \param none * \return * On success, zero is returned. On error, -1 is returned. */ int32_t smart_config_process(void); #endif /** * \brief Disconnect connection from AP. * \param none * \return * 0 if disconnected done, other CC3000 already disconnected. */ int32_t disconnect(); /** * \brief When auto is enabled, the device tries to connect according the following policy: * 1) If fast connect is enabled and last connection is valid, the device will try to * connect to it without the scanning procedure (fast). The last connection will be * marked as invalid, due to adding/removing profile. * 2) If profile exists, the device will try to connect it (Up to seven profiles). * 3) If fast and profiles are not found, and open mode is enabled, the device * will try to connect to any AP. * Note that the policy settings are stored in the CC3000 NVMEM. * \param should_connect_to_open_ap Enable(1), disable(0) connect to any available AP. * \param use_fast_connect Enable(1), disable(0). if enabled, tries to * connect to the last connected AP. * \param use_profiles Enable(1), disable(0) auto connect after reset. * and periodically reconnect if needed. * \return * On success, zero is returned. On error, -1 is returned */ int32_t ioctl_set_connection_policy(uint32_t should_connect_to_open_ap, uint32_t use_fast_connect, uint32_t use_profiles); /** * \brief Delete WLAN profile * \param index Number of profile to delete * \return * On success, zero is returned. On error, -1 is returned */ int32_t ioctl_del_profile(uint32_t index); /** * \brief Mask event according to bit mask. In case that event is * masked (1), the device will not send the masked event to host. * \param mask event mask * \return * On success, zero is returned. On error, -1 is returned */ int32_t set_event_mask(uint32_t mask); /** * \brief Start to acquire device profile. The device acquire its own * profile, if profile message is found. * \param encrypted_flag Indicates whether the information is encrypted * \return * On success, zero is returned. On error, -1 is returned. */ int32_t smart_config_start(uint32_t encrypted_flag); /** * \brief Stop the acquire profile procedure. * \param none * \return * On success, zero is returned. On error, -1 is returned */ int32_t smart_config_stop(void); /** * \brief Configure station ssid prefix. * \param new_prefix 3 bytes identify the SSID prefix for the Smart Config. * \return * On success, zero is returned. On error, -1 is returned. */ 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; }; /** The main object of cc3000 implementation */ class cc3000 { public: /** status structure */ 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; /** * \brief Ctor. * \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); /** * \brief Dtor. */ ~cc3000(); /** * \brief Initiate cc3000. It starts the wlan communication and deletes profiles. * \param patch Patch */ void start(uint8_t patch); /** * \brief Stops the wlan communication. */ void stop(); /** * \brief Restarts the wlan communication. */ void restart(uint8_t patch); /** * \brief Disconnect wlan device * */ bool disconnect(void); /** * \brief 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); /** * \brief 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); /** * \brief 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); /** * \brief 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); /** * \brief Status of the cc3000 connection. * \return true if it's connected, false otherwise. */ bool is_connected(); /** * \brief Status of DHCP. * \param none * \return true if DCHP is configured, false otherwise. */ bool is_dhcp_configured(); /** * \brief Status of smart confing completation. * \param none * \return smart config was set, false otherwise. */ bool is_smart_confing_completed(); /** * \brief Return the cc3000's mac address. * \param address Retreived mac address. * \return */ uint8_t get_mac_address(uint8_t address[6]); /** * \brief Set the cc3000's mac address. * \param address Mac address to be set. * \return */ uint8_t set_mac_address(uint8_t address[6]); /** * \brief 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); /** * \brief 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); /** * \brief 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 /** * \brief 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 /** * \brief Delete all stored profiles. * \param none * \return none */ void delete_profiles(void); /** * \brief Ping an ip address. * \param ip Destination IP address * \param attempts Number of attempts * \param timeout Time to wait for a response,in milliseconds. * \param size Send buffer size which may be up to 1400 bytes */ uint32_t ping(uint32_t ip, uint8_t attempts, uint16_t timeout, uint8_t size); /** * \brief Returns cc3000 instance. Used in Socket interface. * \param none * \return Pointer to cc3000 object */ 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