@microbit/capacitor-community-nordic-dfu 7.0.0-microbit.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.
- package/CapacitorCommunityNordicDfu.podspec +18 -0
- package/LICENSE +21 -0
- package/README.md +290 -0
- package/android/build.gradle +69 -0
- package/android/src/main/AndroidManifest.xml +13 -0
- package/android/src/main/java/com/example/plugin/nordicdfu/DfuService.java +51 -0
- package/android/src/main/java/com/example/plugin/nordicdfu/NordicDfu.java +179 -0
- package/android/src/main/java/com/example/plugin/nordicdfu/NordicDfuPlugin.java +274 -0
- package/android/src/main/java/com/example/plugin/nordicdfu/NotificationActivity.java +27 -0
- package/android/src/main/res/.gitkeep +0 -0
- package/dist/docs.json +900 -0
- package/dist/esm/definitions.d.ts +435 -0
- package/dist/esm/definitions.js +82 -0
- package/dist/esm/definitions.js.map +1 -0
- package/dist/esm/index.d.ts +4 -0
- package/dist/esm/index.js +7 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/web.d.ts +9 -0
- package/dist/esm/web.js +20 -0
- package/dist/esm/web.js.map +1 -0
- package/dist/plugin.cjs.js +116 -0
- package/dist/plugin.cjs.js.map +1 -0
- package/dist/plugin.js +119 -0
- package/dist/plugin.js.map +1 -0
- package/ios/Plugin/Info.plist +24 -0
- package/ios/Plugin/NordicDfu.swift +4 -0
- package/ios/Plugin/Plugin.h +9 -0
- package/ios/Plugin/Plugin.m +8 -0
- package/ios/Plugin/Plugin.swift +368 -0
- package/package.json +102 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
|
|
3
|
+
package = JSON.parse(File.read(File.join(__dir__, 'package.json')))
|
|
4
|
+
|
|
5
|
+
Pod::Spec.new do |s|
|
|
6
|
+
s.name = 'CapacitorCommunityNordicDfu'
|
|
7
|
+
s.version = package['version']
|
|
8
|
+
s.summary = package['description']
|
|
9
|
+
s.license = package['license']
|
|
10
|
+
s.homepage = package['repository']['url']
|
|
11
|
+
s.author = package['author']
|
|
12
|
+
s.source = { :git => package['repository']['url'], :tag => s.version.to_s }
|
|
13
|
+
s.source_files = 'ios/Plugin/**/*.{swift,h,m,c,cc,mm,cpp}'
|
|
14
|
+
s.ios.deployment_target = '14.0'
|
|
15
|
+
s.dependency 'Capacitor'
|
|
16
|
+
s.swift_version = '5.1'
|
|
17
|
+
s.dependency 'NordicDFU', '~> 4.16.0'
|
|
18
|
+
end
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) COPYRIGHT_YEAR COPYRIGHT_HOLDER
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
<p align="center"><br><img src="https://user-images.githubusercontent.com/236501/85893648-1c92e880-b7a8-11ea-926d-95355b8175c7.png" width="128" height="128" /></p>
|
|
2
|
+
<h3 align="center">Nordic DFU</h3>
|
|
3
|
+
<p align="center"><strong><code>capacitor-community-nordic-dfu</code></strong></p>
|
|
4
|
+
<p align="center">
|
|
5
|
+
Capacitor plugin to interface with Nordic DFU's <a href="https://github.com/NordicSemiconductor/IOS-DFU-Library">IOS-DFU-Library</a> and <a href="https://github.com/NordicSemiconductor/Android-DFU-Library">Android-DFU-Library</a>.
|
|
6
|
+
</p>
|
|
7
|
+
|
|
8
|
+
<p align="center">
|
|
9
|
+
<img
|
|
10
|
+
alt="Maintenance status"
|
|
11
|
+
src="https://img.shields.io/maintenance/yes/2025?style=flat-square"/>
|
|
12
|
+
<a
|
|
13
|
+
href="https://github.com/robsonos/nordic-dfu/actions/workflows/ci.yml"
|
|
14
|
+
style="color: inherit; text-decoration: none;">
|
|
15
|
+
<img
|
|
16
|
+
alt="GitHub Workflow Status (with event)"
|
|
17
|
+
src="https://img.shields.io/github/actions/workflow/status/robsonos/nordic-dfu/ci.yml"/>
|
|
18
|
+
</a>
|
|
19
|
+
<a
|
|
20
|
+
href="https://www.npmjs.com/package/capacitor-community-nordic-dfu"
|
|
21
|
+
style="color: inherit; text-decoration: none;">
|
|
22
|
+
<img
|
|
23
|
+
alt="GitHub License"
|
|
24
|
+
src="https://img.shields.io/npm/l/capacitor-community-nordic-dfu?style=flat-square"/>
|
|
25
|
+
</a>
|
|
26
|
+
<br />
|
|
27
|
+
<a
|
|
28
|
+
href="https://www.npmjs.com/package/capacitor-community-nordic-dfu"
|
|
29
|
+
style="color: inherit; text-decoration: none;">
|
|
30
|
+
<img
|
|
31
|
+
alt="Version from npmjs"
|
|
32
|
+
src="https://img.shields.io/npm/v/capacitor-community-nordic-dfu?style=flat-square"/>
|
|
33
|
+
</a>
|
|
34
|
+
<a
|
|
35
|
+
href="https://www.npmjs.com/package/capacitor-community-nordic-dfu"
|
|
36
|
+
style="color: inherit; text-decoration: none;">
|
|
37
|
+
<img
|
|
38
|
+
alt="Downloads from npmjs"
|
|
39
|
+
src="https://img.shields.io/npm/dw/capacitor-community-nordic-dfu?style=flat-square"/>
|
|
40
|
+
</a>
|
|
41
|
+
<a href="#contributors"
|
|
42
|
+
style="color: inherit; text-decoration: none;">
|
|
43
|
+
<img
|
|
44
|
+
alt="GitHub contributors from allcontributors.org"
|
|
45
|
+
src="https://img.shields.io/github/all-contributors/robsonos/nordic-dfu">
|
|
46
|
+
</a>
|
|
47
|
+
</p>
|
|
48
|
+
|
|
49
|
+
## Table of Contents
|
|
50
|
+
|
|
51
|
+
- [Maintainers](#maintainers)
|
|
52
|
+
- [Installation](#installation)
|
|
53
|
+
- [Permissions](#permissions)
|
|
54
|
+
- [API](#api)
|
|
55
|
+
- [Contributors](#contributors)
|
|
56
|
+
|
|
57
|
+
## Maintainers
|
|
58
|
+
|
|
59
|
+
| Maintainer | GitHub | Active |
|
|
60
|
+
| ---------- | --------------------------------------- | ------ |
|
|
61
|
+
| robsonos | [robsonos](https://github.com/robsonos) | yes |
|
|
62
|
+
|
|
63
|
+
## Installation
|
|
64
|
+
|
|
65
|
+
```bash
|
|
66
|
+
npm install capacitor-community-nordic-dfu
|
|
67
|
+
npx cap sync
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
## Permissions
|
|
71
|
+
|
|
72
|
+
Please check the sample permissions in [Android](./example/android/app/src/main/AndroidManifest.xml) and [iOS](./example/ios/App/App/Info.plist) folders.
|
|
73
|
+
|
|
74
|
+
## API
|
|
75
|
+
|
|
76
|
+
<docgen-index>
|
|
77
|
+
|
|
78
|
+
- [`startDFU(...)`](#startdfu)
|
|
79
|
+
- [`checkPermissions()`](#checkpermissions)
|
|
80
|
+
- [`requestPermissions()`](#requestpermissions)
|
|
81
|
+
- [`addListener('DFUStateChanged', ...)`](#addlistenerdfustatechanged-)
|
|
82
|
+
- [`removeAllListeners()`](#removealllisteners)
|
|
83
|
+
- [Interfaces](#interfaces)
|
|
84
|
+
- [Type Aliases](#type-aliases)
|
|
85
|
+
- [Enums](#enums)
|
|
86
|
+
|
|
87
|
+
</docgen-index>
|
|
88
|
+
|
|
89
|
+
<docgen-api>
|
|
90
|
+
<!--Update the source file JSDoc comments and rerun docgen to update the docs below-->
|
|
91
|
+
|
|
92
|
+
Defines the plugin for handling Nordic DFU processes.
|
|
93
|
+
Includes methods to start the DFU process, check permissions, and manage event listeners.
|
|
94
|
+
|
|
95
|
+
### startDFU(...)
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
startDFU(dfuUpdateOptions: DfuUpdateOptions) => Promise<void | PluginResultError>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Initiates the DFU process with the specified options.
|
|
102
|
+
|
|
103
|
+
| Param | Type | Description |
|
|
104
|
+
| ---------------------- | ------------------------------------------------------------- | ---------------------------- |
|
|
105
|
+
| **`dfuUpdateOptions`** | <code><a href="#dfuupdateoptions">DfuUpdateOptions</a></code> | Options for the DFU process. |
|
|
106
|
+
|
|
107
|
+
**Returns:** <code>Promise<void | <a href="#pluginresulterror">PluginResultError</a>></code>
|
|
108
|
+
|
|
109
|
+
**Since:** 1.0.0
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
### checkPermissions()
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
checkPermissions() => Promise<PermissionStatus>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Check status of permissions needed by the plugin
|
|
120
|
+
|
|
121
|
+
**Returns:** <code>Promise<<a href="#permissionstatus">PermissionStatus</a>></code>
|
|
122
|
+
|
|
123
|
+
**Since:** 1.0.0
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### requestPermissions()
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
requestPermissions() => Promise<PermissionStatus>
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Request permissions needed by the plugin
|
|
134
|
+
|
|
135
|
+
**Returns:** <code>Promise<<a href="#permissionstatus">PermissionStatus</a>></code>
|
|
136
|
+
|
|
137
|
+
**Since:** 1.0.0
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### addListener('DFUStateChanged', ...)
|
|
142
|
+
|
|
143
|
+
```typescript
|
|
144
|
+
addListener(eventName: 'DFUStateChanged', handler: (update: DfuUpdate) => void) => Promise<PluginListenerHandle> & PluginListenerHandle
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
Listen for when the DFU state changes
|
|
148
|
+
|
|
149
|
+
| Param | Type | Description |
|
|
150
|
+
| --------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------- |
|
|
151
|
+
| **`eventName`** | <code>'DFUStateChanged'</code> | The name of the event to listen for |
|
|
152
|
+
| **`handler`** | <code>(update: <a href="#dfuupdate">DfuUpdate</a>) => void</code> | The handler function that will be called when the event is fired |
|
|
153
|
+
|
|
154
|
+
**Returns:** <code>Promise<<a href="#pluginlistenerhandle">PluginListenerHandle</a>> & <a href="#pluginlistenerhandle">PluginListenerHandle</a></code>
|
|
155
|
+
|
|
156
|
+
**Since:** 1.0.0
|
|
157
|
+
|
|
158
|
+
---
|
|
159
|
+
|
|
160
|
+
### removeAllListeners()
|
|
161
|
+
|
|
162
|
+
```typescript
|
|
163
|
+
removeAllListeners() => Promise<void>
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Removes all listeners for the DFUStateChanged event
|
|
167
|
+
|
|
168
|
+
**Since:** 1.0.0
|
|
169
|
+
|
|
170
|
+
---
|
|
171
|
+
|
|
172
|
+
### Interfaces
|
|
173
|
+
|
|
174
|
+
#### PluginResultError
|
|
175
|
+
|
|
176
|
+
| Prop | Type |
|
|
177
|
+
| ------------- | ------------------- |
|
|
178
|
+
| **`message`** | <code>string</code> |
|
|
179
|
+
|
|
180
|
+
#### DfuUpdateOptions
|
|
181
|
+
|
|
182
|
+
Specifies the options required for initiating the DFU process.
|
|
183
|
+
|
|
184
|
+
| Prop | Type | Description | Since |
|
|
185
|
+
| ------------------- | ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | ----- |
|
|
186
|
+
| **`deviceAddress`** | <code>string</code> | The target device address. On **Android** this is the BLE MAC address. On **iOS** and **web** it is a randomly generated UUID identifier. | 1.0.0 |
|
|
187
|
+
| **`deviceName`** | <code>string</code> | The name of the device | 1.0.0 |
|
|
188
|
+
| **`filePath`** | <code>string</code> | The path to the firmware file | 1.0.0 |
|
|
189
|
+
| **`dfuOptions`** | <code><a href="#dfuoptions">DfuOptions</a></code> | The additional options for the DFU process | 1.0.0 |
|
|
190
|
+
|
|
191
|
+
#### DfuOptions
|
|
192
|
+
|
|
193
|
+
Outlines additional options for configuring the DFU process.
|
|
194
|
+
|
|
195
|
+
| Prop | Type | Description | Default | Since |
|
|
196
|
+
| ----------------------------------------------------------- | -------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------ | ----- |
|
|
197
|
+
| **`disableNotification`** | <code>boolean</code> | Sets whether the progress notification in the status bar should be disabled. | <code>false</code> | 1.0.0 |
|
|
198
|
+
| **`startAsForegroundService`** | <code>boolean</code> | Sets whether the progress notification in the status bar should be disabled. | <code>false</code> | 1.0.0 |
|
|
199
|
+
| **`keepBond`** | <code>boolean</code> | Sets whether the bond information should be preserver after flashing new application. | <code>false</code> | 1.0.0 |
|
|
200
|
+
| **`restoreBond`** | <code>boolean</code> | Sets whether a new bond should be created after the DFU is complete. The old bond information will be removed before. | <code>false</code> | 1.0.0 |
|
|
201
|
+
| **`dataObjectDelay`** | <code>number</code> | Sets the initial delay (in milliseconds) that the service will wait before sending each data object. | <code>0</code> | 1.0.0 |
|
|
202
|
+
| **`packetReceiptNotificationsEnabled`** | <code>boolean</code> | Enables or disables the Packet Receipt Notification (PRN) procedure. By default the PRNs are disabled on devices with Android Marshmallow or newer and enabled on older ones. | | 1.0.0 |
|
|
203
|
+
| **`packetsReceiptNotificationsValue`** | <code>number</code> | If Packet Receipt Notification procedure is enabled, this method sets the number of packets to be sent before receiving a PRN. | <code>12</code> | 1.0.0 |
|
|
204
|
+
| **`forceDfu`** | <code>boolean</code> | Setting force DFU to true will prevent from jumping to the DFU Bootloader mode in case there is no DFU Version characteristic (Legacy DFU only!). Use this if the DFU operation can be handled by your device running in the application mode. This method is ignored in Secure DFU. | <code>false</code> | 1.0.0 |
|
|
205
|
+
| **`rebootTime`** | <code>number</code> | Sets the time (in milliseconds) required by the device to reboot. The library will wait for this time before scanning for the device in bootloader mode. | <code>0</code> | 1.0.0 |
|
|
206
|
+
| **`scanTimeout`** | <code>number</code> | Sets the scan duration (in milliseconds) when scanning for DFU Bootloader. | <code>5000</code> | 1.0.0 |
|
|
207
|
+
| **`forceScanningForNewAddressInLegacyDfu`** | <code>boolean</code> | When this is set to true, the Legacy Buttonless Service will scan for the device advertising with an incremented MAC address, instead of trying to reconnect to the same device. | <code>false</code> | 1.0.0 |
|
|
208
|
+
| **`disableResume`** | <code>boolean</code> | This options allows to disable the resume feature in Secure DFU. When the extra value is set to true, the DFU will send Init Packet and Data again, despite the firmware might have been send partially before. By default, without setting this extra, or by setting it to false, the DFU will resume the previously cancelled upload if CRC values match. | <code>false</code> | 1.4.0 |
|
|
209
|
+
| **`numberOfRetries`** | <code>number</code> | Sets the number of retries that the DFU service will use to complete DFU. | <code>0</code> | 1.0.0 |
|
|
210
|
+
| **`mtu`** | <code>number</code> | Sets the Maximum Transfer Unit (MTU) value that the Secure DFU service will try to request before performing DFU. **Available for Android only.** By default, value 517 will be used, which is the highest supported y Android. However, as the highest supported MTU by the Secure DFU from SDK 15 (first which supports higher MTU) is 247, the sides will agree on using MTU = 247 instead if the phone supports it (Lollipop or newer device). | | 1.0.0 |
|
|
211
|
+
| **`currentMtu`** | <code>number</code> | Sets the current MTU value. This method should be used only if the device is already connected and MTU has been requested before DFU service is started. **Available for Android only.** | <code>23</code> | 1.0.0 |
|
|
212
|
+
| **`disableMtuRequest`** | <code>boolean</code> | Disables MTU request. **Available for Android only.** | <code>false</code> | 1.4.0 |
|
|
213
|
+
| **`scope`** | <code>number</code> | This method allows to narrow the update to selected parts from the ZIP, for example to allow only application update from a ZIP file that has SD+BL+App. System components scope include the Softdevice and/or the Bootloader (they can't be separated as they are packed in a single bin file and the library does not know whether it contains only the softdevice, the bootloader or both) Application scope includes the application only. | | 1.0.0 |
|
|
214
|
+
| **`mbrSize`** | <code>number</code> | This method sets the size of an MBR (Master Boot Record). It should be used only when updating a file from a HEX file. If you use BIN or ZIP, value set here will be ignored. | <code>4096</code> | 1.0.0 |
|
|
215
|
+
| **`unsafeExperimentalButtonlessServiceInSecureDfuEnabled`** | <code>boolean</code> | Set this flag to true to enable experimental buttonless feature in Secure DFU. When the experimental Buttonless DFU Service is found on a device, the service will use it to switch the device to the bootloader mode, connect to it in that mode and proceed with DFU. | <code>false</code> | 1.0.0 |
|
|
216
|
+
|
|
217
|
+
#### PermissionStatus
|
|
218
|
+
|
|
219
|
+
Represents the current status of permissions in the plugin.
|
|
220
|
+
|
|
221
|
+
| Prop | Type | Description | Since |
|
|
222
|
+
| ------------------- | ----------------------------------------------------------- | ------------------------------------------------ | ----- |
|
|
223
|
+
| **`notifications`** | <code><a href="#permissionstate">PermissionState</a></code> | Indicates the permission state of notifications. | 1.0.0 |
|
|
224
|
+
|
|
225
|
+
#### PluginListenerHandle
|
|
226
|
+
|
|
227
|
+
| Prop | Type |
|
|
228
|
+
| ------------ | ----------------------------------------- |
|
|
229
|
+
| **`remove`** | <code>() => Promise<void></code> |
|
|
230
|
+
|
|
231
|
+
#### DfuUpdate
|
|
232
|
+
|
|
233
|
+
The DFU update object that is passed to the DFUStateChanged event
|
|
234
|
+
|
|
235
|
+
| Prop | Type | Description | Since |
|
|
236
|
+
| ----------- | ------------------------------------------------------- | ------------------------------------------------------------------------------------ | ----- |
|
|
237
|
+
| **`state`** | <code><a href="#dfustate">DfuState</a></code> | Defines the structure for the DFU update object passed to the DFUStateChanged event. | 1.0.0 |
|
|
238
|
+
| **`data`** | <code><a href="#dfuupdatedata">DfuUpdateData</a></code> | The DFU data that is passed to the <a href="#dfuupdate">DfuUpdate</a> object | 1.0.0 |
|
|
239
|
+
|
|
240
|
+
#### DfuUpdateData
|
|
241
|
+
|
|
242
|
+
Contains data related to the DFU update process, such as progress and speed.
|
|
243
|
+
|
|
244
|
+
| Prop | Type | Description | Since |
|
|
245
|
+
| ------------------- | ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----- |
|
|
246
|
+
| **`percent`** | <code>number</code> | The current status of upload (0-99). | 1.0.0 |
|
|
247
|
+
| **`speed`** | <code>number</code> | The current speed in bytes per millisecond. | 1.0.0 |
|
|
248
|
+
| **`avgSpeed`** | <code>number</code> | The average speed in bytes per millisecond. | 1.0.0 |
|
|
249
|
+
| **`currentPart`** | <code>number</code> | The number of parts being sent. In case the ZIP file contains a Soft Device and/or a Bootloader together with the application the SD+BL are sent as part 1, then the service starts again and send the application as part 2. | 1.0.0 |
|
|
250
|
+
| **`partsTotal`** | <code>number</code> | The total number of parts. | 1.0.0 |
|
|
251
|
+
| **`duration`** | <code>number</code> | The total time elapsed since the start of the DFU process in milliseconds | 1.1.0 |
|
|
252
|
+
| **`remainingTime`** | <code>number</code> | The estimated remaining time to the end of the DFU process in milliseconds | 1.1.0 |
|
|
253
|
+
|
|
254
|
+
### Type Aliases
|
|
255
|
+
|
|
256
|
+
#### PermissionState
|
|
257
|
+
|
|
258
|
+
<code>'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'</code>
|
|
259
|
+
|
|
260
|
+
### Enums
|
|
261
|
+
|
|
262
|
+
#### DfuState
|
|
263
|
+
|
|
264
|
+
| Members | Value | Description | Since |
|
|
265
|
+
| -------------------------- | ----------------------------------- | ---------------------------------------------------------------------- | ----- |
|
|
266
|
+
| **`DEVICE_CONNECTING`** | <code>'DEVICE_CONNECTING'</code> | The device is currently connecting. | 1.0.0 |
|
|
267
|
+
| **`DEVICE_CONNECTED`** | <code>'DEVICE_CONNECTED'</code> | The device has successfully connected. **Available for Android only.** | 1.0.0 |
|
|
268
|
+
| **`DFU_PROCESS_STARTING`** | <code>'DFU_PROCESS_STARTING'</code> | The DFU process is about to start. | 1.0.0 |
|
|
269
|
+
| **`DFU_PROCESS_STARTED`** | <code>'DFU_PROCESS_STARTED'</code> | The DFU process has started. **Available for Android only.** | 1.0.0 |
|
|
270
|
+
| **`ENABLING_DFU_MODE`** | <code>'ENABLING_DFU_MODE'</code> | The device is enabling DFU mode. | 1.0.0 |
|
|
271
|
+
| **`DFU_PROGRESS`** | <code>'DFU_PROGRESS'</code> | The DFU process is in progress. | 1.0.0 |
|
|
272
|
+
| **`VALIDATING_FIRMWARE`** | <code>'VALIDATING_FIRMWARE'</code> | The firmware is currently being validated. | 1.0.0 |
|
|
273
|
+
| **`DEVICE_DISCONNECTING`** | <code>'DEVICE_DISCONNECTING'</code> | The device is disconnecting. | 1.0.0 |
|
|
274
|
+
| **`DEVICE_DISCONNECTED`** | <code>'DEVICE_DISCONNECTED'</code> | The device has disconnected. **Available for Android only.** | 1.0.0 |
|
|
275
|
+
| **`DFU_COMPLETED`** | <code>'DFU_COMPLETED'</code> | The DFU process has completed successfully. | 1.0.0 |
|
|
276
|
+
| **`DFU_ABORTED`** | <code>'DFU_ABORTED'</code> | The DFU process has been aborted. | 1.0.0 |
|
|
277
|
+
| **`DFU_FAILED`** | <code>'DFU_FAILED'</code> | The DFU process has failed. | 1.0.0 |
|
|
278
|
+
|
|
279
|
+
</docgen-api>
|
|
280
|
+
|
|
281
|
+
## Contributors
|
|
282
|
+
|
|
283
|
+
<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
|
|
284
|
+
<!-- prettier-ignore-start -->
|
|
285
|
+
<!-- markdownlint-disable -->
|
|
286
|
+
|
|
287
|
+
<!-- markdownlint-restore -->
|
|
288
|
+
<!-- prettier-ignore-end -->
|
|
289
|
+
|
|
290
|
+
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
ext {
|
|
2
|
+
junitVersion = project.hasProperty('junitVersion') ? rootProject.ext.junitVersion : '4.13.2'
|
|
3
|
+
androidxAppCompatVersion = project.hasProperty('androidxAppCompatVersion') ? rootProject.ext.androidxAppCompatVersion : '1.7.0'
|
|
4
|
+
androidxJunitVersion = project.hasProperty('androidxJunitVersion') ? rootProject.ext.androidxJunitVersion : '1.2.1'
|
|
5
|
+
androidxEspressoCoreVersion = project.hasProperty('androidxEspressoCoreVersion') ? rootProject.ext.androidxEspressoCoreVersion : '3.6.1'
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
buildscript {
|
|
9
|
+
ext.kotlin_version = project.hasProperty("kotlin_version") ? rootProject.ext.kotlin_version : '1.9.25'
|
|
10
|
+
ext.coreKtx = project.hasProperty('coreKtx') ? rootProject.ext.coreKtx : '1.12.0'
|
|
11
|
+
|
|
12
|
+
repositories {
|
|
13
|
+
google()
|
|
14
|
+
mavenCentral()
|
|
15
|
+
}
|
|
16
|
+
dependencies {
|
|
17
|
+
classpath 'com.android.tools.build:gradle:8.7.2'
|
|
18
|
+
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
apply plugin: 'com.android.library'
|
|
23
|
+
apply plugin: 'kotlin-android'
|
|
24
|
+
|
|
25
|
+
android {
|
|
26
|
+
namespace "com.example.plugin.nordicdfu"
|
|
27
|
+
compileSdk project.hasProperty('compileSdkVersion') ? rootProject.ext.compileSdkVersion : 35
|
|
28
|
+
defaultConfig {
|
|
29
|
+
minSdkVersion project.hasProperty('minSdkVersion') ? rootProject.ext.minSdkVersion : 23
|
|
30
|
+
targetSdkVersion project.hasProperty('targetSdkVersion') ? rootProject.ext.targetSdkVersion : 35
|
|
31
|
+
versionCode 1
|
|
32
|
+
versionName "1.0"
|
|
33
|
+
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
|
34
|
+
}
|
|
35
|
+
buildTypes {
|
|
36
|
+
release {
|
|
37
|
+
minifyEnabled false
|
|
38
|
+
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
lintOptions {
|
|
42
|
+
abortOnError false
|
|
43
|
+
}
|
|
44
|
+
compileOptions {
|
|
45
|
+
sourceCompatibility JavaVersion.VERSION_21
|
|
46
|
+
targetCompatibility JavaVersion.VERSION_21
|
|
47
|
+
}
|
|
48
|
+
kotlinOptions {
|
|
49
|
+
jvmTarget = 21
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
repositories {
|
|
54
|
+
google()
|
|
55
|
+
mavenCentral()
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
dependencies {
|
|
60
|
+
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
|
61
|
+
implementation project(':capacitor-android')
|
|
62
|
+
implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
|
|
63
|
+
testImplementation "junit:junit:$junitVersion"
|
|
64
|
+
androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
|
|
65
|
+
androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
|
|
66
|
+
implementation "androidx.core:core-ktx:$coreKtx"
|
|
67
|
+
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
|
|
68
|
+
implementation "no.nordicsemi.android:dfu:2.9.0"
|
|
69
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
|
2
|
+
xmlns:tools="http://schemas.android.com/tools">
|
|
3
|
+
|
|
4
|
+
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CONNECTED_DEVICE" />
|
|
5
|
+
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
|
6
|
+
|
|
7
|
+
<application>
|
|
8
|
+
<service
|
|
9
|
+
android:name=".DfuService"
|
|
10
|
+
android:foregroundServiceType="connectedDevice" />
|
|
11
|
+
<activity android:name=".NotificationActivity" />
|
|
12
|
+
</application>
|
|
13
|
+
</manifest>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
package com.example.plugin.nordicdfu;
|
|
2
|
+
|
|
3
|
+
import android.app.Activity;
|
|
4
|
+
import androidx.annotation.NonNull;
|
|
5
|
+
import androidx.core.app.NotificationCompat;
|
|
6
|
+
import no.nordicsemi.android.dfu.BuildConfig;
|
|
7
|
+
import no.nordicsemi.android.dfu.DfuBaseService;
|
|
8
|
+
|
|
9
|
+
public class DfuService extends DfuBaseService {
|
|
10
|
+
|
|
11
|
+
@Override
|
|
12
|
+
protected Class<? extends Activity> getNotificationTarget() {
|
|
13
|
+
/*
|
|
14
|
+
* As a target activity the NotificationActivity is returned, not the
|
|
15
|
+
* MainActivity. This is because the notification must create a new task:
|
|
16
|
+
*
|
|
17
|
+
* intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
|
18
|
+
*
|
|
19
|
+
* when you press it. You can use NotificationActivity to check whether the new
|
|
20
|
+
* activity is a root activity (that means no other activity was open earlier)
|
|
21
|
+
* or that some other activity is already open. In the latter case the
|
|
22
|
+
* NotificationActivity will just be closed. The system will restore the
|
|
23
|
+
* previous activity. However, if the application has been closed during upload
|
|
24
|
+
* and you click the notification, a NotificationActivity will be launched as a
|
|
25
|
+
* root activity. It will create and start the main activity and terminate
|
|
26
|
+
* itself.
|
|
27
|
+
*
|
|
28
|
+
* This method may be used to restore the target activity in case the
|
|
29
|
+
* application was closed or is open. It may also be used to recreate an
|
|
30
|
+
* activity history using startActivities(...).
|
|
31
|
+
*/
|
|
32
|
+
return NotificationActivity.class;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
@Override
|
|
36
|
+
protected boolean isDebug() {
|
|
37
|
+
/*
|
|
38
|
+
* Here return true if you want the service to print more logs in LogCat.
|
|
39
|
+
* Library's BuildConfig in current version of Android Studio is always set to
|
|
40
|
+
* DEBUG=false, so make sure you return true or your.app.BuildConfig.DEBUG here.
|
|
41
|
+
*/
|
|
42
|
+
return BuildConfig.DEBUG;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
@Override
|
|
46
|
+
protected void updateForegroundNotification(@NonNull final NotificationCompat.Builder builder) {
|
|
47
|
+
/*
|
|
48
|
+
* Customize the foreground service notification here.
|
|
49
|
+
*/
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
package com.example.plugin.nordicdfu;
|
|
2
|
+
|
|
3
|
+
import android.content.Context;
|
|
4
|
+
import android.os.Build;
|
|
5
|
+
import androidx.annotation.NonNull;
|
|
6
|
+
import androidx.annotation.Nullable;
|
|
7
|
+
import com.getcapacitor.JSObject;
|
|
8
|
+
import no.nordicsemi.android.dfu.DfuProgressListener;
|
|
9
|
+
import no.nordicsemi.android.dfu.DfuProgressListenerAdapter;
|
|
10
|
+
import no.nordicsemi.android.dfu.DfuServiceInitiator;
|
|
11
|
+
import no.nordicsemi.android.dfu.DfuServiceListenerHelper;
|
|
12
|
+
|
|
13
|
+
public class NordicDfu {
|
|
14
|
+
|
|
15
|
+
interface DfuEventListener {
|
|
16
|
+
void onDfuEvent(String state, @Nullable JSObject data);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
@Nullable
|
|
20
|
+
public DfuEventListener getDFUEventListener() {
|
|
21
|
+
return dfuEventListener;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public void setDFUEventListener(@Nullable DfuEventListener dfuEventListener) {
|
|
25
|
+
this.dfuEventListener = dfuEventListener;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
@Nullable
|
|
29
|
+
private DfuEventListener dfuEventListener;
|
|
30
|
+
|
|
31
|
+
private long startTime = 0;
|
|
32
|
+
|
|
33
|
+
public NordicDfu(Context context) {
|
|
34
|
+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
|
35
|
+
DfuServiceInitiator.createDfuNotificationChannel(context);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
final DfuProgressListener dfuProgressListener = new DfuProgressListenerAdapter() {
|
|
40
|
+
@Override
|
|
41
|
+
public void onDeviceConnecting(@NonNull final String deviceAddress) {
|
|
42
|
+
JSObject ret = new JSObject();
|
|
43
|
+
ret.put("deviceAddress", deviceAddress);
|
|
44
|
+
dfuEventListener.onDfuEvent("DEVICE_CONNECTING", ret);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@Override
|
|
48
|
+
public void onDeviceConnected(@NonNull final String deviceAddress) {
|
|
49
|
+
JSObject ret = new JSObject();
|
|
50
|
+
ret.put("deviceAddress", deviceAddress);
|
|
51
|
+
dfuEventListener.onDfuEvent("DEVICE_CONNECTED", ret);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@Override
|
|
55
|
+
public void onDfuProcessStarting(@NonNull final String deviceAddress) {
|
|
56
|
+
JSObject ret = new JSObject();
|
|
57
|
+
ret.put("deviceAddress", deviceAddress);
|
|
58
|
+
dfuEventListener.onDfuEvent("DFU_PROCESS_STARTING", ret);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
@Override
|
|
62
|
+
public void onDfuProcessStarted(@NonNull final String deviceAddress) {
|
|
63
|
+
startTime = System.currentTimeMillis();
|
|
64
|
+
|
|
65
|
+
JSObject ret = new JSObject();
|
|
66
|
+
ret.put("deviceAddress", deviceAddress);
|
|
67
|
+
dfuEventListener.onDfuEvent("DFU_PROCESS_STARTED", ret);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
@Override
|
|
71
|
+
public void onEnablingDfuMode(@NonNull final String deviceAddress) {
|
|
72
|
+
JSObject ret = new JSObject();
|
|
73
|
+
ret.put("deviceAddress", deviceAddress);
|
|
74
|
+
dfuEventListener.onDfuEvent("ENABLING_DFU_MODE", ret);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@Override
|
|
78
|
+
public void onProgressChanged(
|
|
79
|
+
@NonNull final String deviceAddress,
|
|
80
|
+
final int percent,
|
|
81
|
+
final float speed,
|
|
82
|
+
final float avgSpeed,
|
|
83
|
+
final int currentPart,
|
|
84
|
+
final int partsTotal
|
|
85
|
+
) {
|
|
86
|
+
long currentTime = System.currentTimeMillis();
|
|
87
|
+
long duration = currentTime - startTime;
|
|
88
|
+
long remainingTime = 0;
|
|
89
|
+
|
|
90
|
+
if (percent > 0) {
|
|
91
|
+
long estimatedTotalTime = (duration * 100) / percent;
|
|
92
|
+
remainingTime = estimatedTotalTime - duration;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
JSObject ret = new JSObject();
|
|
96
|
+
ret.put("deviceAddress", deviceAddress);
|
|
97
|
+
ret.put("percent", percent);
|
|
98
|
+
ret.put("speed", speed);
|
|
99
|
+
ret.put("avgSpeed", avgSpeed);
|
|
100
|
+
ret.put("currentPart", currentPart);
|
|
101
|
+
ret.put("partsTotal", partsTotal);
|
|
102
|
+
ret.put("duration", duration);
|
|
103
|
+
ret.put("remainingTime", remainingTime);
|
|
104
|
+
dfuEventListener.onDfuEvent("DFU_PROGRESS", ret);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@Override
|
|
108
|
+
public void onFirmwareValidating(@NonNull final String deviceAddress) {
|
|
109
|
+
JSObject ret = new JSObject();
|
|
110
|
+
ret.put("deviceAddress", deviceAddress);
|
|
111
|
+
dfuEventListener.onDfuEvent("VALIDATING_FIRMWARE", ret);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
@Override
|
|
115
|
+
public void onDeviceDisconnecting(final String deviceAddress) {
|
|
116
|
+
JSObject ret = new JSObject();
|
|
117
|
+
ret.put("deviceAddress", deviceAddress);
|
|
118
|
+
dfuEventListener.onDfuEvent("DEVICE_DISCONNECTING", ret);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
@Override
|
|
122
|
+
public void onDeviceDisconnected(@NonNull final String deviceAddress) {
|
|
123
|
+
JSObject ret = new JSObject();
|
|
124
|
+
ret.put("deviceAddress", deviceAddress);
|
|
125
|
+
dfuEventListener.onDfuEvent("DEVICE_DISCONNECTED", ret);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
@Override
|
|
129
|
+
public void onDfuCompleted(@NonNull final String deviceAddress) {
|
|
130
|
+
JSObject ret = new JSObject();
|
|
131
|
+
ret.put("deviceAddress", deviceAddress);
|
|
132
|
+
dfuEventListener.onDfuEvent("DFU_COMPLETED", ret);
|
|
133
|
+
// TODO: end activity
|
|
134
|
+
// new Handler()
|
|
135
|
+
// .postDelayed(
|
|
136
|
+
// new Runnable() {
|
|
137
|
+
// @Override
|
|
138
|
+
// public void run() {
|
|
139
|
+
// // if this activity is still open and upload process was completed, cancel
|
|
140
|
+
// the notification
|
|
141
|
+
// final NotificationManager manager = (NotificationManager)
|
|
142
|
+
// reactContext.getSystemService(
|
|
143
|
+
// Context.NOTIFICATION_SERVICE
|
|
144
|
+
// );
|
|
145
|
+
// manager.cancel(DfuService.NOTIFICATION_ID);
|
|
146
|
+
// }
|
|
147
|
+
// },
|
|
148
|
+
// 200
|
|
149
|
+
// );
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
@Override
|
|
153
|
+
public void onDfuAborted(@NonNull final String deviceAddress) {
|
|
154
|
+
JSObject ret = new JSObject();
|
|
155
|
+
ret.put("deviceAddress", deviceAddress);
|
|
156
|
+
dfuEventListener.onDfuEvent("DFU_ABORTED", ret);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@Override
|
|
160
|
+
public void onError(@NonNull final String deviceAddress, final int error, final int errorType, final String message) {
|
|
161
|
+
JSObject ret = new JSObject();
|
|
162
|
+
ret.put("deviceAddress", deviceAddress);
|
|
163
|
+
ret.put("error", error);
|
|
164
|
+
ret.put("errorType", errorType);
|
|
165
|
+
ret.put("message", message);
|
|
166
|
+
dfuEventListener.onDfuEvent("DFU_FAILED", ret);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
public void onResume(Context context) {
|
|
171
|
+
DfuServiceListenerHelper.registerProgressListener(context, dfuProgressListener);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public void onPause(Context context) {}
|
|
175
|
+
|
|
176
|
+
public void onDestroy(Context context) {
|
|
177
|
+
DfuServiceListenerHelper.unregisterProgressListener(context, dfuProgressListener);
|
|
178
|
+
}
|
|
179
|
+
}
|