kopia lustrzana https://github.com/sh123/codec2_talkie
Message ack id parsing
rodzic
e6a05091d9
commit
1edf1c4c51
|
@ -10,8 +10,8 @@ android {
|
||||||
applicationId "com.radio.codec2talkie"
|
applicationId "com.radio.codec2talkie"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 30
|
targetSdkVersion 30
|
||||||
versionCode 162
|
versionCode 163
|
||||||
versionName "1.62"
|
versionName "1.63"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import com.radio.codec2talkie.protocol.position.Position;
|
||||||
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Locale;
|
||||||
import java.util.regex.Matcher;
|
import java.util.regex.Matcher;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
@ -14,6 +15,7 @@ public class AprsDataTextMessage implements AprsData {
|
||||||
public String dstCallsign;
|
public String dstCallsign;
|
||||||
public String digipath;
|
public String digipath;
|
||||||
public String textMessage;
|
public String textMessage;
|
||||||
|
public Integer ackId;
|
||||||
|
|
||||||
private boolean _isValid;
|
private boolean _isValid;
|
||||||
|
|
||||||
|
@ -37,6 +39,7 @@ public class AprsDataTextMessage implements AprsData {
|
||||||
this.dstCallsign = textMessage.dst;
|
this.dstCallsign = textMessage.dst;
|
||||||
this.textMessage = textMessage.text;
|
this.textMessage = textMessage.text;
|
||||||
this.digipath = textMessage.digipath;
|
this.digipath = textMessage.digipath;
|
||||||
|
this.ackId = textMessage.ackId;
|
||||||
_isValid = true;
|
_isValid = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,6 +55,7 @@ public class AprsDataTextMessage implements AprsData {
|
||||||
textMessage.dst = this.dstCallsign;
|
textMessage.dst = this.dstCallsign;
|
||||||
textMessage.digipath = this.digipath;
|
textMessage.digipath = this.digipath;
|
||||||
textMessage.text = this.textMessage;
|
textMessage.text = this.textMessage;
|
||||||
|
textMessage.ackId = this.ackId;
|
||||||
return textMessage;
|
return textMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,25 +66,56 @@ public class AprsDataTextMessage implements AprsData {
|
||||||
this.digipath = digipath;
|
this.digipath = digipath;
|
||||||
this.srcCallsign = srcCallsign;
|
this.srcCallsign = srcCallsign;
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(infoData);
|
ByteBuffer buffer = ByteBuffer.wrap(infoData);
|
||||||
|
|
||||||
// callsign, trim ending spaces
|
// callsign, trim ending spaces
|
||||||
byte[] callsign = new byte[9];
|
byte[] callsign = new byte[9];
|
||||||
buffer.get(callsign);
|
buffer.get(callsign);
|
||||||
this.dstCallsign = new String(callsign).replaceAll("\\s+$", "");
|
this.dstCallsign = new String(callsign).replaceAll("\\s+$", "");
|
||||||
|
|
||||||
// ':' separator
|
// ':' separator
|
||||||
byte b = buffer.get();
|
byte b = buffer.get();
|
||||||
if (b != ':') return;
|
if (b != ':') return;
|
||||||
|
|
||||||
// message
|
// message
|
||||||
byte[] message = new byte[buffer.remaining()];
|
byte[] message = new byte[buffer.remaining()];
|
||||||
buffer.get(message);
|
buffer.get(message);
|
||||||
textMessage = new String(message, StandardCharsets.UTF_8);
|
String stringMessage = new String(message, StandardCharsets.UTF_8);
|
||||||
// TODO, message id: {xxxxx (for auto ack)
|
|
||||||
|
// ack/rej message
|
||||||
|
this.ackId = 0;
|
||||||
|
Pattern p = Pattern.compile("^(ack|rej)(\n+){1,5}$", Pattern.DOTALL);
|
||||||
|
Matcher m = p.matcher(stringMessage);
|
||||||
|
if (m.find()) {
|
||||||
|
String type = m.group(1);
|
||||||
|
if (type != null) {
|
||||||
|
String ackIdStr = m.group(2);
|
||||||
|
if (ackIdStr != null)
|
||||||
|
this.ackId = Integer.parseInt(ackIdStr);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// message requires acknowledge {xxxxx (for auto ack)
|
||||||
|
p = Pattern.compile("^(.+){0,67}[{](\\d+){1,5}$", Pattern.DOTALL);
|
||||||
|
m = p.matcher(stringMessage);
|
||||||
|
if (m.find()) {
|
||||||
|
this.textMessage = m.group(1);
|
||||||
|
String ackNumStr = m.group(2);
|
||||||
|
if (ackNumStr != null)
|
||||||
|
this.ackId = Integer.parseInt(ackNumStr);
|
||||||
|
} else if (stringMessage.length() <= 67) {
|
||||||
|
this.textMessage = stringMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO, telemetry, make subclass from message, extend and extract values
|
// TODO, telemetry, make subclass from message, extend and extract values
|
||||||
_isValid = !isTelemetry(textMessage);
|
if (this.textMessage != null)
|
||||||
|
_isValid = !isTelemetry(this.textMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public byte[] toBinary() {
|
public byte[] toBinary() {
|
||||||
return String.format(":%-9s:%s", dstCallsign, textMessage).getBytes();
|
return (ackId > 0)
|
||||||
|
? String.format(Locale.US, ":%-9s:%s{%d", dstCallsign, textMessage, ackId).getBytes()
|
||||||
|
: String.format(":%-9s:%s", dstCallsign, textMessage).getBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -7,15 +7,18 @@ public class TextMessage {
|
||||||
public String dst;
|
public String dst;
|
||||||
public String digipath;
|
public String digipath;
|
||||||
public String text;
|
public String text;
|
||||||
|
public Integer ackId;
|
||||||
|
|
||||||
public MessageItem toMessageItem(boolean isTransmit) {
|
public MessageItem toMessageItem(boolean isTransmit) {
|
||||||
MessageItem messageItem = new MessageItem();
|
MessageItem messageItem = new MessageItem();
|
||||||
messageItem.setTimestampEpoch(System.currentTimeMillis());
|
messageItem.setTimestampEpoch(System.currentTimeMillis());
|
||||||
messageItem.setNeedsAck(false); // TODO
|
|
||||||
messageItem.setIsTransmit(isTransmit);
|
messageItem.setIsTransmit(isTransmit);
|
||||||
messageItem.setSrcCallsign(this.src);
|
messageItem.setSrcCallsign(this.src);
|
||||||
messageItem.setDstCallsign(this.dst);
|
messageItem.setDstCallsign(this.dst);
|
||||||
messageItem.setMessage(this.text);
|
messageItem.setMessage(this.text);
|
||||||
|
messageItem.setAckId(this.ackId);
|
||||||
|
messageItem.setIsAcknowledged(false);
|
||||||
|
messageItem.setRetryCnt(0);
|
||||||
return messageItem;
|
return messageItem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.Executors;
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
@androidx.room.Database(
|
@androidx.room.Database(
|
||||||
version = 11,
|
version = 12,
|
||||||
entities = {LogItem.class, MessageItem.class, PositionItem.class, StationItem.class},
|
entities = {LogItem.class, MessageItem.class, PositionItem.class, StationItem.class},
|
||||||
exportSchema = false
|
exportSchema = false
|
||||||
)
|
)
|
||||||
|
|
|
@ -4,7 +4,7 @@ import androidx.room.Entity;
|
||||||
import androidx.room.Index;
|
import androidx.room.Index;
|
||||||
import androidx.room.PrimaryKey;
|
import androidx.room.PrimaryKey;
|
||||||
|
|
||||||
@Entity(indices = {@Index(value = {"id", "srcCallsign"}, unique = true)})
|
@Entity(indices = {@Index(value = {"id", "srcCallsign", "ackId"}, unique = true)})
|
||||||
public class MessageItem {
|
public class MessageItem {
|
||||||
|
|
||||||
@PrimaryKey(autoGenerate = true)
|
@PrimaryKey(autoGenerate = true)
|
||||||
|
@ -14,7 +14,9 @@ public class MessageItem {
|
||||||
private String dstCallsign;
|
private String dstCallsign;
|
||||||
private String message;
|
private String message;
|
||||||
private boolean needsAck;
|
private boolean needsAck;
|
||||||
private int ackNum;
|
private boolean isAcknowledged;
|
||||||
|
private int ackId;
|
||||||
|
private int retryCnt;
|
||||||
private boolean isTransmit;
|
private boolean isTransmit;
|
||||||
|
|
||||||
public long getId() {
|
public long getId() {
|
||||||
|
@ -35,7 +37,11 @@ public class MessageItem {
|
||||||
|
|
||||||
public boolean getNeedsAck() { return needsAck; }
|
public boolean getNeedsAck() { return needsAck; }
|
||||||
|
|
||||||
public int getAckNum() { return ackNum; }
|
public int getAckId() { return ackId; }
|
||||||
|
|
||||||
|
public int getRetryCnt() { return this.retryCnt; }
|
||||||
|
|
||||||
|
public boolean getIsAcknowledged() { return this.isAcknowledged; }
|
||||||
|
|
||||||
public boolean getIsTransmit() { return isTransmit; }
|
public boolean getIsTransmit() { return isTransmit; }
|
||||||
|
|
||||||
|
@ -43,6 +49,8 @@ public class MessageItem {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setRetryCnt(int retryCnt) { this.retryCnt = retryCnt; }
|
||||||
|
|
||||||
public void setTimestampEpoch(long timestampEpoch) {
|
public void setTimestampEpoch(long timestampEpoch) {
|
||||||
this.timestampEpoch = timestampEpoch;
|
this.timestampEpoch = timestampEpoch;
|
||||||
}
|
}
|
||||||
|
@ -57,8 +65,10 @@ public class MessageItem {
|
||||||
|
|
||||||
public void setNeedsAck(boolean needsAck) { this.needsAck = needsAck; }
|
public void setNeedsAck(boolean needsAck) { this.needsAck = needsAck; }
|
||||||
|
|
||||||
public void setAckNum(int ackNum) { this.ackNum = ackNum; }
|
public void setAckId(int ackId) { this.ackId = ackId; }
|
||||||
|
|
||||||
public void setIsTransmit(boolean isTransmit) { this.isTransmit = isTransmit; }
|
public void setIsTransmit(boolean isTransmit) { this.isTransmit = isTransmit; }
|
||||||
|
|
||||||
|
public void setIsAcknowledged(boolean isAcknowledged) { this.isAcknowledged = isAcknowledged; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,7 @@ public class MessageItemActivity extends AppCompatActivityWithServiceConnection
|
||||||
TextMessage textMessage = new TextMessage();
|
TextMessage textMessage = new TextMessage();
|
||||||
textMessage.dst = _groupName;
|
textMessage.dst = _groupName;
|
||||||
textMessage.text = messageEdit.getText().toString();
|
textMessage.text = messageEdit.getText().toString();
|
||||||
|
textMessage.ackId = 0;
|
||||||
getService().sendTextMessage(textMessage);
|
getService().sendTextMessage(textMessage);
|
||||||
messageEdit.setText("");
|
messageEdit.setText("");
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,8 @@ import com.radio.codec2talkie.R;
|
||||||
import com.radio.codec2talkie.app.AppService;
|
import com.radio.codec2talkie.app.AppService;
|
||||||
import com.radio.codec2talkie.protocol.message.TextMessage;
|
import com.radio.codec2talkie.protocol.message.TextMessage;
|
||||||
|
|
||||||
|
import java.util.Locale;
|
||||||
|
|
||||||
public class MessageGroupDialogSendTo extends AlertDialog implements View.OnClickListener {
|
public class MessageGroupDialogSendTo extends AlertDialog implements View.OnClickListener {
|
||||||
|
|
||||||
private final AppService _appService;
|
private final AppService _appService;
|
||||||
|
@ -44,8 +46,9 @@ public class MessageGroupDialogSendTo extends AlertDialog implements View.OnClic
|
||||||
assert targetEdit != null;
|
assert targetEdit != null;
|
||||||
assert messageEdit != null;
|
assert messageEdit != null;
|
||||||
TextMessage textMessage = new TextMessage();
|
TextMessage textMessage = new TextMessage();
|
||||||
textMessage.dst = targetEdit.getText().toString();
|
textMessage.dst = targetEdit.getText().toString().toUpperCase(Locale.ROOT);
|
||||||
textMessage.text = messageEdit.getText().toString();
|
textMessage.text = messageEdit.getText().toString();
|
||||||
|
textMessage.ackId = 0;
|
||||||
_appService.sendTextMessage(textMessage);
|
_appService.sendTextMessage(textMessage);
|
||||||
dismiss();
|
dismiss();
|
||||||
} else if (id == R.id.send_message_to_btn_cancel) {
|
} else if (id == R.id.send_message_to_btn_cancel) {
|
||||||
|
|
Ładowanie…
Reference in New Issue