Taplinx iOS app reading Desfire EV2

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Taplinx iOS app reading Desfire EV2

1,144 Views
Octopussy
Contributor I

Hi,

I new to the Taplinx for iOS. I'm working on an app to read Desfire EV2 app data. I'm quite experienced with iOS development. I got an app running but I'm not sure how to correctly initiate a getDESFireEV2Instance to select the app and then start to read using authentication. My first step is to actually get the tag details and select the app.

When I call "libraryManager.getTagDetails" the app always crashes. Probably my calling sequence is still wrong.

verifyLicense is implemented and works

Attached is my code that I have so far.

I really hope someone would be able to point me into the right direction.

Thanks so much,

Martin

 

class NFCReader: NSObject, NFCTagReaderSessionDelegate, TapLinxApduHandlerProtocol {
	var session: NFCTagReaderSession?
	var handler: TapLinxApduHandler = TapLinxApduHandler()
	let libraryManager = TLLibraryManager()

	func startSession() {
		session = NFCTagReaderSession(pollingOption: .iso14443, delegate: self, queue: nil)
		session?.alertMessage = "Hold your iPhone near the NFC tag."
		session?.begin()
	}
	
	func tagReaderSessionDidBecomeActive(_ session: NFCTagReaderSession) {
		print("NFCReader.tagReaderSessionDidBecomeActive: Session active.")
	}
	
	func tagReaderSession(_ session: NFCTagReaderSession, didInvalidateWithError error: Error) {
		print("NFCReader.tagReaderSessionDidBecomeActive: Session invalidated: \(error.localizedDescription)")
	}
	
	func tagReaderSession(_ session: NFCTagReaderSession, didDetect tags: [NFCTag]) {
		guard let firstTag = tags.first else {
			print("NFCReader.tagReaderSession: No tags detected.")
			session.invalidate(errorMessage: "No tags detected.")
			return
		}
		
		switch firstTag {
			case .miFare(let miFareTag):
				print("NFCReader.tagReaderSession.connect(to): miFareTag detected")
				self.handleMiFareTag(miFareTag, session: session)
			default:
				print("NFCReader.tagReaderSession.connect(to): Unsupported tag type: \(firstTag)")
				session.invalidate(errorMessage: "Unsupported tag type.")
		}
	}
	
	
	private func handleMiFareTag(_ tag: NFCMiFareTag, session: NFCTagReaderSession) {
		print("handleMiFareTag")
		let reader = TL_IOSNFCReader(uid: tag.identifier, historicalBytes: Data())
		handler = TapLinxApduHandler(reader: reader)
		handler.delegate = self
		libraryManager.setApduHandlerWithApduHandler(handler)
		libraryManager.getTagDetails { tagDetails, success in
			print("getTagDetails: \(success)")
		}
		libraryManager.getDESFireEV2Instance().selectApplication(withAppID: appID) { result in
			print("result: \(result)")
		}
		
//		let desFireEV2 = libraryManager.getDESFireEV2Instance()
//		desFireEV2.getVersionOnCompletion { version, x  in
//			//print("DESFire EV2 Version \(version) - \(x)")
//		}
	}
	
	func apduExchange(withByteArray apduData: Data) -> TL_TagAPDUResponse? {
		var tagAPDUResponse: TL_TagAPDUResponse?
		print("MIFARE CAPDU -> \(apduData.hex)")
		
		return tagAPDUResponse
	}
}

 

 

Labels (2)
0 Kudos
Reply
10 Replies

1,057 Views
Octopussy
Contributor I

Hi ukcas,

unfortunately the call 

var libraryManager : TLLibraryManager! = TLLibraryManager.shared()

 

will crash. Here is the crash log.

Octopussy_0-1734436722982.png

So there seems to be something wrong with the "TLLibraryManager.shared()" call.

If you want I can send you a bare bone project that shows the issue.

Thanks very much,

Martin

 

 

0 Kudos
Reply

1,067 Views
ukcas
NXP Employee
NXP Employee

Dear Octopussy,

TLLibraryManager is a singleton class and we have a class method +(TLLibraryManager *)shared.

 

