int getsockopt (long sd, long level, long optname, void *optval, socklen_t *optlen) { cc3000_check_irq_pin(); unsigned char *ptr, *args; tBsdGetSockOptReturnParams tRetParams; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, level); args = UINT32_TO_STREAM(args, optname); // Initiate a HCI command hci_command_send(HCI_CMND_GETSOCKOPT, ptr, SOCKET_GET_SOCK_OPT_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_GETSOCKOPT, &tRetParams); if (((signed char)tRetParams.iStatus) >= 0) { *optlen = 4; memcpy(optval, tRetParams.ucOptValue, 4); return (0); } else { errno = tRetParams.iStatus; return errno; } }
long listen(long sd, long backlog) { cc3000_check_irq_pin(); long ret; unsigned char *ptr, *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, backlog); // Initiate a HCI command hci_command_send(HCI_CMND_LISTEN, ptr, SOCKET_LISTEN_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_LISTEN, &ret); errno = ret; return(ret); }
long connect(long sd, const sockaddr *addr, long addrlen) { cc3000_check_irq_pin(); long int ret; unsigned char *ptr, *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); addrlen = 8; // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, 0x00000008); args = UINT32_TO_STREAM(args, addrlen); ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); // Initiate a HCI command hci_command_send(HCI_CMND_CONNECT, ptr, SOCKET_CONNECT_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_CONNECT, &ret); errno = ret; return((long)ret); }
long bind(long sd, const sockaddr *addr, long addrlen) { cc3000_check_irq_pin(); long ret; unsigned char *ptr, *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); addrlen = ASIC_ADDR_LEN; // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, 0x00000008); args = UINT32_TO_STREAM(args, addrlen); ARRAY_TO_STREAM(args, ((unsigned char *)addr), addrlen); // Initiate a HCI command hci_command_send(HCI_CMND_BIND, ptr, SOCKET_BIND_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_BIND, &ret); errno = ret; return(ret); }
long closesocket(long sd) { cc3000_check_irq_pin(); long ret; unsigned char *ptr, *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, sd); // Initiate a HCI command hci_command_send(HCI_CMND_CLOSE_SOCKET, ptr, SOCKET_CLOSE_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_CLOSE_SOCKET, &ret); errno = ret; // since 'close' call may result in either OK (and then it closed) or error // mark this socket as invalid set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); return(ret); }
int socket(long domain, long type, long protocol) { cc3000_check_irq_pin(); long ret; unsigned char *ptr, *args; ret = EFAIL; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, domain); args = UINT32_TO_STREAM(args, type); args = UINT32_TO_STREAM(args, protocol); // Initiate a HCI command hci_command_send(HCI_CMND_SOCKET, ptr, SOCKET_OPEN_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_SOCKET, &ret); // Process the event errno = ret; set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); return(ret); }
long accept(long sd, sockaddr *addr, socklen_t *addrlen) { cc3000_check_irq_pin(); long ret; unsigned char *ptr, *args; tBsdReturnParams tAcceptReturnArguments; ret = EFAIL; tAcceptReturnArguments.iStatus = EFAIL; // in case of timeout ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); // Initiate a HCI command hci_command_send(HCI_CMND_ACCEPT, ptr, SOCKET_ACCEPT_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_ACCEPT, &tAcceptReturnArguments); // if we had a problem while waiting, just exit... if (jspIsInterrupted()) return -1; // need specify return parameters!!! memcpy(addr, &tAcceptReturnArguments.tSocketAddress, ASIC_ADDR_LEN); *addrlen = ASIC_ADDR_LEN; errno = tAcceptReturnArguments.iStatus; ret = errno; // if succeeded, iStatus = new socket descriptor. otherwise - error number if(M_IS_VALID_SD(ret)) { set_socket_active_status(ret, SOCKET_STATUS_ACTIVE); } else { set_socket_active_status(sd, SOCKET_STATUS_INACTIVE); } return(ret); }
int gethostbyname(char * hostname, unsigned short usNameLen, unsigned long* out_ip_addr) { cc3000_check_irq_pin(); tBsdGethostbynameParams ret; unsigned char *ptr, *args; errno = EFAIL; if (usNameLen > HOSTNAME_MAX_LENGTH) { return errno; } ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + SIMPLE_LINK_HCI_CMND_TRANSPORT_HEADER_SIZE); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, 8); args = UINT32_TO_STREAM(args, usNameLen); ARRAY_TO_STREAM(args, hostname, usNameLen); // Initiate a HCI command hci_command_send(HCI_CMND_GETHOSTNAME, ptr, SOCKET_GET_HOST_BY_NAME_PARAMS_LEN + usNameLen - 1); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_EVNT_BSD_GETHOSTBYNAME, &ret); errno = ret.retVal; (*((long*)out_ip_addr)) = ret.outputAddress; return (errno); }
//***************************************************************************** // //! simple_link_recv //! //! @param sd socket handle //! @param buf read buffer //! @param len buffer length //! @param flags indicates blocking or non-blocking operation //! @param from pointer to an address structure indicating source address //! @param fromlen source address structure size //! //! @return Return the number of bytes received, or -1 if an error //! occurred //! //! @brief Read data from socket //! Return the length of the message on successful completion. //! If a message is too long to fit in the supplied buffer, //! excess bytes may be discarded depending on the type of //! socket the message is received from // //***************************************************************************** int simple_link_recv(long sd, void *buf, long len, long flags, sockaddr *from, socklen_t *fromlen, long opcode) { cc3000_check_irq_pin(); unsigned char *ptr, *args; tBsdReadReturnParams tSocketReadEvent; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in HCI packet structure args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, len); args = UINT32_TO_STREAM(args, flags); // Generate the read command, and wait for the hci_command_send(opcode, ptr, SOCKET_RECV_FROM_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(opcode, &tSocketReadEvent); // In case the number of bytes is more then zero - read data if (tSocketReadEvent.iNumberOfBytes > 0) { // Wait for the data in a synchronous way. Here we assume that the bug is // big enough to store also parameters of receive from too.... SimpleLinkWaitData(buf, (unsigned char *)from, (unsigned char *)fromlen); } errno = tSocketReadEvent.iNumberOfBytes; return(tSocketReadEvent.iNumberOfBytes); }
int setsockopt(long sd, long level, long optname, const void *optval, socklen_t optlen) { cc3000_check_irq_pin(); int ret; unsigned char *ptr, *args; ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, level); args = UINT32_TO_STREAM(args, optname); args = UINT32_TO_STREAM(args, 0x00000008); args = UINT32_TO_STREAM(args, optlen); ARRAY_TO_STREAM(args, ((unsigned char *)optval), optlen); // Initiate a HCI command hci_command_send(HCI_CMND_SETSOCKOPT, ptr, SOCKET_SET_SOCK_OPT_PARAMS_LEN + optlen); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_CMND_SETSOCKOPT, &ret); if (ret >= 0) { return (0); } else { errno = ret; return ret; } }
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; }
void cc3000_irq_enable(void) { cc3000_check_irq_pin(); cc3000_ints_enabled = true;
//***************************************************************************** // //! simple_link_send //! //! @param sd socket handle //! @param buf write buffer //! @param len buffer length //! @param flags On this version, this parameter is not supported //! @param to pointer to an address structure indicating destination //! address //! @param tolen destination address structure size //! //! @return Return the number of bytes transmitted, or -1 if an error //! occurred, or -2 in case there are no free buffers available //! (only when SEND_NON_BLOCKING is enabled) //! //! @brief This function is used to transmit a message to another //! socket // //***************************************************************************** int simple_link_send(long sd, const void *buf, long len, long flags, const sockaddr *to, long tolen, long opcode) { cc3000_check_irq_pin(); unsigned char uArgSize, addrlen; unsigned char *ptr, *pDataPtr, *args; unsigned long addr_offset; int res; tBsdReadReturnParams tSocketSendEvent; // Check the bsd_arguments if (0 != (res = HostFlowControlConsumeBuff(sd))) { return res; } //Update the number of sent packets tSLInformation.NumberOfSentPackets++; // Allocate a buffer and construct a packet and send it over spi ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_DATA); // Update the offset of data and parameters according to the command switch(opcode) { case HCI_CMND_SENDTO: { addr_offset = len + sizeof(len) + sizeof(len); addrlen = 8; uArgSize = SOCKET_SENDTO_PARAMS_LEN; pDataPtr = ptr + HEADERS_SIZE_DATA + SOCKET_SENDTO_PARAMS_LEN; break; } case HCI_CMND_SEND: { tolen = 0; to = NULL; uArgSize = HCI_CMND_SEND_ARG_LENGTH; pDataPtr = ptr + HEADERS_SIZE_DATA + HCI_CMND_SEND_ARG_LENGTH; break; } default: { break; } } // Fill in temporary command buffer args = UINT32_TO_STREAM(args, sd); args = UINT32_TO_STREAM(args, uArgSize - sizeof(sd)); args = UINT32_TO_STREAM(args, len); args = UINT32_TO_STREAM(args, flags); if (opcode == HCI_CMND_SENDTO) { args = UINT32_TO_STREAM(args, addr_offset); args = UINT32_TO_STREAM(args, addrlen); } // Copy the data received from user into the TX Buffer ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)buf), len); // In case we are using SendTo, copy the to parameters if (opcode == HCI_CMND_SENDTO) { ARRAY_TO_STREAM(pDataPtr, ((unsigned char *)to), tolen); } // Initiate a HCI command hci_data_send(opcode, ptr, uArgSize, len,(unsigned char*)to, tolen); if (opcode == HCI_CMND_SENDTO) SimpleLinkWaitEvent(HCI_EVNT_SENDTO, &tSocketSendEvent); else SimpleLinkWaitEvent(HCI_EVNT_SEND, &tSocketSendEvent); return (len); }
int select(long nfds, fd_set *readsds, fd_set *writesds, fd_set *exceptsds, struct timeval *timeout) { cc3000_check_irq_pin(); unsigned char *ptr, *args; tBsdSelectRecvParams tParams; unsigned long is_blocking; if( timeout == NULL) { is_blocking = 1; /* blocking , infinity timeout */ } else { is_blocking = 0; /* no blocking, timeout */ } // Fill in HCI packet structure ptr = tSLInformation.pucTxCommandBuffer; args = (ptr + HEADERS_SIZE_CMD); // Fill in temporary command buffer args = UINT32_TO_STREAM(args, nfds); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, 0x00000014); args = UINT32_TO_STREAM(args, is_blocking); args = UINT32_TO_STREAM(args, ((readsds) ? *(unsigned long*)readsds : 0)); args = UINT32_TO_STREAM(args, ((writesds) ? *(unsigned long*)writesds : 0)); args = UINT32_TO_STREAM(args, ((exceptsds) ? *(unsigned long*)exceptsds : 0)); if (timeout) { if ( 0 == timeout->tv_sec && timeout->tv_usec < SELECT_TIMEOUT_MIN_MICRO_SECONDS) { timeout->tv_usec = SELECT_TIMEOUT_MIN_MICRO_SECONDS; } args = UINT32_TO_STREAM(args, timeout->tv_sec); args = UINT32_TO_STREAM(args, timeout->tv_usec); } // Initiate a HCI command hci_command_send(HCI_CMND_BSD_SELECT, ptr, SOCKET_SELECT_PARAMS_LEN); // Since we are in blocking state - wait for event complete SimpleLinkWaitEvent(HCI_EVNT_SELECT, &tParams); // Update actually read FD if (tParams.iStatus >= 0) { if (readsds) { memcpy(readsds, &tParams.uiRdfd, sizeof(tParams.uiRdfd)); } if (writesds) { memcpy(writesds, &tParams.uiWrfd, sizeof(tParams.uiWrfd)); } if (exceptsds) { memcpy(exceptsds, &tParams.uiExfd, sizeof(tParams.uiExfd)); } return(tParams.iStatus); } else { errno = tParams.iStatus; return(-1); } }