/*
 * Copyright (C) ID TECH.
 *
 * Author: Eric
 *
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "demo_common.h"
#ifndef WIN32
# include <dlfcn.h>
#endif
#include "libIDT_Device.h"
#include <pthread.h>

void
process_device_select();
void
display_usb_menu();
void
display_usb_menuVP();

extern void
MSR_callBack(int type, IDTMSRData cardData1);
extern void
MSR_callBackp(int type, IDTMSRData * cardData1);
extern void
PIN_callBack(int type, IDTPINData * pinData);
extern void
LCD_callBack(int type, IDTLCDItem * lcdItem);
extern void
RKI_callBack(int resultCode, char * macValue);
extern char *
getDeviceType(int deviceType);
extern int
inputSelection();
extern void
process_exit();
// extern int level;

IDT_COMMON_PROCESS Demo_Common_Process;

IDT_DEMO_LIB_DISPLAY_MENU idtech_display_menu_from_lib;

typedef void (* Demo_Init)(IDT_COMMON_PROCESS pCommonProcess, IDT_DEMO_LIB_DISPLAY_MENU * idtech_display_menu_from_lib);
typedef void (* Demo_getMenuFn)(IDT_DEMO_LIB_DISPLAY_MENU * idtech_display_menu_from_lib);

Demo_Init demo_init;
Demo_getMenuFn demo_getMenuFn;

void
init_demo_lib(int deviceType) {
    Demo_Common_Process.main_display_device_list   = display_usb_menu;
    Demo_Common_Process.main_process_device_select = process_device_select;
    Demo_Common_Process.PIN_callBack  = PIN_callBack;
    Demo_Common_Process.LCD_callBack  = LCD_callBack;
    Demo_Common_Process.FW_callBack   = FW_callBack;
    Demo_Common_Process.RKI_callBack  = RKI_callBack;
    Demo_Common_Process.CMR_callBack  = CMR_callBack;
    Demo_Common_Process.CSFS_callBack = CSFS_callBack;
    Demo_Common_Process.SendDataLog   = SendDataLog;
    Demo_Common_Process.ReadDataLog   = ReadDataLog;

    // MSR
    Demo_Common_Process.printMSRData  = printMSRData;
    Demo_Common_Process.MSR_callBack  = MSR_callBack;
    Demo_Common_Process.MSR_callBackp = MSR_callBackp;
    // EMV
    Demo_Common_Process.printBytes = printBytes;
    Demo_Common_Process.printTLV   = printTLV;
    Demo_Common_Process.convertBytesIntoHexStr = convertBytesIntoHexStr;
    Demo_Common_Process.convertHStrIntoHex     = convertHStrIntoHex;
    Demo_Common_Process.EMV_callBack = EMV_callBack;

    //	Demo_Common_Process.set_auto_emv_authenticate = set_auto_emv_authenticate;
    //	Demo_Common_Process.get_auto_emv_authenticate = get_auto_emv_authenticate;

    //	Demo_Common_Process.set_auto_emv_complete = set_auto_emv_complete;
    //	Demo_Common_Process.get_auto_emv_complete = get_auto_emv_complete;

    Demo_Common_Process.set_emv_Finished = set_emv_Finished;
    Demo_Common_Process.get_emv_Finished = get_emv_Finished;

    Demo_Common_Process.set_pin_Finished = set_pin_Finished;
    Demo_Common_Process.get_pin_Finished = get_pin_Finished;

    Demo_Common_Process.getDUKPT = getDUKPT;

    Demo_Common_Process.inputSelection = inputSelection;

    Demo_Common_Process.printAIDList = printAIDList;

    char libname[256] = { 0 };

    switch (deviceType) {
        #ifdef WIN32
        case IDT_DEVICE_SPECTRUM_PRO:
            sprintf(libname, "libSpectrumPro.dll");
            break;
        case IDT_DEVICE_KIOSK_III:
        case IDT_DEVICE_KIOSK_III_S:
            sprintf(libname, "libKioskIII.dll");
            break;
        case IDT_DEVICE_PIP_READER:
            sprintf(libname, "libPipReader.dll");
            break;
        case IDT_DEVICE_AUGUSTA_HID:
        case IDT_DEVICE_AUGUSTA_S_HID:
        case IDT_DEVICE_AUGUSTA_S_TTK_HID:
        case IDT_DEVICE_AUGUSTA_KB:
            sprintf(libname, "libAugustaHID.dll");
            break;
        case IDT_DEVICE_MINISMART_II:
            sprintf(libname, "libMiniSmartII.dll");
            break;
        case IDT_DEVICE_L80:
        case IDT_DEVICE_L100:
            sprintf(libname, "libL100.dll");
            break;
        case IDT_DEVICE_VP3300_AJ:
        case IDT_DEVICE_VP3300_BT:
        case IDT_DEVICE_VP3300_USB:
            sprintf(libname, "libVP3300.dll");
            break;
        //	case IDT_DEVICE_VP3300_BT:
        //		sprintf(libname,"libVP3300_BT.dll");
        //		break;
        case IDT_DEVICE_UNIPAY_I_V:
        case IDT_DEVICE_UNIPAY_I_V_TTK:
            sprintf(libname, "libUniPayI_V.dll");
            break;
        //	case IDT_DEVICE_VP3300_USB:
        //		sprintf(libname,"libVP3300_USB.dll");
        //		break;
        case IDT_DEVICE_SREDKEY2_HID:
        case IDT_DEVICE_SREDKEY2_KB:
            sprintf(libname, "libSREDKey2.dll");
            break;
        case IDT_DEVICE_VP8800:
            sprintf(libname, "libVP8800.dll");
            break;
        case IDT_DEVICE_NEO2:
        case IDT_DEVICE_NEO2 + 1:
        case IDT_DEVICE_NEO2 + 2:
        case IDT_DEVICE_NEO2 + 3:
        case IDT_DEVICE_NEO2 + 4:
            sprintf(libname, "libNEO2.dll");
            break;
        case IDT_DEVICE_VENDI:
            sprintf(libname, "libVendi.dll");
            break;
        #endif /* ifdef WIN32 */
        #ifdef __linux
        case IDT_DEVICE_SPECTRUM_PRO:
            sprintf(libname, "libSpectrumPro.so");
            break;
        case IDT_DEVICE_KIOSK_III:
        case IDT_DEVICE_KIOSK_III_S:
            sprintf(libname, "libKioskIII.so");
            break;
        case IDT_DEVICE_PIP_READER:
            sprintf(libname, "libPipReader.so");
            break;
        case IDT_DEVICE_AUGUSTA_HID:
        case IDT_DEVICE_AUGUSTA_S_HID:
        case IDT_DEVICE_AUGUSTA_S_TTK_HID:
        case IDT_DEVICE_AUGUSTA_KB:
            sprintf(libname, "libAugustaHID.so");
            break;
        case IDT_DEVICE_MINISMART_II:
            sprintf(libname, "libMiniSmartII.so");
            break;
        case IDT_DEVICE_L80:
        case IDT_DEVICE_L100:
            sprintf(libname, "libL100.so");
            break;
        case IDT_DEVICE_VP3300_AJ:
        case IDT_DEVICE_VP3300_BT:
        case IDT_DEVICE_VP3300_USB:
            sprintf(libname, "libVP3300.so");
            break;
        //	case IDT_DEVICE_VP3300_BT:
        //		sprintf(libname,"libVP3300_BT.so");
        //		break;
        case IDT_DEVICE_UNIPAY_I_V:
        case IDT_DEVICE_UNIPAY_I_V_TTK:
            sprintf(libname, "libUniPayI_V.so");
            break;
        //	case IDT_DEVICE_VP3300_USB:
        //		sprintf(libname,"libVP3300_USB.so");
        //		break;
        case IDT_DEVICE_SREDKEY2_HID:
        case IDT_DEVICE_SREDKEY2_KB:
            sprintf(libname, "libSREDKey2.so");
            break;
        case IDT_DEVICE_VP8800:
            sprintf(libname, "libVP8800.so");
            break;
        case IDT_DEVICE_NEO2:
        case IDT_DEVICE_NEO2 + 1:
        case IDT_DEVICE_NEO2 + 2:
        case IDT_DEVICE_NEO2 + 3:
        case IDT_DEVICE_NEO2 + 4:
            sprintf(libname, "libNEO2.so");
            break;
        case IDT_DEVICE_VENDI:
            sprintf(libname, "libVendi.so");
            break;
        #endif /* ifdef __linux */
        #ifdef __MACH__
        case IDT_DEVICE_SPECTRUM_PRO:
            sprintf(libname, "libSpectrumPro.dylib");
            break;
        case IDT_DEVICE_KIOSK_III:
        case IDT_DEVICE_KIOSK_III_S:
            sprintf(libname, "libKioskIII.dylib");
            break;
        case IDT_DEVICE_PIP_READER:
            sprintf(libname, "libPipReader.dylib");
            break;
        case IDT_DEVICE_AUGUSTA_HID:
        case IDT_DEVICE_AUGUSTA_S_HID:
        case IDT_DEVICE_AUGUSTA_S_TTK_HID:
        case IDT_DEVICE_AUGUSTA_KB:
            sprintf(libname, "libAugustaHID.dylib");
            break;
        case IDT_DEVICE_MINISMART_II:
            sprintf(libname, "libMiniSmartII.dylib");
            break;
        case IDT_DEVICE_L80:
        case IDT_DEVICE_L100:
            sprintf(libname, "libL100.dylib");
            break;
        case IDT_DEVICE_VP3300_AJ:
        case IDT_DEVICE_VP3300_BT:
        case IDT_DEVICE_VP3300_USB:
            sprintf(libname, "libVP3300.dylib");
            break;
        //	case IDT_DEVICE_VP3300_BT:
        //		sprintf(libname,"libVP3300_BT.dylib");
        //		break;
        case IDT_DEVICE_UNIPAY_I_V:
        case IDT_DEVICE_UNIPAY_I_V_TTK:
            sprintf(libname, "libUniPayI_V.dylib");
            break;
        //	case IDT_DEVICE_VP3300_USB:
        //		sprintf(libname,"libVP3300_USB.dylib");
        //		break;
        case IDT_DEVICE_SREDKEY2_HID:
        case IDT_DEVICE_SREDKEY2_KB:
            sprintf(libname, "libSREDKey2.dylib");
            break;
        case IDT_DEVICE_VP8800:
            sprintf(libname, "libVP8800.dylib");
            break;
        case IDT_DEVICE_NEO2:
        case IDT_DEVICE_NEO2 + 1:
        case IDT_DEVICE_NEO2 + 2:
        case IDT_DEVICE_NEO2 + 3:
        case IDT_DEVICE_NEO2 + 4:
            sprintf(libname, "libNEO2.dylib");
            break;
        case IDT_DEVICE_VENDI:
            sprintf(libname, "libVendi.dylib");
            break;
        #endif /* ifdef __MACH__ */
        default:
            break;
    }


    #ifdef WIN32
    void * h = LoadLibrary(libname);
    if (h == NULL) {
        fprintf(stderr, "fail to load %s\n", libname);
        fflush(stdout);
        return;
    }
    #else
    void * h = dlopen(libname, RTLD_LAZY);
    if (h == NULL) {
        fprintf(stderr, "fail to load %s\n", libname);
        fflush(stdout);
        return;
    }
    #endif /* ifdef WIN32 */

    #ifdef WIN32
    demo_init = (Demo_Init) GetProcAddress(h, "libDemo_init");
    if (demo_init == NULL) {
        fprintf(stderr, "fail to load the function libDemo_init\n");
        fflush(stdout);
        return;
    }
    demo_getMenuFn = (Demo_getMenuFn) GetProcAddress(h, "libDemo_getMenuFn");
    #else
    demo_init = (Demo_Init) dlsym(h, "libDemo_init");
    if (demo_init == NULL) {
        fprintf(stderr, "fail to load the function libDemo_init\n");
        fflush(stdout);
        return;
    }
    demo_getMenuFn = (Demo_getMenuFn) dlsym(h, "libDemo_getMenuFn");
    #endif /* ifdef WIN32 */
    demo_init(Demo_Common_Process, &idtech_display_menu_from_lib);
} /* init_demo_lib */

