Updated to use external spawn.

Fork of simplelink_V2 by David Fletcher

G_functions/fPtr_func.cpp

Committer:
dflet
Date:
2015-06-06
Revision:
0:1a07906111ec

File content as of revision 0:1a07906111ec:

/*
 *  - CC31xx/CC32xx Host Driver Implementation
 *
 * Copyright (C) 2014 Texas Instruments Incorporated - http://www.ti.com/
 *
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions
 *  are met:
 *
 *    Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *
 *    Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the
 *    distribution.
 *
 *    Neither the name of Texas Instruments Incorporated nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 *  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 *  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 *  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 *  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
*/

#include "simplelink_V2/cc3100_simplelink.h"

#include "simplelink_V2/cc3100.h"
#include "simplelink_V2/cc3100_driver.h"
#include "simplelink_V2/G_functions/fPtr_func.h"
#include "simplelink_V2/cc3100_nonos.h"
#include "cli_uart.h"

#include "cc3100_trace.h"
    
using namespace mbed_cc3100;    
    
cc3100 _cc3100_(p16, p17, p9, p10, p8, SPI(p5, p6, p7));//LPC1768  irq, nHib, cs, mosi, miso, sck

#ifdef __cplusplus
extern "C" {
#endif 

#define PRINT_BUF_LEN    128
extern int8_t print_buf[PRINT_BUF_LEN];

/* General Events handling*/
#if defined (EXT_LIB_REGISTERED_GENERAL_EVENTS)

typedef _SlEventPropogationStatus_e (*general_callback) (SlDeviceEvent_t *);

static const general_callback  general_callbacks[] =
{
#ifdef SlExtLib1GeneralEventHandler
    SlExtLib1GeneralEventHandler,
#endif

#ifdef SlExtLib2GeneralEventHandler
    SlExtLib2GeneralEventHandler,
#endif

#ifdef SlExtLib3GeneralEventHandler
    SlExtLib3GeneralEventHandler,
#endif

#ifdef SlExtLib4GeneralEventHandler
    SlExtLib4GeneralEventHandler,
#endif

#ifdef SlExtLib5GeneralEventHandler
    SlExtLib5GeneralEventHandler,
#endif
};

#undef _SlDrvHandleGeneralEvents

/********************************************************************
  _SlDrvHandleGeneralEvents
  Iterates through all the general(device) event handlers which are
  registered by   the external libs/user application.
*********************************************************************/
void _SlDrvHandleGeneralEvents(SlDeviceEvent_t *slGeneralEvent)
{
    uint8_t i;

    /* Iterate over all the extenal libs handlers */
    for ( i = 0 ; i < sizeof(general_callbacks)/sizeof(general_callbacks[0]) ; i++ )
    {
        if (EVENT_PROPAGATION_BLOCK == general_callbacks[i](slGeneralEvent) )
        {
            /* exit immediately and do not call the user specific handler as well */
            return;
        }
    }

/* At last call the Application specific handler if registered */
#ifdef sl_GeneralEvtHdlr
    sl_GeneralEvtHdlr(slGeneralEvent);
#endif

}
#endif



/* WLAN Events handling*/

#if defined (EXT_LIB_REGISTERED_WLAN_EVENTS)

typedef _SlEventPropogationStatus_e (*wlan_callback) (SlWlanEvent_t *);

static wlan_callback  wlan_callbacks[] =
{
#ifdef SlExtLib1WlanEventHandler
        SlExtLib1WlanEventHandler,
#endif

#ifdef SlExtLib2WlanEventHandler
        SlExtLib2WlanEventHandler,
#endif

#ifdef SlExtLib3WlanEventHandler
        SlExtLib3WlanEventHandler,
#endif

#ifdef SlExtLib4WlanEventHandler
        SlExtLib4WlanEventHandler,
#endif

#ifdef SlExtLib5WlanEventHandler
        SlExtLib5WlanEventHandler,
#endif
};

#undef _SlDrvHandleWlanEvents

/***********************************************************
  _SlDrvHandleWlanEvents
  Iterates through all the wlan event handlers which are
  registered by the external libs/user application.
************************************************************/
void _SlDrvHandleWlanEvents(SlWlanEvent_t *slWlanEvent)
{
    uint8_t i;

    /* Iterate over all the extenal libs handlers */
    for ( i = 0 ; i < sizeof(wlan_callbacks)/sizeof(wlan_callbacks[0]) ; i++ )
    {
        if ( EVENT_PROPAGATION_BLOCK == wlan_callbacks[i](slWlanEvent) )
        {
            /* exit immediately and do not call the user specific handler as well */
            return;
        }
    }

/* At last call the Application specific handler if registered */
#ifdef sl_WlanEvtHdlr
    sl_WlanEvtHdlr(slWlanEvent);
#endif

}
#endif


/* NetApp Events handling */
#if defined (EXT_LIB_REGISTERED_NETAPP_EVENTS)

typedef _SlEventPropogationStatus_e (*netApp_callback) (SlNetAppEvent_t *);

static const netApp_callback  netApp_callbacks[] =
{
#ifdef SlExtLib1NetAppEventHandler
     SlExtLib1NetAppEventHandler,
#endif

#ifdef SlExtLib2NetAppEventHandler
     SlExtLib2NetAppEventHandler,
#endif

#ifdef SlExtLib3NetAppEventHandler
     SlExtLib3NetAppEventHandler,
#endif

#ifdef SlExtLib4NetAppEventHandler
     SlExtLib4NetAppEventHandler,
#endif

#ifdef SlExtLib5NetAppEventHandler
     SlExtLib5NetAppEventHandler,
#endif
};

#undef _SlDrvHandleNetAppEvents

/************************************************************
  _SlDrvHandleNetAppEvents
  Iterates through all the net app event handlers which are
  registered by   the external libs/user application.
************************************************************/
void _SlDrvHandleNetAppEvents(SlNetAppEvent_t *slNetAppEvent)
{
    uint8_t i;

    /* Iterate over all the extenal libs handlers */
    for ( i = 0 ; i < sizeof(netApp_callbacks)/sizeof(netApp_callbacks[0]) ; i++ )
    {
        if (EVENT_PROPAGATION_BLOCK == netApp_callbacks[i](slNetAppEvent) )
        {
            /* exit immediately and do not call the user specific handler as well */
            return;
        }
    }

/* At last call the Application specific handler if registered */
#ifdef sl_NetAppEvtHdlr
    sl_NetAppEvtHdlr(slNetAppEvent);
#endif

}
#endif


/* Http Server Events handling */
#if defined (EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS)

typedef _SlEventPropogationStatus_e (*httpServer_callback) (SlHttpServerEvent_t*, SlHttpServerResponse_t*);

static const httpServer_callback  httpServer_callbacks[] =
{
#ifdef SlExtLib1HttpServerEventHandler
        SlExtLib1HttpServerEventHandler,
#endif

#ifdef SlExtLib2HttpServerEventHandler
        SlExtLib2HttpServerEventHandler,
#endif

#ifdef SlExtLib3HttpServerEventHandler
        SlExtLib3HttpServerEventHandler,
#endif

#ifdef SlExtLib4HttpServerEventHandler
        SlExtLib4HttpServerEventHandler,
#endif

#ifdef SlExtLib5HttpServerEventHandler
      SlExtLib5HttpServerEventHandler,
#endif
};

#undef _SlDrvHandleHttpServerEvents

/*******************************************************************
  _SlDrvHandleHttpServerEvents
  Iterates through all the http server event handlers which are
  registered by the external libs/user application.
********************************************************************/
void _SlDrvHandleHttpServerEvents(SlHttpServerEvent_t *slHttpServerEvent, SlHttpServerResponse_t *slHttpServerResponse)
{
    _u8 i;

    /* Iterate over all the external libs handlers */
    for ( i = 0 ; i < sizeof(httpServer_callbacks)/sizeof(httpServer_callbacks[0]) ; i++ )
    {
        if ( EVENT_PROPAGATION_BLOCK == httpServer_callbacks[i](slHttpServerEvent, slHttpServerResponse) )
        {
            /* exit immediately and do not call the user specific handler as well */
            return;
        }
    }

/* At last call the Application specific handler if registered */
#ifdef sl_HttpServerCallback
    sl_HttpServerCallback(slHttpServerEvent, slHttpServerResponse);
#endif

}
#endif


/* Socket Events */
#if defined (EXT_LIB_REGISTERED_SOCK_EVENTS)

typedef _SlEventPropogationStatus_e (*sock_callback) (SlSockEvent_t *);

static const sock_callback  sock_callbacks[] =
{
#ifdef SlExtLib1SockEventHandler
        SlExtLib1SockEventHandler,
#endif

#ifdef SlExtLib2SockEventHandler
        SlExtLib2SockEventHandler,
#endif

#ifdef SlExtLib3SockEventHandler
        SlExtLib3SockEventHandler,
#endif

#ifdef SlExtLib4SockEventHandler
        SlExtLib4SockEventHandler,
#endif

#ifdef SlExtLib5SockEventHandler
        SlExtLib5SockEventHandler,
#endif
};

/*************************************************************
  _SlDrvHandleSockEvents
  Iterates through all the socket event handlers which are
  registered by the external libs/user application.
**************************************************************/
void _SlDrvHandleSockEvents(SlSockEvent_t *slSockEvent)
{
    uint8_t i;

    /* Iterate over all the external libs handlers */
    for ( i = 0 ; i < sizeof(sock_callbacks)/sizeof(sock_callbacks[0]) ; i++ )
    {
        if ( EVENT_PROPAGATION_BLOCK == sock_callbacks[i](slSockEvent) )
        {
            /* exit immediately and do not call the user specific handler as well */
            return;
        }
    }

/* At last call the Application specific handler if registered */
#ifdef sl_SockEvtHdlr
    sl_SockEvtHdlr(slSockEvent);
#endif

}

#endif   

/*!
    \brief This function handles ping report events

    \param[in]      pPingReport holds the ping report statistics

    \return         None

    \note

    \warning
*/
void SimpleLinkPingReport(SlPingReport_t *pPingReport)
{
    _cc3100_.SET_STATUS_BIT(g_Status, STATUS_BIT_PING_DONE);

    if(pPingReport == NULL)
        Uart_Write((uint8_t*)" [PING REPORT] NULL Pointer Error\r\n");

    g_PingPacketsRecv = pPingReport->PacketsReceived;
}


/*******************************************************************************/
/*   _sl_HandleAsync_Accept */
/*******************************************************************************/
#ifndef SL_TINY_EXT
void _sl_HandleAsync_Accept(void *pVoidBuf)
{
    _SocketAddrResponse_u *pMsgArgs = (_SocketAddrResponse_u *)_SL_RESP_ARGS_START(pVoidBuf);

    _cc3100_._driver._SlDrvProtectionObjLockWaitForever();

    VERIFY_PROTOCOL(( pMsgArgs->IpV4.sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
    VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);

    memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs,sizeof(_SocketAddrResponse_u));
    _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);

    _cc3100_._driver._SlDrvProtectionObjUnLock();
    return;
}

