@microbit/microbit-connection 0.1.0 → 0.9.0-apps.alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (148) hide show
  1. package/README.md +4 -4
  2. package/build/cjs/accelerometer-service.d.ts +5 -5
  3. package/build/cjs/accelerometer-service.js +41 -42
  4. package/build/cjs/accelerometer-service.js.map +1 -1
  5. package/build/cjs/async-util.d.ts +9 -0
  6. package/build/cjs/async-util.js +27 -7
  7. package/build/cjs/async-util.js.map +1 -1
  8. package/build/cjs/bluetooth-device-wrapper.d.ts +61 -27
  9. package/build/cjs/bluetooth-device-wrapper.js +285 -266
  10. package/build/cjs/bluetooth-device-wrapper.js.map +1 -1
  11. package/build/cjs/bluetooth-profile.d.ts +43 -35
  12. package/build/cjs/bluetooth-profile.js +35 -29
  13. package/build/cjs/bluetooth-profile.js.map +1 -1
  14. package/build/cjs/bluetooth.d.ts +10 -6
  15. package/build/cjs/bluetooth.js +286 -100
  16. package/build/cjs/bluetooth.js.map +1 -1
  17. package/build/cjs/button-service.d.ts +5 -5
  18. package/build/cjs/button-service.js +31 -45
  19. package/build/cjs/button-service.js.map +1 -1
  20. package/build/cjs/device-information-service.d.ts +6 -0
  21. package/build/cjs/device-information-service.js +34 -0
  22. package/build/cjs/device-information-service.js.map +1 -0
  23. package/build/cjs/device.d.ts +65 -8
  24. package/build/cjs/device.js +16 -2
  25. package/build/cjs/device.js.map +1 -1
  26. package/build/cjs/dfu-service.d.ts +9 -0
  27. package/build/cjs/dfu-service.js +26 -0
  28. package/build/cjs/dfu-service.js.map +1 -0
  29. package/build/cjs/flashing/flashing-full.d.ts +14 -0
  30. package/build/cjs/flashing/flashing-full.js +87 -0
  31. package/build/cjs/flashing/flashing-full.js.map +1 -0
  32. package/build/cjs/flashing/flashing-makecode.d.ts +6 -0
  33. package/build/cjs/flashing/flashing-makecode.js +48 -0
  34. package/build/cjs/flashing/flashing-makecode.js.map +1 -0
  35. package/build/cjs/flashing/flashing-partial.d.ts +9 -0
  36. package/build/cjs/flashing/flashing-partial.js +98 -0
  37. package/build/cjs/flashing/flashing-partial.js.map +1 -0
  38. package/build/cjs/flashing/flashing-v1.d.ts +11 -0
  39. package/build/cjs/flashing/flashing-v1.js +24 -0
  40. package/build/cjs/flashing/flashing-v1.js.map +1 -0
  41. package/build/cjs/flashing/nordic-dfu.d.ts +3 -0
  42. package/build/cjs/flashing/nordic-dfu.js +214 -0
  43. package/build/cjs/flashing/nordic-dfu.js.map +1 -0
  44. package/build/cjs/flashing/zip.d.ts +12 -0
  45. package/build/cjs/flashing/zip.js +177 -0
  46. package/build/cjs/flashing/zip.js.map +1 -0
  47. package/build/cjs/index.d.ts +3 -3
  48. package/build/cjs/index.js +2 -1
  49. package/build/cjs/index.js.map +1 -1
  50. package/build/cjs/led-service.d.ts +5 -7
  51. package/build/cjs/led-service.js +13 -44
  52. package/build/cjs/led-service.js.map +1 -1
  53. package/build/cjs/logging.d.ts +1 -1
  54. package/build/cjs/logging.js +3 -3
  55. package/build/cjs/logging.js.map +1 -1
  56. package/build/cjs/magnetometer-service.d.ts +5 -9
  57. package/build/cjs/magnetometer-service.js +30 -65
  58. package/build/cjs/magnetometer-service.js.map +1 -1
  59. package/build/cjs/partial-flashing-service.d.ts +45 -0
  60. package/build/cjs/partial-flashing-service.js +110 -0
  61. package/build/cjs/partial-flashing-service.js.map +1 -0
  62. package/build/cjs/uart-service.d.ts +4 -5
  63. package/build/cjs/uart-service.js +19 -40
  64. package/build/cjs/uart-service.js.map +1 -1
  65. package/build/cjs/usb-device-wrapper.js +33 -8
  66. package/build/cjs/usb-device-wrapper.js.map +1 -1
  67. package/build/cjs/usb-partial-flashing.d.ts +1 -3
  68. package/build/cjs/usb-partial-flashing.js +4 -3
  69. package/build/cjs/usb-partial-flashing.js.map +1 -1
  70. package/build/cjs/usb-radio-bridge.js +1 -2
  71. package/build/cjs/usb-radio-bridge.js.map +1 -1
  72. package/build/cjs/usb.d.ts +4 -2
  73. package/build/cjs/usb.js +31 -16
  74. package/build/cjs/usb.js.map +1 -1
  75. package/build/esm/accelerometer-service.d.ts +5 -5
  76. package/build/esm/accelerometer-service.js +42 -43
  77. package/build/esm/accelerometer-service.js.map +1 -1
  78. package/build/esm/async-util.d.ts +9 -0
  79. package/build/esm/async-util.js +22 -6
  80. package/build/esm/async-util.js.map +1 -1
  81. package/build/esm/bluetooth-device-wrapper.d.ts +61 -27
  82. package/build/esm/bluetooth-device-wrapper.js +284 -265
  83. package/build/esm/bluetooth-device-wrapper.js.map +1 -1
  84. package/build/esm/bluetooth-profile.d.ts +43 -35
  85. package/build/esm/bluetooth-profile.js +35 -29
  86. package/build/esm/bluetooth-profile.js.map +1 -1
  87. package/build/esm/bluetooth.d.ts +10 -6
  88. package/build/esm/bluetooth.js +263 -103
  89. package/build/esm/bluetooth.js.map +1 -1
  90. package/build/esm/button-service.d.ts +5 -5
  91. package/build/esm/button-service.js +32 -46
  92. package/build/esm/button-service.js.map +1 -1
  93. package/build/esm/device-information-service.d.ts +6 -0
  94. package/build/esm/device-information-service.js +30 -0
  95. package/build/esm/device-information-service.js.map +1 -0
  96. package/build/esm/device.d.ts +65 -8
  97. package/build/esm/device.js +15 -1
  98. package/build/esm/device.js.map +1 -1
  99. package/build/esm/dfu-service.d.ts +9 -0
  100. package/build/esm/dfu-service.js +22 -0
  101. package/build/esm/dfu-service.js.map +1 -0
  102. package/build/esm/flashing/flashing-full.d.ts +14 -0
  103. package/build/esm/flashing/flashing-full.js +84 -0
  104. package/build/esm/flashing/flashing-full.js.map +1 -0
  105. package/build/esm/flashing/flashing-makecode.d.ts +6 -0
  106. package/build/esm/flashing/flashing-makecode.js +44 -0
  107. package/build/esm/flashing/flashing-makecode.js.map +1 -0
  108. package/build/esm/flashing/flashing-partial.d.ts +9 -0
  109. package/build/esm/flashing/flashing-partial.js +95 -0
  110. package/build/esm/flashing/flashing-partial.js.map +1 -0
  111. package/build/esm/flashing/flashing-v1.d.ts +11 -0
  112. package/build/esm/flashing/flashing-v1.js +20 -0
  113. package/build/esm/flashing/flashing-v1.js.map +1 -0
  114. package/build/esm/flashing/nordic-dfu.d.ts +3 -0
  115. package/build/esm/flashing/nordic-dfu.js +211 -0
  116. package/build/esm/flashing/nordic-dfu.js.map +1 -0
  117. package/build/esm/flashing/zip.d.ts +12 -0
  118. package/build/esm/flashing/zip.js +174 -0
  119. package/build/esm/flashing/zip.js.map +1 -0
  120. package/build/esm/index.d.ts +3 -3
  121. package/build/esm/index.js +2 -2
  122. package/build/esm/index.js.map +1 -1
  123. package/build/esm/led-service.d.ts +5 -7
  124. package/build/esm/led-service.js +13 -44
  125. package/build/esm/led-service.js.map +1 -1
  126. package/build/esm/logging.d.ts +1 -1
  127. package/build/esm/logging.js +1 -1
  128. package/build/esm/logging.js.map +1 -1
  129. package/build/esm/magnetometer-service.d.ts +5 -9
  130. package/build/esm/magnetometer-service.js +31 -66
  131. package/build/esm/magnetometer-service.js.map +1 -1
  132. package/build/esm/partial-flashing-service.d.ts +45 -0
  133. package/build/esm/partial-flashing-service.js +106 -0
  134. package/build/esm/partial-flashing-service.js.map +1 -0
  135. package/build/esm/uart-service.d.ts +4 -5
  136. package/build/esm/uart-service.js +19 -40
  137. package/build/esm/uart-service.js.map +1 -1
  138. package/build/esm/usb-device-wrapper.js +33 -8
  139. package/build/esm/usb-device-wrapper.js.map +1 -1
  140. package/build/esm/usb-partial-flashing.d.ts +1 -3
  141. package/build/esm/usb-partial-flashing.js +4 -3
  142. package/build/esm/usb-partial-flashing.js.map +1 -1
  143. package/build/esm/usb-radio-bridge.js +2 -3
  144. package/build/esm/usb-radio-bridge.js.map +1 -1
  145. package/build/esm/usb.d.ts +4 -2
  146. package/build/esm/usb.js +33 -18
  147. package/build/esm/usb.js.map +1 -1
  148. package/package.json +7 -3
