package de.graeb.adsbsniffer.adbsreceiver; import android.content.Context; import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbManager; import android.util.Log; import com.google.common.primitives.Bytes; import java.util.Date; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; import de.graeb.adsbsniffer.adbsreceiver.exceptions.NoUsbDeviceFound; import de.graeb.adsbsniffer.adbsreceiver.exceptions.ParseException; /** * Interface for communicating with the GNS58900 Adsb receiver */ public class GNSReceiver { private final LinkedList<Byte> byteBuffer = new LinkedList<>(); private final CDCDevice cdcDevice; /** * Connect to an gns5890 receiver over usb * * @param handler callback * @throws NoUsbDeviceFound no receiver was found */ public GNSReceiver(Context context, final PacketReceivedHandler handler) throws NoUsbDeviceFound { UsbManager usbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE); HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList(); //just get the first device UsbDevice usbDevice = null; if (deviceList != null) { for (UsbDevice device : deviceList.values()) { if (device.getProductId() == 63720 && device.getVendorId() == 1240) { usbDevice = device; break; } } } if (usbDevice == null) { throw new NoUsbDeviceFound(); } cdcDevice = new CDCDevice(usbManager, usbDevice, new ReceiveHandler(handler)); cdcDevice.configure(115200, 0, 8); } /** * Setup of the receiver * * @param mode 0, 2, 3, 4 * @param heartbeat whether enable heartbeat * @param timestamp whether enable heartbeat */ public void setUp(int mode, boolean heartbeat, boolean timestamp) { if (mode < 0 | mode > 4 | mode == 1) { throw new IllegalArgumentException("Illegal mode number: " + mode); } byte CMD_SET_MODE = 0x43; byte FLAG_TIMESTAMP = 0x10; byte FLAG_HEARTBEAT = 0x40; byte[] message = {CMD_SET_MODE, 0}; message[1] = (byte) ((heartbeat ? FLAG_HEARTBEAT : 0) | (timestamp ? FLAG_TIMESTAMP : 0) | (byte) mode); String text = formatForTransfer(message); Log.d("USB", text); cdcDevice.send(text); } private String formatForTransfer(byte[] values) { StringBuilder sb = new StringBuilder("#"); ListIterator<Byte> listIterator = Bytes.asList(values).listIterator(); while (listIterator.hasNext()) { int value = listIterator.next().intValue(); sb.append(value / 16); sb.append(value % 16); if (listIterator.hasNext()) { sb.append('-'); } } sb.append("\n\r"); return sb.toString(); } /** * Reads the incoming data * * Splits it into messages and parses it via ADSBParser */ private class ReceiveHandler implements CDCDevice.ReceivedHandler { private final PacketReceivedHandler handler; public ReceiveHandler(PacketReceivedHandler handler) { this.handler = handler; } @Override public void incoming(byte[] data) { for (byte b : data) { // strip newline and linefeed if (b != '\n' && b != '\r') { byteBuffer.add(b); } } //read until ; notfound: while (true) { // parse lines until no more found ListIterator<Byte> iterator = byteBuffer.listIterator(); do { if (!iterator.hasNext()) { break notfound; } } while (iterator.next() != ';'); List<Byte> sublist = byteBuffer.subList(0, iterator.previousIndex() + 1); byte[] line = Bytes.toArray(sublist); sublist.clear(); // get timestamp Date timestamp = new Date(); if (line[0] == '#') { // ignore status messages continue; } // parse message try { Packet packet = ADSBParser.parse(line, timestamp); if (packet != null) { handler.incoming(packet); } } catch (ParseException e) { throw new IllegalStateException(e); } } } } /** * Callback interface for receiving packets */ public interface PacketReceivedHandler { public void incoming(Packet packet); } }