From 700e26125c813195e85a4a381e1ab04a7a4b2db0 Mon Sep 17 00:00:00 2001 From: Jonas Bengtsson Date: Thu, 5 Jan 2012 21:49:37 +0100 Subject: [PATCH] add basic com. 'hello world' --- AndroidManifest.xml | 1 + src/se/forskningsavd/Communicator.java | 212 +++++++++++++++++++++++++ src/se/forskningsavd/MainActivity.java | 43 ++++- 3 files changed, 250 insertions(+), 6 deletions(-) create mode 100644 src/se/forskningsavd/Communicator.java diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 7787587..2f64ead 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -3,6 +3,7 @@ package="se.forskningsavd" android:versionCode="1" android:versionName="1.0"> + diff --git a/src/se/forskningsavd/Communicator.java b/src/se/forskningsavd/Communicator.java new file mode 100644 index 0000000..4718f69 --- /dev/null +++ b/src/se/forskningsavd/Communicator.java @@ -0,0 +1,212 @@ +package se.forskningsavd; + +import android.util.Log; + +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.SocketException; +import java.nio.ByteBuffer; +import java.util.ArrayList; + +public class Communicator { + static class ReceiverThread extends Thread { + private final DatagramSocket mSocket; + private boolean mRunning = true; + private final SenderThread mSenderThread; + + public ReceiverThread(DatagramSocket socket, SenderThread senderThread) { + mSocket = socket; + mSenderThread = senderThread; + } + + @Override + public void run() { + byte[] buf = new byte[1000]; + DatagramPacket dp = new DatagramPacket(buf, buf.length); + while (mRunning) { + try { + mSocket.receive(dp); + StringBuilder debug = new StringBuilder(); + for (int i = 0; i < dp.getLength(); i++) { + debug.append(String.format("%02x", dp.getData()[i])); + } + String rcvd = "rcvd from " + dp.getAddress() + ", " + dp.getPort() + ": " + + debug; + Log.d("XXX", rcvd); + + ByteBuffer data = ByteBuffer.wrap(dp.getData()); + if (data.get(0) == 'D' && + data.get(1) == 'A' && + data.get(2) == 'T' && + data.get(3) == 'A') { + if (data.array().length >= 4 + 6) { + // TODO signed vs unsigned + final byte trustServer = data.get(4); + final byte trustClient = data.get(5); + int timer = data.getInt(6); + mSenderThread.onServerData(trustServer, trustClient); + + //TODO handle server trusted data + } + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + } + + public void abort() { + mRunning = false; + } + } + + static class SenderThread extends Thread { + /** + * Before retransmitting trusted packets + */ + private static final int TIMEOUT_TRUST = 16; + private final DatagramSocket mSocket; + private boolean mRunning = true; + private byte mTrustServer; + private byte mTrustClient; + private ArrayList mTrustMessages = new ArrayList(); + private int mTrustTimeout; + + public SenderThread(DatagramSocket socket) { + mSocket = socket; + } + + @Override + public void run() { + InetAddress hostAddress = null; + try { + hostAddress = InetAddress.getByName(Settings.HOST); + final String message = "HELO"; + byte[] buf = message.getBytes(); + + DatagramPacket out = new DatagramPacket(buf, buf.length, hostAddress, Settings.PORT); + mSocket.send(out); + } catch (IOException e) { + e.printStackTrace(); + return; + } + + + while (mRunning) { + ByteBuffer buffer = ByteBuffer.allocate(1024); + buffer.put("CTRL".getBytes()); + buffer.put(mTrustServer); + buffer.put(mTrustClient); + buffer.putInt(0); //mx + buffer.putInt(0); //my + buffer.putInt(0); //dx + buffer.putInt(0); //dy + buffer.put((byte) 0); //kb + + // TODO why are these needed???!!1 + buffer.put((byte) 0); + buffer.put((byte) 0); + buffer.put((byte) 0); + buffer.put((byte) 0); + buffer.put((byte) 0); + + synchronized (mTrustMessages) { + if (mTrustTimeout == 0) { + if (mTrustMessages.size() > 0) { + Log.d("XXX", "add trust message"); + final byte[] msg = mTrustMessages.get(0); + buffer.put(msg); + mTrustTimeout = TIMEOUT_TRUST; + } + } else { + mTrustTimeout--; + } + } + + DatagramPacket out = new DatagramPacket(buffer.array(), buffer.position(), hostAddress, 6979); + try { + mSocket.send(out); + StringBuilder debug = new StringBuilder(); + for (int i = 0; i < buffer.position(); i++) { + debug.append(String.format("%02x", buffer.get(i))); + } + Log.d("XXX", "sending " + debug.toString()); + } catch (IOException e) { + e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. + } + + try { + sleep(20); + } catch (InterruptedException e) { + } + } + } + + public void abort() { + mRunning = false; + } + + public void onServerData(byte trustServer, byte trustClient) { + synchronized (mTrustMessages) { + if (!mTrustMessages.isEmpty()) { + Log.d("XXX", "trustClient : " + trustClient + ", mTrustClient: " + mTrustClient); + if (trustClient == mTrustClient) { + mTrustMessages.remove(0); + mTrustClient++; + mTrustTimeout = 0; + } + } + } + } + + public void addTrustedMessage(byte[] ident, byte[] message) { + ByteBuffer buf = ByteBuffer.allocate(ident.length + 1 + message.length); + buf.put(ident); + buf.put((byte) message.length); + buf.put(message); + Log.d("XXX", "addTrustedMessage: '" + new String(buf.array(), 0, buf.position()) + "'"); + + synchronized (mTrustMessages) { + mTrustMessages.add(buf.array()); + } + } + } + + private ReceiverThread mReceiverThread; + private SenderThread mSenderThread; + + public void connect() { + disconnect(); + + final DatagramSocket socket; + try { + socket = new DatagramSocket(); + } catch (SocketException e) { + e.printStackTrace(); + return; + } + mSenderThread = new SenderThread(socket); + mSenderThread.start(); + + mReceiverThread = new ReceiverThread(socket, mSenderThread); + mReceiverThread.start(); + } + + public void sendText(String message) { + mSenderThread.addTrustedMessage("KIWI".getBytes(), message.toUpperCase().getBytes()); + } + + public void disconnect() { + if (mReceiverThread != null) { + mReceiverThread.abort(); + mReceiverThread = null; + } + if (mSenderThread != null) { + mSenderThread.abort(); + mSenderThread = null; + } + } +} diff --git a/src/se/forskningsavd/MainActivity.java b/src/se/forskningsavd/MainActivity.java index 3e93951..83a0f5f 100644 --- a/src/se/forskningsavd/MainActivity.java +++ b/src/se/forskningsavd/MainActivity.java @@ -2,14 +2,45 @@ import android.app.Activity; import android.os.Bundle; +import android.view.View; +import android.widget.Button; +import android.widget.LinearLayout; + +public class MainActivity extends Activity { + private Communicator mCommunicator; -public class MainActivity extends Activity -{ - /** Called when the activity is first created. */ @Override - public void onCreate(Bundle savedInstanceState) - { + public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - setContentView(R.layout.main); + + mCommunicator = new Communicator(); + + LinearLayout layout = new LinearLayout(this); + + Button button = new Button(this); + button.setText("Connect"); + button.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + mCommunicator.connect(); + } + }); + layout.addView(button); + + Button helloWorld = new Button(this); + helloWorld.setText("Hello World"); + helloWorld.setOnClickListener(new View.OnClickListener() { + public void onClick(View view) { + mCommunicator.sendText("Hello world"); + } + }); + layout.addView(helloWorld); + + setContentView(layout); + } + + @Override + protected void onPause() { + mCommunicator.disconnect(); + super.onPause(); } }