2023-10-26 12:42 PM - edited 2023-11-01 10:52 AM
I am trying to do extended read multiple blocks using the following iOS code:
var blocksToRead: UInt8 = 64
// Create the command data
let cmd: [UInt8] = [
0x20, // Flags (0x20 -> read)
0x33, // Extended Read Multiple Blocks
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Tag ID bytes
0x00, 0x00, // Block number bytes
0x00, 0x00 // Number of blocks to read bytes
]
// Convert the command array to Data
let cmdData = Data(cmd)
iso15693Tag.customCommand(requestFlags: RequestFlag(rawValue: 0x20), customCommandCode: 0x33, customRequestParameters: Data(cmd)) {
(response: Data, error: Error?)
in // Handle response and errors similar to Android logic
if let error = error {
print("Transceive Error: \(error)") return
}
// Use response data for further processing
}
getting the following error:
Transceive Error: invalid parameter
Solved! Go to Solution.
2023-12-05 07:37 AM
hi again sahiljain,
I tested your code ScanNFCViewcontroller.txt in my iOS App, and all seems to be working fine.
I have just replaced the retryConnection function by session.restartPolling instead of tag.connect, printed the block number at each reading and added an action on button hit.
I let you see the code sample here attached.
Hope it helps.
Br
2023-10-30 03:32 AM
Hi,
0x20 is the flags byte setting the Address flag. With that you need to use a valid Tag ID bytes: 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 is for sure not the address of a tag in the field. You should have gotten this when the tag was discovered. Alternatively you could also use 0x00 as flag byte and omit the Tag ID. But then it will be in broadcast mode: All tags in the field would feel addressed and potentially start responding.
Regards, Ulysses
2023-10-30 03:56 AM
Here is the updated code with the same error as "invalid parameter"
var cmd: [UInt8] = [
0x20, // Flags (0x20 -> read) 0100000
0x33, //Extended Read Multiple Blocks
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Tag ID (placeholder, will be replaced)
0x00, // (10) Most sig byte of block number
0x00, // (11) Least sig byte of block number
BLOCKS_TO_READ,
0x00 //(13) Most sig byte of number of blocks to read
]
let tagId: [UInt8] = Array(tag.identifier)
cmd[2..<10] = tagId[0..<8]
let blockNumberBytes = withUnsafeBytes(of: blockNumber.bigEndian) { Array($0) }
bfprint("NFC_Tag blockNumberBytes: \(blockNumberBytes)")
cmd[10] = blockNumberBytes[2]
cmd[11] = blockNumberBytes[3]
let binaryStrings = cmd.map { byteToBinaryString($0) }
let cmdData = Data(cmd)
var responseData = Data()
bfprint("NFC_Tag sending customRequestParameters : \(cmd)")
tag.customCommand(requestFlags: RequestFlag(rawValue: 0x20),
customCommandCode: 0x33,
customRequestParameters: cmdData) { result in
switch result {
case .success(let response):
print(Array(response))
case .failure(let error):
// Handle error
self.session?.invalidate(errorMessage: error.localizedDescription)
}
}
2023-10-30 07:02 AM
Hi,
Please print what is actually being sent out. To me it seems that the flags and command byte are send two times - as part of customCommand() params and again as part of cmdData.
BR, Ulysses
2023-10-30 09:30 AM
2023-10-30 09:39 AM
You didn't print or look at my previous comment (2023-10-30 03:02 PM) , did you?
2023-10-30 09:59 AM
I understand that the bytes are being sent out one in command data and the other in custom command, but in iOS following API requires us to send the command data and custom command. and the result throws an error as an "invalid parameter"
API: customCommand(requestFlags: RequestFlag(rawValue: 0x20), customCommandCode: 0x33, customRequestParameters: cmdData)
Attaching screenshot of print command data
2023-10-31 01:37 AM
Hi,
hex values would have been more useful. But I can see that the UID bytes will need to be reversed - they are displayed MSB first but transmitted LSB first.
I am pretty sure that in the customRequestParameters the request flag and command code must not be repeated. Would be a very awkward API.
Also not sure about the request flag - how lower layer is handling as one of the bits in it is for data rate selection. Chances are that lower layer only supports the high datarate. So for sure using 0x02 is the better choice.
So I would start by issuing a a well-known simple command, get it working and then move to more advanced features (addressed mode, extended reads, multiple reads, etc.).
My start would be a single read block from address 0: RequestFlag=0x02, customCommandCode=0x20, customRequestParameters=[0x00]
Best Regards, Ulysses
2023-11-01 04:00 AM
I am attaching a iOS Swift code using "extendedReadSingleBlock" API to sequentially read one block at a time. iterated until all 2048 blocks are retrieved.
However, after reading the initial 2-3 blocks, we encounter the following issue:
[NFCTagReaderSession transceive:tagUpdate:error:]:883 Error Domain=NFCError Code=100 "Tag connection lost" UserInfo={NSLocalizedDescription=Tag connection lost}
To address this connection issue, we've implemented code that attempts to re-establish the connection and resume reading from the interrupted block. Unfortunately, the process persistently fails with the aforementioned error.
2023-12-05 06:00 AM
hi sahiljain
Regarding your issue with custom command, the iOS coreNFC does not support "non addressed mode" for this command. You must use the request flag [.highDataRate] or RequestFlag(rawValue: 0x02). This issue is well known and was raised to Apple since a long time ago. Unfortunately, it is not fixed yet in latest release.
Regarding issue with extendedSingleBlock, I'm checking your code, then will come back to you.
Br,
Victor