Try to instantiate like:

 

import UIKit
import CoreNFC
import Network
 
class ViewController: UIViewController {
    
    lazy var downloadQueue: OperationQueue = {
        var queue = OperationQueue()
        queue.name = "Execute Commands queue"
        queue.maxConcurrentOperationCount = 1
        return queue
    }()
    
    @IBOutlet var scanButton: UIButton? = UIButton()
    
    var connectedTag: NFCISO7816Tag?
    var connectedMifareTag: NFCMiFareTag?
    var tagReaderSession: NFCTagReaderSession!
    var uid = ""
    var isExecutingSelectedCommands = false
    var CommandsToExecute = [String]()
    var handler = TapLinxApduHandler()
    var currentTag: TL_TagInfo?
 
    var libraryManager : TLLibraryManager! = TLLibraryManager.shared()
...

func testMIFARELibraryManagerInstance() {
        let libraryMangager = TLLibraryManager.shared()
        XCTAssertNotNil(libraryMangager)
    }
...

 

 

0 Kudos
Reply

1,119 Views
Fabian_R
NXP TechSupport
NXP TechSupport

Hello, 

Thank you very much for working with us.

Unfortunately, we don't have an example for running in iOS but my recommendation would be to please check the Android example for NTAG and start by adapting this application to iOS. When you are able to correctly implement it on iOS I'm sure it will get easier.

Additionally, please let me know if you have already check the javadoc available in Taplinx site.

Best Regards,
Fabian
0 Kudos
Reply

1,099 Views
Octopussy
Contributor I

Hi Fabian,

the iOS TapLinx library is quite different from the Android one. The issue I'm having is that the initialization of the "TLLibraryManager" doesn't seem to work as expected. 

 

	let libraryManager = TLLibraryManager()
	libraryManager.getDESFireEV2Instance().selectApplication(withAppID: appID) { result in
			print("result: \(result)")
		}

 

This will always result in a crash. So it looks like the instantiation of the "TLLibraryManager" is wrong.

Calling 

 

TLLibraryManager.shared()

 

will also crash right away. But calling

 

TapLinxLibrary.shared()

 

works. so there seems to be an issuer on how the "TLLibraryManager" need to be instantiated.

I would need some help on how to instantiated the "TLLibraryManager" correctly so I can make additional call then.

Thanks,

Martin

Tags (1)
0 Kudos
Reply

920 Views
ukcas
NXP Employee
NXP Employee

Dear Martin,

 

Since library is an obfuscated build, it is not possible to debug the executable. Therefore it needs to be disabled in IDE options.

Follow below steps.

  1. Select the scheme that you are using to run the application
  2. Edit Scheme
  3. In the Info Tab, uncheck the Debug executable option.

Best regards,

TapLinx team

0 Kudos
Reply

904 Views
Octopussy
Contributor I

Hi,

now the app no longer crashes. Thanks for that hint.

I guess to save other people a lot of time this info should go into the "UG10045.pdf" document.

I can now successfully select the application. I have some trouble now to get the authentication and reading of a file working. Here is the info about the card.

Card Type: Desfire EV2

Crypto: AES

File number: 1

File Type: Standard Data File

Communication: Fully enciphered

Read access with Key Number: 1

File data: 10 bytes

Here is my current code:

desFireEV2.selectApplication(withAppID: appID) { success in
  print("selectApplication: success \(success)")
}

desFireEV2.authenticate(withCardKeyNo: 1, withAuthenticationType: .AES, withAuthKeyType: .AES128, withCommandSetForAuth:  .Native, withAuthkey: aesKey) { success in
 print("authenticate: success \(success)")
}

desFireEV2.readData(withFileNo: 1, withOffset: 0, withLength: 10) { data, success in
  print("readDataWithFileNo: success \(success) - data = \(data)")
}

