2

I'm trying to read a page of a Mifare Ultralight tag (more specifically EnOcean PTM 215B) using NFCMifareTag.sendMifareCommand method after it has been discovered and connected onto. The problem is that all commands I've tried to send cause a "Tag connection lost" error which is quite odd as I've just successfully connected to it.

The (simplified) code looks like:

// tag has been determined to be of type NFCMifareTag earlier
session.connect(to: tag) { (error: Error?) in
  if (error != nil) {
    return
  }

  print("Connected to the tag")

  let data: [UInt8] = [0x30, 0x04, 0xEE, 0x26] // READ page 4 + CRC
  let dataPacket = Data(bytes: data, count: data.count)

  tag.sendMifareCommand(
    commandPacket: dataPacket,
    completionHandler: { (response: Data?, error: Error?) in
      if nil != error {
        return // <-- "Tag connection lost" error
      }
      // Handle the data as the operation was successful
    }
  )
}

I'd appreciate any pointers and/or ideas on what could be the reason for this behavior. As mentioned, I've tried various different data packets but all work exactly the same. I've also tried multiple different phones to eliminate hardware problems. The support was just added in iOS 13 and as such I couldn't find any examples online that would use the sendMifareUltralight command.

Roope Hakulinen
  • 7,326
  • 4
  • 43
  • 66

1 Answers1

7

According to the API (CoreNFC/NFCMiFareTag) the CRC will be calculated and inserted automatically. So in your case you only need to send [0x30, 0x04] to read page 4 to 7, the read command 0x30 will read 4 pages you will get 16 bytes.

 /**
 * @method sendMiFareCommand:completionHandler:
 *
 * @param command           The complete MiFare command.  CRC bytes are calculated and inserted automatically to the provided packet data frame.
 * @param completionHandler Completion handler called when the operation is completed.  error is nil if operation succeeds. A @link NFCErrorDomain @link/ error
 *                          is returned when there is a communication issue with the tag. Successfully read data blocks will be returned from the NSData object.
 *
 * @discussion              Send native MIFARE command to a tag.  Support MIFARE UltraLight, Plus, and DESFire products.
 *                          Crypto1 protocol is not supported.  Command chainning is handled internally by the method and the full response composed of the
 *                          individual fragment is returned in the completion handler.
 */
@available(iOS 13.0, *)
func sendMiFareCommand(commandPacket command: Data, completionHandler: @escaping (Data, Error?) -> Void)
wint
  • 1,266
  • 2
  • 14
  • 28
  • 2
    Works indeed without CRC. Documentation on [Apple's developer portal](https://developer.apple.com/documentation/corenfc/nfcmifaretag/3043838-sendmifarecommand?language=swift) states exactly the opposite. I never quite understood why would it ever be API user needs to calculate but with Apple you never understand the reasoning anyways. Anyways, thank you so much for this. I spent weeks banging my head against the wall with this. – Roope Hakulinen Feb 29 '20 at 12:30
  • 1
    Agree, it was really a big pain for we as well. Also super hard to find any example or tutorial. – wint Mar 01 '20 at 01:38
  • Thanks @wint, This is work for me. – Komal Goyani Feb 07 '22 at 05:55