int _device_is_attached[IDT_DEVICE_MAX_DEVICES] = { 0 };
int _device_selected = 0;
void *
threadUpdate_WhenUsbHotplug(void * deviceType) {
    usleep(300000);
    int currentDeviceType = (int) deviceType;
    _device_is_attached[currentDeviceType] = device_isAttached(currentDeviceType);
    if (_device_selected == 0) {
        display_usb_menu();
    } else {
        demo_getMenuFn(&idtech_display_menu_from_lib);
        if (idtech_display_menu_from_lib.pDisplay_Menu_current) {
            idtech_display_menu_from_lib.pDisplay_Menu_current();
        }
    }
    int currentDev = device_getCurrentDeviceType();

    printf("------ \"%s\" Status Changed, please refer to above Hot-Plug message. ------\n\n\n",
      getDeviceType(currentDeviceType));
    if (IDT_DEVICE_UNKNOWN == currentDev) {
        printf("!!!!!!!! NO Device Actived!!!!!!!!!!!\n");
        printf("Please select the device in the main menu. (0 - exit)\n");
        printf("Enter 0 back to the main menu if current menu not allow select device.\n\n\n");
    }
    fflush(stdout);
    return 0;
}

#ifdef WIN32
static pthread_t pHandle_threadUpdate_WhenUsbHotplug;
#else
static pthread_t pHandle_threadUpdate_WhenUsbHotplug = NULL;
#endif

