Skip to content

Commit 1635395

Browse files
committed
Update readme
1 parent ccbbd68 commit 1635395

File tree

5 files changed

+171
-42
lines changed

5 files changed

+171
-42
lines changed

ESIM_PROVISION.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Provision a blank eSIM
2+
3+
### Pre-req
4+
5+
1. Input JSON (A JSON file that has a list of EIDs and their respective RSP URLs)
6+
2. Output JSON (A blank file to store logs)
7+
3. lpa tool (lpa tool binary - differently built for mac and windows)
8+
4. binaries (A folder with the user binaries)
9+
10+
## Setup
11+
12+
### Local setup on computer
13+
14+
Put your files in this structure (for example)
15+
16+
```
17+
18+
```
19+
20+
### Device Setup
21+
22+
1. Connect your device(s) to the computer
23+
2. Run this command
24+
```
25+
particle.js esim provision --input /path/to/input.json --output /path/to/output.json --lpa /path/to/lpa-tool --binaries /path/to/binaries --bulk true
26+
```
27+
28+
### Expected Outcome
29+
First, the device(s) are flashed. Once the download process starts on a given device, device will turn its LED into yellow. If the download passes, LED turns green. If the download failed, LED turns red.
30+
31+
### Notes and Warnings

src/cmd/esim.js