@@ -0,0 +1,30 @@
1
+ import { BleClient } from "@capacitor-community/bluetooth-le";
2
+ import { profile } from "./bluetooth-profile.js";
3
+ export class DeviceInformationService {
4
+ constructor(deviceId) {
5
+ Object.defineProperty(this, "deviceId", {
6
+ enumerable: true,
7
+ configurable: true,
8
+ writable: true,
9
+ value: deviceId
10
+ });
11
+ }
12
+ async getBoardVersion() {
13
+ const serviceMeta = profile.deviceInformation;
14
+ try {
15
+ const modelNumberBytes = await BleClient.read(this.deviceId, serviceMeta.id, serviceMeta.characteristics.modelNumber.id);
16
+ const modelNumber = new TextDecoder().decode(modelNumberBytes);
17
+ if (modelNumber.toLowerCase() === "BBC micro:bit".toLowerCase()) {
18
+ return "V1";
19
+ }
20
+ if (modelNumber.toLowerCase().includes("BBC micro:bit v2".toLowerCase())) {
21
+ return "V2";
22
+ }
23
+ throw new Error(`Unexpected model number ${modelNumber}`);
24
+ }
25
+ catch (e) {
26
+ throw new Error(`Could not read model number: ${e instanceof Error ? e.message : e}`);
27
+ }
28
+ }
29
+ }
30
+ //# sourceMappingURL=device-information-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-information-service.js","sourceRoot":"","sources":["../../lib/device-information-service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAE9D,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,MAAM,OAAO,wBAAwB;IACnC,YAAoB,QAAgB;QAAxB;;;;mBAAQ,QAAQ;WAAQ;IAAG,CAAC;IAExC,KAAK,CAAC,eAAe;QACnB,MAAM,WAAW,GAAG,OAAO,CAAC,iBAAiB,CAAC;QAC9C,IAAI,CAAC;YACH,MAAM,gBAAgB,GAAG,MAAM,SAAS,CAAC,IAAI,CAC3C,IAAI,CAAC,QAAQ,EACb,WAAW,CAAC,EAAE,EACd,WAAW,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAC3C,CAAC;YACF,MAAM,WAAW,GAAG,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAC;YAC/D,IAAI,WAAW,CAAC,WAAW,EAAE,KAAK,eAAe,CAAC,WAAW,EAAE,EAAE,CAAC;gBAChE,OAAO,IAAI,CAAC;YACd,CAAC;YACD,IACE,WAAW,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,kBAAkB,CAAC,WAAW,EAAE,CAAC,EACpE,CAAC;gBACD,OAAO,IAAI,CAAC;YACd,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,2BAA2B,WAAW,EAAE,CAAC,CAAC;QAC5D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CACb,gCAAgC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CACrE,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -41,7 +41,56 @@ export type DeviceErrorCode =
41
41
  /**
42
42
  * Bluetooth service is missing on device.
43
43
  */
