@microbit/microbit-connection 0.0.0-tab.change.177 → 0.1.0

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 (227) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +94 -5
  3. package/build/cjs/accelerometer-service.js +106 -0
  4. package/build/cjs/accelerometer-service.js.map +1 -0
  5. package/build/cjs/accelerometer.js +16 -0
  6. package/build/cjs/accelerometer.js.map +1 -0
  7. package/build/cjs/async-util.js +27 -0
  8. package/build/cjs/async-util.js.map +1 -0
  9. package/build/{bluetooth-device-wrapper.d.ts → cjs/bluetooth-device-wrapper.d.ts} +7 -1
  10. package/build/cjs/bluetooth-device-wrapper.js +467 -0
  11. package/build/cjs/bluetooth-device-wrapper.js.map +1 -0
  12. package/build/cjs/bluetooth-profile.js +86 -0
  13. package/build/cjs/bluetooth-profile.js.map +1 -0
  14. package/build/cjs/bluetooth.d.ts +108 -0
  15. package/build/cjs/bluetooth.js +272 -0
  16. package/build/cjs/bluetooth.js.map +1 -0
  17. package/build/cjs/board-id.js +81 -0
  18. package/build/cjs/board-id.js.map +1 -0
  19. package/build/cjs/board-serial-info.js +51 -0
  20. package/build/cjs/board-serial-info.js.map +1 -0
  21. package/build/cjs/button-service.js +80 -0
  22. package/build/cjs/button-service.js.map +1 -0
  23. package/build/cjs/buttons.js +22 -0
  24. package/build/cjs/buttons.js.map +1 -0
  25. package/build/cjs/constants.js +73 -0
  26. package/build/cjs/constants.js.map +1 -0
  27. package/build/{device.d.ts → cjs/device.d.ts} +6 -31
  28. package/build/cjs/device.js +133 -0
  29. package/build/cjs/device.js.map +1 -0
  30. package/build/{events.d.ts → cjs/events.d.ts} +1 -2
  31. package/build/cjs/events.js +109 -0
  32. package/build/cjs/events.js.map +1 -0
  33. package/build/cjs/hex-flash-data-source.js +26 -0
  34. package/build/cjs/hex-flash-data-source.js.map +1 -0
  35. package/build/cjs/index.d.ts +17 -0
  36. package/build/cjs/index.js +36 -0
  37. package/build/cjs/index.js.map +1 -0
  38. package/build/cjs/led-service.js +120 -0
  39. package/build/{led-service.js.map → cjs/led-service.js.map} +1 -1
  40. package/build/cjs/led.js +3 -0
  41. package/build/cjs/led.js.map +1 -0
  42. package/build/{logging.d.ts → cjs/logging.d.ts} +3 -3
  43. package/build/cjs/logging.js +16 -0
  44. package/build/cjs/logging.js.map +1 -0
  45. package/build/cjs/magnetometer-service.d.ts +22 -0
  46. package/build/cjs/magnetometer-service.js +129 -0
  47. package/build/cjs/magnetometer-service.js.map +1 -0
  48. package/build/cjs/magnetometer.d.ts +9 -0
  49. package/build/cjs/magnetometer.js +16 -0
  50. package/build/cjs/magnetometer.js.map +1 -0
  51. package/build/cjs/package.json +1 -0
  52. package/build/cjs/promise-queue.js +78 -0
  53. package/build/cjs/promise-queue.js.map +1 -0
  54. package/build/cjs/serial-events.d.ts +20 -0
  55. package/build/cjs/serial-events.js +69 -0
  56. package/build/cjs/serial-events.js.map +1 -0
  57. package/build/{service-events.d.ts → cjs/service-events.d.ts} +4 -0
  58. package/build/cjs/service-events.js +39 -0
  59. package/build/cjs/service-events.js.map +1 -0
  60. package/build/cjs/setupTests.js.map +1 -0
  61. package/build/cjs/uart-service.d.ts +13 -0
  62. package/build/cjs/uart-service.js +76 -0
  63. package/build/cjs/uart-service.js.map +1 -0
  64. package/build/cjs/uart.d.ts +4 -0
  65. package/build/cjs/uart.js +16 -0
  66. package/build/cjs/uart.js.map +1 -0
  67. package/build/{usb-device-wrapper.d.ts → cjs/usb-device-wrapper.d.ts} +1 -6
  68. package/build/cjs/usb-device-wrapper.js +412 -0
  69. package/build/cjs/usb-device-wrapper.js.map +1 -0
  70. package/build/cjs/usb-partial-flashing-utils.js +133 -0
  71. package/build/cjs/usb-partial-flashing-utils.js.map +1 -0
  72. package/build/{usb-partial-flashing.d.ts → cjs/usb-partial-flashing.d.ts} +3 -3
  73. package/build/cjs/usb-partial-flashing.js +341 -0
  74. package/build/cjs/usb-partial-flashing.js.map +1 -0
  75. package/build/cjs/usb-radio-bridge.d.ts +24 -0
  76. package/build/cjs/usb-radio-bridge.js +516 -0
  77. package/build/cjs/usb-radio-bridge.js.map +1 -0
  78. package/build/cjs/usb-serial-protocol.js +183 -0
  79. package/build/cjs/usb-serial-protocol.js.map +1 -0
  80. package/build/cjs/usb.d.ts +64 -0
  81. package/build/cjs/usb.js +647 -0
  82. package/build/cjs/usb.js.map +1 -0
  83. package/build/esm/accelerometer-service.d.ts +18 -0
  84. package/build/{accelerometer-service.js → esm/accelerometer-service.js} +1 -1
  85. package/build/esm/accelerometer-service.js.map +1 -0
  86. package/build/esm/accelerometer.d.ts +9 -0
  87. package/build/esm/accelerometer.js.map +1 -0
  88. package/build/esm/async-util.d.ts +13 -0
  89. package/build/esm/async-util.js.map +1 -0
  90. package/build/esm/bluetooth-device-wrapper.d.ts +63 -0
  91. package/build/{bluetooth-device-wrapper.js → esm/bluetooth-device-wrapper.js} +39 -10
  92. package/build/esm/bluetooth-device-wrapper.js.map +1 -0
  93. package/build/esm/bluetooth-profile.d.ts +139 -0
  94. package/build/esm/bluetooth-profile.js.map +1 -0
  95. package/build/esm/bluetooth.d.ts +108 -0
  96. package/build/{bluetooth.js → esm/bluetooth.js} +29 -4
  97. package/build/esm/bluetooth.js.map +1 -0
  98. package/build/esm/board-id.d.ts +36 -0
  99. package/build/esm/board-id.js.map +1 -0
  100. package/build/esm/board-serial-info.d.ts +14 -0
  101. package/build/esm/board-serial-info.js.map +1 -0
  102. package/build/esm/button-service.d.ts +13 -0
  103. package/build/esm/button-service.js.map +1 -0
  104. package/build/esm/buttons.d.ts +10 -0
  105. package/build/esm/buttons.js.map +1 -0
  106. package/build/esm/constants.d.ts +48 -0
  107. package/build/esm/constants.js.map +1 -0
  108. package/build/esm/device.d.ts +181 -0
  109. package/build/{device.js → esm/device.js} +1 -57
  110. package/build/esm/device.js.map +1 -0
  111. package/build/esm/events.d.ts +110 -0
  112. package/build/esm/events.js.map +1 -0
  113. package/build/esm/hex-flash-data-source.d.ts +7 -0
  114. package/build/esm/hex-flash-data-source.js.map +1 -0
  115. package/build/esm/index.d.ts +17 -0
  116. package/build/esm/index.js +12 -0
  117. package/build/esm/index.js.map +1 -0
  118. package/build/esm/led-service.d.ts +20 -0
  119. package/build/esm/led-service.js.map +1 -0
  120. package/build/esm/led.d.ts +6 -0
  121. package/build/esm/led.js.map +1 -0
  122. package/build/esm/logging.d.ts +21 -0
  123. package/build/esm/logging.js.map +1 -0
  124. package/build/esm/magnetometer-service.d.ts +22 -0
  125. package/build/esm/magnetometer-service.js +125 -0
  126. package/build/esm/magnetometer-service.js.map +1 -0
  127. package/build/esm/magnetometer.d.ts +9 -0
  128. package/build/esm/magnetometer.js +12 -0
  129. package/build/esm/magnetometer.js.map +1 -0
  130. package/build/esm/package.json +1 -0
  131. package/build/esm/promise-queue.d.ts +27 -0
  132. package/build/esm/promise-queue.js.map +1 -0
  133. package/build/esm/serial-events.d.ts +20 -0
  134. package/build/esm/serial-events.js +61 -0
  135. package/build/esm/serial-events.js.map +1 -0
  136. package/build/esm/service-events.d.ts +17 -0
  137. package/build/{service-events.js → esm/service-events.js} +12 -0
  138. package/build/esm/service-events.js.map +1 -0
  139. package/build/esm/setupTests.d.ts +6 -0
  140. package/build/{setupTests.js.map → esm/setupTests.js.map} +1 -1
  141. package/build/esm/uart-service.d.ts +13 -0
  142. package/build/esm/uart-service.js +72 -0
  143. package/build/esm/uart-service.js.map +1 -0
  144. package/build/esm/uart.d.ts +4 -0
  145. package/build/esm/uart.js +12 -0
  146. package/build/esm/uart.js.map +1 -0
  147. package/build/esm/usb-device-wrapper.d.ts +47 -0
  148. package/build/{usb-device-wrapper.js → esm/usb-device-wrapper.js} +10 -9
  149. package/build/esm/usb-device-wrapper.js.map +1 -0
  150. package/build/esm/usb-partial-flashing-utils.d.ts +17 -0
  151. package/build/esm/usb-partial-flashing-utils.js.map +1 -0
  152. package/build/esm/usb-partial-flashing.d.ts +69 -0
  153. package/build/{usb-partial-flashing.js → esm/usb-partial-flashing.js} +8 -10
  154. package/build/esm/usb-partial-flashing.js.map +1 -0
  155. package/build/esm/usb-radio-bridge.d.ts +24 -0
  156. package/build/{usb-radio-bridge.js → esm/usb-radio-bridge.js} +11 -4
  157. package/build/esm/usb-radio-bridge.js.map +1 -0
  158. package/build/esm/usb-serial-protocol.d.ts +66 -0
  159. package/build/esm/usb-serial-protocol.js.map +1 -0
  160. package/build/esm/usb.d.ts +64 -0
  161. package/build/{usb.js → esm/usb.js} +228 -35
  162. package/build/esm/usb.js.map +1 -0
  163. package/package.json +21 -8
  164. package/typedoc.json +14 -0
  165. package/build/accelerometer-service.js.map +0 -1
  166. package/build/accelerometer.js.map +0 -1
  167. package/build/async-util.js.map +0 -1
  168. package/build/bluetooth-device-wrapper.js.map +0 -1
  169. package/build/bluetooth-profile.js.map +0 -1
  170. package/build/bluetooth.d.ts +0 -54
  171. package/build/bluetooth.js.map +0 -1
  172. package/build/board-id.js.map +0 -1
  173. package/build/board-serial-info.js.map +0 -1
  174. package/build/button-service.js.map +0 -1
  175. package/build/buttons.js.map +0 -1
  176. package/build/constants.js.map +0 -1
  177. package/build/device.js.map +0 -1
  178. package/build/events.js.map +0 -1
  179. package/build/hex-flash-data-source.js.map +0 -1
  180. package/build/index.d.ts +0 -10
  181. package/build/index.js +0 -8
  182. package/build/index.js.map +0 -1
  183. package/build/led.js.map +0 -1
  184. package/build/logging.js.map +0 -1
  185. package/build/promise-queue.js.map +0 -1
  186. package/build/service-events.js.map +0 -1
  187. package/build/usb-device-wrapper.js.map +0 -1
  188. package/build/usb-partial-flashing-utils.js.map +0 -1
  189. package/build/usb-partial-flashing.js.map +0 -1
  190. package/build/usb-radio-bridge.d.ts +0 -41
  191. package/build/usb-radio-bridge.js.map +0 -1
  192. package/build/usb-serial-protocol.js.map +0 -1
  193. package/build/usb.d.ts +0 -54
  194. package/build/usb.js.map +0 -1
  195. package/vite.config.ts +0 -34
  196. /package/build/{accelerometer-service.d.ts → cjs/accelerometer-service.d.ts} +0 -0
  197. /package/build/{accelerometer.d.ts → cjs/accelerometer.d.ts} +0 -0
  198. /package/build/{async-util.d.ts → cjs/async-util.d.ts} +0 -0
  199. /package/build/{bluetooth-profile.d.ts → cjs/bluetooth-profile.d.ts} +0 -0
  200. /package/build/{board-id.d.ts → cjs/board-id.d.ts} +0 -0
  201. /package/build/{board-serial-info.d.ts → cjs/board-serial-info.d.ts} +0 -0
  202. /package/build/{button-service.d.ts → cjs/button-service.d.ts} +0 -0
  203. /package/build/{buttons.d.ts → cjs/buttons.d.ts} +0 -0
  204. /package/build/{constants.d.ts → cjs/constants.d.ts} +0 -0
  205. /package/build/{hex-flash-data-source.d.ts → cjs/hex-flash-data-source.d.ts} +0 -0
  206. /package/build/{led-service.d.ts → cjs/led-service.d.ts} +0 -0
  207. /package/build/{led.d.ts → cjs/led.d.ts} +0 -0
  208. /package/build/{promise-queue.d.ts → cjs/promise-queue.d.ts} +0 -0
  209. /package/build/{setupTests.d.ts → cjs/setupTests.d.ts} +0 -0
  210. /package/build/{usb-partial-flashing-utils.d.ts → cjs/usb-partial-flashing-utils.d.ts} +0 -0
  211. /package/build/{usb-serial-protocol.d.ts → cjs/usb-serial-protocol.d.ts} +0 -0
  212. /package/build/{accelerometer.js → esm/accelerometer.js} +0 -0
  213. /package/build/{async-util.js → esm/async-util.js} +0 -0
  214. /package/build/{bluetooth-profile.js → esm/bluetooth-profile.js} +0 -0
  215. /package/build/{board-id.js → esm/board-id.js} +0 -0
  216. /package/build/{board-serial-info.js → esm/board-serial-info.js} +0 -0
  217. /package/build/{button-service.js → esm/button-service.js} +0 -0
  218. /package/build/{buttons.js → esm/buttons.js} +0 -0
  219. /package/build/{constants.js → esm/constants.js} +0 -0
  220. /package/build/{events.js → esm/events.js} +0 -0
  221. /package/build/{hex-flash-data-source.js → esm/hex-flash-data-source.js} +0 -0
  222. /package/build/{led-service.js → esm/led-service.js} +0 -0
  223. /package/build/{led.js → esm/led.js} +0 -0
  224. /package/build/{logging.js → esm/logging.js} +0 -0
  225. /package/build/{promise-queue.js → esm/promise-queue.js} +0 -0
  226. /package/build/{usb-partial-flashing-utils.js → esm/usb-partial-flashing-utils.js} +0 -0
  227. /package/build/{usb-serial-protocol.js → esm/usb-serial-protocol.js} +0 -0