Lines changed: 28 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -68,24 +68,15 @@ module.exports = class eSimCommands extends CLICommandBase {
6868

6969
async doProvision(device) {
7070
let provisionOutputLogs = [];
71-
const logAndPush = (message) => {
72-
const messages = Array.isArray(message) ? message : [message];
73-
messages.forEach(msg => {
74-
provisionOutputLogs.push(msg);
75-
if (this.verbose) {
76-
console.log(msg);
77-
}
78-
});
79-
};
8071
const timestamp = new Date().toISOString();
8172
const platform = platformForId(device.specs.productId).name;
8273
const port = device.port;
8374

84-
logAndPush(`${os.EOL}Provisioning device ${device.deviceId} with platform ${platform}`);
75+
provisionOutputLogs.push(`${os.EOL}Provisioning device ${device.deviceId} with platform ${platform}`);
8576

86-
// Flash firmware and retrieve EID
77+
// Flash firmware and wait for AT to work
8778
const flashResp = await this._flashATPassThroughFirmware(device, platform);
88-
logAndPush(...flashResp.output);
79+
provisionOutputLogs.push(...flashResp.output);
8980
if (!flashResp.success) {
9081
await this._changeLed(device, PROVISIONING_FAILURE);
9182
this._addToJson(this.outputJson, {
@@ -98,8 +89,9 @@ module.exports = class eSimCommands extends CLICommandBase {
9889
return;
9990
}
10091

92+
// Get the EID
10193
const eidResp = await this._getEid(port);
102-
logAndPush(...eidResp.output);
94+
provisionOutputLogs.push(...eidResp.output);
10395
if (!eidResp.success) {
10496
await this._changeLed(device, PROVISIONING_FAILURE);
10597
this._addToJson(this.outputJson, {
@@ -112,14 +104,15 @@ module.exports = class eSimCommands extends CLICommandBase {
112104
return;
113105
}
114106
const eid = eidResp.eid;
115-
logAndPush(`EID: ${eid}`);
107+
provisionOutputLogs.push(`EID: ${eid}`);
116108

109+
// Get the profiles for this EID and compare them against the list in the input JSON under the same EID
117110
const matchingEsim = this.inputJsonData.provisioning_data.find(item => item.esim_id === eid);
118111
const iccidFromJson = matchingEsim.profiles.map((profile) => profile.iccid);
119112
const expectedProfilesArray = matchingEsim.profiles;
120113

121114
const profileCmdResp = await this._checkForExistingProfiles(port);
122-
logAndPush(...profileCmdResp.output);
115+
provisionOutputLogs.push(...profileCmdResp.output);
123116
if (!profileCmdResp.success) {
124117
await this._changeLed(device, PROVISIONING_FAILURE);
125118
this._addToJson(this.outputJson, {
@@ -144,7 +137,7 @@ module.exports = class eSimCommands extends CLICommandBase {
144137
// extract the iccids that belong to this EID
145138
const matchingEsim = this.inputJsonData.provisioning_data.find(item => item.esim_id === eid);
146139
if (!matchingEsim) {
147-
logAndPush('No profiles found for the given EID in the input JSON');
140+
provisionOutputLogs.push('No profiles found for the given EID in the input JSON');
148141
this._addToJson(this.outputJson, {
149142
esim_id: eid,
150143
device_id: device.deviceId,
@@ -160,7 +153,7 @@ module.exports = class eSimCommands extends CLICommandBase {
160153
const equal = _.isEqual(_.sortBy(existingIccids), _.sortBy(iccidFromJson));
161154
if (equal) {
162155
this._changeLed(device, PROVISIONING_SUCCESS);
163-
logAndPush('Profiles already provisioned correctly on the device for the given EID');
156+
provisionOutputLogs.push('Profiles already provisioned correctly on the device for the given EID');
164157
this._addToJson(this.outputJson, {
165158
esim_id: eid,
166159
device_id: device.deviceId,
@@ -171,7 +164,7 @@ module.exports = class eSimCommands extends CLICommandBase {
171164
});
172165
return;
173166
} else {
174-
logAndPush('Profiles exist on the device but do not match the profiles in the input JSON');
167+
provisionOutputLogs.push('Profiles exist on the device but do not match the profiles in the input JSON');
175168
await this._changeLed(device, PROVISIONING_FAILURE);
176169
this._addToJson(this.outputJson, {
177170
esim_id: eid,
@@ -186,7 +179,7 @@ module.exports = class eSimCommands extends CLICommandBase {
186179

187180
// Get profiles for this EID from the input JSON
188181
const profileResp = this._getProfiles(eid);
189-
logAndPush(...profileResp.output);
182+
provisionOutputLogs.push(...profileResp.output);
190183
if (!profileResp.success) {
191184
await this._changeLed(device, PROVISIONING_FAILURE);
192185
this._addToJson(this.outputJson, {
@@ -199,17 +192,17 @@ module.exports = class eSimCommands extends CLICommandBase {
199192
return;
200193
}
201194

202-
logAndPush(`${os.EOL}Provisioning the following profiles to EID ${eid}:`);
195+
provisionOutputLogs.push(`${os.EOL}Provisioning the following profiles to EID ${eid}:`);
203196

204197
const profiles = profileResp.profiles;
205198
profiles.forEach((profile, index) => {
206199
const rspUrl = `1\$${profile.smdp}\$${profile.matching_id}`;
207-
logAndPush(`\t${index + 1}. ${profile.provider} (${rspUrl})`);
200+
provisionOutputLogs.push(`\t${index + 1}. ${profile.provider} (${rspUrl})`);
208201
});
209202

203+
// Download each profile and update the JSON output
210204
await this._changeLed(device, PROVISIONING_PROGRESS);
211205

212-
// Download each profile and update the JSON output
213206
const downloadResp = await this._doDownload(profiles, port);
214207
const downloadedProfiles = downloadResp.downloadedProfiles;
215208
const downloadedProfilesArray = downloadedProfiles.map((profile) => {
@@ -220,7 +213,7 @@ module.exports = class eSimCommands extends CLICommandBase {
220213
duration: profile.duration
221214
};
222215
});
223-
logAndPush(...downloadResp.output);
216+
provisionOutputLogs.push(...downloadResp.output);
224217

225218
if (!downloadResp.success) {
226219
await this._changeLed(device, PROVISIONING_FAILURE);
@@ -241,7 +234,7 @@ module.exports = class eSimCommands extends CLICommandBase {
241234
const iccidsOnDeviceAfterDownload = profilesOnDeviceAfterDownload.map((line) => line.split('[')[1].split(',')[0].trim());
242235
const equal = _.isEqual(_.sortBy(iccidsOnDeviceAfterDownload), _.sortBy(iccidFromJson));
243236
if (!equal) {
244-
logAndPush('Profiles did not match after download');
237+
provisionOutputLogs.push('Profiles did not match after download');
245238
await this._changeLed(device, PROVISIONING_FAILURE);
246239
this._addToJson(this.outputJson, {
247240
esim_id: eid,
@@ -268,6 +261,7 @@ module.exports = class eSimCommands extends CLICommandBase {
268261
});
269262

270263
console.log(`${os.EOL}Provisioning complete for EID ${eid}`);
264+
provisionOutputLogs.push(`${os.EOL}Provisioning complete for EID ${eid}`);
271265
}
272266

273267
_validateArgs(args) {
@@ -331,7 +325,7 @@ module.exports = class eSimCommands extends CLICommandBase {
331325
logAndPush('Waiting for the device to reboot...');
332326
await utilities.delay(5000);
333327

334-
// Handle initial logs (temporary workaround)
328+
// Handle initial logs
335329
logAndPush(`${os.EOL}Checking for the AT-OK to work...`);
336330
let atOkReceived = false;
337331
const start = Date.now();
@@ -400,6 +394,7 @@ module.exports = class eSimCommands extends CLICommandBase {
400394
}
401395
}
402396

397+
// Check for profiles that are exsting on the device
403398
async _checkForExistingProfiles(port) {
404399
let outputLogs = [];
405400
const logAndPush = (message) => {
@@ -428,11 +423,11 @@ module.exports = class eSimCommands extends CLICommandBase {
428423
}
429424
}
430425

426+
// Use lpa tool's listProfiles command to get the profiles on the device
431427
async _listProfiles(port) {
432428
try {
433429
const resProfiles = await execa(this.lpa, ['listProfiles', `--serial=${port}`]);
434430
const profilesOutput = resProfiles.stdout;
435-
console.log('[dbg] profilesOutput: ', profilesOutput);
436431

437432
// Extract lines matching the profile format
438433
const profilesList = profilesOutput
@@ -446,6 +441,7 @@ module.exports = class eSimCommands extends CLICommandBase {
446441
}
447442
}
448443

444+
// Get the profiles that match the EID from the input JSON
449445
_getProfiles(eid) {
450446
// Get the profile list that matches the EID that is given by the field eid
451447
let outputLogs = [];
@@ -468,6 +464,9 @@ module.exports = class eSimCommands extends CLICommandBase {
468464
return { success: true, profiles: eidBlock?.profiles, output: outputLogs };
469465
}
470466

467+
// Download profiles to the device
468+
// Profiles are flashed one after another.
469+
// If any profile download fails, the process stops and the device is marked as failed
471470
async _doDownload(profiles, port) {
472471
const outputLogs = [];
473472
const downloadedProfiles = [];
@@ -538,6 +537,8 @@ module.exports = class eSimCommands extends CLICommandBase {
538537
};
539538
}
540539

540+
// Add the output logs to the output JSON file
541+
// If previous data exists, append to it
541542
_addToJson(jsonFile, data) {
542543
try {
543544
// Read and parse existing JSON data
@@ -560,6 +561,7 @@ module.exports = class eSimCommands extends CLICommandBase {
560561
}
561562
}
562563

564+
// Sends a control request to change the LED state
563565
async _changeLed(device, state) {
564566
let outputLogs = [];
565567
let usbDevice;
@@ -575,20 +577,4 @@ module.exports = class eSimCommands extends CLICommandBase {
575577
await usbDevice.close();
576578
}
577579
}
578-
579-
async _getImei(device) {
580-
let outputLogs = [];
581-
let usbDevice;
582-
try {
583-
usbDevice = await usbUtils.getOneUsbDevice({ idOrName: device.deviceId });
584-
const cellInfo = await usbDevice.getCellularInfo({ timeout: 5000 });
585-
outputLogs.push(`IMEI: ${cellInfo?.imei}`);
586-
return { success: true, imei: cellInfo?.imei, output: outputLogs };
587-
} catch (err) {
588-
outputLogs.push(`Failed to get IMEI: ${err.message}`);
589-
return { success: false, output: outputLogs };
590-
} finally {
591-
await usbDevice.close();
592-
}
593-
}
594580
};
Binary file not shown.

test/__fixtures__/esim/input.json

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
{
2+
"provisioning_data": [
3+
{
4+
"esim_id": "89044045116727494900000000232944",
5+
"profiles": [
6+
{
7+
"provider": "skylo",
8+
"esim_profile_id": 2,
9+
"smdp": "smdp-plus-1.eu.cd.rsp.kigen.com",
10+
"matching_id": "EB8C7CA0-878B-4D9B-9F29-7620715B72D6",
11+
"iccid": "89901980101000000201"
12+
13+
},
14+
{
15+
"provider": "kddi",
16+
"esim_profile_id": 3,
17+
"smdp": "h3a.prod.ondemandconnectivity.com",
18+
"matching_id": "0X4S25TZXTBEJPVW2IIZZXU796ZOEJTD",
19+
"iccid": "8943052003855000893"
20+
}
21+
]
22+
},
23+
{
24+
"esim_id": "89044045116727494900000000187063",
25+
"profiles": [
26+
{
27+
"provider": "twilio",
28+
"esim_profile_id": 1,
29+
"smdp": "twl.prod.ondemandconnectivity.com",
30+
"matching_id": "ZCG7E-IJ7R2-P4320-JWKMG",
31+
"iccid": "89883070000051465399"
32+
},
33+
{
34+
"provider": "skylo",
35+
"esim_profile_id": 2,
36+
"smdp": "smdp-plus-1.eu.cd.rsp.kigen.com",
37+
"matching_id": "4ECC316D-B6D4-4E8A-B992-C499CA7C97AD",
38+
"iccid": "89901980101000000227"
39+
40+
},
41+
{
42+
"provider": "kddi",
43+
"esim_profile_id": 3,
44+
"smdp": "h3a.prod.ondemandconnectivity.com",
45+
"matching_id": "FN6CXX6MJI8NNXUU0R0GI96YVIXVLHTY",
46+
"iccid": "8943052003855000927"
47+
}
48+
]
49+
}
50+
]
51+
}

test/__fixtures__/esim/output.json

Lines changed: 61 additions & 0 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)