void
Hotplug_Callback(int deviceType, int hotplugMsg) {
    if (hotplugMsg == DEVICE_PLUGGED_IN) {
        printf("\n>>>>>DEMO_Hotplug_Callback>>>> [%s ATTACHED]\n", getDeviceType(deviceType));
    } else {
        set_emv_Finished(1);
        printf("\n<<<<<DEMO_Hotplug_Callback<<<< [%s DETACHED]\n", getDeviceType(deviceType));
    }
    fflush(stdout);

    #if 0
    if (get_emv_Finished() == 0) {
        emv_cancelTransaction();
        set_emv_Finished(1);
    }

    // should create another thread to process callback
    int currentDeviceType = deviceType;
    # ifdef WIN32
    int rc1 = pthread_create(&pHandle_threadUpdate_WhenUsbHotplug, NULL, threadUpdate_WhenUsbHotplug,
        (void *) currentDeviceType);
    if (rc1 != 0) {
        IDT_LOG_MESSAGE(LOG_LEVEL_INFORMATION, "create thread, %s\n", 0, NULL, PRINTF_FORMAT, __FILE_NAME__, __LINE__,
          __func__, strerror(rc1));
    }
    pthread_detach(pHandle_threadUpdate_WhenUsbHotplug);
    # else
    int rc1 = pthread_create(&pHandle_threadUpdate_WhenUsbHotplug, NULL, threadUpdate_WhenUsbHotplug,
        (void *) currentDeviceType);
    if (rc1 != 0) {
        IDT_LOG_MESSAGE(LOG_LEVEL_INFORMATION, "create thread, %s\n", 0, NULL, PRINTF_FORMAT, __FILE_NAME__, __LINE__,
          __func__, strerror(rc1));
    }
    pthread_detach(pHandle_threadUpdate_WhenUsbHotplug);
    # endif /* ifdef WIN32 */
    #endif /* if 0 */
}