@@ -0,0 +1,516 @@
1
+ "use strict";
2
+ /**
3
+ * (c) 2023, Center for Computational Thinking and Design at Aarhus University and contributors
4
+ *
5
+ * SPDX-License-Identifier: MIT
6
+ */
7
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
8
+ if (k2 === undefined) k2 = k;
9
+ var desc = Object.getOwnPropertyDescriptor(m, k);
10
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
11
+ desc = { enumerable: true, get: function() { return m[k]; } };
12
+ }
13
+ Object.defineProperty(o, k2, desc);
14
+ }) : (function(o, m, k, k2) {
15
+ if (k2 === undefined) k2 = k;
16
+ o[k2] = m[k];
17
+ }));
18
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
19
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
20
+ }) : function(o, v) {
21
+ o["default"] = v;
22
+ });
23
+ var __importStar = (this && this.__importStar) || function (mod) {
24
+ if (mod && mod.__esModule) return mod;
25
+ var result = {};
26
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
27
+ __setModuleDefault(result, mod);
28
+ return result;
29
+ };
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.createRadioBridgeConnection = void 0;
32
+ const accelerometer_js_1 = require("./accelerometer.js");
33
+ const buttons_js_1 = require("./buttons.js");
34
+ const device_js_1 = require("./device.js");
35
+ const events_js_1 = require("./events.js");
36
+ const logging_js_1 = require("./logging.js");
37
+ const protocol = __importStar(require("./usb-serial-protocol.js"));
38
+ const connectTimeoutDuration = 10000;
39
+ class BridgeError extends Error {
40
+ }
41
+ class RemoteError extends Error {
42
+ }
43
+ /**
44
+ * A radio bridge connection factory.
45
+ */
46
+ const createRadioBridgeConnection = (delegate, options) => new MicrobitRadioBridgeConnectionImpl(delegate, options);
47
+ exports.createRadioBridgeConnection = createRadioBridgeConnection;
48
+ /**
49
+ * Wraps around a USB connection to implement a subset of services over a serial protocol.
50
+ *
51
+ * When it connects/disconnects it affects the delegate connection.
52
+ */
53
+ class MicrobitRadioBridgeConnectionImpl extends events_js_1.TypedEventTarget {
54
+ constructor(delegate, options) {
55
+ super();
56
+ Object.defineProperty(this, "delegate", {
57
+ enumerable: true,
58
+ configurable: true,
59
+ writable: true,
60
+ value: delegate
61
+ });
62
+ Object.defineProperty(this, "status", {
63
+ enumerable: true,
64
+ configurable: true,
65
+ writable: true,
66
+ value: void 0
67
+ });
68
+ Object.defineProperty(this, "logging", {
69
+ enumerable: true,
70
+ configurable: true,
71
+ writable: true,
72
+ value: void 0
73
+ });
74
+ Object.defineProperty(this, "serialSession", {
75
+ enumerable: true,
76
+ configurable: true,
77
+ writable: true,
78
+ value: void 0
79
+ });
80
+ Object.defineProperty(this, "remoteDeviceId", {
81
+ enumerable: true,
82
+ configurable: true,
83
+ writable: true,
84
+ value: void 0
85
+ });
86
+ Object.defineProperty(this, "disconnectPromise", {
87
+ enumerable: true,
88
+ configurable: true,
89
+ writable: true,
90
+ value: void 0
91
+ });
92
+ Object.defineProperty(this, "serialSessionOpen", {
93
+ enumerable: true,
94
+ configurable: true,
95
+ writable: true,
96
+ value: false
97
+ });
98
+ Object.defineProperty(this, "ignoreDelegateStatus", {
99
+ enumerable: true,
100
+ configurable: true,
101
+ writable: true,
102
+ value: false
103
+ });
104
+ Object.defineProperty(this, "delegateStatusListener", {
105
+ enumerable: true,
106
+ configurable: true,
107
+ writable: true,
108
+ value: (e) => {
109
+ if (this.ignoreDelegateStatus) {
110
+ return;
111
+ }
112
+ const currentStatus = this.status;
113
+ if (e.status !== device_js_1.ConnectionStatus.CONNECTED) {
114
+ this.setStatus(e.status);
115
+ if (this.serialSessionOpen) {
116
+ // If the session is already closed we don't need to dispose.
117
+ this.serialSession?.dispose();
118
+ }
119
+ }
120
+ else {
121
+ this.status = device_js_1.ConnectionStatus.DISCONNECTED;
122
+ if (currentStatus === device_js_1.ConnectionStatus.DISCONNECTED &&
123
+ this.serialSessionOpen) {
124
+ this.serialSession?.connect();
125
+ }
126
+ }
127
+ }
128
+ });
129
+ this.logging = options?.logging ?? new logging_js_1.NullLogging();
130
+ this.status = this.statusFromDelegate();
131
+ }
132
+ getBoardVersion() {
133
+ return this.delegate.getBoardVersion();
134
+ }
135
+ serialWrite(data) {
136
+ return this.delegate.serialWrite(data);
137
+ }
138
+ async initialize() {
139
+ await this.delegate.initialize();
140
+ this.setStatus(this.statusFromDelegate());
141
+ this.delegate.addEventListener("status", this.delegateStatusListener);
142
+ }
143
+ dispose() {
144
+ this.delegate.removeEventListener("status", this.delegateStatusListener);
145
+ this.delegate.dispose();
146
+ }
147
+ clearDevice() {
148
+ this.delegate.clearDevice();
149
+ }
150
+ setRemoteDeviceId(remoteDeviceId) {
151
+ this.remoteDeviceId = remoteDeviceId;
152
+ }
153
+ async connect() {
154
+ if (this.disconnectPromise) {
155
+ await this.disconnectPromise;
156
+ }
157
+ // TODO: previously this skipped overlapping connect attempts but that seems awkward
158
+ // can we... just not do that? or wait?
159
+ if (this.remoteDeviceId === undefined) {
160
+ throw new BridgeError(`Missing remote micro:bit ID`);
161
+ }
162
+ this.logging.event({
163
+ type: "Connect",
164
+ message: "Serial connect start",
165
+ });
166
+ this.ignoreDelegateStatus = false;
167
+ await this.delegate.connect();
168
+ try {
169
+ this.serialSession = new RadioBridgeSerialSession(this.logging, this.remoteDeviceId, this.delegate, this.dispatchTypedEvent.bind(this), {
170
+ onConnecting: () => this.setStatus(device_js_1.ConnectionStatus.CONNECTING),
171
+ onReconnecting: () => {
172
+ // Leave serial connection running in case the remote device comes back.
173
+ if (this.status !== device_js_1.ConnectionStatus.RECONNECTING) {
174
+ this.setStatus(device_js_1.ConnectionStatus.RECONNECTING);
175
+ }
176
+ },
177
+ onRestartConnection: () => {
178
+ // So that serial session does not get repetitively disposed in
179
+ // delegate status listener when delegate is disconnected for restarting connection
180
+ this.ignoreDelegateStatus = true;
181
+ },
182
+ onFail: () => {
183
+ if (this.status !== device_js_1.ConnectionStatus.DISCONNECTED) {
184
+ this.setStatus(device_js_1.ConnectionStatus.DISCONNECTED);
185
+ }
186
+ this.ignoreDelegateStatus = false;
187
+ this.serialSessionOpen = false;
188
+ },
189
+ onSuccess: () => {
190
+ if (this.status !== device_js_1.ConnectionStatus.CONNECTED) {
191
+ this.setStatus(device_js_1.ConnectionStatus.CONNECTED);
192
+ }
193
+ this.ignoreDelegateStatus = false;
194
+ this.serialSessionOpen = true;
195
+ },
196
+ });
197
+ await this.serialSession.connect();
198
+ this.logging.event({
199
+ type: "Connect",
200
+ message: "Serial connect success",
201
+ });
202
+ return this.status;
203
+ }
204
+ catch (e) {
205
+ this.serialSessionOpen = false;
206
+ this.logging.error("Failed to initialise serial protocol", e);
207
+ this.logging.event({
208
+ type: "Connect",
209
+ message: "Serial connect failed",
210
+ });
211
+ throw e;
212
+ }
213
+ }
214
+ async disconnect() {
215
+ if (this.disconnectPromise) {
216
+ return this.disconnectPromise;
217
+ }
218
+ this.serialSessionOpen = false;
219
+ this.disconnectPromise = (async () => {
220
+ await this.serialSession?.dispose(true);
221
+ this.disconnectPromise = undefined;
222
+ })();
223
+ }
224
+ log(v) {
225
+ this.logging.log(v);
226
+ }
227
+ setStatus(status) {
228
+ this.status = status;
229
+ this.log("Radio connection status " + status);
230
+ this.dispatchTypedEvent("status", new device_js_1.ConnectionStatusEvent(status));
231
+ }
232
+ statusFromDelegate() {
233
+ return this.delegate.status == device_js_1.ConnectionStatus.CONNECTED
234
+ ? device_js_1.ConnectionStatus.DISCONNECTED
235
+ : this.delegate.status;
236
+ }
237
+ }
238
+ /**
239
+ * Wraps a connected delegate for a single session from attempted serial handshake to error/dispose.
240
+ */
241
+ class RadioBridgeSerialSession {
242
+ processButton(button, type, sensorData) {
243
+ if (sensorData[button] !== this.previousButtonState[button]) {
244
+ this.previousButtonState[button] = sensorData[button];
245
+ this.dispatchTypedEvent(type, new buttons_js_1.ButtonEvent(type, sensorData[button] ? buttons_js_1.ButtonState.ShortPress : buttons_js_1.ButtonState.NotPressed));
246
+ }
247
+ }
248
+ constructor(logging, remoteDeviceId, delegate, dispatchTypedEvent, callbacks) {
249
+ Object.defineProperty(this, "logging", {
250
+ enumerable: true,
251
+ configurable: true,
252
+ writable: true,
253
+ value: logging
254
+ });
255
+ Object.defineProperty(this, "remoteDeviceId", {
256
+ enumerable: true,
257
+ configurable: true,
258
+ writable: true,
259
+ value: remoteDeviceId
260
+ });
261
+ Object.defineProperty(this, "delegate", {
262
+ enumerable: true,
263
+ configurable: true,
264
+ writable: true,
265
+ value: delegate
266
+ });
267
+ Object.defineProperty(this, "dispatchTypedEvent", {
268
+ enumerable: true,
269
+ configurable: true,
270
+ writable: true,
271
+ value: dispatchTypedEvent
272
+ });
273
+ Object.defineProperty(this, "callbacks", {
274
+ enumerable: true,
275
+ configurable: true,
276
+ writable: true,
277
+ value: callbacks
278
+ });
279
+ Object.defineProperty(this, "unprocessedData", {
280
+ enumerable: true,
281
+ configurable: true,
282
+ writable: true,
283
+ value: ""
284
+ });
285
+ Object.defineProperty(this, "previousButtonState", {
286
+ enumerable: true,
287
+ configurable: true,
288
+ writable: true,
289
+ value: { buttonA: 0, buttonB: 0 }
290
+ });
291
+ Object.defineProperty(this, "onPeriodicMessageReceived", {
292
+ enumerable: true,
293
+ configurable: true,
294
+ writable: true,
295
+ value: void 0
296
+ });
297
+ Object.defineProperty(this, "lastReceivedMessageTimestamp", {
298
+ enumerable: true,
299
+ configurable: true,
300
+ writable: true,
301
+ value: void 0
302
+ });
303
+ Object.defineProperty(this, "connectionCheckIntervalId", {
304
+ enumerable: true,
305
+ configurable: true,
306
+ writable: true,
307
+ value: void 0
308
+ });
309
+ Object.defineProperty(this, "isRestartingConnection", {
310
+ enumerable: true,
311
+ configurable: true,
312
+ writable: true,
313
+ value: false
314
+ });
315
+ Object.defineProperty(this, "serialErrorListener", {
316
+ enumerable: true,
317
+ configurable: true,
318
+ writable: true,
319
+ value: (event) => {
320
+ this.logging.error("Serial error", event.error);
321
+ void this.dispose();
322
+ }
323
+ });
324
+ Object.defineProperty(this, "serialDataListener", {
325
+ enumerable: true,
326
+ configurable: true,
327
+ writable: true,
328
+ value: (event) => {
329
+ const { data } = event;
330
+ const messages = protocol.splitMessages(this.unprocessedData + data);
331
+ this.unprocessedData = messages.remainingInput;
332
+ messages.messages.forEach(async (msg) => {
333
+ this.lastReceivedMessageTimestamp = Date.now();
334
+ // Messages are either periodic sensor data or command/response
335
+ const sensorData = protocol.processPeriodicMessage(msg);
336
+ if (sensorData) {
337
+ this.onPeriodicMessageReceived?.();
338
+ this.dispatchTypedEvent("accelerometerdatachanged", new accelerometer_js_1.AccelerometerDataEvent({
339
+ x: sensorData.accelerometerX,
340
+ y: sensorData.accelerometerY,
341
+ z: sensorData.accelerometerZ,
342
+ }));
343
+ this.processButton("buttonA", "buttonachanged", sensorData);
344
+ this.processButton("buttonB", "buttonbchanged", sensorData);
345
+ }
346
+ else {
347
+ const messageResponse = protocol.processResponseMessage(msg);
348
+ if (!messageResponse) {
349
+ return;
350
+ }
351
+ const responseResolve = this.responseMap.get(messageResponse.messageId);
352
+ if (responseResolve) {
353
+ this.responseMap.delete(messageResponse.messageId);
354
+ responseResolve(messageResponse);
355
+ }
356
+ }
357
+ });
358
+ }
359
+ });
360
+ Object.defineProperty(this, "responseMap", {
361
+ enumerable: true,
362
+ configurable: true,
363
+ writable: true,
364
+ value: new Map()
365
+ });
366
+ }
367
+ async connect() {
368
+ this.delegate.addEventListener("serialdata", this.serialDataListener);
369
+ this.delegate.addEventListener("serialerror", this.serialErrorListener);
370
+ try {
371
+ if (this.isRestartingConnection) {
372
+ this.callbacks.onReconnecting();
373
+ }
374
+ else {
375
+ this.callbacks.onConnecting();
376
+ }
377
+ await this.handshake();
378
+ this.logging.log(`Serial: using remote device id ${this.remoteDeviceId}`);
379
+ const remoteMbIdCommand = protocol.generateCmdRemoteMbId(this.remoteDeviceId);
380
+ const remoteMbIdResponse = await this.sendCmdWaitResponse(remoteMbIdCommand);
381
+ if (remoteMbIdResponse.type === protocol.ResponseTypes.Error ||
382
+ remoteMbIdResponse.value !== this.remoteDeviceId) {
383
+ throw new BridgeError(`Failed to set remote micro:bit ID. Expected ${this.remoteDeviceId}, got ${remoteMbIdResponse.value}`);
384
+ }
385
+ // Request the micro:bit to start sending the periodic messages
386
+ const startCmd = protocol.generateCmdStart({
387
+ accelerometer: true,
388
+ buttons: true,
389
+ });
390
+ const periodicMessagePromise = new Promise((resolve, reject) => {
391
+ this.onPeriodicMessageReceived = resolve;
392
+ setTimeout(() => {
393
+ this.onPeriodicMessageReceived = undefined;
394
+ reject(new Error("Failed to receive data from remote micro:bit"));
395
+ }, 500);
396
+ });
397
+ const startCmdResponse = await this.sendCmdWaitResponse(startCmd);
398
+ if (startCmdResponse.type === protocol.ResponseTypes.Error) {
399
+ throw new RemoteError(`Failed to start streaming sensors data. Error response received: ${startCmdResponse.message}`);
400
+ }
401
+ // TODO: in the first-time connection case we used to move the error/disconnect to the background here, why? timing?
402
+ await periodicMessagePromise;
403
+ this.isRestartingConnection = false;
404
+ await this.startConnectionCheck();
405
+ this.callbacks.onSuccess();
406
+ }
407
+ catch (e) {
408
+ this.callbacks.onFail();
409
+ await this.dispose();
410
+ }
411
+ }
412
+ async dispose(disconnect = false) {
413
+ this.stopConnectionCheck();
414
+ try {
415
+ await this.sendCmdWaitResponse(protocol.generateCmdStop());
416
+ }
417
+ catch (e) {
418
+ // If this fails the remote micro:bit has already gone away.
419
+ }
420
+ this.responseMap.clear();
421
+ this.delegate.removeEventListener("serialdata", this.serialDataListener);
422
+ this.delegate.removeEventListener("serialerror", this.serialErrorListener);
423
+ if (disconnect) {
424
+ await this.delegate.disconnect();
425
+ }
426
+ await this.delegate.softwareReset();
427
+ }
428
+ async sendCmdWaitResponse(cmd) {
429
+ const responsePromise = new Promise((resolve, reject) => {
430
+ this.responseMap.set(cmd.messageId, resolve);
431
+ setTimeout(() => {
432
+ this.responseMap.delete(cmd.messageId);
433
+ reject(new Error(`Timeout waiting for response ${cmd.messageId}`));
434
+ }, 1_000);
435
+ });
436
+ await this.delegate.serialWrite(cmd.message);
437
+ return responsePromise;
438
+ }
439
+ async startConnectionCheck() {
440
+ // Check for connection lost
441
+ if (this.connectionCheckIntervalId === undefined) {
442
+ this.connectionCheckIntervalId = setInterval(async () => {
443
+ if (this.lastReceivedMessageTimestamp &&
444
+ Date.now() - this.lastReceivedMessageTimestamp <= 1_000) {
445
+ this.callbacks.onSuccess();
446
+ }
447
+ if (this.lastReceivedMessageTimestamp &&
448
+ Date.now() - this.lastReceivedMessageTimestamp > 1_000) {
449
+ this.logging.event({
450
+ type: "Serial",
451
+ message: "Serial connection lost...attempt to reconnect",
452
+ });
453
+ this.callbacks.onReconnecting();
454
+ }
455
+ if (this.lastReceivedMessageTimestamp &&
456
+ Date.now() - this.lastReceivedMessageTimestamp >
457
+ connectTimeoutDuration) {
458
+ await this.restartConnection();
459
+ }
460
+ }, 1000);
461
+ }
462
+ }
463
+ async restartConnection() {
464
+ this.isRestartingConnection = true;
465
+ this.logging.event({
466
+ type: "Serial",
467
+ message: "Serial connection lost...restart connection",
468
+ });
469
+ this.callbacks.onRestartConnection();
470
+ await this.dispose(true);
471
+ await this.delegate.connect();
472
+ await this.connect();
473
+ }
474
+ stopConnectionCheck() {
475
+ clearInterval(this.connectionCheckIntervalId);
476
+ this.connectionCheckIntervalId = undefined;
477
+ this.lastReceivedMessageTimestamp = undefined;
478
+ }
479
+ async handshake() {
480
+ // There is an issue where we cannot read data out from the micro:bit serial
481
+ // buffer until the buffer has been filled.
482
+ // As a workaround we can spam the micro:bit with handshake messages until
483
+ // enough responses have been queued in the buffer to fill it and the data
484
+ // starts to flow.
485
+ this.logging.log("Serial handshake");
486
+ const handshakeResult = await new Promise(async (resolve, reject) => {
487
+ const attempts = 20;
488
+ let attemptCounter = 0;
489
+ let failureCounter = 0;
490
+ let resolved = false;
491
+ while (attemptCounter < 20 && !resolved) {
492
+ attemptCounter++;
493
+ this.sendCmdWaitResponse(protocol.generateCmdHandshake())
494
+ .then((value) => {
495
+ if (!resolved) {
496
+ resolved = true;
497
+ resolve(value);
498
+ }
499
+ })
500
+ .catch(() => {
501
+ // We expect some to time out, likely well after the handshake is completed.
502
+ if (!resolved) {
503
+ if (++failureCounter === attempts) {
504
+ reject(new BridgeError("Handshake not completed"));
505
+ }
506
+ }
507
+ });
508
+ await new Promise((resolve) => setTimeout(resolve, 100));
509
+ }
510
+ });
511
+ if (handshakeResult.value !== protocol.version) {
512
+ throw new BridgeError(`Handshake failed. Unexpected protocol version ${protocol.version}`);
513
+ }
514
+ }
515
+ }
516
+ //# sourceMappingURL=usb-radio-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usb-radio-bridge.js","sourceRoot":"","sources":["../../lib/usb-radio-bridge.ts"],"names":[],"mappings":"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"}