/*
 *****************************************************************************
 *                                                                           *
 *                 IMPINJ CONFIDENTIAL AND PROPRIETARY                       *
 *                                                                           *
 * This source code is the sole property of Impinj, Inc.  Reproduction or    *
 * utilization of this source code in whole or in part is forbidden without  *
 * the prior written consent of Impinj, Inc.                                 *
 *                                                                           *
 * (c) Copyright Impinj, Inc. 2009. All rights reserved.                     *
 *                                                                           *
 *****************************************************************************
 */

/*
 *****************************************************************************
 *
 * $Id: reset.c 65946 2010-11-08 00:41:15Z dshaheen $
 * 
 * Description: 
 *   This sample application demonstrates how to simply reset the radio or 
 *   reset to Boot Loader.
 *   
 *   The functional flow is as follows:
 *     - Start up the RFID Reader Library 
 *     - Enumerate the attached radios
 *     - Open the first enumerated radio and
 *     - Reset the radio based on command line argument
 *     - Close the radio
 *     - Shut down the library
 *
 * Parameters:
 *   A single argument specifies the type of reset (-soft or -bl).
 *
 *****************************************************************************
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory.h>
#include "rfid_library.h"
#include "sample_utility.h"

#define SOFT_RESET "-soft"
#define BL_RESET   "-bl"

int main(
    int     argc,
    char**  argv
    )
{
    RFID_STATUS                             status;
    RFID_RADIO_ENUM*                        pEnum;
    RFID_RADIO_HANDLE                       handle;

    if ((argc != 2)                                             ||
        ((strncmp(SOFT_RESET, argv[1], strlen(SOFT_RESET)) != 0) &&
        (strncmp(BL_RESET, argv[1], strlen(BL_RESET)) != 0)))
    {
        fprintf(
            stderr, 
            "Must specify type of reset:  reset -soft | -bl\n");
        goto EXIT;
    }

    /* Initialize the RFID library                                         */
    status = RFID_Startup(NULL, 0);
    if (RFID_STATUS_OK != status)
    {
        fprintf(
            stderr, 
            "ERROR: RFID_Startup returned %d\n",
            status);
        goto EXIT;
    }

    /* Create an initial structure for enumerating the radios.  We'll adjust  */
    /* it once we know how big to make it.                                    */
    pEnum = (RFID_RADIO_ENUM *) malloc(sizeof(RFID_RADIO_ENUM));
    if (NULL == pEnum)
    {
        fprintf(
            stderr, 
            "ERROR: Failed to allocate memory\n");
        goto SHUTDOWN_LIBRARY;
    }
    pEnum->length       =
        pEnum->totalLength  = sizeof(RFID_RADIO_ENUM);

    /* Enumerate the radios                                                   */
    while (RFID_ERROR_BUFFER_TOO_SMALL == 
        (status = RFID_RetrieveAttachedRadiosList(pEnum, 0)))
    {
        RFID_RADIO_ENUM* pNewEnum = 
            (RFID_RADIO_ENUM *) realloc(pEnum, pEnum->totalLength);
        if (NULL == pNewEnum)
        {
            fprintf(
                stderr, 
                "ERROR: Failed to allocate memory\n");
            goto CLEANUP_ENUM;
        }
        pEnum = pNewEnum;
    }
    if (RFID_STATUS_OK != status)
    {
        fprintf(
            stderr,
            "ERROR: RFID_RetrieveAttachedRadiosList returned %d\n",
            status);
        goto CLEANUP_ENUM;
    }

    /* Open up the first radio - if more than one radio is attached, so be it */
    if (!pEnum->countRadios)
    {
        fprintf(
            stderr, 
            "ERROR: No radios attached to the system\n");
        goto CLEANUP_ENUM;
    }
    status = RFID_RadioOpen(pEnum->ppRadioInfo[0]->cookie, &handle, 0);
    if (RFID_STATUS_OK != status)
    {
        fprintf(
            stderr, 
            "ERROR: RFID_RadioOpen returned %d\n",
            status);
        goto CLEANUP_ENUM;
    }

    // ready to reset.  Based on the argv check above, if it is not soft reset
    // we know it must boot loader (bl)
    if (strncmp(SOFT_RESET, argv[1], strlen(SOFT_RESET)) == 0)
    {
        status = RFID_MacReset(handle, RFID_MAC_RESET_TYPE_SOFT);
    }
    else
    {
        status = RFID_MacReset(handle, RFID_MAC_RESET_TYPE_TO_BOOTLOADER);
    }

    if (RFID_STATUS_OK != status)
    {
        fprintf(
            stderr, 
            "ERROR: RFID_MacReset returned status %d\n", status);
    }
    RFID_RadioClose(handle);

CLEANUP_ENUM:
    free(pEnum);

SHUTDOWN_LIBRARY:
    RFID_Shutdown();

EXIT:
    return 0;
} /* main */