/*******************************************************************************/
/*   _sl_HandleAsync_Connect */
/*******************************************************************************/
void _sl_HandleAsync_Connect(void *pVoidBuf)
{
    _SocketResponse_t *pMsgArgs = (_SocketResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);

    _cc3100_._driver._SlDrvProtectionObjLockWaitForever();

    VERIFY_PROTOCOL((pMsgArgs->sd & BSD_SOCKET_ID_MASK) <= SL_MAX_SOCKETS);
    VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);

    ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->sd = pMsgArgs->sd;
    ((_SocketResponse_t *)(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs))->statusOrLen = pMsgArgs->statusOrLen;

    _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
    _cc3100_._driver._SlDrvProtectionObjUnLock();
    return;
}

/*******************************************************************************/
/*   _sl_HandleAsync_Select */
/*******************************************************************************/
void _sl_HandleAsync_Select(void *pVoidBuf)
{
    _SelectAsyncResponse_t     *pMsgArgs   = (_SelectAsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);

    _cc3100_._driver._SlDrvProtectionObjLockWaitForever();    

    VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);

    memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_SelectAsyncResponse_t));

    _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
    _cc3100_._driver._SlDrvProtectionObjUnLock();

    return;
}

#endif

/******************************************************************************/
/*  _sl_HandleAsync_DnsGetHostByName */
/******************************************************************************/
void _sl_HandleAsync_DnsGetHostByName(void *pVoidBuf)
{
    _GetHostByNameIPv4AsyncResponse_t *pMsgArgs = (_GetHostByNameIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);

    _cc3100_._driver._SlDrvProtectionObjLockWaitForever();

    VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);

    /*IPv6 */
    if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) {
        memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv6AsyncResponse_t));
    }
    /*IPv4 */
    else 
    {
        memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_GetHostByNameIPv4AsyncResponse_t));
    }
    
    _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
    _cc3100_._driver._SlDrvProtectionObjUnLock();
    
    return;
}

