AJ_Status OnboardingReadInfo(AJOBS_Info* info)
{
    AJ_Status status = AJ_OK;
    size_t size = sizeof(AJOBS_Info);
    AJ_NV_DATASET* nvramHandle;
    int sizeRead;

    if (NULL == info) {
        return AJ_ERR_NULL;
    }
    memset(info, 0, size);

    if (!AJ_NVRAM_Exist(AJ_OBS_OBINFO_NV_ID)) {
        return AJ_ERR_INVALID;
    }

    nvramHandle = AJ_NVRAM_Open(AJ_OBS_OBINFO_NV_ID, "r", 0);
    if (nvramHandle != NULL) {
        sizeRead = AJ_NVRAM_Read(info, size, nvramHandle);
        status = AJ_NVRAM_Close(nvramHandle);
        if (sizeRead != sizeRead) {
            status = AJ_ERR_READ;
        } else {
            AJ_AlwaysPrintf(("Read Info values: state=%d, ssid=%s authType=%d pc=%s\n", info->state, info->ssid, info->authType, info->pc));
        }
    }

    return status;
}
static AJ_Status PropertyStore_WriteConfig(uint16_t index, void* ptr, uint16_t size, char* mode)
{
    AJ_Status status = AJ_OK;
    uint16_t sizeWritten = 0;

    AJ_NV_DATASET* nvramHandle = AJ_NVRAM_Open(index, mode, size);
    if (nvramHandle != NULL) {
        sizeWritten = AJ_NVRAM_Write(ptr, size, nvramHandle);
        status = AJ_NVRAM_Close(nvramHandle);
        if (sizeWritten != size) {
            status = AJ_ERR_WRITE;
        }
    }

    return status;
}
static AJ_Status PropertyStore_ReadConfig(uint16_t index, void* ptr, uint16_t size)
{
    AJ_Status status = AJ_OK;
    uint16_t sizeRead = 0;

    AJ_NV_DATASET* nvramHandle = AJ_NVRAM_Open(index, "r", 0);
    if (nvramHandle != NULL) {
        sizeRead = AJ_NVRAM_Read(ptr, size, nvramHandle);
        status = AJ_NVRAM_Close(nvramHandle);
        if (sizeRead != sizeRead) {
            status = AJ_ERR_WRITE;
        }
    }

    return status;
}
AJ_Status OnboardingWriteInfo(AJOBS_Info* info)
{
    AJ_Status status = AJ_OK;
    size_t size = sizeof(AJOBS_Info);
    AJ_NV_DATASET* nvramHandle;
    int sizeWritten;

    if (NULL == info) {
        return AJ_ERR_NULL;
    }

    AJ_AlwaysPrintf(("Going to write Info values: state=%d, ssid=%s authType=%d pc=%s\n", info->state, info->ssid, info->authType, info->pc));

    nvramHandle = AJ_NVRAM_Open(AJ_OBS_OBINFO_NV_ID, "w", size);
    if (nvramHandle != NULL) {
        sizeWritten = AJ_NVRAM_Write(info, size, nvramHandle);
        status = AJ_NVRAM_Close(nvramHandle);
        if (sizeWritten != size) {
            status = AJ_ERR_WRITE;
        }
    }

    return status;
}
Example #5
0
AJ_Status TestNVRAM()
{
    uint16_t id = 16;
    AJ_NV_DATASET* handle = NULL;
    int i = 0;
    size_t bytes = 0;
    AJ_Status status = AJ_OK;
    AJ_NVRAM_Layout_Print();

    {
        handle = AJ_NVRAM_Open(id, "w", 40 + 5);
        AJ_NVRAM_Layout_Print();
        AJ_ASSERT(handle);

        for (i = 0; i < 10; i++) {
            bytes = AJ_NVRAM_Write(&i, sizeof(i), handle);
            if (bytes != sizeof(i)) {
                status = AJ_ERR_FAILURE;
                goto _TEST_NVRAM_EXIT;
            }
        }
        {
            uint8_t buf[3] = { 11, 22, 33 };
            uint8_t buf2[2] = { 44, 55 };
            bytes = AJ_NVRAM_Write(buf, sizeof(buf), handle);
            if (bytes != sizeof(buf)) {
                status = AJ_ERR_FAILURE;
                goto _TEST_NVRAM_EXIT;
            }
            bytes = AJ_NVRAM_Write(buf2, sizeof(buf2), handle);
            if (bytes != sizeof(buf2)) {
                status = AJ_ERR_FAILURE;
                goto _TEST_NVRAM_EXIT;
            }

        }
        AJ_NVRAM_Close(handle);
        AJ_InfoPrintf(("TestNVRAM() Layout Print\n"));
        AJ_NVRAM_Layout_Print();

        handle = AJ_NVRAM_Open(id, "r", 0);
        AJ_ASSERT(handle);
        for (i = 0; i < 10; i++) {
            int data = 0;
            bytes = AJ_NVRAM_Read(&data, sizeof(data), handle);
            if (bytes != sizeof(data) || data != i) {
                status = AJ_ERR_FAILURE;
                goto _TEST_NVRAM_EXIT;
            }
        }
        for (i = 1; i < 6; i++) {
            uint8_t data = 0;
            AJ_NVRAM_Read(&data, 1, handle);
            if (data != i * 11) {
                status = AJ_ERR_FAILURE;
                goto _TEST_NVRAM_EXIT;
            }
        }
        AJ_NVRAM_Close(handle);
    }

    if (AJ_NVRAM_Exist(id + 1)) {
        AJ_ASSERT(AJ_NVRAM_Delete(id + 1) == AJ_OK);
    }

    // Force storage compaction
    for (i = 0; i < 12; i++) {
        if (i == 6) {
            handle = AJ_NVRAM_Open(id + 2, "w", 100);
            AJ_ASSERT(handle);
            status = AJ_NVRAM_Close(handle);
            if (AJ_OK != status) {
                goto _TEST_NVRAM_EXIT;
            }
            continue;
        }
        handle = AJ_NVRAM_Open(id + 1, "w", 200);
        AJ_ASSERT(handle);
        status = AJ_NVRAM_Close(handle);
        if (AJ_OK != status) {
            goto _TEST_NVRAM_EXIT;
        }
    }
    AJ_InfoPrintf(("Compaction Layout Print\n"));
    AJ_NVRAM_Layout_Print();

_TEST_NVRAM_EXIT:
    //AJ_NVRAM_Close(handle);
    return status;
}
Example #6
0
AJ_Status TestNvramDelete()
{
    AJ_Status status = AJ_OK;
    AJ_NV_DATASET* nvramHandle;

    if (tid1 % 2 == 1) {
#ifndef OBS_ONLY
        if (AJ_NVRAM_Exist(tid1)) {
            AJ_ASSERT(AJ_NVRAM_Delete(tid1) == AJ_OK);
        }
        AJ_InfoPrintf(("LAYOUT AFTER DELETE 1\n"));
        AJ_NVRAM_Layout_Print();

        if (AJ_NVRAM_Exist(tid2)) {
            AJ_ASSERT(AJ_NVRAM_Delete(tid2) == AJ_OK);
        }
        AJ_InfoPrintf(("LAYOUT AFTER DELETE 2\n"));
        AJ_NVRAM_Layout_Print();

        if (AJ_NVRAM_Exist(tid3)) {
            AJ_ASSERT(AJ_NVRAM_Delete(tid3) == AJ_OK);
        }
        AJ_InfoPrintf(("LAYOUT AFTER DELETE 3\n"));
        AJ_NVRAM_Layout_Print();

        if (AJ_NVRAM_Exist(tid4)) {
            AJ_ASSERT(AJ_NVRAM_Delete(tid4) == AJ_OK);
        }
        AJ_InfoPrintf(("LAYOUT AFTER DELETE 4\n"));
        AJ_NVRAM_Layout_Print();
#endif

        if (AJ_NVRAM_Exist(AJ_NVRAM_ID_FOR_APPS)) {
            AJOBS_Info_Test emptyInfo;
            AJ_Status status = AJ_OK;
            size_t size = sizeof(AJOBS_Info_Test);

            memset(&emptyInfo, 0, sizeof(emptyInfo));
            AJ_AlwaysPrintf(("Going to write Info values: state=%d, ssid=%s authType=%d pc=%s\n", emptyInfo.state, emptyInfo.ssid, emptyInfo.authType, emptyInfo.pc));
            //AJ_NV_DATASET* nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "w", size); //PROPERTY STORE DEVICE ID
            nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_FOR_APPS, "w", size);
            if (nvramHandle != NULL) {
                int sizeWritten = AJ_NVRAM_Write(&emptyInfo, size, nvramHandle);
                status = AJ_NVRAM_Close(nvramHandle);
                if (sizeWritten != size) {
                    status = AJ_ERR_WRITE;
                    goto _TEST_NVRAM_DELETE_EXIT;
                }
            }
            //nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "r", 0); //PROPERTY STORE DEVICE ID
            nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_FOR_APPS, "r", 0);
            if (nvramHandle != NULL) {
                int sizeRead = AJ_NVRAM_Read(&emptyInfo, size, nvramHandle);
                status = AJ_NVRAM_Close(nvramHandle);
                if (sizeRead != sizeRead) {
                    status = AJ_ERR_READ;
                } else {
                    AJ_AlwaysPrintf(("Read Info values: state=%d, ssid=%s authType=%d pc=%s\n", emptyInfo.state, emptyInfo.ssid, emptyInfo.authType, emptyInfo.pc));
                }
            }
        }
        AJ_InfoPrintf(("LAYOUT AFTER DELETE OBS\n"));
        AJ_NVRAM_Layout_Print();
    } else {
        AJ_NVRAM_Clear();
        AJ_InfoPrintf(("LAYOUT AFTER CLEAR ALL\n"));
        AJ_NVRAM_Layout_Print();
    }
    return status;

