/* * create the WMI request to connect to a socket */ AJ_Status AJ_WSL_NET_socket_connect(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port, uint16_t family) { AJ_Status status; AJ_BufList* connectV4; wsl_work_item* item = NULL; connectV4 = AJ_BufListCreate(); WSL_MarshalPacket(connectV4, WSL_SOCKET, WSL_SOCK_CONNECT, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, port, family, &addr, 0x8); WMI_MarshalHeader(connectV4, 1, 1); AJ_WSL_WMI_PadPayload(connectV4); //AJ_BufListPrintDumpContinuous(connectV4); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectV4); do { status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CONNECT)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_connect(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return status; }
/* * create the WMI request to open a socket on the target device */ int8_t AJ_WSL_NET_socket_open(uint16_t domain, uint16_t type, uint16_t protocol) { AJ_Status status; uint8_t handle = AJ_WSL_SOCKET_MAX; AJ_BufList* open; open = AJ_BufListCreate(); WSL_MarshalPacket(open, WSL_SOCKET, WSL_SOCK_OPEN, 0x0c, domain, type, protocol); WMI_MarshalHeader(open, 1, 1); AJ_WSL_WMI_PadPayload(open); //AJ_BufListPrintDumpContinuous(open); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN), AJ_WSL_HTC_DATA_ENDPOINT1, open); // wait until the command completes { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN), &item); if (status != AJ_OK) { AJ_WSL_WMI_FreeWorkItem(item); return -1; } if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_OPEN)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_open(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode); AJ_InfoPrintf((" Socket Open: handle %08lx error %08lx\n", _handle, _error)); handle = AJ_WSL_FindOpenSocketContext(); if (handle != AJ_WSL_SOCKET_MAX) { AJ_WSL_SOCKET_CONTEXT[handle].targetHandle = _handle; AJ_WSL_SOCKET_CONTEXT[handle].valid = TRUE; AJ_WSL_SOCKET_CONTEXT[handle].domain = domain; AJ_WSL_SOCKET_CONTEXT[handle].type = type; AJ_WSL_SOCKET_CONTEXT[handle].protocol = protocol; } } else { AJ_WarnPrintf(("AJ_WSL_NET_socket_open(): BAD WORK ITEM RECEIVED\n")); } } AJ_WSL_WMI_FreeWorkItem(item); } AJ_Sleep(100); return handle; }
AJ_Status AJ_WSL_NET_set_sock_options(uint32_t socket, uint32_t level, uint32_t optname, uint32_t optlen, uint8_t* optval) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_set_sock_options()\n")); wsl_work_item* item; AJ_BufList* opts; AJ_BufNode* trailer; uint32_t total_length; opts = AJ_BufListCreate(); total_length = AJ_SOCK_OPTS_OFFSET + optlen; WSL_MarshalPacket(opts, WSL_SOCKET, WSL_SOCK_SETSOCKOPT, total_length, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, level, optname, optlen); if (optname == WSL_JOIN_GROUP) { trailer = AJ_BufListCreateNode((optlen / 2) + 2); memcpy(opts->tail->buffer + opts->tail->length - 17, optval, (optlen / 2) + 1); memcpy(trailer->buffer, optval + 17, 15); } else { trailer = AJ_BufListCreateNode(optlen + 3); memset(trailer->buffer, 0, optlen + 3); } AJ_BufListPushTail(opts, trailer); WMI_MarshalHeader(opts, 1, 1); //AJ_BufListPrintDumpContinuous(opts); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_SETSOCKOPT), AJ_WSL_HTC_DATA_ENDPOINT1, opts); // wait until the command completes status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_SETSOCKOPT), &item); AJ_WSL_WMI_FreeWorkItem(item); return status; }
/* * create the WMI request to close a socket on the target device */ AJ_Status AJ_WSL_NET_socket_close(AJ_WSL_SOCKNUM sock) { AJ_Status status; AJ_BufList* close; if (AJ_WSL_SOCKET_CONTEXT[sock].valid == TRUE) { close = AJ_BufListCreate(); WSL_MarshalPacket(close, WSL_SOCKET, WSL_SOCK_CLOSE, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle); WMI_MarshalHeader(close, 1, 1); AJ_WSL_WMI_PadPayload(close); //AJ_BufListPrintDumpContinuous(close); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE), AJ_WSL_HTC_DATA_ENDPOINT1, close); // wait until the command completes do { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_close(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode); AJ_InfoPrintf((" Socket close: handle %08lx error %08lx\n", _handle, _error)); if (_handle == AJ_WSL_SOCKET_CONTEXT[sock].targetHandle) { AJ_WSL_SOCKET_CONTEXT[sock].targetHandle = UINT32_MAX; AJ_WSL_SOCKET_CONTEXT[sock].valid = FALSE; } AJ_WSL_WMI_FreeWorkItem(item); break; // waited until close command completed } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_close(): BAD WORK ITEM RECEIVED\n")); } } AJ_WSL_WMI_FreeWorkItem(item); } while (1); } return status; }
int16_t AJ_WSL_NET_socket_sendto6(uint32_t socket, uint8_t* data, uint16_t size, uint8_t* addr, uint16_t port, uint32_t timeout) { AJ_Status status; AJ_InfoPrintf(("AJ_WSL_NET_socket_sendto()\n")); AJ_BufList* send; AJ_BufNode* tx_data_node; if (AJ_WSL_SOCKET_CONTEXT[socket].valid == FALSE) { AJ_InfoPrintf(("sendto on invalid socket %ld\n", socket)); return -1; } send = AJ_BufListCreate(); tx_data_node = AJ_BufListCreateNodeExternalZero(data, size, FALSE); WMI_MarshalSendTo6(send, AJ_WSL_SOCKET_CONTEXT[socket].targetHandle, tx_data_node, size, addr, port); //send now contains the header info for the two part packet your sending //now write send to the MBOX then the data your sending AJ_WSL_WMI_PadPayload(send); //AJ_BufListPrintDumpContinuous(send); AJ_WSL_WMI_QueueWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), AJ_WSL_HTC_DATA_ENDPOINT2, send); wsl_work_item* item = NULL; /* * Because these are blocking sends, we need to wait until the data has been passed to the target. */ do { status = AJ_WSL_WMI_WaitForWorkItem(socket, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { AJ_InfoPrintf(("AJ_WSL_NET_socket_send(): WORK ITEM RECEIVED\n")); AJ_WSL_WMI_FreeWorkItem(item); break; } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_sendto(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); return size; }
/* * This function just returns the work item. If there is data inside that you want * you have to unmarshal it after you receive the work item. */ AJ_Status AJ_WSL_WMI_WaitForWorkItem(uint32_t socket, uint8_t command, wsl_work_item** item, uint32_t timeout) { AJ_Status status; AJ_Time timer; AJ_InitTimer(&timer); // AJ_AlwaysPrintf(("WaitForWorkItem: %x\n", command)); //wsl_work_item* item; status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[socket].workRxQueue, item, timeout); timeout -= AJ_GetElapsedTime(&timer, TRUE); if ((status == AJ_OK) && item && *item) { if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_INTERUPT)) { // We don't care about the interrupted signal for any calls using this function AJ_WSL_WMI_FreeWorkItem((*item)); status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[socket].workRxQueue, item, timeout); } if ((status == AJ_OK) && ((*item)->itemType == command)) { AJ_InfoPrintf(("AJ_WSL_WMI_WaitForWorkItem(): Received work item %s\n", WSL_WorkItemText(command))); return AJ_OK; } else if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_DISCONNECT)) { AJ_InfoPrintf(("Got disconnect while waiting for %s\n", WSL_WorkItemText(command))); // Clean up the network queues int i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { wsl_work_item* clear; AJ_WSL_SOCKET_CONTEXT[i].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[i].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[i].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } while (AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &clear, 0) == AJ_OK) { AJ_WSL_WMI_FreeWorkItem(clear); } AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue); } AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_LINK_DEAD; } else if ((status == AJ_OK) && ((*item)->itemType == WSL_NET_DATA_RX)) { // If we got data we want to save it and not throw it away, its still not what we // wanted so we can free the work item as it wont be needed at a higher level AJ_InfoPrintf(("Got data while waiting for %s\n", WSL_WorkItemText(command))); if ((*item)->node->length) { AJ_BufNode* new_node = AJ_BufNodeCreateAndTakeOwnership((*item)->node); AJ_BufListPushTail(AJ_WSL_SOCKET_CONTEXT[socket].stashedRxList, new_node); AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_NULL; } } else { AJ_WarnPrintf(("AJ_WSL_WMI_WaitForWorkItem(): Received incorrect work item %s, wanted %s\n", WSL_WorkItemText((*item)->itemType), WSL_WorkItemText(command))); // Wrong work item, but return NULL because we can free the item internally AJ_WSL_WMI_FreeWorkItem((*item)); return AJ_ERR_NULL; } } return AJ_ERR_NULL; }
AJ_Status AJ_WSL_NET_socket_bind6(AJ_WSL_SOCKNUM sock, uint8_t* addr, uint16_t port) { AJ_Status status; AJ_BufList* bind; wsl_work_item* item; bind = AJ_BufListCreate(); WSL_MarshalPacket(bind, WSL_BIND6, 0x0, 0x03, 0x24, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, 0x00, port, addr, 0x00, 0x00020383, 0x0002001c); WMI_MarshalHeader(bind, 1, 1); AJ_WSL_WMI_PadPayload(bind); //AJ_BufListPrintDumpContinuous(bind); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_BIND), AJ_WSL_HTC_DATA_ENDPOINT1, bind); status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_BIND), &item); AJ_WSL_WMI_FreeWorkItem(item); return status; }
AJ_Status AJ_WSL_NET_set_hostname(const char* hostname) { AJ_Status status; AJ_InfoPrintf(("===== SET HOSTNAME ====\n")); wsl_work_item* item; AJ_BufList* host; host = AJ_BufListCreate(); WSL_MarshalPacket(host, WSL_SOCKET, WSL_SOCK_IP_HOST_NAME, 0x21, hostname); WMI_MarshalHeader(host, 1, 1); AJ_WSL_WMI_PadPayload(host); //AJ_BufListPrintDumpContinuous(host); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP_HOST_NAME), AJ_WSL_HTC_DATA_ENDPOINT1, host); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP_HOST_NAME), &item); AJ_WSL_WMI_FreeWorkItem(item); return status; }
AJ_Status AJ_WSL_NET_disconnect(void) { AJ_Status status; AJ_BufList* disconnect; wsl_work_item* item; AJ_AlwaysPrintf((("AJ_WSL_NET_disconnect(): DISCONNECT\n"))); disconnect = AJ_BufListCreate(); WSL_MarshalPacket(disconnect, WSL_DISCONNECT, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(disconnect, 1, 1); AJ_WSL_WMI_PadPayload(disconnect); //AJ_BufListPrintDumpContinuous(disconnect); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_DISCONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, disconnect); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_DISCONNECT), &item); AJ_WSL_WMI_FreeWorkItem(item); return status; }
/* * create the WMI request to bind a socket on the target device to an address and port */ AJ_Status AJ_WSL_NET_socket_bind(AJ_WSL_SOCKNUM sock, uint32_t addr, uint16_t port) { AJ_Status status; AJ_BufList* bind; wsl_work_item* item; bind = AJ_BufListCreate(); WSL_MarshalPacket(bind, WSL_SOCKET, WSL_SOCK_BIND, 0x0, AJ_WSL_SOCKET_CONTEXT[sock].targetHandle, port, AJ_WSL_UDP, &addr, 0x8); WMI_MarshalHeader(bind, 1, 1); AJ_WSL_WMI_PadPayload(bind); //AJ_BufListPrintDumpContinuous(bind); AJ_WSL_WMI_QueueWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_BIND), AJ_WSL_HTC_DATA_ENDPOINT1, bind); status = AJ_WSL_WMI_WaitForWorkItem(sock, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_BIND), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } return status; }
AJ_Status AJ_WSL_ip6config(uint32_t mode, uint8_t* globalAddr, uint8_t* localAddr, uint8_t* gateway, uint8_t* exAddr, uint32_t linkPrefix, uint32_t globalPrefix, uint32_t gwPrefix, uint32_t glbPrefixExt) { AJ_Status status; if (mode != IPCONFIG_QUERY) { AJ_ErrPrintf(("AJ_WSL_ip6config(): Can only query IPV6, cannot use mode %lu\n", mode)); return AJ_ERR_UNEXPECTED; } AJ_BufList* ip6config; ip6config = AJ_BufListCreate(); //First zeros are for v4 WSL_MarshalPacket(ip6config, WSL_SOCKET, WSL_SOCK_IP6CONFIG, 0x60, 0, 0, 0, 0, globalAddr, localAddr, gateway, exAddr, linkPrefix, globalPrefix, gwPrefix, glbPrefixExt); WMI_MarshalHeader(ip6config, 1, 1); AJ_WSL_WMI_PadPayload(ip6config); //AJ_BufListPrintDumpContinuous(ip6config); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ip6config); { wsl_work_item* item = NULL; status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IP6CONFIG)) { AJ_InfoPrintf(("AJ_WSL_ip6config(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; uint32_t _ipv4 = 0; uint32_t _ipv4mask = 0; uint32_t _ipv4gateway = 0; WMI_Unmarshal(item->node->buffer, "quuuuuuuu6666uuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode, _ipv4, _ipv4mask, _ipv4gateway, localAddr, globalAddr, gateway, exAddr, &linkPrefix, &globalPrefix, &gwPrefix, &glbPrefixExt); //AJ_DumpBytes("IPV6", item->node->buffer, 0x60); } else { AJ_WarnPrintf(("AJ_WSL_ip6config(): BAD WORK ITEM RECEIVED\n")); } } AJ_WSL_WMI_FreeWorkItem(item); } return status; }
AJ_Status AJ_WSL_NET_scan(void) { AJ_Status status; AJ_BufList* start_scan; wsl_work_item* item; AJ_WSL_InitScanList(); AJ_WSL_NET_BSS_FILTER(1); AJ_WSL_NET_set_scan_params(); AJ_AlwaysPrintf((("AJ_WSL_NET_scan(): START_SCAN\n"))); start_scan = AJ_BufListCreate(); WSL_MarshalPacket(start_scan, WSL_START_SCAN, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(start_scan, 1, 1); AJ_WSL_WMI_PadPayload(start_scan); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), AJ_WSL_HTC_DATA_ENDPOINT1, start_scan); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), &item); AJ_WSL_WMI_FreeWorkItem(item); return status; }
AJ_Status AJ_WSL_NET_scan(void) { AJ_Status status; AJ_BufList* start_scan; wsl_work_item* item; AJ_WSL_NET_BSS_FILTER(1); AJ_WSL_NET_set_scan_params(); AJ_InfoPrintf((("AJ_WSL_NET_scan(): START_SCAN\n"))); start_scan = AJ_BufListCreate(); WSL_MarshalPacket(start_scan, WSL_START_SCAN, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(start_scan, 1, 1); AJ_WSL_WMI_PadPayload(start_scan); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), AJ_WSL_HTC_DATA_ENDPOINT1, start_scan); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), &item, AJ_NET_TIMEOUT); if (item && (status == AJ_OK)) { if (item->itemType == WSL_NET_SCAN) { AJ_InfoPrintf(("AJ_WSL_NET_scan(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint32_t error; WMI_Unmarshal(item->node->buffer, "quu", &WMIEvent, &toss, &error); if (error != 0) { AJ_ErrPrintf(("AJ_WSL_NET_scan(): Scan error, scan returned: %u", error)); status = AJ_ERR_INVALID; } } else { AJ_WarnPrintf(("AJ_WSL_NET_scan(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } return status; }
void AJ_WSL_MBoxListenAndProcessTask(void* parameters) { g_b_spi_interrupt_data_ready = FALSE; AJ_WSL_SPI_InitializeSPIController(); set_SPI_registers(); write_BOOT_PARAM(); g_b_spi_interrupt_data_ready = FALSE; // loop and process all of the responses while (1) { AJ_Status status; AJ_WSL_HTC_ProcessInterruptCause(); uint8_t i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { do { wsl_work_item* item = NULL; // peek at the queue, then make sure we have enough credits // if we have enough, pull and send the workitem to the MBOX // otherwise, move to the next socket and then eventually out of this loop. // Credits would be available again once AJ_WSL_HTC_ProcessInterruptCause has // read any credit-adjustment trailers status = AJ_QueuePeek(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &item); if ((status != AJ_OK) || (AJ_WSL_HTC_Global.endpoints[item->endpoint].txCredits < 1)) { break; } // pull a work item off of a socket queue and send it AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue, &item, 0); if (!item) { break; } else { //AJ_AlwaysPrintf(("AJ_WSL_MBoxListenAndProcessTask: %x\n", item->itemType)); AJ_WSL_WriteBufListToMBox(0, item->endpoint, AJ_BufListLengthOnWire(item->list), item->list); /* * if this item is sending data, create a workitem indicating completion * this special check is needed because there is no socket send command in WMI, * otherwise we could handle it in AJ_WSL_WMI_ProcessWMIEvent */ if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_NET_DATA_TX)) { wsl_work_item** ppWork; wsl_work_item* sockWork; sockWork = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockWork, 0, sizeof(wsl_work_item)); sockWork->itemType = item->itemType; sockWork->endpoint = item->endpoint; ppWork = &sockWork; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue, ppWork, AJ_TIMER_FOREVER); } AJ_WSL_WMI_FreeWorkItem(item); } } while (1); } if (!g_b_spi_interrupt_data_ready) { AJ_YieldCurrentTask(); } g_b_spi_interrupt_data_ready = FALSE; // reset the state of the interrupt signal } }
/* * create the WMI request to bind a socket on the target device to an address and port */ int16_t AJ_WSL_NET_socket_recv(AJ_WSL_SOCKNUM sock, uint8_t* buffer, uint32_t sizeBuffer, uint32_t timeout) { // AJ_InfoPrintf(("AJ_WSL_NET_socket_recv()\n")); int16_t ret = -1; uint32_t rx = sizeBuffer; uint32_t stash = 0; // read from stash first. uint16_t stashLength; if (sock >= AJ_WSL_SOCKET_MAX) { // tried to get data from an invalid socket, return an error return ret; } if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { // tried to get data from an invalid socket, return the data read from the stash AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); //flush the queue AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue); return ret; } if (AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList) { stashLength = AJ_BufListLengthOnWire(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList); if (stashLength != 0) { stash = min(rx, stashLength); AJ_BufListCopyBytes(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, stash, buffer); AJ_BufListPullBytes(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, stash); // shift left-overs toward the start. ret = stash; sizeBuffer -= stash; } } // wait until there is data if (sizeBuffer) { wsl_work_item* item = NULL; AJ_Status status; // the stash was depleted and you want more data if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { // tried to get data from an invalid socket, return the data read from the stash return ret; } status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item, timeout); if (item) { if (item->itemType == WSL_NET_INTERUPT) { // At this point we dont care about the interrupted signal but we are expecting a RX packet // so we need to pull the next item off the queue AJ_WSL_WMI_FreeWorkItem(item); status = AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item, timeout); } if ((status == AJ_OK) && (item->itemType == WSL_NET_DISCONNECT)) { AJ_InfoPrintf(("Disconnect received\n")); // Clean up the network queues int i; for (i = 0; i < AJ_WSL_SOCKET_MAX; i++) { AJ_WSL_SOCKET_CONTEXT[i].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[i].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[i].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[i].workTxQueue); } ret = -1; } else if ((status == AJ_OK) && (item->itemType == WSL_NET_CLOSE || item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE))) { // Pull the close work item off the queue AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &item, 0); // Socket was closed so tear down the connections AJ_WSL_SOCKET_CONTEXT[sock].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workTxQueue); ret = -1; } else if ((status == AJ_OK) && (item->itemType == WSL_NET_DATA_RX)) { //AJ_InfoPrintf(("=====DATA RX ITEM RECEIVED=====\n")); //AJ_DumpBytes("DATA RX ITEM", item->node->buffer, item->size); rx = min(sizeBuffer, item->size); memcpy(buffer + stash, item->node->buffer, rx); AJ_BufNodePullBytes(item->node, rx); // check node: if not empty assign to stash. if (item->node->length) { AJ_BufListPushTail(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, item->node); item->node = NULL; } ret = rx + stash; } else { AJ_InfoPrintf(("AJ_WSL_NET_socket_recv(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } else { ret = 0; AJ_InfoPrintf(("socket_recv timed out\n")); } } return ret; }
/* * Poll over a socket until there is data ready or till a timeout * * Returns -2 on timeout * -1 on interrupted * 1 on success * 0 on close * */ int16_t AJ_WSL_NET_socket_select(AJ_WSL_SOCKNUM sock, uint32_t timeout) { AJ_Time timer; wsl_work_item* peek; AJ_Status status; int16_t ret = 0; // Check if the socket is valid if (sock >= AJ_WSL_SOCKET_MAX) { // tried to get data from an invalid socket, return an error return ret; } if (AJ_WSL_SOCKET_CONTEXT[sock].valid == FALSE) { // tried to get data from an invalid socket, return the data read from the stash AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); //flush the queue return ret; } AJ_InitTimer(&timer); // There are 5 conditions that we need to check for // 1. If we got an interrupted work item // 2. If there is data in the RX stash // 3. If there is a RX work item in the queue // 4. If there is a socket close work item in the queue // 5. If the timeout has expired while (1) { status = AJ_QueuePeek(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &peek); //AJ_AlwaysPrintf(("Item type = %u\n", peek->itemType)); if ((status == AJ_OK) && (peek->itemType == WSL_NET_INTERUPT)) { // Pull the interrupted item off because we dont need it anymore AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &peek, 0); AJ_WSL_WMI_FreeWorkItem(peek); ret = -1; break; } else if (AJ_BufListLengthOnWire(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList) > 0) { ret = 1; break; } else if ((status == AJ_OK) && (peek->itemType == WSL_NET_DATA_RX)) { ret = 1; break; } else if ((status == AJ_OK) && (peek->itemType == WSL_NET_CLOSE || peek->itemType == WSL_NET_DISCONNECT || peek->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE))) { // Pull the close work item off the queue AJ_QueuePull(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue, &peek, 0); // Socket was closed so tear down the connections AJ_WSL_SOCKET_CONTEXT[sock].valid = FALSE; // Removed any stashed data AJ_BufListFree(AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList, 1); // Reallocate a new stash AJ_WSL_SOCKET_CONTEXT[sock].stashedRxList = AJ_BufListCreate(); // Reset the queue, any work items are now invalid since the socket was closed AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workRxQueue); AJ_QueueReset(AJ_WSL_SOCKET_CONTEXT[sock].workTxQueue); AJ_WSL_WMI_FreeWorkItem(peek); ret = 0; break; } else if (AJ_GetElapsedTime(&timer, TRUE) >= timeout) { ret = -2; break; } } return ret; }
AJ_EXPORT AJ_Status AJ_WSL_NET_connect(const char* SSID, const char* passphrase, WSL_NET_AUTH_MODE auth, WSL_NET_CRYPTO_TYPE crypto, uint8_t softAP) { AJ_Status status; wsl_scan_list* list; list = (wsl_scan_list*)AJ_WSL_GetScanList(); WSL_ClearScanList(list); AJ_WSL_NET_SetPowerMode(2); uint8_t bss_mac[6]; // Open auth does not require you to explicitly set the BSSID so this secondary scan is not needed if (!softAP) { if (auth != WSL_NET_AUTH_NONE) { // Do a scan of just the SSID you want AJ_WSL_SetProbedSSID(SSID, 1); { AJ_BufList* start_scan; uint8_t found = 0; int i; AJ_WSL_NET_set_scan_params(); while (!found) { wsl_work_item* item; AJ_InfoPrintf(("AJ_WSL_NET_scan(): START_SCAN\n")); start_scan = AJ_BufListCreate(); AJ_WSL_SetProbedSSID(SSID, 1); AJ_WSL_NET_set_scan_params(); AJ_WSL_NET_BSS_FILTER(6); WSL_MarshalPacket(start_scan, WSL_START_SCAN, 0, 0, 0, 0, 0, 0, 0, 0); WMI_MarshalHeader(start_scan, 1, 1); AJ_WSL_WMI_PadPayload(start_scan); //AJ_BufListPrintDumpContinuous(start_scan); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), AJ_WSL_HTC_DATA_ENDPOINT1, start_scan); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_SCAN), &item); AJ_WSL_WMI_FreeWorkItem(item); // Get the new list (just of the SSID provided in the connect command) AJ_WSL_NET_scan_stop(); list = (wsl_scan_list*)AJ_WSL_GetScanList(); if (list->size == 0) { AJ_AlwaysPrintf(("Could not find access point %s\n", SSID)); WSL_ClearScanList(list); AJ_Sleep(AJ_WSL_CONNECT_WAIT); continue; } WSL_PrintScanSorted(); // Find the SSID you want to connect to in the second scan list for (i = 0; i < list->size; i++) { if (0 == strcmp(list->list[i].ssid, SSID)) { memcpy(&bss_mac, list->list[i].bssid, 6); found = 1; break; } } WSL_ClearScanList(list); } } } } { AJ_BufList* connect; AJ_BufList* connectOut; static const uint8_t zero_mac[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t connect_mac[6]; wsl_work_item* item = NULL; uint8_t found = 0; connect = AJ_BufListCreate(); /* Three different ways connect can be called. * 1. SoftAP: The devices mac is fetched and used * 2. Using Auth: The SSID's mac is found and used * 3. Open auth: A zero'ed mac is used */ if (softAP) { WSL_MarshalPacket(connect, WSL_SET_SOFT_AP, 0, 0x04, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, getDeviceMac(), 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else if ((auth != WSL_NET_AUTH_NONE) && (crypto != WSL_NET_CRYPTO_WEP)) { WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &bss_mac, 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else { // if the auth mode is open, use zero_mac, and set flags to zero WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &zero_mac, 0x0000, 0x0000); WMI_MarshalHeader(connect, 1, 1); } AJ_InfoPrintf(("AJ_WSL_NET_connect(): CONNECT\n")); AJ_WSL_WMI_PadPayload(connect); //AJ_BufListPrintDumpContinuous(connect); connectOut = AJ_BufListCreateCopy(connect); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectOut); if (softAP) { AJ_AlwaysPrintf(("Waiting for a connection to the softAP %s\n", SSID)); memcpy(&connect_mac, (uint8_t*)getDeviceMac(), sizeof(connect_mac)); while (WSL_MacsAreEqual((uint8_t*)&connect_mac, (uint8_t*)getDeviceMac()) == TRUE) { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item); if (item) { if (item->itemType == WSL_NET_CONNECT) { AJ_InfoPrintf(("AJ_WSL_ip6config(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint16_t channel; WMI_Unmarshal(item->node->buffer, "quqM", &WMIEvent, &toss, &channel, &connect_mac); } else { AJ_WarnPrintf(("AJ_WSL_NET_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); found = 1; } } } else { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item); AJ_WSL_WMI_FreeWorkItem(item); } AJ_BufListFree(connect, 1); return status; } }
AJ_EXPORT AJ_Status AJ_WSL_NET_connect(const char* SSID, const char* passphrase, WSL_NET_AUTH_MODE auth, WSL_NET_CRYPTO_TYPE crypto, uint8_t softAP) { AJ_Status status = AJ_OK; wsl_scan_list* list; list = (wsl_scan_list*)AJ_WSL_GetScanList(); AJ_WSL_NET_SetPowerMode(2); uint8_t bss_mac[6]; // Open auth does not require you to explicitly set the BSSID so this secondary scan is not needed if (!softAP) { if (auth != WSL_NET_AUTH_NONE) { AJ_Time timer; uint8_t found = 0; AJ_InitTimer(&timer); while (!found) { AJ_WSL_InitScanList(AJ_WSL_SCAN_LIST_SIZE); AJ_WSL_SetProbedSSID(SSID, 1); status = AJ_WSL_NET_scan(); // Some kind of scan error if (status != AJ_OK) { WSL_ClearScanList(); continue; } AJ_WSL_NET_scan_stop(); if (AJ_GetElapsedTime(&timer, TRUE) > AJ_WSL_CONNECT_TIMEOUT) { AJ_ErrPrintf(("AJ_WSL_NET_connect() Could not find the access point %s\n", SSID)); WSL_ClearScanList(); return AJ_ERR_FAILURE; } // Find the SSID you want to connect to in the second scan list if (getMacFromSSID(SSID, bss_mac, list)) { WSL_ClearScanList(); found = 1; break; } else { WSL_ClearScanList(); AJ_Sleep(AJ_WSL_CONNECT_WAIT); continue; } } if (crypto != WSL_NET_CRYPTO_WEP) { status = AJ_WSL_NET_SetPassphrase(SSID, passphrase, strlen(passphrase)); if (status != AJ_OK) { return status; } } } } { AJ_BufList* connect; AJ_BufList* connectOut; static const uint8_t zero_mac[6] = { 0, 0, 0, 0, 0, 0 }; uint8_t connect_mac[6]; wsl_work_item* item = NULL; connect = AJ_BufListCreate(); /* Three different ways connect can be called. * 1. SoftAP: The devices mac is fetched and used * 2. Using Auth: The SSID's mac is found and used * 3. Open auth: A zero'ed mac is used */ if (softAP) { WSL_MarshalPacket(connect, WSL_SET_SOFT_AP, 0, 0x04, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, getDeviceMac(), 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else if ((auth != WSL_NET_AUTH_NONE) && (crypto != WSL_NET_CRYPTO_WEP)) { WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &bss_mac, 0x0044, 0x0000); WMI_MarshalHeader(connect, 1, 1); } else { // if the auth mode is open, use zero_mac, and set flags to zero WSL_MarshalPacket(connect, WSL_CONNECT, 0, 0x01, 0x01, auth, crypto, 0x00, crypto, 0x00, strlen(SSID), SSID, 0x0, &zero_mac, 0x0000, 0x0000); WMI_MarshalHeader(connect, 1, 1); } AJ_InfoPrintf(("AJ_WSL_NET_connect(): CONNECT\n")); AJ_WSL_WMI_PadPayload(connect); //AJ_BufListPrintDumpContinuous(connect); connectOut = AJ_BufListCreateCopy(connect); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), AJ_WSL_HTC_DATA_ENDPOINT1, connectOut); if (softAP) { AJ_AlwaysPrintf(("Waiting for a connection to the softAP %s\n", SSID)); memcpy(&connect_mac, (uint8_t*)getDeviceMac(), sizeof(connect_mac)); while (memcmp((uint8_t*)&connect_mac, (uint8_t*)getDeviceMac(), 6) == 0) { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item, AJ_TIMER_FOREVER); if (item && (status == AJ_OK)) { if (item->itemType == WSL_NET_CONNECT) { AJ_InfoPrintf(("AJ_WSL_NET_connect(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t toss; uint16_t channel; WMI_Unmarshal(item->node->buffer, "quqM", &WMIEvent, &toss, &channel, &connect_mac); } else { AJ_WarnPrintf(("AJ_WSL_NET_connect(): BAD WORK ITEM RECEIVED\n")); } AJ_WSL_WMI_FreeWorkItem(item); } } } else { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_NETWORK, WSL_NET_CONNECT), &item, AJ_TIMER_FOREVER); if (item && (status == AJ_OK)) { AJ_WSL_WMI_FreeWorkItem(item); } } AJ_BufListFree(connect, 1); return status; } }
AJ_Status AJ_WSL_ipconfig(uint32_t mode, uint32_t* ip, uint32_t* mask, uint32_t* gateway) { AJ_Status status = AJ_ERR_DHCP; uint16_t ipv6[8] = { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }; wsl_work_item* item = NULL; switch (mode) { case (IPCONFIG_QUERY): { AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_QUERY\n")); AJ_BufList* ipconfig; ipconfig = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 0, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig); { status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item); if (item) { if (item->itemType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG)) { AJ_InfoPrintf(("AJ_WSL_ipconfig(): WORK ITEM RECEIVED\n")); uint16_t WMIEvent; uint32_t reserved; uint32_t _command; uint32_t _handle; uint32_t _error; uint32_t _mode; WMI_Unmarshal(item->node->buffer, "quuuuuuuu", &WMIEvent, &reserved, &_command, &_handle, &_error, &_mode, ip, mask, gateway); if (ip != 0) { status = AJ_OK; } } else { AJ_WarnPrintf(("AJ_WSL_ipconfig(): BAD WORK ITEM RECEIVED\n")); } } } } AJ_WSL_WMI_FreeWorkItem(item); break; case (IPCONFIG_STATIC): AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_STATIC\n")); AJ_BufList* ipconfig_dhcp_static; ipconfig_dhcp_static = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig_dhcp_static, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 1, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig_dhcp_static, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig_dhcp_static); //AJ_BufListPrintDumpContinuous(ipconfig_dhcp_static); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig_dhcp_static); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item); AJ_WSL_WMI_FreeWorkItem(item); AJ_Sleep(1000); break; case (IPCONFIG_DHCP): AJ_InfoPrintf(("AJ_WSL_ipconfig(): IPCONFIG_DHCP\n")); AJ_BufList* ipconfig_dhcp; ipconfig_dhcp = AJ_BufListCreate(); WSL_MarshalPacket(ipconfig_dhcp, WSL_SOCKET, WSL_SOCK_IPCONFIG, 0x60, 2, ip, mask, gateway, &ipv6, &ipv6, &ipv6, &ipv6, 0, 0, 0, 0); WMI_MarshalHeader(ipconfig_dhcp, 1, 1); AJ_WSL_WMI_PadPayload(ipconfig_dhcp); AJ_WSL_WMI_QueueWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), AJ_WSL_HTC_DATA_ENDPOINT1, ipconfig_dhcp); status = AJ_WSL_WMI_WaitForWorkItem(0, AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_IPCONFIG), &item); AJ_WSL_WMI_FreeWorkItem(item); AJ_Sleep(100); break; } return status; }