/******************************************************************************/

/******************************************************************************
    _sl_HandleAsync_DnsGetHostByService

    CALLER          NWP - Async event on sl_DnsGetHostByService with IPv4 Family


    DESCRIPTION:

                    Async event on sl_DnsGetHostByService command with IPv4 Family.
                    Return service attributes like IP address, port and text according to service name.
                    The user sets a service name Full/Part (see example below), and should get the:
                    1. IP of the service
                    2. The port of service.
                    3. The text of service.

                    Hence it can make a connection to the specific service and use it.
                    It is similar to get host by name method.

                    It is done by a single shot query with PTR type on the service name.



                    Note:
                    1. The return's attributes are belonged to first service that is found.
                    It can be other services with the same service name will response to
                    the query. The results of these responses are saved in the peer cache of the NWP, and
                    should be read by another API.


        PARAMETERS:

                  pVoidBuf - is point to opcode of the event.
                  it contains the outputs that are given to the user

                  outputs description:

                   1.out_pAddr[]                    - output: Contain the IP address of the service.
                   2.out_pPort                      - output: Contain the port of the service.
                   3.inout_TextLen                  - Input:  Contain the max length of the text that the user wants to get.
                                                              it means that if the test of service is bigger that its value than
                                                              the text is cut to inout_TextLen value.
                                                      Output: Contain the length of the text that is returned. Can be full text or part
                                                              of the text (see above).

                   4.out_pText                      - Contain the text of the service (full or part see above- inout_TextLen description).

  *


    RETURNS:        success or fail.

******************************************************************************/
#ifndef SL_TINY_EXT
void _sl_HandleAsync_DnsGetHostByService(void *pVoidBuf)
{
    _GetHostByServiceAsyncResponse_t* Res;
    uint16_t TextLen;
    uint16_t UserTextLen;

    /*pVoidBuf - is point to opcode of the event.*/

    /*set pMsgArgs to point to the attribute of the event.*/
    _GetHostByServiceIPv4AsyncResponse_t *pMsgArgs = (_GetHostByServiceIPv4AsyncResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);

    VERIFY_SOCKET_CB(NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs);

    /*IPv6*/
    if(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].AdditionalData & SL_NETAPP_FAMILY_MASK) {
        return;
    }
    /*IPv4*/
    else {
        /*************************************************************************************************

        1. Copy the attribute part of the evnt to the attribute part of the response
        memcpy(g_pCB->GetHostByServiceCB.pAsyncRsp, pMsgArgs, sizeof(_GetHostByServiceIPv4AsyncResponse_t));

        set to TextLen the text length of the service.*/
        TextLen = pMsgArgs->TextLen;

        /*Res pointed to mDNS global object struct */
        Res = (_GetHostByServiceAsyncResponse_t*)g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs;



        /*It is 4 bytes so we avoid from memcpy*/
        Res->out_pAddr[0]   = pMsgArgs->Address;
        Res->out_pPort[0]   = pMsgArgs->Port;
        Res->Status         = pMsgArgs->Status;

        /*set to TextLen the text length of the user (input fromthe user).*/
        UserTextLen = Res->inout_TextLen[0];

        /*Cut the service text if the user requested for smaller text.*/
        UserTextLen = (TextLen <= UserTextLen) ? TextLen : UserTextLen;
        Res->inout_TextLen[0] = UserTextLen ;

        /**************************************************************************************************

        2. Copy the payload part of the evnt (the text) to the payload part of the response
        the lenght of the copy is according to the text length in the attribute part. */


        memcpy(Res->out_pText,
                  (int8_t *)(& pMsgArgs[1]),   /* & pMsgArgs[1] -> 1st byte after the fixed header = 1st byte of variable text.*/
                  UserTextLen);


        /**************************************************************************************************/
        _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
        return;
    }
}
#endif

