#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
// #include <curl/curl.h>

#include "libIDT_Device.h"
#include "demo_common.h"

#define RESULTS_BUF_LEN 4096

enum MENU {
    MAIN_MENU = 0,
    DEVICE_MENU,
    CTLS_MENU,
    MSR_MENU,
    EMV_MENU,
    LCD_MENU,
    PIN_MENU,
    RESULT_MENU,
    NO_MENU
};

enum DeviceTerminalInfo {
    // const message ID
    MSC_ID_PROCESS_WAIT         = 0x11,
    MSC_ID_WELCOME              = 0x23,
    MSC_ID_AMOUNT               = 0x01,
    MSC_ID_AMOUNT_OTHER         = 0x24,
    MSC_ID_CANCELLED            = 0x21,
    MSC_ID_CANCEL_OR_ENTER      = 0x05,
    MSC_ID_ENTER_AMOUNT         = 0x08,
    MSC_ID_ENTER_AMOUNT_OTHER   = 0x25,
    MSC_ID_ENTER_PIN            = 0x09,
    MSC_ID_SWIPE_OR_INSERT      = 0x0B,
    MSC_ID_TIME_OUT             = 0x19,
    MSC_ID_TERMINATE            = 0x17,
    MSC_ID_USE_CHIP_READER      = 0x0E,
    MSC_ID_APPROVED             = 0x03,
    MSC_ID_TRY_AGAIN            = 0x14,
    MSC_ID_CAPK_HASH_VALUE_FAIL = 0x26,
};

// EXPORT_SYMBOLS int isDeviceTransaction;
int isDeviceTransaction;

static pthread_t threadRunGoOnline     = NULL;
static pthread_t threadRunAuthenticate = NULL;

void
MSR_callBackp(int type, IDTMSRData * cardData);
void
EMV_callBack(int device_type, int device_state, unsigned char * data, int dataLen, IDTTransactionData * cardData,
  EMV_Callback * emvCallback, int transactionResultCode);
void
PIN_callBack(int type, IDTPINData * pinData);
void
processEMVData(IDTTransactionData * cardData);
void
printTransactionData(IDTTransactionData * cardData);
void
emvCompleted();
void
waitCardRemoval();
void
showMessageOnLCD(EMV_Callback * emvCallbackInfo, BYTE language[], BYTE message[]);
void
SetOutputTextLCD(char * text[], int lines);
void
processLCDMenuSelect(EMV_Callback * emvCallbackInfo);
void
InputSelectNum(EMV_Callback * emvCallbackInfo, int itemSelected);
int
waitInputfor(int waitingSeconds);
int
waitInputforPIN(EMV_Callback * emvCallbackInfo, char * strPIN);
int
kbhit(void);

void
printMSRData(IDTMSRData * cardData);
void
printfMSRData(IDTMSRData * cardData); // test
void
printPINData(IDTPINData * pinData);
void
process_exit();
void
display_main_menu();
void
programLoop();
int
EMV_authenticate();
int
EMV_complete();
void *
threadDemoAuthenticate();
void *
threadDemoGoOnline();

void
displayMenu();
void
piscesMainMenu();
void
displayPreviousMenu();
void
piscesDeviceMenu();
void
piscesCTLSMenu();
void
piscesMSRMenu();
void
piscesICCMenu();
void
piscesEMVMenu();
void
piscesLCDMenu();
void
piscesPINMenu();
void
piscesWSMenu();
void
getSDKVersion();
void
showPiscesResults(char * results);
void
genTLVString(char * result, unsigned char * data, int len);

char globalResults[RESULTS_BUF_LEN] = { 0 };

int emvFinished = 1;
char menuItemList[9][256];
int lastLength = 0;
int extMessage = 0;
int isWelcome  = 0;

int mode   = 0;
int * prev = NULL;

/**
 * Tells internal demo which menu to return to after displaying results on results screen
 *
 * 0 = piscesMainMenu
 * 1 = piscesDeviceMenu
 * ...
 */
int currentPiscesMenu  = 0;
int previousPiscesMenu = 0;
int exitDemo = 0;

int
main(void) {
    // CURL *curl;
    // CURLcode res;

    // curl_global_init(CURL_GLOBAL_ALL);

    // curl = curl_easy_init();
    //	enableLogging(2);

    //	if (curl) {
    //		curl_version_info_data *info;
    //
    //		info = curl_version_info(CURLVERSION_NOW);
    //
    //		printf("\n\nversion: %s\n", info->version);
    //		printf("\n\nversion number: %d\n", info->version_num);
    //		printf("\n\nhost: %s\n", info->host);
    //		printf("\n\nssl version: %s\n", info->ssl_version);
    //		printf("\n\nssl version num: %d\n", info->ssl_version_num);
    //		printf("\n\nlib version num: %s\n", info->libz_version);
    //
    //		curl_easy_setopt(curl, CURLOPT_URL, "https://google.com/");
    //
    //		curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1);
    //
    //		curl_easy_setopt(curl, CURLOPT_CAPATH, "/mnt/dataflash/certs");
    //
    //		curl_easy_setopt(curl, CURLOPT_CAINFO, "/mnt/dataflash/certs");
    //
    ////		curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0);
    //
    //		char errbuf[CURL_ERROR_SIZE];
    //
    //		curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf);
    //
    //		errbuf[0] = 0;
    //
    //		res = curl_easy_perform(curl);
    //
    //		curl_easy_cleanup(curl);
    //
    //		printf("\n\ncurl results: %d\n\n", res);
    //
    //		if (res != CURLE_OK)
    //            printf("\n\nerror: %s", errbuf);
    //
    //		return;
    //	}

    int device = IDT_DEVICE_VP8800;

    //	IDT_EnableLogging(0xE0, 0);
    //	IDT_EnableLogging(0x80, 0);

    //	IDT_EnableLogging(0x10, 0);

    if (!device_setCurrentDevice(device)) {
        printf("  Fail to Init VP8800!\n");
        device = IDT_DEVICE_UNKNOWN;
    }

    if (device == IDT_DEVICE_UNKNOWN) {
        return 0;
    }
    ctls_registerCallBkp(MSR_callBackp);
    msr_registerCallBkp(MSR_callBackp);
    emv_registerCallBk(EMV_callBack);
    pin_registerCallBk(PIN_callBack);

    #if 1 // test

    currentPiscesMenu  = NO_MENU;
    previousPiscesMenu = NO_MENU;
    memset(globalResults, 0, _CMD_BUF_LEN);

    emv_setAutoAuthenticateTransaction(1);
    emv_setAutoCompleteTransaction(0);

    emvFinished = 0;
    extMessage  = 0;
    isWelcome   = 0;
    sleep(2);
    int rt = emv_startTransaction(1500.00, 0.00, 2, 1, 120, NULL, 0, 0);

    if (rt != RETURN_CODE_DO_SUCCESS) {
        char errorDescription[_CMD_BUF_LEN] = { 0 };

        device_getIDGStatusCodeString(rt, errorDescription);
        sprintf(globalResults, "Start EMV Transaction Failed. Error Code 0x%02X: %s", rt, errorDescription);
        currentPiscesMenu = RESULT_MENU;
        waitCardRemoval();
    }

    while (globalResults[0] == 0 /*|| (extMessage == 1 && isWelcome == 0)*/) {
        sleep(1);
    }
    sleep(1);

    #else  /* if 1 */

    //	piscesMainMenu();

    currentPiscesMenu  = MAIN_MENU;
    previousPiscesMenu = MAIN_MENU;

//    printf("====================================>in main\n");

    #endif /* if 1 */

    while (!exitDemo) {
        displayMenu();
        //		sleep(1);
    }

    return 0;
} /* main */

void
displayMenu() {
    switch (currentPiscesMenu) {
        case MAIN_MENU:
            piscesMainMenu();

            break;
        case DEVICE_MENU:
            piscesDeviceMenu();

            break;
        case CTLS_MENU:
            piscesCTLSMenu();

            break;
        case MSR_MENU:
            piscesMSRMenu();

            break;
        case EMV_MENU:
            piscesEMVMenu();

            break;
        case LCD_MENU:
            piscesLCDMenu();

            break;
        case PIN_MENU:
            piscesPINMenu();

            break;
        case RESULT_MENU:
            showPiscesResults(globalResults);
            memset(globalResults, 0, RESULTS_BUF_LEN);

            break;
        case NO_MENU:
            //          sleep(1);
            mssleep(300);
            break;
    }
} /* displayMenu */

void
MSR_callBackp(int type, IDTMSRData * cardData) {
    isMSRBusy = 0; // Adding this because this only becomes false after the callback finishes but we need to display UI items
    memset(globalResults, 0, RESULTS_BUF_LEN);

    int i;

    switch (type) {
        case MSR_callBack_type_ERR:
            strcpy(globalResults, "MSR Callback: Card Swipe Cancelled\n");
            break;
        case MSR_callBack_type_RETURN_CODE:
            printfMSRData(cardData);
            printMSRData(cardData);
            break;
        case MSR_callBack_type_CARD_READ_ERR:
            strcpy(globalResults, "MSR Callback: Card Read Error\n");
            break;
        case MSR_callBack_type_TIMEOUT:
            strcpy(globalResults, "MSR Callback: Timeout\n");
            break;
        default:
            break;
    }
}

void
EMV_callBack(int device_type, int device_state, unsigned char * data, int dataLen, IDTTransactionData * cardData,
  EMV_Callback * emvCallback, int transactionResultCode) {
    char strErr[200] = { 0 };

    switch (device_state) {
        case TransactionData:
            memset(globalResults, 0, RESULTS_BUF_LEN);
            processEMVData(cardData);
            break;
        case TransactionFailed:
            memset(strErr, 0, 200);
            device_getResponseCodeString(transactionResultCode, strErr);
            printf("Transaction Failed: %s;\n", strErr);
            fflush(stdout);
            sprintf(globalResults, "Transaction Failed: %s;\n", strErr);
            //		emvCompleted();
            waitCardRemoval(); // test
            emvCompleted();
            break;
        case EMVCallback:
            if (transactionResultCode == RETURN_CODE_EMV_PIN) {
                lcd_customDisplayMode(0);

                // Clear the screen twice due to background redraw issue
                lcd_clearDisplay(0);
                lcd_clearDisplay(0);
                // send PIN command
                pin_getEncryptedOnlinePIN(0, 20);
                emvCompleted();
                //			currentMenu = THANK_MENU;
            } else if (transactionResultCode == RETURN_CODE_EMV_SIGNATURE) {
                lcd_customDisplayMode(0);
                lcd_customDisplayMode(1);

                // Clear the screen twice due to background redraw issue
                lcd_clearDisplay(0);
                lcd_clearDisplay(0);
                // send signature
                lcd_captureSignature(60);
                emvCompleted();
                //			currentMenu = THANK_MENU;
            } else {
                if (emvCallback->callbackType == EMV_CALLBACK_TYPE_LCD) { // LCD Callback Type
                    extMessage = 1;
                    if (emvCallback->lcd_displayMode == EMV_LCD_DISPLAY_MODE_CLEAR_SCREEN) {
                        //					clearDisplay();
                        int i = 0;
                        for (i = 0; i < 256; i++) printf("\b");

                        return;
                    }
                    //				else if (emvCallback->lcd_messageMode == EMV_LCD_DISPLAY_MODE_PAUSE)
                    //				{
                    //					showMessageOnLCD(emvCallback,emvCallback->language, emvCallback->lcd_messages);
                    //					emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PAUSE, 0);
                    //				}
                    else if (emvCallback->lcd_displayMode == EMV_LCD_DISPLAY_MODE_MESSAGE) {
                        if (emvCallback->lcd_messageMode == EMV_LCD_DISPLAY_MESSAGE_MODE_4) {
                            showMessageOnLCD(emvCallback, emvCallback->language, emvCallback->lcd_messages);
                            emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PAUSE, 0);
                        } else {
                            showMessageOnLCD(emvCallback, emvCallback->language, emvCallback->lcd_messages);
                        }
                    } else {
                        // Display message with menu/language or prompt, and return result to emv_callbackResponseLCD
                        // Kernel will not proceed until this step is complete
                        processLCDMenuSelect(emvCallback);
                    }
                } else {
                    if (emv_getAutoCompleteTransaction() == 1) {
                        #if 0
                        // should create another thread to process callback
                        int rc1 = pthread_create(&threadRunGoOnline, NULL, threadDemoGoOnline, NULL);
                        if (rc1 != 0) {
                            //					DoPrintF("create thread, %s: %s\n",__func__, strerror(rc1));
                            return;
                        }
                        //				currentMenu = NO_MENU;
                        pthread_detach(threadRunGoOnline);
                        #endif
                        return;
                    } else {
                        //				emvCompleted();
                        sleep(7);
                        //				currentMenu = MAIN_MENU;
                        emvCompleted();
                    }
                }
            }
            break;
    }
} /* EMV_callBack */

void
showMessageOnLCD(EMV_Callback * emvCallbackInfo, BYTE language[], BYTE message[]) {
    char * messageList[9];
    int lines       = 0;
    int position    = 0;
    char * msg      = (char *) message;
    int lengthMsg   = strlen(msg);
    int currentLine = 0;

    memset(messageList, 0, sizeof(char *) * 9);
    while (position < lengthMsg) {
        byte line = message[position++];
        if (position < lengthMsg) {
            if ((line & 0x80) == 0x80) {
                messageList[lines++] = getDisplayMessage(language, message[position++]);
            } else {
                char tmp[256];
                int pos = 0;
                memset(tmp, 0, 256);

                while (position < lengthMsg && message[position] != 0x1C) {
                    tmp[pos++] = message[position++];
                }
                if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT) {
                    currentLine = lines++;
                    memset(menuItemList[currentLine], 0, 256);
                    sprintf(menuItemList[currentLine], "%d : %s", lines, getLanguageCode(tmp));
                    messageList[currentLine] = menuItemList[currentLine];
                } else if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_MENU) {
                    currentLine = lines++;
                    memset(menuItemList[currentLine], 0, 256);
                    sprintf(menuItemList[currentLine], "%d : %s", lines, tmp);
                    messageList[currentLine] = menuItemList[currentLine];
                } else {
                    messageList[lines++] = tmp;
                }
            }
            position++;
            //	if (position < lengthMsg)
            //		sb.AppendLine();
        }
    }

    int i;
    int exist = 0;
    for (i = 0; i < 9; i++) {
        if (messageList[i] != NULL)
            exist = 1;
    }

    if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT) {
        if (exist) {
            printf("----Select Language----\n");
            SetOutputTextLCD(messageList, lines);
        }
    } else if (emvCallbackInfo->lcd_displayMode == EMV_LCD_DISPLAY_MODE_MENU) {
        if (exist) {
            printf("----Select App----\n");
            SetOutputTextLCD(messageList, lines);
        }
    } else {
        if (exist) {
            SetOutputTextLCD(messageList, lines);
        }
    }
    fflush(stdout);
} /* showMessageOnLCD */

void
SetOutputTextLCD(char * text[], int lines) {
    // InvokeRequired required compares the thread ID of the
    // calling thread to the thread ID of the creating thread.
    // If these threads are different, it returns 1.

    int i = 0;
    int backLength = 0;

    if (lines == 1) {
        if (lastLength > 0) {
            for (i = 0; i < lastLength; i++) {
                printf(" ");
            }
            for (i = 0; i != lastLength; i++) {
                putchar('\b');
            }
            fflush(stdout);
        }
        putchar('[');
        printf(text[0]);
        putchar(']');

        if (!strncmp(text[0], "WELCOME", 7)) {
            isWelcome = 1;
        }
        backLength = strlen(text[0]);
        for (i = 0; i != backLength + 2; ++i) {
            putchar('\b');
        }
        fflush(stdout);
        lastLength = backLength + 3;
    } else {
        for (i = 0; i < lines; i++) {
            if (!strncmp(text[i], "WELCOME", 7)) {
                isWelcome = 1;
            }
            printf(text[i]);
            printf("\n");
        }
    }
    fflush(stdout);

    if (isWelcome == 1) {
        //		sleep(1);
        emvCompleted();
    }
} /* SetOutputTextLCD */

void
processLCDMenuSelect(EMV_Callback * emvCallbackInfo) {
    int timeWaitingInput = 30;
    int selected         = 0;

    switch (emvCallbackInfo->callbackType) {
        case EMV_CALLBACK_TYPE_LCD:
            switch (emvCallbackInfo->lcd_displayMode) {
                case EMV_LCD_DISPLAY_MODE_CANCEL:
                    // skip

                    break;
                case EMV_LCD_DISPLAY_MODE_MENU:
                    // LCD control should be changed to select the menu
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    selected = waitInputfor(timeWaitingInput);
                    printf("%d selected\n", selected);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_PROMPT:
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    selected = waitInputfor(timeWaitingInput);
                    printf("%d selected\n", selected);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_MESSAGE:
                    break;
                case EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT:
                    // LCD control should be changed to select the menu
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    selected = waitInputfor(timeWaitingInput);
                    printf("%d selected\n", selected);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_PAUSE:
                    showMessageOnLCD(emvCallbackInfo, emvCallbackInfo->language, emvCallbackInfo->lcd_messages);
                    InputSelectNum(emvCallbackInfo, selected);
                    break;
                case EMV_LCD_DISPLAY_MODE_CLEAR_SCREEN:
                    break;
            }
            fflush(stdout);
            break;
        case EMV_CALLBACK_TYPE_PINPAD:
            InputSelectNum(emvCallbackInfo, selected);
            break;
    }
} /* processLCDMenuSelect */

void
InputSelectNum(EMV_Callback * emvCallbackInfo, int itemSelected) {
    char * messagePINPad;

    if (emvCallbackInfo == null) {
        return;
    }

    switch (emvCallbackInfo->callbackType) {
        case EMV_CALLBACK_TYPE_LCD:
            switch (emvCallbackInfo->lcd_displayMode) {
                case EMV_LCD_DISPLAY_MODE_MENU:
                    emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_MENU, itemSelected);
                    break;
                case EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT:
                    // LCD control should be changed to select the menu
                    emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_LANGUAGE_SELECT, itemSelected);
                    break;
                case EMV_LCD_DISPLAY_MODE_PROMPT:
                    // LCD control should be changed to select the menu
                    if (itemSelected == 0) {
                        emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PROMPT, 0x43);
                    } else {
                        emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PROMPT, 0x45);
                    }
                    break;
                case EMV_LCD_DISPLAY_MODE_PAUSE:
                    emv_callbackResponseLCD(EMV_LCD_DISPLAY_MODE_PAUSE, itemSelected);
                    break;
            }
            break;

        case EMV_CALLBACK_TYPE_PINPAD:
            switch (emvCallbackInfo->pin_pinMode) {
                case EMV_PIN_MODE_CANCEL:
                    break;
                case EMV_PIN_MODE_ONLINE_DUKPT:
                case EMV_PIN_MODE_ONLINE_MKSK:
                case EMV_PIN_MODE_OFFLINE:
                    // Show the PIN * in the LCD
                    messagePINPad = getDisplayMessageByID(MSC_ID_ENTER_PIN);
                    SetOutputTextLCD(&messagePINPad, 1);
                    printf("\n");

                    char strPIN[50] = { 0 };
                    int ret         = waitInputforPIN(emvCallbackInfo, strPIN); // if ret == 1 timeout
                    //					printf("%d selected\n", selected);
                    emv_callbackResponsePIN(emvCallbackInfo, strPIN);

                    break;
            }
            break;
    }
} /* InputSelectNum */

int
waitInputfor(int waitingSeconds) {
    clock_t t0, dt;

    //	int flag;

    t0 = clock();
    //	flag = 1;
    printf("Please input your selection:\n");
    fflush(stdout);
    mode = 0;
    prev = NULL;
    //	while( !kbhit() ) {
    while (!kbhit() ) {
        dt = clock() - t0;
        if (dt >= waitingSeconds * CLOCKS_PER_SEC) {
            //			 flag =0;
            printf("Timeout, (%d S) !\n", waitingSeconds);
            printf("Default to first selection\n");
            fflush(stdout);
            return 1;
        }
    }
    //	scanf("%d",&x); printf("Selected item: %d\n",x);
    //	return x;

    char buffer[50];
    char * str = fgets(buffer, sizeof(buffer), stdin);
    if (str != NULL) {
        char * end;
        long num = strtol(str, &end, 10);
        if (str != end)
            return (int) num;
    } else {
        return 1;
    }

    return 1;
} /* waitInputfor */

int
waitInputforPIN(EMV_Callback * emvCallbackInfo, char * strPIN) {
    clock_t t0, dt;

    //	int flag;

    t0 = clock();
    //	flag = 1;
    //	printf("Please input your selection:\n");
    fflush(stdout);
    int iPrev = 0;
    mode = 1;
    prev = &iPrev;
    //	while( !kbhit_nonempty(&prev) ) {
    while (!kbhit() ) {
        dt = clock() - t0;
        if (dt >= emvCallbackInfo->pin_entryStartTimeout * CLOCKS_PER_SEC) {
            //			 flag =0;
            printf("Timeout, (%d S) !\n", emvCallbackInfo->pin_entryStartTimeout);
            //			 printf("Default to first selection\n");
            fflush(stdout);
            return 1;
        }
    }
    //	scanf("%d",&x); printf("Selected item: %d\n",x);
    //	return x;

    char buffer[50];
    char * str = fgets(buffer, sizeof(buffer), stdin);
    if (str != NULL) {
        int i;
        for (i = 0; i < 50; i++) {
            if (str[i] == '\r' || str[i] == '\n') {
                str[i] = '\0';
                break;
            }
        }
        strcpy(strPIN, str);
        return 0;
        //		char *end;
        //		long num = strtol(str, &end, 10);
        //		if (str != end)
        //			return;
    } else {
        return 1;
    }

    //	return;
} /* waitInputforPIN */

int
kbhit(void) {
    //	struct termios oldt, newt;
    //	int ch;
    //	int oldf;
    //	tcgetattr(STDIN_FILENO, &oldt);
    //	newt = oldt;
    //	newt.c_lflag &= ~(ICANON | ECHO);
    //	tcsetattr(STDIN_FILENO, TCSANOW, &newt);
    //	oldf = fcntl(STDIN_FILENO, F_GETFL, 0);
    //	fcntl(STDIN_FILENO, F_SETFL, oldf | O_NONBLOCK);
    //	ch = getchar();
    //	tcsetattr(STDIN_FILENO, TCSANOW, &oldt);
    //	fcntl(STDIN_FILENO, F_SETFL, oldf);
    //	if (mode == 0)
    //	{
    //		if(ch != EOF)
    //		{
    //			ungetc(ch, stdin);
    //			return 1;
    //		}
    //		return 0;
    //	}
    //	else
    //	{
    //		if(ch != EOF)
    //		{
    //			if (ch == 0x0A || ch == 0x0D)
    //			{
    //				if (*prev == 0x0A || *prev == 0x0D || *prev == 0)
    //				{
    //					*prev = ch;
    //					return 0;
    //				}
    //				else
    //				{
    //					*prev = ch;
    //					ungetc(ch, stdin);
    //					return 1;
    //				}
    //			}
    //			else
    //			{
    //				*prev = ch;
    //				ungetc(ch, stdin);
    //				return 1;
    //			}
    //		}
    //		*prev = ch;
    //		return 0;
    //	}
    return 0;
} /* kbhit */

// void EMV_callBack(int device_type, int device_state, unsigned char * data, int dataLen, IDTTransactionData* cardData, EMV_Callback* emvCallback, int transactionResultCode){
//	memset(globalResults, 0, _CMD_BUF_LEN);
//	char strErr[200] = {0};
//	switch(device_state)
//	{
//	case TransactionData:
//		processEMVData(cardData);
//		break;
//	case TransactionFailed:
//		memset(strErr,0,200);
//		device_getResponseCodeString(transactionResultCode, strErr);
//		printf("Transaction Failed: %s;\n",strErr);
//		fflush(stdout);
//		sprintf(globalResults, "Transaction Failed: %s;\n",strErr);
//		waitCardRemoval(); //test
//		emvCompleted();
//		break;
//	case EMVCallback:
//		if (transactionResultCode == RETURN_CODE_EMV_PIN)
//		{
//			lcd_customDisplayMode(0);
//
//			// Clear the screen twice due to background redraw issue
//			lcd_clearDisplay();
//			lcd_clearDisplay();
//			//send PIN command
//			pin_getEncryptedOnlinePIN(0, 20);
//			emvCompleted();
//		}
//		else if (transactionResultCode == RETURN_CODE_EMV_SIGNATURE)
//		{
//			lcd_customDisplayMode(0);
//			lcd_customDisplayMode(1);
//
//			// Clear the screen twice due to background redraw issue
//			lcd_clearDisplay();
//			lcd_clearDisplay();
//			//send signature
//			lcd_captureSignature(60);
//			emvCompleted();
//		}
//		else
//		{
//			if(emv_getAutoCompleteTransaction()==1)
//			{
//				return;
//			}
//			else
//			{
//				sleep(7);
//				emvCompleted();
//			}
//		}
//		break;
//	}
// }

