void AJ_WSL_WMI_ProcessSocketDataResponse(AJ_BufNode* pNodeHTCBody) { int8_t socketIndex; uint32_t u32; uint16_t lead, payloadSize, _port; uint32_t _handle, srcAddr; uint16_t ipv6addr[8]; uint16_t bufferOffset = 0; wsl_work_item** ppWork; wsl_work_item* sockResp; // AJ_DumpBytes("WMI_SOCKET_RESPONSE B", pNodeHTCBody->buffer, pNodeHTCBody->length); // Get the initial bytes of data in the packet WMI_Unmarshal(pNodeHTCBody->buffer, "quuq", &lead, &u32, &_handle, &_port); //AJ_BufNodePullBytes(pNodeHTCBody, 12); bufferOffset += 12; // look for the matching handle in the global context then mark it invalid socketIndex = AJ_WSL_FindSocketContext(_handle); if (socketIndex == INVALID_SOCKET) { AJ_WarnPrintf(("data returned for invalid socket. Handle = %lu\n", _handle)); return; } if (AJ_WSL_SOCKET_CONTEXT[socketIndex].domain == WSL_AF_INET6) { bufferOffset += 6; // Get the IPv6 address and payload size WMI_Unmarshal(pNodeHTCBody->buffer + bufferOffset, "6uq", &ipv6addr, &u32, &payloadSize); // Advance the buffer to the start of the payload bufferOffset += 28; } else { bufferOffset += 2; // Get the IPv4 address WMI_Unmarshal(pNodeHTCBody->buffer + bufferOffset, "4q", &srcAddr, &payloadSize); // Advance the buffer to the start of the payload bufferOffset += 12; } sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = WSL_NET_DATA_RX; sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); AJ_BufNodePullBytes(sockResp->node, bufferOffset); /// the length of the socket header info header sockResp->node->length = payloadSize; ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); }
/* * 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; }
/* * 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; }
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_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_WMI_ProcessWMIEvent(AJ_BufNode* pNodeHTCBody) { uint16_t eventID; uint16_t info1; uint16_t reserved; int32_t dataUnmarshaled; dataUnmarshaled = WMI_Unmarshal(pNodeHTCBody->buffer, "qqq", &eventID, &info1, &reserved); switch (eventID) { case WSL_WMI_READY_EVENTID: { uint8_t capability; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuMy", &AJ_WSL_TargetFirmware.target_ver, &AJ_WSL_TargetFirmware.abi_ver, &deviceMAC, &capability); AJ_InfoPrintf(("WMI_READY, version A %08lx, version B %08lx capability %x\n", AJ_WSL_TargetFirmware.target_ver, AJ_WSL_TargetFirmware.abi_ver, capability)); AJ_InfoPrintf(("Device MAC: %02x:%02x:%02x:%02x:%02x:%02x\n", deviceMAC[0], deviceMAC[1], deviceMAC[2], deviceMAC[3], deviceMAC[4], deviceMAC[5])); AJ_WSL_HTC_Global.started = TRUE; break; } case WSL_BSS_INFO_EVENTID: { extern void AJ_WSL_BSSINFO_Recv(AJ_BufNode* node); AJ_WSL_BSSINFO_Recv(pNodeHTCBody); break; } case WSL_CMDERROR_EVENTID: { uint16_t commandId; uint8_t error; dataUnmarshaled += WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qy", &commandId, &error); AJ_InfoPrintf(("WMI_CMDERROR, last command %04x, error code %02x \n", commandId, error)); break; } case WSL_WMI_SCAN_COMPLETE_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* scanCompleteResponse; wsl_work_item** pItem; scanCompleteResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(scanCompleteResponse, 0, sizeof(wsl_work_item)); scanCompleteResponse->itemType = WSL_NET_SCAN; scanCompleteResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &scanCompleteResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_DISCONNECT_EVENTID: { uint16_t protocolReason; uint8_t bssid[6]; uint16_t disconnectReason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "qMq", &protocolReason, &bssid, &disconnectReason); AJ_InfoPrintf(("WMI_DISCONNECT event: protocolReason %x, disconnectReason %x\n", protocolReason, disconnectReason)); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(0); } // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* disconnectResponse; wsl_work_item** pItem; disconnectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(disconnectResponse, 0, sizeof(wsl_work_item)); disconnectResponse->itemType = WSL_NET_DISCONNECT; disconnectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &disconnectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); break; } case WSL_WMI_CONNECT_EVENTID: { // now signal the waiting code that the scan has completed // we can do this by posting an item to the global socket context recv queue // the client will pull off a scan complete event and then continue. wsl_work_item* connectResponse; wsl_work_item** pItem; connectResponse = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(connectResponse, 0, sizeof(wsl_work_item)); connectResponse->itemType = WSL_NET_CONNECT; connectResponse->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); pItem = &connectResponse; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[0].workRxQueue, pItem, AJ_TIMER_FOREVER); if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(1); } break; } case WSL_WMI_SOCKET_RESPONSE_EVENTID: { uint32_t responseType; uint32_t socketHandle; uint32_t error; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "uuu", &responseType, &socketHandle, &error); int8_t socketIndex; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); /* look for the matching handle in the global context then mark it invalid */ switch (responseType) { // some of the commands operate on the global socket context case WSL_SOCK_OPEN: case WSL_SOCK_IPCONFIG: case WSL_SOCK_IP6CONFIG: case WSL_SOCK_STACK_INIT: case WSL_SOCK_IP_HOST_NAME: socketIndex = 0; break; default: { socketIndex = AJ_WSL_FindSocketContext(socketHandle); if (socketIndex == INVALID_SOCKET) { AJ_DumpBytes("INVALID SOCKET DUMP", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WarnPrintf(("SOCKET_PING response for invalid socket!\n")); break; } } } if (socketIndex != INVALID_SOCKET) { AJ_Status status = AJ_OK; //push a work item into the Read queue if (status == AJ_OK) { wsl_work_item** ppWork; wsl_work_item* sockResp; sockResp = (wsl_work_item*)AJ_WSL_Malloc(sizeof(wsl_work_item)); memset(sockResp, 0, sizeof(wsl_work_item)); sockResp->itemType = AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, responseType); //sockResp->size = payloadSize; sockResp->node = AJ_BufNodeCreateAndTakeOwnership(pNodeHTCBody); ppWork = &sockResp; AJ_QueuePush(AJ_WSL_SOCKET_CONTEXT[socketIndex].workRxQueue, ppWork, AJ_TIMER_FOREVER); } if ((responseType == AJ_WSL_WORKITEM(AJ_WSL_WORKITEM_SOCKET, WSL_SOCK_CLOSE)) && (socketIndex != INVALID_SOCKET)) { AJ_WSL_SOCKET_CONTEXT[socketIndex].targetHandle = UINT32_MAX; AJ_WSL_SOCKET_CONTEXT[socketIndex].valid = FALSE; } } break; } case WSL_WMI_PEER_NODE_EVENTID: { uint8_t reason; WMI_Unmarshal(pNodeHTCBody->buffer + dataUnmarshaled, "q", &reason); if ((reason == 0) /*&& (AJ_WSL_connectState == AJ_WIFI_CONNECTING)*/) { /* * The 4-way handshake is complete, indicate the state has changed */ if (AJ_WSL_WifiConnectCallback) { (AJ_WSL_WifiConnectCallback)(16 /*RSNA_AUTH_SUCCESS*/); } } break; } // There are several WMI events that aren't parsed. case WSL_REGDOMAIN_EVENTID: case WSL_UNKNOWN2_EVENTID: case WSL_UNKNOWN1_EVENTID: break; default: { AJ_InfoPrintf(("Unknown WMI Event %x\n", eventID)); return; } } AJ_InfoPrintf(("Processed WMI Event: %s\n", WSL_WorkItemText(eventID))); }
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; }
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; } }
/* * read from the mailbox and do something useful with the HTC message. */ void AJ_WSL_HTC_ProcessIncoming(void) { uint16_t lenRead; uint8_t* bufRead; AJ_BufNode* pNodeHTCBody; uint8_t endpointID; uint8_t flags; uint16_t payloadLength; uint8_t controlBytes[2]; AJ_Status status; status = AJ_WSL_ReadFromMBox(AJ_WSL_SPI_MBOX_0, &lenRead, &bufRead); AJ_ASSERT(status == AJ_OK); // now create a AJ_BufList from the data we read pNodeHTCBody = AJ_BufListCreateNodeExternalZero(bufRead, lenRead, FALSE); pNodeHTCBody->flags = 0; // reset the AJ_BUFNODE_EXTERNAL_BUFFER flag, because I own this now. WMI_Unmarshal(pNodeHTCBody->buffer, "yyqyy", &endpointID, &flags, &payloadLength, &controlBytes[0], &controlBytes[1]); AJ_BufNodePullBytes(pNodeHTCBody, 6); //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); AJ_DumpBytes("HTC_CONTROL", pNodeHTCBody->buffer, pNodeHTCBody->length); /* examine the endpoint of the HTC message*/ if ((flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) && ((payloadLength - controlBytes[0]) > 0)) { switch (endpointID) { case AJ_WSL_HTC_CONTROL_ENDPOINT: { uint16_t* messageID = (uint16_t*)pNodeHTCBody->buffer; AJ_InfoPrintf(("Read HTC control endpoint, messageID %x\n", *messageID)); switch (*messageID) { case AJ_WSL_HTC_MSG_READY_ID: { /* process the message and change state */ uint16_t readyMessageID; WMI_Unmarshal(pNodeHTCBody->buffer, "qqqyyy", &readyMessageID, &AJ_WSL_HTC_Global.creditCount, &AJ_WSL_HTC_Global.creditSize, &AJ_WSL_HTC_Global.maxEndpoints, &AJ_WSL_HTC_Global.HTCVersion, &AJ_WSL_HTC_Global.maxMessagesPerBundle); /* SIDE EFFECT */ AJ_WarnPrintf(("MSG_READY, credit count %x, credit size:%d\n", AJ_WSL_HTC_Global.creditCount, AJ_WSL_HTC_Global.creditSize)); AJ_WSL_HTC_Global.endpoints[AJ_WSL_HTC_CONTROL_ENDPOINT].state = AJ_WSL_HTC_UNINITIALIZED_RECV_READY; break; } case AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID: { AJ_WarnPrintf(("HTC MSG AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID\n")); break; } default: AJ_WarnPrintf(("HTC MSG ID unknown\n")); AJ_DumpBytes("WMI_SOCKET_RESPONSE", pNodeHTCBody->buffer, pNodeHTCBody->length); break; } break; } case AJ_WSL_HTC_DATA_ENDPOINT1: { // AJ_DumpBytes("DATA ENDPOINT WMI ", pNodeHTCBody->buffer, pNodeHTCBody->length); AJ_WSL_WMI_ProcessWMIEvent(pNodeHTCBody); break; } case AJ_WSL_HTC_DATA_ENDPOINT2: case AJ_WSL_HTC_DATA_ENDPOINT3: case AJ_WSL_HTC_DATA_ENDPOINT4: { AJ_DumpBytes("DATA ENDPOINT WMI_SOCKET_RESPONSE", pNodeHTCBody->bufferStart, pNodeHTCBody->length); AJ_WSL_WMI_ProcessSocketDataResponse(pNodeHTCBody); //AJ_InfoPrintf(("Read HTC data endpoint %d\n", htcHdr.endpointID)); // TODO send the data up to the next API level //AJ_WSL_WMI_PrintMessage(pNodeHTCBody); break; } default: AJ_ErrPrintf(("UNKNOWN Endpoint %d", endpointID)); AJ_ASSERT(FALSE); break; } } /* * Trailers can come on any packet */ if (flags & AJ_WSL_HTC_RECV_TRAILER_PRESENT) { uint16_t packetLength; uint8_t trailerLength = controlBytes[0]; packetLength = payloadLength - trailerLength; //AJ_InfoPrintf(("Read HTC RX trailer, length %d\n", htcHdr.controlBytes[0])); AJ_BufNodePullBytes(pNodeHTCBody, packetLength); // consume the packet, leave the trailer /* * handle multiple trailers per HTC message */ while (trailerLength) { uint8_t trailerType; uint8_t length; //AJ_BufListNodePrintDump(pNodeHTCBody, NULL); WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &trailerType, &length); AJ_BufNodePullBytes(pNodeHTCBody, 2); // consume the trailer trailerLength -= 2; switch (trailerType) { case AJ_WSL_HTC_RXTRAILER_CREDIT_REPORT: { uint8_t credits; uint8_t endpoint; WMI_Unmarshal(pNodeHTCBody->buffer, "yy", &endpoint, &credits); AJ_InfoPrintf(("Add %d credits to endpoint %d\n", credits, endpoint)); AJ_WSL_HTC_Global.endpoints[endpoint].txCredits += credits; break; } default: { AJ_InfoPrintf(("HTC trailer: type not handled %d\n", trailerType)); } } trailerLength -= length; AJ_BufNodePullBytes(pNodeHTCBody, length); // consume the trailer } } //intentionally freeing the buffer here AJ_BufListFreeNodeAndBuffer(pNodeHTCBody, NULL); }
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; } }