/*****************************************************************************/
/*  _sl_HandleAsync_PingResponse */
/*****************************************************************************/
#ifndef SL_TINY_EXT
void _sl_HandleAsync_PingResponse(void *pVoidBuf)
{
    _PingReportResponse_t *pMsgArgs  = (_PingReportResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);
    SlPingReport_t pingReport;

    if(pPingCallBackFunc) {
        _cc3100_._netapp.CopyPingResultsToReport(pMsgArgs,&pingReport);
        pPingCallBackFunc(&pingReport);
    } else {

        _cc3100_._driver._SlDrvProtectionObjLockWaitForever();
        VERIFY_SOCKET_CB(NULL != g_pCB->PingCB.PingAsync.pAsyncRsp);

        if (NULL != g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs) {
            memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_PingReportResponse_t));
            _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
        }
        _cc3100_._driver._SlDrvProtectionObjUnLock();
    }
    return;
}
#endif

/* ******************************************************************************/
/*  _SlDrvMsgReadSpawnCtx                                                       */
/* ******************************************************************************/

_SlReturnVal_t _SlDrvMsgReadSpawnCtx(void *pValue)
{
//    Uart_Write((uint8_t*)"\n\r _SlDrvMsgReadSpawnCtx \n\r");
#ifdef SL_POLLING_MODE_USED
    int16_t retCode = OSI_OK;
    //  for polling based systems 
    do {
        retCode = _cc3100_->_nonos.sl_LockObjLock(&g_pCB->GlobalLockObj, 0);
        if ( OSI_OK != retCode ) {
            if (TRUE == g_pCB->IsCmdRespWaited) {
                OSI_RET_OK_CHECK( _cc3100_->_nonos.sl_SyncObjSignal(&g_pCB->CmdSyncObj) );
                return SL_RET_CODE_OK;
            }
        }

    } while (OSI_OK != retCode);

#else
    
//    OSI_RET_OK_CHECK(_cc3100_->_nonos.sl_LockObjLock(&g_pCB->GlobalLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE, NON_OS_LOCK_OBJ_LOCK_VALUE, SL_OS_WAIT_FOREVER) );
    _cc3100_._driver._SlDrvObjLockWaitForever(&g_pCB->GlobalLockObj);
    
#endif
    
    g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;//  buffer must be allocated by _SlDrvMsgRead 
    g_pCB->FunctionParams.AsyncExt.AsyncEvtHandler= NULL;
    g_pCB->FunctionParams.AsyncExt.RxMsgClass = CMD_RESP_CLASS;// init to illegal value and verify it's overwritten with the valid one 

    //  Messages might have been read by CmdResp context. Therefore after 
    //  getting LockObj, check again where the Pending Rx Msg is still present. 
    if(FALSE == (_cc3100_._driver._SL_PENDING_RX_MSG(g_pCB))) {
        _cc3100_._driver._SlDrvObjUnLock(&g_pCB->GlobalLockObj);
//        OSI_RET_OK_CHECK(_cc3100_->_nonos.sl_LockObjUnlock(&g_pCB->GlobalLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE));
        return SL_RET_CODE_OK;
    }
    
    VERIFY_RET_OK(_cc3100_._driver._SlDrvMsgRead());
    
    g_pCB->RxDoneCnt++;

    switch(g_pCB->FunctionParams.AsyncExt.RxMsgClass) {
        case ASYNC_EVT_CLASS:
            //  If got here and protected by LockObj a message is waiting  
            //  to be read 
            VERIFY_PROTOCOL(NULL != g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
            
            _cc3100_._driver._SlAsyncEventGenericHandler();
            
#if (SL_MEMORY_MGMT == SL_MEMORY_MGMT_STATIC)
            g_pCB->FunctionParams.AsyncExt.pAsyncBuf = NULL;
#else
            free(g_pCB->FunctionParams.AsyncExt.pAsyncBuf);
#endif
            break;
        case DUMMY_MSG_CLASS:
        case RECV_RESP_CLASS:
            // These types are legal in this context. Do nothing 
            break;
        case CMD_RESP_CLASS:
            // Command response is illegal in this context. 
            // No 'break' here: Assert! 
        default:
            VERIFY_PROTOCOL(0);
    }
    
    _cc3100_._driver._SlDrvObjUnLock(&g_pCB->GlobalLockObj);
//    OSI_RET_OK_CHECK(_cc3100_->_nonos.sl_LockObjUnlock(&g_pCB->GlobalLockObj, NON_OS_LOCK_OBJ_UNLOCK_VALUE));
    
    return(SL_RET_CODE_OK);   

}

/***************************************************************************
_sl_HandleAsync_Stop - handles stop signalling to
a waiting object
****************************************************************************/
void _sl_HandleAsync_Stop(void *pVoidBuf)
{
    _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pVoidBuf);

    VERIFY_SOCKET_CB(NULL != g_pCB->StopCB.pAsyncRsp);

    _cc3100_._driver._SlDrvProtectionObjLockWaitForever();

    memcpy(g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].pRespArgs, pMsgArgs, sizeof(_BasicResponse_t));
    _cc3100_._driver._SlDrvSyncObjSignal(&g_pCB->ObjPool[g_pCB->FunctionParams.AsyncExt.ActionIndex].SyncObj);
    _cc3100_._driver._SlDrvProtectionObjUnLock();
    return;
}

