Main bluetooth syncing implementation done, still some issues

This commit is contained in:
Ziver Koc 2015-01-29 18:03:13 +01:00
parent 97328f9978
commit bb24b03557
5 changed files with 176 additions and 63 deletions

View file

@ -2,6 +2,7 @@ package com.ericsson.uecontrol.core.logic;
import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothDevice;
import com.ericsson.uecontrol.core.UeBehaviour; import com.ericsson.uecontrol.core.UeBehaviour;
import com.ericsson.uecontrol.core.util.BluetoothClient;
import com.ericsson.uecontrol.core.util.BluetoothServer; import com.ericsson.uecontrol.core.util.BluetoothServer;
import com.ericsson.uecontrol.core.util.BluetoothUtil; import com.ericsson.uecontrol.core.util.BluetoothUtil;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
@ -11,24 +12,92 @@ import java.util.List;
/** /**
* Created by ezivkoc on 2015-01-19. * Created by ezivkoc on 2015-01-19.
*/ */
public class UeBehaviourSynchronize extends UeBehaviour { public class UeBehaviourSynchronize extends UeBehaviour implements BluetoothClient.MessageHandler{
private static final Logger log = Logger.getLogger(UeBehaviourSynchronize.class); private static final Logger log = Logger.getLogger(UeBehaviourSynchronize.class);
private static final int SLEEP_PERIOD = 100;
private final String SERVICE_UUID = "5ef27dac-a003-11e4-89d3-123b93f75cba"; private final String SERVICE_UUID = "5ef27dac-a003-11e4-89d3-123b93f75cba";
private static final int SYNC_TIMEOUT = 100; // milliseconds
private static final String SYNC_REQ_MSG = "SYNC REQ";
private static final String SYNC_ACK_MSG = "SYNC ACK";
private static BluetoothServer server;
private static BluetoothClient client;
private long syncTimeoutStamp;
@Override @Override
protected void execute() throws Exception { protected void execute() throws Exception {
log.debug("Searching paired devices..."); if(server == null && client == null) {
List<BluetoothDevice> devices = BluetoothUtil.filterWithService(BluetoothUtil.getPairedDevices(), SERVICE_UUID); log.debug("Searching paired devices...");
if(devices.isEmpty()){ super.setProgress(0.2f);
log.debug("No paired devices found, starting discovery..."); List<BluetoothDevice> devices = BluetoothUtil.filterWithService(BluetoothUtil.getPairedDevices(), SERVICE_UUID);
devices = BluetoothUtil.filterWithService(BluetoothUtil.discover(), SERVICE_UUID); if (!devices.isEmpty()) {
if(devices.isEmpty()){ log.debug("Found paired device("+devices.get(0).getAddress()+"), connecting...");
log.debug("No discoverable devices, setting up server..."); client = new BluetoothClient(devices.get(0), SERVICE_UUID, this);
//BluetoothServer server = new BluetoothServer("uecontrol_sync", SERVICE_UUID); client.start();
}
else {
log.debug("No paired devices found, starting discovery...");
super.setProgress(0.4f);
devices = BluetoothUtil.filterWithService(BluetoothUtil.discover(), SERVICE_UUID);
if (!devices.isEmpty()) {
log.debug("Found device("+devices.get(0).getAddress()+"), connecting...");
client = new BluetoothClient(devices.get(0), SERVICE_UUID, this);
client.start();
}
else{
log.debug("No discoverable devices, setting up server...");
super.setProgress(0.6f);
server = new BluetoothServer("uecontrol_sync", SERVICE_UUID, this);
server.start();
}
}
}
// Wait for sync message
super.setProgress(0.7f);
while(!super.stopExecution()){
if(super.stopExecution()) break;
Thread.sleep(SLEEP_PERIOD);
if(client != null){ // CLIENT
if(syncTimeoutStamp > System.currentTimeMillis()){
client.sendMessage(SYNC_ACK_MSG);
log.debug("Sending SYNC ACK, syncing done");
terminate();
}
}
else if(server != null){ // SERVER
server.sendMessage(SYNC_REQ_MSG);
} }
} }
} }
@Override
public void messageReceived(String msg) {
if(SYNC_REQ_MSG.equals(msg)){ // CLIENT
syncTimeoutStamp = System.currentTimeMillis() + SYNC_TIMEOUT;
log.debug("Received SYNC REQ");
}
else if(SYNC_ACK_MSG.equals(msg)){ // SERVER
log.debug("Received SYNC ACK, syncing done");
terminate();
}
}
@Override
public void reset(){
if(client != null){
client.close();
client = null;
}
if(server != null){
server.close();
server = null;
}
super.reset();
}
@Override @Override
public String getName() { public String getName() {

View file

@ -5,51 +5,60 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.IOException; import java.io.*;
import java.util.UUID; import java.util.UUID;
public class BluetoothClient extends Thread { public class BluetoothClient extends Thread {
private static final Logger log = Logger.getLogger(BluetoothClient.class); private static final Logger log = Logger.getLogger(BluetoothClient.class);
private BluetoothSocket mmSocket; private BluetoothSocket socket;
private BluetoothDevice mmDevice; private BufferedReader in;
private BufferedWriter out;
private MessageHandler msgHandler;
public BluetoothClient(BluetoothDevice device, String service_uuid) { public BluetoothClient(BluetoothDevice device, String service_uuid, MessageHandler msgHandler) throws IOException {
mmDevice = device; log.debug("Starting up bluetooth client.");
this.msgHandler = msgHandler;
// Get a BluetoothSocket to connect with the given BluetoothDevice // Get a BluetoothSocket to connect with the given BluetoothDevice
socket = device.createRfcommSocketToServiceRecord(UUID.fromString(service_uuid));
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
socket.connect();
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
}
protected BluetoothClient(BluetoothSocket socket, MessageHandler msgHandler) throws IOException {
log.debug("Starting up bluetooth worker thread.");
this.msgHandler = msgHandler;
this.socket = socket;
this.in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
this.out = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
}
public void run(){
while(socket != null){
try {
String msg = in.readLine();
msgHandler.messageReceived(msg);
} catch (IOException e) {
log.trace(null, e);
}
}
try { try {
// MY_UUID is the app's UUID string, also used by the server code if (socket != null)
mmSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(service_uuid)); socket.close();
} catch (IOException e) { } catch (IOException e) {
log.trace(null, e); log.trace(null, e);
} }
} }
public void run() { public void sendMessage(String msg) throws IOException {
BluetoothAdapter mBluetoothAdapter = BluetoothUtil.getAdapter(); if(socket != null)
// Cancel discovery because it will slow down the connection out.write(msg);
mBluetoothAdapter.cancelDiscovery();
try {
// Connect the device through the socket. This will block
// until it succeeds or throws an exception
mmSocket.connect();
} catch (IOException connectException) {
// Unable to connect; close the socket and get out
try {
mmSocket.close();
} catch (IOException closeException) {
}
return;
}
// Do work to manage the connection (in a separate thread)
manageConnectedSocket(mmSocket);
}
private void manageConnectedSocket(BluetoothSocket mmSocket) {
} }
/** /**
@ -57,9 +66,15 @@ public class BluetoothClient extends Thread {
*/ */
public void close() { public void close() {
try { try {
mmSocket.close(); socket.close();
socket = null;
} catch (IOException e) { } catch (IOException e) {
log.trace(null, e); log.trace(null, e);
} }
} }
public interface MessageHandler{
public void messageReceived(String msg);
}
} }

View file

@ -1,44 +1,53 @@
package com.ericsson.uecontrol.core.util; package com.ericsson.uecontrol.core.util;
import android.bluetooth.BluetoothAdapter; import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket; import android.bluetooth.BluetoothSocket;
import org.apache.log4j.Logger; import org.apache.log4j.Logger;
import java.io.IOException; import java.io.*;
import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
import com.ericsson.uecontrol.core.util.BluetoothClient.MessageHandler;
public class BluetoothServer extends Thread { public class BluetoothServer extends Thread {
private static final Logger log = Logger.getLogger(BluetoothServer.class); private static final Logger log = Logger.getLogger(BluetoothServer.class);
private BluetoothServerSocket mmServerSocket; private BluetoothServerSocket serverSocket;
private HashMap<BluetoothDevice, BluetoothClient> workers;
private MessageHandler msgHandler;
public BluetoothServer(String service, String service_uuid) { public BluetoothServer(String service, String service_uuid, MessageHandler msgHandler) throws IOException {
try { this.workers = new HashMap<BluetoothDevice, BluetoothClient>();
BluetoothAdapter mBluetoothAdapter = BluetoothUtil.getAdapter(); this.msgHandler = msgHandler;
// MY_UUID is the app's UUID string, also used by the client code
mmServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(service, UUID.fromString(service_uuid)); // MY_UUID is the app's UUID string, also used by the client code
} catch (IOException e) { BluetoothAdapter adapter = BluetoothUtil.getAdapter();
log.trace(null, e); serverSocket = adapter.listenUsingRfcommWithServiceRecord(service, UUID.fromString(service_uuid));
} //BluetoothUtil.setDiscoverable();
} }
public void run() { public void run() {
try { try {
BluetoothSocket socket = null; BluetoothSocket socket = null;
// Keep listening until exception occurs or a socket is returned // Keep listening until exception occurs or a socket is returned
while (true) { while (serverSocket != null) {
try { try {
socket = mmServerSocket.accept(); socket = serverSocket.accept();
} catch (IOException e) { } catch (IOException e) {
break; log.trace(null, e);
} }
// If a connection was accepted // If a connection was accepted
if (socket != null) { if (socket != null) {
// Do work to manage the connection (in a separate thread) // Do work to manage the connection (in a separate thread)
manageConnectedSocket(socket); BluetoothClient client = new BluetoothClient(socket, msgHandler);
mmServerSocket.close(); workers.put(
break; socket.getRemoteDevice(),
client);
client.start();
log.debug("New Client Connection, connection list size: "+workers.size());
} }
} }
}catch (Exception e){ }catch (Exception e){
@ -46,8 +55,13 @@ public class BluetoothServer extends Thread {
} }
} }
private void manageConnectedSocket(BluetoothSocket socket) { public void sendMessage(String msg) throws IOException {
for(BluetoothDevice device : workers.keySet())
sendMessage(device, msg);
}
public void sendMessage(BluetoothDevice device, String msg) throws IOException {
if(workers.containsKey(device))
workers.get(device).sendMessage(msg);
} }
/** /**
@ -55,7 +69,10 @@ public class BluetoothServer extends Thread {
*/ */
public void close() { public void close() {
try { try {
mmServerSocket.close(); serverSocket.close();
serverSocket = null;
for(BluetoothDevice device : workers.keySet())
workers.get(device).close();
} catch (IOException e) { } } catch (IOException e) { }
} }
} }

View file

@ -37,7 +37,7 @@ public class BluetoothUtil {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices(); Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : pairedDevices) { for (BluetoothDevice device : pairedDevices) {
log.debug("Paired device: " + device.getName() + " | " + device.getAddress()); log.debug("Paired device: " + device.getName() + " | " + device.getAddress() + " | " + servicesToString(device));
list.add(device); list.add(device);
} }
return list; return list;
@ -56,7 +56,7 @@ public class BluetoothUtil {
// Get the BluetoothDevice object from the Intent // Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
log.debug("Discovered: " + device.getName() + " | " + device.getAddress()); log.debug("Discovered: " + device.getName() + " | " + device.getAddress() + " | " + servicesToString(device));
list.add(device); list.add(device);
} }
} }
@ -102,7 +102,18 @@ public class BluetoothUtil {
return filtered; return filtered;
} }
public void setDiscoverable() { private static String servicesToString(BluetoothDevice device) {
if(device == null || device.getUuids() == null)
return "";
StringBuilder str = new StringBuilder();
for(int i=0; i<device.getUuids().length; i++){
str.append(device.getUuids()[i].getUuid());
str.append("; ");
}
return str.toString();
}
public static void setDiscoverable() {
Intent discoverableIntent = new Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE); Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 60); discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 60);

View file

@ -290,6 +290,7 @@ public class MainActivity extends FragmentActivity implements OnSharedPreference
if(executor != null){ if(executor != null){
log.info("Terminating executor"); log.info("Terminating executor");
executor.terminate(); executor.terminate();
executor.reset();
} }
super.onBackPressed(); super.onBackPressed();
return; return;