My report on the progress I've made so far:
My first step was to make part of the libNFC functionality available in Java, and after digging a little big I found about JNI and SWIG. Since SWIG seemed to take care of some of the hassle for me, my first try was using SWIG and Cygwin. Following the various SWIG tutorials available, I first created a simple test.c file as bellow:
Code:#include "libnfc.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static dev_info* pdi;
int connectRFID() {
pdi = nfc_connect();
if (pdi != INVALID_DEVICE_INFO) {
nfc_initiator_init(pdi);
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
// Configure the CRC and Parity settings
nfc_configure(pdi,DCO_HANDLE_CRC,true);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
return 1;
} else return 0;
}
I then created the interface file test.i:
Code:%module test
%{
#include "libnfc.h"
extern dev_info* pdi;
extern int connectRFID();
%}
extern dev_info* pdi;
extern int connectRFID();
Finally in Cygwin I ran the follow instructions:
Code:$ swig -java test.i
$ gcc -c test.c test_wrap.c -I/c/'Program Files'/Java/jdk1.6.0_18/include -I/c/'Program Files'/Java/jdk1.6.0_18/include/win32 -l/c/cygwin/usr/include
$ gcc -shared test.o test_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o test.dll
The last input resulted in the following inexplicable errors:
Code:test.o:test.c:(.text+0x7): undefined reference to `_nfc_connect'
test.o:test.c:(.text+0x26): undefined reference to `_nfc_initiator_init'
test.o:test.c:(.text+0x43): undefined reference to `_nfc_configure'
test.o:test.c:(.text+0x60): undefined reference to `_nfc_configure'
test.o:test.c:(.text+0x7d): undefined reference to `_nfc_configure'
test.o:test.c:(.text+0x9a): undefined reference to `_nfc_configure'
test.o:test.c:(.text+0xb7): undefined reference to `_nfc_configure'
test.o:test.c:(.text+0xdf): undefined reference to `_nfc_disconnect'
test_wrap.o:test_wrap.c:(.text+0x91): undefined reference to `_pdi'
test_wrap.o:test_wrap.c:(.text+0xb3): undefined reference to `_pdi'
collect2: ld returned 1 exit status
Which refers to the libNFC functions I have in libraries in C:\cygwin\usr\include. Thinking I was missing something about SWIG and since the *.c file was quite simple, I gave it a shot with "pure" JNI.
Following a simple NetBeans tutorial I created the following Main.java:
Code:/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package libnfc;
/**
*
* @author Augusto
*/
public class Main {
static {
System.load("C:\\NetBeans\\LibNFC\\LibNFCNative\\dist\\LibNFCNative.dll");
}
public Main() {
}
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
System.out.println(new Main().nativeTagID());
}
private native String nativeTagID();
}
I then generated the LibNFCNative.h file with:
Code:C:\jdk1.6.0_18\bin\javah.exe -o LibNFCNative.h -jni -classpath C:\NetBeans\LibNFC\build\classes libNFC.Main
My final piece of code was the LibNFC.c file:
Code:#include <jni.h>
#include <stdio.h>
#include "LibNFCNative.h"
#include "libnfc.h"
#include <stdlib.h>
#include <string.h>
JNIEXPORT jstring JNICALL Java_libnfc_Main_nativeTagID(JNIEnv *env, jobject obj) {
char buf[64];
// Associate pdi with the RFID reader
dev_info* pdi;
pdi = nfc_connect();
if (pdi != INVALID_DEVICE_INFO) {
nfc_initiator_init(pdi);
// Drop the field for a while
nfc_configure(pdi,DCO_ACTIVATE_FIELD,false);
// Let the reader only try once to find a tag
nfc_configure(pdi,DCO_INFINITE_SELECT,false);
// Configure the CRC and Parity settings
nfc_configure(pdi,DCO_HANDLE_CRC,true);
nfc_configure(pdi,DCO_HANDLE_PARITY,true);
// Enable field so more power consuming cards can power themselves up
nfc_configure(pdi,DCO_ACTIVATE_FIELD,true);
buf[0] = "Success";
} else buf[0] = "Failure";
return (*env)->NewStringUTF(env, buf);
}
After adding "-mno-cygwin -Wl,--add-stdcall-alias -shared -m32" in the output for the Compiler, and adding the following folders:
Code:C:/jdk1.6.0_18/include
C:/jdk1.6.0_18/include/win32
C:/Documents and Settings/Augusto/Desktop/libnfc-1.2.1-vs2005/src
Finishing with dist/LibNFCNative.dll in the Linker, I have the exactly same errors of when I tried it with SWIG:
Code:gcc -mno-cygwin -Wl,--add-stdcall-alias -shared -m32 -mno-cygwin -shared -o dist/LibNFCNative.dll build/Debug/Cygwin-Windows/LibNFC.o
build/Debug/Cygwin-Windows/LibNFC.o: In function `Java_libnfc_Main_nativeTagID':
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:14: undefined reference to `_nfc_connect'
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:17: undefined reference to `_nfc_initiator_init'
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:20: undefined reference to `_nfc_configure'
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:23: undefined reference to `_nfc_configure'
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:26: undefined reference to `_nfc_configure'
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:27: undefined reference to `_nfc_configure'
/cygdrive/c/NetBeans/LibNFC/LibNFCNative/LibNFC.c:30: undefined reference to `_nfc_configure'
collect2: ld returned 1 exit status
I'm correctly identifying the library path for libnfc in both cases, and I've tried the library version for Win and Linux. Why is Cygwin messing this up for me? Sorry for the long post.