/* This file demonstrates how to access a card in "VHL & Autoread" operation mode.
 *
 * This requires the reader to be configured for VHL & Autoread.
 *
 * Please refer to "./AppNote_VHL_&_Autoread-01.balcfg" as an example for
 * configuration for factory-new MIFARE Classic cards.
 */
 
 
#include <stdio.h>
#include <baltech_api.h>


// Name of VHL file to use for reading
// (to find it, open configuration in ConfigEditor and see
// "Configuration Components" list)
#define VHL_FILE_CARD_NAME      "VHL File for Counter"


static void exit_on_error(brp_errcode errcode, char *errormessage,
						  brp_protocol dev)
{
	if (errcode != BRP_OK)
	{
		char * errname = brp_map_errcode(errcode);
		if (errname == NULL)
			fprintf(stderr, "%s [brp_errcode:%08X]\n", errormessage, errcode);
		else
			fprintf(stderr, "%s [%s]\n", errormessage, errname);
		brp_destroy(dev);
		exit(EXIT_FAILURE);
	}
}


int main(int argc, char *argv[])
{
	unsigned vhlfile_id;
	brp_errcode errcode;
	bool is_configured_vhlfile_cardname, is_configured_vhlfile_ctrval;
	
	brp_protocol dev = brp_create();
	brp_set_io(dev, brp_create_usb_hid(0));
	errcode = brp_open(dev);
	exit_on_error(errcode, "Failed to connect to USB/HID device", dev);
	
	errcode = brp_VHL_ResolveFilename(dev, VHL_FILE_CARD_NAME, &vhlfile_id);
	exit_on_error(errcode, "Missing VHL file in reader configuration", dev);
	
	// Start scanning with Autoread and stop after first detected card
	// to run further VHL commands
	errcode = brp_AR_SetMode(dev, brp_AutoReadMode_EnableOnce);
	exit_on_error(errcode, "Reader is not configured for the Autoread operation mode", dev);
	
	printf("Please present card...");
	while (1)
	{
		printf(".");
		
		brp_buf uid;
		size_t uid_len;
		
		// Probe if card is detected
		errcode = brp_AR_GetMessage(dev, NULL, &uid, &uid_len, NULL);
		if (errcode == BRP_AR_ErrNoMessage) continue;
		exit_on_error(errcode, "Failed to poll for card", dev);
		break;
	}
	
	unsigned cntr;
	brp_buf read_cntr;
	
	// Read data from card
	errcode = brp_VHL_Read(dev, vhlfile_id, 0, sizeof(cntr), &read_cntr, NULL, NULL);
	exit_on_error(errcode, "Failed to read counter from card", dev);
	cntr = *(unsigned*)read_cntr;
	
	printf("\nDetected Card\n");
	printf("Counter value = %u\n", cntr);
	cntr += 1;
	
	// Write new data to card
	errcode = brp_VHL_Write(dev, vhlfile_id, 0, (brp_buf)&cntr, sizeof(cntr));
	exit_on_error(errcode, "Failed to write counter to card", dev);
	
	printf("New counter value = %u\n", cntr);
	
	printf("Now remove card again...");
	while (1)
	{
		printf(".");
		
		// Probe if card is removed again
		errcode = brp_VHL_IsSelected(dev);
		if (errcode == BRP_VHL_ErrCardNotSelected) break;
		exit_on_error(errcode, "Failed to probe for card", dev);
	}
	
	printf("\nDone\n");
	
	brp_destroy(dev);
	return EXIT_SUCCESS;
}
