diff --git a/app/src/main/java/com/ericsson/uecontrol/core/logic/UeBehaviourSynchronize.java b/app/src/main/java/com/ericsson/uecontrol/core/logic/UeBehaviourSynchronize.java index 5f6e58a..e63f8a0 100755 --- a/app/src/main/java/com/ericsson/uecontrol/core/logic/UeBehaviourSynchronize.java +++ b/app/src/main/java/com/ericsson/uecontrol/core/logic/UeBehaviourSynchronize.java @@ -2,6 +2,7 @@ package com.ericsson.uecontrol.core.logic; import android.bluetooth.BluetoothDevice; 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.BluetoothUtil; import org.apache.log4j.Logger; @@ -11,24 +12,92 @@ import java.util.List; /** * 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 int SLEEP_PERIOD = 100; 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 protected void execute() throws Exception { - log.debug("Searching paired devices..."); - List devices = BluetoothUtil.filterWithService(BluetoothUtil.getPairedDevices(), SERVICE_UUID); - if(devices.isEmpty()){ - log.debug("No paired devices found, starting discovery..."); - devices = BluetoothUtil.filterWithService(BluetoothUtil.discover(), SERVICE_UUID); - if(devices.isEmpty()){ - log.debug("No discoverable devices, setting up server..."); - //BluetoothServer server = new BluetoothServer("uecontrol_sync", SERVICE_UUID); + if(server == null && client == null) { + log.debug("Searching paired devices..."); + super.setProgress(0.2f); + List devices = BluetoothUtil.filterWithService(BluetoothUtil.getPairedDevices(), SERVICE_UUID); + if (!devices.isEmpty()) { + log.debug("Found paired device("+devices.get(0).getAddress()+"), connecting..."); + client = new BluetoothClient(devices.get(0), SERVICE_UUID, this); + 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 public String getName() { diff --git a/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothClient.java b/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothClient.java index 79b0ef2..89c4b96 100755 --- a/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothClient.java +++ b/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothClient.java @@ -5,51 +5,60 @@ import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothSocket; import org.apache.log4j.Logger; -import java.io.IOException; +import java.io.*; import java.util.UUID; public class BluetoothClient extends Thread { private static final Logger log = Logger.getLogger(BluetoothClient.class); - private BluetoothSocket mmSocket; - private BluetoothDevice mmDevice; + private BluetoothSocket socket; + private BufferedReader in; + private BufferedWriter out; + private MessageHandler msgHandler; - public BluetoothClient(BluetoothDevice device, String service_uuid) { - mmDevice = device; + public BluetoothClient(BluetoothDevice device, String service_uuid, MessageHandler msgHandler) throws IOException { + log.debug("Starting up bluetooth client."); + this.msgHandler = msgHandler; // 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 { - // MY_UUID is the app's UUID string, also used by the server code - mmSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(service_uuid)); + if (socket != null) + socket.close(); } catch (IOException e) { log.trace(null, e); } } - public void run() { - BluetoothAdapter mBluetoothAdapter = BluetoothUtil.getAdapter(); - // Cancel discovery because it will slow down the connection - 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) { - + public void sendMessage(String msg) throws IOException { + if(socket != null) + out.write(msg); } /** @@ -57,9 +66,15 @@ public class BluetoothClient extends Thread { */ public void close() { try { - mmSocket.close(); + socket.close(); + socket = null; } catch (IOException e) { log.trace(null, e); } } + + + public interface MessageHandler{ + public void messageReceived(String msg); + } } \ No newline at end of file diff --git a/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothServer.java b/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothServer.java index eb0efa3..0e366a2 100755 --- a/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothServer.java +++ b/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothServer.java @@ -1,44 +1,53 @@ package com.ericsson.uecontrol.core.util; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; import android.bluetooth.BluetoothServerSocket; import android.bluetooth.BluetoothSocket; import org.apache.log4j.Logger; -import java.io.IOException; +import java.io.*; +import java.util.HashMap; import java.util.UUID; +import com.ericsson.uecontrol.core.util.BluetoothClient.MessageHandler; + public class BluetoothServer extends Thread { private static final Logger log = Logger.getLogger(BluetoothServer.class); - private BluetoothServerSocket mmServerSocket; + private BluetoothServerSocket serverSocket; + private HashMap workers; + private MessageHandler msgHandler; - public BluetoothServer(String service, String service_uuid) { - try { - BluetoothAdapter mBluetoothAdapter = BluetoothUtil.getAdapter(); - // MY_UUID is the app's UUID string, also used by the client code - mmServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(service, UUID.fromString(service_uuid)); - } catch (IOException e) { - log.trace(null, e); - } + public BluetoothServer(String service, String service_uuid, MessageHandler msgHandler) throws IOException { + this.workers = new HashMap(); + this.msgHandler = msgHandler; + + // MY_UUID is the app's UUID string, also used by the client code + BluetoothAdapter adapter = BluetoothUtil.getAdapter(); + serverSocket = adapter.listenUsingRfcommWithServiceRecord(service, UUID.fromString(service_uuid)); + //BluetoothUtil.setDiscoverable(); } public void run() { try { BluetoothSocket socket = null; // Keep listening until exception occurs or a socket is returned - while (true) { + while (serverSocket != null) { try { - socket = mmServerSocket.accept(); + socket = serverSocket.accept(); } catch (IOException e) { - break; + log.trace(null, e); } // If a connection was accepted if (socket != null) { // Do work to manage the connection (in a separate thread) - manageConnectedSocket(socket); - mmServerSocket.close(); - break; + BluetoothClient client = new BluetoothClient(socket, msgHandler); + workers.put( + socket.getRemoteDevice(), + client); + client.start(); + log.debug("New Client Connection, connection list size: "+workers.size()); } } }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() { try { - mmServerSocket.close(); + serverSocket.close(); + serverSocket = null; + for(BluetoothDevice device : workers.keySet()) + workers.get(device).close(); } catch (IOException e) { } } } \ No newline at end of file diff --git a/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothUtil.java b/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothUtil.java index fb75331..68cb4c8 100755 --- a/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothUtil.java +++ b/app/src/main/java/com/ericsson/uecontrol/core/util/BluetoothUtil.java @@ -37,7 +37,7 @@ public class BluetoothUtil { Set pairedDevices = mBluetoothAdapter.getBondedDevices(); 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); } return list; @@ -56,7 +56,7 @@ public class BluetoothUtil { // Get the BluetoothDevice object from the Intent 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); } } @@ -102,7 +102,18 @@ public class BluetoothUtil { 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