Example #1
0
long
accept(long sd, sockaddr *addr, socklen_t *addrlen)
{
	long ret;
	unsigned char *ptr, *args;
	tBsdReturnParams tAcceptReturnArguments;
	
	ret = EFAIL;
	ptr = tSLInformation.pucTxCommandBuffer;
	args = (ptr + HEADERS_SIZE_CMD);
	
	// Fill in temporary command buffer
	args = UINT32_TO_STREAM(args, sd);
	
	// Initiate a HCI command
	hci_command_send(HCI_CMND_ACCEPT,
									 ptr, SOCKET_ACCEPT_PARAMS_LEN);
	
	// Since we are in blocking state - wait for event complete
	SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments);
	
	
	// need specify return parameters!!!
	memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
	*addrlen = ASIC_ADDR_LEN;
	errno = tAcceptReturnArguments.iStatus; 
	ret = errno;
	
	// if succeeded, iStatus = new socket descriptor. otherwise - error number 
	if(M_IS_VALID_SD(ret))
	{
		set_socket_active_status(ret, SOCKET_STATUS_ACTIVE);
	}
	else
	{
		set_socket_active_status(sd, SOCKET_STATUS_INACTIVE);
	}
	
	return(ret);
}
Example #2
0
int32_t cc3000_wlan::set_event_mask(uint32_t mask) {
    int32_t ret;
    uint8_t *ptr;
    uint8_t *args;


    if ((mask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE)
    {
        _simple_link.set_tx_complete_signal(0);

        // Since an event is a virtual event - i.e. it is not coming from CC3000
        // there is no need to send anything to the device if it was an only event
        if (mask == HCI_EVNT_WLAN_TX_COMPLETE)
        {
            return 0;
        }

        mask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
        mask |= HCI_EVNT_WLAN_UNSOL_BASE;
    }
    else
    {
        _simple_link.set_tx_complete_signal(1);
    }

    ret = EFAIL;
    ptr = _simple_link.get_transmit_buffer();
    args = (uint8_t *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, mask);

    // Initiate a HCI command
    _hci.command_send(HCI_CMND_EVENT_MASK, ptr, WLAN_SET_MASK_PARAMS_LEN);

    // Wait for command complete event
    _event.simplelink_wait_event(HCI_CMND_EVENT_MASK, &ret);

    return(ret);
}
Example #3
0
INT32 wlan_ioctl_del_profile(UINT32 ulIndex)
{
	INT32 ret;
	UINT8 *ptr;
	UINT8 *args;

	ptr = tSLInformation.pucTxCommandBuffer;
	args = (UINT8 *)(ptr + HEADERS_SIZE_CMD);

	// Fill in HCI packet structure
	args = UINT32_TO_STREAM(args, ulIndex);
	ret = EFAIL;

	// Initiate a HCI command
	hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE,
		ptr, WLAN_DEL_PROFILE_PARAMS_LEN);

	// Wait for command complete event
	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);

	return(ret);
}
Example #4
0
long
wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
                            unsigned char *ucResults)
{
    unsigned char *ptr;
    unsigned char *args;

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    // Fill in temporary command buffer
    args = UINT32_TO_STREAM(args, ulScanTimeout);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS,
                     ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults);

    return(0);
}
Example #5
0
BOOLEAN btsnd_hcic_user_passkey_reply (BD_ADDR bd_addr, UINT32 value)
{
    BT_HDR *p;
    UINT8 *pp;

    if ((p = HCI_GET_CMD_BUF(HCIC_PARAM_SIZE_U_PKEY_REPLY)) == NULL)
        return (FALSE);

    pp = (UINT8 *)(p + 1);

    p->len    = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_U_PKEY_REPLY;
    p->offset = 0;

    UINT16_TO_STREAM (pp, HCI_USER_PASSKEY_REQ_REPLY);
    UINT8_TO_STREAM  (pp, HCIC_PARAM_SIZE_U_PKEY_REPLY);

    BDADDR_TO_STREAM (pp, bd_addr);
    UINT32_TO_STREAM (pp, value);

    btu_hcif_send_cmd (LOCAL_BR_EDR_CONTROLLER_ID,  p);
    return (TRUE);
}
Example #6
0
INT32 wlan_smart_config_start(UINT32 algoEncryptedFlag)
{
	INT32 ret;
	UINT8 *ptr;
	UINT8 *args;

	ret = EFAIL;
	ptr = tSLInformation.pucTxCommandBuffer;
	args = (UINT8 *)(ptr + HEADERS_SIZE_CMD);

	// Fill in HCI packet structure
	args = UINT32_TO_STREAM(args, algoEncryptedFlag);
	ret = EFAIL;

	hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr, 
		WLAN_SMART_CONFIG_START_PARAMS_LEN);

	// Wait for command complete event
	SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);

	return(ret);    
}
    /* init io callback */
    tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin;
    tSLInformation.WlanInterruptEnable  = sWlanInterruptEnable;
    tSLInformation.WlanInterruptDisable = sWlanInterruptDisable;
    tSLInformation.WriteWlanPin = sWriteWlanPin;

    //init asynchronous events callback
    tSLInformation.sWlanCB= sWlanCB;

    // By default TX Complete events are routed to host too
    tSLInformation.InformHostOnTxComplete = 1;
}

//*****************************************************************************
//
//!  SpiReceiveHandler
//!
//!  @param         pvBuffer - pointer to the received data buffer
//!                      The function triggers Received event/data processing
//!
//!  @param         Pointer to the received data
//!  @return        none
//!
//!  @brief         The function triggers Received event/data processing. It is
//!                       called from the SPI library to receive the data
//
//*****************************************************************************
void SpiReceiveHandler(void *pvBuffer)
{
    tSLInformation.usEventOrDataReceived = 1;
    tSLInformation.pucReceivedData = (unsigned char     *)pvBuffer;

    hci_unsolicited_event_handler();
}


//*****************************************************************************
//
//!  wlan_start
//!
//!  @param   usPatchesAvailableAtHost -  flag to indicate if patches available
//!                                    from host or from EEPROM. Due to the
//!                                    fact the patches are burn to the EEPROM
//!                                    using the patch programmer utility, the
//!                                    patches will be available from the EEPROM
//!                                    and not from the host.
//!
//!  @return        none
//!
//!  @brief        Start WLAN device. This function asserts the enable pin of
//!                the device (WLAN_EN), starting the HW initialization process.
//!                The function blocked until device Initialization is completed.
//!                Function also configure patches (FW, driver or bootloader)
//!                and calls appropriate device callbacks.
//!
//!  @Note          Prior calling the function wlan_init shall be called.
//!  @Warning       This function must be called after wlan_init and before any
//!                 other wlan API
//!  @sa            wlan_init , wlan_stop
//!
//
//*****************************************************************************

#ifdef __ENABLE_MULTITHREADED_SUPPORT__
void c_wlan_start(unsigned short usPatchesAvailableAtHost)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
void wlan_start(unsigned short usPatchesAvailableAtHost)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{

    unsigned long ulSpiIRQState;

    tSLInformation.NumberOfSentPackets = 0;
    tSLInformation.NumberOfReleasedPackets = 0;
    tSLInformation.usRxEventOpcode = 0;
    tSLInformation.usNumberOfFreeBuffers = 0;
    tSLInformation.usSlBufferLength = 0;
    tSLInformation.usBufferSize = 0;
    tSLInformation.usRxDataPending = 0;
    tSLInformation.slTransmitDataError = 0;
    tSLInformation.usEventOrDataReceived = 0;
    tSLInformation.pucReceivedData = 0;

    // Allocate the memory for the RX/TX data transactions
    tSLInformation.pucTxCommandBuffer = (unsigned char *)wlan_tx_buffer;

    // init spi
    SpiOpen(SpiReceiveHandler);

    // Check the IRQ line
    ulSpiIRQState = tSLInformation.ReadWlanInterruptPin();

    // ASIC 1273 chip enable: toggle WLAN EN line
    tSLInformation.WriteWlanPin( WLAN_ENABLE );

    if (ulSpiIRQState)
    {
        // wait till the IRQ line goes low
        while(tSLInformation.ReadWlanInterruptPin() != 0)
        {
        }
    }
    else
    {
        // Wait till the IRQ line goes high and then low.
        while(tSLInformation.ReadWlanInterruptPin() == 0)
        {
        }

        while(tSLInformation.ReadWlanInterruptPin() != 0)
        {
        }
    }

    SimpleLink_Init_Start(usPatchesAvailableAtHost);

    // Read Buffer's size and finish
    hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0);
    SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0);
}


//*****************************************************************************
//
//!  wlan_stop
//!
//!  @param         none
//!
//!  @return        none
//!
//!  @brief         Stop WLAN device by putting it into reset state.
//!
//!  @sa            wlan_start
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
void c_wlan_stop(void)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
void wlan_stop(void)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    // ASIC 1273 chip disable
    tSLInformation.WriteWlanPin( WLAN_DISABLE );

    // Wait till IRQ line goes high...
    while(tSLInformation.ReadWlanInterruptPin() == 0)
    {
    }

    // Free the used by WLAN Driver memory
    if (tSLInformation.pucTxCommandBuffer)
    {
        tSLInformation.pucTxCommandBuffer = 0;
    }

    SpiClose();
}


//*****************************************************************************
//
//!  wlan_connect
//!
//!  @param    sec_type   security options:
//!               WLAN_SEC_UNSEC,
//!               WLAN_SEC_WEP (ASCII support only),
//!               WLAN_SEC_WPA or WLAN_SEC_WPA2
//!  @param    ssid       up to 32 bytes and is ASCII SSID of the AP
//!  @param    ssid_len   length of the SSID
//!  @param    bssid      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.
//!              Note that even though a zero is returned on success to trigger
//!              connection operation, it does not mean that CCC3000 is already
//!              connected. An asynchronous "Connected" event is generated when
//!              actual association process finishes and CC3000 is connected to
//!              the AP. If DHCP is set, An asynchronous "DHCP" event is
//!              generated when DHCP process is finish.
//!
//!
//!  @brief      Connect to AP
//!  @warning    Please Note that when connection to AP configured with security
//!              type WEP, please confirm that the key is set as ASCII and not
//!              as HEX.
//!  @sa         wlan_disconnect
//
//*****************************************************************************

#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
                    unsigned char *bssid, unsigned char *key, long key_len)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
                  unsigned char *bssid, unsigned char *key, long key_len)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ret     = EFAIL;
    ptr     = tSLInformation.pucTxCommandBuffer;
    args    = (ptr + HEADERS_SIZE_CMD);

    // Fill in command buffer
    args = UINT32_TO_STREAM(args, 0x0000001c);
    args = UINT32_TO_STREAM(args, ssid_len);
    args = UINT32_TO_STREAM(args, ulSecType);
    args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
    args = UINT32_TO_STREAM(args, key_len);
    args = UINT16_TO_STREAM(args, 0);

    // padding shall be zeroed
    if(bssid)
    {
        ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
    }
    else
    {
        ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
    }

    ARRAY_TO_STREAM(args, ssid, ssid_len);

    if(key_len && key)
    {
        ARRAY_TO_STREAM(args, key, key_len);
    }

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN +
                                     ssid_len + key_len - 1);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret);
    errno = ret;

    return(ret);
}
#else
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_connect(char *ssid, long ssid_len)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_connect(char *ssid, long ssid_len)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ret     = EFAIL;
    ptr     = tSLInformation.pucTxCommandBuffer;
    args    = (ptr + HEADERS_SIZE_CMD);

    // Fill in command buffer
    args = UINT32_TO_STREAM(args, 0x0000001c);
    args = UINT32_TO_STREAM(args, ssid_len);
    args = UINT32_TO_STREAM(args, 0);
    args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
    args = UINT32_TO_STREAM(args, 0);
    args = UINT16_TO_STREAM(args, 0);

    // padding shall be zeroed
    ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
    ARRAY_TO_STREAM(args, ssid, ssid_len);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN +
                                     ssid_len  - 1);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret);
    errno = ret;

    return(ret);
}
#endif

//*****************************************************************************
//
//!  wlan_disconnect
//!
//!  @return    0 disconnected done, other CC3000 already disconnected
//!
//!  @brief      Disconnect connection from AP.
//!
//!  @sa         wlan_connect
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_disconnect(void)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_disconnect(void)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;

    hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret);
    errno = ret;

    return(ret);
}

//*****************************************************************************
//
//!  wlan_ioctl_set_connection_policy
//!
//!  @param    should_connect_to_open_ap  enable(1), disable(0) connect to any
//!            available AP. This parameter corresponds to the configuration of
//!            item # 3 in the brief description.
//!  @param    should_use_fast_connect enable(1), disable(0). if enabled, tries
//!            to connect to the last connected AP. This parameter corresponds
//!            to the configuration of item # 1 in the brief description.
//!  @param    auto_start enable(1), disable(0) auto connect
//!            after reset and periodically reconnect if needed. This
//!            configuration configures option 2 in the above description.
//!
//!  @return     On success, zero is returned. On error, -1 is returned
//!
//!  @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.
//!
//!  @sa         wlan_add_profile , wlan_ioctl_del_profile
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap,
                                        unsigned long ulShouldUseFastConnect,
                                        unsigned long ulUseProfiles)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap,
                                        unsigned long ulShouldUseFastConnect,
                                        unsigned long ulUseProfiles)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;
    args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
    args = UINT32_TO_STREAM(args, ulShouldUseFastConnect);
    args = UINT32_TO_STREAM(args, ulUseProfiles);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY,
                    ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);

    return(ret);
}

//*****************************************************************************
//
//!  wlan_add_profile
//!
//!  @param    ulSecType  WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
//!  @param    ucSsid    ssid  SSID up to 32 bytes
//!  @param    ulSsidLen ssid length
//!  @param    ucBssid   bssid  6 bytes
//!  @param    ulPriority ulPriority profile priority. Lowest priority:0.
//!			   Important Note: Smartconfig process (in unencrypted mode)
//!			   stores the profile internally with priority 1, so changing
//!			   priorities when adding new profiles should be done with extra care
//!  @param    ulPairwiseCipher_Or_TxKeyLen  key length for WEP security
//!  @param    ulGroupCipher_TxKeyIndex  key index
//!  @param    ulKeyMgmt        KEY management
//!  @param    ucPf_OrKey       security key
//!  @param    ulPassPhraseLen  security key length for WPA\WPA2
//!
//!  @return    On success, index (1-7) of the stored profile is returned.
//!				On error, -1 is returned.
//!
//!  @brief     When auto start is enabled, the device connects to
//!             station from the profiles table. Up to 7 profiles are supported.
//!             If several profiles configured the device choose the highest
//!             priority profile, within each priority group, device will choose
//!             profile based on security policy, signal strength, etc
//!             parameters. All the profiles are stored in CC3000 NVMEM.
//!
//!  @sa        wlan_ioctl_del_profile
//
//*****************************************************************************