_TEST_NVRAM_DELETE_EXIT:
    AJ_NVRAM_Close(nvramHandle);
    return status;

}
Example #7
0
AJ_Status TestNvramRead() {
    //uint16_t id = 0;
    AJ_NV_DATASET* d1 = NULL;
    AJ_NV_DATASET* d2 = NULL;
    AJ_NV_DATASET* d3 = NULL;
    AJ_NV_DATASET* d4 = NULL;
    int i = 0;
    size_t bytes1, bytes2, bytes3, bytes4 = 0;
    AJ_Status status = AJ_OK;

    AJ_NVRAM_Layout_Print();

#ifdef READ_STRESS
    while (TRUE) {
#endif
    //AJ_InfoPrintf(("LAYOUT AFTER OPEN - READ MODE\n"));
    //AJ_NVRAM_Layout_Print();

    d1 = AJ_NVRAM_Open(tid1, "r", 0);
    //d1 = AJ_NVRAM_Open(66, "r", 0); //NEGATIVE READ TEST
    AJ_ASSERT(d1);
    for (i = 0; i < d1->capacity / 4; i++) {
        int data1 = 0;
        bytes1 = AJ_NVRAM_Read(&data1, sizeof(data1), d1);
        if (bytes1 != sizeof(data1) || data1 != i) {
            return AJ_ERR_FAILURE;
        }
#ifdef SHOW_READ
        if (i % 10 == 0) {
            AJ_InfoPrintf(("Dataset 1 capacity %u curPos %u flash value: %u\n", d1->capacity, d1->curPos, data1));
        }
#endif
    }
    if (d1 != NULL) {
        AJ_NVRAM_Close(d1);
        AJ_ASSERT(d1);
    }

    d2 = AJ_NVRAM_Open(tid2, "r", 0);
    AJ_ASSERT(d2);
    for (i = 0; i < d2->capacity / 4; i++) {
        int data2 = 0;
        bytes2 = AJ_NVRAM_Read(&data2, sizeof(data2), d2);
        if (bytes2 != sizeof(data2) || data2 != i) {
            return AJ_ERR_FAILURE;
        }
#ifdef SHOW_READ
        if (i % 10 == 0) {
            AJ_InfoPrintf(("Dataset 2 capacity %u curPos %u flash value: %u\n", d2->capacity, d2->curPos, data2));
        }
#endif
    }
    if (d2 != NULL) {
        AJ_NVRAM_Close(d2);
        AJ_ASSERT(d2);
    }

    d3 = AJ_NVRAM_Open(tid3, "r", 0);
    AJ_ASSERT(d3);
    for (i = 0; i < d3->capacity / 4; i++) {
        int data3 = 0;
        bytes3 = AJ_NVRAM_Read(&data3, sizeof(data3), d3);
        if (bytes3 != sizeof(data3) || data3 != i) {
            return AJ_ERR_FAILURE;
        }
#ifdef SHOW_READ
        if (i % 10 == 0) {
            AJ_InfoPrintf(("Dataset 3 capacity %u curPos %u flash value: %u\n", d3->capacity, d3->curPos, data3));
        }
#endif
    }
    if (d3 != NULL) {
        AJ_NVRAM_Close(d3);
        AJ_ASSERT(d3);
    }

    d4 = AJ_NVRAM_Open(tid4, "r", 0);
    AJ_ASSERT(d4);
    for (i = 0; i < d4->capacity / 4; i++) {
        int data4 = 0;
        bytes4 = AJ_NVRAM_Read(&data4, sizeof(data4), d4);
        if (bytes4 != sizeof(data4) || data4 != i) {
            return AJ_ERR_FAILURE;
        }
#ifdef SHOW_READ
        if (i % 10 == 0) {
            AJ_InfoPrintf(("Dataset 4 capacity %u curPos %u flash value: %u\n", d4->capacity, d4->curPos, data4));
        }
#endif
    }
    if (d4 != NULL) {
        AJ_NVRAM_Close(d4);
        AJ_ASSERT(d4);
    }

    AJ_InfoPrintf(("LAYOUT AFTER READ --- END capacity %u curPos %u\n", d4->capacity, d4->curPos));
    AJ_NVRAM_Layout_Print();

#ifdef READ_STRESS
}
#endif
    return status;
}
Example #8
0
AJ_Status TestNvramWrite()
{
    AJ_NV_DATASET* d1 = NULL;
    AJ_NV_DATASET* d2 = NULL;
    AJ_NV_DATASET* d3 = NULL;
    AJ_NV_DATASET* d4 = NULL;
    int i = 0;
    uint16_t cap1, cap2, cap3, cap4 = 0;
    size_t bytes1, bytes2, bytes3, bytes4 = 0;
    AJ_Status status = AJ_OK;

#ifdef WRITE_STRESS
    while (TRUE) {
#endif
    cap1 = (tid1 % ((AJ_NVRAM_REQUESTED / 4) - 100)) + 1;
    cap2 = (tid2 % ((AJ_NVRAM_REQUESTED / 4) - 100)) + 1;
    cap3 = (tid3 % ((AJ_NVRAM_REQUESTED / 4) - 100)) + 1;
    cap4 = (tid4 % ((AJ_NVRAM_REQUESTED / 4) - 100)) + 1;

    d1 = AJ_NVRAM_Open(tid1, "w", cap1);
    for (i = 0; i < AJ_NVRAM_REQUESTED / 4; i++) {
        if ((d1->capacity - d1->curPos) >= sizeof(i)) {
            bytes1 = AJ_NVRAM_Write(&i, sizeof(i), d1);
            if (bytes1 != sizeof(i)) {
                return AJ_ERR_FAILURE;
            }
        }
    }
    AJ_InfoPrintf(("Dataset1 bytes: %u i: %u sizeof(i): %u capacity %u curPos %u\n", bytes1, i, sizeof(i), d1->capacity, d1->curPos));
    AJ_InfoPrintf(("LAYOUT AFTER WRITE\n"));
    AJ_NVRAM_Layout_Print();
    if (d1 != NULL) {
        AJ_NVRAM_Close(d1);
        AJ_ASSERT(d1);
    }

    d2 = AJ_NVRAM_Open(tid2, "w", cap2);
    AJ_ASSERT(d2);
    for (i = 0; i < AJ_NVRAM_REQUESTED / 4; i++) {
        if ((d2->capacity - d2->curPos) >= sizeof(i)) {
            bytes2 = AJ_NVRAM_Write(&i, sizeof(i), d2);
            if (bytes2 != sizeof(i)) {
                return AJ_ERR_FAILURE;
            }
        }
    }
    AJ_InfoPrintf(("Dataset2 bytes: %u i: %u sizeof(i): %u capacity %u curPos %u\n", bytes2, i, sizeof(i), d2->capacity, d2->curPos));
    AJ_InfoPrintf(("LAYOUT AFTER WRITE\n"));
    AJ_NVRAM_Layout_Print();
    if (d2 != NULL) {
        AJ_NVRAM_Close(d2);
        AJ_ASSERT(d2);
    }


    d3 = AJ_NVRAM_Open(tid3, "w", cap3);
    AJ_ASSERT(d3);
    for (i = 0; i < AJ_NVRAM_REQUESTED / 4; i++) {
        if ((d3->capacity - d3->curPos) >= sizeof(i)) {
            bytes3 = AJ_NVRAM_Write(&i, sizeof(i), d3);
            if (bytes3 != sizeof(i)) {
                return AJ_ERR_FAILURE;
            }
        }
    }
    AJ_InfoPrintf(("Dataset3 bytes: %u i: %u sizeof(i): %u capacity %u curPos %u\n", bytes2, i, sizeof(i), d2->capacity, d2->curPos));
    AJ_InfoPrintf(("LAYOUT AFTER WRITE\n"));
    AJ_NVRAM_Layout_Print();
    if (d3 != NULL) {
        AJ_NVRAM_Close(d3);
        AJ_ASSERT(d3);
    }

    d4 = AJ_NVRAM_Open(tid4, "w", cap4);
    AJ_ASSERT(d4);
    for (i = 0; i < AJ_NVRAM_REQUESTED / 4; i++) {
        if ((d4->capacity - d4->curPos) >= sizeof(i)) {
            bytes4 = AJ_NVRAM_Write(&i, sizeof(i), d4);
            if (bytes4 != sizeof(i)) {
                return AJ_ERR_FAILURE;
            }
        }
    }
    AJ_InfoPrintf(("Dataset4 bytes: %u i: %u sizeof(i): %u capacity %u curPos %u\n", bytes2, i, sizeof(i), d2->capacity, d2->curPos));
    AJ_InfoPrintf(("LAYOUT AFTER WRITE\n"));
    AJ_NVRAM_Layout_Print();
    if (d4 != NULL) {
        AJ_NVRAM_Close(d4);
        AJ_ASSERT(d4);
    }

    AJ_InfoPrintf(("LAYOUT AFTER CLOSE - WRITE MODE\n"));
    AJ_NVRAM_Layout_Print();
#ifdef WRITE_STRESS
}
#endif
    return status;
}
Example #9
0
AJ_Status TestObsWrite()
{
    AJ_Status status = AJ_OK;
    AJ_NV_DATASET* nvramHandle;
    AJOBS_Info_Test info;
    int nTest;
    size_t size = sizeof(info);
    char* ssid[] = { "abcdefghABCDEFGH", "aaaaaaaa", "bbbbbbbb", "cccccccc", "dddddddd", "eeeeeeee", "ffffffff", "gggggggg", "hhhhhhhh", "iiiiiiii",
                     "jjjjjjjj", "kkkkkkkk", "llllllll", "mmmmmmmm", "nnnnnnnn", "oooooooo", "pppppppp", "qqqqqqqq", "rrrrrrrr", "ssssssss",
                     "", "tttttttt", "uuuuuuuu", "vvvvvvvv", "wwwwwwww", "xxxxxxxx", "yyyyyyyy", "zzzzzzzz", "11111111", "22222222", "33333333",
                     "44444444", "55555555", "66666666", "77777777", "888888888888888888888888888888", "99999999", "aaaa1111", "bbbb2222", "cccc3333", "dddd4444",
                     "TRTESTING123", "eeee5555", "", "TR-TESTING-43" };
    char pc[] = "aaaaabbbbbcccccAAAAABBBBBCCCCCzzzzzZZZZZ1111122222";
    size_t i;

    AJ_NVRAM_Layout_Print();

    //if( AJ_NVRAM_Exist(AJ_NVRAM_ID_CREDS_MAX + 100)){ //NEGATIVE TEST, ID DOESN'T EXIST
    //if( AJ_NVRAM_Exist(AJ_NVRAM_ID_CREDS_MAX + 1)){ //PROPERTY STORE DEVICE ID
    if (AJ_NVRAM_Exist(AJ_NVRAM_ID_FOR_APPS)) {
        //nvramHandle = AJ_NVRAM_Open(100, "r", 0); //NEGATIVE TEST, OPEN INVALID ID
        //nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "r", 0); //PROPERTY STORE DEVICE ID
        nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_FOR_APPS, "r", 0);
        if (nvramHandle != NULL) {
            int sizeRead = AJ_NVRAM_Read(&info, size, nvramHandle);
            status = AJ_NVRAM_Close(nvramHandle);
            AJ_InfoPrintf(("sizeRead: %u, size: %u\n", sizeRead, size));
            if (sizeRead != size) {
                status = AJ_ERR_READ;
            } else {
                AJ_InfoPrintf(("Read Info values: state=%d, ssid=%s authType=%d pc=%s\n", info.state, info.ssid, info.authType, info.pc));
            }
        }
    }

    //nTest = AJ_NVRAM_Read(&info, size, nvramHandle); //NEGATIVE TEST, READ NULL HANDLE
    //nTest = AJ_NVRAM_Write(&info, size, nvramHandle); //NEGATIVE TEST, WRITE TO NULL HANDLE

    for (i = 0; i < ArraySize(ssid); i++) {
        strncpy(info.ssid, ssid[i], sizeof(info.ssid));
        strncpy(info.pc, pc, sizeof(info.pc));
        info.authType = 0;
        info.state = 0;

#ifdef OBS_STRESS
        while (TRUE) {
#endif

#ifdef SHOW_REWRITES
        AJ_AlwaysPrintf(("Going to write Info values: state=%d, ssid=%s authType=%d pc=%s\n", info.state, info.ssid, info.authType, info.pc));
#endif

        //nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "w", 0); //NEGATIVE TEST, OPEN 0 SIZE
        //nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "t", size); //NEGATIVE TEST, INVALID MODE
        //nvramHandle = AJ_NVRAM_Open(0, "w", size); //NEGATIVE TEST, OPEN 0 ID
        //nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "w", size); //PROPERTY STORE DEVICE ID
        nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_FOR_APPS, "w", size);
        if (nvramHandle != NULL) {
            int sizeWritten = AJ_NVRAM_Write(&info, size, nvramHandle);
            status = AJ_NVRAM_Close(nvramHandle);
            if (sizeWritten != size) {
                status = AJ_ERR_WRITE;
            }
        }
        //nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_CREDS_MAX + 1, "r", 0); //PROPERTY STORE DEVICE ID
        nvramHandle = AJ_NVRAM_Open(AJ_NVRAM_ID_FOR_APPS, "r", 0);
        if (nvramHandle != NULL) {
            int sizeRead = AJ_NVRAM_Read(&info, size, nvramHandle);
            status = AJ_NVRAM_Close(nvramHandle);
            if (sizeRead != sizeRead) {
                status = AJ_ERR_READ;
            }
#ifdef SHOW_REWRITES
            else {
                AJ_InfoPrintf(("Read Info values: state=%d, ssid=%s authType=%d pc=%s\n", info.state, info.ssid, info.authType, info.pc));
            }
#endif
        }

#ifdef NEGATIVE_OPEN
        nvramHandle = AJ_NVRAM_Open(66, "r", 0);
        status = AJ_NVRAM_Close(nvramHandle);
#endif

        //AJ_NVRAM_Layout_Print();
#ifdef OBS_STRESS
        AJ_Sleep(2000);
    }
