Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Improved support

BluetoothDevice now implements Parcelable
Initial client implementation for the Bluetooth Emulator Server
 will give the options of supports custom applications
  • Loading branch information...
commit a23a61208691239606861bde5d705fa93525ac22 1 parent 6fdf46a
Francesco Zanitti authored
View
42 README.md
@@ -7,17 +7,7 @@ As for now, you can communicate between different emulators using the RFComm pro
What you need to do in order to use the simulator instead of the android API, is to change the import from `android.bluetooth` to `dk.itu.android.bluetooth` (and also add the `INTERNET` permission in the android manifest file).
-There are two slight modifies to use the simulator:
-
- - call `getSerializableExtra` instead of `getParcelableExtra` to get a `BluetoothDevice` from the discovery intents:
-
- `BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);`
-
- you'll need to call
-
- `BluetoothDevice device = intent.getSerializableExtra(BluetoothDevice.EXTRA_DEVICE);`
-
- ..this is just because I didn't had time to look at how the parcel-stuff works. If you want, feel free to make the necessary modifications and push a commit ;)
+There is a slight modification to the code, in order to use the simulator:
- call `BluetoothAdapter.SetContext(this);` at some point (the `onCreate` method is fine) in your activity/service.
@@ -28,7 +18,7 @@ You will have to follow some steps:
- download everything in this repository
- compile and install into at least 2 android emulators the *android-bt-simulator* application
- a precompiled version of the application is provided in the *dist* directory
- - there are 3 source dicrectories, `src`, `src-sysactivities` and `src-testapp`. The application need all of them, but for the library jar you just need to compile the main one (`src`). The jar library is provided as convenience in the `dist-shared` directory
+ - there are 3 source directories, `src`, `src-sysactivities` and `src-testapp`. The application need all of them, but for the library jar you just need to compile the main one (`src`). The jar library is provided as convenience in the `dist-shared` directory
- compile the *btsim-server* and run it.
- there is an already precompiled jar in *dist*, execute `java -jar btsimserver.jar --help` to see some options (if you don't have the `adb` command in your path, you will need to set the `adb.path` variable)
@@ -45,4 +35,30 @@ My preferred workflow, at this point, is:
Then, depending on your needs, when you want to deploy the application on an actual device, you will need to delete or comment the `SetContext` call (as this will not compile, since it is not part of the android bluetooth api, but just a custom call for the simulator) and delete and re-import all the bluetooth stuff (this time using the `android.bluetooth` classes).
-I hope this will be useful for somebody, I know that it implements just a subset of the API and it is not possible to put into play different devices than the emulators themselves, but until we got something in the android emulator itself, this is what we got :D
+I hope this will be useful for somebody, I know that it implements just a subset of the API and it is not possible to put into play different devices than the emulators themselves, but until we got something in the android emulator itself, this is what we got :D
+
+## Adding dummy devices
+
+You can add dummy devices to the server, so that you can check if the discovery phase works. This involves communicating directly with the bluetooth emulator server, which accept text-based command.
+
+First of all, fire up a terminal and telnet to localhost, port 8199:
+
+ telnet localhost 8199
+
+when the terminal prompt, use the following syntax:
+
+ 0]tcp.address=10.0.2.2&not.android.emulator=true&bt.address=<address>&device.name=<name>]
+
+e.g. :
+
+ 0]tcp.address=10.0.2.2&not.android.emulator=true&bt.address=00:11:22:AA:BB:CC&device.name=Dummy1]
+
+In general, the bluetooth emulator server accepts commands on the form:
+
+ <command.identifier>]<param.name>=<param.value>&...]
+
+Another useful command is the discovery one, if you want to know which devices are listed in the server, telnet and enter:
+
+ 2]]
+
+then the list of the devices and relative registered services will appear.
View
BIN  android-btsim-application/dist-shared/btsim.jar
Binary file not shown
View
1  android-btsim-application/src/dk/itu/android/bluetooth/BluetoothAdapter.java
@@ -1,6 +1,5 @@
package dk.itu.android.bluetooth;
-import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
View
32 android-btsim-application/src/dk/itu/android/bluetooth/BluetoothClass.java
@@ -1,10 +1,24 @@
package dk.itu.android.bluetooth;
-import java.io.Serializable;
-
import android.os.Parcel;
+import android.os.Parcelable;
-public class BluetoothClass implements Serializable {
+public class BluetoothClass implements Parcelable {
+
+ public static Parcelable.Creator<BluetoothClass> CREATOR = new Parcelable.Creator<BluetoothClass>() {
+ @Override
+ public BluetoothClass createFromParcel(Parcel source) {
+ BluetoothClass out = new BluetoothClass();
+ out.dClass = source.readInt();
+ out.mdClass = source.readInt();
+ out.services = source.createIntArray();
+ return out;
+ }
+ @Override
+ public BluetoothClass[] newArray(int size) {
+ return new BluetoothClass[size];
+ }
+ };
public static class Device {
public static class Major {
@@ -17,10 +31,6 @@
public static final int NETWORKING = android.bluetooth.BluetoothClass.Service.NETWORKING;
}
- /**
- *
- */
- private static final long serialVersionUID = 1L;
int dClass;
int mdClass;
int[] services;
@@ -56,10 +66,14 @@ public boolean hasService(int service) {
return false;
}
public int hashCode() {
- return -1;
+ int out = dClass+mdClass;
+ for(int i : services) { out+=i; }
+ return out;
}
public void writeToParcel(Parcel out, int flags) {
- //not supported?
+ out.writeInt(dClass);
+ out.writeInt(mdClass);
+ out.writeIntArray(services);
}
//
View
53 android-btsim-application/src/dk/itu/android/bluetooth/BluetoothDevice.java
@@ -1,16 +1,42 @@
package dk.itu.android.bluetooth;
import java.io.IOException;
-import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import android.os.Parcel;
+import android.os.Parcelable;
import android.util.Log;
import dk.itu.android.btemu.service.BTService;
-public class BluetoothDevice implements Serializable {
+public class BluetoothDevice implements Parcelable {
+
+ public static Parcelable.Creator<BluetoothDevice> CREATOR = new Parcelable.Creator<BluetoothDevice>() {
+ @Override
+ public BluetoothDevice createFromParcel(Parcel source) {
+ BluetoothDevice out = new BluetoothDevice();
+ out.addr = source.readString();
+ out.tcpAddr = source.readString();
+ out.name = source.readString();
+ Parcelable[] tmp = source.readParcelableArray(BluetoothDevice.class.getClassLoader());
+ for(Parcelable s : tmp) {
+ out.services.add((BTService)s);
+ }
+ return out;
+ }
+ @Override
+ public BluetoothDevice[] newArray(int size) {
+ return new BluetoothDevice[size];
+ }
+ };
+ public void writeToParcel(Parcel out, int flags) {
+ out.writeString(addr);
+ out.writeString(tcpAddr);
+ out.writeString(name);
+ out.writeParcelableArray(services.toArray(new BTService[]{}), 0);
+ }
+
//constants
public static final String ACTION_ACL_CONNECTED = "dk.android.bluetooth.device.action.ACL_CONNECTED";
@@ -33,11 +59,6 @@
public static final int ERROR = 0x80000000;
//
- /**
- *
- */
- private static final long serialVersionUID = 1L;
-
//
public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOException {
String uuids = uuid.toString();
@@ -48,7 +69,7 @@ public BluetoothSocket createRfcommSocketToServiceRecord(UUID uuid) throws IOExc
}
}
- return null;
+ throw new IOException("sdp serivce discovery failed: service not found");
}
public int describeContents(){
return -1;
@@ -58,20 +79,17 @@ public boolean equals(Object o) {
}
public String getAddress(){ return addr; }
public BluetoothClass getBluetoothClass(){ return btClass; }
- int getBondState() {
+ public int getBondState() {
return BOND_NONE;
}
public String getName() {
return name;
}
public int hashCode() {
- return -1;
+ return addr.hashCode();
}
public String toString() {
- return "";
- }
- public void writeToParcel(Parcel out, int flags) {
- //not supported?
+ return "BluetoothDevice " + addr;
}
//
@@ -95,6 +113,13 @@ public BluetoothDevice(String btAddr, String tcpAddr) {
android.bluetooth.BluetoothClass.Device.Major.PHONE,
android.bluetooth.BluetoothClass.Service.NETWORKING);
}
+ private BluetoothDevice() {
+ this.services = new ArrayList<BTService>();
+ this.btClass = new BluetoothClass(
+ android.bluetooth.BluetoothClass.Device.PHONE_SMART,
+ android.bluetooth.BluetoothClass.Device.Major.PHONE,
+ android.bluetooth.BluetoothClass.Service.NETWORKING);
+ }
/**
* THIS IS NOT PART OF THE ANDROID PLATFORM, IGNORE THIS METHOD!
View
24 android-btsim-application/src/dk/itu/android/bluetooth/BluetoothServerSocket.java
@@ -42,19 +42,21 @@ private BluetoothSocket createBTSocket(Socket s) throws IOException {
InputStream is = s.getInputStream();
Log.i(TAG, "creating btsocket, reading btaddr...");
int read;
- byte[] buf = new byte[100];
- read = is.read(buf);
- String btaddr = new String(buf,0,read);
+ byte[] buf = new byte[25];
+
+
+
+ int idx = 0;
+ do {
+ read = is.read();
+ buf[idx] = (byte)read;
+ idx++;
+ } while( '\n' != read );
+
+ String btaddr = new String(buf,0,idx-1);
-// byte read;
-// InputStreamReader isr = new InputStreamReader(is);
-// int read;
-// while('\n' != (char)(read=isr.read())) {
-// sb.append((char)read);
-// }
-// String btaddr = sb.toString().trim();
Log.i(TAG, "received btaddr: " + btaddr);
- BluetoothDevice d = emulator.lookupBT(btaddr);
+ BluetoothDevice d = emulator.lookupBT(btaddr.trim());
return new BluetoothSocket(s, d);
}
View
32 android-btsim-application/src/dk/itu/android/btemu/service/BTService.java
@@ -1,13 +1,33 @@
package dk.itu.android.btemu.service;
-import java.io.Serializable;
+import android.os.Parcel;
+import android.os.Parcelable;
-public class BTService implements Serializable {
+public class BTService implements Parcelable {
- /**
- *
- */
- private static final long serialVersionUID = 1L;
+ public static Parcelable.Creator<BTService> CREATOR = new Parcelable.Creator<BTService>() {
+ @Override
+ public BTService createFromParcel(Parcel source) {
+ BTService out = new BTService();
+ out.tcpPort = source.readInt();
+ out.uuid = source.readString();
+ return out;
+ }
+ @Override
+ public BTService[] newArray(int size) {
+ return new BTService[size];
+ }
+ };
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(tcpPort);
+ dest.writeString(uuid);
+ }
int tcpPort;
String uuid;
View
171 btsim-server/client-src/dk/itu/btemu/client/BtEmuClient.java
@@ -0,0 +1,171 @@
+package dk.itu.btemu.client;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+public class BtEmuClient {
+ static final String UTF8 = "UTF-8";
+
+ static final int JOIN = 0;
+ static final int LEAVE = 1;
+ static final int DISCOVERY = 2;
+ static final int MODIFYSERVICE = 3;
+
+ class Device {
+ String btAddr;
+ String ipAddr;
+ List<Service> services = new ArrayList<Service>();
+
+ public String getBtAddr() {
+ return btAddr;
+ }
+ public String getIpAddr() {
+ return ipAddr;
+ }
+ public List<Service> getServices() {
+ return services;
+ }
+ }
+ class Service {
+ String uuid;
+ int port;
+
+ public int getPort() {
+ return port;
+ }
+ public String getUuid() {
+ return uuid;
+ }
+ }
+
+ String fakeBluetoothAddress;
+
+ String serverAddr;
+ int serverPort;
+
+ Socket socket;
+ BufferedReader isReader;
+ OutputStream os;
+ Thread clientThread;
+
+ boolean running = true;
+
+ public BtEmuClient(String btAddr, String addr,int port) {
+ this.fakeBluetoothAddress = btAddr;
+ this.serverAddr = addr;
+ this.serverPort = port;
+ }
+
+ public BtEmuClient(String btAddr) {
+ this(btAddr,"localhost",8199);
+ }
+
+ public void start() {
+ try {
+ socket = new Socket(this.serverAddr,this.serverPort);
+ os = socket.getOutputStream();
+ isReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ } catch (Exception e) {
+ e.printStackTrace();
+ throw new RuntimeException("cannot connect to server!");
+ }
+ }
+ public void stop() {
+ try {
+ socket.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void join() {
+ send( JOIN,stdCmd() );
+ }
+ public void leave() {
+ send( LEAVE,stdCmd() );
+ }
+ public void addService(String uuid,int port) {
+ modifyService(uuid,port,true);
+ }
+ public void removeService(String uuid) {
+ modifyService(uuid,0,false);
+ }
+ void log(String tag,String s){
+ System.out.println(tag+"\n\t"+s);
+ }
+ private void modifyService(String uuid, int port, boolean added) {
+ Map<String,String> m = stdCmd();
+ m.put("type", added ? "added" : "removed");
+ m.put("tcp.port", port+"");
+ m.put("service.uuid",uuid);
+ send( MODIFYSERVICE,m );
+ }
+ public Set<Device> discovery() {
+ Set<Device> out = new HashSet<Device>();
+ send( DISCOVERY,stdCmd() );
+
+ String line = null;
+ do {
+ try {
+ line = isReader.readLine();
+ } catch (IOException e) {
+ e.printStackTrace();
+ throw new RuntimeException("cannot read inputstream!");
+ }
+ log("DISCOVERY_CMD", "device: " + line);
+ if(line==null) break;
+
+ String[] parts = line.trim().split("--");
+ Device d = new Device();
+ d.btAddr = parts[0];
+ d.ipAddr = parts[1];
+
+ if(parts.length>2) {
+ if(parts[2].length()>0) {
+ String[] sParts = parts[2].split("<><>");
+ for(String p : sParts) {
+ String[] s = p.split("<>");
+ Service srv = new Service();
+ srv.uuid = s[0];
+ srv.port = Integer.parseInt(s[1]);
+ d.services.add(srv);
+ }
+ }
+ }
+ out.add(d);
+ } while(line != null);
+
+ return out;
+ }
+
+ public Map<String,String> stdCmd() {
+ Map<String,String> out = new HashMap<String,String>();
+ out.put("bt.address", this.fakeBluetoothAddress);
+ out.put("tcp.address", "127.0.0.1");
+ out.put("not.android.emulator", "true");
+ return out;
+ }
+
+ void send(int cmdType, Map<String,String> command) {
+ try {
+ os.write( (cmdType+"]").getBytes(UTF8) );
+ for(String k : command.keySet()) {
+ os.write( (k+"="+command.get(k)+"&").getBytes(UTF8) );
+ }
+ os.write("]".getBytes(UTF8));
+ os.flush();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+}
View
BIN  btsim-server/dist/btsimserver.jar
Binary file not shown
View
2  btsim-server/src/dk/itu/btemu/Server.java
@@ -5,7 +5,7 @@
import java.net.Socket;
public class Server {
- public static String ADB_CMD_PATH = "";//Applications/code/android-sdk/tools/";
+ public static String ADB_CMD_PATH = "";//"/Applications/code/android-sdk/tools/";
public static String ADB_EXE = "adb";
public static String ADB_CMD(){ return ADB_CMD_PATH + ADB_EXE; }
static int StartPort = 8123;
View
11 btsim-server/src/dk/itu/btemu/cmd/Join.java
@@ -25,9 +25,14 @@ protected void work( List<Param> params ) throws Exception {
Device device = new Device(ipAddress, btAddress);
State.getInstance().put(btAddress, device);
- BTMacForwardingsChecker checker = new BTMacForwardingsChecker();
- System.out.println("running checker...");
- checker.run();
+
+ if(null == getParam("not.android.emulator")) {
+ BTMacForwardingsChecker checker = new BTMacForwardingsChecker();
+ System.out.println("running checker...");
+ checker.run();
+ } else {
+ device.setAndroidEmulator(false);
+ }
}
@Override
View
8 btsim-server/src/dk/itu/btemu/state/Device.java
@@ -7,6 +7,8 @@
String ipAddr;
String btAddr;
+
+ boolean isAndroidEmulator = true;
/**
* The port at which is running the emulator
@@ -51,4 +53,10 @@ public void setEmulatorPort(int emulatorPort) {
public int getEmulatorPort() {
return emulatorPort;
}
+ public boolean isAndroidEmulator() {
+ return isAndroidEmulator;
+ }
+ public void setAndroidEmulator(boolean isAndroidEmulator) {
+ this.isAndroidEmulator = isAndroidEmulator;
+ }
}
View
11 btsim-server/src/dk/itu/btemu/state/Service.java
@@ -19,8 +19,15 @@ public Service(String UUID, int tcpPort, Device device) {
this.UUID = UUID;
this.tcpPort = tcpPort;
this.device = device;
- this.hostPort = Server.next();
- createNetworkRedirection();
+
+ if(device.isAndroidEmulator()) {
+ this.hostPort = Server.next();
+ createNetworkRedirection();
+ } else {
+ System.out.println("not-android-emulator service");
+ this.hostPort = tcpPort;
+ }
+
}
private void createNetworkRedirection() {
System.out.println("creating network forwarding from "+tcpPort+" to "+hostPort);
Please sign in to comment.
Something went wrong with that request. Please try again.