44
- | "service-missing";
44
+ | "service-missing"
45
+ /**
46
+ * Failed to establish Bluetooth connection.
47
+ */
48
+ | "bluetooth-connection-failed"
49
+ /**
50
+ * Bluetooth is disabled on the device.
51
+ */
52
+ | "bluetooth-disabled"
53
+ /**
54
+ * Missing required Bluetooth permissions.
55
+ */
56
+ | "bluetooth-missing-permissions"
57
+ /**
58
+ * Partial flash operation failed.
59
+ */
60
+ | "flash-partial-failed"
61
+ /**
62
+ * Full flash operation failed.
63
+ */
64
+ | "flash-full-failed"
65
+ /**
66
+ * Flash operation was cancelled.
67
+ */
68
+ | "flash-cancelled";
69
+ export declare enum ProgressStage {
70
+ Initializing = "Initializing",
71
+ FindingDevice = "FindingDevice",
72
+ Connecting = "Connecting",
73
+ PartialFlashing = "PartialFlashing",
74
+ FullFlashing = "FullFlashing"
75
+ }
76
+ /**
77
+ * Progress callback for tracking operation stages (connection and flashing).
78
+ *
79
+ * @param stage - The current stage of the operation
80
+ * @param progress - Optional progress value (0-1) for PartialFlashing and FullFlashing stages.
81
+ * Initializing, FindingDevice, and Connecting stages are called once
82
+ * without progress values to indicate stage entry.
83
+ *
84
+ * @example
85
+ * const progressCallback = (stage, progress) => {
86
+ * if (progress !== undefined) {
87
+ * console.log(`${stage}: ${Math.round(progress * 100)}%`);
88
+ * } else {
89
+ * console.log(`Stage: ${stage}`);
90
+ * }
91
+ * };
92
+ */
93
+ export type ProgressCallback = (stage: ProgressStage, progress?: number) => void;
45
94
  /**
46
95
  * Error type used for all interactions with this module.
47
96
  *
@@ -96,19 +145,26 @@ export declare enum ConnectionStatus {
96
145
  */
97
146
  RECONNECTING = "RECONNECTING"
98
147
  }
