Port from Avnet's Internet Of Things full WiGo demo: SmartConfig - WebServer - Exosite - Android sensor Fusion App

Dependencies:   NVIC_set_all_priorities mbed cc3000_hostdriver_mbedsocket TEMT6200 TSI Wi-Go_eCompass_Lib_V3 WiGo_BattCharger

Wi-Go Reference Design Overview


For additional information on Wi-Go, please visit http://www.em.avnet.com/wi-go
For additional information on Freescale eCompass, please visit
http://www.freescale.com/webapp/sps/site/prod_summary.jsp?code=E-Compass
Ported from Avnet's Wi-Go KEIL code.
Special thanks to Jim Carver from Avnet for providing the Wi-Go board and for his assistance.


Multiple Wi-Fi applications are provided within the latest version of Wi-Go software:

  • SmartConfig App for auto-setup of Wi-Go network parameters.
  • WebServer display of live sensor data.
  • Exosite portal sensor data feed by Wi-Go.
  • Freescale's Sensor Fusion App data feed by Wi-Go.

Wi-Go is intended for "untethered" portable operation (using it's high-capacity Lithium-Polymer battery). The serial terminal text interface is only required for initial setup, thereafter selection of an application from those available is via finger position on the Touch Slider during the initial 6 second startup period.

Running the Wi-Go Demo Suite

Warning

The on-board Firmware must be updated to mbed enable a Wi-Go system.
Goto the Component page to get the FirmwareUpdate tool (scroll down to the FirmwareUpdate topic).

MAG3110 sensor and eCompass Calibration!

As with the other sensor applications, the eCompass function requires quality calibration data to achieve best accuracy.
For the first 15 seconds after power-up it is recommended that "Figure 8" movements with Wi-Go be done in a smooth, repetitive pattern. Don't touch the slider pad during calibration.

Startup
The RGB LED blinks in a GREEN-ORANGE sequence to inform the user the module is waiting for input.
The RGB LED color designates which of the following Apps to launch.

RGB LED ColorApplication to Launch
OrangeErase all wireless profiles
PurpleSmartConfig
BlueWebServer
RedExosite Data Client
GreenAndroid Server

Swipe your index finger across the slider pad, the RGB LED color will change at approximately 20% intervals.
Removing your finger latches the last color displayed. After about 3 seconds, the selected app will start.
Another app can be selected when the slider pad is touched again within the 3 seconds timeout.

After launch of Exosite or Android Server Apps, the eCompass function then controls the RGB LED.
(not in WebServer mode where RGB LEDs are manually controlled by the User).

RGB LED ColorDirection Indication
BlueNear to North
GreenNorth
RedEast / West
PurpleSouth

__Note!__ The D1, D2 and D3 User LEDs on Wi-Go adhere to the following convention for the different Apps

User LED#Description of function controlling the LED
D1is the board heartbeat, derived from the timer interrupt
D2indicates network activity as follows:
Web Server Wi-Go webpage is being served.
Exosite Client Wi-Go is sending data.
Android App Wi-Go is sending data
D3WLAN Network is Connected

Detail of Wi-Go Applications

App #1: SmartConfig
See TI's pages on how to use the SmartConfig tool:

  • Preferred method : Configuration using the SmartConfig tool
  • SmartConfig download: Smart Config and Home Automation
    • iOS app : available at Apple app store.
    • Android app : download and install the Android SmartConfig Application on a PC.
      This file contains the source code as well as the compiled APK file.
      The APK file is stored in ti\CC3000AndroidApp\SmartConfigCC3X\bin.

App #2: WebServer display of live sensor data
__Note!__
When using the WebServer for the first time on a Wi-Fi network you will need to determine the IP address that's assigned to Wi-Go by the DHCP Server. To do this, it is recommended you use one of the following two methods:

  • While Wi-Go is initially tethered to a laptop via USB, launch of the WebServer Application and note the IP address that is reported on the terminal screen immediately after selection of this App.
  • Alternatively, use a 3rd party LAN SCAN type tool to view Wi-Go's IP address.
    eg. FING, - available for free download from Google Play or iTunes App Stores…

Wi-Go's WebServer Application is selected as follows:

  • Press RESET, followed by the eCompass Calibration (mentioned at the top of this page).
    Then use index finger on slider to select the WebServer App (RGB LED = BLUE).
    At end of the 3 second selection period the WebServer App shall launch.
  • If you are tethered to a laptop and have a terminal open the Wi-Fi network connection confirmation will be seen, eg.

'*** Wi-Go board DHCP assigned IP Address = 192.168.43.102
  • Once you have noted Wi-Go's reported IP address, the USB cable may be disconnected and Wi-Go then used as intended, running on it's own battery power.
  • Use an Internet Browser on SmartPhone/Tablet/Laptop (connected to same Hot-Spot/Wireless Router subnet), to now connect to the noted Wi-Go IP address and view the WebServer output: /media/uploads/frankvnk/wi-go_webserver.png
  • the Webserver sensor data is auto-updated every 2 seconds a manual refresh (F5 on laptop).
  • In the event of an error, press refresh to regenerate the screen.
  • Use the mouse (or touch-screen) to exercise the RGB LED output.

App #3: Exosite Data Client
Wi-Go's sensor data gets transmitted via Wi-Fi to a cloud-based Exosite portal where the sensor measurements are displayed graphically on a "dashboard". Users can create unique customized dashboards using drag and drop GUI widgets from the library provided on the Exosite website.
__Note!__ For the Exosite application a "live" connection to the Internet is required !!!

  • Press RESET, followed by the eCompass Calibration (mentioned at the top of this page).
    Then use index finger on slider to select the Exosite Client App (RGB LED = RED)
  • On launching this App, note Wi-Go's MAC address displayed on your terminal
    (if not running a terminal use FING or other WLAN Scan tool to determine Wi-Go's MAC address) /media/uploads/frankvnk/mac_address.png
  • Using your computer's internet browser, go to avnet.exosite.com and sign-up for a free Avnet Trial Exosite Account: /media/uploads/frankvnk/avnet_trial_exosite.png
  • On the next screen, click on the Sign-Up Now button in the displayed Avnet Trial account option.
  • Complete the Account Info and Contact Info then click on Create Account (make sure to use a valid email address!).
  • Check for new incoming email from avnet.exosite.com to the address you provided and click on the link in this email to activate your new Exosite account.
  • Once activated, login using the email address and password that you chose in your registration. Your Exosite Portal and Dashboard should now display. The first time you log-in to your new account, the default Home dashboard will be displayed, pre-configured with two widgets. On the left is the Welcome widget for tips and information. On the right is the Device List widget.
    Dashboards are configurable, so at any time this default dashboard can be changed, widgets deleted and added (Clicking the upside-down triangle icon in a widget's Title bar will allow you to edit it).
  • Before going further with the Dashboard, you need to connect your Wi-Go device to your Exosite account. Do this by going to the left sidebar and selecting Devices followed by selecting the +Add Device link (on right of screen). /media/uploads/frankvnk/add_device.png
  • In the Setup screens that follow, enter the following
Select a supported deviceWi-Go
Enter device MAC Addressnn:nn:nn:nn:nn:nn [your Wi-Go's MAC address including colons]
Enter device Name[choose a descriptive name]
Enter device Location[description of your location]
  • Once completed, under Devices the name chosen for the added Wi-Go device should now be listed.
  • Click on this new Wi-Go device to examine (and edit if necessary) it's Device Information screen.
    /media/uploads/frankvnk/device_information.png
  • Click the CLOSE button to exit the Device Information screen.
  • On your Wi-Go kit now press RESET, followed by the eCompass Calibration (mentioned at the top of this page)
    and again select the Exosite Client App (RGB LED = RED) using your index finger.
  • Refresh your browser (press F5) a couple've times until the Active indicator changes to On (Green).
    /media/uploads/frankvnk/active_indicator.png
  • From the left sidebar click on Home and click on the recently named Wi-Go device which is located under the Device List.
    This will bring-up a default dashboard display similar to what's shown below.
    (Dashboards are typically accessed via the Dashboards menu entry). Check the dashboard is updating with live data by moving your Wi-Go Kit through different orientations.
    /media/uploads/frankvnk/dashboard.png
  • To create a custom dashboard, select Dashboards from the sidebar menu, followed by +Add Dashboard (on right side of Your Dashboards title bar). After completion of the initial configuration screen you will then be able to add Widgets to display the various Wi-Go data sources as well as pictures and text to support your application.
  • More guidance on the creation, editing and sharing of custom dashboards is available under the Exosite support pages

App #4: Android Sensor Fusion App

  • Press RESET, followed by the eCompass Calibration (mentioned at the top of this page)
    , then use index finger on slider to select the Android App (RGB LED = GREEN)
  • Freescale's ''Xtrinsic Sensor Fusion Toolbox'" will run on Android 3.0 or above phone or tablet. Free to download from Google Play, type Sensor fusion in the search box to find it. freescale.sensors.sfusion /media/uploads/frankvnk/sensor_fusion_toolbox.png
  • The Freescale App is well documented. To access the built-in documentation, press the NAV button at top of screen followed by Documentation from the scroll-down menu:
    /media/uploads/frankvnk/sensor_fusion_doc.png
  • Freescale's sensors site provides additional resources such as this overview: free-android-app-teaches-sensor-fusion-basics
  • Go to the Options Menu and select Preferences… /media/uploads/frankvnk/sensor_fusion_preferences.png
  • The following items need to be taken care of:
Enter WiGo's IP address
Enter the SSID (of the Hot-Spot or Wireless Access Point used by Wi-Go)
  • Press Save and Exit!
    /media/uploads/frankvnk/sensor_fusion_save_and_exit.png
  • Exit the Application completely then re-launch the Sensor Fusion Application.
  • Select the ''Source/Algorithm'" menu and change the data source to Wi-Go mag/accel /media/uploads/frankvnk/sensor_fusion_wigo_mag_accel.png
  • The Android App should now be displaying a 3-D image of Wi-Go that you can rotate and flip-over by moving the Wi-Go board accordingly…
  • Use NAV > Device View to display if this view does not come-up by default. /media/uploads/frankvnk/sensor_fusion_nav_device_view.png
  • A Serial Terminal connection is not necessary but if you happen to have one open you should see the following messages as Wi-Go connects to the Android App:
    "Server waiting for connection" followed by
    "connected, transmit buffer size= 96", and then
    "input = 0123456789"
    at which time Wi-Go starts streaming data to the Android App.
Revision:
1:99bfc8d68fd3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cc3000_hostdriver_mbedsocket/cc3000.h	Wed Oct 23 12:01:30 2013 +0000
@@ -0,0 +1,1783 @@
+/*****************************************************************************
+*
+*  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
+// cc3000 Ethernet Interface - enabled by default
+#define CC3000_ETH_COMPAT   1
+
+/** Enable debug messages - set 1  */
+// Debug - Socket interface messages
+#define CC3000_DEBUG_SOCKET 0
+// Debug - HCI TX messages
+#define CC3000_DEBUG_HCI_TX 0
+// Debug - HCI Rx messages
+#define CC3000_DEBUG_HCI_RX 0
+// Debug - General Debug
+#define CC3000_DEBUG        0
+// Add colour to the debug messages, requires a VT100 terminal like putty, comment out to remove
+#define VT100_COLOUR        0
+
+#if (CC3000_DEBUG_SOCKET == 1)
+    #if (VT100_COLOUR == 1)
+        #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
+
+#if (CC3000_DEBUG_HCI_TX == 1)
+    #if (VT100_COLOUR == 1)
+        #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
+
+#if (CC3000_DEBUG_HCI_RX == 1)
+    #if (VT100_COLOUR == 1)
+        #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
+
+#if (CC3000_DEBUG == 1)
+    #if (VT100_COLOUR == 1)
+        #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);
+    /**
+     *  \brief
+     *  \param[in] s_addr in host format ( little endian )
+     *  \param[in] *buf     buffer to write too
+     *  \param[in] buflen   length of supplied buffer
+     *  \return    pointer to buf \n
+     */
+    char * inet_ntoa_r(uint32_t s_addr, char *buf, int buflen);
+#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;
+        bool    enabled;
+    } 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 Start connection to SSID (open/secured) non-blocking
+     *  \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_non_blocking(const uint8_t *ssid, const uint8_t *key, int32_t security_mode);
+    /**
+     *  \brief Connect to SSID (open/secured) with timeout (10s).
+     *  \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 module.
+     *  \return true if it's enabled, false otherwise.
+     */
+    bool is_enabled();
+    /**
+     *  \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;
+    }
+#if (CC3000_ETH_COMPAT == 1)
+    /**
+     *  \brief Get the MAC address of your Ethernet interface.
+     *  \param none
+     *  \return
+     *      Pointer to a string containing the MAC address.
+     */
+    char* getMACAddress();
+
+     /**
+     *  \brief Get the IP address of your Ethernet interface.
+     *  \param none
+     *  \return
+     *      Pointer to a string containing the IP address.
+     */
+    char* getIPAddress();
+
+     /**
+     *  \brief Get the Gateway address of your Ethernet interface
+     *  \param none
+     *  \return
+     *      Pointer to a string containing the Gateway address
+     */
+    char* getGateway();
+
+     /**
+     *  \brief Get the Network mask of your Ethernet interface
+     *  \param none
+     *  \return
+     *      Pointer to a string containing the Network mask
+     */
+    char* getNetworkMask();
+#endif
+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