Java & Android
The shared library in the AMMC zip (ammc.dll, libammc.so, libammc.dylib)
exports a JNI surface besides the plain C one, so Java can call it without any
glue code of your own.
The bridge class
The native methods are bound by name, so the class must be
com.skoky.AmmcBridge and the method names must match exactly:
package com.skoky;
public class AmmcBridge {
static {
System.loadLibrary("ammc");
}
/** Converts a hex-encoded P3 message into a JSON array of messages. */
public static native String p3_to_json(String p3Hex);
/** Decodes an auto-discovery response into "ip;decoder-id". */
public static native String p3_network_to_json(String p3Hex);
/** Encodes a JSON request into hex-encoded P3 bytes to send to the decoder. */
public static native String encode(String json);
/** Converts a P3 timestamp into milliseconds since the epoch. */
public static native String time_to_millis(String rtcTime);
/** Returns the library version. */
public static native String version();
}Using it
import com.skoky.AmmcBridge;
public class Demo {
public static void main(String[] args) {
System.out.println("AMMC " + AmmcBridge.version());
String passing = "8e023300e5630000010001047a00000003041fd855000408589514394cd8"
+ "040005026d0006025000080200008104501304008f";
System.out.println(AmmcBridge.p3_to_json(passing));
String discovery = "8e024200471a000016000804810a000a8104e5870a008f";
System.out.println(AmmcBridge.p3_network_to_json(discovery));
// bytes to send to the decoder to ask for its version
String request = AmmcBridge.encode("{\"msg\":\"VERSION\"}");
}
}
Put the library on the JVM's search path and run:
javac com/skoky/AmmcBridge.java Demo.java
java -Djava.library.path=apple_m DemoAMMC 7.9.1
[{"decoder_id":"041350","gps_locked":false,"hits":80,"low_battery":false,"modified":false,"msg":"PASSING","passing_number":122,"resend":false,"rtc_time":"2013-03-19 21:36:33.607 +02:00","strength":109.0,"transponder":5625887}]
10.0.10.129;00:0A:87:E5Notes
System.loadLibrary("ammc")resolves toammc.dllon Windows andlibammc.so/libammc.dylibelsewhere, so pointjava.library.pathat the folder for your platform (windows64,linux_x86-64,apple_m). UseSystem.load("/full/path/to/libammc.dylib")to skip the search path.p3_to_jsonalways returns a JSON array, since one TCP read can carry several messages. It is empty for a message the library does not decode. Each call keeps nothing from the previous one, so a message split across two reads is lost by both. If you need every passing without gaps, runammc-amb -w 9000and read its WebSocket instead of parsing the socket yourself.p3_network_to_jsonreturnsip;decoder-id, not JSON, despite the name.encodeis the reverse direction: give it{"msg":"VERSION"},{"msg":"NETWORKSETTINGS"}or{"msg":"PING"}and send the returned bytes to the decoder.time_to_millisexpectsyyyy-MM-dd HH:mm:ss.SSSSSSwithout a timezone offset and returns0for anything else — so thertc_timecoming out ofp3_to_jsonhas to have its+02:00suffix stripped first. In most cases parsingrtc_timewithjava.time.OffsetDateTimeis simpler.- All methods are static and thread safe; sockets and reconnects stay in your application.
Android
The same class is used on Android, with the .so files under
src/main/jniLibs/<abi>/. For a working application see our
AMMC Demo timing app,
which reads AMB and Vostok decoders with this library. Contact us for support on
Android or another platform.