diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/CustomDataPrefix.java b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/CustomDataPrefix.java new file mode 100644 index 0000000..913258a --- /dev/null +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/CustomDataPrefix.java @@ -0,0 +1,167 @@ +package com.radio.codec2talkie.protocol; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.radio.codec2talkie.protocol.message.TextMessage; +import com.radio.codec2talkie.protocol.position.Position; +import com.radio.codec2talkie.settings.PreferenceKeys; +import com.radio.codec2talkie.tools.TextTools; +import com.radio.codec2talkie.transport.Transport; + +import java.io.IOException; +import java.nio.ByteBuffer; + +public class CustomDataPrefix implements Protocol { + + private final Protocol _childProtocol; + private ProtocolCallback _parentProtocolCallback; + private final byte[] _bytePrefix; + + public CustomDataPrefix(Protocol childProtocol, SharedPreferences sharedPreferences) { + _childProtocol = childProtocol; + String prefix = sharedPreferences.getString(PreferenceKeys.CUSTOM_PREFIX, ""); + _bytePrefix = TextTools.hexStringToByteArray(prefix); + } + + @Override + public void initialize(Transport transport, Context context, ProtocolCallback protocolCallback) throws IOException { + _parentProtocolCallback = protocolCallback; + _childProtocol.initialize(transport, context, _protocolCallback); + } + + @Override + public int getPcmAudioRecordBufferSize() { + return -1; + } + + @Override + public void sendCompressedAudio(String src, String dst, byte[] frame) throws IOException { + byte[] prefixedData = ByteBuffer.allocate(_bytePrefix.length + frame.length) + .put(_bytePrefix) + .put(frame) + .array(); + _childProtocol.sendCompressedAudio(src, dst, prefixedData); + } + + @Override + public void sendTextMessage(TextMessage textMessage) throws IOException { + _childProtocol.sendTextMessage(textMessage); + } + + @Override + public void sendPcmAudio(String src, String dst, short[] pcmFrame) throws IOException { + _childProtocol.sendPcmAudio(src, dst, pcmFrame); + } + + @Override + public void sendData(String src, String dst, String path, byte[] dataPacket) throws IOException { + byte[] prefixedData = ByteBuffer.allocate(_bytePrefix.length + dataPacket.length) + .put(_bytePrefix) + .put(dataPacket) + .array(); + _childProtocol.sendData(src, dst, path, prefixedData); + } + + @Override + public boolean receive() throws IOException { + return _childProtocol.receive(); + } + + @Override + public void sendPosition(Position position) throws IOException { + _childProtocol.sendPosition(position); + } + + @Override + public void flush() throws IOException { + _childProtocol.flush(); + } + + @Override + public void close() { + _childProtocol.close(); + } + + ProtocolCallback _protocolCallback = new ProtocolCallback() { + @Override + protected void onReceivePosition(Position position) { + _parentProtocolCallback.onReceivePosition(position); + } + + @Override + protected void onReceivePcmAudio(String src, String dst, short[] pcmFrame) { + _parentProtocolCallback.onReceivePcmAudio(src, dst, pcmFrame); + } + + @Override + protected void onReceiveCompressedAudio(String src, String dst, byte[] audioFrame) { + _parentProtocolCallback.onReceiveCompressedAudio(src, dst, audioFrame); + } + + @Override + protected void onReceiveTextMessage(TextMessage textMessage) { + _parentProtocolCallback.onReceiveTextMessage(textMessage); + } + + @Override + protected void onReceiveData(String src, String dst, String path, byte[] data) { + _parentProtocolCallback.onReceiveData(src, dst, path, data); + } + + @Override + protected void onReceiveSignalLevel(short rssi, short snr) { + _parentProtocolCallback.onReceiveSignalLevel(rssi, snr); + } + + @Override + protected void onReceiveTelemetry(int batVoltage) { + _parentProtocolCallback.onReceiveTelemetry(batVoltage); + } + + @Override + protected void onReceiveLog(String logData) { + _parentProtocolCallback.onReceiveLog(logData); + } + + @Override + protected void onTransmitPcmAudio(String src, String dst, short[] frame) { + _parentProtocolCallback.onTransmitPcmAudio(src, dst, frame); + } + + @Override + protected void onTransmitCompressedAudio(String src, String dst, byte[] frame) { + _parentProtocolCallback.onTransmitCompressedAudio(src, dst, frame); + } + + @Override + protected void onTransmitTextMessage(TextMessage textMessage) { + _parentProtocolCallback.onTransmitTextMessage(textMessage); + } + + @Override + protected void onTransmitPosition(Position position) { + _parentProtocolCallback.onTransmitPosition(position); + } + + @Override + protected void onTransmitData(String src, String dst, String path, byte[] data) { + _parentProtocolCallback.onTransmitData(src, dst, path, data); + } + + @Override + protected void onTransmitLog(String logData) { + _parentProtocolCallback.onTransmitLog(logData); + } + + @Override + protected void onProtocolRxError() { + _parentProtocolCallback.onProtocolRxError(); + } + + @Override + protected void onProtocolTxError() { + _parentProtocolCallback.onProtocolTxError(); + } + }; +} diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/ProtocolFactory.java b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/ProtocolFactory.java index a941019..5051bce 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/ProtocolFactory.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/protocol/ProtocolFactory.java @@ -72,6 +72,7 @@ public class ProtocolFactory { boolean aprsIsEnabled = SettingsWrapper.isAprsIsEnabled(sharedPreferences); boolean freedvEnabled = SettingsWrapper.isFreeDvSoundModemModulation(sharedPreferences); boolean codec2Enabled = SettingsWrapper.isCodec2Enabled(sharedPreferences); + boolean isCustomPrefixEnabled = SettingsWrapper.isCustomPrefixEnabled(sharedPreferences); // "root" protocol Protocol proto; @@ -97,6 +98,9 @@ public class ProtocolFactory { break; } + if (isCustomPrefixEnabled) { + proto = new CustomDataPrefix(proto, sharedPreferences); + } if (scramblingEnabled) { proto = new Scrambler(proto, scramblingKey); } @@ -108,7 +112,6 @@ public class ProtocolFactory { if (recordingEnabled) { proto = new Recorder(proto, sharedPreferences); } - proto = new AudioCodec2FrameAggregator(proto, sharedPreferences); proto = new AudioCodec2(proto, sharedPreferences); } else { diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/settings/PreferenceKeys.java b/codec2talkie/src/main/java/com/radio/codec2talkie/settings/PreferenceKeys.java index c706ba4..7984220 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/settings/PreferenceKeys.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/settings/PreferenceKeys.java @@ -29,6 +29,9 @@ public final class PreferenceKeys { public static String PORTS_SOUND_MODEM_FREEDV_SQUELCH_SNR="ports_sound_modem_freedv_squelch_snr"; public static String PORTS_SOUND_MODEM_FREEDV_DATA_MODE="ports_sound_modem_freedv_data_mode"; + public static String CUSTOM_PREFIX_ENABLED = "custom_prefix_enabled"; + public static String CUSTOM_PREFIX = "custom_prefix"; + public static String CODEC_TYPE = "codec_type"; public static String CODEC2_RECORDING_ENABLED = "codec2_recording_enabled"; diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsActivity.java b/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsActivity.java index be5603b..c642e62 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsActivity.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsActivity.java @@ -117,6 +117,15 @@ public class SettingsActivity extends AppCompatActivity } } + public static class SettingsTncExtendedFragment extends PreferenceFragmentCompat + { + @Override + public void onCreatePreferences(Bundle savedInstanceState, String rootKey) { + setPreferencesFromResource(R.xml.preferences_tnc_extended, null); + setNumberInputType(getPreferenceManager()); + } + } + public static class SettingsTcpIpFragment extends PreferenceFragmentCompat { @Override diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsWrapper.java b/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsWrapper.java index b95fe54..1a50a4d 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsWrapper.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/settings/SettingsWrapper.java @@ -44,6 +44,10 @@ public class SettingsWrapper { return sharedPreferences.getString(PreferenceKeys.CODEC_TYPE, "Codec2").equals("Codec2"); } + public static boolean isCustomPrefixEnabled(SharedPreferences sharedPreferences) { + return sharedPreferences.getBoolean(PreferenceKeys.CUSTOM_PREFIX_ENABLED, false); + } + public static int getFreeDvSoundModemModulation(SharedPreferences sharedPreferences) { String modemType = sharedPreferences.getString(PreferenceKeys.PORTS_SOUND_MODEM_TYPE, "1200"); if (modemType.startsWith("F")) { diff --git a/codec2talkie/src/main/java/com/radio/codec2talkie/transport/UsbSerial.java b/codec2talkie/src/main/java/com/radio/codec2talkie/transport/UsbSerial.java index 1772fa5..0912d4e 100644 --- a/codec2talkie/src/main/java/com/radio/codec2talkie/transport/UsbSerial.java +++ b/codec2talkie/src/main/java/com/radio/codec2talkie/transport/UsbSerial.java @@ -1,17 +1,9 @@ package com.radio.codec2talkie.transport; -import android.content.Context; -import android.content.SharedPreferences; - -import androidx.preference.PreferenceManager; - import com.hoho.android.usbserial.driver.SerialTimeoutException; import com.hoho.android.usbserial.driver.UsbSerialPort; -import com.radio.codec2talkie.settings.PreferenceKeys; -import com.radio.codec2talkie.tools.TextTools; import java.io.IOException; -import java.nio.ByteBuffer; public class UsbSerial implements Transport { diff --git a/codec2talkie/src/main/res/values/strings.xml b/codec2talkie/src/main/res/values/strings.xml index d265fca..a896141 100644 --- a/codec2talkie/src/main/res/values/strings.xml +++ b/codec2talkie/src/main/res/values/strings.xml @@ -192,8 +192,15 @@ Serial stop bits USB serial settings Set USB serial settings, such as speed, bits, parity, etc. - Enable USB packet prefix - Prefix USB data with the HEX string for LoRA UART modems + + Extended TNC settings + Additional TNC specific settings + UART modem prefix + + Enable UART prefix + Prefix USB data with the HEX string for some LoRA UART modems + USB packet prefix value as a HEX string + Prefix sent content with a hex string (so called transmission target in UART modems), e.g. C0FFEE Play audio through the speaker Output incoming audio through the speaker diff --git a/codec2talkie/src/main/res/xml/preferences.xml b/codec2talkie/src/main/res/xml/preferences.xml index d30d558..a074069 100644 --- a/codec2talkie/src/main/res/xml/preferences.xml +++ b/codec2talkie/src/main/res/xml/preferences.xml @@ -112,6 +112,12 @@ app:fragment="com.radio.codec2talkie.settings.SettingsActivity$SettingsSoundModemFragment"> + + + + + + + + + + + + + + \ No newline at end of file