Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions ft8af/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <!-- For GPS location access -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Required to hold a WifiManager.MulticastLock so the Wi-Fi chip delivers
FlexRadio UDP discovery broadcasts to us (Android filters broadcast/
multicast packets without it). -->
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission
android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
Expand Down
3 changes: 3 additions & 0 deletions ft8af/app/src/main/java/com/k1af/ft8af/GeneralVariables.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,9 @@ public static boolean isConfiguredUsbAudioOutput(int vid, int pid) {

public static int flexMaxRfPower = 10;//Flex radio max transmit power
public static int flexMaxTunePower = 10;//Flex radio max tune power
// Last FlexRadio address connected to (discovered or typed). Persisted so the
// CAT chip can reconnect on a cold start without re-opening the picker.
public static String flexLastIp = "";

// Hidden debug mode (unlocked by tapping the version 7 times in About).
// When true, Settings exposes the Debug screen for log viewing/sharing.
Expand Down
24 changes: 24 additions & 0 deletions ft8af/app/src/main/java/com/k1af/ft8af/MainViewModel.java
Original file line number Diff line number Diff line change
Expand Up @@ -1283,13 +1283,37 @@ public void connectFlexRadioRig(Context context, FlexRadio flexRadio) {
}
}
GeneralVariables.controlMode = ControlMode.CAT;//network control mode
// Remember the address so the CAT chip can reconnect on a cold start
// without re-opening the picker.
if (flexRadio != null && flexRadio.getIp() != null && !flexRadio.getIp().isEmpty()) {
GeneralVariables.flexLastIp = flexRadio.getIp();
databaseOpr.writeConfig("flexLastIp", flexRadio.getIp(), null);
}
// Reflect the in-progress attempt on the CAT chip immediately; the Flex
// connect is async (TCP), so without this the chip looks idle until/unless
// the link comes up.
setCatConnectionState(CatConnectionState.CONNECTING);
FlexConnector flexConnector = new FlexConnector(context, flexRadio, GeneralVariables.controlMode);
flexConnector.setOnWaveDataReceived(new FlexConnector.OnWaveDataReceived() {
@Override
public void OnDataReceived(int bufferLen, float[] buffer) {
hamRecorder.doOnWaveDataReceived(bufferLen, buffer);
}
});
// Surface success/failure: the Flex path doesn't fire the BaseRig
// onConnected() callback, so without this the CAT chip never turns
// connected and there's no "connected" confirmation toast.
flexConnector.setOnConnectionResult(new FlexConnector.OnConnectionResult() {
@Override
public void onConnected() {
setCatConnectionState(CatConnectionState.CONNECTED);
ToastMessage.show(getStringFromResource(R.string.connected_rig));
}
@Override
public void onFailed() {
setCatConnectionState(CatConnectionState.ERROR);
}
});
flexConnector.connect();
connectRig();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ public class FlexConnector extends BaseRigConnector {
public interface OnWaveDataReceived{
void OnDataReceived(int bufferLen,float[] buffer);
}
/** Fired when the Flex link is up (TCP connected + GUI client created) or fails,
* so MainViewModel can surface the CAT connection state + a success/failure toast. */
public interface OnConnectionResult{
void onConnected();
void onFailed();
}
public int maxRfPower;
public int maxTunePower;

Expand All @@ -40,6 +46,11 @@ public interface OnWaveDataReceived{
private FlexRadio flexRadio;

private OnWaveDataReceived onWaveDataReceived;
private OnConnectionResult onConnectionResult;

public void setOnConnectionResult(OnConnectionResult listener){
this.onConnectionResult = listener;
}


public FlexConnector(Context context, FlexRadio flexRadio, int controlMode) {
Expand Down Expand Up @@ -209,13 +220,14 @@ public void onConnectSuccess(RadioTcpClient tcpClient) {
//flexRadio.sendCommand("c1|client gui\n");
//playData();


if (onConnectionResult != null) onConnectionResult.onConnected();
}

@Override
public void onConnectFail(RadioTcpClient tcpClient) {
ToastMessage.show(String.format(GeneralVariables.getStringFromResource
(R.string.flex_connect_failed),flexRadio.getModel()));
if (onConnectionResult != null) onConnectionResult.onFailed();
}
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2565,6 +2565,9 @@ protected Void doInBackground(Void... voids) {
if (name.equalsIgnoreCase("flexMaxTunePower")) {//Flex max tune power
GeneralVariables.flexMaxTunePower = result.equals("") ? 10 : Integer.parseInt(result);
}
if (name.equalsIgnoreCase("flexLastIp")) {//Last Flex address, for CAT-chip reconnect
GeneralVariables.flexLastIp = result == null ? "" : result;
}
if (name.equalsIgnoreCase("saveSWL")) {//Save decoded messages
GeneralVariables.saveSWLMessage = result.equals("1");
}
Expand Down
28 changes: 27 additions & 1 deletion ft8af/app/src/main/kotlin/radio/ks3ckc/ft8af/FT8AFApp.kt
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,14 @@ import com.k1af.ft8af.ModeProfile
import com.k1af.ft8af.R
import com.k1af.ft8af.database.OperationBand
import com.k1af.ft8af.ft8transmit.FT8TransmitSignal
import com.k1af.ft8af.flex.FlexRadio
import com.k1af.ft8af.rigs.CatConnectionState
import com.k1af.ft8af.rigs.InstructionSet
import com.k1af.ft8af.rigs.BaseRigOperation
import radio.ks3ckc.ft8af.theme.BgApp
import radio.ks3ckc.ft8af.ui.components.ActiveQsoPanel
import radio.ks3ckc.ft8af.ui.components.CatTapAction
import radio.ks3ckc.ft8af.ui.components.catTapAction
import radio.ks3ckc.ft8af.ui.components.shouldShowCatChip
import radio.ks3ckc.ft8af.ui.components.CqOptionsSheet
import radio.ks3ckc.ft8af.ui.components.canEnableFieldDay
Expand Down Expand Up @@ -488,7 +492,29 @@ fun FT8AFApp(mainViewModel: MainViewModel) {
).show()
}
},
onReconnectCat = { mainViewModel.reconnectRig() },
onReconnectCat = {
when (
catTapAction(
connectorExists = mainViewModel.baseRig?.connector != null,
isFlexNetwork = GeneralVariables.instructionSet == InstructionSet.FLEX_NETWORK,
savedFlexIp = GeneralVariables.flexLastIp,
)
) {
CatTapAction.RECONNECT_EXISTING -> mainViewModel.reconnectRig()
CatTapAction.CONNECT_SAVED_FLEX -> {
val flexRadio = FlexRadio()
flexRadio.ip = GeneralVariables.flexLastIp
flexRadio.model = "FlexRadio"
mainViewModel.connectFlexRadioRig(GeneralVariables.getMainContext(), flexRadio)
}
CatTapAction.NEEDS_SETUP ->
Toast.makeText(
context,
context.getString(R.string.cat_needs_setup),
Toast.LENGTH_SHORT,
).show()
}
},
onOpenFrequencyPicker = { showFrequencyPicker = true },
onToggleExpand = { qsoPanelExpanded = !qsoPanelExpanded },
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,29 @@ internal fun catChipVisuals(state: CatConnectionState): CatChipVisuals = when (s
internal fun shouldShowCatChip(controlMode: Int, state: CatConnectionState): Boolean =
controlMode != ControlMode.VOX || state != CatConnectionState.DISCONNECTED

/** What tapping the CAT chip should do, given the current connection state. */
enum class CatTapAction { RECONNECT_EXISTING, CONNECT_SAVED_FLEX, NEEDS_SETUP }

/**
* Decide what a tap on the CAT chip does. If a connector already exists, just
* reconnect it (the existing behavior — handy for Bluetooth/Flex retries).
* Otherwise, on a cold start, if the saved rig is a network Flex with a
* remembered address, connect straight to it — "my settings are set, just
* connect" — instead of doing nothing (the old reconnectRig() no-ops with no
* connector). With nothing saved to go on, the user needs to set the rig up.
*
* Pure so the routing is unit-tested without the rig/connect plumbing.
*/
internal fun catTapAction(
connectorExists: Boolean,
isFlexNetwork: Boolean,
savedFlexIp: String,
): CatTapAction = when {
connectorExists -> CatTapAction.RECONNECT_EXISTING
isFlexNetwork && savedFlexIp.isNotBlank() -> CatTapAction.CONNECT_SAVED_FLEX
else -> CatTapAction.NEEDS_SETUP
}

/**
* A small CAT (rig control) connection indicator for the TX strip. Tappable to
* re-trigger the connection — Bluetooth often only connects on the second try,
Expand Down
Loading
Loading