Skip to content

Commit 061448f

Browse files
committed
reconnect automatically to already bound devices. It's much better now.
1 parent 1935fe3 commit 061448f

7 files changed

Lines changed: 206 additions & 21 deletions

File tree

app/src/main/java/net/sharksystem/asap/android/ASAPServiceMethods.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
package net.sharksystem.asap.android;
22

3-
import android.os.Bundle;
4-
import android.os.Message;
5-
63
public class ASAPServiceMethods {
74

85
///////////// sending asap messages
@@ -23,6 +20,10 @@ public class ASAPServiceMethods {
2320
public static final int START_BLUETOOTH_DISCOVERABLE = 104;
2421
public static final int START_BLUETOOTH_DISCOVERY = 105;
2522

23+
// check from time if there is a paired device in the neighbourhood
24+
public static final int START_RECONNECT_PAIRED_DEVICES = 106;
25+
public static final int STOP_RECONNECT_PAIRED_DEVICES = 107;
26+
2627
///////////// asap engine management
2728
public static final int START_BROADCASTS = 200;
2829
public static final int STOP_BROADCASTS = 201;

app/src/main/java/net/sharksystem/asap/android/bluetooth/BluetoothEngine.java

Lines changed: 85 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,12 @@
1616
import net.sharksystem.asap.android.service2AppMessaging.ASAPServiceRequestNotifyIntent;
1717

1818
import java.io.IOException;
19+
import java.net.Socket;
20+
import java.util.ArrayList;
1921
import java.util.HashMap;
22+
import java.util.List;
2023
import java.util.Map;
24+
import java.util.Set;
2125

2226
import static android.bluetooth.BluetoothAdapter.ACTION_DISCOVERY_FINISHED;
2327
import static android.bluetooth.BluetoothAdapter.ACTION_DISCOVERY_STARTED;
@@ -56,6 +60,12 @@ private BluetoothEngine(ASAPService ASAPService, Context context) {
5660
// Device doesn't support Bluetooth
5761
Log.i(this.getLogStart(), "device does not support bluetooth - give up");
5862
}
63+
64+
// auto start
65+
if(this.mBluetoothAdapter.isEnabled()) {
66+
Log.i(this.getLogStart(), "Bluetooth is on - activate ASAP bluetooth stuff");
67+
this.start();
68+
}
5969
}
6070

6171
private String getLogStart() {
@@ -76,6 +86,10 @@ public void stop() {
7686
}
7787
}
7888

89+
public boolean started() {
90+
return this.btEnvironmentOn;
91+
}
92+
7993
/////////////////////////////////////////////////////////////////////////////////
8094
// do the real bluetooth stuff //
8195
/////////////////////////////////////////////////////////////////////////////////
@@ -289,8 +303,9 @@ BluetoothAdapter getBTAdapter() throws ASAPException {
289303
public static final int BT_MAJOR_CLASS_PHONE = 0x00000200;
290304
public static final int BT_MAJOR_CLASS_COMPUTER = 0x00000100;
291305

292-
void deviceFound(BluetoothDevice btDevice, BluetoothClass btClass) throws ASAPException {
293-
String macAddress = btDevice.getAddress();// MAC address
306+
void tryConnect(BluetoothDevice btDevice, BluetoothClass btClass) throws ASAPException {
307+
btClass = btDevice.getBluetoothClass();
308+
String macAddress = btDevice.getAddress(); // MAC address
294309

295310
int btClassMajorNumber = btClass.getMajorDeviceClass();
296311

@@ -327,7 +342,7 @@ void deviceFound(BluetoothDevice btDevice, BluetoothClass btClass) throws ASAPEx
327342
//this.mBluetoothAdapter.cancelDiscovery();
328343

329344
// already connected?
330-
if(this.checkAlreadyConnected(macAddress)) return;
345+
if(this.checkAlreadyConnectedWithDevice(macAddress)) return;
331346

332347
if(this.shouldConnectToMACPeer(macAddress)) {
333348
Log.d(this.getLogStart(), "create a BT client socket thread");
@@ -338,7 +353,7 @@ void deviceFound(BluetoothDevice btDevice, BluetoothClass btClass) throws ASAPEx
338353
}
339354
}
340355

341-
private boolean checkAlreadyConnected(String macAddress) {
356+
private boolean checkAlreadyConnectedWithDevice(String macAddress) {
342357
BluetoothSocket bluetoothSocket = this.openSockets.get(macAddress);
343358
if(bluetoothSocket != null) {
344359
if(bluetoothSocket.isConnected()) {
@@ -355,8 +370,72 @@ private boolean checkAlreadyConnected(String macAddress) {
355370
return false;
356371
}
357372

373+
@Override
374+
public boolean tryReconnect() {
375+
if(!this.started()) {
376+
Log.d(this.getLogStart(), "don't try to reconnect: BT is not running");
377+
return false;
378+
}
379+
380+
boolean anySuccess = false;
381+
382+
// stolen from: https://developer.android.com/guide/topics/connectivity/bluetooth#java
383+
Set<BluetoothDevice> pairedDevices = this.mBluetoothAdapter.getBondedDevices();
384+
if (pairedDevices.size() > 0) {
385+
// There are paired devices. Get the name and address of each paired device.
386+
for (BluetoothDevice btDevice : pairedDevices) {
387+
String deviceName = btDevice.getName();
388+
String deviceHardwareAddress = btDevice.getAddress(); // MAC address
389+
390+
try {
391+
this.tryConnect(btDevice, btDevice.getBluetoothClass());
392+
anySuccess = true; // at least no exception
393+
} catch (ASAPException e) {
394+
Log.d(this.getLogStart(), "problems reconnecting: "
395+
+ e.getLocalizedMessage());
396+
}
397+
}
398+
}
399+
400+
return anySuccess;
401+
}
402+
358403
private Map<String, BluetoothSocket> openSockets = new HashMap<>();
359404

405+
@Override
406+
public void checkConnectionStatus() {
407+
Log.d(this.getLogStart(), "check connection status");
408+
// some structures are sensitive about changes when their are used
409+
List<String> names2remove = new ArrayList<>();
410+
411+
for(String connectionName : this.openSockets.keySet()) {
412+
BluetoothSocket bluetoothSocket = this.openSockets.get(connectionName);
413+
StringBuilder sb = new StringBuilder();
414+
sb.append("name: ");
415+
sb.append(connectionName);
416+
sb.append(" | isConnected: ");
417+
sb.append(bluetoothSocket.isConnected());
418+
Log.d(this.getLogStart(), sb.toString());
419+
420+
if(!bluetoothSocket.isConnected()) {
421+
try {
422+
names2remove.add(connectionName);
423+
bluetoothSocket.close(); // not necessary but better save than sorry
424+
Log.d(this.getLogStart(), "removed closed socket to " + connectionName);
425+
} catch (IOException e) {
426+
Log.d(this.getLogStart(),
427+
"checkConnectionStatus - closing an unconnected socket: "
428+
+ e.getLocalizedMessage());
429+
}
430+
}
431+
}
432+
433+
// remove
434+
for(String name : names2remove) {
435+
this.openSockets.remove(name);
436+
}
437+
}
438+
360439
/**
361440
* Both client and server sockets
362441
* @param socket
@@ -372,7 +451,7 @@ void handleBTSocket(BluetoothSocket socket, boolean isClient) throws IOException
372451
Log.d(this.getLogStart(), logMessage + remoteMacAddress);
373452

374453
// already an open connection?
375-
if (this.checkAlreadyConnected(remoteMacAddress)) {
454+
if (this.checkAlreadyConnectedWithDevice(remoteMacAddress)) {
376455
socket.close();
377456
return;
378457
}
@@ -440,7 +519,7 @@ private synchronized void handleBTSocket(BluetoothSocket socket) throws IOExcept
440519
String address = socket.getRemoteDevice().getAddress();
441520

442521
// already an open connection?
443-
if (this.checkAlreadyConnected(address)) {
522+
if (this.checkAlreadyConnectedWithDevice(address)) {
444523
socket.close();
445524
return;
446525
}

app/src/main/java/net/sharksystem/asap/android/bluetooth/FoundBTDevicesBroadcastReceiver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void onReceive(Context context, Intent intent) {
3838
Log.d(this.getLogStart(), "found BT class: " + btClass.toString());
3939

4040
try {
41-
this.bluetoothEngine.deviceFound(device, btClass);
41+
this.bluetoothEngine.tryConnect(device, btClass);
4242
} catch (ASAPException e) {
4343
Log.e(this.getLogStart(),
4444
"could not handle device found: " + e.getLocalizedMessage());

app/src/main/java/net/sharksystem/asap/android/service/ASAPMessageHandler.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,12 @@ public void handleMessage(Message msg) {
6666
this.asapService.startBluetoothDiscovery();
6767
break;
6868

69-
case ASAPServiceMethods.START_BROADCASTS:
70-
this.asapService.resumeBroadcasts();
69+
case ASAPServiceMethods.START_RECONNECT_PAIRED_DEVICES:
70+
this.asapService.startReconnectPairedDevices();
71+
break;
72+
73+
case ASAPServiceMethods.STOP_RECONNECT_PAIRED_DEVICES:
74+
this.asapService.startReconnectPairedDevices();
7175
break;
7276

7377
case ASAPServiceMethods.STOP_BROADCASTS:

app/src/main/java/net/sharksystem/asap/android/service/ASAPService.java

Lines changed: 91 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232
import java.util.List;
3333

3434
/**
35-
* Service that searches and creates wifi p2p connections
36-
* to run an ASAP session.
35+
* Service that searches for and creates layer 2 point-to-point connections
36+
* to run an ASAP session on.
3737
*/
3838

3939
public class ASAPService extends Service implements ASAPChunkReceivedListener,
4040
ASAPOnlinePeersChangedListener {
4141

42+
/** time in minutes until a new connection attempt is made to an already paired device is made*/
43+
public static final int WAIT_MINUTES_UNTIL_TRY_RECONNECT = 1; // debugging
44+
//public static final int WAIT_UNTIL_TRY_RECONNECT = 30; // real life
45+
4246
private String asapEngineRootFolderName;
4347

4448
//private asapMultiEngine asapMultiEngine = null;
@@ -164,11 +168,16 @@ public int onStartCommand(Intent intent, int flags, int startId) {
164168
this.asapEngineRootFolderName = asapRoot.getAbsolutePath();
165169
Log.d(this.getLogStart(),"work with folder: " + this.asapEngineRootFolderName);
166170

171+
this.startReconnectPairedDevices();
172+
167173
return super.onStartCommand(intent, flags, startId);
168174
}
169175

170176
public void onDestroy() {
171177
super.onDestroy();
178+
179+
this.stopReconnectPairedDevices();
180+
172181
Log.d(this.getLogStart(),"onDestroy");
173182
}
174183
/**
@@ -210,7 +219,11 @@ void stopWifiDirect() {
210219
void startBluetooth() {
211220
Log.d("ASAPService", "start bluetooth");
212221

213-
BluetoothEngine.getASAPBluetoothEngine(this, this).start();
222+
BluetoothEngine btEngine = BluetoothEngine.getASAPBluetoothEngine(this, this);
223+
btEngine.start();
224+
225+
Log.d(this.getLogStart(), "start reconnect thread");
226+
this.startReconnectPairedDevices();
214227

215228
Log.d("ASAPService", "started bluetooth");
216229
}
@@ -225,6 +238,9 @@ void stopBluetooth() {
225238
asapBluetoothEngine.stop();
226239
}
227240

241+
Log.d(this.getLogStart(), "stop reconnect thread");
242+
this.stopReconnectPairedDevices();
243+
228244
Log.d("ASAPService", "stopped bluetooth");
229245
}
230246

@@ -253,11 +269,6 @@ public void startBluetoothDiscovery() throws ASAPException {
253269
}
254270
}
255271

256-
private String getLogStart() {
257-
return Util.getLogStart(this);
258-
}
259-
260-
261272
//////////////////////////////////////////////////////////////////////////////////////
262273
// status management //
263274
//////////////////////////////////////////////////////////////////////////////////////
@@ -268,6 +279,72 @@ public void propagateProtocolStatus() throws ASAPException {
268279
// Wifi.propagateStatus();
269280
}
270281

282+
private void checkLayer2ConnectionStatus() {
283+
// force layer 2 engine to check their connection status
284+
BluetoothEngine asapBluetoothEngine =
285+
BluetoothEngine.getASAPBluetoothEngine(this, this);
286+
287+
asapBluetoothEngine.checkConnectionStatus();
288+
}
289+
290+
private ReconnectTrigger reconnectTrigger = null;
291+
public void startReconnectPairedDevices() {
292+
if(this.reconnectTrigger != null) {
293+
this.reconnectTrigger.terminate();
294+
}
295+
296+
this.reconnectTrigger = new ReconnectTrigger();
297+
this.reconnectTrigger.start();
298+
}
299+
300+
public void stopReconnectPairedDevices() {
301+
if(this.reconnectTrigger != null) {
302+
this.reconnectTrigger.terminate();
303+
this.reconnectTrigger = null;
304+
}
305+
}
306+
307+
private boolean tryReconnect() {
308+
Log.d(this.getLogStart(), "try to reconnect with paired devices");
309+
310+
BluetoothEngine btEngine =
311+
BluetoothEngine.getASAPBluetoothEngine(this, this);
312+
313+
if(btEngine != null) {
314+
return btEngine.tryReconnect();
315+
}
316+
317+
return false;
318+
}
319+
320+
private class ReconnectTrigger extends Thread {
321+
private boolean terminated = false;
322+
public static final int MAX_FAILATTEMPTS = 3;
323+
324+
void terminate() { this.terminated = true; }
325+
326+
public void run() {
327+
Log.d(ASAPService.this.getLogStart(), "start new ReconnectTriggerThread");
328+
int failedAttemptsCounter = 0;
329+
330+
while (!this.terminated) {
331+
if(!ASAPService.this.tryReconnect()) {
332+
failedAttemptsCounter++;
333+
if(failedAttemptsCounter == MAX_FAILATTEMPTS) {
334+
this.terminate();
335+
break;
336+
}
337+
}
338+
339+
try {
340+
Thread.sleep(ASAPService.WAIT_MINUTES_UNTIL_TRY_RECONNECT * 1000 * 60);
341+
} catch (InterruptedException e) {
342+
// ignore this and go ahead
343+
}
344+
}
345+
Log.d(ASAPService.this.getLogStart(), "ReconnectTriggerThread terminated");
346+
}
347+
}
271348

272349
//////////////////////////////////////////////////////////////////////////////////////
273350
// chunk receiving management //
@@ -349,5 +426,11 @@ public void onlinePeersChanged(ASAPPeer asapPeer) {
349426
intent.putExtra(ASAPServiceRequestNotifyIntent.ASAP_PARAMETER_1, serializedOnlinePeers);
350427

351428
this.sendBroadcast(intent);
429+
430+
this.checkLayer2ConnectionStatus();
431+
}
432+
433+
private String getLogStart() {
434+
return Util.getLogStart(this);
352435
}
353436
}

app/src/main/java/net/sharksystem/asap/android/service/MacLayerEngine.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ protected ASAPService getAsapService() {
4747
public abstract void start();
4848
public abstract void stop();
4949

50+
/** try to reconnect to previously met (paired devices)
51+
* @return true if environment was up and running, false.. if in general impossible to reconnect
52+
*/
53+
public abstract boolean tryReconnect();
54+
5055
public void restart() {
5156
this.stop();
5257
this.start();
@@ -126,7 +131,7 @@ protected void launchASAPConnection(
126131
Log.d(this.getLogStart(), "going to launch a new asap connection");
127132

128133
try {
129-
Log.d(this.getLogStart(), "call asapMultiEngine to handle connection");
134+
Log.d(this.getLogStart(), "call asap peer to handle connection");
130135
// TestConnectionHandler testConnectionHandler = new TestConnectionHandler(this.is, this.os);
131136
// testConnectionHandler.start();
132137
this.asapConnections.put(address,
@@ -136,4 +141,6 @@ protected void launchASAPConnection(
136141
Log.d(this.getLogStart(), "while lauching asap connection: " + e.getLocalizedMessage());
137142
}
138143
}
144+
145+
public abstract void checkConnectionStatus();
139146
}

0 commit comments

Comments
 (0)