#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    unsigned short arg_len;
    long ret;
    unsigned char *ptr;
    long i = 0;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    args = UINT32_TO_STREAM(args, ulSecType);

    // Setup arguments in accordance with the security type
    switch (ulSecType)
    {
        //OPEN
        case WLAN_SEC_UNSEC:
        {
            args = UINT32_TO_STREAM(args, 0x00000014);
            args = UINT32_TO_STREAM(args, ulSsidLen);
            args = UINT16_TO_STREAM(args, 0);
            if(ucBssid)
            {
                ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, ulPriority);
            ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

            arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen;
        }
        break;

        //WEP
        case WLAN_SEC_WEP:
        {
            args = UINT32_TO_STREAM(args, 0x00000020);
            args = UINT32_TO_STREAM(args, ulSsidLen);
            args = UINT16_TO_STREAM(args, 0);
            if(ucBssid)
            {
                ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, ulPriority);
            args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen);
            args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
            args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
            ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

            for(i = 0; i < 4; i++)
            {
                unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen];

                ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen);
            }

            arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen +
                ulPairwiseCipher_Or_TxKeyLen * 4;

        }
        break;

        //WPA
        //WPA2
        case WLAN_SEC_WPA:
        case WLAN_SEC_WPA2:
        {
            args = UINT32_TO_STREAM(args, 0x00000028);
            args = UINT32_TO_STREAM(args, ulSsidLen);
            args = UINT16_TO_STREAM(args, 0);
            if(ucBssid)
            {
                ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, ulPriority);
            args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
            args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
            args = UINT32_TO_STREAM(args, ulKeyMgmt);
            args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen);
            args = UINT32_TO_STREAM(args, ulPassPhraseLen);
            ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
            ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen);

            arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen;
        }

        break;

        //
        // An unrecognized security type was detected. Return an error.
        //
        default:
        {
            return(-1);
        }
    }

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE,
        ptr, arg_len);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);

    return(ret);
}
#else
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    return -1;
}
#endif

//*****************************************************************************
//
//!  wlan_ioctl_del_profile
//!
//!  @param    index   number of profile to delete
//!
//!  @return    On success, zero is returned. On error, -1 is returned
//!
//!  @brief     Delete WLAN profile
//!
//!  @Note      In order to delete all stored profile, set index to 255.
//!
//!  @sa        wlan_add_profile
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_del_profile(unsigned long ulIndex)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_del_profile(unsigned long ulIndex)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, ulIndex);
    ret = EFAIL;

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE,
        ptr, WLAN_DEL_PROFILE_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);

    return(ret);
}

//*****************************************************************************
//
//!  wlan_ioctl_get_scan_results
//!
//!  @param[in]    scan_timeout   parameter not supported
//!  @param[out]   ucResults  scan results (_wlan_full_scan_results_args_t)
//!
//!  @return    On success, zero is returned. On error, -1 is returned
//!
//!  @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. The following is a
//!            format of the scan result:
//!          - 4 Bytes: number of networks found
//!          - 4 Bytes: The status of the scan: 0 - aged results,
//!                     1 - results valid, 2 - no results
//!          - 42 bytes: Result entry, where the bytes are arranged as  follows:
//!
//!                         - 1 bit isValid - is result valid or not
//!                         - 7 bits rssi - RSSI value;
//!                 - 2 bits: securityMode - security mode of the AP:
//!                           0 - Open, 1 - WEP, 2 WPA, 3 WPA2
//!                         - 6 bits: SSID name length
//!                         - 2 bytes: the time at which the entry has entered into
//!                            scans result table
//!                         - 32 bytes: SSID name
//!                 - 6 bytes:  BSSID
//!
//!  @Note      scan_timeout, is not supported on this version.
//!
//!  @sa        wlan_ioctl_set_scan_params
//
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
                                   unsigned char *ucResults)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_get_scan_results(unsigned long ulScanTimeout,
                                   unsigned char *ucResults)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    unsigned char *ptr;
    unsigned char *args;

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    // Fill in temporary command buffer
    args = UINT32_TO_STREAM(args, ulScanTimeout);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS,
        ptr, WLAN_GET_SCAN_RESULTS_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS, ucResults);

    return(0);
}
#endif

//*****************************************************************************
//
//!  wlan_ioctl_set_scan_params
//!
//!  @param    uiEnable - start/stop application scan:
//!            1 = start scan with default interval value of 10 min.
//!            in order to set a different scan interval value apply the value
//!            in milliseconds. minimum 1 second. 0=stop). Wlan reset
//!           (wlan_stop() wlan_start()) is needed when changing scan interval
//!            value. Saved: No
//!  @param   uiMinDwellTime   minimum dwell time value to be used for each
//!           channel, in milliseconds. Saved: yes
//!           Recommended Value: 100 (Default: 20)
//!  @param   uiMaxDwellTime    maximum dwell time value to be used for each
//!           channel, in milliseconds. Saved: yes
//!           Recommended Value: 100 (Default: 30)
//!  @param   uiNumOfProbeRequests  max probe request between dwell time.
//!           Saved: yes. Recommended Value: 5 (Default:2)
//!  @param   uiChannelMask  bitwise, up to 13 channels (0x1fff).
//!           Saved: yes. Default: 0x7ff
//!  @param   uiRSSIThreshold   RSSI threshold. Saved: yes (Default: -80)
//!  @param   uiSNRThreshold    NSR threshold. Saved: yes (Default: 0)
//!  @param   uiDefaultTxPower  probe Tx power. Saved: yes (Default: 205)
//!  @param   aiIntervalList    pointer to array with 16 entries (16 channels)
//!           each entry (unsigned long) holds timeout between periodic scan
//!           (connection scan) - in millisecond. Saved: yes. Default 2000ms.
//!
//!  @return    On success, zero is returned. On error, -1 is returned
//!
//!  @brief    start and stop scan procedure. Set scan parameters.
//!
//!  @Note     uiDefaultTxPower, is not supported on this version.
//!
//!  @sa        wlan_ioctl_get_scan_results
//
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime,
                                  unsigned long uiMaxDwellTime, unsigned long uiNumOfProbeRequests,
                                  unsigned long uiChannelMask, long iRSSIThreshold,
                                  unsigned long uiSNRThreshold, unsigned long uiDefaultTxPower,
                                  unsigned long *aiIntervalList)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_set_scan_params(unsigned long uiEnable, unsigned long uiMinDwellTime,
                                  unsigned long uiMaxDwellTime, unsigned long uiNumOfProbeRequests,
                                  unsigned long uiChannelMask, long iRSSIThreshold,
                                  unsigned long uiSNRThreshold, unsigned long uiDefaultTxPower,
                                  unsigned long *aiIntervalList)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    unsigned long  uiRes;
    unsigned char *ptr;
    unsigned char *args;

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    // Fill in temporary command buffer
    args = UINT32_TO_STREAM(args, 36);
    args = UINT32_TO_STREAM(args, uiEnable);
    args = UINT32_TO_STREAM(args, uiMinDwellTime);
    args = UINT32_TO_STREAM(args, uiMaxDwellTime);
    args = UINT32_TO_STREAM(args, uiNumOfProbeRequests);
    args = UINT32_TO_STREAM(args, uiChannelMask);
    args = UINT32_TO_STREAM(args, iRSSIThreshold);
    args = UINT32_TO_STREAM(args, uiSNRThreshold);
    args = UINT32_TO_STREAM(args, uiDefaultTxPower);
    ARRAY_TO_STREAM(args, aiIntervalList, sizeof(unsigned long) *
                                    SL_SET_SCAN_PARAMS_INTERVAL_LIST_SIZE);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM,
        ptr, WLAN_SET_SCAN_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_SCANPARAM, &uiRes);

    return(uiRes);
}
#endif

//*****************************************************************************
//
//!  wlan_set_event_mask
//!
//!  @param    mask   mask option:
//!       HCI_EVNT_WLAN_UNSOL_CONNECT connect event
//!       HCI_EVNT_WLAN_UNSOL_DISCONNECT disconnect event
//!       HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE  smart config done
//!       HCI_EVNT_WLAN_UNSOL_INIT init done
//!       HCI_EVNT_WLAN_UNSOL_DHCP dhcp event report
//!       HCI_EVNT_WLAN_ASYNC_PING_REPORT ping report
//!       HCI_EVNT_WLAN_KEEPALIVE keepalive
//!       HCI_EVNT_WLAN_TX_COMPLETE - disable information on end of transmission
//!       Saved: no.
//!
//!  @return    On success, zero is returned. On error, -1 is returned
//!
//!  @brief    Mask event according to bit mask. In case that event is
//!            masked (1), the device will not send the masked event to host.
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_set_event_mask(unsigned long ulMask)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_set_event_mask(unsigned long ulMask)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;


    if ((ulMask & HCI_EVNT_WLAN_TX_COMPLETE) == HCI_EVNT_WLAN_TX_COMPLETE)
    {
        tSLInformation.InformHostOnTxComplete = 0;

        // Since an event is a virtual event - i.e. it is not coming from CC3000
        // there is no need to send anything to the device if it was an only event
        if (ulMask == HCI_EVNT_WLAN_TX_COMPLETE)
        {
            return 0;
        }

        ulMask &= ~HCI_EVNT_WLAN_TX_COMPLETE;
        ulMask |= HCI_EVNT_WLAN_UNSOL_BASE;
    }
    else
    {
        tSLInformation.InformHostOnTxComplete = 1;
    }

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;
    args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, ulMask);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_EVENT_MASK,
        ptr, WLAN_SET_MASK_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_EVENT_MASK, &ret);

    return(ret);
}

//*****************************************************************************
//
//!  wlan_ioctl_statusget
//!
//!  @param none
//!
//!  @return    WLAN_STATUS_DISCONNECTED, WLAN_STATUS_SCANING,
//!             STATUS_CONNECTING or WLAN_STATUS_CONNECTED
//!
//!  @brief    get wlan status: disconnected, scanning, connecting or connected
//
//*****************************************************************************
#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_statusget(void)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_statusget(void)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;

    hci_command_send(HCI_CMND_WLAN_IOCTL_STATUSGET,
        ptr, 0);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_STATUSGET, &ret);

    return(ret);
}
#endif

//*****************************************************************************
//
//!  wlan_smart_config_start
//!
//!  @param    algoEncryptedFlag indicates whether the information is encrypted
//!
//!  @return   On success, zero is returned. On error, -1 is returned
//!
//!  @brief   Start to acquire device profile. The device acquire its own
//!           profile, if profile message is found. The acquired AP information
//!           is stored in CC3000 EEPROM only in case AES128 encryption is used.
//!           In case AES128 encryption is not used, a profile is created by
//!           CC3000 internally.
//!
//!  @Note    An asynchronous event - Smart Config Done will be generated as soon
//!           as the process finishes successfully.
//!
//!  @sa      wlan_smart_config_set_prefix , wlan_smart_config_stop
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_smart_config_start(unsigned long algoEncryptedFlag)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_smart_config_start(unsigned long algoEncryptedFlag)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;
    args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, algoEncryptedFlag);
    ret = EFAIL;

    hci_command_send(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, ptr,
                                     WLAN_SMART_CONFIG_START_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START, &ret);

    return(ret);
}
    /* init io callback */
    tSLInformation.ReadWlanInterruptPin = sReadWlanInterruptPin;
    tSLInformation.WlanInterruptEnable  = sWlanInterruptEnable;
    tSLInformation.WlanInterruptDisable = sWlanInterruptDisable;
    tSLInformation.WriteWlanPin = sWriteWlanPin;

    //init asynchronous events callback
    tSLInformation.sWlanCB= sWlanCB;

    // By default TX Complete events are routed to host too
    tSLInformation.InformHostOnTxComplete = 1;
}

//*****************************************************************************
//
//!  SpiReceiveHandler
//!
//!  @param         pvBuffer - pointer to the received data buffer
//!                      The function triggers Received event/data processing
//!
//!  @param         Pointer to the received data
//!  @return        none
//!
//!  @brief         The function triggers Received event/data processing. It is
//!                       called from the SPI library to receive the data
//
//*****************************************************************************
void SpiReceiveHandler(void *pvBuffer)
{
    tSLInformation.usEventOrDataReceived = 1;
    tSLInformation.pucReceivedData = (unsigned char     *)pvBuffer;

    hci_unsolicited_event_handler();
}


//*****************************************************************************
//
//!  wlan_start
//!
//!  @param   usPatchesAvailableAtHost -  flag to indicate if patches available
//!                                    from host or from EEPROM. Due to the
//!                                    fact the patches are burn to the EEPROM
//!                                    using the patch programmer utility, the
//!                                    patches will be available from the EEPROM
//!                                    and not from the host.
//!
//!  @return        none
//!
//!  @brief        Start WLAN device. This function asserts the enable pin of
//!                the device (WLAN_EN), starting the HW initialization process.
//!                The function blocked until device Initialization is completed.
//!                Function also configure patches (FW, driver or bootloader)
//!                and calls appropriate device callbacks.
//!
//!  @Note          Prior calling the function wlan_init shall be called.
//!  @Warning       This function must be called after wlan_init and before any
//!                 other wlan API
//!  @sa            wlan_init , wlan_stop
//!
//
//*****************************************************************************

#ifdef __ENABLE_MULTITHREADED_SUPPORT__
void c_wlan_start(unsigned short usPatchesAvailableAtHost)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
void wlan_start(unsigned short usPatchesAvailableAtHost)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{

    unsigned long ulSpiIRQState;

    tSLInformation.NumberOfSentPackets = 0;
    tSLInformation.NumberOfReleasedPackets = 0;
    tSLInformation.usRxEventOpcode = 0;
    tSLInformation.usNumberOfFreeBuffers = 0;
    tSLInformation.usSlBufferLength = 0;
    tSLInformation.usBufferSize = 0;
    tSLInformation.usRxDataPending = 0;
    tSLInformation.slTransmitDataError = 0;
    tSLInformation.usEventOrDataReceived = 0;
    tSLInformation.pucReceivedData = 0;

    // Allocate the memory for the RX/TX data transactions
    tSLInformation.pucTxCommandBuffer = (unsigned char *)wlan_tx_buffer;

    // init spi
    SpiOpen(SpiReceiveHandler);

    // Check the IRQ line
    ulSpiIRQState = tSLInformation.ReadWlanInterruptPin();

    // ASIC 1273 chip enable: toggle WLAN EN line
    tSLInformation.WriteWlanPin( WLAN_ENABLE );

    if (ulSpiIRQState)
    {
        // wait till the IRQ line goes low
        while(tSLInformation.ReadWlanInterruptPin() != 0)
        {
        }
    }
    else
    {
        // Wait till the IRQ line goes high and then low.
        while(tSLInformation.ReadWlanInterruptPin() == 0)
        {
        }

        while(tSLInformation.ReadWlanInterruptPin() != 0)
        {
        }
    }

    SimpleLink_Init_Start(usPatchesAvailableAtHost);

    // Read Buffer's size and finish
    hci_command_send(HCI_CMND_READ_BUFFER_SIZE, tSLInformation.pucTxCommandBuffer, 0);
    SimpleLinkWaitEvent(HCI_CMND_READ_BUFFER_SIZE, 0);
}