void
PIN_callBack(int type, IDTPINData * pinData) {
    memset(globalResults, 0, RESULTS_BUF_LEN);
    switch (type) {
        case PIN_callBack_type_ERR:
            sprintf(globalResults, "%s\nCallback PIN cancelled\n", globalResults);
            break;
        case PIN_callBack_type_RETURN_CODE:
            printPINData(pinData);
            break;
        case PIN_callBack_type_TIMEOUT:
            sprintf(globalResults, "%s\nPIN Callback Timeout\n", globalResults);
            break;
        default:
            break;
    }
    fflush(stdout);
}

void
printPINData(IDTPINData * pinData) {
    strcpy(globalResults, "Capture PIN Successful\n");
    sprintf(globalResults, "%sCaptured Initial Vector: ", globalResults);
    if (pinData->InitVectorLen > 0) {
        strcat(globalResults, getData(pinData->InitVector, pinData->InitVectorLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sCaptured KSN: ", globalResults);
    if (pinData->KSNLen > 0) {
        strcat(globalResults, getData(pinData->KSN, pinData->KSNLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sCaptured Encrypted PAN: ", globalResults);
    if (pinData->PANLen > 0) {
        strcat(globalResults, getData(pinData->PAN, pinData->PANLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sCaptured Encrypted Expiry: ", globalResults);
    if (pinData->ExpiryDateLen > 0) {
        strcat(globalResults, getData(pinData->ExpiryDate, pinData->ExpiryDateLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sCaptured Encrypted CSC: ", globalResults);
    if (pinData->CSCLen > 0) {
        strcat(globalResults, getData(pinData->CSC, pinData->CSCLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sPAN First Digits: ", globalResults);
    if (pinData->FirstPANDigitsLen > 0) {
        strcat(globalResults, getData(pinData->FirstPANDigits, pinData->FirstPANDigitsLen, 1));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sPAN Last Digits: ", globalResults);
    if (pinData->LastPANDigitsLen > 0) {
        strcat(globalResults, getData(pinData->LastPANDigits, pinData->LastPANDigitsLen, 1));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sCaptured MAC: ", globalResults);
    if (pinData->MACValueLen > 0) {
        strcat(globalResults, getData(pinData->MACValue, pinData->MACValueLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    sprintf(globalResults, "%sCaptured MAC KSN: ", globalResults);
    if (pinData->MACKSNLen > 0) {
        strcat(globalResults, getData(pinData->MACKSN, pinData->MACKSNLen, 0));
    } else {
        sprintf(globalResults, "%sNone\n", globalResults);
    }
    if (pinData->MACStatus & 0x02 == 0x02) {
        sprintf(globalResults, "%sEncryption Type: TDES\n", globalResults);
    } else {
        sprintf(globalResults, "%sEncryption Type: AES\n", globalResults);
    }
    printf("globalResults %s", globalResults);
} /* printPINData */

void
emvCompleted() {
    printf("=== EMV completed=== \n");
    fflush(stdout);
    emvFinished = 1;
    //	displayPreviousMenu();

    if (strlen(globalResults) > 0) {
        currentPiscesMenu = RESULT_MENU;

        //		showPiscesResults(globalResults);
        //		memset(globalResults, 0, RESULTS_BUF_LEN);
    }
}

void
waitCardRemoval() {
    int rt    = -1;
    int times = 0;

    while (rt != 0 && times < 10) {
        rt = device_enablePassThrough(1);
        mssleep(100);
        times++;
    }

    BYTE data[] = { 0x00, 0x01, 0x02, 0x00, 0x04, 0x00, 0x20, 0x00, 0x00, 0x00 };

    times = 0;
    rt    = -1;

    while (rt != 0x0B || times >= 5) {
        rt = device_enhancedPassthrough(data, 10);
        if (rt == 0x08) {
            break;
        } else {
            mssleep(100);
        }
        times++;
    }
    device_enablePassThrough(0);
}

// void processEMVData(IDTTransactionData* cardData){
//	sprintf(globalResults, "EMV Result Code %04X\n",cardData->emv_resultCode);
//	if (cardData->emv_resultCode == EMV_RESULT_CODE_FALLBACK_TO_MSR)
//		printTransactionData(cardData);
//	else if (cardData->emv_resultCode == EMV_RESULT_CODE_SWIPE_NON_ICC)
//		printTransactionData(cardData);
//	else
//	{
//		char tempTLVString[_CMD_BUF_LEN] = { 0 };
//
//		strcat(globalResults, "\nUnencrypted Tags\n");
//		getTLVString(cardData->emv_unencryptedTags, cardData->emv_unencryptedTagsLen, tempTLVString);
//		strcat(globalResults, tempTLVString);
//		memset(tempTLVString, 0, _CMD_BUF_LEN);
//
//		strcat(globalResults, "\nEncrypted Tags\n");
//		getTLVString(cardData->emv_encryptedTags, cardData->emv_encryptedTagsLen, tempTLVString);
//		strcat(globalResults, tempTLVString);
//		memset(tempTLVString, 0, _CMD_BUF_LEN);
//
//		strcat(globalResults, "\nMasked Tags\n");
//		getTLVString(cardData->emv_maskedTags, cardData->emv_maskedTagsLen, tempTLVString);
//		strcat(globalResults, tempTLVString);
//		memset(tempTLVString, 0, _CMD_BUF_LEN);
//	}
//
//	switch(cardData->emv_resultCode)
//	{
//		case EMV_RESULT_CODE_APPROVED_OFFLINE:
//			strcat(globalResults, "EMV_RESULT_CODE_APPROVED_OFFLINE\n");
//			emvCompleted();
//		break;
//		case EMV_RESULT_CODE_DECLINED_OFFLINE:
//			strcat(globalResults, "EMV_RESULT_CODE_DECLINED_OFFLINE\n");
//			emvCompleted();
//		break;
//		case    EMV_RESULT_CODE_APPROVED:
//			strcat(globalResults, "EMV_RESULT_CODE_APPROVED\n");
//			emvCompleted();
//		break;
//		case EMV_RESULT_CODE_DECLINED:
//			strcat(globalResults, "EMV_RESULT_CODE_DECLINED\n");
//			emvCompleted();
//		break;
//		case EMV_RESULT_CODE_GO_ONLINE:
//			strcat(globalResults, "EMV_RESULT_CODE_GO_ONLINE\n");
//
//			if(auto_emv_complete==1)
//			{
//				//should create another thread to process callback
//				int rc1 = pthread_create(&threadRunGoOnline, NULL, threadDemoGoOnline, NULL);
//				if(rc1 != 0){
//					DoPrintF("create thread, %s: %s\n",__func__, strerror(rc1));
//				}
//				pthread_detach(threadRunGoOnline);
//				return;
//			}
//			else
//			{
//				emvCompleted();
//			}
//
//		break;
//		case     EMV_RESULT_CODE_CALL_YOUR_BANK:
//			strcat(globalResults, "EMV_RESULT_CODE_CALL_YOUR_BANK\n");
//		break;
//		case     EMV_RESULT_CODE_NOT_ACCEPTED:
//			strcat(globalResults, "EMV_RESULT_CODE_NOT_ACCEPTED\n");
//			emvCompleted();
//		break;
//		case    EMV_RESULT_CODE_FALLBACK_TO_MSR:
//			strcat(globalResults, "EMV_RESULT_CODE_FALLBACK_TO_MSR\n");
//			emvCompleted();
//		break;
//		case     EMV_RESULT_CODE_TIMEOUT:
//			strcat(globalResults, "EMV_RESULT_CODE_TIMEOUT\n");
//			emvCompleted();
//		break;
//		case     EMV_RESULT_CODE_GO_ONLINE_CTLS:
//			strcat(globalResults, "EMV_RESULT_CODE_GO_ONLINE_CTLS\n");
//			emvCompleted();
//		break;
//		case     EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION:
//			strcat(globalResults, "EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION\n");
//			if(auto_emv_authenticate==1)
//			{
//				//should create another thread to process callback
//				int rc1 = pthread_create(&threadRunAuthenticate, NULL, threadDemoAuthenticate, NULL);
//				if(rc1 != 0){
//					DoPrintF("create thread, %s: %s\n",__func__, strerror(rc1));
//				}
//				pthread_detach(threadRunAuthenticate);
//				return;
//			}
//			else
//			{
//				emvCompleted();
//			}
//		//				if(auto_emv_authenticate==0)
//		//					emvCompleted();
//		break;
//		case     EMV_RESULT_CODE_TRANSACTION_CANCELED:
//			strcat(globalResults, "EMV_RESULT_CODE_TRANSACTION_CANCELED\n");
//			emvCompleted();
//		break;
//		case  EMV_RESULT_CODE_SWIPE_NON_ICC:
//			strcat(globalResults, "EMV_RESULT_CODE_SWIPE_NON_ICC\n");
//			emvCompleted();
//		break;
//		case     EMV_RESULT_CODE_CTLS_TWO_CARDS:
//			strcat(globalResults, "EMV_RESULT_CODE_CTLS_TWO_CARDS\n");
//			emvCompleted();
//		break;
//		case     EMV_RESULT_CODE_CTLS_TERMINATE:
//			strcat(globalResults, "EMV_RESULT_CODE_CTLS_TERMINATE\n");
//			emvCompleted();
//		break;
//		case EMV_RESULT_CODE_CARD_COM_ERROR:
//			strcat(globalResults, "EMV_RESULT_CODE_CARD_COM_ERROR\n");
//			emvCompleted();
//			break;
//		default:
//			sprintf(globalResults, "%sEMV_RESULT_CODE: 0x%04X\n", globalResults, cardData->emv_resultCode);
//			emvCompleted();
//			break;
//	}
//
//	fflush(stdout);
// }

void
processEMVData(IDTTransactionData * cardData) {
    sprintf(globalResults, "EMV Result Code %04X\n", cardData->emv_resultCode);
    if (cardData->emv_resultCode == EMV_RESULT_CODE_FALLBACK_TO_MSR) {
        printTransactionData(cardData);
    } else if (cardData->emv_resultCode == EMV_RESULT_CODE_SWIPE_NON_ICC) {
        printTransactionData(cardData);
    } else {
        char tempTLVString[_CMD_BUF_LEN * 2] = { 0 };

        strcat(globalResults, "\nUnencrypted Tags\n");
        getTLVString(cardData->emv_unencryptedTags, cardData->emv_unencryptedTagsLen, tempTLVString);
        strcat(globalResults, tempTLVString);
        memset(tempTLVString, 0, _CMD_BUF_LEN);
        strcat(globalResults, "\nEncrypted Tags\n");
        getTLVString(cardData->emv_encryptedTags, cardData->emv_encryptedTagsLen, tempTLVString);
        strcat(globalResults, tempTLVString);
        memset(tempTLVString, 0, _CMD_BUF_LEN);
        strcat(globalResults, "\nMasked Tags\n");
        getTLVString(cardData->emv_maskedTags, cardData->emv_maskedTagsLen, tempTLVString);
        strcat(globalResults, tempTLVString);
        memset(tempTLVString, 0, _CMD_BUF_LEN);
    }
    //	printf("==================================>cardData->emv_resultCode %d\n", cardData->emv_resultCode);
    switch (cardData->emv_resultCode) {
        case EMV_RESULT_CODE_APPROVED_OFFLINE:
            strcat(globalResults, "EMV_RESULT_CODE_APPROVED_OFFLINE\n");

            //			emvCompleted();
            //			mssleep(1500);

            //			lcd_clearDisplay(0);
            //			lcd_displayText(0, 130, 0, 0, 1, 9, 0, "Approved", NULL);

            sleep(7);
            #if 1
            if (extMessage == 1) {
                return;
                // wait for Welcome
                //				while (isWelcome == 0)
                //				{
                //					sleep(1);
                //				}
            } else {
                // wait for card removal
                waitCardRemoval();
            }
            #endif /* if 1 */

            //			currentMenu = THANK_MENU;
            //			printf("==================================>EMV_RESULT_CODE_APPROVED_OFFLINE before emvCompleted\n");
            emvCompleted();
            break;
        case EMV_RESULT_CODE_DECLINED_OFFLINE:
            strcat(globalResults, "EMV_RESULT_CODE_DECLINED_OFFLINE\n");

            sleep(7);
            #if 1
            if (extMessage == 1) {
                return;
                // wait for Welcome
                //				while (isWelcome == 0)
                //				{
                //					sleep(1);
                //				}
            } else {
                // wait for card removal
                waitCardRemoval();
            }
            #endif /* if 1 */

            //			currentMenu = THANK_MENU;
            emvCompleted();


            //			mssleep(1500);
            //			lcd_clearDisplay(0);
            //			lcd_displayText(0, 130, 0, 0, 1, 9, 0, "Declined", NULL);
            //			sleep(1);
            //			//wait for card removal
            //			waitCardRemoval();
            ////			currentMenu = MAIN_MENU;
            //			emvCompleted();
            break;
        case    EMV_RESULT_CODE_APPROVED:
            strcat(globalResults, "EMV_RESULT_CODE_APPROVED\n");

            sleep(7);
            #if 1
            if (extMessage == 1) {
                return;
                // wait for Welcome
                //				while (isWelcome == 0)
                //				{
                //					sleep(1);
                //				}
            } else {
                // wait for card removal
                waitCardRemoval();
            }
            #endif /* if 1 */

            //			currentMenu = THANK_MENU;
            emvCompleted();


            //			mssleep(1500);
            //			lcd_clearDisplay(0);
            //			lcd_displayText(0, 130, 0, 0, 1, 9, 0, "Approved", NULL);
            //			sleep(1);
            //			//wait for card removal
            //			waitCardRemoval();
            ////			currentMenu = THANK_MENU;
            //			emvCompleted();
            break;
        case EMV_RESULT_CODE_DECLINED:
            strcat(globalResults, "EMV_RESULT_CODE_DECLINED\n");

            sleep(7);
            #if 1
            if (extMessage == 1) {
                return;
                // wait for Welcome
                //				while (isWelcome == 0)
                //				{
                //					sleep(1);
                //				}
            } else {
                // wait for card removal
                waitCardRemoval();
            }
            #endif /* if 1 */

            //			currentMenu = THANK_MENU;
            emvCompleted();


            //			mssleep(1500);
            //			lcd_clearDisplay(0);
            //			lcd_displayText(0, 130, 0, 0, 1, 9, 0, "Declined", NULL);
            //			sleep(1);
            //			//wait for card removal
            //			waitCardRemoval();
            ////			currentMenu = MAIN_MENU;
            //			emvCompleted();
            break;
        case EMV_RESULT_CODE_GO_ONLINE:
            strcat(globalResults, "EMV_RESULT_CODE_GO_ONLINE\n");

            //			printf("==================================>%s\n", globalResults);

            //			printf("==================================>EMV_RESULT_CODE_GO_ONLINE emv_getAutoCompleteTransaction() %d\n", emv_getAutoCompleteTransaction());
            if (emv_getAutoCompleteTransaction() == 1) {
                #if 0
                threadRunGoOnline = NULL;

                // should create another thread to process callback
                int rc1 = pthread_create(&threadRunGoOnline, NULL, threadDemoGoOnline, NULL);
                if (rc1 != 0) {
                    //					DoPrintF("create thread, %s: %s\n",__func__, strerror(rc1));
                    return;
                }
                //				currentMenu = NO_MENU;

                pthread_detach(threadRunGoOnline);
                return;

                #else  /* if 0 */

                //				threadDemoGoOnline();
                return;

                #endif /* if 0 */
            } else {
                //				printf("==================================>before sleep(3)\n");
                //				sleep(7);
                //				currentMenu = MAIN_MENU;
                //				printf("==================================>EMV_RESULT_CODE_GO_ONLINE before emvCompleted\n");
                //				sleep(2);
                emvCompleted();
            }

            break;
        case     EMV_RESULT_CODE_CALL_YOUR_BANK:
            strcat(globalResults, "EMV_RESULT_CODE_CALL_YOUR_BANK\n");
            //			piscesMainMenu();
            //			emvCompleted();
            // wait for card removal
            waitCardRemoval();
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case     EMV_RESULT_CODE_NOT_ACCEPTED:
            strcat(globalResults, "EMV_RESULT_CODE_NOT_ACCEPTED\n");
            //			emvCompleted();
            // wait for card removal
            waitCardRemoval();
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case    EMV_RESULT_CODE_FALLBACK_TO_MSR:
            strcat(globalResults, "EMV_RESULT_CODE_FALLBACK_TO_MSR\n");
            //			emvCompleted();
            sleep(7);
            //			currentMenu = NO_MENU;
            emvCompleted();
            break;
        case     EMV_RESULT_CODE_TIMEOUT:
            strcat(globalResults, "EMV_RESULT_CODE_TIMEOUT\n");
            //			emvCompleted();
            sleep(7);
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case     EMV_RESULT_CODE_GO_ONLINE_CTLS:
            strcat(globalResults, "EMV_RESULT_CODE_GO_ONLINE_CTLS\n");
            //			emvCompleted();
            sleep(7);
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case     EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION:
            strcat(globalResults, "EMV_RESULT_CODE_AUTHENTICATE_TRANSACTION\n");
            if (emv_getAutoAuthenticateTransaction() == 1) {
                // should create another thread to process callback
                int rc1 = pthread_create(&threadRunAuthenticate, NULL, threadDemoAuthenticate, NULL);
                if (rc1 != 0) {
                    DoPrintF("create thread, %s: %s\n", __func__, strerror(rc1));
                }
                //				currentMenu = NO_MENU;
                pthread_detach(threadRunAuthenticate);
                return;
            } else {
                //				emvCompleted();
                sleep(7);
                //				currentMenu = MAIN_MENU;
                emvCompleted();
            }
            break;
        case     EMV_RESULT_CODE_TRANSACTION_CANCELED:
            strcat(globalResults, "EMV_RESULT_CODE_TRANSACTION_CANCELED\n");
            //			emvCompleted();
            // wait for card removal
            waitCardRemoval();
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case  EMV_RESULT_CODE_SWIPE_NON_ICC:
            strcat(globalResults, "EMV_RESULT_CODE_SWIPE_NON_ICC\n");
            //			emvCompleted();
            sleep(7);
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case     EMV_RESULT_CODE_CTLS_TWO_CARDS:
            strcat(globalResults, "EMV_RESULT_CODE_CTLS_TWO_CARDS\n");
            //			emvCompleted();
            sleep(7);
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case     EMV_RESULT_CODE_CTLS_TERMINATE:
            strcat(globalResults, "EMV_RESULT_CODE_CTLS_TERMINATE\n");
            //			emvCompleted();
            // wait for card removal
            waitCardRemoval();
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        case EMV_RESULT_CODE_CARD_COM_ERROR:
            strcat(globalResults, "EMV_RESULT_CODE_CARD_COM_ERROR\n");
            //			emvCompleted();
            // wait for card removal
            waitCardRemoval();
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
        default:
            sprintf(globalResults, "%sEMV_RESULT_CODE: 0x%04X\n", globalResults, cardData->emv_resultCode);
            //			emvCompleted();
            sleep(7);
            //			currentMenu = MAIN_MENU;
            emvCompleted();
            break;
    }

    fflush(stdout);
} /* processEMVData */

void
printTransactionData(IDTTransactionData * cardData) {
    sprintf(globalResults, "%scardType: %02X\n", globalResults, cardData->msr_cardType);
    sprintf(globalResults, "cardData Len: %d\ncardData:\n", globalResults, cardData->msr_rawDataLen);
    strcat(globalResults, getData(cardData->msr_rawData, cardData->msr_rawDataLen, 0));

    strcat(globalResults, "Track1:\n");
    strcat(globalResults, getData((BYTE *) cardData->msr_track1, cardData->msr_track1Length, 1));

    strcat(globalResults, "Track2:\n");
    strcat(globalResults, getData((BYTE *) cardData->msr_track2, cardData->msr_track2Length, 1));

    strcat(globalResults, "Track3:\n");
    strcat(globalResults, getData((BYTE *) cardData->msr_track3, cardData->msr_track3Length, 1));

    if (cardData->msr_encTrack1Len + cardData->msr_encTrack2Len + cardData->msr_encTrack3Len > 0) {
        if (cardData->msr_captureEncryptType == CAPTURE_ENCRYPT_TYPE_AES) {
            strcat(globalResults, "captureEncryptType: AES\n");
        } else {
            strcat(globalResults, "captureEncryptType: TDES\n");
        }
        if (cardData->msr_isDataVariant) {
            strcat(globalResults, "Key Type: Data Variant\n");
        } else {
            strcat(globalResults, "Key Type: PIN Variant\n");
        }
    }

    sprintf(globalResults, "%siccPresent: %02X\n", globalResults, cardData->iccPresent);

    // encrypted data
    strcat(globalResults, "encTrack1:\n");
    strcat(globalResults, getData(cardData->msr_encTrack1, cardData->msr_encTrack1Len, 0));

    strcat(globalResults, "encTrack2:\n");
    strcat(globalResults, getData(cardData->msr_encTrack2, cardData->msr_encTrack2Len, 0));

    strcat(globalResults, "encTrack3:\n");
    strcat(globalResults, getData(cardData->msr_encTrack3, cardData->msr_encTrack3Len, 0));

    strcat(globalResults, "Track 1 hash:\n");
    strcat(globalResults, getData(cardData->msr_hashTrack1, cardData->msr_hashTrack1Len, 0));

    strcat(globalResults, "Track 2 hash:\n");
    strcat(globalResults, getData(cardData->msr_hashTrack2, cardData->msr_hashTrack2Len, 0));

    strcat(globalResults, "Track 3 hash:\n");
    strcat(globalResults, getData(cardData->msr_hashTrack3, cardData->msr_hashTrack3Len, 0));

    strcat(globalResults, "KSN:\n");
    strcat(globalResults, getData(cardData->msr_KSN, cardData->msr_KSNLen, 0));

    strcat(globalResults, "\n");
} /* printTransactionData */

void *
threadDemoAuthenticate() {
    int r = 0;

    strcat(globalResults, "AUTHENTICATE PROCESSING;\n");

    fflush(stdout);
    r = EMV_authenticate();
    if (r != RETURN_CODE_DO_SUCCESS) {
        strcat(globalResults, ">>Authenticate EMV Trans failed!.");
        fflush(stdout);
        return 0;
    }
}

void *
threadDemoGoOnline() {
    int r = 0;

    strcat(globalResults, "GO ONLINE PROCESSING;\n");
    r = EMV_complete();
    if (r != RETURN_CODE_DO_SUCCESS) {
        char strErr[200] = { 0 };
        memset(strErr, 0, 200);
        device_getIDGStatusCodeString(r, strErr);
        sprintf(globalResults, "%sComplete EMV Transaction Failed. Error Code 0x%02x: %s", globalResults, r, strErr);
        fflush(stdout);

        if (r == RETURN_CODE_P2_DECLINED) {
            emvCompleted();

            if (isDeviceTransaction == 1) {
                isDeviceTransaction = 0;
            }
        }

        return 0;
    }
}

int
EMV_authenticate() {
    fflush(stdout);
    int r = emv_authenticateTransaction(NULL, 0);
    if (r != RETURN_CODE_DO_SUCCESS) {
        strcat(globalResults, "  Do authenticateTransaction(), failed!\n");
        // showErrInfo(r);
    } else {
        strcat(globalResults, " authenticate  OK.\n");
    }
    fflush(stdout);
    return r;
}

int
EMV_complete() {
    fflush(stdout);
    unsigned char data1[20];
    int dataLen1 = 20;
    unsigned char data2[20];
    int dataLen2 = 20;

    const char * str1 = "30 30";
    int r = convertHStrIntoHex(str1, data1, &dataLen1);
    const char * str2 = "11 11 33 44 55 66 77 88 30 30";
    r = convertHStrIntoHex(str2, data2, &dataLen2);
    r = emv_completeTransaction(0, data1, dataLen1, data2, dataLen2, NULL, 0, NULL, 0);
    if (r != RETURN_CODE_DO_SUCCESS) {
        strcat(globalResults, "  Do completeTransaction(), failed!\n");
        // showErrInfo(r);
    } else {
        strcat(globalResults, " apply host  OK.\n");
    }
    fflush(stdout);
    return r;
}

void
printMSRData(IDTMSRData * cardData) {
    sprintf(globalResults, "%scardType: %02X\n", globalResults, cardData->cardType);
    sprintf(globalResults, "%scardData Len: %d\ncardData:\n", globalResults, cardData->cardDataLen);
    strcat(globalResults, getData(cardData->cardData, cardData->cardDataLen, 0));

    strcat(globalResults, "Track1:\n");
    strcat(globalResults, getData((BYTE *) cardData->track1, cardData->track1Length, 1));

    strcat(globalResults, "Track2:\n");
    strcat(globalResults, getData((BYTE *) cardData->track2, cardData->track2Length, 1));

    strcat(globalResults, "Track3:\n");
    strcat(globalResults, getData((BYTE *) cardData->track3, cardData->track3Length, 1));

    if (CAPTURE_ENCODE_TYPE_ISOABA == cardData->cardType) {
        if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_AES) {
            strcat(globalResults, "captureEncryptType: AES\n");
        } else {
            strcat(globalResults, "captureEncryptType: TDES\n");
        }
        if (cardData->isDataVariant) {
            strcat(globalResults, "Key Type: Data Variant\n");
        } else {
            strcat(globalResults, "Key Type: PIN Variant\n");
        }
    }

    strcat(globalResults, "Optional Bytes:\n");
    strcat(globalResults, getData(cardData->optionalBytes, cardData->optionalBytesLen, 0));
    sprintf(globalResults, "%siccPresent: %02X\n", globalResults, cardData->iccPresent);

    // encrypted data
    strcat(globalResults, "encTrack1:\n");
    strcat(globalResults, getData(cardData->encTrack1, cardData->encTrack1Len, 0));

    strcat(globalResults, "encTrack2:\n");
    strcat(globalResults, getData(cardData->encTrack2, cardData->encTrack2Len, 0));

    strcat(globalResults, "encTrack3:\n");
    strcat(globalResults, getData(cardData->encTrack3, cardData->encTrack3Len, 0));

    strcat(globalResults, "Track 1 hash:\n");
    strcat(globalResults, getData(cardData->track1Hash, cardData->track1HashLen, 0));

    strcat(globalResults, "Track 2 hash:\n");
    strcat(globalResults, getData(cardData->track2Hash, cardData->track2HashLen, 0));

    strcat(globalResults, "Track 3 hash:\n");
    strcat(globalResults, getData(cardData->track3Hash, cardData->track3HashLen, 0));

    strcat(globalResults, "serialNumber:\n");
    strcat(globalResults, getData((BYTE *) cardData->serialNumber, cardData->serialNumberLen, 0));

    strcat(globalResults, "KSN:\n");
    strcat(globalResults, getData(cardData->KSN, cardData->KSNLen, 0));
} /* printMSRData */

void
printfMSRData(IDTMSRData * cardData) {
    printf("cardType: %02X\n", cardData->cardType);
    printf("cardData Len: %d\ncardData:\n", cardData->cardDataLen);
    printf("%s", getData(cardData->cardData, cardData->cardDataLen, 0));

    printf("Track1:\n");
    printf("%s", getData((BYTE *) cardData->track1, cardData->track1Length, 1));

    printf("Track2:\n");
    printf("%s", getData((BYTE *) cardData->track2, cardData->track2Length, 1));

    printf("Track3:\n");
    printf("%s", getData((BYTE *) cardData->track3, cardData->track3Length, 1));

    if (CAPTURE_ENCODE_TYPE_ISOABA == cardData->cardType) {
        if (cardData->captureEncryptType == CAPTURE_ENCRYPT_TYPE_AES) {
            printf("captureEncryptType: AES\n");
        } else {
            printf("captureEncryptType: TDES\n");
        }
        if (cardData->isDataVariant) {
            printf("Key Type: Data Variant\n");
        } else {
            printf("Key Type: PIN Variant\n");
        }
    }

    printf("Optional Bytes:\n");
    printf("%s", getData(cardData->optionalBytes, cardData->optionalBytesLen, 0));
    printf("iccPresent: %02X\n", cardData->iccPresent);

    // encrypted data
    printf("encTrack1:\n");
    printf("%s", getData(cardData->encTrack1, cardData->encTrack1Len, 0));

    printf("encTrack2:\n");
    printf("%s", getData(cardData->encTrack2, cardData->encTrack2Len, 0));

    printf("encTrack3:\n");
    printf("%s", getData(cardData->encTrack3, cardData->encTrack3Len, 0));

    printf("Track 1 hash:\n");
    printf("%s", getData(cardData->track1Hash, cardData->track1HashLen, 0));

    printf("Track 2 hash:\n");
    printf("%s", getData(cardData->track2Hash, cardData->track2HashLen, 0));

    printf("Track 3 hash:\n");
    printf("%s", getData(cardData->track3Hash, cardData->track3HashLen, 0));

    printf("serialNumber:\n");
    printf("%s", getData((BYTE *) cardData->serialNumber, cardData->serialNumberLen, 0));

    printf("KSN:\n");
    printf("%s", getData(cardData->KSN, cardData->KSNLen, 0));
} /* printfMSRData */

void
piscesMainMenu() {
    //	currentPiscesMenu = 0;
    previousPiscesMenu = MAIN_MENU;

    // Put device into custom display mode (cycle it to clear)
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();
        exitDemo = 1;
        return;
    }

//    printf("====================================>in piscesMainMenu\n");

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "VP8800 Demo", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Exit Demo", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Device Functions", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> CTLS Functions", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> MSR Functions", "4", 0);
    //	rt = lcd_addItemToList(itemListID, ">> ICC Functions", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> EMV Functions", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> LCD Functions", "6", 0);
    rt = lcd_addItemToList(itemListID, ">> PIN Functions", "7", 0);
    //	rt = lcd_addItemToList(itemListID, ">> WS Functions", "7", 0);

    rt = lcd_addItemToList(itemListID, ">> Get SDK Version", "8", 0);

    rt = lcd_clearEventQueue();

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Keep polling for user input
    while (1) {
        memset(eventType, 0, 4);
        memset(eventGraphicsID, 0, 4);
        memset(eventData, 0, 73);

        int dataReceived = 0;
        rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

        if (!dataReceived) {
            sleep(1); // Poll every second
        } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
          eventType[3] == 0x03) { // Keypad input
            if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
//                printf("====================================>Enter button pressed\n");
                break; // Exit loop and process selection because enter was pressed
            } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x08) {
                // Back / Clear was pressed
                // Exit application because this is the main menu and there is no previous menus

                // Stop custom display mode
                lcd_customDisplayMode(0);

                // Reset state
                lcd_resetInitialState();

                exitDemo = 1;

                return;
            } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                // Exit application because cancel was pressed

                // Stop custom display mode
                lcd_customDisplayMode(0);

                // Reset state
                lcd_resetInitialState();

                exitDemo = 1;

                return;
            }
        } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
            if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
              eventGraphicsID[1] == executeButtonID[1] &&
              eventGraphicsID[2] == executeButtonID[2] && eventGraphicsID[3] == executeButtonID[3]) {
//                printf("====================================>Execute button pressed\n");
                break; // Exit loop and process selection because execution button was pressed
            }
        }
    }

    char selectedItem[32] = { 0 };
    rt = lcd_getSelectedListItem(itemListID, selectedItem);

    // We received the selected item
    if (strlen(selectedItem) > 0) {
        int lineNum = atoi(selectedItem);

        switch (lineNum) {
            case 1: // Exit application
                // Stop custom display mode
                lcd_customDisplayMode(0);

                // Reset state
                lcd_resetInitialState();

                exitDemo = 1;

                return;

            case 2: // Device Menu
                //              piscesDeviceMenu();
                currentPiscesMenu = DEVICE_MENU;

                break;
            case 3: // CTLS Menu
                //              piscesCTLSMenu();
                currentPiscesMenu = CTLS_MENU;

                break;
            case 4: // MSR Menu
                //              piscesMSRMenu();
                currentPiscesMenu = MSR_MENU;

                break;
            //            case 5: // ICC Menu
            //              piscesICCMenu();
            //
            //				break;
            case 5: // EMV Menu
                //              piscesEMVMenu();
                currentPiscesMenu = EMV_MENU;
//                printf("================================>Go to EMV_MENU\n");

                break;
            case 6: // LCD Menu
                //              piscesLCDMenu();
                currentPiscesMenu = LCD_MENU;

                break;
            case 7: // PIN Menu
                //              piscesPINMenu();
                currentPiscesMenu = PIN_MENU;

                break;
                //            case 8: // WS Menu
                //				piscesWSMenu();

                break;
            case 8: // Get SDK Version
                getSDKVersion();
                break;
        }
    }
} /* piscesMainMenu */

#if 0
void
displayPreviousMenu() {
    switch (currentPiscesMenu) {
        case 0:
            piscesMainMenu();

            break;
        case 1:
            piscesDeviceMenu();

            break;
        case 2:
            piscesCTLSMenu();

            break;
        case 3:
            piscesMSRMenu();

            break;
        //        case 4:
        //			piscesICCMenu();
        //
        //			break;
        case 4:
            piscesEMVMenu();

            break;
        case 5:
            piscesLCDMenu();

            break;
        case 6:
            piscesPINMenu();

            break;
            //        case 7:
            //			piscesWSMenu();
            //
            //			break;
    }
} /* displayPreviousMenu */

#endif /* if 0 */

void
piscesDeviceMenu() {
    //	currentPiscesMenu = 1;
    previousPiscesMenu = DEVICE_MENU;

    // Put device into custom display mode (cycle it to clear)
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();
        currentPiscesMenu = MAIN_MENU;

        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "Device Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Start Transaction", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Get Firmware", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Get Serial Number", "4", 0);
    rt = lcd_addItemToList(itemListID, ">> Ping Device", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> 4 short beeps", "6", 0);
    rt = lcd_addItemToList(itemListID, ">> ICC LED On", "7", 0);
    rt = lcd_addItemToList(itemListID, ">> ICC LED Off", "8", 0);
    rt = lcd_addItemToList(itemListID, ">> Blue MSR LED On", "9", 0);
    rt = lcd_addItemToList(itemListID, ">> Blue MSR LED Off", "10", 0);
    rt = lcd_addItemToList(itemListID, ">> Get Drive Free Space", "11", 0);
    rt = lcd_addItemToList(itemListID, ">> List Directory", "12", 0);

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 &&
                  eventData[2] == 0x08) {
                    // Back / Clear was pressed
                    // Return to main menu
                    //                    piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] &&
                  eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            //            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    //                   piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    break;
                case 2: // Start Transaction
                    memset(globalResults, 0, _CMD_BUF_LEN);

                    emv_setAutoAuthenticateTransaction(1);
                    emv_setAutoCompleteTransaction(1);

                    rt = device_startTransaction(1.00, 0.00, 0, 30, NULL, 0);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Start Transaction Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    while (globalResults[0] == 0) {
                        sleep(1);
                    }

                    sleep(2);

                    //                    showPiscesResults(globalResults);

                    currentPiscesMenu = RESULT_MENU;

                    //                    memset(globalResults, 0, _CMD_BUF_LEN);

                    break;
                case 3: // Get Firmware Version
                {
                    char firmwareVersion[_CMD_BUF_LEN] = { 0 };

                    rt = device_getFirmwareVersion(firmwareVersion);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Firmware Version: ");
                        strcat(globalResults, firmwareVersion);
                    } else {
                        sprintf(globalResults, "Get Firmware Version Failed. Error Code 0x%02X", rt);
                    }

                    //                  showPiscesResults(results);
                    //                  memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 4: // Get Serial Number
                {
                    char serialNumber[_CMD_BUF_LEN] = { 0 };

                    rt = config_getSerialNumber(serialNumber);

                    //                  char results[_CMD_BUF_LEN] = { 0 };

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Serial Number: ");
                        strcat(globalResults, serialNumber);
                    } else {
                        sprintf(globalResults, "Get Serial Number Failed. Error Code 0x%02X", rt);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 5: // Ping Device
                    rt = device_pingDevice();

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Ping Device Successful");
                    } else {
                        sprintf(globalResults, "Ping Device Failed. Error Code 0x%02X", rt);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                case 6: // 4 Short Beeps
                    stayInMenu = 1;

                    BYTE values[4] = { 0xFF, 0x04, 0x00, 0x00 };

                    rt = device_controlUserInterface(values);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "4 Short Beeps Failed. Error Code 0x%02X", rt);

                        //                      showPiscesResults(results);
                        //                      memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                    }

                    break;
                case 7: // ICC LED On
                    stayInMenu = 1;

                    rt = device_controlIndicator(0, 1);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "ICC LED On Failed. Error Code 0x%02X", rt);

                        //                      showPiscesResults(results);
                        //                      memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                    }

                    break;
                case 8: // ICC LED Off
                    stayInMenu = 1;

                    rt = device_controlIndicator(0, 0);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "ICC LED Off Failed. Error Code 0x%02X", rt);

                        //                      showPiscesResults(results);
                        //                      memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                    }

                    break;
                case 9: // Blue MSR LED On
                    stayInMenu = 1;

                    rt = device_controlIndicator(1, 1);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Blue MSR LED On Failed. Error Code 0x%02X", rt);

                        //                      showPiscesResults(results);
                        //                      memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                    }

                    break;
                case 10: // Blue MSR LED Off
                    stayInMenu = 1;

                    rt = device_controlIndicator(1, 0);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Blue MSR LED Off Failed. Error Code 0x%02X", rt);

                        //                      showPiscesResults(results);
                        //                      memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                    }

                    break;
                case 11: // Get Drive Free Space
                {
                    int free, used;
                    rt = device_getDriveFreeSpace(&free, &used);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults,
                          "Get Drive Free Space Succeeded\nFree Drive Space: %d\nUsed Drive Space: %d", free,
                          used);
                    } else {
                        sprintf(globalResults, "Get Drive Free Space Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 12: // List Directory
                {
                    char ssDirectory[_CMD_BUF_LEN];
                    int ssDirectoryLen = _CMD_BUF_LEN;
                    memset(ssDirectory, 0, _CMD_BUF_LEN);
                    rt = device_listDirectory(NULL, 0, 1, 0, ssDirectory, &ssDirectoryLen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "List Directory Succeeded\n");
                        int i;
                        for (i = 0; i < ssDirectoryLen; i++) {
                            if (ssDirectory[i] == ',') {
                                strcat(globalResults, "\n");
                            } else {
                                char tmp[2];
                                sprintf(tmp, "%c", ssDirectory[i]);
                                strcat(globalResults, tmp);
                            }
                        }
                    } else {
                        sprintf(globalResults, "List Directory Failed. Error Code 0x%02X", rt);
                    }
                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
            }
        }
    }
} /* piscesDeviceMenu */

void
piscesCTLSMenu() {
    //	currentPiscesMenu = 2;
    previousPiscesMenu = CTLS_MENU;

    // Put device into custom display mode (cycle it to clear)
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();
        currentPiscesMenu = MAIN_MENU;
        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "CTLS Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back to Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Start CTLS Transaction", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Online Result OK", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Online Result NOT OK", "4", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve AID", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove AID", "6", 0);
    rt = lcd_addItemToList(itemListID, ">> Save AID", "7", 0);
    rt = lcd_addItemToList(itemListID, ">> List AIDs", "8", 0);
    rt = lcd_addItemToList(itemListID, ">> List Terminal Data", "9", 0);
    rt = lcd_addItemToList(itemListID, ">> Set Terminal Data", "10", 0);
    rt = lcd_addItemToList(itemListID, ">> Get Config Group", "11", 0);
    rt = lcd_addItemToList(itemListID, ">> Get All Config Groups", "12", 0);
    rt = lcd_addItemToList(itemListID, ">> Set Config Group", "13", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove Config Group", "14", 0);
    rt = lcd_addItemToList(itemListID, ">> Reset Config Group", "15", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve CAPK", "16", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove CAPK", "17", 0);
    rt = lcd_addItemToList(itemListID, ">> List CAPKs", "18", 0);
    rt = lcd_addItemToList(itemListID, ">> Save CAPK", "19", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove All CAPK", "20", 0);
    rt = lcd_addItemToList(itemListID, ">> Load Default CAPK", "21", 0);


    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 &&
                  eventData[2] == 0x08) {
                    // Back / Clear was pressed
                    // Return to main menu
                    //                    piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    //                  printf("====================================>lcd_customDisplayMode10\n");
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
                if (eventData[0] == 0x01 &&
                    eventGraphicsID[0] == executeButtonID[0] &&
                    eventGraphicsID[1] == executeButtonID[1] &&
                    eventGraphicsID[2] == executeButtonID[2] &&
                    eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            //            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    //                   piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    break;
                case 2: // Start Transaction
                    memset(globalResults, 0, _CMD_BUF_LEN);

                    rt = ctls_startTransaction(1.00, 0.00, 0, 30, NULL, 0);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Start CTLS Transaction Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    while (globalResults[0] == 0) {
                        sleep(1);
                    }

                    sleep(5);
                    //                    showPiscesResults(globalResults);

                    //                    memset(globalResults, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                case 3: // Online Result OK
                    rt = ctls_displayOnlineAuthResult(1, NULL, 0);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Online Result OK Successful");
                    } else {
                        sprintf(globalResults, "Online Result OK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                case 4: // Online Result NOT OK
                    rt = ctls_displayOnlineAuthResult(0, NULL, 0);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Online Result NOT OK Successful");
                    } else {
                        sprintf(globalResults, "Online Result NOT OK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                case 5: // Retrieve AID a0 00 00 00 04 10 10
                {
                    int AIDlen8;
                    int tlvlen8;
                    tlvlen8 = 500;
                    BYTE AID[7] = { 0xa0, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10 };
                    AIDlen8 = 7;
                    BYTE tlv[500] = { 0 };
                    memset(tlv, 0, 500);
                    rt = ctls_retrieveApplicationData(AID, AIDlen8, tlv, &tlvlen8);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve AID  a0 00 00 00 04 10 10 Successful\n");
                        strcat(globalResults, "AID data:\n");
                        genTLVString(globalResults, tlv, tlvlen8);
                    } else {
                        sprintf(globalResults, "Retrieve AID  a0 00 00 00 04 10 10 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 6: // Remove AID a0 00 00 00 04 10 10
                {
                    BYTE AID[10] = { 0x9f, 0x06, 0x07, 0xa0, 0x00, 0x00, 0x00, 0x04, 0x10, 0x10 };
                    int AIDlen   = 10;
                    rt = ctls_removeApplicationData(AID, AIDlen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove AID  a0 00 00 00 04 10 10 Successful");
                    } else {
                        sprintf(globalResults, "Remove AID  a0 00 00 00 04 10 10 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 7: // Save AID a0 00 00 00 04 10 10
                {
                    BYTE tlv11[200];
                    int tlvLen11 = 200;
                    char * str2  =
                      "DFEE2D01809F0607A0000000041010DFEE4B0101DFEE2E0110DFEE590102DFEE4D017CDFEE540C020080022080020180020980DFEE2F0180";
                    convertHStrIntoHex(str2, tlv11, &tlvLen11);
                    rt = ctls_setApplicationData(tlv11, tlvLen11);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save AID  a0 00 00 00 04 10 10 Successful");
                    } else {
                        sprintf(globalResults, "Save AID  a0 00 00 00 04 10 10 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 8: // List AIDs
                {
                    BYTE AIDList[_CMD_BUF_LEN] = { 0 };
                    int AIDListLen = _CMD_BUF_LEN;

                    rt = ctls_retrieveAIDList(AIDList, &AIDListLen);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        int len = 0;

                        while (len < AIDListLen) {
                            sprintf(globalResults, "%s%s\n", globalResults, &(AIDList[len]));
                            len += strlen(&(AIDList[len])) + 1;
                        }
                    } else {
                        sprintf(globalResults, "List AIDs Failed. Error Code 0x%02X", rt);
                    }

                    //                  showPiscesResults(results);
                    //                  memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 9: // List Terminal Data
                {
                    BYTE terminalData[_CMD_BUF_LEN] = { 0 };
                    int terminalDataLen = _CMD_BUF_LEN;

                    rt = ctls_retrieveTerminalData(terminalData, &terminalDataLen);

                    //                  char results[_CMD_BUF_LEN] = { 0 };

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        char TLVHexString[_CMD_BUF_LEN] = { 0 };
                        char TLVString[_CMD_BUF_LEN]    = { 0 };

                        convertBytesIntoHexStr(terminalData, terminalDataLen, 0, TLVHexString);
                        getTLVString(terminalData, terminalDataLen, TLVString);

                        char * trimmedTLVString = trim(TLVString);

                        strcpy(globalResults, "List Terminal Data Successful. TLVs: \n\n");
                        strcat(globalResults, TLVHexString);
                        strcat(globalResults, "\n\n");
                        strcat(globalResults, trimmedTLVString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "List Terminal Data Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 10: // Set Terminal Data
                {
                    BYTE tlv16[1024];
                    int tlvlen16 = 1024;
                    //				char * terminalstr ="ffe40100df7c0100df7d0100df7503003000df6a01019f5801039f5903dc80009f5a01009f5e02e0009f5f060000000080009f5d06000000005000df2a06000000005000df2b0132df2c010adf630100df640100df650100df660100fff003020000fff30207fffff90103fffa020000df5101809f0106000000000000df680100df7f0100df2601019c01005f2a0208405f3601029f090200029f1a0208409f1b04000017709f33030008e89f3501229f400560000030009f660480004000fff106000000010000fff403000601fff506000000008000fff80100fffb0100fffc0101fffd05f850acf800fffe05f850aca000ffff0500000000009f15020000df28030008e8df29030068e89f6d0200019f7c140000000000000000000000000000000000000000fff20830303030303030309f4e1e0000000000000000000000000000000000000000000000000000000000009f5301009f03060000000000009f02060000000000019f1c0800000000000000009f160f000000000000000000000000000000ffee1d0404042a0cffee1e01019f410400000000df891b0101fff701009a031608129f21030339139700";
                    //				char * terminalstr ="5F3601029F1A0208409F3501219F33036028C89F4005F000F0A0019F1E085465726D696E616C9F150212349F160F3030303030303030303030303030309F1C0838373635343332319F4E2231303732312057616C6B65722053742E20437970726573732C204341202C5553412EDF260101DF1008656E667265737A68DF110100DF270100DFEE150101DFEE160100DFEE170107DFEE180180DFEE1E08D0DC20D0C41E1400DFEE1F0180DFEE1B083030303135313030DFEE20013CDFEE21010ADFEE2203323C3C";
                    char * terminalstr =
                      "9C01005F2A0208405F3601029F02060000000000019F03060000000000009F1A0208409F3501219F4005F000F0A0019F530100DF812306000000006000DF812606000000008000DFEE1D0504042A0C31DFEE3406000000010000DFEE380100DFEE440295FFDFEE4E0100DFEE5702454EDFEE58022020DFEE630100DFEE680100DFEE6B085465726D696E616CDFEE7503003000DFEE79020000DFEE7A0105DFEE7B03002000DFEF29021000DFEF2A0100DFEF35020000DFEF720100";
                    convertHStrIntoHex(terminalstr, tlv16, &tlvlen16);
                    rt = ctls_setTerminalData(tlv16, tlvlen16);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Set Terminal Data Successful");
                    } else {
                        sprintf(globalResults, "Set Terminal Data Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 11: // Get Config Group
                {
                    BYTE tlv[_DATA_BUF_LEN];
                    int tlvLen = _DATA_BUF_LEN;
                    int group  = 0;
                    int i;
                    rt = ctls_getConfigurationGroup(group, tlv, &tlvLen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Get Config Group %d Succeeded:\n", group);

                        IDTTag tags[250];
                        int tagCount = 250;
                        strcat(globalResults, getData(tlv, tlvLen, 0));
                        TLV_getTags(tlv, tlvLen, tags, &tagCount);
                        if (tagCount > 0) {
                            char tmp[_CMD_BUF_LEN] = { 0 };
                            sprintf(tmp, "Tags Count: %d\n", tagCount);
                            for (i = 0; i < tagCount; i++) {
                                int j;
                                for (j = 0; j < tags[i].tagLen; j++) {
                                    sprintf(tmp, "%s%02X", tmp, tags[i].Tag[j]);
                                }
                                strcat(tmp, ": ");
                                for (j = 0; j < tags[i].valueLen; j++) {
                                    sprintf(tmp, "%s%02X", tmp, tags[i].value[j]);
                                }
                                strcat(tmp, "\n");
                            }
                            strcat(globalResults, tmp);
                        }
                    } else {
                        sprintf(globalResults, "Get Config Group Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 12: // Get All Config Groups
                {
                    BYTE tlv[_DATA_BUF_LEN * 2];
                    int tlvLen = _DATA_BUF_LEN * 2;
                    int i;
                    rt = ctls_getAllConfigurationGroups(tlv, &tlvLen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Get All Config Groups Succeeded:\n");

                        IDTTag tags[250];
                        int tagCount = 250;
                        strcat(globalResults, getData(tlv, tlvLen, 0));
                        TLV_getTags(tlv, tlvLen, tags, &tagCount);
                        if (tagCount > 0) {
                            char tmp[_CMD_BUF_LEN] = { 0 };
                            sprintf(tmp, "Tags Count: %d\n", tagCount);
                            for (i = 0; i < tagCount; i++) {
                                int j;
                                for (j = 0; j < tags[i].tagLen; j++) {
                                    sprintf(tmp, "%s%02X", tmp, tags[i].Tag[j]);
                                }
                                strcat(tmp, ": ");
                                for (j = 0; j < tags[i].valueLen; j++) {
                                    sprintf(tmp, "%s%02X", tmp, tags[i].value[j]);
                                }
                                strcat(tmp, "\n");
                            }
                            strcat(globalResults, tmp);
                        }
                    } else {
                        sprintf(globalResults, "Get All Config Groups Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 13: // Set Config Group //malformatted data
                {
                    BYTE tlv16[1024];
                    int tlvlen16 = 1024;
                    //			char * ConfigurationGroup ="FFE40100DF7C0100DF7D0100DF7503003000DF6A01019F5801039F5903DC80009F5A01009F5E02E0009F5F060000000080009F5D06000000005000DF2A06000000005000DF2B0132DF2C010ADF630100DF640100DF650100DF660100FFF003020000FFF30207FFFFF90103FFFA020000DF5101809F0106000000000000DF7F0100DF2601019C01005F2A0208405F3601029F090200029F1A0208409F1B04000017709F33030008E89F3501229F400560000030009F660480004000FFF106000000010000FFF403000601FFF506000000008000FFF80100FFFB0100FFFC0101FFFD05F850ACF800FFFE05F850ACA000FFFF0500000000009F15020000DF28030008E8DF29030068E89F6D0200019F7C140000000000000000000000000000000000000000FFF20830303030303030309F4E1E0000000000000000000000000000000000000000000000000000000000009F5301009F03060000000000009F02060000000000019F1C0800000000000000009F160F000000000000000000000000000000FFEE1E01019F410400000000DF891B0101FFF70100DF680100FFEE1D0504042A0C31DFEF360400000000DFEF4B0312000097009A030101019F2103000000";
                    char * ConfigurationGroup =
                      "DFEE2D01009C01005F2A0208405F3601029F090200029F150200009F1A0208409F1B04000017709F33030008E89F3501229F400560000030009F6604800040009F6D0200019F7C140000000000000000000000000000000000000000DFEE28030008E8DFEE29030068E8DFEE5C0401500000DFEE700100DFEE71020000DFEE72020000DFEE73020000DFEE740100DFEE3406000000010000DFEE3503000601DFEE3606000000008000DFEE370103DFEE380100DFEE390101DF812205F850ACF800DF812005F850ACA000DF8121050000000000DFEE2D01089F01065649534130309F090200965F2A0208405F3601029F1B0400003A98DFEE13050000000000DFEE14050000000000DFEE04050000000000DFEE050400001388DFEE060101DFEE070101DFEE0D0100DFEE0F0101DFEE3E0101DFEE0E099F02069F03069F3704DFEE3F089F02069F03068A02";
                    convertHStrIntoHex(ConfigurationGroup, tlv16, &tlvlen16);
                    rt = ctls_setConfigurationGroup(tlv16, tlvlen16);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Set Config Group Successful");
                    } else {
                        sprintf(globalResults, "Set Config Group Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 14: // Remove Config Group
                {
                    BYTE tlv[_DATA_BUF_LEN];
                    int tlvLen = _DATA_BUF_LEN;
                    int group  = 0;
                    int i;
                    rt = ctls_removeConfigurationGroup(group);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove Config Group 0 Successful");
                    } else {
                        sprintf(globalResults, "Remove Config Group 0 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 15: // Reset Config Group
                {
                    int group = 0;

                    rt = ctls_resetConfigurationGroup(group);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Reset Config Group 0 Successful");
                    } else {
                        sprintf(globalResults, "Reset Config Group 0 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 16: // Retrieve CAPK A0 00 00 99 99 E1
                {
                    unsigned char data[500];
                    int dataLen = 500;
                    char * str2 = "A0 00 00 99 99 E1";
                    unsigned char pdt1[500];
                    int pdt1Len = 500;
                    convertHStrIntoHex(str2, pdt1, &pdt1Len);
                    rt = ctls_retrieveCAPK(pdt1, pdt1Len, data, &dataLen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        char str1[1024] = { 0 };
                        convertBytesIntoHexStr(data, dataLen, 1, str1);
                        sprintf(globalResults, "Retrieve CAPK succeeded\n%s.", str1);
                    } else {
                        sprintf(globalResults, "Retrieve CAPK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 17: // Remove CAPK A0 00 00 99 99 E1
                {
                    char * str2 = "A0 00 00 99 99 E1";
                    unsigned char pdt1[200];
                    int pdt1Len = 200;
                    convertHStrIntoHex(str2, pdt1, &pdt1Len);
                    rt = ctls_removeCAPK(pdt1, pdt1Len);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove CAPK A0 00 00 99 99 E1 Successful");
                    } else {
                        sprintf(globalResults, "Remove CAPK A0 00 00 99 99 E1 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 18: // List CAPK
                {
                    BYTE CAPKList[_CMD_BUF_LEN] = { 0 };
                    int CAPKListLen = _CMD_BUF_LEN;
                    int x = 0;

                    rt = ctls_retrieveCAPKList(CAPKList, &CAPKListLen);

                    //                  char results[_CMD_BUF_LEN] = { 0 };

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "List CAPK Successful\n\n");
                        char str1[_DATA_BUF_LEN] = { 0 };
                        char tmp[_DATA_BUF_LEN]  = { 0 };
                        BYTE CAPK[6] = { 0 };
                        if (CAPKListLen > 0) {
                            memset(CAPK, 0, 6);
                            for (x = 0; x < CAPKListLen; x = x + 6) {
                                memcpy(CAPK, CAPKList + x, 6);

                                str1[0] = '\0';
                                convertBytesIntoHexStr(CAPK, 6, 1, str1);
                                sprintf(tmp, "\t%s.\n", str1);
                                strcat(globalResults, tmp);
                            }
                        }
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "List CAPK Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 19: // Save CAPK A0 00 00 99 99 E1
                {
                    char * str2 =
                      "a000009999e10101f8707b9bedf031e58a9f843631b90c90d80ed69500000003007099c5b70aa61b4f4c51b6f90b0e3bfb7a3ee0e7db41bc466888b3ec8e9977c762407ef1d79e0afb2823100a020c3e8020593db50e90dbeac18b78d13f96bb2f57eeddc30f256592417cdf739ca6804a10a29d2806e774bfa751f22cf3b65b38f37f91b4daf8aec9b803f7610e06ac9e6b";
                    unsigned char pdt1[400];
                    int pdt1Len = 400;
                    convertHStrIntoHex(str2, pdt1, &pdt1Len);
                    rt = ctls_setCAPK(pdt1, pdt1Len);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save CAPK Successful");
                    } else {
                        sprintf(globalResults, "Save CAPK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 20: // Remove All CAPK
                {
                    rt = ctls_removeAllCAPK();
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove All CAPK Successful");
                    } else {
                        sprintf(globalResults, "Remove All CAPK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 21: // Load Default CAPK
                {
                    rt = ctls_removeAllCAPK();
                    //					printf("Please Wait. Loading Default CAPK...\r\n");
                    char * str22 =
                      "a000009999e10101f8707b9bedf031e58a9f843631b90c90d80ed69500000003007099c5b70aa61b4f4c51b6f90b0e3bfb7a3ee0e7db41bc466888b3ec8e9977c762407ef1d79e0afb2823100a020c3e8020593db50e90dbeac18b78d13f96bb2f57eeddc30f256592417cdf739ca6804a10a29d2806e774bfa751f22cf3b65b38f37f91b4daf8aec9b803f7610e06ac9e6b";
                    unsigned char pdt22[800];
                    int pdt22Len = 800;
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						 showPiscesResults(results);
                        //						 memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000009999e20101c1056adce9e6f76ea77c89cb832f5a4817907a1a000000030070bd232e348b118eb3f6446ef4da6c3bac9b2ae510c5ad107d38343255d21c4bdf4952a42e92c633b1ce4bfec39afb6dfe147ecbb91d681dac15fb0e198e9a7e4636bdca107bcda3384fcb28b06afef90f099e7084511f3cc010d4343503e1e5a67264b4367daa9a3949499272e9b5022f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000009999e301011b795cbb0830e2c5231704fa57424d1c4e50f3e4000100010070bc01e12223e1a41e88bffa801093c5f8cec5cd05dbbdbb787ce87249e8808327c2d218991f97a1131e8a25b0122ed11e709c533e8886a1259addfdcbb396604d24e505a2d0b5dd0384fb0002a7a1eb39bc8a11339c7a9433a948337761be73bc497b8e58736da4636538ad282d3cd3db";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000009999e40101ac8da3e12324d719c1d5c9e6e8580157196efeb9000000030080cbf2e40f0836c9a5e390a37be3b809bdf5d740cb1da38cfc05d5f8d6b7745b5e9a3fa6961e55ff20412108525e66b970f902f7ff4305dd832cd0763e3aa8b8173f84777100b1047bd1d744509312a0932ed25fed52a959430768ccd902fd8c8ad9123e6addb3f34b92e7924d729cb6473533ae2b2b55bf0e44964fdea8440117";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000009999e50101ada2349afd118d55af782d37b64651af1ca61ee5000000030080d4fdae94dedbecc6d20d38b01e91826dc6954338379917b2bb8a6b36b5d3b0c5eda60b337448baffebcc3abdba869e8dadec6c870110c42f5aab90a18f4f867f72e3386ffc7e67e7ff94eba079e531b3cf329517e81c5dd9b3dc65db5f9043190be0be897e5fe48adf5d3bfa0585e076e554f26ec69814797f15669f4a255c13";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000009999e601018aa4f4648f0dc62ab6aed92554ad1a831bafc9e4000100010080ebf9faecc3e5c315709694664775d3fbda5a504d89344dd920c55696e891d9ab622598a9d6ab8fbf35e4599cab7eb22f956992f8ab2e6535decb6b576fa0675f97c23dd4c374a66e6af419c9d204d0b9f93c08d789d63805660fbb629df1b488cfa1d7a13e9b729437eeafe718efa859348ba0d76812a99f31cd364f2a4fd42f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000004fa01017f5acbb96b589f74cb959ed1c35bdb965c3f41060001000100f8a4203e0c7beb27097b63c103c19fdcda671aea7f813065756f3b9b81810cbd4bc4dec548fbf1f3cdae51f847235cbf2c8badd8aca7c93bea3d44e80ed6a7b70e29622619db420accce07e1dd4e6c354f359fbdc9c5b70813926f77d827e52b19daf09bfae5274438bb8f61d17753c9ec0a8efa3b7e46f02692160d2653cdbcc71b7d48bd37968316eb444f6504b9421b7dd3035a2c117d8b1f76a8975440da9563618102397b881cef8ada7689edface32482a2dffed656e7f951db841da78368c6293bfc1053a86a845bfa6578e4b69f100b42b558fde1aecec6d250741bc783aa8a68a4261e7bb9246b10587a498d68dd955ce8b2b2433";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000004fb0101fc787db138f994a0c554cc6734eb3e48a55066cc0001000100909b170603a489c7546c45da57b8ffd1db2061240f0e8c6d1f9abdc6b265aa8911915c1a4eabd8d0ed4755d1b902ba06fe5a645b786cd241295517d44ef1a7c25d75afe0eb28066e4d69fee7abafdd5eeb230f14e402c9840825fa77ead12b5f1c5494701de1897f65fe6bf106d47545ebf70ce7c158068c61f0773534db742ab83c28038c1494f15905d0ad17cf1bd38d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000004fc0101db50b5b0d966300760b1e42125277ba833b652340001000100f8b3296c91f4795bd97112606903407b6eff3ab39246e91095e51d17867da4ade59a48be2fe9b52710283d3d32260e2c7d247214c57d46aa6465e47e0a4b3ffaad8a7f6a190755bccfe3f3fb3989a9f6b1c9e1845bcccad6f20b1dac6033600234e81dac4153212b0f760c23099192aa6c4c9083beffd9a79d2a27b08fecc8e5d437d6c68550a839b1294151daba9d9cb2f160f60f749289f500c8c7f334bd20ebac4ab109cf3c182f1b781c7c097a7903530746c449b99e39e4db6493dd2a02e37c62ae8bc9a7470ecccf8dc06a18c33cd24b30d56f25d2755ce82aa4de4d2eaec07750a03db75ebd0d8ebc9f2a1d85a0d252eff40329be05";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000004fd0101fc505e4a83ff29a3b1bd28dabf52599b2ae9cb14000100010090c9485dbeb5e40415d1b397524f47685f306cfdc499d4e2e7d0cbaf222cfa8184bd111daeedc9cc6ec8540c3f7271ea9990119cc5c43180501d9f45252d6835053fae35696ae8cd67a325647449cf5e594da8f627209f7f03ae8d6dfc0db3e79e28e415df29a5b57d6814856cc30a96da5b8890363e507fcb2e283da1ebb5f18e8e24102b7d0192bb8e35a4f7cd05a435";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000004fe01018535f14cbd6b4ae5028618fab5ac1106549fd03c000100010090e76317965175a08bee510f58830e87b262c70d529803245fa8b88e0c753562de7aeb5a9e3e6c1a98e94d8db7c31407dac5d071e06b80b09e146f22db85f1d72d1ea18d22600032c6dd40e3714d5ada7de9d7d01e88391f893156d6f4bf13e9063559da0786de9bde6b1c9b0bb968edde07145abf877b931682ccb1fb800728724d04af241e2827e0fa1f62591914ff25";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000004ff0101439eb23d8a71b99f879c1a1f1765252d840b9a74000100010090f69dbb5e15983eae3ccf31cf4e47098c2fc16f97a0c710f84777efa99622d86502b138728ab12e3481a84d20e014ad2d634d2836f27f294924b895a87f91f81b8169d4dfdad8d7cbd741804cd61b467c7a9acfeceb71188caa73a907547699d45c9c7d2098ac2966266417f665a46bdd012c097dbd33d1d11aff6ec8a9c0ad814a65b48262ca011636079a328c1aaeb7";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000065020101b973e9f377b419c36ac9696ed95ffb25c8020687000100010080bb7f51983fd8707fd6227c23def5d5377a5a737cef3c5252e578efe136df87b50473f9341f1640c8d258034e14c16993fce6c6b8c3ceeb65fc8fbcd8eb77b3b05ac7c4d09e0fa1ba2efe87d3184db6718ae41a7cad89b8dce0fe80ceb523d5d647f9db58a31d2e71ac677e67fa6e75820736c9893761ee4acd11f31dbdc349ef";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a0000000650301017dc435dbde093d1f0ad0bae0fea4dc12056413dc0000000300f8c9e6c1f3c6949a8a42a91f8d0224132b2865e6d953a5b5a54cffb0412439d54aeba79e9b399a6c104684df3fb727c7f55984db7a450e6aa917e110a7f2343a0024d2785d9ebe09f601d592362fdb237700b567ba14bbe2a6d3d23cf1270b3dd822b5496549bf884948f55a0d308348c4b723bafb6a7f3975ac397cad3c5d0fc2d178716f5e8e79e75beb1c84fa202f80e68069a984e008706b30c212305456201540787925e86a8b28b129a11af204b387cb6ee43db53d15a46e13901bebd5cecf4854251d9e9875b16e82ad1c5938a972842c8f1a42ebb5ae5336b04ff3da8b8dfbe606fca8b9084ee05bf67950ba89897cd089f924dbcd";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000003500101b769775668cacb5d22a647d1d993141edab7237b000100010080d11197590057b84196c2f4d11a8f3c05408f422a35d702f90106ea5b019bb28ae607aa9cdebcd0d81a38d48c7ebb0062d287369ec0c42124246ac30d80cd602ab7238d51084ded4698162c59d25eac1e66255b4db2352526ef0982c3b8ad3d1cce85b01db5788e75e09f44be7361366def9d1e1317b05e5d0ff5290f88a0db47";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000003510101b9d248075a3f23b522fe45573e04374dc4995d71000000030090db5fa29d1fda8c1634b04dccff148abee63c772035c79851d3512107586e02a917f7c7e885e7c4a7d529710a145334ce67dc412cb1597b77aa2543b98d19cf2cb80c522bdbea0f1b113fa2c86216c8c610a2d58f29cf3355ceb1bd3ef410d1edd1f7ae0f16897979de28c6ef293e0a19282bd1d793f1331523fc71a228800468c01a3653d14c6b4851a5c029478e757f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000003530101ac213a2e0d2c0ca35ad0201323536d58097e4e570000000300f8bcd83721be52cccc4b6457321f22a7dc769f54eb8025913be804d9eabbfa19b3d7c5d3ca658d768caf57067eec83c7e6e9f81d0586703ed9dddadd20675d63424980b10eb364e81eb37db40ed100344c928886ff4ccc37203ee6106d5b59d1ac102e2cd2d7ac17f4d96c398e5fd993ecb4ffdf79b17547ff9fa2aa8eefd6cbda124cbb17a0f8528146387135e226b005a474b9062ff264d2ff8efa36814aa2950065b1b04c0a1ae9b2f69d4a4aa979d6ce95fee9485ed0a03aee9bd953e81cfd1ef6e814dfd3c2ce37aefa38c1f9877371e91d6a5eb59fdedf75d3325fa3ca66cdfba0e57146cc789818ff06be5fcc50abd362ae4b80996d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a0000000039601017616e9ac8be014af88ca11a8fb17967b7394030e000000030080b74586d19a207be6627c5b0aafbc44a2ecf5a2942d3a26ce19c4ffaeee920521868922e893e7838225a3947a2614796fb2c0628ce8c11e3825a56d3b1bbaef783a5c6a81f36f8625395126fa983c5216d3166d48acde8a431212ff763a7f79d9edb7fed76b485de45beb829a3d4730848a366d3324c3027032ff8d16a1e44d8d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000003570101251a5f5de61cf28b5c6e2b5807c0644a01d46ff5000100010060942b7f2ba5ea307312b63df77c5243618acc2002bd7ecb74d821fe7bdc78bf28f49f74190ad9b23b9713b140ffec1fb429d93f56bdc7ade4ac075d75532c1e590b21874c7952f29b8c0f0c1ce3aeedc8da25343123e71dcf86c6998e15f756e3";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000003580101753ed0aa23e4cd5abd69eae7904b684a34a57c220001000100c899552c4a1ecd68a0260157fc4151b5992837445d3fc57365ca5692c87be358cdcdf2c92fb6837522842a48eb11cdffe2fd91770c7221e4af6207c2de4004c7dee1b6276dc62d52a87d2cd01fbf2dc4065db52824d2a2167a06d19e6a0f781071cdb2dd314cb94441d8dc0e936317b77bf06f5177f6c5aba3a3bc6aa30209c97260b7a1ad3a192c9b8cd1d153570afcc87c3cd681d13e997fe33b3963a0a1c79772acf991033e1b8397ad0341500e48a24770bc4cbe19d2ccf419504fdbf0389bc2f2fdcd4d44e61f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a00000000354010106960618791a86d387301edd4a3baf2d34fef1b40001000100f8c6ddc0b7645f7f16286ab7e4116655f56dd0c944766040dc68664dd973bd3bfd4c525bcbb95272b6b3ad9ba8860303ad08d9e8cc344a4070f4cfb9eeaf29c8a3460850c264cda39bbe3a7e7d08a69c31b5c8dd9f94ddbc9265758c0e7399adcf4362caee458d414c52b498274881b196dacca7273f687f2a65faeb809d4b2ac1d3d1efb4f6490322318bd296d153b307a3283ab4e5be6ebd910359a8565eb9c4360d24baaca3dbfe393f3d6c830d603c6fc1e83409dfcd80d3a33ba243813bbb4ceaf9cbab6b74b00116f72ab278a88a011d70071e06cab140646438d986d48281624b85b3b2ebb9a6ab3bf2178fcc3011e7caf24897ae7d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000025600101894b8df19bdc691103c3b93979f5ee28c05888a7000100010090a8ee74edef3c0dca5102ff9b5707975ff67b60d64b5e7322d48de9d3bb6153f63512a091b606dd8fd5f6a14588324ef8827844c7ffc0bab2334ae5207770078b69cdc3f2c666cf69e28e16e1816714c4df313bef539cc01da9dd2d6f47de4f247c500b561c099166ad4fc16df12dfb684ac48d35cdd2c47a13a86a5a162306f64e33b092ab74eda71a4091d96e3daa47";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000025610101cccf27c49c15b2a9410ec6089223a3a01ea8433e0001000100f886c7254665e17ce6934df7d082569f208d1cc1ad8e9fb2fe23e3d7467be50b4f874f906adf2280ec9d204f6d10c037a23ce5fd8283c9ed47d1c669abdd7c1cb356c70bcdc44e5c8ae231555f7b786ac9c3155bcd51f28efbc1b33cc87277049219b2c890952736c4713487111678911d9f42e08074cf524e65d721d727f054e6b5e85ec92b3eb59ffee926dd6c314df555c94ad487a99b67cb7c7ba5e46a5b813ddb918b8e3e0423f4302a58686d1263c0baca9e82068c493289e3e6936eca5f9f77e06b0d6fbda718818b835020098c671c5dd7e9b8e8e841d2df32ee94a7f4748484ca44108ab241a5263ba1ff00d51360dddc749d30a1";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000152d00101de1bb8a37cddbceaab043aaef81634120349726d000100010090d05c2a09d09c9031366ec092bcac67d4b1b4f88b10005e1fc45c1b483ae7eb86ff0e884a19c0595a6c34f06386d776a21d620fc9f9c498adca00e66d129bcdd4789837b96dcc7f09da94ccac5ac7cfc07f4600df78e493dc1957deba3f4838a4b8bd4cefe4e4c6119085e5bb21077341c568a21d65d049d666807c39c401cdfee7f7f99b8f9cb34a8841ea62e83e8d63";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000152d10101ffda858cb2af08b79d750cc97fa6efe2ef228dda0001000100f8a71af977c1079304d6dff3f665ab6db3fbdfa1b170287ac6d7bc0afcb7a202a4c815e1fc2e34f75a052564ee2148a39cd6b0f39cfaef95f0294a86c3198e349ff82eece633d50e5860a15082b4b342a90928024057dd51a2401d781b67ae7598d5d1ff26a441970a19a3a58011ca19284279a85567d3119264806caf761122a71fc0492ac8d8d42b036c394fc494e03b43600d7e02cb5267755ace64437cfa7b475ad40ddc93b8c9bcad63801fc492fd251640e41fd13f6e231f56f97283447ab44cbe11910db3c75243784aa9bdf57539c31b51c9f35bf8bc2495762881255478264b792bbdca6498777ae9120ed935bb3e8bea3eab13d9";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000333c001018b094d260bdf8bfc8b9a88b0c177a43fe2fae765000100010090c7cdb6f2a3fe80a8834cdddd326e1082aa2288f47c464d57b34718193431711a44119148055044cfe3313708bed0c98e1c589b0f53cf6d7e829fcd906d21a90fd4cb6baf13110c4685107c27e00981db29dc0ac186e6d701577f23865626244e1f9b2cd1ddfcb9e899b41f5084d8ccc178a7c3f4546cf93187106fab055a7ac67df62e778cb88823ba58cf7546c2b09f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    str22    =
                      "a000000333c10101b6372db9919f8c6c9c88e83d3c600a4ad8adc7a90001000100f892f083cbe46f8dcc0c04e498ba9952ba9d4c09c80dd277e579f07e45772846fa43dd3ab31cc6b08dd18695715949fb108e53a071d393a7fddbf9c5fb0b0507138797317480fc48d633ed38b401a451443ad7f15facda45a62abe24ff6343add0909ea8389348e54e26f842880d1a69f9214368ba30c18de5c5e0cb9253b5abc55fb6ef0a738d927494a30bbf82e340285363b6faa15673829dbb210e710da58ee9e578e7ce55dc812ab7d6dcce0e3b1ae179d664f3356eb951e3c91a1cbbf6a7ca8d0c7ec9c6af7a4941c5051099b9784e56c9162067b8c3b15c5fa4480a645cd2526a69c80ba8ef361be2aa9417defce35b62b0c9cf097d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = ctls_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                    } else {
                        /*
                         * str22 ="";
                         * COMMON.convertHStrIntoHex(str22,pdt22,&pdt22Len);
                         * r = emv_setCAPK(pdt22,pdt22Len);
                         * if ( r != RETURN_CODE_DO_SUCCESS ) {
                         *
                         * printf(" >>>>>>load ..... save CAPK  failed! .......... ----- \n" );
                         *
                         * }else
                         * printf(">>set CAPK: OK. load ........\n");
                         *
                         */
                        sprintf(globalResults, "Load Default CAPK Succeeded\n");
                    }
                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
            }
        }
    }
} /* piscesCTLSMenu */

void
piscesMSRMenu() {
    //	currentPiscesMenu = 3;
    previousPiscesMenu = MSR_MENU;

    // Put device into custom display mode (cycle it to clear)
    //	printf("====================================>lcd_customDisplayMode11\n");
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();
        currentPiscesMenu = MAIN_MENU;

        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "MSR Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Start MSR Transaction", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Flush Track Data", "3", 0);


    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 &&
                  eventData[2] == 0x08) {
                    // Back / Clear was pressed
                    // Return to main menu
                    //                    piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    //                  printf("====================================>lcd_customDisplayMode12\n");
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] &&
                  eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was press
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    //                   piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    break;
                case 2: // Start MSR Transaction
                    rt = msr_startMSRSwipe(60);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Start MSR Transaction Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    sleep(5);

                    //                    showPiscesResults(globalResults);
                    //
                    //                    memset(globalResults, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                case 3: // Flush Track Data
                    rt = msr_flushTrackData();
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(results, "Flush Track Data Successful");
                    } else {
                        sprintf(results, "Flush Track Data Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
            }
        }
    }
} /* piscesMSRMenu */

void
piscesICCMenu() {
    currentPiscesMenu = 4;

    // Put device into custom display mode (cycle it to clear)
    //	printf("====================================>lcd_customDisplayMode13\n");
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();

        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "ICC Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Enable Passthrough", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Disable Passthrough", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Power On ICC", "4", 0);
    rt = lcd_addItemToList(itemListID, ">> Power Off ICC", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> Send APDU", "6", 0);

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        // Clear input queue
        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            // Poll for event
            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 &&
                  eventData[2] == 0x08) {
                    // Back / Clear was pressed
                    // Return to main menu
                    piscesMainMenu();

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    //                  printf("====================================>lcd_customDisplayMode14\n");
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] && eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    piscesMainMenu();

                    break;
                case 2: // Pass Through On
                {
                    rt = device_enablePassThrough(1);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(results, "Pass Through On Succeeded");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Pass Through On Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
                case 3: // Pass Through Off
                {
                    rt = device_enablePassThrough(0);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(results, "Pass Through Off Succeeded\n");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Pass Through Off Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
                case 4: // Power On ICC
                {
                    int ATRLen = _DATA_BUF_LEN;
                    BYTE ATR[_DATA_BUF_LEN] = { 0 };
                    rt = icc_powerOnICC(ATR, &ATRLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        char ATRString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(ATR, ATRLen, 1, ATRString);

                        strcpy(results, "ICC Power On Succeeded\nATR: ");
                        strcat(results, ATRString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Power On ICC Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
                case 5: // Power Off ICC
                {
                    rt = icc_powerOffICC();

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(results, "ICC Power Off Succeeded\n");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Power Off ICC Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
                case 6: // Send APDU
                {
                    char * strAPDU = "00a404000e315041592e5359532e444446303100";
                    BYTE byteAPDU[800];
                    int byteAPDULen = 800;
                    convertHStrIntoHex(strAPDU, byteAPDU, &byteAPDULen);
                    // output
                    BYTE data[200];
                    int dataLen = 200;
                    rt = icc_exchangeAPDU(byteAPDU, byteAPDULen, data, &dataLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        char dataString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(data, dataLen, 1, dataString);

                        strcpy(results, "Send APDU Succeeded\nAPDU Data: ");
                        strcat(results, dataString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Send APDU Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
            }
        }
    }
} /* piscesICCMenu */

void
piscesEMVMenu() {
    //	currentPiscesMenu = 4;
    previousPiscesMenu = EMV_MENU;
//    printf("====================================>in EMV_MENU\n");

    // Put device into custom display mode (cycle it to clear)
    //	printf("====================================>lcd_customDisplayMode15\n");
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    //	if (rt != RETURN_CODE_DO_SUCCESS) {
    //		printf("====================================>piscesEMVMenu Failed\n");
    //		lcd_resetInitialState();
    //		currentPiscesMenu = MAIN_MENU;
    //		return;
    //	}

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "EMV Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Start EMV Transaction", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Kernel Version", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Kernel Checksum", "4", 0);
    rt = lcd_addItemToList(itemListID, ">> Config Checksum", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve AID", "6", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove AID", "7", 0);
    rt = lcd_addItemToList(itemListID, ">> Save AID", "8", 0);
    rt = lcd_addItemToList(itemListID, ">> List AID", "9", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve Terminal Data", "10", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove Terminal Data", "11", 0);
    rt = lcd_addItemToList(itemListID, ">> Save Terminal Data", "12", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve CAPK", "13", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove CAPK", "14", 0);
    rt = lcd_addItemToList(itemListID, ">> Save CAPK", "15", 0);
    rt = lcd_addItemToList(itemListID, ">> List CAPK", "16", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove All CAPK", "17", 0);
    rt = lcd_addItemToList(itemListID, ">> Load Default CAPK", "18", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve CRL", "19", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove CRL", "20", 0);
    rt = lcd_addItemToList(itemListID, ">> Save CRL", "21", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove All CRL", "22", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve CRL status", "23", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve Transaction Tags", "24", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve Exception List", "25", 0);
    rt = lcd_addItemToList(itemListID, ">> Save Exception", "26", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove Exception", "27", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove All Exceptions", "28", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve Exception Log Status", "29", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove Transaction Log", "30", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve Transaction Log Status", "31", 0);
    rt = lcd_addItemToList(itemListID, ">> Retrieve Transaction Log", "32", 0);

    rt = lcd_addItemToList(itemListID, ">> EMV Complete Transaction", "33", 0);


    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        // Clear input queue
        //		printf("=============================================>lcd_clearEventQueue\n");
        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            if (emvFinished == 0) {
                mssleep(300);
                //              printf("=============================================>continue\n");
                continue;
            }

            if (currentPiscesMenu != EMV_MENU) {
                //              sleep(5);
                if (extMessage == 0) {
                    waitCardRemoval();
                }
                return;
            }

            //          printf("=============================================>lcd_getInputEvent\n");
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            // Poll for event
            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 &&
                  eventData[2] == 0x08) {
                    // Back / Clear was pressed
                    // Return to main menu
                    //                    piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    // Exit application because cancel was pressed

                    //                  printf("=====================================>lcd_customDisplayMode16\n");
                    // Stop custom display mode
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] && eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        if (emvFinished == 1) {
            rt = lcd_getSelectedListItem(itemListID, selectedItem);
        }

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            //            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    //                   piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    break;
                case 2: // Start EMV Transaction
                    memset(globalResults, 0, _CMD_BUF_LEN);

                    emv_setAutoAuthenticateTransaction(1);
                    emv_setAutoCompleteTransaction(0);
                    //                  emv_setAutoCompleteTransaction(1);

                    //                  BYTE tag57[] = {0xDF, 0xEE, 0x1A, 0x01, 0x57};
                    //                  rt = emv_startTransaction(1500.00, 0.00, 2, 1, 120, tag57, 5, 0);

                    emvFinished = 0;
                    extMessage  = 0;
                    isWelcome   = 0;
                    sleep(2);
                    rt = emv_startTransaction(1500.00, 0.00, 2, 1, 120, NULL, 0, 0);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Start EMV Transaction Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                        currentPiscesMenu = RESULT_MENU;
                        waitCardRemoval();
                    }

                    #if 1
                    //                  printf("=======================================>globalResults[0] %d extMessage %d isWelcome %d\n", globalResults[0], extMessage, isWelcome);
                    while (globalResults[0] == 0 /*|| (extMessage == 1 && isWelcome == 0)*/) {
                        //                      printf("=======================================>globalResults[0] %d extMessage %d isWelcome %d\n", globalResults[0], extMessage, isWelcome);
                        sleep(1);
                    }
                    sleep(1);
                    //
                    //                  printf("=======================================>wait end\n");

                    //                  currentPiscesMenu = NO_MENU;

                    //                    showPiscesResults(globalResults);
                    //
                    //                    memset(globalResults, 0, _CMD_BUF_LEN);


                    // test
                    //                  currentPiscesMenu = RESULT_MENU;
                    #else  /* if 1 */
                    currentPiscesMenu = NO_MENU;
                    return;

                    #endif /* if 1 */
                    break;
                case 3: // Kernel Version
                {
                    char kernelVersion[_CMD_BUF_LEN] = { 0 };

                    rt = emv_getEMVKernelVersion(kernelVersion);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Kernel Version: ");
                        strcat(globalResults, kernelVersion);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Get Kernel Version Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    //                  showPiscesResults(results);
                    //                  memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 4: // Kernel Checksum
                {
                    BYTE kernelChecksum[_CMD_BUF_LEN] = { 0 };
                    int kernelChecksumLen = _CMD_BUF_LEN;

                    rt = emv_getEMVKernelCheckValue(kernelChecksum, &kernelChecksumLen);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        char kernelCheckSumString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(kernelChecksum, kernelChecksumLen, 1, kernelCheckSumString);

                        strcpy(globalResults, "Kernel Checksum: ");
                        strcat(globalResults, kernelCheckSumString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Get Kernel Checksum Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    //                  showPiscesResults(results);
                    //                  memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 5: // Config Checksum
                {
                    BYTE configChecksum[_CMD_BUF_LEN] = { 0 };
                    int configChecksumLen = _CMD_BUF_LEN;

                    rt = emv_getEMVConfigurationCheckValue(configChecksum, &configChecksumLen);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        char configChecksumString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(configChecksum, configChecksumLen, 1, configChecksumString);

                        strcpy(globalResults, "Config Checksum: ");
                        strcat(globalResults, configChecksumString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Get Config Checksum Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    //                  showPiscesResults(results);
                    //                  memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 6: // Retrieve AID a0 00 00 00 03 10 10
                {
                    int AIDlen8;
                    int tlvlen8;
                    tlvlen8 = 200;
                    BYTE AID[7] = { 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10 };
                    AIDlen8 = 7;
                    BYTE tlv[200] = { 0 };
                    memset(tlv, 0, 200);
                    rt = emv_retrieveApplicationData(AID, AIDlen8, tlv, &tlvlen8);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve AID  a0 00 00 00 03 10 10 Successful\n");
                        strcat(globalResults, "AID data:\n");
                        char str1[_DATA_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(tlv, tlvlen8, 1, str1);
                        strcat(globalResults, str1);
                        strcat(globalResults, "\n");
                        genTLVString(globalResults, tlv, tlvlen8);
                    } else {
                        sprintf(globalResults, "Retrieve AID  a0 00 00 00 03 10 10 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 7: // Remove AID  a0 00 00 00 03 10 10
                {
                    BYTE AID[7] = { 0xa0, 0x00, 0x00, 0x00, 0x03, 0x10, 0x10 };
                    int AIDlen  = 7;
                    rt = emv_removeApplicationData(AID, AIDlen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove AID  a0 00 00 00 03 10 10 Successful");
                    } else {
                        sprintf(globalResults, "Remove AID  a0 00 00 00 03 10 10 Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 8: // Save AID a0 00 00 00 03 10 10
                {
                    BYTE tlv11[512] = { 0 };
                    int tlvLen11    = 512;
                    char * str2     = "dfee2d01089f0607a0000000031010dfee4b0101dfee2e0110dfee4f0102dfee2f0100";
                    convertHStrIntoHex(str2, tlv11, &tlvLen11);
                    rt = emv_setApplicationDataTLV(tlv11, tlvLen11);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save AID a0 00 00 00 03 10 10 Successful");
                    } else {
                        sprintf(globalResults, "Save AID a0 00 00 00 03 10 10 Failed. Error Code 0x%02X", rt);
                    }
                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 9: // Retrieve AID List
                {
                    BYTE AIDList[_CMD_BUF_LEN] = { 0 };
                    int AIDListLen = _CMD_BUF_LEN;

                    rt = emv_retrieveAIDList(AIDList, &AIDListLen);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        int len = 0;

                        while (len < AIDListLen) {
                            sprintf(globalResults, "%s%s\n", globalResults, &(AIDList[len]));
                            len += strlen(&(AIDList[len])) + 1;
                        }
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "List AID Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //                  showPiscesResults(results);
                    //                  memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 10: // Retrieve Terminal Data
                {
                    BYTE terminalData[_CMD_BUF_LEN] = { 0 };
                    int terminalDataLen = _CMD_BUF_LEN;

                    rt = emv_retrieveTerminalData(terminalData, &terminalDataLen);

                    //                  char results[_CMD_BUF_LEN] = { 0 };

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        char TLVHexString[_CMD_BUF_LEN] = { 0 };
                        char TLVString[_CMD_BUF_LEN]    = { 0 };

                        convertBytesIntoHexStr(terminalData, terminalDataLen, 0, TLVHexString);
                        getTLVString(terminalData, terminalDataLen, TLVString);

                        char * trimmedTLVString = trim(TLVString);

                        strcpy(globalResults, "List Terminal Data Successful. TLVs: \n\n");
                        strcat(globalResults, TLVHexString);
                        strcat(globalResults, "\n\n");
                        strcat(globalResults, trimmedTLVString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "List Terminal Data Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 11: // Remove Terminal Data
                {
                    rt = emv_removeTerminalData();

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove Terminal Data Successful");
                    } else {
                        sprintf(globalResults, "Remove Terminal Data Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 12: // Save Terminal Data
                {
                    BYTE tlv16[512];
                    int tlvlen16       = 512;
                    char * terminalstr =
                      "9f330360f8c89f3501229f4005f000f0a0015f3601029f1a0208409f1e085465726d696e616c9f150212349f160f3030303030303030303030303030309f1c0838373635343332319f4e2231303732312057616c6b65722053742e20437970726573732c204341202c5553412edfee0f0101dfee1006656e66726573dfee110101dfee3e0100dfee150101dfee160100dfee170105dfee180190dfee1e08f0dc3cf0c29e9600dfee1f0180dfee1b083030303135313030dfee20013cdfee21010adfee2203323c3c";
                    convertHStrIntoHex(terminalstr, tlv16, &tlvlen16);
                    rt = emv_setTerminalData(tlv16, tlvlen16);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save Terminal Data Successful");
                    } else {
                        sprintf(globalResults, "Save Terminal Data Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }

                case 13: // Retrieve CAPK
                {
                    unsigned char data[500];
                    int dataLen = 500;
                    char * str2 = "A0 00 00 99 99 E1";
                    unsigned char pdt1[500];
                    int pdt1Len = 500;
                    convertHStrIntoHex(str2, pdt1, &pdt1Len);
                    rt = emv_retrieveCAPK(pdt1, pdt1Len, data, &dataLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve CAPK Successful\n");
                    } else {
                        sprintf(globalResults, "Retrieve CAPK Failed. Error Code 0x%02X", rt);
                    }

                    char str1[1024] = { 0 };
                    convertBytesIntoHexStr(data, dataLen, 1, str1);
                    strcat(globalResults, str1);
                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 14: // Remove CAPK
                {
                    char * str2 = "A0 00 00 99 99 E1";
                    unsigned char pdt1[200];
                    int pdt1Len = 200;
                    convertHStrIntoHex(str2, pdt1, &pdt1Len);
                    rt = emv_removeCAPK(pdt1, pdt1Len);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove CAPK Successful");
                    } else {
                        sprintf(globalResults, "Remove CAPK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 15: // Save CAPK
                {
                    char * str2 =
                      "a000009999e10101f8707b9bedf031e58a9f843631b90c90d80ed69500000003007099c5b70aa61b4f4c51b6f90b0e3bfb7a3ee0e7db41bc466888b3ec8e9977c762407ef1d79e0afb2823100a020c3e8020593db50e90dbeac18b78d13f96bb2f57eeddc30f256592417cdf739ca6804a10a29d2806e774bfa751f22cf3b65b38f37f91b4daf8aec9b803f7610e06ac9e6b";
                    unsigned char pdt1[400];
                    int pdt1Len = 400;
                    convertHStrIntoHex(str2, pdt1, &pdt1Len);
                    rt = emv_setCAPK(pdt1, pdt1Len);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save CAPK Successful");
                    } else {
                        sprintf(globalResults, "Save CAPK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 16: // List CAPK
                {
                    BYTE CAPKList[_CMD_BUF_LEN] = { 0 };
                    int CAPKListLen = _CMD_BUF_LEN;

                    rt = emv_retrieveCAPKList(CAPKList, &CAPKListLen);

                    //                  char results[_CMD_BUF_LEN] = { 0 };

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        char CAPKListHexString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(CAPKList, CAPKListLen, 0, CAPKListHexString);
                        strcpy(globalResults, "List CAPK Successful\n\n");
                        strcat(globalResults, CAPKListHexString);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "List CAPK Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 17: // Remove All CAPK
                {
                    rt = emv_removeAllCAPK();

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove All CAPK Successful");
                    } else {
                        sprintf(globalResults, "Remove All CAPK Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 18: // Load Default CAPK
                {
                    //					char *str22 = "a000009999e10101f8707b9bedf031e58a9f843631b90c90d80ed69500000003007099c5b70aa61b4f4c51b6f90b0e3bfb7a3ee0e7db41bc466888b3ec8e9977c762407ef1d79e0afb2823100a020c3e8020593db50e90dbeac18b78d13f96bb2f57eeddc30f256592417cdf739ca6804a10a29d2806e774bfa751f22cf3b65b38f37f91b4daf8aec9b803f7610e06ac9e6b";
                    char * str22 =
                      "a000009999e10101f8707b9bedf031e58a9f843631b90c90d80ed69500000003007099c5b70aa61b4f4c51b6f90b0e3bfb7a3ee0e7db41bc466888b3ec8e9977c762407ef1d79e0afb2823100a020c3e8020593db50e90dbeac18b78d13f96bb2f57eeddc30f256592417cdf739ca6804a10a29d2806e774bfa751f22cf3b65b38f37f91b4daf8aec9b803f7610e06ac9e6b";
                    unsigned char pdt22[800];
                    int pdt22Len = 800;
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "1. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						 showPiscesResults(results);
                        //						 memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000009999e20101c1056adce9e6f76ea77c89cb832f5a4817907a1a000000037000bd232e348b118eb3f6446ef4da6c3bac9b2ae510c5ad107d38343255d21c4bdf4952a42e92c633b1ce4bfec39afb6dfe147ecbb91d681dac15fb0e198e9a7e4636bdca107bcda3384fcb28b06afef90f099e7084511f3cc010d4343503e1e5a67264b4367daa9a3949499272e9b5022f";
                    //					str22 ="a000009999e20101c1056adce9e6f76ea77c89cb832f5a4817907a1a000000030070bd232e348b118eb3f6446ef4da6c3bac9b2ae510c5ad107d38343255d21c4bdf4952a42e92c633b1ce4bfec39afb6dfe147ecbb91d681dac15fb0e198e9a7e4636bdca107bcda3384fcb28b06afef90f099e7084511f3cc010d4343503e1e5a67264b4367daa9a3949499272e9b5022f";
                    str22 =
                      "a000009999e20101c1056adce9e6f76ea77c89cb832f5a4817907a1a000000030070bd232e348b118eb3f6446ef4da6c3bac9b2ae510c5ad107d38343255d21c4bdf4952a42e92c633b1ce4bfec39afb6dfe147ecbb91d681dac15fb0e198e9a7e4636bdca107bcda3384fcb28b06afef90f099e7084511f3cc010d4343503e1e5a67264b4367daa9a3949499272e9b5022f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "2. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000009999e301011b795cbb0830e2c5231704fa57424d1c4e50f3e4000100017000bc01e12223e1a41e88bffa801093c5f8cec5cd05dbbdbb787ce87249e8808327c2d218991f97a1131e8a25b0122ed11e709c533e8886a1259addfdcbb396604d24e505a2d0b5dd0384fb0002a7a1eb39bc8a11339c7a9433a948337761be73bc497b8e58736da4636538ad282d3cd3db";
                    //					str22 ="a000009999e301011b795cbb0830e2c5231704fa57424d1c4e50f3e4000100010070bc01e12223e1a41e88bffa801093c5f8cec5cd05dbbdbb787ce87249e8808327c2d218991f97a1131e8a25b0122ed11e709c533e8886a1259addfdcbb396604d24e505a2d0b5dd0384fb0002a7a1eb39bc8a11339c7a9433a948337761be73bc497b8e58736da4636538ad282d3cd3db";
                    str22 =
                      "a000009999e301011b795cbb0830e2c5231704fa57424d1c4e50f3e4000100010070bc01e12223e1a41e88bffa801093c5f8cec5cd05dbbdbb787ce87249e8808327c2d218991f97a1131e8a25b0122ed11e709c533e8886a1259addfdcbb396604d24e505a2d0b5dd0384fb0002a7a1eb39bc8a11339c7a9433a948337761be73bc497b8e58736da4636538ad282d3cd3db";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "3. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000009999e40101ac8da3e12324d719c1d5c9e6e8580157196efeb9000000038000cbf2e40f0836c9a5e390a37be3b809bdf5d740cb1da38cfc05d5f8d6b7745b5e9a3fa6961e55ff20412108525e66b970f902f7ff4305dd832cd0763e3aa8b8173f84777100b1047bd1d744509312a0932ed25fed52a959430768ccd902fd8c8ad9123e6addb3f34b92e7924d729cb6473533ae2b2b55bf0e44964fdea8440117";
                    //					str22 ="a000009999e40101ac8da3e12324d719c1d5c9e6e8580157196efeb9000000030080cbf2e40f0836c9a5e390a37be3b809bdf5d740cb1da38cfc05d5f8d6b7745b5e9a3fa6961e55ff20412108525e66b970f902f7ff4305dd832cd0763e3aa8b8173f84777100b1047bd1d744509312a0932ed25fed52a959430768ccd902fd8c8ad9123e6addb3f34b92e7924d729cb6473533ae2b2b55bf0e44964fdea8440117";
                    str22 =
                      "a000009999e40101ac8da3e12324d719c1d5c9e6e8580157196efeb9000000030080cbf2e40f0836c9a5e390a37be3b809bdf5d740cb1da38cfc05d5f8d6b7745b5e9a3fa6961e55ff20412108525e66b970f902f7ff4305dd832cd0763e3aa8b8173f84777100b1047bd1d744509312a0932ed25fed52a959430768ccd902fd8c8ad9123e6addb3f34b92e7924d729cb6473533ae2b2b55bf0e44964fdea8440117";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "4. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000009999e50101ada2349afd118d55af782d37b64651af1ca61ee5000000038000d4fdae94dedbecc6d20d38b01e91826dc6954338379917b2bb8a6b36b5d3b0c5eda60b337448baffebcc3abdba869e8dadec6c870110c42f5aab90a18f4f867f72e3386ffc7e67e7ff94eba079e531b3cf329517e81c5dd9b3dc65db5f9043190be0be897e5fe48adf5d3bfa0585e076e554f26ec69814797f15669f4a255c13";
                    //					str22 ="a000009999e50101ada2349afd118d55af782d37b64651af1ca61ee5000000030080d4fdae94dedbecc6d20d38b01e91826dc6954338379917b2bb8a6b36b5d3b0c5eda60b337448baffebcc3abdba869e8dadec6c870110c42f5aab90a18f4f867f72e3386ffc7e67e7ff94eba079e531b3cf329517e81c5dd9b3dc65db5f9043190be0be897e5fe48adf5d3bfa0585e076e554f26ec69814797f15669f4a255c13";
                    str22 =
                      "a000009999e50101ada2349afd118d55af782d37b64651af1ca61ee5000000030080d4fdae94dedbecc6d20d38b01e91826dc6954338379917b2bb8a6b36b5d3b0c5eda60b337448baffebcc3abdba869e8dadec6c870110c42f5aab90a18f4f867f72e3386ffc7e67e7ff94eba079e531b3cf329517e81c5dd9b3dc65db5f9043190be0be897e5fe48adf5d3bfa0585e076e554f26ec69814797f15669f4a255c13";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "5. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000009999e601018aa4f4648f0dc62ab6aed92554ad1a831bafc9e4000100018000ebf9faecc3e5c315709694664775d3fbda5a504d89344dd920c55696e891d9ab622598a9d6ab8fbf35e4599cab7eb22f956992f8ab2e6535decb6b576fa0675f97c23dd4c374a66e6af419c9d204d0b9f93c08d789d63805660fbb629df1b488cfa1d7a13e9b729437eeafe718efa859348ba0d76812a99f31cd364f2a4fd42f";
                    //					str22 ="a000009999e601018aa4f4648f0dc62ab6aed92554ad1a831bafc9e4000100010080ebf9faecc3e5c315709694664775d3fbda5a504d89344dd920c55696e891d9ab622598a9d6ab8fbf35e4599cab7eb22f956992f8ab2e6535decb6b576fa0675f97c23dd4c374a66e6af419c9d204d0b9f93c08d789d63805660fbb629df1b488cfa1d7a13e9b729437eeafe718efa859348ba0d76812a99f31cd364f2a4fd42f";
                    str22 =
                      "a000009999e601018aa4f4648f0dc62ab6aed92554ad1a831bafc9e4000100010080ebf9faecc3e5c315709694664775d3fbda5a504d89344dd920c55696e891d9ab622598a9d6ab8fbf35e4599cab7eb22f956992f8ab2e6535decb6b576fa0675f97c23dd4c374a66e6af419c9d204d0b9f93c08d789d63805660fbb629df1b488cfa1d7a13e9b729437eeafe718efa859348ba0d76812a99f31cd364f2a4fd42f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "6. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000004fa01017f5acbb96b589f74cb959ed1c35bdb965c3f410600010001f800a4203e0c7beb27097b63c103c19fdcda671aea7f813065756f3b9b81810cbd4bc4dec548fbf1f3cdae51f847235cbf2c8badd8aca7c93bea3d44e80ed6a7b70e29622619db420accce07e1dd4e6c354f359fbdc9c5b70813926f77d827e52b19daf09bfae5274438bb8f61d17753c9ec0a8efa3b7e46f02692160d2653cdbcc71b7d48bd37968316eb444f6504b9421b7dd3035a2c117d8b1f76a8975440da9563618102397b881cef8ada7689edface32482a2dffed656e7f951db841da78368c6293bfc1053a86a845bfa6578e4b69f100b42b558fde1aecec6d250741bc783aa8a68a4261e7bb9246b10587a498d68dd955ce8b2b2433";
                    //					str22 ="a000000004fa01017f5acbb96b589f74cb959ed1c35bdb965c3f41060001000180f0a4203e0c7beb27097b63c103c19fdcda671aea7f813065756f3b9b81810cbd4bc4dec548fbf1f3cdae51f847235cbf2c8badd8aca7c93bea3d44e80ed6a7b70e29622619db420accce07e1dd4e6c354f359fbdc9c5b70813926f77d827e52b19daf09bfae5274438bb8f61d17753c9ec0a8efa3b7e46f02692160d2653cdbcc71b7d48bd37968316eb444f6504b9421b7dd3035a2c117d8b1f76a8975440da9563618102397b881cef8ada7689edface32482a2dffed656e7f951db841da78368c6293bfc1053a86a845bfa6578e4b69f100b42b558fde1aecec6d250741bc783aa8a68a4261e7bb9246b10587a498d68dd955ce8b2b2433";
                    str22 =
                      "a000000004fd0101fc505e4a83ff29a3b1bd28dabf52599b2ae9cb14000100010090c9485dbeb5e40415d1b397524f47685f306cfdc499d4e2e7d0cbaf222cfa8184bd111daeedc9cc6ec8540c3f7271ea9990119cc5c43180501d9f45252d6835053fae35696ae8cd67a325647449cf5e594da8f627209f7f03ae8d6dfc0db3e79e28e415df29a5b57d6814856cc30a96da5b8890363e507fcb2e283da1ebb5f18e8e24102b7d0192bb8e35a4f7cd05a435";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000004fb0101fc787db138f994a0c554cc6734eb3e48a55066cc0001000190009b170603a489c7546c45da57b8ffd1db2061240f0e8c6d1f9abdc6b265aa8911915c1a4eabd8d0ed4755d1b902ba06fe5a645b786cd241295517d44ef1a7c25d75afe0eb28066e4d69fee7abafdd5eeb230f14e402c9840825fa77ead12b5f1c5494701de1897f65fe6bf106d47545ebf70ce7c158068c61f0773534db742ab83c28038c1494f15905d0ad17cf1bd38d";
                    //					str22 ="a000000004fb0101fc787db138f994a0c554cc6734eb3e48a55066cc0001000100909b170603a489c7546c45da57b8ffd1db2061240f0e8c6d1f9abdc6b265aa8911915c1a4eabd8d0ed4755d1b902ba06fe5a645b786cd241295517d44ef1a7c25d75afe0eb28066e4d69fee7abafdd5eeb230f14e402c9840825fa77ead12b5f1c5494701de1897f65fe6bf106d47545ebf70ce7c158068c61f0773534db742ab83c28038c1494f15905d0ad17cf1bd38d";
                    str22 =
                      "a000000004fe01018535f14cbd6b4ae5028618fab5ac1106549fd03c000100010090e76317965175a08bee510f58830e87b262c70d529803245fa8b88e0c753562de7aeb5a9e3e6c1a98e94d8db7c31407dac5d071e06b80b09e146f22db85f1d72d1ea18d22600032c6dd40e3714d5ada7de9d7d01e88391f893156d6f4bf13e9063559da0786de9bde6b1c9b0bb968edde07145abf877b931682ccb1fb800728724d04af241e2827e0fa1f62591914ff25";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "7. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000004fc0101db50b5b0d966300760b1e42125277ba833b6523400010001f800b3296c91f4795bd97112606903407b6eff3ab39246e91095e51d17867da4ade59a48be2fe9b52710283d3d32260e2c7d247214c57d46aa6465e47e0a4b3ffaad8a7f6a190755bccfe3f3fb3989a9f6b1c9e1845bcccad6f20b1dac6033600234e81dac4153212b0f760c23099192aa6c4c9083beffd9a79d2a27b08fecc8e5d437d6c68550a839b1294151daba9d9cb2f160f60f749289f500c8c7f334bd20ebac4ab109cf3c182f1b781c7c097a7903530746c449b99e39e4db6493dd2a02e37c62ae8bc9a7470ecccf8dc06a18c33cd24b30d56f25d2755ce82aa4de4d2eaec07750a03db75ebd0d8ebc9f2a1d85a0d252eff40329be05";
                    //					str22 ="a000000004fc0101db50b5b0d966300760b1e42125277ba833b652340001000180f0b3296c91f4795bd97112606903407b6eff3ab39246e91095e51d17867da4ade59a48be2fe9b52710283d3d32260e2c7d247214c57d46aa6465e47e0a4b3ffaad8a7f6a190755bccfe3f3fb3989a9f6b1c9e1845bcccad6f20b1dac6033600234e81dac4153212b0f760c23099192aa6c4c9083beffd9a79d2a27b08fecc8e5d437d6c68550a839b1294151daba9d9cb2f160f60f749289f500c8c7f334bd20ebac4ab109cf3c182f1b781c7c097a7903530746c449b99e39e4db6493dd2a02e37c62ae8bc9a7470ecccf8dc06a18c33cd24b30d56f25d2755ce82aa4de4d2eaec07750a03db75ebd0d8ebc9f2a1d85a0d252eff40329be05";
                    str22 =
                      "a000000004ff0101439eb23d8a71b99f879c1a1f1765252d840b9a74000100010090f69dbb5e15983eae3ccf31cf4e47098c2fc16f97a0c710f84777efa99622d86502b138728ab12e3481a84d20e014ad2d634d2836f27f294924b895a87f91f81b8169d4dfdad8d7cbd741804cd61b467c7a9acfeceb71188caa73a907547699d45c9c7d2098ac2966266417f665a46bdd012c097dbd33d1d11aff6ec8a9c0ad814a65b48262ca011636079a328c1aaeb7";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "8. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000004fd0101fc505e4a83ff29a3b1bd28dabf52599b2ae9cb14000100019000c9485dbeb5e40415d1b397524f47685f306cfdc499d4e2e7d0cbaf222cfa8184bd111daeedc9cc6ec8540c3f7271ea9990119cc5c43180501d9f45252d6835053fae35696ae8cd67a325647449cf5e594da8f627209f7f03ae8d6dfc0db3e79e28e415df29a5b57d6814856cc30a96da5b8890363e507fcb2e283da1ebb5f18e8e24102b7d0192bb8e35a4f7cd05a435";
                    //					str22 ="a000000004fd0101fc505e4a83ff29a3b1bd28dabf52599b2ae9cb14000100010090c9485dbeb5e40415d1b397524f47685f306cfdc499d4e2e7d0cbaf222cfa8184bd111daeedc9cc6ec8540c3f7271ea9990119cc5c43180501d9f45252d6835053fae35696ae8cd67a325647449cf5e594da8f627209f7f03ae8d6dfc0db3e79e28e415df29a5b57d6814856cc30a96da5b8890363e507fcb2e283da1ebb5f18e8e24102b7d0192bb8e35a4f7cd05a435";
                    str22 =
                      "a000000065020101b973e9f377b419c36ac9696ed95ffb25c8020687000100010080bb7f51983fd8707fd6227c23def5d5377a5a737cef3c5252e578efe136df87b50473f9341f1640c8d258034e14c16993fce6c6b8c3ceeb65fc8fbcd8eb77b3b05ac7c4d09e0fa1ba2efe87d3184db6718ae41a7cad89b8dce0fe80ceb523d5d647f9db58a31d2e71ac677e67fa6e75820736c9893761ee4acd11f31dbdc349ef";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "9. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000004fe01018535f14cbd6b4ae5028618fab5ac1106549fd03c000100019000e76317965175a08bee510f58830e87b262c70d529803245fa8b88e0c753562de7aeb5a9e3e6c1a98e94d8db7c31407dac5d071e06b80b09e146f22db85f1d72d1ea18d22600032c6dd40e3714d5ada7de9d7d01e88391f893156d6f4bf13e9063559da0786de9bde6b1c9b0bb968edde07145abf877b931682ccb1fb800728724d04af241e2827e0fa1f62591914ff25";
                    //					str22 ="a000000004fe01018535f14cbd6b4ae5028618fab5ac1106549fd03c000100010090e76317965175a08bee510f58830e87b262c70d529803245fa8b88e0c753562de7aeb5a9e3e6c1a98e94d8db7c31407dac5d071e06b80b09e146f22db85f1d72d1ea18d22600032c6dd40e3714d5ada7de9d7d01e88391f893156d6f4bf13e9063559da0786de9bde6b1c9b0bb968edde07145abf877b931682ccb1fb800728724d04af241e2827e0fa1f62591914ff25";
                    str22 =
                      "a000000003500101b769775668cacb5d22a647d1d993141edab7237b000100010080d11197590057b84196c2f4d11a8f3c05408f422a35d702f90106ea5b019bb28ae607aa9cdebcd0d81a38d48c7ebb0062d287369ec0c42124246ac30d80cd602ab7238d51084ded4698162c59d25eac1e66255b4db2352526ef0982c3b8ad3d1cce85b01db5788e75e09f44be7361366def9d1e1317b05e5d0ff5290f88a0db47";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "10. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000004ff0101439eb23d8a71b99f879c1a1f1765252d840b9a74000100019000f69dbb5e15983eae3ccf31cf4e47098c2fc16f97a0c710f84777efa99622d86502b138728ab12e3481a84d20e014ad2d634d2836f27f294924b895a87f91f81b8169d4dfdad8d7cbd741804cd61b467c7a9acfeceb71188caa73a907547699d45c9c7d2098ac2966266417f665a46bdd012c097dbd33d1d11aff6ec8a9c0ad814a65b48262ca011636079a328c1aaeb7";
                    //					str22 ="a000000004ff0101439eb23d8a71b99f879c1a1f1765252d840b9a74000100010090f69dbb5e15983eae3ccf31cf4e47098c2fc16f97a0c710f84777efa99622d86502b138728ab12e3481a84d20e014ad2d634d2836f27f294924b895a87f91f81b8169d4dfdad8d7cbd741804cd61b467c7a9acfeceb71188caa73a907547699d45c9c7d2098ac2966266417f665a46bdd012c097dbd33d1d11aff6ec8a9c0ad814a65b48262ca011636079a328c1aaeb7";
                    str22 =
                      "a000000003510101b9d248075a3f23b522fe45573e04374dc4995d71000000030090db5fa29d1fda8c1634b04dccff148abee63c772035c79851d3512107586e02a917f7c7e885e7c4a7d529710a145334ce67dc412cb1597b77aa2543b98d19cf2cb80c522bdbea0f1b113fa2c86216c8c610a2d58f29cf3355ceb1bd3ef410d1edd1f7ae0f16897979de28c6ef293e0a19282bd1d793f1331523fc71a228800468c01a3653d14c6b4851a5c029478e757f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "11. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000065020101b973e9f377b419c36ac9696ed95ffb25c8020687000100018000bb7f51983fd8707fd6227c23def5d5377a5a737cef3c5252e578efe136df87b50473f9341f1640c8d258034e14c16993fce6c6b8c3ceeb65fc8fbcd8eb77b3b05ac7c4d09e0fa1ba2efe87d3184db6718ae41a7cad89b8dce0fe80ceb523d5d647f9db58a31d2e71ac677e67fa6e75820736c9893761ee4acd11f31dbdc349ef";
                    //					str22 ="a000000065020101b973e9f377b419c36ac9696ed95ffb25c8020687000100010080bb7f51983fd8707fd6227c23def5d5377a5a737cef3c5252e578efe136df87b50473f9341f1640c8d258034e14c16993fce6c6b8c3ceeb65fc8fbcd8eb77b3b05ac7c4d09e0fa1ba2efe87d3184db6718ae41a7cad89b8dce0fe80ceb523d5d647f9db58a31d2e71ac677e67fa6e75820736c9893761ee4acd11f31dbdc349ef";
                    str22 =
                      "a0000000039601017616e9ac8be014af88ca11a8fb17967b7394030e000000030080b74586d19a207be6627c5b0aafbc44a2ecf5a2942d3a26ce19c4ffaeee920521868922e893e7838225a3947a2614796fb2c0628ce8c11e3825a56d3b1bbaef783a5c6a81f36f8625395126fa983c5216d3166d48acde8a431212ff763a7f79d9edb7fed76b485de45beb829a3d4730848a366d3324c3027032ff8d16a1e44d8d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "12. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a0000000650301017dc435dbde093d1f0ad0bae0fea4dc12056413dc00000003f800c9e6c1f3c6949a8a42a91f8d0224132b2865e6d953a5b5a54cffb0412439d54aeba79e9b399a6c104684df3fb727c7f55984db7a450e6aa917e110a7f2343a0024d2785d9ebe09f601d592362fdb237700b567ba14bbe2a6d3d23cf1270b3dd822b5496549bf884948f55a0d308348c4b723bafb6a7f3975ac397cad3c5d0fc2d178716f5e8e79e75beb1c84fa202f80e68069a984e008706b30c212305456201540787925e86a8b28b129a11af204b387cb6ee43db53d15a46e13901bebd5cecf4854251d9e9875b16e82ad1c5938a972842c8f1a42ebb5ae5336b04ff3da8b8dfbe606fca8b9084ee05bf67950ba89897cd089f924dbcd";
                    //					str22 ="a0000000650301017dc435dbde093d1f0ad0bae0fea4dc12056413dc0000000380f0c9e6c1f3c6949a8a42a91f8d0224132b2865e6d953a5b5a54cffb0412439d54aeba79e9b399a6c104684df3fb727c7f55984db7a450e6aa917e110a7f2343a0024d2785d9ebe09f601d592362fdb237700b567ba14bbe2a6d3d23cf1270b3dd822b5496549bf884948f55a0d308348c4b723bafb6a7f3975ac397cad3c5d0fc2d178716f5e8e79e75beb1c84fa202f80e68069a984e008706b30c212305456201540787925e86a8b28b129a11af204b387cb6ee43db53d15a46e13901bebd5cecf4854251d9e9875b16e82ad1c5938a972842c8f1a42ebb5ae5336b04ff3da8b8dfbe606fca8b9084ee05bf67950ba89897cd089f924dbcd";
                    str22 =
                      "a000000003570101251a5f5de61cf28b5c6e2b5807c0644a01d46ff5000100010060942b7f2ba5ea307312b63df77c5243618acc2002bd7ecb74d821fe7bdc78bf28f49f74190ad9b23b9713b140ffec1fb429d93f56bdc7ade4ac075d75532c1e590b21874c7952f29b8c0f0c1ce3aeedc8da25343123e71dcf86c6998e15f756e3";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "13. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000003500101b769775668cacb5d22a647d1d993141edab7237b000100018000d11197590057b84196c2f4d11a8f3c05408f422a35d702f90106ea5b019bb28ae607aa9cdebcd0d81a38d48c7ebb0062d287369ec0c42124246ac30d80cd602ab7238d51084ded4698162c59d25eac1e66255b4db2352526ef0982c3b8ad3d1cce85b01db5788e75e09f44be7361366def9d1e1317b05e5d0ff5290f88a0db47";
                    //					str22 ="a000000003500101b769775668cacb5d22a647d1d993141edab7237b000100010080d11197590057b84196c2f4d11a8f3c05408f422a35d702f90106ea5b019bb28ae607aa9cdebcd0d81a38d48c7ebb0062d287369ec0c42124246ac30d80cd602ab7238d51084ded4698162c59d25eac1e66255b4db2352526ef0982c3b8ad3d1cce85b01db5788e75e09f44be7361366def9d1e1317b05e5d0ff5290f88a0db47";
                    str22 =
                      "a000000025600101894b8df19bdc691103c3b93979f5ee28c05888a7000100010090a8ee74edef3c0dca5102ff9b5707975ff67b60d64b5e7322d48de9d3bb6153f63512a091b606dd8fd5f6a14588324ef8827844c7ffc0bab2334ae5207770078b69cdc3f2c666cf69e28e16e1816714c4df313bef539cc01da9dd2d6f47de4f247c500b561c099166ad4fc16df12dfb684ac48d35cdd2c47a13a86a5a162306f64e33b092ab74eda71a4091d96e3daa47";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "14. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000003510101b9d248075a3f23b522fe45573e04374dc4995d71000000039000db5fa29d1fda8c1634b04dccff148abee63c772035c79851d3512107586e02a917f7c7e885e7c4a7d529710a145334ce67dc412cb1597b77aa2543b98d19cf2cb80c522bdbea0f1b113fa2c86216c8c610a2d58f29cf3355ceb1bd3ef410d1edd1f7ae0f16897979de28c6ef293e0a19282bd1d793f1331523fc71a228800468c01a3653d14c6b4851a5c029478e757f";
                    //					str22 ="a000000003510101b9d248075a3f23b522fe45573e04374dc4995d71000000030090db5fa29d1fda8c1634b04dccff148abee63c772035c79851d3512107586e02a917f7c7e885e7c4a7d529710a145334ce67dc412cb1597b77aa2543b98d19cf2cb80c522bdbea0f1b113fa2c86216c8c610a2d58f29cf3355ceb1bd3ef410d1edd1f7ae0f16897979de28c6ef293e0a19282bd1d793f1331523fc71a228800468c01a3653d14c6b4851a5c029478e757f";
                    str22 =
                      "a000000152d00101de1bb8a37cddbceaab043aaef81634120349726d000100010090d05c2a09d09c9031366ec092bcac67d4b1b4f88b10005e1fc45c1b483ae7eb86ff0e884a19c0595a6c34f06386d776a21d620fc9f9c498adca00e66d129bcdd4789837b96dcc7f09da94ccac5ac7cfc07f4600df78e493dc1957deba3f4838a4b8bd4cefe4e4c6119085e5bb21077341c568a21d65d049d666807c39c401cdfee7f7f99b8f9cb34a8841ea62e83e8d63";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "15. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000003530101ac213a2e0d2c0ca35ad0201323536d58097e4e5700000003f800bcd83721be52cccc4b6457321f22a7dc769f54eb8025913be804d9eabbfa19b3d7c5d3ca658d768caf57067eec83c7e6e9f81d0586703ed9dddadd20675d63424980b10eb364e81eb37db40ed100344c928886ff4ccc37203ee6106d5b59d1ac102e2cd2d7ac17f4d96c398e5fd993ecb4ffdf79b17547ff9fa2aa8eefd6cbda124cbb17a0f8528146387135e226b005a474b9062ff264d2ff8efa36814aa2950065b1b04c0a1ae9b2f69d4a4aa979d6ce95fee9485ed0a03aee9bd953e81cfd1ef6e814dfd3c2ce37aefa38c1f9877371e91d6a5eb59fdedf75d3325fa3ca66cdfba0e57146cc789818ff06be5fcc50abd362ae4b80996d";
                    //					str22 ="a000000003530101ac213a2e0d2c0ca35ad0201323536d58097e4e570000000380f0bcd83721be52cccc4b6457321f22a7dc769f54eb8025913be804d9eabbfa19b3d7c5d3ca658d768caf57067eec83c7e6e9f81d0586703ed9dddadd20675d63424980b10eb364e81eb37db40ed100344c928886ff4ccc37203ee6106d5b59d1ac102e2cd2d7ac17f4d96c398e5fd993ecb4ffdf79b17547ff9fa2aa8eefd6cbda124cbb17a0f8528146387135e226b005a474b9062ff264d2ff8efa36814aa2950065b1b04c0a1ae9b2f69d4a4aa979d6ce95fee9485ed0a03aee9bd953e81cfd1ef6e814dfd3c2ce37aefa38c1f9877371e91d6a5eb59fdedf75d3325fa3ca66cdfba0e57146cc789818ff06be5fcc50abd362ae4b80996d";
                    str22 =
                      "a000000333c001018b094d260bdf8bfc8b9a88b0c177a43fe2fae765000100010090c7cdb6f2a3fe80a8834cdddd326e1082aa2288f47c464d57b34718193431711a44119148055044cfe3313708bed0c98e1c589b0f53cf6d7e829fcd906d21a90fd4cb6baf13110c4685107c27e00981db29dc0ac186e6d701577f23865626244e1f9b2cd1ddfcb9e899b41f5084d8ccc178a7c3f4546cf93187106fab055a7ac67df62e778cb88823ba58cf7546c2b09f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    #if 0
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "16. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a0000000039601017616e9ac8be014af88ca11a8fb17967b7394030e000000038000b74586d19a207be6627c5b0aafbc44a2ecf5a2942d3a26ce19c4ffaeee920521868922e893e7838225a3947a2614796fb2c0628ce8c11e3825a56d3b1bbaef783a5c6a81f36f8625395126fa983c5216d3166d48acde8a431212ff763a7f79d9edb7fed76b485de45beb829a3d4730848a366d3324c3027032ff8d16a1e44d8d";
                    str22 =
                      "a0000000039601017616e9ac8be014af88ca11a8fb17967b7394030e000000030080b74586d19a207be6627c5b0aafbc44a2ecf5a2942d3a26ce19c4ffaeee920521868922e893e7838225a3947a2614796fb2c0628ce8c11e3825a56d3b1bbaef783a5c6a81f36f8625395126fa983c5216d3166d48acde8a431212ff763a7f79d9edb7fed76b485de45beb829a3d4730848a366d3324c3027032ff8d16a1e44d8d";

                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "17. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000003570101251a5f5de61cf28b5c6e2b5807c0644a01d46ff5000100016000942b7f2ba5ea307312b63df77c5243618acc2002bd7ecb74d821fe7bdc78bf28f49f74190ad9b23b9713b140ffec1fb429d93f56bdc7ade4ac075d75532c1e590b21874c7952f29b8c0f0c1ce3aeedc8da25343123e71dcf86c6998e15f756e3";
                    str22 =
                      "a000000003570101251a5f5de61cf28b5c6e2b5807c0644a01d46ff5000100010060942b7f2ba5ea307312b63df77c5243618acc2002bd7ecb74d821fe7bdc78bf28f49f74190ad9b23b9713b140ffec1fb429d93f56bdc7ade4ac075d75532c1e590b21874c7952f29b8c0f0c1ce3aeedc8da25343123e71dcf86c6998e15f756e3";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "18. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000003580101753ed0aa23e4cd5abd69eae7904b684a34a57c2200010001c80099552c4a1ecd68a0260157fc4151b5992837445d3fc57365ca5692c87be358cdcdf2c92fb6837522842a48eb11cdffe2fd91770c7221e4af6207c2de4004c7dee1b6276dc62d52a87d2cd01fbf2dc4065db52824d2a2167a06d19e6a0f781071cdb2dd314cb94441d8dc0e936317b77bf06f5177f6c5aba3a3bc6aa30209c97260b7a1ad3a192c9b8cd1d153570afcc87c3cd681d13e997fe33b3963a0a1c79772acf991033e1b8397ad0341500e48a24770bc4cbe19d2ccf419504fdbf0389bc2f2fdcd4d44e61f";
                    str22 =
                      "a000000003580101753ed0aa23e4cd5abd69eae7904b684a34a57c220001000180c099552c4a1ecd68a0260157fc4151b5992837445d3fc57365ca5692c87be358cdcdf2c92fb6837522842a48eb11cdffe2fd91770c7221e4af6207c2de4004c7dee1b6276dc62d52a87d2cd01fbf2dc4065db52824d2a2167a06d19e6a0f781071cdb2dd314cb94441d8dc0e936317b77bf06f5177f6c5aba3a3bc6aa30209c97260b7a1ad3a192c9b8cd1d153570afcc87c3cd681d13e997fe33b3963a0a1c79772acf991033e1b8397ad0341500e48a24770bc4cbe19d2ccf419504fdbf0389bc2f2fdcd4d44e61f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "19. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a00000000354010106960618791a86d387301edd4a3baf2d34fef1b400010001f800c6ddc0b7645f7f16286ab7e4116655f56dd0c944766040dc68664dd973bd3bfd4c525bcbb95272b6b3ad9ba8860303ad08d9e8cc344a4070f4cfb9eeaf29c8a3460850c264cda39bbe3a7e7d08a69c31b5c8dd9f94ddbc9265758c0e7399adcf4362caee458d414c52b498274881b196dacca7273f687f2a65faeb809d4b2ac1d3d1efb4f6490322318bd296d153b307a3283ab4e5be6ebd910359a8565eb9c4360d24baaca3dbfe393f3d6c830d603c6fc1e83409dfcd80d3a33ba243813bbb4ceaf9cbab6b74b00116f72ab278a88a011d70071e06cab140646438d986d48281624b85b3b2ebb9a6ab3bf2178fcc3011e7caf24897ae7d";
                    str22 =
                      "a00000000354010106960618791a86d387301edd4a3baf2d34fef1b40001000180f0c6ddc0b7645f7f16286ab7e4116655f56dd0c944766040dc68664dd973bd3bfd4c525bcbb95272b6b3ad9ba8860303ad08d9e8cc344a4070f4cfb9eeaf29c8a3460850c264cda39bbe3a7e7d08a69c31b5c8dd9f94ddbc9265758c0e7399adcf4362caee458d414c52b498274881b196dacca7273f687f2a65faeb809d4b2ac1d3d1efb4f6490322318bd296d153b307a3283ab4e5be6ebd910359a8565eb9c4360d24baaca3dbfe393f3d6c830d603c6fc1e83409dfcd80d3a33ba243813bbb4ceaf9cbab6b74b00116f72ab278a88a011d70071e06cab140646438d986d48281624b85b3b2ebb9a6ab3bf2178fcc3011e7caf24897ae7d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "20. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000025600101894b8df19bdc691103c3b93979f5ee28c05888a7000100019000a8ee74edef3c0dca5102ff9b5707975ff67b60d64b5e7322d48de9d3bb6153f63512a091b606dd8fd5f6a14588324ef8827844c7ffc0bab2334ae5207770078b69cdc3f2c666cf69e28e16e1816714c4df313bef539cc01da9dd2d6f47de4f247c500b561c099166ad4fc16df12dfb684ac48d35cdd2c47a13a86a5a162306f64e33b092ab74eda71a4091d96e3daa47";
                    str22 =
                      "a000000025600101894b8df19bdc691103c3b93979f5ee28c05888a7000100010090a8ee74edef3c0dca5102ff9b5707975ff67b60d64b5e7322d48de9d3bb6153f63512a091b606dd8fd5f6a14588324ef8827844c7ffc0bab2334ae5207770078b69cdc3f2c666cf69e28e16e1816714c4df313bef539cc01da9dd2d6f47de4f247c500b561c099166ad4fc16df12dfb684ac48d35cdd2c47a13a86a5a162306f64e33b092ab74eda71a4091d96e3daa47";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "21. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000025600101894b8df19bdc691103c3b93979f5ee28c05888a7000100019000a8ee74edef3c0dca5102ff9b5707975ff67b60d64b5e7322d48de9d3bb6153f63512a091b606dd8fd5f6a14588324ef8827844c7ffc0bab2334ae5207770078b69cdc3f2c666cf69e28e16e1816714c4df313bef539cc01da9dd2d6f47de4f247c500b561c099166ad4fc16df12dfb684ac48d35cdd2c47a13a86a5a162306f64e33b092ab74eda71a4091d96e3daa47";
                    str22 =
                      "a000000025600101894b8df19bdc691103c3b93979f5ee28c05888a7000100010090a8ee74edef3c0dca5102ff9b5707975ff67b60d64b5e7322d48de9d3bb6153f63512a091b606dd8fd5f6a14588324ef8827844c7ffc0bab2334ae5207770078b69cdc3f2c666cf69e28e16e1816714c4df313bef539cc01da9dd2d6f47de4f247c500b561c099166ad4fc16df12dfb684ac48d35cdd2c47a13a86a5a162306f64e33b092ab74eda71a4091d96e3daa47";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "22. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000025610101cccf27c49c15b2a9410ec6089223a3a01ea8433e00010001f80086c7254665e17ce6934df7d082569f208d1cc1ad8e9fb2fe23e3d7467be50b4f874f906adf2280ec9d204f6d10c037a23ce5fd8283c9ed47d1c669abdd7c1cb356c70bcdc44e5c8ae231555f7b786ac9c3155bcd51f28efbc1b33cc87277049219b2c890952736c4713487111678911d9f42e08074cf524e65d721d727f054e6b5e85ec92b3eb59ffee926dd6c314df555c94ad487a99b67cb7c7ba5e46a5b813ddb918b8e3e0423f4302a58686d1263c0baca9e82068c493289e3e6936eca5f9f77e06b0d6fbda718818b835020098c671c5dd7e9b8e8e841d2df32ee94a7f4748484ca44108ab241a5263ba1ff00d51360dddc749d30a1";
                    str22 =
                      "a000000025610101cccf27c49c15b2a9410ec6089223a3a01ea8433e0001000180f086c7254665e17ce6934df7d082569f208d1cc1ad8e9fb2fe23e3d7467be50b4f874f906adf2280ec9d204f6d10c037a23ce5fd8283c9ed47d1c669abdd7c1cb356c70bcdc44e5c8ae231555f7b786ac9c3155bcd51f28efbc1b33cc87277049219b2c890952736c4713487111678911d9f42e08074cf524e65d721d727f054e6b5e85ec92b3eb59ffee926dd6c314df555c94ad487a99b67cb7c7ba5e46a5b813ddb918b8e3e0423f4302a58686d1263c0baca9e82068c493289e3e6936eca5f9f77e06b0d6fbda718818b835020098c671c5dd7e9b8e8e841d2df32ee94a7f4748484ca44108ab241a5263ba1ff00d51360dddc749d30a1";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "23. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000152d00101de1bb8a37cddbceaab043aaef81634120349726d000100019000d05c2a09d09c9031366ec092bcac67d4b1b4f88b10005e1fc45c1b483ae7eb86ff0e884a19c0595a6c34f06386d776a21d620fc9f9c498adca00e66d129bcdd4789837b96dcc7f09da94ccac5ac7cfc07f4600df78e493dc1957deba3f4838a4b8bd4cefe4e4c6119085e5bb21077341c568a21d65d049d666807c39c401cdfee7f7f99b8f9cb34a8841ea62e83e8d63";
                    str22 =
                      "a000000152d00101de1bb8a37cddbceaab043aaef81634120349726d000100010090d05c2a09d09c9031366ec092bcac67d4b1b4f88b10005e1fc45c1b483ae7eb86ff0e884a19c0595a6c34f06386d776a21d620fc9f9c498adca00e66d129bcdd4789837b96dcc7f09da94ccac5ac7cfc07f4600df78e493dc1957deba3f4838a4b8bd4cefe4e4c6119085e5bb21077341c568a21d65d049d666807c39c401cdfee7f7f99b8f9cb34a8841ea62e83e8d63";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "24. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000152d10101ffda858cb2af08b79d750cc97fa6efe2ef228dda00010001f800a71af977c1079304d6dff3f665ab6db3fbdfa1b170287ac6d7bc0afcb7a202a4c815e1fc2e34f75a052564ee2148a39cd6b0f39cfaef95f0294a86c3198e349ff82eece633d50e5860a15082b4b342a90928024057dd51a2401d781b67ae7598d5d1ff26a441970a19a3a58011ca19284279a85567d3119264806caf761122a71fc0492ac8d8d42b036c394fc494e03b43600d7e02cb5267755ace64437cfa7b475ad40ddc93b8c9bcad63801fc492fd251640e41fd13f6e231f56f97283447ab44cbe11910db3c75243784aa9bdf57539c31b51c9f35bf8bc2495762881255478264b792bbdca6498777ae9120ed935bb3e8bea3eab13d9";
                    str22 =
                      "a000000152d10101ffda858cb2af08b79d750cc97fa6efe2ef228dda0001000180f0a71af977c1079304d6dff3f665ab6db3fbdfa1b170287ac6d7bc0afcb7a202a4c815e1fc2e34f75a052564ee2148a39cd6b0f39cfaef95f0294a86c3198e349ff82eece633d50e5860a15082b4b342a90928024057dd51a2401d781b67ae7598d5d1ff26a441970a19a3a58011ca19284279a85567d3119264806caf761122a71fc0492ac8d8d42b036c394fc494e03b43600d7e02cb5267755ace64437cfa7b475ad40ddc93b8c9bcad63801fc492fd251640e41fd13f6e231f56f97283447ab44cbe11910db3c75243784aa9bdf57539c31b51c9f35bf8bc2495762881255478264b792bbdca6498777ae9120ed935bb3e8bea3eab13d9";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "25. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000333c001018b094d260bdf8bfc8b9a88b0c177a43fe2fae765000100019000c7cdb6f2a3fe80a8834cdddd326e1082aa2288f47c464d57b34718193431711a44119148055044cfe3313708bed0c98e1c589b0f53cf6d7e829fcd906d21a90fd4cb6baf13110c4685107c27e00981db29dc0ac186e6d701577f23865626244e1f9b2cd1ddfcb9e899b41f5084d8ccc178a7c3f4546cf93187106fab055a7ac67df62e778cb88823ba58cf7546c2b09f";
                    str22 =
                      "a000000333c001018b094d260bdf8bfc8b9a88b0c177a43fe2fae765000100010090c7cdb6f2a3fe80a8834cdddd326e1082aa2288f47c464d57b34718193431711a44119148055044cfe3313708bed0c98e1c589b0f53cf6d7e829fcd906d21a90fd4cb6baf13110c4685107c27e00981db29dc0ac186e6d701577f23865626244e1f9b2cd1ddfcb9e899b41f5084d8ccc178a7c3f4546cf93187106fab055a7ac67df62e778cb88823ba58cf7546c2b09f";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "26. Load Default CAPK Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    pdt22Len = 800;
                    //			str22 ="a000000333c10101b6372db9919f8c6c9c88e83d3c600a4ad8adc7a900010001f80092f083cbe46f8dcc0c04e498ba9952ba9d4c09c80dd277e579f07e45772846fa43dd3ab31cc6b08dd18695715949fb108e53a071d393a7fddbf9c5fb0b0507138797317480fc48d633ed38b401a451443ad7f15facda45a62abe24ff6343add0909ea8389348e54e26f842880d1a69f9214368ba30c18de5c5e0cb9253b5abc55fb6ef0a738d927494a30bbf82e340285363b6faa15673829dbb210e710da58ee9e578e7ce55dc812ab7d6dcce0e3b1ae179d664f3356eb951e3c91a1cbbf6a7ca8d0c7ec9c6af7a4941c5051099b9784e56c9162067b8c3b15c5fa4480a645cd2526a69c80ba8ef361be2aa9417defce35b62b0c9cf097d";
                    str22 =
                      "a000000333c10101b6372db9919f8c6c9c88e83d3c600a4ad8adc7a90001000180f092f083cbe46f8dcc0c04e498ba9952ba9d4c09c80dd277e579f07e45772846fa43dd3ab31cc6b08dd18695715949fb108e53a071d393a7fddbf9c5fb0b0507138797317480fc48d633ed38b401a451443ad7f15facda45a62abe24ff6343add0909ea8389348e54e26f842880d1a69f9214368ba30c18de5c5e0cb9253b5abc55fb6ef0a738d927494a30bbf82e340285363b6faa15673829dbb210e710da58ee9e578e7ce55dc812ab7d6dcce0e3b1ae179d664f3356eb951e3c91a1cbbf6a7ca8d0c7ec9c6af7a4941c5051099b9784e56c9162067b8c3b15c5fa4480a645cd2526a69c80ba8ef361be2aa9417defce35b62b0c9cf097d";
                    convertHStrIntoHex(str22, pdt22, &pdt22Len);
                    rt = emv_setCAPK(pdt22, pdt22Len);
                    #endif /* if 0 */
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "27. Load Default CAPK Failed. Error Code 0x%02X", rt);
                    } else {
                        sprintf(globalResults, "Load Default CAPK Succeeded\n");
                    }
                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 19: // Retrieve CRL
                {
                    BYTE CRL[_CMD_BUF_LEN] = { 0 };
                    int CRLLen = _CMD_BUF_LEN;

                    rt = emv_retrieveCRL(CRL, &CRLLen);

                    //                  char results[_CMD_BUF_LEN] = { 0 };

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        int i = 0;
                        int certificateLen = (CRL[0] << 24) | (CRL[1] << 16) | (CRL[2] << 8) | CRL[3];
                        for (i = 0; i < certificateLen; i++) {
                            sprintf(globalResults, "%s%02x%02x%02x%02x%02x%02x%02x%02x%02x\n", globalResults,
                              CRL[i * 9 + 12], CRL[i * 9 + 13], CRL[i * 9 + 14], CRL[i * 9 + 15], CRL[i * 9 + 16],
                              CRL[i * 9 + 17], CRL[i * 9 + 18], CRL[i * 9 + 19], CRL[i * 9 + 20]);
                        }
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "List CRL Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 20: // Remove CRL
                {
                    BYTE list23[500];
                    int lsLen23   = 500;
                    char * crlstr = "A000000004F8";
                    convertHStrIntoHex(crlstr, list23, &lsLen23);
                    rt = emv_removeCRL(list23, lsLen23);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove CRL Successful");
                    } else {
                        sprintf(globalResults, "Remove CRL Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 21: // Save CRL
                {
                    BYTE list25[500];
                    int lsLen25     = 500;
                    char * crlstr25 = "A000000004F8001000";
                    convertHStrIntoHex(crlstr25, list25, &lsLen25);
                    rt = emv_setCRL(list25, lsLen25);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save CRL Successful");
                    } else {
                        sprintf(globalResults, "Save CRL Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 22: // Remove All CRL
                {
                    rt = emv_removeAllCAPK();

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove All CRL Successful");
                    } else {
                        sprintf(globalResults, "Remove All CRL Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 23: // Retrieve CRL status
                {
                    BYTE status[500] = { 0 };
                    int statusLen    = 500;
                    memset(status, 0, statusLen);

                    rt = emv_retrieveCRLStatus(status, &statusLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve CRL status Successful\n");
                        char str[50];
                        sprintf(str, "Version Number: %02X%02x%02x%02x\n", status[0], status[1], status[2], status[3]);
                        strcat(globalResults, str);
                        sprintf(str, "Number of Records: %02X%02x%02x%02x\n", status[4], status[5], status[6],
                          status[7]);
                        strcat(globalResults, str);
                        sprintf(str, "Size of Record: %02X%02x%02x%02X\n", status[8], status[9], status[10],
                          status[11]);
                        strcat(globalResults, str);
                    } else {
                        sprintf(globalResults, "Retrieve CRL status Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 24: // Retrieve Transaction Tags
                {
                    BYTE tags[7] = { 0x9f, 0x02, 0x9f, 0x03, 0x9c, 0x57, 0x5A };

                    IDTTransactionData cardData;

                    rt = emv_retrieveTransactionResult(tags, 7, &cardData);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve Transaction Tags Successful\n");
                        strcat(globalResults, "\nUnencrypted Tags\n");
                        genTLVString(globalResults, cardData.emv_unencryptedTags, cardData.emv_unencryptedTagsLen);
                        strcat(globalResults, "\nEncrypted Tags\n");
                        genTLVString(globalResults, cardData.emv_encryptedTags, cardData.emv_encryptedTagsLen);
                        strcat(globalResults, "\nMasked Tags\n");
                        genTLVString(globalResults, cardData.emv_maskedTags, cardData.emv_maskedTagsLen);
                    } else {
                        sprintf(globalResults, "Retrieve Transaction Tags Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 25: // Retrieve Exception List
                {
                    BYTE exceptionList[500] = { 0 };
                    int exceptionListLen    = 500;
                    memset(exceptionList, 0, exceptionListLen);

                    rt = emv_retrieveExceptionList(exceptionList, &exceptionListLen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve Exception List Successful\n");
                        strcat(globalResults, "Exception List:\n");
                        char exceptionListString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(exceptionList, exceptionListLen, 0, exceptionListString);
                        strcat(globalResults, exceptionListString);
                    } else {
                        sprintf(globalResults, "Retrieve Exception List Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 26: // Save Exception
                {
                    BYTE exception[500] = { 0 };
                    int exceptionLen    = 500;

                    char * exceptionStr = "085413339000001596FFFF00";
                    convertHStrIntoHex(exceptionStr, exception, &exceptionLen);

                    rt = emv_setException(exception, exceptionLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Save Exception Successful");
                    } else {
                        sprintf(globalResults, "Save Exception Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 27: // Remove Exception
                {
                    BYTE exception[500] = { 0 };
                    int exceptionLen    = 500;

                    char * exceptionStr = "085413339000001596FFFF00";
                    convertHStrIntoHex(exceptionStr, exception, &exceptionLen);

                    rt = emv_removeException(exception, exceptionLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove Exception Successful");
                    } else {
                        sprintf(globalResults, "Remove Exception Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 28: // Remove All Exceptions
                {
                    rt = emv_removeAllExceptions();

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove All Exceptions Successful");
                    } else {
                        sprintf(globalResults, "Remove All Exceptions Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 29: // Retrieve Exception Log Status
                {
                    BYTE exceptionLogStatus[500] = { 0 };
                    int exceptionLogStatusLen    = 500;
                    //					memset(exceptionLogStatus, 0, exceptionLogStatusLen);

                    rt = emv_retrieveExceptionLogStatus(exceptionLogStatus, &exceptionLogStatusLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve Exception Log Status Successful\n");
                        char str[50];
                        sprintf(str, "Version Number: %02X%02x%02x%02x\n", exceptionLogStatus[0], exceptionLogStatus[1],
                          exceptionLogStatus[2], exceptionLogStatus[3]);
                        strcat(globalResults, str);
                        sprintf(str, "Number of Records: %02X%02x%02x%02x\n", exceptionLogStatus[4],
                          exceptionLogStatus[5], exceptionLogStatus[6], exceptionLogStatus[7]);
                        strcat(globalResults, str);
                        sprintf(str, "Size of Record: %02X%02x%02x%02X\n", exceptionLogStatus[8], exceptionLogStatus[9],
                          exceptionLogStatus[10], exceptionLogStatus[11]);
                        strcat(globalResults, str);
                    } else {
                        sprintf(globalResults, "Retrieve Exception Log Status Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 30: // Remove Transaction Log
                {
                    rt = emv_removeTransactionLog();

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove Transaction Log Successful");
                    } else {
                        sprintf(globalResults, "Remove Transaction Log Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 31: // Retrieve Transaction Log Status
                {
                    BYTE transactionLogStatus[500] = { 0 };
                    int transactionLogStatusLen    = 500;
                    memset(transactionLogStatus, 0, transactionLogStatusLen);

                    rt = emv_retrieveTransactionLogStatus(transactionLogStatus, &transactionLogStatusLen);

                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve Transaction Log Status Successful\n");
                        char str[50];
                        sprintf(str, "Version Number: %02X%02x%02x%02x\n", transactionLogStatus[0],
                          transactionLogStatus[1], transactionLogStatus[2], transactionLogStatus[3]);
                        strcat(globalResults, str);
                        sprintf(str, "Number of Records: %02X%02x%02x%02x\n", transactionLogStatus[4],
                          transactionLogStatus[5], transactionLogStatus[6], transactionLogStatus[7]);
                        strcat(globalResults, str);
                        sprintf(str, "Size of Record: %02X%02x%02x%02X\n", transactionLogStatus[8],
                          transactionLogStatus[9], transactionLogStatus[10], transactionLogStatus[11]);
                        strcat(globalResults, str);
                    } else {
                        sprintf(globalResults, "Retrieve Transaction Log Status Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 32: // Retrieve Transaction Log
                {
                    BYTE transactionLog[500]       = { 0 };
                    int transactionLogLen          = 500;
                    int remainingTransactionLogLen = 500;
                    memset(transactionLog, 0, transactionLogLen);

                    rt = emv_retrieveTransactionLog(transactionLog, &transactionLogLen, &remainingTransactionLogLen);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Retrieve Transaction Log Successful\n");
                        char str[50] = { 0 };
                        sprintf(str, "Number of Records Remaining: %d\n", remainingTransactionLogLen);
                        strcat(globalResults, str);
                        strcat(globalResults, "Transaction Log: \n");
                        char transactionLogString[_CMD_BUF_LEN] = { 0 };
                        convertBytesIntoHexStr(transactionLog, transactionLogLen, 0, transactionLogString);
                        strcat(globalResults, transactionLogString);
                    } else {
                        sprintf(globalResults, "Retrieve Transaction Log Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 33: // Complete EMV Transaction
                    memset(globalResults, 0, _CMD_BUF_LEN);

                    unsigned char data1[20];
                    int dataLen1 = 20;
                    unsigned char data2[20];
                    int dataLen2 = 20;

                    const char * str1 = "30 30";
                    int r = convertHStrIntoHex(str1, data1, &dataLen1);
                    const char * str2 = "11 22 33 44 55 66 77 88 30 30";
                    convertHStrIntoHex(str2, data2, &dataLen2);
                    emvFinished = 0;
                    sleep(2);
                    rt = emv_completeTransaction(0, data1, dataLen1, data2, dataLen2, NULL, 0, NULL, 0);

                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "EMV Complete Transaction Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                        currentPiscesMenu = RESULT_MENU;
                        waitCardRemoval();
                    }

                    while (globalResults[0] == 0) {
                        sleep(1);
                    }
                    sleep(2);

                    break;
            }
        }
    }
} /* piscesEMVMenu */

void
piscesLCDMenu() {
    //	currentPiscesMenu = 5;
    previousPiscesMenu = LCD_MENU;

    // Put device into custom display mode (cycle it to clear)
    //	printf("====================================>lcd_customDisplayMode17\n");
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();
        currentPiscesMenu = MAIN_MENU;

        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "LCD Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Reset Initial State", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Start Custom Display Mode", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Stop Custom Display Mode", "4", 0);
    rt = lcd_addItemToList(itemListID, ">> Set Colors", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> Clear Display", "6", 0);
    rt = lcd_addItemToList(itemListID, ">> Capture Signature", "7", 0);
    rt = lcd_addItemToList(itemListID, ">> Start Default Slideshow", "8", 0);
    rt = lcd_addItemToList(itemListID, ">> Remove Background", "9", 0);
    rt = lcd_addItemToList(itemListID, ">> Set Default Background", "10", 0);

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    // Clear screen and display current menu on cancel / back / enter
    int displayCurrentMenu = 0;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;


                        displayCurrentMenu = 0;

                        return;
                    }

                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x08) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    // Back / Clear was pressed
                    // Return to main menu
                    //                    piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    //                  printf("====================================>lcd_customDisplayMode18\n");
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] && eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            //            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    //                   piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    break;
                case 2: // Reset Initial State
                {
                    rt = lcd_resetInitialState();
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Reset Initial State Successful");
                    } else {
                        sprintf(globalResults, "Reset Initial State Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }

                //                  rt = lcd_customDisplayMode(0); // Stop custom display mode to allow user input on capture signature screen
                //
                //                  // Reset state if we could not put device into custom display mode
                //                  if (rt != RETURN_CODE_DO_SUCCESS) {
                //                      lcd_resetInitialState();
                //
                //                      return;
                //                  }
                //
                //                  rt = lcd_captureSignature(60);
                //
                //                  if (rt == RETURN_CODE_DO_SUCCESS)
                //                      strcat(results, "Capture Signature Successful");
                //                  else {
                //                      char errorDescription[_CMD_BUF_LEN] = { 0 };
                //
                //                      device_getIDGStatusCodeString(rt, errorDescription);
                //                      sprintf(results, "Capture Signature Failed. Error Code 0x%02X: %s", rt, errorDescription);
                //                  }
                //
                //                  sleep(1);
                //
                //                    showPiscesResults(results);
                //                    memset(results, 0, _CMD_BUF_LEN);

                //                    break;
                case 3: // Start Custom Display Mode
                {
                    rt = lcd_customDisplayMode(1);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Start Custom Display Mode Successful");
                    } else {
                        sprintf(globalResults, "Start Custom Display Mode Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                //                {
                //                  stayInMenu = 1;
                //                  displayCurrentMenu = 1;
                //
                //                  // Put device into custom display mode (cycle it to clear)
                //                  int rt = lcd_customDisplayMode(0);
                //                  rt = lcd_customDisplayMode(1);
                //
                //                  // Reset state if we could not put device into custom display mode
                //                  if (rt != RETURN_CODE_DO_SUCCESS) {
                //                      lcd_resetInitialState();
                //
                //                      return;
                //                  }
                //
                //                  rt = lcd_startSlideShow("DefaultSlideShow", strlen("DefaultSlideShow"), 0, 0, 2, 1, 0, 1, 3, 0, 1);
                //
                //                  if (rt == RETURN_CODE_DO_SUCCESS)
                //                      strcat(results, "Start Default Slide Show Successful");
                //                  else {
                //                      char errorDescription[_CMD_BUF_LEN] = { 0 };
                //
                //                      device_getIDGStatusCodeString(rt, errorDescription);
                //                      sprintf(results, "Get Kernel Version Failed. Error Code 0x%02X: %s", rt, errorDescription);
                //                  }
                //
                //                    break;
                //                }
                case 4: // Stop Custom Display Mode
                {
                    //					printf("====================================>lcd_customDisplayMode19\n");
                    rt = lcd_customDisplayMode(0);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Stop Custom Display Mode Successful");
                    } else {
                        sprintf(globalResults, "Stop Custom Display Mode Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 5: // Set Colors
                {
                    BYTE foreRGB[] = { 0xFF, 0xFF, 0xFF };
                    BYTE backRGB[] = { 0x00, 0x00, 0x00 };
                    rt = lcd_setForeBackColor(foreRGB, 3, backRGB, 3);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Set Colors Successful");
                        sleep(3);
                    } else {
                        sprintf(globalResults, "Set Colors Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 6: // Clear Display
                {
                    rt = lcd_clearDisplay(0);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Clear Display Successful");
                        sleep(3);
                    } else {
                        sprintf(globalResults, "Clear Display Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 7: // Capture Signature
                {
                    rt = lcd_captureSignature(60);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Capture Signature Successful");
                        sleep(60);
                    } else {
                        sprintf(globalResults, "Capture Signature Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 8: // Start Default Slideshow
                {
                    char directory[_DATA_BUF_LEN];
                    int directoryLen = _DATA_BUF_LEN;
                    rt = device_listDirectory(NULL, 0, 1, 0, directory, &directoryLen);

                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "List Directory Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }

                    if (NULL == strstr(directory, "DefaultSlideShow/")) {
                        // create folder
                        device_createDirectory("DefaultSlideShow", 16);
                        // transfer files
                        int i;
                        int failed = 0;
                        for (i = 1; i <= 8; i++) {
                            char out_filename[50];
                            sprintf(out_filename, "DefaultSlideShow/img%d.png", i);
                            char in_filename[50];
                            sprintf(in_filename, "../Resources/%3d.png", i);
                            BYTE fileData[166000];
                            int fileDataLen;
                            FILE * fp;
                            if (NULL == (fp = fopen(in_filename, "rb"))) {
                                sprintf(globalResults, "Could not open file %s\n", in_filename);
                                //								showPiscesResults(results);
                                //								memset(results, 0, _CMD_BUF_LEN);
                                currentPiscesMenu = RESULT_MENU;
                                failed = 1;
                                break;
                            }
                            fseek(fp, 0, SEEK_END);
                            fileDataLen = ftell(fp);
                            if (fileDataLen > 166000) {
                                sprintf(globalResults, "Not enough buffer\n");
                                //								showPiscesResults(results);
                                //								memset(results, 0, _CMD_BUF_LEN);
                                currentPiscesMenu = RESULT_MENU;
                                failed = 1;
                                break;
                            }

                            fseek(fp, 0, SEEK_SET);
                            fread(fileData, fileDataLen, 1, fp);
                            fclose(fp);

                            rt = device_transferFile(out_filename, strlen(out_filename), fileData, fileDataLen);
                            if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                                sprintf(globalResults, "Transfer File Failed. Error Code 0x%02X", rt);
                                //								showPiscesResults(results);
                                //								memset(results, 0, _CMD_BUF_LEN);
                                currentPiscesMenu = RESULT_MENU;
                                failed = 1;
                                break;
                            }
                        }
                        if (failed == 1) {
                            break;
                        }
                    } else {
                        int i;
                        int failed = 0;
                        for (i = 1; i <= 8; i++) {
                            char out_filename[50];
                            sprintf(out_filename, "DefaultSlideShow/img%d.png", i);
                            char in_filename[50];
                            sprintf(in_filename, "../Resources/%3d.png", i);
                            if (NULL == strstr(directory, out_filename)) {
                                //						device_createDirectory("DefaultBackground");
                                // Read in the file
                                BYTE fileData[166000];
                                int fileDataLen;
                                FILE * fp;
                                if (NULL == (fp = fopen(in_filename, "rb"))) {
                                    sprintf(globalResults, "Could not open file %s\n", in_filename);
                                    //									showPiscesResults(results);
                                    //									memset(results, 0, _CMD_BUF_LEN);
                                    currentPiscesMenu = RESULT_MENU;
                                    failed = 1;
                                    break;
                                }

                                fseek(fp, 0, SEEK_END);
                                fileDataLen = ftell(fp);
                                if (fileDataLen > 35000) {
                                    sprintf(globalResults, "Not enough buffer\n");
                                    //									showPiscesResults(results);
                                    //									memset(results, 0, _CMD_BUF_LEN);
                                    currentPiscesMenu = RESULT_MENU;
                                    failed = 1;
                                    break;
                                }
                                fseek(fp, 0, SEEK_SET);
                                fread(fileData, fileDataLen, 1, fp);
                                fclose(fp);
                                rt = device_transferFile(out_filename, strlen(out_filename), fileData, fileDataLen);
                                if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                                    sprintf(globalResults, "Transfer File Failed. Error Code 0x%02X", rt);
                                    //									showPiscesResults(results);
                                    //									memset(results, 0, _CMD_BUF_LEN);
                                    currentPiscesMenu = RESULT_MENU;
                                    failed = 1;
                                    break;
                                }
                            }
                        }
                        if (failed == 1) {
                            break;
                        }
                    }
                    //					printf("====================================>lcd_customDisplayMode20\n");
                    lcd_customDisplayMode(0);
                    lcd_customDisplayMode(1);
                    rt = lcd_startSlideShow("DefaultSlideShow", strlen("DefaultSlideShow"), 0, 0, 2, 1, 0, 1, 3, 0, 1);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Start Default Slideshow Successful");
                        sleep(30);
                    } else {
                        sprintf(globalResults, "Start Default Slideshow Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 9: // Remove Background
                {
                    //					printf("====================================>lcd_customDisplayMode21\n");
                    lcd_customDisplayMode(0);
                    lcd_customDisplayMode(1);
                    rt = lcd_setBackgroundImage(NULL, 0, 0);
                    //					printf("====================================>lcd_customDisplayMode22\n");
                    lcd_customDisplayMode(0);
                    lcd_resetInitialState();
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Remove Background Successful");
                    } else {
                        sprintf(globalResults, "Remove Background Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
                case 10: // Set Default Background
                {
                    char directory[_DATA_BUF_LEN];
                    int directoryLen = _DATA_BUF_LEN;
                    rt = device_listDirectory(NULL, 0, 1, 0, directory, &directoryLen);
                    if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        sprintf(globalResults, "List Directory Failed. Error Code 0x%02X", rt);
                        //						showPiscesResults(results);
                        //						memset(results, 0, _CMD_BUF_LEN);
                        currentPiscesMenu = RESULT_MENU;
                        break;
                    }
                    if (NULL == strstr(directory, "DefaultBackground/default.png")) {
                        device_createDirectory("DefaultBackground", 17);
                        // Read in the file
                        BYTE fileData[35000];
                        int fileDataLen;
                        FILE * fp;
                        if (NULL == (fp = fopen("../Resources/default.png", "rb"))) {
                            sprintf(globalResults, "Could not open file ../Resources/default.png\n");
                            //							showPiscesResults(results);
                            //							memset(results, 0, _CMD_BUF_LEN);
                            currentPiscesMenu = RESULT_MENU;
                            break;
                        }

                        fseek(fp, 0, SEEK_END);
                        fileDataLen = ftell(fp);
                        if (fileDataLen > 35000) {
                            sprintf(globalResults, "Not enough buffer\n");
                            //							showPiscesResults(results);
                            //							memset(results, 0, _CMD_BUF_LEN);
                            currentPiscesMenu = RESULT_MENU;
                            break;
                        }

                        fseek(fp, 0, SEEK_SET);
                        fread(fileData, fileDataLen, 1, fp);
                        fclose(fp);

                        rt = device_transferFile("DefaultBackground/default.png", strlen(
                                "DefaultBackground/default.png"), fileData, fileDataLen);
                        if (rt != IDG_P2_STATUS_CODE_DO_SUCCESS) {
                            sprintf(globalResults, "Transfer File Failed. Error Code 0x%02X", rt);
                            //							showPiscesResults(results);
                            //							memset(results, 0, _CMD_BUF_LEN);
                            currentPiscesMenu = RESULT_MENU;
                            break;
                        }
                    }
                    //					printf("====================================>lcd_customDisplayMode23\n");
                    lcd_customDisplayMode(0);
                    lcd_customDisplayMode(1);
                    rt = lcd_setBackgroundImage("DefaultBackground/default.png", strlen(
                            "DefaultBackground/default.png"), 1);
                    //					printf("====================================>lcd_customDisplayMode24\n");
                    lcd_customDisplayMode(0);
                    lcd_resetInitialState();
                    //			device_calibrateParameters(0x02);
                    if (rt == IDG_P2_STATUS_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Set Default Background Successful");
                        sleep(3);
                    } else {
                        sprintf(globalResults, "Set Default Background Failed. Error Code 0x%02X", rt);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;
                    break;
                }
            }
        }
    }
} /* piscesLCDMenu */

void
piscesPINMenu() {
    //	currentPiscesMenu = 6;
    previousPiscesMenu = PIN_MENU;

    // Put device into custom display mode (cycle it to clear)
    //	printf("====================================>lcd_customDisplayMode25\n");
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();
        currentPiscesMenu = MAIN_MENU;

        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "PIN Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Capture PIN", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Get PAN", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Prompt Credit / Debit", "4", 0);

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    // Clear screen and display current menu on cancel / back / enter
    int displayCurrentMenu = 0;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x08) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    // Back / Clear was pressed
                    // Return to main menu
                    //                    piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    //                  printf("====================================>lcd_customDisplayMode26\n");
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Check for screen button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] && eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            //            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    //                   piscesMainMenu();
                    currentPiscesMenu = MAIN_MENU;

                    break;
                case 2: // Capture PIN
                    //                  printf("====================================>lcd_customDisplayMode27\n");
                    rt = lcd_customDisplayMode(0); // Stop custom display mode to allow user input on capture signature screen

                    // Reset state if we could not put device into custom display mode
                    if (rt != RETURN_CODE_DO_SUCCESS) {
                        lcd_resetInitialState();
                        currentPiscesMenu = MAIN_MENU;

                        return;
                    }

                    rt = pin_getEncryptedOnlinePIN(0, 20);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        //                      strcpy(globalResults, "Capture PIN Successful");
                        sleep(1);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Capture PIN Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //                  sleep(1);

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                case 3: // Get PAN
                {
                    rt = pin_getPAN(1, 120);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Get PAN Successful");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Get PAN Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //					showPiscesResults(results);
                    //					memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
                case 4: // Prompt Credit / Debit
                {
                    BYTE retData[4];
                    int retDataLen = 4;
                    rt = pin_promptCreditDebit("$", 1, "1.00", 4, 20, retData, &retDataLen);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(globalResults, "Prompt Credit / Debit Successful");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(globalResults, "Prompt Credit / Debit Failed. Error Code 0x%02X: %s", rt,
                          errorDescription);
                    }

                    //                  sleep(1);

                    //                    showPiscesResults(results);
                    //                    memset(results, 0, _CMD_BUF_LEN);
                    currentPiscesMenu = RESULT_MENU;

                    break;
                }
            }
        }
    }
} /* piscesPINMenu */

void
piscesWSMenu() {
    currentPiscesMenu = 7;

    // Put device into custom display mode (cycle it to clear)
    //	printf("====================================>lcd_customDisplayMode28\n");
    int rt = lcd_customDisplayMode(0);
    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        lcd_resetInitialState();

        return;
    }

    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "WS Menu", NULL);

    BYTE executeButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Execute", 255, 255, 255, 0, 0, 0, executeButtonID);

    BYTE itemListID[4] = { 0 };
    rt = lcd_createList(11, 55, 17, 10, 1, 4, 1, 1, 1, 1, 1, itemListID);

    rt = lcd_addItemToList(itemListID, ">> Back To Main Menu", "1", 1);
    rt = lcd_addItemToList(itemListID, ">> Request CSR", "2", 0);
    rt = lcd_addItemToList(itemListID, ">> Load Certificate", "3", 0);
    rt = lcd_addItemToList(itemListID, ">> Revoke Certificate", "4", 0);
    rt = lcd_addItemToList(itemListID, ">> Delete Certificate", "5", 0);
    rt = lcd_addItemToList(itemListID, ">> Get Cert Chain Status", "6", 0);
    rt = lcd_addItemToList(itemListID, ">> Update Roor Cert", "7", 0);

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Some commands do not warrant switching menus after execution
    int stayInMenu = 1;

    // Clear screen and display current menu on cancel / back / enter
    int displayCurrentMenu = 0;

    while (stayInMenu) {
        // Do not stay in menu unless required
        stayInMenu = 0;

        rt = lcd_clearEventQueue();

        // Keep polling for user input
        while (1) {
            memset(eventType, 0, 4);
            memset(eventGraphicsID, 0, 4);
            memset(eventData, 0, 73);

            int dataReceived = 0;
            rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

            if (!dataReceived) {
                sleep(1); // Poll every second
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
              eventType[3] == 0x03) { // Keypad input
                if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    break; // Exit loop and process selection because enter was pressed
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x08) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    // Back / Clear was pressed
                    // Return to main menu
                    piscesMainMenu();

                    return;
                } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                    if (displayCurrentMenu) {
                        //                      displayPreviousMenu();
                        currentPiscesMenu = MAIN_MENU;

                        displayCurrentMenu = 0;

                        return;
                    }

                    // Exit application because cancel was pressed

                    // Stop custom display mode
                    //                  printf("====================================>lcd_customDisplayMode29\n");
                    lcd_customDisplayMode(0);

                    // Reset state
                    lcd_resetInitialState();
                    exitDemo = 1;

                    return;
                }
            } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Check for screen button press
                if (eventData[0] == 0x01 && eventGraphicsID[0] == executeButtonID[0] &&
                  eventGraphicsID[1] == executeButtonID[1] &&
                  eventGraphicsID[2] == executeButtonID[2] && eventGraphicsID[3] == executeButtonID[3]) {
                    break;  // Exit loop and process selection because execution button was pressed
                }
            }
        }

        char selectedItem[32] = { 0 };
        rt = lcd_getSelectedListItem(itemListID, selectedItem);

        // We received the selected item
        if (strlen(selectedItem) > 0) {
            int lineNum = atoi(selectedItem);

            int rt = 0;
            char results[_CMD_BUF_LEN] = { 0 };

            switch (lineNum) {
                case 1: // Back to Main Menu
                    piscesMainMenu();

                    break;
                case 2: // Request CSR
                {
                    RequestCSR csr;
                    memset(&csr, 0, sizeof(RequestCSR));
                    rt = ws_requestCSR(&csr);
                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(results, "Request CSR Successful");
                        char tmp[100] = { 0 };
                        sprintf(tmp, "CSR Encrypting Keys: %s\n", csr.encKeysName);
                        strcat(results, tmp);
                        sprintf(tmp, "%s\n\n", csr.encKeysCSR);
                        strcat(results, tmp);
                        sprintf(tmp, "CSR Validating/Signing Keys: %s\n", csr.encSigningName);
                        strcat(results, tmp);
                        sprintf(tmp, "%s\n\n", csr.encSigningCSR);
                        strcat(results, tmp);
                        sprintf(tmp, "CSR Validating/Signing 3rd Party Apps: %s\n", csr.encAppsName);
                        strcat(results, tmp);
                        sprintf(tmp, "%s\n\n", csr.encAppsCSR);
                        strcat(results, tmp);
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Request CSR Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }
                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);
                    break;
                }
                case 3: // Load Certificate
                {
                    rt = ws_loadSSLCert("1.00", 4, "1.00", 4);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(results, "Load Certificate Successful");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Load Certificate Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
                case 4: // Revoke Certificate
                {
                    rt = ws_revokeSSLCert("123", 3);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(results, "Revoke Certificate Successful");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Revoke Certificate Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    //                  sleep(1);

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
                case 5: // Delete Certificate
                {
                    rt = ws_deleteSSLCert("123", 3);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(results, "Delete Certificate Successful");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Delete Certificate Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);
                    break;
                }
                case 6: // Get Cert Chain Status
                {
                    int type;
                    rt = ws_getCertChainType(&type);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        if (type == 1) {
                            strcpy(results, "Get Cert Chain Status Succeeded\nCert Chain Type: Production\n");
                        } else {
                            strcpy(results, "Get Cert Chain Status Succeeded\nCert Chain Type: Test\n");
                        }
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Get Cert Chain Status Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }

                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);
                    break;
                }
                case 7: // Update Roor Cert
                {
                    rt = ws_updateRootCertificate("1.00", 4, "1.00", 4, "1.00", 4);

                    if (rt == RETURN_CODE_DO_SUCCESS) {
                        strcpy(results, "Update Roor Cert Successful");
                    } else {
                        char errorDescription[_CMD_BUF_LEN] = { 0 };

                        device_getIDGStatusCodeString(rt, errorDescription);
                        sprintf(results, "Update Roor Cert Failed. Error Code 0x%02X: %s", rt, errorDescription);
                    }
                    showPiscesResults(results);
                    memset(results, 0, _CMD_BUF_LEN);

                    break;
                }
            }
        }
    }
} /* piscesWSMenu */

void
getSDKVersion() {
    #if 0
    char SDKVersion[_CMD_BUF_LEN] = { 0 };
    char libraryVersion[64]       = { 0 };

    int rc = config_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcpy(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get config library version failed. Error code 0x%02x: %s\n", rc, errorDescription);

        strcpy(&SDKVersion[strlen(SDKVersion)], errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = ctls_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get ctls library version failed. Error code 0x%02x: %s\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = device_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get device library version failed. Error code 0x%02x: %s\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = emv_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get emv library version failed. Error code 0x%02x: %s\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = icc_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get icc library version failed. Error code 0x%02x: %s\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = msr_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get msr library version failed. Error code 0x%02x: %s\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = lcd_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get lcd library version failed. Error code 0x%02x: %s\n\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    memset(libraryVersion, 0, 64);
    rc = pin_getVersion(libraryVersion);

    if (rc == RETURN_CODE_DO_SUCCESS) {
        strcat(SDKVersion, libraryVersion);
        strcat(SDKVersion, "\n");
    } else {
        char errorMessage[_CMD_BUF_LEN] = { 0 };
        char errorDescription[256]      = { 0 };

        device_getIDGStatusCodeString(rc, errorDescription);

        sprintf(errorMessage, "Get pin library version failed. Error code 0x%02x: %s\n\n", rc, errorDescription);

        strcat(SDKVersion, errorMessage);
    }

    /*
     * memset(libraryVersion, 0, 64);
     * rc = crypto_getVersion(libraryVersion);
     *
     * if (rc == RETURN_CODE_DO_SUCCESS) {
     *  strcat(SDKVersion, libraryVersion);
     *  strcat(SDKVersion, "\n");
     * } else {
     *  char errorMessage[_CMD_BUF_LEN] = { 0 };
     *  char errorDescription[256] = {0};
     *
     *  device_getResponseCodeString(rc, errorDescription);
     *
     *  sprintf(errorMessage, "Get crypto library version failed. Error code 0x%02x: %s\n\n", rc, errorDescription);
     *
     *  strcat(SDKVersion, errorMessage);
     * }
     */
    //	showPiscesResults(SDKVersion);
    #endif /* if 0 */
    //	showPiscesResults(SDK_Version());
    strcpy(globalResults, SDK_Version());
    currentPiscesMenu = RESULT_MENU;
} /* getSDKVersion */

void
showPiscesResults(char * results) {
    // Put device into custom display mode (cycle it to clear)
    //	printf("==================================>lcd_customDisplayMode30\n");
    int rt = lcd_customDisplayMode(0);

    rt = lcd_customDisplayMode(1);

    // Reset state if we could not put device into custom display mode
    if (rt != RETURN_CODE_DO_SUCCESS) {
        //		displayPreviousMenu();
        currentPiscesMenu = previousPiscesMenu;
        return;
    }


    // Clear the screen twice due to background redraw issue
    rt = lcd_clearDisplay(0);
    rt = lcd_clearDisplay(0);

    rt = lcd_displayText(0, 15, 0, 0, 1, 9, 0, "Response", NULL);

    BYTE backButtonID[4] = { 0 };
    rt = lcd_displayButton(0, 350, 0, 0, 1, 9, 0, "Back", 255, 255, 255, 0, 0, 0, backButtonID);

    if (strlen(results) > 0) {
        char * trimmedResults = trim(results);

        // Divide results because paragraph display cannot break up continuous text
        // Insert space before maximum line width is met
        char buffer[RESULTS_BUF_LEN] = { 0 };
        int position     = 0;
        int spaceCounter = 0;
        const int MAX_CHARS_PER_LINE = 18;

        int i;
        for (i = 0; i < strlen(trimmedResults); i++) {
            spaceCounter++;

            // Insert space if there is not one within 18 characters
            if (spaceCounter >= MAX_CHARS_PER_LINE) {
                buffer[position++] = 0x20;
                spaceCounter       = 0;
            }

            BYTE byteData = trimmedResults[i];

            // Insert a space before line feed
            if (byteData == 0x0A || byteData == 0x0D) {
                buffer[position++] = 0x20;
            }
            buffer[position++] = byteData;

            // Insert a space after line feed
            if (byteData == 0x0A || byteData == 0x0D) {
                buffer[position++] = 0x20;
            }
            // Reset space counter if one is found
            if (isspace(byteData)) {
                spaceCounter = 0;
            }
        }

        memset(results, 0, _CMD_BUF_LEN);
        if (strlen(buffer) > 3999) {
            strncpy(results, buffer, 3999);  // Display text can not be more than 3999 characters
        } else {
            strcpy(results, buffer);
        }
        rt = lcd_displayParagraph(7, 55, 304, 292, 1, 4, 2, results);
    } else { // Display "No Data Available" if there are no results
        rt = lcd_displayParagraph(7, 55, 304, 292, 1, 4, 2, "No Data Available");
    }

    if (rt != RETURN_CODE_DO_SUCCESS) { // Display "Cannot display string. Unexpected format"
        rt = lcd_displayParagraph(7, 55, 304, 292, 1, 4, 2, "Cannot display string. Unexpected format");
    }

    rt = lcd_clearEventQueue();

    BYTE eventType[4]       = { 0 };
    BYTE eventGraphicsID[4] = { 0 };
    BYTE eventData[73]      = { 0 };

    // Keep polling for user input
    while (1) {
        memset(eventType, 0, 4);
        memset(eventGraphicsID, 0, 4);
        memset(eventData, 0, 73);

        // Poll for event
        int dataReceived = 0;
        rt = lcd_getInputEvent(0, &dataReceived, eventType, eventGraphicsID, eventData);

        if (!dataReceived) {
            sleep(1); // Poll every second
        } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 &&
          eventType[3] == 0x03) { // Keypad input
            if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x0D) {
                break; // Exit loop because enter was pressed
            } else if (eventData[0] == 0x01 && eventData[1] == 0x00 &&
              eventData[2] == 0x08) {
                // Back / Clear was pressed
                // Exit loop and return to previous menu
                break;
            } else if (eventData[0] == 0x01 && eventData[1] == 0x00 && eventData[2] == 0x1B) {
                // Exit application because cancel was pressed

                // Stop custom display mode
                //              printf("==================================>lcd_customDisplayMode31\n");
                lcd_customDisplayMode(0);

                // Reset state
                lcd_resetInitialState();
                exitDemo = 1;

                return;
            }
        } else if (eventType[0] == 0x00 && eventType[1] == 0x03 && eventType[2] == 0x00 && eventType[3] == 0x00) { // Button press
            if (eventData[0] == 0x01 && eventGraphicsID[0] == backButtonID[0] &&
              eventGraphicsID[1] == backButtonID[1] &&
              eventGraphicsID[2] == backButtonID[2] &&
              eventGraphicsID[3] == backButtonID[3]) {
                break;  // Exit loop and return to previous menu because back button was pressed
            }
        }
    }

    //    displayPreviousMenu();
    currentPiscesMenu = previousPiscesMenu;
} /* showPiscesResults */

void
genTLVString(char * result, unsigned char * data, int len) {
    int m             = 0;
    int pos           = 0;
    int length        = 0;
    int lengthCounter = 0;
    char TLVString[_CMD_BUF_LEN] = { 0 };

    for (m = 0; m < len; m++) {
        if (pos == 0) {
            if ((data[m] & 0x1F) == 0x1f) {
                if ((data[m + 1] & 0x80) == 0x80 && (data[m] != 0xFF || !isAIDTag(data[m + 1]))) {
                    char buffer[15] = { 0 };
                    sprintf(buffer, "  %02X%02X%02X: ", data[m], data[m + 1], data[m + 2]);
                    strcat(TLVString, buffer);
                    pos = pos + 3;
                } else {
                    char buffer[15] = { 0 };
                    sprintf(buffer, "  %02X%02X:   ", data[m], data[m + 1]);
                    strcat(TLVString, buffer);
                    pos = pos + 2;
                }
            } else {
                char buffer[15] = { 0 };
                sprintf(buffer, "  %02X:     ", data[m]);
                strcat(TLVString, buffer);
                pos = pos + 1;
            }

            if ((data[m + pos] & 0x80) != 0x80) {
                length = data[m + pos];
                // printf(" <1len:%d> ",length);
                if (length > 0) {
                    pos = pos + 1;
                }
                // printf(" <1len1:%d> ",pos);
                m = m + pos;
                // printf(" <1len2:%d> ",m);
            } else if (data[m + pos] == 0x81) {
                length = data[m + pos + 1];
                // printf(" <2len:%d> ",length);
                pos = pos + 2;
                m   = m + pos;
            } else {
                length = ((data[m + pos + 1] * 0x100) + data[m + pos + 2]);
                // printf(" <3len:%d> ",length);
                pos = pos + 3;
                m   = m + pos;
            }
        }
        if (length == 0) {
            // printf(" <4len:%d> ",length);
            pos = 0;
            lengthCounter = 0;
            char buffer[5] = { 0 };
            sprintf(buffer, "\n");
            strcat(TLVString, buffer);
        } else {
            char buffer[5] = { 0 };
            sprintf(buffer, "%02X", data[m]);
            strcat(TLVString, buffer);
            lengthCounter++;
            // printf(" <5len:%d> ",lengthCounter);
            if (lengthCounter == length) {
                // printf(" <6len:%d> ",length);
                pos = 0;
                lengthCounter = 0;
                sprintf(buffer, "\n");
                strcat(TLVString, buffer);
            }
        }
    }
    strcat(result, TLVString);
} /* genTLVString */