#endif
    }
    AJ_NVRAM_Layout_Print();
    return status;
}
Example #10
0
AJ_Status CreateTrailOfBreadcrumbs(void)
{
    uint16_t minNvramSpaceNeeded;
    uint16_t currentAvailableNvramSpace;


    uint16_t someNvramId = 0;
    AJ_NV_DATASET* someDataHandle = NULL;

    uint8_t sizeOfEachSlice;
    uint16_t i;

    size_t numBytesExpectingToWrite;
    size_t numBytesActuallyWritten;

    /*
     * Test program would write (place breadcrumbs) over the NVRAM, anyway.
     */
    AJ_NVRAM_Clear();

    currentAvailableNvramSpace = AJ_NVRAM_GetSizeRemaining();

    /*
     * At minimum, the test needs to store:
     * a. The message itself
     * b. The number of breadcrumbs in the trail (the mininum value is 1)
     *    (this is essentially the value held by lengthOfBreadcrumbTrail)
     */
    minNvramSpaceNeeded = (estimatedOverheadPerNvramItem + sizeof(sensumManifestum)) +
                          (estimatedOverheadPerNvramItem + sizeof(lengthOfBreadcrumbTrail));

    if (currentAvailableNvramSpace < minNvramSpaceNeeded) {
        AJ_Printf("ERROR: Available NVRAM space (%u bytes) is less than needed (%u bytes).\n", currentAvailableNvramSpace, minNvramSpaceNeeded);
        return AJ_ERR_RESOURCES;
    }

    /*
     * Any remaining space can be used to add more breadcrumbs.
     * max_num_bread_crumbs = nvram_size_available / size_occupied_by_each_crumb
     *
     * size_occupied_by_each_crumb = estimatedOverheadPerNvramItem + sizeof(id)
     */
    lengthOfBreadcrumbTrail = (currentAvailableNvramSpace - minNvramSpaceNeeded) /
                              (estimatedOverheadPerNvramItem  + sizeof(someNvramId));

    /*
     * Create the trail of bread crumbs starting at smId
     *
     * Generate a random list of nvram ids, lengthOfBreadcrumbTrail number of
     * elements. The list should not have any duplicates and should not include
     * marker ids viz. smId and countId.
     *
     * This is necessary to ensure that the trail of breadcrumbs is without
     * any loops. The simplest way to generate a list of unique nvram ids
     * would be to divide the available space into equal slices and generate
     * one id from each slice.
     *
     * The starting id is AJ_NVRAM_ID_APPS_BEGIN and the ending id is 0xFFFF.
     *
     * There are a total of (lengthOfBreadcrumbTrail + 1) items to
     * go through, including the starting point smId.
     */

    sizeOfEachSlice = (0xFFFF - AJ_NVRAM_ID_APPS_BEGIN) / lengthOfBreadcrumbTrail;

    /* The starting point has to be the constant marker, smId */
    someNvramId = smId;
    for (i = 0; i < lengthOfBreadcrumbTrail + 1; i++) {
        uint8_t randByte;
        uint16_t startId;
        uint16_t nextId;

        void* pointerToData;

        AJ_RandBytes(&randByte, sizeof(randByte));
        startId = AJ_NVRAM_ID_APPS_BEGIN + sizeOfEachSlice * i;

        nextId = startId + randByte % sizeOfEachSlice;

        /* Ensure uniqueness of id - no conflicts with well-known markers */
        if (smId == nextId || countId == nextId) {
            nextId += (0 == i % 2) ? -1 : 1;
        }

        numBytesExpectingToWrite =  (lengthOfBreadcrumbTrail != i) ? sizeof(nextId) : sizeof(sensumManifestum);

        currentAvailableNvramSpace = AJ_NVRAM_GetSizeRemaining();

        someDataHandle = AJ_NVRAM_Open(someNvramId, AJTestWriteMode, numBytesExpectingToWrite);

        if (NULL == someDataHandle) {
            /* Cannot proceed any further due to failed breadcrumb access */
            return AJ_ERR_NVRAM_WRITE;
        }

        pointerToData = (lengthOfBreadcrumbTrail != i) ? (void*) (&nextId) : (void*) sensumManifestum;
        numBytesActuallyWritten = AJ_NVRAM_Write(pointerToData,
                                                 numBytesExpectingToWrite,
                                                 someDataHandle);

        /* done writing the data, can close the handle */
        if (AJ_OK != AJ_NVRAM_Close(someDataHandle)) {
            AJ_Printf("WARN: For id: %u, AJ_NVRAM_Close did NOT return %s (code: %u)\n", someNvramId, AJ_StatusText(AJ_OK), AJ_OK);
        }

        if (AJTestNvramWriteFailure == numBytesActuallyWritten ||
            numBytesExpectingToWrite != numBytesActuallyWritten) {
            /* Cannot proceed any further due to breadcrumb write failure */
            return AJ_ERR_NVRAM_WRITE;
        }

        /*
         * The write has been successful.
         *
         * Check whether estimatedOverheadPerNvramItem (rough estimate) is
         * accurate. Overestimating estimatedOverheadPerNvramItem is fine
         * (erring on the side on caution).
         */
        if (estimatedOverheadPerNvramItem < currentAvailableNvramSpace - AJ_NVRAM_GetSizeRemaining() - numBytesExpectingToWrite) {
            AJ_Printf("ERROR: The estimated overhead per NVRAM item (%u bytes) is not accurate. It needs to be increased.\n", estimatedOverheadPerNvramItem);
            return AJ_ERR_FAILURE;
        }

        /* Move to the next breadcrumb */
        someNvramId = nextId;
    }

    /*
     * All the items are written.
     * Write the value of lengthOfBreadcrumbTrail
     */
    someDataHandle = AJ_NVRAM_Open(countId, AJTestWriteMode, sizeof(lengthOfBreadcrumbTrail));

    if (NULL == someDataHandle) {
        return AJ_ERR_NVRAM_WRITE;
    }

    numBytesExpectingToWrite = sizeof(lengthOfBreadcrumbTrail);
    numBytesActuallyWritten = AJ_NVRAM_Write((void*)&lengthOfBreadcrumbTrail,
                                             numBytesExpectingToWrite,
                                             someDataHandle);

    /* done writing the data, can close the handle */
    if (AJ_OK != AJ_NVRAM_Close(someDataHandle)) {
        AJ_Printf("WARN: For id: %u, AJ_NVRAM_Close did NOT return %s (code: %u)\n", countId, AJ_StatusText(AJ_OK), AJ_OK);
    }

    if (AJTestNvramWriteFailure == numBytesActuallyWritten ||
        numBytesExpectingToWrite != numBytesActuallyWritten) {
        return AJ_ERR_NVRAM_WRITE;
    }

    return AJ_OK;
}
Example #11
0
AJ_Status FollowTrailOfBreadcrumbs(void)
{
    static char scratchPad[sizeof(sensumManifestum)];

    uint16_t someNvramId = 0;
    AJ_NV_DATASET* someDataHandle = NULL;

    size_t numBytesExpectingToRead;
    size_t numBytesActuallyRead;

    uint16_t i;

    /*
     * As long as NVRAM wasn't cleared between two successive runs of
     * the test, it should be possible to read the known data written at
     * the very end of the test by the previous run.
     *
     * The first item to read is the number of breadcrumbs.
     */

    if (1 != AJ_NVRAM_Exist(countId)) {
        /* cannot find the marker countId */
        return AJ_ERR_NVRAM_READ;
    }

    someDataHandle = AJ_NVRAM_Open(countId, AJTestReadMode, 0);
    if (NULL == someDataHandle) {
        /* cannot open the marker countId */
        return AJ_ERR_NVRAM_READ;
    }

    numBytesExpectingToRead = sizeof(lengthOfBreadcrumbTrail);
    numBytesActuallyRead = AJ_NVRAM_Read((void*)&lengthOfBreadcrumbTrail,
                                         numBytesExpectingToRead,
                                         someDataHandle);

    if (AJ_OK != AJ_NVRAM_Close(someDataHandle)) {
        AJ_Printf("WARN: For id: %u, AJ_NVRAM_Close did NOT return %s (code: %u)\n", countId, AJ_StatusText(AJ_OK), AJ_OK);
    }

    if (AJTestNvramReadFailure == numBytesActuallyRead ||
        numBytesExpectingToRead != numBytesActuallyRead) {
        /* could not read from the marker countId */
        return AJ_ERR_NVRAM_READ;
    }

    /*
     * Follow the trail of bread crumbs starting at smId
     */
    someNvramId = smId;
    for (i  = 0; i < lengthOfBreadcrumbTrail + 1; i++) {
        uint8_t isIdPresent = AJ_NVRAM_Exist(someNvramId);

        void* pointerToData = (lengthOfBreadcrumbTrail != i) ? (void*) &someNvramId : (void*) scratchPad;

        someDataHandle = (1 == isIdPresent) ? AJ_NVRAM_Open(someNvramId, AJTestReadMode, 0) : NULL;

        if (NULL == someDataHandle) {
            /* Cannot proceed any further due to failed breadcrumb access */
            return AJ_ERR_NVRAM_READ;
        }

        numBytesExpectingToRead =  (lengthOfBreadcrumbTrail != i) ? sizeof(someNvramId) : sizeof(sensumManifestum);
        numBytesActuallyRead = AJ_NVRAM_Read(pointerToData,
                                             numBytesExpectingToRead,
                                             someDataHandle);

        /* done reading the data, can close the handle */
        if (AJ_OK != AJ_NVRAM_Close(someDataHandle)) {
            AJ_Printf("WARN: For id: %u, AJ_NVRAM_Close did NOT return %s (code: %u)\n", someNvramId, AJ_StatusText(AJ_OK), AJ_OK);
        }

        if (AJTestNvramReadFailure == numBytesActuallyRead ||
            numBytesExpectingToRead != numBytesActuallyRead) {
            /* Cannot proceed any further due to breadcrumb read failure */
            return AJ_ERR_NVRAM_READ;
        }


        if (lengthOfBreadcrumbTrail == i) {
            /* Final crumb where message has been retrieved */
            return (0 == strcmp(scratchPad, sensumManifestum)) ? AJ_OK : AJ_ERR_NVRAM_READ;
        }
    }

    return AJ_OK;
}