//*****************************************************************************
//
//!  wlan_stop
//!
//!  @param         none
//!
//!  @return        none
//!
//!  @brief         Stop WLAN device by putting it into reset state.
//!
//!  @sa            wlan_start
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
void c_wlan_stop(void)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
void wlan_stop(void)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    // ASIC 1273 chip disable
    tSLInformation.WriteWlanPin( WLAN_DISABLE );

    // Wait till IRQ line goes high...
    while(tSLInformation.ReadWlanInterruptPin() == 0)
    {
    }

    // Free the used by WLAN Driver memory
    if (tSLInformation.pucTxCommandBuffer)
    {
        tSLInformation.pucTxCommandBuffer = 0;
    }

    SpiClose();
}


//*****************************************************************************
//
//!  wlan_connect
//!
//!  @param    sec_type   security options:
//!               WLAN_SEC_UNSEC,
//!               WLAN_SEC_WEP (ASCII support only),
//!               WLAN_SEC_WPA or WLAN_SEC_WPA2
//!  @param    ssid       up to 32 bytes and is ASCII SSID of the AP
//!  @param    ssid_len   length of the SSID
//!  @param    bssid      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.
//!              Note that even though a zero is returned on success to trigger
//!              connection operation, it does not mean that CCC3000 is already
//!              connected. An asynchronous "Connected" event is generated when
//!              actual association process finishes and CC3000 is connected to
//!              the AP. If DHCP is set, An asynchronous "DHCP" event is
//!              generated when DHCP process is finish.
//!
//!
//!  @brief      Connect to AP
//!  @warning    Please Note that when connection to AP configured with security
//!              type WEP, please confirm that the key is set as ASCII and not
//!              as HEX.
//!  @sa         wlan_disconnect
//
//*****************************************************************************

#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
                    unsigned char *bssid, unsigned char *key, long key_len)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_connect(unsigned long ulSecType, char *ssid, long ssid_len,
                  unsigned char *bssid, unsigned char *key, long key_len)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ret     = EFAIL;
    ptr     = tSLInformation.pucTxCommandBuffer;
    args    = (ptr + HEADERS_SIZE_CMD);

    // Fill in command buffer
    args = UINT32_TO_STREAM(args, 0x0000001c);
    args = UINT32_TO_STREAM(args, ssid_len);
    args = UINT32_TO_STREAM(args, ulSecType);
    args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
    args = UINT32_TO_STREAM(args, key_len);
    args = UINT16_TO_STREAM(args, 0);

    // padding shall be zeroed
    if(bssid)
    {
        ARRAY_TO_STREAM(args, bssid, ETH_ALEN);
    }
    else
    {
        ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
    }

    ARRAY_TO_STREAM(args, ssid, ssid_len);

    if(key_len && key)
    {
        ARRAY_TO_STREAM(args, key, key_len);
    }

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN +
                                     ssid_len + key_len - 1);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret);
    errno = ret;

    return(ret);
}
#else
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_connect(char *ssid, long ssid_len)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_connect(char *ssid, long ssid_len)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ret     = EFAIL;
    ptr     = tSLInformation.pucTxCommandBuffer;
    args    = (ptr + HEADERS_SIZE_CMD);

    // Fill in command buffer
    args = UINT32_TO_STREAM(args, 0x0000001c);
    args = UINT32_TO_STREAM(args, ssid_len);
    args = UINT32_TO_STREAM(args, 0);
    args = UINT32_TO_STREAM(args, 0x00000010 + ssid_len);
    args = UINT32_TO_STREAM(args, 0);
    args = UINT16_TO_STREAM(args, 0);

    // padding shall be zeroed
    ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
    ARRAY_TO_STREAM(args, ssid, ssid_len);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_CONNECT, ptr, WLAN_CONNECT_PARAM_LEN +
                                     ssid_len  - 1);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_CONNECT, &ret);
    errno = ret;

    return(ret);
}
#endif

//*****************************************************************************
//
//!  wlan_disconnect
//!
//!  @return    0 disconnected done, other CC3000 already disconnected
//!
//!  @brief      Disconnect connection from AP.
//!
//!  @sa         wlan_connect
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_disconnect(void)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_disconnect(void)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;

    hci_command_send(HCI_CMND_WLAN_DISCONNECT, ptr, 0);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_DISCONNECT, &ret);
    errno = ret;

    return(ret);
}

//*****************************************************************************
//
//!  wlan_ioctl_set_connection_policy
//!
//!  @param    should_connect_to_open_ap  enable(1), disable(0) connect to any
//!            available AP. This parameter corresponds to the configuration of
//!            item # 3 in the brief description.
//!  @param    should_use_fast_connect enable(1), disable(0). if enabled, tries
//!            to connect to the last connected AP. This parameter corresponds
//!            to the configuration of item # 1 in the brief description.
//!  @param    auto_start enable(1), disable(0) auto connect
//!            after reset and periodically reconnect if needed. This
//!            configuration configures option 2 in the above description.
//!
//!  @return     On success, zero is returned. On error, -1 is returned
//!
//!  @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.
//!
//!  @sa         wlan_add_profile , wlan_ioctl_del_profile
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap,
                                        unsigned long ulShouldUseFastConnect,
                                        unsigned long ulUseProfiles)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_set_connection_policy(unsigned long should_connect_to_open_ap,
                                        unsigned long ulShouldUseFastConnect,
                                        unsigned long ulUseProfiles)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;

    ret = EFAIL;
    ptr = tSLInformation.pucTxCommandBuffer;
    args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, should_connect_to_open_ap);
    args = UINT32_TO_STREAM(args, ulShouldUseFastConnect);
    args = UINT32_TO_STREAM(args, ulUseProfiles);

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY,
                    ptr, WLAN_SET_CONNECTION_POLICY_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY, &ret);

    return(ret);
}

//*****************************************************************************
//
//!  wlan_add_profile
//!
//!  @param    ulSecType  WLAN_SEC_UNSEC,WLAN_SEC_WEP,WLAN_SEC_WPA,WLAN_SEC_WPA2
//!  @param    ucSsid    ssid  SSID up to 32 bytes
//!  @param    ulSsidLen ssid length
//!  @param    ucBssid   bssid  6 bytes
//!  @param    ulPriority ulPriority profile priority. Lowest priority:0.
//!			   Important Note: Smartconfig process (in unencrypted mode)
//!			   stores the profile internally with priority 1, so changing
//!			   priorities when adding new profiles should be done with extra care
//!  @param    ulPairwiseCipher_Or_TxKeyLen  key length for WEP security
//!  @param    ulGroupCipher_TxKeyIndex  key index
//!  @param    ulKeyMgmt        KEY management
//!  @param    ucPf_OrKey       security key
//!  @param    ulPassPhraseLen  security key length for WPA\WPA2
//!
//!  @return    On success, index (1-7) of the stored profile is returned.
//!				On error, -1 is returned.
//!
//!  @brief     When auto start is enabled, the device connects to
//!             station from the profiles table. Up to 7 profiles are supported.
//!             If several profiles configured the device choose the highest
//!             priority profile, within each priority group, device will choose
//!             profile based on security policy, signal strength, etc
//!             parameters. All the profiles are stored in CC3000 NVMEM.
//!
//!  @sa        wlan_ioctl_del_profile
//
//*****************************************************************************

#ifndef CC3000_TINY_DRIVER
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    unsigned short arg_len;
    long ret;
    unsigned char *ptr;
    long i = 0;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    args = UINT32_TO_STREAM(args, ulSecType);

    // Setup arguments in accordance with the security type
    switch (ulSecType)
    {
        //OPEN
        case WLAN_SEC_UNSEC:
        {
            args = UINT32_TO_STREAM(args, 0x00000014);
            args = UINT32_TO_STREAM(args, ulSsidLen);
            args = UINT16_TO_STREAM(args, 0);
            if(ucBssid)
            {
                ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, ulPriority);
            ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

            arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen;
        }
        break;

        //WEP
        case WLAN_SEC_WEP:
        {
            args = UINT32_TO_STREAM(args, 0x00000020);
            args = UINT32_TO_STREAM(args, ulSsidLen);
            args = UINT16_TO_STREAM(args, 0);
            if(ucBssid)
            {
                ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, ulPriority);
            args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen);
            args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
            args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
            ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

            for(i = 0; i < 4; i++)
            {
                unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen];

                ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen);
            }

            arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen +
                ulPairwiseCipher_Or_TxKeyLen * 4;

        }
        break;

        //WPA
        //WPA2
        case WLAN_SEC_WPA:
        case WLAN_SEC_WPA2:
        {
            args = UINT32_TO_STREAM(args, 0x00000028);
            args = UINT32_TO_STREAM(args, ulSsidLen);
            args = UINT16_TO_STREAM(args, 0);
            if(ucBssid)
            {
                ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, ulPriority);
            args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
            args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
            args = UINT32_TO_STREAM(args, ulKeyMgmt);
            args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen);
            args = UINT32_TO_STREAM(args, ulPassPhraseLen);
            ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
            ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen);

            arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen;
        }

        break;

        //
        // An unrecognized security type was detected. Return an error.
        //
        default:
        {
            return(-1);
        }
    }

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE,
        ptr, arg_len);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);

    return(ret);
}
#else
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_add_profile(unsigned long ulSecType,
                                        unsigned char* ucSsid,
                                        unsigned long ulSsidLen,
                                        unsigned char *ucBssid,
                                        unsigned long ulPriority,
                                        unsigned long ulPairwiseCipher_Or_TxKeyLen,
                                        unsigned long ulGroupCipher_TxKeyIndex,
                                        unsigned long ulKeyMgmt,
                                        unsigned char* ucPf_OrKey,
                                        unsigned long ulPassPhraseLen)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    return -1;
}
#endif

//*****************************************************************************
//
//!  wlan_ioctl_del_profile
//!
//!  @param    index   number of profile to delete
//!
//!  @return    On success, zero is returned. On error, -1 is returned
//!
//!  @brief     Delete WLAN profile
//!
//!  @Note      In order to delete all stored profile, set index to 255.
//!
//!  @sa        wlan_add_profile
//
//*****************************************************************************
#ifdef __ENABLE_MULTITHREADED_SUPPORT__
long c_wlan_ioctl_del_profile(unsigned long ulIndex)
#else /* __ENABLE_MULTITHREADED_SUPPORT__ */
long wlan_ioctl_del_profile(unsigned long ulIndex)
#endif /* __ENABLE_MULTITHREADED_SUPPORT__ */
{
    long ret;
    unsigned char *ptr;
    unsigned char *args;

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (unsigned char *)(ptr + HEADERS_SIZE_CMD);

    // Fill in HCI packet structure
    args = UINT32_TO_STREAM(args, ulIndex);
    ret = EFAIL;

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_DEL_PROFILE,
        ptr, WLAN_DEL_PROFILE_PARAMS_LEN);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_DEL_PROFILE, &ret);

    return(ret);
}
Example #9
0
//*****************************************************************************
//
//! accept
//!
//!  @param[in]   sd      socket descriptor (handle)
//!  @param[out]  addr    the argument addr is a pointer to a sockaddr structure
//!                       This structure is filled in with the address of the
//!                       peer socket, as known to the communications layer.
//!                       determined. The exact format of the address returned
//!                       addr is by the socket's address sockaddr.
//!                       On this version only AF_INET is supported.
//!                       This argument returns in network order.
//!  @param[out] addrlen  the addrlen argument is a value-result argument:
//!                       it should initially contain the size of the structure
//!                       pointed to by addr.
//!
//!  @return  For socket in blocking mode:
//!                   On success, socket handle. on failure negative
//!               For socket in non-blocking mode:
//!                  - On connection establishment, socket handle
//!                  - On connection pending, SOC_IN_PROGRESS (-2)
//!                - On failure, SOC_ERROR  (-1)
//!
//!  @brief  accept a connection on a socket:
//!          This function is used with connection-based socket types
//!          (SOCK_STREAM). It extracts the first connection request on the
//!          queue of pending connections, creates a new connected socket, and
//!          returns a new file descriptor referring to that socket.
//!          The newly created socket is not in the listening state.
//!          The original socket sd is unaffected by this call.
//!          The argument sd is a socket that has been created with socket(),
//!          bound to a local address with bind(), and is  listening for
//!          connections after a listen(). The argument addr is a pointer
//!          to a sockaddr structure. This structure is filled in with the
//!          address of the peer socket, as known to the communications layer.
//!          The exact format of the address returned addr is determined by the
//!          socket's address family. The addrlen argument is a value-result
//!          argument: it should initially contain the size of the structure
//!          pointed to by addr, on return it will contain the actual
//!          length (in bytes) of the address returned.
//!
//! @sa     socket ; bind ; listen
//
//*****************************************************************************
long c_accept(long sd, sockaddr *addr, socklen_t *addrlen)
{
  long ret;
  uint8_t *args;
  tBsdReturnParams tAcceptReturnArguments;

  ret = EFAIL;
  args = hci_get_cmd_buffer();

  // Fill in temporary command buffer
  args = UINT32_TO_STREAM(args, sd);

  // Initiate a HCI command
  hci_command_send(HCI_CMND_ACCEPT, SOCKET_ACCEPT_PARAMS_LEN,
      HCI_CMND_ACCEPT, &tAcceptReturnArguments);

  // need specify return parameters!!!
  memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN);
  *addrlen = ASIC_ADDR_LEN;
  errno = tAcceptReturnArguments.iStatus;
  ret = errno;

  return(ret);
}
Example #10
0
int
select(long nfds, TICC3000fd_set *readsds, TICC3000fd_set *writesds, TICC3000fd_set *exceptsds, 
       struct timeval *timeout)
{
	unsigned char *ptr, *args;
	tBsdSelectRecvParams tParams;
	unsigned long is_blocking;
	
	if( timeout == NULL)
	{
		is_blocking = 1; /* blocking , infinity timeout */
	}
	else
	{
		is_blocking = 0; /* no blocking, timeout */
	}
	
	// Fill in HCI packet structure
	ptr = tSLInformation.pucTxCommandBuffer;
	args = (ptr + HEADERS_SIZE_CMD);
	
