Kojto CC3000 Hostdriver With Mbed Socket interface

Dependents:   WiFiDip-KitchenSink WiFiDip-UsbKitchenSink WiFiDipCortexSensor WifiDipCortex-UDPDemo

Fork of cc3000_hostdriver_mbedsocket by Martin Kojtal

cc3000.h

Committer:
SolderSplashLabs
Date:
2013-10-03
Revision:
25:4d4072a9cc12
Parent:
24:ba3fa29197ac
Child:
26:456f73ed2a75

File content as of revision 25:4d4072a9cc12:

/*****************************************************************************
*
*  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
 */
 
// 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 color 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:
    /** 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