Esempio n. 1
0
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;

}
/**
 * @brief  The handler for Interrupt that is generated on SPI at the end of DMA
 transfer.
 * @param  None
 * @retval None
 */
void SPI_DMA_IntHandler(void)
{
	unsigned long ucTxFinished, ucRxFinished;
	unsigned short data_to_recv = 0;

	ucTxFinished = DMA_GetFlagStatus(CC3000_SPI_TX_DMA_TCFLAG );
	ucRxFinished = DMA_GetFlagStatus(CC3000_SPI_RX_DMA_TCFLAG );
	switch(sSpiInformation.ulSpiState)
	{
	case eSPI_STATE_READ_IRQ:
	  // Both Done
          if (ucTxFinished && ucRxFinished)
          {
                  /* Clear SPI_DMA Interrupt Pending Flags */
                  DMA_ClearFlag(CC3000_SPI_TX_DMA_TCFLAG | CC3000_SPI_RX_DMA_TCFLAG);

                  sSpiInformation.ulSpiState = eSPI_STATE_READ_PROCEED;

                  uint16_t *pnetlen = (uint16_t *) &sSpiInformation.pRxPacket[READ_OFFSET_TO_LENGTH];
                  data_to_recv = ntohs(*pnetlen);
                  if (data_to_recv)
                     {
                       /* We will read ARRAY_SIZE(spi_readCommand) + data_to_recv. is it odd? */

                       if ((data_to_recv +  arraySize(spi_readCommand)) & 1)
                         {
                           /* Odd so make it even */

                           data_to_recv++;
                         }

                       /* Read the whole payload in at the beginning of the buffer
                        * Will it fit?
                        */
                       SPARK_ASSERT(data_to_recv <= arraySize(wlan_rx_buffer));
                       SpiIO(eRead,sSpiInformation.pRxPacket,data_to_recv, FALSE);
                     }
          }
	  break;

	case eSPI_STATE_READ_PROCEED:
          //
          // All the data was read - finalize handling by switching to the task
          // and calling from task Event Handler
          //
          if (ucRxFinished)
          {
                  /* Clear SPI_DMA Interrupt Pending Flags */
                  DMA_ClearFlag(CC3000_SPI_TX_DMA_TCFLAG | CC3000_SPI_RX_DMA_TCFLAG);

                  SpiPauseSpi();
                  SetState(eSPI_STATE_IDLE, eDeAssert);
                  WARN("CC3000 DmaHandler release read spi bus");
                  // Call out to the Unsolicited handler
                  // It will handle the event or leave it there for an outstanding opcode
                  // It it handles it the it Will resume the SPI ISR
                  // It it dose not handles it and there are not outstanding Opcodes the it Will resume the SPI ISR
                  sSpiInformation.SPIRxHandler(sSpiInformation.pRxPacket);

          }
          break;

	case eSPI_STATE_FIRST_WRITE:
	case eSPI_STATE_WRITE_PROCEED:
          if (ucTxFinished)
          {
                  /* Loop until SPI busy */
                  while (SPI_I2S_GetFlagStatus(CC3000_SPI, SPI_I2S_FLAG_BSY ) != RESET)
                  {
                  }

                  /* Clear SPI_DMA Interrupt Pending Flags */
                  DMA_ClearFlag(CC3000_SPI_TX_DMA_TCFLAG | CC3000_SPI_RX_DMA_TCFLAG);

                  if ( sSpiInformation.ulSpiState == eSPI_STATE_FIRST_WRITE)
                  {
                      sSpiInformation.ulSpiState = eSPI_STATE_WRITE_PROCEED;
                  }
                  else
                  {
                      SetState(eSPI_STATE_IDLE, eDeAssert);
                      WARN("CC3000 DmaHandler release write spi bus");
                  }
          }
          break;

	default:
	  INVALID_CASE(sSpiInformation.ulSpiState);
	  break;

	}
}