PN7120 raw transceive command doesn't work

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

PN7120 raw transceive command doesn't work

Jump to solution
2,411 Views
michalgrosicki
Contributor II

Hello everyone,

We're trying to utilize linux_libnfc-nci library to read/write ISO 15693 tags (concretely ICODE SLIX). We are using OM5577 development kit with raspberry pi and linux image provided on the kit's site. Demo app included with the code works fine. We are able to poll, read and write NDEF messages to various types of tags (aforementioned SLIXes, but also NTags for example). Problems start when we try to use the library in our own code. Below is a very simple code we are running (in this instance we try to get system informations, but we tried several other commands like read single block or read multiple blocks):

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linux_nfc_api.h"
 
void arrival_callback(nfc_tag_info_t * tag_info) {
   int tx_len = 2;
   unsigned char tx[2] = {0x00, 0x2B};
   unsigned char rx[255];
   int result;
   int i;
   memset(rx, 0, 255);
   printf("Hello\n");
   for (i = 0; i < tag_info->uid_length; i++) {
      printf("%02X", tag_info->uid[i]);
   }
   printf("\nIs it me you're looking for?\n");
   result = nfcTag_transceive(tag_info->handle, tx, tx_len, rx, 255, 500);
   printf("Result: %d\nData: [%s]\nHandle: %d\n", result, rx, tag_info->handle);
 
}
 
void departure_callback(void) {
   printf("Bye\n");
}
 
int main(void) {
   nfcTagCallback_t callback;
   callback.onTagArrival = arrival_callback;
   callback.onTagDeparture = departure_callback;
   nfcManager_doInitialize();
   nfcManager_registerTagCallback(&callback);
   nfcManager_enableDiscovery(0xef, 0, 0, 0);
   printf("NFC status: %d\n", nfcManager_isNfcActive());
   getchar();
   nfcManager_disableDiscovery();
   nfcManager_doDeinitialize();
   return 0;
}

After running above code we can see, that the tag is detected by the reader, we get correct tag ID, but nfcTag_transceive function always returns 0. Looking at the provided API guide it seems like it should work, but maybe we're missing something.

Looking forward for suggestions.

Best regards,

Michał

Labels (1)
Tags (1)
1 Solution
1,698 Views
michalgrosicki
Contributor II

We figured it out. I turns out that linux_libnfc-nci makes heavy use of threads and it would seem that it is incorrect to try to communicate with the reader from the callback. The solution was to move nfcTag_transceive() call to the main thread of the application and now everything works as it supposed to.

Best regards,

Michał

View solution in original post

0 Kudos
Reply
3 Replies
1,698 Views
belpairechristo
Contributor I

Hello Michal,

I have the same problem. Do you have the same kind of example you provided working with threads ?

Thanks in advance!

Best regards,

Christophe

0 Kudos
Reply
1,698 Views
michalgrosicki
Contributor II

Hi Christophe,

Here is simple example for ICODE SLIX tag, that should work.

#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "linux_nfc_api.h"

nfc_tag_info_t global_info;
int tag_detected = 0;
void arrival_callback(nfc_tag_info_t * tag_info) {
   memcpy(&global_info, tag_info, sizeof(nfc_tag_info_t));
   tag_detected = 1;
}

void departure_callback(void) {
   printf("Bye\n");
}

void read_single_block(unsigned char address) {
   int tx_len = 11;
   unsigned char tx[11] = {0x20, 0x20};
   unsigned char rx[255];
   int result;
   for (int i = 0; i < global_info.uid_length; i++) {
      printf("%02X", global_info.uid[i]);
   }
   memcpy(&tx[2], global_info.uid, global_info.uid_length);
   tx[10] = address;
   memset(rx, 0, 255);
   result = nfcTag_transceive(global_info.handle, tx, tx_len, rx, 255, 500);
   printf("\nResult: %d\nData: [%s]\nHandle: %d\n", result, rx+1, global_info.handle);
}

int main(void) {
   nfcTagCallback_t callback;
   callback.onTagArrival = arrival_callback;
   callback.onTagDeparture = departure_callback;
   nfcManager_doInitialize();
   nfcManager_registerTagCallback(&callback);
   nfcManager_enableDiscovery(0xef, 0, 0, 0);
   printf("NFC status: %d\n", nfcManager_isNfcActive());
   while (!tag_detected) {
      sleep(2);
   }
   read_single_block(0x05);
   getchar();
   nfcManager_disableDiscovery();
   nfcManager_doDeinitialize();
   return 0;
}

The main difference is in the placement of the transceive function. Hope this will be helpful.

Best regards,

Michał

1,699 Views
michalgrosicki
Contributor II

We figured it out. I turns out that linux_libnfc-nci makes heavy use of threads and it would seem that it is incorrect to try to communicate with the reader from the callback. The solution was to move nfcTag_transceive() call to the main thread of the application and now everything works as it supposed to.

Best regards,

Michał

0 Kudos
Reply