Skip to content

Commit

Permalink
add basic com. 'hello world'
Browse files Browse the repository at this point in the history
  • Loading branch information
jonasb committed Jan 5, 2012
1 parent 9ba6fcf commit 700e261
Show file tree
Hide file tree
Showing 3 changed files with 250 additions and 6 deletions.
1 change: 1 addition & 0 deletions AndroidManifest.xml
Expand Up @@ -3,6 +3,7 @@
package="se.forskningsavd"
android:versionCode="1"
android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<application android:label="@string/app_name" >
<activity android:name="MainActivity"
android:label="@string/app_name">
Expand Down
212 changes: 212 additions & 0 deletions 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<byte[]> mTrustMessages = new ArrayList<byte[]>();
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;
}
}
}
43 changes: 37 additions & 6 deletions src/se/forskningsavd/MainActivity.java
Expand Up @@ -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();
}
}

0 comments on commit 700e261

Please sign in to comment.