codec2_talkie/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/ax25/AX25Callsign.java

143 wiersze
3.9 KiB
Java

package com.radio.codec2talkie.protocol.ax25;
import androidx.annotation.NonNull;
import java.nio.ByteBuffer;
public class AX25Callsign {
public static int CallsignMaxSize = 7;
public String callsign;
public int ssid;
public boolean isValid;
public boolean isLast = false;
public AX25Callsign() {}
public AX25Callsign(String callsign, String ssid) {
this.callsign = callsign;
this.ssid = Integer.parseInt(ssid);
}
public static String formatCallsign(String callsign, String ssid) {
return String.format("%s-%s", callsign, ssid);
}
public void fromString(String inputCallsignWithSsid) {
isValid = false;
if (inputCallsignWithSsid == null) return;
// WIDE1*
String callsignWithSsid = inputCallsignWithSsid.replace("*", "");
// ABCDEF-XX
if (callsignWithSsid.length() > CallsignMaxSize + 2 || callsignWithSsid.length() == 0) return;
int delimiterIndex = callsignWithSsid.indexOf('-');
// ABCDEF-
if (delimiterIndex != -1 && delimiterIndex == callsignWithSsid.length() - 1) return;
callsign = callsignWithSsid;
ssid = 0;
if (delimiterIndex == -1) {
// ABCDEF
if (callsign.length() >= CallsignMaxSize) return;
} else {
callsign = callsignWithSsid.substring(0, delimiterIndex);
try {
ssid = Integer.parseInt(callsignWithSsid.substring(delimiterIndex + 1));
} catch(NumberFormatException e) {
return;
}
}
isValid = true;
}
public void fromBinary(byte[] data) {
isValid = false;
if (data == null) return;
if (data.length != CallsignMaxSize) return;
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < data.length - 1; i++) {
int d = (data[i] & 0xff) >>> 1;
char c = (char)d;
if (c == ' '){
break;
} else {
buffer.append(c);
}
}
callsign = buffer.toString();
byte lastByte = data[data.length - 1];
isLast = (lastByte & 0x01) == 1;
ssid = (lastByte >>> 1) & 0x0f;
if (callsign.length() == 0) return;
isValid = true;
}
@NonNull
public String toString() {
String callsignPlusSsid = callsign;
if (ssid == 0) {
if (isWide())
callsignPlusSsid += "*";
} else {
callsignPlusSsid += "-" + ssid;
}
return callsignPlusSsid;
}
public byte[] toBinary() {
ByteBuffer buffer = ByteBuffer.allocate(CallsignMaxSize);
for (int i = 0; i < CallsignMaxSize - 1; i++) {
if (i < callsign.length()) {
byte c = (byte) callsign.charAt(i);
buffer.put((byte)(c << 1));
} else {
// append ' ' for short callsigns
buffer.put((byte)(0x20 << 1));
}
}
byte binSsid = (byte)(ssid << 1);
if (isLast) {
binSsid |= 1;
}
buffer.put(binSsid);
// return
buffer.flip();
byte[] b = new byte[buffer.remaining()];
buffer.get(b);
return b;
}
public boolean isWide() {
return callsign.toUpperCase().startsWith("WIDE");
}
public boolean isTrace() {
return callsign.toUpperCase().startsWith("TRACE");
}
public boolean isSoftware() {
return callsign.toUpperCase().matches("^(AP)[A-Z]{1,4}$");
}
public boolean isPath() {
return isWide();
}
public boolean digiRepeatCallsign() {
if (ssid > 0) {
ssid -= 1;
return true;
}
return false;
}
public boolean digiRepeat() {
if (isPath()) {
return digiRepeatCallsign();
}
return false;
}
}