├── .clang-format ├── .clang-tidy ├── .github └── ISSUE_TEMPLATE │ └── custom.md ├── .gitignore ├── .jshintrc ├── .travis.yml ├── CMakeLists.txt ├── LICENSE ├── README.md ├── TODO.txt ├── azure-pipelines.yml ├── build.js ├── cmake ├── apple.cmake ├── clang-dev-tools.cmake ├── gcc.cmake └── msvc.cmake ├── doc ├── api.js └── rtt.js ├── index.js ├── package.json ├── scripts ├── get-jlink.js ├── pre-install.js └── publish-all-prebuilt.js ├── src ├── common.h ├── export.cpp ├── highlevel.cpp ├── highlevel.h ├── highlevel_batons.h ├── highlevel_common.h ├── highlevel_helpers.cpp ├── highlevel_helpers.h ├── libraryloader.h ├── nan_wrap.h ├── osfiles.cpp ├── osfiles.h ├── platform │ ├── linux │ │ ├── libraryloader.cpp │ │ ├── libraryloader_platform.h │ │ └── osfiles.cpp │ ├── osx │ │ ├── libraryloader.cpp │ │ ├── libraryloader_platform.h │ │ └── osfiles.cpp │ └── win │ │ ├── libraryloader.cpp │ │ ├── libraryloader_platform.h │ │ ├── osfiles.cpp │ │ └── win_delay_load_hook.cpp └── utility │ ├── conversion.cpp │ ├── conversion.h │ ├── errormessage.cpp │ ├── errormessage.h │ ├── utility.cpp │ └── utility.h └── test ├── __snapshots__ └── index.test.js.snap ├── generic.test.js ├── hex ├── connectivity_1.1.0_1m_with_s132_3.0.hex ├── modem-dfu-image.zip ├── program.hex ├── rtt.hex ├── while_true_nrf53_application.hex └── while_true_nrf53_network.hex ├── index.test.js ├── modem-dfu-destructive.test.js ├── racecondition.test.js ├── rtt.js ├── rtt.test.js ├── rttfailing.test.js ├── single-device-destructive.test.js └── single-device-non-destructive.test.js /.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | Language: Cpp 3 | AccessModifierOffset: -2 4 | AlignAfterOpenBracket: Align 5 | AlignConsecutiveAssignments: true 6 | AlignConsecutiveDeclarations: false 7 | AlignEscapedNewlines: Right 8 | AlignOperands: true 9 | AlignTrailingComments: true 10 | AllowAllParametersOfDeclarationOnNextLine: false 11 | AllowShortBlocksOnASingleLine: false 12 | AllowShortCaseLabelsOnASingleLine: false 13 | AllowShortFunctionsOnASingleLine: None 14 | AllowShortIfStatementsOnASingleLine: false 15 | AllowShortLoopsOnASingleLine: false 16 | AlwaysBreakAfterDefinitionReturnType: None 17 | AlwaysBreakAfterReturnType: None 18 | AlwaysBreakBeforeMultilineStrings: false 19 | AlwaysBreakTemplateDeclarations: false 20 | BinPackArguments: false 21 | BinPackParameters: false 22 | BraceWrapping: 23 | AfterClass: true 24 | AfterControlStatement: true 25 | AfterEnum: true 26 | AfterFunction: true 27 | AfterNamespace: true 28 | AfterObjCDeclaration: false 29 | AfterStruct: true 30 | AfterUnion: true 31 | AfterExternBlock: false 32 | BeforeCatch: true 33 | BeforeElse: true 34 | IndentBraces: false 35 | SplitEmptyFunction: true 36 | SplitEmptyRecord: true 37 | SplitEmptyNamespace: true 38 | BreakBeforeBinaryOperators: None 39 | BreakBeforeBraces: Custom 40 | BreakBeforeInheritanceComma: false 41 | BreakBeforeTernaryOperators: true 42 | BreakConstructorInitializersBeforeComma: true 43 | BreakConstructorInitializers: BeforeColon 44 | BreakAfterJavaFieldAnnotations: false 45 | BreakStringLiterals: true 46 | ColumnLimit: 120 47 | CommentPragmas: '^ IWYU pragma:' 48 | CompactNamespaces: false 49 | ConstructorInitializerAllOnOneLineOrOnePerLine: false 50 | ConstructorInitializerIndentWidth: 4 51 | ContinuationIndentWidth: 4 52 | Cpp11BracedListStyle: true 53 | DerivePointerAlignment: false 54 | DisableFormat: false 55 | ExperimentalAutoDetectBinPacking: false 56 | FixNamespaceComments: true 57 | ForEachMacros: 58 | - foreach 59 | - Q_FOREACH 60 | - BOOST_FOREACH 61 | IncludeBlocks: Preserve 62 | IncludeCategories: 63 | - Regex: '^"(llvm|llvm-c|clang|clang-c)/' 64 | Priority: 2 65 | - Regex: '^(<|"(gtest|gmock|isl|json)/)' 66 | Priority: 3 67 | - Regex: '.*' 68 | Priority: 1 69 | IncludeIsMainRegex: '(Test)?$' 70 | IndentCaseLabels: true 71 | IndentPPDirectives: None 72 | IndentWidth: 4 73 | IndentWrappedFunctionNames: false 74 | JavaScriptQuotes: Leave 75 | JavaScriptWrapImports: true 76 | KeepEmptyLinesAtTheStartOfBlocks: false 77 | MacroBlockBegin: '' 78 | MacroBlockEnd: '' 79 | MaxEmptyLinesToKeep: 1 80 | NamespaceIndentation: All 81 | ObjCBlockIndentWidth: 2 82 | ObjCSpaceAfterProperty: false 83 | ObjCSpaceBeforeProtocolList: true 84 | PenaltyBreakAssignment: 2 85 | PenaltyBreakBeforeFirstCallParameter: 19 86 | PenaltyBreakComment: 300 87 | PenaltyBreakFirstLessLess: 200 88 | PenaltyBreakString: 1000 89 | PenaltyExcessCharacter: 1000000 90 | PenaltyReturnTypeOnItsOwnLine: 200 91 | PointerAlignment: Middle 92 | ReflowComments: true 93 | SortIncludes: true 94 | SortUsingDeclarations: true 95 | SpaceAfterCStyleCast: false 96 | SpaceAfterTemplateKeyword: true 97 | SpaceBeforeAssignmentOperators: true 98 | SpaceBeforeParens: ControlStatements 99 | SpaceInEmptyParentheses: false 100 | SpacesBeforeTrailingComments: 1 101 | SpacesInAngles: false 102 | SpacesInContainerLiterals: true 103 | SpacesInCStyleCastParentheses: false 104 | SpacesInParentheses: false 105 | SpacesInSquareBrackets: false 106 | Standard: Cpp11 107 | TabWidth: 8 108 | UseTab: Never 109 | -------------------------------------------------------------------------------- /.clang-tidy: -------------------------------------------------------------------------------- 1 | --- 2 | Checks: '*,-llvm-header-guard,-llvm-include-order,-llvm-namespace-comment,-readability-else-after-return,-misc-macro-parentheses,-clang-analyzer-alpha.core.CastToStruct,-modernize-raw-string-literal,-cppcoreguidelines-pro-bounds-array-to-pointer-decay,-cppcoreguidelines-pro-bounds-constant-array-index,-cppcoreguidelines-pro-bounds-pointer-arithmetic,-cppcoreguidelines-pro-type-member-init,-cppcoreguidelines-pro-type-reinterpret-cast,-cppcoreguidelines-pro-type-vararg,-google-readability-namespace-comments,-google-readability-braces-around-statements,-readability-braces-around-statements,-google-readability-todo,-google-runtime-int,-google-runtime-references,-fuchsia-default-arguments,-clang-diagnostic-unknown-warning-option' 3 | HeaderFilterRegex: 'src/.*' 4 | ... 5 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/custom.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Custom issue template 3 | about: Please report bugs and feedback in DevZone 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | Please use the [Nordic DevZone](https://devzone.nordicsemi.com) portal to report bugs, questions or feedback in general. If you would like to suggest code changes, feel free to submit a pull request. 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | *~ 3 | /*.hex 4 | /build/* 5 | /CMakeFiles 6 | /docs 7 | /jest.json 8 | /node_modules 9 | /nrfjprog/ 10 | /nrfjprogdll/ 11 | /package-lock.json 12 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "esnext": true, 3 | "node": true, 4 | "mocha": true 5 | } 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | branches: 2 | only: 3 | - master 4 | - /^v?[0-9]/ 5 | 6 | language: cpp 7 | 8 | filter_secrets: false 9 | 10 | os: 11 | - linux 12 | - osx 13 | - windows 14 | 15 | addons: 16 | apt: 17 | sources: ubuntu-toolchain-r-test 18 | packages: g++-6 ninja-build 19 | homebrew: 20 | packages: ninja 21 | 22 | env: 23 | global: 24 | - NODE_ARCH="64" 25 | matrix: 26 | - NODE_VERSION="8.15.0" 27 | - NODE_VERSION="10.15.0" 28 | - NODE_VERSION="11.7.0" 29 | - NODE_VERSION="8.15.0" npm_config_runtime="electron" npm_config_target="2.0.17" npm_config_disturl="https://atom.io/download/electron" 30 | - NODE_VERSION="10.15.0" npm_config_runtime="electron" npm_config_target="4.0.6" npm_config_disturl="https://atom.io/download/electron" 31 | 32 | matrix: 33 | include: 34 | - os: windows 35 | env: NODE_ARCH="32" NODE_VERSION="8.15.0" 36 | - os: windows 37 | env: NODE_ARCH="32" NODE_VERSION="10.15.0" 38 | - os: windows 39 | env: NODE_ARCH="32" NODE_VERSION="11.7.0" 40 | - os: windows 41 | env: NODE_ARCH="32" NODE_VERSION="8.15.0" npm_config_runtime="electron" npm_config_target="2.0.17" npm_config_disturl="https://atom.io/download/electron" 42 | - os: windows 43 | env: NODE_ARCH="32" NODE_VERSION="10.15.0" npm_config_runtime="electron" npm_config_target="4.0.6" npm_config_disturl="https://atom.io/download/electron" 44 | 45 | before_install: 46 | - | 47 | if [ $TRAVIS_OS_NAME == "windows" ]; then 48 | choco install -y nvm 49 | export NVM_HOME="C:\ProgramData\nvm" 50 | export NVM_SYMLINK="C:\Program Files\nodejs" 51 | export PATH=$PATH:$NVM_HOME:$NVM_SYMLINK 52 | nvm install $NODE_VERSION $NODE_ARCH 53 | nvm use $NODE_VERSION $NODE_ARCH 54 | else 55 | nvm install $NODE_VERSION 56 | nvm use $NODE_VERSION 57 | fi 58 | - | 59 | if [ $TRAVIS_OS_NAME == "linux" ]; then 60 | sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 100 61 | sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/gcc-6 100 62 | fi 63 | 64 | script: 65 | - npm install --build-from-source 66 | - npm run package-prebuilt 67 | - echo tag=$TRAVIS_TAG pullrequest=$TRAVIS_PULL_REQUEST 68 | - | 69 | if [[ "$TRAVIS_TAG" =~ ^v?[0-9] ]] && [[ "$TRAVIS_PULL_REQUEST" == "false" ]]; then 70 | npm run publish-prebuilt 71 | fi 72 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.12) 2 | 3 | # Name of the project (will be the name of the plugin) 4 | project (pc-nrfjprog-js) 5 | 6 | if(APPLE) 7 | set(CMAKE_SKIP_BUILD_RPATH TRUE) 8 | set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 9 | set(CMAKE_MACOSX_RPATH 1) 10 | endif() 11 | 12 | set(CMAKE_BUILD_WITH_INSTALL_RPATH TRUE) 13 | set(CMAKE_INSTALL_RPATH "nrfjprog" "@loader_path" "@loader_path/../../nrfjprog") 14 | 15 | # set(NRF_COMMAND_LINE_TOOLS_CMAKE_PACKAGE_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/nrfjprog/share) 16 | 17 | # message(STATUS "LOCATION: ${NRF_COMMAND_LINE_TOOLS_CMAKE_PACKAGE_LOCATION}") 18 | 19 | # find_package(nRFCommandLineTools 20 | # 10.4.1 EXACT 21 | # REQUIRED 22 | # COMPONENTS nrf::highlevelnrfjprog nrf::nrfjprogdll 23 | # PATHS ${NRF_COMMAND_LINE_TOOLS_CMAKE_PACKAGE_LOCATION} 24 | # ) 25 | 26 | set(CMAKE_CXX_STANDARD 14) 27 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 28 | 29 | # Platform specific 30 | if(MSVC) 31 | include(cmake/msvc.cmake) 32 | elseif(APPLE) 33 | include(cmake/apple.cmake) 34 | else() 35 | include(cmake/gcc.cmake) 36 | endif() 37 | 38 | # Include the local include directories 39 | # include_directories(${PLATFORM_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/nrfjprog/include) 40 | include_directories(${PLATFORM_INCLUDE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/nrfjprog) 41 | 42 | # Essential include files to build a node addon, 43 | # you should add this line in every CMake.js based project. 44 | include_directories(SYSTEM ${CMAKE_JS_INC}) 45 | 46 | # Specify source files 47 | set(SOURCE_FILES 48 | src/export.cpp 49 | src/highlevel_helpers.cpp 50 | src/highlevel.cpp 51 | src/osfiles.cpp 52 | src/utility/conversion.cpp 53 | src/utility/errormessage.cpp 54 | src/utility/utility.cpp 55 | ) 56 | 57 | # This line will tell CMake that we're building a shared library 58 | # named after the project's name 59 | add_library(${PROJECT_NAME} SHARED ${SOURCE_FILES} ${PLATFORM_SOURCE_FILES}) 60 | 61 | # This line will give our library file a .node extension without any "lib" prefix 62 | set_target_properties(${PROJECT_NAME} 63 | PROPERTIES 64 | COMPILE_FLAGS "${CMAKE_CXX_FLAGS} -DBUILDING_NODE_EXTENSION" 65 | PREFIX "" 66 | SUFFIX ".node" 67 | ) 68 | 69 | if(WIN32) 70 | set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_DEFINITIONS "_CRT_SECURE_NO_WARNINGS") 71 | set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "/DELAYLOAD:node.exe") 72 | elseif(APPLE) 73 | set_target_properties(${PROJECT_NAME} PROPERTIES LINK_FLAGS "-framework CoreFoundation -framework IOKit") 74 | set_property(TARGET ${PROJECT_NAME} PROPERTY MACOSX_RPATH ON) 75 | else() 76 | # Assume Linux 77 | # target_link_libraries(${PROJECT_NAME} "udev") 78 | endif() 79 | 80 | if(MSVC) 81 | target_compile_options(${PROJECT_NAME} PRIVATE /W4) 82 | else() 83 | target_compile_options(${PROJECT_NAME} PRIVATE -Wall -Wextra -pedantic) 84 | endif() 85 | 86 | message(STATUS ${NRFJPROG_LIB}) 87 | 88 | 89 | find_library(HIGHLEVEL highlevelnrfjprog PATHS "${CMAKE_SOURCE_DIR}/nrfjprog") 90 | 91 | # Essential library files to link to a node addon, 92 | # you should add this line in every CMake.js based project. 93 | target_link_libraries(${PROJECT_NAME} PRIVATE ${CMAKE_JS_LIB} ${HIGHLEVEL}) 94 | 95 | include (cmake/clang-dev-tools.cmake) 96 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | 3 | All rights reserved. 4 | 5 | Use in source and binary forms, redistribution in binary form only, with 6 | or without modification, are permitted provided that the following conditions 7 | are met: 8 | 9 | 1. Redistributions in binary form, except as embedded into a Nordic 10 | Semiconductor ASA integrated circuit in a product or a software update for 11 | such product, must reproduce the above copyright notice, this list of 12 | conditions and the following disclaimer in the documentation and/or other 13 | materials provided with the distribution. 14 | 15 | 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | contributors may be used to endorse or promote products derived from this 17 | software without specific prior written permission. 18 | 19 | 3. This software, with or without modification, must only be used with a Nordic 20 | Semiconductor ASA integrated circuit. 21 | 22 | 4. Any software provided in binary form under this license must not be reverse 23 | engineered, decompiled, modified and/or disassembled. 24 | 25 | THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # pc-nrfjprog-js 2 | 3 | Node.js library that exposes the functionality of the [nRF Command Line Tools](https://www.nordicsemi.com/Software-and-Tools/Development-Tools/nRF-Command-Line-Tools), used for development, programming, and debugging of Nordic Semiconductor's SoCs (System on Chip). 4 | 5 | ## Installing 6 | 7 | The library can be installed from npm, using: 8 | 9 | npm install pc-nrfjprog-js 10 | 11 | This will pull down precompiled binaries for your platform/runtime environment. If precompiled binaries do not exist, then npm will try to compile them, which requires: 12 | 13 | * Node.js (>=4) 14 | * npm (>=3.7.0) 15 | * CMake (>=2.8.12) 16 | * A C/C++ toolchain 17 | 18 | As part of the installation procedure, pc-nrfjprog-js will check if it can access the nrfjprog libraries, and verify that they are up to date. If not, it will try to install/upgrade these libraries. 19 | 20 | ## Building from source 21 | 22 | The library can be built from source, using: 23 | 24 | npm run build 25 | 26 | The library can be build from source while installing, using: 27 | 28 | npm install --build-from-source 29 | 30 | Building from source requires the tools from Installing to be installed. 31 | 32 | ## Required setup 33 | 34 | [SEGGER J-Link Software](https://www.segger.com/downloads/jlink/#J-LinkSoftwareAndDocumentationPack) must be downloaded and installed. 35 | 36 | If you are seeing errors like `Errorcode: CouldNotLoadDLL (0x3)` then please check that the J-Link library is properly installed. 37 | 38 | ## API documentation 39 | 40 | https://nordicsemiconductor.github.io/pc-nrfjprog-js/ 41 | 42 | ## Example 43 | 44 | ``` 45 | const nrfjprogjs = require('pc-nrfjprog-js'); 46 | 47 | nrfjprogjs.getConnectedDevices(function(err, devices) { 48 | console.log('There are ' + devices.length + ' nRF devices connected.'); 49 | }); 50 | ``` 51 | 52 | ## Tests 53 | 54 | The project has integration tests that run against a devkit/dongle. Note that these tests will erase the contents on the connected devkit/dongle. To run the tests: 55 | 56 | npm test 57 | -------------------------------------------------------------------------------- /TODO.txt: -------------------------------------------------------------------------------- 1 | - Figure out how to handle errors when loading JLinkARM.dll, currently the AddOn just terminates NodeJS. -------------------------------------------------------------------------------- /build.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | const cmakeJS = require('cmake-js'); 38 | const os = require('os'); 39 | 40 | function build(debug, target) 41 | { 42 | const { npm_config_runtime, npm_config_target, npm_config_arch } = process.env; 43 | 44 | const runtime = npm_config_runtime || 'node'; 45 | const runtimeVersion = npm_config_target || process.version.substr(1); 46 | const arch = npm_config_arch || (process.platform === 'win32' ? os.arch() : undefined); 47 | const generator = 'Ninja'; 48 | 49 | const options = { 50 | runtime, 51 | runtimeVersion, 52 | arch, 53 | debug, 54 | preferGnu: true, 55 | target, 56 | generator, 57 | }; 58 | 59 | if (process.platform === 'win32' && target !== 'tidy') { 60 | if (arch === 'ia32') { 61 | options.generator = 'Visual Studio 15 2017'; 62 | } else if (arch === 'x64') { 63 | options.generator = 'Visual Studio 15 2017 Win64'; 64 | } else { 65 | console.log(`${arch} is not supported on Windows`); 66 | } 67 | } 68 | 69 | const buildSystem = new cmakeJS.BuildSystem(options); 70 | buildSystem.rebuild(); 71 | } 72 | 73 | let times = 0; 74 | 75 | function main(args = []) { 76 | const debug = args.includes('--debug'); 77 | const target = args.includes('--target') ? args[args.indexOf('--target') + 1] : undefined; 78 | 79 | try { 80 | build(debug, target); 81 | } catch(e) { 82 | if (e.code != 'MODULE_NOT_FOUND') { 83 | throw e; 84 | } 85 | times += 1; 86 | if (times == 5) { 87 | throw e; 88 | } 89 | setTimeout(() => main(args), 2000); 90 | } 91 | } 92 | 93 | main(process.argv); 94 | -------------------------------------------------------------------------------- /cmake/apple.cmake: -------------------------------------------------------------------------------- 1 | add_compile_options(-pthread -std=c++11) 2 | 3 | set(PLATFORM_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/osx) 4 | 5 | file (GLOB PLATFORM_SOURCE_FILES 6 | src/platform/osx/libraryloader.cpp 7 | src/platform/osx/osfiles.cpp 8 | ) 9 | -------------------------------------------------------------------------------- /cmake/clang-dev-tools.cmake: -------------------------------------------------------------------------------- 1 | if(WIN32) 2 | if (NOT CMAKE_GENERATOR STREQUAL "Ninja") 3 | set(NOT_SUPPORTED_MESSAGE "clang-tidy is only supported with Ninja generator on Microsoft Windows.") 4 | message(STATUS "${NOT_SUPPORTED_MESSAGE}") 5 | 6 | # For the target not to fail: 7 | add_custom_target(tidy COMMAND echo "${NOT_SUPPORTED_MESSAGE}") 8 | return() 9 | else() 10 | find_package (Python COMPONENTS Interpreter) 11 | 12 | if(NOT Python_Interpreter_FOUND) 13 | set(PYTHON_MISSING_MESSAGE "Python interpreter not found, it is required for run-clang-tidy.py") 14 | message(STATUS "${PYTHON_MISSING_MESSAGE}") 15 | add_custom_target(tidy COMMAND echo "${PYTHON_MISSING_MESSAGE}") 16 | return() 17 | endif() 18 | endif() 19 | endif() 20 | 21 | find_program(CLANG_TIDY NAMES run-clang-tidy-7.py run-clang-tidy.py) 22 | 23 | if(NOT CLANG_TIDY) 24 | message(STATUS "Did not find clang-tidy, target tidy is disabled.") 25 | message(STATUS "If clang-tidy is installed, make sure run-clang-tidy.py and clang-tidy is in PATH") 26 | 27 | # For the target not to fail: 28 | add_custom_target(tidy COMMAND echo "Clang-tidy is not installed") 29 | else() 30 | message(STATUS "Found clang-tidy, use \"cmake --build . --target tidy\" to run it.") 31 | 32 | # This will create build/compile_commands.json 33 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) 34 | 35 | # Configuration of rules are picked up from .clang-tidy 36 | message(STATUS "Picking up clang-tidy rules from ${CMAKE_SOURCE_DIR}/.clang-tidy") 37 | set(CLANG_TIDY_ARGS "") 38 | 39 | if (WIN32) 40 | add_custom_target(tidy 41 | COMMAND ${Python_EXECUTABLE} ${CLANG_TIDY} ${CLANG_TIDY_ARGS} . 42 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 43 | ) 44 | else() 45 | add_custom_target(tidy 46 | COMMAND ${CLANG_TIDY} ${CLANG_TIDY_ARGS} . 47 | WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 48 | ) 49 | endif() 50 | endif() 51 | -------------------------------------------------------------------------------- /cmake/gcc.cmake: -------------------------------------------------------------------------------- 1 | add_compile_options( 2 | -Wall 3 | -Wno-effc++ 4 | -Wno-unknown-pragmas 5 | -Wno-undef 6 | -Wstrict-overflow=2 7 | -Wno-long-long 8 | -Wfloat-equal 9 | -Wshadow 10 | -Wpointer-arith 11 | -Wlogical-op 12 | #-H # Used for debugging header dependencies. See https://docs.freebsd.org/info/gcc/gcc.info.Preprocessor_Options.html 13 | ) 14 | 15 | set(PLATFORM_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/linux) 16 | 17 | file (GLOB PLATFORM_SOURCE_FILES 18 | src/platform/linux/libraryloader.cpp 19 | src/platform/linux/osfiles.cpp 20 | ) 21 | -------------------------------------------------------------------------------- /cmake/msvc.cmake: -------------------------------------------------------------------------------- 1 | message(STATUS "WIN32 build.") 2 | 3 | add_definitions( 4 | -D_WIN32_WINNT=0x0502 5 | -DNOMINMAX 6 | ) 7 | 8 | # Issue with VC and disabling of C4200: https://connect.microsoft.com/VisualStudio/feedback/details/1114440 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /wd4200") 10 | 11 | set(PLATFORM_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/src/platform/win) 12 | 13 | file (GLOB PLATFORM_SOURCE_FILES 14 | src/platform/win/libraryloader.cpp 15 | src/platform/win/osfiles.cpp 16 | src/platform/win/win_delay_load_hook.cpp 17 | ) 18 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | const path = require('path'); 38 | const nRFjprog = require('bindings')('pc-nrfjprog-js'); 39 | 40 | const instance = new nRFjprog.nRFjprog(); 41 | 42 | // When this module is bundled with nRFConnect application the location of 43 | // nRFjprog libraries depend on the target platform, therefore we give the 44 | // possibility to nRFConnect to set the expected location via environment 45 | // variable. If not set, the path is expected to be under this module: 46 | const envLibPath = process.env.NRFJPROG_LIBRARY_PATH; 47 | const moduleLibPath = path.join(__dirname, 'nrfjprog'); 48 | 49 | Object.keys(nRFjprog).forEach(key => { 50 | if (key === 'setLibrarySearchPath') { 51 | nRFjprog.setLibrarySearchPath(envLibPath || moduleLibPath); 52 | instance.getLibraryVersion(err => { 53 | if (err) { 54 | // obsolete fallback, only works in some cases 55 | nRFjprog.setLibrarySearchPath(process.cwd()); 56 | } 57 | }); 58 | } else if (key !== 'nRFjprog') { 59 | instance[key] = nRFjprog[key]; 60 | } 61 | }); 62 | 63 | module.exports = instance; 64 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "pc-nrfjprog-js", 3 | "version": "1.7.4", 4 | "description": "Javascript bindings for nrfjprog", 5 | "main": "index.js", 6 | "nrfjprog": { 7 | "version": "10.11.1", 8 | "jlink": "V686f" 9 | }, 10 | "scripts": { 11 | "build": "node build.js", 12 | "tidy": "node build.js --target tidy", 13 | "lint": "jshint api/ test/ && jscs api/ test/", 14 | "clean-prebuilt": "node-pre-gyp clean", 15 | "package-prebuilt": "node-pre-gyp package", 16 | "publish-prebuilt": "node-pre-gyp-github publish", 17 | "install": "node scripts/pre-install.js && ( (which nrfconnect-build && nrfconnect-build fetch-draft) || node-pre-gyp install --fallback-to-build=false || node build.js )", 18 | "docs": "jsdoc doc -t node_modules/minami -R README.md -d docs", 19 | "deploy-docs": "gh-pages -d docs", 20 | "test": "jest --runInBand --verbose --testResultsProcessor jest-bamboo-formatter -- index.test.js", 21 | "test-watch": "jest --watch --runInBand" 22 | }, 23 | "repository": { 24 | "type": "git", 25 | "url": "https://github.com/NordicSemiconductor/pc-nrfjprog-js.git" 26 | }, 27 | "bin": { 28 | "get-jlink": "./scripts/get-jlink.js" 29 | }, 30 | "binary": { 31 | "module_name": "pc-nrfjprog-js", 32 | "module_path": "./build/Release", 33 | "host": "https://github.com/NordicSemiconductor/pc-nrfjprog-js/releases/download/", 34 | "remote_path": "v{version}" 35 | }, 36 | "files": [ 37 | "cmake", 38 | "src", 39 | "scripts", 40 | "build.js", 41 | "CMakeLists.txt", 42 | "index.js" 43 | ], 44 | "author": "Nordic Semiconductor ASA", 45 | "license": "SEE LICENSE IN LICENSE", 46 | "dependencies": { 47 | "axios": "^0.19.0", 48 | "bindings": "^1.5.0", 49 | "chalk": "^2.4.2", 50 | "cmake-js": "^5.3.0", 51 | "commander": "^2.20.0", 52 | "nan": "^2.14.0", 53 | "node-pre-gyp": "^0.13.0", 54 | "regedit": "^3.0.2", 55 | "sander": "^0.6.0", 56 | "semver": "^6.2.0", 57 | "sudo-prompt": "^9.0.0", 58 | "tar": "^4.4.10" 59 | }, 60 | "devDependencies": { 61 | "gh-pages": "^2.0.1", 62 | "jest": "^24.8.0", 63 | "jest-bamboo-formatter": "1.0.1", 64 | "jsdoc": "^3.6.2", 65 | "minami": "^1.2.3", 66 | "node-pre-gyp-github": "1.4.3", 67 | "pc-nrfconnect-build": "github:NordicPlayground/pc-nrfconnect-build#semver:^0.3.0" 68 | }, 69 | "jest": { 70 | "testMatch": [ 71 | "**/test/?(*.)+(test).js?(x)" 72 | ] 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /scripts/get-jlink.js: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 3 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 4 | * 5 | * All rights reserved. 6 | * 7 | * Use in source and binary forms, redistribution in binary form only, with 8 | * or without modification, are permitted provided that the following conditions 9 | * are met: 10 | * 11 | * 1. Redistributions in binary form, except as embedded into a Nordic 12 | * Semiconductor ASA integrated circuit in a product or a software update for 13 | * such product, must reproduce the above copyright notice, this list of 14 | * conditions and the following disclaimer in the documentation and/or other 15 | * materials provided with the distribution. 16 | * 17 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 18 | * contributors may be used to endorse or promote products derived from this 19 | * software without specific prior written permission. 20 | * 21 | * 3. This software, with or without modification, must only be used with a Nordic 22 | * Semiconductor ASA integrated circuit. 23 | * 24 | * 4. Any software provided in binary form under this license must not be reverse 25 | * engineered, decompiled, modified and/or disassembled. 26 | * 27 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 28 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 29 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 30 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 31 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 32 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 33 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 34 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 35 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 36 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 37 | */ 38 | 39 | 'use strict'; 40 | 41 | if (process.platform !== 'win32') { 42 | console.log(`Unsupported platform: '${process.platform}', you need to visit https://www.segger.com/downloads/jlink`); 43 | process.exit(); 44 | } 45 | 46 | const commander = require('commander'); 47 | const axios = require('axios'); 48 | const fs = require('fs'); 49 | const sander = require('sander'); 50 | const path = require('path'); 51 | const sudo = require('sudo-prompt'); 52 | const regedit = require('regedit'); 53 | const crypto = require('crypto'); 54 | const { version, nrfjprog } = require('../package.json'); 55 | 56 | commander 57 | .version(version) 58 | .usage('Utility to download and/or execute the J-Link installer.') 59 | .option('-l, --list', 'only list the installed versions and the required version') 60 | .option('-o, --output ', 'output path, defaults to cwd, if directory it must exist') 61 | .option('-s, --save-as ', '') 62 | .option('-i, --install', 'execute the installer') 63 | .parse(process.argv); 64 | 65 | const minVersion = nrfjprog.jlink; 66 | const filename = `JLink_Windows_${minVersion}.exe`; 67 | const fileUrl = `https://github.com/NordicSemiconductor/pc-nrfjprog-js/releases/download/nrfjprog/${filename}`; 68 | 69 | let destinationFile = path.join(process.cwd(), filename); 70 | 71 | if (commander.output) { 72 | let isDirectory = false; 73 | try { 74 | isDirectory = fs.statSync(commander.output).isDirectory() 75 | } catch(err) {} 76 | destinationFile = isDirectory 77 | ? path.join(commander.output, filename) 78 | : commander.output; 79 | } 80 | 81 | function getCurrentJLinkVersion() { 82 | return new Promise(resolve => { 83 | const reg = 'HKCU\\Software\\SEGGER\\J-Link'; 84 | regedit.list(reg, (err, result) => { 85 | if (err) { 86 | return resolve(); 87 | } 88 | const versions = (result[reg].keys || []).sort(); 89 | console.log('Currently installed J-Link versions:', versions.join(' ')); 90 | return resolve(versions.pop()); 91 | }); 92 | }); 93 | } 94 | 95 | async function downloadChecksum() { 96 | console.log('Downloading', `${fileUrl}.md5`); 97 | const { status, data } = await axios.get(`${fileUrl}.md5`); 98 | if (status !== 200) { 99 | throw new Error(`Unable to download ${fileUrl}.md5. ` + 100 | `Got status code ${status}`); 101 | } 102 | return data.split(' ').shift(); 103 | } 104 | 105 | async function downloadFile() { 106 | const hash = crypto.createHash('md5'); 107 | const expectedChecksum = await downloadChecksum(); 108 | console.log('Downloading', fileUrl); 109 | const { status, data: stream } = await axios.get( 110 | fileUrl, 111 | { responseType: 'stream' }, 112 | ); 113 | if (status !== 200) { 114 | throw new Error(`Unable to download ${fileUrl}. ` + 115 | `Got status code ${status}`); 116 | } 117 | console.log('Saving', destinationFile); 118 | await sander.mkdir(path.dirname(destinationFile)); 119 | return new Promise((resolve, reject) => { 120 | const file = fs.createWriteStream(destinationFile); 121 | stream.pipe(file); 122 | stream.on('data', data => hash.update(data)); 123 | stream.on('error', reject); 124 | stream.on('end', () => { 125 | file.end(); 126 | const calculatedChecksum = hash.digest('hex'); 127 | if (calculatedChecksum !== expectedChecksum) { 128 | fs.unlinkSync(destinationFile); 129 | console.log('Calculated checksum:', calculatedChecksum); 130 | console.log('Expected checksum: ', expectedChecksum); 131 | reject(new Error('Checksum verification failed.')); 132 | } 133 | resolve(); 134 | }); 135 | }); 136 | } 137 | 138 | function installJLink() { 139 | return new Promise(resolve => { 140 | const options = { name: 'JLink installer' }; 141 | return sudo.exec(destinationFile, options, (error, stdout, stderr) => { 142 | if (error) throw error; 143 | console.log(stdout); 144 | resolve(); 145 | }); 146 | }); 147 | } 148 | 149 | Promise.resolve() 150 | .then(() => getCurrentJLinkVersion()) 151 | .then(currentVersion => { 152 | console.log('Minimum version required:', minVersion); 153 | if (commander.list) { 154 | process.exit(); 155 | } 156 | if (currentVersion >= minVersion && commander.install) { 157 | console.log('Installation will be skipped'); 158 | commander.install = false; 159 | } 160 | }) 161 | .then(() => downloadFile(fileUrl)) 162 | .then(() => commander.install && installJLink()) 163 | .catch(error => { 164 | console.error('\n!!! EXCEPTION', error.message); 165 | process.exit(-1); 166 | }) 167 | .then(process.exit); 168 | -------------------------------------------------------------------------------- /scripts/pre-install.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | /* 38 | * nRF5x Command Line Tools (nrfjprog) is required for pc-nrfjprog-js to function. 39 | * This script checks if nrfjprog libraries are found, and installs them if required. 40 | * 41 | * On Linux/macOS, the nrfjprog artifact (tar) is extracted into nrfjprog/ directory. This 42 | * directory will then contain both headers (required when building) and libraries 43 | * (required at runtime). 44 | * 45 | * On Windows, the nrfjprog installer (exe) is run, which installs the libraries and 46 | * headers in Program Files. The pc-nrfjprog-js library will then find the nrfjprog 47 | * libraries by doing a registry lookup. 48 | */ 49 | 50 | 'use strict'; 51 | 52 | const axios = require('axios'); 53 | const tar = require('tar'); 54 | const fs = require('fs'); 55 | const sander = require('sander'); 56 | const path = require('path'); 57 | const semver = require('semver'); 58 | const crypto = require('crypto'); 59 | 60 | const { nrfjprog } = require('../package.json'); 61 | 62 | const DOWNLOAD_DIR = path.join(__dirname, '..', 'nrfjprog'); 63 | const BUILD_DIR = path.join(__dirname, '..', 'build', 'Release'); 64 | const DOWNLOAD_URL = 'https://github.com/NordicSemiconductor/pc-nrfjprog-js/releases/download/nrfjprog'; 65 | 66 | const requiredVersion = nrfjprog.version; 67 | const platform = `${process.platform}_${process.arch}`; 68 | const filename = `nrfjprog-${requiredVersion}-${platform}.tar.gz`; 69 | const fileUrl = `${DOWNLOAD_URL}/${filename}`; 70 | const destinationFile = path.join(DOWNLOAD_DIR, filename); 71 | const skipDownload = process.env.INTERNAL; 72 | const localNrfjprogPath = process.env.LOCAL_NRFJPROG_PATH; 73 | 74 | async function downloadChecksum() { 75 | console.log('Downloading', `${fileUrl}.md5`); 76 | const { status, data } = await axios.get(`${fileUrl}.md5`); 77 | if (status !== 200) { 78 | throw new Error(`Unable to download ${fileUrl}.md5. ` + 79 | `Got status code ${status}`); 80 | } 81 | return data.split(' ').shift(); 82 | } 83 | 84 | async function downloadFile() { 85 | if (skipDownload === 'true') { 86 | console.log('INTERNAL is set to true. Skip downloading nrfjprog.'); 87 | if (localNrfjprogPath) { 88 | console.log(`LOCAL_NRFJPROG_PATH is set to ${localNrfjprogPath}`); 89 | sander.copyFileSync(localNrfjprogPath).to(destinationFile) 90 | } 91 | return Promise.resolve(); 92 | } 93 | 94 | const hash = crypto.createHash('md5'); 95 | const expectedChecksum = await downloadChecksum(); 96 | 97 | console.log(`Downloading nrfjprog from ${fileUrl}...`); 98 | await removeDirIfExists(DOWNLOAD_DIR) 99 | await sander.mkdir(DOWNLOAD_DIR); 100 | 101 | const { status, data: stream } = await axios.get( 102 | `${fileUrl}`, 103 | {responseType: 'stream'} 104 | ); 105 | if (status !== 200) { 106 | throw new Error(`Unable to download ${fileUrl}. ` + 107 | `Got status code ${status}`); 108 | } 109 | 110 | return new Promise((resolve, reject) => { 111 | const file = fs.createWriteStream(destinationFile); 112 | stream.pipe(file); 113 | stream.on('data', data => hash.update(data)); 114 | stream.on('error', reject); 115 | stream.on('end', () => { 116 | file.end(); 117 | const calculatedChecksum = hash.digest('hex'); 118 | if (calculatedChecksum !== expectedChecksum) { 119 | fs.unlinkSync(destinationFile); 120 | console.log('Calculated checksum:', calculatedChecksum); 121 | console.log('Expected checksum: ', expectedChecksum); 122 | reject(new Error('Checksum verification failed.')); 123 | } 124 | resolve(); 125 | }); 126 | }); 127 | } 128 | 129 | function extractTarFile(filePath, outputDir) { 130 | return sander.mkdir(outputDir) 131 | .then(() => tar.extract({ 132 | file: filePath, 133 | strip: 1, 134 | keep: true, 135 | cwd: outputDir, 136 | })); 137 | } 138 | 139 | function getLibraryVersion() { 140 | return new Promise((resolve, reject) => { 141 | try { 142 | // eslint-disable-next-line global-require 143 | const nrfjprog = require('..'); 144 | nrfjprog.getLibraryVersion((err, version) => { 145 | if (err) { 146 | reject(err); 147 | } else { 148 | resolve(version); 149 | } 150 | }); 151 | } catch (ex) { 152 | reject(ex); 153 | } 154 | }); 155 | } 156 | 157 | function removeFileIfExists(filePath) { 158 | if (sander.existsSync(filePath)) { 159 | return sander.unlink(filePath); 160 | } 161 | return Promise.resolve(); 162 | } 163 | 164 | function removeDirIfExists(dirPath) { 165 | if (sander.existsSync(dirPath)) { 166 | return sander.rimraf(dirPath); 167 | } 168 | return Promise.resolve(); 169 | } 170 | 171 | function installNrfjprog(pathToArtifact) { 172 | if (pathToArtifact.endsWith('.tar') || pathToArtifact.endsWith('.tar.gz')) { 173 | console.log(`Extracting ${pathToArtifact} to ${DOWNLOAD_DIR}...`); 174 | return extractTarFile(pathToArtifact, DOWNLOAD_DIR) 175 | .then(() => sander.readdir(DOWNLOAD_DIR)) 176 | .then(files => files.filter(fn => fn.match(/\.(so|dll|dylib)$/))) 177 | .then(files => files.forEach( 178 | fn => sander.symlinkOrCopySync(path.join(DOWNLOAD_DIR, fn)).to(path.join(BUILD_DIR, fn)) 179 | )); 180 | } 181 | return Promise.reject(new Error(`Unsupported nrfjprog artifact: ${pathToArtifact}`)); 182 | } 183 | 184 | let isInstallationRequired = false; 185 | getLibraryVersion() 186 | .then(version => { 187 | const currentVersion = `${version.major}.${version.minor}.${version.revision}`; 188 | if (semver.lt(currentVersion, requiredVersion)) { 189 | console.log(`Found nrfjprog version ${currentVersion}, but ` + 190 | `${requiredVersion} is required`); 191 | isInstallationRequired = true; 192 | } else { 193 | console.log('Found nrfjprog libraries at required version', version); 194 | } 195 | }) 196 | .catch(error => { 197 | console.log(`Validation of nrfjprog libraries failed: ${error.message}`); 198 | isInstallationRequired = true; 199 | }) 200 | .then(() => { 201 | if (isInstallationRequired) { 202 | console.log('Trying to install nrfjprog'); 203 | 204 | let exitCode = 0; 205 | return downloadFile() 206 | // without this sleep windows install fails with EBUSY 207 | .then(() => new Promise(resolve => setTimeout(resolve, 1000))) 208 | .then(() => installNrfjprog(destinationFile)) 209 | .catch(error => { 210 | exitCode = 1; 211 | console.error(`Error when installing nrfjprog libraries: ${error.message}`); 212 | }) 213 | .then(() => removeFileIfExists(destinationFile)) 214 | .catch(error => { 215 | exitCode = 1; 216 | console.error(`Unable to remove downloaded nrfjprog artifact: ${error.message}`); 217 | }) 218 | .then(() => process.exit(exitCode)); 219 | } 220 | return Promise.resolve(); 221 | }); 222 | -------------------------------------------------------------------------------- /scripts/publish-all-prebuilt.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const spawn = require('child_process').spawn; 40 | 41 | /* 42 | * This script builds and publishes precompiled binaries for pc-nrfjprog-js 43 | * to GitHub. Using the platform and arch for the current system, and building 44 | * binaries for all the runtime/version combinations configured below. 45 | */ 46 | 47 | const BUILD_CONFIGS = [ 48 | { 49 | npm_config_runtime: 'node', 50 | npm_config_target: '8.12.0', 51 | }, 52 | { 53 | npm_config_runtime: 'node', 54 | npm_config_target: '6.12.0', 55 | }, 56 | { 57 | npm_config_runtime: 'electron', 58 | npm_config_target: '1.6.7', 59 | npm_config_disturl: 'https://atom.io/download/electron', 60 | }, 61 | { 62 | npm_config_runtime: 'electron', 63 | npm_config_target: '1.8.7', 64 | npm_config_disturl: 'https://atom.io/download/electron', 65 | }, 66 | { 67 | npm_config_runtime: 'electron', 68 | npm_config_target: '2.0.11', 69 | npm_config_disturl: 'https://atom.io/download/electron', 70 | }, 71 | ]; 72 | 73 | function runNpm(args, envVars) { 74 | return new Promise((resolve, reject) => { 75 | const env = Object.assign({}, process.env); 76 | Object.keys(envVars).forEach(key => { 77 | env[key] = envVars[key]; 78 | }); 79 | const options = { 80 | env, 81 | shell: true, 82 | stdio: 'inherit', 83 | }; 84 | spawn('npm', args, options).on('exit', code => { 85 | if (code === 0) { 86 | resolve(); 87 | } else { 88 | reject(new Error(`The npm process exited with code ${code}`)); 89 | } 90 | }); 91 | }); 92 | } 93 | 94 | function cleanPrebuilt(config) { 95 | console.log('Removing any locally existing .node binaries'); 96 | return runNpm(['run', 'clean-prebuilt'], config); 97 | } 98 | 99 | function prebuild(config) { 100 | console.log(`Building ${JSON.stringify(config)}`); 101 | return runNpm(['install'], config); 102 | } 103 | 104 | function packagePrebuilt(config) { 105 | console.log(`Packaging ${JSON.stringify(config)}`); 106 | return runNpm(['run', 'package-prebuilt'], config); 107 | } 108 | 109 | function publishPrebuilt(config) { 110 | console.log(`Publishing ${JSON.stringify(config)}`); 111 | return runNpm(['run', 'publish-prebuilt'], config); 112 | } 113 | 114 | function buildAndPublishAll(configs) { 115 | return configs.reduce((prev, config) => ( 116 | prev.then(() => cleanPrebuilt(config)) 117 | .then(() => prebuild(config)) 118 | .then(() => packagePrebuilt(config)) 119 | .then(() => publishPrebuilt(config)) 120 | ), Promise.resolve()); 121 | } 122 | 123 | if (!process.env.NODE_PRE_GYP_GITHUB_TOKEN) { 124 | console.error('Environment variable NODE_PRE_GYP_GITHUB_TOKEN was not provided. ' + 125 | 'Unable to publish to GitHub.'); 126 | process.exit(1); 127 | } 128 | 129 | buildAndPublishAll(BUILD_CONFIGS) 130 | .catch(error => { 131 | console.error(`Error when building/publishing binaries: ${error.message}.`); 132 | process.exit(1); 133 | }); 134 | -------------------------------------------------------------------------------- /src/common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef COMMON_H 38 | #define COMMON_H 39 | 40 | #include 41 | 42 | #define NAME_MAP_ENTRY(EXP) \ 43 | { \ 44 | EXP, "" #EXP "" \ 45 | } 46 | 47 | // Typedef of name to string with enum name, covers most cases 48 | // TODO: fix this so that a name map have specific enums istead of 49 | using name_map_t = std::map; 50 | 51 | #endif // COMMON_H 52 | -------------------------------------------------------------------------------- /src/export.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | #ifndef EXPORT_H 37 | #define EXPORT_H 38 | 39 | #include "highlevel.h" 40 | #include "nan_wrap.h" 41 | #include "osfiles.h" 42 | 43 | extern "C" { 44 | NAN_MODULE_INIT(init) 45 | { 46 | OSFilesInit(target); 47 | HighLevel::initConsts(target); 48 | HighLevel::Init(target); 49 | } 50 | }; 51 | 52 | NODE_MODULE(pc_nrfjprog, init); 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /src/highlevel.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | #ifndef HIGHLEVEL_H 37 | #define HIGHLEVEL_H 38 | 39 | #include "nan_wrap.h" 40 | 41 | #include 42 | #include 43 | 44 | #include "osfiles.h" 45 | #include "highlevelnrfjprogdll.h" 46 | 47 | #include "highlevel_batons.h" 48 | #include "utility/errormessage.h" 49 | 50 | class HighLevel : public Nan::ObjectWrap 51 | { 52 | public: 53 | static NAN_MODULE_INIT(Init); 54 | static void initConsts(Nan::ADDON_REGISTER_FUNCTION_ARGS_TYPE target); 55 | 56 | private: 57 | explicit HighLevel(); 58 | 59 | static NAN_METHOD(New); 60 | 61 | // Sync methods 62 | 63 | // Async methods 64 | static NAN_METHOD(GetLibraryVersion); // Params: callback(error, libraryversion) 65 | static NAN_METHOD(GetConnectedDevices); // Params: callback(error, connectedDevices) 66 | static NAN_METHOD(GetSerialNumbers); // Params: callback(error, serialnumbers) 67 | 68 | static NAN_METHOD(GetDeviceInfo); // Params: serialnumber, callback(error, deviceinfo) 69 | static NAN_METHOD(GetProbeInfo); // Params: serialnumber, callback(error, probeinfo) 70 | static NAN_METHOD(GetLibraryInfo); // Params: serialnumber, callback(error, libraryinfo) 71 | 72 | static NAN_METHOD(Read); // Params: serialnumber, address, length, callback(error, data) 73 | static NAN_METHOD(ReadU32); // Params: serialnumber, address, callback(error, data) 74 | 75 | static NAN_METHOD(Program); // Params: serialnumber, filename, options {verify, chip_erase_mode, 76 | // qspi_erase_mode, reset}, callback(progress), callback(error) 77 | static NAN_METHOD(ProgramDFU); // Params: serialnumber, filename, callback(progress), 78 | // callback(error) 79 | static NAN_METHOD(ProgramMcuBootDFU); // Params: serialnumber, filename, callback(progress), 80 | // callback(error) 81 | static NAN_METHOD(ProgramModemUartDFU); // Params: serialnumber, filename, callback(progress), 82 | // callback(error) 83 | 84 | static NAN_METHOD(ReadToFile); // Params: serialnumber, filename, options {readram, readcode, 85 | // readuicr, readqspi}, callback(progress), callback(error) 86 | static NAN_METHOD(Verify); // Params: serialnumber, filename, callback(progress), 87 | // callback(error) 88 | static NAN_METHOD(Erase); // Params: serialnumber, options {erase_mode, start_address, 89 | // end_address}, callback(progress), callback(error) 90 | 91 | static NAN_METHOD(Recover); // Params: serialnumber, callback(progress), callback(error) 92 | static NAN_METHOD(Reset); // Params: serialnumber, callback(error) 93 | 94 | static NAN_METHOD(Write); // Params: serialnumber, address, dataarray, callback(error) 95 | static NAN_METHOD(WriteU32); // Params: serialnumber, address, data, callback(error) 96 | 97 | static NAN_METHOD(OpenDevice); // Params: serialnumber, callback(error) 98 | static NAN_METHOD(CloseDevice); // Params: serialnumber, callback(error) 99 | 100 | static NAN_METHOD(RttStart); // Params: serialNumber, { location }, callback(error, down, up) 101 | static NAN_METHOD(RttStop); // Params: callback(error) 102 | 103 | static NAN_METHOD(RttRead); // Params: channelIndex, callback(error, data, raw, time) 104 | static NAN_METHOD(RttWrite); // Params: channelIndex, data, callback(error, writtenlength, time) 105 | 106 | static void CallFunction(Nan::NAN_METHOD_ARGS_TYPE info, 107 | const parse_parameters_function_t &parse, 108 | const execute_function_t &execute, const return_function_t &ret, 109 | const bool hasSerialNumber = false 110 | ); 111 | static void ExecuteFunction(uv_work_t *req); 112 | static void ReturnFunction(uv_work_t *req); 113 | 114 | static void init(v8::Local target); 115 | 116 | static void log(const char *msg); 117 | static void log(const std::string &msg); 118 | static void resetLog(); 119 | 120 | static void progressCallback(const char *process); 121 | static void sendProgress(uv_async_t *handle); 122 | 123 | static bool isRttStarted(Probe_handle_t probe); 124 | static nrfjprogdll_err_t waitForControlBlock(Probe_handle_t probe, bool &isControlBlockFound); 125 | static nrfjprogdll_err_t getChannelInformation(RTTStartBaton *baton, bool &isChannelInformationAvailable); 126 | static nrfjprogdll_err_t rttCleanup(Probe_handle_t probe); 127 | }; 128 | 129 | #endif // __NRFJPROG_H__ 130 | -------------------------------------------------------------------------------- /src/highlevel_batons.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef NRFJPROG_BATONS_H 38 | #define NRFJPROG_BATONS_H 39 | 40 | #include "highlevel_common.h" 41 | #include "highlevel_helpers.h" 42 | #include 43 | #include 44 | #include 45 | 46 | class Baton 47 | { 48 | public: 49 | explicit Baton(const std::string _name, const uint32_t _returnParameterCount, 50 | const bool _mayHaveProgressCallback, const probe_type_t _probeType = DEBUG_PROBE, Probe_handle_t _probe = nullptr) 51 | : returnParameterCount(_returnParameterCount) 52 | , name(_name) 53 | , mayHaveProgressCallback(_mayHaveProgressCallback) 54 | , serialNumber(0) 55 | , coProcessor(CP_APPLICATION) 56 | , result(JsSuccess) 57 | , probeType(_probeType) 58 | , probe(_probe) 59 | , lowlevelError(SUCCESS) 60 | , cpuNeedsReset(false) 61 | { 62 | req = std::make_unique(); 63 | req->data = static_cast(this); 64 | } 65 | 66 | virtual ~Baton() 67 | { 68 | req.reset(); 69 | callback.reset(); 70 | } 71 | 72 | const int32_t returnParameterCount; 73 | const std::string name; 74 | const bool mayHaveProgressCallback; 75 | 76 | uint32_t serialNumber; 77 | coprocessor_t coProcessor; 78 | uint32_t result; 79 | probe_type_t probeType; 80 | Probe_handle_t probe; 81 | nrfjprogdll_err_t lowlevelError; 82 | bool cpuNeedsReset; 83 | 84 | std::chrono::high_resolution_clock::time_point functionStart; 85 | 86 | std::unique_ptr req; 87 | std::unique_ptr callback; 88 | 89 | execute_function_t executeFunction; 90 | return_function_t returnFunction; 91 | 92 | static std::timed_mutex executionMutex; 93 | }; 94 | 95 | class BatonNeedsReset : public Baton 96 | { 97 | public: 98 | BatonNeedsReset(const std::string _name, const uint32_t _returnParameterCount, 99 | const bool _mayHaveProgressCallback, 100 | const probe_type_t _probeType = DEBUG_PROBE, 101 | Probe_handle_t _probe = nullptr) 102 | : Baton(_name, _returnParameterCount, _mayHaveProgressCallback, _probeType, _probe) 103 | { 104 | cpuNeedsReset = true; 105 | } 106 | }; 107 | 108 | class GetLibraryVersionBaton : public Baton 109 | { 110 | public: 111 | GetLibraryVersionBaton() 112 | : Baton("get library version", 1, false) 113 | {} 114 | uint32_t major; 115 | uint32_t minor; 116 | uint32_t revision; 117 | }; 118 | 119 | class GetConnectedDevicesBaton : public Baton 120 | { 121 | public: 122 | GetConnectedDevicesBaton() 123 | : Baton("get connected devices", 1, false) 124 | {} 125 | std::vector> probes; 126 | }; 127 | 128 | class GetSerialNumbersBaton : public Baton 129 | { 130 | public: 131 | GetSerialNumbersBaton() 132 | : Baton("get serial numbers", 1, false) 133 | {} 134 | std::vector serialNumbers; 135 | }; 136 | 137 | class GetDeviceInfoBaton : public Baton 138 | { 139 | public: 140 | GetDeviceInfoBaton() 141 | : Baton("get device info", 1, false) 142 | {} 143 | uint32_t serialNumber; 144 | device_info_t deviceInfo; 145 | }; 146 | 147 | class GetProbeInfoBaton : public Baton 148 | { 149 | public: 150 | GetProbeInfoBaton() 151 | : Baton("get probe info", 1, false) 152 | {} 153 | probe_info_t probeInfo; 154 | }; 155 | 156 | class GetLibraryInfoBaton : public Baton 157 | { 158 | public: 159 | GetLibraryInfoBaton() 160 | : Baton("get library info", 1, false) 161 | {} 162 | library_info_t libraryInfo; 163 | }; 164 | 165 | class GetDeviceVersionBaton : public Baton 166 | { 167 | public: 168 | GetDeviceVersionBaton() 169 | : Baton("get device version", 1, false) 170 | {} 171 | uint32_t serialNumber; 172 | device_version_t deviceVersion; 173 | }; 174 | 175 | class ReadBaton : public BatonNeedsReset 176 | { 177 | public: 178 | ReadBaton() 179 | : BatonNeedsReset("read", 1, false) 180 | {} 181 | 182 | uint32_t address; 183 | uint32_t length; 184 | std::vector data; 185 | }; 186 | 187 | class ReadU32Baton : public BatonNeedsReset 188 | { 189 | public: 190 | ReadU32Baton() 191 | : BatonNeedsReset("read u32", 1, false) 192 | {} 193 | uint32_t address; 194 | uint32_t length; 195 | uint32_t data; 196 | }; 197 | 198 | class ProgramBaton : public BatonNeedsReset 199 | { 200 | public: 201 | ProgramBaton() 202 | : BatonNeedsReset("program", 0, true) 203 | {} 204 | std::string file; 205 | std::string filename; 206 | program_options_t options; 207 | input_format_t inputFormat; 208 | }; 209 | 210 | class ProgramDFUBaton : public BatonNeedsReset 211 | { 212 | public: 213 | ProgramDFUBaton() 214 | : BatonNeedsReset("program", 0, true, DFU_PROBE) 215 | {} 216 | std::string filename; 217 | }; 218 | 219 | class ProgramMcuBootDFUBaton : public Baton 220 | { 221 | public: 222 | ProgramMcuBootDFUBaton() 223 | : Baton("program", 0, true, MCUBOOT_PROBE) 224 | {} 225 | std::string filename; 226 | std::string uart; 227 | uint32_t baudRate; 228 | uint32_t responseTimeout; 229 | }; 230 | 231 | class ProgramModemUartDFUBaton : public Baton 232 | { 233 | public: 234 | ProgramModemUartDFUBaton() 235 | : Baton("program", 0, true, MODEMUARTDFU_PROBE) 236 | {} 237 | std::string filename; 238 | std::string uart; 239 | uint32_t baudRate; 240 | uint32_t responseTimeout; 241 | }; 242 | 243 | class VerifyBaton : public BatonNeedsReset 244 | { 245 | public: 246 | VerifyBaton() 247 | : BatonNeedsReset("verify", 0, true) 248 | {} 249 | std::string filename; 250 | }; 251 | 252 | class ReadToFileBaton : public BatonNeedsReset 253 | { 254 | public: 255 | ReadToFileBaton() 256 | : BatonNeedsReset("read to file", 0, true) 257 | {} 258 | std::string filename; 259 | read_options_t options; 260 | }; 261 | 262 | class EraseBaton : public BatonNeedsReset 263 | { 264 | public: 265 | EraseBaton() 266 | : BatonNeedsReset("erase", 0, true) 267 | {} 268 | erase_action_t erase_mode; 269 | uint32_t start_address; 270 | uint32_t end_address; 271 | }; 272 | 273 | class RecoverBaton : public BatonNeedsReset 274 | { 275 | public: 276 | RecoverBaton() 277 | : BatonNeedsReset("recover", 0, true) 278 | {} 279 | }; 280 | 281 | class ResetBaton : public Baton 282 | { 283 | public: 284 | ResetBaton() 285 | : Baton("reset", 0, false) 286 | {} 287 | }; 288 | 289 | class WriteBaton : public BatonNeedsReset 290 | { 291 | public: 292 | WriteBaton() 293 | : BatonNeedsReset("write", 0, false) 294 | {} 295 | uint32_t address; 296 | std::vector data; 297 | uint32_t length; 298 | }; 299 | 300 | class WriteU32Baton : public BatonNeedsReset 301 | { 302 | public: 303 | WriteU32Baton() 304 | : BatonNeedsReset("write u32", 0, false) 305 | {} 306 | uint32_t address; 307 | uint32_t data; 308 | }; 309 | 310 | class OpenBaton : public Baton 311 | { 312 | public: 313 | OpenBaton() 314 | : Baton("open device long term", 0, false) 315 | {} 316 | }; 317 | 318 | class CloseBaton : public BatonNeedsReset 319 | { 320 | public: 321 | CloseBaton() 322 | : BatonNeedsReset("close opened device", 0, false) 323 | {} 324 | }; 325 | 326 | class RTTStartBaton : public Baton 327 | { 328 | public: 329 | RTTStartBaton() 330 | : Baton("start rtt", 2, false) 331 | {} 332 | std::string toString() 333 | { 334 | std::stringstream stream; 335 | 336 | stream << "Parameters:" << std::endl; 337 | stream << "Serialnumber: " << serialNumber << std::endl; 338 | stream << "Has Controlblock: " << (hasControlBlockLocation ? "true" : "false") << std::endl; 339 | stream << "Controlblock location: " << controlBlockLocation << std::endl; 340 | 341 | return stream.str(); 342 | } 343 | 344 | uint32_t serialNumber; 345 | bool hasControlBlockLocation; 346 | bool foundControlBlock; 347 | uint32_t controlBlockLocation; 348 | 349 | uint32_t clockSpeed; 350 | device_family_t family; 351 | std::string jlinkarmlocation; 352 | 353 | bool foundChannelInformation; 354 | std::vector> upChannelInfo; 355 | std::vector> downChannelInfo; 356 | }; 357 | 358 | class RTTStopBaton : public Baton 359 | { 360 | public: 361 | RTTStopBaton() 362 | : Baton("stop rtt", 0, false) 363 | {} 364 | std::string toString() 365 | { 366 | return "No parameters"; 367 | } 368 | 369 | bool rttNotStarted; 370 | }; 371 | 372 | class RTTReadBaton : public Baton 373 | { 374 | public: 375 | RTTReadBaton() 376 | : Baton("rtt read", 3, false) 377 | {} 378 | std::string toString() 379 | { 380 | std::stringstream stream; 381 | 382 | stream << "Parameters:" << std::endl; 383 | stream << "ChanneldIndex: " << channelIndex << std::endl; 384 | stream << "Length wanted: " << length << std::endl; 385 | stream << "RTT not started: " << rttNotStarted; 386 | 387 | return stream.str(); 388 | } 389 | 390 | uint32_t channelIndex; 391 | uint32_t length; 392 | std::vector data; 393 | 394 | bool rttNotStarted; 395 | }; 396 | 397 | class RTTWriteBaton : public Baton 398 | { 399 | public: 400 | RTTWriteBaton() 401 | : Baton("rtt write", 2, false) 402 | {} 403 | std::string toString() 404 | { 405 | std::stringstream stream; 406 | 407 | stream << "Parameters:" << std::endl; 408 | stream << "ChanneldIndex: " << channelIndex << std::endl; 409 | stream << "Length wanted: " << length << std::endl; 410 | stream << "Data" << data.data() << std::endl; 411 | 412 | return stream.str(); 413 | } 414 | 415 | uint32_t channelIndex; 416 | uint32_t length; 417 | std::vector data; 418 | 419 | bool rttNotStarted; 420 | }; 421 | 422 | #endif 423 | -------------------------------------------------------------------------------- /src/highlevel_common.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef HIGHLEVEL_COMMON_H 38 | #define HIGHLEVEL_COMMON_H 39 | 40 | #include "DllCommonDefinitions.h" 41 | #include "common.h" 42 | #include "highlevelnrfjprogdll.h" 43 | #include "nan_wrap.h" 44 | #include 45 | #include 46 | 47 | typedef enum 48 | { 49 | MCUBOOT_PROBE, 50 | DFU_PROBE, 51 | DEBUG_PROBE, 52 | MODEMUARTDFU_PROBE 53 | } probe_type_t; 54 | 55 | typedef enum 56 | { 57 | INPUT_FORMAT_HEX_FILE, 58 | INPUT_FORMAT_HEX_STRING 59 | } input_format_t; 60 | 61 | typedef enum 62 | { 63 | JsSuccess, 64 | CouldNotFindJlinkDLL, 65 | CouldNotFindJprogDLL, 66 | CouldNotLoadDLL, 67 | CouldNotOpenDevice, 68 | CouldNotResetDevice, 69 | CouldNotCloseDevice, 70 | CouldNotOpenDLL, 71 | CouldNotConnectToDevice, 72 | CouldNotCallFunction, 73 | CouldNotErase, 74 | CouldNotProgram, 75 | CouldNotRead, 76 | CouldNotOpenHexFile, 77 | CouldNotExecuteDueToLoad 78 | } errorcode_t; 79 | 80 | static name_map_t nrfjprog_js_err_map = { 81 | {errorcode_t::JsSuccess, "Success"}, 82 | {errorcode_t::CouldNotFindJlinkDLL, "CouldNotFindJlinkDLL"}, 83 | {errorcode_t::CouldNotFindJprogDLL, "CouldNotFindJprogDLL"}, 84 | {errorcode_t::CouldNotLoadDLL, "CouldNotLoadDLL"}, 85 | {errorcode_t::CouldNotOpenDLL, "CouldNotOpenDLL"}, 86 | {errorcode_t::CouldNotOpenDevice, "CouldNotOpenDevice"}, 87 | {errorcode_t::CouldNotResetDevice, "CouldNotResetDevice"}, 88 | {errorcode_t::CouldNotCloseDevice, "CouldNotCloseDevice"}, 89 | {errorcode_t::CouldNotConnectToDevice, "CouldNotConnectToDevice"}, 90 | {errorcode_t::CouldNotCallFunction, "CouldNotCallFunction"}, 91 | {errorcode_t::CouldNotErase, "CouldNotErase"}, 92 | {errorcode_t::CouldNotProgram, "CouldNotProgram"}, 93 | {errorcode_t::CouldNotRead, "CouldNotRead"}, 94 | {errorcode_t::CouldNotOpenHexFile, "CouldNotOpenHexFile"}, 95 | {errorcode_t::CouldNotExecuteDueToLoad, "Could not execute the function due to too many calls in line"}}; 96 | 97 | static name_map_t nrfjprogdll_err_map = {NAME_MAP_ENTRY(SUCCESS), 98 | NAME_MAP_ENTRY(OUT_OF_MEMORY), 99 | NAME_MAP_ENTRY(INVALID_OPERATION), 100 | NAME_MAP_ENTRY(INVALID_PARAMETER), 101 | NAME_MAP_ENTRY(INVALID_DEVICE_FOR_OPERATION), 102 | NAME_MAP_ENTRY(WRONG_FAMILY_FOR_DEVICE), 103 | NAME_MAP_ENTRY(EMULATOR_NOT_CONNECTED), 104 | NAME_MAP_ENTRY(CANNOT_CONNECT), 105 | NAME_MAP_ENTRY(LOW_VOLTAGE), 106 | NAME_MAP_ENTRY(NO_EMULATOR_CONNECTED), 107 | NAME_MAP_ENTRY(NVMC_ERROR), 108 | NAME_MAP_ENTRY(RECOVER_FAILED), 109 | NAME_MAP_ENTRY(RAM_IS_OFF_ERROR), 110 | NAME_MAP_ENTRY(NOT_AVAILABLE_BECAUSE_PROTECTION), 111 | NAME_MAP_ENTRY(NOT_AVAILABLE_BECAUSE_MPU_CONFIG), 112 | NAME_MAP_ENTRY(JLINKARM_DLL_NOT_FOUND), 113 | NAME_MAP_ENTRY(JLINKARM_DLL_COULD_NOT_BE_OPENED), 114 | NAME_MAP_ENTRY(JLINKARM_DLL_ERROR), 115 | NAME_MAP_ENTRY(JLINKARM_DLL_TOO_OLD), 116 | NAME_MAP_ENTRY(NRFJPROG_SUB_DLL_NOT_FOUND), 117 | NAME_MAP_ENTRY(NRFJPROG_SUB_DLL_COULD_NOT_BE_OPENED), 118 | NAME_MAP_ENTRY(NRFJPROG_SUB_DLL_COULD_NOT_LOAD_FUNCTIONS), 119 | NAME_MAP_ENTRY(VERIFY_ERROR), 120 | NAME_MAP_ENTRY(NOT_IMPLEMENTED_ERROR)}; 121 | 122 | // Forward declare batons 123 | class Baton; 124 | 125 | typedef std::function parse_parameters_function_t; 126 | typedef std::function execute_function_t; 127 | typedef std::function>(Baton *)> return_function_t; 128 | 129 | #endif // __NRFJPROG_COMMON_H__ 130 | -------------------------------------------------------------------------------- /src/highlevel_helpers.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "highlevel_helpers.h" 38 | 39 | #include "utility/conversion.h" 40 | #include "utility/utility.h" 41 | 42 | v8::Local ProbeDetails::ToJs() 43 | { 44 | Nan::EscapableHandleScope scope; 45 | v8::Local obj = Nan::New(); 46 | 47 | Utility::Set(obj, "serialNumber", Convert::toJsNumber(serial_number)); 48 | Utility::Set(obj, "deviceInfo", DeviceInfo(device_info).ToJs()); 49 | Utility::Set(obj, "probeInfo", ProbeInfo(probe_info).ToJs()); 50 | Utility::Set(obj, "libraryInfo", LibraryInfo(library_info).ToJs()); 51 | 52 | return scope.Escape(obj); 53 | } 54 | 55 | v8::Local ProbeInfo::ToJs() 56 | { 57 | Nan::EscapableHandleScope scope; 58 | v8::Local obj = Nan::New(); 59 | 60 | Utility::Set(obj, "serialNumber", Convert::toJsNumber(probe_info.serial_number)); 61 | Utility::Set(obj, "clockSpeedkHz", Convert::toJsNumber(probe_info.clockspeed_khz)); 62 | Utility::Set(obj, "firmwareString", Convert::toJsString(static_cast(probe_info.firmware_string))); 63 | 64 | return scope.Escape(obj); 65 | } 66 | 67 | v8::Local DeviceInfo::ToJs() 68 | { 69 | Nan::EscapableHandleScope scope; 70 | v8::Local obj = Nan::New(); 71 | 72 | Utility::Set(obj, "family", Convert::toJsNumber(device_info.device_family)); 73 | Utility::Set(obj, "deviceType", Convert::toJsNumber(device_info.device_type)); 74 | 75 | /* Code flash info. */ 76 | Utility::Set(obj, "codeAddress", Convert::toJsNumber(device_info.code_address)); 77 | Utility::Set(obj, "codePageSize", Convert::toJsNumber(device_info.code_page_size)); 78 | Utility::Set(obj, "codeSize", Convert::toJsNumber(device_info.code_size)); 79 | 80 | /* Info flash info. */ 81 | Utility::Set(obj, "uicrAddress", Convert::toJsNumber(device_info.uicr_address)); 82 | Utility::Set(obj, "infoPageSize", Convert::toJsNumber(device_info.info_page_size)); 83 | 84 | /* RAM info. */ 85 | Utility::Set(obj, "codeRamPresent", Convert::toJsBool(device_info.code_ram_present)); 86 | Utility::Set(obj, "codeRamAddress", Convert::toJsNumber(device_info.code_ram_address)); 87 | Utility::Set(obj, "dataRamAddress", Convert::toJsNumber(device_info.data_ram_address)); 88 | Utility::Set(obj, "ramSize", Convert::toJsNumber(device_info.ram_size)); 89 | 90 | /* QSPI info. */ 91 | Utility::Set(obj, "qspiPresent", Convert::toJsBool(device_info.qspi_present)); 92 | Utility::Set(obj, "xipAddress", Convert::toJsNumber(device_info.xip_address)); 93 | Utility::Set(obj, "xipSize", Convert::toJsNumber(device_info.xip_size)); 94 | 95 | /* Pin reset. */ 96 | Utility::Set(obj, "pinResetPin", Convert::toJsNumber(device_info.pin_reset_pin)); 97 | 98 | return scope.Escape(obj); 99 | } 100 | 101 | v8::Local LibraryInfo::ToJs() 102 | { 103 | Nan::EscapableHandleScope scope; 104 | v8::Local obj = Nan::New(); 105 | v8::Local versionObj = Nan::New(); 106 | 107 | Utility::Set(versionObj, "major", Convert::toJsNumber(library_info.version_major)); 108 | Utility::Set(versionObj, "minor", Convert::toJsNumber(library_info.version_minor)); 109 | Utility::Set(versionObj, "revision", Convert::toJsString(&library_info.version_revision, 1)); 110 | 111 | Utility::Set(obj, "version", versionObj); 112 | Utility::Set(obj, "path", Convert::toJsString(static_cast(library_info.file_path))); 113 | 114 | return scope.Escape(obj); 115 | } 116 | 117 | EraseOptions::EraseOptions(v8::Local obj) 118 | : eraseMode(ERASE_ALL) 119 | , startAddress(0) 120 | , endAddress(0) 121 | { 122 | if (Utility::Has(obj, "erase_mode")) 123 | { 124 | eraseMode = static_cast(Convert::getNativeUint32(obj, "erase_mode")); 125 | } 126 | 127 | if (Utility::Has(obj, "start_address")) 128 | { 129 | startAddress = Convert::getNativeUint32(obj, "start_address"); 130 | } 131 | else if (Utility::Has(obj, "start_adress")) 132 | { 133 | // Legacy support - the right name for the option is "start aDDress". This 134 | // code block is here to let software using the old (and wrong) spelling work still. 135 | startAddress = Convert::getNativeUint32(obj, "start_adress"); 136 | } 137 | 138 | if (Utility::Has(obj, "end_address")) 139 | { 140 | endAddress = Convert::getNativeUint32(obj, "end_address"); 141 | } 142 | } 143 | 144 | ReadToFileOptions::ReadToFileOptions(v8::Local obj) 145 | : options() 146 | { 147 | options.readram = false; 148 | options.readcode = true; 149 | options.readuicr = false; 150 | options.readqspi = false; 151 | 152 | if (Utility::Has(obj, "readram")) 153 | { 154 | options.readram = Convert::getBool(obj, "readram"); 155 | } 156 | 157 | if (Utility::Has(obj, "readcode")) 158 | { 159 | options.readcode = Convert::getBool(obj, "readcode"); 160 | } 161 | 162 | if (Utility::Has(obj, "readuicr")) 163 | { 164 | options.readuicr = Convert::getBool(obj, "readuicr"); 165 | } 166 | 167 | if (Utility::Has(obj, "readqspi")) 168 | { 169 | options.readqspi = Convert::getBool(obj, "readqspi"); 170 | } 171 | } 172 | 173 | ProgramOptions::ProgramOptions(v8::Local obj) 174 | : options() 175 | , inputFormat(INPUT_FORMAT_HEX_FILE) 176 | { 177 | options.verify = VERIFY_READ; 178 | options.chip_erase_mode = ERASE_ALL; 179 | options.qspi_erase_mode = ERASE_NONE; 180 | options.reset = RESET_SYSTEM; 181 | 182 | if (Utility::Has(obj, "verify")) 183 | { 184 | const bool verify = Convert::getBool(obj, "verify"); 185 | options.verify = verify ? VERIFY_READ : VERIFY_NONE; 186 | } 187 | 188 | if (Utility::Has(obj, "chip_erase_mode")) 189 | { 190 | options.chip_erase_mode = static_cast(Convert::getNativeUint32(obj, "chip_erase_mode")); 191 | } 192 | 193 | if (Utility::Has(obj, "qspi_erase_mode")) 194 | { 195 | options.qspi_erase_mode = static_cast(Convert::getNativeUint32(obj, "qspi_erase_mode")); 196 | } 197 | 198 | if (Utility::Has(obj, "reset")) 199 | { 200 | const bool reset = Convert::getBool(obj, "reset"); 201 | options.reset = reset ? RESET_SYSTEM : RESET_NONE; 202 | } 203 | 204 | if (Utility::Has(obj, "inputFormat")) 205 | { 206 | inputFormat = static_cast(Convert::getNativeUint32(obj, "inputFormat")); 207 | } 208 | } 209 | 210 | VerifyOptions::VerifyOptions(v8::Local) 211 | { 212 | } 213 | 214 | v8::Local ChannelInfo::ToJs() 215 | { 216 | Nan::EscapableHandleScope scope; 217 | v8::Local obj = Nan::New(); 218 | 219 | Utility::Set(obj, "channelIndex", Convert::toJsNumber(channelIndex)); 220 | Utility::Set(obj, "direction", Convert::toJsNumber(direction)); 221 | Utility::Set(obj, "name", Convert::toJsString(name)); 222 | Utility::Set(obj, "size", Convert::toJsNumber(size)); 223 | 224 | return scope.Escape(obj); 225 | } 226 | 227 | StartOptions::StartOptions(v8::Local obj) 228 | { 229 | hasControlBlockLocation = false; 230 | 231 | if (Utility::Has(obj, "controlBlockLocation")) 232 | { 233 | hasControlBlockLocation = true; 234 | controlBlockLocation = Convert::getNativeUint32(obj, "controlBlockLocation"); 235 | } 236 | } 237 | -------------------------------------------------------------------------------- /src/highlevel_helpers.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef HIGHLEVEL_HELPERS_H 38 | #define HIGHLEVEL_HELPERS_H 39 | 40 | #include "highlevel_common.h" 41 | #include "highlevelnrfjprogdll.h" 42 | #include "nan_wrap.h" 43 | 44 | class ProbeDetails 45 | { 46 | public: 47 | ProbeDetails(uint32_t _serial_number, device_info_t _device_info, probe_info_t _probe_info, 48 | library_info_t _library_info) 49 | : serial_number(_serial_number) 50 | , device_info(_device_info) 51 | , probe_info(_probe_info) 52 | , library_info(_library_info) 53 | {} 54 | 55 | v8::Local ToJs(); 56 | 57 | private: 58 | const uint32_t serial_number; 59 | const device_info_t device_info; 60 | const probe_info_t probe_info; 61 | const library_info_t library_info; 62 | }; 63 | 64 | class ProbeInfo 65 | { 66 | public: 67 | ProbeInfo(probe_info_t _probe_info) 68 | : probe_info(_probe_info) 69 | {} 70 | 71 | v8::Local ToJs(); 72 | 73 | private: 74 | const probe_info_t probe_info; 75 | }; 76 | 77 | class DeviceInfo 78 | { 79 | public: 80 | DeviceInfo(device_info_t _device_info) 81 | : device_info(_device_info) 82 | {} 83 | 84 | v8::Local ToJs(); 85 | 86 | private: 87 | const device_info_t device_info; 88 | }; 89 | 90 | class LibraryInfo 91 | { 92 | public: 93 | LibraryInfo(library_info_t _library_info) 94 | : library_info(_library_info) 95 | {} 96 | 97 | v8::Local ToJs(); 98 | 99 | private: 100 | const library_info_t library_info; 101 | }; 102 | 103 | class EraseOptions 104 | { 105 | public: 106 | EraseOptions(v8::Local obj); 107 | 108 | erase_action_t eraseMode; 109 | uint32_t startAddress; 110 | uint32_t endAddress; 111 | }; 112 | 113 | class ReadToFileOptions 114 | { 115 | public: 116 | ReadToFileOptions(v8::Local obj); 117 | 118 | read_options_t options; 119 | }; 120 | 121 | class ProgramOptions 122 | { 123 | public: 124 | ProgramOptions(v8::Local obj); 125 | 126 | program_options_t options; 127 | input_format_t inputFormat; 128 | }; 129 | 130 | // RTT related helpers 131 | class ChannelInfo 132 | { 133 | public: 134 | ChannelInfo(uint32_t _channelIndex, rtt_direction_t _direction, std::string &_name, 135 | const uint32_t _size) 136 | : channelIndex(_channelIndex) 137 | , direction(_direction) 138 | , name(_name) 139 | , size(_size) 140 | {} 141 | 142 | v8::Local ToJs(); 143 | 144 | private: 145 | const uint32_t channelIndex; 146 | const rtt_direction_t direction; 147 | const std::string name; 148 | const uint32_t size; 149 | }; 150 | 151 | class StartOptions 152 | { 153 | public: 154 | StartOptions(v8::Local obj); 155 | 156 | uint32_t controlBlockLocation; 157 | bool hasControlBlockLocation; 158 | }; 159 | 160 | class VerifyOptions 161 | { 162 | public: 163 | VerifyOptions(v8::Local); 164 | }; 165 | 166 | #endif 167 | -------------------------------------------------------------------------------- /src/libraryloader.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef LIBRARY_LOADER_H 38 | #define LIBRARY_LOADER_H 39 | 40 | #include "libraryloader_platform.h" 41 | #include 42 | 43 | LoadedFunctionType LoadFunction(LibraryHandleType, const char *func_name); 44 | 45 | template 46 | static bool load_func_ptr(T *func_ptr, const char *func_name, LibraryHandleType libraryHandle) 47 | { 48 | *func_ptr = (T)LoadFunction(libraryHandle, func_name); 49 | 50 | if (*func_ptr == nullptr) 51 | { 52 | return false; 53 | } 54 | 55 | return true; 56 | } 57 | 58 | LibraryHandleType LibraryLoad(const std::string &path); 59 | void LibraryFree(LibraryHandleType libraryHandle); 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/nan_wrap.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #ifdef _MSC_VER 4 | #pragma warning( push ) 5 | #pragma warning( disable : 4251 4275 ) 6 | #endif 7 | 8 | #include 9 | 10 | #ifdef _MSC_VER 11 | #pragma warning( pop ) 12 | #endif -------------------------------------------------------------------------------- /src/osfiles.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "osfiles.h" 38 | 39 | #include 40 | #include 41 | 42 | void OSFilesInit(v8::Local target) 43 | { 44 | Nan::SetMethod(target, "setLibrarySearchPath", OSFilesSetLibrarySearchPath); 45 | } 46 | 47 | FileFormatHandler::FileFormatHandler(const std::string & fileinfo, input_format_t inputFormat) 48 | { 49 | if (inputFormat == INPUT_FORMAT_HEX_STRING) 50 | { 51 | file = std::unique_ptr(new TempFile(fileinfo)); 52 | } 53 | else 54 | { 55 | file = std::unique_ptr(new LocalFile(fileinfo)); 56 | } 57 | } 58 | 59 | std::string FileFormatHandler::getFileName() 60 | { 61 | return file->getFileName(); 62 | } 63 | 64 | bool FileFormatHandler::exists() 65 | { 66 | return AbstractFile::pathExists(getFileName()); 67 | } 68 | 69 | std::string FileFormatHandler::errormessage() 70 | { 71 | return file->errormessage(); 72 | } 73 | 74 | std::string AbstractFile::getFileName() 75 | { 76 | return filename; 77 | } 78 | 79 | bool AbstractFile::pathExists(const std::string & path) 80 | { 81 | return pathExists(path.c_str()); 82 | } 83 | 84 | TempFile::TempFile(const std::string & fileContent) 85 | : error(TempNoError) 86 | { 87 | filename = writeTempFile(fileContent); 88 | } 89 | 90 | TempFile::~TempFile() 91 | { 92 | deleteFile(); 93 | } 94 | 95 | std::string TempFile::writeTempFile(const std::string & fileContent) 96 | { 97 | std::string filePath = getTempFileName(); 98 | 99 | if (filePath.empty()) 100 | { 101 | return std::string(); 102 | } 103 | 104 | std::ofstream outputfile; 105 | outputfile.open(filePath, std::ios_base::out | std::ios_base::trunc | std::ios_base::binary); 106 | outputfile << fileContent; 107 | outputfile.close(); 108 | 109 | return filePath; 110 | } 111 | 112 | std::string TempFile::errormessage() 113 | { 114 | switch (error) 115 | { 116 | case TempPathNotFound: 117 | return "Could not find a location to store the temp file"; 118 | case TempCouldNotCreateFile: 119 | return "Could not create the temporary file"; 120 | case TempNoError: 121 | default: 122 | break; 123 | } 124 | return "No error"; 125 | } 126 | 127 | LocalFile::LocalFile(const std::string & fileName) 128 | { 129 | filename = fileName; 130 | } 131 | 132 | std::string LocalFile::errormessage() 133 | { 134 | return "Could not find the file " + filename; 135 | } 136 | -------------------------------------------------------------------------------- /src/osfiles.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef OS_FILES_H 38 | #define OS_FILES_H 39 | 40 | #include "highlevel_common.h" 41 | 42 | #include 43 | 44 | #include "nan_wrap.h" 45 | 46 | #define COMMON_MAX_PATH (4096) /* Arbitrarily selected MAX_PATH for every platform. */ 47 | #define COMMON_MAX_COMMAND_LINE \ 48 | (8191) /* Arbitrarily selected MAX_COMMAND_LINE_LENGTH for every platform, according to limit \ 49 | \ \ 50 | \ \ \ 51 | for windows: \ \ \ 52 | http://stackoverflow.com/questions/3205027/maximum-length-of-command-line-string. */ 53 | #define COMMON_MAX_INI_LINE (1024) 54 | 55 | void OSFilesInit(v8::Local target); 56 | 57 | NAN_METHOD(OSFilesSetLibrarySearchPath); 58 | errorcode_t OSFilesFindLibrary(std::string &libraryPath, const std::string &fileName); 59 | std::string getHighLevelLibraryName(); 60 | std::string getnrfjprogLibraryName(); 61 | 62 | class AbstractFile 63 | { 64 | public: 65 | virtual ~AbstractFile(){}; 66 | 67 | std::string getFileName(); 68 | virtual std::string errormessage() = 0; 69 | 70 | static bool pathExists(const std::string &path); 71 | static bool pathExists(const char *path); 72 | 73 | protected: 74 | std::string filename; 75 | }; 76 | 77 | class LocalFile : public AbstractFile 78 | { 79 | public: 80 | LocalFile(const std::string &fileName); 81 | virtual std::string errormessage() override; 82 | }; 83 | 84 | class TempFile : public AbstractFile 85 | { 86 | public: 87 | TempFile(const std::string &fileContent); 88 | virtual ~TempFile() override; 89 | virtual std::string errormessage() override; 90 | 91 | private: 92 | std::string writeTempFile(const std::string &fileContent); 93 | std::string getTempFileName(); 94 | void deleteFile(); 95 | 96 | enum TempFileErrorcode { TempNoError, TempPathNotFound, TempCouldNotCreateFile } error; 97 | }; 98 | 99 | class FileFormatHandler 100 | { 101 | public: 102 | FileFormatHandler(const std::string &fileinfo, input_format_t inputFormat); 103 | 104 | std::string getFileName(); 105 | bool exists(); 106 | std::string errormessage(); 107 | 108 | private: 109 | std::unique_ptr file; 110 | }; 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /src/platform/linux/libraryloader.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "../../libraryloader.h" 38 | 39 | #include 40 | #include 41 | 42 | LoadedFunctionType LoadFunction(LibraryHandleType libraryHandle, const char * func_name) 43 | { 44 | return dlsym(libraryHandle, func_name); 45 | } 46 | 47 | LibraryHandleType LibraryLoad(const std::string & path) 48 | { 49 | return dlopen(path.c_str(), RTLD_LAZY); 50 | } 51 | 52 | void LibraryFree(LibraryHandleType libraryHandle) 53 | { 54 | if (libraryHandle != nullptr) 55 | { 56 | dlclose(libraryHandle); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/platform/linux/libraryloader_platform.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef LIBRARYLOADER_PLATFORM_H 38 | #define LIBRARYLOADER_PLATFORM_H 39 | 40 | typedef void * LoadedFunctionType; 41 | typedef void * LibraryHandleType; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/platform/linux/osfiles.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "../../osfiles.h" 38 | #include "../../utility/conversion.h" 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | #include 49 | 50 | #include 51 | 52 | #include 53 | 54 | std::string * pLibrarySearchPath = nullptr; 55 | 56 | // NAN_METHOD is a macro; it's shorthand so you don't have to write that the 57 | // first and only parameter is of type Nan::FunctionCallbackInfo 58 | NAN_METHOD(OSFilesSetLibrarySearchPath) 59 | { 60 | static std::string librarySearchPath; 61 | pLibrarySearchPath = &librarySearchPath; 62 | 63 | // Parse parameter from the FunctionCallbackInfo received 64 | if (info.Length() > 0 && info[0]->IsString()) 65 | { 66 | librarySearchPath.assign(Convert::getNativeString(info[0])); 67 | } 68 | else 69 | { 70 | Nan::ThrowError(Nan::New("Expected string as the first argument").ToLocalChecked()); 71 | } 72 | } 73 | 74 | /* Try to locate a dynamically-linked library named fileName, and set libraryPath 75 | * to the full path to that library. 76 | */ 77 | errorcode_t OSFilesFindLibrary(std::string & libraryPath, const std::string & fileName) 78 | { 79 | std::vector tempLibraryPath(COMMON_MAX_PATH, '\0'); 80 | 81 | // Fetch path of currently running executable 82 | ssize_t len; 83 | len = readlink("/proc/self/exe", tempLibraryPath.data(), COMMON_MAX_PATH - 1); 84 | 85 | if (len == -1) 86 | { 87 | return errorcode_t::CouldNotFindJprogDLL; 88 | } 89 | 90 | // If there is a file with the requested fileName in the same path as the 91 | // current node.js (or electron) executable, use that. 92 | libraryPath.append(dirname(tempLibraryPath.data())); 93 | libraryPath.append("/"); 94 | libraryPath.append(fileName); 95 | if (AbstractFile::pathExists(libraryPath)) 96 | { 97 | return errorcode_t::JsSuccess; 98 | } 99 | 100 | // Try the path specified from calling OSFilesSetLibrarySearchPath 101 | if (pLibrarySearchPath != nullptr) 102 | { 103 | libraryPath.assign(*pLibrarySearchPath); 104 | } 105 | else 106 | { 107 | libraryPath.assign(""); 108 | } 109 | libraryPath.append("/"); 110 | libraryPath.append(fileName); 111 | if (AbstractFile::pathExists(libraryPath)) 112 | { 113 | return errorcode_t::JsSuccess; 114 | } 115 | 116 | // Last recourse, try loading the library through dlopen(). 117 | // That will look into /usr/lib and into whatever LD_LIBRARY_PATH looks into. 118 | void * libraryHandle = dlopen(fileName.c_str(), RTLD_LAZY); 119 | 120 | if (libraryHandle != nullptr) 121 | { 122 | dlclose(libraryHandle); 123 | libraryPath = fileName; 124 | return errorcode_t::JsSuccess; 125 | } 126 | 127 | // If the library hasn't been found, return JLinkARMDllNotFoundError 128 | return errorcode_t::CouldNotFindJprogDLL; 129 | } 130 | 131 | bool AbstractFile::pathExists(const char * path) 132 | { 133 | struct stat buffer 134 | { 135 | }; 136 | return ((0 == stat(path, &buffer))); 137 | } 138 | 139 | /* Return the temp folder found by checking TMPDIR, TMP, TEMP, or TEMPDIR. If none of these are 140 | * valid, "/tmp" is returned. */ 141 | std::string OSFilesGetTempFolderPath() 142 | { 143 | static const std::vector temp_keys = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; 144 | 145 | for (const std::string & temp_key : temp_keys) 146 | { 147 | char * val = getenv(temp_key.c_str()); 148 | 149 | if (val != nullptr) 150 | { 151 | return std::string(val); 152 | } 153 | } 154 | 155 | return std::string("/tmp"); 156 | } 157 | 158 | /* Return a valid, unique file name in the temp folder. 159 | * The temp folder is found by checking TMPDIR, TMP, TEMP, or TEMPDIR. If none of these are found, 160 | * "/tmp" is used. */ 161 | std::string TempFile::getTempFileName() 162 | { 163 | std::string tempFileNameTemplate = OSFilesGetTempFolderPath() + "/nRFXXXXXX.hex"; 164 | 165 | std::vector tempFileName(COMMON_MAX_PATH, '\0'); 166 | 167 | strncpy(tempFileName.data(), tempFileNameTemplate.c_str(), COMMON_MAX_PATH); 168 | 169 | int temp_file = mkstemps(tempFileName.data(), 4); 170 | 171 | if (temp_file == -1) 172 | { 173 | error = TempCouldNotCreateFile; 174 | return std::string(); 175 | } 176 | 177 | /* mkstemps returns an opened file descriptor. */ 178 | close(temp_file); 179 | 180 | return std::string(tempFileName.data()); 181 | } 182 | 183 | void TempFile::deleteFile() 184 | { 185 | if (pathExists(filename)) 186 | { 187 | remove(filename.c_str()); 188 | } 189 | 190 | filename.clear(); 191 | } 192 | 193 | std::string getHighLevelLibraryName() 194 | { 195 | return std::string("libhighlevelnrfjprog.so"); 196 | } 197 | 198 | std::string getnrfjprogLibraryName() 199 | { 200 | return std::string("libnrfjprogdll.so"); 201 | } 202 | -------------------------------------------------------------------------------- /src/platform/osx/libraryloader.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "../../libraryloader.h" 38 | 39 | #include 40 | #include 41 | 42 | LoadedFunctionType LoadFunction(LibraryHandleType libraryHandle, const char * func_name) 43 | { 44 | return dlsym(libraryHandle, func_name); 45 | } 46 | 47 | LibraryHandleType LibraryLoad(const std::string & path) 48 | { 49 | return dlopen(path.c_str(), RTLD_LAZY); 50 | } 51 | 52 | void LibraryFree(LibraryHandleType libraryHandle) 53 | { 54 | if (libraryHandle) 55 | { 56 | dlclose(libraryHandle); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/platform/osx/libraryloader_platform.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef LIBRARYLOADER_PLATFORM_H 38 | #define LIBRARYLOADER_PLATFORM_H 39 | 40 | typedef void * LoadedFunctionType; 41 | typedef void * LibraryHandleType; 42 | 43 | #endif 44 | -------------------------------------------------------------------------------- /src/platform/osx/osfiles.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "../../osfiles.h" 38 | #include "../../utility/conversion.h" 39 | 40 | #include 41 | 42 | #include 43 | #include 44 | #include 45 | #include 46 | 47 | #include 48 | #include 49 | 50 | #include 51 | 52 | #include // proc pidpathinfo maxsize 53 | 54 | std::string * pLibrarySearchPath = nullptr; 55 | 56 | NAN_METHOD(OSFilesSetLibrarySearchPath) 57 | { 58 | static std::string librarySearchPath; 59 | pLibrarySearchPath = &librarySearchPath; 60 | 61 | // Parse parameter from the FunctionCallbackInfo received 62 | if (info.Length() > 0 && info[0]->IsString()) 63 | { 64 | librarySearchPath.assign(Convert::getNativeString(info[0])); 65 | } 66 | else 67 | { 68 | Nan::ThrowError(Nan::New("Expected string as the first argument").ToLocalChecked()); 69 | } 70 | } 71 | 72 | errorcode_t OSFilesFindLibrary(std::string & libraryPath, const std::string & fileName) 73 | { 74 | int ret; 75 | pid_t pid; 76 | std::vector pathbuf(PROC_PIDPATHINFO_MAXSIZE, '\0'); 77 | 78 | // Fetch path of currently running executable 79 | pid = getpid(); 80 | ret = proc_pidpath(pid, pathbuf.data(), PROC_PIDPATHINFO_MAXSIZE - 1); 81 | 82 | if (ret <= 0) 83 | { 84 | // PID not found, error 85 | return errorcode_t::CouldNotFindJprogDLL; 86 | } 87 | 88 | // If there is a file with the requested fileName in the same path as the 89 | // current node.js (or electron) executable, use that. 90 | libraryPath.append(dirname(pathbuf.data())); 91 | libraryPath.append("/"); 92 | libraryPath.append(fileName); 93 | if (AbstractFile::pathExists(libraryPath)) 94 | { 95 | return errorcode_t::JsSuccess; 96 | } 97 | 98 | // Try the path specified from calling OSFilesSetLibrarySearchPath 99 | if (pLibrarySearchPath != nullptr) 100 | { 101 | libraryPath.assign(*pLibrarySearchPath); 102 | } 103 | else 104 | { 105 | libraryPath.assign(""); 106 | } 107 | libraryPath.append("/"); 108 | libraryPath.append(fileName); 109 | if (AbstractFile::pathExists(libraryPath)) 110 | { 111 | return errorcode_t::JsSuccess; 112 | } 113 | 114 | // Last recourse, try loading the library through dlopen(). 115 | // That will look into /usr/lib and into whatever LD_LIBRARY_PATH looks into. 116 | void * libraryHandle = dlopen(fileName.c_str(), RTLD_LAZY); 117 | 118 | if (libraryHandle) 119 | { 120 | dlclose(libraryHandle); 121 | libraryPath = fileName; 122 | return errorcode_t::JsSuccess; 123 | } 124 | 125 | return errorcode_t::CouldNotFindJprogDLL; 126 | } 127 | 128 | bool AbstractFile::pathExists(const char * path) 129 | { 130 | struct stat buffer; 131 | return ((0 == stat(path, &buffer))); 132 | } 133 | 134 | /* Return the temp folder found by checking TMPDIR, TMP, TEMP, or TEMPDIR. If none of these are 135 | * valid, "/tmp" is returned. */ 136 | std::string OSFilesGetTempFolderPath(void) 137 | { 138 | std::string tempKeys[4] = {"TMPDIR", "TMP", "TEMP", "TEMPDIR"}; 139 | 140 | for (uint32_t i = 0; i < 4; i++) 141 | { 142 | char * val = getenv(tempKeys[i].c_str()); 143 | 144 | if (val != NULL) 145 | { 146 | return std::string(val); 147 | } 148 | } 149 | 150 | return std::string("/tmp"); 151 | } 152 | 153 | /* Return a valid, unique file name in the temp folder. 154 | * The temp folder is found by checking TMPDIR, TMP, TEMP, or TEMPDIR. If none of these are found, 155 | * "/tmp" is used. */ 156 | std::string TempFile::getTempFileName() 157 | { 158 | std::string tempFileNameTemplate = OSFilesGetTempFolderPath() + "/nRFXXXXXX.hex"; 159 | 160 | std::vector tempFileName(COMMON_MAX_PATH, '\0'); 161 | 162 | strncpy(tempFileName.data(), tempFileNameTemplate.c_str(), COMMON_MAX_PATH); 163 | 164 | int temp_file = mkstemps(tempFileName.data(), 4); 165 | 166 | if (temp_file == -1) 167 | { 168 | error = TempCouldNotCreateFile; 169 | return std::string(); 170 | } 171 | 172 | /* mkstemps returns an opened file descriptor. */ 173 | close(temp_file); 174 | 175 | return std::string(tempFileName.data()); 176 | } 177 | 178 | void TempFile::deleteFile() 179 | { 180 | if (pathExists(filename)) 181 | { 182 | remove(filename.c_str()); 183 | } 184 | 185 | filename.clear(); 186 | } 187 | 188 | std::string getHighLevelLibraryName() 189 | { 190 | return std::string("libhighlevelnrfjprog.dylib"); 191 | } 192 | 193 | std::string getnrfjprogLibraryName() 194 | { 195 | return std::string("libnrfjprogdll.dylib"); 196 | } 197 | -------------------------------------------------------------------------------- /src/platform/win/libraryloader.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include 38 | 39 | #include "../../libraryloader.h" 40 | 41 | #include 42 | 43 | LoadedFunctionType LoadFunction(LibraryHandleType libraryHandle, const char * func_name) 44 | { 45 | return GetProcAddress(libraryHandle, func_name); 46 | } 47 | 48 | LibraryHandleType LibraryLoad(const std::string & path) 49 | { 50 | const int wchars_num = MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, nullptr, 0); 51 | auto wstr = std::vector(wchars_num); 52 | MultiByteToWideChar(CP_UTF8, 0, path.c_str(), -1, wstr.data(), wchars_num); 53 | 54 | return LoadLibraryW(wstr.data()); 55 | } 56 | 57 | void LibraryFree(LibraryHandleType libraryHandle) 58 | { 59 | if (libraryHandle != nullptr) 60 | { 61 | FreeLibrary(libraryHandle); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /src/platform/win/libraryloader_platform.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef LIBRARYLOADER_PLATFORM_H 38 | #define LIBRARYLOADER_PLATFORM_H 39 | 40 | #include 41 | 42 | typedef FARPROC LoadedFunctionType; 43 | typedef HMODULE LibraryHandleType; 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /src/platform/win/osfiles.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef _CRT_SECURE_NO_WARNINGS 38 | #define _CRT_SECURE_NO_WARNINGS 39 | #endif 40 | 41 | #include 42 | #include 43 | 44 | #include "../../osfiles.h" 45 | #include "../../utility/conversion.h" 46 | 47 | #include "../../nan_wrap.h" 48 | 49 | #include "Shlwapi.h" 50 | #include 51 | 52 | #pragma comment(lib, "Shlwapi.lib") 53 | 54 | #define MAX_KEY_LENGTH 1000 55 | #define MAX_VALUE_NAME 1000 56 | 57 | std::string * pLibrarySearchPath = nullptr; 58 | 59 | NAN_METHOD(OSFilesSetLibrarySearchPath) 60 | { 61 | static std::string librarySearchPath; 62 | pLibrarySearchPath = &librarySearchPath; 63 | 64 | // Parse parameter from the FunctionCallbackInfo received 65 | if (info.Length() > 0 && info[0]->IsString()) 66 | { 67 | librarySearchPath.assign(Convert::getNativeString(info[0])); 68 | } 69 | else 70 | { 71 | Nan::ThrowError(Nan::New("Expected string as the first argument").ToLocalChecked()); 72 | } 73 | } 74 | 75 | errorcode_t OSFilesFindLibrary(std::string & libraryPath, const std::string & fileName) 76 | { 77 | // Try to find the DLLs from the path given to OSFilesSetLibrarySearchPath() 78 | if (pLibrarySearchPath != nullptr) 79 | { 80 | libraryPath.assign(*pLibrarySearchPath); 81 | } 82 | else 83 | { 84 | libraryPath.assign(""); 85 | } 86 | libraryPath.append("\\"); 87 | libraryPath.append(fileName); 88 | if (AbstractFile::pathExists(libraryPath)) 89 | { 90 | return errorcode_t::JsSuccess; 91 | } 92 | 93 | return errorcode_t::CouldNotFindJprogDLL; 94 | } 95 | 96 | bool AbstractFile::pathExists(const char * path) 97 | { 98 | const int wchars_num = MultiByteToWideChar(CP_UTF8, 0, path, -1, nullptr, 0); 99 | auto wstr = std::vector(wchars_num); 100 | MultiByteToWideChar(CP_UTF8, 0, path, -1, wstr.data(), wchars_num); 101 | 102 | return PathFileExistsW(wstr.data()) == TRUE; 103 | } 104 | 105 | std::string TempFile::getTempFileName() 106 | { 107 | /* Folder name should never be longer than MAX_PATH-14 characters to be compatible with 108 | * GetTempFileName function. */ 109 | std::vector tempFolderPath(MAX_PATH); 110 | std::vector tempFilePath(MAX_PATH); 111 | 112 | const DWORD pathLength = GetTempPath(MAX_PATH, tempFolderPath.data()); 113 | 114 | if (pathLength > MAX_PATH || (pathLength == 0)) 115 | { 116 | error = TempPathNotFound; 117 | return std::string(); 118 | } 119 | 120 | if (GetTempFileName(tempFolderPath.data(), TEXT("NRF"), 0, tempFilePath.data()) == 0) 121 | { 122 | error = TempCouldNotCreateFile; 123 | return std::string(); 124 | } 125 | 126 | return std::string(tempFilePath.data()); 127 | } 128 | 129 | void TempFile::deleteFile() 130 | { 131 | if (pathExists(filename)) 132 | { 133 | DeleteFile(filename.c_str()); 134 | } 135 | 136 | filename.clear(); 137 | } 138 | 139 | std::string getHighLevelLibraryName() 140 | { 141 | return std::string("highlevelnrfjprog.dll"); 142 | } 143 | 144 | std::string getnrfjprogLibraryName() 145 | { 146 | return std::string("nrfjprog.dll"); 147 | } 148 | -------------------------------------------------------------------------------- /src/platform/win/win_delay_load_hook.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * When this file is linked to a DLL, it sets up a delay-load hook that 3 | * intervenes when the DLL is trying to load 'node.exe' or 'iojs.exe' 4 | * dynamically. Instead of trying to locate the .exe file it'll just return 5 | * a handle to the process image. 6 | * 7 | * This allows compiled addons to work when node.exe or iojs.exe is renamed. 8 | * 9 | * https://electronjs.org/docs/tutorial/using-native-node-modules#a-note-about-win_delay_load_hook 10 | */ 11 | 12 | #ifdef _MSC_VER 13 | 14 | #ifndef WIN32_LEAN_AND_MEAN 15 | #define WIN32_LEAN_AND_MEAN 16 | #endif 17 | 18 | #include 19 | 20 | #include 21 | #include 22 | 23 | static FARPROC WINAPI load_exe_hook(unsigned int event, DelayLoadInfo * info) 24 | { 25 | HMODULE m; 26 | if (event != dliNotePreLoadLibrary) 27 | return nullptr; 28 | 29 | if (_stricmp(info->szDll, "iojs.exe") != 0 && _stricmp(info->szDll, "node.exe") != 0) 30 | return nullptr; 31 | 32 | m = GetModuleHandle(nullptr); 33 | return reinterpret_cast(m); 34 | } 35 | 36 | decltype(__pfnDliNotifyHook2) __pfnDliNotifyHook2 = load_exe_hook; 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /src/utility/conversion.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef CONVERSION_H 38 | #define CONVERSION_H 39 | 40 | #include "../common.h" 41 | #include "../nan_wrap.h" 42 | #include 43 | 44 | class Convert 45 | { 46 | public: 47 | static uint32_t getNativeUint32(v8::Local js, const char * name); 48 | static uint32_t getNativeUint32(v8::Local js); 49 | static uint16_t getNativeUint16(v8::Local js, const char * name); 50 | static uint16_t getNativeUint16(v8::Local js); 51 | static uint8_t getNativeUint8(v8::Local js, const char * name); 52 | static uint8_t getNativeUint8(v8::Local js); 53 | static int32_t getNativeInt32(v8::Local js, const char * name); 54 | static int32_t getNativeInt32(v8::Local js); 55 | static int16_t getNativeInt16(v8::Local js, const char * name); 56 | static int16_t getNativeInt16(v8::Local js); 57 | static int8_t getNativeInt8(v8::Local js, const char * name); 58 | static int8_t getNativeInt8(v8::Local js); 59 | static double getNativeDouble(v8::Local js, const char * name); 60 | static double getNativeDouble(v8::Local js); 61 | static uint8_t getNativeBool(v8::Local js, const char * name); 62 | static uint8_t getNativeBool(v8::Local js); 63 | static bool getBool(v8::Local js, const char * name); 64 | static bool getBool(v8::Local js); 65 | static std::vector getVectorForChar(v8::Local js, const char * name); 66 | static std::vector getVectorForChar(v8::Local js); 67 | static std::vector getVectorForUint8(v8::Local js, const char * name); 68 | static std::vector getVectorForUint8(v8::Local js); 69 | static uint32_t getLengthOfArray(v8::Local js, const char * name); 70 | static uint32_t getLengthOfArray(v8::Local js); 71 | static v8::Local getJsObject(v8::Local js, const char * name); 72 | static v8::Local getJsObject(v8::Local js); 73 | static v8::Local getJsObjectOrNull(v8::Local js, const char * name); 74 | static v8::Local getJsObjectOrNull(v8::Local js); 75 | static std::string getNativeString(v8::Local js, const char * name); 76 | static std::string getNativeString(v8::Local js); 77 | 78 | static v8::Handle toJsNumber(int32_t nativeValue); 79 | static v8::Handle toJsNumber(uint32_t nativeValue); 80 | static v8::Handle toJsNumber(int16_t nativeValue); 81 | static v8::Handle toJsNumber(uint16_t nativeValue); 82 | static v8::Handle toJsNumber(int8_t nativeValue); 83 | static v8::Handle toJsNumber(uint8_t nativeValue); 84 | static v8::Handle toJsNumber(double nativeValue); 85 | static v8::Handle toJsBool(uint8_t nativeValue); 86 | static v8::Handle toJsBool(bool nativeValue); 87 | static v8::Handle toJsValueArray(uint8_t * nativeValue, uint32_t length); 88 | static v8::Handle toJsString(const char * cString); 89 | static v8::Handle toJsString(const char * cString, size_t length); 90 | static v8::Handle toJsString(uint8_t * cString, size_t length); 91 | static v8::Handle toJsString(const std::string & string); 92 | static const char * valueToString(uint16_t value, name_map_t name_map, const char * defaultValue = "Unknown value"); 93 | static v8::Handle valueToJsString( 94 | uint16_t, 95 | name_map_t name_map, 96 | v8::Handle defaultValue = Nan::New("Unknown value").ToLocalChecked()); 97 | 98 | static v8::Handle toTimeDifferenceUS(std::chrono::high_resolution_clock::time_point startTime, 99 | std::chrono::high_resolution_clock::time_point endTime); 100 | 101 | static v8::Local getCallbackFunction(v8::Local js, const char * name); 102 | static v8::Local getCallbackFunction(v8::Local js); 103 | 104 | static v8::Handle encodeHex(const char * text, int length); 105 | }; 106 | 107 | #endif 108 | -------------------------------------------------------------------------------- /src/utility/errormessage.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "errormessage.h" 38 | 39 | #include 40 | 41 | #include "../highlevel_common.h" 42 | #include "conversion.h" 43 | #include "utility.h" 44 | 45 | v8::Local ErrorMessage::getErrorMessage(const int errorCode, 46 | const name_map_t & errorcodeMapper, 47 | const std::string & customMessage) 48 | { 49 | return getErrorMessage(errorCode, errorcodeMapper, customMessage, std::string(), static_cast(0)); 50 | } 51 | 52 | v8::Local ErrorMessage::getErrorMessage(const int errorCode, 53 | const name_map_t & errorcodeMapper, 54 | const std::string & customMessage, 55 | const std::string & logmessage, 56 | const nrfjprogdll_err_t & lowlevelError) 57 | { 58 | Nan::EscapableHandleScope scope; 59 | 60 | if (errorCode == 0) 61 | { 62 | return scope.Escape(Nan::Undefined()); 63 | } 64 | 65 | const std::string errorcodeString(Convert::valueToString(errorCode, errorcodeMapper)); 66 | 67 | std::ostringstream errorStringStream; 68 | errorStringStream << "Error occured when " << customMessage << ". " 69 | << "Errorcode: " << errorcodeString << " (0x" << std::hex << errorCode << ")" << std::endl; 70 | 71 | const std::string lowLevelMessage(Convert::valueToString(lowlevelError, nrfjprogdll_err_map)); 72 | 73 | if (lowlevelError != SUCCESS) 74 | { 75 | errorStringStream << "Lowlevel error: " << lowLevelMessage << " (" << lowlevelError << ")" << std::endl; 76 | } 77 | 78 | const v8::Local error = Nan::Error(errorStringStream.str().c_str()); 79 | const v8::Local errorObject = error.As(); 80 | 81 | Utility::Set(errorObject, "errno", Convert::toJsNumber(errorCode)); 82 | Utility::Set(errorObject, "errcode", Convert::toJsString(errorcodeString)); 83 | Utility::Set(errorObject, "erroperation", Convert::toJsString(customMessage)); 84 | Utility::Set(errorObject, "errmsg", Convert::toJsString(errorStringStream.str())); 85 | Utility::Set(errorObject, "lowlevelErrorNo", Convert::toJsNumber(lowlevelError)); 86 | Utility::Set(errorObject, "lowlevelError", Convert::toJsString(lowLevelMessage)); 87 | Utility::Set(errorObject, "log", Convert::toJsString(logmessage)); 88 | 89 | return scope.Escape(error); 90 | } 91 | 92 | v8::Local ErrorMessage::getTypeErrorMessage(const int argumentNumber, const std::string & message) 93 | { 94 | static name_map_t argumentCountMap = { 95 | {0, "First"}, {1, "Second"}, {2, "Third"}, {3, "Fourth"}, {4, "Fifth"}, {5, "Sixth"}, {6, "Seventh"}}; 96 | 97 | std::ostringstream stream; 98 | 99 | if (argumentNumber != CUSTOM_ARGUMENT_PARSE_ERROR) 100 | { 101 | stream << Convert::valueToString(argumentNumber, argumentCountMap, "Unknown") << " argument must be a " 102 | << message; 103 | } 104 | else 105 | { 106 | stream << message; 107 | } 108 | 109 | return Convert::toJsString(stream.str())->ToString(Nan::GetCurrentContext()).ToLocalChecked(); 110 | } 111 | 112 | v8::Local ErrorMessage::getStructErrorMessage(const std::string & name, const std::string & message) 113 | { 114 | std::ostringstream stream; 115 | 116 | stream << "Property: " << name << " Message: " << message; 117 | 118 | return Convert::toJsString(stream.str())->ToString(Nan::GetCurrentContext()).ToLocalChecked(); 119 | } 120 | -------------------------------------------------------------------------------- /src/utility/errormessage.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef ERRORMESSAGE_H 38 | #define ERRORMESSAGE_H 39 | 40 | #include "../common.h" 41 | #include "../nan_wrap.h" 42 | #include "DllCommonDefinitions.h" 43 | 44 | #define CUSTOM_ARGUMENT_PARSE_ERROR (-1) 45 | 46 | class ErrorMessage 47 | { 48 | public: 49 | static v8::Local getErrorMessage(int errorCode, 50 | const name_map_t & errorcodeMapper, 51 | const std::string & customMessage); 52 | static v8::Local getErrorMessage(int errorCode, 53 | const name_map_t & errorcodeMapper, 54 | const std::string & customMessage, 55 | const std::string & logmessage, 56 | const nrfjprogdll_err_t & lowlevelError); 57 | static v8::Local getTypeErrorMessage(int argumentNumber, const std::string & message); 58 | static v8::Local getStructErrorMessage(const std::string & name, const std::string & message); 59 | }; 60 | 61 | #endif 62 | -------------------------------------------------------------------------------- /src/utility/utility.cpp: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #include "utility.h" 38 | #include "conversion.h" 39 | 40 | v8::Local Utility::Get(v8::Local jsobj, const char * name) 41 | { 42 | Nan::EscapableHandleScope scope; 43 | return scope.Escape(Nan::Get(jsobj, Nan::New(name).ToLocalChecked()).ToLocalChecked()); 44 | } 45 | 46 | v8::Local Utility::Get(v8::Local jsobj, const int index) 47 | { 48 | Nan::EscapableHandleScope scope; 49 | return scope.Escape(Nan::Get(jsobj, index).ToLocalChecked()); 50 | } 51 | 52 | void Utility::SetMethod(v8::Handle target, const char * exportName, Nan::FunctionCallback function) 53 | { 54 | Utility::Set(target, exportName, Nan::GetFunction(Nan::New(function)).ToLocalChecked()); 55 | } 56 | 57 | bool Utility::Set(v8::Handle target, const char * name, int32_t value) 58 | { 59 | return Utility::Set(target, name, Convert::toJsNumber(value)); 60 | } 61 | 62 | bool Utility::Set(v8::Handle target, const char * name, uint32_t value) 63 | { 64 | return Utility::Set(target, name, Convert::toJsNumber(value)); 65 | } 66 | 67 | bool Utility::Set(v8::Handle target, const char * name, int16_t value) 68 | { 69 | return Utility::Set(target, name, Convert::toJsNumber(value)); 70 | } 71 | 72 | bool Utility::Set(v8::Handle target, const char * name, uint16_t value) 73 | { 74 | return Utility::Set(target, name, Convert::toJsNumber(value)); 75 | } 76 | 77 | bool Utility::Set(v8::Handle target, const char * name, int8_t value) 78 | { 79 | return Utility::Set(target, name, Convert::toJsNumber(value)); 80 | } 81 | 82 | bool Utility::Set(v8::Handle target, const char * name, uint8_t value) 83 | { 84 | return Utility::Set(target, name, Convert::toJsNumber(value)); 85 | } 86 | 87 | bool Utility::Set(v8::Handle target, const char * name, bool value) 88 | { 89 | return Utility::Set(target, name, Convert::toJsBool(value)); 90 | } 91 | 92 | bool Utility::Set(v8::Handle target, const char * name, double value) 93 | { 94 | return Utility::Set(target, name, Convert::toJsNumber(value)); 95 | } 96 | 97 | bool Utility::Set(v8::Handle target, const char * name, const char * value) 98 | { 99 | return Utility::Set(target, name, Convert::toJsString(value)); 100 | } 101 | 102 | bool Utility::Set(v8::Handle target, const char * name, const std::string & value) 103 | { 104 | return Utility::Set(target, name, Convert::toJsString(value)); 105 | } 106 | 107 | bool Utility::Set(v8::Handle target, const char * name, v8::Local value) 108 | { 109 | return Nan::Set(target, Nan::New(name).ToLocalChecked(), value).FromMaybe(false); 110 | } 111 | 112 | bool Utility::Has(v8::Handle target, const char * name) 113 | { 114 | return target->Has(target->CreationContext(), Nan::New(name).ToLocalChecked()).FromMaybe(false); 115 | } 116 | 117 | bool Utility::Has(v8::Handle target, const int index) 118 | { 119 | return target->Has(target->CreationContext(), Nan::New(index)).FromMaybe(false); 120 | } 121 | 122 | void Utility::SetReturnValue(Nan::NAN_METHOD_ARGS_TYPE info, v8::Local value) 123 | { 124 | info.GetReturnValue().Set(value); 125 | } 126 | 127 | bool Utility::IsObject(v8::Local jsobj, const char * name) 128 | { 129 | return Utility::Get(jsobj, name)->IsObject(); 130 | } 131 | 132 | bool Utility::IsNull(v8::Local jsobj, const char * name) 133 | { 134 | return Utility::Get(jsobj, name)->IsNull(); 135 | } 136 | 137 | bool Utility::IsNull(v8::Local jsobj) 138 | { 139 | if (Utility::Has(jsobj, "special_hack_null_object")) 140 | { 141 | return true; 142 | } 143 | if (!jsobj->IsObject()) 144 | { 145 | return true; 146 | } 147 | return jsobj->IsNull(); 148 | } 149 | 150 | bool Utility::IsBetween(const uint8_t value, const uint8_t min, const uint8_t max) 151 | { 152 | return !(value < min || value > max); 153 | } 154 | 155 | bool Utility::EnsureAsciiNumbers(uint8_t * value, const int length) 156 | { 157 | for (int i = 0; i < length; ++i) 158 | { 159 | if (IsBetween(value[i], 0, 9)) 160 | { 161 | value[i] = value[i] + '0'; 162 | } 163 | else if (!IsBetween(value[i], '0', '9')) 164 | { 165 | return false; 166 | } 167 | } 168 | 169 | return true; 170 | } 171 | -------------------------------------------------------------------------------- /src/utility/utility.h: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | #ifndef UTILITY_H 38 | #define UTILITY_H 39 | 40 | #include "../nan_wrap.h" 41 | 42 | class Utility 43 | { 44 | public: 45 | static v8::Local Get(v8::Local jsobj, const char * name); 46 | static v8::Local Get(v8::Local jsobj, int index); 47 | static void SetMethod(v8::Handle target, const char * exportName, Nan::FunctionCallback function); 48 | 49 | static bool Set(v8::Handle target, const char * name, int32_t value); 50 | static bool Set(v8::Handle target, const char * name, uint32_t value); 51 | static bool Set(v8::Handle target, const char * name, int16_t value); 52 | static bool Set(v8::Handle target, const char * name, uint16_t value); 53 | static bool Set(v8::Handle target, const char * name, int8_t value); 54 | static bool Set(v8::Handle target, const char * name, uint8_t value); 55 | static bool Set(v8::Handle target, const char * name, bool value); 56 | static bool Set(v8::Handle target, const char * name, double value); 57 | static bool Set(v8::Handle target, const char * name, const char * value); 58 | static bool Set(v8::Handle target, const char * name, const std::string & value); 59 | static bool Set(v8::Handle target, const char * name, v8::Local value); 60 | 61 | static bool Has(v8::Handle target, const char * name); 62 | static bool Has(v8::Handle target, int index); 63 | 64 | static void SetReturnValue(Nan::NAN_METHOD_ARGS_TYPE info, v8::Local value); 65 | 66 | static bool IsObject(v8::Local jsobj, const char * name); 67 | static bool IsNull(v8::Local jsobj, const char * name); 68 | static bool IsNull(v8::Local jsobj); 69 | 70 | static bool IsBetween(uint8_t value, uint8_t min, uint8_t max); 71 | static bool EnsureAsciiNumbers(uint8_t * value, int length); 72 | }; 73 | 74 | #endif 75 | -------------------------------------------------------------------------------- /test/__snapshots__/index.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`Generic functionality throws when too few parameters are sent in 1`] = `"First argument must be a function"`; 4 | 5 | exports[`Generic functionality throws when too many parameters are sent in 1`] = `"Too many parameters. The function get library version does not take 2 parameters."`; 6 | 7 | exports[`Generic functionality throws when wrong type of parameters are sent in 1`] = `"First argument must be a function"`; 8 | 9 | exports[`RTT fails cleanly when calling other functions before start fails cleanly when calling read without start 1`] = ` 10 | [Error: Error occured when rtt read. Errorcode: CouldNotCallFunction (0x9) 11 | Lowlevel error: Unknown value (ffffff02) 12 | ] 13 | `; 14 | 15 | exports[`RTT fails cleanly when calling other functions before start fails cleanly when calling write without start 1`] = ` 16 | [Error: Error occured when rtt write. Errorcode: CouldNotCallFunction (0x9) 17 | Lowlevel error: Unknown value (ffffff02) 18 | ] 19 | `; 20 | 21 | exports[`RTT opens and close as expected returns an error when using wrong control block location 1`] = ` 22 | [Error: Error occured when start rtt. Errorcode: CouldNotCallFunction (0x9) 23 | Lowlevel error: Unknown value (ffffff24) 24 | ] 25 | `; 26 | 27 | exports[`RTT opens and close as expected returns an error when wrong serialnumber 1`] = ` 28 | [Error: Error occured when start rtt. Errorcode: CouldNotCallFunction (0x9) 29 | Lowlevel error: INVALID_PARAMETER (fffffffd) 30 | ] 31 | `; 32 | 33 | exports[`RTT reads from device reads startmessage 1`] = `"RTT Loopback Session started, DK connected"`; 34 | 35 | exports[`RTT reads from device reads startmessage 2`] = ` 36 | Array [ 37 | 82, 38 | 84, 39 | 84, 40 | 32, 41 | 76, 42 | 111, 43 | 111, 44 | 112, 45 | 98, 46 | 97, 47 | 99, 48 | 107, 49 | 32, 50 | 83, 51 | 101, 52 | 115, 53 | 115, 54 | 105, 55 | 111, 56 | 110, 57 | 32, 58 | 115, 59 | 116, 60 | 97, 61 | 114, 62 | 116, 63 | 101, 64 | 100, 65 | 44, 66 | 32, 67 | 68, 68 | 75, 69 | 32, 70 | 99, 71 | 111, 72 | 110, 73 | 110, 74 | 101, 75 | 99, 76 | 116, 77 | 101, 78 | 100, 79 | ] 80 | `; 81 | 82 | exports[`RTT without RTT firmware can not start RTT fails cleanly 1`] = ` 83 | [Error: Error occured when start rtt. Errorcode: CouldNotCallFunction (0x9) 84 | Lowlevel error: Unknown value (ffffff24) 85 | ] 86 | `; 87 | 88 | exports[`Single device - non-destructive throws an error when device do not exist 1`] = ` 89 | [Error: Error occured when get device info. Errorcode: CouldNotOpenDevice (0x4) 90 | Lowlevel error: EMULATOR_NOT_CONNECTED (fffffff6) 91 | ] 92 | `; 93 | -------------------------------------------------------------------------------- /test/generic.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | 41 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; 42 | 43 | const generic = () => { 44 | it('gets library version', done => { 45 | const callback = (err, version) => { 46 | expect(err).toBeUndefined(); 47 | expect(version).toHaveProperty('major'); 48 | expect(version).toHaveProperty('minor'); 49 | expect(version).toHaveProperty('revision'); 50 | done(); 51 | }; 52 | 53 | nRFjprog.getLibraryVersion(callback); 54 | }); 55 | 56 | it('gets deprecated dll version', done => { 57 | const callback = (err, version) => { 58 | expect(err).toBeUndefined(); 59 | expect(version).toHaveProperty('major'); 60 | expect(version).toHaveProperty('minor'); 61 | expect(version).toHaveProperty('revision'); 62 | done(); 63 | }; 64 | 65 | nRFjprog.getDllVersion(callback); 66 | }); 67 | 68 | it('finds all connected devices', done => { 69 | const callback = (err, connectedDevices) => { 70 | expect(err).toBeUndefined(); 71 | expect(connectedDevices.length).toBeGreaterThanOrEqual(1); 72 | expect(connectedDevices[0]).toHaveProperty('serialNumber'); 73 | expect(connectedDevices[0]).toHaveProperty('deviceInfo'); 74 | expect(connectedDevices[0]).toHaveProperty('probeInfo'); 75 | expect(connectedDevices[0]).toHaveProperty('libraryInfo'); 76 | done(); 77 | }; 78 | 79 | nRFjprog.getConnectedDevices(callback); 80 | }); 81 | 82 | it('finds all connected serialnumbers', done => { 83 | const callback = (err, serialNumbers) => { 84 | expect(err).toBeUndefined(); 85 | expect(serialNumbers.length).toBeGreaterThanOrEqual(1); 86 | expect(serialNumbers[0]).toEqual(expect.any(Number)); 87 | 88 | done(); 89 | }; 90 | 91 | nRFjprog.getSerialNumbers(callback); 92 | }); 93 | 94 | it('throws when too few parameters are sent in', () => { 95 | expect(() => { nRFjprog.getLibraryVersion(); }).toThrowErrorMatchingSnapshot(); 96 | }); 97 | 98 | it('throws when too many parameters are sent in', () => { 99 | const mockCallback = jest.fn(); 100 | 101 | expect(() => { nRFjprog.getLibraryVersion(mockCallback, mockCallback); }).toThrowErrorMatchingSnapshot(); 102 | }); 103 | 104 | it('throws when wrong type of parameters are sent in', () => { 105 | expect(() => { nRFjprog.getLibraryVersion(1); }).toThrowErrorMatchingSnapshot(); 106 | }); 107 | }; 108 | 109 | exports.generic = generic; 110 | -------------------------------------------------------------------------------- /test/hex/modem-dfu-image.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NordicSemiconductor/pc-nrfjprog-js/c918b8f06d57214e0e5f642258000bdb273f6683/test/hex/modem-dfu-image.zip -------------------------------------------------------------------------------- /test/hex/while_true_nrf53_application.hex: -------------------------------------------------------------------------------- 1 | :020000040000FA 2 | :10000000082000201904000021040000230400003F 3 | :100010002504000027040000290400002B04000030 4 | :100020000000000000000000000000002D0400009F 5 | :100030002F04000000000000310400003304000021 6 | :100040003504000035040000000000003504000005 7 | :100050000000000035040000000000000000000067 8 | :1000600035040000350400003504000000000000E5 9 | :1000700000000000350400003504000035040000D5 10 | :1000800035040000350400000000000000000000FE 11 | :1000900035040000350400000000000000000000EE 12 | :1000A000350400003504000035040000350400006C 13 | :1000B000350400003504000035040000350400005C 14 | :1000C000350400003504000035040000350400004C 15 | :1000D00000000000000000003504000000000000E7 16 | :1000E0003504000000000000350400003504000065 17 | :1000F000000000003504000000000000350400008E 18 | :1001000000000000000000000000000000000000EF 19 | :10011000000000000000000035040000350400006D 20 | :100120000000000035040000000000000000000096 21 | :1001300000000000000000000000000000000000BF 22 | :1001400000000000000000000000000000000000AF 23 | :100150003504000000000000000000000000000066 24 | :10016000000000000000000000000000000000008F 25 | :10017000000000000000000000000000000000007F 26 | :10018000000000000000000000000000000000006F 27 | :10019000000000000000000000000000000000005F 28 | :1001A000000000000000000000000000000000004F 29 | :1001B000000000000000000000000000000000003F 30 | :1001C000000000000000000000000000000000002F 31 | :1001D000000000000000000000000000000000001F 32 | :1001E000000000000000000000000000000000000F 33 | :1001F00000000000000000000000000000000000FF 34 | :1002000000000000000000000000000000000000EE 35 | :1002100000000000000000000000000000000000DE 36 | :1002200000000000000000000000000000000000CE 37 | :1002300000000000000000000000000000000000BE 38 | :1002400000000000000000000000000000000000AE 39 | :10025000000000000000000000000000000000009E 40 | :10026000000000000000000000000000000000008E 41 | :10027000000000000000000000000000000000007E 42 | :10028000000000000000000000000000000000006E 43 | :10029000000000000000000000000000000000005E 44 | :1002A000000000000000000000000000000000004E 45 | :1002B000000000000000000000000000000000003E 46 | :1002C000000000000000000000000000000000002E 47 | :1002D000000000000000000000000000000000001E 48 | :1002E000000000000000000000000000000000000E 49 | :1002F00000000000000000000000000000000000FE 50 | :1003000000000000000000000000000000000000ED 51 | :1003100000000000000000000000000000000000DD 52 | :1003200000000000000000000000000000000000CD 53 | :1003300000000000000000000000000000000000BD 54 | :1003400000000000000000000000000000000000AD 55 | :10035000000000000000000000000000000000009D 56 | :10036000000000000000000000000000000000008D 57 | :10037000000000000000000000000000000000007D 58 | :10038000000000000000000000000000000000006D 59 | :10039000000000000000000000000000000000005D 60 | :1003A000000000000000000000000000000000004D 61 | :1003B000000000000000000000000000000000003D 62 | :1003C000000000000000000000000000000000002D 63 | :1003D000000000000000000000000000000000001D 64 | :1003E000000000000000000000000000000000000D 65 | :1003F00000000000000000000000000000000000FD 66 | :10040000DFF80CD000F04EF800480047150400005B 67 | :1004100008200020FEE70000074880470748004703 68 | :10042000FEE7FEE7FEE7FEE7FEE7FEE7FEE7FEE7A4 69 | :10043000FEE7FEE7FEE700005104000001040000B3 70 | :100440000148024901607047000000200020A10718 71 | :10045000002010490AE051F83020013208D001EBA9 72 | :10046000C002526851F8303001301A60FF28F2D9CA 73 | :100470000948416841F440614160016841F47001FC 74 | :100480000160BFF34F8F0548BFF36F8F04490160D0 75 | :10049000704700BF0003FF0088ED00E0000000206F 76 | :1004A0000020A107064C074D06E0E06840F001037C 77 | :1004B00094E8070098471034AC42F6D3FFF7A4FF46 78 | :1004C000E80400000805000002E008C8121F08C187 79 | :1004D000002AFAD170477047002001E001C1121FC5 80 | :1004E000002AFBD170470000080500000000002032 81 | :1004F00008000000C80400001005000008000020EB 82 | :1005000000200000D80400000020A1070000000027 83 | :0400000500000401F2 84 | :00000001FF 85 | -------------------------------------------------------------------------------- /test/hex/while_true_nrf53_network.hex: -------------------------------------------------------------------------------- 1 | :020000040100F9 2 | :10000000082000215D020001650200016702000175 3 | :10001000690200016B0200016D0200016F02000124 4 | :10002000000000000000000000000000710200015C 5 | :100030007302000100000000750200017702000158 6 | :1000400000000000000000000000000000000000B0 7 | :100050000000000079020001000000000000000024 8 | :1000600079020001790200017902000179020001A0 9 | :10007000790200017902000179020001000000000C 10 | :100080007902000179020001790200017902000180 11 | :100090007902000100000000790200010000000068 12 | :1000A0007902000179020001790200017902000160 13 | :1000B0007902000179020001000000000000000048 14 | :1000C0000000000000000000000000000000000030 15 | :1000D0000000000000000000000000000000000020 16 | :1000E0000000000000000000000000000000000010 17 | :1000F0000000000000000000000000000000000000 18 | :1001000000000000000000000000000000000000EF 19 | :1001100000000000000000000000000000000000DF 20 | :1001200000000000000000000000000000000000CF 21 | :1001300000000000000000000000000000000000BF 22 | :1001400000000000000000000000000000000000AF 23 | :10015000000000000000000000000000000000009F 24 | :10016000000000000000000000000000000000008F 25 | :10017000000000000000000000000000000000007F 26 | :10018000000000000000000000000000000000006F 27 | :10019000000000000000000000000000000000005F 28 | :1001A000000000000000000000000000000000004F 29 | :1001B000000000000000000000000000000000003F 30 | :1001C000000000000000000000000000000000002F 31 | :1001D000000000000000000000000000000000001F 32 | :1001E000000000000000000000000000000000000F 33 | :1001F00000000000000000000000000000000000FF 34 | :1002000000000000000000000000000000000000EE 35 | :1002100000000000000000000000000000000000DE 36 | :1002200000000000000000000000000000000000CE 37 | :1002300000000000000000000000000000000000BE 38 | :1002400000000000DFF80CD000F03EF80048004746 39 | :100250005902000108200021FEE7000007488047FE 40 | :1002600007480047FEE7FEE7FEE7FEE7FEE7FEE79A 41 | :10027000FEE7FEE7FEE7FEE7FEE70000950200016D 42 | :100280004502000101480249016070470000002159 43 | :100290000090D003002009490AE051F830200132D3 44 | :1002A00008D001EBC002526851F8303001301A60BA 45 | :1002B000FF28F2D902480349016070470003FF019B 46 | :1002C000000000210090D003064C074D06E0E068D6 47 | :1002D00040F0010394E8070098471034AC42F6D38D 48 | :1002E000FFF7B4FF0C0300012C03000102E008C873 49 | :1002F000121F08C1002AFAD170477047002001E0A0 50 | :1003000001C1121F002AFBD1704700003003000119 51 | :100310000000002108000000EC0200013803000189 52 | :100320000800002100200000FC0200010000000085 53 | :080330000090D0030000000062 54 | :0400000501000245AF 55 | :00000001FF 56 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | const { generic } = require('./generic.test') 38 | const { raceCondition } = require('./racecondition.test') 39 | const { singleDeviceDesctructive } = require('./single-device-destructive.test') 40 | const { singleDeviceNonDesctructive } = require('./single-device-non-destructive.test') 41 | const { rtt } = require('./rtt.test') 42 | const { rttFailing } = require('./rttfailing.test') 43 | // const { modemDfu } = require('./modem-dfu-destructive.test') 44 | 45 | describe('Generic functionality', generic); 46 | describe('Handles race conditions gracefully', raceCondition); 47 | describe('Single device - destructive', singleDeviceDesctructive); 48 | describe('Single device - non-destructive', singleDeviceNonDesctructive); 49 | describe('RTT', rtt); 50 | describe('RTT without RTT firmware', rttFailing); 51 | // describe('Modem DFU', modemDfu); 52 | 53 | -------------------------------------------------------------------------------- /test/modem-dfu-destructive.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | 41 | jest.setTimeout(100000); 42 | 43 | const serialNumber = process.env.DK91_SERIAL_NUMBER; 44 | const testcase = serialNumber ? it : it.skip; 45 | 46 | const modemDfu = async () => { 47 | testcase('modem-dfu', async () => { 48 | expect(serialNumber).toBeDefined(); 49 | await new Promise((resolve, reject) => ( 50 | nRFjprog.programDFU(Number(serialNumber), "./test/hex/modem-dfu-image.zip", (err) => { 51 | expect(err).toBeUndefined(); 52 | return err ? reject(err) : resolve(); 53 | }) 54 | )); 55 | }); 56 | }; 57 | 58 | exports.modemDfu = modemDfu; 59 | -------------------------------------------------------------------------------- /test/racecondition.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | 41 | let device; 42 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; 43 | 44 | const raceCondition = () => { 45 | beforeAll(done => { 46 | const callback = (err, connectedDevices) => { 47 | expect(err).toBeUndefined(); 48 | expect(connectedDevices.length).toBeGreaterThanOrEqual(1); 49 | device = connectedDevices[0]; 50 | done(); 51 | }; 52 | 53 | nRFjprog.getConnectedDevices(callback); 54 | }); 55 | 56 | it('allows multiple, fast, calls in a row', done => { 57 | let errorCount = 0; 58 | const getVersionAttempts = 20; 59 | let callbackCalled = 0; 60 | 61 | const getVersionCallback = (err) => { 62 | if (err) { 63 | errorCount++; 64 | } 65 | 66 | callbackCalled++; 67 | 68 | if (callbackCalled === getVersionAttempts) { 69 | expect(errorCount).toBe(0); 70 | done(); 71 | } 72 | }; 73 | 74 | for (let i = 0; i < getVersionAttempts; i++) { 75 | nRFjprog.getLibraryVersion(getVersionCallback); 76 | } 77 | }); 78 | 79 | it('returns an error when attempting 5 programs in a row', done => { 80 | let errorCount = 0; 81 | const programAttempts = 5; 82 | let callbackCalled = 0; 83 | 84 | const programCallback = (err) => { 85 | if (err) { 86 | errorCount++; 87 | } 88 | 89 | callbackCalled++; 90 | 91 | if (callbackCalled === programAttempts) { 92 | expect(errorCount).toBeGreaterThan(0); 93 | done(); 94 | } 95 | }; 96 | 97 | for (let i = 0; i < programAttempts; i++) { 98 | nRFjprog.program(device.serialNumber, "./test/hex/connectivity_1.1.0_1m_with_s132_3.0.hex", { }, programCallback); 99 | } 100 | }); 101 | }; 102 | 103 | exports.raceCondition = raceCondition; 104 | -------------------------------------------------------------------------------- /test/rtt.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | const RTT = nRFjprog.RTT; 41 | 42 | let device; 43 | 44 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; 45 | 46 | describe('RTT', () => { 47 | beforeAll(done => { 48 | const programCallback = err => { 49 | expect(err).toBeUndefined(); 50 | 51 | done(); 52 | }; 53 | 54 | const callback = (err, connectedDevices) => { 55 | expect(err).toBeUndefined(); 56 | expect(connectedDevices.length).toBeGreaterThanOrEqual(1); 57 | 58 | // We only have firmware for the nRF52 at the moment. RTT also works with nRF51, but with another firmware 59 | let nrf52devices = connectedDevices.filter(device => device.deviceInfo.family === nRFjprog.NRF52_FAMILY); 60 | 61 | device = nrf52devices[0]; 62 | 63 | expect(device).toBeDefined(); 64 | 65 | nRFjprog.program(device.serialNumber, "./test/hex/rtt.hex", { }, programCallback); 66 | }; 67 | 68 | nRFjprog.getConnectedDevices(callback); 69 | }); 70 | 71 | describe('opens and close as expected', () => { 72 | it('starts a rtt session', (done) => { 73 | const stopCallback = (err) => { 74 | expect(err).toBeUndefined(); 75 | done(); 76 | }; 77 | 78 | const startCallback = (err, down, up) => { 79 | expect(err).toBeUndefined(); 80 | expect(down).toBeDefined(); 81 | expect(up).toBeDefined(); 82 | 83 | RTT.stop(stopCallback); 84 | }; 85 | 86 | RTT.start(device.serialNumber, {}, startCallback); 87 | }); 88 | 89 | it('starts a rtt session when using correct control block location', (done) => { 90 | const stopCallback = (err) => { 91 | expect(err).toBeUndefined(); 92 | done(); 93 | }; 94 | 95 | const startCallback = (err, down, up) => { 96 | expect(err).toBeUndefined(); 97 | expect(down).toBeDefined(); 98 | expect(up).toBeDefined(); 99 | 100 | RTT.stop(stopCallback); 101 | }; 102 | 103 | RTT.start(device.serialNumber, { controlBlockLocation: 0x200006E0 }, startCallback); 104 | }); 105 | 106 | it('returns an error when wrong serialnumber', done => { 107 | const startCallback = (err, down, up) => { 108 | expect(err).toBeDefined(); 109 | expect(err).toMatchSnapshot(); 110 | 111 | done(); 112 | }; 113 | 114 | RTT.start(0, {}, startCallback); 115 | }); 116 | 117 | it('returns an error when using wrong control block location', done => { 118 | const startCallback = (err, down, up) => { 119 | expect(err).toBeDefined(); 120 | expect(err).toMatchSnapshot(); 121 | 122 | done(); 123 | }; 124 | 125 | RTT.start(device.serialNumber, { controlBlockLocation: 15 }, startCallback); 126 | }); 127 | }); 128 | 129 | describe('fails cleanly when calling other functions before start', () => { 130 | it('fails cleanly when calling read without start', (done) => { 131 | const readCallback = (err, data, raw, time) => { 132 | expect(err).toBeDefined(); 133 | expect(err).toMatchSnapshot(); 134 | 135 | done(); 136 | }; 137 | 138 | RTT.read(0, 100, readCallback); 139 | }); 140 | 141 | it('fails cleanly when calling write without start', (done) => { 142 | const writeCallback = (err, length, time) => { 143 | expect(err).toBeDefined(); 144 | expect(err).toMatchSnapshot(); 145 | 146 | done(); 147 | }; 148 | 149 | RTT.write(0, "test", writeCallback); 150 | }); 151 | 152 | it('fails cleanly when calling stop without start', (done) => { 153 | const stopCallback = (err) => { 154 | expect(err).toBeDefined(); 155 | expect(err).toMatchSnapshot(); 156 | 157 | done(); 158 | }; 159 | 160 | RTT.stop(stopCallback); 161 | }); 162 | }); 163 | 164 | describe('reads from device', () => { 165 | beforeEach(done => { 166 | const startCallback = (err, down, up) => { 167 | expect(err).toBeUndefined(); 168 | expect(down).toBeDefined(); 169 | expect(up).toBeDefined(); 170 | 171 | done(); 172 | }; 173 | 174 | RTT.start(device.serialNumber, {}, startCallback); 175 | }); 176 | 177 | afterEach(done => { 178 | const stopCallback = (err) => { 179 | expect(err).toBeUndefined(); 180 | done(); 181 | }; 182 | 183 | RTT.stop(stopCallback); 184 | }); 185 | 186 | it('reads startmessage', done => { 187 | const readCallback = (err, data, raw, time) => { 188 | expect(err).toBeUndefined(); 189 | expect(data).toMatchSnapshot(); 190 | expect(raw).toMatchSnapshot(); 191 | expect(time).toBeDefined(); 192 | 193 | done(); 194 | }; 195 | 196 | RTT.read(0, 100, readCallback); 197 | }); 198 | 199 | it('reads the set number of bytes', done => { 200 | const readLength = 5; 201 | const readCallback = (err, data, raw) => { 202 | expect(err).toBeUndefined(); 203 | expect(data.length).toBe(readLength); 204 | expect(raw.length).toBe(readLength); 205 | 206 | done(); 207 | }; 208 | 209 | RTT.read(0, readLength, readCallback); 210 | }); 211 | }); 212 | 213 | describe('writes to device', () => { 214 | beforeEach(done => { 215 | const readCallback = (err, data, raw, time) => { 216 | expect(err).toBeUndefined(); 217 | 218 | done(); 219 | } 220 | 221 | const startCallback = (err, down, up) => { 222 | expect(err).toBeUndefined(); 223 | expect(down).toBeDefined(); 224 | expect(up).toBeDefined(); 225 | 226 | // Clear the read buffers 227 | RTT.read(0, 100, readCallback); 228 | }; 229 | 230 | RTT.start(device.serialNumber, {}, startCallback); 231 | }); 232 | 233 | afterEach(done => { 234 | const stopCallback = (err) => { 235 | expect(err).toBeUndefined(); 236 | done(); 237 | }; 238 | 239 | RTT.stop(stopCallback); 240 | }); 241 | 242 | it('writes a text to loopback and reads it back', done => { 243 | const writetext = "this is a test"; 244 | let readStartTime = Date.now(); 245 | 246 | const readCallback = (err, data, raw) => { 247 | expect(err).toBeUndefined(); 248 | 249 | if (data.length === 0 250 | && Date.now() - readStartTime < 2000) { 251 | RTT.read(0, 100, readCallback); 252 | return; 253 | } 254 | 255 | expect(data).toBe(writetext); 256 | 257 | done(); 258 | }; 259 | 260 | const writeCallback = (err, length, time) => { 261 | expect(err).toBeUndefined(); 262 | expect(length).toBe(writetext.length); 263 | expect(time).toBeDefined(); 264 | 265 | readStartTime = Date.now(); 266 | RTT.read(0, 100, readCallback); 267 | }; 268 | 269 | RTT.write(0, writetext, writeCallback); 270 | }); 271 | 272 | it('writes a arry of integers to loopback and reads it back', done => { 273 | const writearray = [0, 1, 2, 3]; 274 | let readStartTime = Date.now(); 275 | 276 | const readCallback = (err, data, raw) => { 277 | expect(err).toBeUndefined(); 278 | 279 | if (raw.length === 0 280 | && Date.now() - readStartTime < 2000) { 281 | RTT.read(0, 100, readCallback); 282 | return; 283 | } 284 | 285 | expect(raw).toEqual(writearray); 286 | 287 | done(); 288 | }; 289 | 290 | const writeCallback = (err, length, time) => { 291 | expect(err).toBeUndefined(); 292 | expect(length).toBe(writearray.length); 293 | expect(time).toBeDefined(); 294 | 295 | readStartTime = Date.now(); 296 | RTT.read(0, 100, readCallback); 297 | }; 298 | 299 | RTT.write(0, writearray, writeCallback); 300 | }); 301 | }); 302 | 303 | describe('race condition', () => { 304 | afterEach(done => { 305 | const stopCallback = (err) => { 306 | expect(err).toBeUndefined(); 307 | done(); 308 | }; 309 | 310 | RTT.stop(stopCallback); 311 | }); 312 | 313 | it('handle race conditions by waiting', done => { 314 | const readOrder = []; 315 | const startCallback = (err, down, up) => { 316 | expect(err).toBeUndefined(); 317 | expect(down).toBeDefined(); 318 | expect(up).toBeDefined(); 319 | }; 320 | 321 | const readCallback = (number, err, data, raw) => { 322 | readOrder.push(number); 323 | expect(err).toBeUndefined(); 324 | 325 | if (readOrder.length === 3) { 326 | expect(readOrder).toEqual(expect.arrayContaining([1, 2, 3])); 327 | done(); 328 | } 329 | }; 330 | 331 | RTT.start(device.serialNumber, {}, startCallback); 332 | RTT.read(0, 100, readCallback.bind(null, 1)); 333 | RTT.read(0, 100, readCallback.bind(null, 2)); 334 | RTT.read(0, 100, readCallback.bind(null, 3)); 335 | }); 336 | 337 | // A timeout of 10 seconds is to long to trip this up 338 | it.skip('returns an error when the call time exceeds 10 seconds', done => { 339 | const errCount = 0; 340 | const writeElementCount = 10000; 341 | const writeResults = []; 342 | 343 | const startCallback = (err, down, up) => { 344 | expect(err).toBeUndefined(); 345 | expect(down).toBeDefined(); 346 | expect(up).toBeDefined(); 347 | }; 348 | 349 | const writeCallback = (err, writeLength, time) => { 350 | if (err) { 351 | errCount++; 352 | } 353 | 354 | writeResults.push(err); 355 | 356 | if (writeResults.length % 1000 === 0) { 357 | console.log(writeResults.length); 358 | } 359 | 360 | if (writeResults.length === writeElementCount) { 361 | expect(errCount).toBeGreaterThan(0); 362 | done(); 363 | } 364 | }; 365 | 366 | RTT.start(device.serialNumber, {}, startCallback); 367 | 368 | for (let i = 0; i < readElementCount; i++) { 369 | RTT.write(0, "test", writeCallback); 370 | } 371 | }); 372 | }); 373 | }); 374 | 375 | 376 | -------------------------------------------------------------------------------- /test/rttfailing.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | 41 | let device; 42 | 43 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; 44 | 45 | const rttFailing = () => { 46 | beforeAll(done => { 47 | const programCallback = err => { 48 | expect(err).toBeUndefined(); 49 | 50 | done(); 51 | }; 52 | 53 | const callback = (err, connectedDevices) => { 54 | expect(err).toBeUndefined(); 55 | expect(connectedDevices.length).toBeGreaterThanOrEqual(1); 56 | device = connectedDevices[0]; 57 | 58 | nRFjprog.program(device.serialNumber, "./test/hex/program.hex", { }, programCallback); 59 | }; 60 | 61 | nRFjprog.getConnectedDevices(callback); 62 | }); 63 | 64 | describe('can not start RTT', () => { 65 | it('fails cleanly', (done) => { 66 | const startCallback = (err, down, up) => { 67 | expect(err).toBeDefined(); 68 | expect(err).toMatchSnapshot(); 69 | 70 | done(); 71 | }; 72 | 73 | nRFjprog.rttStart(device.serialNumber, {}, startCallback); 74 | }); 75 | }); 76 | }; 77 | 78 | exports.rttFailing = rttFailing; 79 | -------------------------------------------------------------------------------- /test/single-device-destructive.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | const fs = require('fs'); 41 | 42 | let device; 43 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; 44 | 45 | let testfile = './test/hex/connectivity_1.1.0_1m_with_s132_3.0.hex'; 46 | 47 | const singleDeviceDesctructive = () => { 48 | beforeAll(done => { 49 | const callback = (err, connectedDevices) => { 50 | expect(err).toBeUndefined(); 51 | expect(connectedDevices.length).toBeGreaterThanOrEqual(1); 52 | device = connectedDevices[0]; 53 | if (device.deviceInfo.family === nRFjprog.NRF53_FAMILY) { 54 | testfile = './test/hex/while_true_nrf53_application.hex'; 55 | } 56 | done(); 57 | }; 58 | 59 | nRFjprog.getConnectedDevices(callback); 60 | }); 61 | 62 | it('erases the whole device', done => { 63 | const callback = (err) => { 64 | expect(err).toBeUndefined(); 65 | done(); 66 | }; 67 | 68 | nRFjprog.erase(device.serialNumber, {}, callback); 69 | }); 70 | 71 | it('programs a hex file', done => { 72 | 73 | const callback = (err) => { 74 | expect(err).toBeUndefined(); 75 | 76 | nRFjprog.verify(device.serialNumber, testfile, { }, verifyCallback); 77 | }; 78 | 79 | const verifyCallback = (err) => { 80 | expect(err).toBeUndefined(); 81 | done(); 82 | }; 83 | 84 | nRFjprog.program(device.serialNumber, testfile, { }, callback); 85 | }); 86 | 87 | it('reads device content', done => { 88 | const callback = (err) => { 89 | expect(err).toBeUndefined(); 90 | done(); 91 | }; 92 | 93 | nRFjprog.readToFile(device.serialNumber, "./after_readToFile.hex", { readcode: true, readuicr: true }, callback); 94 | }); 95 | 96 | it('verifies a hex file', done => { 97 | const callback = (err) => { 98 | expect(err).toBeUndefined(); 99 | done(); 100 | }; 101 | 102 | nRFjprog.verify(device.serialNumber, testfile, { }, callback); 103 | }); 104 | 105 | // There's an issue with the mocked progress callback under jest, 106 | // but it works fine otherwise, hence it's skipped here 107 | it.skip('verifies a hex file with progress callback', done => { 108 | const mockProgressCallback = jest.fn(); 109 | 110 | const callback = (err) => { 111 | expect(err).toBeUndefined(); 112 | // expect(mockProgressCallback).toHaveBeenCalled(); 113 | done(); 114 | }; 115 | 116 | nRFjprog.verify(device.serialNumber, testfile, { }, mockProgressCallback, callback); 117 | }); 118 | 119 | it('programs a hex string', done => { 120 | const callback = (err) => { 121 | expect(err).toBeUndefined(); 122 | 123 | nRFjprog.verify(device.serialNumber, testfile, { }, verifyCallback); 124 | }; 125 | 126 | const verifyCallback = (err) => { 127 | expect(err).toBeUndefined(); 128 | done(); 129 | }; 130 | 131 | const filecontent = fs.readFileSync(testfile).toString('utf-8'); 132 | 133 | nRFjprog.program(device.serialNumber, filecontent, { inputFormat: nRFjprog.INPUT_FORMAT_HEX_STRING }, callback); 134 | }); 135 | 136 | it('recovers a device', done => { 137 | const callback = (err) => { 138 | expect(err).toBeUndefined(); 139 | 140 | nRFjprog.readToFile(device.serialNumber, "./after_recover.hex", { readcode: true, readuicr: true }, readToFileCallback); 141 | }; 142 | 143 | const readToFileCallback = (err) => { 144 | expect(err).toBeUndefined(); 145 | done(); 146 | }; 147 | 148 | nRFjprog.recover(device.serialNumber, callback); 149 | }); 150 | 151 | it('writes an array to a device', done => { 152 | const address = 0x1028; 153 | const data = [0, 1, 2, 3, 4, 5, 6]; 154 | 155 | const callback = (err) => { 156 | expect(err).toBeUndefined(); 157 | 158 | nRFjprog.read(device.serialNumber, address, data.length, readCallback); 159 | }; 160 | 161 | const readCallback = (err, contents) => { 162 | expect(err).toBeUndefined(); 163 | expect(contents).toBeDefined(); 164 | expect(contents).toEqual(expect.arrayContaining(data)); 165 | done(); 166 | }; 167 | 168 | nRFjprog.write(device.serialNumber, address, data, callback); 169 | }); 170 | 171 | it('writes a 32 bit value to a device', done => { 172 | const address = 0x1024; 173 | const data = 0x12345678; 174 | 175 | const callback = (err) => { 176 | expect(err).toBeUndefined(); 177 | 178 | nRFjprog.readU32(device.serialNumber, address, readCallback); 179 | }; 180 | 181 | const readCallback = (err, contents) => { 182 | expect(err).toBeUndefined(); 183 | expect(contents).toBeDefined(); 184 | expect(contents).toEqual(data); 185 | done(); 186 | }; 187 | 188 | nRFjprog.writeU32(device.serialNumber, address, data, callback); 189 | }); 190 | }; 191 | 192 | exports.singleDeviceDesctructive = singleDeviceDesctructive; 193 | -------------------------------------------------------------------------------- /test/single-device-non-destructive.test.js: -------------------------------------------------------------------------------- 1 | /* Copyright (c) 2015 - 2019, Nordic Semiconductor ASA 2 | * 3 | * All rights reserved. 4 | * 5 | * Use in source and binary forms, redistribution in binary form only, with 6 | * or without modification, are permitted provided that the following conditions 7 | * are met: 8 | * 9 | * 1. Redistributions in binary form, except as embedded into a Nordic 10 | * Semiconductor ASA integrated circuit in a product or a software update for 11 | * such product, must reproduce the above copyright notice, this list of 12 | * conditions and the following disclaimer in the documentation and/or other 13 | * materials provided with the distribution. 14 | * 15 | * 2. Neither the name of Nordic Semiconductor ASA nor the names of its 16 | * contributors may be used to endorse or promote products derived from this 17 | * software without specific prior written permission. 18 | * 19 | * 3. This software, with or without modification, must only be used with a Nordic 20 | * Semiconductor ASA integrated circuit. 21 | * 22 | * 4. Any software provided in binary form under this license must not be reverse 23 | * engineered, decompiled, modified and/or disassembled. 24 | * 25 | * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS OR 26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 27 | * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE 28 | * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE LIABLE 29 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 30 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 31 | * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 32 | * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 33 | * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35 | */ 36 | 37 | 'use strict'; 38 | 39 | const nRFjprog = require('../index.js'); 40 | 41 | let device; 42 | jasmine.DEFAULT_TIMEOUT_INTERVAL = 100000; 43 | 44 | const singleDeviceNonDesctructive = () => { 45 | beforeAll(done => { 46 | const callback = (err, connectedDevices) => { 47 | expect(err).toBeUndefined(); 48 | expect(connectedDevices.length).toBeGreaterThanOrEqual(1); 49 | device = connectedDevices[0]; 50 | 51 | done(); 52 | }; 53 | 54 | nRFjprog.getConnectedDevices(callback); 55 | }); 56 | 57 | it('finds correct device info', done => { 58 | const callback = (err, deviceInfo) => { 59 | expect(err).toBeUndefined(); 60 | expect(deviceInfo).toMatchObject(device.deviceInfo); 61 | done(); 62 | }; 63 | 64 | nRFjprog.getDeviceInfo(device.serialNumber, callback); 65 | }); 66 | 67 | it('finds correct probe info', done => { 68 | const callback = (err, probeInfo) => { 69 | expect(err).toBeUndefined(); 70 | expect(probeInfo).toMatchObject(device.probeInfo); 71 | expect(probeInfo).toHaveProperty('serialNumber'); 72 | expect(probeInfo).toHaveProperty('clockSpeedkHz'); 73 | expect(probeInfo).toHaveProperty('firmwareString'); 74 | done(); 75 | }; 76 | 77 | nRFjprog.getProbeInfo(device.serialNumber, callback); 78 | }); 79 | 80 | it('finds correct library info', done => { 81 | const callback = (err, libraryInfo) => { 82 | expect(err).toBeUndefined(); 83 | expect(libraryInfo).toMatchObject(device.libraryInfo); 84 | expect(libraryInfo).toHaveProperty('version'); 85 | expect(libraryInfo.version).toHaveProperty('major'); 86 | expect(libraryInfo.version).toHaveProperty('minor'); 87 | expect(libraryInfo.version).toHaveProperty('revision'); 88 | expect(libraryInfo).toHaveProperty('path'); 89 | done(); 90 | }; 91 | 92 | nRFjprog.getLibraryInfo(device.serialNumber, callback); 93 | }); 94 | 95 | it('throws an error when device do not exist', done => { 96 | const callback = (err, deviceInfo) => { 97 | expect(err).toMatchSnapshot(); 98 | expect(deviceInfo).toBeUndefined(); 99 | done(); 100 | }; 101 | 102 | nRFjprog.getDeviceInfo(1, callback); 103 | }); 104 | 105 | it('reads from specified address', done => { 106 | const callback = (err, contents) => { 107 | expect(err).toBeUndefined(); 108 | expect(contents).toBeDefined(); 109 | done(); 110 | }; 111 | 112 | nRFjprog.read(device.serialNumber, 0x0, 1, callback); 113 | }); 114 | 115 | it('reads 5 bytes from specified address', done => { 116 | const readLength = 5; 117 | 118 | const callback = (err, contents) => { 119 | expect(err).toBeUndefined(); 120 | expect(contents).toBeDefined(); 121 | expect(contents.length).toBe(readLength); 122 | done(); 123 | }; 124 | 125 | nRFjprog.read(device.serialNumber, 0x0, readLength, callback); 126 | }); 127 | 128 | it('reads unsigned 32 from specified address', done => { 129 | const callback = (err, contents) => { 130 | expect(err).toBeUndefined(); 131 | expect(contents).toBeDefined(); 132 | done(); 133 | }; 134 | 135 | nRFjprog.readU32(device.serialNumber, 0x0, callback); 136 | }); 137 | 138 | it('keeps connection open when using open/close', done => { 139 | const readLength = 10; 140 | 141 | const callback = (err, contents) => { 142 | expect(err).toBeUndefined(); 143 | nRFjprog.close(device.serialNumber, (err) => { 144 | expect(err).toBeUndefined(); 145 | expect(contents.length).toBe(readLength); 146 | done(); 147 | }); 148 | }; 149 | 150 | nRFjprog.open(device.serialNumber, (err) => { 151 | expect(err).toBeUndefined(); 152 | nRFjprog.read(device.serialNumber, 0x0, readLength, callback); 153 | }); 154 | }); 155 | 156 | it('calling open twice returns an error', done => { 157 | nRFjprog.open(device.serialNumber, (err) => { 158 | expect(err).toBeUndefined(); 159 | nRFjprog.open(device.serialNumber, (err) => { 160 | expect(err).toBeDefined(); 161 | nRFjprog.close(device.serialNumber, (err) => { 162 | expect(err).toBeUndefined(); 163 | done(); 164 | }); 165 | }); 166 | }); 167 | }); 168 | 169 | it('should be able to reopen after close', done => { 170 | nRFjprog.open(device.serialNumber, (err) => { 171 | expect(err).toBeUndefined(); 172 | nRFjprog.close(device.serialNumber, (err) => { 173 | expect(err).toBeUndefined(); 174 | nRFjprog.open(device.serialNumber, (err) => { 175 | expect(err).toBeUndefined(); 176 | nRFjprog.close(device.serialNumber, (err) => { 177 | expect(err).toBeUndefined(); 178 | done(); 179 | }); 180 | }); 181 | }); 182 | }); 183 | }); 184 | 185 | it('calling close twice has no effect', done => { 186 | nRFjprog.open(device.serialNumber, (err) => { 187 | expect(err).toBeUndefined(); 188 | nRFjprog.close(device.serialNumber, (err) => { 189 | expect(err).toBeUndefined(); 190 | nRFjprog.close(device.serialNumber, (err) => { 191 | expect(err).toBeUndefined(); 192 | done(); 193 | }); 194 | }); 195 | }); 196 | }); 197 | 198 | it('reads more than 0x10000 bytes', done => { 199 | const readLength = 0x10004; 200 | 201 | const callback = (err, contents) => { 202 | expect(err).toBeUndefined(); 203 | expect(contents).toBeDefined(); 204 | expect(contents.length).toBe(readLength); 205 | done(); 206 | }; 207 | 208 | nRFjprog.read(device.serialNumber, 0x0, readLength, callback); 209 | }); 210 | }; 211 | 212 | exports.singleDeviceNonDesctructive = singleDeviceNonDesctructive; 213 | --------------------------------------------------------------------------------