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;
}
Example #2
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;
}
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 #4
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 #5
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

	}

}
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;
            }
        }
    }
}
Example #7
0
long hci_unsol_event_handler(char *event_hdr)
{
  char * data = NULL;
  long event_type;
  unsigned long NumberOfReleasedPackets;
  unsigned long NumberOfSentPackets;

  STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET, event_type);

  if (event_type == HCI_EVNT_PATCHES_REQ)
    {
      hci_unsol_handle_patch_request(event_hdr);
    }

  if (event_type & HCI_EVNT_UNSOL_BASE)
    {
      switch (event_type)
        {
        case HCI_EVNT_DATA_UNSOL_FREE_BUFF:
          {
            hci_event_unsol_flowcontrol_handler(event_hdr);

            NumberOfReleasedPackets = tSLInformation.NumberOfReleasedPackets;
            NumberOfSentPackets = tSLInformation.NumberOfSentPackets;

            if (NumberOfReleasedPackets == NumberOfSentPackets)
              {
                if (tSLInformation.InformHostOnTxComplete)
                  {
                    tSLInformation.sWlanCB(HCI_EVENT_CC3000_CAN_SHUT_DOWN, NULL, 0);
                  }
              }

            return 1;
          }
      }
  }

  if (event_type & HCI_EVNT_WLAN_UNSOL_BASE)
    {
      switch (event_type)
        {
        case HCI_EVNT_WLAN_KEEPALIVE:
        case HCI_EVNT_WLAN_UNSOL_CONNECT:
        case HCI_EVNT_WLAN_UNSOL_DISCONNECT:
        case HCI_EVNT_WLAN_UNSOL_INIT:
        case HCI_EVNT_WLAN_ASYNC_SIMPLE_CONFIG_DONE:

        if (tSLInformation.sWlanCB)
          {
            tSLInformation.sWlanCB(event_type, 0, 0);
          }
        break;

        case HCI_EVNT_WLAN_UNSOL_DHCP:
          {
            uint8_t  params[NETAPP_IPCONFIG_MAC_OFFSET + 1];  /* Extra byte is for the status */
            uint8_t *recParams = params;

            data = (FAR char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;

            /* Read IP address */

            STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH);
            data += 4;

            /* Read subnet */

            STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH);
            data += 4;

            /* Read default GW */

            STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH);
            data += 4;

            /* Read DHCP server */

            STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH);
            data += 4;

            /* Read DNS server */

            STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH);

            /* Read the status */

            STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, *recParams);

            if (tSLInformation.sWlanCB)
              {
                tSLInformation.sWlanCB(event_type, (char *)params, sizeof(params));
              }
          }
          break;

        case HCI_EVNT_WLAN_ASYNC_PING_REPORT:
          {
            netapp_pingreport_args_t params;
            data = (FAR char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
            STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, params.packets_sent);
            STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_RCVD_OFFSET, params.packets_received);
            STREAM_TO_UINT32(data, NETAPP_PING_MIN_RTT_OFFSET, params.min_round_time);
            STREAM_TO_UINT32(data, NETAPP_PING_MAX_RTT_OFFSET, params.max_round_time);
            STREAM_TO_UINT32(data, NETAPP_PING_AVG_RTT_OFFSET, params.avg_round_time);

            if (tSLInformation.sWlanCB)
              {
                tSLInformation.sWlanCB(event_type, (char *)&params, sizeof(params));
              }
          }
          break;

        case HCI_EVNT_BSD_TCP_CLOSE_WAIT:
          {
            int sockfd;

            data = (FAR char *)(event_hdr) + HCI_EVENT_HEADER_SIZE;
            STREAM_TO_UINT32(data, NETAPP_PING_PACKETS_SENT_OFFSET, sockfd);
            data += 4;

            (void)cc3000_remote_closed_socket(sockfd);

            if (tSLInformation.sWlanCB)
              {
                tSLInformation.sWlanCB(event_type, NULL, 0);
              }
          }
          break;

        /* 'default' case which means "event not supported" */

        default:
          return 0;
        }

      return 1;
    }

  if ((event_type == HCI_EVNT_SEND) || (event_type == HCI_EVNT_SENDTO) ||
      (event_type == HCI_EVNT_WRITE))
    {
      char *pArg;
      long status;

      pArg = M_BSD_RESP_PARAMS_OFFSET(event_hdr);
      STREAM_TO_UINT32(pArg, BSD_RSP_PARAMS_STATUS_OFFSET, status);

      if (ERROR_SOCKET_INACTIVE == status)
        {
          /* The only synchronous event that can come from SL device in form of
           * command complete is "Command Complete" on data sent, in case SL device
           * was unable to transmit
           */

          STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET,
                          tSLInformation.slTransmitDataError);
                          update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr));

          return 1;
        }
      else
        {
          return 0;
        }
    }

  return 0;
}