void cc3000_event::update_socket_active_status(uint8_t *resp_params) { int32_t status, sd; STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET,sd); STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET,status); if (ERROR_SOCKET_INACTIVE == status) { set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); } }
//***************************************************************************** // //! update_socket_active_status //! //! @param resp_params Socket IS //! @return Current status of the socket. //! //! @brief Retrieve socket status // //***************************************************************************** void update_socket_active_status(CHAR *resp_params) { INT32 status, sd; STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_SOCKET_OFFSET, sd); STREAM_TO_UINT32(resp_params, BSD_RSP_PARAMS_STATUS_OFFSET, status); if (ERROR_SOCKET_INACTIVE == status) { set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); } }
/******************************************************************************* ** ** Function smp_proc_passkey ** ** Description This function is called to process a passkey. ** ** Returns void ** *******************************************************************************/ void smp_proc_passkey(tSMP_CB *p_cb , tBTM_RAND_ENC *p) { UINT8 *tt = p_cb->tk; tSMP_KEY key; UINT32 passkey; /* 19655 test number; */ UINT8 *pp = p->param_buf; SMP_TRACE_DEBUG0 ("smp_proc_passkey "); STREAM_TO_UINT32(passkey, pp); passkey &= ~SMP_PASSKEY_MASK; /* truncate by maximum value */ while (passkey > BTM_MAX_PASSKEY_VAL) passkey >>= 1; SMP_TRACE_ERROR1("Passkey generated = %d", passkey); /* save the TK */ memset(p_cb->tk, 0, BT_OCTET16_LEN); UINT32_TO_STREAM(tt, passkey); key.key_type = SMP_KEY_TYPE_TK; key.p_data = p_cb->tk; if (p_cb->p_callback) { (*p_cb->p_callback)(SMP_PASSKEY_NOTIF_EVT, p_cb->pairing_bda, (tSMP_EVT_DATA *)&passkey); } smp_sm_event(p_cb, SMP_KEY_READY_EVT, (tSMP_INT_DATA *)&key); }
void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf) { UINT16 cmd_len; #if (GATTS_INCLUDED == TRUE) UINT8 op_code; #endif ///GATTS_INCLUDED == TRUE UINT8 *p, *p_orig = (UINT8 *)(p_buf + 1) + p_buf->offset; UINT32 counter; if (p_buf->len < GATT_AUTH_SIGN_LEN + 4) { GATT_TRACE_ERROR("%s: Data length %u less than expected %u", __func__, p_buf->len, GATT_AUTH_SIGN_LEN + 4); return; } cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4; p = p_orig + cmd_len - 4; STREAM_TO_UINT32(counter, p); if (BTM_BleVerifySignature(p_tcb->peer_bda, p_orig, cmd_len, counter, p)) { #if (GATTS_INCLUDED == TRUE) STREAM_TO_UINT8(op_code, p_orig); gatt_server_handle_client_req (p_tcb, op_code, (UINT16)(p_buf->len - 1), p_orig); #endif ///GATTS_INCLUDED == TRUE } else { /* if this is a bad signature, assume from attacker, ignore it */ GATT_TRACE_ERROR("Signature Verification Failed, data ignored"); } return; }
/******************************************************************************* ** ** Function nfc_enabled ** ** Description NFCC enabled, proceed with stack start up. ** ** Returns void ** *******************************************************************************/ void nfc_enabled (tNFC_STATUS nfc_status, BT_HDR *p_init_rsp_msg) { tNFC_RESPONSE evt_data; tNFC_CONN_CB *p_cb = &nfc_cb.conn_cb[NFC_RF_CONN_ID]; UINT8 *p; UINT8 num_interfaces = 0, xx; int yy = 0; memset (&evt_data, 0, sizeof (tNFC_RESPONSE)); if (nfc_status == NCI_STATUS_OK) { nfc_set_state (NFC_STATE_IDLE); p = (UINT8 *) (p_init_rsp_msg + 1) + p_init_rsp_msg->offset + NCI_MSG_HDR_SIZE + 1; /* we currently only support NCI of the same version. * We may need to change this, when we support multiple version of NFCC */ evt_data.enable.nci_version = NCI_VERSION; STREAM_TO_UINT32 (evt_data.enable.nci_features, p); STREAM_TO_UINT8 (num_interfaces, p); evt_data.enable.nci_interfaces = 0; for (xx = 0; xx < num_interfaces; xx++) { if ((*p) <= NCI_INTERFACE_MAX) evt_data.enable.nci_interfaces |= (1 << (*p)); #if(NFC_NXP_NOT_OPEN_INCLUDED == TRUE) else if (((*p) >= NCI_INTERFACE_FIRST_VS) && (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE)) #else else if (((*p) > NCI_INTERFACE_FIRST_VS) && (yy < NFC_NFCC_MAX_NUM_VS_INTERFACE)) #endif { /* save the VS RF interface in control block, if there's still room */ nfc_cb.vs_interface[yy++] = *p; } p++; } nfc_cb.nci_interfaces = evt_data.enable.nci_interfaces; memcpy (evt_data.enable.vs_interface, nfc_cb.vs_interface, NFC_NFCC_MAX_NUM_VS_INTERFACE); evt_data.enable.max_conn = *p++; STREAM_TO_UINT16 (evt_data.enable.max_ce_table, p); #if (NFC_RW_ONLY == FALSE) nfc_cb.max_ce_table = evt_data.enable.max_ce_table; nfc_cb.nci_features = evt_data.enable.nci_features; nfc_cb.max_conn = evt_data.enable.max_conn; #endif nfc_cb.nci_ctrl_size = *p++; /* Max Control Packet Payload Length */ p_cb->init_credits = p_cb->num_buff = 0; STREAM_TO_UINT16 (evt_data.enable.max_param_size, p); nfc_set_conn_id (p_cb, NFC_RF_CONN_ID); evt_data.enable.manufacture_id = *p++; STREAM_TO_ARRAY (evt_data.enable.nfcc_info, p, NFC_NFCC_INFO_LEN); NFC_DiscoveryMap (nfc_cb.num_disc_maps, (tNCI_DISCOVER_MAPS *) nfc_cb.p_disc_maps, NULL); }
/******************************************************************************* ** ** Function gatt_verify_signature ** ** Description This function start to verify the sign data when receiving ** the data from peer device. ** ** Returns ** *******************************************************************************/ void gatt_verify_signature(tGATT_TCB *p_tcb, BT_HDR *p_buf) { UINT16 cmd_len; UINT8 op_code; UINT8 *p, *p_orig = (UINT8 *)(p_buf + 1) + p_buf->offset; UINT32 counter; cmd_len = p_buf->len - GATT_AUTH_SIGN_LEN + 4; p = p_orig + cmd_len - 4; STREAM_TO_UINT32(counter, p); if (BTM_BleVerifySignature(p_tcb->peer_bda, p_orig, cmd_len, counter, p)) { STREAM_TO_UINT8(op_code, p_orig); gatt_server_handle_client_req (p_tcb, op_code, (UINT16)(p_buf->len - 1), p_orig); } else { /* if this is a bad signature, assume from attacker, ignore it */ GATT_TRACE_ERROR("Signature Verification Failed, data ignored"); } return; }
//***************************************************************************** // //! hci_unsol_event_handler //! //! @param event_hdr event header //! //! @return 1 if event supported and handled //! 0 if event is not supported //! //! @brief Handle unsolicited events // //***************************************************************************** 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_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: { unsigned char params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status unsigned char *recParams = params; data = (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 = (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 *)¶ms, sizeof(params)); } } break; case HCI_EVNT_BSD_TCP_CLOSE_WAIT: { data = (char *)(event_hdr) + HCI_EVENT_HEADER_SIZE; if( tSLInformation.sWlanCB ) { //data[0] represents the socket id, for which FIN was received by remote. //Upon receiving this event, the user can close the socket, or else the //socket will be closded after inacvitity timeout (by default 60 seconds) tSLInformation.sWlanCB(event_type, data, 1); } } 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); } //handle a case where unsolicited event arrived, but was not handled by any of the cases above if ((event_type != tSLInformation.usRxEventOpcode) && (event_type != HCI_EVNT_PATCHES_REQ)) { return(1); } return(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; }
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_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 = (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 = (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 *)¶ms, sizeof(params)); } } break; case HCI_EVNT_BSD_TCP_CLOSE_WAIT: { 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; }
uint8_t *hci_event_handler(void *pRetParams, uint8_t *from, uint8_t *fromlen) { uint8_t *pucReceivedData, ucArgsize; uint16_t usLength; uint8_t *pucReceivedParams; uint16_t usReceivedEventOpcode = 0; unsigned long retValue32; uint8_t * RecvParams; uint8_t *RetParams; while (1) { if (tSLInformation.usEventOrDataReceived != 0) { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { /* Event Received */ STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = (uint8_t *)pRetParams; /* In case unsolicited event received - here the handling finished */ if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams, 0, *(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((uint8_t *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams, GET_HOST_BY_NAME_RETVAL_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, GET_HOST_BY_NAME_ADDR_OFFSET, *(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams, ACCEPT_SD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, ACCEPT_RETURN_STATUS_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; /* This argument returns in network order */ memcpy((uint8_t *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(struct sockaddr)); } break; case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_SD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_NUM_BYTES_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE__FLAGS__OFFSET, *(unsigned long *)pRetParams); if (((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status (((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor, SOCKET_STATUS_INACTIVE); } } break; case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_SD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SL_RECEIVE_NUM_BYTES_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; } break; case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_STATUS_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_READFD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_WRITEFD_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, SELECT_EXFD_OFFSET, *(unsigned long *)pRetParams); } break; case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, ((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); /* This argument returns in network order */ memcpy((uint8_t *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams, GET_SCAN_RESULTS_TABlE_COUNT_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams, GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams, GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams, GET_SCAN_RESULTS_FRAME_TIME_OFFSET, *(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((uint8_t *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: /* Read IP address */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read subnet */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read default GW */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read DHCP server */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read DNS server */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; /* Read Mac address */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; /* Read SSID */ STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); break; default: PANIC(); break; } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; } } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); /* Data received: note that the only case where from and from length * are not null is in recv from, so fill the args accordingly */ if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET), *fromlen); } memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, usLength - ucArgsize); tSLInformation.usRxDataPending = 0; } tSLInformation.usEventOrDataReceived = 0; cc3000_resume(); /* Since we are going to TX - we need to handle this event after the * ResumeSPi since we need interrupts */ if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { break; } } } return NULL; }
unsigned char * hci_event_handler(void *pRetParams, unsigned char *from, long *fromlen) { unsigned char *pucReceivedData, ucArgsize; unsigned short usLength; unsigned char *pucReceivedParams; unsigned short usReceivedEventOpcode = 0; unsigned long retValue32; unsigned char * RecvParams; unsigned char *RetParams; volatile system_tick_t start = GetSystem1MsTick(); while (1) { if (tSLInformation.usEventOrDataReceived == 0) { volatile system_tick_t now = GetSystem1MsTick(); volatile system_tick_t elapsed = now - start; if (elapsed < 0) { // Did we wrap elapsed = start + now; // yes now } if (cc3000__event_timeout_ms && (elapsed >= cc3000__event_timeout_ms)) { ERROR("Timeout now %ld start %ld elapsed %ld cc3000__event_timeout_ms %ld",now,start,elapsed,cc3000__event_timeout_ms); ERROR("Timeout waiting on tSLInformation.usRxEventOpcode 0x%04x",tSLInformation.usRxEventOpcode); // Timeout Return Error for requested Opcode // This sucks because callers should have initialized pucReceivedParams switch(tSLInformation.usRxEventOpcode) { default: INVALID_CASE(tSLInformation.usRxEventOpcode); break; case HCI_CMND_SIMPLE_LINK_START: case HCI_CMND_READ_BUFFER_SIZE: break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: case HCI_EVNT_READ_SP_VERSION: case HCI_EVNT_SELECT: *(unsigned char *)pRetParams = -1; break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: case HCI_EVNT_BSD_GETHOSTBYNAME: *(int32_t *)pRetParams = -1; break; case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: case HCI_EVNT_ACCEPT: case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: case HCI_CMND_GETSOCKOPT: *(int32_t *)pRetParams = -1; pRetParams += sizeof(int32_t ); *(int32_t *)pRetParams = -1; break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: *(int32_t *)pRetParams = 0; break; case HCI_NETAPP_IPCONFIG: memset(pRetParams,0,sizeof(tNetappIpconfigRetArgs)); break; } break; // Exit Loop } } else { pucReceivedData = (tSLInformation.pucReceivedData); if (*pucReceivedData == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((char *)pucReceivedData, HCI_EVENT_OPCODE_OFFSET, usReceivedEventOpcode); pucReceivedParams = pucReceivedData + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = pRetParams; // In case unsolicited event received - here the handling finished if (hci_unsol_event_handler((char *)pucReceivedData) == 0) { STREAM_TO_UINT8(pucReceivedData, HCI_DATA_LENGTH_OFFSET, usLength); switch(usReceivedEventOpcode) { case HCI_CMND_READ_BUFFER_SIZE: { STREAM_TO_UINT8((char *)pucReceivedParams, 0, tSLInformation.usNumberOfFreeBuffers); STREAM_TO_UINT16((char *)pucReceivedParams, 1, tSLInformation.usSlBufferLength); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,*(unsigned char *)pRetParams); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((char *)pucReceivedParams, 0, *(unsigned long *)pRetParams); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET, *(unsigned char *)pRetParams); pRetParams = ((char *)pRetParams) + 1; STREAM_TO_UINT32((char *)pucReceivedParams, 0, retValue32); UINT32_TO_STREAM((unsigned char *)pRetParams, retValue32); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((char *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(unsigned long *)pRetParams); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_SD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(unsigned long *)pRetParams); if(((tBsdReadReturnParams *)pRetParams)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)pRetParams)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_READFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,SELECT_EXFD_OFFSET,*(unsigned long *)pRetParams); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(pucReceivedData, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)pRetParams)->iStatus); //This argument returns in network order memcpy((unsigned char *)pRetParams, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT32((char *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 4; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; STREAM_TO_UINT16((char *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(unsigned long *)pRetParams); pRetParams = ((char *)pRetParams) + 2; memcpy((unsigned char *)pRetParams, (char *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); } } if (usReceivedEventOpcode == tSLInformation.usRxEventOpcode) { tSLInformation.usRxEventOpcode = 0; tSLInformation.solicitedResponse = 0; } } else { if (tSLInformation.usRxDataPending == 0) { ERROR("type != HCI_TYPE_EVNT is (%d) usRxDataPending=%d usRxEventOpcode=%u usReceivedEventOpcode=%u", *pucReceivedData, tSLInformation.usRxDataPending, tSLInformation.usRxEventOpcode, usReceivedEventOpcode); } else { pucReceivedParams = pucReceivedData; STREAM_TO_UINT8((char *)pucReceivedData, HCI_PACKET_ARGSIZE_OFFSET, ucArgsize); STREAM_TO_UINT16((char *)pucReceivedData, HCI_PACKET_LENGTH_OFFSET, usLength); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((char *)(pucReceivedData + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(unsigned long *)fromlen); memcpy(from, (pucReceivedData + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } // Let's vet length long length = usLength - ucArgsize; if (length <= 0 || length > arraySize(wlan_rx_buffer)) { // Not sane length = -1; } else { memcpy(pRetParams, pucReceivedParams + HCI_DATA_HEADER_SIZE + ucArgsize, length); } // fixes the Nvram read not returning length if (fromlen) { *fromlen = length; } tSLInformation.usRxDataPending = 0; } } tSLInformation.usEventOrDataReceived = 0; SpiResumeSpi(); // Since we are going to TX - we need to handle this event after the // ResumeSPi since we need interrupts if ((*pucReceivedData == HCI_TYPE_EVNT) && (usReceivedEventOpcode == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((char *)pucReceivedData); } if ((tSLInformation.usRxEventOpcode == 0) && (tSLInformation.usRxDataPending == 0)) { break; } } } return NULL; }
/* internal mini-search for a box signature */ int jpeg2000_file_parse(wxInputStream& stream, unsigned long int filepoint, unsigned long int filelimit, int level, char *scansign, unsigned long int *scanpoint) { unsigned long int LBox = 0x00000000; char TBox[5] = "\0\0\0\0"; int8byte XLBox = 0x0000000000000000; unsigned long int box_length = 0; int last_box = 0, box_num = 0; int box_type = ANY_BOX; unsigned char fourbytes[4]; int box_number = 0; /* cycle all over the file */ box_num = 0; last_box = 0; while (!last_box) { /* do not exceed file limit */ if (filepoint >= filelimit) return (0); /* seek on file */ if (stream.SeekI(filepoint, wxFromStart) == wxInvalidOffset) return (-1); /* read the mandatory LBox, 4 bytes */ if (!stream.Read(fourbytes, 4)) { wxLogError(wxT("Problem reading LBox from the file (file ended?)")); return -1; }; LBox = STREAM_TO_UINT32(fourbytes, 0); /* read the mandatory TBox, 4 bytes */ if (!stream.Read(TBox, 4)) { wxLogError(wxT("Problem reading TBox from the file (file ended?)")); return -1; }; /* look if scansign is got */ if ((scansign != NULL) && (memcmp(TBox, scansign, 4) == 0)) { /* hack/exploit */ // stop as soon as you find the level-th codebox if (box_number == level) { memcpy(scansign, " ", 4); *scanpoint = filepoint; return (0); } else box_number++; }; /* determine the box type */ for (box_type = JP_BOX; box_type < UNK_BOX; box_type++) if (memcmp(TBox, jpeg2000box[box_type].value, 4) == 0) break; /* read the optional XLBox, 8 bytes */ if (LBox == 1) { if (!stream.Read(&XLBox, 8)) { wxLogError(wxT("Problem reading XLBox from the file (file ended?)")); return -1; }; box_length = (unsigned long int) BYTE_SWAP8(XLBox); } else if (LBox == 0x00000000) { /* last box in file */ last_box = 1; box_length = filelimit - filepoint; } else box_length = LBox; /* go deep in the box */ jpeg2000_box_handler_function((jpeg2000boxtype) box_type, stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, level, scansign, scanpoint); /* if it's a superbox go inside it */ if (jpeg2000box[box_type].sbox) jpeg2000_file_parse(stream, (LBox == 1) ? (filepoint + 16) : (filepoint + 8), filepoint + box_length, level, scansign, scanpoint); /* increment box number and filepoint*/ box_num++; filepoint += box_length; }; /* all good */ return (0); }
//***************************************************************************** // //! hci_unsol_event_handler //! //! @param event_hdr event header //! //! @return 1 if event supported and handled //! 0 if event is not supported //! //! @brief Handle unsolicited events // //***************************************************************************** INT32 hci_unsol_event_handler(CHAR *event_hdr) { CHAR *data = NULL; INT32 event_type; UINT32 NumberOfReleasedPackets; UINT32 NumberOfSentPackets; STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET, event_type); // Adafruit CC3k Host Driver Difference // Extra debug output. // Noted 12-12-2014 by tdicola DEBUGPRINT_F("\tHCI_UNSOL_EVT: "); DEBUGPRINT_HEX16(event_type); 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 params[NETAPP_IPCONFIG_MAC_OFFSET + 1]; // extra byte is for the status UINT8 *recParams = params; data = (CHAR *) (event_hdr) + HCI_EVENT_HEADER_SIZE; // Read IP address STREAM_TO_STREAM(data, recParams, NETAPP_IPCONFIG_IP_LENGTH); data += 4; #ifdef MDNS_ADVERTISE_HOST localIP[0] = *(recParams - NETAPP_IPCONFIG_IP_LENGTH); localIP[1] = *(recParams - NETAPP_IPCONFIG_IP_LENGTH + 1); localIP[2] = *(recParams - NETAPP_IPCONFIG_IP_LENGTH + 2); localIP[3] = *(recParams - NETAPP_IPCONFIG_IP_LENGTH + 3); #endif // 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 = (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 *) ¶ms, sizeof(params)); } } break; case HCI_EVNT_BSD_TCP_CLOSE_WAIT: { // Adafruit CC3k Host Driver Difference // Extra debug output. // Noted 12-12-2014 by tdicola DEBUGPRINT_F("\tTCP Close Wait\n\r"); data = (CHAR *) (event_hdr) + HCI_EVENT_HEADER_SIZE; if (tSLInformation.sWlanCB) { // data[0] represents the socket id, for which FIN was received by // remote. // Upon receiving this event, the user can close the socket, or else // the // socket will be closded after inacvitity timeout (by default 60 // seconds) tSLInformation.sWlanCB(event_type, data, 1); } } break; case HCI_EVNT_ASYNC_ARP_DONE: case HCI_EVNT_ASYNC_ARP_WAITING: if (tSLInformation.sWlanCB) { tSLInformation.sWlanCB(event_type, 0, 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; INT32 status; // Adafruit CC3k Host Driver Difference // Extra debug output. // Noted 12-12-2014 by tdicola DEBUGPRINT_F("\tSEND event response\n\r"); 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); } // handle a case where unsolicited event arrived, but was not handled by any // of the cases above if ((event_type != tSLInformation.usRxEventOpcode) && (event_type != HCI_EVNT_PATCHES_REQ)) { return (1); } return (0); }
uint8_t *cc3000_event::hci_event_handler(void *ret_param, uint8_t *from, uint8_t *fromlen) { uint8_t *received_data, argument_size; uint16_t length; uint8_t *pucReceivedParams; uint16_t received_op_code = 0; uint32_t return_value; uint8_t * RecvParams; uint8_t *RetParams; while (1) { if (_simple_link.get_data_received_flag() != 0) { received_data = _simple_link.get_received_data(); if (*received_data == HCI_TYPE_EVNT) { // Event Received STREAM_TO_UINT16((uint8_t *)received_data, HCI_EVENT_OPCODE_OFFSET,received_op_code); pucReceivedParams = received_data + HCI_EVENT_HEADER_SIZE; RecvParams = pucReceivedParams; RetParams = (uint8_t *)ret_param; // unsolicited event received - finish handling if (hci_unsol_event_handler((uint8_t *)received_data) == 0) { STREAM_TO_UINT8(received_data, HCI_DATA_LENGTH_OFFSET, length); hci_event_debug_print( received_op_code ); switch(received_op_code) { case HCI_CMND_READ_BUFFER_SIZE: { uint16_t temp = _simple_link.get_number_free_buffers(); STREAM_TO_UINT8((uint8_t *)pucReceivedParams, 0, temp); _simple_link.set_number_free_buffers(temp); temp = _simple_link.get_buffer_length(); STREAM_TO_UINT16((uint8_t *)pucReceivedParams, 1, temp); _simple_link.set_buffer_length(temp); } break; case HCI_CMND_WLAN_CONFIGURE_PATCH: case HCI_NETAPP_DHCP: case HCI_NETAPP_PING_SEND: case HCI_NETAPP_PING_STOP: case HCI_NETAPP_ARP_FLUSH: case HCI_NETAPP_SET_DEBUG_LEVEL: case HCI_NETAPP_SET_TIMERS: case HCI_EVNT_NVMEM_READ: case HCI_EVNT_NVMEM_CREATE_ENTRY: case HCI_CMND_NVMEM_WRITE_PATCH: case HCI_NETAPP_PING_REPORT: case HCI_EVNT_MDNS_ADVERTISE: STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); break; case HCI_CMND_SETSOCKOPT: case HCI_CMND_WLAN_CONNECT: case HCI_CMND_WLAN_IOCTL_STATUSGET: case HCI_EVNT_WLAN_IOCTL_ADD_PROFILE: case HCI_CMND_WLAN_IOCTL_DEL_PROFILE: case HCI_CMND_WLAN_IOCTL_SET_CONNECTION_POLICY: case HCI_CMND_WLAN_IOCTL_SET_SCANPARAM: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_START: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_STOP: case HCI_CMND_WLAN_IOCTL_SIMPLE_CONFIG_SET_PREFIX: case HCI_CMND_EVENT_MASK: case HCI_EVNT_WLAN_DISCONNECT: case HCI_EVNT_SOCKET: case HCI_EVNT_BIND: case HCI_CMND_LISTEN: case HCI_EVNT_CLOSE_SOCKET: case HCI_EVNT_CONNECT: case HCI_EVNT_NVMEM_WRITE: STREAM_TO_UINT32((uint8_t *)pucReceivedParams,0, *(uint32_t *)ret_param); break; case HCI_EVNT_READ_SP_VERSION: STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET, *(uint8_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 1; STREAM_TO_UINT32((uint8_t *)pucReceivedParams, 0, return_value); UINT32_TO_STREAM((uint8_t *)ret_param, return_value); break; case HCI_EVNT_BSD_GETHOSTBYNAME: STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_RETVAL_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_HOST_BY_NAME_ADDR_OFFSET,*(uint32_t *)ret_param); break; case HCI_EVNT_ACCEPT: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_SD_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,ACCEPT_RETURN_STATUS_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; //This argument returns in network order memcpy((uint8_t *)ret_param, pucReceivedParams + ACCEPT_ADDRESS__OFFSET, sizeof(sockaddr)); break; } case HCI_EVNT_RECV: case HCI_EVNT_RECVFROM: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE__FLAGS__OFFSET,*(uint32_t *)ret_param); if(((tBsdReadReturnParams *)ret_param)->iNumberOfBytes == ERROR_SOCKET_INACTIVE) { set_socket_active_status(((tBsdReadReturnParams *)ret_param)->iSocketDescriptor,SOCKET_STATUS_INACTIVE); } break; } case HCI_EVNT_SEND: case HCI_EVNT_SENDTO: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_SD_OFFSET ,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SL_RECEIVE_NUM_BYTES_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; break; } case HCI_EVNT_SELECT: { STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_STATUS_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_READFD_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_WRITEFD_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,SELECT_EXFD_OFFSET,*(uint32_t *)ret_param); break; } case HCI_CMND_GETSOCKOPT: STREAM_TO_UINT8(received_data, HCI_EVENT_STATUS_OFFSET,((tBsdGetSockOptReturnParams *)ret_param)->iStatus); //This argument returns in network order memcpy((uint8_t *)ret_param, pucReceivedParams, 4); break; case HCI_CMND_WLAN_IOCTL_GET_SCAN_RESULTS: STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_TABlE_COUNT_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT32((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_SCANRESULT_STATUS_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 4; STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_ISVALID_TO_SSIDLEN_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 2; STREAM_TO_UINT16((uint8_t *)pucReceivedParams,GET_SCAN_RESULTS_FRAME_TIME_OFFSET,*(uint32_t *)ret_param); ret_param = ((uint8_t *)ret_param) + 2; memcpy((uint8_t *)ret_param, (uint8_t *)(pucReceivedParams + GET_SCAN_RESULTS_FRAME_TIME_OFFSET + 2), GET_SCAN_RESULTS_SSID_MAC_LENGTH); break; case HCI_CMND_SIMPLE_LINK_START: break; case HCI_NETAPP_IPCONFIG: //Read IP address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read subnet STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read default GW STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DHCP server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read DNS server STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_IP_LENGTH); RecvParams += 4; //Read Mac address STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_MAC_LENGTH); RecvParams += 6; //Read SSID STREAM_TO_STREAM(RecvParams,RetParams,NETAPP_IPCONFIG_SSID_LENGTH); break; default : DBG_HCI("UNKNOWN Event Received : 0x%04X ", received_op_code); break; } } if (received_op_code == _simple_link.get_op_code()) { _simple_link.set_op_code(0); } } else { pucReceivedParams = received_data; STREAM_TO_UINT8((uint8_t *)received_data, HCI_PACKET_ARGSIZE_OFFSET, argument_size); STREAM_TO_UINT16((uint8_t *)received_data, HCI_PACKET_LENGTH_OFFSET, length); // Data received: note that the only case where from and from length // are not null is in recv from, so fill the args accordingly if (from) { STREAM_TO_UINT32((uint8_t *)(received_data + HCI_DATA_HEADER_SIZE), BSD_RECV_FROM_FROMLEN_OFFSET, *(uint32_t *)fromlen); memcpy(from, (received_data + HCI_DATA_HEADER_SIZE + BSD_RECV_FROM_FROM_OFFSET) ,*fromlen); } memcpy(ret_param, pucReceivedParams + HCI_DATA_HEADER_SIZE + argument_size, length - argument_size); _simple_link.set_pending_data(0); } _simple_link.set_data_received_flag(0); _spi.wlan_irq_enable(); // Since we are going to TX - we need to handle this event after the ResumeSPi since we need interrupts if ((*received_data == HCI_TYPE_EVNT) && (received_op_code == HCI_EVNT_PATCHES_REQ)) { hci_unsol_handle_patch_request((uint8_t *)received_data); } if ((_simple_link.get_op_code() == 0) && (_simple_link.get_pending_data() == 0)) { return NULL; } } } }
UINT8 *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; } } } }
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 } }
/******************************************************************************* ** ** Function process_l2cap_cmd ** ** Description This function is called when a packet is received on the ** L2CAP signalling CID ** ** Returns void ** *******************************************************************************/ static void process_l2cap_cmd (tL2C_LCB *p_lcb, UINT8 *p, UINT16 pkt_len) { UINT8 *p_pkt_end, *p_next_cmd, *p_cfg_end, *p_cfg_start; UINT8 cmd_code, cfg_code, cfg_len, id; tL2C_CONN_INFO con_info; tL2CAP_CFG_INFO cfg_info; UINT16 rej_reason, rej_mtu, lcid, rcid, info_type; tL2C_CCB *p_ccb; tL2C_RCB *p_rcb; BOOLEAN cfg_rej; UINT16 cfg_rej_len, cmd_len; UINT16 result; tL2C_CONN_INFO ci; #if (defined BLE_INCLUDED && BLE_INCLUDED == TRUE) /* if l2cap command received in CID 1 on top of an LE link, ignore this command */ if (p_lcb->is_ble_link) return; #endif p_next_cmd = p; p_pkt_end = p + pkt_len; memset (&cfg_info, 0, sizeof(cfg_info)); /* An L2CAP packet may contain multiple commands */ while (TRUE) { /* Smallest command is 4 bytes */ if ((p = p_next_cmd) > (p_pkt_end - 4)) break; STREAM_TO_UINT8 (cmd_code, p); STREAM_TO_UINT8 (id, p); STREAM_TO_UINT16 (cmd_len, p); if(cmd_len > GKI_BUF2_SIZE) { L2CAP_TRACE_WARNING0 ("L2CAP - Invalid MTU Size"); l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_MTU_EXCEEDED, id, 0, 0); return; } /* Check command length does not exceed packet length */ if ((p_next_cmd = p + cmd_len) > p_pkt_end) { L2CAP_TRACE_WARNING3 ("Command len bad pkt_len: %d cmd_len: %d code: %d", pkt_len, cmd_len, cmd_code); break; } switch (cmd_code) { case L2CAP_CMD_REJECT: STREAM_TO_UINT16 (rej_reason, p); if (rej_reason == L2CAP_CMD_REJ_MTU_EXCEEDED) { STREAM_TO_UINT16 (rej_mtu, p); /* What to do with the MTU reject ? We have negotiated an MTU. For now */ /* we will ignore it and let a higher protocol timeout take care of it */ L2CAP_TRACE_WARNING2 ("L2CAP - MTU rej Handle: %d MTU: %d", p_lcb->handle, rej_mtu); } if (rej_reason == L2CAP_CMD_REJ_INVALID_CID) { STREAM_TO_UINT16 (rcid, p); STREAM_TO_UINT16 (lcid, p); L2CAP_TRACE_WARNING2 ("L2CAP - rej with CID invalid, LCID: 0x%04x RCID: 0x%04x", lcid, rcid); /* Remote CID invalid. Treat as a disconnect */ if (((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) && (p_ccb->remote_cid == rcid)) { /* Fake link disconnect - no reply is generated */ l2c_csm_execute (p_ccb, L2CEVT_LP_DISCONNECT_IND, NULL); } } /* SonyEricsson Info request Bug workaround (Continue connection) */ else if (rej_reason == L2CAP_CMD_REJ_NOT_UNDERSTOOD && p_lcb->w4_info_rsp) { btu_stop_timer (&p_lcb->info_timer_entry); p_lcb->w4_info_rsp = FALSE; ci.status = HCI_SUCCESS; memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR)); /* For all channels, send the event through their FSMs */ for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) { l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci); } } break; case L2CAP_CMD_CONN_REQ: STREAM_TO_UINT16 (con_info.psm, p); STREAM_TO_UINT16 (rcid, p); if ((p_rcb = l2cu_find_rcb_by_psm (con_info.psm)) == NULL) { L2CAP_TRACE_WARNING1 ("L2CAP - rcvd conn req for unknown PSM: %d", con_info.psm); l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_PSM); break; } else { if (!p_rcb->api.pL2CA_ConnectInd_Cb) { L2CAP_TRACE_WARNING1 ("L2CAP - rcvd conn req for outgoing-only connection PSM: %d", con_info.psm); l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_PSM); break; } } if ((p_ccb = l2cu_allocate_ccb (p_lcb, 0)) == NULL) { L2CAP_TRACE_ERROR0 ("L2CAP - unable to allocate CCB"); l2cu_reject_connection (p_lcb, rcid, id, L2CAP_CONN_NO_RESOURCES); break; } p_ccb->remote_id = id; p_ccb->p_rcb = p_rcb; p_ccb->remote_cid = rcid; l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_REQ, &con_info); break; case L2CAP_CMD_CONN_RSP: STREAM_TO_UINT16 (con_info.remote_cid, p); STREAM_TO_UINT16 (lcid, p); STREAM_TO_UINT16 (con_info.l2cap_result, p); STREAM_TO_UINT16 (con_info.l2cap_status, p); if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) == NULL) { L2CAP_TRACE_WARNING2 ("L2CAP - no CCB for conn rsp, LCID: %d RCID: %d", lcid, con_info.remote_cid); break; } if (p_ccb->local_id != id) { L2CAP_TRACE_WARNING2 ("L2CAP - con rsp - bad ID. Exp: %d Got: %d", p_ccb->local_id, id); break; } if (con_info.l2cap_result == L2CAP_CONN_OK) l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP, &con_info); else if (con_info.l2cap_result == L2CAP_CONN_PENDING) l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_PND, &con_info); else l2c_csm_execute(p_ccb, L2CEVT_L2CAP_CONNECT_RSP_NEG, &con_info); break; case L2CAP_CMD_CONFIG_REQ: p_cfg_end = p + cmd_len; cfg_rej = FALSE; cfg_rej_len = 0; STREAM_TO_UINT16 (lcid, p); STREAM_TO_UINT16 (cfg_info.flags, p); p_cfg_start = p; cfg_info.flush_to_present = cfg_info.mtu_present = cfg_info.qos_present = cfg_info.fcr_present = cfg_info.fcs_present = FALSE; while (p < p_cfg_end) { STREAM_TO_UINT8 (cfg_code, p); STREAM_TO_UINT8 (cfg_len, p); switch (cfg_code & 0x7F) { case L2CAP_CFG_TYPE_MTU: cfg_info.mtu_present = TRUE; STREAM_TO_UINT16 (cfg_info.mtu, p); break; case L2CAP_CFG_TYPE_FLUSH_TOUT: cfg_info.flush_to_present = TRUE; STREAM_TO_UINT16 (cfg_info.flush_to, p); break; case L2CAP_CFG_TYPE_QOS: cfg_info.qos_present = TRUE; STREAM_TO_UINT8 (cfg_info.qos.qos_flags, p); STREAM_TO_UINT8 (cfg_info.qos.service_type, p); STREAM_TO_UINT32 (cfg_info.qos.token_rate, p); STREAM_TO_UINT32 (cfg_info.qos.token_bucket_size, p); STREAM_TO_UINT32 (cfg_info.qos.peak_bandwidth, p); STREAM_TO_UINT32 (cfg_info.qos.latency, p); STREAM_TO_UINT32 (cfg_info.qos.delay_variation, p); break; case L2CAP_CFG_TYPE_FCR: cfg_info.fcr_present = TRUE; STREAM_TO_UINT8 (cfg_info.fcr.mode, p); STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p); STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p); STREAM_TO_UINT16 (cfg_info.fcr.rtrans_tout, p); STREAM_TO_UINT16 (cfg_info.fcr.mon_tout, p); STREAM_TO_UINT16 (cfg_info.fcr.mps, p); break; case L2CAP_CFG_TYPE_FCS: cfg_info.fcs_present = TRUE; STREAM_TO_UINT8 (cfg_info.fcs, p); break; case L2CAP_CFG_TYPE_EXT_FLOW: cfg_info.ext_flow_spec_present = TRUE; STREAM_TO_UINT8 (cfg_info.ext_flow_spec.id, p); STREAM_TO_UINT8 (cfg_info.ext_flow_spec.stype, p); STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p); STREAM_TO_UINT32 (cfg_info.ext_flow_spec.sdu_inter_time, p); STREAM_TO_UINT32 (cfg_info.ext_flow_spec.access_latency, p); STREAM_TO_UINT32 (cfg_info.ext_flow_spec.flush_timeout, p); break; default: /* sanity check option length */ if ((cfg_len + L2CAP_CFG_OPTION_OVERHEAD) <= cmd_len) { p += cfg_len; if ((cfg_code & 0x80) == 0) { cfg_rej_len += cfg_len + L2CAP_CFG_OPTION_OVERHEAD; cfg_rej = TRUE; } } /* bad length; force loop exit */ else { p = p_cfg_end; cfg_rej = TRUE; } break; } } if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) { p_ccb->remote_id = id; if (cfg_rej) { l2cu_send_peer_config_rej (p_ccb, p_cfg_start, (UINT16) (cmd_len - L2CAP_CONFIG_REQ_LEN), cfg_rej_len); } else { l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_REQ, &cfg_info); } } else { /* updated spec says send command reject on invalid cid */ l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_INVALID_CID, id, 0, 0); } break; case L2CAP_CMD_CONFIG_RSP: p_cfg_end = p + cmd_len; STREAM_TO_UINT16 (lcid, p); STREAM_TO_UINT16 (cfg_info.flags, p); STREAM_TO_UINT16 (cfg_info.result, p); cfg_info.flush_to_present = cfg_info.mtu_present = cfg_info.qos_present = cfg_info.fcr_present = cfg_info.fcs_present = FALSE; while (p < p_cfg_end) { STREAM_TO_UINT8 (cfg_code, p); STREAM_TO_UINT8 (cfg_len, p); switch (cfg_code & 0x7F) { case L2CAP_CFG_TYPE_MTU: cfg_info.mtu_present = TRUE; STREAM_TO_UINT16 (cfg_info.mtu, p); break; case L2CAP_CFG_TYPE_FLUSH_TOUT: cfg_info.flush_to_present = TRUE; STREAM_TO_UINT16 (cfg_info.flush_to, p); break; case L2CAP_CFG_TYPE_QOS: cfg_info.qos_present = TRUE; STREAM_TO_UINT8 (cfg_info.qos.qos_flags, p); STREAM_TO_UINT8 (cfg_info.qos.service_type, p); STREAM_TO_UINT32 (cfg_info.qos.token_rate, p); STREAM_TO_UINT32 (cfg_info.qos.token_bucket_size, p); STREAM_TO_UINT32 (cfg_info.qos.peak_bandwidth, p); STREAM_TO_UINT32 (cfg_info.qos.latency, p); STREAM_TO_UINT32 (cfg_info.qos.delay_variation, p); break; case L2CAP_CFG_TYPE_FCR: cfg_info.fcr_present = TRUE; STREAM_TO_UINT8 (cfg_info.fcr.mode, p); STREAM_TO_UINT8 (cfg_info.fcr.tx_win_sz, p); STREAM_TO_UINT8 (cfg_info.fcr.max_transmit, p); STREAM_TO_UINT16 (cfg_info.fcr.rtrans_tout, p); STREAM_TO_UINT16 (cfg_info.fcr.mon_tout, p); STREAM_TO_UINT16 (cfg_info.fcr.mps, p); break; case L2CAP_CFG_TYPE_FCS: cfg_info.fcs_present = TRUE; STREAM_TO_UINT8 (cfg_info.fcs, p); break; case L2CAP_CFG_TYPE_EXT_FLOW: cfg_info.ext_flow_spec_present = TRUE; STREAM_TO_UINT8 (cfg_info.ext_flow_spec.id, p); STREAM_TO_UINT8 (cfg_info.ext_flow_spec.stype, p); STREAM_TO_UINT16 (cfg_info.ext_flow_spec.max_sdu_size, p); STREAM_TO_UINT32 (cfg_info.ext_flow_spec.sdu_inter_time, p); STREAM_TO_UINT32 (cfg_info.ext_flow_spec.access_latency, p); STREAM_TO_UINT32 (cfg_info.ext_flow_spec.flush_timeout, p); break; } } if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) { if (p_ccb->local_id != id) { L2CAP_TRACE_WARNING2 ("L2CAP - cfg rsp - bad ID. Exp: %d Got: %d", p_ccb->local_id, id); break; } if ( (cfg_info.result == L2CAP_CFG_OK) || (cfg_info.result == L2CAP_CFG_PENDING) ) l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_RSP, &cfg_info); else l2c_csm_execute (p_ccb, L2CEVT_L2CAP_CONFIG_RSP_NEG, &cfg_info); } else { L2CAP_TRACE_WARNING1 ("L2CAP - rcvd cfg rsp for unknown CID: 0x%04x", lcid); } break; case L2CAP_CMD_DISC_REQ: STREAM_TO_UINT16 (lcid, p); STREAM_TO_UINT16 (rcid, p); if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) { if (p_ccb->remote_cid == rcid) { p_ccb->remote_id = id; l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_REQ, &con_info); } } else l2cu_send_peer_disc_rsp (p_lcb, id, lcid, rcid); break; case L2CAP_CMD_DISC_RSP: STREAM_TO_UINT16 (rcid, p); STREAM_TO_UINT16 (lcid, p); if ((p_ccb = l2cu_find_ccb_by_cid (p_lcb, lcid)) != NULL) { if ((p_ccb->remote_cid == rcid) && (p_ccb->local_id == id)) { l2c_csm_execute (p_ccb, L2CEVT_L2CAP_DISCONNECT_RSP, &con_info); } } break; case L2CAP_CMD_ECHO_REQ: l2cu_send_peer_echo_rsp (p_lcb, id, p, cmd_len); break; case L2CAP_CMD_ECHO_RSP: if (p_lcb->p_echo_rsp_cb) { tL2CA_ECHO_RSP_CB *p_cb = p_lcb->p_echo_rsp_cb; /* Zero out the callback in case app immediately calls us again */ p_lcb->p_echo_rsp_cb = NULL; (*p_cb) (L2CAP_PING_RESULT_OK); } break; case L2CAP_CMD_INFO_REQ: STREAM_TO_UINT16 (info_type, p); l2cu_send_peer_info_rsp (p_lcb, id, info_type); break; case L2CAP_CMD_INFO_RSP: /* Stop the link connect timer if sent before L2CAP connection is up */ if (p_lcb->w4_info_rsp) { btu_stop_timer (&p_lcb->info_timer_entry); p_lcb->w4_info_rsp = FALSE; } STREAM_TO_UINT16 (info_type, p); STREAM_TO_UINT16 (result, p); p_lcb->info_rx_bits |= (1 << info_type); if ( (info_type == L2CAP_EXTENDED_FEATURES_INFO_TYPE) && (result == L2CAP_INFO_RESP_RESULT_SUCCESS) ) { STREAM_TO_UINT32( p_lcb->peer_ext_fea, p ); #if (L2CAP_NUM_FIXED_CHNLS > 0) if (p_lcb->peer_ext_fea & L2CAP_EXTFEA_FIXED_CHNLS) { l2cu_send_peer_info_req (p_lcb, L2CAP_FIXED_CHANNELS_INFO_TYPE); break; } else { l2cu_process_fixed_chnl_resp (p_lcb); } #endif } #if (L2CAP_NUM_FIXED_CHNLS > 0) if (info_type == L2CAP_FIXED_CHANNELS_INFO_TYPE) { if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) { memcpy (p_lcb->peer_chnl_mask, p, L2CAP_FIXED_CHNL_ARRAY_SIZE); } l2cu_process_fixed_chnl_resp (p_lcb); } #endif #if (L2CAP_UCD_INCLUDED == TRUE) else if (info_type == L2CAP_CONNLESS_MTU_INFO_TYPE) { if (result == L2CAP_INFO_RESP_RESULT_SUCCESS) { STREAM_TO_UINT16 (p_lcb->ucd_mtu, p); } } #endif ci.status = HCI_SUCCESS; memcpy (ci.bd_addr, p_lcb->remote_bd_addr, sizeof(BD_ADDR)); for (p_ccb = p_lcb->ccb_queue.p_first_ccb; p_ccb; p_ccb = p_ccb->p_next_ccb) { l2c_csm_execute (p_ccb, L2CEVT_L2CAP_INFO_RSP, &ci); } break; default: L2CAP_TRACE_WARNING1 ("L2CAP - bad cmd code: %d", cmd_code); l2cu_send_peer_cmd_reject (p_lcb, L2CAP_CMD_REJ_NOT_UNDERSTOOD, id, 0, 0); return; } } }
/******************************************************************************* ** ** Function nfc_hal_dm_proc_msg_during_init ** ** Description Process NCI message while initializing NFCC ** ** Returns void ** *******************************************************************************/ void nfc_hal_dm_proc_msg_during_init (NFC_HDR *p_msg) { UINT8 *p; UINT8 reset_reason, reset_type; UINT8 mt, pbf, gid, op_code; UINT8 *p_old, old_gid, old_oid, old_mt; UINT8 u8; tNFC_HAL_NCI_CBACK *p_cback = NULL; UINT8 chipverlen; UINT8 chipverstr[NCI_SPD_HEADER_CHIPVER_LEN]; UINT32 hw_id = 0; HAL_TRACE_DEBUG1 ("nfc_hal_dm_proc_msg_during_init(): init state:%d", nfc_hal_cb.dev_cb.initializing_state); p = (UINT8 *) (p_msg + 1) + p_msg->offset; NCI_MSG_PRS_HDR0 (p, mt, pbf, gid); NCI_MSG_PRS_HDR1 (p, op_code); /* check if waiting for this response */ if ( (nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_CMD) ||(nfc_hal_cb.ncit_cb.nci_wait_rsp == NFC_HAL_WAIT_RSP_VSC) ) { if (mt == NCI_MT_RSP) { p_old = nfc_hal_cb.ncit_cb.last_hdr; NCI_MSG_PRS_HDR0 (p_old, old_mt, pbf, old_gid); old_oid = ((*p_old) & NCI_OID_MASK); /* make sure this is the RSP we are waiting for before updating the command window */ if ((old_gid == gid) && (old_oid == op_code)) { nfc_hal_cb.ncit_cb.nci_wait_rsp = NFC_HAL_WAIT_RSP_NONE; p_cback = (tNFC_HAL_NCI_CBACK *)nfc_hal_cb.ncit_cb.p_vsc_cback; nfc_hal_cb.ncit_cb.p_vsc_cback = NULL; nfc_hal_main_stop_quick_timer (&nfc_hal_cb.ncit_cb.nci_wait_rsp_timer); } } } if (gid == NCI_GID_CORE) { if (op_code == NCI_MSG_CORE_RESET) { if (mt == NCI_MT_NTF) { if ( (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_NFCC_ENABLE) ||(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_POST_XTAL_SET) ) { /* ** Core reset ntf in the following cases; ** 1) after power up (raising REG_PU) ** 2) after setting xtal index ** Start pre-initializing NFCC */ nfc_hal_main_stop_quick_timer (&nfc_hal_cb.timer); nfc_hal_dm_pre_init_nfcc (); } else { /* Core reset ntf after post-patch download, Call reset notification callback */ p++; /* Skip over param len */ STREAM_TO_UINT8 (reset_reason, p); STREAM_TO_UINT8 (reset_type, p); nfc_hal_prm_spd_reset_ntf (reset_reason, reset_type); } } } else if (p_cback) { (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), p_msg->len, (UINT8 *) (p_msg + 1) + p_msg->offset); } } else if (gid == NCI_GID_PROP) /* this is for download patch */ { if (mt == NCI_MT_NTF) op_code |= NCI_NTF_BIT; else op_code |= NCI_RSP_BIT; if (nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_XTAL_SET) { if (op_code == (NCI_RSP_BIT|NCI_MSG_GET_XTAL_INDEX_FROM_DH)) { /* start timer in case that NFCC doesn't send RESET NTF after loading patch from NVM */ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_POST_XTAL_SET); nfc_hal_main_start_quick_timer (&nfc_hal_cb.timer, NFC_HAL_TTYPE_NFCC_ENABLE, ((p_nfc_hal_cfg->nfc_hal_post_xtal_timeout)*QUICK_TIMER_TICKS_PER_SEC)/1000); } } else if ( (op_code == NFC_VS_GET_BUILD_INFO_EVT) &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_BUILD_INFO) ) { p += NCI_BUILD_INFO_OFFSET_HWID; STREAM_TO_UINT32 (hw_id, p); nfc_hal_cb.dev_cb.brcm_hw_id = nfc_hal_dm_adjust_hw_id (hw_id); HAL_TRACE_DEBUG2 ("brcm_hw_id: 0x%x -> 0x%x", hw_id, nfc_hal_cb.dev_cb.brcm_hw_id); STREAM_TO_UINT8 (chipverlen, p); memset (chipverstr, 0, NCI_SPD_HEADER_CHIPVER_LEN); STREAM_TO_ARRAY (chipverstr, p, chipverlen); nfc_hal_hci_handle_build_info (chipverlen, chipverstr); nfc_hal_cb.pre_set_mem_idx = 0; if (!nfc_hal_dm_check_pre_set_mem()) { /* pre-set mem started */ return; } nfc_hal_dm_check_xtal(); } else if ( (op_code == NFC_VS_GET_PATCH_VERSION_EVT) &&(nfc_hal_cb.dev_cb.initializing_state == NFC_HAL_INIT_STATE_W4_PATCH_INFO) ) { /* Store NVM info to control block */ /* Skip over rsp len */ p++; /* Get project id */ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.project_id, p); /* RFU */ p++; /* Get chip version string */ STREAM_TO_UINT8 (u8, p); if (u8 > NFC_HAL_PRM_MAX_CHIP_VER_LEN) u8 = NFC_HAL_PRM_MAX_CHIP_VER_LEN; memcpy (nfc_hal_cb.nvm_cb.chip_ver, p, u8); p += NCI_PATCH_INFO_VERSION_LEN; /* Get major/minor version */ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_major, p); STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.ver_minor, p); /* Skip over max_size and patch_max_size */ p += 4; /* Get current lpm patch size */ STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.lpm_size, p); STREAM_TO_UINT16 (nfc_hal_cb.nvm_cb.fpm_size, p); /* clear all flags which may be set during previous initialization */ nfc_hal_cb.nvm_cb.flags = 0; /* Set patch present flag */ if ((nfc_hal_cb.nvm_cb.fpm_size) || (nfc_hal_cb.nvm_cb.lpm_size)) nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_PATCH_PRESENT; /* LPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */ STREAM_TO_UINT8 (u8, p); if (u8) { /* LPM patch in NVM fails CRC check */ nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_LPM_BAD; } /* FPMPatchCodeHasBadCRC (if not bad crc, then indicate LPM patch is present in nvm) */ STREAM_TO_UINT8 (u8, p); if (u8) { /* FPM patch in NVM fails CRC check */ nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_FPM_BAD; } /* Check if downloading patch to RAM only (no NVM) */ STREAM_TO_UINT8 (nfc_hal_cb.nvm_cb.nvm_type, p); if (nfc_hal_cb.nvm_cb.nvm_type == NCI_SPD_NVM_TYPE_NONE) { nfc_hal_cb.nvm_cb.flags |= NFC_HAL_NVM_FLAGS_NO_NVM; } /* let platform update baudrate or download patch */ NFC_HAL_SET_INIT_STATE (NFC_HAL_INIT_STATE_W4_APP_COMPLETE); nfc_hal_post_reset_init (nfc_hal_cb.dev_cb.brcm_hw_id, nfc_hal_cb.nvm_cb.nvm_type); } else if (p_cback) { (*p_cback) ((tNFC_HAL_NCI_EVT) (op_code), p_msg->len, (UINT8 *) (p_msg + 1) + p_msg->offset); } else if (op_code == NFC_VS_SEC_PATCH_AUTH_EVT) { HAL_TRACE_DEBUG0 ("signature!!"); nfc_hal_prm_nci_command_complete_cback ((tNFC_HAL_NCI_EVT) (op_code), p_msg->len, (UINT8 *) (p_msg + 1) + p_msg->offset); } } }
int32_t cc3000_event::hci_unsol_event_handler(uint8_t *event_hdr) { uint8_t *data = NULL; int32_t event_type; uint32_t number_of_released_packets; uint32_t number_of_sent_packets; STREAM_TO_UINT16(event_hdr, HCI_EVENT_OPCODE_OFFSET,event_type); if (event_type & HCI_EVNT_UNSOL_BASE) { switch(event_type) { case HCI_EVNT_DATA_UNSOL_FREE_BUFF: { hci_event_unsol_flowcontrol_handler(event_hdr); number_of_released_packets = _simple_link.get_released_packets(); number_of_sent_packets = _simple_link.get_sent_packets(); if (number_of_released_packets == number_of_sent_packets) { if (_simple_link.get_tx_complete_signal()) { //tWlanCB func_pointer = (tWlanCB)_simple_link.get_func_pointer(WLAN_CB); _cc3000.usync_callback(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: _cc3000.usync_callback(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 = (uint8_t *)(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); _cc3000.usync_callback(event_type, (uint8_t *)params, sizeof(params)); break; } case HCI_EVNT_WLAN_ASYNC_PING_REPORT: { netapp_pingreport_args_t params; data = (uint8_t *)(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); _cc3000.usync_callback(event_type, (uint8_t *)¶ms, sizeof(params)); break; } case HCI_EVNT_BSD_TCP_CLOSE_WAIT: { _cc3000.usync_callback(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)) { uint8_t *pArg; int32_t 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 int32_t transmit_error = _simple_link.get_transmit_error(); STREAM_TO_UINT8(event_hdr, HCI_EVENT_STATUS_OFFSET, transmit_error); _simple_link.set_transmit_error(transmit_error); update_socket_active_status(M_BSD_RESP_PARAMS_OFFSET(event_hdr)); return (1); } else { return (0); } } return(0); }