Skip to content

Commit 3b389a2

Browse files
committed
v2 support
1 parent 46c957b commit 3b389a2

File tree

2 files changed

+65
-27
lines changed

2 files changed

+65
-27
lines changed

src/main/java/org/microbit/android/partialflashing/HexUtils.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,29 @@ public int searchForData(String search) throws IOException {
9797
// Return -1 if no match
9898
return -1;
9999
}
100+
101+
/*
102+
* A function to search for data in a hex file
103+
* @param the _string_ of data to search for
104+
* @return the index of the data. -1 if not found.
105+
*/
106+
public int searchForDataRegEx(String search) throws IOException {
107+
// Iterate through
108+
ListIterator i = hexLines.listIterator();
109+
while (i.hasNext()) {
110+
// Have to call nextIndex() before next()
111+
int index = i.nextIndex();
112+
113+
// Return index if successful
114+
String match = i.next().toString();
115+
if(match.matches(search)){
116+
return index;
117+
}
118+
}
119+
120+
// Return -1 if no match
121+
return -1;
122+
}
100123

101124
/*
102125
* Returns data from an index

src/main/java/org/microbit/android/partialflashing/PartialFlashingBaseService.java

Lines changed: 42 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
2525

2626
import java.io.IOException;
27-
import java.lang.reflect.Method;
2827
import java.util.Arrays;
2928
import java.util.UUID;
3029

@@ -41,6 +40,7 @@ public abstract class PartialFlashingBaseService extends IntentService {
4140
public static final UUID PARTIAL_FLASH_CHARACTERISTIC = UUID.fromString("e97d3b10-251d-470a-a062-fa1922dfa9a8");
4241
public static final UUID PARTIAL_FLASHING_SERVICE = UUID.fromString("e97dd91d-251d-470a-a062-fa1922dfa9a8");
4342
public static final String PXT_MAGIC = "708E3B92C615A841C49866C975EE5197";
43+
public static final String UPY_MAGIC = ".*FE307F59.{16}9DD7B1C1.*";
4444

4545
private static final UUID MICROBIT_DFU_SERVICE = UUID.fromString("e95d93b0-251d-470a-a062-fa1922dfa9a8");
4646
private static final UUID MICROBIT_SECURE_DFU_SERVICE = UUID.fromString("0000fe59-0000-1000-8000-00805f9b34fb");
@@ -89,6 +89,7 @@ public abstract class PartialFlashingBaseService extends IntentService {
8989
private static final int REGION_MAKECODE = 2;
9090

9191
// DAL Hash
92+
boolean python = false;
9293
String dalHash;
9394

9495
// Partial Flashing Commands
@@ -193,17 +194,17 @@ public void onServicesDiscovered(BluetoothGatt gatt, int status) {
193194
Log.w(TAG, "onServicesDiscovered SUCCESS");
194195

195196
Log.v(TAG, String.valueOf(gatt.getServices()));
196-
mConnectionState = STATE_CONNECTED_AND_READY;
197197
} else {
198198
Log.w(TAG, "onServicesDiscovered received: " + status);
199199
mConnectionState = STATE_ERROR;
200200
}
201201

202202
// Clear locks
203+
mConnectionState = STATE_CONNECTED_AND_READY;
203204
synchronized (lock) {
204205
lock.notifyAll();
205206
}
206-
Log.v(TAG, "Cleared locks");
207+
Log.v(TAG, "onServicesDiscovered :: Cleared locks");
207208
}
208209

209210
@Override
@@ -254,7 +255,10 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris
254255
Log.v(TAG, "Hash: " + bytesToHex(hash));
255256

256257
// If Region is DAL get HASH
257-
if (notificationValue[1] == REGION_DAL)
258+
if (notificationValue[1] == REGION_DAL && python == false)
259+
dalHash = bytesToHex(hash);
260+
261+
if (notificationValue[1] == REGION_DAL && python == true)
258262
dalHash = bytesToHex(hash);
259263

260264
synchronized (region_lock) {
@@ -276,12 +280,14 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris
276280
public void onDescriptorWrite (BluetoothGatt gatt,
277281
BluetoothGattDescriptor descriptor,
278282
int status){
283+
Log.v(TAG, "onDescriptorWrite :: " + status);
284+
279285
if(status == BluetoothGatt.GATT_SUCCESS) {
280286
Log.v(TAG, "Descriptor success");
281287
Log.v(TAG, "GATT: " + gatt.toString() + ", Desc: " + descriptor.toString() + ", Status: " + status);
282288
descriptorWriteSuccess = true;
283289
} else {
284-
Log.v(TAG, "Descriptor write failed");
290+
Log.v(TAG, "onDescriptorWrite: " + status);
285291
}
286292

287293
synchronized (lock) {
@@ -356,6 +362,12 @@ public int attemptPartialFlash(String filePath) {
356362
HexUtils hex = new HexUtils(filePath);
357363
Log.v(TAG, "searchForData()");
358364
int magicIndex = hex.searchForData(PXT_MAGIC);
365+
366+
if (magicIndex == -1) {
367+
magicIndex = hex.searchForDataRegEx(UPY_MAGIC);
368+
python = true;
369+
}
370+
359371
Log.v(TAG, "/searchForData() = " + magicIndex);
360372
if (magicIndex > -1) {
361373

@@ -370,14 +382,31 @@ public int attemptPartialFlash(String filePath) {
370382
}
371383

372384
// Find DAL hash
385+
if(python) magicIndex = magicIndex - 3;
386+
373387
int record_length = hex.getRecordDataLengthFromIndex(magicIndex );
374388
Log.v(TAG, "Length of record: " + record_length);
375389

376390
int magic_offset = (record_length == 64) ? 32 : 0;
377391
String hashes = hex.getDataFromIndex(magicIndex + ((record_length == 64) ? 0 : 1)); // Size of rows
378392
int chunks_per_line = magic_offset / 16;
379393

380-
if(!hashes.substring(magic_offset, magic_offset + 16).equals(dalHash)) {
394+
Log.v(TAG, hashes);
395+
396+
if(hashes.charAt(3) == '2') {
397+
// Uses a hash pointer. Create regex and extract from hex
398+
String regEx = ".*" +
399+
dalHash +
400+
".*";
401+
int hashIndex = hex.searchForDataRegEx(regEx);
402+
403+
// TODO Uses CRC of hash
404+
if(hashIndex == -1 ) {
405+
// return PF_ATTEMPT_DFU;
406+
}
407+
// hashes = hex.getDataFromIndex(hashIndex);
408+
// Log.v(TAG, "hash: " + hashes);
409+
} else if(!hashes.substring(magic_offset, magic_offset + 16).equals(dalHash)) {
381410
Log.v(TAG, hashes.substring(magic_offset, magic_offset + 16) + " " + (dalHash));
382411
return PF_ATTEMPT_DFU;
383412
}
@@ -582,7 +611,7 @@ protected void onHandleIntent(@Nullable Intent intent) {
582611
// Check partial flashing service exists
583612
if(pfService == null) {
584613
Log.v(TAG, "Partial Flashing Service == null");
585-
final Intent broadcast = new Intent(BROADCAST_PF_FAILED);
614+
final Intent broadcast = new Intent(BROADCAST_PF_ATTEMPT_DFU);
586615
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
587616
return;
588617
}
@@ -591,8 +620,9 @@ protected void onHandleIntent(@Nullable Intent intent) {
591620
partialFlashCharacteristic = pfService.getCharacteristic(PARTIAL_FLASH_CHARACTERISTIC);
592621

593622
if(partialFlashCharacteristic == null) {
594-
final Intent broadcast = new Intent(BROADCAST_PF_FAILED);
623+
final Intent broadcast = new Intent(BROADCAST_PF_ATTEMPT_DFU);
595624
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
625+
return;
596626
}
597627

598628
// Set up notifications
@@ -603,21 +633,17 @@ protected void onHandleIntent(@Nullable Intent intent) {
603633
BluetoothGattDescriptor descriptor = partialFlashCharacteristic.getDescriptor(CLIENT_CHARACTERISTIC_CONFIG);
604634
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
605635
res = mBluetoothGatt.writeDescriptor(descriptor);
636+
Log.v(TAG,"writeDescriptor: " + res);
606637

607638
// We have to wait until device receives a response or an error occur
608639
try {
609640
synchronized (lock) {
610-
lock.wait(2000);
611-
Log.v(TAG, String.valueOf(descriptor.getValue()));
641+
lock.wait();
642+
Log.v(TAG, "Descriptor value: " + descriptor.getValue());
612643
}
613644
} catch (final InterruptedException e) {
614645
}
615646

616-
if(!descriptorWriteSuccess) {
617-
final Intent broadcast = new Intent(BROADCAST_PF_FAILED);
618-
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
619-
}
620-
621647
/*
622648
if(false) {
623649
// Partial flashing started but failed. Need to PF or USB flash to fix
@@ -653,7 +679,7 @@ protected void onHandleIntent(@Nullable Intent intent) {
653679
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
654680
return;
655681
}
656-
;
682+
657683

658684
microbitDFUCharacteristic.setValue(payload);
659685
boolean status = mBluetoothGatt.writeCharacteristic(microbitDFUCharacteristic);
@@ -668,17 +694,6 @@ protected void onHandleIntent(@Nullable Intent intent) {
668694
}
669695
}
670696

671-
// Refresh services
672-
try {
673-
// BluetoothGatt gatt
674-
final Method refresh = mBluetoothGatt.getClass().getMethod("refresh");
675-
if (refresh != null) {
676-
refresh.invoke(mBluetoothGatt);
677-
}
678-
} catch (Exception e) {
679-
// Log it
680-
}
681-
682697
mBluetoothGatt.disconnect();
683698

684699
Log.v(TAG, "Send Intent: BROADCAST_PF_ATTEMPT_DFU");

0 commit comments

Comments
 (0)