/******************************************************************************
_SlDrvDeviceEventHandler - handles internally device async events
******************************************************************************/
void _SlDrvDeviceEventHandler(void *pArgs)
{
    _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs;
   
    switch(pHdr->GenHeader.Opcode) {
        case SL_OPCODE_DEVICE_INITCOMPLETE:
            _cc3100_._sl_HandleAsync_InitComplete(pHdr);
            
            break;
        case SL_OPCODE_DEVICE_STOP_ASYNC_RESPONSE:
            _sl_HandleAsync_Stop(pHdr);
            
            break;
        

        case SL_OPCODE_DEVICE_ABORT:
            {
#if defined (sl_GeneralEvtHdlr) || defined(EXT_LIB_REGISTERED_GENERAL_EVENTS)
                SlDeviceEvent_t      devHandler;
                devHandler.Event = SL_DEVICE_ABORT_ERROR_EVENT; 
                devHandler.EventData.deviceReport.AbortType = *((uint32_t*)pArgs + 2);
                devHandler.EventData.deviceReport.AbortData = *((uint32_t*)pArgs + 3);
                _SlDrvHandleGeneralEvents(&devHandler);
#endif      
            }
        break;    
        case  SL_OPCODE_DEVICE_DEVICEASYNCFATALERROR:
#if defined (sl_GeneralEvtHdlr) || defined(EXT_LIB_REGISTERED_GENERAL_EVENTS)
        {
            _BasicResponse_t *pMsgArgs = (_BasicResponse_t *)_SL_RESP_ARGS_START(pHdr);
            SlDeviceEvent_t devHandler;
            devHandler.Event = SL_DEVICE_FATAL_ERROR_EVENT;
            devHandler.EventData.deviceEvent.status = pMsgArgs->status & 0xFF;
            devHandler.EventData.deviceEvent.sender = (SlErrorSender_e)((pMsgArgs->status >> 8) & 0xFF);
            _SlDrvHandleGeneralEvents(&devHandler);
        }
#endif
        break;
        default:
            SL_ERROR_TRACE2(MSG_306, "ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x = %i", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode);
            //printf("ASSERT: _SlDrvDeviceEventHandler : invalid opcode = 0x%x = %i", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode);
            
    }
}

