Example #1
0
/*
 * Get a pointer to the next record in the provided TLV sequence.
 *             | 0x03 | 0x02 | 0xbe | 0xef | 0x00 | 0x00 | 0xfe |
 * First call  ---'                           |      |
 * Second call -------------------------------'      |
 * Third call  --------------------------------------'
 * Fourth call NULL
 */
uint8_t *
tlv_next (uint8_t *stream)
{
    uint8_t *res = NULL;
    if (stream[0] != TLV_TERMINATOR)
        res = stream + tlv_record_length (stream, NULL, NULL);

    return res;
}
Example #2
0
/*
 * Full-length of all TLV fields.
 */
size_t
tlv_sequence_length (uint8_t *stream)
{
    size_t res = 0;

    do {
        res += tlv_record_length (stream, NULL, NULL);
    } while ((stream = tlv_next (stream)));

    return res;
}
Example #3
0
/*
 * Decode TLV from data stream.
 */
uint8_t *
tlv_decode (const uint8_t *istream, uint8_t *type, uint16_t *size)
{
    size_t fls = 0;
    size_t fvs = 0;
    uint8_t *res = NULL;

    if (type)
        *type = istream[0];

    tlv_record_length (istream, &fls, &fvs);

    if (size) {
        *size = fvs;
    }

    if ((res = malloc (fvs))) {
        memcpy (res, istream + 1 + fls, fvs);
    }
    return res;
}
int
mifare_classic_read_ndef(MifareTag tag, char * buffer, char *max_size)
{
    int error = EXIT_SUCCESS;
    Mad mad;


	// NFCForum card has a MAD, load it.
	if (0 == mifare_classic_connect (tag)) {
	} else {
		return -2;
	}

	if ((mad = mad_read (tag))) {
		// Dump the NFCForum application using MAD information
		ssize_t len;
		if ((len = mifare_application_read (tag, mad, mad_nfcforum_aid, buffer, max_size, mifare_classic_nfcforum_public_key_a, MFC_KEY_A)) != -1) {
			uint8_t tlv_type;
			uint16_t tlv_data_len;
			uint8_t * tlv_data;
			uint8_t * pbuffer = buffer;
			uint8_t found = false;
			while (!found)
			{
				tlv_data = tlv_decode (pbuffer, &tlv_type, &tlv_data_len);
				switch (tlv_type) {
					case 0x00:
						printf ("NFC Forum application contains a \"NULL TLV\", Skipping...\n");	// According to [ANNFC1K4K], we skip this Tag to read further TLV blocks.
						pbuffer += tlv_record_length(pbuffer, NULL, NULL);
						if (pbuffer >= buffer + sizeof(buffer)) {
							error= -3;
							found = true;
						}
					break;
					case 0x03:
						printf ("NFC Forum application contains a \"NDEF Message TLV\".\n");
						found = true;
						error = tlv_data_len;
						memcpy(buffer,tlv_data,tlv_data_len);
					break;
					case 0xFD:
						printf ("NFC Forum application contains a \"Proprietary TLV\", Skipping...\n");	// According to [ANNFC1K4K], we can skip this TLV to read further TLV blocks.
						pbuffer += tlv_record_length(pbuffer, NULL, NULL);
						if (pbuffer >= buffer + sizeof(buffer)) {
							error= -4;
							found = true;
						}
					break;
					case 0xFE:
						printf ("NFC Forum application contains a \"Terminator TLV\", no available data.\n");
						error= -5;
						found = true;
					break;
					default:
						printf ("NFC Forum application contains an invalid TLV.\n");
						error= -6;
						found = true;
				}
			}

		} else {
			printf ("No NFC Forum application.\n");
			error= -7;
		}
	} else {
		printf ("No MAD detected.\n");
	}
	vPortFree (mad);

	return error;
}