Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write to Mifare Classic 1K card in Electron App #7

Closed
PimButton opened this issue Feb 16, 2017 · 7 comments
Closed

Write to Mifare Classic 1K card in Electron App #7

PimButton opened this issue Feb 16, 2017 · 7 comments
Labels

Comments

@PimButton
Copy link

Hi @pokusew,

Thanks for the great library, it has saved me a lot of time! I am currently working on a app that should write some data to a Mifare 1Kb card from within an Electron app.

Because Electron does not support async and await I'm having some trouble integrating the example as shown in the readme.

This is my current code:

reader.on('card', card => {

        // card is object containig folowing data
        // [always] String type: TAG_ISO_14443_3 (standard nfc tags like Mifare) or TAG_ISO_14443_4 (Android HCE and others)
        // [only TAG_ISO_14443_3] String uid: tag uid
        // [only TAG_ISO_14443_4] Buffer data: raw data from select APDU response

        console.log(`${reader.reader.name}  card detected`, card);

        try {
          
         const key = 'FFFFFFFFFFFF';
         const keyType = 0x61;
        
         // we will authenticate block 4, 5, 6, 7 (which we want to read)
         Promise.all([
             reader.authenticate(4, keyType, key),
             reader.authenticate(5, keyType, key),
             reader.authenticate(6, keyType, key),
             reader.authenticate(7, keyType, key)
         ]);
        
         console.log(`blocks successfully authenticated`);
        
        } catch (err) {
         console.error(`error when authenticating data`, { reader: reader.name, card, err });
         return;
        }
        
        // I added the TimeOut to work around the missing await support
        setTimeout(function() {

          // example write 16bit integer
        try {

              // reader.write(blockNumber, data, blockSize = 4)
              // - blockNumber - memory block number where to start writing
              // - data - what to write
              // ! Caution! data.length must be divisible by blockSize

              const data = Buffer.allocUnsafe(16);
              data.writeInt16BE(800);

              reader.write(4, data);

              console.log(`data written`, { reader: reader.name, card });

          } catch (err) {
              console.error(`error when writing data`, { reader: reader.name, card, err });
          }

        }, 4000);

        

    });

This however does not work, I alway get the blocks successfully authenticated message, but I think that this since i removed await the catch function never gets called. The error message that I receive is Uncaught (in promise) WriteError: Write operation failed: Status code: 0x6300. Please see the screenshot below for the full output (the Data and Object array that are logged are other functions from the program, separate from this issue):
schermafbeelding 2017-02-16 om 14 57 56

If you require any more information I would be happy to provide it!
Thanks in advance,

@PimButton
Copy link
Author

So I experimented a bit more and just cloned the complete repository, ran the install command and uncommented the authentication code but still no luck.
The read command now works but writing to the chip still fails somehow. See this screenshot for output:

schermafbeelding 2017-02-17 om 16 14 07

Any tips for looking in the right direction?

@pokusew
Copy link
Owner

pokusew commented Feb 17, 2017

@PimButton 0x6300 is status code from the NFC card, that means, that the operation failed – the cause could be, that you are using bad key (or key type). Don't you need to authenticate also with another key (maybe key B) for writing data to your card?

@PimButton
Copy link
Author

Ok so another update:
Turns out the block size for Mifare 1K cards is 16 instead of 4. So I had to change the reader.write call to adjust for that. Writing now works in the standalone example.

However, still no luck in Electron. Reading / Writing seems to depend on Async / Await and that does not work in Electron by default. I tried using Babel but gives a lot of headache... Did you ever get this working?

@Mr-Black-Dahlia
Copy link

Can't you get async/await through externals?

@PimButton
Copy link
Author

@indiecore-fm would love to, but can't seem to find how to do that exactly. Any hints in the right direction?

@pokusew
Copy link
Owner

pokusew commented Feb 20, 2017

@PimButton Instead of async/await you can you Promises (which should work without transpiler because they are already supported in Chrome).

So with Promises the code could look like:

reader.on('card', card => {

	const key = 'FFFFFFFFFFFF';
	const keyType = KEY_TYPE_A; // KEY_TYPE_B

	// EXAMPLE reading and writing data to Mifare 1K with Promises
	// 16 bytes data assuming containing 16bit integer
	Promise.all([
		reader.authenticate(4, keyType, key),
		// you add more authenticate call if you want auth more blocks
	])
		// READ data
		.then(() => reader.read(4, 16, 16))
		.then(data => {

			console.log(`data read`, data);

			const number1 = data.readInt16BE();

			console.log(`data converted`, number1);

			// WRITE data

			const number2 = Buffer.allocUnsafe(16);
			number2.writeInt16BE(Math.random() * 100);

			return reader.write(4, number2, 16);

		})
		.then(() => {
			console.log(`data written`);
		})
		.catch(err => {
			console.log(`error`, err);
		});

});

But I recommend you to use Babel transpiler (with Webpack) in your Electron app.
It's really worth it. Then you can use all new ES features to write better code easier.
I am using it in production app with 100s deploys on real devices and it works pretty well. I can't imagine being without it.

You can take a look at https://github.com/chentsulin/electron-react-boilerplate, where both Babel and Webpack are set up.

If you have difficulties, I can help you set it up in your app if you want.

Hope, it helps.

@Mr-Black-Dahlia
Copy link

Of course! Promises! Great idea @pokusew I'll have to give that a try when I build my desktop app.

@pokusew pokusew closed this as completed May 28, 2017
@pokusew pokusew changed the title Write to Mifare 1Kb card in Electron App Write to Mifare Classic 1K card in Electron App May 28, 2017
pokusew added a commit that referenced this issue Jun 2, 2017
Improve examples (#16, #7)
Add new keywords into package.json
Add example from readme into examples folder
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants