Skip to content

Flash first flow #13

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 15, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -54,14 +54,23 @@ public void logi(String message) {
// ================================================================
// INTENT SERVICE

public static final String DFU_BROADCAST_ERROR = "no.nordicsemi.android.dfu.broadcast.BROADCAST_ERROR";
public static final String BROADCAST_ERROR = "org.microbit.android.partialflashing.broadcast.BROADCAST_ERROR";
public static final String BROADCAST_ACTION = "org.microbit.android.partialflashing.broadcast.BROADCAST_ACTION";
public static final String BROADCAST_PROGRESS = "org.microbit.android.partialflashing.broadcast.BROADCAST_PROGRESS";
public static final String BROADCAST_START = "org.microbit.android.partialflashing.broadcast.BROADCAST_START";
public static final String BROADCAST_COMPLETE = "org.microbit.android.partialflashing.broadcast.BROADCAST_COMPLETE";
public static final String EXTRA_PROGRESS = "org.microbit.android.partialflashing.extra.EXTRA_PROGRESS";
public static final String BROADCAST_PF_FAILED = "org.microbit.android.partialflashing.broadcast.BROADCAST_PF_FAILED";
public static final String BROADCAST_PF_ATTEMPT_DFU = "org.microbit.android.partialflashing.broadcast.BROADCAST_PF_ATTEMPT_DFU";
public static final String BROADCAST_PF_ABORTED = "org.microbit.android.partialflashing.broadcast.BROADCAST_PF_ABORTED";
public static final String EXTRA_ACTION = "org.microbit.android.partialflashing.extra.EXTRA_ACTION";
public static final int ACTION_ABORT = 0;
public static final String EXTRA_DATA = "org.microbit.android.partialflashing.extra.EXTRA_DATA";
public static final int ERROR_CONNECT = 1;
public static final int ERROR_RECONNECT = 2;
public static final int ERROR_DFU_MODE = 3;

private boolean abortReceived = false;

protected abstract Class<? extends Activity> getNotificationTarget();

Expand All @@ -73,7 +82,19 @@ public PartialFlashingBaseService() {
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, final Intent intent) {
logi( "Received Broadcast: " + intent.toString());
logi("Received Broadcast: " + intent.toString());
int extra = intent.getIntExtra(EXTRA_ACTION, -1);
switch (extra) {
case ACTION_ABORT:
abortReceived = true;
// Clear locks
synchronized (lock) {
lock.notifyAll();
}
break;
default:
break;
}
}
};

