예제 #1
0
/*
 * 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;
}
예제 #2
0
static void run_buflist_external(const struct test_case* test)
{

    uint8_t externA[10];
    uint8_t externB[10];
    /*
     * verify the buffer list management
     */
    AJ_BufList* list1 = AJ_BufListCreate();
    AJ_BufNode* pNode1 = AJ_BufListCreateNodeExternalBuffer((uint8_t*)&externA, sizeof(externA));
    AJ_BufNode* pNode2 = AJ_BufListCreateNodeExternalBuffer((uint8_t*)&externB, sizeof(externB));

    AJ_AlwaysPrintf(("\n\n**************\nTEST:  %s\n\n", __FUNCTION__));

    memset(pNode1->buffer, 0x1, pNode1->length);
    memset(pNode2->buffer, 0x2, pNode2->length);

    AJ_BufListPushHead(list1, pNode1);
    AJ_BufListPushTail(list1, pNode2);

    AJ_BufNodeIterate(AJ_BufListNodePrint, list1, NULL);
    AJ_BufNodeIterate(AJ_BufListNodePrintDump, list1, NULL);

    AJ_BufListFree(list1, 1);


}
예제 #3
0
void AJ_WSL_WMI_FreeWorkItem(wsl_work_item* item)
{
    if (item) {
        AJ_BufListFree(item->list, TRUE);
        AJ_BufListFreeNodeAndBuffer(item->node, NULL);
        AJ_WSL_Free(item);
    }
}
예제 #4
0
파일: aj_wsl_net.c 프로젝트: fonlabs/ajtcl
/*
 *  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;
}
예제 #5
0
파일: aj_wsl_net.c 프로젝트: fonlabs/ajtcl
/*
 * 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;
}
예제 #6
0
파일: aj_wsl_net.c 프로젝트: fonlabs/ajtcl
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;
    }
}
예제 #7
0
static void run_buflist_coalesce(const struct test_case* test)
{

    /*
     * verify the buffer list management
     */
    AJ_BufList* list1 = AJ_BufListCreate();
    AJ_BufNode* pNode1 = AJ_BufListCreateNode(100);
    AJ_BufNode* pNode2 = AJ_BufListCreateNode(200);

    AJ_AlwaysPrintf(("\n\n**************\nTEST:  %s\n\n", __FUNCTION__));

    memset(pNode1->buffer, 0x1, pNode1->length);
    memset(pNode2->buffer, 0x2, pNode2->length);

    AJ_BufListPushHead(list1, pNode1);
    AJ_BufListPushTail(list1, pNode2);

    AJ_BufNodeIterate(AJ_BufListNodePrint, list1, NULL);
    AJ_BufNodeIterate(AJ_BufListNodePrintDump, list1, NULL);

    AJ_BufListFree(list1, 1);



    // Test squeezing together a few buffer nodes in a list.
    AJ_AlwaysPrintf(("%s", "\n\nTEST: Coalesce Start\n"));
    {
        AJ_BufList* list3 = AJ_BufListCreate();

        AJ_BufNode* pNodeA = AJ_BufListCreateNode(8);
        AJ_BufNode* pNodeB = AJ_BufListCreateNode(8);
        AJ_BufNode* pNodeC = AJ_BufListCreateNode(8);
        AJ_BufNode* pNodeD = AJ_BufListCreateNode(8);
        memset(pNodeA->buffer, 0xA1, 8);
        memset(pNodeB->buffer, 0xB2, 8);
        memset(pNodeC->buffer, 0xC3, 8);
        memset(pNodeD->buffer, 0xD4, 8);

        AJ_BufListPushHead(list3, pNodeA);
        AJ_BufListPushTail(list3, pNodeB);
        AJ_BufListPushTail(list3, pNodeC);
        AJ_BufListPushTail(list3, pNodeD);

        AJ_BufNodeIterate(AJ_BufListNodePrintDump, list3, NULL);

        AJ_AlwaysPrintf(("%s", "\n\nTEST: coalesce the head twice, then dump\n"));
        AJ_BufListCoalesce(list3->head);
        AJ_BufListCoalesce(list3->head);
        AJ_BufNodeIterate(AJ_BufListNodePrintDump, list3, NULL);


        AJ_AlwaysPrintf(("%s", "\n\nTEST: Next pull 16 bytes then dump\n"));

        AJ_BufListPullBytes(list3, 4);
        AJ_BufListPullBytes(list3, 4);
        AJ_BufListPullBytes(list3, 8);
        AJ_BufNodeIterate(AJ_BufListNodePrintDump, list3, NULL);
        AJ_AlwaysPrintf(("%s", "\n\nTEST: PULL BYTES 16 end\n"));

        AJ_BufListFree(list3, 1);
    }
    AJ_AlwaysPrintf(("%s", "\nTEST: Coalesce End\n"));
}
예제 #8
0
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;
    }
}
예제 #9
0
파일: unit_test.c 프로젝트: fonlabs/ajtcl
static void run_wsl_htc_parsing(const struct test_case* test)
{

    /*
     * create a chain of buffers that simulate each protocol layer wrapping the layer above it.
     * The values chosen to populate the buffers are not legal protocol values, they just show
     * where the bytes are laid out in memory.
     */
    AJ_BufList* list2 = AJ_BufListCreate();

    AJ_BufNode* pNodeAppData = AJ_BufListCreateNodeZero(16, 1);
    AJ_BufNode_WMI* pNodeWMI;
    AJ_BufNode* pNodeWMITrail;
    AJ_BufNode* pNodeHTC;
    wsl_htc_msg_connect_service* msgConnectService;
    AJ_BufNode* pNodeHTCTrail;
    AJ_BufNode* pNodeHTCHeader;
    wsl_htc_hdr* msgHdr;

    AJ_AlwaysPrintf(("\n\n**************\nTEST:  %s\n\n", __FUNCTION__));


    strcpy((char*)pNodeAppData->buffer, "AppData string");

    pNodeWMI = AJ_BufListCreateNode(sizeof(wsl_spi_command));

    // stuff the buffer with a command.
    ((wsl_spi_command*)pNodeWMI->buffer)->cmd_addr = AJ_WSL_SPI_SPI_STATUS;
    ((wsl_spi_command*)pNodeWMI->buffer)->cmd_rx = 1;
    ((wsl_spi_command*)pNodeWMI->buffer)->cmd_reg = 1;
    *((uint16_t*)pNodeWMI->buffer) = CPU_TO_BE16(*(uint16_t*)pNodeWMI->buffer);   // Swap the bytes around

    // create a bogus trailer
    pNodeWMITrail = AJ_BufListCreateNode(8);
    memset(pNodeWMITrail->buffer, 0xA1, 8);


    // create an HTC command
    pNodeHTC = AJ_BufListCreateNode(sizeof(wsl_htc_msg_connect_service));
    msgConnectService = (wsl_htc_msg_connect_service*)pNodeHTC->buffer;
    msgConnectService->msg.messageID = AJ_WSL_HTC_CONNECT_SERVICE_ID;
    msgConnectService->serviceID = 0x5678; // random choice
    msgConnectService->flags = 0xCDEF; // random choice
    msgConnectService->serviceMetadataLength = 0; // random choice
    msgConnectService->metadata = 0; // random choice
    AJ_WSL_HTC_MSG_CONNECT_TO_WIRE(msgConnectService);
    // create another bogus trailer
    pNodeHTCTrail = AJ_BufListCreateNode(8);
    memset(pNodeHTCTrail->buffer, 0xB2, 8);



    // AppData was added then WMI was added, then HTC wrapped around that
    AJ_BufListPushHead(list2, pNodeAppData);
    AJ_BufListPushHead(list2, pNodeWMI);
    AJ_BufListPushTail(list2, pNodeWMITrail);

    AJ_BufListPushHead(list2, pNodeHTC);
    AJ_BufListPushTail(list2, pNodeHTCTrail);

    // create an HTC header structure with the correct size field (based on the size of the data to send on the wire)
    pNodeHTCHeader = AJ_BufListCreateNode(sizeof(wsl_htc_hdr));
    msgHdr = (wsl_htc_hdr*)pNodeHTCHeader->buffer;
    msgHdr->endpointID = AJ_WSL_HTC_CONTROL_ENDPOINT;
    msgHdr->flags = 0;
    msgHdr->controlBytes[0]  = 0xAB;
    msgHdr->controlBytes[1]  = 0xCD;
    msgHdr->payloadLength = AJ_BufListLengthOnWire(list2);
    AJ_WSL_HTC_HDR_TO_WIRE(msgHdr);

    AJ_AlwaysPrintf(("\n\nPayload size would be: %d\n\n", AJ_BufListLengthOnWire(list2)));
    AJ_BufListPushHead(list2, pNodeHTCHeader);


    AJ_AlwaysPrintf(("%s", "write this to the wire\n\n"));
    AJ_BufListIterateOnWire(AJ_BufListWriteToWire_Simulated, list2, &toTarget);
    AJ_AlwaysPrintf(("\n\nDone wire write, length on wire: %d\n\n", AJ_BufListLengthOnWire(list2)));

    AJ_BufListFree(list2, 1);

/*
    {
        // simulate a number of reads from the SPI buffer
        fakeWireRead = fakeWireBuffer;
        uint16_t readBufferSize = sizeof(fakeWireBuffer);

        AJ_AlwaysPrintf(("%s", "Wire Bufer\n"));
        while (readBufferSize > 0) {
            uint8_t byteRead  = AJ_BufListReadByteFromWire_Simulated();
            AJ_AlwaysPrintf(("%02X ", byteRead));
            readBufferSize--;
        }
    }
 */

    toTarget.fakeWireRead = toTarget.fakeWireBuffer;
//    fakeWireRead = fakeWireBuffer; // reset the read pointer to the start of our buffer
    {
        wsl_htc_hdr htcHdr1;
        AJ_BufNode* pNodeHTCBody;
        wsl_htc_msg* htcMsg1;

        AJ_AlwaysPrintf(("%s", "Read HTC header from wire buffer\n"));
        AJ_BufListReadBytesFromWire_Simulated(sizeof(htcHdr1), (uint8_t*)&htcHdr1, &toTarget);

        // convert the fields to the correct endianness
        AJ_WSL_HTC_HDR_FROM_WIRE(&htcHdr1);
        AJ_AlwaysPrintf(("\n HTC Hdr payload length 0x%04x\n\n", htcHdr1.payloadLength));

        AJ_AlwaysPrintf(("%s", "Read HTC from wire buffer\n"));
        pNodeHTCBody = AJ_BufListCreateNode(htcHdr1.payloadLength /*+ sizeof(wsl_htc_msg)*/);
        htcMsg1 = (wsl_htc_msg*)pNodeHTCBody->buffer;

        AJ_BufListReadBytesFromWire_Simulated(pNodeHTCBody->length, pNodeHTCBody->buffer, &toTarget);

        switch (htcHdr1.endpointID) {
        case AJ_WSL_HTC_CONTROL_ENDPOINT:
            AJ_AlwaysPrintf(("%s", "Read HTC control endpoint\n"));

//                break;
        case AJ_WSL_HTC_DATA_ENDPOINT1:
        case AJ_WSL_HTC_DATA_ENDPOINT2:
        case AJ_WSL_HTC_DATA_ENDPOINT3:
        case AJ_WSL_HTC_DATA_ENDPOINT4:
            AJ_AlwaysPrintf(("\n%s %d\n", "Read HTC data endpoint", htcHdr1.endpointID));
            // TODO send the data up to the next API level
            AJ_WSL_WMI_PrintMessage(pNodeHTCBody);
            break;

        default:
            AJ_AlwaysPrintf(("%s %d", "UNKNOWN Endpoint", htcHdr1.endpointID));
            break;

        }



//        AJ_BufListReadBytesFromWire_Simulated(pNodeHTCBody->length, pNodeHTCBody->buffer);
        AJ_WSL_HTC_MSG_FROM_WIRE(htcMsg1);
        switch (htcMsg1->messageID) {
        case AJ_WSL_HTC_MSG_READY_ID: {
                wsl_htc_msg_ready* htcMsgReady1 = (wsl_htc_msg_ready*)pNodeHTCBody->buffer;
                AJ_AlwaysPrintf(("%s", "Read HTC msg AJ_WSL_HTC_MSG_READY_ID \n"));
                AJ_WSL_HTC_MSG_READY_FROM_WIRE(htcMsgReady1);
                AJ_AlwaysPrintf(("\n HTC connect service message 0x%04x, CreditCount 0x%04X CreditSize 0x%04X\n\n", htcMsgReady1->msg.messageID, htcMsgReady1->creditCount, htcMsgReady1->creditSize));
                break;
            }

        case AJ_WSL_HTC_CONNECT_SERVICE_ID: {
                wsl_htc_msg_connect_service* htcMsgCS1 = (wsl_htc_msg_connect_service*) pNodeHTCBody->buffer;
                AJ_AlwaysPrintf(("%s", "Read HTC msg AJ_WSL_HTC_CONNECT_SERVICE_ID \n"));
                AJ_WSL_HTC_MSG_CONNECT_FROM_WIRE(htcMsgCS1);
                AJ_AlwaysPrintf(("\n HTC connect service message 0x%04x, serviceID 0x%04X \n\n", htcMsgCS1->msg.messageID, htcMsgCS1->serviceID));
                break;
            }

        case AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID: {
                wsl_htc_msg_service_connect_response* htcServiceConnectResponse1 = (wsl_htc_msg_service_connect_response*)pNodeHTCBody->buffer;
                AJ_AlwaysPrintf(("%s", "Read HTC msg AJ_WSL_HTC_SERVICE_CONNECT_RESPONSE_ID \n"));
                AJ_WSL_HTC_MSG_SERVICE_CONNECT_RESPONSE_FROM_WIRE(htcServiceConnectResponse1);
                AJ_AlwaysPrintf(("\n HTC service connect response 0x%04x, serviceID 0x%04X metadatalength 0x%04X\n\n", htcServiceConnectResponse1->msg.messageID, htcServiceConnectResponse1->serviceID, htcServiceConnectResponse1->serviceMetadataLength));
                break;
            }

        case AJ_WSL_HTC_SETUP_COMPLETE_ID: {
                AJ_AlwaysPrintf(("%s", "Read HTC msg AJ_WSL_HTC_SETUP_COMPLETE_ID \n"));
                break;
            }

        case AJ_WSL_HTC_HOST_READY_ID: {
                AJ_AlwaysPrintf(("%s", "Read HTC msg AJ_WSL_HTC_HOST_READY_ID \n"));
                break;
            }

        default: {
                AJ_ASSERT(htcMsg1->messageID <= AJ_WSL_HTC_HOST_READY_ID);
                break;
            }
        }
    }
}