Working connect/disconnect, OPR ERR and KEY REL flashing, code cleanup with Butterknife
This commit is contained in:
@@ -11,6 +11,11 @@ import java.net.SocketAddress;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import de.rumpold.androiddsky.network.YaAgcClient;
|
||||
import de.rumpold.androiddsky.ui.DSKYActivity;
|
||||
@@ -19,9 +24,18 @@ import de.rumpold.androiddsky.ui.DSKYActivity;
|
||||
* Created by Adriano on 17.05.2016.
|
||||
*/
|
||||
public class DSKY {
|
||||
private static final String TAG = "TAG";
|
||||
public interface ConnectionListener {
|
||||
void onConnect();
|
||||
|
||||
void onDisconnect();
|
||||
}
|
||||
|
||||
private static final String TAG = "DSKY";
|
||||
|
||||
private final Lock connectLock = new ReentrantLock();
|
||||
|
||||
private final DSKYActivity activity;
|
||||
private ConnectionListener listener;
|
||||
private final YaAgcClient client;
|
||||
|
||||
private String prog;
|
||||
@@ -36,19 +50,19 @@ public class DSKY {
|
||||
private char[] register2 = new char[5];
|
||||
private char[] register3 = new char[5];
|
||||
|
||||
private boolean compActy;
|
||||
private boolean uplinkActy;
|
||||
private boolean noAtt;
|
||||
private boolean gimbalLock;
|
||||
private boolean tracker;
|
||||
private boolean temp;
|
||||
private boolean vel;
|
||||
private boolean alt;
|
||||
private boolean progError;
|
||||
private boolean keyRel;
|
||||
private boolean oprErr;
|
||||
private boolean stby;
|
||||
private boolean restart;
|
||||
private volatile boolean compActy;
|
||||
private volatile boolean uplinkActy;
|
||||
private volatile boolean noAtt;
|
||||
private volatile boolean gimbalLock;
|
||||
private volatile boolean tracker;
|
||||
private volatile boolean temp;
|
||||
private volatile boolean vel;
|
||||
private volatile boolean alt;
|
||||
private volatile boolean progError;
|
||||
private volatile boolean keyRel;
|
||||
private volatile boolean oprErr;
|
||||
private volatile boolean stby;
|
||||
private volatile boolean restart;
|
||||
|
||||
private final Map<String, Integer> keycodeMap = new HashMap<>();
|
||||
|
||||
@@ -74,20 +88,10 @@ public class DSKY {
|
||||
keycodeMap.put("PRO", 1 << 13);
|
||||
}
|
||||
|
||||
public DSKY(DSKYActivity activity) {
|
||||
public DSKY(DSKYActivity activity, ConnectionListener listener) {
|
||||
this.activity = activity;
|
||||
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
|
||||
final String agcHost = preferences.getString("agc_host", null);
|
||||
final int agcPort = Integer.parseInt(preferences.getString("agc_port", "-1"));
|
||||
|
||||
if (agcHost == null || agcPort <= 0) {
|
||||
this.client = null;
|
||||
return;
|
||||
} else {
|
||||
final SocketAddress agcAddress = new InetSocketAddress(agcHost, agcPort);
|
||||
this.client = new YaAgcClient(this, agcAddress);
|
||||
}
|
||||
this.listener = listener;
|
||||
this.client = new YaAgcClient(this);
|
||||
|
||||
Arrays.fill(register1, ' ');
|
||||
Arrays.fill(register2, ' ');
|
||||
@@ -103,14 +107,53 @@ public class DSKY {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
if (client != null) {
|
||||
client.connect();
|
||||
Log.d(TAG, "Acquiring connect lock... ");
|
||||
connectLock.lock();
|
||||
Log.d(TAG, "Done.");
|
||||
|
||||
final SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(activity.getApplicationContext());
|
||||
final String agcHost = preferences.getString("agc_host", null);
|
||||
final int agcPort = Integer.parseInt(preferences.getString("agc_port", "-1"));
|
||||
final SocketAddress agcAddress = new InetSocketAddress(agcHost, agcPort);
|
||||
final boolean success = client.connect(agcAddress);
|
||||
|
||||
if (success) {
|
||||
Log.i(TAG, "Successfully connected");
|
||||
listener.onConnect();
|
||||
} else {
|
||||
Log.w(TAG, "Connection failed");
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// throw new RuntimeException("Cannot connect to yaAGC", e);
|
||||
} finally {
|
||||
connectLock.unlock();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new Timer().schedule(new TimerTask() {
|
||||
private final AtomicBoolean _keyRel = new AtomicBoolean(false);
|
||||
private final AtomicBoolean _oprErr = new AtomicBoolean(false);
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Log.v("BLINK", String.format("keyRel=%b/%b, oprErr=%b/%b",
|
||||
keyRel, _keyRel.get(), oprErr, _oprErr.get()));
|
||||
handle(R.id.lbl_keyRel, _keyRel, keyRel);
|
||||
handle(R.id.lbl_oprErr, _oprErr, oprErr);
|
||||
}
|
||||
|
||||
private void handle(int indicator, AtomicBoolean internalState, boolean state) {
|
||||
if (state) {
|
||||
internalState.set(!internalState.get());
|
||||
activity.updateIndicator(indicator, internalState.get());
|
||||
|
||||
} else {
|
||||
internalState.set(false);
|
||||
activity.updateIndicator(indicator, false);
|
||||
}
|
||||
}
|
||||
}, 667, 667);
|
||||
}
|
||||
|
||||
public void refreshDisplay() {
|
||||
@@ -119,9 +162,9 @@ public class DSKY {
|
||||
activity.updateIndicator(R.id.lbl_uplinkActy, uplinkActy);
|
||||
activity.updateIndicator(R.id.lbl_prog, progError);
|
||||
activity.updateIndicator(R.id.lbl_tracker, tracker);
|
||||
activity.updateIndicator(R.id.lbl_oprErr, oprErr);
|
||||
// activity.updateIndicator(R.id.lbl_oprErr, oprErr);
|
||||
activity.updateIndicator(R.id.lbl_stby, stby);
|
||||
activity.updateIndicator(R.id.lbl_keyRel, keyRel);
|
||||
// activity.updateIndicator(R.id.lbl_keyRel, keyRel);
|
||||
activity.updateIndicator(R.id.lbl_restart, restart);
|
||||
|
||||
activity.updateIndicator(R.id.lbl_compActy, compActy);
|
||||
@@ -155,7 +198,9 @@ public class DSKY {
|
||||
client.disconnect();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException("Cannot connect to yaAGC", e);
|
||||
throw new RuntimeException("Cannot disconnect from yaAGC", e);
|
||||
} finally {
|
||||
listener.onDisconnect();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,7 +8,7 @@ import android.widget.Toast;
|
||||
import java.io.IOException;
|
||||
import java.net.SocketAddress;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.channels.ClosedByInterruptException;
|
||||
import java.nio.channels.AsynchronousCloseException;
|
||||
import java.nio.channels.SocketChannel;
|
||||
|
||||
import de.rumpold.androiddsky.DSKY;
|
||||
@@ -23,7 +23,6 @@ public class YaAgcClient {
|
||||
private static final int KEYBOARD_CHANNEL = 015;
|
||||
|
||||
private final DSKY dsky;
|
||||
private final SocketAddress agcAddress;
|
||||
private SocketChannel agcChannel;
|
||||
private Thread handler;
|
||||
|
||||
@@ -56,7 +55,7 @@ public class YaAgcClient {
|
||||
|
||||
buf.position(buf.position() + 4);
|
||||
}
|
||||
} catch (ClosedByInterruptException | InterruptedException ignored) {
|
||||
} catch (AsynchronousCloseException | InterruptedException ignored) {
|
||||
} catch (IOException e) {
|
||||
Log.w(TAG, "Connection error", e);
|
||||
new Handler(Looper.getMainLooper()).post(new Runnable() {
|
||||
@@ -72,12 +71,11 @@ public class YaAgcClient {
|
||||
}
|
||||
}
|
||||
|
||||
public YaAgcClient(DSKY dsky, SocketAddress agcAddress) {
|
||||
public YaAgcClient(DSKY dsky) {
|
||||
this.dsky = dsky;
|
||||
this.agcAddress = agcAddress;
|
||||
}
|
||||
|
||||
public void connect() throws IOException {
|
||||
public boolean connect(SocketAddress agcAddress) throws IOException {
|
||||
Log.i(TAG, "Connecting to yaAGC at " + agcAddress);
|
||||
agcChannel = SocketChannel.open();
|
||||
boolean success = agcChannel.connect(agcAddress);
|
||||
@@ -87,6 +85,8 @@ public class YaAgcClient {
|
||||
handler = new Thread(new DSKYHandler(), "DSKY I/O Handler");
|
||||
handler.start();
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
public void disconnect() throws IOException {
|
||||
@@ -103,7 +103,7 @@ public class YaAgcClient {
|
||||
}
|
||||
|
||||
public boolean isConnected() {
|
||||
return agcChannel.isConnected();
|
||||
return agcChannel != null && agcChannel.isConnected();
|
||||
}
|
||||
|
||||
public void sendKeyCode(int keyCode) throws IOException {
|
||||
@@ -178,6 +178,10 @@ public class YaAgcClient {
|
||||
handleChannel11(packet);
|
||||
break;
|
||||
|
||||
case 013:
|
||||
handleChannel13(packet);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
@@ -190,6 +194,18 @@ public class YaAgcClient {
|
||||
dsky.refreshDisplay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle changes of additional indicators, transmitted on I/O channel 13
|
||||
*
|
||||
* @param packet
|
||||
*/
|
||||
private void handleChannel13(AgcPacket packet) {
|
||||
final boolean stby = (packet.getDataCode() & 0b0100_0000_0000) != 0;
|
||||
dsky.setStby(stby);
|
||||
|
||||
Log.d(TAG, String.format("[DSKY indicators] stby = %b", stby));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle changes of the indicator lights, transmitted on I/O channel 11
|
||||
*
|
||||
@@ -199,13 +215,17 @@ public class YaAgcClient {
|
||||
final boolean compActy = (packet.getDataCode() & 0b0000_0010) != 0;
|
||||
final boolean uplinkActy = (packet.getDataCode() & 0b0000_0100) != 0;
|
||||
final boolean temp = (packet.getDataCode() & 0b0000_1000) != 0;
|
||||
final boolean keyRel = (packet.getDataCode() & 0b0001_0000) != 0;
|
||||
final boolean oprErr = (packet.getDataCode() & 0b0100_0000) != 0;
|
||||
|
||||
dsky.setCompActy(compActy);
|
||||
dsky.setUplinkActy(uplinkActy);
|
||||
dsky.setTemp(temp);
|
||||
dsky.setKeyRel(keyRel);
|
||||
dsky.setOprErr(oprErr);
|
||||
|
||||
Log.d(TAG, String.format("[DSKY indicators] compActy = %s, uplinkActy = %s, temp = %s",
|
||||
compActy, uplinkActy, temp));
|
||||
Log.d(TAG, String.format("[DSKY indicators] compActy = %b, uplinkActy = %b, temp = %b, keyRel = %b",
|
||||
compActy, uplinkActy, temp, keyRel));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,13 +6,16 @@ import android.os.Handler;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.IdRes;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.util.Log;
|
||||
import android.view.HapticFeedbackConstants;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import butterknife.BindColor;
|
||||
import butterknife.ButterKnife;
|
||||
import butterknife.OnClick;
|
||||
import de.rumpold.androiddsky.DSKY;
|
||||
import de.rumpold.androiddsky.R;
|
||||
|
||||
@@ -21,30 +24,33 @@ import de.rumpold.androiddsky.R;
|
||||
* status bar and navigation/system bar) with user interaction.
|
||||
*/
|
||||
public class DSKYActivity extends AppCompatActivity {
|
||||
/**
|
||||
* Some older devices needs a small delay between UI widget updates
|
||||
* and a change of the status and navigation bar.
|
||||
*/
|
||||
private static final int UI_ANIMATION_DELAY = 300;
|
||||
private static final String TAG = "DSKYActivity";
|
||||
|
||||
private final Handler mViewHandler = new Handler();
|
||||
private MenuItem disconnectButton;
|
||||
private MenuItem connectButton;
|
||||
|
||||
private DSKY dsky;
|
||||
private int rightActiveColor;
|
||||
private int activeColor;
|
||||
private int passiveColor;
|
||||
private int compActyColor;
|
||||
|
||||
public void updateIndicator(@IdRes final int id, final boolean state) {
|
||||
@BindColor(R.color.indicatorRightActive)
|
||||
int rightActiveColor;
|
||||
@BindColor(R.color.indicatorActive)
|
||||
int activeColor;
|
||||
@BindColor(R.color.indicatorPassive)
|
||||
int passiveColor;
|
||||
@BindColor(R.color.compActy)
|
||||
int compActyColor;
|
||||
|
||||
public void updateIndicator(@IdRes final int id, final boolean active) {
|
||||
mViewHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TextView indicator = (TextView) findViewById(id);
|
||||
final TextView indicator = findViewById(id);
|
||||
if (indicator == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (state) {
|
||||
if (active) {
|
||||
final int color;
|
||||
if ("right".equals(indicator.getTag())) {
|
||||
color = rightActiveColor;
|
||||
@@ -65,7 +71,7 @@ public class DSKYActivity extends AppCompatActivity {
|
||||
mViewHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
TextView display = (TextView) findViewById(id);
|
||||
final TextView display = findViewById(id);
|
||||
display.setText(value);
|
||||
}
|
||||
});
|
||||
@@ -74,29 +80,53 @@ public class DSKYActivity extends AppCompatActivity {
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
setContentView(R.layout.activity_dsky);
|
||||
ButterKnife.bind(this);
|
||||
|
||||
dsky = new DSKY(this);
|
||||
dsky = new DSKY(this, new DSKY.ConnectionListener() {
|
||||
@Override
|
||||
public void onConnect() {
|
||||
Log.i(TAG, "Connected to AGC");
|
||||
mViewHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (connectButton != null) {
|
||||
connectButton.setVisible(false);
|
||||
}
|
||||
if (disconnectButton != null) {
|
||||
disconnectButton.setVisible(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Colors
|
||||
rightActiveColor = getResources().getColor(R.color.indicatorRightActive);
|
||||
activeColor = getResources().getColor(R.color.indicatorActive);
|
||||
passiveColor = getResources().getColor(R.color.indicatorPassive);
|
||||
compActyColor = getResources().getColor(R.color.compActy);
|
||||
|
||||
createButtonListeners();
|
||||
@Override
|
||||
public void onDisconnect() {
|
||||
Log.i(TAG, "Disconnected from AGC");
|
||||
mViewHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (connectButton != null) {
|
||||
connectButton.setVisible(true);
|
||||
}
|
||||
if (disconnectButton != null) {
|
||||
disconnectButton.setVisible(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.action_connect:
|
||||
if (!dsky.isConnected()) {
|
||||
dsky.connect();
|
||||
} else {
|
||||
return true;
|
||||
|
||||
case R.id.action_disconnect:
|
||||
dsky.disconnect();
|
||||
}
|
||||
return true;
|
||||
|
||||
case R.id.action_settings:
|
||||
@@ -112,40 +142,23 @@ public class DSKYActivity extends AppCompatActivity {
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.dsky_menu, menu);
|
||||
connectButton = menu.findItem(R.id.action_connect);
|
||||
disconnectButton = menu.findItem(R.id.action_disconnect);
|
||||
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
private void createButtonListeners() {
|
||||
final View.OnClickListener buttonListener = new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
final Button button = (Button) view;
|
||||
@OnClick({R.id.btn_verb, R.id.btn_noun, R.id.btn_plus, R.id.btn_minus,
|
||||
R.id.btn_0, R.id.btn_1, R.id.btn_2,
|
||||
R.id.btn_3, R.id.btn_4, R.id.btn_5,
|
||||
R.id.btn_6, R.id.btn_7, R.id.btn_8, R.id.btn_9,
|
||||
R.id.btn_clr, R.id.btn_pro, R.id.btn_key_rel,
|
||||
R.id.btn_entr, R.id.btn_rset})
|
||||
public void dskyButtonCallback(Button button) {
|
||||
button.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY,
|
||||
HapticFeedbackConstants.FLAG_IGNORE_GLOBAL_SETTING);
|
||||
dsky.buttonPressed(button.getText().toString());
|
||||
}
|
||||
};
|
||||
|
||||
findViewById(R.id.btn_verb).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_noun).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_plus).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_minus).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_0).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_1).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_2).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_3).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_4).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_5).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_6).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_7).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_8).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_9).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_clr).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_pro).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_key_rel).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_entr).setOnClickListener(buttonListener);
|
||||
findViewById(R.id.btn_rset).setOnClickListener(buttonListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostCreate(Bundle savedInstanceState) {
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||
<item
|
||||
android:id="@+id/action_disconnect"
|
||||
android:title="Disconnect"
|
||||
app:showAsAction="ifRoom" />
|
||||
<item
|
||||
android:id="@+id/action_connect"
|
||||
android:title="Connect"
|
||||
|
||||
Reference in New Issue
Block a user