Expand All @@ -85,6 +106,8 @@ public void onCreate() {

logi( "onCreate");

abortReceived = false;

// Create intent filter and add to Local Broadcast Manager so that we can use an Intent to
// start the Partial Flashing Service

Expand Down Expand Up @@ -134,6 +157,8 @@ protected void onHandleIntent(@Nullable Intent intent) {
final boolean pf = intent.getBooleanExtra("pf", true);

partialFlash( filePath, deviceAddress, pf);

checkAbort();
logi("onHandleIntent END");
}

Expand Down Expand Up @@ -251,14 +276,16 @@ private void partialFlash( final String filePath, final String deviceAddress, fi

for ( int i = 0; i < 3; i++) {
mBluetoothGatt = connect(deviceAddress);
if ( abortReceived) return;
if (mBluetoothGatt != null)
break;
}

if (mBluetoothGatt == null) {
logi( "Failed to connect");
logi( "Send Intent: DFU_BROADCAST_ERROR");
final Intent broadcast = new Intent(DFU_BROADCAST_ERROR);
logi( "Send Intent: BROADCAST_ERROR");
final Intent broadcast = new Intent(BROADCAST_ERROR);
broadcast.putExtra(EXTRA_DATA, ERROR_CONNECT);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
return;
}
Expand All @@ -272,16 +299,16 @@ private void partialFlash( final String filePath, final String deviceAddress, fi
// But it doesn't seem to work in Android 8
cccEnable(serviceChangedCharacteristic(), false);
logi( "Reconnect");
mBluetoothGatt.disconnect();
lockWait(2000);
mBluetoothGatt.close();
mBluetoothGatt = null;
disconnectAndClose();
if ( abortReceived) return;

mBluetoothGatt = connect(deviceAddress);
if ( abortReceived) return;
if (mBluetoothGatt == null) {
logi( "Failed to connect");
logi( "Send Intent: DFU_BROADCAST_ERROR");
final Intent broadcast = new Intent(DFU_BROADCAST_ERROR);
logi( "Send Intent: BROADCAST_ERROR");
final Intent broadcast = new Intent(BROADCAST_ERROR);
broadcast.putExtra(EXTRA_DATA, ERROR_RECONNECT);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
return;
}
Expand All @@ -297,6 +324,8 @@ private void partialFlash( final String filePath, final String deviceAddress, fi
refreshV1ForMicroBitDfu();
}

if ( abortReceived) return;

int pfResult = PF_ATTEMPT_DFU;
if ( pf) {
logi( "Trying to partial flash");
Expand All @@ -306,6 +335,7 @@ private void partialFlash( final String filePath, final String deviceAddress, fi
}

String action = "";
int extra = 0;

switch ( pfResult) {
case PF_FAILED: {
Expand All @@ -322,7 +352,8 @@ private void partialFlash( final String filePath, final String deviceAddress, fi
if( isV1) {
if ( !enterDFUModeV1()) {
logi( "Failed to enter DFU mode");
action = DFU_BROADCAST_ERROR;
action = BROADCAST_ERROR;
extra = ERROR_DFU_MODE;
}
}
break;
Expand All @@ -333,13 +364,9 @@ private void partialFlash( final String filePath, final String deviceAddress, fi
}
}

logi( "disconnect");
mBluetoothGatt.disconnect();
lockWait( 2000);
mBluetoothGatt.close();
mBluetoothGatt = null;
disconnectAndClose();

if ( isV1 && action == BROADCAST_PF_ATTEMPT_DFU) {
if (isV1 && action.equals(BROADCAST_PF_ATTEMPT_DFU)) {
// Try to ensure the NordicDfu profile
for ( int i = 0; i < 5; i++) {
mBluetoothGatt = connect(deviceAddress);
Expand All @@ -350,21 +377,43 @@ private void partialFlash( final String filePath, final String deviceAddress, fi

if ( mBluetoothGatt != null) {
refreshV1ForNordicDfu();
mBluetoothGatt.disconnect();
lockWait(2000);
mBluetoothGatt.close();
mBluetoothGatt = null;
disconnectAndClose();
}
}

if ( !action.isEmpty()) {
logi( "Send Intent: " + action);
final Intent broadcast = new Intent(action);
if ( action.equals(BROADCAST_ERROR)) {
broadcast.putExtra(EXTRA_DATA, extra);
}
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
}
logi( "partialFlash End");
}

@SuppressLint("MissingPermission")
private void disconnectAndClose() {
if ( mBluetoothGatt != null) {
logi("disconnect");
mBluetoothGatt.disconnect();
lockWait(2000);
mBluetoothGatt.close();
mBluetoothGatt = null;
}
}

private boolean checkAbort() {
if ( !abortReceived) {
return false;
}
disconnectAndClose();
logi("Send Intent: " + BROADCAST_PF_ABORTED);
final Intent broadcast = new Intent(BROADCAST_PF_ABORTED);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
return true;
}

// Various callback methods defined by the BLE API.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@SuppressLint("MissingPermission")
Expand Down Expand Up @@ -1172,6 +1221,10 @@ protected BluetoothGatt connect(@NonNull final String address) {
break;
}

if ( abortReceived) {
mConnectionState = STATE_ERROR;
}

waiting = false;
switch ( mConnectionState) {
case STATE_CONNECTED_AND_READY:
Expand Down