From 1ba07efce2a600875f2723cd474fbea47d7bae10 Mon Sep 17 00:00:00 2001 From: Nerivec <62446222+Nerivec@users.noreply.github.com> Date: Tue, 31 Dec 2024 05:22:01 +0100 Subject: [PATCH] Fix binding table too large corrupting NVM3 on tokens restore --- README.md | 14 ++++++------- package.json | 2 +- src/commands/stack/index.ts | 42 ++++++++++++++++++++++++++++++++++++- 3 files changed, 49 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0be2035..2d8d6cc 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ $ npm install -g ember-zli $ ember-zli COMMAND running command... $ ember-zli (--version) -ember-zli/2.9.3 win32-x64 node-v22.11.0 +ember-zli/2.9.4 win32-x64 node-v22.11.0 $ ember-zli --help [COMMAND] USAGE $ ember-zli COMMAND @@ -61,7 +61,7 @@ EXAMPLES $ ember-zli bootloader ``` -_See code: [src/commands/bootloader/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.3/src/commands/bootloader/index.ts)_ +_See code: [src/commands/bootloader/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.4/src/commands/bootloader/index.ts)_ ## `ember-zli help [COMMAND]` @@ -98,7 +98,7 @@ EXAMPLES $ ember-zli monitor ``` -_See code: [src/commands/monitor/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.3/src/commands/monitor/index.ts)_ +_See code: [src/commands/monitor/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.4/src/commands/monitor/index.ts)_ ## `ember-zli router` @@ -115,7 +115,7 @@ EXAMPLES $ ember-zli router ``` -_See code: [src/commands/router/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.3/src/commands/router/index.ts)_ +_See code: [src/commands/router/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.4/src/commands/router/index.ts)_ ## `ember-zli sniff` @@ -132,7 +132,7 @@ EXAMPLES $ ember-zli sniff ``` -_See code: [src/commands/sniff/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.3/src/commands/sniff/index.ts)_ +_See code: [src/commands/sniff/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.4/src/commands/sniff/index.ts)_ ## `ember-zli stack` @@ -149,7 +149,7 @@ EXAMPLES $ ember-zli stack ``` -_See code: [src/commands/stack/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.3/src/commands/stack/index.ts)_ +_See code: [src/commands/stack/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.4/src/commands/stack/index.ts)_ ## `ember-zli utils` @@ -166,7 +166,7 @@ EXAMPLES $ ember-zli utils ``` -_See code: [src/commands/utils/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.3/src/commands/utils/index.ts)_ +_See code: [src/commands/utils/index.ts](https://github.com/Nerivec/ember-zli/blob/v2.9.4/src/commands/utils/index.ts)_ ## `ember-zli version` diff --git a/package.json b/package.json index 9d0f944..06b22e7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ember-zli", "description": "Interact with EmberZNet-based adapters using zigbee-herdsman 'ember' driver", - "version": "2.9.3", + "version": "2.9.4", "author": "Nerivec", "bin": { "ember-zli": "bin/run.js" diff --git a/src/commands/stack/index.ts b/src/commands/stack/index.ts index e21fd4d..9ad5e18 100644 --- a/src/commands/stack/index.ts +++ b/src/commands/stack/index.ts @@ -986,7 +986,47 @@ export default class Stack extends Command { private async menuTokensRestore(ezsp: Ezsp): Promise { const backupFile = await browseToFile('Tokens backup file location', DEFAULT_TOKENS_BACKUP_PATH) - const tokensBuf = Buffer.from(readFileSync(backupFile, 'utf8'), 'hex') + let tokensBuf = Buffer.from(readFileSync(backupFile, 'utf8'), 'hex') + + { + // check for binding table corrupting NVM3 if size is too large (32 tested as "safe") + let bindingTableMod: undefined | { arraySizeOffset: number; clipStartOffset: number; clipEndOffset: number } + let readOffset: number = 0 + const inTokenCount = tokensBuf.readUInt8(readOffset++) + + for (let i = 0; i < inTokenCount; i++) { + const nvm3Key = tokensBuf.readUInt32LE(readOffset) // 4 bytes Token Key/Creator + readOffset += 4 + const size = tokensBuf.readUInt8(readOffset++) // 1 byte token size + const arraySize = tokensBuf.readUInt8(readOffset++) // 1 byte array size. + + if (nvm3Key === NVM3ObjectKey.STACK_BINDING_TABLE && arraySize > 32) { + logger.warning(`Binding table is too large, which is known to corrupt NVM3, keeping only first 32 entries.`) + + bindingTableMod = { + arraySizeOffset: readOffset - 1, + clipStartOffset: readOffset + 32 * size, + clipEndOffset: readOffset + arraySize * size, + } + } + + readOffset += arraySize * size + } + + if (bindingTableMod) { + tokensBuf[bindingTableMod.arraySizeOffset] = 32 + + const tokensBufStart = tokensBuf.subarray(0, bindingTableMod.clipStartOffset) + const tokensBufEnd = tokensBuf.subarray(bindingTableMod.clipEndOffset) + tokensBuf = Buffer.concat([tokensBufStart, tokensBufEnd]) + const saveFile = `${backupFile}-fixed.nvm3` + + writeFileSync(saveFile, tokensBuf.toString('hex'), 'utf8') + + logger.info(`Fixed tokens backup written to '${saveFile}'.`) + } + } + const status = await EmberTokensManager.restoreTokens(ezsp, tokensBuf) if (status === SLStatus.OK) {