	// Fill in temporary command buffer
	args = UINT32_TO_STREAM(args, nfds);
	args = UINT32_TO_STREAM(args, 0x00000014);
	args = UINT32_TO_STREAM(args, 0x00000014);
	args = UINT32_TO_STREAM(args, 0x00000014);
	args = UINT32_TO_STREAM(args, 0x00000014);
	args = UINT32_TO_STREAM(args, is_blocking);
	args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0));
	args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0));
	args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0));
	
	if (timeout)
	{
		if ( 0 == timeout->tv_sec && timeout->tv_usec < 
				SELECT_TIMEOUT_MIN_MICRO_SECONDS)
		{
			timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
		}
		args = UINT32_TO_STREAM(args, timeout->tv_sec);
		args = UINT32_TO_STREAM(args, timeout->tv_usec);
	}
	
	// Initiate a HCI command
	hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN);
	
	// Since we are in blocking state - wait for event complete
	SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams);
	
	// Update actually read FD
	if (tParams.iStatus >= 0)
	{
		if (readsds)
		{
			memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));
		}
		
		if (writesds)
		{
			memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); 
		}
		
		if (exceptsds)
		{
			memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); 
		}
		
		return(tParams.iStatus);
		
	}
	else
	{
		errno = tParams.iStatus;
		return(-1);
	}
}
Example #11
0
//*****************************************************************************
//
//!  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
//!                  occurred, or -2 in case there are no free buffers available
//!                 (only when SEND_NON_BLOCKING is enabled)
//!
//!  @brief          This function is used to transmit a message to another
//!                  socket
//
//*****************************************************************************
int
simple_link_send(long sd, const void *buf, long len, long flags,
              const sockaddr *to, long tolen, long opcode)
{    
	unsigned char uArgSize,  addrlen;
	unsigned char *ptr, *pDataPtr, *args;
	unsigned long addr_offset;
	int res;
        tBsdReadReturnParams tSocketSendEvent;
	
	// Check the bsd_arguments
	if (0 != (res = HostFlowControlConsumeBuff(sd)))
	{
		return res;
	}
	
	//Update the number of sent packets
	tSLInformation.NumberOfSentPackets++;
	
	// Allocate a buffer and construct a packet and send it over spi
	ptr = tSLInformation.pucTxCommandBuffer;
	args = (ptr + HEADERS_SIZE_DATA);
	
	// Update the offset of data and parameters according to the command
	switch(opcode)
	{ 
	case HCI_CMND_SENDTO:
		{
			addr_offset = len + sizeof(len) + sizeof(len);
			addrlen = 8;
			uArgSize = SOCKET_SENDTO_PARAMS_LEN;
			pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN;
			break;
		}
		
	case HCI_CMND_SEND:
		{
			tolen = 0;
			to = NULL;
			uArgSize = HCI_CMND_SEND_ARG_LENGTH;
			pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH;
			break;
		}
		
	default:
		{
			break;
		}
	}
	
	// Fill in temporary command buffer
	args = UINT32_TO_STREAM(args, sd);
	args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
	args = UINT32_TO_STREAM(args, len);
	args = UINT32_TO_STREAM(args, flags);
	
	if (opcode == HCI_CMND_SENDTO)
	{
		args = UINT32_TO_STREAM(args, addr_offset);
		args = UINT32_TO_STREAM(args, addrlen);
	}
	
	// Copy the data received from user into the TX Buffer
	ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len);
	
	// In case we are using SendTo, copy the to parameters
	if (opcode == HCI_CMND_SENDTO)
	{	
		ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen);
	}
	
	// Initiate a HCI command
	hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen);
        
         if (opcode == HCI_CMND_SENDTO)
            SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent);
         else
            SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent);
	
	return	(len);
}
Example #12
0
unsigned char *
hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
{
	unsigned char *pucReceivedData, ucArgsize;
	unsigned short usLength;
	unsigned char *pucReceivedParams;
	unsigned short usReceivedEventOpcode = 0;
	unsigned long retValue32;
    unsigned char * RecvParams;
    unsigned char *RetParams;

    JsSysTime timeout = jshGetSystemTime() + jshGetTimeFromMilliseconds(10000); // blocking for 10 seconds (!!!)

	cc3000_irq_disable();
	while (!jspIsInterrupted())
	{
		if (tSLInformation.usEventOrDataReceived != 0)
		{				
			pucReceivedData = (tSLInformation.pucReceivedData);

			if (*pucReceivedData == HCI_TYPE_EVNT)
			{
				// Event Received
				STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET,
												 usReceivedEventOpcode);
				pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;		
				RecvParams = pucReceivedParams;
				RetParams = pRetParams;
				
				// In case unsolicited event received - here the handling finished
				if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
				{
					STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
					
					switch(usReceivedEventOpcode)
					{		
					case HCI_CMND_READ_BUFFER_SIZE:
						{
							STREAM_TO_UINT8((char *)pucReceivedParams, 0, 
															tSLInformation.usNumberOfFreeBuffers);
							STREAM_TO_UINT16((char *)pucReceivedParams, 1, 
															 tSLInformation.usSlBufferLength);
						}
						break;
						
					case HCI_CMND_WLAN_CONFIGURE_PATCH:
					case HCI_NETAPP_DHCP:
					case HCI_NETAPP_PING_SEND:
					case HCI_NETAPP_PING_STOP:
					case HCI_NETAPP_ARP_FLUSH:
					case HCI_NETAPP_SET_DEBUG_LEVEL:
					case HCI_NETAPP_SET_TIMERS:
					case HCI_EVNT_NVMEM_READ:
					case HCI_EVNT_NVMEM_CREATE_ENTRY:
					case HCI_CMND_NVMEM_WRITE_PATCH:
					case HCI_NETAPP_PING_REPORT:
					case HCI_EVNT_MDNS_ADVERTISE:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
														,*(unsigned char *)pRetParams);
						break;
						
					case HCI_CMND_SETSOCKOPT:
					case HCI_CMND_WLAN_CONNECT:
					case HCI_CMND_WLAN_IOCTL_STATUSGET:
					case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
					case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
					case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
					case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
					case HCI_CMND_EVENT_MASK:
					case HCI_EVNT_WLAN_DISCONNECT:
					case HCI_EVNT_SOCKET:
					case HCI_EVNT_BIND:
					case HCI_CMND_LISTEN:
					case HCI_EVNT_CLOSE_SOCKET:
					case HCI_EVNT_CONNECT:
					case HCI_EVNT_NVMEM_WRITE:
						
						STREAM_TO_UINT32((char *)pucReceivedParams,0
														 ,*(unsigned long *)pRetParams);
						break;
						
					case HCI_EVNT_READ_SP_VERSION:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
														,*(unsigned char *)pRetParams);
						pRetParams = ((char *)pRetParams) + 1;
						STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
						UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);				
						break;
						
					case HCI_EVNT_BSD_GETHOSTBYNAME:
						
						STREAM_TO_UINT32((char *)pucReceivedParams
						      ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;
						STREAM_TO_UINT32((char *)pucReceivedParams
									,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);					
						break;
						
					case HCI_EVNT_ACCEPT:
						{
							STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET
															 ,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams
										,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
              pRetParams = ((char *)pRetParams) + 4; 
							
							//This argument returns in network order
							memcpy((unsigned char *)pRetParams, 
								  pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));	
							break;
						}
						
					case HCI_EVNT_RECV:
					case HCI_EVNT_RECVFROM:
						{
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);
							
							if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
							{
								set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
							}
							break;
						}
                                                
                                        case HCI_EVNT_SEND:
					case HCI_EVNT_SENDTO:
						{
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							
							break;
						}
						
					case HCI_EVNT_SELECT:
						{ 
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);			
							break;
						}
						
					case HCI_CMND_GETSOCKOPT:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
						//This argument returns in network order
						memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
						break;
						
					case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
						
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;   					
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;                                                        					
						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 2;   					
						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 2;  
						memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);	
						break;
						
					case HCI_CMND_SIMPLE_LINK_START:
						break;
						
					case HCI_NETAPP_IPCONFIG:
						
						//Read IP address
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read subnet
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read default GW
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read DHCP server                                          	
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read DNS server                                           
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read Mac address                            	
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
						RecvParams += 6;
						
						//Read SSID
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
	
					}
				}
				
				if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
				{
					tSLInformation.usRxEventOpcode = 0;
				}
			}
			else
			{
				pucReceivedParams = pucReceivedData;
				STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
				
				STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);

				// Data received: note that the only case where from and from length 
				// are not null is in recv from, so fill the args accordingly
				if (from)
				{
					STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
					memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
				}
				
				if (pRetParams) // GW: just in case. It'll probably still crash though :(
				  memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
							 usLength - ucArgsize);
				
				tSLInformation.usRxDataPending = 0;
			}
		
			tSLInformation.usEventOrDataReceived = 0;
			
			cc3000_spi_resume();
			
			// Since we are going to TX - we need to handle this event after the 
			// ResumeSPi since we need interrupts
			if ((*pucReceivedData == HCI_TYPE_EVNT) &&
					(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
			{
				hci_unsol_handle_patch_request((char *)pucReceivedData);
			}
			
			if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
			{
			  cc3000_irq_enable();
		      return NULL;
			}	
		} else
		    cc3000_check_irq_pin();

		if (jshGetSystemTime() > timeout) {
                  jspSetInterrupted(true);
		  jsError("Timeout in CC3000 driver (%d)", tSLInformation.usRxEventOpcode);
		  break;
		}
	}
	cc3000_irq_enable();
        return NULL;
}
uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) {
    uint8_t *received_data, argument_size;
    uint16_t length;
    uint8_t *pucReceivedParams;
    uint16_t received_op_code = 0;
    uint32_t return_value;
    uint8_t * RecvParams;
    uint8_t *RetParams;

    while (1)
    {
        if (_simple_link.get_data_received_flag() != 0)
        {
            received_data = _simple_link.get_received_data();
            if (*received_data == HCI_TYPE_EVNT)
            {
                // Event Received
                STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code);
                pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE;
                RecvParams = pucReceivedParams;
                RetParams = (uint8_t *)ret_param;

                // unsolicited event received - finish handling
                if (hci_unsol_event_handler((uint8_t *)received_data) == 0)
                {
                    STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length);

                    hci_event_debug_print( received_op_code );

                    switch(received_op_code)
                    {
                    case HCI_CMND_READ_BUFFER_SIZE:
                        {
                            uint16_t temp = _simple_link.get_number_free_buffers();
                            STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp);
                            _simple_link.set_number_free_buffers(temp);

                            temp = _simple_link.get_buffer_length();
                            STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp);
                            _simple_link.set_buffer_length(temp);
                        }
                        break;

                    case HCI_CMND_WLAN_CONFIGURE_PATCH:
                    case HCI_NETAPP_DHCP:
                    case HCI_NETAPP_PING_SEND:
                    case HCI_NETAPP_PING_STOP:
                    case HCI_NETAPP_ARP_FLUSH:
                    case HCI_NETAPP_SET_DEBUG_LEVEL:
                    case HCI_NETAPP_SET_TIMERS:
                    case HCI_EVNT_NVMEM_READ:
                    case HCI_EVNT_NVMEM_CREATE_ENTRY:
                    case HCI_CMND_NVMEM_WRITE_PATCH:
                    case HCI_NETAPP_PING_REPORT:
                    case HCI_EVNT_MDNS_ADVERTISE:

                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
                        break;

                    case HCI_CMND_SETSOCKOPT:
                    case HCI_CMND_WLAN_CONNECT:
                    case HCI_CMND_WLAN_IOCTL_STATUSGET:
                    case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
                    case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
                    case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
                    case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
                    case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
                    case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
                    case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
                    case HCI_CMND_EVENT_MASK:
                    case HCI_EVNT_WLAN_DISCONNECT:
                    case HCI_EVNT_SOCKET:
                    case HCI_EVNT_BIND:
                    case HCI_CMND_LISTEN:
                    case HCI_EVNT_CLOSE_SOCKET:
                    case HCI_EVNT_CONNECT:
                    case HCI_EVNT_NVMEM_WRITE:

                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param);
                        break;

                    case HCI_EVNT_READ_SP_VERSION:

                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param);
                        ret_param = ((uint8_t *)ret_param) + 1;
                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value);
                        UINT32_TO_STREAM((uint8_t *)ret_param, return_value);
                        break;

                    case HCI_EVNT_BSD_GETHOSTBYNAME:

                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param);
                        ret_param = ((uint8_t *)ret_param) + 4;
                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param);
                        break;

                    case HCI_EVNT_ACCEPT:
                        {
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;

                            //This argument returns in network order
                            memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
                            break;
                        }

                    case HCI_EVNT_RECV:
                    case HCI_EVNT_RECVFROM:
                        {
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param);

                            if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
                            {
                                set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
                            }
                            break;
                        }

                    case HCI_EVNT_SEND:
                    case HCI_EVNT_SENDTO:
                        {
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;

                            break;
                        }

                    case HCI_EVNT_SELECT:
                        {
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param);
                            ret_param = ((uint8_t *)ret_param) + 4;
                            STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param);
                            break;
                        }

                    case HCI_CMND_GETSOCKOPT:

                        STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus);
                        //This argument returns in network order
                        memcpy((uint8_t *)ret_param, pucReceivedParams, 4);
                        break;

                    case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:

                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param);
                        ret_param = ((uint8_t *)ret_param) + 4;
                        STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param);
                        ret_param = ((uint8_t *)ret_param) + 4;
                        STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param);
                        ret_param = ((uint8_t *)ret_param) + 2;
                        STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param);
                        ret_param = ((uint8_t *)ret_param) + 2;
                        memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);
                        break;

                    case HCI_CMND_SIMPLE_LINK_START:
                        break;

                    case HCI_NETAPP_IPCONFIG:

                        //Read IP address
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                        RecvParams += 4;

                        //Read subnet
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                        RecvParams += 4;

                        //Read default GW
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                        RecvParams += 4;

                        //Read DHCP server
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                        RecvParams += 4;

                        //Read DNS server
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                        RecvParams += 4;

                        //Read Mac address
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
                        RecvParams += 6;

                        //Read SSID
                        STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
                        break;

                    default :
                        DBG_HCI("UNKNOWN Event Received : 0x%04X ", received_op_code);
                        break;
                    }

                }
                if (received_op_code == _simple_link.get_op_code())
                {
                    _simple_link.set_op_code(0);
                }
            }
            else
            {
                pucReceivedParams = received_data;
                STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size);

                STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length);

                // Data received: note that the only case where from and from length
                // are not null is in recv from, so fill the args accordingly
                if (from)
                {
                    STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen);
                    memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
                }

                memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size);

                _simple_link.set_pending_data(0);
            }

            _simple_link.set_data_received_flag(0);
            _spi.wlan_irq_enable();

            // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts
            if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ))
            {
                hci_unsol_handle_patch_request((uint8_t *)received_data);
            }
            if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0))
            {
                return NULL;
            }
        }
    }
}
uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen)
{
  uint8_t *pucReceivedData, ucArgsize;
  uint16_t usLength;
  uint8_t *pucReceivedParams;
  uint16_t usReceivedEventOpcode = 0;
  unsigned long retValue32;
  uint8_t * RecvParams;
  uint8_t *RetParams;

  while (1)
    {
      if (tSLInformation.usEventOrDataReceived != 0) {
          pucReceivedData = (tSLInformation.pucReceivedData);

          if (*pucReceivedData == HCI_TYPE_EVNT)
            {
              /* Event Received */

              STREAM_TO_UINT16((char *)pucReceivedData,
                               HCI_EVENT_OPCODE_OFFSET,
                               usReceivedEventOpcode);

              pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;
              RecvParams = pucReceivedParams;
              RetParams = (uint8_t *)pRetParams;

              /* In case unsolicited event received - here the handling finished */

              if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
                {
                  STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);

                  switch(usReceivedEventOpcode)
                    {
                    case HCI_CMND_READ_BUFFER_SIZE:
                      {
                        STREAM_TO_UINT8((char *)pucReceivedParams, 0,
                                        tSLInformation.usNumberOfFreeBuffers);
                        STREAM_TO_UINT16((char *)pucReceivedParams, 1,
                                         tSLInformation.usSlBufferLength);
                      }
                      break;

                    case HCI_CMND_WLAN_CONFIGURE_PATCH:
                    case HCI_NETAPP_DHCP:
                    case HCI_NETAPP_PING_SEND:
                    case HCI_NETAPP_PING_STOP:
                    case HCI_NETAPP_ARP_FLUSH:
                    case HCI_NETAPP_SET_DEBUG_LEVEL:
                    case HCI_NETAPP_SET_TIMERS:
                    case HCI_EVNT_NVMEM_READ:
                    case HCI_EVNT_NVMEM_CREATE_ENTRY:
                    case HCI_CMND_NVMEM_WRITE_PATCH:
                    case HCI_NETAPP_PING_REPORT:
                    case HCI_EVNT_MDNS_ADVERTISE:

                      STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,
                                      *(uint8_t *)pRetParams);
                      break;

                    case HCI_CMND_SETSOCKOPT:
                    case HCI_CMND_WLAN_CONNECT:
                    case HCI_CMND_WLAN_IOCTL_STATUSGET:
                    case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
                    case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
                    case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
                    case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
                    case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
                    case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
                    case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
                    case HCI_CMND_EVENT_MASK:
                    case HCI_EVNT_WLAN_DISCONNECT:
                    case HCI_EVNT_SOCKET:
                    case HCI_EVNT_BIND:
                    case HCI_CMND_LISTEN:
                    case HCI_EVNT_CLOSE_SOCKET:
                    case HCI_EVNT_CONNECT:
                    case HCI_EVNT_NVMEM_WRITE:

                      STREAM_TO_UINT32((char *)pucReceivedParams, 0,
                                       *(unsigned long *)pRetParams);
                      break;

                    case HCI_EVNT_READ_SP_VERSION:

                      STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,
                                      *(uint8_t *)pRetParams);
                      pRetParams = ((char *)pRetParams) + 1;
                      STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
                      UINT32_TO_STREAM((uint8_t *)pRetParams, retValue32);
                      break;

                    case HCI_EVNT_BSD_GETHOSTBYNAME:

                      STREAM_TO_UINT32((char *)pucReceivedParams,
                                       GET_HOST_BY_NAME_RETVAL_OFFSET,
                                       *(unsigned long *)pRetParams);
                      pRetParams = ((char *)pRetParams) + 4;
                      STREAM_TO_UINT32((char *)pucReceivedParams,
                                       GET_HOST_BY_NAME_ADDR_OFFSET,
                                       *(unsigned long *)pRetParams);
                      break;

                    case HCI_EVNT_ACCEPT:
                      {
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         ACCEPT_SD_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         ACCEPT_RETURN_STATUS_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;

                        /* This argument returns in network order */

                        memcpy((uint8_t *)pRetParams,
                               pucReceivedParams + ACCEPT_ADDRESS__OFFSET,
                               sizeof(struct sockaddr));
                      }
                      break;

                    case HCI_EVNT_RECV:
                    case HCI_EVNT_RECVFROM:
                      {
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SL_RECEIVE_SD_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SL_RECEIVE_NUM_BYTES_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SL_RECEIVE__FLAGS__OFFSET,
                                         *(unsigned long *)pRetParams);

                        if (((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes ==
                            ERROR_SOCKET_INACTIVE)
                          {
                            set_socket_active_status
                              (((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,
                              SOCKET_STATUS_INACTIVE);
                          }
                      }
                      break;

                    case HCI_EVNT_SEND:
                    case HCI_EVNT_SENDTO:
                      {
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SL_RECEIVE_SD_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SL_RECEIVE_NUM_BYTES_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                      }
                    break;

                    case HCI_EVNT_SELECT:
                      {
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SELECT_STATUS_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SELECT_READFD_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SELECT_WRITEFD_OFFSET,
                                         *(unsigned long *)pRetParams);
                        pRetParams = ((char *)pRetParams) + 4;
                        STREAM_TO_UINT32((char *)pucReceivedParams,
                                         SELECT_EXFD_OFFSET,
                                         *(unsigned long *)pRetParams);
                      }
                      break;

                    case HCI_CMND_GETSOCKOPT:

                      STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,
                                      ((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);

                      /* This argument returns in network order */

                      memcpy((uint8_t *)pRetParams, pucReceivedParams, 4);
                      break;

                    case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:

                      STREAM_TO_UINT32((char *)pucReceivedParams,
                                       GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,
                                       *(unsigned long *)pRetParams);
                      pRetParams = ((char *)pRetParams) + 4;
                      STREAM_TO_UINT32((char *)pucReceivedParams,
                                       GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,
                                       *(unsigned long *)pRetParams);
                      pRetParams = ((char *)pRetParams) + 4;

                      STREAM_TO_UINT16((char *)pucReceivedParams,
                                       GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,
                                       *(unsigned long *)pRetParams);
                      pRetParams = ((char *)pRetParams) + 2;
                      STREAM_TO_UINT16((char *)pucReceivedParams,
                                       GET_SCAN_RESULTS_FRAME_TIME_OFFSET,
                                       *(unsigned long *)pRetParams);
                      pRetParams = ((char *)pRetParams) + 2;
                      memcpy((uint8_t *)pRetParams,
                             (char *)(pucReceivedParams +
                             GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2),
                             GET_SCAN_RESULTS_SSID_MAC_LENGTH);
                      break;

                    case HCI_CMND_SIMPLE_LINK_START:
                      break;

                    case HCI_NETAPP_IPCONFIG:

                      /* Read IP address */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                      RecvParams += 4;

                      /* Read subnet */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                      RecvParams += 4;

                      /* Read default GW */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                      RecvParams += 4;

                      /* Read DHCP server */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                      RecvParams += 4;

                      /* Read DNS server */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
                      RecvParams += 4;

                      /* Read Mac address */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
                      RecvParams += 6;

                      /* Read SSID */

                      STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
                      break;

                    default:
                      PANIC();
                      break;
                    }
                }

             if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
                {
                  tSLInformation.usRxEventOpcode = 0;
                }
            }
          else
            {
              pucReceivedParams = pucReceivedData;
              STREAM_TO_UINT8((char *)pucReceivedData,
                              HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);

              STREAM_TO_UINT16((char *)pucReceivedData,
                               HCI_PACKET_LENGTH_OFFSET, usLength);

              /* Data received: note that the only case where from and from length
               * are not null is in recv from, so fill the args accordingly
               */

              if (from)
                {
                  STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE),
                                   BSD_RECV_FROM_FROMLEN_OFFSET,
                                   *(unsigned long *)fromlen);
                  memcpy(from,
                        (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET),
                        *fromlen);
                }

              memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
                     usLength - ucArgsize);

              tSLInformation.usRxDataPending = 0;
            }

          tSLInformation.usEventOrDataReceived = 0;

          cc3000_resume();

          /* Since we are going to TX - we need to handle this event after the
           * ResumeSPi since we need interrupts
           */

          if ((*pucReceivedData == HCI_TYPE_EVNT) &&
              (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
            {
              hci_unsol_handle_patch_request((char *)pucReceivedData);
            }

          if ((tSLInformation.usRxEventOpcode == 0) &&
              (tSLInformation.usRxDataPending == 0))
            {
              break;
            }
        }
    }

  return NULL;
}
unsigned char *
hci_event_handler(void *pRetParams, unsigned char *from, long *fromlen)
{
	unsigned char *pucReceivedData, ucArgsize;
	unsigned short usLength;
	unsigned char *pucReceivedParams;
	unsigned short usReceivedEventOpcode = 0;
	unsigned long retValue32;
	unsigned char * RecvParams;
        unsigned char *RetParams;
	
	volatile system_tick_t start = GetSystem1MsTick();

	while (1)
	{
		if (tSLInformation.usEventOrDataReceived == 0)
		{
                    volatile system_tick_t now = GetSystem1MsTick();
                    volatile system_tick_t elapsed = now - start;
                      if (elapsed < 0) { // Did we wrap
                         elapsed = start + now; // yes now
                      }

		    if (cc3000__event_timeout_ms && (elapsed >= cc3000__event_timeout_ms))
		    {
                        ERROR("Timeout now %ld start %ld elapsed %ld cc3000__event_timeout_ms %ld",now,start,elapsed,cc3000__event_timeout_ms);
                        ERROR("Timeout waiting on tSLInformation.usRxEventOpcode 0x%04x",tSLInformation.usRxEventOpcode);

		        // Timeout Return Error for requested Opcode
		        // This sucks because callers should have initialized pucReceivedParams
                        switch(tSLInformation.usRxEventOpcode)
                        {

                        default:
                          INVALID_CASE(tSLInformation.usRxEventOpcode);
                          break;

                        case HCI_CMND_SIMPLE_LINK_START:
                        case HCI_CMND_READ_BUFFER_SIZE:
                          break;

                        case HCI_CMND_WLAN_CONFIGURE_PATCH:
                        case HCI_NETAPP_DHCP:
                        case HCI_NETAPP_PING_SEND:
                        case HCI_NETAPP_PING_STOP:
                        case HCI_NETAPP_ARP_FLUSH:
                        case HCI_NETAPP_SET_DEBUG_LEVEL:
                        case HCI_NETAPP_SET_TIMERS:
                        case HCI_EVNT_NVMEM_READ:
                        case HCI_EVNT_NVMEM_CREATE_ENTRY:
                        case HCI_CMND_NVMEM_WRITE_PATCH:
                        case HCI_NETAPP_PING_REPORT:
                        case HCI_EVNT_MDNS_ADVERTISE:
                        case HCI_EVNT_READ_SP_VERSION:
                        case HCI_EVNT_SELECT:
                          *(unsigned char *)pRetParams = -1;
                            break;

                        case HCI_CMND_SETSOCKOPT:
                        case HCI_CMND_WLAN_CONNECT:
                        case HCI_CMND_WLAN_IOCTL_STATUSGET:
                        case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
                        case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
                        case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
                        case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
                        case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
                        case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
                        case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
                        case HCI_CMND_EVENT_MASK:
                        case HCI_EVNT_WLAN_DISCONNECT:
                        case HCI_EVNT_SOCKET:
                        case HCI_EVNT_BIND:
                        case HCI_CMND_LISTEN:
                        case HCI_EVNT_CLOSE_SOCKET:
                        case HCI_EVNT_CONNECT:
                        case HCI_EVNT_NVMEM_WRITE:
                        case HCI_EVNT_BSD_GETHOSTBYNAME:
                            *(int32_t *)pRetParams = -1;
                            break;


                        case HCI_EVNT_RECV:
                        case HCI_EVNT_RECVFROM:
                        case HCI_EVNT_ACCEPT:
                        case HCI_EVNT_SEND:
                        case HCI_EVNT_SENDTO:
                        case HCI_CMND_GETSOCKOPT:
                          *(int32_t *)pRetParams = -1;
                          pRetParams += sizeof(int32_t );
                          *(int32_t *)pRetParams = -1;
                          break;

                        case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
                          *(int32_t *)pRetParams = 0;
                          break;


                        case HCI_NETAPP_IPCONFIG:
                          memset(pRetParams,0,sizeof(tNetappIpconfigRetArgs));
                          break;
                        }
                        break; // Exit Loop
		    }

   	        }
		else
		{				
			pucReceivedData = (tSLInformation.pucReceivedData);

			if (*pucReceivedData == HCI_TYPE_EVNT)
			{
				// Event Received
				STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode);
				pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;		
				RecvParams = pucReceivedParams;
				RetParams = pRetParams;
				
				// In case unsolicited event received - here the handling finished
				if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
				{
					STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
					
					switch(usReceivedEventOpcode)
					{		
					case HCI_CMND_READ_BUFFER_SIZE:
						{
                                                  STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers);
                                                  STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength);
						}
						break;
						
					case HCI_CMND_WLAN_CONFIGURE_PATCH:
					case HCI_NETAPP_DHCP:
					case HCI_NETAPP_PING_SEND:
					case HCI_NETAPP_PING_STOP:
					case HCI_NETAPP_ARP_FLUSH:
					case HCI_NETAPP_SET_DEBUG_LEVEL:
					case HCI_NETAPP_SET_TIMERS:
					case HCI_EVNT_NVMEM_READ:
					case HCI_EVNT_NVMEM_CREATE_ENTRY:
					case HCI_CMND_NVMEM_WRITE_PATCH:
					case HCI_NETAPP_PING_REPORT:
					case HCI_EVNT_MDNS_ADVERTISE:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,*(unsigned char *)pRetParams);
						break;
						
					case HCI_CMND_SETSOCKOPT:
					case HCI_CMND_WLAN_CONNECT:
					case HCI_CMND_WLAN_IOCTL_STATUSGET:
					case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
					case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
					case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
					case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
					case HCI_CMND_EVENT_MASK:
					case HCI_EVNT_WLAN_DISCONNECT:
					case HCI_EVNT_SOCKET:
					case HCI_EVNT_BIND:
					case HCI_CMND_LISTEN:
					case HCI_EVNT_CLOSE_SOCKET:
					case HCI_EVNT_CONNECT:
					case HCI_EVNT_NVMEM_WRITE:
						
						STREAM_TO_UINT32((char *)pucReceivedParams, 0, *(unsigned long *)pRetParams);
						break;
						
					case HCI_EVNT_READ_SP_VERSION:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(unsigned char *)pRetParams);
						pRetParams = ((char *)pRetParams) + 1;
						STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
						UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);				
						break;
						
					case HCI_EVNT_BSD_GETHOSTBYNAME:
						
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);
						break;
						
					case HCI_EVNT_ACCEPT:
						{
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;

                                                  //This argument returns in network order
                                                  memcpy((unsigned char *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));
                                                  break;
						}
						
					case HCI_EVNT_RECV:
					case HCI_EVNT_RECVFROM:
						{
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);

                                                  if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
                                                  {
                                                          set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
                                                  }
                                                  break;
						}
                                                
                                        case HCI_EVNT_SEND:
					case HCI_EVNT_SENDTO:
						{
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;

                                                  break;
						}
						
					case HCI_EVNT_SELECT:
						{ 
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
                                                  pRetParams = ((char *)pRetParams) + 4;
                                                  STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);
                                                  break;
						}
						
					case HCI_CMND_GETSOCKOPT:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
						//This argument returns in network order
						memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
						break;
						
					case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
						
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;   					
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;                                                        					
						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 2;   					
						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 2;  
						memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);	
						break;
						
					case HCI_CMND_SIMPLE_LINK_START:
						break;
						
					case HCI_NETAPP_IPCONFIG:
						
						//Read IP address
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read subnet
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read default GW
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read DHCP server                                          	
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read DNS server                                           
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read Mac address                            	
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
						RecvParams += 6;
						
						//Read SSID
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
	
					}
				}
				
				if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
				{
					tSLInformation.usRxEventOpcode = 0;
                                        tSLInformation.solicitedResponse = 0;
				}
			}
			else
			{
			    if (tSLInformation.usRxDataPending == 0)
                                {
                                    ERROR("type != HCI_TYPE_EVNT is (%d) usRxDataPending=%d usRxEventOpcode=%u usReceivedEventOpcode=%u",
                                        *pucReceivedData,
                                        tSLInformation.usRxDataPending,
                                        tSLInformation.usRxEventOpcode,
                                        usReceivedEventOpcode);
                                }
			        else
			        {
                                  pucReceivedParams = pucReceivedData;
                                  STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);

                                  STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);

                                  // Data received: note that the only case where from and from length
                                  // are not null is in recv from, so fill the args accordingly
                                  if (from)
                                  {
                                    STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
                                    memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
                                  }

                                  // Let's vet length
                                  long length = usLength - ucArgsize;

                                  if (length <= 0 || length > arraySize(wlan_rx_buffer))
                                  {
                                      // Not sane
                                      length = -1;
                                  }
                                  else
                                  {
                                      memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, length);
                                  }

                                  // fixes the Nvram read not returning length
                                  if (fromlen)
                                  {
                                    *fromlen = length;
                                  }

                                  tSLInformation.usRxDataPending = 0;
			    }
			}
		
			tSLInformation.usEventOrDataReceived = 0;
			
			SpiResumeSpi();
			
			// Since we are going to TX - we need to handle this event after the 
			// ResumeSPi since we need interrupts
			if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
			{
				hci_unsol_handle_patch_request((char *)pucReceivedData);
			}
			
			if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
			{
			    break;
			}	
		}
	}
        return NULL;

}
Example #16
0
long
wlan_add_profile(unsigned long ulSecType,
                 unsigned char* ucSsid,
                 unsigned long ulSsidLen,
                 unsigned char *ucBssid,
                 unsigned long ulPriority,
                 unsigned long ulPairwiseCipher_Or_TxKeyLen,
                 unsigned long ulGroupCipher_TxKeyIndex,
                 unsigned long ulKeyMgmt,
                 unsigned char* ucPf_OrKey,
                 unsigned long ulPassPhraseLen)
{
    unsigned short arg_len;
    long ret;
    unsigned char *ptr;
    long i = 0;
    unsigned char *args;
    unsigned char bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ptr = tSLInformation.pucTxCommandBuffer;
    args = (ptr + HEADERS_SIZE_CMD);

    args = UINT32_TO_STREAM(args, ulSecType);

    // Setup arguments in accordance with the security type
    switch (ulSecType)
    {
    //OPEN
    case WLAN_SEC_UNSEC:
    {
        args = UINT32_TO_STREAM(args, 0x00000014);
        args = UINT32_TO_STREAM(args, ulSsidLen);
        args = UINT16_TO_STREAM(args, 0);
        if(ucBssid)
        {
            ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
        }
        else
        {
            ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
        }
        args = UINT32_TO_STREAM(args, ulPriority);
        ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

        arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ulSsidLen;
    }
    break;

    //WEP
    case WLAN_SEC_WEP:
    {
        args = UINT32_TO_STREAM(args, 0x00000020);
        args = UINT32_TO_STREAM(args, ulSsidLen);
        args = UINT16_TO_STREAM(args, 0);
        if(ucBssid)
        {
            ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
        }
        else
        {
            ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
        }
        args = UINT32_TO_STREAM(args, ulPriority);
        args = UINT32_TO_STREAM(args, 0x0000000C + ulSsidLen);
        args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
        args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
        ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);

        for(i = 0; i < 4; i++)
        {
            unsigned char *p = &ucPf_OrKey[i * ulPairwiseCipher_Or_TxKeyLen];

            ARRAY_TO_STREAM(args, p, ulPairwiseCipher_Or_TxKeyLen);
        }

        arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ulSsidLen +
                  ulPairwiseCipher_Or_TxKeyLen * 4;

    }
    break;

    //WPA
    //WPA2
    case WLAN_SEC_WPA:
    case WLAN_SEC_WPA2:
    {
        args = UINT32_TO_STREAM(args, 0x00000028);
        args = UINT32_TO_STREAM(args, ulSsidLen);
        args = UINT16_TO_STREAM(args, 0);
        if(ucBssid)
        {
            ARRAY_TO_STREAM(args, ucBssid, ETH_ALEN);
        }
        else
        {
            ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
        }
        args = UINT32_TO_STREAM(args, ulPriority);
        args = UINT32_TO_STREAM(args, ulPairwiseCipher_Or_TxKeyLen);
        args = UINT32_TO_STREAM(args, ulGroupCipher_TxKeyIndex);
        args = UINT32_TO_STREAM(args, ulKeyMgmt);
        args = UINT32_TO_STREAM(args, 0x00000008 + ulSsidLen);
        args = UINT32_TO_STREAM(args, ulPassPhraseLen);
        ARRAY_TO_STREAM(args, ucSsid, ulSsidLen);
        ARRAY_TO_STREAM(args, ucPf_OrKey, ulPassPhraseLen);

        arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ulSsidLen + ulPassPhraseLen;
    }

    break;
    }

    // Initiate a HCI command
    hci_command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE,
                     ptr, arg_len);

    // Wait for command complete event
    SimpleLinkWaitEvent(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);

    return(ret);
}
Example #17
0
/*******************************************************************************
**
** Function         hw_config_cback
**
** Description      Callback function for controller configuration
**
** Returns          None
**
*******************************************************************************/
void hw_config_cback(void *p_mem)
{
    HC_BT_HDR *p_evt_buf = (HC_BT_HDR *) p_mem;
    char        *p_name, *p_tmp;
    uint8_t     *p, status;
    uint16_t    opcode;
    HC_BT_HDR  *p_buf=NULL;
    uint8_t     is_proceeding = FALSE;
    int         i;
#if (USE_CONTROLLER_BDADDR == TRUE)
    const uint8_t null_bdaddr[BD_ADDR_LEN] = {0,0,0,0,0,0};
#endif

    status = *((uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_STATUS_RET_BYTE);
    p = (uint8_t *)(p_evt_buf + 1) + HCI_EVT_CMD_CMPL_OPCODE;
    STREAM_TO_UINT16(opcode,p);

    /* Ask a new buffer big enough to hold any HCI commands sent in here */
    if ((status == 0) && bt_vendor_cbacks)
        p_buf = (HC_BT_HDR *) bt_vendor_cbacks->alloc(BT_HC_HDR_SIZE + \
                                                       HCI_CMD_MAX_LEN);

	ALOGI("[Atmel %s] rcvd cb with state: %d!!,status:%d,op_code:%x",__func__, hw_cfg_cb.state,status,opcode);
	if (p_buf != NULL)
	{
		p_buf->event = MSG_STACK_TO_HC_HCI_CMD;
		p_buf->offset = 0;
		p_buf->len = 0;
		p_buf->layer_specific = 0;

        p = (uint8_t *) (p_buf + 1);

        switch (hw_cfg_cb.state)
        {
            case HW_CFG_SET_UART_BAUD_1:
                /* update baud rate of host's UART port */
                ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
                userial_vendor_set_baud( \
                    line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
                );

                /* read local name */
                UINT16_TO_STREAM(p, HCI_READ_LOCAL_NAME);
                *p = 0; /* parameter length */

                p_buf->len = HCI_CMD_PREAMBLE_SIZE;
                hw_cfg_cb.state = HW_CFG_READ_LOCAL_NAME;

                is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_READ_LOCAL_NAME, \
                                                    p_buf, hw_config_cback);
                break;

            case HW_CFG_READ_LOCAL_NAME:
                p_tmp = p_name = (char *) (p_evt_buf + 1) + \
                         HCI_EVT_CMD_CMPL_LOCAL_NAME_STRING;

                for (i=0; (i < LOCAL_NAME_BUFFER_LEN)||(*(p_name+i) != 0); i++)
                    *(p_name+i) = toupper(*(p_name+i));

                if ((p_name = strstr(p_name, "BCM")) != NULL)
                {
                    strncpy(hw_cfg_cb.local_chip_name, p_name, \
                            LOCAL_NAME_BUFFER_LEN-1);
                }
                else
                {
                    strncpy(hw_cfg_cb.local_chip_name, "UNKNOWN", \
                            LOCAL_NAME_BUFFER_LEN-1);
                    p_name = p_tmp;
                }

                hw_cfg_cb.local_chip_name[LOCAL_NAME_BUFFER_LEN-1] = 0;

                BTHWDBG("Chipset %s", hw_cfg_cb.local_chip_name);

                if ((status = hw_config_findpatch(p_name)) == TRUE)
                {
                    if ((hw_cfg_cb.fw_fd = open(p_name, O_RDONLY)) == -1)
                    {
                        ALOGE("vendor lib preload failed to open [%s]", p_name);
                    }
                    else
                    {
                    #if 0
                        /* vsc_download_minidriver */
                        UINT16_TO_STREAM(p, HCI_VSC_DOWNLOAD_MINIDRV);
                        *p = 0; /* parameter length */

                        p_buf->len = HCI_CMD_PREAMBLE_SIZE;
                        hw_cfg_cb.state = HW_CFG_DL_MINIDRIVER;

                        is_proceeding = bt_vendor_cbacks->xmit_cb( \
                                            HCI_VSC_DOWNLOAD_MINIDRV, p_buf, \
                                            hw_config_cback);
					#endif	
                    }
                }
                else
                {
                    ALOGE( \
                    "vendor lib preload failed to locate firmware patch file" \
                    );
                }

                if (is_proceeding == FALSE)
                {
                    //is_proceeding = hw_config_set_bdaddr(p_buf);
                }
                break;

            case HW_CFG_DL_MINIDRIVER:
                /* give time for placing firmware in download mode */
                ms_delay(50);
                hw_cfg_cb.state = HW_CFG_DL_FW_PATCH;
                /* fall through intentionally */
            case HW_CFG_DL_FW_PATCH:
                p_buf->len = read(hw_cfg_cb.fw_fd, p, HCI_CMD_PREAMBLE_SIZE);
                if (p_buf->len > 0)
                {
                #if 0
                    if ((p_buf->len < HCI_CMD_PREAMBLE_SIZE) || \
                        (opcode == HCI_VSC_LAUNCH_RAM))
                    {
                        ALOGW("firmware patch file might be altered!");
                    }
                    else
                    {
                        p_buf->len += read(hw_cfg_cb.fw_fd, \
                                           p+HCI_CMD_PREAMBLE_SIZE,\
                                           *(p+HCD_REC_PAYLOAD_LEN_BYTE));
                        STREAM_TO_UINT16(opcode,p);
                        is_proceeding = bt_vendor_cbacks->xmit_cb(opcode, \
                                                p_buf, hw_config_cback);
                        break;
                    }
				#endif
                }

                close(hw_cfg_cb.fw_fd);
                hw_cfg_cb.fw_fd = -1;

                /* Normally the firmware patch configuration file
                 * sets the new starting baud rate at 115200.
                 * So, we need update host's baud rate accordingly.
                 */
                ALOGI("bt vendor lib: set UART baud 115200");
                userial_vendor_set_baud(USERIAL_BAUD_115200);

                /* Next, we would like to boost baud rate up again
                 * to desired working speed.
                 */
                hw_cfg_cb.f_set_baud_2 = TRUE;

                /* Check if we need to pause a few hundred milliseconds
                 * before sending down any HCI command.
                 */
                ms_delay(look_up_fw_settlement_delay());

                /* fall through intentionally */
            case HW_CFG_START:
                if (UART_TARGET_BAUD_RATE > 3000000)
                {
                #if 1
                    /* set UART clock to 48MHz */
                    UINT16_TO_STREAM(p, HCI_VSC_WRITE_UART_CLOCK_SETTING);
                    *p++ = 1; /* parameter length */
                    *p = 1; /* (1,"UART CLOCK 48 MHz")(2,"UART CLOCK 24 MHz") */

                    p_buf->len = HCI_CMD_PREAMBLE_SIZE + 1;
                    hw_cfg_cb.state = HW_CFG_SET_UART_CLOCK;

                    is_proceeding = bt_vendor_cbacks->xmit_cb( \
                                        HCI_VSC_WRITE_UART_CLOCK_SETTING, \
                                        p_buf, hw_config_cback);
                    break;
				#endif
                }
                /* fall through intentionally */
            case HW_CFG_SET_UART_CLOCK:
                /* set controller's UART baud rate to 3M */
                UINT16_TO_STREAM(p, HCI_VSC_UPDATE_BAUDRATE);
                *p++ = UPDATE_BAUDRATE_CMD_PARAM_SIZE; /* parameter length */
                *p++ = 0; /* encoded baud rate */
                *p++ = 0; /* use encoded form */
                UINT32_TO_STREAM(p, UART_TARGET_BAUD_RATE);

                p_buf->len = HCI_CMD_PREAMBLE_SIZE + \
                             UPDATE_BAUDRATE_CMD_PARAM_SIZE;
                hw_cfg_cb.state = (hw_cfg_cb.f_set_baud_2) ? \
                            HW_CFG_SET_UART_BAUD_2 : HW_CFG_SET_UART_BAUD_1;

                is_proceeding = bt_vendor_cbacks->xmit_cb(HCI_VSC_UPDATE_BAUDRATE, \
                                                    p_buf, hw_config_cback);
                break;

            case HW_CFG_SET_UART_BAUD_2:
                /* update baud rate of host's UART port */
                ALOGI("bt vendor lib: set UART baud %i", UART_TARGET_BAUD_RATE);
                userial_vendor_set_baud( \
                    line_speed_to_userial_baud(UART_TARGET_BAUD_RATE) \
                );

#if (USE_CONTROLLER_BDADDR == TRUE)
                if ((is_proceeding = hw_config_read_bdaddr(p_buf)) == TRUE)
                    break;
#else
               // if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
                //    break;
#endif
                /* fall through intentionally */
            case HW_CFG_SET_BD_ADDR:
                ALOGI("vendor lib fwcfg completed");
                bt_vendor_cbacks->dealloc(p_buf);
                bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);

                hw_cfg_cb.state = 0;

                if (hw_cfg_cb.fw_fd != -1)
                {
                    close(hw_cfg_cb.fw_fd);
                    hw_cfg_cb.fw_fd = -1;
                }

                is_proceeding = TRUE;
                break;

#if (USE_CONTROLLER_BDADDR == TRUE)
            case HW_CFG_READ_BD_ADDR:
                p_tmp = (char *) (p_evt_buf + 1) + \
                         HCI_EVT_CMD_CMPL_LOCAL_BDADDR_ARRAY;

                if (memcmp(p_tmp, null_bdaddr, BD_ADDR_LEN) == 0)
                {
                    // Controller does not have a valid OTP BDADDR!
                    // Set the BTIF initial BDADDR instead.
                   // if ((is_proceeding = hw_config_set_bdaddr(p_buf)) == TRUE)
                   //     break;
                }
                else
                {
                    ALOGI("Controller OTP bdaddr %02X:%02X:%02X:%02X:%02X:%02X",
                        *(p_tmp+5), *(p_tmp+4), *(p_tmp+3),
                        *(p_tmp+2), *(p_tmp+1), *p_tmp);
                }

                ALOGI("vendor lib fwcfg completed");
                bt_vendor_cbacks->dealloc(p_buf);
                bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_SUCCESS);

				hw_cfg_cb.state = 0;

                if (hw_cfg_cb.fw_fd != -1)
                {
                    close(hw_cfg_cb.fw_fd);
                    hw_cfg_cb.fw_fd = -1;
                }

                is_proceeding = TRUE;
                break;
#endif // (USE_CONTROLLER_BDADDR == TRUE)
        } // switch(hw_cfg_cb.state)
    } // if (p_buf != NULL)

    /* Free the RX event buffer */
    if (bt_vendor_cbacks)
        bt_vendor_cbacks->dealloc(p_evt_buf);

    if (is_proceeding == FALSE)
    {
        ALOGE("vendor lib fwcfg aborted!!!");
        if (bt_vendor_cbacks)
        {
            if (p_buf != NULL)
                bt_vendor_cbacks->dealloc(p_buf);

            bt_vendor_cbacks->fwcfg_cb(BT_VND_OP_RESULT_FAIL);
        }

        if (hw_cfg_cb.fw_fd != -1)
        {
            close(hw_cfg_cb.fw_fd);
            hw_cfg_cb.fw_fd = -1;
        }

        hw_cfg_cb.state = 0;
    }
}
Example #18
0
//*****************************************************************************
//
//! select
//!
//!  @param[in]   nfds       the highest-numbered file descriptor in any of the
//!                           three sets, plus 1.
//!  @param[out]   writesds   socket descriptors list for write monitoring
//!  @param[out]   readsds    socket descriptors list for read monitoring
//!  @param[out]   exceptsds  socket descriptors list for exception monitoring
//!  @param[in]   timeout     is an upper bound on the amount of time elapsed
//!                           before select() returns. Null means infinity
//!                           timeout. The minimum timeout is 5 milliseconds,
//!                          less than 5 milliseconds will be set
//!                           automatically to 5 milliseconds.
//!  @return    On success, select() returns the number of file descriptors
//!             contained in the three returned descriptor sets (that is, the
//!             total number of bits that are set in readfds, writefds,
//!             exceptfds) which may be zero if the timeout expires before
//!             anything interesting  happens.
//!             On error, -1 is returned.
//!                   *readsds - return the sockets on which Read request will
//!                              return without delay with valid data.
//!                   *writesds - return the sockets on which Write request
//!                                 will return without delay.
//!                   *exceptsds - return the sockets which closed recently.
//!
//!  @brief  Monitor socket activity
//!          Select allow a program to monitor multiple file descriptors,
//!          waiting until one or more of the file descriptors become
//!         "ready" for some class of I/O operation
//!
//!  @Note   If the timeout value set to less than 5ms it will automatically set
//!          to 5ms to prevent overload of the system
//!
//!  @sa socket
//
//*****************************************************************************
int c_select(long nfds, wfd_set *readsds, wfd_set *writesds,
    wfd_set *exceptsds, struct timeval *timeout)
{
  uint8_t *args;
  tBsdSelectRecvParams tParams;
  uint32_t is_blocking;

  if( timeout == NULL) {
    is_blocking = 1; /* blocking , infinity timeout */
  }
  else {
    is_blocking = 0; /* no blocking, timeout */
  }

  // Fill in HCI packet structure
  args = hci_get_cmd_buffer();

  // Fill in temporary command buffer
  args = UINT32_TO_STREAM(args, nfds);
  args = UINT32_TO_STREAM(args, 0x00000014);
  args = UINT32_TO_STREAM(args, 0x00000014);
  args = UINT32_TO_STREAM(args, 0x00000014);
  args = UINT32_TO_STREAM(args, 0x00000014);
  args = UINT32_TO_STREAM(args, is_blocking);
  args = UINT32_TO_STREAM(args, ((readsds) ? *(uint32_t*)readsds : 0));
  args = UINT32_TO_STREAM(args, ((writesds) ? *(uint32_t*)writesds : 0));
  args = UINT32_TO_STREAM(args, ((exceptsds) ? *(uint32_t*)exceptsds : 0));

  if (timeout) {
    if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) {
      timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS;
    }
    args = UINT32_TO_STREAM(args, timeout->tv_sec);
    args = UINT32_TO_STREAM(args, timeout->tv_usec);
  }

  // Initiate a HCI command
  hci_command_send(HCI_CMND_BSD_SELECT, SOCKET_SELECT_PARAMS_LEN,
      HCI_EVNT_SELECT, &tParams);

  // Update actually read FD
  if (tParams.iStatus >= 0) {
    if (readsds)
      memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd));

    if (writesds)
      memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd));

    if (exceptsds)
      memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd));

    return(tParams.iStatus);
  }
  else {
    errno = tParams.iStatus;
    return(-1);
  }
}
Example #19
0
//*****************************************************************************
//
//!  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
//!                  occurred, or -2 in case there are no free buffers available
//!
//!  @brief          This function is used to transmit a message to another
//!                  socket
//
//*****************************************************************************
static int
simple_link_send(long sd, const void *buf, long len, long flags,
              const sockaddr *to, long tolen, long opcode)
{
  uint8_t uArgSize,  addrlen;
  uint8_t *pDataPtr, *args;
  uint32_t addr_offset = 0;
  int res;
  tBsdReadReturnParams tSocketSendEvent;
  uint16_t rx_opcode;

  // Check the bsd_arguments
  if ((res = consume_buf(sd)) != 0)
    return res;

  // Allocate a buffer and construct a packet and send it over spi
  args = hci_get_data_buffer();

  // Update the offset of data and parameters according to the command
  switch(opcode) {
    case HCI_CMND_SENDTO:
      addr_offset = len + sizeof(len) + sizeof(len);
      addrlen = 8;
      uArgSize = SOCKET_SENDTO_PARAMS_LEN;
      pDataPtr = args + SOCKET_SENDTO_PARAMS_LEN;
      break;

    case HCI_CMND_SEND:
      tolen = 0;
      to = NULL;
      uArgSize = HCI_CMND_SEND_ARG_LENGTH;
      pDataPtr = args + HCI_CMND_SEND_ARG_LENGTH;
      break;

    default:
      return -1;
  }

  // Fill in temporary command buffer
  args = UINT32_TO_STREAM(args, sd);
  args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd));
  args = UINT32_TO_STREAM(args, len);
  args = UINT32_TO_STREAM(args, flags);

  if (opcode == HCI_CMND_SENDTO) {
    args = UINT32_TO_STREAM(args, addr_offset);
    args = UINT32_TO_STREAM(args, addrlen);
  }

  // Copy the data received from user into the TX Buffer
  ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)buf), len);

  // In case we are using SendTo, copy the to parameters
  if (opcode == HCI_CMND_SENDTO) {
    ARRAY_TO_STREAM(pDataPtr, ((uint8_t *)to), tolen);
  }

  if (opcode == HCI_CMND_SENDTO)
    rx_opcode = HCI_EVNT_SENDTO;
  else
    rx_opcode = HCI_EVNT_SEND;

  // Initiate a HCI command
  hci_data_send(opcode, uArgSize, len, (uint8_t*)to, tolen,
      rx_opcode, &tSocketSendEvent);

  return  (len);
}
Example #20
0
UINT8 *hci_event_handler(void *pRetParams, UINT8 *from, UINT8 *fromlen) {
  UINT8 *pucReceivedData, ucArgsize;
  UINT16 usLength;
  UINT8 *pucReceivedParams;
  UINT16 usReceivedEventOpcode = 0;
  UINT32 retValue32;
  UINT8 *RecvParams;
  UINT8 *RetParams;

  while (1) {
    // Adafruit CC3k Host Driver Difference
    // Call cc3k_int_poll to try to keep from missing interrupts.
    // Noted 12-12-2014 by tdicola
    cc3k_int_poll();

    if (tSLInformation.usEventOrDataReceived != 0) {
      pucReceivedData = (tSLInformation.pucReceivedData);

      if (*pucReceivedData == HCI_TYPE_EVNT) {
        // Event Received
        STREAM_TO_UINT16((CHAR *) pucReceivedData, HCI_EVENT_OPCODE_OFFSET,
                         usReceivedEventOpcode);
        pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE;
        RecvParams = pucReceivedParams;
        // Adafruit CC3k Host Driver Difference
        // Explicit cast of pRetParams to UINT8* to fix compiler warning.
        // Noted 12-12-2014 by tdicola
        RetParams = (UINT8 *) pRetParams;

        // In case unsolicited event received - here the handling finished
        if (hci_unsol_event_handler((CHAR *) pucReceivedData) == 0) {
          STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);

          switch (usReceivedEventOpcode) {
            case HCI_CMND_READ_BUFFER_SIZE: {
              STREAM_TO_UINT8((CHAR *) pucReceivedParams, 0,
                              tSLInformation.usNumberOfFreeBuffers);
              STREAM_TO_UINT16((CHAR *) pucReceivedParams, 1,
                               tSLInformation.usSlBufferLength);
            } break;

            case HCI_CMND_WLAN_CONFIGURE_PATCH:
            case HCI_NETAPP_DHCP:
            case HCI_NETAPP_PING_SEND:
            case HCI_NETAPP_PING_STOP:
            case HCI_NETAPP_ARP_FLUSH:
            case HCI_NETAPP_SET_DEBUG_LEVEL:
            case HCI_NETAPP_SET_TIMERS:
            case HCI_EVNT_NVMEM_READ:
            case HCI_EVNT_NVMEM_CREATE_ENTRY:
            case HCI_CMND_NVMEM_WRITE_PATCH:
            case HCI_NETAPP_PING_REPORT:
            case HCI_EVNT_MDNS_ADVERTISE:

              STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,
                              *(UINT8 *) pRetParams);
              break;

            case HCI_CMND_SETSOCKOPT:
            case HCI_CMND_WLAN_CONNECT:
            case HCI_CMND_WLAN_IOCTL_STATUSGET:
            case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
            case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
            case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
            case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
            case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
            case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
            case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
            case HCI_CMND_EVENT_MASK:
            case HCI_EVNT_WLAN_DISCONNECT:
            case HCI_EVNT_SOCKET:
            case HCI_EVNT_BIND:
            case HCI_CMND_LISTEN:
            case HCI_EVNT_CLOSE_SOCKET:
            case HCI_EVNT_CONNECT:
            case HCI_EVNT_NVMEM_WRITE:

              STREAM_TO_UINT32((CHAR *) pucReceivedParams, 0,
                               *(UINT32 *) pRetParams);
              break;

            case HCI_EVNT_READ_SP_VERSION:

              STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,
                              *(UINT8 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 1;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, 0, retValue32);
              UINT32_TO_STREAM((UINT8 *) pRetParams, retValue32);
              break;

            case HCI_EVNT_BSD_GETHOSTBYNAME:

              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               GET_HOST_BY_NAME_RETVAL_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               GET_HOST_BY_NAME_ADDR_OFFSET,
                               *(UINT32 *) pRetParams);
              break;

            case HCI_EVNT_GETMSSVALUE:

              STREAM_TO_UINT16((CHAR *) pucReceivedParams,
                               GET_MSS_VAL_RETVAL_OFFSET,
                               *(UINT16 *) pRetParams);

              break;

            case HCI_EVNT_ACCEPT: {
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, ACCEPT_SD_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               ACCEPT_RETURN_STATUS_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;

              // This argument returns in network order
              memcpy((UINT8 *) pRetParams,
                     pucReceivedParams + ACCEPT_ADDRESS__OFFSET,
                     sizeof(sockaddr));
              break;
            }

            case HCI_EVNT_RECV:
            case HCI_EVNT_RECVFROM: {
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE_SD_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               SL_RECEIVE_NUM_BYTES_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               SL_RECEIVE__FLAGS__OFFSET,
                               *(UINT32 *) pRetParams);

              if (((tBsdReadReturnParams *) pRetParams)->iNumberOfBytes ==
                  ERROR_SOCKET_INACTIVE) {
                set_socket_active_status(
                    ((tBsdReadReturnParams *) pRetParams)->iSocketDescriptor,
                    SOCKET_STATUS_INACTIVE);
              }
              break;
            }

            case HCI_EVNT_SEND:
            case HCI_EVNT_SENDTO: {
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, SL_RECEIVE_SD_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               SL_RECEIVE_NUM_BYTES_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;

              break;
            }

            case HCI_EVNT_SELECT: {
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_STATUS_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_READFD_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               SELECT_WRITEFD_OFFSET, *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams, SELECT_EXFD_OFFSET,
                               *(UINT32 *) pRetParams);
              break;
            }

            case HCI_CMND_GETSOCKOPT:

              STREAM_TO_UINT8(
                  pucReceivedData, HCI_EVENT_STATUS_OFFSET,
                  ((tBsdGetSockOptReturnParams *) pRetParams)->iStatus);
              // This argument returns in network order
              memcpy((UINT8 *) pRetParams, pucReceivedParams, 4);
              break;

            case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:

              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT32((CHAR *) pucReceivedParams,
                               GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 4;
              STREAM_TO_UINT16((CHAR *) pucReceivedParams,
                               GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 2;
              STREAM_TO_UINT16((CHAR *) pucReceivedParams,
                               GET_SCAN_RESULTS_FRAME_TIME_OFFSET,
                               *(UINT32 *) pRetParams);
              pRetParams = ((CHAR *) pRetParams) + 2;
              memcpy((UINT8 *) pRetParams,
                     (CHAR *) (pucReceivedParams +
                               GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2),
                     GET_SCAN_RESULTS_SSID_MAC_LENGTH);
              break;

            case HCI_CMND_SIMPLE_LINK_START:
              break;

            case HCI_NETAPP_IPCONFIG:

              // Read IP address
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_IP_LENGTH);
              RecvParams += 4;

              // Read subnet
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_IP_LENGTH);
              RecvParams += 4;

              // Read default GW
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_IP_LENGTH);
              RecvParams += 4;

              // Read DHCP server
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_IP_LENGTH);
              RecvParams += 4;

              // Read DNS server
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_IP_LENGTH);
              RecvParams += 4;

              // Read Mac address
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_MAC_LENGTH);
              RecvParams += 6;

              // Read SSID
              STREAM_TO_STREAM(RecvParams, RetParams,
                               NETAPP_IPCONFIG_SSID_LENGTH);
          }
        }

        if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) {
          tSLInformation.usRxEventOpcode = 0;
        }
      } else {
        pucReceivedParams = pucReceivedData;
        STREAM_TO_UINT8((CHAR *) pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET,
                        ucArgsize);

        STREAM_TO_UINT16((CHAR *) pucReceivedData, HCI_PACKET_LENGTH_OFFSET,
                         usLength);

        // Data received: note that the only case where from and from length
        // are not null is in recv from, so fill the args accordingly
        if (from) {
          STREAM_TO_UINT32((CHAR *) (pucReceivedData + HCI_DATA_HEADER_SIZE),
                           BSD_RECV_FROM_FROMLEN_OFFSET, *(UINT32 *) fromlen);
          memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE +
                        BSD_RECV_FROM_FROM_OFFSET),
                 *fromlen);
        }

        memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
               usLength - ucArgsize);

        tSLInformation.usRxDataPending = 0;
      }

      tSLInformation.usEventOrDataReceived = 0;

      SpiResumeSpi();

      // Since we are going to TX - we need to handle this event after the
      // ResumeSPi since we need interrupts
      if ((*pucReceivedData == HCI_TYPE_EVNT) &&
          (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) {
        hci_unsol_handle_patch_request((CHAR *) pucReceivedData);
      }

      if ((tSLInformation.usRxEventOpcode == 0) &&
          (tSLInformation.usRxDataPending == 0)) {
        return NULL;
      }
    }
  }
}
Example #21
0
unsigned char *
hci_event_handler(void *pRetParams, unsigned char *from, unsigned char *fromlen)
{
	renableIRQ();
//	TM_DEBUG("hci event handler");
//	TM_DEBUG("event or data recieved y/n? %ul", tSLInformation.usEventOrDataReceived);
//	TM_DEBUG("the actual event/data %ul", (unsigned char *)tSLInformation.pucReceivedData[0]);
	volatile unsigned char *pucReceivedData, ucArgsize;
	unsigned short usLength;
	unsigned char *pucReceivedParams;
	unsigned short usReceivedEventOpcode = 0;
	unsigned long retValue32;
	unsigned char * RecvParams;
	unsigned char *RetParams;

#ifdef CC3K_TIMEOUT
	uint32_t ccStartTime = tm_uptime_micro();
#endif

	while (1)
	{
		CC_BLOCKS();

		if (tSLInformation.usEventOrDataReceived != 0)
		{

			pucReceivedData = (tSLInformation.pucReceivedData);

			if (*pucReceivedData == HCI_TYPE_EVNT)
			{
				// Event Received
				STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET,
												 usReceivedEventOpcode);
				pucReceivedParams = (unsigned char*) (pucReceivedData + HCI_EVENT_HEADER_SIZE);
				RecvParams = pucReceivedParams;
				RetParams = pRetParams;
//				TM_DEBUG("PUC RECIEVED DATA pre %ul", (char *)pucReceivedData[0]);
				// In case unsolicited event received - here the handling finished
				if (hci_unsol_event_handler((char *)pucReceivedData) == 0)
				{
					STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength);
//					TM_DEBUG("PUC RECIEVED DATA %ul",(char *) pucReceivedData[0]);
					switch(usReceivedEventOpcode)
					{		
					case HCI_CMND_READ_BUFFER_SIZE:
						{
							STREAM_TO_UINT8((char *)pucReceivedParams, 0, 
															tSLInformation.usNumberOfFreeBuffers);
							STREAM_TO_UINT16((char *)pucReceivedParams, 1, 
															 tSLInformation.usSlBufferLength);
						}
						break;
						
					case HCI_CMND_WLAN_CONFIGURE_PATCH:
					case HCI_NETAPP_DHCP:
					case HCI_NETAPP_PING_SEND:
					case HCI_NETAPP_PING_STOP:
					case HCI_NETAPP_ARP_FLUSH:
					case HCI_NETAPP_SET_DEBUG_LEVEL:
					case HCI_NETAPP_SET_TIMERS:
					case HCI_EVNT_NVMEM_READ:
					case HCI_EVNT_NVMEM_CREATE_ENTRY:
					case HCI_CMND_NVMEM_WRITE_PATCH:
					case HCI_NETAPP_PING_REPORT:
					case HCI_EVNT_MDNS_ADVERTISE:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
														,*(unsigned char *)pRetParams);
						break;
						
					case HCI_CMND_SETSOCKOPT:
					case HCI_CMND_WLAN_CONNECT:
					case HCI_CMND_WLAN_IOCTL_STATUSGET:
					case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
					case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
					case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
					case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
					case HCI_CMND_EVENT_MASK:
					case HCI_EVNT_WLAN_DISCONNECT:
					case HCI_EVNT_SOCKET:
					case HCI_EVNT_BIND:
					case HCI_CMND_LISTEN:
					case HCI_EVNT_CLOSE_SOCKET:
					case HCI_EVNT_CONNECT:
					case HCI_EVNT_NVMEM_WRITE:
						
						STREAM_TO_UINT32((char *)pucReceivedParams,0
														 ,*(unsigned long *)pRetParams);
						break;
						
					case HCI_EVNT_READ_SP_VERSION:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET
														,*(unsigned char *)pRetParams);
						pRetParams = ((char *)pRetParams) + 1;
						STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32);
						UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32);				
						break;
						
					case HCI_EVNT_BSD_GETHOSTBYNAME:
						
						STREAM_TO_UINT32((char *)pucReceivedParams
						      ,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;
						STREAM_TO_UINT32((char *)pucReceivedParams
									,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams);					
						break;
						
					case HCI_EVNT_ACCEPT:
						{
							STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET
															 ,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams
										,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams);
              pRetParams = ((char *)pRetParams) + 4; 
							
							//This argument returns in network order
							memcpy((unsigned char *)pRetParams, 
								  pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr));	
							break;
						}
						
					case HCI_EVNT_RECV:
					case HCI_EVNT_RECVFROM:
						{
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams);
							
							if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE)
							{
								set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE);
							}
							break;
						}
                                                
                                        case HCI_EVNT_SEND:
					case HCI_EVNT_SENDTO:
						{
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							
							break;
						}
						
					case HCI_EVNT_SELECT:
						{ 
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams);
							pRetParams = ((char *)pRetParams) + 4;
							STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams);			
							break;
						}
						
					case HCI_CMND_GETSOCKOPT:
						
						STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus);
						//This argument returns in network order
						memcpy((unsigned char *)pRetParams, pucReceivedParams, 4);
						break;
						
					case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
						
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;   					
						STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 4;                                                        					
						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 2;   					
						STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams);
						pRetParams = ((char *)pRetParams) + 2;  
						memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH);	
						break;
						
					case HCI_CMND_SIMPLE_LINK_START:
						break;
						
					case HCI_NETAPP_IPCONFIG:
						
						//Read IP address
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read subnet
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read default GW
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read DHCP server                                          	
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read DNS server                                           
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH);
						RecvParams += 4;
						
						//Read Mac address                            	
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH);
						RecvParams += 6;
						
						//Read SSID
						STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH);
	
					}
				}
				
				if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode)
				{
					tSLInformation.usRxEventOpcode = 0;
				}
			}
			else
			{				
				pucReceivedParams = (unsigned char*) pucReceivedData;
				STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize);
				
				STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength);

				// Data received: note that the only case where from and from length 
				// are not null is in recv from, so fill the args accordingly
				if (from)
				{
					STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen);
					memcpy(from, (void*) (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen);
				}
				
				memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize,
							 usLength - ucArgsize);
				
				tSLInformation.usRxDataPending = 0;
			}
		
			tSLInformation.usEventOrDataReceived = 0;
			
			SpiResumeSpi();
			
			// Since we are going to TX - we need to handle this event after the 
			// ResumeSPi since we need interrupts
			if ((*pucReceivedData == HCI_TYPE_EVNT) &&
					(usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ))
			{
				hci_unsol_handle_patch_request((char *)pucReceivedData);
			}
			
			if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0))
			{
				return NULL;
			}	
		} 
