Пример #1
0
static int detect_mad16(void)
{
	unsigned char tmp, tmp2, bit;
	int i, port;

	/*
	 * Check that reading a register doesn't return bus float (0xff)
	 * when the card is accessed using password. This may fail in case
	 * the card is in low power mode. Normally at least the power saving
	 * mode bit should be 0.
	 */

	if ((tmp = mad_read(MC1_PORT)) == 0xff)
	{
		DDB(printk("MC1_PORT returned 0xff\n"));
		return 0;
	}
	for (i = 0xf8d; i <= 0xf98; i++)
		if (!c924pnp)
			DDB(printk("Port %0x (init value) = %0x\n", i, mad_read(i))) else
			DDB(printk("Port %0x (init value) = %0x\n", i-0x80, mad_read(i)));

	if (board_type == C930)
		return detect_c930();

	/*
	 * Now check that the gate is closed on first I/O after writing
	 * the password. (This is how a MAD16 compatible card works).
	 */

	if ((tmp2 = inb(MC1_PORT)) == tmp)	/* It didn't close */
	{
		DDB(printk("MC1_PORT didn't close after read (0x%02x)\n", tmp2));
		return 0;
	}

	bit  = (c924pnp) ?     0x20 : 0x80;
	port = (c924pnp) ? MC2_PORT : MC1_PORT;

	tmp = mad_read(port);
	mad_write(port, tmp ^ bit);	/* Toggle a bit */
	if ((tmp2 = mad_read(port)) != (tmp ^ bit))	/* Compare the bit */
	{
		mad_write(port, tmp);	/* Restore */
		DDB(printk("Bit revert test failed (0x%02x, 0x%02x)\n", tmp, tmp2));
		return 0;
	}
	mad_write(port, tmp);	/* Restore */
	return 1;		/* Bingo */
}
Пример #2
0
void attach_mad16_mpu(struct address_info *hw_config)
{
	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
	{
#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)

		if (mad_read(MC1_PORT) & 0x20)
			hw_config->io_base = 0x240;
		else
			hw_config->io_base = 0x220;

		hw_config->name = "Mad16/Mozart";
		sb_dsp_init(hw_config);
#endif

		return;
	}
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
	if (!already_initialized)
		return;

	hw_config->driver_use_1 = SB_MIDI_ONLY;
	hw_config->name = "Mad16/Mozart";
	attach_uart401(hw_config);
#endif
}
Пример #3
0
void
madattach(struct wss_softc *sc)
{
	struct ad1848_softc *ac;
	unsigned char cs4231_mode;
	int joy;

	ac = (struct ad1848_softc *)&sc->sc_ad1848;
	if (sc->mad_chip_type == MAD_NONE)
		return;

	/* Do we want the joystick disabled? */
	joy = device_cfdata(ac->sc_dev)->cf_flags & 2 ? MC1_JOYDISABLE : 0;

	/* enable WSS emulation at the I/O port */
	mad_write(sc, MC1_PORT, M_WSS_PORT_SELECT(sc->mad_ioindex) | joy);
	mad_write(sc, MC2_PORT, MC2_NO_CD_DRQ); /* disable CD */
	mad_write(sc, MC3_PORT, 0xf0); /* Disable SB */

	cs4231_mode =
		strncmp(ac->chip_name, "CS4248", 6) == 0 ||
		strncmp(ac->chip_name, "CS4231", 6) == 0 ? 0x02 : 0;

	if (sc->mad_chip_type == MAD_82C929) {
		mad_write(sc, MC4_PORT, 0x92);
		mad_write(sc, MC5_PORT, 0xA5 | cs4231_mode);
		mad_write(sc, MC6_PORT, 0x03);	/* Disable MPU401 */
	} else {
		mad_write(sc, MC4_PORT, 0x02);
		mad_write(sc, MC5_PORT, 0x30 | cs4231_mode);
	}

#ifdef AUDIO_DEBUG
	if (wssdebug) {
		int i;
		for (i = MC1_PORT; i <= MC7_PORT; i++)
			DPRINTF(("port %03x after init = %02x\n",
				 i, mad_read(sc, i)));
	}
#endif
}
Пример #4
0
int probe_mad16_mpu(struct address_info *hw_config)
{
#if defined(CONFIG_UART401) && defined(CONFIG_MIDI)
	static int mpu_attached = 0;
	static int valid_ports[] = {
		0x330, 0x320, 0x310, 0x300
	};
	
	static short valid_irqs[] = {9, 10, 5, 7};
	unsigned char tmp;
	int i;				/* A variable with secret power */

	if (!already_initialized)	/* The MSS port must be initialized first */
		return 0;

	if (mpu_attached)		/* Don't let them call this twice */
		return 0;
	mpu_attached = 1;

	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
	{

#if defined(CONFIG_MIDI) && defined(CONFIG_MAD16_OLDCARD)
		unsigned char   tmp;

		tmp = mad_read(MC3_PORT);

		/* 
		 * MAD16 SB base is defined by the WSS base. It cannot be changed 
		 * alone.
		 * Ignore configured I/O base. Use the active setting. 
		 */

		if (mad_read(MC1_PORT) & 0x20)
			hw_config->io_base = 0x240;
		else
			hw_config->io_base = 0x220;

		switch (hw_config->irq)
		{
			case 5:
				tmp = (tmp & 0x3f) | 0x80;
				break;
			case 7:
				tmp = (tmp & 0x3f);
				break;
			case 11:
				tmp = (tmp & 0x3f) | 0x40;
				break;
			default:
				printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
				return 0;
		}

		mad_write(MC3_PORT, tmp | 0x04);
		hw_config->driver_use_1 = SB_MIDI_ONLY;
		return sb_dsp_detect(hw_config);
#else
		return 0;
#endif
	}
	tmp = mad_read(MC6_PORT) & 0x83;
	tmp |= 0x80;		/* MPU-401 enable */

/*
 * Set the MPU base bits
 */

	for (i = 0; i < 5; i++)
	{
		if (i > 3)	/* Out of array bounds */
		{
			printk(KERN_ERR "MAD16 / Mozart: Invalid MIDI port 0x%x\n", hw_config->io_base);
			return 0;
		}
		if (valid_ports[i] == hw_config->io_base)
		{
			tmp |= i << 5;
			break;
		}
	}

/*
 * Set the MPU IRQ bits
 */

	for (i = 0; i < 5; i++)
	{
		if (i > 3)	/* Out of array bounds */
		{
			printk(KERN_ERR "MAD16 / Mozart: Invalid MIDI IRQ %d\n", hw_config->irq);
			return 0;
		}
		if (valid_irqs[i] == hw_config->irq)
		{
			tmp |= i << 3;
			break;
		}
	}
	mad_write(MC6_PORT, tmp);	/* Write MPU401 config */

	return probe_uart401(hw_config);
#else
	return 0;
#endif
}
Пример #5
0
int probe_mad16(struct address_info *hw_config)
{
	int i;
	static int valid_ports[] = 
	{
		0x530, 0xe80, 0xf40, 0x604
	};
	unsigned char tmp;
	unsigned char cs4231_mode = 0;

	int ad_flags = 0;

	if (already_initialized)
		return 0;

	mad16_osp = hw_config->osp;

	/*
	 *    Check that all ports return 0xff (bus float) when no password
	 *      is written to the password register.
	 */

	DDB(printk("--- Detecting MAD16 / Mozart ---\n"));
	if (!chip_detect())
		return 0;

	if (board_type == C930)
		return init_c930(hw_config);


	for (i = 0xf8d; i <= 0xf93; i++)
		if (!c924pnp)
			DDB(printk("port %03x = %02x\n", i, mad_read(i))) else
			DDB(printk("port %03x = %02x\n", i-0x80, mad_read(i)));

/*
 * Set the WSS address
 */

	tmp = (mad_read(MC1_PORT) & 0x0f) | 0x80;	/* Enable WSS, Disable SB */

	for (i = 0; i < 5; i++)
	{
		if (i > 3)	/* Not a valid port */
		{
			printk(KERN_ERR "MAD16/Mozart: Bad WSS base address 0x%x\n", hw_config->io_base);
			return 0;
		}
		if (valid_ports[i] == hw_config->io_base)
		{
			tmp |= i << 4;	/* WSS port select bits */
			break;
		}
	}

	/*
	 * Set optional CD-ROM and joystick settings.
	 */

	tmp &= ~0x0f;
#if defined(MAD16_CONF)
	tmp |= ((MAD16_CONF) & 0x0f);	/* CD-ROM and joystick bits */
#endif
	mad_write(MC1_PORT, tmp);

#if defined(MAD16_CONF) && defined(MAD16_CDSEL)
	tmp = MAD16_CDSEL;
#else
	tmp = mad_read(MC2_PORT);
#endif

#ifdef MAD16_OPL4
	tmp |= 0x20;		/* Enable OPL4 access */
#endif

	mad_write(MC2_PORT, tmp);
	mad_write(MC3_PORT, 0xf0);	/* Disable SB */

	if (board_type == C924)	/* Specific C924 init values */
	{
		mad_write(MC4_PORT, 0xA0);
		mad_write(MC5_PORT, 0x05);
		mad_write(MC6_PORT, 0x03);
	}
	if (!ad1848_detect(hw_config->io_base + 4, &ad_flags, mad16_osp))
		return 0;

	if (ad_flags & (AD_F_CS4231 | AD_F_CS4248))
		cs4231_mode = 0x02;	/* CS4248/CS4231 sync delay switch */

	if (board_type == C929)
	{
		mad_write(MC4_PORT, 0xa2);
		mad_write(MC5_PORT, 0xA5 | cs4231_mode);
		mad_write(MC6_PORT, 0x03);	/* Disable MPU401 */
	}
	else
	{
		mad_write(MC4_PORT, 0x02);
		mad_write(MC5_PORT, 0x30 | cs4231_mode);
	}

	for (i = 0xf8d; i <= 0xf93; i++) if (!c924pnp)
		DDB(printk("port %03x after init = %02x\n", i, mad_read(i))) else
		DDB(printk("port %03x after init = %02x\n", i-0x80, mad_read(i)));
	wss_init(hw_config);

	return 1;
}
Пример #6
0
static int chip_detect(void)
{
	int i;

	/*
	 *    Then try to detect with the old password
	 */
	board_type = C924;

	DDB(printk("Detect using password = 0xE5\n"));
	
	if (!detect_mad16())	/* No luck. Try different model */
	{
		board_type = C928;

		DDB(printk("Detect using password = 0xE2\n"));

		if (!detect_mad16())
		{
			board_type = C929;

			DDB(printk("Detect using password = 0xE3\n"));

			if (!detect_mad16())
			{
				if (inb(PASSWD_REG) != 0xff)
					return 0;

				/*
				 * First relocate MC# registers to 0xe0e/0xe0f, disable password 
				 */

				outb((0xE4), PASSWD_REG);
				outb((0x80), PASSWD_REG);

				board_type = C930;

				DDB(printk("Detect using password = 0xE4\n"));

				for (i = 0xf8d; i <= 0xf93; i++)
					DDB(printk("port %03x = %02x\n", i, mad_read(i)));
                                if(!detect_mad16()) {

				  /* The C931 has the password reg at F8D */
				  outb((0xE4), 0xF8D);
				  outb((0x80), 0xF8D);
				  DDB(printk("Detect using password = 0xE4 for C931\n"));

				  if (!detect_mad16()) {
				    board_type = C924;
				    c924pnp++;
				    DDB(printk("Detect using password = 0xE5 (again), port offset -0x80\n"));
				    if (!detect_mad16()) {
				      c924pnp=0;
				      return 0;
				    }
				  
				    DDB(printk("mad16.c: 82C924 PnP detected\n"));
				  }
				}
				else
				  DDB(printk("mad16.c: 82C930 detected\n"));
			} else
				DDB(printk("mad16.c: 82C929 detected\n"));
		} else {
			unsigned char model;

			if (((model = mad_read(MC3_PORT)) & 0x03) == 0x03) {
				DDB(printk("mad16.c: Mozart detected\n"));
				board_type = MOZART;
			} else {
				DDB(printk("mad16.c: 82C928 detected???\n"));
				board_type = C928;
			}
		}
	}
	return 1;
}
Пример #7
0
static int detect_c930(void)
{
	unsigned char   tmp = mad_read(MC1_PORT);

	if ((tmp & 0x06) != 0x06)
	{
		DDB(printk("Wrong C930 signature (%x)\n", tmp));
		/* return 0; */
	}
	mad_write(MC1_PORT, 0);

	if (mad_read(MC1_PORT) != 0x06)
	{
		DDB(printk("Wrong C930 signature2 (%x)\n", tmp));
		/* return 0; */
	}
	mad_write(MC1_PORT, tmp);	/* Restore bits */

	mad_write(MC7_PORT, 0);
	if ((tmp = mad_read(MC7_PORT)) != 0)
	{
		DDB(printk("MC7 not writable (%x)\n", tmp));
		return 0;
	}
	mad_write(MC7_PORT, 0xcb);
	if ((tmp = mad_read(MC7_PORT)) != 0xcb)
	{
		DDB(printk("MC7 not writable2 (%x)\n", tmp));
		return 0;
	}

	tmp = mad_read(MC0_PORT+18);
	if (tmp == 0xff || tmp == 0x00)
		return 1;
	/* We probably have a C931 */
	DDB(printk("Detected C931 config=0x%02x\n", tmp));
	c931_detected = 1;

	/*
         * We cannot configure the chip if it is in PnP mode.
         * If we have a CSN assigned (bit 8 in MC13) we first try
         * a software reset, then a software power off, finally
         * Clearing PnP mode. The last option is not
	 * Bit 8 in MC13 
         */
	if ((mad_read(MC0_PORT+13) & 0x80) == 0)
		return 1;

	/* Software reset */
	mad_write(MC9_PORT, 0x02);
	mad_write(MC9_PORT, 0x00);

	if ((mad_read(MC0_PORT+13) & 0x80) == 0)
		return 1;
	
	/* Power off, and on again */
	mad_write(MC9_PORT, 0xc2);
	mad_write(MC9_PORT, 0xc0);

	if ((mad_read(MC0_PORT+13) & 0x80) == 0)
		return 1;
	
#if 0	
	/* Force off PnP mode. This is not recommended because
	 * the PnP bios will not recognize the chip on the next
	 * warm boot and may assignd different resources to other
	 * PnP/PCI cards.
	 */
	mad_write(MC0_PORT+17, 0x04);
#endif
	return 1;
}
Пример #8
0
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;
}
Пример #9
0
void
test_mifare_classic_mad (void)
{
    MifareClassicKey key_a_transport = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    MifareClassicKey key_b_sector_00 = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };
    MifareClassicKey key_b_sector_10 = { 0x1a, 0x98, 0x2c, 0x7e, 0x45 ,0x9a };
    MifareClassicBlock tb;
    Mad mad;
    int res;

    /*  __  __   _   ___      _
     * |  \/  | /_\ |   \__ _/ |
     * | |\/| |/ _ \| |) \ V / |
     * |_|  |_/_/ \_\___/ \_/|_|
     */

    mad = mad_new (1);
    cut_assert_not_null (mad, cut_message ("mad_new() failed"));

    // Prepare sector 0x00 for writing a MAD.
    res = mifare_classic_authenticate (tag, 0x00, key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));

    mifare_classic_trailer_block (&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_00);

    res = mifare_classic_write (tag, 0x03, tb);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));

    // Write the empty MAD
    res = mad_write (tag, mad, key_b_sector_00, NULL);
    cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));


    // Check the empty MAD
    MifareClassicBlock ref_01 = {
        0xce, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    MifareClassicBlock ref_02 = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    MifareClassicBlock data;

    res = mifare_classic_authenticate (tag, 0x01, mad_public_key_a, MFC_KEY_A);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));

    res = mifare_classic_read (tag, 0x01, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_01, sizeof (ref_01), data, sizeof (data), cut_message ("Wrong data"));

    res = mifare_classic_read (tag, 0x02, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_02, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data"));

    Mad mad2 = mad_read (tag);
    cut_assert_not_null (mad2, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (mad, sizeof (mad), mad2, sizeof (mad2), cut_message ("Wrong MAD"));

    const char application_data[] = "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
                                    "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
                                    "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
                                    "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
                                    "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> " \
                                    "APPLICATION DATA >> APPLICATION DATA >> APPLICATION DATA >> ";

    MadAid aid = {
        .function_cluster_code = 0x01,
        .application_code      = 0x12
    };

    // Write some data in the application
    MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, aid, sizeof (application_data));
    cut_assert_not_null (sectors, cut_message ("mifare_application_alloc() failed"));
    free (sectors);

    res = mad_write (tag, mad, key_b_sector_00, NULL);
    cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));

    ssize_t s = mifare_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed"));

    char read_buf[500];

    // Read it again
    s = mifare_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_read() failed"));
    cut_assert_equal_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data"));

    mad_free (mad);
    mad_free (mad2);

    // Revert to the transport configuration
    res = mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
    res = mifare_classic_format_sector (tag, 0x00);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));

    /*  __  __   _   ___      ___
     * |  \/  | /_\ |   \__ _|_  )
     * | |\/| |/ _ \| |) \ V // /
     * |_|  |_/_/ \_\___/ \_//___|
     */
    if (freefare_get_tag_type (tag) != CLASSIC_4K) {
        cut_omit ("MADv2 requires a MIFARE Classic 4K to be tested");
    }

    mad = mad_new (2);
    cut_assert_not_null (mad, cut_message ("mad_new() failed"));

    // Prepare sector 0x00 for writing a MAD.
    res = mifare_classic_authenticate (tag, 0x00, key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));

    mifare_classic_trailer_block (&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_00);

    res = mifare_classic_write (tag, 0x03, tb);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));

    // Prepare sector 0x10 for writing a MAD.
    res = mifare_classic_authenticate (tag, 0x40, key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));

    mifare_classic_trailer_block (&tb, key_a_transport, 00, 00, 00, 06, 0x00, key_b_sector_10);

    res = mifare_classic_write (tag, 0x43, tb);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_write() failed"));

    // Write the empty MAD
    res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10);
    cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));

    // Check the empty MAD

    res = mifare_classic_authenticate (tag, 0x01, mad_public_key_a, MFC_KEY_A);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));

    res = mifare_classic_read (tag, 0x01, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_01, sizeof (ref_01), data, sizeof (data), cut_message ("Wrong data"));

    res = mifare_classic_read (tag, 0x02, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_02, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data"));

    MifareClassicBlock ref_40 = {
        0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    MifareClassicBlock ref_41 = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };
    MifareClassicBlock ref_42 = {
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
    };

    res = mifare_classic_authenticate (tag, 0x40, mad_public_key_a, MFC_KEY_A);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));

    res = mifare_classic_read (tag, 0x40, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_40, sizeof (ref_01), data, sizeof (data), cut_message ("Wrong data"));

    res = mifare_classic_read (tag, 0x41, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_41, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data"));

    res = mifare_classic_read (tag, 0x42, &data);
    cut_assert_equal_int (0, res, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (ref_42, sizeof (ref_02), data, sizeof (data), cut_message ("Wrong data"));


    mad2 = mad_read (tag);
    cut_assert_not_null (mad2, cut_message ("mad_read() failed"));
    cut_assert_equal_memory (mad, sizeof (mad), mad2, sizeof (mad2), cut_message ("Wrong MAD"));

    // Write some data in the application
    sectors = mifare_application_alloc (mad, aid, sizeof (application_data));
    cut_assert_not_null (sectors, cut_message ("mifare_application_alloc() failed"));
    free (sectors);

    res = mad_write (tag, mad, key_b_sector_00, key_b_sector_10);
    cut_assert_equal_int (0, res, cut_message ("mad_write() failed"));

    s = mifare_application_write (tag, mad, aid, &application_data, sizeof (application_data), key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_write() failed"));

    // Read it again
    s = mifare_application_read (tag, mad, aid, read_buf, sizeof (application_data), key_a_transport, MFC_KEY_A);
    cut_assert_equal_int (sizeof (application_data), s, cut_message ("mifare_application_read() failed"));
    cut_assert_equal_memory (application_data, sizeof (application_data), read_buf, s, cut_message ("Wrong application data"));

    mad_free (mad);
    mad_free (mad2);

    // Revert to the transport configuration
    res = mifare_classic_authenticate (tag, 0x00, key_b_sector_00, MFC_KEY_B);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
    res = mifare_classic_format_sector (tag, 0x00);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));

    res = mifare_classic_authenticate (tag, 0x40, key_b_sector_10, MFC_KEY_B);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_authenticate() failed"));
    res = mifare_classic_format_sector (tag, 0x10);
    cut_assert_equal_int (0, res, cut_message ("mifare_classic_format_sector() failed"));

}
Пример #10
0
int
main(int argc, char *argv[])
{
	
	MYSQL *conn;
	MYSQL_RES *result;
	MYSQL_ROW row;
	int retval;
	
	conn = mysql_init(NULL);
	
	retval = mysql_real_connect(conn, def_host_name, def_user_name, def_password, def_db_name, def_port_num, def_socket_name, def_client_flag);
	if(!retval)
	{
		printf("Error connecting to database: %s\n", mysql_error(conn));
		return -1;
	}
	printf("Connection successful\n");
	
	int error = 0;
    nfc_device_t *device = NULL;
    MifareTag *tags = NULL;
    Mad mad;
    MifareClassicKey transport_key = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	
	char ndef_input[15] = {'\0'};
	char ID[9] = {'\0'};
	double balance = 0;

	printf("\nID: ");
	scanf("%s", ID);
	while (getchar() != '\n') continue;
	
	printf("\nBalance: ");
	scanf("%lf", &balance);
	while (getchar() != '\n') continue;
	
	ID[0] = toupper(ID[0]);
	ID[1] = toupper(ID[1]);
	
	char balance_char[6] = {'\0'};
	snprintf(balance_char, 6, "%.2f", balance);
	
	//ensure balance always with 4 digit, 4.00 => 04.00
	char final_balance[6] = {'\0'};
	if(strlen(balance_char) != 5)
	{
		strcat(final_balance, "0");
		strcat(final_balance, balance_char);
	}
	else
	{
		strcpy(final_balance, balance_char);
	}

	strcat(ndef_input, ID);
	strcat(ndef_input, final_balance);

	int i = 0;
    if (ndef_input == NULL) {
		printf("Write default message.\n");
		for(i=0; i < sizeof(ndef_default_msg); i++)
		{
			ndef_msg[i] = (uint8_t)ndef_default_msg[i];
		}
			
        ndef_msg_len = sizeof(ndef_default_msg);
    } 
	else {
		for(i=0; i < strlen(ndef_input); i++)
		{
			ndef_msg[i] = (uint8_t)ndef_input[i];
		}
			
		ndef_msg_len = strlen(ndef_input);
    }
    printf ("NDEF message is %zu bytes long.\n", ndef_msg_len);

    struct mifare_classic_key_and_type *card_write_keys;
    if (!(card_write_keys = malloc (40 * sizeof (*card_write_keys)))) {
		err (EXIT_FAILURE, "malloc");
    }

    nfc_device_desc_t devices[8];
    size_t device_count;

    nfc_list_devices (devices, 8, &device_count);
    if (!device_count)
		errx (EXIT_FAILURE, "No NFC device found.");

    for (size_t d = 0; d < device_count; d++) {
		device = nfc_connect (&(devices[d]));
		if (!device) {
			warnx ("nfc_connect() failed.");
			error = EXIT_FAILURE;
			continue;
		}

		tags = freefare_get_tags (device);
		if (!tags) {
			nfc_disconnect (device);
			errx (EXIT_FAILURE, "Error listing MIFARE classic tag.");
		}

		for (int i = 0; (!error) && tags[i]; i++) 
		{
			switch (freefare_get_tag_type (tags[i])) {
				case CLASSIC_1K:
				case CLASSIC_4K:
					break;
				default:
					continue;
			}

			char *tag_uid = freefare_get_tag_uid (tags[i]);
			char buffer[BUFSIZ];

			printf ("Found %s with UID %s.\n", freefare_get_tag_friendly_name (tags[i]), tag_uid);
			bool write_ndef = true;
				
			for (int n = 0; n < 40; n++) {
				memcpy(card_write_keys[n].key, transport_key, sizeof (transport_key));
				card_write_keys[n].type = MFC_KEY_A;
			}

			if (write_ndef) 
			{
				switch (freefare_get_tag_type (tags[i])) {
					case CLASSIC_4K:
						if (!search_sector_key (tags[i], 0x10, &(card_write_keys[0x10].key), &(card_write_keys[0x10].type))) {
							error = 1;
							goto error;
						}
						/* fallthrough */
					case CLASSIC_1K:
						if (!search_sector_key (tags[i], 0x00, &(card_write_keys[0x00].key), &(card_write_keys[0x00].type))) {
							error = 1;
							goto error;
						}
						break;
					default:
						/* Keep compiler quiet */
						break;
				}

				if (!error) {
					/* Ensure the auth key is always a B one. If not, change it! */
					switch (freefare_get_tag_type (tags[i])) {
						case CLASSIC_4K:
						if (card_write_keys[0x10].type != MFC_KEY_B) {
							if( 0 != fix_mad_trailer_block (device, tags[i], 0x10, card_write_keys[0x10].key, card_write_keys[0x10].type)) {
								error = 1;
								goto error;
							}
							memcpy (&(card_write_keys[0x10].key), &default_keyb, sizeof (MifareClassicKey));
							card_write_keys[0x10].type = MFC_KEY_B;
						}
						/* fallthrough */
						case CLASSIC_1K:
						if (card_write_keys[0x00].type != MFC_KEY_B) {
							if( 0 != fix_mad_trailer_block (device, tags[i], 0x00, card_write_keys[0x00].key, card_write_keys[0x00].type)) {
								error = 1;
								goto error;
							}
							memcpy (&(card_write_keys[0x00].key), &default_keyb, sizeof (MifareClassicKey));
							card_write_keys[0x00].type = MFC_KEY_B;
							}
							break;
						default:
							/* Keep compiler quiet */
							break;
					}
				}

				size_t encoded_size;
				uint8_t *tlv_data = tlv_encode (3, ndef_msg, ndef_msg_len, &encoded_size);

				/*
				 * At his point, we should have collected all information needed to
				 * succeed.
				 */

				// If the card already has a MAD, load it.
				if ((mad = mad_read (tags[i]))) {
					// If our application already exists, erase it.
					MifareClassicSectorNumber *sectors, *p;
					sectors = p = mifare_application_find (mad, mad_nfcforum_aid);
					if (sectors) {
						while (*p) {
							if (mifare_classic_authenticate (tags[i], mifare_classic_sector_last_block(*p), default_keyb, MFC_KEY_B) < 0) {
								nfc_perror (device, "mifare_classic_authenticate");
								error = 1;
								goto error;
							}
							if (mifare_classic_format_sector (tags[i], *p) < 0) {
								nfc_perror (device, "mifare_classic_format_sector");
								error = 1;
								goto error;
							}
							p++;
						}
					}
					free (sectors);
					mifare_application_free (mad, mad_nfcforum_aid);
				} else {

					// Create a MAD and mark unaccessible sectors in the card
					if (!(mad = mad_new ((freefare_get_tag_type (tags[i]) == CLASSIC_4K) ? 2 : 1))) {
						perror ("mad_new");
						error = 1;
						goto error;
					}

					MifareClassicSectorNumber max_s;
					switch (freefare_get_tag_type (tags[i])) {
						case CLASSIC_1K:
							max_s = 15;
							break;
						case CLASSIC_4K:
							max_s = 39;
							break;
						default:
							/* Keep compiler quiet */
							break;
					}

					// Mark unusable sectors as so
					for (size_t s = max_s; s; s--) {
						if (s == 0x10) 
							continue;
						if (!search_sector_key (tags[i], s, &(card_write_keys[s].key), &(card_write_keys[s].type))) {
							mad_set_aid (mad, s, mad_defect_aid);
						} else if ((memcmp (card_write_keys[s].key, transport_key, sizeof (transport_key)) != 0) &&
							   (card_write_keys[s].type != MFC_KEY_A)) {
									// Revert to transport configuration
									if (mifare_classic_format_sector (tags[i], s) < 0) {
										nfc_perror (device, "mifare_classic_format_sector");
										error = 1;
										goto error;
									}
						}
					}
				}

				MifareClassicSectorNumber *sectors = mifare_application_alloc (mad, mad_nfcforum_aid, encoded_size);
				if (!sectors) {
					nfc_perror (device, "mifare_application_alloc");
					error = EXIT_FAILURE;
					goto error;
				}

				if (mad_write (tags[i], mad, card_write_keys[0x00].key, card_write_keys[0x10].key) < 0) {
					nfc_perror (device, "mad_write");
					error = EXIT_FAILURE;
					goto error;
				}

				int s = 0;
				while (sectors[s]) {
					MifareClassicBlockNumber block = mifare_classic_sector_last_block (sectors[s]);
					MifareClassicBlock block_data;
					mifare_classic_trailer_block (&block_data, mifare_classic_nfcforum_public_key_a, 0x0, 0x0, 0x0, 0x6, 0x40, default_keyb);
					if (mifare_classic_authenticate (tags[i], block, card_write_keys[sectors[s]].key, card_write_keys[sectors[s]].type) < 0) {
						nfc_perror (device, "mifare_classic_authenticate");
						error = EXIT_FAILURE;
						goto error;
					}
					if (mifare_classic_write (tags[i], block, block_data) < 0) {
						nfc_perror (device, "mifare_classic_write");
						error = EXIT_FAILURE;
						goto error;
					}
					s++;
				}

				if ((ssize_t) encoded_size != mifare_application_write (tags[i], mad, mad_nfcforum_aid, tlv_data, encoded_size, default_keyb, MCAB_WRITE_KEYB)) {
					nfc_perror (device, "mifare_application_write");
					error = EXIT_FAILURE;
					goto error;
				}


				//create new student record in database
				char sql_stmnt[57] = {'\0'};
				int n = 0;
				
				//filter tag_uid
				ulong uid_length = strlen(tag_uid);
				char uid_esc[(2 * uid_length)+1];
				mysql_real_escape_string(conn, uid_esc, tag_uid, uid_length);

				//filter ID
				ulong id_length = strlen(ID);
				char id_esc[(2 * id_length)+1];
				mysql_real_escape_string(conn, id_esc, ID, id_length);
				
				n = snprintf(sql_stmnt, 57, "INSERT INTO student VALUES('%s', '%s', %.1f)", uid_esc, id_esc, balance);
				retval = mysql_real_query(conn, sql_stmnt, n);
				if(retval)
				{
					printf("Inserting data from DB Failed\n");
					return -1;
				}
				printf("Insert to DB successful\n");
				
				free (sectors);

				free (tlv_data);

				free (mad);
			
			}
			error:
			free (tag_uid);
			
		}
		//should at the line 412, but the compiler keep on complaining
		//jump into scope of identifier with variably modified type
		//no idea why that happens, goto is always call inside any {} to outside error:
		//even at 412, still not outside enough
		

		freefare_free_tags (tags);
		nfc_disconnect (device);
    }

    free (card_write_keys);
	mysql_free_result(result);
	mysql_close(conn);

		exit (error);
}
Пример #11
0
static int __init probe_mad16_mpu(struct address_info *hw_config)
{
	static int mpu_attached = 0;
	unsigned char tmp;

	if (!already_initialized)	/* The MSS port must be initialized first */
		return 0;

	if (mpu_attached)		/* Don't let them call this twice */
		return 0;
	mpu_attached = 1;

	if (board_type < C929)	/* Early chip. No MPU support. Just SB MIDI */
	{

#ifdef CONFIG_MAD16_OLDCARD

		tmp = mad_read(MC3_PORT);

		/* 
		 * MAD16 SB base is defined by the WSS base. It cannot be changed 
		 * alone.
		 * Ignore configured I/O base. Use the active setting. 
		 */

		if (mad_read(MC1_PORT) & 0x20)
			hw_config->io_base = 0x240;
		else
			hw_config->io_base = 0x220;

		switch (hw_config->irq)
		{
			case 5:
				tmp = (tmp & 0x3f) | 0x80;
				break;
			case 7:
				tmp = (tmp & 0x3f);
				break;
			case 11:
				tmp = (tmp & 0x3f) | 0x40;
				break;
			default:
				printk(KERN_ERR "mad16/Mozart: Invalid MIDI IRQ\n");
				return 0;
		}

		mad_write(MC3_PORT, tmp | 0x04);
		hw_config->driver_use_1 = SB_MIDI_ONLY;
		if (!sb_dsp_detect(hw_config, 0, 0, NULL))
			return 0;

		if (mad_read(MC1_PORT) & 0x20)
			hw_config->io_base = 0x240;
		else
			hw_config->io_base = 0x220;

		hw_config->name = "Mad16/Mozart";
		sb_dsp_init(hw_config, THIS_MODULE);
		return 1;
#else
		/* assuming all later Mozart cards are identified as
		 * either 82C928 or Mozart. If so, following code attempts
		 * to set MPU register. TODO - add probing
		 */

		tmp = mad_read(MC8_PORT);

		switch (hw_config->irq)
		{
			case 5:
				tmp |= 0x08;
				break;
			case 7:
				tmp |= 0x10;
				break;
			case 9:
				tmp |= 0x18;
				break;
			case 10:
				tmp |= 0x20;
				break;
			case 11:
				tmp |= 0x28;
				break;
			default:
				printk(KERN_ERR "mad16/MOZART: invalid mpu_irq\n");
				return 0;
		}

		switch (hw_config->io_base)
		{
			case 0x300:
				tmp |= 0x01;
				break;
			case 0x310:
				tmp |= 0x03;
				break;
			case 0x320:
				tmp |= 0x05;
				break;
			case 0x330:
				tmp |= 0x07;
				break;
			default:
				printk(KERN_ERR "mad16/MOZART: invalid mpu_io\n");
				return 0;
		}

		mad_write(MC8_PORT, tmp);	/* write MPU port parameters */
		goto probe_401;
#endif
	}
	tmp = mad_read(MC6_PORT) & 0x83;
	tmp |= 0x80;		/* MPU-401 enable */

	/* Set the MPU base bits */

	switch (hw_config->io_base)
	{
		case 0x300:
			tmp |= 0x60;
			break;
		case 0x310:
			tmp |= 0x40;
			break;
		case 0x320:
			tmp |= 0x20;
			break;
		case 0x330:
			tmp |= 0x00;
			break;
		default:
			printk(KERN_ERR "MAD16: Invalid MIDI port 0x%x\n", hw_config->io_base);
			return 0;
	}

	/* Set the MPU IRQ bits */

	switch (hw_config->irq)
	{
		case 5:
			tmp |= 0x10;
			break;
		case 7:
			tmp |= 0x18;
			break;
		case 9:
			tmp |= 0x00;
			break;
		case 10:
			tmp |= 0x08;
			break;
		default:
			printk(KERN_ERR "MAD16: Invalid MIDI IRQ %d\n", hw_config->irq);
			break;
	}
			
	mad_write(MC6_PORT, tmp);	/* Write MPU401 config */

#ifndef CONFIG_MAD16_OLDCARD
probe_401:
#endif
	hw_config->driver_use_1 = SB_MIDI_ONLY;
	hw_config->name = "Mad16/Mozart";
	return probe_uart401(hw_config, THIS_MODULE);
}