// int registered = 0;
int
usb_init() {
    int r = 0;
    int i = 0;

    #ifdef PISCES
    process_device_select();
    return 0;

    #endif
    #ifndef __MACH__
    //	if (registered == 0)
    //	{
    registerHotplugCallBk(Hotplug_Callback);
    //		registered = 1;
    //	}
    #endif
    for (i = 0; i < IDT_DEVICE_MAX_DEVICES; i++) {
        _device_is_attached[i] = 0;
    }
    //	device_setConfigPath("/media/psf/Home/Repo/idt_cpp_sdk/C++_Demo/x86_64");

    //	char xmlc[5000] = {0};
    //	FILE *xmlF = NULL;
    //	xmlF = fopen("NEO2_Devices.xml", "r");
    //	int s = fread(xmlc, sizeof(char), 5000, xmlF);
    //	fclose(xmlF);
    //	printf("xml: size %d\n%s\n", s, xmlc);
    //	device_setNEO2DevicesConfigs(xmlc, s);
    r = device_init();
    if (r != RETURN_CODE_DO_SUCCESS) {
        printf("  Fail to init USB!\n");
        fflush(stdout);
        return 0;
    }
    for (i = 0; i < IDT_DEVICE_MAX_DEVICES; i++) {
        _device_is_attached[i] = device_isAttached(i);
    }
    process_device_select();
    return 0;
} /* usb_init */