#ifdef CC3K_TIMEOUT

		else {

			// check the system timer
			// compare it to maximum allowed wait
			if (tm_uptime_micro() - ccStartTime >= CC3000_MAX_WAIT) {

				// set pRetParams to some default values
				switch(tSLInformation.usRxEventOpcode) {
					case HCI_CMND_READ_BUFFER_SIZE:
						// tSLInformation values are defaulted to 0
						tSLInformation.usNumberOfFreeBuffers = 0;
						tSLInformation.usSlBufferLength = 0;
						break;
					case HCI_CMND_WLAN_CONFIGURE_PATCH:
					case HCI_NETAPP_DHCP:
					case HCI_NETAPP_PING_SEND:
					case HCI_NETAPP_PING_STOP:
					case HCI_NETAPP_ARP_FLUSH:
					case HCI_NETAPP_SET_DEBUG_LEVEL:
					case HCI_NETAPP_SET_TIMERS:
					case HCI_EVNT_NVMEM_READ:
					case HCI_EVNT_NVMEM_CREATE_ENTRY:
					case HCI_CMND_NVMEM_WRITE_PATCH:
					case HCI_NETAPP_PING_REPORT:
					case HCI_EVNT_MDNS_ADVERTISE:
						// return CC3K_TIMEOUT_ERR for errored out on timeout
						*(signed char *)pRetParams = CC3K_TIMEOUT_ERR;
						break;
						
					case HCI_CMND_SETSOCKOPT:
					case HCI_CMND_WLAN_CONNECT:
					case HCI_CMND_WLAN_IOCTL_STATUSGET:
					case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE:
					case HCI_CMND_WLAN_IOCTL_DEL_PROFILE:
					case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY:
					case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP:
					case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX:
					case HCI_CMND_EVENT_MASK:
					case HCI_EVNT_WLAN_DISCONNECT:
					case HCI_EVNT_SOCKET:
					case HCI_EVNT_BIND:
					case HCI_CMND_LISTEN:
					case HCI_EVNT_CLOSE_SOCKET:
					case HCI_EVNT_CONNECT:
					case HCI_EVNT_NVMEM_WRITE:
						// return CC3K_TIMEOUT_ERR for errored out on timeout
						*(long *)pRetParams = CC3K_TIMEOUT_ERR;
						break;
						
					case HCI_EVNT_BSD_GETHOSTBYNAME:
						// expects a tBsdGethostbynameParams, set error on retVal and default outputAddress
						((tBsdGethostbynameParams *)pRetParams)->retVal = CC3K_TIMEOUT_ERR;
						((tBsdGethostbynameParams *)pRetParams)->outputAddress = 0;				
						break;
					
					case HCI_EVNT_READ_SP_VERSION:
					case HCI_CMND_SIMPLE_LINK_START:
					case HCI_EVNT_ACCEPT:
					case HCI_EVNT_RECV:
					case HCI_EVNT_RECVFROM:
						{
							// these don't do anything, we're not in a blocking loop for this
							break;
						}

					case HCI_EVNT_SEND:
					case HCI_EVNT_SENDTO:
						// expects a tBsdReadReturnParams, set the iNumberOfBytes to zero
						((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes = 0;
						break;
						
					case HCI_EVNT_SELECT:
						// expects a tBsdSelectRecvParams, set the isStatus
						((tBsdSelectRecvParams *)pRetParams)->iStatus = CC3K_TIMEOUT_ERR;
						break;
						
					case HCI_CMND_GETSOCKOPT:
						// HCI_CMND_GETSOCKOPT expects a tBsdGetSockOptReturnParams, set the error code
						((tBsdGetSockOptReturnParams *)pRetParams)->iStatus = CC3K_TIMEOUT_ERR;
						break;
						
					case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS:
						// no results on error
						*(unsigned char *)pRetParams = 0;
						break;
						
					case HCI_NETAPP_IPCONFIG:
						// set all values to zero
						memset(pRetParams,0,sizeof(tNetappIpconfigRetArgs));
						break;
				}
				
				TM_DEBUG("HCI Event error on command: %x", tSLInformation.usRxEventOpcode);

				// past maximum wait, get out of here
				return NULL;
			}

		}
#endif

	}

}
Example #22
0
int32_t cc3000_wlan::add_profile(uint32_t sec_type,
                      uint8_t* ssid,
                      uint32_t ssid_length,
                      uint8_t *b_ssid,
                      uint32_t priority,
                      uint32_t pairwise_cipher_or_tx_key_len,
                      uint32_t group_cipher_tx_key_index,
                      uint32_t key_mgmt,
                      uint8_t* pf_or_key,
                      uint32_t pass_phrase_len) {
    uint16_t arg_len = 0x00;
    int32_t ret;
    uint8_t *ptr;
    int32_t i = 0;
    uint8_t *args;
    uint8_t bssid_zero[] = {0, 0, 0, 0, 0, 0};

    ptr = _simple_link.get_transmit_buffer();
    args = (ptr + HEADERS_SIZE_CMD);

    args = UINT32_TO_STREAM(args, sec_type);

    // Setup arguments in accordance with the security type
    switch (sec_type)
    {
        //OPEN
    case WLAN_SEC_UNSEC:
        {
            args = UINT32_TO_STREAM(args, 0x00000014);
            args = UINT32_TO_STREAM(args, ssid_length);
            args = UINT16_TO_STREAM(args, 0);
            if(b_ssid)
            {
                ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, priority);
            ARRAY_TO_STREAM(args, ssid, ssid_length);

            arg_len = WLAN_ADD_PROFILE_NOSEC_PARAM_LEN + ssid_length;
        }
        break;

        //WEP
    case WLAN_SEC_WEP:
        {
            args = UINT32_TO_STREAM(args, 0x00000020);
            args = UINT32_TO_STREAM(args, ssid_length);
            args = UINT16_TO_STREAM(args, 0);
            if(b_ssid)
            {
                ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, priority);
            args = UINT32_TO_STREAM(args, 0x0000000C + ssid_length);
            args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
            args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
            ARRAY_TO_STREAM(args, ssid, ssid_length);

            for(i = 0; i < 4; i++)
            {
                uint8_t *p = &pf_or_key[i * pairwise_cipher_or_tx_key_len];

                ARRAY_TO_STREAM(args, p, pairwise_cipher_or_tx_key_len);
            }

            arg_len = WLAN_ADD_PROFILE_WEP_PARAM_LEN + ssid_length +
                pairwise_cipher_or_tx_key_len * 4;

        }
        break;

        //WPA
        //WPA2
    case WLAN_SEC_WPA:
    case WLAN_SEC_WPA2:
        {
            args = UINT32_TO_STREAM(args, 0x00000028);
            args = UINT32_TO_STREAM(args, ssid_length);
            args = UINT16_TO_STREAM(args, 0);
            if(b_ssid)
            {
                ARRAY_TO_STREAM(args, b_ssid, ETH_ALEN);
            }
            else
            {
                ARRAY_TO_STREAM(args, bssid_zero, ETH_ALEN);
            }
            args = UINT32_TO_STREAM(args, priority);
            args = UINT32_TO_STREAM(args, pairwise_cipher_or_tx_key_len);
            args = UINT32_TO_STREAM(args, group_cipher_tx_key_index);
            args = UINT32_TO_STREAM(args, key_mgmt);
            args = UINT32_TO_STREAM(args, 0x00000008 + ssid_length);
            args = UINT32_TO_STREAM(args, pass_phrase_len);
            ARRAY_TO_STREAM(args, ssid, ssid_length);
            ARRAY_TO_STREAM(args, pf_or_key, pass_phrase_len);

            arg_len = WLAN_ADD_PROFILE_WPA_PARAM_LEN + ssid_length + pass_phrase_len;
        }

        break;
    }

    // Initiate a HCI command
    _hci.command_send(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, ptr, arg_len);

    // Wait for command complete event
    _event.simplelink_wait_event(HCI_CMND_WLAN_IOCTL_ADD_PROFILE, &ret);

    return(ret);
}