/*****************************************************************************/
/* _SlDrvNetAppEventHandler */
/*****************************************************************************/
void _SlDrvNetAppEventHandler(void *pArgs)
{
    _SlResponseHeader_t *pHdr = (_SlResponseHeader_t *)pArgs;
#if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS)
    SlHttpServerEvent_t     httpServerEvent;    
    SlHttpServerResponse_t  httpServerResponse;
#endif
    switch(pHdr->GenHeader.Opcode) {
        case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE:
        case SL_OPCODE_NETAPP_DNSGETHOSTBYNAMEASYNCRESPONSE_V6:
            _sl_HandleAsync_DnsGetHostByName(pArgs);
            break;
#ifndef SL_TINY_EXT             
        case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE:
        case SL_OPCODE_NETAPP_MDNSGETHOSTBYSERVICEASYNCRESPONSE_V6:
            _sl_HandleAsync_DnsGetHostByService(pArgs);
            break;
        case SL_OPCODE_NETAPP_PINGREPORTREQUESTRESPONSE:
            _sl_HandleAsync_PingResponse(pArgs);
            break;
#endif

#if defined(sl_HttpServerCallback) || defined(EXT_LIB_REGISTERED_HTTP_SERVER_EVENTS)            
        case SL_OPCODE_NETAPP_HTTPGETTOKENVALUE: {

            uint8_t *pTokenName;
            slHttpServerData_t Token_value;
            sl_NetAppHttpServerGetToken_t *httpGetToken = (sl_NetAppHttpServerGetToken_t *)_SL_RESP_ARGS_START(pHdr);
            pTokenName = (uint8_t *)((sl_NetAppHttpServerGetToken_t *)httpGetToken + 1);

            httpServerResponse.Response = SL_NETAPP_HTTPSETTOKENVALUE;
            httpServerResponse.ResponseData.token_value.len = MAX_TOKEN_VALUE_LEN;

            /* Reuse the async buffer for getting the token value response from the user */
            httpServerResponse.ResponseData.token_value.data = (uint8_t *)_SL_RESP_ARGS_START(pHdr) + MAX_TOKEN_NAME_LEN;
            httpServerEvent.Event = SL_NETAPP_HTTPGETTOKENVALUE_EVENT;

            httpServerEvent.EventData.httpTokenName.len = httpGetToken->token_name_len;
            httpServerEvent.EventData.httpTokenName.data = pTokenName;

            Token_value.token_name =  pTokenName;

            _SlDrvHandleHttpServerEvents (&httpServerEvent, &httpServerResponse);

            Token_value.value_len = httpServerResponse.ResponseData.token_value.len;
            Token_value.name_len = httpServerEvent.EventData.httpTokenName.len;

            Token_value.token_value = httpServerResponse.ResponseData.token_value.data;


            _cc3100_._netapp.sl_NetAppSendTokenValue(&Token_value);
#endif
        }
        break;

        case SL_OPCODE_NETAPP_HTTPPOSTTOKENVALUE: {
#ifdef sl_HttpServerCallback
            uint8_t *pPostParams;

            sl_NetAppHttpServerPostToken_t *httpPostTokenArgs = (sl_NetAppHttpServerPostToken_t *)_SL_RESP_ARGS_START(pHdr);
            pPostParams = (uint8_t *)((sl_NetAppHttpServerPostToken_t *)httpPostTokenArgs + 1);

            httpServerEvent.Event = SL_NETAPP_HTTPPOSTTOKENVALUE_EVENT;

            httpServerEvent.EventData.httpPostData.action.len = httpPostTokenArgs->post_action_len;
            httpServerEvent.EventData.httpPostData.action.data = pPostParams;
            pPostParams+=httpPostTokenArgs->post_action_len;

            httpServerEvent.EventData.httpPostData.token_name.len = httpPostTokenArgs->token_name_len;
            httpServerEvent.EventData.httpPostData.token_name.data = pPostParams;
            pPostParams+=httpPostTokenArgs->token_name_len;

            httpServerEvent.EventData.httpPostData.token_value.len = httpPostTokenArgs->token_value_len;
            httpServerEvent.EventData.httpPostData.token_value.data = pPostParams;

            httpServerResponse.Response = SL_NETAPP_RESPONSE_NONE;


            _SlDrvHandleHttpServerEvents (&httpServerEvent, &httpServerResponse);
        }
        break;
#endif        
        default:
            SL_ERROR_TRACE2(MSG_305, "ASSERT: _SlDrvNetAppEventHandler : invalid opcode = 0x%x = %i", pHdr->GenHeader.Opcode, pHdr->GenHeader.Opcode);
            VERIFY_PROTOCOL(0);
    }
}

/*
 * ASYNCHRONOUS EVENT HANDLERS -- Start
 */