// add the device list dynamically
int _device_list_menu[IDT_DEVICE_MAX_DEVICES] = { 0 };
int deviceConnectedCount = 0;
void
process_device_select() {
    int choice;

    // Get The Device Type
    int deviceType = IDT_DEVICE_UNKNOWN;
    int loopOkay   = 0;

    do {
        #ifdef PISCES
        display_usb_menuVP();
        #else
        display_usb_menu();
        #endif
        choice = inputSelection();
        #ifdef PISCES
        if (choice == 1) {
            deviceType = IDT_DEVICE_VP8800;
        }
        #else
        if (choice > 0) {
            if (choice <= deviceConnectedCount) {
                deviceType = _device_list_menu[choice];
            }
        }
        #endif
        else if (choice == 0) {
            process_exit();
            return;
        }

        if (device_setCurrentDevice(deviceType)) {
            loopOkay         = 1;
            _device_selected = 1;
        } else {
            printf("Could not set device type\n");
        }
        fflush(stdout);
        if (1 == loopOkay) break;
    } while (choice != 0);
    if (loopOkay == 1) {
        init_demo_lib(deviceType);
    }
} /* process_device_select */

void
display_usb_menuVP() {
    printf("\t\t*****************************************\n");
    printf("\t\t********* IDTech VP8800 Library *********\n");
    printf("\t\t************** Device Menu **************\n");
    printf("\t\t0.  Back to Options Menu\n");
    printf("\t\t1.  Start VP8800 Communication\n");
    printf("\t\t************************************************\n");
    //	idtech_display_menu_from_lib.pDisplay_Menu_current = display_main_menu;
    idtech_display_menu_from_lib.pDisplay_Menu_current = display_usb_menuVP;
    fflush(stdout);
}