 Authentication returns "success = true"

When calling"desFireEV2.readData" readData returns "success = false" and I see the following in the log

Command sent to card : F501

MIFARE CAPDU -> f501

[general] response.tag.type: DESFire

[general] response.responseData: {length = 1, bytes = 0xae}

Response received : AE

An exception occurred: ItF9fDb

Here are some details: com.nxp.nfclib.exceptions.PICCException: Authentication Error SW2 = -82

When I change the "withCommandSetForAuth" to ".ISO" I receive the following in the log

Command sent to card : 90F50000010100

MIFARE CAPDU -> 90f50000010100

[general] response.tag.type: DESFire

[general] response.responseData: {length = 2, bytes = 0x91ae}

Response received : 91AE

An exception occurred: ItF9fDb

Here are some details: com.nxp.nfclib.exceptions.PICCException: Authentication Error SW2 = -82

I'm not sure what I'm doing wrong here. Can you please help. This seems to be the last blocker to resolve.

Thanks,

Martin

0 Kudos
Reply

788 Views
pMolon
Contributor I

Hi,

I'm trying to figure out how to communicate with a DESFire EV card in my iOS app. My problem is that whenever I try to authenticate, I get an "Incomplete response received from PICC" error.

Below is my code:

let des3 = libraryManager.getDESFireEV3Instance()

// Default key
let defaultKey: [UInt8] = [0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF] // Default key (0xFF repeated)
let keyData = Data(defaultKey)

des3.authenticate(withCardKeyNo: 0, withAuthenticationType: .native, withAuthKeyType: .THREEDES, withCommandSetForAuth: .Native, withAuthkey: keyData, onCompletion: { isSuccess in
    print(isSuccess)
})

 

Response from the log:

[55205:3622464] AuthType - Native KeyType - THREEDES KeyInfo.KeyArray - {length = 16, bytes = 0xffffffffffffffffffffffffffffffff}, cardKeyNo - 0
[55205:3622464] [general] Command sent to card : 0A00
MIFARE CAPDU -> 0a00
[55205:3622464] [general] Response received : null
[55205:3622464] Exception com.nxp.nfclib.exceptions.InvalidResponseLengthException: Incomplete response received from PICC.

 

I'm not sure if I'm missing something in my setup. Any guidance would be greatly appreciated.

Thank you!

Tags (1)
0 Kudos
Reply

879 Views
Florian_Mikulik
NXP Employee
NXP Employee

Hi Martin,

From your pasted Log, it seems the code fails at a GetFileSettings command (F501 or 90 F5 00 00 01 01 00 as the ISO equivalent).

If i get it correctly, previous to this you are authenticating with Application Key 1. The reason for the failing GetFile settings therefore might be that the application requires an authentication with the Application Master Key (Key 0) for sending the GetFileSettings command. This would explaing the error code at this place.

Can you please crosscheck the configuration of the application with the DESFire datasheet, if this setting is enabled or not? You can also try to authentication with Key 0 before the read command and check if there is any difference.

In case this does not bring more clarity, please provide some more communication Logs that we can see what is going on. Ideally, if you can provide the APDUs, this would be perfect!

 

regards,

Florian

 

Customer Application Support Engineer - Gratkorn - Austria
0 Kudos
Reply

852 Views
Octopussy
Contributor I

Hi Florian,

I don't have the Application Master key 0. The additional info about the card / spec that I have is:

PICC Master Key Settings
Application / KeySetting can be viewed without PICC: Yes

Application Setting

Crypto setting : AES

Application / KeySetting can be viewed without Master key: No

File Level

File Level communication: Fully enciphered

The Android version of the app, developed many years ago with an older version of the Taplink SDK, uses a readData call passing "IDESFireEV1.CommunicationType.Enciphered" as one of the parameters.

I think this is what the "GetFileSettings" command is used for internally when I call "readData" to determine the file level encryption.

What can I do to resolve the issue? Is there another readData call like the one in the old SDK to specify the CommunicationType?

I do need a solution for the issue.

If you still need more logging with APDUs let me know.

Thanks,

Martin

0 Kudos
Reply

840 Views
Florian_Mikulik
NXP Employee
NXP Employee

Hi Martin,

 

Indeed, i have the same impression than you have.

Let me check internally and come back to you asap!

 

regards,

Florian

Customer Application Support Engineer - Gratkorn - Austria
0 Kudos
Reply