/*!
    \brief This function handles WLAN events

    \param[in]      pWlanEvent is the event passed to the handler

    \return         None

    \note

    \warning
*/
#if (defined(sl_WlanEvtHdlr))
void SimpleLinkWlanEventHandler(SlWlanEvent_t *pWlanEvent)
{
    unsigned char  g_ucConnectionSSID[32+1]; //Connection SSID
    unsigned char  g_ucConnectionBSSID[6]; //Connection BSSID
    
    if(pWlanEvent == NULL)
        Uart_Write((uint8_t*)" [WLAN EVENT] NULL Pointer Error \n\r");

    switch(pWlanEvent->Event) {
        case SL_WLAN_CONNECT_EVENT: {
            _cc3100_.SET_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION);
            
            // Copy new connection SSID and BSSID to global parameters
            memcpy(g_ucConnectionSSID,pWlanEvent->EventData.
                   STAandP2PModeWlanConnected.ssid_name,
                   pWlanEvent->EventData.STAandP2PModeWlanConnected.ssid_len);
            memcpy(g_ucConnectionBSSID,
                   pWlanEvent->EventData.STAandP2PModeWlanConnected.bssid,
                   SL_BSSID_LENGTH);
            
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "[WLAN EVENT] STA Connected to the AP: %s ,""BSSID: %x:%x:%x:%x:%x:%x\n\r",
                       g_ucConnectionSSID,g_ucConnectionBSSID[0],
                       g_ucConnectionBSSID[1],g_ucConnectionBSSID[2],
                       g_ucConnectionBSSID[3],g_ucConnectionBSSID[4],
                       g_ucConnectionBSSID[5]);
            Uart_Write((uint8_t *) print_buf);
            /*
             * Information about the connected AP (like name, MAC etc) will be
             * available in 'slWlanConnectAsyncResponse_t' - Applications
             * can use it if required
             *
             * slWlanConnectAsyncResponse_t *pEventData = NULL;
             * pEventData = &pWlanEvent->EventData.STAandP2PModeWlanConnected;
             *
             */
        }
        break;

        case SL_WLAN_DISCONNECT_EVENT: {
            slWlanConnectAsyncResponse_t*  pEventData = NULL;

            _cc3100_.CLR_STATUS_BIT(g_Status, STATUS_BIT_CONNECTION);
            _cc3100_.CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);

            pEventData = &pWlanEvent->EventData.STAandP2PModeDisconnected;

            /* If the user has initiated 'Disconnect' request, 'reason_code' is SL_USER_INITIATED_DISCONNECTION */
            if(SL_USER_INITIATED_DISCONNECTION == pEventData->reason_code) {
                memset(print_buf, 0x00, PRINT_BUF_LEN);
                sprintf((char*) print_buf, "[WLAN EVENT]Device disconnected from the AP: %s,"
                    "BSSID: %x:%x:%x:%x:%x:%x on application's request \n\r",
                           g_ucConnectionSSID,g_ucConnectionBSSID[0],
                           g_ucConnectionBSSID[1],g_ucConnectionBSSID[2],
                           g_ucConnectionBSSID[3],g_ucConnectionBSSID[4],
                           g_ucConnectionBSSID[5]);
                Uart_Write((uint8_t *) print_buf);
            } else {
                memset(print_buf, 0x00, PRINT_BUF_LEN);
                sprintf((char*) print_buf, "[WLAN ERROR]Device disconnected from the AP AP: %s,"
                        "BSSID: %x:%x:%x:%x:%x:%x on an ERROR..!! \n\r",
                           g_ucConnectionSSID,g_ucConnectionBSSID[0],
                           g_ucConnectionBSSID[1],g_ucConnectionBSSID[2],
                           g_ucConnectionBSSID[3],g_ucConnectionBSSID[4],
                           g_ucConnectionBSSID[5]);
                Uart_Write((uint8_t *) print_buf);
            }
            memset(g_ucConnectionSSID,0,sizeof(g_ucConnectionSSID));
            memset(g_ucConnectionBSSID,0,sizeof(g_ucConnectionBSSID));
        }
        break;

        case SL_WLAN_STA_CONNECTED_EVENT: {
            _cc3100_.SET_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED);
        }
        break;

        case SL_WLAN_STA_DISCONNECTED_EVENT: {
            _cc3100_.CLR_STATUS_BIT(g_Status, STATUS_BIT_STA_CONNECTED);
            _cc3100_.CLR_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED);
        }
        break;

        default: {
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "[WLAN EVENT] Unexpected event [0x%x]\n\r",pWlanEvent->Event);
            Uart_Write((uint8_t *) print_buf); 
        }
        break;
    }
}
#endif