void
display_usb_menu() {
    int i = 0;

    deviceConnectedCount = 0;
    printf("\t\t************************************************\n");
    printf("\t\t*********** IDT Universal SDK ******************\n");
    printf("\t\t********* Device Select Options ****************\n");
    printf("\t\t0.  Back to Interface Menu\n");
    for (i = 0; i < IDT_DEVICE_MAX_DEVICES; i++) {
        _device_list_menu[i] = IDT_DEVICE_UNKNOWN;
    }

    if (_device_is_attached[IDT_DEVICE_SPECTRUM_PRO]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_SPECTRUM_PRO;
        if (device_getCurrentDeviceType() == IDT_DEVICE_SPECTRUM_PRO) {
            printf("\t\t%d.  Spectrum Pro [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Spectrum Pro [Connected]\n", deviceConnectedCount);
        }
    }

    if (_device_is_attached[IDT_DEVICE_KIOSK_III]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_KIOSK_III;
        if (device_getCurrentDeviceType() == IDT_DEVICE_KIOSK_III) {
            printf("\t\t%d.  Kiosk III/IV [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Kiosk III/IV [Connected]\n", deviceConnectedCount);
        }
    }

    if (_device_is_attached[IDT_DEVICE_KIOSK_III_S]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_KIOSK_III_S;
        if (device_getCurrentDeviceType() == IDT_DEVICE_KIOSK_III_S) {
            printf("\t\t%d.  Kiosk III S [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Kiosk III S [Connected]\n", deviceConnectedCount);
        }
    }

    if (_device_is_attached[IDT_DEVICE_PIP_READER]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_PIP_READER;
        if (device_getCurrentDeviceType() == IDT_DEVICE_PIP_READER) {
            printf("\t\t%d.  Pip Reader [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Pip Reader [Connected]\n", deviceConnectedCount);
        }
    }


    if (_device_is_attached[IDT_DEVICE_VP3300_USB]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_VP3300_USB;
        if (device_getCurrentDeviceType() == IDT_DEVICE_VP3300_USB) {
            printf("\t\t%d.  VP3300 USB [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  VP3300 USB [Connected]\n", deviceConnectedCount);
        }
    }

    if (_device_is_attached[IDT_DEVICE_SREDKEY2_HID]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_SREDKEY2_HID;
        if (device_getCurrentDeviceType() == IDT_DEVICE_SREDKEY2_HID) {
            printf("\t\t%d.  SREDKey 2 HID [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  SREDKey 2 HID [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_SREDKEY2_KB]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_SREDKEY2_KB;
        if (device_getCurrentDeviceType() == IDT_DEVICE_SREDKEY2_KB) {
            printf("\t\t%d.  SREDKey 2 KB [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  SREDKey 2 KB [Connected]\n", deviceConnectedCount);
        }
    }

    if (_device_is_attached[IDT_DEVICE_VP3300_AJ]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_VP3300_AJ;
        if (device_getCurrentDeviceType() == IDT_DEVICE_VP3300_AJ) {
            printf("\t\t%d.  VP3300 Audio Jack [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  VP3300 Audio Jack [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_VP3300_BT]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_VP3300_BT;
        if (device_getCurrentDeviceType() == IDT_DEVICE_VP3300_BT) {
            printf("\t\t%d.  VP3300 Bluetooth [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  VP3300 Bluetooth [Connected]\n", deviceConnectedCount);
        }
    }

    if (_device_is_attached[IDT_DEVICE_UNIPAY_I_V]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_UNIPAY_I_V;
        if (device_getCurrentDeviceType() == IDT_DEVICE_UNIPAY_I_V) {
            printf("\t\t%d.  UniPay I_V [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  UniPay I_V [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_UNIPAY_I_V_TTK]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_UNIPAY_I_V_TTK;
        if (device_getCurrentDeviceType() == IDT_DEVICE_UNIPAY_I_V_TTK) {
            printf("\t\t%d.  UniPay I_V TTK [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  UniPay I_V TTK [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_VP8800]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_VP8800;
        if (device_getCurrentDeviceType() == IDT_DEVICE_VP8800) {
            printf("\t\t%d.  VP8800 [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  VP8800 [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_NEO2]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_NEO2;
        char deviceName[30];
        device_getDeviceName(IDT_DEVICE_NEO2, deviceName, 30);

        if (deviceName[0] == '\0') {
            deviceConnectedCount--;
        } else {
            if (device_getCurrentDeviceType() == IDT_DEVICE_NEO2) {
                printf("\t\t%d.  %s [Connected] [Actived]\n", deviceConnectedCount, deviceName);
            } else {
                printf("\t\t%d.  %s [Connected]\n", deviceConnectedCount, deviceName);
            }
        }
    }
    if (_device_is_attached[IDT_DEVICE_NEO2 + 1]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_NEO2 + 1;
        char deviceName[30];
        device_getDeviceName(IDT_DEVICE_NEO2 + 1, deviceName, 30);
        if (deviceName[0] == '\0') {
            deviceConnectedCount--;
        } else {
            if (device_getCurrentDeviceType() == IDT_DEVICE_NEO2 + 1) {
                printf("\t\t%d.  %s [Connected] [Actived]\n", deviceConnectedCount, deviceName);
            } else {
                printf("\t\t%d.  %s [Connected]\n", deviceConnectedCount, deviceName);
            }
        }
    }
    if (_device_is_attached[IDT_DEVICE_NEO2 + 2]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_NEO2 + 2;
        char deviceName[30];
        device_getDeviceName(IDT_DEVICE_NEO2 + 2, deviceName, 30);
        if (deviceName[0] == '\0') {
            deviceConnectedCount--;
        } else {
            if (device_getCurrentDeviceType() == IDT_DEVICE_NEO2 + 2) {
                printf("\t\t%d.  %s [Connected] [Actived]\n", deviceConnectedCount, deviceName);
            } else {
                printf("\t\t%d.  %s [Connected]\n", deviceConnectedCount, deviceName);
            }
        }
    }
    if (_device_is_attached[IDT_DEVICE_NEO2 + 3]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_NEO2 + 3;
        char deviceName[30];
        device_getDeviceName(IDT_DEVICE_NEO2 + 3, deviceName, 30);
        if (deviceName[0] == '\0') {
            deviceConnectedCount--;
        } else {
            if (device_getCurrentDeviceType() == IDT_DEVICE_NEO2 + 3) {
                printf("\t\t%d.  %s [Connected] [Actived]\n", deviceConnectedCount, deviceName);
            } else {
                printf("\t\t%d.  %s [Connected]\n", deviceConnectedCount, deviceName);
            }
        }
    }
    if (_device_is_attached[IDT_DEVICE_NEO2 + 4]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_NEO2 + 4;
        char deviceName[30];
        device_getDeviceName(IDT_DEVICE_NEO2 + 4, deviceName, 30);
        if (deviceName[0] == '\0') {
            deviceConnectedCount--;
        } else {
            if (device_getCurrentDeviceType() == IDT_DEVICE_NEO2 + 4) {
                printf("\t\t%d.  %s [Connected] [Actived]\n", deviceConnectedCount, deviceName);
            } else {
                printf("\t\t%d.  %s [Connected]\n", deviceConnectedCount, deviceName);
            }
        }
    }
    if (_device_is_attached[IDT_DEVICE_VENDI]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_VENDI;
        if (device_getCurrentDeviceType() == IDT_DEVICE_VENDI) {
            printf("\t\t%d.  Vendi [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Vendi [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_AUGUSTA_HID]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_AUGUSTA_HID;

        if (device_getCurrentDeviceType() == IDT_DEVICE_AUGUSTA_HID) {
            printf("\t\t%d.  Augusta HID [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Augusta HID [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_AUGUSTA_S_HID]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_AUGUSTA_S_HID;
        if (device_getCurrentDeviceType() == IDT_DEVICE_AUGUSTA_S_HID) {
            printf("\t\t%d.  Augusta S HID [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Augusta S HID [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_AUGUSTA_S_TTK_HID]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_AUGUSTA_S_TTK_HID;
        if (device_getCurrentDeviceType() == IDT_DEVICE_AUGUSTA_S_TTK_HID) {
            printf("\t\t%d.  Augusta S TTK HID [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Augusta S TTK HID [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_AUGUSTA_KB]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_AUGUSTA_KB;
        if (device_getCurrentDeviceType() == IDT_DEVICE_AUGUSTA_KB) {
            printf("\t\t%d.  Augusta KB [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  Augusta KB [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_MINISMART_II]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_MINISMART_II;

        if (device_getCurrentDeviceType() == IDT_DEVICE_MINISMART_II) {
            printf("\t\t%d.  MiniSmart II [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  MiniSmart II [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_L80]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_L80;

        if (device_getCurrentDeviceType() == IDT_DEVICE_L80) {
            printf("\t\t%d.  L80 [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  L80 [Connected]\n", deviceConnectedCount);
        }
    }
    if (_device_is_attached[IDT_DEVICE_L100]) {
        deviceConnectedCount++;
        _device_list_menu[deviceConnectedCount] = IDT_DEVICE_L100;

        if (device_getCurrentDeviceType() == IDT_DEVICE_L100) {
            printf("\t\t%d.  L100 [Connected] [Actived]\n", deviceConnectedCount);
        } else {
            printf("\t\t%d.  L100 [Connected]\n", deviceConnectedCount);
        }
    }

    // RS232 Test
    //	deviceConnectedCount++;
    //	_device_list_menu[deviceConnectedCount] = IDT_DEVICE_SPECTRUM_PRO_COM;
    //	printf("\t\t%d.  Spectrum Pro Com\n",deviceConnectedCount);

    if (deviceConnectedCount > 0) {
        printf("\t\t************************************************\n");
    } else {
        printf("\n!!!!!!!!NO Device Attached, please plug in IDTech Device!!!!!!!!\n");
    }
    idtech_display_menu_from_lib.pDisplay_Menu_current = display_usb_menu;
    fflush(stdout);
} /* display_usb_menu */

// void process_exit()
// {
//	device_close();
//
////	printf("Application Exit.\n");
////	fflush(stdout);
// }
