@@ -96,6 +96,10 @@ public abstract class PartialFlashingBaseService extends IntentService {
96
96
boolean python = false ;
97
97
String dalHash ;
98
98
99
+ long code_startAddress = 0 ;
100
+
101
+ long code_endAddress = 0 ;
102
+
99
103
// Partial Flashing Commands
100
104
private static final byte REGION_INFO_COMMAND = 0x0 ;
101
105
private static final byte FLASH_COMMAND = 0x1 ;
@@ -150,7 +154,6 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status,
150
154
String intentAction ;
151
155
if (newState == BluetoothProfile .STATE_CONNECTED ) {
152
156
153
- final boolean success = gatt .discoverServices ();
154
157
mConnectionState = STATE_CONNECTED ;
155
158
156
159
/* Taken from Nordic. See reasoning here: https://github.com/NordicSemiconductor/Android-DFU-Library/blob/e0ab213a369982ae9cf452b55783ba0bdc5a7916/dfu/src/main/java/no/nordicsemi/android/dfu/DfuBaseService.java#L888 */
@@ -165,11 +168,10 @@ public void onConnectionStateChange(BluetoothGatt gatt, int status,
165
168
}
166
169
Log .v (TAG , "Bond timeout" );
167
170
}
168
- // After 1.6s the services are already discovered so the following gatt.discoverServices() finishes almost immediately.
169
- // NOTE: This also works with shorted waiting time. The gatt.discoverServices() must be called after the indication is received which is
171
+ // NOTE: This also works with shorted waiting time. The gatt.discoverServices() must be called after the indication is received which is
170
172
// about 600ms after establishing connection. Values 600 - 1600ms should be OK.
171
173
}
172
- gatt .discoverServices ();
174
+ final boolean success = gatt .discoverServices ();
173
175
174
176
if (!success ) {
175
177
Log .e (TAG ,"ERROR_SERVICE_DISCOVERY_NOT_STARTED" );
@@ -255,6 +257,18 @@ public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteris
255
257
byte [] endAddress = Arrays .copyOfRange (notificationValue , 6 , 10 );
256
258
Log .v (TAG , "startAddress: " + bytesToHex (startAddress ) + " endAddress: " + bytesToHex (endAddress ));
257
259
260
+ if ( notificationValue [1 ] == REGION_MAKECODE ) {
261
+ code_startAddress = Byte .toUnsignedLong (startAddress [0 ])
262
+ + Byte .toUnsignedLong (startAddress [0 ]) * 256
263
+ + Byte .toUnsignedLong (startAddress [0 ]) * 256 * 256
264
+ + Byte .toUnsignedLong (startAddress [0 ]) * 256 * 256 * 256 ;
265
+
266
+ code_endAddress = Byte .toUnsignedLong (endAddress [0 ])
267
+ + Byte .toUnsignedLong (endAddress [0 ]) * 256
268
+ + Byte .toUnsignedLong (endAddress [0 ]) * 256 * 256
269
+ + Byte .toUnsignedLong (endAddress [0 ]) * 256 * 256 * 256 ;
270
+ }
271
+
258
272
byte [] hash = Arrays .copyOfRange (notificationValue , 10 , 18 );
259
273
Log .v (TAG , "Hash: " + bytesToHex (hash ));
260
274
@@ -351,11 +365,6 @@ public Boolean writePartialFlash(BluetoothGattCharacteristic partialFlashCharact
351
365
352
366
public int attemptPartialFlash (String filePath ) {
353
367
Log .v (TAG , "Flashing: " + filePath );
354
- long startTime = SystemClock .elapsedRealtime ();
355
-
356
- int count = 0 ;
357
- int progressBar = 0 ;
358
- int numOfLines = 0 ;
359
368
360
369
sendProgressBroadcastStart ();
361
370
@@ -365,30 +374,49 @@ public int attemptPartialFlash(String filePath) {
365
374
Log .v (TAG , filePath );
366
375
HexUtils hex = new HexUtils (filePath );
367
376
Log .v (TAG , "searchForData()" );
377
+ String hash = "" ;
368
378
int magicIndex = hex .searchForData (PXT_MAGIC );
379
+ if (magicIndex > -1 ) {
380
+ python = false ;
381
+ String magicData = hex .getDataFromIndex (magicIndex );
382
+ int next = magicData .indexOf (PXT_MAGIC ) + PXT_MAGIC .length ();
383
+ if ( next < magicData .length ()) {
384
+ hash = magicData .substring ( next );
385
+ }
386
+ if ( hash .length () < 16 ) {
387
+ String nextData = hex .getDataFromIndex ( magicIndex + 1 );
388
+ hash = hash + nextData .substring ( 0 , 16 - hash .length ());
389
+ }
390
+ } else {
391
+ // magicIndex = hex.searchForDataRegEx(UPY_MAGIC);
392
+ // python = true;
393
+ }
369
394
370
395
if (magicIndex == -1 ) {
371
- magicIndex = hex . searchForDataRegEx ( UPY_MAGIC );
372
- python = true ;
396
+ Log . v ( TAG , "No magic" );
397
+ return PF_ATTEMPT_DFU ;
373
398
}
374
399
375
- Log .v (TAG , "/searchForData() = " + magicIndex );
376
- if (magicIndex > -1 ) {
377
-
378
- Log .v (TAG , "Found PXT_MAGIC" );
379
-
380
- // Get Memory Map from Microbit
381
- try {
382
- Log .v (TAG , "readMemoryMap()" );
383
- readMemoryMap ();
384
- } catch (InterruptedException e ) {
385
- e .printStackTrace ();
400
+ Log .v (TAG , "Found PXT_MAGIC at " + magicIndex );
401
+
402
+ // Get Memory Map from Microbit
403
+ try {
404
+ Log .v (TAG , "readMemoryMap()" );
405
+ readMemoryMap ();
406
+ } catch (InterruptedException e ) {
407
+ e .printStackTrace ();
408
+ }
409
+
410
+ // Compare DAL hash
411
+ if ( !python ) {
412
+ if (!hash .equals (dalHash )) {
413
+ Log .v (TAG , hash + " " + (dalHash ));
414
+ return PF_ATTEMPT_DFU ;
386
415
}
387
-
388
- // Find DAL hash
389
- if (python ) magicIndex = magicIndex - 3 ;
416
+ } else {
417
+ magicIndex = magicIndex - 3 ;
390
418
391
- int record_length = hex .getRecordDataLengthFromIndex (magicIndex );
419
+ int record_length = hex .getRecordDataLengthFromIndex (magicIndex );
392
420
Log .v (TAG , "Length of record: " + record_length );
393
421
394
422
int magic_offset = (record_length == 64 ) ? 32 : 0 ;
@@ -397,131 +425,158 @@ public int attemptPartialFlash(String filePath) {
397
425
398
426
Log .v (TAG , hashes );
399
427
400
- if (hashes .charAt (3 ) == '2' ) {
428
+ if (hashes .charAt (3 ) == '2' ) {
401
429
// Uses a hash pointer. Create regex and extract from hex
402
430
String regEx = ".*" +
403
431
dalHash +
404
432
".*" ;
405
433
int hashIndex = hex .searchForDataRegEx (regEx );
406
434
407
435
// TODO Uses CRC of hash
408
- if (hashIndex == -1 ) {
436
+ if (hashIndex == -1 ) {
409
437
// return PF_ATTEMPT_DFU;
410
438
}
411
439
// hashes = hex.getDataFromIndex(hashIndex);
412
440
// Log.v(TAG, "hash: " + hashes);
413
- } else if (!hashes .substring (magic_offset , magic_offset + 16 ).equals (dalHash )) {
414
- Log .v (TAG , hashes .substring (magic_offset , magic_offset + 16 ) + " " + (dalHash ));
415
- return PF_ATTEMPT_DFU ;
441
+ } else if (!hashes .substring (magic_offset , magic_offset + 16 ).equals (dalHash )) {
442
+ Log .v (TAG , hashes .substring (magic_offset , magic_offset + 16 ) + " " + (dalHash ));
443
+ return PF_ATTEMPT_DFU ;
416
444
}
445
+ }
417
446
418
- numOfLines = hex .numOfLines () - magicIndex ;
419
- Log .v (TAG , "Total lines: " + numOfLines );
420
-
421
- // Ready to flash!
422
- // Loop through data
423
- String hexData ;
424
- int packetNum = 0 ;
425
- int lineCount = 0 ;
447
+ int count = 0 ;
448
+ int numOfLines = hex .numOfLines () - magicIndex ;
449
+ Log .v (TAG , "Total lines: " + numOfLines );
450
+
451
+ int magicLo = hex .getRecordAddressFromIndex (magicIndex );
452
+ int magicHi = hex .getSegmentAddress (magicIndex );
453
+ long magicA = (long ) magicLo + (long ) magicHi * 256 * 256 ;
454
+
455
+ // Ready to flash!
456
+ // Loop through data
457
+ int packetNum = 0 ;
458
+ int lineCount = 0 ;
459
+ int part = 0 ;
460
+ int line0 = 0 ;
461
+ int part0 = 0 ;
462
+
463
+ int addrLo = hex .getRecordAddressFromIndex (magicIndex + lineCount );
464
+ int addrHi = hex .getSegmentAddress (magicIndex + lineCount );
465
+ long addr = (long ) addrLo + (long ) addrHi * 256 * 256 ;
466
+
467
+ String hexData ;
468
+ String partData ;
469
+
470
+ Log .v (TAG , "enter flashing loop" );
471
+
472
+ long startTime = SystemClock .elapsedRealtime ();
473
+ while (true ) {
474
+ // Timeout if total is > 30 seconds
475
+ if (SystemClock .elapsedRealtime () - startTime > 60000 ) {
476
+ Log .v (TAG , "Partial flashing has timed out" );
477
+ return PF_FAILED ;
478
+ }
426
479
427
- Log .v (TAG , "enter flashing loop" );
480
+ // Check if EOF
481
+ if (hex .getRecordTypeFromIndex (magicIndex + lineCount ) != 0 ) {
482
+ break ;
483
+ }
428
484
429
- while (true ){
430
- // Timeout if total is > 30 seconds
431
- if (SystemClock .elapsedRealtime () - startTime > 60000 ) {
432
- Log .v (TAG , "Partial flashing has timed out" );
433
- return PF_FAILED ;
434
- }
485
+ addrLo = hex .getRecordAddressFromIndex (magicIndex + lineCount );
486
+ addrHi = hex .getSegmentAddress (magicIndex + lineCount );
487
+ addr = (long ) addrLo + (long ) addrHi * 256 * 256 ;
435
488
436
- // Get next data to write
437
- hexData = hex .getDataFromIndex (magicIndex + lineCount );
489
+ hexData = hex .getDataFromIndex ( magicIndex + lineCount );
490
+ if ( part + 32 > hexData .length ()) {
491
+ partData = hexData .substring ( part );
492
+ } else {
493
+ partData = hexData .substring (part , part + 32 );
494
+ }
495
+ Log .v (TAG , partData );
496
+
497
+ // recordToByteArray() build a PF command block with the data
498
+ int offsetToSend = 0 ;
499
+ if (count == 0 ) {
500
+ offsetToSend = addrLo + part ;
501
+ } else if (count == 1 ) {
502
+ offsetToSend = addrHi ;
503
+ }
504
+ byte chunk [] = HexUtils .recordToByteArray (partData , offsetToSend , packetNum );
438
505
439
- Log .v (TAG , hexData );
506
+ // Write without response
507
+ // Wait for previous write to complete
508
+ boolean writeStatus = writePartialFlash (partialFlashCharacteristic , chunk );
440
509
441
- // Check if EOF
442
- if (hex .getRecordTypeFromIndex (magicIndex + lineCount ) != 0 ) break ;
510
+ if ( count == 0 )
511
+ {
512
+ line0 = lineCount ;
513
+ part0 = part ;
514
+ }
443
515
444
- // Split into bytes
445
- int offsetToSend = 0 ;
446
- if (count == 0 ) {
447
- offsetToSend = hex .getRecordAddressFromIndex (magicIndex + lineCount );
448
- }
516
+ // Sleep after 4 packets
517
+ count ++;
518
+ if ( count == 4 ){
519
+ count = 0 ;
449
520
450
- if (count == 1 ) {
451
- offsetToSend = hex .getSegmentAddress (magicIndex + lineCount );
452
- }
521
+ // Wait for notification
522
+ Log .v (TAG , "Wait for notification" );
453
523
454
- byte chunk [] = HexUtils .recordToByteArray (hexData , offsetToSend , packetNum );
455
-
456
- // Write without response
457
- // Wait for previous write to complete
458
- boolean writeStatus = writePartialFlash (partialFlashCharacteristic , chunk );
459
-
460
- // Sleep after 4 packets
461
- count ++;
462
- if (count == 4 ){
463
- count = 0 ;
464
-
465
- // Wait for notification
466
- Log .v (TAG , "Wait for notification" );
467
-
468
- // Send broadcast while waiting
469
- int percent = Math .round ((float )100 * ((float )(lineCount ) / (float )(numOfLines )));
470
- sendProgressBroadcast (percent );
471
-
472
- long timeout = SystemClock .elapsedRealtime ();
473
- while (packetState == PACKET_STATE_WAITING ) {
474
- synchronized (lock ) {
475
- lock .wait (5000 );
476
- }
524
+ // Send broadcast while waiting
525
+ int percent = Math .round ((float )100 * ((float )(lineCount ) / (float )(numOfLines )));
526
+ sendProgressBroadcast (percent );
477
527
478
- // Timeout if longer than 5 seconds
479
- if ((SystemClock .elapsedRealtime () - timeout ) > 5000 )return PF_FAILED ;
528
+ long timeout = SystemClock .elapsedRealtime ();
529
+ while (packetState == PACKET_STATE_WAITING ) {
530
+ synchronized (lock ) {
531
+ lock .wait (5000 );
480
532
}
481
533
482
- packetState = PACKET_STATE_WAITING ;
483
-
484
- Log .v (TAG , "/Wait for notification" );
485
-
486
- } else {
487
- Thread .sleep (5 );
534
+ // Timeout if longer than 5 seconds
535
+ if ((SystemClock .elapsedRealtime () - timeout ) > 5000 )
536
+ return PF_FAILED ;
488
537
}
489
538
490
- // If notification is retransmit -> retransmit last block.
491
- // Else set start of new block
492
- if (packetState == PACKET_STATE_RETRANSMIT ) {
493
- lineCount = lineCount - 4 ;
494
- } else {
495
- // Next line
496
- lineCount = lineCount + 1 ;
497
- }
539
+ packetState = PACKET_STATE_WAITING ;
498
540
499
- // Always increment packet #
500
- packetNum = packetNum + 1 ;
541
+ Log .v (TAG , "/Wait for notification" );
501
542
543
+ } else {
544
+ Thread .sleep (5 );
502
545
}
503
546
547
+ // If notification is retransmit -> retransmit last block.
548
+ // Else set start of new block
549
+ if (packetState == PACKET_STATE_RETRANSMIT ) {
550
+ lineCount = line0 ;
551
+ part = part0 ;
552
+ } else {
553
+ // Next part
554
+ part = part + partData .length ();
555
+ if ( part >= hexData .length ()) {
556
+ part = 0 ;
557
+ lineCount = lineCount + 1 ;
558
+ }
559
+ }
504
560
505
-
506
- // Write End of Flash packet
507
- byte [] endOfFlashPacket = {(byte )0x02 };
508
- writePartialFlash (partialFlashCharacteristic , endOfFlashPacket );
509
-
510
- // Finished Writing
511
- Log .v (TAG , "Flash Complete" );
512
- packetState = PACKET_STATE_COMPLETE_FLASH ;
513
- sendProgressBroadcast (100 );
514
- sendProgressBroadcastComplete ();
515
-
516
- // Time execution
517
- long endTime = SystemClock .elapsedRealtime ();
518
- long elapsedMilliSeconds = endTime - startTime ;
519
- double elapsedSeconds = elapsedMilliSeconds / 1000.0 ;
520
- Log .v (TAG , "Flash Time: " + Float .toString ((float )elapsedSeconds ) + " seconds" );
521
-
522
- } else {
523
- return PF_ATTEMPT_DFU ;
561
+ // Always increment packet #
562
+ packetNum = packetNum + 1 ;
524
563
}
564
+
565
+ // Write End of Flash packet
566
+ byte [] endOfFlashPacket = {(byte )0x02 };
567
+ writePartialFlash (partialFlashCharacteristic , endOfFlashPacket );
568
+
569
+ // Finished Writing
570
+ Log .v (TAG , "Flash Complete" );
571
+ packetState = PACKET_STATE_COMPLETE_FLASH ;
572
+ sendProgressBroadcast (100 );
573
+ sendProgressBroadcastComplete ();
574
+
575
+ // Time execution
576
+ long endTime = SystemClock .elapsedRealtime ();
577
+ long elapsedMilliSeconds = endTime - startTime ;
578
+ double elapsedSeconds = elapsedMilliSeconds / 1000.0 ;
579
+ Log .v (TAG , "Flash Time: " + Float .toString ((float )elapsedSeconds ) + " seconds" );
525
580
} catch (IOException e ) {
526
581
e .printStackTrace ();
527
582
} catch (InterruptedException e ) {
0 commit comments