148
+ export interface ConnectOptions {
149
+ /**
150
+ * Optional progress callback for tracking connection stages.
151
+ */
152
+ progress?: ProgressCallback;
153
+ }
99
154
  export interface FlashOptions {
100
155
  /**
101
156
  * True to use a partial flash where possible, false to force a full flash.
157
+ * Default: true.
102
158
  */
103
- partial: boolean;
159
+ partial?: boolean;
104
160
  /**
105
- * A progress callback. Called with undefined when the process is complete or has failed.
161
+ * Optional progress callback for tracking connection and flash stages.
106
162
  *
107
163
  * Requesting a partial flash doesn't guarantee one is performed. Partial flashes are avoided
108
164
  * if too many blocks have changed and failed partial flashes are retried as full flashes.
109
165
  * The partial parameter reports the flash type currently in progress.
110
166
  */
111
- progress: (percentage: number | undefined, partial: boolean) => void;
167
+ progress?: ProgressCallback;
112
168
  /**
113
169
  * Smallest possible progress increment to limit callback rate.
114
170
  */
@@ -130,7 +186,8 @@ export declare class AfterRequestDevice extends Event {
130
186
  }
131
187
  export declare class BackgroundErrorEvent extends Event {
132
188
  readonly errorMessage: string;
133
- constructor(errorMessage: string);
189
+ readonly error?: unknown | undefined;
190
+ constructor(errorMessage: string, error?: unknown | undefined);
134
191
  }
135
192
  export declare class DeviceConnectionEventMap {
136
193
  "status": ConnectionStatusEvent;
@@ -150,11 +207,11 @@ export interface DeviceConnection<M extends ValueIsEvent<M>> extends TypedEventT
150
207
  dispose(): void;
151
208
  /**
152
209
  * Connects to a currently paired device or requests pairing.
153
- * Throws on error.
154
210
  *
155
- * @returns the final connection status.
211
+ * @param options Optional connection options including progress callback.
212
+ * @throws {DeviceError} On connection failure. The error.code property indicates the failure type.
156
213
  */
157
- connect(): Promise<ConnectionStatus>;
214
+ connect(options?: ConnectOptions): Promise<void>;
158
215
  /**
159
216
  * Get the board version.
160
217
  *
@@ -1,3 +1,11 @@
1
+ export var ProgressStage;
2
+ (function (ProgressStage) {
3
+ ProgressStage["Initializing"] = "Initializing";
4
+ ProgressStage["FindingDevice"] = "FindingDevice";
5
+ ProgressStage["Connecting"] = "Connecting";
6
+ ProgressStage["PartialFlashing"] = "PartialFlashing";
7
+ ProgressStage["FullFlashing"] = "FullFlashing";
8
+ })(ProgressStage || (ProgressStage = {}));
1
9
  /**
2
10
  * Error type used for all interactions with this module.
3
11
  *
@@ -82,7 +90,7 @@ export class AfterRequestDevice extends Event {
82
90
  }
83
91
  }
84
92
  export class BackgroundErrorEvent extends Event {
85
- constructor(errorMessage) {
93
+ constructor(errorMessage, error) {
86
94
  super("backgrounderror");
87
95
  Object.defineProperty(this, "errorMessage", {
88
96
  enumerable: true,
@@ -90,6 +98,12 @@ export class BackgroundErrorEvent extends Event {
90
98
  writable: true,
91
99
  value: errorMessage
92
100
  });
101
+ Object.defineProperty(this, "error", {
102
+ enumerable: true,
103
+ configurable: true,
104
+ writable: true,
105
+ value: error
106
+ });
93
107
  }
94
108
  }
95
109
  export class DeviceConnectionEventMap {
@@ -1 +1 @@
1
- {"version":3,"file":"device.js","sourceRoot":"","sources":["../../lib/device.ts"],"names":[],"mappings":"AA8CA;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAEpC,YAAY,EAAE,IAAI,EAAE,OAAO,EAA+C;QACxE,KAAK,CAAC,OAAO,CAAC,CAAC;QAFjB;;;;;WAAsB;QAGpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,gBAkCX;AAlCD,WAAY,gBAAgB;IAC1B;;;OAGG;IACH,2DAAuC,CAAA;IACvC;;OAEG;IACH,mDAA+B,CAAA;IAC/B;;;;;OAKG;IACH,iEAA6C,CAAA;IAC7C;;OAEG;IACH,iDAA6B,CAAA;IAC7B;;OAEG;IACH,2CAAuB,CAAA;IACvB;;OAEG;IACH,6CAAyB,CAAA;IACzB;;;OAGG;IACH,iDAA6B,CAAA;AAC/B,CAAC,EAlCW,gBAAgB,KAAhB,gBAAgB,QAkC3B;AAqBD,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAQ5C,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAA4B,MAAwB;QAClD,KAAK,CAAC,QAAQ,CAAC,CAAC;QADN;;;;mBAAgB,MAAM;WAAkB;IAEpD,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YAA4B,YAAoB;QAC9C,KAAK,CAAC,iBAAiB,CAAC,CAAC;QADf;;;;mBAAgB,YAAY;WAAQ;IAEhD,CAAC;CACF;AAED,MAAM,OAAO,wBAAwB;IAArC;QACE,4BAAA,QAAQ;;;;;WAAwB;QAChC,4BAAA,iBAAiB;;;;;WAAuB;QACxC,4BAAA,qBAAqB;;;;;WAAQ;QAC7B,4BAAA,oBAAoB;;;;;WAAQ;IAC9B,CAAC;CAAA"}
1
+ {"version":3,"file":"device.js","sourceRoot":"","sources":["../../lib/device.ts"],"names":[],"mappings":"AAsEA,MAAM,CAAN,IAAY,aAMX;AAND,WAAY,aAAa;IACvB,8CAA6B,CAAA;IAC7B,gDAA+B,CAAA;IAC/B,0CAAyB,CAAA;IACzB,oDAAmC,CAAA;IACnC,8CAA6B,CAAA;AAC/B,CAAC,EANW,aAAa,KAAb,aAAa,QAMxB;AAwBD;;;;;;;;GAQG;AACH,MAAM,OAAO,WAAY,SAAQ,KAAK;IAEpC,YAAY,EAAE,IAAI,EAAE,OAAO,EAA+C;QACxE,KAAK,CAAC,OAAO,CAAC,CAAC;QAFjB;;;;;WAAsB;QAGpB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;CACF;AAED;;GAEG;AACH,MAAM,CAAN,IAAY,gBAkCX;AAlCD,WAAY,gBAAgB;IAC1B;;;OAGG;IACH,2DAAuC,CAAA;IACvC;;OAEG;IACH,mDAA+B,CAAA;IAC/B;;;;;OAKG;IACH,iEAA6C,CAAA;IAC7C;;OAEG;IACH,iDAA6B,CAAA;IAC7B;;OAEG;IACH,2CAAuB,CAAA;IACvB;;OAEG;IACH,6CAAyB,CAAA;IACzB;;;OAGG;IACH,iDAA6B,CAAA;AAC/B,CAAC,EAlCW,gBAAgB,KAAhB,gBAAgB,QAkC3B;AA6BD,MAAM,OAAO,cAAe,SAAQ,KAAK;CAAG;AAQ5C,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IAC9C,YAA4B,MAAwB;QAClD,KAAK,CAAC,QAAQ,CAAC,CAAC;QADN;;;;mBAAgB,MAAM;WAAkB;IAEpD,CAAC;CACF;AAED,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C;QACE,KAAK,CAAC,qBAAqB,CAAC,CAAC;IAC/B,CAAC;CACF;AAED,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAC3C;QACE,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC9B,CAAC;CACF;AAED,MAAM,OAAO,oBAAqB,SAAQ,KAAK;IAC7C,YACkB,YAAoB,EACpB,KAAe;QAE/B,KAAK,CAAC,iBAAiB,CAAC,CAAC;QAHzB;;;;mBAAgB,YAAY;WAAQ;QACpC;;;;mBAAgB,KAAK;WAAU;IAGjC,CAAC;CACF;AAED,MAAM,OAAO,wBAAwB;IAArC;QACE,4BAAA,QAAQ;;;;;WAAwB;QAChC,4BAAA,iBAAiB;;;;;WAAuB;QACxC,4BAAA,qBAAqB;;;;;WAAQ;QAC7B,4BAAA,oBAAoB;;;;;WAAQ;IAC9B,CAAC;CAAA"}
@@ -0,0 +1,9 @@
1
+ export declare const NORDIC_DFU_SERVICE = "00001530-1212-EFDE-1523-785FEABCD123";
2
+ export declare class DfuService {
3
+ private deviceId;
4
+ constructor(deviceId: string);
5
+ /**
6
+ * We do this for V1 only.
7
+ */
8
+ requestRebootToBootloader(): Promise<void>;
9
+ }
@@ -0,0 +1,22 @@
1
+ import { BleClient, numbersToDataView, } from "@capacitor-community/bluetooth-le";
2
+ import { profile } from "./bluetooth-profile.js";
3
+ // This is the service that should be available on V1 after the reboot.
4
+ // We don't use it directly (the Nordic DFU library does) but we check it's there.
5
+ export const NORDIC_DFU_SERVICE = "00001530-1212-EFDE-1523-785FEABCD123";
6
+ export class DfuService {
7
+ constructor(deviceId) {
8
+ Object.defineProperty(this, "deviceId", {
9
+ enumerable: true,
10
+ configurable: true,
11
+ writable: true,
12
+ value: deviceId
13
+ });
14
+ }
15
+ /**
16
+ * We do this for V1 only.
17
+ */
18
+ async requestRebootToBootloader() {
19
+ await BleClient.write(this.deviceId, profile.dfuControl.id, profile.dfuControl.characteristics.control.id, numbersToDataView([0x01]));
20
+ }
21
+ }
22
+ //# sourceMappingURL=dfu-service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dfu-service.js","sourceRoot":"","sources":["../../lib/dfu-service.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,SAAS,EACT,iBAAiB,GAClB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAEjD,uEAAuE;AACvE,kFAAkF;AAClF,MAAM,CAAC,MAAM,kBAAkB,GAAG,sCAAsC,CAAC;AAEzE,MAAM,OAAO,UAAU;IACrB,YAAoB,QAAgB;QAAxB;;;;mBAAQ,QAAQ;WAAQ;IAAG,CAAC;IAExC;;OAEG;IACH,KAAK,CAAC,yBAAyB;QAC7B,MAAM,SAAS,CAAC,KAAK,CACnB,IAAI,CAAC,QAAQ,EACb,OAAO,CAAC,UAAU,CAAC,EAAE,EACrB,OAAO,CAAC,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,EAAE,EAC7C,iBAAiB,CAAC,CAAC,IAAI,CAAC,CAAC,CAC1B,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,14 @@
1
+ import MemoryMap from "nrf-intel-hex";
2
+ import { BoardVersion, ProgressCallback } from "../device.js";
3
+ import { BluetoothDeviceWrapper } from "../bluetooth-device-wrapper.js";
4
+ /**
5
+ * Perform a full flash via Nordic's DFU service.
6
+ *
7
+ * The connection is closed before handing off to Nordic's service which will
8
+ * connect again.
9
+ *
10
+ * The device is assumed to be bonded.
11
+ *
12
+ * @throws {DeviceError} On flash failure.
13
+ */
14
+ export declare function fullFlash(connection: BluetoothDeviceWrapper, boardVersion: BoardVersion, memoryMap: MemoryMap, progress: ProgressCallback): Promise<void>;
@@ -0,0 +1,84 @@
1
+ import { DeviceError, FlashDataError, ProgressStage, } from "../device.js";
2
+ import { DfuService, NORDIC_DFU_SERVICE } from "../dfu-service.js";
3
+ import { refreshServicesForV1IfDesiredServiceMissing } from "./flashing-v1.js";
4
+ import { flashDfu } from "./nordic-dfu.js";
5
+ import { delay } from "../async-util.js";
6
+ /**
7
+ * Perform a full flash via Nordic's DFU service.
8
+ *
9
+ * The connection is closed before handing off to Nordic's service which will
10
+ * connect again.
11
+ *
12
+ * The device is assumed to be bonded.
13
+ *
14
+ * @throws {DeviceError} On flash failure.
15
+ */
16
+ export async function fullFlash(connection, boardVersion, memoryMap, progress) {
17
+ connection.log("Full flash");
18
+ progress(ProgressStage.FullFlashing);
19
+ const { deviceId } = connection.device;
20
+ try {
21
+ if (boardVersion === "V1") {
22
+ connection.log("Rebooting V1 to bootloader");
23
+ const dfuService = new DfuService(deviceId);
24
+ try {
25
+ await dfuService.requestRebootToBootloader();
26
+ }
27
+ catch (e) {
28
+ connection.error("Failed to request reboot to bootloader", e);
29
+ throw new DeviceError({
30
+ code: "flash-full-failed",
31
+ message: e instanceof Error ? e.message : "Failed to reboot to bootloader",
32
+ });
33
+ }
34
+ // Wait for device to automatically disconnect as it reboots into bootloader
35
+ connection.log("Waiting for device to reboot and disconnect");
36
+ try {
37
+ await connection.waitForDisconnect(3000);
38
+ }
39
+ catch {
40
+ connection.log("Device did not disconnect automatically, disconnecting manually");
41
+ await connection.disconnect();
42
+ }
43
+ // Give device time to disconnect and reboot into bootloader mode
44
+ await delay(2500);
45
+ // Reconnect to device now in bootloader mode
46
+ progress(ProgressStage.Connecting);
47
+ await connection.connect();
48
+ await refreshServicesForV1IfDesiredServiceMissing(deviceId, NORDIC_DFU_SERVICE);
49
+ }
50
+ }
51
+ finally {
52
+ // The Nordic code opens its own connection.
53
+ await connection.disconnect();
54
+ // If we've previously been connected, maybe this helps???
55
+ await delay(3000);
56
+ }
57
+ const appBin = createAppBin(memoryMap, boardVersion);
58
+ if (appBin === null) {
59
+ connection.log("Invalid hex (app bin case)");
60
+ throw new FlashDataError("Invalid hex data: could not extract app binary");
61
+ }
62
+ connection.log(`Extracted app bin: ${appBin.length} bytes`);
63
+ await flashDfu(connection, boardVersion, appBin, progress);
64
+ }
65
+ const createAppBin = (memoryMap, boardVersion) => {
66
+ const appRegionBoundaries = {
67
+ V1: { start: 0x18000, end: 0x3c000 },
68
+ V2: { start: 0x1c000, end: 0x77000 },
69
+ }[boardVersion];
70
+ // Calculate data size within the app region
71
+ let maxAddress = appRegionBoundaries.start;
72
+ for (const [blockAddr, block] of memoryMap) {
73
+ const blockEnd = blockAddr + block.length;
74
+ if (blockEnd > appRegionBoundaries.start &&
75
+ blockAddr < appRegionBoundaries.end) {
76
+ maxAddress = Math.max(maxAddress, Math.min(blockEnd, appRegionBoundaries.end));
77
+ }
78
+ }
79
+ let size = maxAddress - appRegionBoundaries.start;
80
+ // 4-byte alignment required by DFU
81
+ size = Math.ceil(size / 4) * 4;
82
+ return memoryMap.slicePad(appRegionBoundaries.start, size);
83
+ };
84
+ //# sourceMappingURL=flashing-full.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flashing-full.js","sourceRoot":"","sources":["../../../lib/flashing/flashing-full.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import MemoryMap from "nrf-intel-hex";
2
+ import { RegionInfo } from "../partial-flashing-service";
3
+ /**
4
+ * Find the MakeCode code region in a MemoryMap (typically from a hex file).
5
+ */
6
+ export declare const findMakeCodeRegionInMemoryMap: (memoryMap: MemoryMap, deviceCodeRegion: RegionInfo) => RegionInfo | null;
@@ -0,0 +1,44 @@
1
+ const PXT_MAGIC_HEX = "708E3B92C615A841C49866C975EE5197";
2
+ /**
3
+ * Find the MakeCode code region in a MemoryMap (typically from a hex file).
4
+ */
5
+ export const findMakeCodeRegionInMemoryMap = (memoryMap, deviceCodeRegion) => {
6
+ for (const [blockAddr, block] of memoryMap) {
7
+ const offset = findByteSequence(block, PXT_MAGIC_HEX);
8
+ if (offset >= 0) {
9
+ const start = blockAddr + offset;
10
+ const hashOffset = start + PXT_MAGIC_HEX.length / 2;
11
+ const hashBytes = memoryMap.slicePad(hashOffset, 8);
12
+ const hash = bytesToHex(hashBytes);
13
+ // Find the highest address with data in the memory map within the code region
14
+ let end = start;
15
+ for (const [blockAddr, block] of memoryMap) {
16
+ const blockEnd = blockAddr + block.length;
17
+ if (blockEnd > start && blockAddr < deviceCodeRegion.end) {
18
+ end = Math.max(end, Math.min(blockEnd, deviceCodeRegion.end));
19
+ }
20
+ }
21
+ // Round up to next 64-byte boundary
22
+ end = Math.ceil(end / 64) * 64;
23
+ return { start, end, hash };
24
+ }
25
+ }
26
+ return null;
27
+ };
28
+ const bytesToHex = (bytes) => {
29
+ return Array.from(bytes)
30
+ .map((byte) => byte.toString(16).padStart(2, "0").toUpperCase())
31
+ .join("");
32
+ };
33
+ function findByteSequence(data, hexTarget) {
34
+ const target = new Uint8Array(hexTarget.match(/.{1,2}/g).map((byte) => parseInt(byte, 16)));
35
+ outer: for (let i = 0; i <= data.length - target.length; i++) {
36
+ for (let j = 0; j < target.length; j++) {
37
+ if (data[i + j] !== target[j])
38
+ continue outer;
39
+ }
40
+ return i;
41
+ }
42
+ return -1;
43
+ }
44
+ //# sourceMappingURL=flashing-makecode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flashing-makecode.js","sourceRoot":"","sources":["../../../lib/flashing/flashing-makecode.ts"],"names":[],"mappings":"AAGA,MAAM,aAAa,GAAG,kCAAkC,CAAC;AAEzD;;GAEG;AACH,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,SAAoB,EACpB,gBAA4B,EACT,EAAE;IACrB,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;QAC3C,MAAM,MAAM,GAAG,gBAAgB,CAAC,KAAK,EAAE,aAAa,CAAC,CAAC;QACtD,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;YAChB,MAAM,KAAK,GAAG,SAAS,GAAG,MAAM,CAAC;YACjC,MAAM,UAAU,GAAG,KAAK,GAAG,aAAa,CAAC,MAAM,GAAG,CAAC,CAAC;YACpD,MAAM,SAAS,GAAG,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;YACpD,MAAM,IAAI,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;YAEnC,8EAA8E;YAC9E,IAAI,GAAG,GAAG,KAAK,CAAC;YAChB,KAAK,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;gBAC3C,MAAM,QAAQ,GAAG,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC;gBAC1C,IAAI,QAAQ,GAAG,KAAK,IAAI,SAAS,GAAG,gBAAgB,CAAC,GAAG,EAAE,CAAC;oBACzD,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,gBAAgB,CAAC,GAAG,CAAC,CAAC,CAAC;gBAChE,CAAC;YACH,CAAC;YACD,oCAAoC;YACpC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;YAE/B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAEF,MAAM,UAAU,GAAG,CAAC,KAAiB,EAAU,EAAE;IAC/C,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC;SACrB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,WAAW,EAAE,CAAC;SAC/D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC,CAAC;AAEF,SAAS,gBAAgB,CAAC,IAAgB,EAAE,SAAiB;IAC3D,MAAM,MAAM,GAAG,IAAI,UAAU,CAC3B,SAAS,CAAC,KAAK,CAAC,SAAS,CAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAC9D,CAAC;IAEF,KAAK,EAAE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC7D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,CAAC;gBAAE,SAAS,KAAK,CAAC;QAChD,CAAC;QACD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,OAAO,CAAC,CAAC,CAAC;AACZ,CAAC"}
@@ -0,0 +1,9 @@
1
+ import MemoryMap from "nrf-intel-hex";
2
+ import { BluetoothDeviceWrapper } from "../bluetooth-device-wrapper.js";
3
+ import { ProgressCallback } from "../device.js";
4
+ export declare enum PartialFlashResult {
5
+ Success = "Success",
6
+ AttemptFullFlash = "AttemptFullFlash"
7
+ }
8
+ declare const partialFlash: (connection: BluetoothDeviceWrapper, memoryMap: MemoryMap, progress: ProgressCallback) => Promise<PartialFlashResult>;
9
+ export default partialFlash;
@@ -0,0 +1,95 @@
1
+ import { PacketState, PartialFlashingService, RegionId, } from "../partial-flashing-service.js";
2
+ import { findMakeCodeRegionInMemoryMap } from "./flashing-makecode.js";
3
+ import { delay, DisconnectError } from "../async-util.js";
4
+ import { DeviceError, ProgressStage } from "../device.js";
5
+ export var PartialFlashResult;
6
+ (function (PartialFlashResult) {
7
+ PartialFlashResult["Success"] = "Success";
8
+ PartialFlashResult["AttemptFullFlash"] = "AttemptFullFlash";
9
+ })(PartialFlashResult || (PartialFlashResult = {}));
10
+ const partialFlash = async (connection, memoryMap, progress) => {
11
+ const pf = new PartialFlashingService(connection);
12
+ await pf.startNotifications();
13
+ const result = await connection.raceDisconnectAndTimeout(partialFlashInternal(connection, pf, memoryMap, progress), { timeout: 30_000, actionName: "partial flash" });
14
+ try {
15
+ await pf.stopNotifications();
16
+ }
17
+ catch (e) {
18
+ // V1 disconnects quickly after a partial flash.
19
+ if (!(e instanceof DisconnectError)) {
20
+ connection.error("Error stopping notifications", e);
21
+ }
22
+ }
23
+ return result;
24
+ };
25
+ const partialFlashInternal = async (connection, pf, memoryMap, progress) => {
26
+ connection.log("Partial flash");
27
+ progress(ProgressStage.PartialFlashing);
28
+ try {
29
+ const deviceCodeRegion = await pf.getRegionInfo(RegionId.MakeCode);
30
+ if (deviceCodeRegion === null) {
31
+ connection.log("Could not read code region");
32
+ return PartialFlashResult.AttemptFullFlash;
33
+ }
34
+ const deviceDalRegion = await pf.getRegionInfo(RegionId.Dal);
35
+ if (deviceDalRegion === null) {
36
+ connection.log("Could not read DAL region");
37
+ return PartialFlashResult.AttemptFullFlash;
38
+ }
39
+ progress(ProgressStage.PartialFlashing);
40
+ const fileCodeRegion = findMakeCodeRegionInMemoryMap(memoryMap, deviceCodeRegion);
41
+ if (fileCodeRegion === null) {
42
+ connection.log("No partial flash data");
43
+ return PartialFlashResult.AttemptFullFlash;
44
+ }
45
+ if (fileCodeRegion.hash !== deviceDalRegion.hash) {
46
+ connection.log(`DAL hash comparison failed. Hex: ${fileCodeRegion.hash} vs device: ${deviceDalRegion.hash}`);
47
+ return PartialFlashResult.AttemptFullFlash;
48
+ }
49
+ if (deviceCodeRegion.start !== fileCodeRegion.start) {
50
+ connection.log("Code start address doesn't match");
51
+ return PartialFlashResult.AttemptFullFlash;
52
+ }
53
+ let nextPacketNumber = 0;
54
+ outer: for (let offset = fileCodeRegion.start; offset < fileCodeRegion.end;) {
55
+ const batchStartAddress = offset;
56
+ for (let packetInBatch = 0; packetInBatch < 4; ++packetInBatch) {
57
+ const packetNumber = nextPacketNumber++;
58
+ const packetDataOffset = offset + packetInBatch * 16;
59
+ if (packetInBatch < 3) {
60
+ await pf.writeFlash(memoryMap, batchStartAddress, packetDataOffset, packetNumber, packetInBatch);
61
+ }
62
+ else {
63
+ const result = await pf.writeFlashForNotification(memoryMap, batchStartAddress, packetDataOffset, packetNumber, packetInBatch);
64
+ if (result === PacketState.Retransmit) {
65
+ // Retry the whole 64 bytes.
66
+ connection.log(`Retransmit requested at offset ${offset}`);
67
+ continue outer;
68
+ }
69
+ else {
70
+ progress(ProgressStage.PartialFlashing, (offset - fileCodeRegion.start) /
71
+ (fileCodeRegion.end - fileCodeRegion.start));
72
+ }
73
+ }
74
+ }
75
+ offset += 64;
76
+ }
77
+ await delay(100); // allow time for write to complete
78
+ await pf.writeEndOfFlashPacket();
79
+ await delay(100); // allow time for write to complete
80
+ progress(ProgressStage.PartialFlashing, 1);
81
+ return PartialFlashResult.Success;
82
+ }
83
+ catch (e) {
84
+ connection.error("Partial flash failed", e);
85
+ if (e instanceof DeviceError) {
86
+ throw e;
87
+ }
88
+ throw new DeviceError({
89
+ code: "flash-partial-failed",
90
+ message: e instanceof Error ? e.message : String(e),
91
+ });
92
+ }
93
+ };
94
+ export default partialFlash;
95
+ //# sourceMappingURL=flashing-partial.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flashing-partial.js","sourceRoot":"","sources":["../../../lib/flashing/flashing-partial.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * V1 changes the service it offers in application/bootloader mode.
3
+ *
4
+ * We don't trust Android to have an up-to-date copy of services so will fall back
5
+ * to calling internal API via reflection if the desired/expected service is not
6
+ * listed.
7
+ *
8
+ * It might be that this is only needed for older versions of Android where we
9
+ * can't get service changed indications.
10
+ */
11
+ export declare const refreshServicesForV1IfDesiredServiceMissing: (deviceId: string, desiredServiceUuid: string) => Promise<void>;
@@ -0,0 +1,20 @@
1
+ import { BleClient } from "@capacitor-community/bluetooth-le";
2
+ /**
3
+ * V1 changes the service it offers in application/bootloader mode.
4
+ *
5
+ * We don't trust Android to have an up-to-date copy of services so will fall back
6
+ * to calling internal API via reflection if the desired/expected service is not
7
+ * listed.
8
+ *
9
+ * It might be that this is only needed for older versions of Android where we
10
+ * can't get service changed indications.
11
+ */
12
+ export const refreshServicesForV1IfDesiredServiceMissing = async (deviceId, desiredServiceUuid) => {
13
+ const services = await BleClient.getServices(deviceId);
14
+ const deviceHasService = services.some((s) => s.uuid === desiredServiceUuid);
15
+ if (!deviceHasService) {
16
+ // On Android this does use the refresh reflection hack.
17
+ await BleClient.discoverServices(deviceId);
18
+ }
19
+ };
20
+ //# sourceMappingURL=flashing-v1.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"flashing-v1.js","sourceRoot":"","sources":["../../../lib/flashing/flashing-v1.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAE9D;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,2CAA2C,GAAG,KAAK,EAC9D,QAAgB,EAChB,kBAA0B,EAC1B,EAAE;IACF,MAAM,QAAQ,GAAG,MAAM,SAAS,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACvD,MAAM,gBAAgB,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,kBAAkB,CAAC,CAAC;IAC7E,IAAI,CAAC,gBAAgB,EAAE,CAAC;QACtB,wDAAwD;QACxD,MAAM,SAAS,CAAC,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAC7C,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { BluetoothDeviceWrapper } from "../bluetooth-device-wrapper.js";
2
+ import { BoardVersion, ProgressCallback } from "../device";
3
+ export declare function flashDfu(connection: BluetoothDeviceWrapper, boardVersion: BoardVersion, appBin: Uint8Array, progress: ProgressCallback): Promise<void>;