Skip to content

Commit 8b8c013

Browse files
committed
Fix to addToJson and many minr fixes
1 parent 4c926fa commit 8b8c013

File tree

1 file changed

+139
-96
lines changed

1 file changed

+139
-96
lines changed

src/cmd/esim.js

Lines changed: 139 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -27,18 +27,15 @@ module.exports = class eSimCommands extends CLICommandBase {
2727
async provision(args) {
2828
this._validateArgs(args);
2929

30+
// Get the serial port and device details
3031
const port = await this._getSerialPortForSingleDevice();
31-
32-
// get the device usb handle from the serial port
3332
const device = await this.serial.whatSerialPortDidYouMean(port);
3433
const platform = platformForId(device.specs.productId).name;
3534

3635
console.log(`${os.EOL}Provisioning device ${device.deviceId} with platform ${platform}`);
3736

37+
// Flash firmware and retrieve EID
3838
await this._flashATPassThroughFirmware(device, platform, port);
39-
40-
// This assumes that the input JSON does not have a mapping between EID and profiles
41-
// So obtain the EID from the device and put it in outupt JSON
4239
const eid = await this._getEid(port);
4340
console.log(`${os.EOL}EID: ${eid}`);
4441

@@ -49,59 +46,55 @@ module.exports = class eSimCommands extends CLICommandBase {
4946
const inputJsonData = JSON.parse(input);
5047

5148
// Get the profile list that matches the EID that is given by the field eid
52-
const eidBlock = inputJsonData.EIDs.filter((block) => block.eid === eid);
53-
const profiles = eidBlock[0]?.profiles;
54-
if (profiles.length === 0) {
55-
throw new Error('No profiles to provision in the input json');
49+
const eidBlock = inputJsonData.EIDs.find((block) => block.esim_id === eid);
50+
51+
if (!eidBlock || !eidBlock.profiles || eidBlock.profiles.length === 0) {
52+
throw new Error('No profiles to provision in the input JSON');
5653
}
5754

55+
const profiles = eidBlock?.profiles;
56+
5857
console.log(`${os.EOL}Provisioning the following profiles: `);
59-
let cnt = 0;
60-
for (const profile of profiles) {
61-
cnt++;
62-
const smdp = profile.smdp;
63-
const matchingId = profile.matching_id;
64-
const rspUrl = `1\$${smdp}\$${matchingId}`;
65-
console.log(`\t${cnt}. ${profile.provider} (${rspUrl})`);
66-
}
58+
profiles.forEach((profile, index) => {
59+
const rspUrl = `1\$${profile.smdp}\$${profile.matching_id}`;
60+
console.log(`\t${index + 1}. ${profile.provider} (${rspUrl})`);
61+
});
6762

6863
// Download each profile
69-
cnt = 0;
70-
for (const profile of profiles) {
71-
cnt++;
72-
let iccid = null;
73-
const smdp = profile.smdp;
74-
const matchingId = profile.matching_id;
75-
const rspUrl = `1\$${smdp}\$${matchingId}`;
76-
console.log(`${os.EOL}${cnt}. Downloading ${profile.provider} profile from ${rspUrl}`);
64+
for (const [index, profile] of profiles.entries()) {
65+
const rspUrl = `1\$${profile.smdp}\$${profile.matching_id}`;
66+
console.log(`${os.EOL}${index + 1}. Downloading ${profile.provider} profile from ${rspUrl}`);
7767

7868
const start = Date.now();
79-
80-
const res = await execa(this.lpa, ['download', rspUrl, `--serial=${port}`]);
81-
82-
const end = Date.now();
83-
const timeTaken = (end - start) / 1000;
84-
85-
const output = res.stdout;
86-
if (output.includes('Profile successfully downloaded')) {
87-
console.log(`${os.EOL}\tProfile successfully downloaded in ${timeTaken} sec`);
88-
const iccidLine = output.split('\n').find((line) => line.includes('Profile with ICCID'));
89-
// FIXME: Get the string after the "ICCID" string
90-
iccid = iccidLine.split(' ')[4];
91-
} else {
92-
console.log(`${os.EOL}\tProfile download failed`);
69+
let iccid = null;
70+
71+
try {
72+
const res = await execa(this.lpa, ['download', rspUrl, `--serial=${port}`]);
73+
const timeTaken = ((Date.now() - start) / 1000).toFixed(2);
74+
75+
const output = res.stdout;
76+
if (output.includes('Profile successfully downloaded')) {
77+
console.log(`${os.EOL}\tProfile successfully downloaded in ${timeTaken} sec`);
78+
const iccidLine = output.split('\n').find((line) => line.includes('Profile with ICCID'));
79+
if (iccidLine) {
80+
iccid = iccidLine.split(' ')[4]; // Extract ICCID
81+
}
82+
} else {
83+
console.log(`${os.EOL}\tProfile download failed`);
84+
}
85+
86+
const outputData = {
87+
EID: eid,
88+
provider: profile.provider,
89+
iccid,
90+
time: timeTaken,
91+
output,
92+
};
93+
94+
this._addToJson(this.outputJson, outputData);
95+
} catch (err) {
96+
console.error(`${os.EOL}\tFailed to download profile: ${err.message}`);
9397
}
94-
95-
const outputData = {
96-
EID: eid,
97-
provider: profile.provider,
98-
iccid: iccid,
99-
time: timeTaken,
100-
output: output
101-
};
102-
103-
await this._addToJson(this.outputJson, outputData);
104-
console.log(os.EOL);
10598
}
10699

107100
console.log(`${os.EOL}Provisioning complete`);
@@ -127,79 +120,129 @@ module.exports = class eSimCommands extends CLICommandBase {
127120

128121
async _getSerialPortForSingleDevice() {
129122
const deviceSerialPorts = await usbUtils.getUsbSystemPathsForMac();
130-
if (deviceSerialPorts.length > 1) {
131-
throw new Error('Multiple devices found. Please unplug all but one device or use --bulk option');
132-
}
123+
if (deviceSerialPorts.length !== 1) {
124+
const errorMessage = deviceSerialPorts.length > 1
125+
? 'Multiple devices found. Please unplug all but one device or use the --bulk option.'
126+
: 'No devices found. Please connect a device and try again.';
127+
throw new Error(errorMessage);
128+
}
133129
return deviceSerialPorts[0];
134130
}
135131

136132
async _flashATPassThroughFirmware(device, platform, port) {
137-
// Obtain the pre-compiled firmware binary from local folder
138-
// TODO: Do this with binary inspect for more reliability
133+
// Locate the firmware binary
134+
console.log(`${os.EOL}Locating firmware for platform: ${platform}`);
139135
const fwBinaries = fs.readdirSync(PATH_TO_PASS_THROUGH_BINARIES);
140-
const validBin = fwBinaries.filter((file) => file.endsWith(`${platform}.bin`));
141-
const fwPath = path.join(PATH_TO_PASS_THROUGH_BINARIES, validBin[0]);
136+
const validBin = fwBinaries.find((file) => file.endsWith(`${platform}.bin`));
137+
138+
if (!validBin) {
139+
throw new Error(`No firmware binary found for platform: ${platform}`);
140+
}
141+
142+
const fwPath = path.join(PATH_TO_PASS_THROUGH_BINARIES, validBin);
143+
console.log(`${os.EOL}Found firmware: ${fwPath}`);
142144

143-
// Flash the AT passthrough firmware
144-
console.log(`${os.EOL}Flashing AT passthrough firmware ${fwPath} to the device`);
145+
// Flash the firmware
146+
console.log(`${os.EOL}Flashing AT passthrough firmware to the device...`);
145147
const flashCmdInstance = new FlashCommand();
146-
await flashCmdInstance.flashLocal({ files: [fwPath], applicationOnly: true, verbose: true });
147-
console.log(`${os.EOL}AT passthrough firmware flashed`);
148+
await flashCmdInstance.flashLocal({
149+
files: [fwPath],
150+
applicationOnly: true,
151+
verbose: true,
152+
});
153+
console.log(`${os.EOL}Firmware flashed successfully`);
148154

155+
// Wait for the device to respond
156+
console.log(`${os.EOL}Waiting for device to respond...`);
149157
const deviceResponded = await usbUtils.waitForDeviceToRespond(device.deviceId);
158+
150159
if (!deviceResponded) {
151-
throw new Error('Device did not respond after flashing AT passthrough firmware');
160+
throw new Error('Device did not respond after flashing firmware');
152161
}
153-
console.log(`${os.EOL}Device responded after flashing AT passthrough firmware`);
162+
console.log(`${os.EOL}Device responded successfully`);
154163
await deviceResponded.close();
155164

156-
// FIXME: Use the firmware that does not have initial logs and then remove this block
157-
console.log(`${os.EOL}Wait for the initial logs to clear up`);
165+
// Handle initial logs (temporary workaround)
166+
console.log(`${os.EOL}Clearing initial logs (temporary workaround)...`);
158167
console.log(`${os.EOL}--------------------------------------`);
159168
const monitor = await this.serial.monitorPort({ port, follow: false });
160-
await utilities.delay(30000);
169+
170+
// Wait for logs to clear
171+
await utilities.delay(30000); // 30-second delay
161172
await monitor.stop();
162-
await utilities.delay(5000);
173+
await utilities.delay(5000); // Additional delay to ensure logs are cleared
163174
console.log(`${os.EOL}--------------------------------------`);
164-
console.log(`${os.EOL}Initial logs likely cleared`);
175+
console.log(`${os.EOL}Initial logs cleared`);
165176
}
166177

178+
167179
async _getEid(port) {
168-
console.log(`${os.EOL}Getting EID from the device`);
169-
const resEid = await execa(this.lpa, ['getEid', `--serial=${port}`]);
170-
const eidOutput = resEid.stdout;
171-
let eid = null;
172-
173-
// get the line in eidOutput that starts with "EID: " and then get the next word
174-
eidOutput.split('\n').forEach((line) => {
175-
if (line.startsWith('EID: ')) {
176-
eid = line.split(' ')[1];
180+
console.log(`${os.EOL}Getting EID from the device...`);
181+
182+
try {
183+
const resEid = await execa(this.lpa, ['getEid', `--serial=${port}`]);
184+
const eidOutput = resEid.stdout;
185+
186+
// Find the line starting with "EID: " and extract the EID
187+
const eid = eidOutput
188+
.split('\n')
189+
.find((line) => line.startsWith('EID: '))
190+
?.split(' ')[1];
191+
192+
if (!eid) {
193+
throw new Error('EID not found in the output');
177194
}
178-
});
179-
if (!eid) {
180-
throw new Error('EID not found in the output');
195+
return eid;
196+
} catch (error) {
197+
console.error(`${os.EOL}Failed to retrieve EID: ${error.message}`);
198+
throw error;
181199
}
182-
return eid;
183200
}
184201

185202
async _checkForExistingProfiles(port) {
186-
console.log(`${os.EOL}Checking for existing profiles`);
187-
const resProfiles = await execa(this.lpa, ['listProfiles', `--serial=${port}`]);
188-
const profilesOutput = resProfiles.stdout;
189-
const profilesList = profilesOutput
190-
.split('\n')
191-
.filter((line) => line.match(/^\d+:\[\w+,\s(?:enabled|disabled),\s?\]$/));
192-
// console.log('Profiles list: ', profilesList);
193-
if (profilesList.length > 0) {
194-
throw new Error('Profile(s) already exist. Bad device bucket.');
203+
console.log(`${os.EOL}Checking for existing profiles...`);
204+
205+
try {
206+
const resProfiles = await execa(this.lpa, ['listProfiles', `--serial=${port}`]);
207+
const profilesOutput = resProfiles.stdout;
208+
209+
// Extract lines matching the profile format
210+
const profilesList = profilesOutput
211+
.split('\n')
212+
.filter((line) => line.match(/^\d+:\[\w+,\s(?:enabled|disabled),\s?\]$/));
213+
214+
if (profilesList.length > 0) {
215+
console.error(`${os.EOL}Profile(s) already exist:`, profilesList);
216+
throw new Error('Profile(s) already exist. Device bucket is not clean.');
217+
}
218+
219+
console.log(`${os.EOL}No existing profiles found`);
220+
} catch (error) {
221+
console.error(`${os.EOL}Failed to check for existing profiles: ${error.message}`);
222+
throw error;
195223
}
196-
console.log(`${os.EOL}No existing profiles found`);
197224
}
225+
226+
_addToJson(jsonFile, data) {
227+
try {
228+
// Read and parse existing JSON data
229+
let existingJson = [];
230+
if (fs.existsSync(jsonFile)) {
231+
const existing = fs.readFileSync(jsonFile, 'utf-8');
232+
existingJson = JSON.parse(existing);
233+
if (!Array.isArray(existingJson)) {
234+
throw new Error('Existing JSON data is not an array');
235+
}
236+
}
198237

199-
async _addToJson(jsonFile, data) {
200-
const existing = fs.readFileSync(jsonFile);
201-
const existingJson = JSON.parse(existing);
202-
existingJson.push(data);
203-
fs.writeFileSync(jsonFile, JSON.stringify(existingJson, null, 4));
238+
existingJson.push(data);
239+
240+
// Write updated JSON back to the file with indentation
241+
fs.writeFileSync(jsonFile, JSON.stringify(existingJson, null, 4));
242+
console.log('Data appended successfully');
243+
} catch (error) {
244+
console.error(`Failed to append data to JSON file: ${error.message}`);
245+
}
204246
}
247+
205248
};

0 commit comments

Comments
 (0)