Example #1
1
int NFC_Mifare_Classic(int argc, const char *argv[]) //! Lecture - Écriture d'une carte MIFARE Classic
{
    action_t atAction = ACTION_USAGE;
    uint8_t *pbtUID;
    int    unlock = 0;
    if (argc < 2)
    {
        sprintf(message_erreur,"Syntaxe incorrecte !");
        return EXIT_FAILURE; //! Échec !
    }
    const char *command = argv[1];
    if (strcmp(command, "r") == 0 || strcmp(command, "R") == 0)
    {
        if (argc < 4)
        {
            sprintf(message_erreur,"Syntaxe incorrecte !");
            return EXIT_FAILURE; //! Échec !
        }
        atAction = ACTION_READ;
        if (strcmp(command, "R") == 0)
        {
            unlock = 1;
        }
        bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
        bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
        bUseKeyFile = (argc > 4);
        bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
    }
    else if (strcmp(command, "w") == 0 || strcmp(command, "W") == 0)
    {
        if (argc < 4)
        {
            sprintf(message_erreur,"Syntaxe incorrecte !");
            return EXIT_FAILURE; //! Échec !
        }
        atAction = ACTION_WRITE;
        if (strcmp(command, "W") == 0)
        {
            unlock = 1;
        }
        bUseKeyA = tolower((int)((unsigned char) * (argv[2]))) == 'a';
        bTolerateFailures = tolower((int)((unsigned char) * (argv[2]))) != (int)((unsigned char) * (argv[2]));
        bUseKeyFile = (argc > 4);
        bForceKeyFile = ((argc > 5) && (strcmp((char *)argv[5], "f") == 0));
    }
    if (atAction == ACTION_USAGE)
    {
        sprintf(message_erreur,"Syntaxe incorrecte !");
        return EXIT_FAILURE; //! Échec !
    }
    //! We don't know yet the card size so let's read only the UID from the keyfile for the moment
    if (bUseKeyFile)
    {
        FILE *pfKeys = fopen(argv[4], "rb");
        if (pfKeys == NULL)
        {
            sprintf(message_erreur,"Could not open keys file: %s\n", argv[4]);
            return EXIT_FAILURE; //! Échec !
        }
        if (fread(&mtKeys, 1, 4, pfKeys) != 4)
        {
            sprintf(message_erreur,"Could not read UID from key file: %s !", argv[4]);
            fclose(pfKeys);
            return EXIT_FAILURE; //! Échec !
        }
        fclose(pfKeys);
    }
    nfc_init(&context);
    if (context == NULL)
    {
        sprintf(message_erreur,"Unable to init libnfc (malloc) !");
        return EXIT_FAILURE; //! Échec !
    }
    //! Try to open the NFC reader
    pnd = nfc_open(context, NULL);
    if (pnd == NULL)
    {
        sprintf(message_erreur,"Error opening NFC reader !");
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    }
    if (nfc_initiator_init(pnd) < 0)
    {
        nfc_perror(pnd, "nfc_initiator_init");
        nfc_strerror_r(pnd, message_erreur, TAILLE_MESSAGE_ERREUR);
        nfc_close(pnd);
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    };
    //! Let the reader only try once to find a tag
    if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0)
    {
        nfc_perror(pnd, "nfc_device_set_property_bool");
        nfc_strerror_r(pnd, message_erreur, TAILLE_MESSAGE_ERREUR);
        nfc_close(pnd);
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    }
    //! Disable ISO14443-4 switching in order to read devices that emulate Mifare Classic with ISO14443-4 compliance.
    nfc_device_set_property_bool(pnd, NP_AUTO_ISO14443_4, false);
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"NFC reader: %s opened\n", nfc_device_get_name(pnd));
    #endif
    //! Try to find a MIFARE Classic tag
    if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0)
    {
        sprintf(message_erreur,"Error: no tag was found !");
        nfc_close(pnd);
        nfc_exit(context);
        return EXIT_FAILURE; //! Échec !
    }
    //! Test if we are dealing with a MIFARE compatible tag
    if ((nt.nti.nai.btSak & 0x08) == 0)
    {
        #ifdef DEBUG_PRINTF
        fprintf(stderr,"Warning: tag is probably not a MFC !");
        #endif
    }
    //! Get the info from the current tag
    pbtUID = nt.nti.nai.abtUid;
    if (bUseKeyFile)
    {
        uint8_t fileUid[4];
        memcpy(fileUid, mtKeys.amb[0].mbm.abtUID, 4);
        //! Compare if key dump UID is the same as the current tag UID, at least for the first 4 bytes
        if (memcmp(pbtUID, fileUid, 4) != 0)
        {
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"Expected MIFARE Classic card with UID starting as: %02x%02x%02x%02x\n", fileUid[0], fileUid[1], fileUid[2], fileUid[3]);
            fprintf(stderr,"Got card with UID starting as:                     %02x%02x%02x%02x\n", pbtUID[0], pbtUID[1], pbtUID[2], pbtUID[3]);
            #endif
            if (! bForceKeyFile)
            {
                sprintf(message_erreur,"Aborting !");
                nfc_close(pnd);
                nfc_exit(context);
                return EXIT_FAILURE; //! Échec !
            }
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Found MIFARE Classic card:\n");
    #endif
    print_nfc_target(&nt, false);
    //! Guessing size
    if ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x02)
        //! 4K
        uiBlocks = 0xff;
    else if ((nt.nti.nai.btSak & 0x01) == 0x01)
        //! 320b
        uiBlocks = 0x13;
    else
        //! 1K/2K, checked through RATS
        uiBlocks = 0x3f;
    //! Testing RATS
    int res;
    if ((res = get_rats()) > 0)
    {
        if ((res >= 10) && (abtRx[5] == 0xc1) && (abtRx[6] == 0x05) && (abtRx[7] == 0x2f) && (abtRx[8] == 0x2f) && ((nt.nti.nai.abtAtqa[1] & 0x02) == 0x00))
        {
            //! MIFARE Plus 2K
            uiBlocks = 0x7f;
        }
        //! Chinese magic emulation card, ATS=0978009102:dabc1910
        if ((res == 9)  && (abtRx[5] == 0xda) && (abtRx[6] == 0xbc) && (abtRx[7] == 0x19) && (abtRx[8] == 0x10))
        {
            magic2 = true;
        }
    }
    #ifdef DEBUG_PRINTF
    fprintf(stderr,"Guessing size: seems to be a %i-byte card\n", (uiBlocks + 1) * 16);
    #endif
    if (bUseKeyFile)
    {
        FILE *pfKeys = fopen(argv[4], "rb");
        if (pfKeys == NULL)
        {
            sprintf(message_erreur,"Could not open keys file: %s !", argv[4]);
            return EXIT_FAILURE; //! Échec !
        }
        if (fread(&mtKeys, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfKeys) != (uiBlocks + 1) * sizeof(mifare_classic_block))
        {
            sprintf(message_erreur,"Could not read keys file: %s !", argv[4]);
            fclose(pfKeys);
            return EXIT_FAILURE; //! Échec !
        }
        fclose(pfKeys);
    }
    if (atAction == ACTION_READ)
    {
        memset(&mtDump, 0x00, sizeof(mtDump));
    }
    else
    {
        FILE *pfDump = fopen(argv[3], "rb");
        if (pfDump == NULL)
        {
            sprintf(message_erreur,"Could not open dump file: %s !", argv[3]);
            return EXIT_FAILURE; //! Échec !
        }
        if (fread(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != (uiBlocks + 1) * sizeof(mifare_classic_block))
        {
            sprintf(message_erreur,"Could not read dump file: %s !", argv[3]);
            fclose(pfDump);
            return EXIT_FAILURE; //! Échec !
        }
        fclose(pfDump);
    }
    if (atAction == ACTION_READ)
    {
        if (read_card(unlock))
        {
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"Writing data to file: %s ...", argv[3]);
            #endif
            fflush(stdout);
            FILE *pfDump = fopen(argv[3], "wb");
            if (pfDump == NULL)
            {
                sprintf(message_erreur,"Could not open dump file: %s !", argv[3]);
                nfc_close(pnd);
                nfc_exit(context);
                return EXIT_FAILURE; //! Échec !
            }
            if (fwrite(&mtDump, 1, (uiBlocks + 1) * sizeof(mifare_classic_block), pfDump) != ((uiBlocks + 1) * sizeof(mifare_classic_block)))
            {
                sprintf(message_erreur,"\nCould not write to file: %s !", argv[3]);
                fclose(pfDump);
                nfc_close(pnd);
                nfc_exit(context);
                return EXIT_FAILURE; //! Échec !
            }
            #ifdef DEBUG_PRINTF
            fprintf(stderr,"Done.\n");
            #endif
            fclose(pfDump);
        }
        else
        {
            nfc_close(pnd);
            nfc_exit(context);
            return EXIT_FAILURE;
        }
    }
    else if (atAction == ACTION_WRITE)
    {
        write_card(unlock);
    }
    nfc_close(pnd);
    nfc_exit(context);
    return EXIT_SUCCESS; //! Succès !
}
Example #2
0
/*
***********************************************************
*    Function: fus_write_trailer()
*
*    Description: write batch, totals, and file trailer records
*
*    Input:     fd          FILE POINTER
*               tot_tran        total detail records in file
*               tot_debit_amt   total debit amount in pennies
*               tot_credit_amt  total credit amount in pennies
*
*    Output:    None
*
*    Returns:     1 if SUCCESS, 0 if Error
****************************************************************
*/
static 
int fus_write_trailer(FILE *fd, int tot_tran, Arb_numeric *tot_debit_amt,
	Arb_numeric *tot_credit_amt)
{
    char card[512];
    Arb_numeric result = ARB_NUMERIC_ZERO;
    char iamount[ARB_NUMERIC_LEN];
    char idebit[ARB_NUMERIC_LEN];
    char icredit[ARB_NUMERIC_LEN];

    arb_num_arith(&result, tot_debit_amt, ARB_NUM_ADD, tot_credit_amt);

    arb_numeric_to_string(&result, iamount);
    arb_numeric_to_string(tot_debit_amt, idebit);
    arb_numeric_to_string(tot_credit_amt, icredit);
    if(!VerifyNumberString(iamount, FUS_FILE_AMOUNT_MAX_LENGTH) || 
       !VerifyNumberString(idebit, FUS_FILE_AMOUNT_MAX_LENGTH) || 
       !VerifyNumberString(icredit, FUS_FILE_AMOUNT_MAX_LENGTH))
    {
	fprintf(RptFileFD,"\nERROR - Problem with total Amount!\n");
	emit(FILE_LINE, CPM_WRITE_CARD, gFile_id);
    	return (0);
    }

    /* Batch Totals record */
    sprintf(card, "B #RECS=%.6d #ORDS=%.6d $TOT=%09.9s $SALES=%09.9s $REFUNDS=%09.9s  ",
	((tot_tran * 2) + 1), tot_tran, iamount,
	idebit, icredit);

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, CPM_WRITE_CARD, gFile_id);
	return(0);
    }

    /* File Totals record */
    sprintf(card, "T #RECS=%.6d #ORDS=%.6d $TOT=%09.9s $SALES=%09.9s $REFUNDS=%09.9s  ",
	((tot_tran * 2) + 2), tot_tran, iamount,
	idebit, icredit);

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, CPM_WRITE_CARD, gFile_id);
	return(0);
    }

    /* File Trailer record */
    sprintf(card,"PID=%-6.6s %-8.8s SID=%-6.6s %-8.8s END   %-6.6s%-28.28s",
	gCH_curr.fus_pres_id, gCH_curr.fus_pres_pass,
	gCH_curr.fus_sub_id, gCH_curr.fus_sub_pass,
	&gFile_date_time[2],    /* YYMMDD */
	"");

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, CPM_WRITE_CARD, gFile_id);
	return(0);
    }

   return(1);
}
Example #3
0
/*
***********************************************************
*    Function: knn_write_trailer()
*
*    Description: write file trailer
*
*    Input:	fd          FILE POINTER
		tot_tran	total records in file
		tot_amt		total amount
*
*    Output:	None
*
*    Returns:     1 if SUCCESS, 0 if Error
****************************************************************
*/
static 
int knn_write_trailer(FILE *fd, int tot_tran, Arb_numeric *tot_amt)
{
    char  card[512];
    char buff[ARB_NUMERIC_LEN];

    arb_numeric_to_string(tot_amt, buff);
    if(!VerifyNumberString(buff, KNN_FILE_AMOUNT_MAX_LENGTH))
    {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	fprintf(RptFileFD,"\nERROR - Problem with total Amount length!\n");
    	return (0);
    }

    /* Add 2 to total record count (header and trailer */
    sprintf(card, "TR%.8d%018.18s%-70.70s",
	tot_tran+2, buff, "");

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

   return(1);
}
Example #4
0
/*
***********************************************************
*    Function: fus_write_detail_record()
*
*    Description: write record  to the out put file
*
*    Input:    fd          FILE POINTER
*              data        transaction data record
*
*    Output:
*
*    Returns:  1 if SUCCESS, 0 if Error
****************************************************************
*/
static 
int fus_write_detail_record(FILE *fd, TRANS *trec)
{
   char card[512];
   char unique_id[16];
   char	eft_trans_type;
   char	acct_type;
   char iamount[ARB_NUMERIC_LEN];

   /* A unique id per record */
   /* Combine 2-digit tracking_id_serv, 10-digit tracking_id, 3 digit counter */
   sprintf(unique_id, "%.2d%.10d%.3d", trec->tracking_id_serv,
	trec->tracking_id, trec->counter);

    if (trec->eft_trans_type == EFT_DEBIT_CHECK) {
	eft_trans_type = FUS_DEBIT_CHECKING;
	acct_type = FUS_ACCT_TYPE_CHECKING;
    } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_CHECK) {
	eft_trans_type = FUS_DEBIT_PRENOTE_CHECKING;
	acct_type = FUS_ACCT_TYPE_CHECKING;
    } else if (trec->eft_trans_type == EFT_DEBIT_SAVINGS) {
	eft_trans_type = FUS_DEBIT_SAVINGS;
	acct_type = FUS_ACCT_TYPE_SAVINGS;
    } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_SAVINGS) {
	eft_trans_type = FUS_DEBIT_PRENOTE_SAVINGS;
	acct_type = FUS_ACCT_TYPE_SAVINGS;
    } else if (trec->eft_trans_type == EFT_CREDIT_CHECK) {
	eft_trans_type = FUS_CREDIT_CHECKING;
	acct_type = FUS_ACCT_TYPE_CHECKING;
    } else if (trec->eft_trans_type == EFT_CREDIT_SAVINGS) {
	eft_trans_type = FUS_CREDIT_SAVINGS;
	acct_type = FUS_ACCT_TYPE_SAVINGS;
    }

    arb_numeric_to_string(&trec->amount, iamount);
    if(!VerifyNumberString(iamount, FUS_AMOUNT_MAX_LENGTH))
    	return (0);

    sprintf(card, "S%-6.6s%-16.16sO%cK%-9.9s%-17.17s %c B %07.7s%-16.16s",
	gCH_curr.fus_merchant_id,
	unique_id,
	eft_trans_type,
	trec->cust_bank_sort_code,
	trec->cust_bank_acc_num,
	acct_type,
	iamount,
	" ");

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

    return(1);
}
Example #5
0
/*
***********************************************************
*    Function: frn_write_trailer()
*
*    Description: write file trailer
*
*    Input:	fd	FILE POINTER
*		debit_amt	debit amount
*		credit_amt	credit amount
*
*    Output:	None
*
*    Returns:     1 if SUCCESS, 0 if Error
****************************************************************
*/
static 
int frn_write_trailer(FILE *fd, Arb_numeric *debit_amt, Arb_numeric *credit_amt)
{
    char  card[512];
    char *op_id;
    char debit_amount[ARB_NUMERIC_LEN];		/* CAMqa86327 */
    char credit_amount[ARB_NUMERIC_LEN];	/* CAMqa86327 */
 
    
    if (gCH_curr.frn_fast_mode)
	op_id = gCH_curr.frn_fast_op_id;
    else
	op_id = gCH_curr.frn_norm_op_id;

    /************************************************/
    /* CAMqa86327 - Trailer record now has debit    */
    /* amount and credit amount separtely instead   */
    /* total amount.                                */
    /************************************************/

    arb_numeric_to_string(debit_amt, debit_amount);
    if(!VerifyNumberString(debit_amount, FRN_BATCH_AMOUNT_MAX_LENGTH))
    {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	fprintf(RptFileFD,"\nERROR - Problem with total Amount length!\n");
    	return (0);
    }

    arb_numeric_to_string(credit_amt, credit_amount);
    if(!VerifyNumberString(credit_amount, FRN_BATCH_AMOUNT_MAX_LENGTH))
    {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	fprintf(RptFileFD,"\nERROR - Problem with total Amount length!\n");
    	return (0);
    }

/* BUG: Not handling 16 byte trailer amount well */
    sprintf(card, "08%-2.2s%-8.8s%-6.6s%-84.84s%016.16s%016.16s%-26.26s",
	op_id,
	"",
        gCH_curr.frn_national_num,
	"",
	debit_amount,
	credit_amount,
	"");

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

   return(1);
}
Example #6
0
/*
***********************************************************
*    Function: knn_write_detail_record()
*
*    Description: write record  to the out put file
*
*    Input:    fd          FILE POINTER
*              data        transaction data record
*
*    Output:
*
*    Returns:  1 if SUCCESS, 0 if Error
****************************************************************
*/
static
int knn_write_detail_record(FILE *fd, TRANS *trec)
{
   char card[512];
   char unique_id[16];
   int	eft_trans_type;
   char buff[ARB_NUMERIC_LEN];
   char scust_bank_acc_name[PAYMENT_PROFILE_ownr_lname_SZ-1];

   /* A unique id per record */
   /* Combine 2-digit tracking_id_serv, 10-digit tracking_id, 3 digit counter */
   sprintf(unique_id, "%.2d%.10d%.3d", trec->tracking_id_serv,
	trec->tracking_id, trec->counter);

    if (trec->eft_trans_type == EFT_DEBIT_CHECK) {
	eft_trans_type = KNN_DEBIT_CHECKING;
    } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_CHECK) {
	eft_trans_type = KNN_DEBIT_PRENOTE_CHECKING;
    } else if (trec->eft_trans_type == EFT_DEBIT_SAVINGS) {
	eft_trans_type = KNN_DEBIT_SAVINGS;
    } else if (trec->eft_trans_type == EFT_DEBIT_PRENOTE_SAVINGS) {
	eft_trans_type = KNN_DEBIT_PRENOTE_SAVINGS;
    } else if (trec->eft_trans_type == EFT_CREDIT_CHECK) {
	eft_trans_type = KNN_CREDIT_CHECKING;
    } else if (trec->eft_trans_type == EFT_CREDIT_SAVINGS) {
	eft_trans_type = KNN_CREDIT_SAVINGS;
    }

    arb_numeric_to_string(&trec->amount, buff);
    if(!VerifyNumberString(buff, KNN_AMOUNT_MAX_LENGTH))
    	return (0);

    arb_safe_strncpy(scust_bank_acc_name, trec->cust_bank_acc_name, 23);
	
    sprintf(card, "DT%c%-9.9s%-20.20s%018.18s%-22.22s%-6.6s%-15.15s0000 ",
	eft_trans_type,
	trec->cust_bank_sort_code,
	trec->cust_bank_acc_num,
	buff,
	scust_bank_acc_name,
	&gFile_date_time[2],
	unique_id);

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

    return(1);
}
Example #7
0
/*
***********************************************************
*    Function: knn_write_header()
*
*    Description: write the header record for the send file
*
*    Input:	fd		FILE Descripter
*
*    Output: none
*    Return:	1 if SUCCESS, 0 if FAILURE
****************************************************************
*/
static 
int knn_write_header(FILE *fd)
{
    char  card[512];

    sprintf(card,"HD%-12.12s%-4.4sCOMVERSE  %-6.6s%-6.6s%.8d%-50.50s",
	gCH_curr.knn_merchant_acct, gCH_curr.knn_merchant_id,
	&gFile_date_time[2],	/* Date time is YYYYMMDDhhmmss, we need YYMMDD */
	&gFile_date_time[8],	/* Date time is YYYYMMDDhhmmss, we need hhmmss */
	gCycle_id, " ");

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

    return(1);
}
Example #8
0
/***********************************************************
*    Function: fus_write_addr_record()
*
*    Description: write record  to the out put file
*
*    Input:    fd          FILE POINTER
*              data        transaction data record
*
*    Output:
*
*    Returns:  1 if SUCCESS, 0 if Error
***********************************************************/
static 
int fus_write_addr_record(FILE *fd, TRANS *trec)
{
	char card[512];
	char scust_bank_acc_name[PAYMENT_PROFILE_ownr_lname_SZ-1];

	arb_safe_strncpy(scust_bank_acc_name, trec->cust_bank_acc_name, 31);

	sprintf(card, "AM%-30.30s%-48.48s", scust_bank_acc_name, "");

	if (write_card(fd, card) != 1)
	{
		emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
		return(0);
	}
	
	return(1);
}
Example #9
0
/*
***********************************************************
*    Function: fus_write_header()
*
*    Description: write the header record for the send file
*
*    Input:	fd		FILE Descripter
*
*    Output: none
*    Return:	1 if SUCCESS, 0 if FAILURE
****************************************************************
*/
static 
int fus_write_header(FILE *fd)
{
    char  card[512];

    sprintf(card,"PID=%-6.6s %-8.8s SID=%-6.6s %-8.8s START %-6.6s%-6.6s%.8d%-14.14s",
	gCH_curr.fus_pres_id, gCH_curr.fus_pres_pass,
	gCH_curr.fus_sub_id, gCH_curr.fus_sub_pass,
	&gFile_date_time[2],    /* YYMMDD */
	&gFile_date_time[8],	/* hhmmss */
	gCycle_id, " ");

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

    return(1);
}
Example #10
0
/*
***********************************************************
*    Function: frn_write_header()
*
*    Description: write the header record for the send file
*
*    Input:	fd		FILE Descripter
*
*    Output: none
*    Return:	1 if SUCCESS, 0 if FAILURE
****************************************************************
*/
static 
int frn_write_header(FILE *fd, CURRENCY_STRUCT *currency_struct)
{
    char  card[512];
    char *op_id;
    char  ppdd_date[7];

    char *currency_format = (char*)" ";

    if (gLanguage_code > 0)
	strcpy(currency_format, currency_struct->currency_format);

    /* need DDMMY value, not yyyymmdd */
    sprintf(ppdd_date, "%-2.2s%-2.2s%-1.1s", &gPpdd_day[6],
	&gPpdd_day[4], &gPpdd_day[3]);

    if (gCH_curr.frn_fast_mode)
	op_id = gCH_curr.frn_fast_op_id;
    else
	op_id = gCH_curr.frn_norm_op_id;

    sprintf(card,"03%-2.2s        %-6.6s       %-5.5s%-24.24s%.7d%-19.19s%1.1s%-5.5s%-5.5s%-11.11s%-47.47s%-5.5s      ",
	op_id,
	gCH_curr.frn_national_num,
	ppdd_date,			/* DDMMY, ppdd_date/posting date */
	gCH_curr.frn_company_name,
	gCycle_id,
	" ",
	currency_format, 		/* Added for CAMqa54502 */
	" ",
	gCH_curr.frn_agency_code,
	gCH_curr.frn_account_num,
	" ",
	gCH_curr.frn_bank_code);

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

    return(1);
}
Example #11
0
bool psxcard_device::transfer(uint8_t to, uint8_t *from)
{
	bool ret=true;

	switch (state)
	{
		case state_illegal:
			if (is_loaded())
			{
//              printf("CARD: begin\n");
				state = state_command;
				*from = 0x00;
			}
			else
			{
				ret = false;
			}
			break;

		case state_command:
			cmd=to;
			*from=0x5a;
			state=state_cmdack;
			break;

		case state_cmdack:
			*from=0x5d;
			state=state_wait;
			break;

		case state_wait:
			*from=0x00;
			state=state_addr_hi;
			break;

		case state_addr_hi:
			addr=(to<<8);
//          printf("addr_hi: %02x, addr = %x\n", to, addr);
			*from=to;
			state=state_addr_lo;
			break;

		case state_addr_lo:
			addr|=(to&0xff);
//          printf("addr_lo: %02x, addr = %x, cmd = %x\n", to, addr, cmd);

			switch (cmd)
			{
				case 'R':   // 0x52
				{
					pkt[0]=*from=0x5c;
					pkt[1]=0x5d;
					pkt[2]=(addr>>8);
					pkt[3]=(addr&0xff);
					read_card(addr,&pkt[4]);
					pkt[4+128]=checksum_data(&pkt[2],128+2);
					pkt[5+128]=0x47;
					pkt_sz=6+128;
					pkt_ptr=1;
					state=state_read;
					break;
				}
				case 'W':   // 0x57
				{
					pkt[0]=addr>>8;
					pkt[1]=addr&0xff;
					pkt_sz=129+2;
					pkt_ptr=2;
					state=state_write;
					*from=to;
					break;
				}
				default:
					state=state_illegal;
					break;
			}
			break;

		case state_read:
			//assert(to==0);
//          printf("state_read: pkt_ptr = %d, pkt_sz = %d\n", pkt_ptr, pkt_sz);
			*from=pkt[pkt_ptr++];
			if (pkt_ptr==pkt_sz)
			{
				#ifdef debug_card
					printf("card: read finished\n");
				#endif

				state=state_end;
			}
			break;

		case state_write:
			*from=to;
			pkt[pkt_ptr++]=to;
			if (pkt_ptr==pkt_sz)
			{
				*from=0x5c;
				state=state_writeack_2;
			}
			break;

		case state_writeack_2:
			*from=0x5d;
			state=state_writechk;
			break;

		case state_writechk:
		{
			unsigned char chk=checksum_data(pkt,128+2);
			if (chk==pkt[128+2])
			{
				#ifdef debug_card
					printf("card: write ok\n");
				#endif

				write_card(addr,pkt+2);

				*from='G';
			} else
			{
				#ifdef debug_card
					printf("card: write fail\n");
				#endif

				*from='N';
			}
			state=state_end;
			break;
		}

		case state_end:
			ret = false;
			state = state_illegal;
			break;

		default: /*assert(0);*/ ret=false; break;
	}

	#ifdef debug_card
//      printf("card: transfer to=%02x from=%02x ret=%c\n",to,*from,ret ? 'T' : 'F');
	#endif

	return ret;
}
Example #12
0
/*
***********************************************************
*    Function: frn_write_detail_record()
*
*    Description: write record to the output file
*
*    Input:  fd		FILE POINTER
*            data	transaction data record
*            tran_ind	credit/debit indicator
*
*    Output:
*
*    Returns:  1 if SUCCESS, 0 if Error
****************************************************************
*/
static 
int frn_write_detail_record(FILE *fd, TRANS *trec, char *currency_format)
{
    char card[512];
    char unique_id[16];
    char *op_id;
    int iamount = 0;
    char scust_bank_acc_name[PAYMENT_PROFILE_ownr_lname_SZ-1];
    char trans_type;	/* CAMqa86327 */
    char str_amount[ARB_NUMERIC_LEN]; /* DENqa05053 */

    /* A unique id per record */
    /* Combine 2-digit tracking_id_serv, 10-digit tracking_id, 3 digit counter */
    sprintf(unique_id, "%.2d%.10d%.3d", trec->tracking_id_serv,
	trec->tracking_id, trec->counter);

    if (gCH_curr.frn_fast_mode)
	op_id = gCH_curr.frn_fast_op_id;
    else
	op_id = gCH_curr.frn_norm_op_id;

    /*****************************************************/
    /* DENqa05053                                        */
    /* Leaving iamount for FT specific record layout     */
    /* Adding string like what is used in trailer to     */
    /* handle amount up to 16 byte length                */
    /*****************************************************/   
    arb_numeric_to_int(&trec->amount, &iamount);

    arb_numeric_to_string(&trec->amount, str_amount);
    if(!VerifyNumberString(str_amount, FRN_AMOUNT_MAX_LENGTH))
        return (0);  

    arb_safe_strncpy(scust_bank_acc_name, trec->cust_bank_acc_name, 25);

    /*************************************************************/
    /* CAMqa86327 - set transaction type to either C (credit) or */
    /* D (debit) depending on the eft_trans_type.                */
    /*************************************************************/

    if (trec->eft_trans_type == EFT_DEBIT_CHECK ||
    	    trec->eft_trans_type == EFT_DEBIT_SAVINGS ||
	    trec->eft_trans_type == EFT_DEBIT_PRENOTE_CHECK ||
	    trec->eft_trans_type == EFT_DEBIT_PRENOTE_SAVINGS)
    {
        trans_type = 'D'; /* debit */
    }
    else
    {
        trans_type = 'C'; /* credit */
    }

/* FT Specific compile option for alternative FT specific record layout */
#ifdef FT
    sprintf(card, "06%-2.2s%-8.8s%-6.6s%.12d%-24.24s%-24.24s%-2.2s%1.1s%-5.5s%-5.5s%-11.11s%.16d*%-15.15s%.9d      %-5.5s%c%-5.5s",
        op_id,
        "",
        gCH_curr.frn_national_num,
        trec->bill_ref_no,
        scust_bank_acc_name,
        trec->bank_agency_name,
		"",
		currency_format,	/* Added for CAMqa54502 */
        "",
        trec->bank_agency_code,
        trec->cust_bank_acc_num,
        iamount,
        unique_id,
        trec->bill_ref_no,
        trec->cust_bank_sort_code,
	trans_type,
        "");
#else
    /* BUG: we are not handling the full 16 byte amount well. */
    sprintf(card, "06%-2.2s%-8.8s%-6.6s%.12d%-24.24s%-24.24s%-8.8s%-5.5s%-11.11s%016.16s%-15.15s%.16d%-5.5s%c%-5.5s",
	op_id,
	"",
	gCH_curr.frn_national_num,
	trec->bill_ref_no,
	scust_bank_acc_name,
	trec->bank_agency_name,
	"",
	trec->bank_agency_code,
	trec->cust_bank_acc_num,
	str_amount,
	unique_id,
	trec->bill_ref_no,
	trec->cust_bank_sort_code,
	trans_type,
	"");
#endif

    if (write_card(fd, card) != 1) {
	emit(FILE_LINE, EFT_WRITE_CARD, gFile_id);
	return(0);
    }

    return(1);
}
Example #13
0
int
main (int argc, const char *argv[])
{
  bool    bReadAction;
  FILE   *pfDump;

  if (argc < 3) {
    printf ("\n");
    printf ("%s r|w <dump.mfd>\n", argv[0]);
    printf ("\n");
    printf ("r|w         - Perform read from or write to card\n");
    printf ("<dump.mfd>  - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
    printf ("\n");
    return 1;
  }

  DBG ("\nChecking arguments and settings\n");

  bReadAction = tolower ((int) ((unsigned char) *(argv[1])) == 'r');

  if (bReadAction) {
    memset (&mtDump, 0x00, sizeof (mtDump));
  } else {
    pfDump = fopen (argv[2], "rb");

    if (pfDump == NULL) {
      ERR ("Could not open dump file: %s\n", argv[2]);
      return 1;
    }

    if (fread (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
      ERR ("Could not read from dump file: %s\n", argv[2]);
      fclose (pfDump);
      return 1;
    }
    fclose (pfDump);
  }
  DBG ("Successfully opened the dump file\n");

  // Try to open the NFC device
  pnd = nfc_connect (NULL);
  if (pnd == NULL) {
    ERR ("Error connecting NFC device\n");
    return 1;
  }

  nfc_initiator_init (pnd);

  // Drop the field for a while
  if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, false)) {
    nfc_perror (pnd, "nfc_configure");
    exit (EXIT_FAILURE);
  }
  // Let the device only try once to find a tag
  if (!nfc_configure (pnd, NDO_INFINITE_SELECT, false)) {
    nfc_perror (pnd, "nfc_configure");
    exit (EXIT_FAILURE);
  }
  if (!nfc_configure (pnd, NDO_HANDLE_CRC, true)) {
    nfc_perror (pnd, "nfc_configure");
    exit (EXIT_FAILURE);
  }
  if (!nfc_configure (pnd, NDO_HANDLE_PARITY, true)) {
    nfc_perror (pnd, "nfc_configure");
    exit (EXIT_FAILURE);
  }
  // Enable field so more power consuming cards can power themselves up
  if (!nfc_configure (pnd, NDO_ACTIVATE_FIELD, true)) {
    nfc_perror (pnd, "nfc_configure");
    exit (EXIT_FAILURE);
  }

  printf ("Connected to NFC device: %s\n", pnd->acName);

  // Try to find a MIFARE Ultralight tag
  if (!nfc_initiator_select_passive_target (pnd, nmMifare, NULL, 0, &nt)) {
    ERR ("no tag was found\n");
    nfc_disconnect (pnd);
    return 1;
  }
  // Test if we are dealing with a MIFARE compatible tag

  if (nt.nti.nai.abtAtqa[1] != 0x44) {
    ERR ("tag is not a MIFARE Ultralight card\n");
    nfc_disconnect (pnd);
    return EXIT_FAILURE;
  }
  // Get the info from the current tag
  printf ("Found MIFARE Ultralight card with UID: ");
  size_t  szPos;
  for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) {
    printf ("%02x", nt.nti.nai.abtUid[szPos]);
  }
  printf("\n");

  if (bReadAction) {
    if (read_card ()) {
      printf ("Writing data to file: %s ... ", argv[2]);
      fflush (stdout);
      pfDump = fopen (argv[2], "wb");
      if (pfDump == NULL) {
        printf ("Could not open file: %s\n", argv[2]);
        return EXIT_FAILURE;
      }
      if (fwrite (&mtDump, 1, sizeof (mtDump), pfDump) != sizeof (mtDump)) {
        printf ("Could not write to file: %s\n", argv[2]);
        return EXIT_FAILURE;
      }
      fclose (pfDump);
      printf ("Done.\n");
    }
  } else {
    write_card ();
  }

  nfc_disconnect (pnd);

  return EXIT_SUCCESS;
}
Example #14
0
int
main(int argc, const char *argv[])
{
  bool    bReadAction;
  FILE   *pfDump;

  if (argc < 3) {
    printf("\n");
    printf("%s r|w <dump.mfd>\n", argv[0]);
    printf("\n");
    printf("r|w         - Perform read from or write to card\n");
    printf("<dump.mfd>  - MiFare Dump (MFD) used to write (card to MFD) or (MFD to card)\n");
    printf("\n");
    exit(EXIT_FAILURE);
  }

  DBG("\nChecking arguments and settings\n");

  bReadAction = tolower((int)((unsigned char) * (argv[1])) == 'r');

  if (bReadAction) {
    memset(&mtDump, 0x00, sizeof(mtDump));
  } else {
    pfDump = fopen(argv[2], "rb");

    if (pfDump == NULL) {
      ERR("Could not open dump file: %s\n", argv[2]);
      exit(EXIT_FAILURE);
    }

    if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
      ERR("Could not read from dump file: %s\n", argv[2]);
      fclose(pfDump);
      exit(EXIT_FAILURE);
    }
    fclose(pfDump);
  }
  DBG("Successfully opened the dump file\n");

  nfc_context *context;
  nfc_init(&context);
  if (context == NULL) {
    ERR("Unable to init libnfc (malloc)");
    exit(EXIT_FAILURE);
  }

  // Try to open the NFC device
  pnd = nfc_open(context, NULL);
  if (pnd == NULL) {
    ERR("Error opening NFC device");
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  if (nfc_initiator_init(pnd) < 0) {
    nfc_perror(pnd, "nfc_initiator_init");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  // Let the device only try once to find a tag
  if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  printf("NFC device: %s opened\n", nfc_device_get_name(pnd));

  // Try to find a MIFARE Ultralight tag
  if (nfc_initiator_select_passive_target(pnd, nmMifare, NULL, 0, &nt) <= 0) {
    ERR("no tag was found\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Test if we are dealing with a MIFARE compatible tag

  if (nt.nti.nai.abtAtqa[1] != 0x44) {
    ERR("tag is not a MIFARE Ultralight card\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Get the info from the current tag
  printf("Found MIFARE Ultralight card with UID: ");
  size_t  szPos;
  for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) {
    printf("%02x", nt.nti.nai.abtUid[szPos]);
  }
  printf("\n");

  if (bReadAction) {
    if (read_card()) {
      printf("Writing data to file: %s ... ", argv[2]);
      fflush(stdout);
      pfDump = fopen(argv[2], "wb");
      if (pfDump == NULL) {
        printf("Could not open file: %s\n", argv[2]);
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
        printf("Could not write to file: %s\n", argv[2]);
        fclose(pfDump);
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      fclose(pfDump);
      printf("Done.\n");
    }
  } else {
    write_card();
  }

  nfc_close(pnd);
  nfc_exit(context);
  exit(EXIT_SUCCESS);
}
Example #15
0
int
main(int argc, const char *argv[])
{
  int     iAction = 0;
  uint8_t iUID[MAX_UID_LEN] = { 0x0 };
  size_t  szUID = 0;
  bool    bOTP = false;
  bool    bLock = false;
  bool    bUID = false;
  FILE   *pfDump;

  if (argc < 2) {
      print_usage(argv);
      exit(EXIT_FAILURE);
  }

  DBG("\nChecking arguments and settings\n");

  // Get commandline options
  for (int arg = 1; arg < argc; arg++) {
    if (0 == strcmp(argv[arg], "r")) {
      iAction = 1;
    } else if (0 == strcmp(argv[arg], "w")) {
      iAction = 2;
    } else if (0 == strcmp(argv[arg], "--with-uid")) {
      if (argc < 5) {
        ERR("Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4");
        exit(EXIT_FAILURE);
      }
      szUID = str_to_uid(argv[4], iUID);
    } else if (0 == strcmp(argv[arg], "--full")) {
      bOTP = true;
      bLock = true;
      bUID = true;
    } else if (0 == strcmp(argv[arg], "--otp")) {
      bOTP = true;
    } else if (0 == strcmp(argv[arg], "--lock")) {
      bLock = true;
    } else if (0 == strcmp(argv[arg], "--uid")) {
      bUID = true;
    } else if (0 == strcmp(argv[arg], "--check-magic")) {
      iAction = 3;
    } else {
      //Skip validation of the filename
      if ((arg != 2) && (arg != 4)) {
        ERR("%s is not supported option.", argv[arg]);
        print_usage(argv);
        exit(EXIT_FAILURE);
      }
    }
  }

  if (iAction == 1) {
    memset(&mtDump, 0x00, sizeof(mtDump));
  } else if (iAction == 2) {
    pfDump = fopen(argv[2], "rb");

    if (pfDump == NULL) {
      ERR("Could not open dump file: %s\n", argv[2]);
      exit(EXIT_FAILURE);
    }

    if (fread(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
      ERR("Could not read from dump file: %s\n", argv[2]);
      fclose(pfDump);
      exit(EXIT_FAILURE);
    }
    fclose(pfDump);
    DBG("Successfully opened the dump file\n");
  } else if (iAction == 3) {
    DBG("Switching to Check Magic Mode\n");
  } else {
    ERR("Unable to determine operating mode");
    exit(EXIT_FAILURE);
  }

  nfc_context *context;
  nfc_init(&context);
  if (context == NULL) {
    ERR("Unable to init libnfc (malloc)");
    exit(EXIT_FAILURE);
  }

  // Try to open the NFC device
  pnd = nfc_open(context, NULL);
  if (pnd == NULL) {
    ERR("Error opening NFC device");
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  printf("NFC device: %s opened\n", nfc_device_get_name(pnd));

  if (list_passive_targets(pnd)) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  if (nfc_initiator_init(pnd) < 0) {
    nfc_perror(pnd, "nfc_initiator_init");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  // Let the device only try once to find a tag
  if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  // Try to find a MIFARE Ultralight tag
  if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) {
    ERR("no tag was found\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Test if we are dealing with a MIFARE compatible tag

  if (nt.nti.nai.abtAtqa[1] != 0x44) {
    ERR("tag is not a MIFARE Ultralight card\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Get the info from the current tag
  printf("Using MIFARE Ultralight card with UID: ");
  size_t  szPos;
  for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) {
    printf("%02x", nt.nti.nai.abtUid[szPos]);
  }
  printf("\n");

  if (iAction == 1) {
    if (read_card()) {
      printf("Writing data to file: %s ... ", argv[2]);
      fflush(stdout);
      pfDump = fopen(argv[2], "wb");
      if (pfDump == NULL) {
        printf("Could not open file: %s\n", argv[2]);
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      if (fwrite(&mtDump, 1, sizeof(mtDump), pfDump) != sizeof(mtDump)) {
        printf("Could not write to file: %s\n", argv[2]);
        fclose(pfDump);
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
      }
      fclose(pfDump);
      printf("Done.\n");
    }
  } else if (iAction == 2) {
    write_card(bOTP, bLock, bUID);
  } else if (iAction == 3) {
    if (!check_magic()) {
        printf("Card is not magic\n");
        nfc_close(pnd);
        nfc_exit(context);
        exit(EXIT_FAILURE);
    } else {
        printf("Card is magic\n");
    }
  }

  nfc_close(pnd);
  nfc_exit(context);
  exit(EXIT_SUCCESS);
}
Example #16
0
int
main(int argc, const char *argv[])
{
  int     iAction = 0;
  uint8_t iDumpSize = sizeof(mifareul_tag);
  uint8_t iUID[MAX_UID_LEN] = { 0x0 };
  size_t  szUID = 0;
  bool    bOTP = false;
  bool    bLock = false;
  bool    bUID = false;
  bool    bPWD = false;
  bool    bPart = false;
  bool    bFilename = false;
  FILE   *pfDump;

  if (argc < 3) {
    print_usage(argv);
    exit(EXIT_FAILURE);
  }

  DBG("\nChecking arguments and settings\n");

  // Get commandline options
  for (int arg = 1; arg < argc; arg++) {
    if (0 == strcmp(argv[arg], "r")) {
      iAction = 1;
    } else if (0 == strcmp(argv[arg], "w")) {
      iAction = 2;
    } else if (0 == strcmp(argv[arg], "--with-uid")) {
      if (arg + 1 == argc) {
        ERR("Please supply a UID of 4, 7 or 10 bytes long. Ex: a1:b2:c3:d4");
        exit(EXIT_FAILURE);
      }
      szUID = str_to_uid(argv[++arg], iUID);
    } else if (0 == strcmp(argv[arg], "--full")) {
      bOTP = true;
      bLock = true;
      bUID = true;
    } else if (0 == strcmp(argv[arg], "--otp")) {
      bOTP = true;
    } else if (0 == strcmp(argv[arg], "--lock")) {
      bLock = true;
    } else if (0 == strcmp(argv[arg], "--uid")) {
      bUID = true;
    } else if (0 == strcmp(argv[arg], "--check-magic")) {
      iAction = 3;
    } else if (0 == strcmp(argv[arg], "--partial")) {
      bPart = true;
    } else if (0 == strcmp(argv[arg], "--pw")) {
      bPWD = true;
      if (arg + 1 == argc || strlen(argv[++arg]) != 8 || ! ev1_load_pwd(iPWD, argv[arg])) {
        ERR("Please supply a PASSWORD of 8 HEX digits");
        exit(EXIT_FAILURE);
      }
    } else {
      //Skip validation of the filename
      if (arg != 2) {
        ERR("%s is not a supported option.", argv[arg]);
        print_usage(argv);
        exit(EXIT_FAILURE);
      } else {
        bFilename = true;
      }
    }
  }
  if (! bFilename) {
    ERR("Please supply a Mifare Dump filename");
    exit(EXIT_FAILURE);
  }

  nfc_context *context;
  nfc_init(&context);
  if (context == NULL) {
    ERR("Unable to init libnfc (malloc)");
    exit(EXIT_FAILURE);
  }

  // Try to open the NFC device
  pnd = nfc_open(context, NULL);
  if (pnd == NULL) {
    ERR("Error opening NFC device");
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  printf("NFC device: %s opened\n", nfc_device_get_name(pnd));

  if (list_passive_targets(pnd)) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  if (nfc_initiator_init(pnd) < 0) {
    nfc_perror(pnd, "nfc_initiator_init");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  // Let the device only try once to find a tag
  if (nfc_device_set_property_bool(pnd, NP_INFINITE_SELECT, false) < 0) {
    nfc_perror(pnd, "nfc_device_set_property_bool");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  // Try to find a MIFARE Ultralight tag
  if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) {
    ERR("no tag was found\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }

  // Test if we are dealing with a MIFARE compatible tag
  if (nt.nti.nai.abtAtqa[1] != 0x44) {
    ERR("tag is not a MIFARE Ultralight card\n");
    nfc_close(pnd);
    nfc_exit(context);
    exit(EXIT_FAILURE);
  }
  // Get the info from the current tag
  printf("Using MIFARE Ultralight card with UID: ");
  size_t  szPos;
  for (szPos = 0; szPos < nt.nti.nai.szUidLen; szPos++) {
    printf("%02x", nt.nti.nai.abtUid[szPos]);
  }
  printf("\n");

  // test if tag is EV1
  if (get_ev1_version()) {
    if (!bPWD)
      printf("Tag is EV1 - PASSWORD may be required\n");
    printf("EV1 storage size: ");
    if (abtRx[6] == 0x0b) {
      printf("48 bytes\n");
      uiBlocks = 0x14;
      iEV1Type = EV1_UL11;
      iDumpSize = sizeof(mifareul_ev1_mf0ul11_tag);
    } else if (abtRx[6] == 0x0e) {
      printf("128 bytes\n");
      uiBlocks = 0x29;
      iEV1Type = EV1_UL21;
      iDumpSize = sizeof(mifareul_ev1_mf0ul21_tag);
    } else
      printf("unknown!\n");
  } else {
    // re-init non EV1 tag
    if (nfc_initiator_select_passive_target(pnd, nmMifare, (szUID) ? iUID : NULL, szUID, &nt) <= 0) {
      ERR("no tag was found\n");
      nfc_close(pnd);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
  }

  // EV1 login required
  if (bPWD) {
    printf("Authing with PWD: %02x%02x%02x%02x ", iPWD[0], iPWD[1], iPWD[2], iPWD[3]);
    if (!ev1_pwd_auth(iPWD)) {
      printf("\n");
      ERR("AUTH failed!\n");
      exit(EXIT_FAILURE);
    } else {
      printf("Success - PACK: %02x%02x\n", abtRx[0], abtRx[1]);
      memcpy(iPACK, abtRx, 2);
    }
  }

  if (iAction == 1) {
    memset(&mtDump, 0x00, sizeof(mtDump));
  } else if (iAction == 2) {
    pfDump = fopen(argv[2], "rb");

    if (pfDump == NULL) {
      ERR("Could not open dump file: %s\n", argv[2]);
      exit(EXIT_FAILURE);
    }

    size_t  szDump;
    if (((szDump = fread(&mtDump, 1, sizeof(mtDump), pfDump)) != iDumpSize && !bPart) || szDump <= 0) {
      ERR("Could not read from dump file or size mismatch: %s\n", argv[2]);
      fclose(pfDump);
      exit(EXIT_FAILURE);
    }
    if (szDump != iDumpSize)
      printf("Performing partial write\n");
    fclose(pfDump);
    DBG("Successfully opened the dump file\n");
  } else if (iAction == 3) {
    DBG("Switching to Check Magic Mode\n");
  } else {
    ERR("Unable to determine operating mode");
    exit(EXIT_FAILURE);
  }

  if (iAction == 1) {
    bool bRF = read_card();
    printf("Writing data to file: %s ... ", argv[2]);
    fflush(stdout);
    pfDump = fopen(argv[2], "wb");
    if (pfDump == NULL) {
      printf("Could not open file: %s\n", argv[2]);
      nfc_close(pnd);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
    if (fwrite(&mtDump, 1, uiReadPages * 4, pfDump) != uiReadPages * 4) {
      printf("Could not write to file: %s\n", argv[2]);
      fclose(pfDump);
      nfc_close(pnd);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    }
    fclose(pfDump);
    printf("Done.\n");
    if (!bRF)
      printf("Warning! Read failed - partial data written to file!\n");
  } else if (iAction == 2) {
    write_card(bOTP, bLock, bUID);
  } else if (iAction == 3) {
    if (!check_magic()) {
      printf("Card is not magic\n");
      nfc_close(pnd);
      nfc_exit(context);
      exit(EXIT_FAILURE);
    } else {
      printf("Card is magic\n");
    }
  }

  nfc_close(pnd);
  nfc_exit(context);
  exit(EXIT_SUCCESS);
}