/*!
    \brief This function handles events for IP address acquisition via DHCP
           indication

    \param[in]      pNetAppEvent is the event passed to the handler

    \return         None

    \note

    \warning
*/
#if (defined(sl_NetAppEvtHdlr))
void SimpleLinkNetAppEventHandler(SlNetAppEvent_t *pNetAppEvent)
{
    
    if(pNetAppEvent == NULL){
        Uart_Write((uint8_t *)" [NETAPP EVENT] NULL Pointer Error \n\r");
    }
    
    switch(pNetAppEvent->Event) {
        case SL_NETAPP_IPV4_IPACQUIRED_EVENT: {
            SlIpV4AcquiredAsync_t *pEventData = NULL;
            _cc3100_.SET_STATUS_BIT(g_Status, STATUS_BIT_IP_ACQUIRED);            
            pEventData = &pNetAppEvent->EventData.ipAcquiredV4;           
            g_GatewayIP = pEventData->gateway;
            
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "[NETAPP EVENT] IP Acquired: IP=%d.%d.%d.%d , ""Gateway=%d.%d.%d.%d\n\r",
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,3),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,2),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,1),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.ip,0),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,3),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,2),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,1),
            _cc3100_._netcfg.SL_IPV4_BYTE(pNetAppEvent->EventData.ipAcquiredV4.gateway,0));
            Uart_Write((uint8_t *) print_buf);
            
        }
        break;

        case SL_NETAPP_IP_LEASED_EVENT: {           
            g_StationIP = pNetAppEvent->EventData.ipLeased.ip_address;          
            _cc3100_.SET_STATUS_BIT(g_Status, STATUS_BIT_IP_LEASED);
                       
        }
        break;

        default: {
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "[NETAPP EVENT] Unexpected event [0x%x] \n\r",pNetAppEvent->Event);
            Uart_Write((uint8_t *) print_buf);
        }
        break;
    }
}
#endif 

/*!
    \brief This function handles socket events indication

    \param[in]      pSock is the event passed to the handler

    \return         None
*/
#if (defined(sl_SockEvtHdlr))
void SimpleLinkSockEventHandler(SlSockEvent_t *pSock)
{
    if(pSock == NULL)
        Uart_Write((uint8_t *)" [SOCK EVENT] NULL Pointer Error \n\r");
    
    switch( pSock->Event )
    {
        case SL_SOCKET_TX_FAILED_EVENT:
            /*
             * TX Failed
             *
             * Information about the socket descriptor and status will be
             * available in 'SlSockEventData_t' - Applications can use it if
             * required
             *
             * SlSockEventData_t *pEventData = NULL;
             * pEventData = & pSock->EventData;
             */
            
            switch( pSock->socketAsyncEvent.SockTxFailData.status )
            {
                case SL_ECLOSE:
                    Uart_Write((uint8_t *)" [SOCK EVENT] Close socket operation, failed to transmit all queued packets\n\r");
                    break;
                default:
                     memset(print_buf, 0x00, PRINT_BUF_LEN);
                     sprintf((char*) print_buf, "[SOCK ERROR] - TX FAILED : socket %d , reason""(%d) \n\n", pSock->socketAsyncEvent.SockTxFailData.sd, pSock->socketAsyncEvent.SockTxFailData.status);           
                     Uart_Write((uint8_t *) print_buf);
                    break;
            }
            break;

        default:
            memset(print_buf, 0x00, PRINT_BUF_LEN);
            sprintf((char*) print_buf, "[SOCK EVENT] - Unexpected Event [%x0x]\n\n",pSock->Event);
            Uart_Write((uint8_t *) print_buf);
            break;
    }
}
#endif

/*!
    \brief This function handles callback for the HTTP server events

    \param[in]      pHttpEvent - Contains the relevant event information
    \param[in]      pHttpResponse - Should be filled by the user with the
                    relevant response information

    \return         None

    \note

    \warning
*/
#if (defined(sl_HttpServerCallback))
void SimpleLinkHttpServerCallback(SlHttpServerEvent_t *pHttpEvent, SlHttpServerResponse_t *pHttpResponse)
{
    /*
     * This application doesn't work with HTTP server - Hence these
     * events are not handled here
     */
    Uart_Write((uint8_t *)" [HTTP EVENT] Unexpected event \n\r");
}
#endif
/*!
    \brief This function handles general error events indication

    \param[in]      pDevEvent is the event passed to the handler

    \return         None
*/
#if (defined(sl_GeneralEvtHdlr))
void SimpleLinkGeneralEventHandler(SlDeviceEvent_t *pDevEvent)
{
    /*
     * Most of the general errors are not FATAL are are to be handled
     * appropriately by the application
     */
    memset(print_buf, 0x00, PRINT_BUF_LEN);
    sprintf((char*) print_buf, "[GENERAL EVENT] - ID=[%d] Sender=[%d]\n\n", pDevEvent->EventData.deviceEvent.status, pDevEvent->EventData.deviceEvent.sender); 
    Uart_Write((uint8_t *) print_buf);
}
#endif

#ifdef  __cplusplus
}
#endif /*  __cplusplus */

//}//namespace